News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Finding breakpoints w/o RAM addresses  (Read 1912 times)

vonMuir

  • Jr. Member
  • **
  • Posts: 26
    • View Profile
Finding breakpoints w/o RAM addresses
« on: July 18, 2016, 07:38:01 pm »
I've been having a lot of success with my first hack on Sega Genesis, but I'm having trouble finding a way to locate a specific breakpoint I'm looking for. I'll try to be brief:

I want to rewrite the asm code so that my characters will not be able to trade with each other, unless under certain conditions. I also want a message on the screen to display information for the player.

Fortunately, this sort of exists in the game already. The conditions for the trade are different and the message on screen is different, but my life would be so easy if I could just locate this code and modify to my own needs. I'll need to have a similar message for other things later on in the hack, so you could imagine that locating this code will save me hours upon hours of work.

The problem is that I can't find anything concrete in the RAM data to set a breakpoint on: I found a FONT table for the message onscreen and searched every which way for the hex data (including relative/arbitrary search). The VDP data is stored in a separate place from the game's RAM. Most of the pertinent data would be in the VRAM, but I can't find a debugger that breaks on VRAM (RegenD has a menu for it, but it doesn't seem to work).

The only thing that really changes when I trigger the action above is the VDP, so I don't have anything else to go on. If I knew the op codes for writing to the VRAM, I might be able to find it in the ROM file. I might be able to find it if the debugger just breaks when I hit the button on my joypad, but I don't think there's a way to break for that either.

Actually, how does the game even know where to direct the PC when you hit a joypad button? I know it's a somewhat unrelated, but I'm curious.

Well, any ideas? I don't know if there's a standard way to approach this problem or if I need to come at it some other way entirely.

Malias

  • Sr. Member
  • ****
  • Posts: 303
    • View Profile
Re: Finding breakpoints w/o RAM addresses
« Reply #1 on: July 18, 2016, 08:52:37 pm »
They're not breakpoints, but Gens r57shell Mod let's you set hooks for VRAM writes.  Also, games will often stage VRAM data in RAM before transferring.  So, that font table could very well be what gets used in vram.  Have you tried setting a read breakpoint on a font character that displays on screen?  If it's the one used to show the messages, it should trigger and give you a place to trace back from.
The great achievement is to lose one's reason for no reason, and to let my lady know that if I can do this without cause, what should I do if there were cause?
     ~Don Quixote~

vonMuir

  • Jr. Member
  • **
  • Posts: 26
    • View Profile
Re: Finding breakpoints w/o RAM addresses
« Reply #2 on: July 19, 2016, 12:29:10 am »
They're not breakpoints, but Gens r57shell Mod let's you set hooks for VRAM writes.

Is that the RAM Watch thing?


Quote from:
Have you tried setting a read breakpoint on a font character that displays on screen?

Yeah, but it didn't break.


I may have found a workaround. I found a similar conditional trade in the game (which I had forgotten about) that uses regular ASCII font from the ROM file. I was able to break on the read of the ROM offset and then trace the op code back to the point that triggered the condition.

I inserted some code that SHOULD have altered the condition, but it didn't seem to work. I think I'll be able to get it to work if I just troubleshoot for a little bit (which I'll do in the morning). I'll update if I'm successful.

In the meantime, I certainly wouldn't mind any other advice.

STARWIN

  • Sr. Member
  • ****
  • Posts: 454
    • View Profile
Re: Finding breakpoints w/o RAM addresses
« Reply #3 on: July 19, 2016, 10:09:47 am »
Fortunately, this sort of exists in the game already. The conditions for the trade are different and the message on screen is different, but my life would be so easy if I could just locate this code and modify to my own needs.

The problem is that I can't find anything concrete in the RAM data to set a breakpoint on

The condition you mentioned above has to involve one or more RAM reads.

I might be able to find it if the debugger just breaks when I hit the button on my joypad, but I don't think there's a way to break for that either.

Actually, how does the game even know where to direct the PC when you hit a joypad button? I know it's a somewhat unrelated, but I'm curious.

Controller input is a good route to try, it is always "close" to any event that directly depends on it (though the game's input can flow thru a bit more addresses than you'd like, like generic structures that the input always follows). The input is memory mapped, check the 68k memory map to get the idea. And then read somewhere how to read input in genesis (like the cpu reads "data" or "serial receive" in a certain way?). As these are in the memory map, read/write breakpoints should work as usual.

So if you then check a breakpoint that breaks at every input read, it is still a bit annoying because it breaks all the time! There are at least two ways to observe what happens when you press a key:

1. Start recording trace log, press the key and stop. Then just go over the log searching for the magical input address until you notice a different output from "nothing pressed". The main problem here is that the trace log gets massive easily, so either do it quickly or set a breakpoint that breaks in the desired end state. It lets you read the control flow nicely though (as a price you can't see the code that wasn't taken).

2. If the debugger supports conditional breakpoints, you can make it break when the input routine reads a value differing from "nothing pressed" or specifically the keystate you are looking for.

Alternatively it is possible that the keystate gets read into some generic RAM location (before doing anything with it) that you can see/diff from a savestate easily (but there can be many such locations).

edit: https://emu-docs.org/Genesis/sega2f.htm section 4. or similar sources talk about I/O. It mentions the Z80 but looks like the controller area is just after its area, so hopefully no connection to that.
« Last Edit: July 19, 2016, 10:24:15 am by STARWIN »

vonMuir

  • Jr. Member
  • **
  • Posts: 26
    • View Profile
Re: Finding breakpoints w/o RAM addresses
« Reply #4 on: July 20, 2016, 02:27:59 pm »
The condition you mentioned above has to involve one or more RAM reads.

How can you be so sure? What should I expect those RAM values to reference?

Quote from:
Controller input is a good route to try...

It looks like the statuses of both joypads are expressed at $380001:
https://wiki.neogeodev.org/index.php?title=Memory_mapped_registers

Thank you for the step by step instructions. I'm going to try this out when I get a chance (it could really come in handy for a couple of mods I need to make). I've been able to get conditional breaks at the above address (although I haven't checked to see if it's breaking correctly or not).

STARWIN

  • Sr. Member
  • ****
  • Posts: 454
    • View Profile
Re: Finding breakpoints w/o RAM addresses
« Reply #5 on: July 20, 2016, 02:44:28 pm »
How can you be so sure? What should I expect those RAM values to reference?

If there is a condition, there is code that checks if something is true or not. ROM doesn't change (read-only), so if the condition depends on ROM only, then it is either always true or false. But that would be dumb because it equals taking the true or false path, with no condition at all.

So you are left with RAM and some I/O and such.. well it would be bizarre to check the controller (or other non-RAM source) specifically for each condition in the game, so it probably goes to a generic location, which tends to be RAM. Registers aren't usually used for long-term variables. So yeah, I can't be certain but some things make more sense than others.

I don't know what the values could be and I don't know what kind of condition we are talking about. Relevant things don't exist in isolation though, as otherwise causality/data/values couldn't flow thru the game and it would be stuck.