Sunday, 14 January 2024

Converting VIC20 Multi-Part Games - Rock Man

Another VIC20 Cartridge Conversion from the Patreon archive.

Rock Man is quiet a nice Boulderdash / Repton type game.

This one is available as a tape and also a disk version with slightly different code. I think I hit a problem when looking at the tap version last time, so let's have a go with the D64 version this time.

It is in two parts. The first program loads and brings up a title page.

It then switches to an instructions screen where you can set keys if you want to.

And then the game loads.

The first looks like a BASIC program, but it include a SYS 5800 call, jumping to code which is immediately after the end of the BASIC program. I think that is why this one was previously passed on, it just makes it a bit more difficult to work on as that file has to be specially generated.

Looking at 5800 ($16A8), there is quite a lot of code which appears to be setting up the VIC chip, clearing the colour RAM etc.

There is a lot of code, so I didn't get too involved in reverse engineering. I was just looking for the usual calls to the KERNAL load routines.

Ah, there they are right at the end, with the filename of the next part immediately after.

So far so good, although it is not clear what is going on before the first call, but it is easy enough to replace the first KERNAL routine call JSR FFBA with JMP xxxx to go back to the cartridge ROM to load the next part.

I tried that, but it didn't work.

I put a breakpoint on the code in the cartridge, but it didn't fire. I put a breakpoint on the code at $18E2, but it didn't fire either.

Odd?

I did a bit more stepping through and it turns out it copies this code to the cassette buffer and runs it from there. (I should have realised as the code at $0349 sets the filename to be read from $0362, where it is now)

But hang on, what's that BRK instruction at $0340? That shouldn't be there.

I initially thought this was copy protection, but investigating further I think it is a mistake in the code.

I think I need to change style....

"Hey it's Robin. Today we're looking at a bug in a 40 year old game....."

This is the code which gets written to the cassette buffer.

Note the instruction at $0340 is LDX #$08, load the X register with $08. Later, there is a call to $FFBA, which is SETLFS, a KERNAL routine which sets various device addresses based on the X, Y and A registers. it stores the X register at $BA, the primary address of the device being accessed. $08 is the expected value here for the disk drive. It most likely contains $08 already since it just loaded part 1 from there.

This is the code which calls that code block, and the last thing it does is load the current value of $00BA and stores it at $0340. Several odd things here. Why use LDX $00BA? it would have saved a byte and a cycle to use the faster the zero page version, LDX $BA. Secondly, and most importantly, it is writing to $0340, rather than $0341, which I think is what was intended. I think the code at $16D5 should have been STX $0341.

When loading from disk, the LDX #$08 now gets replaced with $08 $08, which is PHP then another PHP. Which I am sure is not intentional, as it will not set the X register. By a fluke, the PHP instructions are basically harmless (pushing extra things onto the stack, which is likely to be cleared by the new game), and X just happens to already contain 08, so it does actually work.

When loading from cartridge, the disk routines have not been accessed, so the value of $00BA is uninitialised, $00 on the emulator. The buggy code copies the value to the wrong place it ends up as BRK and PHP, rather than LDX #$00 (which would have been fine since the disk routine was never being called).

I had also changed the call to SETLFS to be the jump to the cartridge ROM to load part 2.

To fix this, I fixed the bug and changed $16F6 to $41 so the code change the value stored at $0341 as I think was intended.

That makes LDX #$00, set X to $00. That does not matter as it is not used. There are no unexpected BRK or PHP instructions. I could have fixed this by replacing the write with three NOPs, or changing the jump to $033E to go straight to the cartridge at $A080, but I was just trying to minimise changes.

After that, it was just a case of loading in part 2 and running it as normal.

Trying out the cartridge, that worked correctly. As soon as you have selected the keys or no keys, it loads straight into the game.

I left the LOADING ROCK MAN message as it is only there for a second, and I did not want to change the BASIC program as it is a lot easier if the assembler after it stays in a fixed location so I only have to patch the code in a couple of places.

Quite a nice game, with slightly different rock fall mechanics to Boulder Dash or Repton, I will enjoy getting to know this one.

And yes, I did spent far too long making a badge. What of it? I don't go around to your house and criticise how you spend your Tuesday evenings.


Advertisements

Penultimate +2 Cartridge

The Penultimate +2 Cartridge is in stock at The Future Was 8 bit, note the new website is TFW8b.com. On offer today for £49.99 + VAT

More info in a previous post:


Patreon

You can support me via Patreon, and get access to advance previews of posts like this and behind the scenes updates. This also includes access to my Patreon only Discord server for even more regular updates.

https://www.patreon.com/tynemouthsoftware