diff options
| -rw-r--r-- | m0110.c | 313 | ||||
| -rw-r--r-- | m0110.h | 9 | ||||
| -rw-r--r--[-rwxr-xr-x] | m0110_usb/doc/m0110.jpg | bin | 49360 -> 49360 bytes | |||
| -rw-r--r--[-rwxr-xr-x] | m0110_usb/doc/teensy.jpg | bin | 50081 -> 50081 bytes | |||
| -rw-r--r-- | m0110_usb/keymap.c | 66 | ||||
| -rw-r--r-- | m0110_usb/matrix.c | 28 | ||||
| -rw-r--r-- | rules.mk | 2 |
7 files changed, 223 insertions, 195 deletions
| @@ -44,6 +44,7 @@ POSSIBILITY OF SUCH DAMAGE. | |||
| 44 | #include "debug.h" | 44 | #include "debug.h" |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | static inline uint8_t raw2scan(uint8_t raw); | ||
| 47 | static inline uint8_t inquiry(void); | 48 | static inline uint8_t inquiry(void); |
| 48 | static inline uint8_t instant(void); | 49 | static inline uint8_t instant(void); |
| 49 | static inline void clock_lo(void); | 50 | static inline void clock_lo(void); |
| @@ -60,147 +61,6 @@ static inline void idle(void); | |||
| 60 | static inline void request(void); | 61 | static inline void request(void); |
| 61 | 62 | ||
| 62 | 63 | ||
| 63 | /* | ||
| 64 | Primitive M0110 Library for AVR | ||
| 65 | ============================== | ||
| 66 | |||
| 67 | |||
| 68 | Signaling | ||
| 69 | --------- | ||
| 70 | CLOCK is always from KEYBOARD. DATA are sent with MSB first. | ||
| 71 | |||
| 72 | 1) IDLE: both lines are high. | ||
| 73 | CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 74 | DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 75 | |||
| 76 | 2) KEYBOARD->HOST: HOST reads bit on rising edge. | ||
| 77 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | ||
| 78 | DATA ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | ||
| 79 | <--> 160us(clock low) | ||
| 80 | <---> 180us(clock high) | ||
| 81 | |||
| 82 | 3) HOST->KEYBOARD: HOST asserts bit on falling edge. | ||
| 83 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | ||
| 84 | DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | ||
| 85 | <----> 840us(request to send by host) <---> 80us(hold DATA) | ||
| 86 | <--> 180us(clock low) | ||
| 87 | <---> 220us(clock high) | ||
| 88 | |||
| 89 | |||
| 90 | Protocol | ||
| 91 | -------- | ||
| 92 | COMMAND: | ||
| 93 | Inquiry 0x10 get key event | ||
| 94 | Instant 0x12 get key event | ||
| 95 | Model 0x14 get model number(M0110 responds with 0x09) | ||
| 96 | bit 7 1 if another device connected(used when keypad exists?) | ||
| 97 | bit4-6 next device model number | ||
| 98 | bit1-3 keyboard model number | ||
| 99 | bit 0 always 1 | ||
| 100 | Test 0x16 test(ACK:0x7D/NAK:0x77) | ||
| 101 | |||
| 102 | KEY EVENT: | ||
| 103 | bit 7 key state(0:press 1:release) | ||
| 104 | bit 6-1 scan code(see below) | ||
| 105 | bit 0 always 1 | ||
| 106 | To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1). | ||
| 107 | |||
| 108 | Note: On the M0110A, the numpad keys and the arrow keys are preceded by 0x79. | ||
| 109 | Moreover, the numpad keys =, /, * and + are preceded by shift-down 0x71 on press and shift-up 0xF1 on release. | ||
| 110 | So, the data transferred by nupmad 5 is "79 2F" whereas for numpad + it's "71 79 0D". | ||
| 111 | |||
| 112 | ARROW KEYS: | ||
| 113 | Arrow keys and Pad+,*,/,=(Calc keys) share same byte sequence and its preceding byte | ||
| 114 | 0x71 and 0xF1 means press and release event of SHIFT. These cause very confusing situation. | ||
| 115 | It is difficult or impossible to tell Calc key from Arrow key with SHIFT in some cases. | ||
| 116 | |||
| 117 | Raw key events: | ||
| 118 | press release | ||
| 119 | ---------------- ---------------- | ||
| 120 | Left: 0x79, 0x0D 0x79, 0x8D | ||
| 121 | Right: 0x79, 0x05 0x79, 0x85 | ||
| 122 | Up: 0x79, 0x1B 0x79, 0x9B | ||
| 123 | Down: 0x79, 0x11 0x79, 0x91 | ||
| 124 | Pad+: 0x71, 0x79, 0x0D 0xF1, 0x79, 0x8D | ||
| 125 | Pad*: 0x71, 0x79, 0x05 0xF1, 0x79, 0x85 | ||
| 126 | Pad/: 0x71, 0x79, 0x1B 0xF1, 0x79, 0x9B | ||
| 127 | Pad=: 0x71, 0x79, 0x11 0xF1, 0x79, 0x91 | ||
| 128 | |||
| 129 | SCAN CODE: | ||
| 130 | m0111_recv_key() function returns follwing scan codes instead of raw key events. | ||
| 131 | Scan codes are 1 byte long and bit7 is set when key is released. | ||
| 132 | |||
| 133 | M0110 | ||
| 134 | ,---------------------------------------------------------. | ||
| 135 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| | ||
| 136 | |---------------------------------------------------------| | ||
| 137 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | ||
| 138 | |---------------------------------------------------------| | ||
| 139 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | ||
| 140 | |---------------------------------------------------------| | ||
| 141 | |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | ||
| 142 | `---------------------------------------------------------' | ||
| 143 | |Opt|Mac | Space |Enter|Opt| | ||
| 144 | `------------------------------------------------' | ||
| 145 | ,---------------------------------------------------------. | ||
| 146 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | ||
| 147 | |---------------------------------------------------------| | ||
| 148 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | ||
| 149 | |---------------------------------------------------------| | ||
| 150 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | ||
| 151 | |---------------------------------------------------------| | ||
| 152 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | ||
| 153 | `---------------------------------------------------------' | ||
| 154 | | 3A| 37| 31 | 34| 3A| | ||
| 155 | `------------------------------------------------' | ||
| 156 | |||
| 157 | M0110A | ||
| 158 | ,---------------------------------------------------------. ,---------------. | ||
| 159 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| | ||
| 160 | |---------------------------------------------------------| |---------------| | ||
| 161 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 162 | |-----------------------------------------------------' | |---------------| | ||
| 163 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 164 | |---------------------------------------------------------| |---------------| | ||
| 165 | |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 166 | |---------------------------------------------------------' |-----------|Ent| | ||
| 167 | |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | | ||
| 168 | `---------------------------------------------------------' `---------------' | ||
| 169 | ,---------------------------------------------------------. ,---------------. | ||
| 170 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62| | ||
| 171 | |---------------------------------------------------------| |---------------| | ||
| 172 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E| | ||
| 173 | |-----------------------------------------------------' | |---------------| | ||
| 174 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66| | ||
| 175 | |---------------------------------------------------------| |---------------| | ||
| 176 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| | | ||
| 177 | |---------------------------------------------------------' |-----------| 4C| | ||
| 178 | | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| | | ||
| 179 | `---------------------------------------------------------' `---------------' | ||
| 180 | |||
| 181 | |||
| 182 | References | ||
| 183 | ---------- | ||
| 184 | Technical Info for 128K/512K and Plus | ||
| 185 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf | ||
| 186 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf | ||
| 187 | Protocol: | ||
| 188 | Page 20 of Tech Info for 128K/512K | ||
| 189 | http://www.mac.linux-m68k.org/devel/plushw.php | ||
| 190 | Connector: | ||
| 191 | Page 20 of Tech Info for 128K/512K | ||
| 192 | http://www.kbdbabel.org/conn/kbd_connector_macplus.png | ||
| 193 | Signaling: | ||
| 194 | http://www.kbdbabel.org/signaling/kbd_signaling_mac.png | ||
| 195 | http://typematic.blog.shinobi.jp/Entry/14/ | ||
| 196 | Scan Codes: | ||
| 197 | Page 22 of Tech Info for 128K/512K | ||
| 198 | Page 07 of Tech Info for Plus | ||
| 199 | http://m0115.web.fc2.com/m0110.jpg | ||
| 200 | http://m0115.web.fc2.com/m0110a.jpg | ||
| 201 | */ | ||
| 202 | |||
| 203 | |||
| 204 | #define WAIT_US(stat, us, err) do { \ | 64 | #define WAIT_US(stat, us, err) do { \ |
| 205 | if (!wait_##stat(us)) { \ | 65 | if (!wait_##stat(us)) { \ |
| 206 | m0110_error = err; \ | 66 | m0110_error = err; \ |
| @@ -307,7 +167,7 @@ uint8_t m0110_recv_key(void) | |||
| 307 | switch (key & 0x7F) { | 167 | switch (key & 0x7F) { |
| 308 | case M0110_KEYPAD: | 168 | case M0110_KEYPAD: |
| 309 | // Pad/Arrow keys | 169 | // Pad/Arrow keys |
| 310 | return (M0110_RAW2SCAN(instant()) | M0110_KEYPAD_OFFSET); | 170 | return (raw2scan(instant()) | M0110_KEYPAD_OFFSET); |
| 311 | break; | 171 | break; |
| 312 | case M0110_SHIFT: | 172 | case M0110_SHIFT: |
| 313 | key2 = instant(); | 173 | key2 = instant(); |
| @@ -319,26 +179,34 @@ uint8_t m0110_recv_key(void) | |||
| 319 | case M0110_ARROW_LEFT: | 179 | case M0110_ARROW_LEFT: |
| 320 | case M0110_ARROW_RIGHT: | 180 | case M0110_ARROW_RIGHT: |
| 321 | // Calc keys | 181 | // Calc keys |
| 322 | return (M0110_RAW2SCAN(key3) | M0110_CALC_OFFSET); | 182 | return (raw2scan(key3) | M0110_CALC_OFFSET); |
| 323 | default: | 183 | default: |
| 324 | // Shift + Pad/Arrow keys | 184 | // Shift + Pad/Arrow keys |
| 325 | keybuf = M0110_RAW2SCAN(key3); | 185 | keybuf = raw2scan(key3); |
| 326 | return (M0110_RAW2SCAN(key) | M0110_KEYPAD_OFFSET); | 186 | return (raw2scan(key) | M0110_KEYPAD_OFFSET); |
| 327 | } | 187 | } |
| 328 | } else { | 188 | } else { |
| 329 | // Shift + other keys | 189 | // Shift + other keys |
| 330 | keybuf = M0110_RAW2SCAN(key2); | 190 | keybuf = raw2scan(key2); |
| 331 | return M0110_RAW2SCAN(key); | 191 | return raw2scan(key); |
| 332 | } | 192 | } |
| 333 | break; | 193 | break; |
| 334 | default: | 194 | default: |
| 335 | // other keys | 195 | // other keys |
| 336 | return M0110_RAW2SCAN(key); | 196 | return raw2scan(key); |
| 337 | break; | 197 | break; |
| 338 | } | 198 | } |
| 339 | } | 199 | } |
| 340 | 200 | ||
| 341 | 201 | ||
| 202 | static inline uint8_t raw2scan(uint8_t raw) { | ||
| 203 | return (raw == M0110_NULL) ? M0110_NULL : ( | ||
| 204 | (raw == M0110_ERROR) ? M0110_ERROR : ( | ||
| 205 | ((raw&0x80) | ((raw&0x7F)>>1)) | ||
| 206 | ) | ||
| 207 | ); | ||
| 208 | } | ||
| 209 | |||
| 342 | static inline uint8_t inquiry(void) | 210 | static inline uint8_t inquiry(void) |
| 343 | { | 211 | { |
| 344 | m0110_send(M0110_INQUIRY); | 212 | m0110_send(M0110_INQUIRY); |
| @@ -348,7 +216,12 @@ static inline uint8_t inquiry(void) | |||
| 348 | static inline uint8_t instant(void) | 216 | static inline uint8_t instant(void) |
| 349 | { | 217 | { |
| 350 | m0110_send(M0110_INSTANT); | 218 | m0110_send(M0110_INSTANT); |
| 351 | return m0110_recv(); | 219 | //return m0110_recv(); |
| 220 | uint8_t data = m0110_recv(); | ||
| 221 | if (data != 0x7B) { | ||
| 222 | print("data: "); phex(data); print("\n"); | ||
| 223 | } | ||
| 224 | return data; | ||
| 352 | } | 225 | } |
| 353 | 226 | ||
| 354 | static inline void clock_lo() | 227 | static inline void clock_lo() |
| @@ -420,3 +293,145 @@ static inline void request(void) | |||
| 420 | clock_hi(); | 293 | clock_hi(); |
| 421 | data_lo(); | 294 | data_lo(); |
| 422 | } | 295 | } |
| 296 | |||
| 297 | |||
| 298 | |||
| 299 | /* | ||
| 300 | Primitive M0110 Library for AVR | ||
| 301 | ============================== | ||
| 302 | |||
| 303 | |||
| 304 | Signaling | ||
| 305 | --------- | ||
| 306 | CLOCK is always from KEYBOARD. DATA are sent with MSB first. | ||
| 307 | |||
| 308 | 1) IDLE: both lines are high. | ||
| 309 | CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 310 | DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 311 | |||
| 312 | 2) KEYBOARD->HOST: HOST reads bit on rising edge. | ||
| 313 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | ||
| 314 | DATA ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | ||
| 315 | <--> 160us(clock low) | ||
| 316 | <---> 180us(clock high) | ||
| 317 | |||
| 318 | 3) HOST->KEYBOARD: HOST asserts bit on falling edge. | ||
| 319 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | ||
| 320 | DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | ||
| 321 | <----> 840us(request to send by host) <---> 80us(hold DATA) | ||
| 322 | <--> 180us(clock low) | ||
| 323 | <---> 220us(clock high) | ||
| 324 | |||
| 325 | |||
| 326 | Protocol | ||
| 327 | -------- | ||
| 328 | COMMAND: | ||
| 329 | Inquiry 0x10 get key event | ||
| 330 | Instant 0x12 get key event | ||
| 331 | Model 0x14 get model number(M0110 responds with 0x09) | ||
| 332 | bit 7 1 if another device connected(used when keypad exists?) | ||
| 333 | bit4-6 next device model number | ||
| 334 | bit1-3 keyboard model number | ||
| 335 | bit 0 always 1 | ||
| 336 | Test 0x16 test(ACK:0x7D/NAK:0x77) | ||
| 337 | |||
| 338 | KEY EVENT: | ||
| 339 | bit 7 key state(0:press 1:release) | ||
| 340 | bit 6-1 scan code(see below) | ||
| 341 | bit 0 always 1 | ||
| 342 | To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1). | ||
| 343 | |||
| 344 | Note: On the M0110A, the numpad keys and the arrow keys are preceded by 0x79. | ||
| 345 | Moreover, the numpad keys =, /, * and + are preceded by shift-down 0x71 on press and shift-up 0xF1 on release. | ||
| 346 | So, the data transferred by nupmad 5 is "79 2F" whereas for numpad + it's "71 79 0D". | ||
| 347 | |||
| 348 | ARROW KEYS: | ||
| 349 | Arrow keys and Pad+,*,/,=(Calc keys) share same byte sequence and its preceding byte | ||
| 350 | 0x71 and 0xF1 means press and release event of SHIFT. These cause very confusing situation. | ||
| 351 | It is difficult or impossible to tell Calc key from Arrow key with SHIFT in some cases. | ||
| 352 | |||
| 353 | Raw key events: | ||
| 354 | press release | ||
| 355 | ---------------- ---------------- | ||
| 356 | Left: 0x79, 0x0D 0x79, 0x8D | ||
| 357 | Right: 0x79, 0x05 0x79, 0x85 | ||
| 358 | Up: 0x79, 0x1B 0x79, 0x9B | ||
| 359 | Down: 0x79, 0x11 0x79, 0x91 | ||
| 360 | Pad+: 0x71, 0x79, 0x0D 0xF1, 0x79, 0x8D | ||
| 361 | Pad*: 0x71, 0x79, 0x05 0xF1, 0x79, 0x85 | ||
| 362 | Pad/: 0x71, 0x79, 0x1B 0xF1, 0x79, 0x9B | ||
| 363 | Pad=: 0x71, 0x79, 0x11 0xF1, 0x79, 0x91 | ||
| 364 | |||
| 365 | SCAN CODE: | ||
| 366 | m0111_recv_key() function returns follwing scan codes instead of raw key events. | ||
| 367 | Scan codes are 1 byte long and bit7 is set when key is released. | ||
| 368 | |||
| 369 | M0110 | ||
| 370 | ,---------------------------------------------------------. | ||
| 371 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| | ||
| 372 | |---------------------------------------------------------| | ||
| 373 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | ||
| 374 | |---------------------------------------------------------| | ||
| 375 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | ||
| 376 | |---------------------------------------------------------| | ||
| 377 | |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | ||
| 378 | `---------------------------------------------------------' | ||
| 379 | |Opt|Mac | Space |Enter|Opt| | ||
| 380 | `------------------------------------------------' | ||
| 381 | ,---------------------------------------------------------. | ||
| 382 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | ||
| 383 | |---------------------------------------------------------| | ||
| 384 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | ||
| 385 | |---------------------------------------------------------| | ||
| 386 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | ||
| 387 | |---------------------------------------------------------| | ||
| 388 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | ||
| 389 | `---------------------------------------------------------' | ||
| 390 | | 3A| 37| 31 | 34| 3A| | ||
| 391 | `------------------------------------------------' | ||
| 392 | |||
| 393 | M0110A | ||
| 394 | ,---------------------------------------------------------. ,---------------. | ||
| 395 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| | ||
| 396 | |---------------------------------------------------------| |---------------| | ||
| 397 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 398 | |-----------------------------------------------------' | |---------------| | ||
| 399 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 400 | |---------------------------------------------------------| |---------------| | ||
| 401 | |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 402 | |---------------------------------------------------------' |-----------|Ent| | ||
| 403 | |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | | ||
| 404 | `---------------------------------------------------------' `---------------' | ||
| 405 | ,---------------------------------------------------------. ,---------------. | ||
| 406 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62| | ||
| 407 | |---------------------------------------------------------| |---------------| | ||
| 408 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E| | ||
| 409 | |-----------------------------------------------------' | |---------------| | ||
| 410 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66| | ||
| 411 | |---------------------------------------------------------| |---------------| | ||
| 412 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| | | ||
| 413 | |---------------------------------------------------------' |-----------| 4C| | ||
| 414 | | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| | | ||
| 415 | `---------------------------------------------------------' `---------------' | ||
| 416 | |||
| 417 | |||
| 418 | References | ||
| 419 | ---------- | ||
| 420 | Technical Info for 128K/512K and Plus | ||
| 421 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf | ||
| 422 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf | ||
| 423 | Protocol: | ||
| 424 | Page 20 of Tech Info for 128K/512K | ||
| 425 | http://www.mac.linux-m68k.org/devel/plushw.php | ||
| 426 | Connector: | ||
| 427 | Page 20 of Tech Info for 128K/512K | ||
| 428 | http://www.kbdbabel.org/conn/kbd_connector_macplus.png | ||
| 429 | Signaling: | ||
| 430 | http://www.kbdbabel.org/signaling/kbd_signaling_mac.png | ||
| 431 | http://typematic.blog.shinobi.jp/Entry/14/ | ||
| 432 | Scan Codes: | ||
| 433 | Page 22 of Tech Info for 128K/512K | ||
| 434 | Page 07 of Tech Info for Plus | ||
| 435 | http://m0115.web.fc2.com/m0110.jpg | ||
| 436 | http://m0115.web.fc2.com/m0110a.jpg | ||
| 437 | */ | ||
| @@ -78,15 +78,6 @@ POSSIBILITY OF SUCH DAMAGE. | |||
| 78 | #define M0110_KEYPAD_OFFSET 0x40 | 78 | #define M0110_KEYPAD_OFFSET 0x40 |
| 79 | #define M0110_CALC_OFFSET 0x60 | 79 | #define M0110_CALC_OFFSET 0x60 |
| 80 | 80 | ||
| 81 | /* convert key event raw response into scan code */ | ||
| 82 | #define M0110_RAW2SCAN(key) ( \ | ||
| 83 | (key == M0110_NULL) ? M0110_NULL : ( \ | ||
| 84 | (key == M0110_ERROR) ? M0110_ERROR : ( \ | ||
| 85 | ((key&0x80) | ((key&0x7F)>>1)) \ | ||
| 86 | ) \ | ||
| 87 | ) \ | ||
| 88 | ) | ||
| 89 | |||
| 90 | 81 | ||
| 91 | extern uint8_t m0110_error; | 82 | extern uint8_t m0110_error; |
| 92 | 83 | ||
diff --git a/m0110_usb/doc/m0110.jpg b/m0110_usb/doc/m0110.jpg index ef9a123ab..ef9a123ab 100755..100644 --- a/m0110_usb/doc/m0110.jpg +++ b/m0110_usb/doc/m0110.jpg | |||
| Binary files differ | |||
diff --git a/m0110_usb/doc/teensy.jpg b/m0110_usb/doc/teensy.jpg index 96e93e7e2..96e93e7e2 100755..100644 --- a/m0110_usb/doc/teensy.jpg +++ b/m0110_usb/doc/teensy.jpg | |||
| Binary files differ | |||
diff --git a/m0110_usb/keymap.c b/m0110_usb/keymap.c index 8c509a59b..c6b7cbd3b 100644 --- a/m0110_usb/keymap.c +++ b/m0110_usb/keymap.c | |||
| @@ -58,7 +58,7 @@ static const uint8_t PROGMEM fn_layer[] = { | |||
| 58 | 1, // Fn0 | 58 | 1, // Fn0 |
| 59 | 2, // Fn1 | 59 | 2, // Fn1 |
| 60 | 3, // Fn2 | 60 | 3, // Fn2 |
| 61 | 0, // Fn3 | 61 | 1, // Fn3 |
| 62 | 0, // Fn4 | 62 | 0, // Fn4 |
| 63 | 0, // Fn5 | 63 | 0, // Fn5 |
| 64 | 0, // Fn6 | 64 | 0, // Fn6 |
| @@ -68,15 +68,17 @@ static const uint8_t PROGMEM fn_layer[] = { | |||
| 68 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. | 68 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. |
| 69 | // See layer.c for details. | 69 | // See layer.c for details. |
| 70 | static const uint8_t PROGMEM fn_keycode[] = { | 70 | static const uint8_t PROGMEM fn_keycode[] = { |
| 71 | #ifndef HASU | ||
| 71 | KB_ESC, // Fn0 | 72 | KB_ESC, // Fn0 |
| 72 | #ifdef HASU | ||
| 73 | KB_SCOLON, // Fn1 | ||
| 74 | KB_SLASH, // Fn2 | ||
| 75 | #else | ||
| 76 | KB_NO, // Fn1 | 73 | KB_NO, // Fn1 |
| 77 | KB_NO, // Fn2 | 74 | KB_NO, // Fn2 |
| 78 | #endif | ||
| 79 | KB_NO, // Fn3 | 75 | KB_NO, // Fn3 |
| 76 | #else | ||
| 77 | KB_NO, // Fn0 | ||
| 78 | KB_SCOLON, // Fn1 | ||
| 79 | KB_SLASH, // Fn2 | ||
| 80 | KB_UP, // Fn3 | ||
| 81 | #endif | ||
| 80 | KB_NO, // Fn4 | 82 | KB_NO, // Fn4 |
| 81 | KB_NO, // Fn5 | 83 | KB_NO, // Fn5 |
| 82 | KB_NO, // Fn6 | 84 | KB_NO, // Fn6 |
| @@ -107,7 +109,6 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 107 | * |---------------------------------------------------------| |-----------|Ent| | 109 | * |---------------------------------------------------------| |-----------|Ent| |
| 108 | * |Ctrl |Alt | Space |Gui| \|Lft|Rgt|Dn | | 0| .| | | 110 | * |Ctrl |Alt | Space |Gui| \|Lft|Rgt|Dn | | 0| .| | |
| 109 | * `---------------------------------------------------------' `---------------' | 111 | * `---------------------------------------------------------' `---------------' |
| 110 | * You can register Esc by hitting(press&release) Fn0 quickly. | ||
| 111 | * | 112 | * |
| 112 | * HHKB/WASD cursor Layer(Fn0): | 113 | * HHKB/WASD cursor Layer(Fn0): |
| 113 | * ,---------------------------------------------------------. ,---------------. | 114 | * ,---------------------------------------------------------. ,---------------. |
| @@ -122,25 +123,44 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 122 | * |Ctrl |Alt | Space |Gui | \|Lft|Rgt|Dn | | 0| .| | | 123 | * |Ctrl |Alt | Space |Gui | \|Lft|Rgt|Dn | | 0| .| | |
| 123 | * `---------------------------------------------------------' `---------------' | 124 | * `---------------------------------------------------------' `---------------' |
| 124 | * | 125 | * |
| 125 | * NOTE: Key between Space and \ in above diagram is M0110 Enter(assigned to Gui). | 126 | * NOTE: You can register Esc by hitting(press&release) Fn0 quickly. |
| 127 | * NOTE: Gui between Space and \ is Enter on M0110 not exists on M0110A. | ||
| 126 | * NOTE: LShift and RShift are logically same key. (M0110, M0110A) | 128 | * NOTE: LShift and RShift are logically same key. (M0110, M0110A) |
| 127 | * NOTE: LOption and ROption are logically same key. (M0110) | 129 | * NOTE: LOption and ROption are logically same key. (M0110) |
| 128 | */ | 130 | */ |
| 129 | #ifdef HASU | 131 | #ifndef HASU |
| 132 | KEYMAP( | ||
| 133 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LGUI,PEQL,PSLS,PAST, | ||
| 134 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS, | ||
| 135 | FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, | ||
| 136 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT, | ||
| 137 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT | ||
| 138 | ), | ||
| 139 | // HHKB & WASD | ||
| 140 | KEYMAP( | ||
| 141 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,PEQL,PSLS,PAST, | ||
| 142 | CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, INS, P7, P8, P9, PMNS, | ||
| 143 | FN0, LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, P4, P5, P6, PPLS, | ||
| 144 | LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, UP, P1, P2, P3, PENT, | ||
| 145 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT | ||
| 146 | ), | ||
| 147 | #else | ||
| 148 | // hasu's keymap | ||
| 149 | // To enable use this 'make' option: make EXTRAFLAGS=-DHASU | ||
| 130 | KEYMAP( | 150 | KEYMAP( |
| 131 | ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, ESC, PEQL,PSLS,PAST, | 151 | ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, ESC, PEQL,PSLS,PAST, |
| 132 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS, | 152 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS, |
| 133 | LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT, ENT, P4, P5, P6, PPLS, | 153 | LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT, ENT, P4, P5, P6, PPLS, |
| 134 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN2, UP, P1, P2, P3, PENT, | 154 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN2, FN3, P1, P2, P3, PENT, |
| 135 | FN0, LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT | 155 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT |
| 136 | ), | 156 | ), |
| 137 | // HHKB & WASD | 157 | // HHKB & WASD |
| 138 | KEYMAP( | 158 | KEYMAP( |
| 139 | GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,PEQL,PSLS,PAST, | 159 | GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,PEQL,PSLS,PAST, |
| 140 | CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, INS, P7, P8, P9, PMNS, | 160 | CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, INS, P7, P8, P9, PMNS, |
| 141 | LCTL,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, P4, P5, P6, PPLS, | 161 | LCTL,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, P4, P5, P6, PPLS, |
| 142 | LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, UP, P1, P2, P3, PENT, | 162 | LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, FN3, P1, P2, P3, PENT, |
| 143 | FN0, LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT | 163 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT |
| 144 | ), | 164 | ), |
| 145 | // vi mousekeys | 165 | // vi mousekeys |
| 146 | KEYMAP( | 166 | KEYMAP( |
| @@ -148,7 +168,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 148 | CAPS,NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, P7, P8, P9, PMNS, | 168 | CAPS,NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, P7, P8, P9, PMNS, |
| 149 | NO, VOLD,VOLU,MUTE,NO, NO, MS_L,MS_D,MS_U,MS_R,FN1, NO, ENT, P4, P5, P6, PPLS, | 169 | NO, VOLD,VOLU,MUTE,NO, NO, MS_L,MS_D,MS_U,MS_R,FN1, NO, ENT, P4, P5, P6, PPLS, |
| 150 | LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,NO, NO, NO, UP, P1, P2, P3, PENT, | 170 | LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,NO, NO, NO, UP, P1, P2, P3, PENT, |
| 151 | LCTL,LALT, BTN1, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT | 171 | LCTL,LALT, BTN1, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT |
| 152 | ), | 172 | ), |
| 153 | // vi cusorkeys | 173 | // vi cusorkeys |
| 154 | KEYMAP( | 174 | KEYMAP( |
| @@ -156,23 +176,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 156 | CAPS,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, P7, P8, P9, PMNS, | 176 | CAPS,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, P7, P8, P9, PMNS, |
| 157 | NO, NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS, | 177 | NO, NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS, |
| 158 | LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN2, UP, P1, P2, P3, PENT, | 178 | LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN2, UP, P1, P2, P3, PENT, |
| 159 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT | 179 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT |
| 160 | ), | ||
| 161 | #else | ||
| 162 | KEYMAP( | ||
| 163 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LGUI,PEQL,PSLS,PAST, | ||
| 164 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS, | ||
| 165 | FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, | ||
| 166 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT, | ||
| 167 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT | ||
| 168 | ), | ||
| 169 | // HHKB & WASD | ||
| 170 | KEYMAP( | ||
| 171 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,PEQL,PSLS,PAST, | ||
| 172 | CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, INS, P7, P8, P9, PMNS, | ||
| 173 | FN0, LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, P4, P5, P6, PPLS, | ||
| 174 | LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, UP, P1, P2, P3, PENT, | ||
| 175 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT | ||
| 176 | ), | 180 | ), |
| 177 | #endif | 181 | #endif |
| 178 | }; | 182 | }; |
diff --git a/m0110_usb/matrix.c b/m0110_usb/matrix.c index 11303ee0f..b28045b9c 100644 --- a/m0110_usb/matrix.c +++ b/m0110_usb/matrix.c | |||
| @@ -32,10 +32,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 32 | 32 | ||
| 33 | 33 | ||
| 34 | #define CAPS 0x39 | 34 | #define CAPS 0x39 |
| 35 | #define CAPS_UP (CAPS | 0x80) | 35 | #define CAPS_BREAK (CAPS | 0x80) |
| 36 | #define ROW(key) ((key)>>3&0x0F) | 36 | #define ROW(key) ((key)>>3&0x0F) |
| 37 | #define COL(key) ((key)&0x07) | 37 | #define COL(key) ((key)&0x07) |
| 38 | 38 | ||
| 39 | #define ARROW_UP_BREAK (0x4D | 0x80) | ||
| 40 | #define ARROW_DOWN_BREAK (0x48 | 0x80) | ||
| 41 | #define ARROW_LEFT_BREAK (0x46 | 0x80) | ||
| 42 | #define ARROW_RIGHT_BREAK (0x42 | 0x80) | ||
| 43 | |||
| 39 | 44 | ||
| 40 | static bool is_modified = false; | 45 | static bool is_modified = false; |
| 41 | 46 | ||
| @@ -88,14 +93,27 @@ uint8_t matrix_scan(void) | |||
| 88 | // Send Caps key up event | 93 | // Send Caps key up event |
| 89 | if (matrix_is_on(ROW(CAPS), COL(CAPS))) { | 94 | if (matrix_is_on(ROW(CAPS), COL(CAPS))) { |
| 90 | is_modified = true; | 95 | is_modified = true; |
| 91 | register_key(CAPS_UP); | 96 | register_key(CAPS_BREAK); |
| 92 | } | 97 | } |
| 93 | #endif | 98 | #endif |
| 94 | if (key == M0110_NULL) { | 99 | if (key == M0110_NULL) { |
| 95 | return 0; | 100 | return 0; |
| 96 | } else if (key == M0110_ERROR) { | 101 | } else if (key == M0110_ERROR) { |
| 97 | // TODO: error recovery or reinit | ||
| 98 | return 0; | 102 | return 0; |
| 103 | } else if (key == ARROW_UP_BREAK || | ||
| 104 | key == ARROW_DOWN_BREAK || | ||
| 105 | key == ARROW_LEFT_BREAK || | ||
| 106 | key == ARROW_RIGHT_BREAK) { | ||
| 107 | // WORK AROUND: exceptional handling for M0110A | ||
| 108 | // Unregister both Arrow key and coressponding Calc key when receive Arrow key break. | ||
| 109 | // | ||
| 110 | // Shift + Calc keys(=/*+): | ||
| 111 | // Send no Shift break(0xF1) when release Calc keys. Can't be desinguished from Arrow keys. | ||
| 112 | // (press: 0x71, 0x79, 0xXX release: 0x79, 0xXX) | ||
| 113 | // See m0110.c for key events and scan codes. | ||
| 114 | is_modified = true; | ||
| 115 | register_key(key); | ||
| 116 | register_key(key|M0110_CALC_OFFSET); | ||
| 99 | } else { | 117 | } else { |
| 100 | #ifdef MATRIX_HAS_LOCKING_CAPS | 118 | #ifdef MATRIX_HAS_LOCKING_CAPS |
| 101 | if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { | 119 | if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { |
| @@ -103,11 +121,11 @@ uint8_t matrix_scan(void) | |||
| 103 | // Ignore LockingCaps key down event | 121 | // Ignore LockingCaps key down event |
| 104 | if (key == CAPS) return 0; | 122 | if (key == CAPS) return 0; |
| 105 | // Convert LockingCaps key up event into down event | 123 | // Convert LockingCaps key up event into down event |
| 106 | if (key == CAPS_UP) key = CAPS; | 124 | if (key == CAPS_BREAK) key = CAPS; |
| 107 | } else { | 125 | } else { |
| 108 | // CAPS LOCK off: | 126 | // CAPS LOCK off: |
| 109 | // Ignore LockingCaps key up event | 127 | // Ignore LockingCaps key up event |
| 110 | if (key == CAPS_UP) return 0; | 128 | if (key == CAPS_BREAK) return 0; |
| 111 | } | 129 | } |
| 112 | #endif | 130 | #endif |
| 113 | is_modified = true; | 131 | is_modified = true; |
| @@ -317,7 +317,7 @@ GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d | |||
| 317 | 317 | ||
| 318 | # Combine all necessary flags and optional flags. | 318 | # Combine all necessary flags and optional flags. |
| 319 | # Add target processor to flags. | 319 | # Add target processor to flags. |
| 320 | # You can give EXTRAFLAGS at 'make' command line. | 320 | # You can give extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar |
| 321 | ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) | 321 | ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) |
| 322 | ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) | 322 | ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) |
| 323 | ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS) | 323 | ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS) |
