hosted by guitarsite.de



or the "Signature of Death"

Content

CBM80 or the "Signature of Death"
The "unstoppable" EXROM Reset
Kernal 2.1
The Code of Death


Some programs abuse the cartridge signature to gain control over the behavior of the reset and the restore key. This serves as a kind of copy protection and can cause head scratching and even desperation, because the beloved C64 seems to be broken.

The C64 has a simple mechanism, that allows a cartridge to be recognized and to appear within the computers address space.
● The EXROM signal is held LOW by the cartridge
● At 0x8004 a cartridge signature appears, which is CBM80 (the bytes 0xC3, 0xC2, 0xCD, 0x38, 0x30)
● The start-address of the cartridge program (at 0x8000, LOW by first)
● The redirected NMI vector (at 0x8002, low byte first)

At the very beginning of the C64 reset procedure (which is also called after power up), the computer searches for the CBM80 signature, redirects the NMI vector according to the cartridge header and jumps to the cartridge start address.

The copy protected software leaves a cartridge signature in RAM. Yes, in RAM! At 0x8000. If the reset button is pressed, the kernal branches to the cartridge start address at 0x8000... but wait... Where is the EXROM signal???

The CPU does not recognize the state of the EXROM signal. The job of making the cartridge appear in the address space is done by the PLA, the central logic of the C64. So instead of reading the cartridge ROM, the CPU finds the cartridge signature in RAM.

So, you press the reset button and instead or booting the machine, finally showing "**** COMMODORE BASIC V2 ****", the C64 has to do, whatever the software wants it to do. The RESTORE key also does, whatever the software wants it to do.

And now comes the horrible part of it...
after switching off and on the C64, it still does not boot properly... at least not after a short power off. It was reported, that with some kind of RAM (Fujitsu) the power off needs to be over 15 minutes for the C64 to boot again. But how can that happen?


A DRAM cell (bit)


A DRAM cell consists mainly of a MOSFET (transistor) and a capacitor (C), which is a small structure in the silicon of the memory chip. The bit which is stored in such a cell is representing the charge inside the capacitor. To keep the information, the DRAM has to be refreshed periodically. The VIC-II chip does that job. This period uses to be much shorter than the time required for the capacitor to discharge. While being powered down, the MOSFET is high impedance. It is also not affected by the discharge resistor at the power switch of the C64. So, the charge stays... and stays... and stays... and as long as the CBM80 is not corrupted, the C64 will not boot properly.

The following animation is created of real memory dumps (DolphinDOS monitor) after playing GYRUSS. The first was taken after an EXROM Reset, the following frames were taken after a power of. The duration of the particular power off before the dump is indicated on top.






The "Unstoppable" EXROM Reset
Is there a cure for this behavior? Yes, at least a temporary one: The EXROM reset. The EXROM reset holds the EXROM signal low, a short time, after the reset signal goes HIGH (=inactive) again. This way, the CPU will see a not present cartridge ROM instead of the RAM. So, there is some nonsense at address 0x8004, but definitely not the CBM80 signature, that is in the RAM (which is invisible). This way the normal reset procedure is executed, the normal NMI vector is installed and everything is fine... Everything? No!

The cartridge signature is still in RAM. And while the C64 is powered up, it will not get lost. So, if you then switch off the computer for a short time, the problem of the corrupted reset stays, but...

In case you load a program, that overwrites the cartridge signature, everything is fine again. Or you could destroy the signature manually. 0x8004 hexadecimal is 32772 in decimal. So a

POKE32772, 0

will do the job. The first bit of the signature is now 0x00 instead of 0xC3. When you now reset the C64 or cycle the power, everything is fine.

Now, if the kernal would do this job, the malaise would never occur. No matter, what software is running and whether it leaves the signature of death... in case the RAM at 0x8004 is set to any other value than 0xC3 before the kernal checks for the cartridge signature, everything would be fine. Always!
Kernal v2.1
First, I thought, it might be easy to talk to somebody, who has made an alternative Kernal, like the marvelous JaffyDOS from World of Jani , and convince that person of making a slight change, but it seems, that those kernals use the complete possible size of the kernal, so modifications would be a huge work, mainly to crunch some routines.

This is, why I decided to find a free space within the original Kernal and do the modification myself.


Screen shot of the "Kernal v2.1"

Both,
Basic v2.1 and Kernal v2.1 are not a perfect name, but I decided to keep it simple.

Beside the text, I just had to modify a few bytes to get a working result.

Right after Reset or Power On, the Kernal is searching for the cartridge signature and in case it is found, the NMI vector is redirected and the CPU continues execution at the cartridge start address.
This is a disassembly of the reset routine, which the regular reset vector is pointing at.


FCE2 A2 FF LDX #$FF
FCE4 78 SEI
FCE5 9A TXS
FCE6 D8 CLD
FCE7 20 02 FD
JSR $FD02 ; checking the cartridge signature
FCEA D0 03 BNE $FCEF

FCEC 6C 00 80 JMP ($8000) ; if found, jump to the cartridge start address
FCFF […]
; compare the content of $8004 … to the signature
FD02 A2 05 LDX #$05
FD04 BD 0F FD LDA $FD0F,X
FD07 DD 03 80 CMP $8003,X
FD0A D0 03 BNE $FD0F
FD0C CA DEX
FD0D D0 F5 BNE $FD04
FD0F 60 RTS

; cartridge signature „CBM80“

FD10 .BY $C3,$C2,$CD,$38,$30



In an unused space of the Kernal, a very simple routine was inserted, which is setting the first byte of the fake cartridge signature CBM80 to $00. Then the execution is continued at the original reset routine.

E4B7 A9 00 LDA #$00 ; load that 0x00
F4B9 8D 04 80 STA $8004 ; write it to the first byte of cartridge signature
F4BC 4C E2 FC JMP $FCE2 ; continue execution at the regular reset vector

To start the execution at this routine, the RESET vector was modified:

FFFC .WD $E4B7 ; RESET vector

This modification has proved to be functional. All games, that would cause the trouble as described before, work perfectly, but the trouble is gone after the reset or a power cycle. Only 8 additional bytes can do the job!
The Code of Death
Loading troublesome games is one way to test the theory, but writing my own program for proving my theory was the better way.

Just a few basic lines, will sctew up your C64 - not forever, though. A few minutes without power will revive the computer.

10 DATA 00,127,09,128,195,194,205,56
20 DATA 48,32,121
30 FOR I=32768 TO 32778
40 READ V
50 POKE I,V
60 NEXT


This writes the fake cartridge signature to the RAM. As a result, the reset button will not work properly anymore, you will see a black screen instead. Horrible. Try a power cycle, it will probably not work, either. But do not panic, time or Kernal v2.1 will cure the C64.
This Project on Github/Other Resources
● You can find the binaries for the Kernal v2.1, the Code of Death and further information on my github repository .
● My
Keyboard Controlled Kernal Switch provides and EXROM reset and lets you easily switch between multiple kernals by pressing RESTORE and a numeral.
● Ray Carlsen has some interesting
information about the EXROM reset on his home page .