Breakpoint Tuesday


The breakpoint infrastructure inside Rick's debugger is relatively simple, but effective.  Up to eight breakpoints, labelled A-H, can be configured.  Within the debugger they can be set to be active or inactive using the BRKS fields:


It is not possible to set the address of a breakpoint within the debugger UI.  Instead, to configure a breakpoint a small section of code has to be added to the program under test at the point of interest.  This is done in a similar manner to the main entry point, like this:
    INCR    R0                      ;
                                    ;
    BEGIN                           ; <<<
    CALL    L_D408                  ; <<< CONDITIONALLY TRIGGER BREAKPOINT A
    PULR    R5                      ; <<<
                                    ;
    DECR    R0                      ; <<< DEBUGGER STARTS HERE
    RETURN                          ; done

Just like the main debugger entry point identified earlier, this call allows the debugger to take control if required. In this instance, it will intervene if breakpoints are active generally (i.e. we are running to a breakpoint) and the specific breakpoint ("A" in this case) is active. If both of these conditions are met the debugger will fall into interactive mode at the following instruction. Any particular breakpoint can be called from multiple points in the program if required.

Speaking of running to a breakpoint, pressing the right Clear button requests that the debugger does just this. So the full set of controls are:
  • Both bottom action buttons (LSHIFT + RSHIFT) = Enter the debugger
  • Any disc (SPACE) = Show the game screen while disc held
  • Any top action (S or RETURN) = Executes a (S)ingle instruction and returns to the debugger
  • Any bottom left action (COMMA or LSHIFT) = Cycle the field focus (yellow highlight) backwards by one
  • Any bottom right action (PERIOD or RSHIFT)  = Cycle the field focus forwards by one
  • Left 0-9 (0-9) = Enter the key value into the least significant digit of the current field, shifting all other digits left
  • Right 1-6 (A-F) = Enter values A-F into the least significant digit of the current field, shifting all other digits left
  • Right 7 (MINUS) = Decrement the current field by 1
  • Right 8 (Z) = Sets the current field to (Z)ero
  • Right 9 (EQUALS) = Increment the current field by 1
  • Right Clear (K) = run to the next active brea(K)point
  • Right 0 (R) = unconditionally (R)un the program (effectively quit the debugger)
  • Right Enter (T) = unconditional (T)race instructions (i.e. run showing the CPU state - can be interrupted by pressing both bottom action buttons)
  • Left Clear (X) = Trace to the e(X)it of the current subroutine
  • Left Enter (U) = Trace to the next (U)ser (i.e. non-EXEC) instruction
An updated version of the kbd.hack file with better bindings for Right Clear (K) and Right 0 (R) can be found here, along with a test driver that also has breakpoint A defined in it.

There is also a third means of triggering the debugger. This similar to a breakpoint, but is triggered unconditionally. It is used in a similar manner to other entry points:
    INCR    R0                      ;
                                    ;
    BEGIN                           ; <<<
    CALL    L_D482                  ; <<< UNCONDITIONALLY TRIGGER DEBUGGER
    PULR    R5                      ; <<<
                                    ;
    DECR    R0                      ; <<< DEBUGGER STARTS HERE
    RETURN                          ; done

And that seems to be pretty much it as far as entry points go. The full listing in the format "Suggested name - Address - Purpose" seems to be:
  • RKD_DEBUG - $d491 - Conditional controller entry point, should probably be called regularly, for example in an Interrupt Service Routine (ISR)
  • RKD_TRAP - $d482 - Unconditional interactive debugger entry
  • RKD_BRKA - $d408 - Conditional breakpoint A entry
  • RKD_BRKB - $d414 - Conditional breakpoint B entry
  • RKD_BRKC - $d420 - Conditional breakpoint C entry
  • RKD_BRKD - $d42c - Conditional breakpoint D entry
  • RKD_BRKE - $d438 - Conditional breakpoint E entry
  • RKD_BRKF - $d444 - Conditional breakpoint F entry
  • RKD_BRKG - $d450 - Conditional breakpoint G entry
  • RKD_BRKH - $d45c - Conditional breakpoint H entry
So the next thing is to finish off commenting the source code and get to the bottom of how the debugger really works.

Comments