cc65/libsrc/c128/break.s

136 lines
2.9 KiB
ArmAsm

;
; Ullrich von Bassewitz, 27.09.1998
;
; void __fastcall__ set_brk (unsigned Addr);
; void reset_brk (void);
;
.export _set_brk, _reset_brk
.destructor _reset_brk
.export _brk_a, _brk_x, _brk_y, _brk_sr, _brk_pc
.importzp ptr1
.include "c128.inc"
.bss
_brk_a: .res 1
_brk_x: .res 1
_brk_y: .res 1
_brk_sr: .res 1
_brk_pc: .res 2
.data
uservec: jmp $FFFF ; Patched at runtime
.code
; Set the break vector
.proc _set_brk
sta uservec+1
stx uservec+2 ; Set the user vector
lda brk_old+1
ora brk_old+2 ; Did we save the vector already?
bne @L1 ; Jump if we installed the handler already
lda BRKVec ; Save the old vector
sta brk_old+1
lda BRKVec+1
sta brk_old+2
lda #<brk_stub ; Set the break vector to our stub
ldx #>brk_stub
sta BRKVec
stx BRKVec+1
lda #<brk_handler ; Set the indirect vector to our handler
ldx #>brk_handler
sta brk_ind+1
stx brk_ind+2
@L1: rts
.endproc
; Reset the break vector
.proc _reset_brk
lda brk_old+1
ldx brk_old+2
beq @L9 ; Jump if vector not installed
sta BRKVec
stx BRKVec+1
lda #$00
sta brk_old+1 ; Clear the saved vector
sta brk_old+2
@L9: rts
.endproc
; Break handler, called if a break occurs
.proc brk_handler
pla
sta _brk_y
pla
sta _brk_x
pla
sta _brk_a
pla
and #$EF ; Clear break bit
sta _brk_sr
pla ; PC low
sec
sbc #2 ; Point to start of brk
sta _brk_pc
pla ; PC high
sbc #0
sta _brk_pc+1
jsr uservec ; Call the user's routine
lda _brk_pc+1
pha
lda _brk_pc
pha
lda _brk_sr
pha
ldx _brk_x
ldy _brk_y
lda _brk_a
rti ; Jump back...
.endproc
; Break stub, must go into low (non banked) memory
.segment "LOWCODE"
.proc brk_stub
pla ; Get original MMU_CR value
sta MMU_CR ; And set it
jmp brk_ind ; Jump indirect to break
.endproc
; ------------------------------------------------------------------------
; Data
.data
; Old break vector preceeded by a jump opcode
brk_old:
jmp $0000
; Indirect vectors preceeded by a jump opcode
brk_ind:
jmp $0000