-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Apple Desktop Bus
It can trasnlate Apple ADB keyboard/mouse protocol to USB, you can use it to plug old ADB keyboard/mouse into modern computer.
- Source code: https://github.com/tmk/tmk_keyboard/tree/master/converter/adb_usb
- General info and discussion: https://geekhack.org/index.php?topic=14290.0
You can buy prebuilt TMK ADB-USB converter and support this project here.
https://geekhack.org/index.php?topic=72052.0
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.
- 4.7k didn't work with daisy-chained multiple devices: https://github.com/tmk/tmk_keyboard/issues/683#issuecomment-850190574
- Some mouses required 4.7k ohm and didn't work with 10k pull-up. https://geekhack.org/index.php?topic=14290.msg3117619#msg3117619
- 10k Ohm didn't work for Turbo Mouse 5 with vintage coiled ADB cable, which is expected to have quite a bit capacitance. 4.7k did work. Note that 4.7k won't work when multiple devices are connected. See above.
- Low value resistor like 100 Ohm doesn't work also: https://geekhack.org/index.php?topic=14290.msg2903590#msg2903590
- Rise time: http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139
- Signal form: http://geekhack.org/index.php?topic=14290.msg296052#msg296052
See this for the latest info.
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
Default address of mouse is 3. Mouse handler ID below are curretnly supported.
- Apple Classic Mouse protocol (1, 2)
- Apple Extended Mouse protocol (4)
- Kensington Turbo Mouse 5 #64210 and Thinking Mouse (0x32)
- Macally 2-button Mouse (0x42)
- Logitech MouseMan/TrackMan Proprietary protocol (0x4C*)
- Logitech MouseMan/TrackMan Extended protocol (0x4D*)
- Microspeed MacTrac (0x2F, 0x5F) - Not confirmed
- Contour Design Countour Mouse (0x66)
- Mouse Systems A3 Mouse/Trackball (0x03) - Not confirmed
- CH Products Tracball Pro/DT225 (0x42) - Not confirmed
- Other two-button mouses: https://github.com/tmk/tmk_keyboard/issues/724
- NeXT ADB Mouse: https://github.com/tmk/tmk_keyboard/issues/724#issuecomment-1108481526
- Pippin Pad: https://github.com/tmk/tmk_keyboard/issues/724#issue-1182765401
See this for other mouses.
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
)
The converter polls the registered devices at 12ms interval with Service Request(SRQ) support.(hook_main_loop
)
keyboard_setup
, keyboard_proc
mouse_setup
, mouse_proc
appliance_setup
, appliance_proc
ADB female socket from the front:
,--_--.
/ o4 3o \ 1: DATA
| o2 1o | 2: PSW(Power SW)
- === - 3: VCC
`-___-' 4: GND
Griffin iMate and Apple IIGS ADB interface have 470 ohm pull-up resistor.
- https://downloads.reactivemicro.com/Apple%20II%20Items/Hardware/IIgs/Schematic/
- another schematic of IIgs
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?
- Code: https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/protocol/adb.c
- Guide to Macintosh Family Hardware: https://vintageapple.org/inside_o/pdf/Guide_to_Macintosh_Family_Hardware_2nd_Edition_1990.pdf
- ADB Manager: https://developer.apple.com/library/archive/documentation/mac/pdf/Devices/ADB_Manager.pdf
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 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
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)
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
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 );
}
}
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)
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)
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
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.
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.
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.
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.
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)
ID | Description |
---|---|
FF | Self Test |
FE | Change address if no collision |
FD | Change address if activated |
00 | Change address and field |
Mac OS X driver: https://github.com/apple-oss-distributions/AppleADBKeyboard/blob/AppleADBKeyboard-239.1/AppleADBKeyboard.cpp
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.
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
1514131211 . . 8 7 . . . . . . 0
| | | | | | | | | | | | | | | |
| | | | | | | | +-+-+-+-+-+-+-+- Handler ID
| | | | +-+-+-+----------------- Address
| | | +------------------------- 0
| | +--------------------------- Service request enable(1 = enabled)
| +----------------------------- Exceptional event(alwyas 1 if not used)
+------------------------------- 0
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
https://elixir.bootlin.com/linux/v5.17/source/drivers/macintosh/adbhid.c#L790
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
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
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
Mac OS X driver: https://github.com/apple-oss-distributions/AppleADBMouse/blob/AppleADBMouse-212/AppleADBMouse.cpp
https://github.com/tmk/tmk_keyboard/issues/725
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.
- https://elixir.bootlin.com/linux/v5.17.4/source/drivers/macintosh/adbhid.c
- https://opensource.apple.com//source/IOHIDFamily/IOHIDFamily-701.20.10/IOHIDFamily/Cosmo_USB2ADB.c
TMK ADB-USB Converter default mapping
,---. .---------------. ,---------------. ,---------------. ,-----------. ,---.
|Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |F24|
`---' `---------------' `---------------' `---------------' `-----------' `---'
,-----------------------------------------------------------. ,-----------. ,---------------. ,---.
| `| 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 |Opt |Cmd |Eng| Space |Jpn|Ent|Cmd* |Opt |Ctrl | |Lef|Dow|Rig| | 0| ,| .| | |F13|
`-----------------------------------------------------------' `-----------' `---------------' `---'
Eng:英数, Jpn:かな
,---. .---------------. ,---------------. ,---------------. ,-----------. ,---.
| 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.
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
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
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)
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| |
`---------------------------------------------------------' `---------------'
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
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| ,| .| |
`-----------------------------------------------------------' `---------------'
,--------.
| 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| |
`-----------------------------------------------------------' `---------------'
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.
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.
10.5.8 is the last version that includes ADB driver codes.
- https://opensource.apple.com/releases/
- https://github.com/apple-oss-distributions/AppleADBKeyboard/blob/AppleADBKeyboard-239.1/AppleADBKeyboard.cpp
- https://github.com/apple-oss-distributions/AppleADBMouse/blob/AppleADBMouse-212/AppleADBMouse.cpp
- https://github.com/apple-oss-distributions/IOADBFamily/tree/IOADBFamily-6/IOADBBus
- https://github.com/apple-oss-distributions/AppleADBButtons/tree/AppleADBButtons-300
Service request(5-17)
- https://archive.org/details/Apple_IIgs_Hardware_Reference_HiRes/page/n144/mode/2up
- ftp://ftp.apple.asimov.net/pub/apple_II/documentation/hardware/machines/Apple%20IIgs%20Hardware%20Reference.pdf
- http://www.novasar.com/files/GSHARDWAREREF.pdf
- [Inside Macintosh volume V, pages 191-192]
- http://72.0.193.250/Documentation/macppc/adbkeycodes/
- http://m0115.web.fc2.com/m0115.jpg
- http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-421.18.3/IOHIDFamily/Cosmo_USB2ADB.c
My iMate indicates device version "3.70" in Device descriptor and its PCB has revision mark "2010 Rev 6 (iMate)".
- VID:077d PID:0405
- USB Descriptor: https://gist.github.com/tmk/472e52c9502302be173790c5e5fa0829
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:
- https://web.archive.org/web/20070814104158/http://www.griffintechnology.com/support/imate/index.php
- https://web.archive.org/web/20060221140419/http://www.griffintechnology.com/support/imate/index.php
- 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
- 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
Mechanical locking CapsLock keys are supported. It can be out of sync with state on host computer but iMate doesn't resync it.
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.
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.
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.
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.
https://geekhack.org/index.php?topic=4185.0
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
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.
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