; Disassembly of the Klinger CC 1.1 ROM ; ; Tom Trebisky 12-9-2019 ; ; This is code for a 65SC02 chip (a 6502 without bit instructions) ; This unit has chips with date codes of 1988 and 1989 ; The 6502 was available in 1978 or earlier. ; ; ----------------------------- ; ; Here is a 6502 refresher: ; ; The 6502 is pretty much a single register 8 bit machine. ; The "A" register is the accumulator. ; There are also 8 bit index registers X and Y. ; Ther is an 8 bit stack pointer "S". ; The PC is a 16 bit register. ; ; The TXS instruction can be used to initialize the stack ; (this is never done in this code) ; The stack lives in page 1 ( 0100 to 01ff ) ; but the value of S is unknown after power on in many variants ; This code never seems to initialize it, so who knows. ; This code never directly does anything with the stack ; (no calls/returns/pushes/pops) ; However, it does allow IRQ and that will put 3 things ; on the stack (and remove them on RTI), so there must ; be a valid stack. ; This chip variant must set the S to zero on power up. ; Now I, mind you, would have added the two instructions ; to ensure this, especially with plenty of space in the ROM. ; But this product works, so apparently the hardware must ; ensure that S gets initialized on startup. ; ; Some 6502 instructions that aren't obvious at a glance. ; ; BIT - compares A to memory location ?? ; CMP - compares A to an immediate value or zero page item ?? ; ; A first guess at the address map. ; ; 0000 to 7fff - ram (128 bytes duplicated) ; 8000 to bfff - device registers (duplicate) ; c000 to ffff - eprom (duplicate) ; ; In other words only A15 and A14 are involved in ; the address decode. ?? Z00 .equ $00 Z01 .equ $01 Z02 .equ $02 Z08 .equ $08 Z30 .equ $30 Z31 .equ $31 Z32 .equ $32 Z33 .equ $33 ; These look like device registers. D8004 .equ $8004 D8005 .equ $8005 D8006 .equ $8006 D8007 .equ $8007 D8008 .equ $8008 D8009 .equ $8009 D800a .equ $800a D800b .equ $800b .org $f800 ; **************** RESET - execution starts here. f800 a9 0a RESET: LDA #$0a ; A = 0x0A f802 85 00 STA Z00 f804 a9 0d LDA #$0d ; A = 0x0D f806 85 01 STA Z01 f808 a9 00 LDA #$00 ; A = 0 f80a 85 30 STA Z30 f80c 85 31 STA Z31 f80e 85 32 STA Z32 f810 85 33 STA Z33 f812 8d 05 80 STA D8005 f815 8d 07 80 STA D8007 f818 8d 09 80 STA D8009 f81b 8d 0b 80 STA D800b f81e 8d 04 80 STA D8004 f821 8d 08 80 STA D8008 f824 8d 0a 80 STA D800a f827 a9 7f LDA #$7f ; A = 0x7f f829 8d 06 80 STA D8006 f82c a9 3c LDA #$3c ; 60 < f82e 8d 07 80 STA D8007 f831 a9 36 LDA #$36 ; 54 6 f833 8d 09 80 STA D8009 f836 a9 36 LDA #$36 ; 54 6 f838 8d 0b 80 STA D800b f83b a9 37 LDA #$37 ; 55 7 f83d 8d 05 80 STA D8005 f840 ad 06 80 LDA D8006 f843 78 Lf843: SEI ; disable interrupts f844 ad 0a 80 LDA D800a ; read device register f847 49 13 EOR #$13 ; invert the masked bits f849 25 31 AND Z31 f84b c5 32 CMP Z32 f84d d0 2c BNE Lf87b f84f 58 CLI ; enable interrupts f850 2c 07 80 BIT D8007 f853 10 ee BPL Lf843 ; loop back f855 2c 04 80 BIT D8004 f858 ad 06 80 LDA D8006 f85b 70 2c BVS Lf889 f85d a5 30 LDA Z30 f85f c9 00 CMP #$00 ; 0 . f861 f0 72 BEQ Lf8d5 f863 c9 01 CMP #$01 ; 1 . f865 d0 03 BNE Lf86a ; just below ... f867 4c a6 f9 JMP Lf9a6 f86a c9 02 Lf86a: CMP #$02 ; 2 . f86c d0 03 BNE Lf871 ; just below ... f86e 4c b6 f9 JMP Lf9b6 f871 c9 03 Lf871: CMP #$03 ; 3 . f873 d0 03 BNE Lf878 f875 4c c8 f9 JMP Lf9c8 f878 4c db f9 Lf878: JMP Lf9db f87b 85 32 Lf87b: STA Z32 f87d c9 00 CMP #$00 ; 0 . f87f f0 c2 BEQ Lf843 f881 a9 3e LDA #$3e ; 62 > f883 8d 0b 80 STA D800b f886 4c 43 f8 JMP Lf843 f889 ad 0a 80 Lf889: LDA D800a f88c 49 0f EOR #$0f ; 15 . f88e 29 3f AND #$3f ; 63 ? f890 8d 06 80 STA D8006 f893 a9 34 LDA #$34 ; 52 4 f895 8d 07 80 STA D8007 f898 2c 06 80 Lf898: BIT D8006 f89b 10 fb BPL Lf898 f89d a9 3c LDA #$3c ; 60 < f89f 8d 07 80 STA D8007 f8a2 2c 04 80 Lf8a2: BIT D8004 f8a5 70 fb BVS Lf8a2 f8a7 a9 36 LDA #$36 ; 54 6 f8a9 8d 0b 80 STA D800b f8ac 4c 43 f8 JMP Lf843 f8af 2c 04 80 Lf8af: BIT D8004 f8b2 30 8f BMI Lf843 f8b4 2c 06 80 BIT D8006 f8b7 30 f6 BMI Lf8af f8b9 b5 00 LDA Z00,X f8bb 8d 06 80 STA D8006 f8be a9 34 LDA #$34 ; 52 4 f8c0 8d 07 80 STA D8007 f8c3 2c 06 80 Lf8c3: BIT D8006 f8c6 10 fb BPL Lf8c3 f8c8 a9 3c LDA #$3c ; 60 < f8ca 8d 07 80 STA D8007 f8cd ca DEX f8ce e0 ff CPX #$ff ; 255 . f8d0 d0 dd BNE Lf8af f8d2 4c 43 f8 JMP Lf843 f8d5 a0 00 Lf8d5: LDY #$00 ; 0 . f8d7 ad 08 80 LDA D8008 f8da a9 3e Lf8da: LDA #$3e ; 62 > f8dc 8d 09 80 STA D8009 f8df a9 36 LDA #$36 ; 54 6 f8e1 ea NOP f8e2 8d 09 80 Lf8e2: STA D8009 f8e5 2c 09 80 BIT D8009 f8e8 10 f8 BPL Lf8e2 f8ea ad 08 80 LDA D8008 f8ed 0a ASL f8ee 4a LSR f8ef 4a LSR f8f0 4a LSR f8f1 4a LSR f8f2 4a LSR f8f3 aa TAX f8f4 ad 08 80 LDA D8008 f8f7 29 0f AND #$0f ; 15 . f8f9 09 30 ORA #$30 ; 48 0 f8fb 95 02 STA Z02,X f8fd c8 INY f8fe c0 06 CPY #$06 ; 6 . f900 d0 d8 BNE Lf8da f902 ad 08 80 LDA D8008 f905 0a ASL f906 a9 2b LDA #$2b ; 43 + f908 b0 02 BCS Lf90c f90a a9 2d LDA #$2d ; 45 - f90c 85 08 Lf90c: STA Z08 f90e a2 08 LDX #$08 ; 8 . f910 4c af f8 JMP Lf8af ; **************** IRQ f913 a9 3f IRQ: LDA #$3f ; 63 ? f915 8d 05 80 STA D8005 f918 ad 04 80 LDA D8004 f91b 29 3f AND #$3f ; 63 ? f91d 24 33 BIT Z33 f91f 30 0b BMI Lf92c f921 c9 16 CMP #$16 ; 22 . f923 d0 2d BNE Lf952 f925 a9 ff LDA #$ff ; 255 . f927 85 33 STA Z33 f929 4c 52 f9 JMP Lf952 f92c c9 30 Lf92c: CMP #$30 ; 48 0 f92e 30 22 BMI Lf952 f930 29 0f AND #$0f ; 15 . f932 c9 05 CMP #$05 ; 5 . f934 f0 35 BEQ Lf96b f936 c9 06 CMP #$06 ; 6 . f938 f0 3c BEQ Lf976 f93a c9 07 CMP #$07 ; 7 . f93c f0 43 BEQ Lf981 f93e c9 08 CMP #$08 ; 8 . f940 f0 4a BEQ Lf98c f942 c9 09 CMP #$09 ; 9 . f944 f0 51 BEQ Lf997 f946 85 30 STA Z30 f948 c9 00 CMP #$00 ; 0 . f94a d0 02 BNE Lf94e f94c 85 31 STA Z31 f94e a9 00 Lf94e: LDA #$00 ; 0 . f950 85 33 STA Z33 f952 a9 37 Lf952: LDA #$37 ; 55 7 f954 8d 05 80 STA D8005 f957 40 RTI f958 ad 0a 80 Lf958: LDA D800a f95b 49 13 EOR #$13 ; 19 . f95d 25 31 AND Z31 f95f 85 32 STA Z32 f961 a9 00 LDA #$00 ; 0 . f963 85 33 STA Z33 f965 a9 37 LDA #$37 ; 55 7 f967 8d 05 80 STA D8005 f96a 40 RTI f96b a9 07 Lf96b: LDA #$07 ; 7 . f96d 85 31 STA Z31 f96f a9 00 LDA #$00 ; 0 . f971 85 30 STA Z30 f973 4c 58 f9 JMP Lf958 f976 a9 0b Lf976: LDA #$0b ; 11 . f978 85 31 STA Z31 f97a a9 00 LDA #$00 ; 0 . f97c 85 30 STA Z30 f97e 4c 58 f9 JMP Lf958 f981 a9 13 Lf981: LDA #$13 ; 19 . f983 85 31 STA Z31 f985 a9 00 LDA #$00 ; 0 . f987 85 30 STA Z30 f989 4c 58 f9 JMP Lf958 f98c a9 20 Lf98c: LDA #$20 ; 32 f98e 85 31 STA Z31 f990 a9 05 LDA #$05 ; 5 . f992 85 30 STA Z30 f994 4c 58 f9 JMP Lf958 f997 a9 40 Lf997: LDA #$40 ; 64 @ f999 8d 06 80 STA D8006 f99c d0 4e BNE Lf9ec f99e a9 00 Lf99e: LDA #$00 ; 0 . f9a0 8d 06 80 STA D8006 f9a3 4c 58 f9 JMP Lf958 ; END of interrupt code ?? f9a6 ad 0a 80 Lf9a6: LDA D800a f9a9 49 03 EOR #$03 ; 3 . f9ab 29 03 AND #$03 ; 3 . f9ad 09 30 ORA #$30 ; 48 0 f9af 85 02 STA Z02 f9b1 a2 02 LDX #$02 ; 2 . f9b3 4c af f8 JMP Lf8af f9b6 ad 0a 80 Lf9b6: LDA D800a f9b9 4a LSR f9ba 4a LSR f9bb 49 01 EOR #$01 ; 1 . f9bd 29 01 AND #$01 ; 1 . f9bf 09 30 ORA #$30 ; 48 0 f9c1 85 02 STA Z02 f9c3 a2 02 LDX #$02 ; 2 . f9c5 4c af f8 JMP Lf8af f9c8 ad 0a 80 Lf9c8: LDA D800a f9cb 4a LSR f9cc 4a LSR f9cd 4a LSR f9ce 49 01 EOR #$01 ; 1 . f9d0 29 03 AND #$03 ; 3 . f9d2 09 30 ORA #$30 ; 48 0 f9d4 85 02 STA Z02 f9d6 a2 02 LDX #$02 ; 2 . f9d8 4c af f8 JMP Lf8af f9db ad 0a 80 Lf9db: LDA D800a f9de 4a LSR f9df 4a LSR f9e0 4a LSR f9e1 4a LSR f9e2 4a LSR f9e3 09 30 ORA #$30 ; 48 0 f9e5 85 02 STA Z02 f9e7 a2 02 LDX #$02 ; 2 . f9e9 4c af f8 JMP Lf8af f9ec ea Lf9ec: NOP f9ed ea NOP f9ee ea NOP f9ef ea NOP f9f0 ea NOP f9f1 ea NOP f9f2 ea NOP f9f3 ea NOP f9f4 ea NOP f9f5 ea NOP f9f6 ea NOP f9f7 ea NOP f9f8 ea NOP f9f9 ea NOP f9fa ea NOP f9fb ea NOP f9fc d0 a0 BNE Lf99e f9fe 00 BRK f9ff .byte $00,$00,$00,$00,$00,$00,$00,$00 ; "........" fa07 .byte $00,$00,$00,$00,$00,$00,$00,$00 ; "........" ..... ..... ..... ..... ffe7 .byte $00,$00,$00,$00,$00,$00,$00,$00 ; "........" ffef .byte $00,$00,$00,$00,$00,$00,$00,$00 ; "........" fff7 .byte $00,$00,$00 ; The last 6 bytes in the ROM are the reset/interrupt vectors fffa .byte $00, $00 ; NMI - unused fffc .byte $00, $f8 ; RESET - to $f800 fffe .byte $13, $f9 ; IRQ - to $f913 ; THE END