-
Notifications
You must be signed in to change notification settings - Fork 0
/
screen_io_rom.6502
373 lines (285 loc) · 5.15 KB
/
screen_io_rom.6502
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
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
; IO Routines for "ROM" and simple test code
;
; zero-page variables
define X $f5
define Y $f6
define SCREEN_PTR $f7
define SCREEN_PTR_HI $f8
define SCROLL_SRC $f9
define SCROLL_SRC_HI $fa
define SCROLL_DST $fb
define SCROLL_DST_HI $fc
define TEMP_Y $fd
; constants
define SCREEN_BASE $f000 ; first char on screen
define SCREEN_LAST $f780 ; start of last row
define ROWS 25
define COLS 80
; routine vectors/entry points
define SCINIT $ff81 ; initialize/clear screen
define CHRIN $ffcf ; get one char form keyboard
define CHROUT $ffd2 ; output one char to screen
define SCREEN $ffed ; get screen size
define PLOT $fff0 ; get/set cursor coordinates
; main code
jsr SCINIT
jsr CHRIN
loop: sec
jsr PLOT
ora #$80
jsr CHROUT
lda #$83 ; left
jsr CHROUT
getkey: jsr CHRIN
cmp #$00
beq getkey
pha
sec
jsr PLOT
and #$7f
jsr CHROUT
lda #$83 ; left
jsr CHROUT
pla
jsr CHROUT
jmp loop
*=$fe00
; ==================================================
; GOTO :: position to (X,Y) on screen
GOTO: pha
txa
pha
tya
pha
ldy Y
lda goto_tbl_low,y
clc
adc X
sta SCREEN_PTR
lda goto_tbl_hi,y
adc #$00
sta SCREEN_PTR_HI
pla
tay
pla
tax
pla
rts
goto_tbl_low:
dcb $00,$50,$A0,$F0,$40,$90,$E0,$30,$80,$D0,$20
dcb $70,$C0,$10,$60,$B0,$00,$50,$A0,$F0,$40,$90
dcb $E0,$30,$80
goto_tbl_hi:
dcb $F0,$F0,$F0,$F0,$F1,$F1,$F1,$F2,$F2,$F2,$F3
dcb $F3,$F3,$F4,$F4,$F4,$F5,$F5,$F5,$F5,$F6,$F6
dcb $F6,$F7,$F7
; ==================================================
; PUT :: output a printable or control character
; regA = character
R_PUT: cmp #$08
beq C_BS
cmp #$0a
beq C_RETURN
cmp #$0d
beq C_RETURN
cmp #$80
beq C_UP
cmp #$81
beq C_RIGHT
cmp #$82
beq C_DOWN
cmp #$83
beq C_LEFT
; ==================================================
; CHROUT :: output a printable character
; regA = character
R_CHROUT: jsr GOTO
sty TEMP_Y
ldy #$00
sta (SCREEN_PTR),y
jsr C_RIGHT
ldy TEMP_Y
rts
; ==================================================
; C_BS :: backspace
C_BS: pha
tya
pha
txa
pha
jsr C_LEFT
jsr GOTO
ldy #$00
lda #$20
sta (SCREEN_PTR),y
ldx COLS
dex
pla
tax
pla
tay
pla
rts
; ==================================================
; C_RETURN :: carriage return
C_RETURN: pha
lda #$00
sta X
jsr C_DOWN
pla
rts
; ==================================================
; C_RIGHT :: move cursor one position right
C_RIGHT: pha
inc X
lda #COLS
cmp X
bne c_right_done
lda #$00
sta X
jsr C_DOWN
c_right_done: pla
rts
; ==================================================
; C_LEFT :: move cursor one position left
C_LEFT: pha
dec X
bpl c_left_done
lda Y
beq c_left_home
lda #COLS
sta X
jsr C_UP
clc
bcc c_left_done
c_left_home: lda #$00
sta X
sta Y
c_left_done: pla
rts
; ==================================================
; C_DOWN :: move cursor one position down
C_DOWN: pha
inc Y
lda #ROWS
cmp Y
bne c_down_done
jsr SCROLL
dec Y
c_down_done: pla
rts
; ==================================================
; C_UP :: move cursor one position up
C_UP: dec Y
bpl c_up_done
inc Y ; go to first row if off screen
c_up_done: rts
; ==================================================
; CLEAR :: clear the screen
R_CLEAR: pha
tya
pha
LDA #$00
STA X
STA Y
jsr GOTO
ldy #$00
clear_loop_2: lda #$20
clear_loop: sta (SCREEN_PTR),y
iny
bne clear_loop
inc SCREEN_PTR_HI
lda SCREEN_PTR_HI
cmp #$f8
bne clear_loop_2
jsr GOTO
pla
tya
pla
rts
; ==================================================
; R_CHRIN :: get one character from keyboard buffer
; if the user has typed one (else $00)
R_CHRIN: lda $ff
beq chrin_done
pha
lda #$00
sta $ff
pla
chrin_done: rts
; ==================================================
; R_SCREEN :: return screen size
R_SCREEN: ldy #ROWS
ldx #COLS
rts
; ==================================================
; R_PLOT :: get/set screen position
;
; C==0: set cursor position to (X,Y)
; return pointer as Y=high, X=low
;
; C==1: read cursor position as (X,Y)
; return character at position in A
R_PLOT: bcs plot_read
stx X
sty Y
jsr GOTO
ldy SCREEN_PTR_HI
lda SCREEN_PTR
rts
plot_read: jsr GOTO
ldy #$00
lda (SCREEN_PTR),y
ldx X
ldy Y
rts
; ==================================================
; SCROLL :: scroll screen up one line
SCROLL: pha
tya
pha
lda #$00
sta SCROLL_DST
lda #COLS
sta SCROLL_SRC
lda #$f0
sta SCROLL_SRC_HI
sta SCROLL_DST_HI
ldy #$00
scroll_loop: lda (SCROLL_SRC),y
sta (SCROLL_DST),y
iny
bne scroll_loop
inc SCROLL_SRC_HI
inc SCROLL_DST_HI
lda #$f7
cmp SCROLL_SRC_HI
bne scroll_loop
scroll_loop2: lda (SCROLL_SRC),y
sta (SCROLL_DST),y
iny
cpy #$80
bne scroll_loop2
ldy #$00
lda #$20
clear_last: sta SCREEN_LAST,y
iny
cpy #80
bne clear_last
pla
tay
pla
rts
; ================================================
;
; Vector table / entry points
*=$ff81 ; SCINIT
jmp R_CLEAR
*=$ffcf ; CHRIN
jmp R_CHRIN
*=$ffd2 ; CHROUT
jmp R_PUT
*=$ffed ; SCREEN
jmp R_SCREEN
*=$fff0 ; PLOT
jmp R_PLOT