A collection of tools, code, schematics, and documentation to do with my Kaypro II ROM hacking

Disassembled-With-Notes.asm 40KB

    0000 c3 4b 00 K JP 004b 0003 c3 86 01 JP 0186 ;Possibly garbage - this address is in the middle of an instruction 0006 c3 04 06 JP 0604 0009 c3 67 05 g JP 0567 000c c3 d8 01 JP 01d8 000f c3 b4 01 JP 01b4 0012 c3 cc 01 JP 01cc 0015 c3 bb 01 JP 01bb 0018 c3 c7 01 JP 01c7 001b c3 ec 01 JP 01ec 001e c3 07 02 JP 0207 0021 c3 e4 03 JP 03e4 0024 c3 0f 04 JP 040f 0027 c3 1e 04 JP 041e 002a c3 74 05 t JP 0574 002d c3 7c 05 | JP 057c 0030 c3 87 05 JP 0587 ;keyboard read 0033 c3 cb 05 JP 05cb 0036 c3 d1 05 JP 05d1 0039 c3 d9 05 JP 05d9 ;serial write 003c c3 e9 05 JP 05e9 003f c3 f1 05 JP 05f1 0042 c3 e3 05 JP 05e3 0045 c3 1d 06 JP 061d 0048 c3 25 04 % JP 0425 ;; executed on boot 004b f3 DI ;disable maskable interrupts 004c 31 ff ff 1 LD SP,65535 ;stack pointer at top of ram 004f 06 0a LD B,10 0051 cd 25 04 % CALL 0425 0054 cd 67 05 g CALL 0567 0057 cd 04 06 CALL 0604 005a cd 86 01 CALL 0186 005d 18 08 JR +8 ;jmp to 0x65 005f 3d = DEC A 0060 00 NOP 0061 00 NOP 0062 00 NOP 0063 00 NOP 0064 00 NOP 0065 00 NOP 0066 c9 RET 0067 cd f1 07 CALL 07f1 ;; Garbage, or part of the string in some way. 006a 1b DEC DE 006a 1b DEC DE 006b 3d = DEC A ;; Bootup text - * KAYPRO II * 006c 2a 3f 2a *?* LD HL,(2a3f) 006f 20 20 JR NZ,+32 0071 20 20 JR NZ,+32 0073 4b K LD C,E 0074 41 A LD B,C 0075 59 Y LD E,C 0076 50 P LD D,B 0077 52 R LD D,D 0078 4f O LD C,A 0079 20 49 I JR NZ,+73 007b 49 I LD C,C 007c 20 20 JR NZ,+32 007e 20 20 JR NZ,+32 0080 2a 1b 3d * = LD HL,(3d1b) ;No null terminator. Length of string may be hardcoded somewhere 0083 2d - DEC L 0084 34 4 INC (HL) ;; " Please place your diskette into drive A" ;; Not sure what causes the A to flash. I tried putting the 0x08(comes after A and before null terminator) ;; into my homebrew firmware, but it didn't make it flash. 0x08 might be used by the function built into the firmware, ;; which makes it flash some other way. 0085 20 50 P JR NZ,+80 0087 6c l LD L,H 0088 65 e LD H,L 0089 61 a LD H,C 008a 73 s LD (HL),E 008b 65 e LD H,L 008c 20 70 p JR NZ,+112 008e 6c l LD L,H 008f 61 a LD H,C 0090 63 c LD H,E 0091 65 e LD H,L 0092 20 79 y JR NZ,+121 0094 6f o LD L,A 0095 75 u LD (HL),L 0096 72 r LD (HL),D 0097 20 64 d JR NZ,+100 0099 69 i LD L,C 009a 73 s LD (HL),E 009b 6b k LD L,E 009c 65 e LD H,L 009d 74 t LD (HL),H 009e 74 t LD (HL),H 009f 65 e LD H,L 00a0 20 69 i JR NZ,+105 00a2 6e n LD L,(HL) 00a3 74 t LD (HL),H 00a4 6f o LD L,A 00a5 20 44 D JR NZ,+68 00a7 72 r LD (HL),D 00a8 69 i LD L,C 00a9 76 v HALT 00aa 65 e LD H,L 00ab 20 41 A JR NZ,+65 00ad 08 EX AF,AF' 00ae 00 NOP ;We have a null terminator this time.. why? 00af 0e 00 LD C,0 00b1 cd b4 01 CALL 01b4 00b4 01 00 00 LD BC,0 00b7 cd cc 01 CALL 01cc 00ba 0e 00 LD C,0 00bc cd bb 01 CALL 01bb 00bf 01 00 fa LD BC,64000 00c2 cd c7 01 CALL 01c7 00c5 cd ec 01 CALL 01ec 00c8 f3 DI 00c9 b7 OR A 00ca 20 3e > JR NZ,+62 00cc ed 4b 02 fa K LD BC,(fa02) 00d0 ed 43 14 fc C LD (fc14),BC 00d4 ed 4b 04 fa K LD BC,(fa04) 00d8 c5 PUSH BC 00d9 ed 4b 06 fa K LD BC,(fa06) 00dd 41 A LD B,C 00de 0e 01 LD C,1 00e0 c5 PUSH BC 00e1 cd bb 01 CALL 01bb 00e4 cd ec 01 CALL 01ec 00e7 f3 DI 00e8 c1 POP BC 00e9 b7 OR A 00ea 20 1e JR NZ,+30 00ec 2a 14 fc * LD HL,(fc14) 00ef 11 80 00 LD DE,128 00f2 19 ADD HL,DE 00f3 22 14 fc \" LD (fc14),HL ;Added the \ to make my editor happy 00f6 05 DEC B 00f7 c8 RET Z 00f8 0c INC C 00f9 3e 28 >( LD A,40 00fb b9 CP C 00fc 20 e2 JR NZ,-30 00fe 0e 10 LD C,16 0100 c5 PUSH BC 0101 01 01 00 LD BC,1 0104 cd cc 01 CALL 01cc 0107 c1 POP BC 0108 18 d6 JR -42 010a cd f1 07 CALL 07f1 010d 0a LD A,(BC) 010e 0d DEC C 010f 0a LD A,(BC) 0110 0d DEC C 0111 07 RLCA ;; Floppy error text 0112 49 I LD C,C 0113 20 63 c JR NZ,+99 0115 61 a LD H,C 0116 6e n LD L,(HL) 0117 6e n LD L,(HL) 0118 6f o LD L,A 0119 74 t LD (HL),H 011a 20 72 r JR NZ,+114 011c 65 e LD H,L 011d 61 a LD H,C 011e 64 d LD H,H 011f 20 79 y JR NZ,+121 0121 6f o LD L,A 0122 75 u LD (HL),L 0123 72 r LD (HL),D 0124 20 64 d JR NZ,+100 0126 69 i LD L,C 0127 73 s LD (HL),E 0128 6b k LD L,E 0129 65 e LD H,L 012a 74 t LD (HL),H 012b 74 t LD (HL),H 012c 65 e LD H,L 012d 2e 00 . LD L,0 ;Another null terminator 012f cd 1e 04 CALL 041e 0132 18 fe JR -2 ;Start of garbage 0134 00 NOP 0135 00 NOP 0136 00 NOP 0137 00 NOP 0138 00 NOP 0139 00 NOP 013a 00 NOP 013b 00 NOP 013c 73 s LD (HL),E 013d ff RST 0x38 013e a2 AND D 013f fe 1a CP 26 0141 fe 2a * CP 42 0143 fe 00 CP 0 0145 00 NOP 0146 00 NOP 0147 00 NOP 0148 00 NOP 0149 00 NOP 014a 00 NOP 014b 00 NOP 014c 00 NOP ;Maybe end of garbage? 014d 73 s LD (HL),E 014e ff RST 0x38 014f a2 AND D 0150 fe 43 C CP 67 0152 fe 53 S CP 83 0154 fe 00 CP 0 0156 12 LD (DE),A 0157 00 NOP 0158 03 INC BC 0159 07 RLCA 015a 00 NOP 015b 52 R LD D,D 015c 00 NOP 015d 1f RRA 015e 00 NOP 015f 80 ADD A,B 0160 00 NOP 0161 08 EX AF,AF' 0162 00 NOP 0163 03 INC BC 0164 00 NOP 0165 28 00 ( JR Z,+0 0167 03 INC BC 0168 07 RLCA 0169 00 NOP 016a c2 00 3f ? JP NZ,3f00 016d 00 NOP 016e f0 RET P 016f 00 NOP 0170 10 00 DJNZ +0 0172 01 00 01 LD BC,256 0175 06 0b LD B,11 0177 10 03 DJNZ +3 0179 08 EX AF,AF' 017a 0d DEC C 017b 12 LD (DE),A 017c 05 DEC B 017d 0a LD A,(BC) 017e 0f RRCA 017f 02 LD (BC),A 0180 07 RLCA 0181 0c INC C 0182 11 04 09 LD DE,2308 0185 0e 21 ! LD C,33 0187 a7 AND A 0188 04 INC B 0189 11 cd fe LD DE,65229 018c 01 87 00 LD BC,135 018f ed b0 LDIR 0191 21 34 01 !4 LD HL,308 0194 11 71 fe q LD DE,65137 0197 01 52 00 R LD BC,82 019a ed b0 LDIR 019c af XOR A 019d 32 09 fc 2 LD (fc09),A 01a0 32 0b fc 2 LD (fc0b),A 01a3 3e 00 > LD A,0 01a5 32 17 fe 2 LD (fe17),A 01a8 3e ff > LD A,255 01aa 32 16 fe 2 LD (fe16),A 01ad 32 18 fe 2 LD (fe18),A 01b0 32 19 fe 2 LD (fe19),A 01b3 c9 RET ;;One of the JPs at the start of the image leads here 01b4 79 y LD A,C ;A=C 01b5 32 00 fc 2 LD (fc00),A ;Copy the value in A/C to (fc00), which is near the top of the memory 01b8 c3 1d 03 JP 031d ;End of function - JP to 031d, and ret from there 01bb 79 y LD A,C ;A=C 01bc 32 03 fc 2 LD (fc03),A ;(fc03) = A, like above function but 3 byte offset 01bf 3a 17 fe : LD A,(fe17) ;A = (fe17) 01c2 b7 OR A ;Probably sets the Z flag(explains next call) 01c3 c2 e0 03 JP NZ,03e0 ;If value @ fe17 is not zero, jp to 03e0 01c6 c9 RET ;we're done 01c7 ed 43 14 fc C LD (fc14),BC ;A lot of functions around this area seem pretty similar: 01cb c9 RET ;Load register into high memory, then jump somewhere else 01cc ed 43 01 fc C LD (fc01),BC 01d0 3a 17 fe : LD A,(fe17) 01d3 b7 OR A 01d4 c2 d4 03 JP NZ,03d4 01d7 c9 RET 01d8 3a 17 fe : LD A,(fe17) 01db b7 OR A 01dc c2 cb 03 JP NZ,03cb 01df 3a 0a fc : LD A,(fc0a) 01e2 b7 OR A 01e3 c2 e9 01 JP NZ,01e9 01e6 32 09 fc 2 LD (fc09),A 01e9 c3 cb 03 JP 03cb 01ec 3a 17 fe : LD A,(fe17) 01ef b7 OR A 01f0 c2 dc fe JP NZ,fedc 01f3 af XOR A 01f4 32 0b fc 2 LD (fc0b),A 01f7 3e 01 > LD A,1 01f9 32 12 fc 2 LD (fc12),A 01fc 32 11 fc 2 LD (fc11),A 01ff 3e 02 > LD A,2 0201 32 13 fc 2 LD (fc13),A 0204 c3 79 02 y JP 0279 0207 3a 17 fe : LD A,(fe17) 020a b7 OR A 020b c2 ed fe JP NZ,feed 020e af XOR A 020f 32 12 fc 2 LD (fc12),A 0212 79 y LD A,C 0213 32 13 fc 2 LD (fc13),A 0216 fe 02 CP 2 0218 c2 32 02 2 JP NZ,0232 021b 3e 08 > LD A,8 021d 32 0b fc 2 LD (fc0b),A 0220 3a 00 fc : LD A,(fc00) 0223 32 0c fc 2 LD (fc0c),A 0226 2a 01 fc * LD HL,(fc01) 0229 22 0d fc " LD (fc0d),HL 022c 3a 03 fc : LD A,(fc03) 022f 32 0f fc 2 LD (fc0f),A 0232 3a 0b fc : LD A,(fc0b) 0235 b7 OR A 0236 ca 71 02 q JP Z,0271 0239 3d = DEC A 023a 32 0b fc 2 LD (fc0b),A 023d 3a 00 fc : LD A,(fc00) 0240 21 0c fc ! LD HL,64524 0243 be CP (HL) 0244 c2 71 02 q JP NZ,0271 0247 21 0d fc ! LD HL,64525 024a cd 11 03 CALL 0311 024d c2 71 02 q JP NZ,0271 0250 3a 03 fc : LD A,(fc03) 0253 21 0f fc ! LD HL,64527 0256 be CP (HL) 0257 c2 71 02 q JP NZ,0271 025a 34 4 INC (HL) 025b 7e ~ LD A,(HL) 025c fe 28 ( CP 40 025e da 6a 02 j JP C,026a 0261 36 00 6 LD (HL),0 0263 2a 0d fc * LD HL,(fc0d) 0266 23 # INC HL 0267 22 0d fc " LD (fc0d),HL 026a af XOR A 026b 32 11 fc 2 LD (fc11),A 026e c3 79 02 y JP 0279 0271 af XOR A 0272 32 0b fc 2 LD (fc0b),A 0275 3c < INC A 0276 32 11 fc 2 LD (fc11),A 0279 af XOR A 027a 32 10 fc 2 LD (fc10),A 027d 3a 03 fc : LD A,(fc03) 0280 b7 OR A 0281 1f RRA 0282 b7 OR A 0283 1f RRA 0284 32 08 fc 2 LD (fc08),A 0287 21 09 fc ! LD HL,64521 028a 7e ~ LD A,(HL) 028b 36 01 6 LD (HL),1 028d b7 OR A 028e ca b5 02 JP Z,02b5 0291 3a 00 fc : LD A,(fc00) 0294 21 04 fc ! LD HL,64516 0297 be CP (HL) 0298 c2 ae 02 JP NZ,02ae 029b 21 05 fc ! LD HL,64517 029e cd 11 03 CALL 0311 02a1 c2 ae 02 JP NZ,02ae 02a4 3a 08 fc : LD A,(fc08) 02a7 21 07 fc ! LD HL,64519 02aa be CP (HL) 02ab ca d2 02 JP Z,02d2 02ae 3a 0a fc : LD A,(fc0a) 02b1 b7 OR A 02b2 c4 39 04 9 CALL NZ,0439 02b5 3a 00 fc : LD A,(fc00) 02b8 32 04 fc 2 LD (fc04),A 02bb 2a 01 fc * LD HL,(fc01) 02be 22 05 fc \" LD (fc05),HL ;Added the \ to make my editor happy 02c1 3a 08 fc : LD A,(fc08) 02c4 32 07 fc 2 LD (fc07),A 02c7 3a 11 fc : LD A,(fc11) 02ca b7 OR A 02cb c4 76 04 v CALL NZ,0476 02ce af XOR A 02cf 32 0a fc 2 LD (fc0a),A 02d2 3a 03 fc : LD A,(fc03) 02d5 e6 03 AND 3 02d7 6f o LD L,A 02d8 26 00 & LD H,0 02da 29 ) ADD HL,HL 02db 29 ) ADD HL,HL 02dc 29 ) ADD HL,HL 02dd 29 ) ADD HL,HL 02de 29 ) ADD HL,HL 02df 29 ) ADD HL,HL 02e0 29 ) ADD HL,HL 02e1 11 16 fc LD DE,64534 02e4 19 ADD HL,DE 02e5 ed 5b 14 fc [ LD DE,(fc14) 02e9 01 80 00 LD BC,128 02ec 3a 12 fc : LD A,(fc12) 02ef b7 OR A 02f0 20 06 JR NZ,+6 02f2 3e 01 > LD A,1 02f4 32 0a fc 2 LD (fc0a),A 02f7 eb EX DE,HL 02f8 cd cd fe CALL fecd 02fb 3a 13 fc : LD A,(fc13) 02fe fe 01 CP 1 0300 3a 10 fc : LD A,(fc10) 0303 c0 RET NZ 0304 b7 OR A 0305 c0 RET NZ 0306 af XOR A 0307 32 0a fc 2 LD (fc0a),A 030a cd 39 04 9 CALL 0439 030d 3a 10 fc : LD A,(fc10) 0310 c9 RET 0311 eb EX DE,HL 0312 21 01 fc ! LD HL,64513 0315 1a LD A,(DE) 0316 be CP (HL) 0317 c0 RET NZ 0318 13 INC DE 0319 23 # INC HL 031a 1a LD A,(DE) 031b be CP (HL) 031c c9 RET 031d 21 00 00 ! LD HL,0 0320 79 y LD A,C 0321 fe 02 CP 2 0323 d0 RET NC 0324 b7 OR A 0325 21 71 fe !q LD HL,65137 0328 28 03 ( JR Z,+3 032a 21 82 fe ! LD HL,65154 032d 3a 16 fe : LD A,(fe16) 0330 b9 CP C 0331 c8 RET Z 0332 79 y LD A,C 0333 32 16 fe 2 LD (fe16),A 0336 b7 OR A 0337 e5 PUSH HL 0338 11 10 00 LD DE,16 033b 19 ADD HL,DE 033c 7e ~ LD A,(HL) 033d 32 17 fe 2 LD (fe17),A 0340 21 19 fe ! LD HL,65049 0343 28 01 ( JR Z,+1 0345 2b + DEC HL 0346 7e ~ LD A,(HL) 0347 fe ff CP 255 0349 28 03 ( JR Z,+3 034b db 11 IN A,(11) 034d 77 w LD (HL),A 034e 79 y LD A,C 034f b7 OR A 0350 21 18 fe ! LD HL,65048 0353 28 01 ( JR Z,+1 0355 23 # INC HL 0356 7e ~ LD A,(HL) 0357 d3 11 OUT (11),A 0359 eb EX DE,HL 035a e1 POP HL 035b fe ff CP 255 035d c0 RET NZ 035e cd ef 03 CALL 03ef 0361 cd d8 01 CALL 01d8 0364 db 1c IN A,(1c) ;read in system port ;; clear bit 5 ;; bit 5 seems to be E38 in the schematic ;; which seems to enable double density disks 0366 e6 df AND 223 ;0b1101 1111 0368 f6 00 OR 0 ;; ;; 1c is the system port ;; used for memory bank selection(!), disk drive control, and printer handshaking 036a d3 1c OUT (1c),A 036c cd c1 03 CALL 03c1 036f 28 0e ( JR Z,+14 0371 db 1c IN A,(1c) 0373 e6 df AND 223 0375 f6 20 OR 32 0377 d3 1c OUT (1c),A 0379 cd c1 03 CALL 03c1 037c c0 RET NZ 037d 18 1e JR +30 037f e5 PUSH HL 0380 d5 PUSH DE 0381 11 00 00 LD DE,0 0384 73 s LD (HL),E 0385 23 # INC HL 0386 72 r LD (HL),D 0387 11 09 00 LD DE,9 038a 19 ADD HL,DE 038b 11 a2 fe LD DE,65186 038e 73 s LD (HL),E 038f 23 # INC HL 0390 72 r LD (HL),D 0391 11 05 00 LD DE,5 0394 19 ADD HL,DE 0395 3e 00 > LD A,0 0397 77 w LD (HL),A 0398 32 17 fe 2 LD (fe17),A 039b 18 1c JR +28 039d e5 PUSH HL 039e d5 PUSH DE 039f 11 b1 fe LD DE,65201 03a2 73 s LD (HL),E 03a3 23 # INC HL 03a4 72 r LD (HL),D 03a5 11 09 00 LD DE,9 03a8 19 ADD HL,DE 03a9 11 93 fe LD DE,65171 03ac 73 s LD (HL),E 03ad 23 # INC HL 03ae 72 r LD (HL),D 03af 11 05 00 LD DE,5 03b2 19 ADD HL,DE 03b3 3e 20 > LD A,32 03b5 77 w LD (HL),A 03b6 32 17 fe 2 LD (fe17),A 03b9 d1 POP DE 03ba e1 POP HL 03bb db 12 IN A,(12) 03bd d3 11 OUT (11),A 03bf 12 LD (DE),A 03c0 c9 RET 03c1 3e c4 > LD A,196 03c3 d3 10 OUT (10),A 03c5 cd 31 04 1 CALL 0431 ;halt 03c8 cb 67 g BIT 4,A 03ca c9 RET 03cb cd ef 03 CALL 03ef 03ce 3e 00 > LD A,0 03d0 d3 10 OUT (10),A 03d2 18 5d ] JR +93 03d4 cd ef 03 CALL 03ef 03d7 79 y LD A,C 03d8 d3 13 OUT (13),A 03da 3e 10 > LD A,16 03dc d3 10 OUT (10),A 03de 18 51 Q JR +81 03e0 79 y LD A,C 03e1 d3 12 OUT (12),A 03e3 c9 RET 03e4 7a z LD A,D 03e5 b3 OR E 03e6 60 ` LD H,B 03e7 69 i LD L,C 03e8 c8 RET Z 03e9 eb EX DE,HL 03ea 09 ADD HL,BC 03eb 6e n LD L,(HL) 03ec 26 00 & LD H,0 03ee c9 RET 03ef e5 PUSH HL 03f0 d5 PUSH DE 03f1 c5 PUSH BC 03f2 3e d0 > LD A,208 03f4 d3 10 OUT (10),A 03f6 cd 0f 04 CALL 040f 03f9 3a 16 fe : LD A,(fe16) 03fc 5f _ LD E,A 03fd db 1c IN A,(1c) 03ff e6 fc AND 252 0401 b3 OR E 0402 3c < INC A 0403 e6 df AND 223 0405 21 17 fe ! LD HL,65047 0408 b6 OR (HL) 0409 d3 1c OUT (1c),A 040b c1 POP BC 040c d1 POP DE 040d e1 POP HL 040e c9 RET ;; Sets system port bit 6 to 0 ;; I believe this turns on the floppy motor. enable_mtr: 040f db 1c IN A,(1c) ;load in system port 0411 cb 77 w BIT 6,A ;check bit 6 (bits go from 0 to 7) 0413 c8 RET Z ;If bit 6 is 0, return(we're done) 0414 cb b7 RES 6,A ;set bit 6 to 0 0416 d3 1c OUT (1c),A ;write it to the system port 0418 06 32 2 LD B,50 041a cd 25 04 % CALL 0425 041d c9 RET ;;; end enable_mtr ;;;Note: Why does enable_mtr check the bit before settings it ;;; But disable_mtr doesn't? disable_mtr: 041e db 1c IN A,(1c) ;load in system port 0420 cb f7 SET 6,A ;set bit 6 to 1 0422 d3 1c OUT (1c),A ;write to system port 0424 c9 RET ;we're done disable_mtr ;; Seems to be some kind of sleep function. ;; parent loop runs B times ;; child loop runs 1670 times per parent loop ;; child is 24 cycles ;; 24*1670=40080 ;; At 2.5MHz, this is about 16ms 0425 11 86 06 LD DE,1670 ;de = 1670 d = 16, e = 70 0428 1b DEC DE ;decrement de 0429 7a z LD A,D ;set a to d 042a b3 OR E ;OR e and a (so OR e and d, and store it in A) 042b c2 28 04 ( JP NZ,0428 ;JMP to 0x0428, if A is not zero (NZ) ;When we get here, A = 0, de = 0 042e 10 f5 DJNZ -11 ;decrement b. If not 0, jmp back 11 to 425 0430 c9 RET ;we're done! 0431 76 v HALT 0432 db 10 IN A,(10) 0434 cb 47 G BIT 0,A 0436 20 fa JR NZ,-6 0438 c9 RET 0439 2e 03 . LD L,3 043b 11 0f 04 LD DE,1039 043e e5 PUSH HL 043f d5 PUSH DE 0440 cd 91 04 CALL 0491 0443 cd f4 fe CALL fef4 0446 32 10 fc 2 LD (fc10),A 0449 d1 POP DE 044a 28 0c ( JR Z,+12 044c 1d DEC E 044d 20 f0 JR NZ,-16 044f 15 DEC D 0450 c8 RET Z 0451 cd cb 03 CALL 03cb 0454 1e 0f LD E,15 0456 18 e7 JR -25 0458 06 00 LD B,0 045a 3e 88 > LD A,136 045c d3 10 OUT (10),A 045e 76 v HALT 045f db 13 IN A,(13) 0461 10 fb DJNZ -5 0463 76 v HALT 0464 db 13 IN A,(13) 0466 10 fb DJNZ -5 0468 cd 31 04 1 CALL 0431 046b e6 9c AND 156 046d e1 POP HL 046e c8 RET Z 046f 2d - DEC L 0470 20 c9 JR NZ,-55 0472 3e ff > LD A,255 0474 b7 OR A 0475 c9 RET 0476 11 0f 04 LD DE,1039 0479 d5 PUSH DE 047a cd 91 04 CALL 0491 047d cd e3 fe CALL fee3 0480 32 10 fc 2 LD (fc10),A 0483 d1 POP DE 0484 c8 RET Z 0485 1d DEC E 0486 20 f1 JR NZ,-15 0488 15 DEC D 0489 c8 RET Z 048a cd cb 03 CALL 03cb 048d 1e 0f LD E,15 048f 18 e8 JR -24 0491 3a 04 fc : LD A,(fc04) 0494 4f O LD C,A 0495 cd 1d 03 CALL 031d 0498 ed 4b 05 fc K LD BC,(fc05) 049c cd d4 03 CALL 03d4 049f 3a 07 fc : LD A,(fc07) 04a2 4f O LD C,A 04a3 cd e0 03 CALL 03e0 04a6 c9 RET ;; copies a section of RAM into the secondary bank ;; (I think - I don't know which bank is which) ;; Bank B is VRAM, so this function will write to the screen ;; BC - The # of bytes to copy ;; HL - The start of the string to print ;; DE - The char address to start printing at 04a7 db 1c IN A,(1c) ;read in system port 04a9 cb bf RES 7,A ;set bit 7 to 0 (bank switch) 04ab d3 1c OUT (1c),A ;write to system port ;; ldir is a pretty big instruction. ;; First, it copies 1 byte from (hl) to (de) ;; Second, it increments hl and de ;; Third, decrements bc ;; Forth, it returns to step 1, if b is not 0 ;; To summarize, it's memcpy but built into the hardware ;; (Also, interrupts can fire while it is executing!) 04ad ed b0 LDIR 04af db 1c IN A,(1c) ;read in system port (probably in case interrupt has fired in the meantime) 04b1 cb ff SET 7,A ;set bit 7 to 1 (bank switch) 04b3 d3 1c OUT (1c),A ;write to system port 04b5 c9 RET ;we're done! 04b6 2a 14 fc * LD HL,(fc14) 04b9 06 01 LD B,1 04bb 18 05 JR +5 04bd 21 16 fc ! LD HL,64534 04c0 06 04 LD B,4 04c2 11 88 9c LD DE,40072 04c5 18 0f JR +15 04c7 2a 14 fc * LD HL,(fc14) 04ca 06 01 LD B,1 04cc 18 05 JR +5 04ce 21 16 fc ! LD HL,64534 04d1 06 04 LD B,4 04d3 11 ac fc LD DE,64684 04d6 cd ef 03 CALL 03ef 04d9 f3 DI 04da db 1c IN A,(1c) 04dc cb bf RES 7,A 04de d3 1c OUT (1c),A 04e0 e5 PUSH HL 04e1 21 66 00 !f LD HL,102 04e4 7e ~ LD A,(HL) 04e5 08 EX AF,AF' 04e6 36 c9 6 LD (HL),201 04e8 e1 POP HL 04e9 78 x LD A,B 04ea 01 13 80 LD BC,32787 04ed cb 47 G BIT 0,A 04ef 20 02 JR NZ,+2 04f1 06 00 LD B,0 04f3 fe 01 CP 1 04f5 f5 PUSH AF 04f6 7b { LD A,E 04f7 fe ac CP 172 04f9 28 11 ( JR Z,+17 04fb d3 10 OUT (10),A 04fd f1 POP AF 04fe 28 05 ( JR Z,+5 0500 76 v HALT 0501 ed a2 INI 0503 20 fb JR NZ,-5 0505 76 v HALT 0506 ed a2 INI 0508 20 fb JR NZ,-5 050a 18 0f JR +15 050c d3 10 OUT (10),A 050e f1 POP AF 050f 28 05 ( JR Z,+5 0511 76 v HALT 0512 ed a3 OUTI 0514 20 fb JR NZ,-5 0516 76 v HALT 0517 ed a3 OUTI 0519 20 fb JR NZ,-5 051b 08 EX AF,AF' 051c 32 66 00 2f LD (0066),A 051f db 1c IN A,(1c) 0521 cb ff SET 7,A 0523 d3 1c OUT (1c),A 0525 fb EI 0526 cd 31 04 1 CALL 0431 0529 a2 AND D 052a c8 RET Z 052b 3e 01 > LD A,1 052d c9 RET 052e 1c INC E 052f 07 RLCA 0530 18 0c JR +12 0532 05 DEC B 0533 07 RLCA 0534 04 INC B 0535 07 RLCA 0536 44 D LD B,H 0537 07 RLCA 0538 03 INC BC 0539 07 RLCA 053a c1 POP BC 053b 07 RLCA 053c 05 DEC B 053d 07 RLCA 053e e8 RET PE 053f 07 RLCA 0540 01 07 00 LD BC,7 0543 06 18 LD B,24 0545 00 NOP 0546 05 DEC B 0547 06 04 LD B,4 ;Obviously garbage. Why would you load values to a register 0549 06 44 D LD B,68 ;And immediately overwrite them? 054b 06 03 LD B,3 054d 06 e1 LD B,225 054f 06 05 LD B,5 0551 06 e8 LD B,232 0553 06 01 LD B,1 0555 06 00 LD B,0 0557 1d DEC E 0558 03 INC BC 0559 1c INC E 055a 81 ADD A,C 055b 1d DEC E 055c cf RST 0x08 055d 1d DEC E 055e 0c INC C 055f 09 ADD HL,BC 0560 03 INC BC 0561 09 ADD HL,BC 0562 0f RRCA 0563 0b DEC BC 0564 03 INC BC 0565 0b DEC BC 0566 4f O LD C,A ;; second function called on boot 0567 21 2e 05 !. LD HL,1326 ;set HL to 1326 056a 46 F LD B,(HL) ;set B to *HL = val at 1326 = 0x1C 056b 23 # INC HL ;HL++ 056c 4e N LD C,(HL) ;set C to *HL = val at 1327 = 0x07 056d 23 # INC HL ;HL++ 056e 7e ~ LD A,(HL) ;set A to val at 1328 = 0x18 ;; the first time we get here. ;; c=12 a=5 ;; what is on port 12? 056f ed 79 y OUT (c),A ;write 0x18 to 0x07 0571 10 f8 DJNZ -8 0573 c9 RET ;; Returns A = 0 if there's nothing in the keyboard buffer ;; Returns A = 255 if there's a char 0574 db 07 IN A,(07) ;keyboard control register 0576 e6 01 AND 1 ;RX character available 0578 c8 RET Z ;return A = 0 if rx not available 0579 3e ff > LD A,255 057b c9 RET ;return A = 255 057c cd 74 05 t CALL 0574 057f 28 fb ( JR Z,-5 0581 db 05 IN A,(05) 0583 cd 91 05 CALL 0591 0586 c9 RET ;; Digging through the schematic, I found that the keyboard and serial port connect through the same chip ;; Port is on A, keyboard is on B (Both are serial) ;; I was also able to find the datasheet for the chip(MK3884) ;; The datasheet is in one of the PDFs in the git repository ;; (1981 Mostek Z80 Microcomputer data book) ;; Each serial connection has a data register and a control register ;; They are selected like this: ;; PORT | A0 | A1 | Desc ;; 04 | 0 | 0 | Serial, data register ;; 05 | 0 | 1 | Keyboard, data register ;; 06 | 1 | 0 | Serial, control register ;; 07 | 1 | 1 | Keyboard, control register ;; ;; Loop until keyboard TX buffer is empty. ;; Then, we write 1 byte to the keyboard 0587 db 07 IN A,(07) ;Keyboard, control register 0589 e6 04 AND 4 ;Set all the bits to 0 except for bit 2 ;Bit 2 = TX data buffer empty 058b 28 fa ( JR Z,-6 ;If TX buffer not empty, jmp back to 0x587 058d 79 y LD A,C 058e d3 05 OUT (05),A ;KEYBOARD data register 0590 c9 RET ;We're done 0591 21 a6 05 ! LD HL,1446 0594 01 13 00 LD BC,19 0597 ed b1 CPIR 0599 c0 RET NZ 059a 11 a6 05 LD DE,1446 059d b7 OR A 059e ed 52 R SBC HL,DE 05a0 11 b8 05 LD DE,1464 05a3 19 ADD HL,DE 05a4 7e ~ LD A,(HL) 05a5 c9 RET 05a6 f1 POP AF 05a7 f2 f3 f4 JP P,f4f3 05aa b1 OR C 05ab c0 RET NZ 05ac c1 POP BC 05ad c2 d0 d1 JP NZ,d1d0 05b0 d2 e1 e2 JP NC,e2e1 05b3 e3 EX (SP),HL 05b4 e4 d3 c3 CALL PO,c3d3 05b7 b2 OR D 05b8 ff RST 0x38 05b9 80 ADD A,B 05ba 81 ADD A,C 05bb 82 ADD A,D 05bc 83 ADD A,E 05bd 84 ADD A,H 05be 85 ADD A,L 05bf 86 ADD A,(HL) 05c0 87 ADD A,A 05c1 88 ADC A,B 05c2 89 ADC A,C 05c3 8a ADC A,D 05c4 8b ADC A,E 05c5 8c ADC A,H 05c6 8d ADC A,L 05c7 8e ADC A,(HL) 05c8 8f ADC A,A 05c9 90 SUB B 05ca 91 SUB C 05cb db 06 IN A,(06) 05cd e6 01 AND 1 05cf 18 1c JR +28 05d1 cd cb 05 CALL 05cb 05d4 28 fb ( JR Z,-5 05d6 db 04 IN A,(04) 05d8 c9 RET ;; Writes a byte to the serial port. 05d9 db 06 IN A,(06) ;SERIAL STATUS 05db e6 04 AND 4 ;b100 ;; Serial status register must have bit 2 enabled = TX buffer empty ;; otherwise, we jp to 0x5d9 and loop ;; = infinite loop until TX buffer is cleared 05dd 28 fa ( JR Z,-6 05df 79 y LD A,C ;At this point, TX buffer is empty 05e0 d3 04 OUT (04),A ;SERIAL DATA REGISTER - write A 05e2 c9 RET ;We're done 05e3 db 06 IN A,(06) 05e5 e6 04 AND 4 05e7 18 04 JR +4 05e9 db 1c IN A,(1c) 05eb cb 5f _ BIT 3,A 05ed c8 RET Z 05ee 3e ff > LD A,255 05f0 c9 RET 05f1 cd e9 05 CALL 05e9 05f4 28 fb ( JR Z,-5 05f6 79 y LD A,C 05f7 d3 08 OUT (08),A 05f9 db 1c IN A,(1c) 05fb cb e7 SET 4,A 05fd d3 1c OUT (1c),A 05ff cb a7 RES 4,A 0601 d3 1c OUT (1c),A 0603 c9 RET 0604 3e 20 > LD A,32 0606 32 6d fe 2m LD (fe6d),A 0609 cd c3 06 CALL 06c3 060c 22 6e fe "n LD (fe6e),HL 060f af XOR A 0610 32 6c fe 2l LD (fe6c),A 0613 3e 17 > LD A,23 0615 d3 14 OUT (14),A 0617 3e 7f > LD A,127 0619 32 70 fe 2p LD (fe70),A 061c c9 RET 061d 3a 6c fe :l LD A,(fe6c) 0620 b7 OR A 0621 c2 3a 07 : JP NZ,073a 0624 3e 07 > LD A,7 0626 b9 CP C 0627 20 05 JR NZ,+5 0629 0e 04 LD C,4 062b c3 87 05 JP 0587 062e cd 21 07 ! CALL 0721 0631 11 94 07 LD DE,1940 0634 d5 PUSH DE 0635 79 y LD A,C 0636 fe 0a CP 10 0638 28 64 (d JR Z,+100 063a fe 0d CP 13 063c ca 2f 07 / JP Z,072f 063f fe 08 CP 8 0641 28 61 (a JR Z,+97 0643 fe 0c CP 12 0645 28 63 (c JR Z,+99 0647 fe 0b CP 11 0649 28 67 (g JR Z,+103 064b fe 1b CP 27 064d ca 34 07 4 JP Z,0734 0650 fe 18 CP 24 0652 ca fc 06 JP Z,06fc 0655 fe 17 CP 23 0657 28 7f ( JR Z,+127 0659 fe 1a CP 26 065b 28 66 (f JR Z,+102 065d fe 1e CP 30 065f 28 73 (s JR Z,+115 0661 fe 60 ` CP 96 0663 38 04 8 JR C,+4 0665 3a 70 fe :p LD A,(fe70) 0668 a1 AND C 0669 77 w LD (HL),A 066a 23 # INC HL 066b 7d } LD A,L 066c e6 7f AND 127 066e fe 50 P CP 80 0670 d8 RET C 0671 cd 2f 07 / CALL 072f 0674 18 28 ( JR +40 0676 11 ff 3b ; LD DE,15359 0679 7a z LD A,D 067a bc CP H 067b 38 04 8 JR C,+4 067d c0 RET NZ 067e 7b { LD A,E 067f bd CP L 0680 d0 RET NC 0681 06 17 LD B,23 0683 21 80 30 ! 0 LD HL,12416 0686 11 00 30 0 LD DE,12288 0689 c5 PUSH BC 068a 01 50 00 P LD BC,80 068d ed b0 LDIR 068f 01 30 00 0 LD BC,48 0692 09 ADD HL,BC 0693 eb EX DE,HL 0694 09 ADD HL,BC 0695 eb EX DE,HL 0696 c1 POP BC 0697 10 f0 DJNZ -16 0699 21 80 3b ! ; LD HL,15232 069c 18 5e ^ JR +94 069e 11 80 00 LD DE,128 06a1 19 ADD HL,DE 06a2 18 d2 JR -46 06a4 7d } LD A,L 06a5 e6 7f AND 127 06a7 c8 RET Z 06a8 2b + DEC HL 06a9 c9 RET 06aa 7d } LD A,L 06ab e6 7f AND 127 06ad fe 4f O CP 79 06af d0 RET NC 06b0 23 # INC HL 06b1 c9 RET 06b2 e5 PUSH HL 06b3 11 80 ff LD DE,65408 06b6 19 ADD HL,DE 06b7 e5 PUSH HL 06b8 b7 OR A 06b9 11 00 30 0 LD DE,12288 06bc ed 52 R SBC HL,DE 06be e1 POP HL 06bf d1 POP DE 06c0 d0 RET NC 06c1 eb EX DE,HL 06c2 c9 RET 06c3 21 00 30 ! 0 LD HL,12288 06c6 11 01 30 0 LD DE,12289 06c9 01 ff 0b LD BC,3071 06cc 36 20 6 LD (HL),32 06ce ed b0 LDIR 06d0 21 00 30 ! 0 LD HL,12288 06d3 c9 RET 06d4 21 00 30 ! 0 LD HL,12288 06d7 c9 RET 06d8 e5 PUSH HL 06d9 cd fc 06 CALL 06fc 06dc 11 80 00 LD DE,128 06df 7d } LD A,L 06e0 e6 80 AND 128 06e2 6f o LD L,A 06e3 19 ADD HL,DE 06e4 3e 3c >< LD A,60 06e6 bc CP H 06e7 28 11 ( JR Z,+17 06e9 5d ] LD E,L 06ea 54 T LD D,H 06eb b7 OR A 06ec 21 ff 3b ! ; LD HL,15359 06ef ed 52 R SBC HL,DE 06f1 4d M LD C,L 06f2 44 D LD B,H 06f3 62 b LD H,D 06f4 6b k LD L,E 06f5 13 INC DE 06f6 36 20 6 LD (HL),32 06f8 ed b0 LDIR 06fa e1 POP HL 06fb c9 RET 06fc 7d } LD A,L 06fd e6 7f AND 127 06ff fe 4f O CP 79 0701 38 03 8 JR C,+3 0703 36 20 6 LD (HL),32 0705 c9 RET 0706 e5 PUSH HL 0707 e5 PUSH HL 0708 7d } LD A,L 0709 e6 80 AND 128 070b 6f o LD L,A 070c 11 4f 00 O LD DE,79 070f 19 ADD HL,DE 0710 d1 POP DE 0711 d5 PUSH DE 0712 b7 OR A 0713 ed 52 R SBC HL,DE 0715 4d M LD C,L 0716 44 D LD B,H 0717 e1 POP HL 0718 5d ] LD E,L 0719 54 T LD D,H 071a 13 INC DE 071b 36 20 6 LD (HL),32 071d ed b0 LDIR 071f e1 POP HL 0720 c9 RET 0721 2a 6e fe *n LD HL,(fe6e) 0724 7e ~ LD A,(HL) 0725 fe df CP 223 0727 3e 20 > LD A,32 0729 20 01 JR NZ,+1 072b 77 w LD (HL),A 072c cb be RES 7,(HL) 072e c9 RET 072f 7d } LD A,L 0730 e6 80 AND 128 0732 6f o LD L,A 0733 c9 RET 0734 3e 01 > LD A,1 0736 32 6c fe 2l LD (fe6c),A 0739 c9 RET 073a 21 a1 07 ! LD HL,1953 073d e5 PUSH HL 073e 21 6c fe !l LD HL,65132 0741 36 00 6 LD (HL),0 0743 fe 01 CP 1 0745 20 19 JR NZ,+25 0747 79 y LD A,C 0748 cb bf RES 7,A 074a fe 47 G CP 71 074c 28 54 (T JR Z,+84 074e fe 41 A CP 65 0750 28 56 (V JR Z,+86 0752 fe 52 R CP 82 0754 28 58 (X JR Z,+88 0756 fe 45 E CP 69 0758 28 66 (f JR Z,+102 075a fe 3d = CP 61 075c c0 RET NZ 075d 36 02 6 LD (HL),2 075f c9 RET 0760 fe 02 CP 2 0762 20 07 JR NZ,+7 0764 79 y LD A,C 0765 32 6d fe 2m LD (fe6d),A 0768 36 03 6 LD (HL),3 076a c9 RET 076b fe 03 CP 3 076d c0 RET NZ 076e cd 21 07 ! CALL 0721 0771 e1 POP HL 0772 21 00 30 ! 0 LD HL,12288 0775 79 y LD A,C 0776 d6 20 SUB 32 0778 d6 50 P SUB 80 077a 30 fc 0 JR NC,-4 077c c6 50 P ADD A,80 077e 6f o LD L,A 077f 3a 6d fe :m LD A,(fe6d) 0782 d6 20 SUB 32 0784 d6 18 SUB 24 0786 30 fc 0 JR NC,-4 0788 c6 18 ADD A,24 078a 11 80 00 LD DE,128 078d ca 94 07 JP Z,0794 0790 19 ADD HL,DE 0791 3d = DEC A 0792 18 f9 JR -7 0794 7e ~ LD A,(HL) 0795 fe 20 CP 32 0797 20 02 JR NZ,+2 0799 3e df > LD A,223 079b cb ff SET 7,A 079d 77 w LD (HL),A 079e 22 6e fe "n LD (fe6e),HL 07a1 c9 RET 07a2 3e 1f > LD A,31 07a4 32 70 fe 2p LD (fe70),A 07a7 c9 RET 07a8 3e 7f > LD A,127 07aa 32 70 fe 2p LD (fe70),A 07ad c9 RET 07ae e1 POP HL 07af cd d7 07 CALL 07d7 07b2 d5 PUSH DE 07b3 28 02 ( JR Z,+2 07b5 ed b0 LDIR 07b7 21 80 3b ! ; LD HL,15232 07ba cd fc 06 CALL 06fc 07bd e1 POP HL 07be 18 d4 JR -44 07c0 e1 POP HL 07c1 cd d7 07 CALL 07d7 07c4 d5 PUSH DE 07c5 28 08 ( JR Z,+8 07c7 11 ff 3b ; LD DE,15359 07ca 21 7f 3b ! ; LD HL,15231 07cd ed b8 LDDR 07cf e1 POP HL 07d0 e5 PUSH HL 07d1 cd fc 06 CALL 06fc 07d4 e1 POP HL 07d5 18 bd JR -67 07d7 cd 21 07 ! CALL 0721 07da cd 2f 07 / CALL 072f 07dd e5 PUSH HL 07de eb EX DE,HL 07df 21 80 3b ! ; LD HL,15232 07e2 b7 OR A 07e3 ed 52 R SBC HL,DE 07e5 44 D LD B,H 07e6 4d M LD C,L 07e7 e1 POP HL 07e8 e5 PUSH HL 07e9 11 80 00 LD DE,128 07ec 19 ADD HL,DE 07ed d1 POP DE 07ee 78 x LD A,B 07ef b1 OR C 07f0 c9 RET 07f1 e3 EX (SP),HL 07f2 7e ~ LD A,(HL) 07f3 23 # INC HL 07f4 e3 EX (SP),HL 07f5 b7 OR A 07f6 c8 RET Z 07f7 4f O LD C,A 07f8 cd 1d 06 CALL 061d 07fb 18 f4 JR -12 07fd ff RST 0x38 07fe ff RST 0x38 07ff ff RST 0x38 0800 00 NOP