I haven’t got much to report here, post 147 continued the massive ‘change all files again’ refactoring efforts in MAME which kinda derailed progress for a few days, although things appear to have settled down again now. I don’t think I would have made much progress anyway, I haven’t really been in a MAME mood, so in reality the timing of the changes probably wasn’t that bad, even if the first part of them (which crept into 147) are largely responsible for the ‘Mortal Kombat is broken!! bug which I must have seen posted on at least 30 forums (surprising really because regressions in other drivers can go unreported for the best part of a year but I guess the MK games are unfathomably popular) Breakage aside, I still need to write about some of the other cool bits in 147 however, again the lack of a MAME mood hasn’t really helped there.
Probably the most interesting piece of progress lately is Kale’s work on the Seibu COP protection. It’s no secret that a fair number of the remaining unemulated 90s games are serious tough cookies when it comes to figure them out, for many systems it’s like the final boss run with every battle suffering from SNK Boss Syndrome.
I’ve mentioned the COP here before, it handles all sorts of game operations, movement, collisions, DMA, BCD maths, indirect ways to access memory and is even semi-programmable through a series of short ‘Macro’ commands which get uploaded to a table on startup etc. It also manages to blur the lines well between what are operations actually performed by the COP and what are external operations. The programmable Macros also only seem to be half the story for some of the functions they provide, the collision ones for example appear to be incredibly simple, too simple, with barely enough operations to grab the values from the doubly indirected table they use and perform calculations on them, so it’s likely the actual macros only perform half the work for several operations allowing for game specific customization of how more complex commands hardcoded in the silicon are fed their data etc.
Kale has been doing most of the work on this, as mentioned, I’ve been trying to understand bits of it, the collisions, hitbox checking etc. which is less straightforward than it should be for the more complex cases of Legionnaire and Zero Team. I think I’ve figured out how it determines the basic size of the hitboxes, we have X co-ordinates, Y co-ordinates, origin and size, which works much better than what we have now in the “SD Gundam Sangokushi Rainbow Tairiku Senki” case (you no longer fall through the elevators etc.) but actually ends up worse for Legionnaire, which has 2 extra 8-bit parameters and additional flags checked based on those. Logically you’d expect them to be Z, but you have no pointer to any RAM containing a base virtual ‘Z’ co-ordinate (assuming it isn’t just after the X or Y one, I should check) Also in terms of the resulting flags, for X and Y you get the distance between the parts returned in registers, you get no such thing for a possible Z value which would make Z checks meaningless because you’d only have the hardcoded ‘Z’ values from the doubly indirected ROM table.
Further confusing things is that Legionnaire, with the ‘correct’ basic hitbox sizes only checks collisions to your right, if you’re facing left, it sends the same hitbox as if you were attacking right, and there doesn’t seem to be a parameter to flip it, so you still end up attacking enemies to your right instead of left. This makes me think the extra parameters might just exist to extend the hitbox, or another command is failing and the software is requesting the wrong hitbox from ROM because some of the game code still thinks you’re facing right (there is other odd logic like having to double the X speed value another command returns if you’re moving left which might suggest the same, the half speed might be a backwards walk speed for enemies)
To make things even more annoying the ROM tables are inconsistent. Every game calls the same set of commands, which fill in the same values. Legionnaire’s second table is 4 words (xxxx yyyy ???? 0000) with the first table containing pointers to every 4 words. Zero Team has data in the format (xxxx yyyy ???? 0000 0000 0000) and pointers in the first table to every 3 words, meaning every 2nd pointer is basically useless because it points to blank data. Then you have the games which don’t have any ‘depth / z / ????’ value which just have the tables in (xxxx yyyy xxxx yyyy xxxx yyyy etc.) formats and point to every 2 words. I assume this means that the calculations are independent of each others because if the commands get processed the same then they’re going to end up with invalid ‘x’ data from the next entry for the ‘depth / z / ????’ parameter in the cases which pack the table without the ???? values. Kale’s testing would appear to back this up because he was getting an unpredictable value he couldn’t understand at all in one of the result registers.
So you can see the challenge, and that’s only dealing with a tiny, tiny piece of the puzzle. For these games to work perfectly every single piece needs to be understood properly, implemented properly, and full verified / tested against real hardware results. It’s possible the chip has alternate ways of doing things too, if for example the ‘Macros’ executed for the collision simple substitute some kind of regular memory access it’s entirely possible there are manual ways of doing the same thing (and I actually wonder if this isn’t what Raiden 2 does, it accesses registers nothing else does for some bullet / sprite processing, although they could be specific to the sprite chip on that game because it uploads the encryption params to the same area, which is what I mean about the lines between COP functionality and other hardware being blurred)
I could speculate endlessly on this because right now there are so many unknowns, so many little surprises, odd choices etc. that you’re left wondering what’s around the next corner and really questioning how everything fits into place.
What Kale is doing is cool, but I think everybody needs to keep their expectations realistic, there is simply so much game logic tied to the device in all these games that getting to a point where it can be considered trusted is going to be a long slog and between now and then I fully expect things to both improve and regress multiple times as new findings are made and previous ones invalidated.
In some sense we’re lucky, we’ve got a large number of games making different use of the protection device, but it means coming up with a generic implementation to keep everything happy is important, as opposed to coming up with per game hacks just to provide the logic the game wants, which is what the Seibu Cup Soccer bootleg appears to do, albeit still mostly in hardware with additional hardcoded tables, making it no easier to emulate than the original! The good thing about having a large number of games is it gives us a variety of test cases, and a good slap if we’re doing things wrong, or not fully implementing something, as the collision stuff proves.
As stated before, to the best of our knowledge the COP protection isn’t provided by an MCU, but fixed function logic programmed inside one of the customs, ie it’s not something you could decap with really meaningful “well let’s just emulate the CPU then” results, so an accurate simulation is essential.
If none of this makes any sense to you, that’s fine, an awful lot of it still doesn’t make sense to anybody else who has looked at this thing either, unlike a number of other systems which are relatively simply and just suffer from a lack of interest this one has slain every other developer who dared come close.