1
0
mirror of https://github.com/cc65/cc65.git synced 2024-11-16 02:10:52 +00:00
cc65/libsrc/dbg/dbgsupp.s

204 lines
4.7 KiB
ArmAsm

;
; Ullrich von Bassewitz, 08.08.1998
;
; Support routines for the debugger
;
.export _DbgInit
.export _DbgSP, _DbgCS, _DbgHI
.import popptr1, return0, _DbgEntry, _set_brk, _end_brk
.import _DbgBreaks
.import _brk_pc
.import __ZP_START__ ; Linker generated
.include "zeropage.inc"
; C callable function, will install the debugger
_DbgInit:
lda #<DbgBreak
ldx #>DbgBreak
jmp _set_brk
; Entry for the break vector.
DbgBreak:
pla
sta retsav
pla
sta retsav+1
cli
tsx ; Stack pointer
stx _DbgSP
jsr DbgSwapZP ; Swap stuff
lda #<DbgStack ; Set new stack
sta sp
lda #>DbgStack
sta sp+1
jsr ResetDbgBreaks ; Reset temporary breakpoints
jsr _DbgEntry ; Call C code
jsr SetDbgBreaks ; Set temporary breakpoints
jsr DbgSwapZP ; Swap stuff back
lda retsav+1
pha
lda retsav
pha
rts
; Stack used when in debugger mode
.bss
.res 256
DbgStack:
; Swap space for the C temporaries
CTemp:
_DbgCS: .res 2 ; sp
_DbgHI: .res 2 ; sreg
.res (zpsavespace-4) ; Other stuff
_DbgSP: .res 1
retsav: .res 2 ; Save buffer for return address
.code
; Swap the C temporaries
DbgSwapZP:
ldy #zpsavespace-1
Swap1: ldx CTemp,y
lda <__ZP_START__,y
sta CTemp,y
txa
sta sp,y
dey
bpl Swap1
rts
; ----------------------------------------------------------------------------
; Utility functions
; Set/reset the breakpoints. We must do that here since the breakpoints
; may be in the runtime stuff, causing the C part to fail before it has
; reset the breakpoints. See declaration of struct breakpoint in the C
; source
MaxBreaks = 48 ; 4*12
ResetDbgBreaks:
ldy #0
ldx #0
L4: lda _DbgBreaks+3,x ; Get bk_use
beq L6 ; Jump if not set
bpl L5 ; Jump if user breakpoint
lda #0
sta _DbgBreaks+3,x ; Clear if temp breakpoint
L5: lda _DbgBreaks+1,x ; PC hi
sta ptr1+1
lda _DbgBreaks,x ; PC lo
sta ptr1
lda _DbgBreaks+2,x ; Old OPC
sta (ptr1),y ; Reset the breakpoint
L6: inx
inx
inx
inx
cpx #MaxBreaks ; Done?
bne L4
rts
SetDbgBreaks:
ldx #0
ldy #0
L7: lda _DbgBreaks+3,x ; Get bk_use
beq L8 ; Jump if not set
lda _DbgBreaks+1,x ; PC hi
sta ptr1+1
lda _DbgBreaks,x ; PC lo
sta ptr1
lda (ptr1),y ; Get the breakpoint OPC...
sta _DbgBreaks+2,x ; ...and save it
lda #$00 ; Load BRK opcode
sta (ptr1),y
L8: inx
inx
inx
inx
cpx #MaxBreaks ; Done?
bne L7
rts
; Get a free breakpoint slot or return 0
.export _DbgGetBreakSlot
_DbgGetBreakSlot:
ldx #0
L10: lda _DbgBreaks+3,x ; Get bk_use
beq L11 ; Jump if not set
inx
inx
inx
inx
cpx #MaxBreaks ; Done?
bne L10
jmp return0 ; No free slot
L11: stx tmp1
lda #<_DbgBreaks
ldx #>_DbgBreaks
clc
adc tmp1
bcc L12
inx
L12: ldy #1 ; Force != 0
rts
; Check if a given address has a user breakpoint set, if found, return the
; slot, otherwise return 0.
.export _DbgIsBreak
_DbgIsBreak:
jsr popptr1 ; Get address
ldx #0
L20: lda _DbgBreaks+3,x ; Get bk_use
beq L21 ; Jump if not set
bmi L21 ; Jump if temp breakpoint
lda _DbgBreaks,x ; Low byte of address
cmp ptr1
bne L21
lda _DbgBreaks+1,x ; High byte of address
cmp ptr1+1
beq L22
L21: inx
inx
inx
inx
cpx #MaxBreaks ; Done?
bne L20
jmp return0 ; Not found
L22: stx tmp1
lda #<_DbgBreaks
ldx #>_DbgBreaks
clc
adc tmp1
bcc L23
inx
L23: ldy #1 ; Force != 0
rts