1503033 DISASSEMBLY =================== A. Tarpai 2010 October Comments and corrections are welcome to tarpai76 at gmail! Feel free This file has been downloaded from http://www.halicery.com/8042/8042_1503033.TXT For more detailed info on the 8042 please look at http://www.halicery.com/8042/8042_INTERN.TXT. TOC Intro 8042 ROM disassembly 8042 RAM map What is this? ============= Commented disassembly of the file 1503033.bin, a 2KB IBM ROM dump of an AT 8042 keyboard controller (KBC) from 1983. The rom is from the MESS project, I wrote a simple 41/42 disassembler and did my best to comment this wonderful vintage piece. Why? ==== It is for historical interest.. and fun. An attept to understand how one of the 8042 KBC internally worked. I love keyboard hardware programming and it gave me a lot of headache to understand why are things like they are, and I was hoping to find some answers in this quite old and outdated code. Reading and commenting the code reminded me of the good ol' 8-bit days anyway and that I'm still alive.. Conclusions =========== Not much actually..:) The 8042 programming interface is well documented by IBM and the firmware really does what it said to do. No hidden code or undocumented features. Still, it's very interesting - IMHO! Syntax ====== Everything is hexa, $ is the sign. Eg. #$CF is an immediate hexa 8-bit value. The 2K Program memory (ROM) is separate from the small RAM (128 bytes). The RAM is also the place for 8 general purpose registers, R0-R7. @R0 and @R1 can be used to indirectly address the other RAM locations. There is an Accumulator (A). @A addresses locations in program ROM. P1 and P2 are the two 8-bit I/O ports. The two test input pins (T0 and T1) are directly tested by the conditional branch instructions, eg. JNT0 $0310 jumps when T0=0. This firmware relies on the following ===================================== +---------------+ | P27| -> DATA | 8042 P26| -> _CLK (inverted) | ==== | | P17| <- KEYBOARD SWITCH (0=INHIBITED) | | | T0| <- CLK | T1| <- DATA (NB: P26 connects to an INVERTER and then drives the keyboard CLOCK line!) STATUS bits =========== STATUS is a physical register. Host reads it on 0x64: sw-bits hw-bits +---------------- ----------------+ <-- |PER|RTO|TTO|INH| |A0 | |IBF|OBF| +---------------- ----------------+ Command Byte (CMD) bits in this 8042 firmware ============================================= CMD is a byte in the 8042's RAM. Host can read it by writing 0x20 (or 0) to 0x64, then reading 0x60: +--------------------------------+ <-- | - |XLAT|XT |_EN|OVR| F0|IBF|OBF| +--------------------------------+ TODO ==== - There are some white spots, like the ROM checksum, and many small details to be cleared up. - Find a PS/2-style keyboard/mouse controller ROM dump(!) - Find a keyboard ROM dump (the 'other side') *** Opening 1503033.bin ; START VECTORS 0000: 04 45 JMP $0045 ; -> Reset 0002: 00 NOP 0003: 04 3A JMP $003A ; -> IBF intr 0005: 00 NOP 0006: 00 NOP 0007: 04 21 JMP $0021 ; -> Timer intr ; Timer intr ; ========== ; This is something special: used as a general timeout in subroutines. ; It manipulates the Stack Pointer and pretends the ; called function returned with value 2 in the Accumulator. ; (And disables kbd on the wire). Brilliant. 0021: 65 STOP TCNT 0022: C7 MOV A,PSW 0023: 53 07 ANL A,#$07 0025: 07 DEC A ; dec SP 0026: A8 MOV R0,A 0027: C7 MOV A,PSW 0028: 53 F8 ANL A,#$F8 002A: 48 ORL A,R0 002B: D7 MOV PSW,A 002C: B8 20 MOV R0,#$20 ; check bit5 in CMD 002E: F0 MOV A,@R0 002F: B2 35 JB5 $0035 0031: 74 DE CALL $03DE ; AT-KBD: we pull CLK low and hold 0033: 04 37 JMP $0037 0035: 9A 7F ANL P2,#$7F ; XT-KBD: we just pull DATA low 0037: 23 02 MOV A,#$02 0039: 93 RETR ; IBF intr ; ======== ; This is not supposed to happen ; and is considered as ERROR. We just count it in @2F. ; Then back to Main 003A: 65 STOP TCNT 003B: 15 DIS I 003C: B8 2F MOV R0,#$2F 003E: F0 MOV A,@R0 003F: 17 INC A 0040: C6 43 JZ $0043 0042: A0 MOV @R0,A 0043: 24 02 JMP $0102 ; -> Main ; Reset routine ; ============= ; ; \/\/\__________ CLK pulled low ; _________ (AT-KBD disabled state?) ; \/\/\/ DATA set high 0045: 23 CF MOV A,#$CF ; DATA=1 CLK=0 (KBD DISABLED) 0047: 3A OUTL P2,A 0048: F5 EN FLAGS ; OBF/_IBF routing ON to P24/P25, but so far disabled (P2=CF) 0049: 26 4D JNT0 $004D 004B: 9A BF ANL P2,#$BF 004D: 09 IN A,P1 004E: 90 MOV STS,A ; Stage1 004F: D6 4F JNIBF $004F ; wait for data from Host.. 0051: 23 10 MOV A,#$10 0053: 90 MOV STS,A 0054: 22 IN A,DBB 0055: 76 59 JF1 $0059 0057: 04 4F JMP $004F 0059: D3 AA XRL A,#$AA ; Command Self-Test? 005B: 96 4F JNZ $004F 005D: E4 06 JMP $0706 ; do Command AA (it will return here on success) 005F: 23 60 MOV A,#$60 ; Stage2. Init RAM variables 0061: 90 MOV STS,A 0062: B8 20 MOV R0,#$20 0064: B0 10 MOV @R0,#$10 ; @20=10 (CMD = kbd disable by default) 0066: 18 INC R0 0067: B0 01 MOV @R0,#$01 ; @21=1 (this is how many times we try after parity error) 0069: 18 INC R0 006A: B0 06 MOV @R0,#$06 ; @22=6 006C: 18 INC R0 006D: 18 INC R0 006E: 18 INC R0 006F: B0 01 MOV @R0,#$01 ; @25=1 0071: 18 INC R0 0072: 18 INC R0 0073: B0 FB MOV @R0,#$FB ; @27=FB (Timer reload value for send data to kbd) 0075: 18 INC R0 0076: B0 E0 MOV @R0,#$E0 ; @28=E0 (Timer reload before read scan code?) 0078: 18 INC R0 0079: B0 06 MOV @R0,#$06 ; @29=6 007B: 18 INC R0 007C: B0 10 MOV @R0,#$10 ; @2A=10 (pull CLK low and hold for AT-KBD in a loop of @2A) 007E: 18 INC R0 007F: B0 20 MOV @R0,#$20 ; @2B=20 (base for RAM address read/write commands) 0081: 18 INC R0 0082: B0 15 MOV @R0,#$15 ; @2C=15 (set and hold CLK/DATA for XT-KBD in a loop of 256 x @2C before IDLE) 0084: BC 55 MOV R4,#$55 ; Send 55 to Host (Self-test completed) 0086: B9 00 MOV R1,#$00 0088: 74 D3 CALL $03D3 008A: 24 02 JMP $0102 ; -> Main ; to read this page 008C: A3 MOVP A,@A 008D: 83 RET ; to read this page 0100: A3 MOVP A,@A 0101: 83 RET ; Main Entry ; ========== 0102: 86 0A JOBF $010A ; DBBOUT still full? (wait until Host reads out previous byte sent) 0104: D6 10 JNIBF $0110 ; DBBOUT empty, go an poll kbd if enabled ; DBBIN is full: parse command/data 0106: 76 49 JF1 $0149 ; Command written to 0x64. Returns to $0102 0108: 44 02 JMP $0202 ; Data is written to 0x60. Returns to $0102 010A: D6 02 JNIBF $0102 ; DBBOUT full, loop until emptied or we receive sth 010C: 76 06 JF1 $0106 010E: 24 02 JMP $0102 ; -> Main ; DBBIN empty: deal with kbd 0110: B8 20 MOV R0,#$20 ; 0112: F0 MOV A,@R0 0113: 92 02 JB4 $0102 ; _EN set -> kbd disabled, back to Main loop ; KBD enabled: do XT- or AT-protocol based on CMD5 0115: B2 3F JB5 $013F ; XT-kbd? ; AT-KBD enabled ; (or has just been enabled by Host, @2E=1: then we make sure DATA is high) 0117: B8 28 MOV R0,#$28 ; Preload Timer for later call $03AE (READ BYTE FROM AT-KBD) 0119: F0 MOV A,@R0 011A: 62 MOV T,A 011B: B8 2E MOV R0,#$2E ; Host has just enabled kbd by clearing _EN in CMD? 011D: F0 MOV A,@R0 011E: C6 26 JZ $0126 0120: 46 02 JNT1 $0102 ; ??? start all over if DATA is pulled low?? 0122: 46 02 JNT1 $0102 ; ??? make sure DATA is still high?? 0124: 27 CLR A ; OK, DATA is Idle 0125: A0 MOV @R0,A ; clear flag, release CLK and do the poll loop 0126: 9A BF ANL P2,#$BF ; release CLK! 0128: 24 2A JMP $012A ; and do the AT-KBD Main Poll Loop ; AT-KBD Main Poll Loop of CLK and IBF ; ==================================== ; Either CLK gets pulled down by AT-KBD ; or Host sends a byte will exit from here 012A: 26 32 JNT0 $0132 ; kbd pulled CLK down? 012C: D6 2A JNIBF $012A ; Host wrote 0x60 or 0x64 ; byte arrived from Host in AT-mode 012E: 74 DE CALL $03DE ; pull CLK low and hold (disable kbd.. it will be re-enabled when reading the response byte) 0130: 24 06 JMP $0106 ; and deal with command/data from Host. Returns to $0102 ; DBBIN empty ; AT-KBD pulled CLK down 0132: 26 4B JNT0 $014B ; CLK fall was noise, count ERROR in @24 and loop again ; CLK |_| short fall 0134: 74 DE CALL $03DE 0136: B8 24 MOV R0,#$24 0138: F0 MOV A,@R0 0139: 17 INC A 013A: C6 26 JZ $0126 013C: A0 MOV @R0,A 013D: 24 26 JMP $0126 ; XT-KBD Main Poll Loop of CLK and IBF ; ==================================== ; (strange, CLK always checked twice.. ?) 013F: 36 45 JT0 $0145 0141: 36 3F JT0 $013F 0143: 84 02 JMP $0402 ; XT-KBD has pulled CLK low -> read scan code 0145: D6 3F JNIBF $013F ; byte arrived from Host in XT-mode: now what? ; (XT-KBD is uni-directional.. funny) 0147: 24 06 JMP $0106 ; Command, XT-mode(!) 0149: A4 02 JMP $0502 ; Command Parser, AT-mode ; OK, AT-KBD pulled the CLK down ; (scan code is expected) 014B: 74 AE CALL $03AE ; READ BYTE FROM AT-KBD 014D: 12 53 JB0 $0153 ; parity error? 014F: 32 79 JB1 $0179 ; timeout error? 0151: 24 7F JMP $017F ; OK -> ; scan code received with Parity Error 0153: B8 21 MOV R0,#$21 ; # of retry-s variable @21 (=1 init) 0155: F0 MOV A,@R0 0156: C6 75 JZ $0175 0158: AD MOV R5,A ; if we allow retry (normally do, 1) -> loop in R5 ; Resend RETRY after Parity error 0159: B8 23 MOV R0,#$23 ; inc ERROR COUNTER @23 015B: F0 MOV A,@R0 015C: 17 INC A 015D: C6 60 JZ $0160 015F: A0 MOV @R0,A 0160: BC FE MOV R4,#$FE ; Send FE (resend) to AT-KBD 0162: 54 32 CALL $0232 0164: 32 75 JB1 $0175 ; did sending FE timed out? 0166: B9 29 MOV R1,#$29 ; Receive scan code again from AT-KBD, call 380 passing R1=29(?) 0168: 74 80 CALL $0380 016A: 12 73 JB0 $0173 ; did second attempt ended with Parity Error again? Try again, loop 016C: 32 75 JB1 $0175 ; did second attempt ended with Time Out? 016E: FC MOV A,R4 016F: D3 FE XRL A,#$FE 0171: 96 7F JNZ $017F 0173: ED 59 DJNZ R5,$0159 0175: B9 80 MOV R1,#$80 ; sending FE to AT-KBD Timed out 0177: 24 7B JMP $017B ; Scan code receive ended with Timeout Error 0179: B9 40 MOV R1,#$40 017B: BC 00 MOV R4,#$00 017D: 24 81 JMP $0181 ; Send received scan code from AT-KBD to Host ; Translation set? 017F: B9 00 MOV R1,#$00 0181: B8 20 MOV R0,#$20 0183: F0 MOV A,@R0 0184: 37 CPL A 0185: D2 BE JB6 $01BE ; XLAT? ; XLAT=1 ; Translate set-2 to set-1 ; Watch for ; - set-2 scan codes over 0x7f ; - F0 break codes ; - INH and key switch 0187: FC MOV A,R4 ; XLAT ON: translate to set-1 (7-bit make codes, msb set for break codes) 0188: D3 83 XRL A,#$83 018A: 96 90 JNZ $0190 018C: BC 02 MOV R4,#$02 ; 0x80 -> 0x02 (=F7) 018E: 24 97 JMP $0197 0190: FC MOV A,R4 0191: D3 84 XRL A,#$84 0193: 96 97 JNZ $0197 0195: BC 7F MOV R4,#$7F ; 0x84 -> 0x7F (=SysRq, the new key pressed) 0197: F0 MOV A,@R0 ; Send scan code to Host only if (INH || SW) 0198: 72 A6 JB3 $01A6 ; (INH=CMD3, SW=P17) 019A: 09 IN A,P1 019B: F2 A6 JB7 $01A6 019D: FC MOV A,R4 ; KBD disabled. 019E: F2 B4 JB7 $01B4 ; Just store make/break in @2D and exit 01A0: 27 CLR A 01A1: B8 2D MOV R0,#$2D 01A3: A0 MOV @R0,A 01A4: 24 C0 JMP $01C0 01A6: FC MOV A,R4 ; KBD enabled. 01A7: F2 B4 JB7 $01B4 ; Is it break code? 01A9: E3 MOVP3 A,@A ; No, do the translation (table at $0300, 128 bytes) 01AA: AC MOV R4,A ; get possible break code bit 01AB: B8 2D MOV R0,#$2D 01AD: F0 MOV A,@R0 01AE: 4C ORL A,R4 01AF: AC MOV R4,A 01B0: 27 CLR A 01B1: A0 MOV @R0,A 01B2: 24 BE JMP $01BE ; send to Host 01B4: D3 F0 XRL A,#$F0 ; did AT-KBD send us the break code (F0)? 01B6: 96 BE JNZ $01BE ; no, send R4 to Host and exit 01B8: B8 2D MOV R0,#$2D ; yes, set flag @2D and exit 01BA: B0 80 MOV @R0,#$80 01BC: 24 C0 JMP $01C0 ; XLAT=0, do nothing ; Send byte and status to Host 01BE: 74 D3 CALL $03D3 ; R4->DBBOUT, R1->STATUS 01C0: 24 02 JMP $0102 ; -> Main *************************************************************** ** BANK 2: ** ** ** ** $0202 Send Keyboard Command to KBD and read reply ** ** $0232 Send byte to KBD ** *************************************************************** ; to read this page 0200: A3 MOVP A,@A 0201: 83 RET ; Host has written to 0x60 0202: 22 IN A,DBB 0203: AC MOV R4,A 0204: B8 20 MOV R0,#$20 0206: F0 MOV A,@R0 0207: 53 EF ANL A,#$EF 0209: A0 MOV @R0,A ; enable kbd in CMD BYTE (for reading response?) - will be disabled before back to Main 020A: B2 2E JB5 $022E ; CMD5? ; Send Byte to AT-kbd 020C: 54 32 CALL $0232 ; Send byte in R4 020E: 8A 80 ORL P2,#$80 ; DATA=1 (above returned with CLK pulled low) 0210: B9 20 MOV R1,#$20 0212: 32 28 JB1 $0228 ; Timeout Error? Set TxTO and Resend 0214: B8 22 MOV R0,#$22 ; pass @22 to $0380 if non-zero (=6 on reset) 0216: F0 MOV A,@R0 0217: C6 30 JZ $0230 0219: A9 MOV R1,A ; receive reply (pass 6 in R1?) 021A: 74 80 CALL $0380 021C: B9 A0 MOV R1,#$A0 021E: 12 28 JB0 $0228 ; Parity Error? Set PERR & RxTO and Resend 0220: B9 60 MOV R1,#$60 0222: 32 28 JB1 $0228 ; Timeout Error? Set RxTO & TxTO and Resend 0224: B9 00 MOV R1,#$00 ; OK. Send reply byte to Host 0226: 44 2A JMP $022A ; Parity Error occured during sending byte to kbd 0228: BC FE MOV R4,#$FE ; Send FE to Host (resend) 022A: 74 D3 CALL $03D3 022C: 44 30 JMP $0230 ; -> Main 022E: 94 50 CALL $0450 ; Send Byte to XT-kbd 0230: 24 02 JMP $0102 ; -> Main ; Send byte in AT-keyboard protocol (byte in R4) 0232: 9A 7F ANL P2,#$7F ; pull DATA low 0234: 74 DE CALL $03DE ; pull CLK low and hold (prepare AT-kbd to receive byte?) 0236: B8 26 MOV R0,#$26 0238: F0 MOV A,@R0 0239: 62 MOV T,A ; Timer Reload with @26 for start bit 023A: 55 STRT T 023B: B8 27 MOV R0,#$27 023D: BA 08 MOV R2,#$08 023F: BB 00 MOV R3,#$00 0241: 9A BF ANL P2,#$BF ; release CLK! 0243: FC MOV A,R4 ; loop for sending 8 data bits 0244: 67 RRC A 0245: AC MOV R4,A 0246: 36 46 JT0 $0246 ; wait for CLK falling edge.. 0248: F6 4E JC $024E 024A: 9A 7F ANL P2,#$7F ; then write DATA 024C: 44 51 JMP $0251 024E: 8A 80 ORL P2,#$80 0250: 1B INC R3 ; compute parity 0251: 65 STOP TCNT 0252: F0 MOV A,@R0 0253: 62 MOV T,A ; Timer Reload with @27 for data bits 0254: 55 STRT T 0255: 26 55 JNT0 $0255 ; wait for CLK rising edge.. 0257: EA 43 DJNZ R2,$0243 ; next data bit 0259: 23 01 MOV A,#$01 ; send Parity bit 025B: DB XRL A,R3 025C: 67 RRC A 025D: 36 5D JT0 $025D 025F: F6 65 JC $0265 0261: 9A 7F ANL P2,#$7F 0263: 44 67 JMP $0267 0265: 8A 80 ORL P2,#$80 0267: 65 STOP TCNT 0268: F0 MOV A,@R0 ; send Stop bit.. 0269: 62 MOV T,A 026A: 55 STRT T 026B: 26 6B JNT0 $026B 026D: 44 6F JMP $026F 026F: 36 6F JT0 $026F 0271: 8A 80 ORL P2,#$80 0273: 65 STOP TCNT 0274: F0 MOV A,@R0 ; Wait for |_| on DATA (ACK).. 0275: 62 MOV T,A 0276: 55 STRT T 0277: 56 77 JT1 $0277 0279: 44 7B JMP $027B 027B: 46 7B JNT1 $027B 027D: 65 STOP TCNT 027E: 00 NOP 027F: 74 DE CALL $03DE ; pull CLK low and hold 0281: 27 CLR A ; return A=0, OK 0282: 83 RET ******************************************************************************* ** BANK 3: ** ** ** ** $0300 set-2 to set-1 translation table (128 entries) ** ** $0380 Read byte from AT-KBD (wait first for CLK pulled low by kbd) ** ** $03AE Read byte from AT-KBD (CLK already pulled low by kbd) ** ** $03D3 SEND BYTE to HOST (R4) and set STATUS (R1) ** ** $03DE PULL CLK LOW and HOLD for AT-KBD ** ******************************************************************************* 0300: ff 43 41 3f 3d 3b 3c 58 | 64 44 42 40 3e 0f 29 59 0310: 65 38 2a 70 1d 10 02 5a | 66 71 2c 1f 1e 11 03 5b 0320: 67 2e 2d 20 12 05 04 5c | 68 39 2f 21 14 13 06 5d 0330: 69 31 30 23 22 15 07 5e | 6a 72 32 24 16 08 09 5f 0340: 6b 33 25 17 18 0b 0a 60 | 6c 34 35 26 27 19 0c 61 0350: 6d 73 28 74 1a 0d 62 6e | 3a 36 1c 1b 75 2b 63 76 0360: 55 56 77 78 79 7a 0e 7b | 7c 4f 7d 4b 47 7e 7f 6f 0370: 52 53 50 4c 4d 48 01 45 | 57 4e 51 4a 37 49 46 54 ; This was always a little mistique.. what is this really? 0380: B8 28 MOV R0,#$28 ; reload Timer with @28 0382: F0 MOV A,@R0 ; that is for $03AE! 0383: 62 MOV T,A 0384: 9A BF ANL P2,#$BF ; release CLK.. and wait for kbd to answer in a doesn't-make-sense-way(?) 0386: 27 CLR A ; loop R1-times (6?) 0387: 26 AC JNT0 $03AC ;CLK pulled low by kbd? 0389: 17 INC A 038A: C6 90 JZ $0390 038C: 26 AC JNT0 $03AC 038E: 64 87 JMP $0387 0390: 26 AC JNT0 $03AC 0392: C9 DEC R1 0393: F9 MOV A,R1 0394: 96 86 JNZ $0386 0396: 64 A7 JMP $03A7 ; disable kbd and return with Timeout Error 0398: AA MOV R2,A 0399: 74 DE CALL $03DE ; pull CLK low and hold 039B: FA MOV A,R2 039C: 17 INC A 039D: C6 A3 JZ $03A3 039F: 9A BF ANL P2,#$BF ; release CLK.. 03A1: 64 87 JMP $0387 03A3: C9 DEC R1 03A4: F9 MOV A,R1 03A5: 96 84 JNZ $0384 03A7: 74 DE CALL $03DE ; pull CLK low and hold 03A9: 23 02 MOV A,#$02 ; disable kbd and return with Timeout Error 03AB: 83 RET 03AC: 36 98 JT0 $0398 ; CLK pulled low by kbd AND stable? Yes.. we fall thru start reading byte ; Receive byte from AT-keyboard ; CLK fell.. and CMD5=0. Timer should be preloaded. ; we read DATA on falling edges of CLK ; and compute parity (will be returned in A) ; (Amazing how much 8-bit code fits into 37 bytes!:) 03AE: 55 STRT T 03AF: BA 09 MOV R2,#$09 03B1: BB 00 MOV R3,#$00 03B3: 26 B3 JNT0 $03B3 03B5: 67 RRC A 03B6: 36 B6 JT0 $03B6 ; wait for CLK falling edge.. 03B8: 97 CLR C 03B9: 46 BD JNT1 $03BD ; read in DATA into Carry 03BB: A7 CPL C 03BC: 1B INC R3 03BD: EA B3 DJNZ R2,$03B3 03BF: AC MOV R4,A 03C0: 26 C0 JNT0 $03C0 03C2: 64 C4 JMP $03C4 03C4: 36 C4 JT0 $03C4 03C6: 65 STOP TCNT ; done 03C7: 00 NOP 03C8: 74 DE CALL $03DE ; pull CLK low 03CA: FB MOV A,R3 ; return parity: A=0 is OK 03CB: 12 D1 JB0 $03D1 03CD: 23 01 MOV A,#$01 03CF: 64 D2 JMP $03D2 03D1: 27 CLR A 03D2: 83 RET ; Send data and status to Host ; R1 -> STATUS (host can read 0x64) ; R4 -> DBBOUT (host can read 0x60) ; this then sets OBF -> IRQ1 on AT 03D3: 09 IN A,P1 ; Copy keylock status bit 03D4: 53 80 ANL A,#$80 03D6: 77 RR A 03D7: 77 RR A 03D8: 77 RR A 03D9: 49 ORL A,R1 03DA: 90 MOV STS,A ; write STATUS 03DB: FC MOV A,R4 03DC: 02 OUT DBB,A ; write DBBOUT 03DD: 83 RET ; Frequently called. ; What does this mean to an AT-keyboard? Disable? Abort sending scan codes and wait for command? ; __ ; \____ _ _ pull CLK low and hold stable a while 03DE: 8A 40 ORL P2,#$40 03E0: B8 2A MOV R0,#$2A 03E2: F0 MOV A,@R0 03E3: A8 MOV R0,A 03E4: E8 E4 DJNZ R0,$03E4 03E6: 83 RET ***************************************************************** ** BANK 4: XT-keyboard protocol routines ** ** ** ** $0402 Read byte from XT-KBD ** ** $0450 Send byte to XT-KBD (hae?) ** ***************************************************************** ; to read this page 0400: A3 MOVP A,@A 0401: 83 RET ; Read scan code from XT-KBD and handle errors ; send result to Host 0402: 94 1C CALL $041C 0404: 12 1A JB0 $041A ; 0406: 32 14 JB1 $0414 0408: B9 00 MOV R1,#$00 040A: B8 20 MOV R0,#$20 040C: F0 MOV A,@R0 040D: 72 18 JB3 $0418 040F: 09 IN A,P1 0410: F2 18 JB7 $0418 ; SW=1 send scan code to Host 0412: 84 1A JMP $041A ; SW=0 exit to Main 0414: B9 40 MOV R1,#$40 ; 0416: BC FF MOV R4,#$FF 0418: 74 D3 CALL $03D3 041A: 24 02 JMP $0102 ; -> Main ; Receive byte in XT-keyboard protocol ; CLK fell.. and CMD5=1 041C: 27 CLR A 041D: 62 MOV T,A 041E: 55 STRT T 041F: B8 09 MOV R0,#$09 0421: 27 CLR A 0422: 8A 80 ORL P2,#$80 0424: 00 NOP 0425: 00 NOP 0426: 00 NOP 0427: 00 NOP 0428: 26 37 JNT0 $0437 042A: B8 24 MOV R0,#$24 042C: F0 MOV A,@R0 042D: 17 INC A 042E: C6 31 JZ $0431 0430: A0 MOV @R0,A 0431: 23 01 MOV A,#$01 0433: 9A 7F ANL P2,#$7F 0435: 84 4E JMP $044E 0437: 26 37 JNT0 $0437 0439: 26 37 JNT0 $0437 043B: 97 CLR C 043C: 46 3F JNT1 $043F 043E: A7 CPL C 043F: 67 RRC A 0440: 36 40 JT0 $0440 0442: 36 40 JT0 $0440 0444: E8 37 DJNZ R0,$0437 0446: 9A 7F ANL P2,#$7F 0448: 26 48 JNT0 $0448 044A: 26 48 JNT0 $0448 044C: AC MOV R4,A 044D: 27 CLR A 044E: 65 STOP TCNT 044F: 83 RET ; Send byte to XT-keyboard??? 0450: D2 54 JB6 $0454 ; XLAT? 0452: 84 68 JMP $0468 0454: B9 00 MOV R1,#$00 ; XLAT=1 0456: E9 56 DJNZ R1,$0456 0458: FC MOV A,R4 0459: AA MOV R2,A 045A: D3 EE XRL A,#$EE 045C: C6 60 JZ $0460 045E: BC FA MOV R4,#$FA 0460: B9 00 MOV R1,#$00 0462: 74 D3 CALL $03D3 ; Send to Host 0464: FA MOV A,R2 0465: 17 INC A 0466: 96 7A JNZ $047A ; Set and hold.. then IDLE for XT-keyboard(?) ; ___ ; CLK \___ __ __/ ; __ __ _ ; DATA / \____ 0468: 8A 40 ORL P2,#$40 ; XLAT=0 046A: 8A 80 ORL P2,#$80 046C: B8 2C MOV R0,#$2C ; pull CLK low and set DATA high 046E: F0 MOV A,@R0 046F: A8 MOV R0,A 0470: B9 00 MOV R1,#$00 0472: E9 72 DJNZ R1,$0472 0474: E8 72 DJNZ R0,$0472 ; hold it in a loop of 256 x @2C 0476: 9A 7F ANL P2,#$7F 0478: 9A BF ANL P2,#$BF ; set the XT idle state 047A: 83 RET ******************************************************************************* ** ** ** BANK 5: Command parser and most Commands ** ******************************************************************************* ; to read this page 0500: A3 MOVP A,@A 0501: 83 RET ; There is a byte in DBBIN written to 0x64 bu the Host 0502: 22 IN A,DBB ; xxxx xxxx 0503: F2 09 JB7 $0509 ; 0xxx xxxx 0505: D2 12 JB6 $0512 ; 00xx xxxx 0507: A4 0D JMP $050D ; 1xxx xxxx 0509: D2 8C JB6 $058C ; 10xx xxxx 050B: A4 62 JMP $0562 ; Command 00xx xxxx: Read RAM ; 0x00-0x1F will read 0x20-0x3F ; 0x20-0x3F will read 0x20-0x3F 050D: B4 59 CALL $0559 ; Compute RAM address 050F: F0 MOV A,@R0 ; read RAM into A 0510: A4 DE JMP $05DE ; -> send A to Host and go Main ; Command 01xx xxxx: Write RAM ; 0x40-0x5F will write 0x20-0x3F ; 0x60-0x7F will write 0x20-0x3F 0512: B4 59 CALL $0559 ; Compute RAM address 0514: D6 14 JNIBF $0514 ; wait for byte from Host.. 0516: 76 02 JF1 $0502 ; command? abort 0518: D3 20 XRL A,#$20 ; Host writes CMD BYTE? 051A: C6 20 JZ $0520 ; no, write RAM and exit 051C: 22 IN A,DBB 051D: A0 MOV @R0,A 051E: A4 E3 JMP $05E3 ; -> Main ; This is special: Host writes CMD BYTE at 0x20 ; watch the bits 0520: F0 MOV A,@R0 ; save CMD 0521: A9 MOV R1,A ; into R1 (for re-enabling the AT-KBD) 0522: 22 IN A,DBB 0523: A0 MOV @R0,A ; write CMD (!) 0524: 12 42 JB0 $0542 ; CMD0 (OBF) 0526: 9A EF ANL P2,#$EF ; P24=0 (OBF routed) 0528: 32 46 JB1 $0546 ; CMD1 (_IBF) 052A: 9A DF ANL P2,#$DF ; P25=0 052C: 52 4A JB2 $054A ; CMD2 (mirror of F0 in STATUS) 052E: 85 CLR F0 ; F0=0 052F: 92 4F JB4 $054F ; CMD4 (_EN) 0531: F9 MOV A,R1 ; check previous _EN 0532: 37 CPL A 0533: 92 39 JB4 $0539 ; _EN 1->0 transition? Host enabled a previously disabled keyboard? 0535: B9 2E MOV R1,#$2E ; just set flag @2E=1 for Main and do next bit 0537: B1 01 MOV @R1,#$01 ; (bc that will leave the AT-KBD disabled, CLK low!) 0539: F0 MOV A,@R0 053A: B2 53 JB5 $0553 ; CMD5? ; CMD5=0, set AT-KBD protocol: DISABLE AT-KBD on the wire immediately ; ______ ; __/ set DATA high (idle) ; ___ ; \_____ pull CLK low (= disable AT-KBD) 053C: 8A 80 ORL P2,#$80 053E: 8A 40 ORL P2,#$40 0540: A4 E3 JMP $05E3 ; -> Main ; Host wrote CMD0 (OBF) 0542: 8A 10 ORL P2,#$10 ; P24=1 means enable OBF routing (= IRQ1 enable on AT) 0544: A4 28 JMP $0528 ; next bit.. ; Host wrote CMD1 (_IBF) 0546: 8A 20 ORL P2,#$20 ; P25=1 0548: A4 2C JMP $052C ; CMD2 (mirror of F0 in STATUS) 054A: B6 2F JF0 $052F 054C: 95 CPL F0 ; F0=1 054D: A4 2F JMP $052F ; Host set CMD4 (_EN) = DISABLE KEYBOARD ; __ ; \______ pull CLK LOW immediately 054F: 8A 40 ORL P2,#$40 0551: A4 3A JMP $053A ; CMD=1 (XT-keyboard protocol): SET XT-KBD to IDLE on the wire immediately ; __ ; \______ DATA pulled low ; _____ ; ___/ CLK high (idle) = this is XT-mode IDLE state. 0553: 9A 7F ANL P2,#$7F 0555: 9A BF ANL P2,#$BF 0557: A4 E3 JMP $05E3 ; -> Main ; Compute RAM address for R/W commands ; if 001x xxxx (0x20 - 0x3F) we leave it (actual RAM address) ; if 000x xxxx (0x00 - 0x1F) we add the value @2B (that is reset to 0x20) 0559: 53 3F ANL A,#$3F 055B: B2 60 JB5 $0560 055D: B8 2B MOV R0,#$2B 055F: 60 ADD A,@R0 0560: A8 MOV R0,A 0561: 83 RET ; return RAM address in R0 ; 10xx xxxx 0562: 03 56 ADD A,#$56 0564: 96 68 JNZ $0568 ; Command AA ; Self-test and Reset 0566: E4 00 JMP $0700 0568: 07 DEC A 0569: 96 6F JNZ $056F ; Command AB ; Test kbd interface (DATA and CLK lines) 056B: D4 69 CALL $0669 ; returns 0 (OK), 1, 2, 3 or 4 in R4 056D: A4 DF JMP $05DF ; -> send R4 to Host with OK, then ->Main 056F: 07 DEC A 0570: 96 76 JNZ $0576 ; Command AC ; Diagnostic Dump of 20 bytes in scan code set-1 format 0572: D4 12 CALL $0612 0574: A4 E3 JMP $05E3 ; -> Main 0576: 07 DEC A 0577: 96 81 JNZ $0581 ; Command AD ; Disable kbd interface ; = set _EN 0579: B8 20 MOV R0,#$20 057B: F0 MOV A,@R0 057C: 43 10 ORL A,#$10 ; CMD4=1 _EN (kbd disabled) 057E: A0 MOV @R0,A 057F: A4 E3 JMP $05E3 ; -> Main 0581: 07 DEC A 0582: 96 E3 JNZ $05E3 ; -> Main ; Command AE ; Enable kbd interface ; = clr _EN 0584: B8 20 MOV R0,#$20 0586: F0 MOV A,@R0 0587: 53 EF ANL A,#$EF ; CMD4=0 _EN (kbd enabled) 0589: A0 MOV @R0,A 058A: A4 E3 JMP $05E3 ; -> Main ; 11xx xxxx 058C: B2 AC JB5 $05AC ; 110x xxxx 058E: 92 CE JB4 $05CE ; 1100 xxxx 0590: D3 C0 XRL A,#$C0 0592: 96 97 JNZ $0597 ; Command C0 ; Read P1 into A and return 0594: 09 IN A,P1 0595: A4 DE JMP $05DE ; -> send A to Host and -> Main 0597: D3 02 XRL A,#$02 0599: 96 A1 JNZ $05A1 ; Command C2 ; Read P1 higher nibble into STATUS (4..7 only) ; and loop until Host writes a dummy byte to 0x60 or 0x64 (!) ; (what is this? to let Host poll P1 through STATUS?) 059B: 09 IN A,P1 059C: 90 MOV STS,A 059D: D6 9B JNIBF $059B 059F: A4 E3 JMP $05E3 ; -> Main 05A1: D3 01 XRL A,#$01 ; ignore all other 0xCx 05A3: 96 E3 JNZ $05E3 ; -> Main ; C1 ; Read P1 lower nibble into STATUS (4..7 only) ; and loop until Host writes a dummy byte to 0x60 or 0x64 (!) ; (what is this? to let Host poll P1 through STATUS?) 05A5: 09 IN A,P1 05A6: 47 SWAP A 05A7: 90 MOV STS,A 05A8: D6 A5 JNIBF $05A5 05AA: A4 E3 JMP $05E3 ; -> Main 05AC: 92 BC JB4 $05BC 05AE: D3 E0 XRL A,#$E0 ; we ignore if not E0 05B0: 96 E3 JNZ $05E3 ; -> Main ; Command E0 ; Read T0/T1 input pins (CLK/DATA) 05B2: 26 B6 JNT0 $05B6 05B4: 43 01 ORL A,#$01 05B6: 46 DE JNT1 $05DE 05B8: 43 02 ORL A,#$02 05BA: A4 DE JMP $05DE ; -> send A to Host and -> Main ; Command F0..FF ; Pulse P2 bits 0..3 05BC: AA MOV R2,A 05BD: 37 CPL A 05BE: A9 MOV R1,A 05BF: B8 20 MOV R0,#$20 05C1: F0 MOV A,@R0 05C2: 47 SWAP A 05C3: 53 30 ANL A,#$30 05C5: AB MOV R3,A 05C6: 0A IN A,P2 05C7: 4B ORL A,R3 05C8: 5A ANL A,R2 05C9: 3A OUTL P2,A 05CA: 49 ORL A,R1 05CB: 3A OUTL P2,A 05CC: A4 E3 JMP $05E3 ; -> Main 05CE: D3 D0 XRL A,#$D0 05D0: C6 DD JZ $05DD 05D2: 07 DEC A 05D3: 96 E3 JNZ $05E3 ; -> Main ; Command D1 ; Write P2 05D5: D6 D5 JNIBF $05D5 ; wait for byte from Host (NB! infinite loop) 05D7: 76 02 JF1 $0502 ; 0x64 written? Parse command 05D9: 22 IN A,DBB ; read byte written to 0x60 05DA: 3A OUTL P2,A ; out P2 05DB: A4 E3 JMP $05E3 ; -> Main ; Command D0 ; Read P2 05DD: 0A IN A,P2 ; read P2 ; Return to Main with sending A to Host 05DE: AC MOV R4,A ; send to Host fall through ; Return to Main with sending R4 to Host 05DF: B9 00 MOV R1,#$00 ; STATUS=OK 05E1: 74 D3 CALL $03D3 ; send R4 to Host ; Return to Main 05E3: 27 CLR A ; 05E4: 24 02 JMP $0102 ; -> Main **************************************** *** BANK 6: Command AC and AB ** **************************************** ; 16 ASCII hexa digits in scan code set-1 format ; Eg. 0B in scan code set-1 is the '0'-key.. 0600: 0B 02 03 04 05 06 07 08 09 0A 1E 30 2E 20 12 21 ; to read this page 0610: A3 MOVP A,@A 0611: 83 RET ; Command AC ; ========== ; Will send 20 bytes to Host in scan code set-1 format(!), like "10 06 E0 ..." ; First it stored these: ; @30=P1 ; @31=P2 ; @32 T0/T1 (KB CLK and DATA from Test pins) ; @33 PSW ; Then pumps 20 bytes out from @20-@33 ; @20 (CMD byte) ; @21-@2F (different variables, error counters, see above) 0612: 23 10 MOV A,#$10 ; set _EN 0614: 90 MOV STS,A 0615: B8 30 MOV R0,#$30 0617: 09 IN A,P1 0618: A0 MOV @R0,A ; @30=P1 0619: 18 INC R0 061A: 0A IN A,P2 061B: A0 MOV @R0,A ; @31=P2 061C: 18 INC R0 061D: 27 CLR A 061E: 26 22 JNT0 $0622 0620: 43 01 ORL A,#$01 0622: 46 26 JNT1 $0626 0624: 43 02 ORL A,#$02 0626: A0 MOV @R0,A ; @32=T0/T1 0627: 18 INC R0 0628: C7 MOV A,PSW 0629: A0 MOV @R0,A ; @33=PSW 062A: B9 14 MOV R1,#$14 ; Dump 20 bytes 062C: B8 20 MOV R0,#$20 ; from @20 062E: D6 32 JNIBF $0632 ; Host should just read patiently 0630: C4 57 JMP $0657 ; Host sending aborts dumping 0632: 86 2E JOBF $062E 0634: D4 58 CALL $0658 0636: F0 MOV A,@R0 0637: 47 SWAP A ; hexa hi-nibble first 0638: 53 0F ANL A,#$0F 063A: A3 MOVP A,@A ; look-up 063B: 02 OUT DBB,A ; send scan code to Host 063C: D6 40 JNIBF $0640 063E: C4 57 JMP $0657 0640: 86 3C JOBF $063C 0642: D4 58 CALL $0658 ; delay.. 0644: F0 MOV A,@R0 ; hexa lo-nibble 0645: 53 0F ANL A,#$0F 0647: A3 MOVP A,@A 0648: 02 OUT DBB,A 0649: D6 4D JNIBF $064D 064B: C4 57 JMP $0657 064D: 86 49 JOBF $0649 064F: D4 58 CALL $0658 0651: 23 39 MOV A,#$39 ; send 0x39 (set-1 space? yes!) 0653: 02 OUT DBB,A 0654: 18 INC R0 ; inc pointer 0655: E9 2E DJNZ R1,$062E ; loop 0657: 83 RET ; Some delay to give Host to remove characters 0658: F8 MOV A,R0 0659: AA MOV R2,A 065A: F9 MOV A,R1 065B: AB MOV R3,A 065C: B8 00 MOV R0,#$00 065E: B9 40 MOV R1,#$40 0660: E8 60 DJNZ R0,$0660 0662: E9 60 DJNZ R1,$0660 0664: FB MOV A,R3 0665: A9 MOV R1,A 0666: FA MOV A,R2 0667: A8 MOV R0,A 0668: 83 RET ; Command AB ; ========== ; "lines stuck test" ; returns 0 (OK), 1, 2, 3 or 4 0669: 9A BF ANL P2,#$BF ; release CLK line (=> should be HIGH) 066B: 8A 80 ORL P2,#$80 ; release DATA line (=> should be HIGH) 066D: B8 00 MOV R0,#$00 066F: 36 77 JT0 $0677 ; OK, CLK high 0671: E8 6F DJNZ R0,$066F 0673: BC 01 MOV R4,#$01 ; Error, CLK stuck low 0675: C4 98 JMP $0698 0677: 8A 40 ORL P2,#$40 ; pull CLK low 0679: C4 7B JMP $067B ; delay 067B: 26 83 JNT0 $0683 ; OK, CLK low 067D: 9A BF ANL P2,#$BF ; (release CLK line anyway from my side) 067F: BC 02 MOV R4,#$02 ; Error, CLK stuck low 0681: C4 98 JMP $0698 0683: B8 00 MOV R0,#$00 ; 0685: 56 8D JT1 $068D ; OK, DATA high 0687: E8 85 DJNZ R0,$0685 0689: BC 03 MOV R4,#$03 ; Error, DATA stuck low 068B: C4 98 JMP $0698 068D: 9A 7F ANL P2,#$7F ; pull DATA low 068F: 00 NOP 0690: BC 00 MOV R4,#$00 ; 0692: 46 96 JNT1 $0696 ; OK 0694: BC 04 MOV R4,#$04 ; Error, DATA stuck high 0696: 8A 80 ORL P2,#$80 ; release DATA line anyway, exit 0698: 83 RET ********************************** *** BANK7: SELF-TEST *** ********************************** ; Entry point when Host sends Command AA 0700: 89 FF ORL P1,#$FF 0702: 23 CF MOV A,#$CF 0704: 3A OUTL P2,A 0705: C5 SEL RB0 ; Entry point after Reset 0706: 23 20 MOV A,#$20 0708: 90 MOV STS,A 0709: 96 0D JNZ $070D 070B: 04 4F JMP $004F 070D: 27 CLR A 070E: C6 12 JZ $0712 0710: 04 4F JMP $004F 0712: 97 CLR C 0713: E6 17 JNC $0717 0715: 04 4F JMP $004F 0717: A7 CPL C 0718: F6 1C JC $071C 071A: 04 4F JMP $004F 071C: 23 30 MOV A,#$30 071E: 90 MOV STS,A 071F: B8 00 MOV R0,#$00 0721: F8 MOV A,R0 0722: 96 52 JNZ $0752 0724: B8 55 MOV R0,#$55 0726: F8 MOV A,R0 0727: D3 55 XRL A,#$55 0729: 96 52 JNZ $0752 072B: B8 AA MOV R0,#$AA 072D: F8 MOV A,R0 072E: D3 AA XRL A,#$AA 0730: 96 52 JNZ $0752 0732: B8 7F MOV R0,#$7F ; 128 bytes of RAM 0734: F8 MOV A,R0 0735: A0 MOV @R0,A 0736: E8 34 DJNZ R0,$0734 0738: B8 7F MOV R0,#$7F ; 128 bytes of RAM 073A: F8 MOV A,R0 073B: D0 XRL A,@R0 073C: 96 52 JNZ $0752 073E: 23 55 MOV A,#$55 0740: A0 MOV @R0,A 0741: D0 XRL A,@R0 0742: 96 52 JNZ $0752 0744: 23 AA MOV A,#$AA 0746: A0 MOV @R0,A 0747: D0 XRL A,@R0 0748: 96 52 JNZ $0752 074A: A0 MOV @R0,A 074B: D0 XRL A,@R0 074C: 96 52 JNZ $0752 074E: E8 3A DJNZ R0,$073A 0750: E4 54 JMP $0754 0752: 04 4F JMP $004F 0754: 23 40 MOV A,#$40 ; ROM checksum? 0756: 90 MOV STS,A 0757: 23 FF MOV A,#$FF 0759: AE MOV R6,A 075A: AF MOV R7,A 075B: BA 08 MOV R2,#$08 075D: B8 00 MOV R0,#$00 075F: FA MOV A,R2 0760: AB MOV R3,A 0761: F8 MOV A,R0 0762: 37 CPL A 0763: 17 INC A 0764: EB 67 DJNZ R3,$0767 0766: A3 MOVP A,@A 0767: EB 6B DJNZ R3,$076B 0769: D4 10 CALL $0610 076B: EB 6F DJNZ R3,$076F 076D: B4 00 CALL $0500 076F: EB 73 DJNZ R3,$0773 0771: 94 00 CALL $0400 0773: EB 76 DJNZ R3,$0776 0775: E3 MOVP3 A,@A 0776: EB 7A DJNZ R3,$077A 0778: 54 00 CALL $0200 077A: EB 7E DJNZ R3,$077E 077C: 34 00 CALL $0100 077E: EB 82 DJNZ R3,$0782 0780: 14 8C CALL $008C 0782: DE XRL A,R6 0783: AD MOV R5,A 0784: 47 SWAP A 0785: AC MOV R4,A 0786: DD XRL A,R5 0787: AE MOV R6,A 0788: E7 RL A 0789: 53 E0 ANL A,#$E0 078B: DD XRL A,R5 078C: 2E XCH A,R6 078D: F7 RLC A 078E: 47 SWAP A 078F: 67 RRC A 0790: 67 RRC A 0791: E7 RL A 0792: 53 F1 ANL A,#$F1 0794: 2C XCH A,R4 0795: 53 0F ANL A,#$0F 0797: AD MOV R5,A 0798: E7 RL A 0799: DC XRL A,R4 079A: DF XRL A,R7 079B: 2E XCH A,R6 079C: DD XRL A,R5 079D: AF MOV R7,A 079E: E8 5F DJNZ R0,$075F 07A0: EA 5F DJNZ R2,$075F 07A2: FE MOV A,R6 07A3: 96 AA JNZ $07AA 07A5: FF MOV A,R7 07A6: 96 AA JNZ $07AA 07A8: E4 AC JMP $07AC 07AA: 04 4F JMP $004F 07AC: 23 50 MOV A,#$50 ; Test Timer intr 07AE: 90 MOV STS,A 07AF: 27 CLR A 07B0: 62 MOV T,A 07B1: 25 EN TCNTI ; INT enable 07B2: B9 0F MOV R1,#$0F 07B4: F4 C4 CALL $07C4 ; A=0 here 07B6: 32 C2 JB1 $07C2 ; A=2? Timer Intr occured 07B8: B9 02 MOV R1,#$02 07BA: F4 C4 CALL $07C4 07BC: 32 C0 JB1 $07C0 07BE: E4 C2 JMP $07C2 07C0: 04 5F JMP $005F 07C2: 04 4F JMP $004F 07C4: 55 STRT T ; loop and let Timer intr happen 07C5: B8 00 MOV R0,#$00 07C7: E8 C7 DJNZ R0,$07C7 07C9: E9 C7 DJNZ R1,$07C7 07CB: 65 STOP TCNT 07CC: 00 NOP 07CD: 83 RET ; A0 38 (what is this at the end of the ROM?) 07FE: A0 MOV @R0,A 07FF: 38 OUTL P0,A RAM Memory Map ============== The 8042 has 128 bytes of RAM. The RAM also stores 2 x 8 General Registers and the Program Stack. The rest is used by the firmware for variables (eg. the COMMAND BYTE @20, timer reload values, flags) and for different *Error Counters*: they count an event from zero to 255, but not more, and can be read by the AC Command. Theoretically.. the Host could write these parameters and affect the operation of the 8042! Eg. to change a timer reload value, clear an Error Counter, etc.. just thinking. @00 --+ R0-R7 @01 | 8 BANK0 registers @02 | Direct RAM access: @03 | R0-R7 implicite in instruction byte @04 | Indirect RAM access: @05 | Indexed through @R0 or @R1 @06 | @07 --+ @08 --+ @09 | @0A | @0B | @0C | @0D | 8 words (2 x 8 bytes) @0E | @0F | PROGRAM STACK @10 | @11 | @12 | @13 | @14 | @15 | @16 | @17 --+ @18 --+ @19 | @1A | R0'-R7' @1B | 8 BANK1 registers @1C | @1D | @1E | @2F --+ @20 --- COMMAND BYTE, the *mighty* @21 --- This is how many times we resend (FE) after parity error (init to 1) @22 --- (=0x06) Used in 380. checked for zero after succesful sending byte to kbd. If zero, jump back into main loop.. @23 --- ERROR CNT: # of parity errors detected since reset @24 --- ERROR CNT: too short signal fall on CLK detected (noise?) @25 --- (=0x01) ? @26 --- TIMER RELOAD, first pulse, when Send BYTE to KBD (init to 0x00) @27 --- TIMER RELOAD, bit pulses, when Send BYTE to KBD (init to 0xFB) @28 --- Timer reload (=0xE0): after kbd pulls down CLK, this is how much we wait to set it high again. @29 --- (=0x06) ? @2A --- loop counter for pulling CLK low and hold it stable for a while (how long? 60us? 250us?) @2B --- base for RAM write command = 0x20 @2C --- loop counter for XT-keyboard before set to IDLE @2D --- make/brake code (0x00 or 0x80) for scan code set-2 @2E --- flag, Host has enabled a previously disabled kbd by clearing _EN in Command Byte @2F --- ERROR CNT: IBF interrupt occured (not supposed to, we poll IBF) @30 --- We copy P1 here for CMD AC (Diagnostic Dump) @31 --- We copy P2 here for CMD AC (Diagnostic Dump) @32 --- bit0: T0, bit1:T1 (KB CLK and DATA from Test pins) for CMD AC (Diagnostic Dump) @33 --- PSW (Program Status Word) of the 8042, for CMD AC (Diagnostic Dump) @34-@7F unused?