This is possibly a bit of a premature announcement because I don’t consider the game to be working yet but I’ve spent a large amount of the past week looking at the IGS game ‘Puzzli 2’ with some real hardware assistance from rtw.
As with almost all IGS games of this period there is an MCU on the board providing certain functions for use by the main game code. The ultimate goal is to find a way to trick the MCU into spilling out it’s internal ROM and simply emulate the ARM CPU program contained inside but in some cases that isn’t possible because the MCU is not using any commands with unchecked lookups into internal ROM.
After running a data logger on the Puzzli 2 board and watching what it wrote to and read from the device it quickly appeared Puzzli 2 was one of those cases, all functions were work on the data passed in, transform it and give it back in another format.
There are 3 main functions the Puzzli 2 MCU provides, first, descrambling of the addresses where the Z80 code is stored for sound / music, this was the first thing I hooked up after studying the logs (albeit with hardcoded addresses because the scramble isn’t clear) It was also confirmed that the device provides the correct addresses for Puzzli 2 or Puzzli 2 Super depending on which game code you have running, so clearly the addresses returned are derived from the data passed to the device at startup.
The second function is providing offsets to where graphics / palettes are stored. This is used for the random tiles shown during the intro animation and all the backgrounds. In the end this turned out to be a two step operation, the first step multiplying the two nibbles of data passed by 0x19 and 0x5, the second step being the addition of a 4-bit value to the final result.
The third, and by far most complex thing it does is descramble and decompress the level data structure for each level. Before each level starts the 68k passes in a stream of data from ROM, the MCU then applies a loop of 16 8-bit xor values to that data (from a 256 byte table, the first value passed is the 8-bit offset into that table) Having done that, in the same step (without revealing the intermediate results to the 68k) the MCU fills in a 10×8 structure for the level data as well as a few misc variables based on the input stream. The MCU is also responsible for flagging to the 68k when it has received enough data to build a level.
The level structure is then read back with another command, again with the MCU signaling when enough data has been returned based on the data passed earlier.
What this means is to simulate the protection device I had to understand the format of the source level data, and the format of the level data the game expects (sizes, object types etc.) as well as find a way to figure out the scrambling, easier said than done because you can’t see the descrambled data directly, only the final level structure after the MCU has also expanded / decompressed that descrambled data. Understanding this was by far the most time consuming part and is where work still really needs to be done.
The work done so far has however seen the game emulation improve significantly, many level structures are built correctly, although currently if I look at all the levels the game has several contain what appear to be invalid elements (if you put them in a level the level becomes impossible to finish) interestingly many of these are stripped from the Puzzli 2 Super rom, so I don’t know if they’re unused data, game bugs, or if they do something else on the level they’re meant to be used (they could also be errors in my descrambling, but the xor addresses on which they fall are confirmed with other levels so that’s unlikely)
Needless to say this is a lot of work, and while I took a lot of joy from being able to clean up and remove all the per-game simulations of the Data East 104 / 156 chips there are still cases like this where we have no choice but to simulate things (unless a way for the MCUs to be decapped becomes available)
There are also problems with my interpretation of the ‘depth’ data, I think I see where it’s passed and read but what I’m doing to it is clearly wrong, the width data passed at the same time appears to be processed correctly by the simulation. Depth is one of the level difficulty factors and it being wrong is causing the black bars at the bottom of some screens because it’s drawing everything too high up / for an easier difficulty setting.
Hopefully I can figure out the remaining issues and we can get this one marked as working in the near future. Interestingly it also points at there being a background colour register we’re not emulating on PGM, unless some of the backgrounds are just glitchy on real hardware (it happens more often on games than you’d think). Even if things aren’t fully working yet this felt like promising enough progress to mention it, and should give some insight into just how tricky even the easier cases can be sometimes. Also for those wondering Puzzli 2 Super is quite a significant upgrade, it adds the entire VS CPU mode, the regular Puzzli 2 only has a VS. mode for 2 players.
One thing I really like about this game is the music, I find many of the tunes to be catchy and perfectly fitting for a game of this kind. I don’t know if like with Bee Storm they’re not all exactly original creations but I have a feeling we might find out with time if people end up matching them to source mods ;-) The intro music I’d hope is original because it syncs up so well with the intro animation and is delightfully bouncy!
In other PGM news XingXing dumped the internal ROM of a Knights of Valor 2 Nine Dragons or ‘kov2plus’ as it’s otherwise known, that was actually next on my todo list but it looks like some time has been saved. Instead I’ll bump Puzzle Star to the #1 spot after this one is done, and hopefully figure out how that one manages the level data properly so that it’s playable beyond the first world.
*edit* after some further work I’ve made some more improvements and fixes to the emulation, including fixing the backgrounds, and what seems to be an additional region protection that was causing resets when you attempted to insert coins to continue. I’ve uploaded a video to YouTube showing gameplay plus the various attract cycles for each region at the end.