Sunday, 16 July 2023

3D Monster Maze for the VIC20

3D Monster Maze is of course the best game for the ZX81.

I liked it so much that I wrote a version of it for the Commodore PET - http://blog.tynemouthsoftware.co.uk/2022/07/remaking-3d-monster-maze-for-the-commodore-pet.html

As always, credit to M.E.Evans for their wonderful game, and to Paul Farrow for reverse engineering it.

Now it is time to bring it to the Commodore VIC20.

It seems to be early January 2023 when I did most of the work on the VIC20 version of 3D Monster Maze. This was initially planned as an extra game to add to the Penultimate +2 Cartridge that was being prototyped at the time.

Stage 1 - Can it Work?

When I set about the Commodore PET version, there were a couple of issues to address, the screen was a different size (40x25 instead of 32x24), and was missing a couple of crucial graphics characters.

Both of those issues were resolved by rearranging the maze view to 25x25 characters with a central single square.

The VIC20 has the same lack of those particular character graphics, although it would be possible to replace those with user defined characters.

The bigger issue is the screen is now only 22x23 characters.

I considered two options. One was to make the maze 13x25 characters, and have each 8x8 character act as two characters in the maze. That would sort of fit due to the wider characters used on the VIC20, but I expected it would take a lot more effort to achieve.

The alternative was to expand the VIC20 screen to 25x25 and use the whole screen as the maze view.

The ZX81 had a largely empty rectangle to the right which contained only the score, so I thought I could just move that to the top of the screen where it seems to fit fine and is never obscured by walls or Rex.

25x25 is just about achievable in both PAL and NTSC modes, although it is very tight on NTSC. Worst case, you lose some of the outermost wall edges, but that is no real loss.

That was one of the first test screenshots, but even from that it looked like it would work. (although the bottom line had cut off some of the the left hand wall).

It does require extra memory. The normal 22x23 screen takes up 506 bytes, and can live at either 0x1000-0x11FF or 0x1E00-0x1FFF. The englarged 25x25 screen uses 625 bytes. It would overflow the 0x1E00 starting point into RAM in the 0x2000 region, which is not accessible to the VIC chip. So it has to be in the 0x1000 to 0x1270 region, which requires some shuffling around with the code that would normally start at either 0x1001 or 0x1201.

Stage 2 - Proof of Principle

The plan was to take the PET version and rework it for the VIC20. A lot of it could stay the same as it was a mix of C and 6502 assembler, equally at home on the PET or the VIC. The screen drawing and memory map were of course different.

I put something together and it seemed to fit the screen rather nicely. 

At this point I was using the black and white graphics from the PET (although it would have been seen as black and green on most PET monitors).

The only change from the ZX81 version was smooth walls, although I did leave in the option to switch to crinkly walls if you wanted, to give a more ZX81 mode.

For the PET version, I left those two options in, but also added a version which was actually black and green.

For the main VIC version, I wanted to add some colour, but not too much.

I tried various options, most of which were hideous. Yellow with blue checked walls was looking like an option. (Looking back at this, I still sort of like the yellow walls)

But the blue and white seemed the best option.

Add Rex in green and that's it sorted.

NTSC viewers get the extra benefit that the chequerboard patterns is interpreted as colour data by some monitors, so you get a lovely wallpaper.

I have again left in the option to change between the modes, with four options now:

  • VIC20 colour version
  • VIC20 black and white
  • ZX81 style black and white with crinkly edges
  • PET greenscreen style

I updated the keyboard and joystick routines for the VIC 20 and had a playable version. It wasn't very good as the drawing the screen had not been optimised, and the joystick scanning was only once a cycle, so it wasn't very fast or responsive, but there was potential for a decent game.

Stage 3 - Time Passes

Some time passed.

There was the possibility of a tape release.

More time passed.

There was the possibility of a cartridge release.

Even more time passed.

Finally, this version was added to the early test versions of the Penultimate +2 cartridge, the plan being to go back to it at some point and tidy it up and turn it into a proper release.

Stage 4 - Everything is Broken

Eventually, I had the rest of the PU+2 where it was at a pretty much complete state, so that could go out to testers to give it a run though (still with the old version of 3DMM). That gave me time to get back and finish off 3DMM.

Sadly I wasn't feeling at my best, and spent an awful lot of time dealing with a series of issues, with together thoroughly confused me.

I will spare you the detail of a couple of very long Patreon posts where I am trying to work out why it won't build any more, or why it won't run, or why it was generating invalid code etc.

Suffice to say, it was a couple of silly mistakes, some confusion with the location of the C stack, some initialisation code in the wrong place, and some debug code pasted in somehow with missing LF characters one some lines, leaving only CR characters, which the compiler apparently ignores, leading to several lines following a comment also being ignored.

It took a long time to get my head back together sufficiently to work out all those issues and get back on track.

Stage 5 - Back on Track

Once I was able to build working versions again, I was able to get back to finishing off the code.

I was able to save a lot of time redrawing the screen with a simple flag that was set only when the screen actually needed updating.

I moved the game loop timing to a timer interrupt, so it would always run 10 game cycles every second, whether it was drawing the screen or not.

I used the VIC frame line counter to work out when to redraw the screen to avoid tearing, and replaced the generic MEMCPY call with a dedicated copy routine that worked section by section copying screen and colour information alternately.

To make the joystick more responsive, I added a routine to the 60Hz interrupt to scan the joystick and process the keys in the same way as the keyboard scan routine, with key repeat. The then added any joystick movements into the keyboard buffer as if they were keypresses, which seems to work very well.

Stage 6 - Exit Pursued by Dinosaur

It has been very easy to test the "you got captured" ending as it can be difficult to avoid getting eaten.

Not much to change here, other than making the text black and keeping Rex green.

One thing I hadn't looked at on the demo was the exit screen. This was going to need a bit more work as the original versions had all the text in the rectangle on the side that I no longer have on the VIC20 version.

My initial version used the same random character patterns, but added cycling colours as well.

I didn't get to test that much, as I didn't find the exit very often during testing.

In order to help with that, I wanted to add a map view. This was very useful on the PET version, appearing on the right hand side of the display on 80 column PETs.

I decided that rather than being a static flash of the map, as in Masogs, that it should stay on screen, and actually be playable.

That adds a new aspect to the game, because you can now see Rex, and in time, work out how the AI that moves him works. (sorry to break it to you guys, but Rex isn't real, he is controlled by AI. Sorry if I reuied anyones childhood)

I used some user defined graphics to make sort of boulders for the walls, and a version of Rex (who looks unfortunately a bit like a smiley face), and also a down and right arrow to match the up and left arrows in the standard character set. These show the player and the direction they are facing. Tank controls aren't everyone's favourite, but are the only way to go in the 3D maze.

So you can then start to work out how to trap Rex, so you can make your way leisurely to the exit.

And that, of course, allows me to test the exit code a lot more easily.

I decided the combination of colours and characters was a bit busy, so I went for just colours.

The black and white and green versions still have cycling characters as before.

The text is now placed top and bottom of the "time tunnel" effect.

Once the text is cleared, I create a sort of tunnel of white light effect with the central white area expanding until it fills the screen.

Then it switches to the "mists of time" clearing, as at the start of the game and drops the character back to their start point at the bottom right of the maze.

Stage 7 - Rex Woz Ere

One oddity in the original ZX81 version is that Rex leaves a trail in the maze data as he walks around. Corridor squares have a different value once Rex has traversed them, leaving a sort of breadcrumb trail. This was never used in the ZX81 version. Maybe there was a maze view routine that was removed before release?

I show these on the map as dots, so you can see where Rex has been (also coloured green).

I did think about some kind of footprints on the 3D view, but couldn't get that to look right.

Another idea I considered was anywhere Rex had stood for a long time ("Rex Lies in Wait"), to add some graffiti to the wall, "Rex Woz Ere" type idea, but it wouldn't scale, so you would only see it on certain views and it would disappear if you got too close or too far away, so wasn't very good.

It is a shame because I would have also liked to randomly add things like "Eat at Joe's" on the walls of the maze. Sort of like the teapot in the pipes screensaver.

And of course, I wouldn't have been able to resist adding this one.

Or should that be

But sadly, that is now an easter egg for anyone that reads to the end of a long blog post, rather than in the game itself.

Stage 8 - Easter Eggs?

There are still a couple of easter eggs in the game. One is the same as the PET version (that TFW8b spoiled by showing it on the video introducing the game).

The other was also in the PET version, but was set to not happen very often. The VIC20 version however has to have this happen every time.

Lets see if anyone finds it.

The Maze view and different colours / characters are sort of easter eggs, as you would only know about them if you actually read all the scrolling instructions at the start of the game, so it is more of a reward for perseverance.

After watching TFW8b play through the game on the PET, I added a feature to the PET version that speeded up the scrolling if you pressed any keys.

I have taken that a step further for the VIC version, and just skipped to the end if you press a key.



Advertisements

Penultimate +2 Cartridge

The VIC20 version of 3D Monster Maze is exclusively avilable on the Penultimate +2 Cartridge, now in stock at The Future Was 8 bit:

More info in a previous post:

http://blog.tynemouthsoftware.co.uk/2023/06/penultimate-plus-2-cartridge.html


Patreon

You can support me via Patreon, and get access to advance previews of posts like this and behind the scenes updates. These are often in more detail than I can fit in here. This also includes access to my Patreon only Discord server for even more regular updates.

https://www.patreon.com/tynemouthsoftware

Sunday, 9 July 2023

Converting even more multipart games for the VIC20 - Falcon Fighter and Kwazy Kwaks

More techniques analysed for squeezing the last few bytes space out of an unexpanded VIC20. Also some more methods of converting these multipart games into single PRG files or CRT images for inclusion in the Penultimate +2 cartridge.

Falcon Fighter

This is another initially simple looking one. Two files in a TAP image, a nice little Defender type game (or is it Scramble type, I can never remember the difference).

The first part loads up, displays a title screen and then loads the second part.

OK, that's going to be an easy one, isn't it?

Based on previous games, I did try just loading and running the second part, but there is more to it than that.

A lot more.

Further investigation shows the first part runs a few lines of BASIC then jumps to some assembler after the BASIC program.

There is also something nice / weird going on that whenever you list the file, it clears the screen and prints up that title.

The first part of code is run from 413 + PEEK(43) + PEEK(44)*256, which is quite neat. It is using the offset from the load address, so it will cope with 0K, 3K or larger expansion RAM.

On the unexpanded VIC20, that translates to address 0x11B0.

The code there does some setup, including copying a block of code to 0x0200. It then does another calculation about where the next block of code is at, which works out to 0x12A8 and jumps there. Why not use a relative branch instruction? Why not just have the code in a contiguous block? Seems to be deliberately obfuscated.

This second block of code at 0x12A8 does more video setup and finally returns to BASIC.

I didn't investigate fully, but it may only have been doing the graphics for that title screen, nothing actually useful for the game.

BASIC then prints the titles and finally a SYS 512 call, this time a fixed address, 0x0200, where code was previously copied.

This code setups the file operations to load the second program, the game itself. Once the second part is copied into RAM (the call to 0xFFD5), it returns to that code at 0x0218 which runs the game by jumping somewhere into the middle of it (0x1830).

I tried a few ways to convert this, my first plan was meant to be a quick fix. I didn't disassemble the rest of the code, but I found the section in the first file which is copied to 0x0200.

I modified that to jump back into the cartridge ROM and copy the second part into RAM and run it. (looks like this screenshot is a later version where I returned to this code at 0x0218 to run the game)

I was worried that it would leave a flash of the white title screen before starting the game, but when I ran it, it did flash up the white screen, but then locked up and went back to a READY prompt.

I tried a few modifications to the code at 0x0200, but in the end I went for the simpler option of copying the first program into RAM, but not actually running it and instead just jumping to the first block of code, which in turn jumps to the second block, and then the RTS instruction will return to the cartridge loader code.

From here it can copy the second program into RAM and jump to the same spot as the original code block from 0x0200 did.

But that didn't work either.

Stepping through the code, I found where it stopped, it tried to jump to some code at 0x03F2.

I don't remember any of the previous code copying anything to 0x03F2?

I went back to the TAP version and ran it and checked what was at 0x03F2.

Ah, OK, some valid code, but how did it get there?

This took me far too long to work out.

The first program did not write to that area. I watched for writes from the second program, but it didn't write there either.

I also looked through the code to see where this was being copied from, but I couldn't find it.

I have seen code that was obfuscated by XOR or negation, but was hoping it wasn't that in this case. (must remember to write that one up)

I put the watch on the full program and tried again, and then I finally saw a write to that area, but it was coming from the KERNAL LOAD routine? How was it doing that?

LOAD was only being called once, and that was to load the second part. That had a load address of 0x1001, the default for an unexpanded VIC20, so whether it is doing the equivalent of LOAD "game",8,1 or LOAD "game",8 it will be going to 1001. The only way it could get to a lower address is to loop around, but it wasn't big enough for that?

I scratched my head for a while, then had one of those "no, surely it can't be that, can it?" moments.

And yes, it was.

That code is in the cassette buffer.

But it isn't in the file, so it must be the overrun at the end of the file.

Code in the overrun of a TAP file in the cassette buffer.

Wow that's quite unusual. I've not seen that before.

I tried saving that block from the TAP file version, then pausing my cartridge version just before it called that code and loaded it back in. And it worked.

I added an extra section to the cartridge loader to copy that block of code into the cassette buffer and it's now working.

That was quite a lot of work, but satisfying to get to the bottom of this little 40 year old mystery.

Kwazy Kwaks

This one is a Duck Hunt game, as two PRG files in a D64. Hopefully this will be nice and simple.

Hopefully.

It is a shooting gallery / duck shoot type game, although there are 10 pages of instructions to tell you that.

Yes, 10 pages.

The final page offers you an opportunity to read all 10 pages again, or load the game.

I don't think anyone reads them anyway, they just hit whatever key is required enough times to get into the game.

The game itself will load and run separately, so I did think about just using that and ignoring the instructions, however, it starts with a plain "PRESS RUN/STOP"

So you don't get an on screen title or accreditation.

That's not great, I like to leave those in where possible, so back to plan A.

Since I had to modify the intro program anyway to replace the LOAD command with a SYS command to load from the cartridge, I made another slight change.

Now it shows the title screen, but then goes straight to the last screen, which now offers a change to read the instructions (which I don't expect anyone will), or go straight to playing the game (which is what everyone will do).

I had a quick look at seeing if I could bypass the "PRESS RUN/STOP" on the first play, but it is using it's own code to read the keyboard, so I just left it as is.

So that's another one done. What lies in wait next time?

Copyright

A word on copyright.

These games were all released in the 1980s, and as far as we are aware, are not commercially available any more.

The only way to get these games is to buy a copy of the tape in a freezer bag from ebay, which only benefits the ebay sellers, or download free from any number of websites online.

All these cartridge conversions are doing is making access easier. The main points of the Penultimate +2 Cartridge is the RAM expansion, the file browser and things like that, and the TFW8b titles including many new and exclusive titles. This is currently around 25% of the games of the cartridge. Titles like the ones in this post are added to give you more choice and easier access to them. These will, over time be replaced by more new TFW8b titles.

If anyone has any claim on any titles currently in the cartridge, let TFW8b know via the contact form on their website if you want them be removed from future versions of the cartridge.



Advertisements

Penultimate +2 Cartridge

The Penultimate +2 Cartridge with these and a host of other games is now in stock at The Future Was 8 bit:

More info in a previous post:

http://blog.tynemouthsoftware.co.uk/2023/06/penultimate-plus-2-cartridge.html


Patreon

You can support me via Patreon, and get access to advance previews of posts like this and behind the scenes updates. These are often in more detail than I can fit in here. This also includes access to my Patreon only Discord server for even more regular updates.

https://www.patreon.com/tynemouthsoftware

Sunday, 2 July 2023

Converting more multipart games for the VIC20 - Cataclysm, Battleground and City Crusher

Following on from last weeks introduction, here are some more multi-part games investigated and converted into cartridge games that can run directly from the VIC20 Penultimate +2 Cartridge.

Cataclysm

This looks a nice simple one, two files in a TAP image. Sort of a reverse Blitz game, this time you have to shoot down the bombers that are attacking your city.

The first part is BASIC, and prints up instructions.

This one does need a bit of explanation, so I will leave these in.

When the third page is displayed, it starts to load the actual game.

It does this by poking some code into RAM at 02A1, and then running it.

In a similar way to Galaxia last week, this sets up a file load which loads the second part into RAM at 1000 (not the usual 1001), and then it jumps to 1700 to start the game.

I edited the BASIC program to remove the file load code and replaced it with a repeat of the "PRESS A KEY" code, and then added a SYS call to jump back to the cartridge loader code to copy and run the game code.

So, for once, that did turn out to be a simple one. Let's hope my luck continues.....


City Crusher

Another one of many Blitz style games that TFW8b seems to like. This looked quite a simple one, two BASIC files in a D64 image, designed for the unexpanded VIC20.

The first is mostly DATA statements and some FOR loops that READ the DATA and POKE in into RAM in the font and colour RAM area. The second is the game itself.

I started off with the simple approach used in Mars Landing, copy the first BASIC program into RAM and run it. The end of the program needs to be changed from LOADing part 2 to doing a SYS call back into the ROM to copy the second program over where the first had been and then running that.

That worked, but parsing the DATA statements and programming the RAM took over 5 seconds, sitting on a blank screen. Not ideal. I could put a "Loading..." type screen up, but I decided it would be better to just replace the first part with some assembler which does the same job.

I fired up the Vice emulator and mounted the D64 image (but didn't auto start it).

xvic -memory none -8 "City Crusher.D64"

I then loaded the BASIC program and found the last two lines, the ones which fed the LOAD instruction for the second part into the keyboard buffer. I deleted those lines and ran the program.

5 seconds later, it had loaded up the RAM and returned to the READY prompt.

Into the Vice monitor, and I saved the RAM to disk. For simplicity, I dumped the whole 64K space.

save "after first.bin" 0 0000 FFFF

0 says write to the current folder, and 0000-FFFF is the address range to save.

The file is in the standard format, so the first two bytes contain the load address, and should be removed to give the pure 64K block of data.

Looking through the BASIC code, it writes to several locations.

POKE56,28

This lowers the end of RAM from 1E00 to 1C00, to free that area for graphics

FORZ=7168TO7679:READX:POKEZ,X:NEXT

This fills a block from 1C00 to 1DFF with graphics data.

FORZ=673TO751:READX:POKEZ,X:NEXT

This puts some code from 2A1 to 2EF

FORZ=319TO414:READX:POKEZ,X:NEXT

This puts some code from 13F to 19E

FORZ=0TO73:READX,Y:POKE37888+Z,X:POKE38144+Z,Y:NEXT

This preloads the colour RAM from 9400 to 9449 and 9500 to 9549.

Finally, the code which loads the second part. This first clears the screen and prints the LOAD command.

FORZ=0TO9:POKE631+Z,13:NEXT:POKE198,10

This fills the keyboard buffer with the return character, and sets the count of characters in the buffer to 10. These will be processed after the program has finished. The screen is already setup with the LOAD command, so that will be executed and part 2 loaded.

In order to make this into a cartridge, I needed to replicate all that, but with fast assembly language routines. I extracted the appropriate sections from the memory dump, and modified the cartridge loader to copy each of those into the appropriate sections of RAM.

Finally, it copies the second part into RAM, relinks BASIC and runs the game.

That all happens in the blink of an eye, much faster than the BASIC loader.

My initial cartridge ROM was 8K, but by shuffling things around I was able to get that down to 4K. There are now quite a lot of 4K cartridge ROMs and PRG files into the Penulitimate +2 Cartridge, squeezing even more content into the ROM.

Battleground

Battleground is another interesting one.

This is a two part loader. The first is just 105 bytes, but it has an unusually load address. Rather than the standard 1001 for an unexpanded VIC, it is loaded to address 02A1. This is mostly unused memory (reserved for program indirects), apart from the last 10 bytes which overwrite some BASIC vectors from 0300 to 0309.

The values are overwritten with the standard values, all apart from two bytes which change the BASIC warm start from C483 to 02A1. So when loading is finished, the BASIC ROM code reads the values at 0302/0303 and jumps to that address. That is normally C483, which prints up the normal READY prompt, but changing these values means it will now call the code at 02A1 instead.

That code writes a lot of values to RAM. The first thing it disables the RUN/STOP key (causing it to lock up), then it resets the BASIC warm start to the normal value.

Next it writes some keys values into the keyboard buffer - L O A D then RETURN. Then R, SHIFT+U (which is a shortcut for RUN) and RETURN again. It sets the number of characters in the buffer to 9 so these will be recognised and processed later.

Then it sets the background and border to white, and the text colour to red.

Next it changes the address of the SAVE routine, so it will not be possible to save the game.

Finally, it jumps to E378 which is part of the initialisation routine. This clears the screen and prints the *** CBM BASIC V2 *** messages and the RAM count, and the READY prompt, all now in red.

The VIC20 KERNAL now checks the keyboard buffer and pulls out LOAD + RETURN and starts to load the actual game (saved with no name).

When loaded, BASIC prints up the READY prompt again and checks the keyboard buffer. This still contains RUN + RETURN, which then runs the game. (OK, it's actually R + shift U).

All of that to stop you being able to SAVE a copy of the game.

However, all you have to do is wind the tape on a bit, so it bypasses the first program, then LOAD the game as normal, and you can then SAVE it? You then have a normal PRG file that I can add directly the the Penultimate + 2 Cartridge, 

Seems a lot of work which must have required a lot of scouring the VIC20 Programmers Reference Guide, and it makes it quite neat I suppose to have it auto start, but I wonder if the "copy protection" would have stopped anyone?



Advertisements

Penultimate +2 Cartridge

The Penultimate +2 Cartridge with these and a host of other games is available to order from The Future Was 8 bit, shipping starting this week.

More info in a previous post:

http://blog.tynemouthsoftware.co.uk/2023/06/penultimate-plus-2-cartridge.html


Patreon

You can support me via Patreon, and get access to advance previews of posts like this and behind the scenes updates. These are often in more detail than I can fit in here. This also includes access to my Patreon only Discord server for even more regular updates.

https://www.patreon.com/tynemouthsoftware