Update
CHECK64 is an updated package for 586220/781220/789010 diagnostics, see Diagnostic Carts and Manuals.
This post spawned out of a discussion at a facebook group about the commodore diagnostics reporting errors when using custom kernals. I decided to modify the kernal detection routine to identify good known kernals from a checksum table. Thanks to Jonny Hylander, Fredric QJ BlÄholtz and Krister Andersson for ideas and suggestions.
586220+ : Initial version. Disassembly and kernel identification routines by www.worldofjani.com.
586220+ v0.4 : Marty/Radwar sent a huge list of kernal checksums. This version is able to identify a staggering 49 different kernals, for example Professional Dos, RapiDos, DolphinDos and Speeddos. Download the v0.4 sourcecode for a full list.
586220++ v0.5 SX-64 Tape Port check removal : KiWi at www.SX-64.de sent me a version which works correctly on the SX-64. Scroll down for the download and sourcecode. See his page here.
586220++ v0.5 Expanded window for paddle test by Sven Arke. Klick here.
586220* Proper chip number display for SX-64 and C-64 by Ted Saari. Readme.
See Diagnostic Carts and Manuals for information about the harness for this ROM.
2020-06 : giox sent me an updated standalone program which identifies 137 kernals. There is an ID clash (which can be expected at some point) for 901246-01(4064 Kernal) and Armageddon.
Background.
The diagnostic 586220 does a checksum on the kernal ROM to verify if it is ok. It will only identify the original CBM ROMs. All other (even good, for example JiffyDos) kernals will be marked as “BAD”.
The 586220 was used since i have done an reassembly/disassembly of it earlier.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$892f ;KERNAL ROM TEST LDA #$37 STA A01 LDA #>$E000 STA AF9 LDA #$20 ;$2000 bytes of memory (20 pages) STA A0F LDA #$00 ;set checksum = 0 STA AF8 TAY CLC I8941 ADC (PF8),Y ;+ INY BNE I8941 INC AF9 DEC A0F ;page counter BNE I8941 ADC #$00 ;< A-register holds checksum |
Code to calculate the checksum.
Depending on $FF80(Kernel revision) the checksum is either $E0 or $E1. This determines if Kernal is marked as “OK” or “BAD” by the diagnostic test.
I remembered that the C128 diagnostic cart displays the checksum. When running the C128 diagnostic(789010) the checksum on the C64 Kernal is reported as $D4. After investigating the code, which is identical to the one above except for the fact that only $1F00 of memory is checked, this is probably due to $FF00-$FF04 belong to the MMU.
We shared ideas about how this would be accomplished, but also noticed that some of the different kernals generated the same checksum. This might be deliberate for them to pass a diagnostic test.
All code below is compatible with 64tass (i.e. Turbo Assembler compatible).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
lda #0 sta zp_chk1 ;csum1 lo sta zp_chk2 ;csum2 mid sta zp_chk3 ;csum3 hi sta zp_addr+0 ;addr lo tay ;=0 chkloop clc adc (zp_addr),y ;+ bcc chkskip inc zp_chk2 ;csum2 mid bne chkskip pha tya ;addr lo(y) eor zp_chk3 ;csum3 hi sta zp_chk3 pla chkskip iny bne chkloop inc zp_addr+1 ;addr hi dex ;pages to check bne chkloop sta zp_chk1 ; |
The new checksum routine. To make a distinction, the address lowbyte is xor:ed and therefor not resulting in an identical checksum.
…I made a program that can identify the kernal ROM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
checksumtbl .word rom_name_1 .byte $bb,$d4,$fd ;checksum 901227-01 .word rom_name_2 .byte $b6,$c7,$0a ;checksum 901227-03 .word rom_name_3 .byte $bd,$c7,$0b ;checksum sx.251104-04 rom_name_1 .text "901227-01",0 rom_name_2 .text "901227-03",0 rom_name_3 .text "251104-04 sx64",0 |
A table is used for the checksum and a pointer(.word) to the matching ROM name. You can easily add new checksums and ROMs to the code.
Incorporate the checksum with Diagnostic 586220
The goal is to replace the original checksum routine with the code above.
1 2 3 4 5 |
I822C JSR I8888 ;COLOR RAM test JSR I890E ;KERNAL/BASIC/CHARAC ROM test JSR I8A44 ;CASSETTE test |
As we can see in the disassembly, the routine for ROM tests are at $890E. Further investigations reveal that code between $890E and $8A44 can be replaced. This area also has the routines to check BASIC and CHARACTER ROM.
1 2 3 4 5 6 7 8 9 10 |
I8926 LDA F9946,X ;"CHARAC" STA F05B8,X DEX BPL I8926 ;-------------------------------------------------------- ; CALCULATE CHECKSUMS FOR ROMs ; clear from current position up to $8A44 |
Checksum routine is located a few lines below $8926.
After inserting the code, you can now assemble(compile) the code with c64tass. I won’t go into details about the code itself, but it is presented and downloadable further down on the page.
1 2 3 |
64tass -a 586220plus.tas -o 586220plus.o64 |
The output file (.o64) can now be written to an eprom. Skip the two first bytes (0x00, 0x80) which is the loadingadress of the file.
1 2 3 4 5 |
cartconv -t normal -name "586220plus" -i 586220plus.o64 -o 586220plus.crt winvice\x64.exe -cartcrt 586220plus.crt -kernal 901227-03.bin |
You can also test the cart in vice by converting it to a crt. Cartconv.exe is included with the Vice emulator.
586220+ diagnostic, it is now possible to identify the kernal ROM.
The new checksum code.
Checksums for BASIC and CHAR are also displayed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
; code by jani@worldofjani.com outscrnadr = kern_out kern_out = A0575 basic_out = A059D char_out = A05C5 KERNAL_ROM = $E000 BASIC_ROM = $A000 CHAR_ROM = $D000 zp_offs = $f0 zp_chk1 = $f1 zp_chk2 = $f2 zp_chk3 = $f3 zp_addr = $f4 ;+1 LDA #$37 STA A01 lda #>KERNAL_ROM ldx #$20 ldy #(kern_out-outscrnadr) jsr newchecksum jsr id_kROM lda #>BASIC_ROM ldx #$20 ldy #(basic_out-outscrnadr) jsr newchecksum LDA #$33 STA A01 LDA #>CHAR_ROM ldx #$10 ldy #(char_out-outscrnadr) jsr newchecksum LDA #$37 STA A01 jmp exit_chksum id_kROM lda #<checksumtbl sta zp_addr+0 lda #>checksumtbl sta zp_addr+1 id_loop ldy #4 lda (zp_addr),y cmp #$ff beq id_notfound cmp zp_chk1 bne id_noteq dey lda (zp_addr),y cmp zp_chk2 bne id_noteq dey lda (zp_addr),y cmp zp_chk3 beq id_found id_noteq lda zp_addr+0 clc adc #5 sta zp_addr+0 lda zp_addr+1 adc #0 sta zp_addr+1 bne id_loop id_notfound lda #<rom_name0 ldx #>rom_name0 ldy #0 beq id_unknown id_found dey lda (zp_addr),y tax dey lda (zp_addr),y id_unknown sta zp_chk1+0 stx zp_chk1+1 id_txtl lda (zp_chk1),y beq id_exitx sta $0750+1,y iny bne id_txtl id_exitx rts newchecksum sta zp_addr+1 sty zp_offs lda #0 sta zp_chk1 ;csum1 lo sta zp_chk2 ;csum2 mid sta zp_chk3 ;csum3 hi sta zp_addr+0 ;addr lo tay ;=0 chkloop clc adc (zp_addr),y ;+ bcc chkskip inc zp_chk2 ;csum2 mid bne chkskip pha tya ;addr lo(y) eor zp_chk3 ;csum3 hi sta zp_chk3 pla chkskip iny bne chkloop inc zp_addr+1 ;addr hi dex bne chkloop sta zp_chk1 ldy zp_offs jsr hex2XA ;lo sta outscrnadr+4,y txa sta outscrnadr+5,y lda zp_chk2 ;mid jsr hex2XA sta outscrnadr+2,y txa sta outscrnadr+3,y lda zp_chk3 ;hi jsr hex2XA sta outscrnadr+0,y txa sta outscrnadr+1,y rts hex2XA pha and #$0f jsr hex2sa tax pla lsr lsr lsr lsr hex2sa clc adc #$30 cmp #$3a bmi hex2sb sbc #$39 hex2sb rts ;-------------------------------------------------------- checksumtbl = *-5 .word rom_name1 .byte $bb,$d4,$fd ;checksum 901227-01 .word rom_name2 .byte $8b,$c7,$0b ;901227-02 .word rom_name3 .byte $b6,$c7,$0a ;901227-03 .word rom_name4 .byte $ea,$c9,$09 ;901227-03-DK .word rom_name5 .byte $b3,$c5,$ca ;swedish-02 .word rom_name6 .byte $b0,$c5,$c9 ;swedish-03 .word rom_name7 .byte $bd,$c7,$0b ;sx.251104-04 .word rom_name8 .byte $ba,$c7,$88 ;sx64-scand.bin .word rom_name9 .byte $5c,$d1,$83 ;906145-02-jp .word rom_name10 .byte $56,$b5,$ca ;c64gs .word rom_name11 .byte $68,$a9,$e5 ;Jiffydos6.01 .word $ffff .byte $ff,$ff,$ff ;END ;-------------------------------------------------------- .enc "screen" rom_name0 .text "unknown",0 rom_name1 .text "901227-01",0 rom_name2 .text "901227-02",0 rom_name3 .text "901227-03",0 rom_name4 .text "901227-03 dk",0 rom_name5 .text "swedish-02",0 ;325017-02 rom_name6 .text "swedish-03",0 ;325182-01 (c128) rom_name7 .text "251104-04 sx64",0 rom_name8 .text "sx64-scand",0 rom_name9 .text "906145-02 jp",0 rom_name10 .text "390852-01 gs64",0 rom_name11 .text "jiffydos 6.01",0 .enc "none" ;-------------------------------------------------------- |
Comments