;
.export _set_brk, _reset_brk
+ .destructor _reset_brk
.export _brk_a, _brk_x, _brk_y, _brk_sr, _brk_pc
- .import _atexit
- .importzp ptr1
+ .importzp ptr1
.include "c128.inc"
_brk_sr: .res 1
_brk_pc: .res 2
-oldvec: .res 2 ; Old vector
-
-
.data
-uservec: jmp $FFFF ; Patched at runtime
+uservec: jmp $FFFF ; Patched at runtime
.code
-; Where will we put the break stub?
-stub_addr = $0E00 ; BASIC sprite area
-
-
; Set the break vector
.proc _set_brk
sta uservec+1
stx uservec+2 ; Set the user vector
- lda oldvec
- ora oldvec+1 ; Did we save the vector already?
- bne L2 ; Jump if we installed the handler already
+ 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
- sta oldvec
+ lda BRKVec ; Save the old vector
+ sta brk_old+1
lda BRKVec+1
- sta oldvec+1 ; Save the old vector
+ sta brk_old+2
- ldy #stub_size-1 ; Copy our stub into the low mem area
-L1: lda brk_stub,y
- sta stub_addr,y
- dey
- bpl L1
+ lda #<brk_stub ; Set the break vector to our stub
+ ldx #>brk_stub
+ sta BRKVec
+ stx BRKVec+1
- lda #<_reset_brk
- ldx #>_reset_brk
- jsr _atexit ; Install an exit handler
+ lda #<brk_handler ; Set the indirect vector to our handler
+ ldx #>brk_handler
+ sta brk_ind+1
+ stx brk_ind+2
-L2: lda #<stub_addr ; Set the break vector to our stub
- sta BRKVec
- lda #>stub_addr
- sta BRKVec+1
- rts
+@L1: rts
.endproc
; Reset the break vector
.proc _reset_brk
- lda oldvec
- sta BRKVec
- lda oldvec+1
- sta BRKVec+1
- rts
+ 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
pla
sta _brk_a
pla
- and #$EF ; Clear break bit
+ and #$EF ; Clear break bit
sta _brk_sr
- pla ; PC low
+ pla ; PC low
sec
- sbc #2 ; Point to start of brk
+ sbc #2 ; Point to start of brk
sta _brk_pc
- pla ; PC high
+ pla ; PC high
sbc #0
sta _brk_pc+1
- jsr uservec ; Call the user's routine
+ jsr uservec ; Call the user's routine
lda _brk_pc+1
pha
ldx _brk_x
ldy _brk_y
lda _brk_a
- rti ; Jump back...
+ 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
-brk_stub:
- .org stub_addr
- pla ; Get original MMU value
- sta MMU_CR ; Re-enable our config
- jmp brk_handler ; Jump to the user handler
- .reloc
+; Indirect vectors preceeded by a jump opcode
+brk_ind:
+ jmp $0000
-stub_size = * - brk_stub