A day or so and 700 instructions later, we find the following block fairly early in the debugger code base (remember all headers and comments have been added by yours truly, and therefore, may be inaccurate):
; ------------------------------------------------------------------------------ ; Possible entry point to the debugger? - otherwise code appears unreachable ; looks like this might be the main "run" mode entry point, checks for ; controller input, returns if both bottom action buttons not pressed. ; Otherwise waits for buttons to be released and starts to capture state ; Inputs: None ; Outputs: None L_D491: PSHR R5 ; store state, including status word PSHR R4 ; PSHR R0 ; GSWD R0 ; PSHR R0 ; MVII #$1f, R0 ; are both right bottom action buttons CMP .PSG0.rgt_hand, R0 ; pressed? BEQ L_D4A5 ; if yes, goto L_D4A5 ; CMP .PSG0.lft_hand, R0 ; both left bottom action buttons pressed? BEQ L_D4A5 ; if yes, goto L_D4A5 ; L_D4A0: ; PULR R0 ; restore state and return RSWD R0 ; PULR R0 ; PULR R4 ; PULR R7 ; done ; ------------------------------------------------------------------------------ ; Common continuation of handling L_D4A5: MVI .PSG0.lft_hand, R0 ; wait for both controllers to be AND .PSG0.rgt_hand, R0 ; released CMPI #$ff, R0 ; BNEQ L_D4A5 ; ; MOVR R6, R5 ; copy stack pointer SUBI #$4, R5 ; look back 4 entries - func return address MVI@ R5, R0 ; load return address SDBD ; store return address in $d28c, $d28d MVII #$d28c, R5 ; INCR R0 ; MVO@ R0, R5 ; SWAP R0, 1 ; MVO@ R0, R5 ; .... much more to come
Now this is very interesting, because it seems to check whether both bottom action buttons on either controller have been pressed. If not, it just returns. If either controller does have both bottom action buttons pressed, it waits for them to be released. Then does a bit of stack juggling to retrieve the value of the program counter at the point that the routine was called, and writes it to $d28c and $d28d! Remember those addresses from the last post?
Well, well, well.
It looks like we might have a route in. What we need is something to call this bad boy and see what it does. If we put together a minimal test driver, we can give it a bash.
You can find a zip file with the code and ROM for Test-1 here.
This will run on JzIntv and possibly an LTO Flash. To use it, just tap the disk to get past the title screen (the background will turn black), then press and release both bottom action buttons. The top half of the screen is overwritten and we're presented with this:
It lives! Looking at the information on the debugger screen, much of it makes sense. Top left we have the current values of the 8 CPU registers (R0-R7). Top right we have the current status flag values for (S)ign, (Z)ero, o(V)erflow and (C)arry. The field beneath the status flags is presumably to do with the setting of breakpoints. I guess, we don't have any set at the moment. The left of the 5th line seems to be a memory inspector - the value $0001 is found at address $5000. It is not clear what, if anything, is on the right of the 5th line. Below that, on the 6th line, the current opcode and mnemonic are displayed, which of course relates back to the addresses $d28c and $d28d, and the code we looked at yesterday.
It looks as though the yellow highlight on the R0 value is some kind of focus indicator. You seem to be able to key values into the R0 field using the numeric keypad on the controllers. New values appear in the least significant nibble, shifting other digits left. Pressing and holding the disc will show the game screen, the debugger reappears when you release it. I guess the debugger must be buffering the game screen somewhere. Transitioning between the two screens or pressing keys causes a flickery transition which is a bit odd.
So why the "kind of"? Well pressing some keys, notably the upper action buttons which appear to single step instructions, cause crashes. Perhaps the debugger is not complete, or more likely we are calling it incorrectly. Regardless, this is very promising. More soon...
Comments
Post a Comment