-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscroll2.asm
339 lines (294 loc) · 8.66 KB
/
scroll2.asm
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
;startup address
* = $0801
;create BASIC startup (SYS line)
!basic
;debuglines = 1
;userasterirq = 1
screen1 = $0400
;screen1 = $2000
; set start of screen memory
; see https://www.c64-wiki.de/wiki/Bildschirmspeicher
lda $d018
and #%00001111
ora #(screen1 / 1024) << 4
sta $d018
; init sid max freq
lda #$ff
sta $d40e
sta $d40f
lda #$80
sta $d412 ; noise waveform
lda #$be
jsr clearcolorram
!ifdef userasterirq {
jsr init_irq
jmp * ; endless loop
} else {
jmp busywait
}
!ifndef userasterirq {
busywait:
sei
-- lda #$fc ; wait for raster line $fc.
- cmp $d012
bne -
jsr scroll
lda $dc01 ; spacebar pressed?
cmp #$ff
beq --
lda $d011 ; restore scroll offset
and #%11111000
ora #%00000011
sta $d011
!if screen1 != $0400 {
lda $d018 ; restore original screen mem if other was used
and #%00001111
ora #($0400 / 1024) << 4
sta $d018
}
cli
rts
}
; --------------------------------------------------------------------------------------
; Init raster interrupt
; --------------------------------------------------------------------------------------
!ifdef userasterirq {
init_irq:
sei ; set interrupt bit, make the CPU ignore interrupt requests
lda #$40 ; wait for raster line $40.
- cmp $d012 ; don't know why I need this. Otherwise rastr_irq is only called once if
bne - ; the current raster line < $35 or > $fe
lda #%01111111
sta $dc0d ; disable timer interrupts which can be generated by the two CIA chips
sta $dd0d ; the kernal uses such an interrupt to flash the cursor and scan the keyboard, so we better
; stop it.
lda $dc0d ; by reading this two registers we negate any pending CIA irqs.
lda $dd0d ; if we don't do this, a pending CIA irq might occur after we finish setting up our irq.
; we don't want that to happen.
lda #%00000001 ; raster line triggers interrupt
sta $d01a
lda #$fc ; set rasterline where interrupt shall occur
sta $d012
lda $d011 ; clear high bit
and #%01111111
sta $d011
lda #$35 ; we turn off the BASIC and KERNAL rom here
sta $01 ; the cpu now sees RAM everywhere except at $d000-$e000, where still the registers of
; SID/VICII/etc are visible
lda #<rastr_irq ; this is how we set up
sta $fffe ; the address of our interrupt code
lda #>rastr_irq
sta $ffff
cli ; clear interrupt flag, allowing the CPU to respond to interrupt requests
rts
}
; --------------------------------------------------------------------------------------
; Raster interrupt
; --------------------------------------------------------------------------------------
!ifdef userasterirq {
rastr_irq:
pha ; store register A in stack
txa
pha ; store register X in stack
tya
pha ; store register Y in stack
asl $d019 ; IRQ bestätigen
jsr scroll
pla
tay ; restore register Y from stack (remember stack is FIFO: First In First Out)
pla
tax ; restore register X from stack
pla ; restore register A from stack
rti ; Return From Interrupt, this will load into the Program Counter register the address
; where the CPU was when the interrupt condition arised which will make the CPU continue
; the code it was interrupted at also restores the status register of the CPU
}
; --------------------------------------------------------------------------------------
; Smooth scrolling
; --------------------------------------------------------------------------------------
scroll:
!ifdef debuglines {
lda #$7
sta $d020 ; change border colour to yellow
}
lda $d011
and #%111
tax
dex
bmi +
dec $d011
jmp ++
+ lda $d011
ora #%111
sta $d011
jsr shiftup
jsr newline
++
!ifdef debuglines {
lda #$0
sta $d020 ; change border colour to black
}
rts
newline:
; fill last line with random chars
ldx #39
- lda $d41b
ror
lda #77
adc #0
sta screen1+40*24,x
dex
bpl -
rts
shiftup:
; Shift the screen memory one row up.
; We do this in blocks of 10*25 bytes.
clc
lda #0
- tax
lda screen1+40+000,x
sta screen1+00+000,x
lda screen1+41+000,x
sta screen1+01+000,x
lda screen1+42+000,x
sta screen1+02+000,x
lda screen1+43+000,x
sta screen1+03+000,x
lda screen1+44+000,x
sta screen1+04+000,x
lda screen1+45+000,x
sta screen1+05+000,x
lda screen1+46+000,x
sta screen1+06+000,x
lda screen1+47+000,x
sta screen1+07+000,x
lda screen1+48+000,x
sta screen1+08+000,x
lda screen1+49+000,x
sta screen1+09+000,x
txa
adc #10
cmp #250
bne -
clc
lda #0
- tax
lda screen1+40+250,x
sta screen1+00+250,x
lda screen1+41+250,x
sta screen1+01+250,x
lda screen1+42+250,x
sta screen1+02+250,x
lda screen1+43+250,x
sta screen1+03+250,x
lda screen1+44+250,x
sta screen1+04+250,x
lda screen1+45+250,x
sta screen1+05+250,x
lda screen1+46+250,x
sta screen1+06+250,x
lda screen1+47+250,x
sta screen1+07+250,x
lda screen1+48+250,x
sta screen1+08+250,x
lda screen1+49+250,x
sta screen1+09+250,x
txa
adc #10
cmp #250
bne -
clc
lda #0
- tax
lda screen1+40+500,x
sta screen1+00+500,x
lda screen1+41+500,x
sta screen1+01+500,x
lda screen1+42+500,x
sta screen1+02+500,x
lda screen1+43+500,x
sta screen1+03+500,x
lda screen1+44+500,x
sta screen1+04+500,x
lda screen1+45+500,x
sta screen1+05+500,x
lda screen1+46+500,x
sta screen1+06+500,x
lda screen1+47+500,x
sta screen1+07+500,x
lda screen1+48+500,x
sta screen1+08+500,x
lda screen1+49+500,x
sta screen1+09+500,x
txa
adc #10
cmp #250
bne -
clc
lda #0
- tax
lda screen1+40+750,x
sta screen1+00+750,x
lda screen1+41+750,x
sta screen1+01+750,x
lda screen1+42+750,x
sta screen1+02+750,x
lda screen1+43+750,x
sta screen1+03+750,x
lda screen1+44+750,x
sta screen1+04+750,x
lda screen1+45+750,x
sta screen1+05+750,x
lda screen1+46+750,x
sta screen1+06+750,x
lda screen1+47+750,x
sta screen1+07+750,x
lda screen1+48+750,x
sta screen1+08+750,x
lda screen1+49+750,x
sta screen1+09+750,x
txa
adc #10
cmp #210
bne -
rts
; --------------------------------------------------------------------------------------
; Misc routines
; --------------------------------------------------------------------------------------
clearcolorram:
ldx #250
- dex ; this sets Z flags if last round
sta $d800+000,x
sta $d800+250,x
sta $d800+500,x
sta $d800+750,x
bne -
rts
!if 0 {
fillscreen:
lda #$be
jsr clearcolorram
lda #0
sta .f
lda #<screen1
sta .faddr+1
lda #>screen1
sta .faddr+2
ldy #25-1
.lp inc .f
lda .f
ldx #40-1
.faddr sta screen1,x
dex
bpl .faddr
lda .faddr+1
clc
adc #40
sta .faddr+1
bcc +
inc .faddr+2
+ dey
bpl .lp
rts
.f !byte 0
}