Sunday, 28 January 2024

Converting VIC20 Multi-Part Games - Operation Ganymed

Another VIC20 Cartridge Conversion from the Patreon archive.

Operation Ganymed was another early request. It's a better Jupiter Lander than Jupiter Lander, but it is in many parts, with trick filenames etc. and was marked down as "too much work".

The first part has a filename which includes a screen clear and colour change. And yes, that is the spelling, not Ganymede the moon of Jupiter.

This then goes straight to loading a second part, this time with a colour and border change, and no actual name.

The result, after nearly 2 minutes of loading, is a title screen.

After pressing space, the third part starts loading, again with a clear screen filename.

Another minute and we are at instructions.

These do not mention Operation Ganymed(e), but instead seem to be indicating "Lunar Module" might have been the title?

Each screen is a different colour, and you progress through by pressing shift, which is a little unusual.

The final page ends with a "please wait..." as part four is loaded in the background.

Finally the game loads, with the option of playing the game, or changing the colour.

And it plays well, a nicer version of Jupiter Lander.

No mention of Operation Ganymed here either, and again L.M. Lunar Module?

The alternate colour scheme is pretty much the same, just with a black background.

Investigation

There was a lot going on here. Lots of files with trick filenames and adding it all up, it almost fills the memory three times, the title, the instructions and then the game.

  • Part 1 title screen 561 bytes
  • Part 2 chars data 2050 bytes
  • Part 3 instructions 2017 bytes
  • Part 4 game 3586 bytes

Part 1 is BASIC, and uses a variation of the ON A GOTO type technique to do different things when the program runs for a second time.

I put a breakpoint in the monitor at the point the filename is written to screen and then changed the colour back to blue so that I could see what was going on.

So it seems the second part didn't have a trick filename, the colours were already set to not be visible.

Part2 is called NEWCHRS, and is character data, loaded at $1400. I thought this was character data for the game, but this gets overwritten later on, so it only for the title screen. It's OK, but not sure it was worth the effort. Could have done something similar with PETSCII characters and shaved a few minutes off the load time?

The second pass through the program prints up that title screen and waits for you to press space (or a timeout after 15 seconds which is nice), and then loads part 3 using the plan and simple LOAD command.

Part 3 is again BASIC, and is the instructions.

At the end of the 4th page of instructions, it pokes some code into RAM and then runs it.

This calls the usual KERNAL routines to load the program, but then jumps to the address held in RAM at $0001.

Looking at the RAM, it is set to $1949, which is a reasonable entry point, but when did that get set?

It was only later I realised it was set in this program, in line 20.

See?

No?

Well, I had better look at line 20 in CBM prg Studio, see if that can shed any light on it.

And there we are, the delete characters will overwrite the two pokes with the REM statement. Neat.

Once it loads the game, it jumps to that address and starts the game.

The Conversion Process

This was the first time I had to deal with 4 parts, so I had to copy and paste the copy routine a couple of times. Copy the character data for the title to RAM at $1400, then load the part 1 program to $1001 as normal. I removed the loading routines and jumped back to cartridge ROM as usual.

For the instructions, I modified the end to reuse the "press shift" routine and then jump back to the ROM, where it would copy the final forth part into RAM and jump to the secret start address.

And it didn't work. It displayed the F1/F3 screen and then started the game, but the lander didn't appear and it just hung there.

I wasn't sure what the difference was, maybe some extra routines somewhere? I dumped the whole RAM from the working tape and my broken cartridge versions and compared them.

And there were some differences in the code area.

I did a bit more looking around trying to find out what was going on. It didn't seem like the routine in Cops'n'Robbers where the whole data was XORed before running, just a few changed here and there between what was loaded from tape, and what was currently running.

http://blog.tynemouthsoftware.co.uk/2024/01/converting-vic20-multi-part-games-cops-n-robbers.html

At this point I had two options.

  1. Investigate further to find out how the code is being modified and replicate that
  2. Cheat.

I couldn't see anything obvious going on, and I had already done a lot of these so I decided to cheat. I just cut out the code block from the RAM dump and loaded that instead, and it worked fine.

I will leave that one last mystery unsolved, since the game is working nicely now. I thought I might revisit it when I wrote this up for Patreon (I didn't). Maybe I will revisit it before I post it to the main blog (I won't). (ed: I didn't)


Advertisements

Penultimate +2 Cartridge

The Penultimate +2 Cartridge is in stock at The Future Was 8 bit, note the new website is TFW8b.com.

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

Sunday, 21 January 2024

Converting VIC20 Multi-Part Games - Outback

Another VIC20 Cartridge Conversion from the Patreon archive.

Outback is a quirky little shooting game where the player can only move up and down and fire, with a bit of a hint of Lemmings, and a stronger hint of Pooyan.

Outback was another of the challenging ones. First off was actually finding a working version. There were several tap files online, but none of them seemed to load fully, they would just run on after the final part was meant to have loaded.

There isn't anything to say there is a problem, it just sits there doing nothing. But, it has been set to black text on a black background. If I change the text colour, you can see the problem.

TFW8b had a cassette, and recorded tap files of both sides. Side A did the same thing, but finally the version from side B loaded.

It appears to be in many parts. The first parts goes straight to loading a second.


The second puts up a title screen with the "LEAVE THE TAPE" message, and it is presumably loading things in the background.

Changing the text colour again, this time it is loading correctly.

There may be several parts being loaded at this point.

Finally we arrive at "PRESS BUTTON".

Next you are prompted to enter a skill level.

And then the game begins.

For some reason the player wonn't move up or down and just autofires. I am told it works correctly on real hardware, but it did not work on vice.

That was the point I gave up at last time, as I thought the file was still damaged. However, now I think I know what was happening, I thought it warranted further investigation.

Further Investigation

This is a four part loader.

The first part does some copy protection, then loads the second part.

The second part loads the third and forth parts and then runs the game.

The first, second and forth parts are BASIC. The third is character data and assembled code.

Part one is mainly pokes. Let's see what is going on.

POKE 198,6 sets the keyboard buffer count to 6

POKE 632...POKE 636 puts 6 characters into the keyboard buffer. These are L, shift+O, return, R, shift+U, return.

L + shift O is the shortcut for LOAD and R + shift U is RUN. This loads and runs the second program.

POKE 648,30 sets video address to $1E00 (which is where it would already be on an unexpanded VIC20)

POKE 808, PEEK(808)+2 disables the stop key by changing the error handler from $F770 to $F772

POKE 37150, PEEK(37150) AND 127 This is the interrupt register on VIA#1 and sending 0111 1111 will disable all interrupts, including the restore key.

IF PEEK(56) > 30 THEN POKE 642,32 

If 8K or more is installed, this rearranges the memory to use the screen at $1E00

SYS 64824

64824 is $FD38, a call into the KERNAL ROM which will process the characters in the keyboard buffer as stored above (LOAD and then RUN)

Not sure why it does that as that would happen anyway when the program ends?

Program 2 then loads, lets have a look at that.

This uses a trick to detect when a program is run multiple times. At first run, A will equal 0, so the first statement will set A to 1, and then the ON A GOTO will GOTO 30.

30 prints up a title screen. POKE 36879,8 set the border and background to black.

It then does LOAD "",1,1 which will load from cassette to the address in the file. 

After the load, whatever program is in memory will be run. The program it has loaded has a load address of $1800, so that has gone into the memory at $1800. When it comes to do the RUN, the original program 2 is still in memory at the default load address of $1001, so that gets run for a second time.

Now, A goes to 2, and the ON A GOTO now GOes TO line 1000. Here it does the same keyboard buffer trick with LOAD and RUN as program one, and then the forth and final program is loaded and run.

This is a BASIC program, and is finally the game itself.

It starts with RUN 510, which jumps to the line which prints "PRESS BUTTON".

The Conversion Process

I worked out I only needed the following lines from the first program to disable run/stop and restore. 

POKE 808, PEEK(808)+2 : POKE 37150, PEEK(37150) AND 127

The rest is to do with loading part two and rearranging the memory if required. I control the memory arrangement for the game when loaded from cartridge, so it will not be needed.

I only needed the title screen from the second program, so I made a new BASIC program with the bits from program one and two combined.

I got rid of the ON A GOTO stuff and all the LOAD and keyboard buffer prep. We don't need that anymore.

I changed LEAVE THE TAPE to PRESS A KEY and added a simple wait on key press and then a SYS call back into the cartridge ROM.

Back in the cartridge ROM, it loads the character data to $1800, and the final program to the usual address of $1001 and then runs it.

I made one change to the game program, I change the RUN line at the start to bypass the "press button" / high score screen and go straight to the skill level selection screen. That screen is still displayed when you lose the game, it is only skipped on the first run.

I put it all together and tried it in the emulator and it worked, the player could move and fire.

I realised what it was that was stopping the player moving, the problem previously seen in Bandits (http://blog.tynemouthsoftware.co.uk/2023/08/inexplicable-autofire-explained.html) where the joystick read is done without masking the bits. If you still have play pressed on the datasette, it will read wrong. 

My cartridge version didn't use the datasette, so it is not a problem. I tested the tap version again in the emulator, and verified it wasn't moving. Then I stopped the datasette and the autofire immediately stopped and I was able to move and fire at last.



Advertisements

Penultimate +2 Cartridge

The Penultimate +2 Cartridge is in stock at The Future Was 8 bit, note the new website is TFW8b.com.

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

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