Sunday, 29 September 2024

Adding Super Monza Gran Prix 2 to the Penultimate Cartridge

There are a bunch of new release from The Future Was 8 bit on cassette and cartridge, including some VIC20 titles. When there is a new VIC20 game, I like to get that ready to add to the next update to the Penultimate Cartridge.

First there was Super Monza Grand Prix.

Then there was Super Monza Grand Prix 2.

Then there was a special TFW8b edition of Super Monza Grand Prix 2, with extra tracks.

Each side of the tape has a different set of track on. So there are two different versions of Super Monza Grand Prix 2 TFW8b edition, and ideally both of those would go into the Penultimate Cartridge.

I am also going to have to revisit the list of titles for some of the ones we have flagged as could potentially be dropped to clear some space (looking at you Q*Bert, how are you still in the cartridge?)

But it doesn't stop there. For the cassette release, TFW8b added a title screen and the option of reading a few pages of instructions before loading the game.

And since there were two version of SMGP2 with different track sets, there were two different introduction programs and two different games.

Both of these versions, and their intros are to be added to the Penultimate +2 Cartridge for the next update.

My first question was "can we have a single version with all the tracks?"

"No".

Oh. OK. Plan B, I would hope the track data might be at the end of the programs, and the majority would be the same, so I just need one copy of the main program and swap in one set of tracks or the other.

"No."

Ah. OK. It appears the game has been recompiled, as although much of the code looks the same, all the jump and data locations have shifted, so there is no commonality between the two versions. (I wasn't expecting there to be any commonality with SMGP1, and indeed there isn't).

So, we discussed the options, and didn't like the idea of having both versions on the main menu, three Super Monza Grand Prix is a bit much.

Ideally, the introduction program would be changed to ask the user to select the track set and then run the main program.

OK, that shouldn't be a problem......

......1 week later.....

My brain melted.

This one fought me all the way, but I finally managed to fit it into the cartridge.

Essentially I had to load one program (the introduction, now more a menu with instructions) and then let the user choose a set of tracks and then load one of two programs based on their choice.

After the user has selected their track set, they have the choice of showing the instructions, as before, or going straight into the game.

There were a couple of examples of that sort of thing already.

Final Orbit was actually a double title, Final Orbit and Bumper Bash. #NotMyCartridge

It always starts Final Orbit, but if you hit the Commodore key, it switched to Bumper Bash.

Both games were present in the 8K ROM. I guess some time in the 1980s, some executive was presented with a game which was something like 4.5K, so they had the bright idea of fitting a second game in what would otherwise be wasted space in an 8K ROM (which would have been more expensive that a 4K one if the game had been smaller).

Final Orbit had been in the cartridge for a while, with probably none of the users knowing the alternate game was there. When I added the live patching of games in the previous update (did I write about that?), I patched Final Orbit so it no longer switched, and added Bumper Bash to the menu with a different patch that meant it was locked in Bumper Bash mode, which is good as that is arguably the better game of the two.

Another example of this sort of thing is back in the early days of the Penultimate+ Cartridge. I had a Easter egg in the menu (which I don't think anyone found). Once you triggered it, the credits menu gained a new option "Tic Tac Toe".

When you selected that, it loaded a game of Tic Tac Toe, although it didn't say that (Some of you are probably old enough to get the reference.)

(I realise now I should have called it Falken's Maze, it's been a while since I watched that movie because every time I do I have to stop myself buying an Imsai 8080)

That lived at the end of the Spaceship Minus One ROM, as that game was about 5K and in those days I only had 8K slots so there was 3K spare and Tic Tac Toe was a simple BASIC program.

The 8K ROM is mapped into the VIC20 memory space at A000-BFFF. Space Ship -1 was a cassette conversion, a two part game. The first was a title / instruction, and the second the game itself.

As the first part was just loading a page of text, I added that to my normal ROM loader code so that it displayed that first, then went on to the game.

The actual Space Ship -1 game was stored in the ROM, but was copied into RAM at $1000 to run it (as if it had just been loaded from tape).

When the loader detected the Easter egg had been triggered, instead of showing the instructions and loading Space Ship -1, it copied a different game into RAM and ran that instead.

“The only winning move is not to play.”

Oh wait....

In those cases, both games fitted into a single 8K ROM. I have also converted several tape games into 8K or 16K ROM cartridges where the multiple parts are loaded into RAM and run, jumping back into the ROM with a SYS call to load the next part. (those are covered in excruciating detail in dozens of posts in the "converting multipart VIC20 games" series.)

This is different though, the two versions of Super Monza Grand Prix 2 (remember that?) are around 28K each, so I cannot load both into a 32K cartridge and then select one or the other.

The Penultimate works by switching banks of ROM to select different titles, but that is only controlled by the cartridge menu, and is disabled once a game is launched. I could use that mechanism to switch track sets, but I don't really want to have to enable it outside the menu. (since a game writing to the IO port could trigger the bank or mode switching which would stop it working - pretty sure Gorf does, I think related to the voice synthesizer it can use).

So, how am I going to do this?

Whilst looking at the options, TFW8b pointed out he had shrunk the tape versions using Exomiser. This is a self extracting compressor for PRG files. I hadn't looked into it before. The only experience I had with it were a bunch of games that were added at one point that didn't work properly on the cartridge and I had to ask for un-Exomised versions to get them to work.

You can spot it by a telltale flashing @ or A on the bottom right of the screen as the game is being decompressed.

However, TFW8b explained that was probably a problem with the command line options that had been used to generate the games I had been sent, so I investigated further.

And with the correct options it worked surprisingly well, getting both games reduced by about half.

Great, so now I could fit both games into a 32K block.

That was where things got complicated.

Time for some more diagrams. I hope the previous ones made sense, as these will be a bit more complicated.

Each 32K block in the ROM can be mapped into the VIC address space in various ways.

A recent update with direct loading of PRG files from those blocks, allowed files to be loaded from anywhere in the ROM to anywhere in the RAM.

I just need to make a menu program which runs and then copies one of the two games into position and runs them.

It took me a while to get my head around all the repositioning, particularly due to the gap at 8000-9FFF (character ROM, colour RAM, I/O etc.).

This means the file is contiguous in the ROM image, 0000-7500. This is copied to RAM 1200-7FFF and A000-A7FF

The menu is 0A00 bytes, and is copied from 0000-09FF in the ROM to 1200-1BFF in RAM.

The first track set version of SMPG2 is 3800 bytes, and is in the ROM from 0A00-4200. This is copied into RAM initially at 1C00-5400.

If the user selects set 1, the menu program needs to copy the game from 1C00-5400 to 1200-49FF. However, that would overwrite the menu program that was doing the copying, so I need some remote code.

I could copy code into the cassette buffer, but I can just as easily add a page of loader code at the end and just jump to that.

So that's what I did, and eventually (once I got my head around the addressing), it worked.

The final step is for Exomiser to expand the game back to 28K, which is does in place, and the game is ready to run.

Great, now for set 2. OK, strap in, this one is a bit more complicated. Maybe get that second cup of tea.

4200-6DFF in the ROM is copied into RAM at 5400-7FFF, and 6E00-74FF in ROM goes to A000-A6FF in RAM. (to get around the gap at 8000-9FFF)

That meant copying from 5400-7FFF in RAM to 1200-3DFF and A000-A6FF to 3E00-43FF. (note the second game is smaller than the first).

OK, here we go, let's try game 2.

Oh, it sort of worked, the flashing A in the corner showed it was decompressing, but locked up and stopped flashing.

It had started to decompress the program, so at least the start of the program was in the right place. I assumed I must have got the numbers wrong, so went back and worked them out again.

No, I had them right.

I tried various ways around and rewrote the copy routine in a slightly nicer way, but it still failed.

I then realised that this was all running from RAM, so I should be able to test it in the Vice emulator.

I copied the 32K ROM block form the cartridge and split it into the part that loads to 1200 and the part that loads to A000 and loaded those into Vice.

The number of times I had to type that in, I am still getting flashbacks.

Success, or rather failure. It did the same thing, and failed to decompress properly. At least I can debug it now and see what is going on.

First step is to check through RAM to see if the blocks were in the right place.

I went through checking the start and the end and for gaps in the middle, but it all seemed to be there.

So I saved the section of RAM and compared it to the original.

What? There were two bytes different in the middle of the file. Just two.

2BFE in the file was 4E and should be 16.

2BFF was 32 and should be 31?

I wasn't sure what was causing that, but I worked it backwards. 2BFF in the original file is copied into RAM to be run at 3DFF, and it is copied from 7FFF. Oh, that's interesting that's just before the 8000 gap?

I spent a while trying to work that one out, breaking at various places and checking for corruption, and also watching for reads and writes and finally caught a function in the BASIC ROM writing to that address. Eh?

Well, it seems that is some sort of temporary storage, set at address 55. It is 00 at boot, so gets set somewhere, and when I tried to change it, but it got reset to 7FFF, the top of the RAM that BASIC can see.

There didn't seem anything I could do to stop BASIC writing there, any time I moved it, it decided it liked 7FFF better than anything I suggested, so switched back.

I went for an awful bodge just to test this out, and poked the correct values into those two locations before running the game, and it worked!

Maybe I could live with that bodge? I then had a horrible thought, if this is caused by BASIC, will it be worse if I go through the extra pages of instructions?

Yes, it broke it as well, now more bytes were damaged.

To test it, I wrote 0 to the bytes in that area, then ran the menu through to the last page of instructions.

Yes, more things were getting corrupted.

Less of a bodge(?), I added a routine copy the last page of data from 7F00-7FFF to spare RAM at A800-A8FF. (it doesn't need to be 256 bytes, but it's easier to just do the whole block and it gives BASIC lots of space to trash stuff).

Then it was just a case of a nice and easy three stages coping blocks from 5400, A800 and then A000. (I did consider trying to split the file in two in the ROM image and introduce a gap, but I didn't want to have to mess with the PRG files in case they get updated in future.)

And finally, that worked.

Well, that was an awful lot of work, head scratching and brain melting, but I got there in the end. I hope the game is worth it.

There are now just two Super Monza Grand Prixes in the menu.

One a side note, in the process of doing that, I got quite adept at using the Exomiser to compress games, and have found quite a few titles in the cartridge that compressed by 25% to 50%, so I won't actually have to remove anything to add the new games, in fact, I freed up enough space to add several more titles.

So I am currently writing one in raw assembler, which seemed like a good idea at the time.

Wish me luck.


Advertisements

The cassette version of Super Monza Grand Prix 2 is available on cassette from TFW8b.com, along side another V2 game, Pentagorat II, now downgraded to the C64. And don't forget there is a triple pack option where you can choose three £4.99 games for £13.49. (all prices exclude VAT)

Also for the C64 is a great new graphical adventure game, Kingdom of the Seven Stones.

The updated version of the Penultimate +2 will be available shortly, alongside the new Penultimate +3, which adds an internal SD2IEC. More on that in a future post. (I guess I need to write an office suite for the Penultimate +4)

#NotMyBench

There is also my store with the full range of Minstrel and Mini PET accessories. Mini PET kits are all sold out now, but I do still have some Minstrel 3 kits left, which will last until I run out of Z80s.

I can ship worldwide, use the link at the top of the page to contact me with your location and what you want. Sorry I have to keep saying that. I am working on an alternative.

All the links can be found here:

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, and some of these posts contain bits from several Patreon posts. This also includes access to my Patreon only Discord server for even more regular updates. If you want to see more posts like this, it would be great if you could give me a bit of support on Patreon, or via the PayPal link at the top of each blog post.

Sunday, 22 September 2024

divMMC Troubleshooting

As far as I am aware, most users order a divMMC future from The Future Was 8 bit, they plug it in and it works first time.

Occasionally, we hear from users that have problems, so I thought I would cover some of the troubleshooting steps we go through.

First I should cover normal operation, as sometimes that is all the problem is.

  • Is the Spectrum switched off? Good. 
  • Is the edge connector clean? Good. 
  • Do you have an SD card with the appropriate files on? Good.

Now put those all together and switch on.

You should see a black boot screen for a few seconds, with several lines that all show OK.

You then press the button illuminated red on the divMMC. (the non-illuminated one is reset)

That should turn green and bring up a file browser menu.

From there you can select games to load using arrow keys (CAPS SHIFT + 5,6,7,8) or a joystick plugged into the divMMC.

Select your program and away you go.

Troubleshooting

If that does not happen, let's look at some of the potential causes.

Sometimes it can be simple things, such as

  • Pressing the reset button on the divMMC instead of menu
  • Pressing 5,6,7,8 without CAPS SHIFT
  • A broken joystick
  • Joystick with autofire activated
  • SD card empty / wrong files / wrong format / ejected / still in the box

If you see the black ESXDOS boot screen flash up for a few seconds with "fail" messages and then disappear and drop you to the normal Sinclair boot message, and pressing the illuminated menu button does nothing, then this is usually an issue with the SD card.

SD Cards

As SD cards can be a bit of a problem, there is an option to buy the divMMC with a pre-programmed SD card. These are brands and sizes which are known to work well, so is often the safest option.

Not all SD cards are the same. The divMMC uses the older MMC protocol (the clue is in the name).  Most SD cards still support that mode. 

However, some newer, faster cards, and particularly microSD cards do not support this any more, and so will not work.

The general rule for any SD card based solution for an 8 bit machine is to go for the oldest, the slowest and the lowest capacity card you can find.

Anything up to about 4GB were usually fine. Many of the 8GBs and 16GBs likewise, but when you get to lightening fast 128GB and things like that, you will probably be out of luck.

It can be worth looking around your older tech like cameras or sat navs or media players, digital photo frames etc. or even an old Raspberry Pi. See if a card could be stolen, or swapped for a larger modern one.

The adapters that come with some microSD cards can also be a bit rubbish, so beware of those and use full size cards if possible, or try a different adapter.

SD card formatting

SD cards can be formatted in some odd ways, particularly if used on a Raspberry Pi or something like that where they may be partitioned in a non-standard way.

The best way to make sure an unknown SD card is back to the standard partitioning and format is to use the SD Formatter Tool for the SD Association:

The filing system should be FAT, FAT16 or FAT32. Anything else such as VFAT or NTFS will not work.

SD card contents

One issue we see quite a lot when something like a divMMC hasn't been used for a while is the SD card has been stolen for something else, so the user gets a new one, drags a couple of .tap or .z80 files on and then finds it doesn't boot.

The SD card needs to contain the divMMC software in the correct BIN, SYS and TMP folders, for things like the file browser etc.

And, importantly, needs to be the same version as the firmware.

When the boot screen appears, check top right for something like v0.8.9-DivMMC and make sure you have the appropriate files in BIN, SYS and TMP folders in the root of the SD card.

You can download full SD card images as well as just the divMMC files from TFW8b.com

You can also get these from esxDOS.org (go here if you boot screen is older than the current version)

One you have the matching set of files, it should boot correctly.

Upgrading firmware

You can upgrade the firmware on the device, but you should only do this if you have a good reason to. If it is working fine, just stick with it. If there is a fix or a feature in the latest version you must have, then upgrade instructions can be found here.

Random Colours

If you get random coloured lines or dots on the screen, try powering on with no SD card installed. If that gets you to a Sinclair prompt, then follow the procedure above for updating the firmware. We have seen this a few times when the Spectrum has had power problems and that has corrupted the firmware.

If that makes no difference, make sure you do not have a EPROM ROM replacement (which does not support the ROM disable line), or if the ROM have been replaced, check the N / H jumpers have been set appropriately for the replacement chip (N for NEC chips, H for Hitachi or others). These have different pinouts that only show when using ROM disable from the edge connector.

If you still see noise with the SD card removed, and the Spectrum works fine without, then best contact support at this point as the firmware may have become corrupted past the point it can heal itself.

No boot screen

This is one I have seen more times that I would have expected. You get an apparently working ZX Spectrum, plug in a divMMC and when you switch it on, you go straight to the Sinclair copyright screen as if there was nothing plugged in.

A word of caution, several things can cause this, this is a known problem, but it is not necessarily your problem, so check out all the other options first.

First check if the SD card is properly inserted. Has it clicked in? try to click in it and out a couple of times to be sure.

If no SD card is inserted, the divMMC future will be disabled (this is used to upgrade the firmware and replaces a jumper on some other models).

If you are using a microSD adapter, try another or ideally a full size SD card, as previously stated, these adapters can be a bit rubbish.

Check the edge connector, make sure it is not dirty or corroded. Use the patented* TFW8b edge connector repair tool if you have one.

* not actually patented.

Try another Spectrum if you can, or try another divMMC or divIDE or interface 1, as long as that is known good, and see if anything else works.

If you have got here and you are seeing no boot screen or any other activity, then it may be you have one of a surprising number of Z80 chips in Spectrums that have a bad M1 line. If you have an oscilloscope, probe pin 27 of the Z80 and see what you can see.

Normally the M1 line goes low at the start of the instruction cycle, when it is reading the op-code of an instruction. Other times it should be high.

Measuring the M1 line (green) should look something like this, with the clock line (yellow) at the top for reference, both on 2 volts per division.

It has another use in certain modes. When an interrupt signal has been received, the Z80 will pull M1 low and then pull IORQ low to indicate an interrupt acknowledge. This is not a normal IO request, and IO devices should ignore this. Not all do, but the divMMC is properly behaved, and will ignore interrupt acknowledges, and only react to proper IO requests.

Essentially, the divMMC will not respond to any IO requests unless the M1 line is high.

Unlike the ZX80 or ZX81, the ZX Spectrum does not actually use the M1 line internally. (The ZX80/81 use the M1 line to know when to trigger the NOP generator to feed the Z80 a NOP when the video is being read).

This means you can have a perfectly functional ZX Spectrum with a bad M1 line and not know about it until you connect something which needs the M1 line.

It can be difficult for some users to accept that their beloved machine may have a fault, but it's either the 40 year old computer that's been though who knows how many hands, or the brand new device which has been recently build and tested. I like to think of it like buying a brand new caravan and hitching it up to an old Ford Cortina. If the lights don't work, do you blame the new trailer, or the dodgy 70s tow bar wiring? Yes, the headlights might work, but you wouldn't know the tow bar socket was bad until you plugged something into it.

It seems the signal is just not there. It's not weak, I have tried buffering it, amplifying it, pulling it high and low, and it is still just noise. Even over a long time it's just noise.

I don't know why so many Z80s in Spectrums have bad M1 lines.

  • Did the come from the factory like that?
  • Did Sir Clive buy a faulty batch because he knew the Spectrum didn't need the M1 line?
  • Do they just fail over time?
  • Are they susceptible to static from the edge connector?
  • M1 is right next to 12V from the switching regulator on the edge connector, have these all be shorted out when someone pulls out a joystick interface at an angle when powered on?

If your Spectrum has an M1 line like that, then you either need to learn to love loading from cassette, or you need to replace the Z80.

Sadly those went out of production a few months ago, and it doesn't look like there are any plans for Zilog or any of the second sources to bring them back. (there are some projects to try to recreate the Z80, so hopefully one day you will again be able to buy something with 40 pins that is a drop in replacement)

There are still Z80's available from TFW8b, whilst stocks last as they say.

I have a Spectrum here with this issue, so lets get it fixed.

Looking at the board, it appears the Z80 and ROM chip have been replaced in the past.

Based on the unmistakable smell of 80s flux, I would have thought this happened sometime in the 80s when the machine was only a few years old - the rest of the chips seem to have matching late 1983 / early 1984 date codes.

I start by desoldering the Z80. Please only do this if you have experience with this sort of thing. It is very easy to damage these boards, lift tracks and pull out through hole plating etc. so please be careful and use lots of flux and lots of time, and if in doubt, don't.

Nice clean removal, no damage caused by me (or the person that originally removed the Z80).

Time for a new one. An RS bagged one no less. (actually, I can tell you a trade secret here, since they no longer sell them. Because RS, their pricing was a bit off, and it worked out cheaper to buy bags full of the individual bagged Z80s instead of buying them in a tube. This makes no sense, but I have spent many happy evenings in front of YouTube "shelling" Z80s and putting them back into tubes)

I notice it says PEC on the bag, but PEG on the chip. Not sure, but I think PEC is not ROSH and PEG is the later lead free version?

Anyway, old Z80, new Z80. Lets get it fitted.

I like to use a socket, in the unlikely case this doesn't fix the issue, I can put the original back.

All nice and neat.

Checking the M1 pin now, it looks a lot better.

The M1 line is now doing stuff as it should, all nice and clean sharp transitions. The number of clock cycles per instruction varies, so the mark space will not be consistent, however, it will always be clearly 0 or 1.

Time to give it a go, and well, of course it worked.

Ah, that's what I was looking for.

I love a bit of Spellbound. It's a hard life having to test these things....

So there we are, another Z80 with a bad M1 line found and replaced and a working ZX Spectrum and divMMC ready to go back.

I've cut out a bit of a long and ranty bit about "refurbished" computers here, go to Patreon if you want to see the original version.

By the way, if you have read this far, please give the post on Twitter a like and/or comment, and consider subscribing to the Patreon if you want to read more of these. Check back here every Sunday for a new post.

Anyway, it all seems to be working, ready to go back.


Advertisements

DivMMC Future

The DivMMC Future is available from The Future Was 8 bit. Don't worry if it shows as "backorder", more are currently being built and should be shipping this week.

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, and some of these posts contain bits from several Patreon posts. This also includes access to my Patreon only Discord server for even more regular updates.