On Thursday, June 29, 2017 at 6:46:59 PM UTC-7,
anthon...@gmail.com wrote:
> Michael, can you give a very quick overview of how you would go about reverse-engineering a game from AppleWin? I'm looking at the debugger manual but I don't see an option for extracting code from memory and saving to disk.
Sure, ask the simple questions. :-) I kid -- I'm more then happy to help out.
From the debugger you can use the BSAVE command. Type: HELP BSAVE to display the built in debugger help.
Let's say I want to save a chunk of memory from $6000..$BFFF -- then I would use this command:
bsave "game.bin",6000:BFFF
Every game has a "main loop". I prefer to work "bottom-up" to find it, but you can also work "top-down". I often switch back and forth.
There are usually 2 main attack vectors I use for reverse engineering:
1. Search for where the speaker is accessed since ALL games MUST use $C030 to toggle the squeeker. Now someone _could_ use one of the billion 6502 indirect modes -- such as $C000,X -- but no one ever does that in practice for the speaker. We want to search for the absolute address (in big endian format) 30 C0
For example, let's fire up Montezuma's Revenge. Since I loaded it from DOS 3.3 I know it starts at $13F0, because the DOS3.3 last load address AA72.AA73 has F0 13.
s 1300:bfff 30 c0
Returns these 9 locations:
1:$7759
2:$7775
3:$7790
4:$77AD
5:$77C8
6:$77E9
7:$780C
8:$7827
9:$8B34
Let's examine the code around these results. Type this into the debugger
@1-1
Oh look, what do we find?
7758: LDA $C030
775B: DEC $C1
775D: BNE $775B
775F: DEC $C0
7761: BNE $7754
7763: RTS
I usually set a breakpoint on the RTS to see who called us.
BPX 7763
There is also some more speaker code at 7764, and 7780. Let's trap those too.
BPX 777F
BPX 779A
PRESS <F7> to exit debugger
Starting a new game, via CALL-151, 13F0G, press RETURN to play.
And when the player makes a "jump" sound, our breakpoint at 777F is triggered. Pressing SPACE to process the RTS we see we were called from $7730, which in turn was called from $69AC.
We'll probably want to search $6000 .. $6FFF for the main loop.
2. Find the blitter via setting a breakpoint when the HGR screen is accessed.
BPC
BPM 2000:3FFF
F7
Immediately we stop at $B0F1. Let's put this in context.
U B0EB
We see that this memcpy() loop has been manually unrolled as there are:
* 8x LDA ($9A),Y
* 8x STA ($80),Y
If we inspect what the pointers are we find:
* Source pointer ZP $9A = $F53
* Dest pointer ZP $80 = $21D3
We can even inspect the HGR screen(s) via the debugger commands:
HGR1
HGR2
We see that Montezuma's Revenge is using page flipping as well.
That was a quick primer but feel free to post question.
Hope that helped.