Monday 29 July 2013

Time Travel (1.21 Giggawatts required)

Tonight I have been attempting time travel. One thing I've wanted to change early on in this hack has been the year of gameplay. Starflight starts in 4620, which doesn't fit for a Mass Effect game [SPOILER]depending on how you play number 3![/SPOILER]

As noted before, I've found the operations centre messages in the ROM, but changing the dates makes the title not appear in the message list. The message is still there, and still selectable/readable, but the title will not show. I reckon this is tied into the in-game calendar, as changing the title doesn't make it disappear, only changing the date. I thought I would try a quick and ugly brute force attempt to change the games start date. Searching for text in the ROM for "4620" only brings up the message titles. So I tried to look for the hex (120C would be the equivalent).

I found 20 examples. I changed the title of the message so the date read 2158, and went through one by one changing any instance of 120C into 086E (the hex equivalent of 2158). 19 of these changed nothing when viewing the message centre. Changing the first totally borked the game:

The EA splash freaks out. Different restarts can make it freak out in different colours, but it never gets past it. So I can safely say that those 2 bytes aren't the initial date. Gives me a rough idea for where to start when removing the EA splash (which I would like to at some point), but no help with my current goal.

So time for another way to find the time format. Idea here was to look through what was happening in RAM, so I fired up regend (the only debugging Mega Drive emulator that actually seems to function in Wine), and got the ship orbiting. As there was little happening on-screen, and no input to confuse things, I thought it would be easy to spot something as simple as the ticking clock of time. After investing some time of my own, I wasn't wrong. The fun starts at RAM position 0x943B...

0x943B (highlighted green) is a simple rising tick, that flips at 93h. Strange number, but if it gets the game timing right who am I to judge? The next byte (highlighted in red) constantly matches the current "hour" in-game. This however, seems to be stored in BCD - i.e., 09 flips over to 10, as opposed to 0A as you'd expect in hex. The following byte (highlighted blue) matches the current in-game "day" (again stored BCD-style). As expected, the next 2 bytes hold the "month" and "year" as expected, again in BCD. The "year" byte only holds 2 digits, such as 46XX. So I did what comes naturally - try and break it and see what happens! Pause emulation, push a few nonsensical times into the RAM, let emulation resume and...

It's broken. Kinda. Though for some reason, the game just doesn't care. Even though it is the 1Cth day, of the C4th month, 462F anno domini. So I let it roll, to see what the date would tick over to... Day 1C clicked to 23, which made some kinda sense. C is equivalent to 12, which added to the 10 makes 22. Which should turn to 23.

Changing the date/time to something more impossible has odd side effects. For example, setting the hour to 26, gets it trapped on the same day, with the time getting higher and higher with never changing a date. Looks like the time handling routine is just "hour==24" to change the date, as opposed to "hour>=24".

For fun, I set the year to 4699, and letting it tick over returns it back to 4600. This reinforces my impression that the "46XX" year is hard coded into the ROM. I imagine the date routine for checking messages will add 4600 to the year byte before comparison. Now the challenge will be to find 4600d in the ROM somewhere (or 11F8h), and find the code that initializes 0x943F in RAM, and tweak them both to change the year in the game.

Time to start learning more about regend's debugging features!

No comments:

Post a Comment