1368 lines
39 KiB
Text
1368 lines
39 KiB
Text
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?
|
|
|
|
|
|
<EOF>
|
|
|