Well, this came in just in time. I am designing a cartridge port expander board and I wanted to implement a "hard reset" button on it. As you demonstrated very well, a normal CPU reset doesn't get you out of some very persistent software. I read up on this and found out this "unstoppable reset" is called an "EXROM reset" in C64 lingo. Your video just saved me a lot of time for coming up with values for a working R/C timer, much appreciated!
I'd consider using a cheap microcontroller like an ATtiny for precise and adjustable timing, as the timing is slightly different for other KERNALs like JiffyDos. The exact timing can be figured out with a scope or logic analyzer watching the reset and ROML lines while EXROM is held low-after reset you'll see two clusters of accesses to ROML, first to check the signature, then later for the memory test. For the timing circuit EXROM should be released between those two points, otherwise MEMTOP will be set to $8000 instead of $A000.
My first computer was a Texas Instruments TI-99/4a. You had to write every line, everytime. Wish I still had it, actually. In 1981 I was 13. It was an interesting time. Internet wasn't even squealing yet! Kids from today, would be asking if we could take them to see dinosaurs! Sit them down, and give them a 64, without a cassette player!
After market reset switch mods seem to have been pretty popular. The C64 I showed in the video had one installed at a repair shop in 1983 according to the receipt in the box.
I used a metallic paperclip to short GND and RESET on the user port. Later on I rigged a switchable short connected to pins on the SID chip directly on the board. It worked to install POKES in many older games. More recent games, not so much. Some used the CBM80 trick (Krakout did this) to prevent the user from resetting. Moreover, the cold start routine destroys some of the contents of the RAM, like bits of the stack and BASIC/KERNEL variables below $400, as well as the screen memory at $400-$7ff. Larger games liked to store data or code in there. So I bought an Action Replay cartridge in 1989. It also had freeze functionality.
I’m tempted to create a custom kernal rom that pokes 00 into the first of those 5 bytes before checking for CBM80. If it is a cartridge it will have no effect and run the cartridge. If it’s ram, the “infection” will be gone. … just a wild thought ;). Thanks for the video.
Check the link to Sven's Techsite - he did exactly that. I think a better solution could be to do the normal memory test first and only check the signature if ROM is detected there (MEMTOP set to 8000)
I imagine this is several decades old news to long time C64 assembly coders, but it was new to me and I thought it would be a fun project to learn KickAssembler.
A bunch of games used to do this as well to prevent reset with using the power switch to turn off and on (and some demos too). One of the quick and dirty ways to add a reset (and I done this and have a C64 with it on still!) was to basically put a push button between pins 1 and 3 - so between ground and the reset line. Some games as per the 5 bytes in RAM did stop that though - didn't actually test how long to hold it in for to see if it would reset because if at first you don't succeed, use the power switch. So yeah, still got a C64 with a 40 year bit of twisted wire, push switch with blu-tac stuck to the stop of this C64!
Was having flashbacks to popup ads on early internet browsers !😖😂 Interesting and well-done video! Really nice to see people enjoying the older machines and the freedom / responsibility / control they provide for the programmer! 🤓
When you can still type statements at the BASIC prompt you can issue a poke command to change one of the bytes in the 5 byte sequence instead of powering down the machine for some period of time.
I've had tons of 64s and I've never seen a dram that could hold its contents more that maybe 10 to 15 seconds after power off. 15 mins is a very unfounded claim. (I currently own 12 or so 64s)
It does sound quite extreme, perhaps an urban legend. In the link to Sven's Techsite, he shows a series of memory dumps where it took several times switching the power off, up to 60 seconds, before the CBM80 signature cleared out (though you can see corrupted bytes here and there even after 5 seconds).
@@TrevorMakes maybe the commodore shouldve had a routine in rom to clear (and test)all the ram addresses before everything else, like in most sinclair machines ?😉
@andygozzo72 There is a non-destructive memory test, but it just sets the top of free BASIC RAM to wherever it fails first, usually either cartridge or BASIC ROM. Not really a proper diagnostic. (but I do think that the memory test should have been done first and skipped the signature check if RAM had been found there) I think there is some benefit to not clearing the RAM though, since it does allow you to recover what was there previously... Commodore just goofed by making the old contents of RAM able to influence the startup and NMI procedures.
Back in the good old days I had at least one game that was really hard to wipe out of the memory. You would need to turn the computer off for a good 5 minutes at worst to restart normally. 007 Licence To kill was one of those. On my 1988 C model I don't remember this being the issue, but on the late production phase ca. 1991 units bro and I got from a campaign sale, this was. And now, I think I know one possible reason. I have understood that some of the late models were built with static ram. So it would not need refreshing to retain data - and it could retain data for a considerable time without power.
7:24: wait, what? You push the button, the lines will get pulled low and the caps will slowly charge until the resistor dividers made of the line's pull-ups and your resistors settle. You release the button, the lines will get pulled high immediately, as the capacitors' circuits are open. So, basically, the only working parts here are the button and the diode ;) Connect the caps between the ground and the button (one through a 50 Ohm resistor, the other through a 50 Ohm resistor and the diode you already have to remove sparking, though I'd use a BAT54C and a single resistor because less parts), connect your 10 and 12k resistors between the caps and Vcc - and two more diodes to pull RESET and EXROM low without unnecessarily loading the on-board logic with the caps.
You're correct, the lines start climbing back up while the button is held down, not when it's released. I didn't design this circuit; it's an old one that had been shared in a few places, but I agree there's room for improvement. Ray Carlsen's circuit portcommodore.com/rcarlsen/cbm/c64/RESET%20CIRCUITS/c64%20cold%20reset.jpg looks like an improvement, but would need to be done internally rather than on the cartridge port lines. I'm already working on a follow up using a single microcontroller which will watch the ROML line for when to release EXROM, rather than relying on a capacitor for crude timing.
I thought this was pretty interesting! I could see it potentially be used as copy protection in some games to defeat the reset switch.. To your knowledge was this ever used in commercial software or games as a method of tamper or copy protection? I know a lot of freezer carts used for pirating games had reset buttons on them. Not sure how the reset circuit was used in this context, but I am sure others must know?
The link in the description to Sven's Techsite mentions Gyruss using this, but otherwise I never found a specific list of games. My impression from forum posts and other articles was that this was mainly used for copy protection in games as you suggest. I do think a more practical use for this type of reset circuit would be for cracking copy protected code which would otherwise be cleared from RAM if you switch the power off.
They finally implemented ASM there? Good to know, I never used Arduinos TBH, as I only like coding in ASM for those AVRs (both for fun and work, as I hate micro-optimizing the C code there), and it only takes a somewhat $5 programmer for the job :)
@@TheBypasser In the end it's an Atmega 328P, you can program any microcontroller in ASM :) You can access the registers in the Arduino IDE tho, gotta have a very good reason to spend the extra time writing directly in Assembly imo.
@@orti1283 I thought they have implemented it in the IDE. Never tried it tho, as IMO the best IDE for AVRASM is the older AVRStudio 4 (the pre-VS-one), as the debugging is just awesome there. And yes, there are numerous reasons to use ASM for those cores (which is not that long to code, and takes way less time compared to micro-optimizing the C code), especially for the industrial devices: no "code chaos" (e.g. changing one line will not affect the whole Flash - the address constants only, and that is it), clock-accurate routines, overlapping interrupt code, fast port control by pre-loading the port states on the registers and keeping them static throughout the whole process etc.
This has NOTHING to do with the CPU. What's insanely stupid about this exploit is why address 8000 is even looked at in the first place. It's not like the CPU starts executing at 8000, it's got two 16bit vectors before the signature, so where is the code that understands this layout?
The CPU starts executing the code at FCE2 (vector from FFFC), shown in the last part of the video. The subroutine at FD02 is where it checks the signature. I suppose they could have put the signature in the other cartridge ROM at A000, which defaults to BASIC ROM instead of RAM.
Right.. It's not the CPU, but the kernal ROM that checks for the cartridge signature in the memory map at 8000, so it's not that insanely stupid. It's needed so the cartridge can run automatically when inserted and the machine is powered on, otherwise you would have to type something like SYS 49152 or SYS 32768 to start the cartridge. This is the reason SYS 32768 (8000), SYS 49152 (C000) or SYS 64738 (soft reset) were often used to start games that were dumped from cartridge to disk. This, along with bank switching to RAM for almost the entire memory map is also what made it possible to dump cartridge games to disk and have it work with little or no modification (unless there was copy protection in the cartridge ROM)
@@seansretroverse9082 The point is, I'm not a C64 user. I was a BBC Micro user and wrote a fair amount of commercial games, so I knew a lot about how the 6502/6510 initialized itself before starting to execute instructions. The BBC didn't have all the extra memory layout of the C64, just had 0000 - FFFF with everything above 8000 being paged in ROMs and other hardware registers at FE00. Now the MOS will initialise through the reset vector at FFFC, which is actually a CPU requirement and then start to initialize the ROMs, offering services to each in terms of grabbing its own workspace etc. The fact that the MOS looks at 8000 before starting the ROM servicing is a little insane. I can get why they did it, but if the cartridge slot had been interfaced correctly, it could have been the first one offered the services rather than some crazy memory hack to make it happen. Like I said, I don't know the C64 well, since I never had one, but one of the things that made BBC stand out was the bonkers attention to detail in the MOS. Even to the point that it had values for colours for up to 24bit depth, but obviously that never came, but it was still an amazing bit of programming. Then the BBC Master with it's paged RAM, and ROM initialization was another piece of coding wizardry. It's just mental having something so hacky in a machine like the C64 that I love watching demos on.
What's insanely stupid is that the reset code doesn't check it's actually ROM that is checked for the signature before going there on reset. I suppose by having the ROM cartridge itself switch out the RAM it made it harder to get a ROM image into that RAM to be able to modify it in any way - an early form of DRM?
Yup, but only if the code hasn't prevented you from being able to exit the program to type in BASIC commands. Side note, even with the reset circuit in this video, you still need to do the poke as you describe to get STOP+RESTORE to work again.
Good idea about periodically refreshing the signature and other vectors-would be pretty annoying to have both the IRQ and NMI going and patching up each other's vectors and timer flags. I suppose you could also add a BASIC wedge that would silently block POKEs to just those address ranges.
@@TrevorMakesI'm not sure about what should be achieved here... given these computers' mostly isolated nature, real viruses are hard to write, as they need to propagate, and that's nontrivial in this case. Any hacks, even like this in the video can be classified as intended behavior, hard to catch this as infection..
@chipetke this is a completely contrived example meant for nothing more than displaying an interesting animation. The Codebase64 site does have a page about C64 viruses if you'd be interested in reading further.
In VICE at least it does work. "Reset machine CPU" will keep the signature in tact, while "Power cycle machine" will clear it out. Doesn't really cause any harm