Thank you, I guess I'm too dense to understand it, for I already read the document and posted here. But hey, thanks. *sigh*
I apologize for the terse responses. I'm at $DAYJOB replying between meetings.
The function at $8A4A (page 85) steps through the breakpoint address list, copying instruction out of the program at the breakpoint addresses to a separate buffer, and replacing them with SIN instructions. This gets called just before running the program. There's a converse function at $8D07 (page 97) that replaces the SIN,1 instructions with the original instructions. Those two functions are fairly simple, and give you basic breakpoint capability
The function at $8A65 (pages 85 - 92 (!!)) is for single stepping. It actually tries to decode the length of an instruction, even accounting for conditional branches (finding both legs of the conditional branch), JSRs with data after them (at least for commonly-used EXEC subroutines), and so forth. For instructions that modify R7, it actually modifies the opcode to see what effect the instruction has on R7, so it can single-step over jump tables. It's crazy. The single-step code uses SIN,2 (opcode $37) rather than SIN,1 (opcode $36). The two opcodes both behave the same in the CPU; the different opcodes are there for software to distinguish a breakpoint from a single-step in the interrupt handler. The function at $8D1F (page 97) replaces the SIN,2 instructions with the original instructions.
The INTR handler at $8C2B (pages 93-95) decodes whether we hit a breakpoint (SIN,1), the far side of a single-step (SIN,2), or an ordinary interrupt.
BTW, while writing this post, I noticed an error in the doc, which I went and fixed in the original Google Doc. This bit is wrong:
L_8C62: MVO@ R2, R3 ; 8C62 This looks like dead code.
; We read R2 from @R3 above, and
; now we write it unmodified to @R3
Actually, R2 is modified. It's decremented by 1 at $8C3A. So, I've corrected that to read:
L_8C62: MVO@ R2, R3 ; 8C62 Rewrite the program counter on the
; stack to point to the instruction
; we had replaced with SIN,1.
I'm sure I've made a few other minor flubs here and there. I'm rather embarrassed by that one though. It seems rather obvious in retrospect that if we take an interrupt due to SIN, the saved program counter will point after SIN. To resume at the breakpoint, you need to rewind the PC to point to the SIN instruction and replace it with the original instruction.
Edited by intvnut, Tue Apr 24, 2018 2:24 PM.