-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcursor.inc
319 lines (275 loc) · 8.76 KB
/
cursor.inc
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
;*******************************************************************************
;Copyright 2022-2024, Stefan Jakobsson
;
;Redistribution and use in source and binary forms, with or without modification,
;are permitted provided that the following conditions are met:
;
;1. Redistributions of source code must retain the above copyright notice, this
; list of conditions and the following disclaimer.
;
;2. Redistributions in binary form must reproduce the above copyright notice,
; this list of conditions and the following disclaimer in the documentation
; and/or other materials provided with the distribution.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
;FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
;SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
;CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
;OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
;OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*******************************************************************************
;******************************************************************************
;Function name.......: cursor_init
;Purpose.............: Initializes the cursor
;Input...............: None
;Returns.............: Nothing
;Error returns.......: None
.proc cursor_init
;Set position
stz CRS_X
lda #2
sta CRS_Y
;Init cursor toggle counter
lda #30
sta cursor_toggle_counter
;Set cursor state = hidden
stz cursor_state
rts
.endproc
;******************************************************************************
;Function name.......: cursor_invert
;Purpose.............: Inverts color at cursor position
;Input...............: None
;Returns.............: Nothing
;Error returns.......: None
.proc cursor_invert
lda #VERA_BUFADR_H
sta VERA_H
lda cursor_state
and #%00000001
beq show
hide:
lda last_shown_at
asl
ina
sta VERA_L
lda last_shown_at+1
sta VERA_M
bra swap
show:
lda CRS_X
sta last_shown_at
asl
ina
sta VERA_L
clc
lda CRS_Y
adc #VERA_BUFADR_M
sta last_shown_at+1
sta VERA_M
;Swap background/foreground colors
swap:
lda VERA_D0
jsr cmd_swap_colors
sta VERA_D0
;Update cursor state
inc cursor_state
rts
.segment "VARS"
last_shown_at: .res 2
.CODE
.endproc
;******************************************************************************
;Function name.......: cursor_move
;Purpose.............: Moves the cursor to specified column and row
;Input...............: X=cursor column, Y=cursor row
;Returns.............: Nothing
;Error returns.......: None
.proc cursor_move
lda cursor_state
and #%00000001
beq :+
jsr cursor_invert
: stx CRS_X
sty CRS_Y
lda cursor_toggle_counter
beq :+
jsr cursor_invert
lda #30
sta cursor_toggle_counter
: rts
.endproc
;******************************************************************************
;Function name.......: cursor_move_right
;Purpose.............: Moves cursor one step right, but not beyond rightmost
; column of the screen
;Input...............: Nothing
;Returns.............: C=1 if at rightmost position of screen, else C=0
;Error returns.......: None
.proc cursor_move_right
ldx CRS_X
inx
cpx screen_width
bcs rightmost
ldy CRS_Y
jsr cursor_move
clc ;We're not at rightmost position, return C=0
rts
rightmost:
sec ;We're at rightmost position, return C=1
rts
.endproc
;******************************************************************************
;Function name.......: cursor_move_left
;Purpose.............: Moves cursor one step left, but not beyond leftmost
; column of the screen
;Input...............: Nothing
;Returns.............: C=1 if at leftmost position of screen, else C=0
;Error returns.......: None
.proc cursor_move_left
ldx CRS_X
cpx #0
beq leftmost
dex
ldy CRS_Y
jsr cursor_move
clc ;We're not at leftmost position, return C=0
rts
leftmost:
sec ;We're at leftmost position, return C=1
rts
.endproc
;******************************************************************************
;Function name.......: cursor_move_up
;Purpose.............: Moves the cursor one row up, but not beyond the first
; user editable row
;Input...............: Nothing
;Returns.............: C=1 if at top of screen, else C=0
;Error returns.......: None
.proc cursor_move_up
ldy CRS_Y
cpy #2 ;Row 2 is the first editable screen row, program header above
beq top
dey
ldx CRS_X
jsr cursor_move
clc ;We're not at top of screen, return C=0
rts
top:
sec ;We're at top of screen, return C=1
rts
.endproc
;******************************************************************************
;Function name.......: cursor_move_down
;Purpose.............: Moves the cursor one row down, but not beyond the last
; user editable row
;Input...............: Nothing
;Returns.............: C=1 if at bottom of screen, else C=0
;Error returns.......: None
.proc cursor_move_down
clc
lda CRS_Y
adc #5
cmp screen_height ;The last editable row
beq bottom
ldy CRS_Y
iny
ldx CRS_X
jsr cursor_move
clc ;We're not at bottom of screen, return C=0
rts
bottom:
sec ;We're at bottom of screen, return C=1
rts
.endproc
;******************************************************************************
;Function name.......: cursor_move_crlf
;Purpose.............: Moves the cursor to the first column of next row, but
; the cursor will not be moved below the last editable
; row
;Input...............: Nothing
;Returns.............: C=1 if at bottom of screen, else C=0
;Error returns.......: None
.proc cursor_move_crlf
ldy CRS_Y
tya
clc
adc #5
cmp screen_height
beq bottom
iny
ldx #0
jsr cursor_move
clc ;We're not at bottom of screen, return C=0
rts
bottom:
;Move cursor to start of row
ldy CRS_Y
ldx #0
jsr cursor_move
sec ;We're at bottom of screen, return C=1
rts
.endproc
;******************************************************************************
;Function name.......: cursor_toggle
;Purpose.............: Controls cursor toggle. The cursor will change state
; (hidden or visible) for every 30 invocations of this
; function. When called once every VBLANK, the cursor
; toggle period will be 1 second.
;Input...............: cursor_toggle_counter=0 means that the cursor is
; disabled (hidden)
;Returns.............: Nothing
;Error returns.......: None
.proc cursor_toggle
;Check if cursor is disabled, cursor_toggle_counter = 0
lda cursor_toggle_counter
beq exit ;Cursor disabled
toggle:
dec cursor_toggle_counter
bne exit
jsr cursor_invert
lda #30 ;Restart counter for 1/2 second
sta cursor_toggle_counter
exit:
rts
.endproc
;******************************************************************************
;Function name.......: cursor_activate
;Purpose.............: Acivates the cursor, making it visible and enabling
; cursor toggle
;Input...............: Nothing
;Returns.............: Nothing
;Error returns.......: None
.proc cursor_activate
lda cursor_state
and #%00000001
bne :+
jsr cursor_invert
: lda #30 ;The cursor is already visible, set counter to default start value = 30 (1/2 second)
sta cursor_toggle_counter
rts
.endproc
;******************************************************************************
;Function name.......: cursor_disable
;Purpose.............: Disables and hides the cursor
;Input...............: Nothing
;Returns.............: Nothing
;Error returns.......: None
.proc cursor_disable
lda cursor_state
and #%00000001
beq :+
jsr cursor_invert
: stz cursor_toggle_counter
rts
.endproc
.segment "VARS"
CRS_X: .res 1 ;Cursor screen column position
CRS_Y: .res 1 ;Cursor screen row position
cursor_toggle_counter: .res 1
cursor_state: .res 1
.CODE