diff options
Diffstat (limited to 'm0110.c')
| -rw-r--r-- | m0110.c | 98 |
1 files changed, 74 insertions, 24 deletions
| @@ -66,7 +66,7 @@ Signaling | |||
| 66 | --------- | 66 | --------- |
| 67 | CLOCK is always from KEYBOARD. DATA are sent with MSB first. | 67 | CLOCK is always from KEYBOARD. DATA are sent with MSB first. |
| 68 | 68 | ||
| 69 | 1) IDLE: both line is high. | 69 | 1) IDLE: both lines are high. |
| 70 | CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 70 | CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 71 | DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 71 | DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 72 | 72 | ||
| @@ -79,7 +79,7 @@ CLOCK is always from KEYBOARD. DATA are sent with MSB first. | |||
| 79 | 3) HOST->KEYBOARD: HOST asserts bit on falling edge. | 79 | 3) HOST->KEYBOARD: HOST asserts bit on falling edge. |
| 80 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | 80 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ |
| 81 | DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | 81 | DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ |
| 82 | <----> 840us(request to send by host) <-> 80us(hold DATA) | 82 | <----> 840us(request to send by host) <---> 80us(hold DATA) |
| 83 | <--> 180us(clock low) | 83 | <--> 180us(clock low) |
| 84 | <---> 220us(clock high) | 84 | <---> 220us(clock high) |
| 85 | 85 | ||
| @@ -98,11 +98,18 @@ COMMAND: | |||
| 98 | 98 | ||
| 99 | KEY EVENT: | 99 | KEY EVENT: |
| 100 | bit 7 key state(0:press 1:release) | 100 | bit 7 key state(0:press 1:release) |
| 101 | bit 6-1 scan code | 101 | bit 6-1 scan code(see below) |
| 102 | bit 0 always 1 | 102 | bit 0 always 1 |
| 103 | To get scan code, use ((bits&(1<<7)) | ((bits&7F))>>1). | 103 | To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1). |
| 104 | |||
| 105 | Note: On the M0110A, the numpad keys and the arrow keys are preceded by 0x79. | ||
| 106 | Moreover, the numpad keys =, /, * and + are preceded by shift-down 0x71 on press and shift-up 0xF1 on release. | ||
| 107 | So, the data transferred by nupmad 5 is "79 2F" whereas for numpad + it's "71 79 0D". | ||
| 104 | 108 | ||
| 105 | SCAN CODE: | 109 | SCAN CODE: |
| 110 | m0111_recv_key() function returns follwing scan codes instead of raw key events. | ||
| 111 | Scan codes are 1 byte long and bit7 is set when key is released. | ||
| 112 | |||
| 106 | M0110 | 113 | M0110 |
| 107 | ,---------------------------------------------------------. | 114 | ,---------------------------------------------------------. |
| 108 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| | 115 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |
| @@ -127,29 +134,74 @@ SCAN CODE: | |||
| 127 | | 3A| 37| 31 | 34| 3A| | 134 | | 3A| 37| 31 | 34| 3A| |
| 128 | `------------------------------------------------' | 135 | `------------------------------------------------' |
| 129 | 136 | ||
| 137 | M0110A | ||
| 138 | ,---------------------------------------------------------. ,---------------. | ||
| 139 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| | ||
| 140 | |---------------------------------------------------------| |---------------| | ||
| 141 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 142 | |-----------------------------------------------------' | |---------------| | ||
| 143 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 144 | |---------------------------------------------------------| |---------------| | ||
| 145 | |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 146 | |---------------------------------------------------------' |-----------|Ent| | ||
| 147 | |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | | ||
| 148 | `---------------------------------------------------------' `---------------' | ||
| 149 | ,---------------------------------------------------------. ,---------------. | ||
| 150 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62| | ||
| 151 | |---------------------------------------------------------| |---------------| | ||
| 152 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E| | ||
| 153 | |-----------------------------------------------------' | |---------------| | ||
| 154 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66| | ||
| 155 | |---------------------------------------------------------| |---------------| | ||
| 156 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| | | ||
| 157 | |---------------------------------------------------------' |-----------| 4C| | ||
| 158 | | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| | | ||
| 159 | `---------------------------------------------------------' `---------------' | ||
| 160 | |||
| 130 | 161 | ||
| 131 | References | 162 | References |
| 132 | ---------- | 163 | ---------- |
| 164 | Technical Info for 128K/512K and Plus | ||
| 165 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf | ||
| 166 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf | ||
| 133 | Protocol: | 167 | Protocol: |
| 168 | Page 20 of Tech Info for 128K/512K | ||
| 134 | http://www.mac.linux-m68k.org/devel/plushw.php | 169 | http://www.mac.linux-m68k.org/devel/plushw.php |
| 135 | Connector: | 170 | Connector: |
| 171 | Page 20 of Tech Info for 128K/512K | ||
| 136 | http://www.kbdbabel.org/conn/kbd_connector_macplus.png | 172 | http://www.kbdbabel.org/conn/kbd_connector_macplus.png |
| 137 | Signaling: | 173 | Signaling: |
| 138 | http://www.kbdbabel.org/signaling/kbd_signaling_mac.png | 174 | http://www.kbdbabel.org/signaling/kbd_signaling_mac.png |
| 139 | http://typematic.blog.shinobi.jp/Entry/14/ | 175 | http://typematic.blog.shinobi.jp/Entry/14/ |
| 140 | Scan Codes: | 176 | Scan Codes: |
| 177 | Page 22 of Tech Info for 128K/512K | ||
| 178 | Page 07 of Tech Info for Plus | ||
| 141 | http://m0115.web.fc2.com/m0110.jpg | 179 | http://m0115.web.fc2.com/m0110.jpg |
| 142 | http://m0115.web.fc2.com/m0110a.jpg | 180 | http://m0115.web.fc2.com/m0110a.jpg |
| 143 | */ | 181 | */ |
| 144 | 182 | ||
| 145 | 183 | ||
| 146 | #define WAIT(stat, us, err) do { \ | 184 | #define WAIT_US(stat, us, err) do { \ |
| 147 | if (!wait_##stat(us)) { \ | 185 | if (!wait_##stat(us)) { \ |
| 148 | m0110_error = err; \ | 186 | m0110_error = err; \ |
| 149 | goto ERROR; \ | 187 | goto ERROR; \ |
| 150 | } \ | 188 | } \ |
| 151 | } while (0) | 189 | } while (0) |
| 152 | 190 | ||
| 191 | #define WAIT_MS(stat, ms, err) do { \ | ||
| 192 | uint16_t _ms = ms; \ | ||
| 193 | while (_ms) { \ | ||
| 194 | if (wait_##stat(1000)) { \ | ||
| 195 | break; \ | ||
| 196 | } \ | ||
| 197 | _ms--; \ | ||
| 198 | } \ | ||
| 199 | if (_ms == 0) { \ | ||
| 200 | m0110_error = err; \ | ||
| 201 | goto ERROR; \ | ||
| 202 | } \ | ||
| 203 | } while (0) | ||
| 204 | |||
| 153 | 205 | ||
| 154 | uint8_t m0110_error = 0; | 206 | uint8_t m0110_error = 0; |
| 155 | 207 | ||
| @@ -158,9 +210,13 @@ void m0110_init(void) | |||
| 158 | { | 210 | { |
| 159 | uint8_t data; | 211 | uint8_t data; |
| 160 | idle(); | 212 | idle(); |
| 161 | _delay_ms(255); | 213 | _delay_ms(1000); |
| 162 | 214 | ||
| 163 | m0110_send(M0110_MODLE); | 215 | // Model Number |
| 216 | // M0110 : 0x09 00001001 : model number 4 (100) | ||
| 217 | // M0110A: 0x0B 00001011 : model number 5 (101) | ||
| 218 | // M0110 & M0120: ??? | ||
| 219 | m0110_send(M0110_MODEL); | ||
| 164 | data = m0110_recv(); | 220 | data = m0110_recv(); |
| 165 | print("m0110_init model: "); phex(data); print("\n"); | 221 | print("m0110_init model: "); phex(data); print("\n"); |
| 166 | 222 | ||
| @@ -174,24 +230,22 @@ uint8_t m0110_send(uint8_t data) | |||
| 174 | m0110_error = 0; | 230 | m0110_error = 0; |
| 175 | 231 | ||
| 176 | request(); | 232 | request(); |
| 177 | WAIT(clock_lo, 1000, 0); | 233 | WAIT_MS(clock_lo, 250, 1); // keyboard may block long time |
| 178 | for (uint8_t bit = 0x80; bit; bit >>= 1) { | 234 | for (uint8_t bit = 0x80; bit; bit >>= 1) { |
| 179 | WAIT(clock_lo, 250, 3); | 235 | WAIT_US(clock_lo, 250, 3); |
| 180 | _delay_us(15); | ||
| 181 | if (data&bit) { | 236 | if (data&bit) { |
| 182 | data_hi(); | 237 | data_hi(); |
| 183 | } else { | 238 | } else { |
| 184 | data_lo(); | 239 | data_lo(); |
| 185 | } | 240 | } |
| 186 | WAIT(clock_hi, 200, 4); | 241 | WAIT_US(clock_hi, 200, 4); |
| 187 | } | 242 | } |
| 188 | _delay_us(100); // hold last bit for 80us | 243 | _delay_us(100); // hold last bit for 80us |
| 189 | idle(); | 244 | idle(); |
| 190 | return 1; | 245 | return 1; |
| 191 | ERROR: | 246 | ERROR: |
| 192 | if (m0110_error) { | 247 | print("m0110_send err: "); phex(m0110_error); print("\n"); |
| 193 | print("m0110_send err: "); phex(m0110_error); print("\n"); | 248 | _delay_ms(500); |
| 194 | } | ||
| 195 | idle(); | 249 | idle(); |
| 196 | return 0; | 250 | return 0; |
| 197 | } | 251 | } |
| @@ -201,24 +255,20 @@ uint8_t m0110_recv(void) | |||
| 201 | uint8_t data = 0; | 255 | uint8_t data = 0; |
| 202 | m0110_error = 0; | 256 | m0110_error = 0; |
| 203 | 257 | ||
| 204 | WAIT(clock_lo, -1, 0); // need 250ms? insted 0xffff(16bit max)us | 258 | WAIT_MS(clock_lo, 250, 1); // keyboard may block long time |
| 205 | for (uint8_t i = 0; i < 8; i++) { | 259 | for (uint8_t i = 0; i < 8; i++) { |
| 206 | data <<= 1; | 260 | data <<= 1; |
| 207 | WAIT(clock_lo, 200, 2); | 261 | WAIT_US(clock_lo, 200, 2); |
| 208 | WAIT(clock_hi, 200, 3); | 262 | WAIT_US(clock_hi, 200, 3); |
| 209 | if (data_in()) { | 263 | if (data_in()) { |
| 210 | data |= 1; | 264 | data |= 1; |
| 211 | } | 265 | } |
| 212 | } | 266 | } |
| 213 | idle(); | 267 | idle(); |
| 214 | if (data != M0110_NULL) { | ||
| 215 | print("m0110_recv data: "); phex(data); print("\n"); | ||
| 216 | } | ||
| 217 | return data; | 268 | return data; |
| 218 | ERROR: | 269 | ERROR: |
| 219 | if (m0110_error) { | 270 | print("m0110_recv err: "); phex(m0110_error); print("\n"); |
| 220 | print("m0110_recv err: "); phex(m0110_error); print("\n"); | 271 | _delay_ms(500); |
| 221 | } | ||
| 222 | idle(); | 272 | idle(); |
| 223 | return 0xFF; | 273 | return 0xFF; |
| 224 | } | 274 | } |
| @@ -231,7 +281,7 @@ uint8_t m0110_recv_key(void) | |||
| 231 | if (key == 0xFF || key == M0110_NULL) | 281 | if (key == 0xFF || key == M0110_NULL) |
| 232 | return M0110_NULL; | 282 | return M0110_NULL; |
| 233 | else | 283 | else |
| 234 | return ((key&(1<<7)) | ((key&0x7F)>>1)); | 284 | return M0110_RAW2SCAN(key); |
| 235 | } | 285 | } |
| 236 | 286 | ||
| 237 | 287 | ||
