Advertisement
Guest User

Untitled

a guest
Aug 17th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 78.33 KB | None | 0 0
  1. ; For compact keyboard, tie /INT low - Ctrl-Caps Lock enables Num Lock (disable with Caps Lock):
  2. ; 04 4 -> 5a Keypad (
  3. ; 05 5 -> 5b Keypad )
  4. ; 06 6 -> 5c Keypad /
  5. ; 07 7 -> 3d Keypad 7
  6. ; 08 8 -> 3e Keypad 8
  7. ; 09 9 -> 3f Keypad 9
  8. ; 0a 0 -> 5d Keypad *
  9. ; 16 U -> 2d Keypad 4
  10. ; 17 I -> 2e Keypad 5
  11. ; 18 O -> 2f Keypad 6
  12. ; 19 P -> 4a Keypad -
  13. ; 26 J -> 1d Keypad 1
  14. ; 27 K -> 1e Keypad 2
  15. ; 28 L -> 1f Keypad 3
  16. ; 29 ; -> 5e Keypad +
  17. ; 37 M -> 0f Keypad 0
  18. ; 39 . -> 3c Keypad .
  19. ; 44 Return -> 43 Enter
  20. ;
  21. ; |PA0|PA1|PA2|PA3|PA4|PA5|PA6|PA7|PC0|PC1|PC2|PC3|PC4|PC5|PC6|GND
  22. ; | 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30
  23. ; -------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
  24. ; PB4 1 |tab| Q | W | E | R | T | Y | U | I | O | P | [ | ] |cr |lt |
  25. ; PB5 2 |cap| A | S | D | F | G | H | J | K | L | ; | ' | \ |del|rt |
  26. ; PB6 3 | § | Z | X | C | V | B | N | M | , | . | / | |sp |bs |dn |
  27. ; PB7 4 |kp*|kp+|kp9|kp6|kp3|kp.|kp8|kp5|kp2|ent|kp7|kp4|kp1|kp0|kp-|
  28. ; PB3 5 | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | ¥ |up |
  29. ; PD0 6 | | | | | | | | | | | | | | | |rsh
  30. ; PB2 7 |esc|kp(|F1 |F2 |F3 |F4 |F5 |kp)|F6 |kp/|F7 |F8 |F9 |F10|hlp|
  31. ; PD1 8 | | | | | | | | | | | | | | | |ral
  32. ; PD2 10 | | | | | | | | | | | | | | | |rmt
  33. ; PD3 11 | | | | | | | | | | | | | | | |ctl
  34. ; PD4 12 | | | | | | | | | | | | | | | |lsh
  35. ; PD5 13 | | | | | | | | | | | | | | | |lal
  36. ; PD7 14 | | | | | | | | | | | | | | | |lmt
  37. ;
  38. ; PC7 31 drives caps lock LED
  39. ; PB1 drives KB_CLOCK
  40. ; PB0 drives KB_DATA and loops back to TCAP
  41. ; TCMP drives KB_RESET
  42. ;
  43. ; SPI 0x01ca four blinks on caps lock
  44. ; SCI 0x01ca four blinks on caps lock
  45. ; TIMER 0x0505
  46. ; IRQ 0x0570 return immediately
  47. ; SWI 0x01ca four blinks on caps lock
  48. ; RESET 0x0102
  49.  
  50. ; unsigned char const PB_MASK_KDAT = 0x01;
  51. ; unsigned char const PB_MASK_KCLK = 0x02;
  52. ;
  53. ; unsigned char const PC_MASK_CAPS = 0x80;
  54. ;
  55. ; unsigned char const PD_MASK_RSH = 0x01;
  56. ; unsigned char const PD_MASK_RAL = 0x02;
  57. ; unsigned char const PD_MASK_RMT = 0x04;
  58. ; unsigned char const PD_MASK_CTL = 0x08;
  59. ; unsigned char const PD_MASK_LSH = 0x10;
  60. ; unsigned char const PD_MASK_LAL = 0x20;
  61. ; unsigned char const PD_MASK_LMT = 0x80;
  62. ; unsigned char const PD_MASK_RIGHT = PD_MASK_RSH | PD_MASK_RAL | PD_MASK_RMT;
  63. ; unsigned char const PD_MASK_LEFT = PD_MASK_LSH | PD_MASK_LAL | PD_MASK_LMT;
  64. ; unsigned char const PD_MASK_ALL = PD_MASK_RIGHT | PD_MASK_CTL | PD_MASK_LEFT;
  65. ; unsigned char const PD_MASK_RESET = PD_MASK_RMT | PD_MASK_CTL | PD_MASK_LMT;
  66. ;
  67. ; unsigned char const CODE_MASK_DOWN = 0x00;
  68. ; unsigned char const CODE_MASK_UP = 0x80;
  69. ; unsigned char const CODE_CAPS_LCK = 0x62;
  70. ; unsigned char const CODE_RST_WARN = 0x78;
  71. ; unsigned char const CODE_PREV_BAD = 0xf9;
  72. ; unsigned char const CODE_KBD_FAIL = 0xfc;
  73. ; unsigned char const CODE_UP_INIT = 0xfd;
  74. ; unsigned char const CODE_UP_TERM = 0xfe;
  75. ;
  76. ;
  77. ; unsigned char scan[32]; // 0x0080..0x009f
  78. ; unsigned char queue_bytes[14]; // 0x00a6..0x00b3
  79. ; unsigned char queue_tail; // 0x00b4
  80. ; unsigned char queue_head; // 0x00b5
  81. ; bool caps_lock; // 0x00b8 & 0x80
  82. ; bool retransmit; // 0x00b8 & 0x40
  83. ; bool expect_ack; // 0x00b8 & 0x20
  84. ; bool first_scan; // 0x00b8 & 0x10
  85. ; bool resync; // 0x00b8 & 0x08
  86. ; bool queue_drop; // 0x00b8 & 0x04
  87. ; bool queue_full; // 0x00b8 & 0x02
  88. ; bool keys_changed; // 0x00b8 & 0x01
  89. ; unsigned char prev_code; // 0x00ba
  90. ; bool num_lock; // 0x00bc & 0x08
  91. ; unsigned char blink_count; // 0x00bd
  92.  
  93.  
  94. reset_vector:
  95. ; disable_interrupts(); // disable interrupts while setting up
  96. ; reset_stack_pointer();
  97. ; *(unsigned char *)0x1ff1 = 0x01;
  98. ; COPR = 0x00;
  99. ; TCR = 0x01; // capture falling edge, drive TCMP high on compare
  100. ; SCCR2 = SCCR1 = SPCR = 0x00; // disable serial communication
  101. ; *(unsigned char *)0x1fdf = 0x00;
  102. ; *(unsigned char *)0x3fdf = 0x00;
  103. ; PORTC = ~PC_MASK_CAPS; // light Caps Lock LED while initialising
  104. ; DDRC = DDRA = PORTD = PORTB = PORTA = 0xff; // ports A and C are output, drive all rows high
  105. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK; // drive KDAT and KCLK high
  106. ; COPR = 0x00;
  107. ; unsigned char addr;
  108. ; addr = 0x80;
  109. ; do
  110. ; {
  111. ; if (*(unsigned char *)addr != addr) goto ram_test;
  112. ; }
  113. ; while (++addr >= 0xfb);
  114. ; goto watchdog_pass;
  115. ; ram_test:
  116. ; COPR = 0x00;
  117. ; unsigned char val;
  118. ; bool msb;
  119. ; addr = 0x80;
  120. ; do
  121. ; {
  122. ; val = 0xfe;
  123. ; do
  124. ; {
  125. ; *(unsigned char *)addr = val;
  126. ; if (*(unsigned char *)addr != val) goto ram_fail;
  127. ; msb = val & 0x80;
  128. ; val = (val << 1) | 0x01;
  129. ; }
  130. ; while (msb);
  131. ; }
  132. ; while (++addr);
  133. ; addr = 0x80;
  134. ; do
  135. ; {
  136. ; val = 0x01;
  137. ; do
  138. ; {
  139. ; *(unsigned char *)addr = val;
  140. ; if (*(unsigned char *)addr != val) goto ram_fail;
  141. ; msb = val & 0x80;
  142. ; val <<= 1;
  143. ; }
  144. ; while (!msb);
  145. ; }
  146. ; while (++addr);
  147. ; addr = 0x80;
  148. ; do { *(unsigned char *)addr = addr; } while (++addr);
  149. ; addr = 0x80;
  150. ; do { if (*(unsigned char *)addr != addr) goto memory_fail; } while (++addr);
  151. ; *(unsigned char *)0x80 = val;
  152. ; goto program_check;
  153. ; ram_fail:
  154. ; goto memory_fail;
  155. 0102: 9B sei ; disable interrupts
  156. 0103: 9C rsp ; reset stack pointer
  157. 0104: A6 01 lda #$01 ; WTF?
  158. 0106: C7 1F F1 sta $1FF1
  159. 0109: A6 00 lda #$00 ; reset NCOP
  160. 010B: C7 1F F0 sta $1FF0
  161. 010E: A6 01 lda #$01 ; disable timer/capture/compare interrupts, output 1 on next compare match
  162. 0110: B7 12 sta TCR
  163. 0112: A6 00 lda #$00 ; disable SPI/SCI
  164. 0114: B7 0A sta SPCR
  165. 0116: B7 0E sta SCCR1
  166. 0118: B7 0F sta SCCR2
  167. 011A: C7 1F DF sta $1FDF ; WTF?
  168. 011D: C7 3F DF sta $3FDF
  169. 0120: A6 7F lda #$7F ; PC7 low, all other digital outputs high
  170. 0122: B7 02 sta PORTC
  171. 0124: A6 FF lda #$FF
  172. 0126: B7 00 sta PORTA
  173. 0128: B7 01 sta PORTB
  174. 012A: B7 03 sta PORTD
  175. 012C: B7 04 sta DDRA ; make ports A and C outputs
  176. 012E: B7 06 sta DDRC
  177. 0130: A6 03 lda #$03 ; make PB0 (KB_DATA) and PB1 (KB_CLOCK) outputs
  178. 0132: B7 05 sta DDRB
  179. 0134: A6 00 lda #$00 ; reset NCOP
  180. 0136: C7 1F F0 sta $1FF0
  181. 0139: AE 80 ldx #$80 ; check that data at 0x80..0xfc matches addresses
  182. 013B: F3 cpx (x)
  183. 013C: 26 08 bne $146
  184. 013E: 5C incx ; ++x
  185. 013F: A3 FB cpx #$FB ; loop if greater than than 0xfb (note the bug!)
  186. 0141: 24 F8 bcc $13B
  187. 0143: CC 02 8A jmp $028A ; goto 0x028a
  188. 0146: A6 00 lda #$00 ; reset ncop
  189. 0148: C7 1F F0 sta $1FF0
  190. 014B: AE 80 ldx #$80
  191. 014D: A6 FE lda #$FE
  192. 014F: F7 sta (x)
  193. 0150: F1 cmpa (x)
  194. 0151: 26 27 bne $17A
  195. 0153: 99 sec
  196. 0154: 49 rola
  197. 0155: 25 F8 bcs $14F
  198. 0157: 5C incx
  199. 0158: 26 F3 bne $14D
  200. 015A: AE 80 ldx #$80
  201. 015C: A6 01 lda #$01
  202. 015E: F7 sta (x)
  203. 015F: F1 cmpa (x)
  204. 0160: 26 18 bne $17A
  205. 0162: 48 asla
  206. 0163: 24 F9 bcc $15E
  207. 0165: 5C incx
  208. 0166: 26 F4 bne $15C
  209. 0168: AE 80 ldx #$80
  210. 016A: FF stx (x)
  211. 016B: 5C incx
  212. 016C: 26 FC bne $16A
  213. 016E: AE 80 ldx #$80
  214. 0170: F3 cpx (x)
  215. 0171: 26 5F bne $1D2
  216. 0173: 5C incx
  217. 0174: 26 FA bne $170
  218. 0176: B7 80 sta $80
  219. 0178: 20 0A bra $184
  220. 017A: CC 01 D2 jmp $01D2
  221.  
  222. 017D: D6 01 00 lda (x+$0100)
  223. 0180: 81 rts
  224. 0181: 00 00 fdb $0000
  225. 0183: 08 fcb $08
  226.  
  227. ; program_check:
  228. ; typedef unsigned char (*fetch_func)(unsigned char);
  229. ; constexpr fetch_func fetch = (fetch_func)0x50;
  230. ; constexpr unsigned short *sum = (unsigned short *)0x54;
  231. ; COPR = 0x00;
  232. ; unsigned char i;
  233. ; i = 0x07;
  234. ; do { (unsigned char *)(0x50 + i) = (unsigned char *)(0x017d + i); } while (!--i & 0x80);
  235. ; i = 0x02;
  236. ; do
  237. ; {
  238. ; do { *sum += fetch_func(i); } while (++i);
  239. ; ++*(unsigned char *)0x51;
  240. ; }
  241. ; while (!(--*(unsigned char *)0x56));
  242. ; if (*sum != *(unsigned short)0x0100) goto 0x01d6;
  243. ; COPR = 0x00;
  244. ; i = 0x80;
  245. ; do { *(unsigned char *)i = i; } while (++i);
  246. ; i = 0x80;
  247. ; do
  248. ; {
  249. ; int j = 0;
  250. ; while (--j) { }
  251. ; }
  252. ; while (--i);
  253. ; goto watchdog_fail;
  254. 0184: A6 00 lda #$00 ; reset NCOP
  255. 0186: C7 1F F0 sta $1FF0
  256. 0189: AE 07 ldx #$07 ; copy a function that fetches a value from program ROM into RAM at 0x50
  257. 018B: D6 01 7D lda (x+$017D) ; followed by two zeros for checksum and a block count of 8
  258. 018E: E7 50 sta (x+$50)
  259. 0190: 5A decx
  260. 0191: 2A F8 bpl $18B
  261. 0193: AE 02 ldx #$02 ; sum program ROM from 0x0102 to 0x01ff
  262. 0195: BD 50 jsr $50
  263. 0197: BB 55 adda $55
  264. 0199: B7 55 sta $55
  265. 019B: 24 02 bcc $19F
  266. 019D: 3C 54 inc $54
  267. 019F: 5C incx
  268. 01A0: 26 F3 bne $195
  269. 01A2: 3C 51 inc $51 ; increment the high byte of base address in fetch function
  270. 01A4: 3A 56 dec $56 ; loop if more blocks
  271. 01A6: 2A ED bpl $195
  272. 01A8: C1 01 01 cmpa $0101 ; if checksum doesn't match expected value at 0x0100, goto 0x01d6
  273. 01AB: 26 29 bne $1D6
  274. 01AD: B6 54 lda $54
  275. 01AF: C1 01 00 cmpa $0100
  276. 01B2: 26 22 bne $1D6
  277. 01B4: A6 00 lda #$00 ; reset NCOP
  278. 01B6: C7 1F F0 sta $1FF0
  279. 01B9: AE 80 ldx #$80 ; store values 0x80..0xff in locations 0x00..0xff
  280. 01BB: FF stx (x)
  281. 01BC: 5C incx
  282. 01BD: 26 FC bne $1BB
  283. 01BF: A6 80 lda #$80 ; nested delay loops waiting for COP reset
  284. 01C1: 5F clrx
  285. 01C2: 5A decx
  286. 01C3: 26 FD bne $1C2
  287. 01C5: 4A deca
  288. 01C6: 26 F9 bne $1C1
  289. 01C8: 20 04 bra $1CE
  290.  
  291. ; unexpected_int: // 0x01ca
  292. ; a = 0x0f;
  293. ; goto blink_led;
  294. ; watchdog_fail: // 0x01ce
  295. ; a = 0x07;
  296. ; goto blink_led;
  297. ; memory_fail: // 0x01d2
  298. ; a = 0x03;
  299. ; goto blink_led;
  300. ; program_fail: // 0x01d6
  301. ; a = 0x01;
  302. ; blink_led:
  303. ; disable_interrupts();
  304. ; unsigned char result = a; // 0x0056
  305. ; *(unsigned char *)0x80 = a;
  306. ; *(unsigned char *)0x1ff1 = 0x00;
  307. ; COPR = 0x00;
  308.  
  309. ; // force resynchronisation by clocking out 1 bits
  310. ; unsigned char status;
  311. ; do
  312. ; { // 0x01e5
  313. ; PORTB = ~PB_MASK_KDAT; // KDAT low (logical 1 as it's active low)
  314. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK; // drive KDAT and KCLK
  315. ; bit_delay();
  316. ; PORTB = ~(PB_MASK_KDAT | PB_MASK_KCLK); // clock out the bit
  317. ; bit_delay();
  318. ; PORTB = ~PB_MASK_KDAT;
  319. ; bit_delay();
  320. ; PORTB = ~0x00; // release KDAT and disable KDAT output (PB0)
  321. ; DDRB = PB_MASK_KCLK;
  322. ; unsigned char const high = TRH; // get current timer count
  323. ; unsigned char const low = TRL;
  324. ; if (high & TSR) { } // clear timer/capture/compare status
  325. ; if (high & ICRH) { }
  326. ; if (high & ICRL { }
  327. ; if (high & TSR) { }
  328. ; OCRH = high; // copy timer value to output compare register
  329. ; OCRL = low;
  330. ; do { COPR = 0x00; } while (!(status = TSR & 0xc0)); // wait for compare or capture event
  331. ; if (status & ICRL) { } // clear out input capture flag
  332. ; }
  333. ; while (!(status & 0x80)); // loop if it wasn't an input capture event
  334. ;
  335. ; // send 0xfc self-test failure code
  336. ; unsigned char data = ~CODE_KBD_FAIL; // 0x00a3
  337. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK; // drive KDAT and KCLK
  338. ; unsigned bits = 8;
  339. ; do
  340. ; { // 0x022f
  341. ; data = (data << 1) + ((data & 0x80) ? 1 : 0); // rotate value left (do first because MSB sent last)
  342. ; unsigned char val = data | 0x7f; // clock out leftmost bit
  343. ; PORTB = val = (val << 2) | PB_MASK_KCLK | ((val & 0x80) ? PB_MASK_KDAT : 0);
  344. ; bit_delay();
  345. ; PORTB = val &= ~PB_MASK_KCLK;
  346. ; bit_delay();
  347. ; PORTB = val |= PB_MASK_KCLK;
  348. ; bit_delay();
  349. ; }
  350. ; while (--bits); // loop while bits remaining to send
  351. ;
  352. ; // loop while blinking LEDs
  353. ; while (true)
  354. ; { // 0x0251
  355. ; DDRC = PORTB = 0xff; // make port C all outputs, release KCLK and KDAT
  356. ; if (0xff & TSR) { } // clear timer and output compare status
  357. ; if (0xff & OCRL) { }
  358. ; unsigned wait;
  359. ; wait = 2; // wait for two compare events
  360. ; do
  361. ; {
  362. ; do { COPR = 0x00; } while (!(TSR & 0x40));
  363. ; if (0x00 & OCRL) { }
  364. ; }
  365. ; while (!--wait);
  366. ; result = (result << 1) + ((result & 0x80) ? 1 : 0); // rotate blink pattern left
  367. ; PORTC = (result | ~PC_MASK_CAPS) ^ PC_MASK_CAPS; // light Caps Lock LED if leftmost bit is set
  368. ; wait = 2; // wait for two compare events
  369. ; do
  370. ; {
  371. ; do { COPR = 0x00; } while (!(TSR & 0x40));
  372. ; if (0x00 & OCRL) { }
  373. ; }
  374. ; while (!--wait);
  375. ; PORTC |= PC_MASK_CAPS; // extinguish Caps Lock LED
  376. ; }
  377. 01CA: A6 0F lda #$0F
  378. 01CC: 20 0A bra $1D8
  379. 01CE: A6 07 lda #$07
  380. 01D0: 20 06 bra $1D8
  381. 01D2: A6 03 lda #$03
  382. 01D4: 20 02 bra $1D8
  383. 01D6: A6 01 lda #$01
  384.  
  385. 01D8: 9B sei ; disable interrupts
  386. 01D9: B7 56 sta $56 ; stash self-test result at 0x56 and 0x80
  387. 01DB: B7 80 sta $80
  388. 01DD: A6 00 lda #$00 ; WTF?
  389. 01DF: C7 1F F1 sta $1FF1
  390. 01E2: C7 1F F0 sta $1FF0 ; reset NCOP
  391. 01E5: A6 FE lda #$FE ; KB_DATA low, KB_CLOCK high, both outputs
  392. 01E7: B7 01 sta PORTB
  393. 01E9: A6 03 lda #$03
  394. 01EB: B7 05 sta DDRB
  395. 01ED: CD 07 7D jsr $077D ; bit_delay()
  396. 01F0: A6 FC lda #$FC ; KB_DATA low, KB_CLOCK low
  397. 01F2: B7 01 sta PORTB ; bit_delay()
  398. 01F4: CD 07 7D jsr $077D
  399. 01F7: A6 FE lda #$FE ; KB_DATA low, KB_CLOCK high
  400. 01F9: B7 01 sta PORTB
  401. 01FB: CD 07 7D jsr $077D ; bit_delay()
  402. 01FE: A6 FF lda #$FF ; KB_DATA high, KB_CLOCK high
  403. 0200: B7 01 sta PORTB
  404. 0202: A6 02 lda #$02 ; KB_DATA input, KB_CLOCK output
  405. 0204: B7 05 sta DDRB
  406. 0206: B6 18 lda TRH ; put current timer contents in a:x
  407. 0208: BE 19 ldx TRL
  408. 020A: B5 13 bita TSR ; ensure ICF is clear
  409. 020C: B5 14 bita ICRH
  410. 020E: B5 15 bita ICRL
  411. 0210: B5 13 bita TSR ; store retrieved timer value in OCR (and clear OCF)
  412. 0212: B7 16 sta OCRH
  413. 0214: BF 17 stx OCRL
  414. 0216: A6 00 lda #$00 ; reset NCOP
  415. 0218: C7 1F F0 sta $1FF0
  416. 021B: B6 13 lda TSR ; wait for input capture/output compare
  417. 021D: A4 C0 anda #$C0
  418. 021F: 27 F5 beq $216
  419. 0221: 2A C2 bpl $1E5 ; if it wasn't input capture, loop to 0x01e5
  420.  
  421. 0223: B5 15 bita ICRL ; read ICRL to clear input capture flag
  422. 0225: A6 03 lda #$03 ; *(unsigned char)0xa3 = 0x03
  423. 0227: B7 A3 sta $A3
  424. 0229: A6 03 lda #$03 ; KB_DATA output, KB_CLOCK output
  425. 022B: B7 05 sta DDRB
  426. 022D: AE 08 ldx #$08 ; bit count 8 in x
  427. 022F: B6 A3 lda $A3 ; rotate data left by one bit
  428. 0231: 48 asla
  429. 0232: A9 00 adca #$00
  430. 0234: B7 A3 sta $A3
  431. 0236: AA 7F ora #$7F ; PORTB = 0xfe | (data >> 7)
  432. 0238: 99 sec
  433. 0239: 49 rola
  434. 023A: 49 rola
  435. 023B: B7 01 sta PORTB
  436. 023D: CD 07 7D jsr $077D ; bit_delay()
  437. 0240: A4 FD anda #$FD ; pull KB_CLOCK low
  438. 0242: B7 01 sta PORTB
  439. 0244: CD 07 7D jsr $077D ; bit_delay()
  440. 0247: AA 02 ora #$02 ; pull KB_CLOCK high
  441. 0249: B7 01 sta PORTB
  442. 024B: CD 07 7D jsr $077D ; bit_delay()
  443. 024E: 5A decx ; decrement bit count and loop if not zero
  444. 024F: 26 DE bne $22F
  445.  
  446. 0251: A6 FF lda #$FF ; pull KB_CLOCK and KB_DATA high
  447. 0253: B7 01 sta PORTB
  448. 0255: B7 06 sta DDRC ; make PORTC outputs
  449. 0257: B5 13 bita TSR ; ensure OCF is clear by reading TSR followed by OCRL
  450. 0259: B5 17 bita OCRL
  451. 025B: AE 02 ldx #$02 ; wait count = 2
  452. 025D: A6 00 lda #$00 ; reset NCOP
  453. 025F: C7 1F F0 sta $1FF0
  454. 0262: 0D 13 F8 brclr 6,TSR,$25D ; loop while OCF is false
  455. 0265: B5 17 bita OCRL ; read OCRL to clear OCF
  456. 0267: 5A decx ; decrement wait count and loop if non-zero
  457. 0268: 26 F3 bne $25D
  458. 026A: B6 56 lda $56 ; rotate result left one bit
  459. 026C: 48 asla
  460. 026D: A9 00 adca #$00
  461. 026F: B7 56 sta $56
  462. 0271: AA 7F ora #$7F ; put inverse of MSB of result on caps lock LED
  463. 0273: A8 80 eora #$80
  464. 0275: B7 02 sta PORTC
  465. 0277: AE 02 ldx #$02 ; wait count = 2
  466. 0279: A6 00 lda #$00
  467. 027B: C7 1F F0 sta $1FF0 ; wait for output capture and clear flag
  468. 027E: 0D 13 F8 brclr 6,TSR,$279
  469. 0281: B5 17 bita OCRL
  470. 0283: 5A decx ; decrement wait count and loop if non-zero
  471. 0284: 26 F3 bne $279
  472. 0286: 1E 02 bset 7,PORTC ; turn off caps lock LED
  473. 0288: 20 C7 bra $251 ; repeat forever
  474.  
  475. ; watchdog_pass: // 0x028a
  476. ; disable_interrupts();
  477. ; reset_stack_pointer();
  478. ; PORTD = PORTC = PORTB = PORTA = 0xff;
  479. ; DDRC = DDRA = 0xff;
  480. ; DDRB = 0x03;
  481. ; unsigned char i = sizeof(scan) - 1; // fill scan state with all keys up
  482. ; do { scan[i] = 0xff; } while (!(--i & 0x80));
  483. ; unsigned char sent_modifiers = 0x7f; // 0xa1
  484. ; unsigned char modifiers = 0x7f; // 0xa0
  485. ; queue_head = queue_tail = 0x00; // start with transmit queue empty
  486. ; num_lock = false; // start with standard key map
  487. ; *(unsigned char *)0xbc = 0x00;
  488. ; keys_changed = queue_full = queue_drop = resync = retransmit = caps_lock = false;
  489. ; first_scan = expect_ack = true;
  490. ; unsigned char high = TRH; // clear timer/capture/compare flags
  491. ; unsigned char low = TRL;
  492. ; if (high & TSR) { }
  493. ; if (high & ICRH) { }
  494. ; if (high & ICRL) { }
  495. ; if (high & TSR) { }
  496. ; OCRH = high; // maximise time to compare interrupt
  497. ; OCRL = low;
  498. ; TCR = 0xc3; // capture interrupt on (rising), compare interrupt on (high)
  499. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK; // drive KDAT and KCLK
  500. ; queue_byte(CODE_UP_INIT); // queue initiate power-up key stream code
  501. ; while (true)
  502. ; { // 0x02d4
  503. ; DDRC = DDRA = PORTB = ~0x00; // make ports A and C outputs, drive KCLK and KDAT high
  504. ; unsigned char ghosts = 0xff; // 0xb9
  505. ; unsigned char cols_hit = 0xff; // 0xbb
  506. ; keys_changed = false; // haven't seen any key changes yet on this scan
  507. ; unsigned char row = 0; // 0xb7
  508. ; PORTA = 0x00; // first eight rows low, disable interrupts
  509. ; disable_interrupts();
  510. ; PORTC &= PC_MASK_CAPS; // drive other seven rows low, re-enable interrupts
  511. ; enable_interrupts();
  512. ; unsigned char i; // spin for 86 machine cycles so inputs can settle
  513. ; i = 14;
  514. ; while (--i) { }
  515. ; if ((PORTB | PB_MASK_KDAT | PB_MASK_KCLK) == ~0x00) // check for case where no matrix keys are down
  516. ; { // 0x02fd
  517. ; i = 0; // see if any matrix keys were down on the last scan
  518. ; do
  519. ; { // 0x02ff
  520. ; if (scan[i] != 0xff) goto check_matrix; // if so, check matrix properly
  521. ; }
  522. ; while (15 > ++i);
  523. ; goto check_modifiers; // otherwise check new state of modifiers
  524. ; }
  525. ; check_matrix: // 0x030a
  526. ; do
  527. ; { // 0x030a
  528. ; disable_interrupts(); // disable interrups while setting row drive
  529. ; if (8 <= row)
  530. ; { // 0x030f
  531. ; unsigned char pattern = insert_zero(row & 0x07); // this row is on port C - generate pattern
  532. ; if (!(PORTC & 0x80)) pattern &= 0x7f; // preserve Caps Lock LED state and push to port C buffer
  533. ; PORTC = pattern;
  534. ; DDRC = (pattern ^ 0xff) | 0x80; // release other matrix rows rather than driving high
  535. ; PORTA = 0xff;
  536. ; DDRA = 0x00;
  537. ; }
  538. ; else
  539. ; { // 0x032d
  540. ; unsigned char const pattern = insert_zero(row); // this row is on port A - generate pattern
  541. ; PORTA = pattern; // push to port A buffer
  542. ; DDRA = pattern ^ 0xff; // release other matrix rows rather than driving high
  543. ; PORTC |= 0x7f;
  544. ; DDRC = 0x80;
  545. ; }
  546. ; enable_interrupts(); // re-enable interrupts
  547. ; i = 14; // spin for 86 machine cycles so inputs can settle
  548. ; while (--i) { }
  549. ; i = PORTB; // read columns and update/flag if it changed since last scan
  550. ; if (scan[row] != i)
  551. ; { // 0x0350
  552. ; scan[row] = i;
  553. ; keys_changed = true;
  554. ; }
  555. ; unsigned char current = scan[row]; // 0x00a3
  556. ; ghosts &= cols_hit | current; // update values for ghosting check
  557. ; cols_hit &= current;
  558. ; }
  559. ; while (15 > ++row);
  560. ; check_modifiers: // 0x036e
  561. ; unsigned char current = PORTD & PD_MASK_ALL; // get modifier state (active low) in contiguous bits
  562. ; if (current & 0x80) current |= 0x40;
  563. ; current &= 0x7f;
  564. ; if (current != modifiers) // update/flag if it changed since last check
  565. ; { // 0x037c
  566. ; modifiers = current;
  567. ; keys_changed = true;
  568. ; }
  569. ; if (keys_changed) // if we see a change, wait for keys to stop bouncing
  570. ; { // 0x0383
  571. ; i = 179; // spin for 1792 machine cycles
  572. ; do { nop(); nop(); } while (--i);
  573. ; continue;
  574. ; }
  575. ;
  576. ; // keys seem to be stable
  577. ; row = 0;
  578. ; do
  579. ; { // 0x3b9
  580. ; unsigned char column = 0; // 0xb6
  581. ; do
  582. ; { // 0x03bb
  583. ; unsigned char current = insert_zero(column + 2); // 0x00a3
  584. ; unsigned char const tmp = scan[row] | current; // 0x00a2
  585. ; if ((current | scan[16 + row]) != tmp) // if this key didn't change, check the next one
  586. ; continue;
  587. ;
  588. ; unsigned char makebit; // 0x00a2
  589. ; if (tmp == 0xff)
  590. ; { // 0x03dd
  591. ; makebit = CODE_MASK_UP; // key released
  592. ; }
  593. ; else
  594. ; { // 0x03e3
  595. ; makebit = CODE_MASK_DOWN; // ignore key down if it fails ghosting test
  596. ; if (((scan[row] ^ 0xff) & current) && ((ghosts | current) ^ 0xff))
  597. ; continue;
  598. ; }
  599. ;
  600. ; // try to notify the host about this key transition
  601. ; while (true)
  602. ; { // 0x03f8
  603. ; unsigned short const tmp = ((row << 1) && 0xff) + ((row << 2) & 0xff);
  604. ; unsigned char const offset = column + (tmp & 0xff) + ((tmp >> 8) & 0x01);
  605. ; unsigned char code;
  606. ; if (!irq_high() && num_lock) // in compact mode, the keypad can be remapped
  607. ; code = TRANS_NUM[offset];
  608. ; else
  609. ; code = TRANS_STD[offset];
  610. ;
  611. ; if (code != CODE_CAPS_LCK) // if it's not Caps Lock, combine with make/break and queue
  612. ; { // 0x0414
  613. ; if (!queue_byte(code | makebit)) break;
  614. ; do { COPR = 0x00; } while (queue_full); // if the queue was full, spin and retry when there's space
  615. ; continue;
  616. ; }
  617. ; else if (makebit & 0x80) // don't send Caps Lock release code here
  618. ; {
  619. ; break;
  620. ; }
  621. ;
  622. ; // in compact mode, Caps Lock is used for remapping the numeric keypad over the main keyboard
  623. ; if (!irq_high())
  624. ; { // 0x041e
  625. ; if (((PORTD & PD_MASK_ALL) ^ PD_MASK_ALL) == PD_MASK_CTL)
  626. ; { // 0x0428
  627. ; num_lock = true; // this was Ctrl-Caps Lock, remap numeric keypad
  628. ; blink_count = 0;
  629. ; if (!caps_lock) break; // if Caps Lock was off, this doesn't turn it on
  630. ; }
  631. ; else if (num_lock)
  632. ; { // 0x0434
  633. ; disable_interrupts(); // Caps Lock disables numeric keypad remapping
  634. ; num_lock = false;
  635. ; caps_lock = false;
  636. ; PORTC |= PC_MASK_CAPS; // extinguish Caps Lock LED
  637. ; enable_interrupts();
  638. ; break;
  639. ; }
  640. ; }
  641. ;
  642. ; // send the logical Caps Lock transition
  643. ; if (queue_byte(TRANS_STD[offset]) | (caps_lock ? CODE_MASK_UP : CODE_MASK_DOWN))
  644. ; { // 0x044a
  645. ; do { COPR = 0x00; } while (queue_full); // no space in queue - spin until there is and retry
  646. ; }
  647. ; else
  648. ; { // 0x0455
  649. ; disable_interrupts(); // update caps lock state and LED
  650. ; unsigned char const tmp = (caps_lock = !caps_lock) ? 0x00 : PC_MASK_CAPS_LOCK;
  651. ; enable_interrupts();
  652. ; PORTC = tmp | ~PC_MASK_CAPS_LOCK;
  653. ; break;
  654. ; }
  655. ; }
  656. ; scan[16 + row] ^= ~insert_zero(column + 2); // update state of keys sent to host
  657. ; }
  658. ; while (++column < 6);
  659. ; COPR = 0x00;
  660. ; }
  661. ; while (++row < 15);
  662. ;
  663. ; // update modifiers with dedicated input lines
  664. ; unsigned char bit = 0; // 0xb6
  665. ; do
  666. ; { // 0x0482
  667. ; unsigned char current = insert_zero(bit); // 0xa3
  668. ; unsigned char state = modifiers | current; // 0xa2
  669. ; if ((sent_modifiers | current) != state) // if it doesn't match what we last sent, get it queued
  670. ; { // 0x04b5
  671. ; state = (state ^ 0xff) ? CODE_MASK_DOWN : CODE_MASK_UP;
  672. ; while (queue_byte(TRANS_MOD[bit] | state)) // if the queue is full, spin until it isn't and retry
  673. ; { // 0x04cf
  674. ; do { COPR = 0x00; } while (queue_full);
  675. ; }
  676. ; sent_modifiers ^= insert_zero(bit) ^ 0xff; // track the state we've sent to the host
  677. ; }
  678. ; }
  679. ; while (7 > ++bit);
  680. ;
  681. ; if (first_scan)
  682. ; { // 0x04ef
  683. ; first_scan = false;
  684. ; while (queue_byte(CODE_UP_TERM))
  685. ; { // 0x04f8
  686. ; do { COPR = 0x00; } while (queue_full);
  687. ; }
  688. ; }
  689. ; }
  690. 028A: 9B sei ; disable interrupts
  691. 028B: 9C rsp ; reset stack pointer
  692. 028C: A6 FF lda #$FF ; set all I/O port latches to 0xff
  693. 028E: B7 00 sta PORTA
  694. 0290: B7 01 sta PORTB
  695. 0292: B7 02 sta PORTC
  696. 0294: B7 03 sta PORTD
  697. 0296: B7 04 sta DDRA ; make ports A and B outputs
  698. 0298: B7 06 sta DDRC
  699. 029A: A6 03 lda #$03 ; make PB0 (KB_DATA) and PB1 (KB_CLOCK) outputs
  700. 029C: B7 05 sta DDRB
  701. 029E: A6 FF lda #$FF ; fill previos scan storage with 0xff
  702. 02A0: AE 1F ldx #$1F
  703. 02A2: E7 80 sta (x+$80)
  704. 02A4: 5A decx
  705. 02A5: 2A FB bpl $2A2
  706. 02A7: A6 7F lda #$7F
  707. 02A9: B7 A1 sta $A1
  708. 02AB: B7 A0 sta $A0 ; modifiers = 0x7f
  709. 02AD: 3F B4 clr $B4
  710. 02AF: 3F B5 clr $B5
  711. 02B1: 3F BC clr $BC
  712. 02B3: A6 30 lda #$30
  713. 02B5: B7 B8 sta $B8
  714. 02B7: B6 18 lda TRH ; get current timer value in a:x
  715. 02B9: BE 19 ldx TRL
  716. 02BB: B5 13 bita TSR ; read TSR followed by ICRH and ICRL to reset ICF
  717. 02BD: B5 14 bita ICRH
  718. 02BF: B5 15 bita ICRL
  719. 02C1: B5 13 bita TSR ; read TSR then set OCRH to a and OCRL to x to reset OCF
  720. 02C3: B7 16 sta OCRH
  721. 02C5: BF 17 stx OCRL
  722. 02C7: A6 C3 lda #$C3 ; set ICIE/OCIE, clear TOIE, set IEDG, set OLVL
  723. 02C9: B7 12 sta TCR
  724. 02CB: A6 02 lda #$02 ; make KB_CLOCK output, make KB_DATA input
  725. 02CD: B7 05 sta DDRB
  726. 02CF: A6 FD lda #$FD ; queue_byte(0xfd)
  727. 02D1: CD 03 8D jsr $038D
  728. 02D4: A6 FF lda #$FF ; all lines of port B high, ports A and C all outputs
  729. 02D6: B7 01 sta PORTB
  730. 02D8: B7 04 sta DDRA
  731. 02DA: B7 06 sta DDRC
  732. 02DC: B7 B9 sta $B9 ; ghosts = cols_hit = 0xff
  733. 02DE: B7 BB sta $BB
  734. 02E0: 11 B8 bclr 0,$B8
  735. 02E2: 3F B7 clr $B7 ; row = 0;
  736. 02E4: A6 00 lda #$00 ; drive first eight rows low
  737. 02E6: B7 00 sta PORTA
  738. 02E8: 9B sei ; disable interrupts
  739. 02E9: B6 02 lda PORTC ; drive other seven rows low (leave caps lock LED alone)
  740. 02EB: A4 80 anda #$80
  741. 02ED: B7 02 sta PORTC
  742. 02EF: 9A cli ; enable interrupts
  743. 02F0: A6 0E lda #$0E ; fourteen loops (allow inputs to settle)
  744. 02F2: 4A deca
  745. 02F3: 26 FD bne $2F2
  746. 02F5: B6 01 lda PORTB ; if any matrix keys are down goto 0x030a
  747. 02F7: AA 03 ora #$03
  748. 02F9: A1 FF cmpa #$FF
  749. 02FB: 26 0D bne $30A
  750. 02FD: AE 00 ldx #$00 ; if any matrix keys were down on previous scan goto 0x030a
  751. 02FF: E1 80 cmpa (x+$80)
  752. 0301: 26 07 bne $30A
  753. 0303: 5C incx
  754. 0304: A3 0F cpx #$0F
  755. 0306: 2B F7 bmi $2FF
  756. 0308: 20 64 bra $36E ; no matrix keys released, goto 0x036e
  757. 030A: 9B sei ; disable interrupts while setting row drive
  758. 030B: B6 B7 lda $B7 ; if row less than 8 goto 0x032d
  759. 030D: A1 08 cmpa #$08
  760. 030F: 2B 1C bmi $32D
  761. 0311: A4 07 anda #$07 ; insert_zero(row & 0x07)
  762. 0313: CD 07 84 jsr $0784
  763. 0316: 0E 02 02 brset 7,PORTC,$31B ; drive this row low, drop drive to other lines besides caps lock LED
  764. 0319: A4 7F anda #$7F
  765. 031B: B7 02 sta PORTC
  766. 031D: A8 FF eora #$FF
  767. 031F: AA 80 ora #$80
  768. 0321: B7 06 sta DDRC
  769. 0323: A6 FF lda #$FF
  770. 0325: B7 00 sta PORTA
  771. 0327: A6 00 lda #$00
  772. 0329: B7 04 sta DDRA
  773. 032B: 20 13 bra $340
  774. 032D: CD 07 84 jsr $0784 ; insert_zero(row)
  775. 0330: B7 00 sta PORTA ; drive this row low, drop drive to other lines besides caps lock LED
  776. 0332: A8 FF eora #$FF
  777. 0334: B7 04 sta DDRA
  778. 0336: B6 02 lda PORTC
  779. 0338: AA 7F ora #$7F
  780. 033A: B7 02 sta PORTC
  781. 033C: A6 80 lda #$80
  782. 033E: B7 06 sta DDRC
  783. 0340: 9A cli ; re-enable interrupts
  784. 0341: A6 0E lda #$0E ; fourteen loops (allow inputs to settle)
  785. 0343: 4A deca
  786. 0344: 26 FD bne $343
  787. 0346: BE B7 ldx $B7 ; compare value from previous scan to current state
  788. 0348: B6 01 lda PORTB
  789. 034A: AA 03 ora #$03
  790. 034C: E1 80 cmpa (x+$80)
  791. 034E: 27 04 beq $354
  792. 0350: E7 80 sta (x+$80) ; update and set keys_changed if changed
  793. 0352: 10 B8 bset 0,$B8
  794. 0354: E6 80 lda (x+$80) ; *(unsigned char *)0xa3 = scan[row]
  795. 0356: B7 A3 sta $A3
  796. 0358: B6 BB lda $BB ; ghosts &= cols_hit | *(unsigned char *)0xa3
  797. 035A: BA A3 ora $A3
  798. 035C: B4 B9 anda $B9
  799. 035E: B7 B9 sta $B9
  800. 0360: B6 BB lda $BB ; cols_hit &= *(unsigned char)0xa3
  801. 0362: B4 A3 anda $A3
  802. 0364: B7 BB sta $BB
  803. 0366: 3C B7 inc $B7 ; increment row and loop if less than 15
  804. 0368: B6 B7 lda $B7
  805. 036A: A1 0F cmpa #$0F
  806. 036C: 2B 9C bmi $30A
  807. 036E: B6 03 lda PORTD ; get modifier state, shift left Amiga into bit 6
  808. 0370: A4 BF anda #$BF
  809. 0372: 2A 02 bpl $376
  810. 0374: AA 40 ora #$40
  811. 0376: A4 7F anda #$7F
  812. 0378: B1 A0 cmpa $A0 ; if changed update and set keys_changed
  813. 037A: 27 04 beq $380
  814. 037C: B7 A0 sta $A0
  815. 037E: 10 B8 bset 0,$B8
  816. 0380: 01 B8 34 brclr 0,$B8,$3B7 ; if (!keys_changed) goto 0x03b7
  817. 0383: A6 B3 lda #$B3 ; loop for a while (debounce?)
  818. 0385: 9D nop
  819. 0386: 9D nop
  820. 0387: 4A deca
  821. 0388: 26 FB bne $385
  822. 038A: CC 02 D4 jmp $02D4 ; jump back to key scanning loop
  823.  
  824. ; // returns 0xff if byte dropped, or 0x00 otherwise
  825. ; unsigned char queue_byte(unsigned char val)
  826. ; {
  827. ; disable_interrupts();
  828. ; unsigned char data = val; // 0x00a3
  829. ; if (queue_full)
  830. ; {
  831. ; queue_drop = true;
  832. ; enable_interrupts();
  833. ; return 0xff;
  834. ; }
  835. ; queue_bytes[queue_tail++] = data;
  836. ; if (queue_tail >= sizeof(queue_bytes))
  837. ; queue_tail = 0;
  838. ; if (val == queue_head)
  839. ; queue_full = true;
  840. ; force_capture_interrupt();
  841. ; enable_interrupts();
  842. ; return 0x00;
  843. ; }
  844. 038D: 9B sei
  845. 038E: B7 A3 sta $A3
  846. 0390: 03 B8 06 brclr 1,$B8,$399
  847. 0393: 14 B8 bset 2,$B8
  848. 0395: 9A cli
  849. 0396: A6 FF lda #$FF
  850. 0398: 81 rts
  851. 0399: BE B4 ldx $B4
  852. 039B: B6 A3 lda $A3
  853. 039D: E7 A6 sta (x+$A6)
  854. 039F: 3C B4 inc $B4
  855. 03A1: B6 B4 lda $B4
  856. 03A3: A1 0E cmpa #$0E
  857. 03A5: 2B 03 bmi $3AA
  858. 03A7: 4F clra
  859. 03A8: B7 B4 sta $B4
  860. 03AA: B1 B5 cmpa $B5
  861. 03AC: 26 02 bne $3B0
  862. 03AE: 12 B8 bset 1,$B8
  863. 03B0: CD 07 56 jsr $0756
  864. 03B3: 9A cli
  865. 03B4: A6 00 lda #$00
  866. 03B6: 81 rts
  867.  
  868. 03B7: 3F B7 clr $B7 ; set row and column to zero
  869. 03B9: 3F B6 clr $B6
  870. 03BB: BE B7 ldx $B7
  871. 03BD: B6 B6 lda $B6
  872. 03BF: AB 02 adda #$02 ; current = insert_zero(column + 2)
  873. 03C1: CD 07 84 jsr $0784
  874. 03C4: B7 A3 sta $A3
  875. 03C6: E6 80 lda (x+$80) ; if ((current | scan[16 + row]) == (current | scan[row])) goto 0x484
  876. 03C8: BA A3 ora $A3
  877. 03CA: B7 A2 sta $A2
  878. 03CC: E6 90 lda (x+$90)
  879. 03CE: BA A3 ora $A3
  880. 03D0: B1 A2 cmpa $A2
  881. 03D2: 26 03 bne $3D7
  882. 03D4: CC 04 84 jmp $0484
  883. 03D7: B6 A2 lda $A2 ; if ((current | scan[row]) ^ 0xff) goto 0x03e3
  884. 03D9: A8 FF eora #$FF
  885. 03DB: 26 06 bne $3E3
  886. 03DD: A6 80 lda #$80 ; key up, store 0x80
  887. 03DF: B7 A2 sta $A2
  888. 03E1: 20 15 bra $3F8
  889. 03E3: 3F A2 clr $A2 ; else store 0x00
  890. 03E5: E6 80 lda (x+$80) ; if (!((scan[row] ^ 0xff) & current)) goto 0x03f8
  891. 03E7: A8 FF eora #$FF
  892. 03E9: B4 A3 anda $A3
  893. 03EB: 27 0B beq $3F8
  894. 03ED: B6 B9 lda $B9 ; if (!((ghosts | current) ^ 0xff)) goto 0x03f8
  895. 03EF: BA A3 ora $A3
  896. 03F1: A8 FF eora #$FF
  897. 03F3: 27 03 beq $3F8
  898. 03F5: CC 04 84 jmp $0484 ; goto 0x0484
  899. 03F8: B6 B7 lda $B7 ; tmp = (unsigned short)((row << 1) && 0xff) + ((row << 2) & 0xff)
  900. 03FA: 48 asla
  901. 03FB: B7 A3 sta $A3
  902. 03FD: 48 asla
  903. 03FE: BB A3 adda $A3
  904. 0400: B9 B6 adca $B6 ; x = column + (tmp & 0xff) + ((tmp >> 8) & 0x01)
  905. 0402: 97 tax
  906. 0403: 2F 08 bih $40D ; if (!irq_high() && num_lock)
  907. 0405: 07 BC 05 brclr 3,$BC,$40D
  908. 0408: D6 07 F0 lda (x+$07F0) ; fetch code from x + 0x07f0
  909. 040B: 20 03 bra $410
  910. 040D: D6 07 8F lda (x+$078F) ; else fetch code from x + 0x078f
  911. 0410: A1 62 cmpa #$62 ; if code is not 0x62 (caps lock), bitwise or with make/break bit and goto 0x0465
  912. 0412: 27 04 beq $418
  913. 0414: BA A2 ora $A2
  914. 0416: 20 4D bra $465
  915.  
  916. 0418: B6 A2 lda $A2 ; if make bit is set goto 0x0475
  917. 041A: 2B 59 bmi $475
  918. 041C: 2F 20 bih $43E ; if (irq_high()) goto 0x043e
  919. 041E: B6 03 lda PORTD ; if control is only modifier pressed
  920. 0420: A4 BF anda #$BF
  921. 0422: A8 BF eora #$BF
  922. 0424: A1 08 cmpa #$08
  923. 0426: 26 09 bne $431
  924. 0428: 16 BC bset 3,$BC ; num_lock = true
  925. 042A: 3F BD clr $BD ; blink_count = 0
  926. 042C: 0E B8 0F brset 7,$B8,$43E ; if (caps_lock) goto 0x043e
  927. 042F: 20 44 bra $475 ; goto 0x0475
  928.  
  929. 0431: 07 BC 0A brclr 3,$BC,$43E ; if (num_lock)
  930. 0434: 9B sei ; disable interrupts
  931. 0435: 17 BC bclr 3,$BC ; num_lock = false
  932. 0437: 1F B8 bclr 7,$B8 ; caps_lock = false
  933. 0439: 1E 02 bset 7,PORTC ; turn off caps lock LED
  934. 043B: 9A cli
  935. 043C: 20 37 bra $475 ; goto 0x0475
  936.  
  937. 043E: B6 B8 lda $B8 ; if (queue_byte(*(unsigned char *)(0x78f + x) | (*(unsigned char *)0xb8 & 0x80)))
  938. 0440: A4 80 anda #$80
  939. 0442: DA 07 8F ora (x+$078F)
  940. 0445: CD 03 8D jsr $038D
  941. 0448: 27 0B beq $455
  942. 044A: A6 00 lda #$00 ; repeatedly reset reset NCOP while transmit queue is full
  943. 044C: C7 1F F0 sta $1FF0
  944. 044F: 02 B8 F8 brset 1,$B8,$44A
  945. 0452: CC 03 F8 jmp $03F8 ; loop to 0x03f8
  946.  
  947. 0455: 9B sei ; disable interrupts
  948. 0456: B6 B8 lda $B8 ; a = *(unsigned char *)0xb8 ^= 0x80
  949. 0458: A8 80 eora #$80
  950. 045A: B7 B8 sta $B8
  951. 045C: 9A cli ; enable interrupts
  952. 045D: A8 80 eora #$80 ; PORTC = (a ^ 0x80) | 0x7f
  953. 045F: AA 7F ora #$7F
  954. 0461: B7 02 sta PORTC
  955. 0463: 20 10 bra $475 ; goto 0x0475
  956.  
  957. 0465: CD 03 8D jsr $038D ; if (!queue_byte(code)) goto 0x0475
  958. 0468: 27 0B beq $475
  959. 046A: A6 00 lda #$00 ; repeatedly reset reset NCOP while transmit queue is full
  960. 046C: C7 1F F0 sta $1FF0
  961. 046F: 02 B8 F8 brset 1,$B8,$46A
  962. 0472: CC 03 F8 jmp $03F8 ; loop to 0x03f8
  963.  
  964. 0475: BE B7 ldx $B7 ; scan[16 + row] ^= ~insert_zero(column + 2)
  965. 0477: B6 B6 lda $B6
  966. 0479: AB 02 adda #$02
  967. 047B: CD 07 84 jsr $0784
  968. 047E: A8 FF eora #$FF
  969. 0480: E8 90 eora (x+$90)
  970. 0482: E7 90 sta (x+$90)
  971.  
  972. 0484: 3C B6 inc $B6 ; increment column and loop to 0x03bb if less than 6
  973. 0486: B6 B6 lda $B6
  974. 0488: A1 06 cmpa #$06
  975. 048A: 2A 03 bpl $48F
  976. 048C: CC 03 BB jmp $03BB
  977.  
  978. 048F: A6 00 lda #$00 ; reset NCOP
  979. 0491: C7 1F F0 sta $1FF0
  980. 0494: 3C B7 inc $B7 ; increment row and loop to 0x3b9 if less than 15
  981. 0496: B6 B7 lda $B7
  982. 0498: A1 0F cmpa #$0F
  983. 049A: 2A 03 bpl $49F
  984. 049C: CC 03 B9 jmp $03B9
  985.  
  986. 049F: 4F clra ; bit = 0
  987. 04A0: B7 B6 sta $B6
  988. 04A2: B6 B6 lda $B6 ; current = insert_zero(bit)
  989. 04A4: CD 07 84 jsr $0784
  990. 04A7: B7 A3 sta $A3
  991. 04A9: BA A0 ora $A0 ; state = modifiers | current
  992. 04AB: B7 A2 sta $A2
  993. 04AD: B6 A1 lda $A1 ; if ((sent_modifiers | current) != state) goto 0x04e4
  994. 04AF: BA A3 ora $A3
  995. 04B1: B1 A2 cmpa $A2
  996. 04B3: 27 2F beq $4E4
  997. 04B5: B6 A2 lda $A2 ; if (state ^ 0xff)
  998. 04B7: A8 FF eora #$FF
  999. 04B9: 27 04 beq $4BF
  1000. 04BB: 3F A2 clr $A2 ; state = 0x00
  1001. 04BD: 20 04 bra $4C3 ; else
  1002. 04BF: A6 80 lda #$80 ; state = 0x80
  1003. 04C1: B7 A2 sta $A2
  1004.  
  1005. 04C3: BE B6 ldx $B6 ; while (queue_byte(TRANS_MOD[bit] | state))
  1006. 04C5: D6 07 E9 lda (x+$07E9)
  1007. 04C8: BA A2 ora $A2
  1008. 04CA: CD 03 8D jsr $038D
  1009. 04CD: 27 0A beq $4D9
  1010. 04CF: A6 00 lda #$00 ; repeatedly reset reset NCOP while transmit queue is full
  1011. 04D1: C7 1F F0 sta $1FF0
  1012. 04D4: 02 B8 F8 brset 1,$B8,$4CF
  1013. 04D7: 20 EA bra $4C3
  1014.  
  1015. 04D9: B6 B6 lda $B6 ; sent_modifiers ^= insert_zero(bit) ^ 0xff
  1016. 04DB: CD 07 84 jsr $0784
  1017. 04DE: A8 FF eora #$FF
  1018. 04E0: B8 A1 eora $A1
  1019. 04E2: B7 A1 sta $A1
  1020. 04E4: 3C B6 inc $B6 ; increment bit and loop to 0x04a2 if less than 7
  1021. 04E6: B6 B6 lda $B6
  1022. 04E8: A1 07 cmpa #$07
  1023. 04EA: 2B B6 bmi $4A2
  1024.  
  1025. 04EC: 09 B8 13 brclr 4,$B8,$502 ; if (!first_scan) goto 0x0502
  1026. 04EF: 19 B8 bclr 4,$B8
  1027. 04F1: A6 FE lda #$FE ; while (queue_byte(CODE_UP_TERM))
  1028. 04F3: CD 03 8D jsr $038D
  1029. 04F6: 27 0A beq $502
  1030. 04F8: A6 00 lda #$00 ; repeatedly reset reset NCOP while transmit queue is full
  1031. 04FA: C7 1F F0 sta $1FF0
  1032. 04FD: 02 B8 F8 brset 1,$B8,$4F8
  1033. 0500: 20 EF bra $4F1
  1034.  
  1035. 0502: CC 02 D4 jmp $02D4
  1036.  
  1037. ; void timer_handler()
  1038. ; { // 0x0505
  1039. ; PORTB = 0xff; // ensure KDAT and KCLK are both high
  1040. ; if (PORTD & PD_MASK_RESET) // check for C-A-A reset combo
  1041. ; { // 0x050f
  1042. ; unsigned char const status = TSR;
  1043. ; if (status & 0xc0) // check for capture or compare event
  1044. ; { // 0x0515
  1045. ; if (!(status & 0x80)) // check absence of capture flag (must be compare)
  1046. ; { // 0x051a
  1047. ; if (status & TSR) { } // clear out the compare flag
  1048. ; if (status & OCRL) { }
  1049. ; if (expect_ack) // if we were sending data, this is a timeout
  1050. ; { // 0x0521
  1051. ; resync = true; // acknowledge timeout - start resynchronisation
  1052. ; PORTB = ~PORTB_MASK_KDAT; // clock out a logical 1 bit
  1053. ; DDRB = PORTB_MASK_KDAT | PORTB_MASK_KCLK;
  1054. ; bit_delay();
  1055. ; PORTB = ~(PORTB_MASK_KDAT | PORTB_MASK_KCLK);
  1056. ; bit_delay();
  1057. ; PORTB = ~PORTB_MASK_KDAT;
  1058. ; bit_delay();
  1059. ; DDRB = PORTB_MASK_KCLK;
  1060. ; unsigned char const high = TRH, low = TRL; // get current timer value
  1061. ; if (high & TSR) { } // clear timer/capture/compare status
  1062. ; if (high & ICRH) { }
  1063. ; if (high & ICRL) { }
  1064. ; if (high & TSR) { }
  1065. ; OCRH = high; // copy timer value to output compare register
  1066. ; OCRL = low;
  1067. ; }
  1068. ; }
  1069. ; else // handle capture event (KDAT edge detected)
  1070. ; { // 0x06bb
  1071. ; if (status & TSR) { } // clear out the compare flag
  1072. ; if (status & ICRL) { }
  1073. ; unsigned char code; // 0xa5
  1074. ; if (resync) // are we currently trying to resynchronise?
  1075. ; { // 0x06c2
  1076. ; code = queue_bytes[queue_head]; // check whether next queued code is start of stuck keys
  1077. ; if (CODE_UP_INIT == code)
  1078. ; { // 0x06ca
  1079. ; resync = false;
  1080. ; }
  1081. ; else
  1082. ; { // 0x06ce
  1083. ; resync = false; // if not, tell the host the last code was bad
  1084. ; retransmit = true;
  1085. ; code = CODE_PREV_BAD;
  1086. ; goto send_code;
  1087. ; }
  1088. ; }
  1089. ; if (retransmit) // if we have a code to retransmit, fetch it
  1090. ; { // 0x06d9
  1091. ; retransmit = false;
  1092. ; code = prev_code;
  1093. ; }
  1094. ; else
  1095. ; { // 0x06df
  1096. ; if (queue_drop) // notify host of buffer overflow if necessary
  1097. ; { // 0x06e2
  1098. ; queue_drop = false;
  1099. ; code = CODE_BUF_OFLOW;
  1100. ; }
  1101. ; else if ((queue_head == queue_tail) && !expect_ack)
  1102. ; { // 0x06f4
  1103. ; return; // nothing queued, return from interrupt
  1104. ; }
  1105. ; else
  1106. ; { // 0x06f5
  1107. ; queue_full = false; // pull a byte off the queue
  1108. ; code = queue_bytes[queue_head++];
  1109. ; if (queue_head >= sizeof(queue_bytes))
  1110. ; queue_head = 0;
  1111. ; }
  1112. ; prev_code = code; // store code in case retransmission is necessary
  1113. ; }
  1114. ; send_code: // 0x0709
  1115. ; code = ~code; // invert the code and clock it out
  1116. ; unsigned i = 8; // 0xa4
  1117. ; do
  1118. ; { // 0x0711
  1119. ; code = (code << 1) + ((code & 0x80) ? 1 : 0); // rotate value left (do first because MSB sent last)
  1120. ; unsigned char val = data | 0x7f; // clock out leftmost bit
  1121. ; PORTB = val = (val << 2) | PB_MASK_KCLK | ((val & 0x80) ? PB_MASK_KDAT : 0);
  1122. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK;
  1123. ; bit_delay();
  1124. ; PORTB = val &= ~PB_MASK_KCLK;
  1125. ; bit_delay();
  1126. ; PORTB = val |= PB_MASK_KCLK;
  1127. ; bit_delay();
  1128. ; }
  1129. ; while (--i);
  1130. ; PORTB = ~0x00; // release KDAT cleanly
  1131. ; bit_delay();
  1132. ; DDRB = PB_MASK_KCLK;
  1133. ;
  1134. ; // set acknowledge timeout
  1135. ; expect_ack = true; // expect a response
  1136. ; unsigned char const high = TRH; // get current timer value
  1137. ; unsigned char const low = TRL;
  1138. ; if (high & TSR) { } // clear timer and capture status
  1139. ; if (high & ICRH) { }
  1140. ; if (high & ICRL) { }
  1141. ; if (high & TSR) { }
  1142. ; OCRH = high; // copy timer value to output compare register
  1143. ; OCRL = low;
  1144. ; return; // return from interrupt
  1145. ; }
  1146. ; }
  1147. ;
  1148. ; // blink Caps Lock LED while numeric keypad is remapped over main keyboard (31/32 duty cycle)
  1149. ; if (!irq_high() && num_lock)
  1150. ; { // 0x055c
  1151. ; unsigned char tmp = blink_count + 1; // increment counter wrapping at 32
  1152. ; if (tmp >= 32) tmp = 0;
  1153. ; blink_count = tmp;
  1154. ; if (!tmp) PORTC |= PC_MASK_CAPS; // extinguish at 0
  1155. ; if (tmp == 1) PORTC &= ~PC_MASK_CAPS; // light at 1
  1156. ; }
  1157. ; }
  1158. ; else
  1159. ; { // 0x0571
  1160. ; disable_interrupts(); // C-A-A detected - request host reset
  1161. ; if (expect_ack) // ensure we're not waiting on an acknowledge
  1162. ; { // 0x5eb
  1163. ; unsigned char count = 9; // 0xa2
  1164. ; unsigned char const high = TRH; // get current timer value
  1165. ; unsigned char const low = TRL;
  1166. ; if (high & TSR) { } // clear timer and capture status
  1167. ; if (high & ICRH) { }
  1168. ; if (high & ICRL) { }
  1169. ; if (high & TSR) { }
  1170. ; OCRH = high; // copy timer value to output compare register
  1171. ; OCRL = low;
  1172. ; unsigned char status;
  1173. ; while (true)
  1174. ; { // 0x05ff
  1175. ; do // wait for input capture or output compare event
  1176. ; { // 0x05ff
  1177. ; PORTB = ~0x00; // drive KCLK high and release KDAT
  1178. ; DDRB = PB_MASK_KCLK;
  1179. ; COPR = 0x00;
  1180. ; }
  1181. ; while (!(status = TSR & 0xc0));
  1182. ; if (status & 0x80) // check for input capture event (acknowledge)
  1183. ; { // 0x0614
  1184. ; if (status & ICRL) { } // clear input capture flag
  1185. ; expect_ack = false; // no longer something to be acknowledged
  1186. ; break;
  1187. ; }
  1188. ; else
  1189. ; {
  1190. ; if (status & OCRL) { } // clear output compare flag
  1191. ; if (!--count) // decrement counter and give up waiting if it reaches zero
  1192. ; { // 0x061d
  1193. ; goto hard_reset;
  1194. ; }
  1195. ; else
  1196. ; { // 0x0621
  1197. ; PORTB = ~PB_MASK_KDAT; // clock out a logical 1 bit
  1198. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK;
  1199. ; bit_delay();
  1200. ; PORTB = ~(PB_MASK_KDAT | PB_MASK_KCLK);
  1201. ; bit_delay();
  1202. ; PORTB = ~PB_MASK_KDAT;
  1203. ; bit_delay();
  1204. ; status = PORTB = ~0x00;
  1205. ; bit_delay();
  1206. ; if (status & TSR)
  1207. ; }
  1208. ; }
  1209. ; }
  1210. ; }
  1211. ;
  1212. ; // send first reset warning and wait for standard acknowledge
  1213. ; send_reset_warning(); // send first high-level reset warning
  1214. ; unsigned char const high = TRH; // get current timer value
  1215. ; unsigned char const low = TRL;
  1216. ; if (high & TSR) { } // clear timer and capture status
  1217. ; if (high & ICRH) { }
  1218. ; if (high & ICRL) { }
  1219. ; if (high & TSR) { }
  1220. ; OCRH = high; // copy timer value to output compare register
  1221. ; OCRL = low;
  1222. ; DDRB = PB_MASK_KCLK; // release KDAT
  1223. ; unsigned wait = 2; // 0xa2
  1224. ; PORTB = ~0x00;
  1225. ; unsigned char status;
  1226. ; while (true) // wait for compare or capture event
  1227. ; { // 0x0594
  1228. ; do { COPR = 0x00; } while (!(status = TSR & 0xc0));
  1229. ; if (status & 0x80) break; // if it was compare (KDAT transition), go to next step
  1230. ; if (status & OCRL) { } // clear output compare flag
  1231. ; if (!--wait) goto hard_reset; // if we see two compare events in a row, give up waiting
  1232. ; }
  1233. ; if (status & ICRL) { } // clear input capture flag
  1234. ;
  1235. ; // send second reset warning and wait for KDAT to be asserted
  1236. ; send_reset_warning(); // send second high-level reset warning
  1237. ; wait = 2; // wait for up to two more compare events
  1238. ; while (true) // wait for compare event or acknowledge
  1239. ; { // 0x05b7
  1240. ; PORTB = ~0x00; // drive KCLK high
  1241. ; status = COPR = 0x00;
  1242. ; if (!(PORTB & PB_MASK_KDAT)) // break if we see KDAT pulled low (acknowledge)
  1243. ; {
  1244. ; break;
  1245. ; }
  1246. ; else if (TSR & 0x40) // check for compare event
  1247. ; {
  1248. ; if (status & OCRL) { } // clear output compare flag
  1249. ; if (!--wait) goto hard_reset; // if we see two compare events in a row, give up waiting
  1250. ; }
  1251. ; }
  1252. ;
  1253. ; // wait for the host to clean up before it releases KDAT
  1254. ; wait = 68;
  1255. ; while (true)
  1256. ; { // 0x05d3
  1257. ; PORTB = ~0x00;
  1258. ; status = COPR = 0x00;
  1259. ; if (!(PORTB & PB_MASK_KDAT)) // break if KDAT is released (ready for hard reset)
  1260. ; {
  1261. ; break;
  1262. ; }
  1263. ; else if (TSR & 0x40) // check for compare event
  1264. ; {
  1265. ; if (status & OCRL) { } // clear output compare flag
  1266. ; if (!--wait) break; // if we see 68 compare events in a row, give up waiting
  1267. ; }
  1268. ; }
  1269. ;
  1270. ; hard_reset: // 0x0682
  1271. ; do
  1272. ; {
  1273. ; disable_interrupts();
  1274. ; TCR = 0x00; // capture falling edge, drive TCMP low on compare
  1275. ; unsigned short cmp = TRL + 16; // trigger compare in 16 counts
  1276. ; cmp += (unsigned short)TRH << 8;
  1277. ; OCRH = (unsigned char)(cmp >> 8);
  1278. ; OCRL = (unsigned char)cmp;
  1279. ; wait = 10; // do delay loop ten times
  1280. ; do
  1281. ; { // 0x0698
  1282. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK; // drive KCLK low and KDAT high
  1283. ; PORTB = ~PB_MASK_KCLK;
  1284. ; COPR = 0x00;
  1285. ; unsigned i = 65; // spin for 100,427 machine cycles
  1286. ; do
  1287. ; { // 0x06a8
  1288. ; unsigned j = 0;
  1289. ; while (--j) { }
  1290. ; }
  1291. ; while (--i);
  1292. ; }
  1293. ; while (--wait);
  1294. ; }
  1295. ; while (!(PORTD & PD_MASK_RESET)); // check that C-A-A combo is still held
  1296. ; goto reset_vector;
  1297. ; }
  1298. ; }
  1299. 0505: A6 FF lda #$FF ; drive KB_CLOCK and KB_DATA high
  1300. 0507: B7 01 sta PORTB
  1301. 0509: B6 03 lda PORTD ; if Ctrl, left Amiga and right Amiga are down, goto 0x0571
  1302. 050B: A4 8C anda #$8C
  1303. 050D: 27 62 beq $571
  1304. 050F: B6 13 lda TSR ; if both OCF and ICF are low (TOF interrupt) goto 0x0557
  1305. 0511: A4 C0 anda #$C0
  1306. 0513: 27 42 beq $557
  1307. 0515: 2A 03 bpl $51A ; if ICF is high goto 0x06bb
  1308. 0517: CC 06 BB jmp $06BB
  1309. 051A: B5 13 bita TSR ; read TSR followed by OCRL to clear OCF
  1310. 051C: B5 17 bita OCRL
  1311. 051E: 0B B8 36 brclr 5,$B8,$557 ; if bit 5 of 0x00b8 is clear, goto 0x0557
  1312. 0521: 16 B8 bset 3,$B8 ; set bit 3 of 0x00b8
  1313. 0523: A6 FE lda #$FE ; pull KB_CLOCK high and KB_DATA low, make KB_DATA and KB_CLOCK outputs
  1314. 0525: B7 01 sta PORTB
  1315. 0527: A6 03 lda #$03
  1316. 0529: B7 05 sta DDRB
  1317. 052B: CD 07 7D jsr $077D ; bit_delay()
  1318. 052E: A6 FC lda #$FC ; pull KB_CLOCK and KB_DATA low
  1319. 0530: B7 01 sta PORTB
  1320. 0532: CD 07 7D jsr $077D ; bit_delay()
  1321. 0535: A6 FE lda #$FE ; pull KB_CLOCK high and KB_DATA low
  1322. 0537: B7 01 sta PORTB
  1323. 0539: CD 07 7D jsr $077D ; bit_delay()
  1324. 053C: A6 FF lda #$FF ; pull KB_CLOCK and KB_DATA low
  1325. 053E: B7 01 sta PORTB
  1326. 0540: CD 07 7D jsr $077D ; bit_delay()
  1327. 0543: A6 02 lda #$02 ; make KB_CLOCK an output and KB_DATA an input
  1328. 0545: B7 05 sta DDRB
  1329. 0547: B6 18 lda TRH ; get current timer value in a:x
  1330. 0549: BE 19 ldx TRL
  1331. 054B: B5 13 bita TSR ; read TSR followed by ICRH and ICRL to ensure ICF is cleared
  1332. 054D: B5 14 bita ICRH
  1333. 054F: B5 15 bita ICRL
  1334. 0551: B5 13 bita TSR ; read TSR, then store timer value in OCR (clear OCF, maximise time to output compare)
  1335. 0553: B7 16 sta OCRH
  1336. 0555: BF 17 stx OCRL
  1337. 0557: 2F 17 bih $570 ; if /INT is high or num_lock flag is clear, goto 0x0570 (return from interrupt)
  1338. 0559: 07 BC 14 brclr 3,$BC,$570
  1339. 055C: B6 BD lda $BD ; increment blink_count, wrapping at 0x20
  1340. 055E: 4C inca
  1341. 055F: A1 20 cmpa #$20
  1342. 0561: 25 01 bcs $564
  1343. 0563: 4F clra
  1344. 0564: B7 BD sta $BD
  1345. 0566: 26 02 bne $56A ; if it wrapped around, drive caps lock LED high
  1346. 0568: 1E 02 bset 7,PORTC
  1347. 056A: A1 01 cmpa #$01 ; if value was 0x01, drive caps lock LED low
  1348. 056C: 26 02 bne $570
  1349. 056E: 1F 02 bclr 7,PORTC
  1350.  
  1351. ; void irq_handler() { }
  1352. 0570: 80 rti
  1353.  
  1354. 0571: 9B sei ; disable interrupts
  1355. 0572: B6 B8 lda $B8 ; if (expect_ack) goto 0x05eb
  1356. 0574: A4 20 anda #$20
  1357. 0576: 27 03 beq $57B
  1358. 0578: CC 05 EB jmp $05EB
  1359. 057B: CD 06 47 jsr $0647 ; send_reset_warning();
  1360. 057E: B6 18 lda TRH ; a:x = TR
  1361. 0580: BE 19 ldx TRL
  1362. 0582: B5 13 bita TSR ; read TSR followed by ICRH and ICRL to clear ICF
  1363. 0584: B5 14 bita ICRH
  1364. 0586: B5 15 bita ICRL
  1365. 0588: B5 13 bita TSR ; read TSR, then store timer value in OCR (clear OCF, maximise time to output compare)
  1366. 058A: B7 16 sta OCRH
  1367. 058C: BF 17 stx OCRL
  1368. 058E: A6 02 lda #$02 ; KB_CLOCK output
  1369. 0590: B7 05 sta DDRB
  1370. 0592: B7 A2 sta $A2 ; set wait count at 0xa2 to 2
  1371. 0594: A6 FF lda #$FF ; drive KB_CLOCK high
  1372. 0596: B7 01 sta PORTB
  1373. 0598: A6 00 lda #$00 ; reset NCOP
  1374. 059A: C7 1F F0 sta $1FF0
  1375. 059D: B6 13 lda TSR ; wait for input capture/output compare
  1376. 059F: A4 C0 anda #$C0
  1377. 05A1: 27 F1 beq $594
  1378. 05A3: 2B 09 bmi $5AE ; if it was input capture, goto 0x05ae
  1379. 05A5: B5 17 bita OCRL
  1380. 05A7: 3A A2 dec $A2 ; decrement wait count at 0xa2 loop to 0x0594 if not zero
  1381. 05A9: 26 E9 bne $594
  1382. 05AB: CC 06 82 jmp $0682 ; goto 0x0682
  1383.  
  1384. 05AE: B5 15 bita ICRL ; read ICRL to reset input capture flag
  1385. 05B0: CD 06 47 jsr $0647 ; send_reset_warning()
  1386. 05B3: A6 02 lda #$02 ; set wait count at 0xa2 to 2
  1387. 05B5: B7 A2 sta $A2
  1388. 05B7: A6 FF lda #$FF ; drive KB_CLOCK high
  1389. 05B9: B7 01 sta PORTB
  1390. 05BB: A6 00 lda #$00 ; reset NCOP
  1391. 05BD: C7 1F F0 sta $1FF0
  1392. 05C0: 01 01 0C brclr 0,PORTB,$5CF ; if KB_DATA is low (acknowledge), goto 0x05cf
  1393. 05C3: 0D 13 F1 brclr 6,TSR,$5B7 ; if no compare event has occurred, loop to 0x05b7
  1394. 05C6: B5 17 bita OCRL ; read OCRL to clear output compare flag
  1395. 05C8: 3A A2 dec $A2 ; decrement wait count at 0xa2 loop to 0x05b7 if not zero
  1396. 05CA: 26 EB bne $5B7
  1397. 05CC: CC 06 82 jmp $0682 ; goto 0x0682
  1398.  
  1399. 05CF: A6 44 lda #$44 ; wait = 68
  1400. 05D1: B7 A2 sta $A2
  1401. 05D3: A6 FF lda #$FF ; drive KB_CLOCK high
  1402. 05D5: B7 01 sta PORTB
  1403. 05D7: A6 00 lda #$00 ; reset NCOP
  1404. 05D9: C7 1F F0 sta $1FF0
  1405. 05DC: 00 01 09 brset 0,PORTB,$5E8 ; if KB_DATA is high, goto 0x05e8 (will jump to 0x0682)
  1406. 05DF: 0D 13 F1 brclr 6,TSR,$5D3 ; if no compare event has occurred, loop to 0x05d3
  1407. 05E2: B5 17 bita OCRL ; read OCRL to clear output compare flag
  1408. 05E4: 3A A2 dec $A2
  1409. 05E6: 26 EB bne $5D3
  1410. 05E8: CC 06 82 jmp $0682
  1411.  
  1412. 05EB: A6 09 lda #$09 ; count = 9;
  1413. 05ED: B7 A2 sta $A2
  1414. 05EF: B6 18 lda TRH ; a:x = TR
  1415. 05F1: BE 19 ldx TRL
  1416. 05F3: B5 13 bita TSR ; read TSR followed by ICRH and ICRL to clear ICF
  1417. 05F5: B5 14 bita ICRH
  1418. 05F7: B5 15 bita ICRL
  1419. 05F9: B5 13 bita TSR ; read TSR, then store timer value in OCR (clear OCF, maximise time to output compare)
  1420. 05FB: B7 16 sta OCRH
  1421. 05FD: BF 17 stx OCRL
  1422. 05FF: A6 FF lda #$FF ; drive KB_CLOCK high and release KB_DATA
  1423. 0601: B7 01 sta PORTB
  1424. 0603: A6 02 lda #$02
  1425. 0605: B7 05 sta DDRB
  1426. 0607: A6 00 lda #$00 ; reset NCOP
  1427. 0609: C7 1F F0 sta $1FF0
  1428. 060C: B6 13 lda TSR ; loop to 0x05ff if no input capture/output compare event seen
  1429. 060E: A4 C0 anda #$C0
  1430. 0610: 27 ED beq $5FF
  1431.  
  1432. 0612: 2A 07 bpl $61B ; if input capture event was seen
  1433. 0614: B5 15 bita ICRL ; read ICRL to clear input capture flag
  1434. 0616: 1B B8 bclr 5,$B8 ; expect_ack = false
  1435. 0618: CC 05 7B jmp $057B ; goto 0x057b
  1436.  
  1437. 061B: B5 17 bita OCRL ; read OCRL to clear output compare flag
  1438. 061D: 3A A2 dec $A2 ; if (!--count) goto 0x0682
  1439. 061F: 27 61 beq $682
  1440. 0621: A6 FE lda #$FE ; drive KB_DATA low
  1441. 0623: B7 01 sta PORTB
  1442. 0625: A6 03 lda #$03 ; KB_DATA output, KB_CLOCK output
  1443. 0627: B7 05 sta DDRB
  1444. 0629: CD 07 7D jsr $077D ; bit_delay()
  1445. 062C: A6 FC lda #$FC ; drive KB_DATA and KB_CLOCK low
  1446. 062E: B7 01 sta PORTB
  1447. 0630: CD 07 7D jsr $077D ; bit_delay()
  1448. 0633: A6 FE lda #$FE ; release KB_CLOCK
  1449. 0635: B7 01 sta PORTB
  1450. 0637: CD 07 7D jsr $077D ; bit_delay()
  1451. 063A: A6 FF lda #$FF ; release KB_DATA
  1452. 063C: B7 01 sta PORTB
  1453. 063E: CD 07 7D jsr $077D ; bit_delay()
  1454. 0641: B5 13 bita TSR ; read TSR followed by ICRL to clear input capture flag
  1455. 0643: B5 15 bita ICRL
  1456. 0645: 20 B8 bra $5FF ; loop to 0x05ff
  1457.  
  1458.  
  1459. ; // send reset warning code to host
  1460. ; void send_reset_warning()
  1461. ; {
  1462. ; unsigned char code = ~CODE_RST_WARN; // 0xa5
  1463. ; unsigned i = 8; // 0xa4
  1464. ; do
  1465. ; { // 0x064f
  1466. ; code = (code << 1) + ((code & 0x80) ? 1 : 0); // rotate value left (do first because MSB sent last)
  1467. ; unsigned char val = data | 0x7f; // clock out leftmost bit
  1468. ; PORTB = val = (val << 2) | PB_MASK_KCLK | ((val & 0x80) ? PB_MASK_KDAT : 0);
  1469. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK;
  1470. ; bit_delay();
  1471. ; PORTB = val &= ~PB_MASK_KCLK;
  1472. ; bit_delay();
  1473. ; PORTB = val |= PB_MASK_KCLK;
  1474. ; bit_delay();
  1475. ; }
  1476. ; while (--i);
  1477. ; PORTB = ~0x00; // release KDAT cleanly
  1478. ; bit_delay();
  1479. ; DDRB = PB_MASK_KCLK;
  1480. ; }
  1481. 0647: A6 87 lda #$87 ; code = ~CODE_RST_WARN
  1482. 0649: B7 A5 sta $A5
  1483. 064B: A6 08 lda #$08 ; set bit counter at 0xa4 to 8
  1484. 064D: B7 A4 sta $A4
  1485. 064F: B6 A5 lda $A5 ; rotate code left by one bit
  1486. 0651: 48 asla
  1487. 0652: A9 00 adca #$00
  1488. 0654: B7 A5 sta $A5
  1489. 0656: AA 7F ora #$7F ; PORTB = 0xfe | (data >> 7)
  1490. 0658: 99 sec
  1491. 0659: 49 rola
  1492. 065A: 49 rola
  1493. 065B: B7 01 sta PORTB
  1494. 065D: AE 03 ldx #$03 ; KB_DATA output, KB_CLOCK output
  1495. 065F: BF 05 stx DDRB
  1496. 0661: CD 07 7D jsr $077D ; bit_delay()
  1497. 0664: A4 FD anda #$FD ; pull KB_CLOCK low
  1498. 0666: B7 01 sta PORTB
  1499. 0668: CD 07 7D jsr $077D ; bit_delay()
  1500. 066B: AA 02 ora #$02 ; pull KB_CLOCK high
  1501. 066D: B7 01 sta PORTB
  1502. 066F: CD 07 7D jsr $077D ; bit_delay()
  1503. 0672: 3A A4 dec $A4 ; decrement bit counter at 0xa4 and loop to 0x064f if not zero
  1504. 0674: 26 D9 bne $64F
  1505. 0676: A6 FF lda #$FF ; pull KB_CLOCK and KB_DATA high
  1506. 0678: B7 01 sta PORTB
  1507. 067A: CD 07 7D jsr $077D ; bit_delay()
  1508. 067D: A6 02 lda #$02 ; release KB_DATA
  1509. 067F: B7 05 sta DDRB
  1510. 0681: 81 rts ; return
  1511.  
  1512.  
  1513. 0682: 9B sei ; disable interrupts
  1514. 0683: A6 00 lda #$00
  1515. 0685: B7 12 sta TCR ; disable timer/capture/compare interrupts, capture falling edge, drive TCMP low on compare
  1516. 0687: B6 19 lda TRL
  1517. 0689: AB 10 adda #$10
  1518. 068B: 97 tax ; a:x = TR + 16
  1519. 068C: B6 18 lda TRH
  1520. 068E: A9 00 adca #$00
  1521. 0690: B7 16 sta OCRH ; OCRH = a
  1522. 0692: BF 17 stx OCRL ; OCRL = x
  1523. 0694: A6 0A lda #$0A ; wait = 10
  1524. 0696: B7 A2 sta $A2
  1525. 0698: A6 03 lda #$03 ; KB_DATA output, KB_CLOCK output
  1526. 069A: B7 05 sta DDRB
  1527. 069C: A6 FD lda #$FD ; drive KB_CLOCK low
  1528. 069E: B7 01 sta PORTB
  1529. 06A0: A6 00 lda #$00 ; reset NCOP
  1530. 06A2: C7 1F F0 sta $1FF0
  1531. 06A5: A6 41 lda #$41 ; load counter with 65
  1532. 06A7: 5F clrx ; spin 256 iterations decrementing x
  1533. 06A8: 5A decx
  1534. 06A9: 26 FD bne $6A8 ; decrement counter and loop to 0x06a8 if not zero
  1535. 06AB: 4A deca
  1536. 06AC: 26 F9 bne $6A7
  1537. 06AE: 3A A2 dec $A2 ; decrement wait and loop to 0x0698 if not zero
  1538. 06B0: 26 E6 bne $698
  1539. 06B2: B6 03 lda PORTD ; if C-A-A is still held down, loop to 0x0682
  1540. 06B4: A4 8C anda #$8C
  1541. 06B6: 27 CA beq $682
  1542. 06B8: CC 01 02 jmp $0102
  1543.  
  1544. 06BB: B5 13 bita TSR ; read TSR followed by ICRL to clear ICF
  1545. 06BD: B5 15 bita ICRL
  1546. 06BF: 07 B8 14 brclr 3,$B8,$6D6 ; if (resync)
  1547. 06C2: BE B5 ldx $B5 ; if ((a = queue_bytes[queue_head]) == 0xfd)
  1548. 06C4: E6 A6 lda (x+$A6)
  1549. 06C6: A1 FD cmpa #$FD
  1550. 06C8: 26 04 bne $6CE
  1551. 06CA: 17 B8 bclr 3,$B8 ; resync = false
  1552. 06CC: 20 08 bra $6D6 ; else
  1553. 06CE: 17 B8 bclr 3,$B8 ; resync = false
  1554. 06D0: 1C B8 bset 6,$B8 ; retransmit = true
  1555. 06D2: A6 F9 lda #$F9 ; a = 0xf9
  1556. 06D4: 20 33 bra $709 ; goto 0x0709
  1557.  
  1558. 06D6: 0D B8 06 brclr 6,$B8,$6DF ; if (retransmit)
  1559. 06D9: 1D B8 bclr 6,$B8 ; retransmit = false
  1560. 06DB: B6 BA lda $BA ; a = prev_code
  1561. 06DD: 20 2A bra $709 ; goto 0x0709
  1562.  
  1563. 06DF: 05 B8 06 brclr 2,$B8,$6E8 ; if (queue_drop)
  1564. 06E2: 15 B8 bclr 2,$B8 ; queue_drop = false
  1565. 06E4: A6 FA lda #$FA ; a = 0xfa
  1566. 06E6: 20 1F bra $707 ; else
  1567. 06E8: B6 B5 lda $B5 ; a = x = queue_head
  1568. 06EA: 97 tax
  1569. 06EB: B1 B4 cmpa $B4 ; if ((a == queue_tail) && !expect_ack) return from interrupt
  1570. 06ED: 26 06 bne $6F5
  1571. 06EF: 02 B8 03 brset 1,$B8,$6F5
  1572. 06F2: 1B B8 bclr 5,$B8
  1573. 06F4: 80 rti
  1574.  
  1575. 06F5: 13 B8 bclr 1,$B8 ; queue_full = false
  1576. 06F7: E6 A6 lda (x+$A6) ; *(unsigned char *)0xa5 = queue_bytes[queue_head++]
  1577. 06F9: B7 A5 sta $A5
  1578. 06FB: 3C B5 inc $B5
  1579. 06FD: B6 B5 lda $B5 ; if (queue_head >= sizeof(queue_bytes))
  1580. 06FF: A1 0E cmpa #$0E
  1581. 0701: 2B 02 bmi $705
  1582. 0703: 3F B5 clr $B5 ; queue_head = 0
  1583. 0705: B6 A5 lda $A5 ; a = *(unsigned char *)0xa5
  1584.  
  1585. 0707: B7 BA sta $BA ; prev_code = a
  1586.  
  1587. 0709: A8 FF eora #$FF ; code = ~a
  1588. 070B: B7 A5 sta $A5
  1589. 070D: A6 08 lda #$08 ; set bit counter at 0xa4 to 8
  1590. 070F: B7 A4 sta $A4
  1591. 0711: B6 A5 lda $A5 ; rotate code left by one bit
  1592. 0713: 48 asla
  1593. 0714: A9 00 adca #$00
  1594. 0716: B7 A5 sta $A5
  1595. 0718: AA 7F ora #$7F ; PORTB = 0xfe | (data >> 7)
  1596. 071A: 99 sec
  1597. 071B: 49 rola
  1598. 071C: 49 rola
  1599. 071D: B7 01 sta PORTB
  1600. 071F: AE 03 ldx #$03 ; KB_DATA output, KB_CLOCK output
  1601. 0721: BF 05 stx DDRB
  1602. 0723: CD 07 7D jsr $077D ; bit_delay()
  1603. 0726: A4 FD anda #$FD ; pull KB_CLOCK low
  1604. 0728: B7 01 sta PORTB
  1605. 072A: CD 07 7D jsr $077D ; bit_delay()
  1606. 072D: AA 02 ora #$02 ; pull KB_CLOCK high
  1607. 072F: B7 01 sta PORTB
  1608. 0731: CD 07 7D jsr $077D ; bit_delay()
  1609. 0734: 3A A4 dec $A4 ; decrement bit counter at 0xa4 and loop to 0x0711 if not zero
  1610. 0736: 26 D9 bne $711
  1611. 0738: A6 FF lda #$FF ; pull KB_CLOCK and KB_DATA high
  1612. 073A: B7 01 sta PORTB
  1613. 073C: CD 07 7D jsr $077D ; bit_delay()
  1614. 073F: A6 02 lda #$02 ; release KB_DATA
  1615. 0741: B7 05 sta DDRB
  1616. 0743: 1A B8 bset 5,$B8
  1617. 0745: B6 18 lda TRH ; a:x = TR
  1618. 0747: BE 19 ldx TRL
  1619. 0749: B5 13 bita TSR ; clear input capture flag
  1620. 074B: B5 14 bita ICRH
  1621. 074D: B5 15 bita ICRL
  1622. 074F: B5 13 bita TSR
  1623. 0751: B7 16 sta OCRH ; OCRH = a
  1624. 0753: BF 17 stx OCRL ; OCRL = x
  1625. 0755: 80 rti ; return from interrupt
  1626.  
  1627. ; // pulse KDAT low if we don't already have data queued to force a capture interrupt
  1628. ; void force_capture_interrupt()
  1629. ; {
  1630. ; if (!expect_ack)
  1631. ; { // 0x075d
  1632. ; PORTB = ~0x00; // drive KCLK and KDAT high
  1633. ; DDRB = PB_MASK_KDAT | PB_MASK_KCLK;
  1634. ; bit_delay();
  1635. ; PORTB = ~PB_MASK_KDAT; // pulse KDAT low
  1636. ; bit_delay();
  1637. ; PORTB = ~0x00;
  1638. ; bit_delay();
  1639. ; DDRB = PB_MASK_KCLK; // release KDAT
  1640. ; expect_ack = true;
  1641. ; }
  1642. ; }
  1643. 0756: B6 B8 lda $B8
  1644. 0758: A4 20 anda #$20
  1645. 075A: 27 01 beq $75D
  1646. 075C: 81 rts
  1647. 075D: A6 FF lda #$FF
  1648. 075F: B7 01 sta PORTB
  1649. 0761: A6 03 lda #$03
  1650. 0763: B7 05 sta DDRB
  1651. 0765: CD 07 7D jsr $077D
  1652. 0768: A6 FE lda #$FE
  1653. 076A: B7 01 sta PORTB
  1654. 076C: CD 07 7D jsr $077D
  1655. 076F: A6 FF lda #$FF
  1656. 0771: B7 01 sta PORTB
  1657. 0773: CD 07 7D jsr $077D
  1658. 0776: A6 02 lda #$02
  1659. 0778: B7 05 sta DDRB
  1660. 077A: 1A B8 bset 5,$B8
  1661. 077C: 81 rts
  1662.  
  1663. ; // 18 machine cycle delay plus JSR overhead
  1664. ; void bit_delay()
  1665. ; {
  1666. ; nop();
  1667. ; nop();
  1668. ; nop();
  1669. ; nop();
  1670. ; nop();
  1671. ; nop();
  1672. ; }
  1673. 077D: 9D nop
  1674. 077E: 9D nop
  1675. 077F: 9D nop
  1676. 0780: 9D nop
  1677. 0781: 9D nop
  1678. 0782: 9D nop
  1679. 0783: 81 rts
  1680.  
  1681. ; // calculates (unsigned char)~(1 << (val % 9))
  1682. ; unsigned char insert_zero(unsigned char val)
  1683. ; {
  1684. ; unsigned char result = 0xff;
  1685. ; bool msb = false;
  1686. ; do
  1687. ; {
  1688. ; unsigned char const tmp = msb ? 0x01 : 0x00;
  1689. ; msb = result & 0x80;
  1690. ; result = (result << 1) | tmp;
  1691. ; }
  1692. ; while (!(--val & 0x80));
  1693. ; return result;
  1694. ; }
  1695. 0784: B7 A2 sta $A2
  1696. 0786: A6 FF lda #$FF
  1697. 0788: 98 clc
  1698. 0789: 49 rola
  1699. 078A: 3A A2 dec $A2
  1700. 078C: 2A FB bpl $789
  1701. 078E: 81 rts
  1702.  
  1703.  
  1704. ; unsigned char const TRANS_STD[90] = {
  1705. ; 0x45, 0x00, 0x42, 0x62, 0x30, 0x5d,
  1706. ; 0x5a, 0x01, 0x10, 0x20, 0x31, 0x5e,
  1707. ; 0x50, 0x02, 0x11, 0x21, 0x32, 0x3f,
  1708. ; 0x51, 0x03, 0x12, 0x22, 0x33, 0x2f,
  1709. ; 0x52, 0x04, 0x13, 0x23, 0x34, 0x1f,
  1710. ; 0x53, 0x05, 0x14, 0x24, 0x35, 0x3c,
  1711. ; 0x54, 0x06, 0x15, 0x25, 0x36, 0x3e,
  1712. ; 0x5b, 0x07, 0x16, 0x26, 0x37, 0x2e,
  1713. ; 0x55, 0x08, 0x17, 0x27, 0x38, 0x1e,
  1714. ; 0x5c, 0x09, 0x18, 0x28, 0x39, 0x43,
  1715. ; 0x56, 0x0a, 0x19, 0x29, 0x3a, 0x3d,
  1716. ; 0x57, 0x0b, 0x1a, 0x2a, 0x3b, 0x2d,
  1717. ; 0x58, 0x0c, 0x1b, 0x2b, 0x40, 0x1d,
  1718. ; 0x59, 0x0d, 0x44, 0x46, 0x41, 0x0f,
  1719. ; 0x5f, 0x4c, 0x4f, 0x4e, 0x4d, 0x4a };
  1720. 078F: 45 00 42 db $45,$00,$42
  1721. 0792: 62 30 5D db $62,$30,$5D
  1722. 0795: 5A 01 10 db $5A,$01,$10
  1723. 0798: 20 31 5E db $20,$31,$5E
  1724. 079B: 50 02 11 db $50,$02,$11
  1725. 079E: 21 32 3F db $21,$32,$3F
  1726. 07A1: 51 03 12 db $51,$03,$12
  1727. 07A4: 22 33 2F db $22,$33,$2F
  1728. 07A7: 52 04 13 db $52,$04,$13
  1729. 07AA: 23 34 1F db $23,$34,$1f
  1730. 07AD: 53 05 14 db $53,$05,$14
  1731. 07B0: 24 35 3C db $24,$35,$3C
  1732. 07B3: 54 06 15 db $54,$06,$15
  1733. 07B6: 25 36 3E db $25,$36,$3E
  1734. 07B9: 5B 07 16 db $5B,$07,$16
  1735. 07BC: 26 37 2E db $26,$37,$2E
  1736. 07BF: 55 08 17 db $55,$08,$17
  1737. 07C2: 27 38 1E db $27,$38,$1E
  1738. 07C5: 5C 09 18 db $5C,$09,$18
  1739. 07C8: 28 39 43 db $28,$39,$43
  1740. 07CB: 56 0A 19 db $56,$0A,$19
  1741. 07CE: 29 3A 3D db $29,$3A,$3D
  1742. 07D1: 57 0B 1A db $57,$0B,$1A
  1743. 07D4: 2A 3B 2D db $2A,$3B,$2D
  1744. 07D7: 58 0C 1B db $58,$0C,$1B
  1745. 07DA: 2B 40 1D db $2B,$40,$1D
  1746. 07DD: 59 0D 44 db $59,$0D,$44
  1747. 07E0: 46 41 0F db $46,$41,$0F
  1748. 07E3: 5F 4C 4F db $5F,$4C,$4F
  1749. 07E6: 4E 4D 4A db $4E,$4D,$4A
  1750.  
  1751.  
  1752. ; unsigned char const TRANS_MOD[7] = { 0x61, 0x65, 0x67, 0x63, 0x60, 0x64, 0x66 };
  1753. 07E9: 61 65 67 db $61,$65,$67
  1754. 07EC: 63 60 64 db $63,$60,$64
  1755. 07EF: 66 db $66
  1756.  
  1757.  
  1758. ; unsigned char const TRANS_NUM[90] = {
  1759. ; 0x45, 0x00, 0x42, 0x62, 0x30, 0x5d,
  1760. ; 0x5a, 0x01, 0x10, 0x20, 0x31, 0x5e,
  1761. ; 0x50, 0x02, 0x11, 0x21, 0x32, 0x3f,
  1762. ; 0x51, 0x03, 0x12, 0x22, 0x33, 0x2f,
  1763. ; 0x52, 0x5a, 0x13, 0x23, 0x34, 0x1f,
  1764. ; 0x53, 0x5b, 0x14, 0x24, 0x35, 0x3c,
  1765. ; 0x54, 0x5c, 0x15, 0x25, 0x36, 0x3e,
  1766. ; 0x5b, 0x3d, 0x2d, 0x1d, 0x0f, 0x2e,
  1767. ; 0x55, 0x3e, 0x2e, 0x1e, 0x38, 0x1e,
  1768. ; 0x5c, 0x3f, 0x2f, 0x1f, 0x3c, 0x43,
  1769. ; 0x56, 0x5d, 0x4a, 0x5e, 0x3a, 0x3d,
  1770. ; 0x57, 0x0b, 0x1a, 0x2a, 0x3b, 0x2d,
  1771. ; 0x58, 0x0c, 0x1b, 0x2b, 0x40, 0x1d,
  1772. ; 0x59, 0x0d, 0x43, 0x46, 0x41, 0x0f,
  1773. ; 0x5f, 0x4c, 0x4f, 0x4e, 0x4d, 0x4a };
  1774. 07F0: 45 00 42 db $45,$00,$42
  1775. 07F3: 62 30 5D db $62,$30,$5D
  1776. 07F6: 5A 01 10 db $5A,$01,$10
  1777. 07F9: 20 31 5E db $20,$31,$5E
  1778. 07FC: 50 02 11 db $50,$02,$11
  1779. 07FF: 21 32 3F db $21,$32,$3F
  1780. 0802: 51 03 12 db $51,$03,$12
  1781. 0805: 22 33 2F db $22,$33,$2F
  1782. 0808: 52 5A 13 db $52,$5A,$13
  1783. 080B: 23 34 1F db $23,$34,$1F
  1784. 080E: 53 5B 14 db $53,$5B,$14
  1785. 0811: 24 35 3C db $24,$35,$3C
  1786. 0814: 54 5C 15 db $54,$5C,$15
  1787. 0817: 25 36 3E db $25,$36,$3E
  1788. 081A: 5B 3D 2D db $5B,$3D,$2D
  1789. 081D: 1D 0F 2E db $1D,$0F,$2E
  1790. 0820: 55 3E 2E db $55,$3E,$2E
  1791. 0823: 1E 38 1E db $1E,$38,$1E
  1792. 0826: 5C 3F 2F db $5C,$3F,$2F
  1793. 0829: 1F 3C 43 db $1F,$3C,$43
  1794. 082C: 56 5D 4A db $56,$5D,$4A
  1795. 082F: 5E 3A 3D db $5E,$3A,$3D
  1796. 0832: 57 0B 1A db $57,$0B,$1A
  1797. 0835: 2A 3B 2D db $2A,$3B,$2D
  1798. 0838: 58 0C 1B db $58,$0C,$1B
  1799. 083B: 2B 40 1D db $2B,$40,$1D
  1800. 083E: 59 0D 43 db $59,$0D,$43
  1801. 0841: 46 41 0F db $46,$41,$0F
  1802. 0844: 5F 4C 4F db $5F,$4C,$4F
  1803. 0847: 4E 4D 4A db $4E,$4D 4A
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement