makestuff / umdkv2

APP:USB MegaDrive DevKit v2
http://www.makestuff.eu/wordpress/?category_name=umdkv2
GNU Lesser General Public License v3.0
111 stars 22 forks source link

Errors from gdb-bridge when interrupting Sonic & Knuckles #3

Open makestuff opened 8 years ago

makestuff commented 8 years ago
chris@wotan$ gdb-bridge -l 8000
UMDKv2 Bridge Tool Copyright (C) 2014 Chris McClelland

Waiting for GDB connection on :8000...
Got GDB connection from 127.0.0.1:7109
umdkDirectReadBytes(): Illegal direct-read from 0xFFFFFFF0-0xFFFFFFF1 range!
umdkDirectWriteBytes(): Illegal direct-write to 0xFFFFFFF0-0xFFFFFFF1 range!
^C
chris@wotan$ 
makestuff commented 8 years ago

This problem is caused by the fact that this game's VBlank routine is in WRAM. Unfortunately this reduces to a catch-22 situation: we can't read or write to WRAM without the monitor, and we can't acquire the monitor without writing to WRAM.

The code executing in WRAM doesn't show up in the trace log, but the CPU invariably ends up fetching an opcode from 0x000584 soon after each VBlank interrupt:

            22417980 C RD 000078 FFFF
            22418005 C RD 00007A FFF0
            22418138 C RD 000584 4E71

In fact, tracing all writes to 0xFFFFF0 suggests there's just a simple jmp 0x000584 there:

$ logread trace.log | grep -P "W. FFFFF[024] "
             6693005 C WB FFFFF4 0000
             6693119 C WB FFFFF2 0000
             6693144 C WB FFFFF0 0000
             9067697 C WB FFFFF0 4EF9
             9067823 C WB FFFFF2 0000
             9067848 C WB FFFFF4 0584
$ printf '\x4E\xF9\x00\x00\x05\x84' > jmp.bin
$ dis68 jmp.bin 0x000000 1
0x000000  jmp 0x584
$ 

So this would be a great use of the -b <brkAddr> option to gdb-bridge, but unfortunately the code that supports overriding the default brkAddr was factored out somewhere along the line. But a hacked vbAddr = 0x000584 in the code does work, which proves there's nothing more mysterious going on.

TODO: Allow the user-supplied -b <brkAddr> to override the default address determined by calls to umdkDirectReadLong(handle, VB_VEC, &vbAddr, NULL).