-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathraster.s
363 lines (332 loc) · 11.9 KB
/
raster.s
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
IRQ1_LINE = MIN_SPRY-12
IRQ3_LINE = SCROLLROWS*8+44
IRQ4_LINE = IRQ3_LINE+8
IRQ6_LINE = 248
PANEL_BG2 = $0b
PANEL_BG3 = $0c
TEXT_BG1 = $00
TEXT_BG2 = $0b
TEXT_BG3 = $0c
; IRQ common startup code
StartIrq: cld
sta irqSaveA
stx irqSaveX
sty irqSaveY
lda #$35 ;Ensure IO memory is available
sta $01
rts
; Blank the gamescreen and turn off sprites
; (return to normal display by calling UpdateFrame)
;
; Parameters: -
; Returns: X=0
; Modifies: A,X
BlankScreen: jsr WaitBottom
lda #$57
sta Irq1_ScrollY+1
ldx #$00
stx Irq1_D015+1
stx Irq1_MaxSprY+1
stx Irq6_LevelUpdate+1 ;Disable level animation by default
rts
; Raster interrupt 3. Gamescreen / scorepanel split
Irq3: sta irqSaveA
stx irqSaveX
lda #$35
sta $01 ;Ensure IO memory is available
Irq3_Direct: lda $d011
ldx #IRQ3_LINE
Irq3_Wait: cpx $d012
bcs Irq3_Wait
cmp #$15
bne Irq3_NoBadLine
Irq3_Blank: lda #$57 ;Immediate blanking if badline
sta $d011
lda #PANEL_D018 ;Set panelscreen screen ptr.
sta $d018
Irq3_SplitDone: sty irqSaveY
lsr newFrame ;Can update sprites now
lda #$00
sta $d015 ;Make sure sprites are off in the border and
sta $d021 ;do not disturb the fastloader
lda #PANEL_BG2 ;Set scorepanel multicolors
sta $d022
lda #PANEL_BG3
sta $d023
lda #<Irq4
ldx #>Irq4
ldy #IRQ4_LINE
Irq3_EndJump: jmp SetNextIrq
Irq3_NoBadLine: ora #$07 ;No badline: stabilize Y-scroll first
sta $d011
nop
ldx #5
Irq3_Delay: dex
bpl Irq3_Delay
bmi Irq3_Blank
; Raster interrupt 1. Show game screen
Irq1_NoSprites: jmp Irq2_AllDone
Irq1: jsr StartIrq
ldx #$00 ;Reset frame update
stx newFrame
Irq1_MinSprY: lda #$00 ;Copy new min/max sprite Y range to know
Irq1_StoreMinSprY: ;when fastloader can transfer data
sta FL_MinSprY+1
Irq1_MaxSprY: lda #$00
Irq1_StoreMaxSprY:
sta FL_MaxSprY+1
Irq1_ScrollX: lda #$17
sta $d016
Irq1_ScrollY: lda #$57
sta $d011
Irq1_Screen: ldy #GAMESCR1_D018
sty $d018
Irq1_Bg1: lda #$00
sta $d021
Irq1_Bg2: lda #$00
sta $d022
Irq1_Bg3: lda #$00
sta $d023
Irq1_ScreenFrame:
lda #$00 ;Ensure sprite frames are loaded to the
cmp Irq2_Spr0Frame+2 ;correct screen
beq Irq1_NoScreenFrameChange
sta Irq2_Spr0Frame+2
sta Irq2_Spr1Frame+2
sta Irq2_Spr2Frame+2
sta Irq2_Spr3Frame+2
sta Irq2_Spr4Frame+2
sta Irq2_Spr5Frame+2
sta Irq2_Spr6Frame+2
sta Irq2_Spr7Frame+2
Irq1_NoScreenFrameChange:
stx $d07a ;SCPU back to slow mode
stx $d030 ;C128 back to 1MHz
Irq1_D015: lda #$00
sta $d015
beq Irq1_NoSprites
Irq1_HasSprites:lda #<Irq2 ;Set up the sprite display IRQ
sta $fffe
lda #>Irq2
sta $ffff
Irq1_FirstSortSpr:
ldx #$00 ;Go through the first sprite IRQ immediately
;Raster interrupt 2. This is where sprite displaying happens
Irq2_Spr0: lda sortSprY,x
sta $d00f
lda sortSprX,x
ldy sortSprD010,x
sta $d00e
sty $d010
lda sortSprF,x
Irq2_Spr0Frame: sta screen1+$03ff
lda sortSprC,x
sta $d02e
bmi Irq2_SprIrqDone2
inx
Irq2_Spr1: lda sortSprY,x
sta $d00d
lda sortSprX,x
ldy sortSprD010,x
sta $d00c
sty $d010
lda sortSprF,x
Irq2_Spr1Frame: sta screen1+$03fe
lda sortSprC,x
sta $d02d
bmi Irq2_SprIrqDone2
inx
Irq2_Spr2: lda sortSprY,x
sta $d00b
lda sortSprX,x
ldy sortSprD010,x
sta $d00a
sty $d010
lda sortSprF,x
Irq2_Spr2Frame: sta screen1+$03fd
lda sortSprC,x
sta $d02c
bmi Irq2_SprIrqDone2
inx
Irq2_Spr3: lda sortSprY,x
sta $d009
lda sortSprX,x
ldy sortSprD010,x
sta $d008
sty $d010
lda sortSprF,x
Irq2_Spr3Frame: sta screen1+$03fc
lda sortSprC,x
sta $d02b
bpl Irq2_ToSpr4
Irq2_SprIrqDone2:
jmp Irq2_SprIrqDone
Irq2_ToSpr4: inx
Irq2_Spr4: lda sortSprY,x
sta $d007
lda sortSprX,x
ldy sortSprD010,x
sta $d006
sty $d010
lda sortSprF,x
Irq2_Spr4Frame: sta screen1+$03fb
lda sortSprC,x
sta $d02a
bmi Irq2_SprIrqDone
inx
Irq2_Spr5: lda sortSprY,x
sta $d005
lda sortSprX,x
ldy sortSprD010,x
sta $d004
sty $d010
lda sortSprF,x
Irq2_Spr5Frame: sta screen1+$03fa
lda sortSprC,x
sta $d029
bmi Irq2_SprIrqDone
inx
Irq2_Spr6: lda sortSprY,x
sta $d003
lda sortSprX,x
ldy sortSprD010,x
sta $d002
sty $d010
lda sortSprF,x
Irq2_Spr6Frame: sta screen1+$03f9
lda sortSprC,x
sta $d028
bmi Irq2_SprIrqDone
inx
Irq2_Spr7: lda sortSprY,x
sta $d001
lda sortSprX,x
ldy sortSprD010,x
sta $d000
sty $d010
lda sortSprF,x
Irq2_Spr7Frame: sta screen1+$03f8
lda sortSprC,x
sta $d027
bmi Irq2_SprIrqDone
inx
Irq2_ToSpr0: jmp Irq2_Spr0
if (Irq2_Spr0 & $ff00) != (Irq2_Spr7 & $ff00)
err
endif
Irq2_SprIrqDone:
ldy sprIrqLine,x ;Get startline of next IRQ
beq Irq2_AllDone ;(0 if was last)
inx
stx Irq2_SprIndex+1 ;Store next IRQ sprite start-index
txa
and #$07
tax
lda sprIrqJumpTbl,x ;Get the correct jump address
sta Irq2_SprJump+1
lda fileOpen
beq Irq2_SprIrqDoneNoLoad
dey
Irq2_SprIrqDoneNoLoad:
tya
sec
sbc #$03 ;Already late from the next IRQ?
cmp $d012
bcs SetNextIrqNoAddress
bcc Irq2_Direct ;If yes, execute directly
Irq2: cld ;To save time, do not use StartIrq here, as the sprite IRQs
sta irqSaveA ;may repeat several times
stx irqSaveX
sty irqSaveY
lda #$35
sta $01 ;Ensure IO memory is available
Irq2_Direct:
Irq2_SprIndex: ldx #$00
Irq2_SprJump: jmp Irq2_Spr0
Irq2_AllDone: ldy #IRQ3_LINE-1
lda fileOpen
beq Irq2_AllDoneNoLoad
dey
Irq2_AllDoneNoLoad:
tya
sec
sbc #$03
cmp $d012 ;Late from the scorepanel IRQ?
bcc Irq2_LatePanel
lda #<Irq3
ldx #>Irq3
SetNextIrq: sta $fffe
stx $ffff
SetNextIrqNoAddress:
sty $d012
dec $d019 ;Acknowledge raster IRQ
lda irqSave01
sta $01 ;Restore $01 value
lda irqSaveA
ldx irqSaveX
ldy irqSaveY
rti
Irq2_LatePanel: ldy irqSaveY
jmp Irq3_Direct
;Raster interrupt 4. Show panel, play music, set C128 to 2MHz mode and SCPU to turbo mode,
;if no loading going on. Also animate level graphics
Irq4: jsr StartIrq
lda #$18
sta $d016
lda #$17 ;Switch screen back on
sta $d011
if SHOW_PLAYROUTINE_TIME > 0
inc $d020
endif
jsr PlayRoutine ;Play music/sound effects
if SHOW_PLAYROUTINE_TIME > 0
dec $d020
endif
Irq4_Irq6Jump: lda #<Irq6
ldx #>Irq6
ldy #IRQ6_LINE
jmp SetNextIrq
;Raster interrupt 6. Enable SCPU/C128 turbo if no loading or split, do levelupdate. On plain C64
;jumps directly here from interrupt 4.
Irq6: jsr StartIrq
Irq6_LevelUpdate:
lda #$00 ;Animate level background?
beq Irq6_NoLevelUpdate
if SHOW_LEVELUPDATE_TIME > 0
inc $d020
endif
jsr UpdateLevel
if SHOW_LEVELUPDATE_TIME > 0
dec $d020
endif
Irq6_NoLevelUpdate:
ldy #IRQ1_LINE
Irq6_SplitMode: ldx #$00 ;Check for split mode instead of normal IRQ1
bne Irq6_BeginSplit
Irq6_CheckTurbo:ldx fileOpen
bne Irq6_NoTurbo
inx
stx $d07b ;SCPU turbo mode & C128 2MHz mode enable
stx $d030
Irq6_NoTurbo:
Irq5_End: lda #<Irq1 ;Back to screen top interrupt
ldx #>Irq1
Irq6_NextIrqCommon:
jmp SetNextIrq
Irq6_BeginSplit:
lda #<Irq5
ldx #>Irq5
bne Irq6_NextIrqCommon
; Raster interrupt 5. Generic raster split engine
Irq5: jsr StartIrq
ldx #$00 ;Always sprites off first
Irq5_Loop: jsr Irq5_Get ;Register index or endmark + split pos
tay
cpy #$40
bcs Irq5_End ;Execute IRQ1 at the chosen position after end
jsr Irq5_Get
sta $d000,y
bcc Irq5_Loop
Irq5_Get: lda $1000,x
inx
rts