File: break.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (135 lines) | stat: -rw-r--r-- 2,930 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
;
; 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