Skip to content

Apple Desktop Bus

hasu@tmk edited this page Nov 9, 2024 · 129 revisions

TMK ADB-USB Conveter

It can trasnlate Apple ADB keyboard/mouse protocol to USB, you can use it to plug old ADB keyboard/mouse into modern computer.

Prebuilt Converter

You can buy prebuilt TMK ADB-USB converter and support this project here.

https://geekhack.org/index.php?topic=72052.0

Pull-up Resistor

You must have an external pull-up resistor between VCC(5V) and DATA(PD0) line. 1k ohm is strongly recommended.(470 ohm is more legitimate? see this.)

Keyboard                                       MCU(AVR)
   -----.                                      ,-----.
      5V|---------------------------------+----|VCC  |
        |                                 |    |     |
        |                                 R    |     |
        |                                 |    |     |
    DATA|---------------------------------+----|PD0  |
        |                                      |     |
     GND|--------------------------------------|GND  |
   -----'                                      `-----'
R: 1K Ohm resistor

4.7k-10k won't work in some cases like longer curled cable or daisy-chained multiple devices. See issues below.

Supported Device

See this for the latest info.

Keyboard

Default address of keyboard is 2. Most of other keyboards should be supported.

  • Apple Standard Keyboard(1) - M0116
  • Apple Extended Keyboard(2) - M0115, M3501
  • Apple Extended Keyboard Protocol(3)
  • Apple Standard Keyboard ISO(4) - M0118
  • Apple Adjustable Keyboard($10) - M1242
  • Apple Desktop Bus Keyboard - 658-4081
  • Key Tronic TrakPro(Mac) with track ball - ok

Supported layouts: ANSI, ISO, JIS

Mouse

Default address of mouse is 3. Mouse handler ID below are curretnly supported.

See this for other mouses.

TMK implementation

Hot-plug support

The converter scans address 1-15 to detect plugged or unpluged device at 1 sec interval. If new device is found it is moved to higher address 8-15, initialized and registered onto device_table before it is polled. (resolve_address)

Polling

The converter polls the registered devices at 12ms interval with Service Request(SRQ) support.(hook_main_loop)

Keyboard handler

keyboard_setup, keyboard_proc

Mouse handler

mouse_setup, mouse_proc

Appliance handler

appliance_setup, appliance_proc

Hardware

Pinouts

ADB female socket from the front:
  ,--_--.
 / o4 3o \      1: DATA
| o2   1o |     2: PSW(Power SW)
 -  ===  -      3: VCC
  `-___-'       4: GND

Interface

Host side

Griffin iMate and Apple IIGS ADB interface have 470 ohm pull-up resistor.

Peripheral side

Apple Desktop Bus Mouse II(BCGM2706) seems to have 1k ohm pull-up.

Kensington Turbo Mouse 5 has no pull-up resistor, internal pull-up only?

Protocol

Communication

This is a minimum information for keyboard communication.
See "Resources" for detail.

Signaling:
____            __              _____ __                 ____
    ____________  ||||||||||||__     _  |||||||||||||||__

    |800us     |  |7 Command 0|  |   |  |15-63  Data  0|Stopbit(0)
    +Attention |              |  |   +Startbit(1)
               +Startbit(1)   |  +Tlt(140-260us)
                              +stopbit(0)

Bit cells:
            ___
bit0: ______
      65us  35us
         ______
bit1: ___
      35us  65us

Attention & start bit:
Host asserts low in 560-1040us then places start bit(1).

Tlt(Stop to Start):
Bus stays high in 140-260us then device places start bit(1).

Global reset:
Host asserts low in 2.8-5.2ms. All devices are forced to reset.

Service request from device(Srq):
Device can request to send at commad(Global only?) stop bit.
Requesting device keeps low for 140-260us at stop bit of command.

Data:
This can be 2-8 bytes.

Bit Cell

bit cell time: 70-130us
bit0 low time: 60-70% of bit cell time
bit1 low time: 30-40% of bit cell time

bit0:
                 ______
     ____________
     60-70%


bit1:
           ____________
     ______
     30-40%

if (low_time > hi_time) then "0" else "1"

from Apple IIgs Hardware Reference Second Edition p.136

Global Reset signal

The computer initiates a reset of all devices on the ADB bus by holding the bus low for a minimum of 3.0 ms. Each device clears all pending service requests and returns to a state in which it can accept commands and assert Service Request signals. (p.317 Guide)

Service Request

A Service Request signal is used by a device to inform the computer that the device has data to send. A device sends a Service Request signal by holding the bus low during the low portion of the stop bit of any command or data transaction. The device must lengthen the stop by a minimum of 140 µs beyond its normal duration, as shown in Figure 8-15. (p.318 Guide)

To send a Service Request signal, a device waits until the end of a command and then holds the bus low for 140 to 260 µs. (p.325 Guide)

Command:
......._     ______________________    ___ ............_     -------
        |   |                      |  |   |             |   |
Command |   |                      |  |   | Data bytes  |   |
........|___|  |     140-260       |__|   |_............|___|
        |stop0 | Tlt Stop-to-Start |start1|             |stop0 |

Command without data:
......._     __________________________
        |   |
Command |   |
........|___|  |     140-260       |
        |stop0 | Tlt Stop-to-Start |

Service Request:
......._                     ______    ___ ............_     -------
        |     140-260       |      |  |   |             |   |
Command |  Service Request  |      |  |   | Data bytes  |   |
........|___________________|      |__|   |_............|___|
        |stop0 |                   |start1|             |stop0 |
......._                     __________
        |     140-260       |
Command |  Service Request  |
........|___________________|
        |stop0 |

/*
This can be happened?
......._     ______________________    ___ ............_                   -----
        |   |                      |  |   |             |    140-260      |
Command |   |                      |  |   | Data bytes  | Service Request |
........|___|  |     140-260       |__|   |_............|_________________|
        |stop0 | Tlt Stop-to-Start |start1|             |stop0 |
*/

Data: 2-8 bytes

    
"Service requests are issued by the devices during a very specific time at the
end of the reception of the command packet.
If a device in need of service issues a service request, it must do so within
the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."

"A device sends a Service Request signal by holding the bus low during the low
portion of the stop bit of any command or data transaction. The device must lengthen
the stop by a minimum of 140 uS beyond its normal duration, as shown in Figure 8-15."

http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf

Address Resolution

At system startup, the ADB Manager polls all ADB devices at each ADB address and begins the process of building the ADB device table by sending a Talk Register 3 command to each device. Each ADB device at a specific address attempts to respond by sending a random device address. If more than one ADB device shares an address, however, each device that detects a collision immediately stops transmitting data. The device that has not detected the collision completes sending its random address across the bus. In response, the ADB Manager sends to the original address a Listen Register 3 command that contains a new ADB device address and a device handler ID of $FE. A new ADB device address is always a value between $8 and $E($F?). A device handler ID of $FE instructs a device to change to the new device address only if it does not detect a collision. Any detecting devices will therefore ignore the next Listen Register 3 command containing a new ADB device address. As a result, only the device that did not detect the collision moves to the new address; the detecting devices remain at the original address. The ADB Manager now sends another Talk Register 3 command to the new address to verify that the device moved to that location. In response, the moved device must once again return a random address. The ADB Manager repeats this process until it receives no response when it sends a Talk Register 3 command to the shared address. This indicates that no devices reside at the address and that it is an available address location for a device. The ADB Manager then moves the first(last?) device it relocated to a new address back to its original address. (p.5-16 ADB Manager)

At startup, the Start Manager sends a Talk Register 3command to each ADB address. If there is more than one device at an address, each device that loses the collision sets its internal collision flag and disables its movable address function. The Start Manager then sends a Listen Register 3command to that address with a Device Handler ID of $FE and a new device address. The device that did not detect the collision is moved to the new address. This process is repeated until the response to a Talk Register 3command at that address is a timeout, that is, until there are no more devices at that address. Then one of the devices is moved back to the default address, and the Start Manager goes on to the next address.(p.325 Guide)

Click
    resetBus(); // Reset command(not global reset) to reset all devices

    /*
     * Okay, now attempt reassign the
     * bus
     */

    unresolvedAddrs = 0;
    freeAddrs = 0xfffe;

    // Scan address 1-15
    /* Skip 0 -- it's special! */
    for (i = 1; i < 16; i++) {
        if( probeAddress(i) ) { // Talk Register 3
            unresolvedAddrs |= ( 1 << i );
            freeAddrs &= ~( 1 << i );
        }
    }

    /* Now attempt to reassign the addresses */
    while( unresolvedAddrs) {
        if( !freeAddrs) {
            panic("ADB: Cannot find a free ADB slot for reassignment!");
        }

        freeNum = firstBit(freeAddrs);
        devNum = firstBit(unresolvedAddrs);

        if( !moveDeviceFrom(devNum, freeNum, true) ) {
            /* It didn't move.. bad! */
            IOLog("WARNING : ADB DEVICE %d having problems " "probing!\n", devNum);
        } else {
            if( probeAddress(devNum) ) {
                /* Found another device at the address, leave
                * the first device moved to one side and set up
                * newly found device for probing
                */
                freeAddrs &= ~( 1 << freeNum );

                devNum = 0;

            } else {
                /* no more at this address, good !*/
                /* Move it back.. */
                moveDeviceFrom(freeNum,devNum,false);
            }
        }
        if(devNum) {
            unresolvedAddrs &= ~( 1 << devNum );
        }
    }

Collision Detection

Whenever an ADB device attempts to bring the bus high, it should verify whether the bus actually goes high. If the bus instead goes low, this indicates that another device is also trying to send data. The device detecting the collision must immediately stop transmitting and save the data it was sending.

For the ADB Manager to accomplish address resolution, an ADB device must meet two design requirements: first, it must have collision detection, and second, it must always respond to a Talk Register 3 command by returning a random device address in bits 8 through 11. The ability of devices to send random addresses plays a crucial role in collision detection. (p.5-15 ADB Manager)

Polling

If there are no service requests pending, the ADB Manager sends a Talk Register 0command to address $03 (the default active device, usually the mouse) and the ADB transceiver repeats this command every 11 ms.

When receiving the Service Request signal it sends a Talk Register 0 command to each device on the bus until it finds the one requiring service.

The last device to send data to the computer becomes the active device, and the ADB transceiver addresses Talk Register O commands to that device every 11 ms until some other device asserts a Service Request signal. (p.325 Guide)

Commands

ADB command is 1byte and consists of 4bit-address, 2bit-command
type and 2bit-register. The commands are always sent by Host.

Command format:
7 6 5 4 3 2 1 0
| | | |------------ address
        | |-------- command type
            | |---- register

bits                commands
------------------------------------------------------
- - - - 0 0 0 0     Send Reset(reset all devices)
A A A A 0 0 0 1     Flush(reset a device)
- - - - 0 0 1 0     Reserved
- - - - 0 0 1 1     Reserved
- - - - 0 1 - -     Reserved
A A A A 1 0 R R     Listen(write to a device)
A A A A 1 1 R R     Talk(read from a device)

The command to read keycodes from keyboard is 0x2C which
consist of keyboard address 2 and Talk against register 0.

Address:
2:  keyboard
3:  mice

Registers:
0: application(keyboard uses this to store its data.)
1: application
2: application(keyboard uses this for LEDs and state of modifiers)
3: status and command

Talk

The ADB Manager sends a Talk command to a device to fetch user input (or other data) from the device. The Talk command requests that a specified device send the contents of a specified device register across the bus. After the device sends the data from the specified register, the ADB Manager places the data into a buffer in RAM, which the ADB Manager makes available for use by device handlers or (in rare cases) applications. In the case of a Talk Register 0 command, the ADB device should respond to the ADB Manager only if it has new data to send.

Listen

The ADB Manager sends a Listen command to a device to instruct it to prepare to receive additional data. The Listen command indicates which data register is to receive the data. After sending a Listen command, the ADB Manager then transfers data from a buffer in RAM to the device. The device must overwrite the existing contents of the specified register with the new data.

Flush

The ADB Manager sends a Flush command to a device to force it to flush any existing user-input data from a specified device register. The device should prepare itself to receive any further input from the user.

SendReset

The ADB Manager uses a SendReset command to force all devices on the bus to reset themselves to their startup states. Each device should clear any of its pending device actions and prepare to accept new ADB commands and user input data immediately. Note that the ADB device does not actually receive the SendReset command but recognizes that it should reset itself when the bus is driven low by the 3 millisecond reset pulse. Your application should never send the SendReset command.

Address

Addr Description
0 Reserved
1 Dongle
2 keyboard
3 Mouse
4 Tablet
5 Reserved
6 Reserved
7 Appliance
8-15 Soft Address

Default address 0 is used by the ADB host; addresses 8 through 15 are used as locations for locating devices dynamically.

The default address $0 is reserved for the Macintosh computer. Addresses $8 through $E($F?) are reserved by the ADB Manager for dynamically relocating devices to resolve address collision. (p.5-12 Guide)

Handler ID

ID Description
FF Self Test
FE Change address if no collision
FD Change address if activated
00 Change address and field

Keyboard Protocol

Mac OS X driver: https://github.com/apple-oss-distributions/AppleADBKeyboard/blob/AppleADBKeyboard-239.1/AppleADBKeyboard.cpp

Keyboard Data(Register0)

This 16bit data can contains two keycodes and two released flags.
First keycode is palced in upper byte. When one keyocode is sent,
lower byte is 0xFF.
Release flag is 1 when key is released.

1514 . . . . . 8 7 6 . . . . . 0
 | | | | | | | | | +-+-+-+-+-+-+-   Keycode2
 | | | | | | | | +---------------   Released2(1 when the key is released)
 | +-+-+-+-+-+-+-----------------   Keycode1
 +-------------------------------   Released1(1 when the key is released)

Keycodes:
Scancode consists of 7bit keycode and 1bit release flag.
Device can send two keycodes at once. If just one keycode is sent
keycode1 contains it and keyocode2 is 0xFF.

Power switch:
You can read the state from PSW line(active low) however
the switch has a special scancode 0x7F7F, so you can
also read from Data line. It uses 0xFFFF for release scancode.

Keyboard LEDs & state of keys(Register2)

This register hold current state of three LEDs and nine keys.
The state of LEDs can be changed by sending Listen command.

1514 . . . . . . 7 6 5 . 3 2 1 0
 | | | | | | | | | | | | | | | +-   LED1(NumLock)
 | | | | | | | | | | | | | | +---   LED2(CapsLock)
 | | | | | | | | | | | | | +-----   LED3(ScrollLock)
 | | | | | | | | | | +-+-+-------   Reserved
 | | | | | | | | | +-------------   ScrollLock
 | | | | | | | | +---------------   NumLock
 | | | | | | | +-----------------   Apple/Command
 | | | | | | +-------------------   Option
 | | | | | +---------------------   Shift
 | | | | +-----------------------   Control
 | | | +-------------------------   Reset/Power
 | | +---------------------------   CapsLock
 | +-----------------------------   Delete
 +-------------------------------   Reserved

Address, Handler ID and bits(Register3)

1514131211 . . 8 7 . . . . . . 0
 | | | | | | | | | | | | | | | |
 | | | | | | | | +-+-+-+-+-+-+-+-   Handler ID
 | | | | +-+-+-+-----------------   Address
 | | | +-------------------------   0
 | | +---------------------------   Service request enable(1 = enabled)
 | +-----------------------------   Exceptional event(alwyas 1 if not used)
 +-------------------------------   0

Keyboard Handler ID

Apple Standard Keyboard M0116:        0x01
Apple Extended Keyboard M0115:        0x02
Apple Extended Keyboard II M3501:     0x02
Apple Standard Keyboard ISO M0118:    0x04
Apple Extended Keyboard ISO M0115:    0x05
Apple Extended Keyboard II ISO M3501: 0x05
Apple Keyboard II M0487:              0x08
Apple Keyboard II ISO:                0x09
Apple Adjustable Keypad M1242:        0x0E
Apple Adjustable Keyboard M1242:      0x10
Apple Adjustable Keyboard ISO:        0x11
Apple Adjustable Keyboard JIS:        0x12(18)
Apple Keyboard II JIS M0487:          0x16(22)
Apple Design Keyboard M2980:          0x1B(27)?

NeXT ADB Keyboard German:             0x03
ANSI: 0x01 0x02 0x03 0x06 0x08 0x0C 0x10 0x18 0x1B 0x1C 0xC0 0xC3 0xC6
ISO: 0x04 0x05 0x07 0x09 0x0D 0x11 0x14 0x19 0x1D 0xC1 0xC4 0xC7
JIS: 0x12 0x15 0x16 0x17 0x1A 0x1E 0xC2 0xC5 0xC8 0xC9

http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/arch/macppc/include/adbsys.h?rev=1.4.4.2&content-type=text/x-cvsweb-markup

https://elixir.bootlin.com/linux/v5.17/source/drivers/macintosh/adbhid.c#L790

https://github.com/apple-oss-distributions/AppleADBKeyboard/blob/AppleADBKeyboard-239.1/AppleADBKeyboard.cpp#L464-L480

NeXT: https://geekhack.org/index.php?topic=14290.msg2996688#msg2996688

M0487 JIS: https://geekhack.org/index.php?topic=14290.msg3121108#msg3121108

M0118: https://github.com/tmk/tmk_keyboard/issues/756#issuecomment-1464950762

Keyboard Extended Protocol

On Standard Keyboards left and right modifiers cannot be discriminated. Right Shift acts just as left Shift for example.

On Extended Keyboards left and right modifiers can be descriminated except for Command key. Left and Right Command key are identical.

OSX supports Keyboard Extended Protocol only for Handler ID 2, 3 and 5(Apple Extended Keyboard M0115/M3501/ISO). https://github.com/apple-oss-distributions/AppleADBKeyboard/blob/AppleADBKeyboard-239.1/AppleADBKeyboard.cpp#L470-L480

Polling Interval

12ms interval is good compromise in consideration of unresponsive keyboards including M0116 and IIgs keyboard. (as of 2021-11)

Extended keyboard can go with far lower interval but it(<8ms?) will causes problem of missing key strokes on some keyboards. https://geekhack.org/index.php?topic=14290.msg1068919#msg1068919

Polling interval of other ADB host implementations:

ADB polling periods
PowerBook 520c: 11.7 ms
PowerMac 8500 11.2 ms
Belkin ADB-USB adapter: 8.34 ms

Since this isn't for gaming, I'd say 11.5 ms is a good level. Clearly lower values are risky.

https://geekhack.org/index.php?topic=14290.msg1070139#msg1070139

Mouse Protocol

Mac OS X driver: https://github.com/apple-oss-distributions/AppleADBMouse/blob/AppleADBMouse-212/AppleADBMouse.cpp

Device specific driver

https://github.com/tmk/tmk_keyboard/issues/725

Protocol Decoder

I wrote ADB protocol decoder for sigrok. You can use this deocoder with sigrok PulseView to see ADB commands and data.

https://github.com/tmk/decoder-adb

See this for installation of decoder.

https://github.com/tmk/tmk_keyboard/wiki/Signal-Capture-for-debug#installation

For the decoder cheap $10-20 Logic Analyzer works well for this job. 1MHz sample rate is actually good enough for ADB protocol.

Scan codes

Unimap Default Mapping

TMK ADB-USB Converter default mapping on Keymap Editor

,---.   .---------------. ,---------------. ,---------------. ,-----------.             ,---.
|Esc|   |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|             |Pwr|
`---'   `---------------' `---------------' `---------------' `-----------'             `---'
,-----------------------------------------------------------. ,-----------. ,---------------. ,---.
|  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|JPY| BS| |Ins|Hom|PgU| |NmL|  =|  /|  *| |VUp|
|-----------------------------------------------------------| |-----------| |---------------| |---|
|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \  | |Del|End|PgD| |  7|  8|  9|  -| |VDn|
|-----------------------------------------------------------| `-----------' |---------------| |---|
|CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  #| Ret|               |  4|  5|  6|  +| |Mut|
|-----------------------------------------------------------|     ,---.     |---------------| `---'
|Shif|  <|  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /| RO| Shift|     |Up |     |  1|  2|  3|   |
|-----------------------------------------------------------| ,-----------. |-----------|Ent| ,---.
|Ctrl |Alt |Gui  |Muh|    Space    |Hen|Hir|Gui* |Alt |Ctrl | |Lef|Dow|Rig| |  0|  ,|  .|   | |Ply|
`-----------------------------------------------------------' `-----------' `---------------' `---'
Muh:無変換, Hen:変換, Hir:ひらがな

,---.   .---------------. ,---------------. ,---------------. ,-----------.             ,---.
| 35|   | 7A| 78| 63| 76| | 60| 61| 62| 64| | 65| 6D| 67| 6F| | 69| 6B| 71|             | 7F|
`---'   `---------------' `---------------' `---------------' `-----------'             `---'
,-----------------------------------------------------------. ,-----------. ,---------------. ,---.
|*32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 5D| 33| | 72| 73| 74| | 47| 51| 4B| 43| | 48|
|-----------------------------------------------------------| |-----------| |---------------| |---|
|  30 | 0C| 0D| 0E| 0F| 11| 10| 20| 22| 1F| 23| 21| 1E|  2A | | 75| 77| 79| | 59| 5B| 5C| 4E| | 49|
|-----------------------------------------------------------| `-----------' |---------------| |---|
|  39  | 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|*70| 24 |               | 56| 57| 58| 45| | 4A|
|-----------------------------------------------------------|     ,---.     |---------------| `---'
| 38 |*0A| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 5E|  7B  |     | 3E|     | 53| 54| 55|   |
|-----------------------------------------------------------| ,-----------. |-----------| 4C| ,---.
|  36 | 3A |  37 | 66|       31    | 68| 6A| *37 | 7C |  7D | | 3B| 3D| 3C| | 52| 5F| 41|   | | 42|
`-----------------------------------------------------------' `-----------' `---------------' `---'
NOTE: Not-extended ADB keyboards have no discrimination between left and right modifiers.
Use left ones for mapping. Right modifier always sends same code as left one.
Apple Extended Keyboard can discriminate the modifiers except for Command(GUI) key.
For ISO keyboard scan code 0A and 32 are swapped and scan code 2A is translated to 70.
For JIS Keyboard scan code 2A is translated to 70.

Apple Extended Keyboard M0115:

Click

https://deskthority.net/wiki/images/1/1a/Apple_M0115_top.jpg

,---.   .---------------. ,---------------. ,---------------. ,-----------.             ,---.
|Esc|   |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|             |Pwr|
`---'   `---------------' `---------------' `---------------' `-----------'             `---'
,-----------------------------------------------------------. ,-----------. ,---------------.
|  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backspa| |Ins|Hom|PgU| |NmL|  =|  /|  *|
|-----------------------------------------------------------| |-----------| |---------------|
|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \  | |Del|End|PgD| |  7|  8|  9|  -|
|-----------------------------------------------------------| `-----------' |---------------|
|CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  Return|               |  4|  5|  6|  +|
|-----------------------------------------------------------|     ,---.     |---------------|
|Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|Shift     |     |Up |     |  1|  2|  3|   |
|-----------------------------------------------------------| ,-----------. |-----------|Ent|
|Ctrl |Opt | Cmd |        Space            | Cmd |Opt |Ctrl | |Lef|Dow|Rig| |      0|  .|   |
`-----------------------------------------------------------' `-----------' `---------------'
                   
,---.   .---------------. ,---------------. ,---------------. ,-----------.             ,---.
| 35|   | 7A| 78| 63| 76| | 60| 61| 62| 64| | 65| 6D| 67| 6F| | 69| 6B| 71|             | 7F|
`---'   `---------------' `---------------' `---------------' `-----------'             `---'
,-----------------------------------------------------------. ,-----------. ,---------------.
| 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33  | | 72| 73| 74| | 47| 51| 4B| 43|
|-----------------------------------------------------------| |-----------| |---------------|
|  30 | 0C| 0D| 0E| 0F| 11| 10| 20| 22| 1F| 23| 21| 1E|  2A | | 75| 77| 79| | 59| 5B| 5C| 4E|
|-----------------------------------------------------------| `-----------' |---------------|
|  39  | 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|   24   |               | 56| 57| 58| 45|
|-----------------------------------------------------------|     ,---.     |---------------|
|   38   | 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|    7B    |     | 3E|     | 53| 54| 55|   |
|-----------------------------------------------------------| ,-----------. |-----------| 4C|
|  36 | 3A |  37 |           31            |  37 | 7C |  7D | | 3B| 3D| 3C| |    52 | 41|   |
`-----------------------------------------------------------' `-----------' `---------------'
* Power key scan code 7F7F is translated into 7F by TMK converter

M0115D German: https://imgur.com/a/6FhnkSP

Apple Extended Keyboard II ISO specific keys:

Click

https://user-images.githubusercontent.com/6669125/32100612-b973cdb0-bb14-11e7-86de-0794e77eec66.png

,-----------------------------------------------------------.
| 0A |   |   |   |   |   |   |   |   |   |   |   |   |      |
|-----------------------------------------------------------|
|      |   |   |   |   |   |   |   |   |   |   |   |   |    |
|-------------------------------------------------------` 24|
|       |   |   |   |   |   |   |   |   |   |   |   | 2A|   |
|-----------------------------------------------------------|
|  38 | 32|   |   |   |   |   |   |   |   |   |   |         |
|-----------------------------------------------------------|
|     |    |     |                         |     |    |     |
`-----------------------------------------------------------'
* For Apple ISO keyboard 0A and 32 are swapped
    https://github.com/tmk/tmk_keyboard/issues/35
* For Apple ISO keyboard 2A is translated to 70
* Default mapping on Unimap
    32->0A: NONUS_BACKSLASH
    0A->32: GRAVE
    2A->70: NONUS_HASH

Apple Adjustable Keyboard Media keys:

Click

https://deskthority.net/wiki/images/6/64/Apple_Adjustable_front.JPG

Scan codes from Appliance address 7 are translated onto Unimap:
    48: Volume Up   (03 before translation)
    49: Volume Down (02 before translation)
    4A: Mute        (01 before translation)
    42: Mic         (00 before translation)

Apple M0116:

Click

https://deskthority.net/wiki/images/7/75/Apple_M0116_full.jpg

                   ,--------.
                   |  Power |
                   `--------'
,---------------------------------------------------------.  ,---------------.
|Esc|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Delet|  |Clr|  =|  /|  *|
|---------------------------------------------------------|  |---------------|
|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|   |  |  7|  8|  9|  +|
|-----------------------------------------------------'   |  |---------------|
|Ctrl  |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return|  |  4|  5|  6|  -|
|---------------------------------------------------------|  |---------------|
|Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /|   Shift|  |  1|  2|  3|   |
|---------------------------------------------------------|  |-----------|Ent|
|Cap|Opt| Cmd  |  `|    Space         |  \|Lef|Rig|Dow|Up |  |      0|  .|   |
`---------------------------------------------------------'  `---------------'

                   ,--------.
                   |   7F7F |
                   `--------'
,---------------------------------------------------------.  ,---------------.
| 35| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33|  | 47| 51| 4B| 43|
|---------------------------------------------------------|  |---------------|
|  30 | 0C| 0D| 0E| 0F| 11| 10| 20| 22| 1F| 23| 21| 1E| 2A|  | 59| 5B| 5C| 45|
|---------------------------------------------------------|  |---------------|
|  36  | 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|  24  |  | 56| 57| 58| 4E|
|---------------------------------------------------------|  |---------------|
|   38   | 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|   7B   |  | 53| 54| 55|   |
|---------------------------------------------------------|  |-----------| 4C|
| 39| 3A|  37  | 32|      31          | 2A| 3B| 3C| 3D| 3E|  |    52 | 41|   |
`---------------------------------------------------------'  `---------------'

Apple M0118:

Click

https://deskthority.net/wiki/images/e/e3/Apple_M0118_top.jpg

https://i.imgur.com/pJ9WoLk.jpg

                   ,--------.
                   |  Power |
                   `--------'
,---------------------------------------------------------.  ,---------------.
|Esc|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Delet|  |Clr|  =|  /|  *|
|---------------------------------------------------------|  |---------------|
|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|Rtn|  |  7|  8|  9|  +|
|------------------------------------------------------`  |  |---------------|
|CaspsL|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  \|  |  |  4|  5|  6|  -|
|---------------------------------------------------------|  |---------------|
|Shif|  `|  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /|Shif|Up |  |  1|  2|  3|   |
|---------------------------------------------------------|  |-----------|Ent|
|Ctrl| Opt | Cmd  |     Space          | Cmd  |Lef|Rig|Dow|  |      0|  .|   |
`---------------------------------------------------------'  `---------------'

                   ,--------.
                   |   7F7F |
                   `--------'
,---------------------------------------------------------.  ,---------------.
| 35| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33|  | 47| 51| 4B| 43|
|---------------------------------------------------------|  |---------------|
|  30 | 0C| 0D| 0E| 0F| 11| 10| 20| 22| 1F| 23| 21| 1E| 24|  | 59| 5B| 5C| 45|
|------------------------------------------------------`  |  |---------------|
|  39  | 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 2A|  |  | 56| 57| 58| 4E|
|---------------------------------------------------------|  |---------------|
| 38 | 32| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 7B | 3E|  | 53| 54| 55|   |
|---------------------------------------------------------|  |-----------| 4C|
| 36 | 3A  |   37 |         31         |   37 | 3B| 3C| 3D|  |    52 | 41|   |
`---------------------------------------------------------'  `---------------'
* Default mapping on Unimap
    32->0A: NONUS_BACKSLASH
    2A->70: NONUS_HASH

Apple M0487 JIS:

Click

Apple Keyboard II JIS M0487

                   ,--------.
                   |  Power |
                   `--------'
,-----------------------------------------------------------.  ,---------------.
|Esc|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  ^|JPY|Del|  |Clr|  =|  /|  *|
|-----------------------------------------------------------|  |---------------|
|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  @|  [|     |  |  7|  8|  9|  -|
|------------------------------------------------------`    |  |---------------|
|Ctrl  |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  :|  ]|Retn|  |  4|  5|  6|  +|
|-----------------------------------------------------------|  |---------------|
|Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /| RO| Shift|  |  1|  2|  3|   |
|-----------------------------------------------------------|  |-----------|Ent|
|Cap| Opt | Cmd  |EIS|    Space     |KAN|Ent|Lef|Rig|Dow|Up |  |  0|  ,|  .|   |
`-----------------------------------------------------------'  `---------------'
EIS:英数, KAN:かな

                   ,--------.
                   |   7F7F |
                   `--------'
,-----------------------------------------------------------.  ,---------------.
| 35| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 5D| 33|  | 47| 51| 4B| 43|
|-----------------------------------------------------------|  |---------------|
|  30 | 0C| 0D| 0E| 0F| 11| 10| 20| 22| 1F| 23| 21| 1E|     |  | 59| 5B| 5C| 4E|
|------------------------------------------------------`    |  |---------------|
|  36  | 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 2A| 24 |  | 56| 57| 58| 45|
|-----------------------------------------------------------|  |---------------|
|   38   | 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 5E| 7B   |  | 53| 54| 55|   |
|-----------------------------------------------------------|  |-----------| 4C|
| 39|  7C |  37  | 66|      31      | 68| 6A| 3B| 3C| 3D| 3E|  | 52| 5F| 41|   |
`-----------------------------------------------------------'  `---------------'

NeXT ANSI:

Click

https://deskthority.net/wiki/images/8/87/NeXT_ADB_keyboard.jpg

,-----------------------------------------------------------.   -   -   -   ,---------------.
| Esc|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  ß|  '| BSpc | |Hom|Pwr|PgU| |NmL|  /|  *|  -|
|-----------------------------------------------------------|   -   -   -   |---------------|
| Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \ | |End|   |PgD| |  7|  8|  9|  +|
|-----------------------------------------------------------|   -       -   |-----------|   |
| Ctrl  |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '| Return|               |  4|  5|  6|   |
|-----------------------------------------------------------|     ,---.     |---------------|
| Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /|    Shift|     |Up |     |  1|  2|  3|   |
|-----------------------------------------------------------| ,-----------. |-----------|Ent|
|Caps| Alt | Help|        Space            | Help| Alt |  ` | |Lef|Dow|Rig| |      0|  .|   |
`-----------------------------------------------------------' `-----------' `---------------'
                   |_Command_____________|

,-----------------------------------------------------------.   -   -   -   ,---------------.
| 35 | 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|  33  | | 73| ??| 74| | 51| 4B| 43| 4E|
|-----------------------------------------------------------|   -   -   -   |---------------|
|  30  | 0C| 0D| 0E| 0F| 11| 10| 20| 22| 1F| 23| 21| 1E| 2A | | 77|   | 79| | 59| 5B| 5C|   |
|-----------------------------------------------------------|   -       -   |-----------| 45|
|   36  | 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|  24   |               | 56| 57| 58|   |
|-----------------------------------------------------------|     ,---.     |---------------|
|    38   | 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|   7B    |     | 3E|     | 53| 54| 55|   |
|-----------------------------------------------------------| ,-----------. |-----------| 4C|
| 39 |  3A |  72 |           31            |  72 |  7C | 32 | | 3B| 3D| 3C| |     52| 41|   |
`-----------------------------------------------------------' `-----------' `---------------'
                   |_________37__________|
Note that 72 is recognized as Insert by default.

Power key doesn't register scan code. To check PSW will be required.

NeXT German:

Click

https://i.imgur.com/N0Z8LgE.jpg

https://geekhack.org/index.php?topic=14290.msg2998949#msg2998949

,-----------------------------------------------------------.   -   -   -   ,---------------.
| Esc|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  ß|  '| BSpc | |Hom|Pwr|PgU| |NmL|  /|  *|  -|
|-----------------------------------------------------------|   -   -   -   |---------------|
| Tab  |  Q|  W|  E|  R|  T|  Z|  U|  I|  O|  P|  Ü|  +| Ret| |End|   |PgD| |  7|  8|  9|  +|
|-------------------------------------------------------`   |   -       -   |-----------|   |
| Ctrl  |  A|  S|  D|  F|  G|  H|  J|  K|  L|  Ö|  Ä|  #|   |               |  4|  5|  6|   |
|-----------------------------------------------------------|     ,---.     |---------------|
| Shft|  <|  Y|  X|  C|  V|  B|  N|  M|  ,|  .|  -|    Shift|     |Up |     |  1|  2|  3|   |
|-----------------------------------------------------------| ,-----------. |-----------|Ent|
|Caps| Alt | [i] |        Space            | [i] | Alt |   \| |Lef|Dow|Rig| |      0|  .|   |
`-----------------------------------------------------------' `-----------' `---------------'
                   |_Command_____________|

,-----------------------------------------------------------.   -   -   -   ,---------------.
| 35 | 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|  33  | | 73| ??| 74| | 47| 51| 4B| 43|
|-----------------------------------------------------------|   -   -   -   |---------------|
|  30  | 0C| 0D| 0E| 0F| 11| 10| 20| 22| 1F| 23| 21| 1E| 24 | | 77|   | 79| | 59| 5B| 5C|   |
|-------------------------------------------------------`   |   -       -   |-----------| 45|
|   36  | 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 2A|   |               | 56| 57| 58|   |
|-----------------------------------------------------------|     ,---.     |---------------|
|  38 | 0A| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|   7B    |     | 3E|     | 53| 54| 55|   |
|-----------------------------------------------------------| ,-----------. |-----------| 4C|
| 39 |  3A |  72 |           31            |  72 |  7C | 32 | | 3B| 3D| 3C| |     52| 41|   |
`-----------------------------------------------------------' `-----------' `---------------'
                   |_________37__________|
* No need to swap 0A and 32 for NeXT
Note that 72 is recognized as Insert by default.

Power key doesn't register scan code. To check PSW will be required.

Resources

ADB drivers on Mac OS X

10.5.8 is the last version that includes ADB driver codes.

ADB - The Untold Story: Space Aliens Ate My Mouse

ADB Manager

Service request(5-17)

Apple IIgs Hardware Reference

1989 Second Edition [Chapter 6 p.121]

21 Nov, 1986 [Chapter 7 p.141]

ADB Keycode

ADB Signaling

ADB Overview & History

Microchip Application Note: ADB device(with code for PIC16C)

AVR ATtiny2131 ADB to PS/2 converter(Japanese)

Griffin iMate

My iMate indicates device version "3.70" in Device descriptor and its PCB has revision mark "2010 Rev 6 (iMate)".

I found that iMate connects four I/O ports of MCU to data line.(wired-OR) I think they are intended to augment line drive(sink) capability(12mA * 4). TMK converter sink capability may be weak(20mA) in some situations.

Archived Griffin pages:

Open

Technical Specifications:

Compatibility:

Driver:

OS 9 Driver Archive:

FAQ:

Startup behaviour

  • Power on
  • Set LED all off
  • 100ms wait
  • Bus is pulled down for 4ms - Hard Reset
  • 4ms wait at bus idle state
  • Set Mouse Classic2 protocol - Listen Addr3:Reg3 with 0x6002
  • Start polling keyboard with 10ms interval - Talk Addr2:Reg0
  • Set LED system status

After that

  • When SRQ or bus is pulled down(plug-in) for a while(70ms-300ms)

    • Start polling keyboard and mouse in trun until replied with 8ms interval
  • After a device is replied on one of the addresses

    • Start polling only on the address

Set LED

  • Read current key status- Talk Addr2:Reg2
  • Write LED status(and key status as read) - Listen Addr2:Reg2

ADB Manager documents p.5-28

Notice that the MySetLEDValue function first reads the current value in device register 2. This is necessary to preserve the bits in that register that do not encode the LED state. Register 2 contains sixteen bits; be sure to change only the three bits that represent the three LED lights.

https://developer.apple.com/library/archive/documentation/mac/pdf/Devices/ADB_Manager.pdf

Locking Keys

Mechanical locking CapsLock keys are supported. It can be out of sync with state on host computer but iMate doesn't resync it.

multi button mouse support(Extended protocol)

Not supported by itself and device specific driver is needed.

  • Classic2 protocol(200cpi) is supported.
  • Unclear if Extended protocol is supported.
  • Kensington Turbo Mouse sends button1 for all buttons with iMate.

Extended keyboard support

iMate itself doesn't support Extended keyboard unfortunately. This means right modifiers always send key code as same as left modifiers on modern OS.

It was supported by Griffin driver and Apple ADB driver probably at the time of OS9 and early OSX.

hot-plug support

No. Mouse is initialized only when iMate is plugged.

Classic mouse and Turbo Mouse works in 200cpi when cold start but in 100cpi when hot-plug.

Power/Keypad =

iMate sends HID Usage 0x66 and 0x67 for the keys correctly but its Report descriptor declares wrong range of value as 0-101(0x00-0x65) unfortunately. Not sure that it is a stupid bug or intentional design.

In the result Linux and Windows10 don't recognize the keys at least but not confirmed on MacOS. You can't use the keys at all.

ISO keyboard Quirks

https://geekhack.org/index.php?topic=4185.0

How Griffin driver works

I guess that: Griffin iMate driver just provides a virtual ADB port on OSX(up to 10.3.x)/OS9, which can be used by ADB drivers supplied by vendors. Checking source codes of imate-osx iMate seems to receive vendor-specific request including ADB command at control endpoint0 and reply in IN-interrupt endpoint1(which is used for keyboard in usual operation).

TBD

Battery

iMate works without problem without the coin battery(CR1225).

It is needed only for some old G3(G4) PowerMac/iMac to be powered on from keyboard power key.

https://www.instructables.com/Intro-31/

Newmotion uKey

The USB/ADB Adapter is compatible with Apple's ADB devices such as: keyboards, mice, joysticks, trackballs, and hardware dongles.

https://web.archive.org/web/20010303190438/http://www.newmotion.com.tw/products/ukey.html

Dirvers: https://web.archive.org/web/20010205052600/http://www.newmotion.com.tw/download/index.html

Compatibility list: https://web.archive.org/web/20010218003234/http://www.newmotion.com.tw/support/compatibility/adb.html

version 1.5 fialure: https://web.archive.org/web/20070311231412/http://www.reudo.co.jp/usb2adb/us2a_sup.html

keyboard quirks: https://geekhack.org/index.php?topic=4185.0

Clone this wiki locally