This repository has been archived by the owner on Aug 25, 2022. It is now read-only.
forked from neilsf/xcb-ext-rasterinterrupt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xcb-ext-rasterinterrupt.bas
191 lines (164 loc) · 3.37 KB
/
xcb-ext-rasterinterrupt.bas
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
rem *****************************************
rem * XC=BASIC Raster interrput extension
rem *
rem * by Csaba Fekete
rem *
rem * Compatible with XC=BASIC v2.2.04 and up
rem * Namespace: ri_
rem *****************************************
const RI_CIA1_ICR = $dc0d
const RI_CIA2_ICR = $dd0d
const RI_VIC_CTR = $d011
const RI_VIC_RASTER = $d012
const RI_VIC_IRQ_R = $d019
const RI_VIC_IRQ_EN = $d01a
data ri_isr_addr_lo![] = 0, 0, 0, 0, 0, 0, 0, 0
data ri_isr_addr_hi![] = 0, 0, 0, 0, 0, 0, 0, 0
data ri_ras_lo![] = 0, 0, 0, 0, 0, 0, 0, 0
data ri_ras_hi![] = 0, 0, 0, 0, 0, 0, 0, 0
ri_isr_count! = 0
ri_current_isr! = 0
ri_syshandler = $ea31
proc ri_isr_launcher
asm "
ldx _ri_current_isr
lda.wx _ri_isr_addr_lo
sta .ri_isr_addr + 1
lda.wx _ri_isr_addr_hi
sta .ri_isr_addr + 2
.ri_isr_addr
jsr $0000
ldx _ri_current_isr
inx
cpx _ri_isr_count
bne .set_line
ldx #$00
.set_line
stx _ri_current_isr
; Set next interrupt line
lda.wx _ri_ras_lo
sta _RI_VIC_RASTER
lda.wx _ri_ras_hi
beq .clear
lda _RI_VIC_CTR
ora #%10000000
sta _RI_VIC_CTR
jmp .ack
.clear
lda _RI_VIC_CTR
and #%01111111
sta _RI_VIC_CTR
.ack
; Acknowledge and let sys handler finish
asl _RI_VIC_IRQ_R
lda _ri_current_isr
beq .syshandler
jmp $ea81
.syshandler
jmp (_ri_syshandler)
"
endproc
rem ******************************
rem * Command
rem * ri_on
rem *
rem * No args
rem ******************************
proc ri_on
\ri_current_isr! = 0
asm "
sei
; disable CIA irqs
lda #$7f
sta _RI_CIA1_ICR
sta _RI_CIA2_ICR
lda _RI_CIA1_ICR
lda _RI_CIA2_ICR
; Set initial raster line
lda _ri_ras_lo
sta _RI_VIC_RASTER
lda _ri_ras_hi
beq .clear
lda _RI_VIC_CTR
ora #%10000000
sta _RI_VIC_CTR
jmp .skip
.clear
lda _RI_VIC_CTR
and #%01111111
sta _RI_VIC_CTR
.skip
lda #<_Pri_isr_launcher
sta $0314
lda #>_Pri_isr_launcher
sta $0315
; enable VIC raster interrupts
lda #$01
sta _RI_VIC_IRQ_EN
cli
"
endproc
rem ******************************
rem * Command
rem * ri_off
rem *
rem * No args
rem ******************************
proc ri_off
asm "
sei
; disable VIC raster interrupts
lda #$00
sta _RI_VIC_IRQ_EN
; enable CIA irqs
lda #$ff
sta _RI_CIA1_ICR
sta _RI_CIA2_ICR
; reset handler ptr
lda #$31
sta $0314
lda #$ea
sta $0315
cli
"
endproc
rem ******************************
rem * Command
rem * ri_set_isr
rem *
rem * Args:
rem * handler_no!
rem * handler_addr
rem * raster_line
rem ******************************
proc ri_set_isr(isr_no!, isr_addr, raster_line)
asm "
ldx {self}.isr_no
lda {self}.isr_addr
sta.wx _ri_isr_addr_lo
lda {self}.isr_addr + 1
sta.wx _ri_isr_addr_hi
lda {self}.raster_line
sta.wx _ri_ras_lo
lda {self}.raster_line + 1
sta.wx _ri_ras_hi
"
endproc
rem ******************************
rem * Command
rem * ri_syshandler_on
rem *
rem * No args
rem ******************************
proc ri_syshandler_on
\ri_syshandler = $ea31
endproc
rem ******************************
rem * Command
rem * ri_syshandler_off
rem *
rem * No args
rem ******************************
proc ri_syshandler_off
\ri_syshandler = $ea81
endproc