Skip to content

Apple M0110 Keyboard Protocol

hasu@tmk edited this page Jan 29, 2024 · 20 revisions

Pinouts

Mac 128k/512k/Plus Keyboard pinout
.---------, 
| 1 2 3 4 | 1 GND
|         | 2 Clock
|         | 3 Data
`---___---' 4 5V
from front of connector

Signaling

CLOCK is always from KEYBOARD. DATA are sent with MSB first.

1) IDLE: both lines are high.
    CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    DATA  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2) KEYBOARD->HOST: HOST reads bit on rising edge.
    CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
    DATA  ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
                      <--> 160us(clock low)
                         <---> 180us(clock high)

3) HOST->KEYBOARD: HOST asserts bit on falling edge.
    CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
    DATA  ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
                <----> 840us(request to send by host)                     <---> 80us(hold DATA)
                      <--> 180us(clock low)
                         <---> 220us(clock high)

Protocol

COMMAND

Inquiry     0x10    get key event with block
Instant     0x12    get key event
Model       0x14    get model number(M0110 responds with 0x09)
                    bit 7   1 if another device connected(used when keypad exists?)
                    bit4-6  next device model number
                    bit1-3  keyboard model number
                    bit 0   always 1
Test        0x16    test(ACK:0x7D/NAK:0x77)

KEY EVENT

bit 7       key state(0:press 1:release)
bit 6-1     scan code(see below)
bit 0       always 1
To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1).

Note: On the M0110A, Keypad keys and Arrow keys are preceded by 0x79.
      Moreover, some Keypad keys(=, /, * and +) are preceded by 0x71 on press and 0xF1 on release.

Raw Codes

M0110 / M0120

m0110_rawcodes

All keys on M0120 keypad are prefixed with 0x79 simply:

press: 0x79, 0xDD where DD = raw code
release: 0x79, 0xUU where UU = raw code | 0x80

M0110A

,---------------------------------------------------------. ,---------------.
|  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Bcksp| |Clr|  =|  /|  *|
|---------------------------------------------------------| |---------------|
|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|   | |  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|  ,|  ,|  /|Shft|Up | |  1|  2|  3|   |
|---------------------------------------------------------' |-----------|Ent|
|Optio|Mac    |           Space           |  \|Lft|Rgt|Dn | |      0|  .|   |
`---------------------------------------------------------' `---------------'
,---------------------------------------------------------. ,---------------.
| 65| 25| 27| 29| 2B| 2F| 2D| 35| 39| 33| 3B| 37| 31|   67| |+0F|*11|*1B|*05|
|---------------------------------------------------------| |---------------|
|   61| 19| 1B| 1D| 1F| 23| 21| 41| 45| 3F| 47| 43| 3D|   | |+33|+37|+39|+1D|
|-----------------------------------------------------'   | |---------------|
|    73| 01| 03| 05| 07| 0B| 09| 4D| 51| 4B| 53| 4F|    49| |+2D|+2F|+31|*0D|
|---------------------------------------------------------| |---------------|
|      71| 0D| 0F| 11| 13| 17| 5B| 5D| 27| 5F| 59|  71|+1B| |+27|+29|+2B|   |
|---------------------------------------------------------' |-----------|+19|
|   75|     6F|            63             | 55|+0D|+05|+11| |    +25|+03|   |
`---------------------------------------------------------' `---------------'
+ 0x79, 0xDD / 0xF1, 0xUU
* 0x71, 0x79, 0xDD / 0xF1, 0x79, 0xUU
where DD and UU indicates code for press and release

Scan Codes

TMK converer uses following scan codes instead of M0110 raw codes. The scan codes are converted from raw codes basically like below. MSB(bit7) is set when key is released.

    scancode = ((raw&0x80) | ((raw&0x7F)>>1))

And keys on keypad are converted exceptionally.

https://github.com/tmk/tmk_keyboard/blob/5208d3165768f93e23e7b46358e1fed252baa241/tmk_core/protocol/m0110.c#L157-L313

M0110 / M0120

,---------------------------------------------------------.    ,---------------.
|  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backs|    |Clr|  -|Lft|Rgt|
|---------------------------------------------------------|    |---------------|
|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \|    |  7|  8|  9|Up |
|---------------------------------------------------------|    |---------------|
|CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return|    |  4|  5|  6|Dn |
|---------------------------------------------------------|    |---------------|
|Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|        |    |  1|  2|  3|   |
`---------------------------------------------------------'    |-----------|Ent|
     |Opt|Mac |         Space               |Enter|Opt|        |      0|  .|   |
     `------------------------------------------------'        `---------------'
,---------------------------------------------------------.    ,---------------.
| 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33|    | 47| 4E| 46| 42|
|---------------------------------------------------------|    |---------------|
|   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A|    | 59| 5B| 5C| 4D|
|---------------------------------------------------------|    |---------------|
|    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|    24|    | 56| 57| 58| 48|
|---------------------------------------------------------|    |---------------|
|      38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|      38|    | 53| 54| 55|   |
`---------------------------------------------------------'    |-----------| 4C|
     | 3A|  37|             31              |   34| 3A|        |     52| 41|   |
     `------------------------------------------------'        `---------------'

M0110 International

,---------------------------------------------------------.
| 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33|
|---------------------------------------------------------|
|   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A|
|------------------------------------------------------   |
|    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24|  |
|---------------------------------------------------------|
|  38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 0A|      38|
`---------------------------------------------------------'
     | 3A|  37|             34              |   31| 3A|
     `------------------------------------------------'

M0110A

,---------------------------------------------------------. ,---------------.
|  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Bcksp| |Clr|  =|  /|  *|
|---------------------------------------------------------| |---------------|
|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|   | |  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|  ,|  ,|  /|Shft|Up | |  1|  2|  3|   |
|---------------------------------------------------------' |-----------|Ent|
|Optio|Mac    |           Space           |  \|Lft|Rgt|Dn | |      0|  .|   |
`---------------------------------------------------------' `---------------'
,---------------------------------------------------------. ,---------------.
| 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33| | 47| 68| 6D| 62|
|---------------------------------------------------------| |---------------|
|   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E|   | | 59| 5B| 5C| 4E|
|-----------------------------------------------------'   | |---------------|
|    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|    24| | 56| 57| 58| 66|
|---------------------------------------------------------| |---------------|
|      38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|  38| 4D| | 53| 54| 55|   |
|---------------------------------------------------------' |-----------| 4C|
|   3A|     37|            31             | 2A| 46| 42| 48| |     52| 41|   |
`---------------------------------------------------------' `---------------'

Technical resources

Discussion thread

Source code

Technical Info for 128K/512K and Plus

Protocol:

Connector:

  • Page 20 of Tech Info for 128K/512K

Signaling:

Raw/Scan codes:

Clone this wiki locally