Wednesday, 28 September 2022

The Devious Map

I've been plugging away at the RE since the last post, but haven't been able to devote any large amount of time to it just yet, but thought I should post an update.

I have made some progress on the SUB CPU which reportedly controls the graphics objects and hardware. What I've discovered thus far would tend to support that theory.

I've spent most of the time trying to understand how the map data is stored in ROM. I'm almost embarrassed to say that it still eludes me, even after multiple sessions and with reference to both the MAME driver and the MiSTer Xevious core RTL code. In fact I'm beginning to wonder if my faculties are beginning to fail me; it has been a while since I've done any really challenging development, let alone reverse-engineering. But I'll come back to the map in a bit...

In the process I've worked out the scrolling logic and with it, identified the mechanism that defines the objects (both ground-based and air) in each area. Without going into too much detail, the game keeps track of what I've termed a scroll counter, and for each area there is a table with entries for each object, sorted by their coordinate (scroll counter value) and a few parameters. As the map scrolls, the code checks to see if there's an object on that row and if so, looks up a function table to handle the object.

By patching a single conditional return, the map can be rendered entirely devoid of any objects.

At this stage I haven't identified which functions correspond to which object, but I may focus on that next. It may not be as straightforward as one might think, as the first few functions I looked at simply set variables in shared RAM and return - no doubt for subsequent use by the main CPU. At least one of them does check the dipswitch setting for difficulty, so that will be a clue.

So, the map that is doing my head in. A full map image is 2048x1024 pixels, which corresponds to 256x128 tiles. Each of the 16 areas comprises a 256x32 tile (28 visible) strip on the map, some areas overlapping, some identical. I've even identified the table of offsets into the map for each area (strip).

The complete Xevious World Map

Two issues have me confounded. Firstly, there appears to be 512 different background tiles as displayed in MAME. However, the tilemap code (and the RTL) only deal with an 8-bit tile code. There's no tile bank switch that I'm aware of, so I simply cannot fathom how more than 256 tiles are used.

Secondly, a map of 256x128 tiles equals 32,768 tiles to define. Add 8 bits of attribute data (palette, colour, flip etc) and I'm expecting 64kB of data! However, there are three (3) ROM devices containing map data, for a total of just 16kB. But it gets more confusing; a lot more confusing. The map ROM is not directly accessible in CPU memory space, but rather the address is latched in two 8-bit registers. And the decoding from these registers is far from straightforward; 2 of the 3 ROMs are actually used to further generate addresses and with extra logic for automatically flipping thrown in.

I should add that I've found the code that reads in a 32-tile row from the map as it scrolls. As yet it hasn't revealed any clues, though I've just started to experiment and I do have a few ideas.

So unless I'm really losing it, and someone reading this points out the obvious (in which case I'll consider throwing in the towel and retiring) there's something more to the map than a simple array of tiles. I'll definitely write up a post about it if and when I manage to decrypt it all.

4 comments:

  1. I got an email from Ville (thanks!) suggesting there could be some form of meta/macro tile mechanism in place. That is certainly a possibility and something I had considered as well.

    However, if there is such a mechanism, I can't see it atm. Perhaps that logic is implemented in the two devices that munge the address latches to generate the address in the 3rd device... it's possible. I'll continue on with this in mind. Thanks again Ville!

    ReplyDelete
  2. A loooong time ago I wanted to remake Xevious and I extracted the map from the ROMs and made it scroll. I remember data being stored sideways, or at least horizontally instead of vertically, so I also had to turn it all on the side before showing it. I did all this in Pascal 7.0, which is not exactly suited for that 😆 I don't believe I would've deleted my code, but I couldn't find it last night either. The curse of having too much storage, lol. I have no plans to pick that project up again, but I'm looking forward to following your experiences with it.

    ReplyDelete
    Replies
    1. I originally did want to understand how it's stored, but in retrospect it will be enough to extract the map via the same mechanism the game uses; I'll port the relevant extracts from MAME driver and simply feed in coordinates in the correct order.

      The game builds the map one row (32 tiles) at a time in the background video ram block(s). That logic I've already RE'd and can use to drive the map generation.

      If you do ever come across your code though, I can read Pascal! ;)

      Delete
  3. Not sure why I can't see gp2000's comment here (notified by email) but here's part of what he had to say...

    "I find I can only take static analysis so far and I'm much better off getting in there and tracing data and looking at what data is consumed to produce a certain result. There's also something to be said for altering the data and seeing what happens."

    Definitely an approach I commonly use in RE'ing. In fact just last night I was using it on another part of the program - the object table that defines all the air and ground-based objects in the game.

    And as I alluded to in my response to Sokurah, I'll extract the map by feeding coordinates into the emulated latches and ROMs, even without a full understanding of how the map is stored.

    ReplyDelete