-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstd_kernel.asm
296 lines (256 loc) · 6.28 KB
/
std_kernel.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
processor 6502
include "vcs.h"
include "macro.h"
include "timers.h"
WHITE = $0E
GREEN = $C2
BLUE = $76
YELLOW = $1E
SEG.U vars
ORG $80 ; start of RAM
SCANLINE_N ds 1
PLAYER0_X ds 1
PLAYER0_Y ds 1
PLAYER0_X_PREV ds 1
PLAYER0_Y_PREV ds 1
PLAYER0_SLICE_EVEN ds 1 ; player slice even lines
PLAYER0_SLICE_ODD ds 1 ; player slice odd lines
BK_COLOR ds 1
TEMP ds 1
SEG
ORG $F000
Reset
CLEAN_START
lda #0
sta PLAYER0_X
lda #84
sta PLAYER0_Y
lda #GREEN
sta BK_COLOR
lda #$FA
sta COLUP0 ; color player 0
lda #100
sta PLAYER0_SLICE_EVEN ; next player 0 bitslice to draw
lda #$44
sta PLAYER0_SLICE_ODD
lda #1 ; set D0 CTRLPF for reflection
sta CTRLPF
StartOfFrame
lda #2
sta VBLANK ; blank video signal
VERTICAL_SYNC
TIMER_VBLANK ; init timer for VBLANK period
JSR FramePre ; do any setup before the frame
TIMER_WAIT
lda #0
sta VBLANK ; unblank video signal
TIMER_FRAME ; init timer for the visible frame
lda #0
STA WSYNC
ScanLine
JSR DoScanLineLoop
ldx #YELLOW ; yellow for the block of lines not rendered. If visible FRAME_TIMER is too long
stx COLUBK
TIMER_WAIT
lda #2
sta VBLANK ; blank video signal
TIMER_OVERSCAN ; init timer for overscan
JSR FramePost
TIMER_WAIT
JMP StartOfFrame
FramePre
lda #WHITE
sta COLUPF ; set the playfield color
ldx PLAYER0_Y
stx PLAYER0_Y_PREV
lda #$20
bit SWCHA
bne .testUp
inx
jmp .storeY
.testUp
lda #$10
bit SWCHA
bne .storeY
dex
.storeY
stx PLAYER0_Y
ldx PLAYER0_X
stx PLAYER0_X_PREV
lda #$80
bit SWCHA
bne .testLeft
inx
jmp .storeX
.testLeft
lda #$40
bit SWCHA
bne .storeX
dex
.storeX
stx PLAYER0_X
lda PLAYER0_X
jsr setHorizontalPos
sta WSYNC ; wait for new scanline to fine tune position player 1
sta HMOVE
rts
; scan line is in acc and y
; set playfield and sprites based on scanline
;
DoScanLineLoop
lda #0
sta SCANLINE_N
tay
.continue
STA WSYNC
ldx PLAYER0_SLICE_EVEN
stx GRP0
tay
and #%11111100 ; divide by 4 (to repeat 4 lines) and mult by 4 (to index into bitmap)
tax
lda Field0,x
sta PF0
lda Field1,x
sta PF1
lda Field2,x
sta PF2
; must be done after the odd scanline
sta WSYNC
ldx PLAYER0_SLICE_ODD
stx GRP0
; compute next player slice
tya
sec ; 2s complement so set carry
sbc PLAYER0_Y
bmi .clearPlayer
cmp #8
bpl .clearPlayer
tax
lda PlayerBitmap,x
sta PLAYER0_SLICE_EVEN
lda PlayerBitmap+1,x
sta PLAYER0_SLICE_ODD
jmp .increment
.clearPlayer
nop
nop
nop
nop
lda #0
sta PLAYER0_SLICE_EVEN
sta PLAYER0_SLICE_ODD
.increment
inc SCANLINE_N
inc SCANLINE_N
lda SCANLINE_N
cmp #192
bne .continue
; clear playfield at end of line
STA WSYNC
lda #0
sta PF0
sta PF1
sta PF2
rts
; if timing is correct this color is not seen because it should be called in non-visible overscan area
FramePost
bit CXP0FB
bpl .noCollision
lda #BLUE
sta COLUBK
ldx PLAYER0_X_PREV
stx PLAYER0_X
ldx PLAYER0_Y_PREV
stx PLAYER0_Y
jmp .clearCollision
.noCollision
lda #GREEN
sta COLUBK
.clearCollision
lda #0
sta CXCLR
sta PF0 ; clear
sta PF1 ; clear
sta PF2 ; clear
RTS
org $FF00 ; *********************** GRAPHICS DATA
setHorizontalPos
sta WSYNC
sec
.DivideLoop
sbc #15
bcs .DivideLoop
eor #7
asl
asl
asl
asl
sta HMP0
sta RESP0
rts
Playfield
.byte %11110000,%11111111,%11111111,$00 ; lower nibble ignored and upper reversed for 1st. 3rd reversed, 4th ignored
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00111100,%00000000,$00
.byte %00010000,%00100100,%00000000,$00
.byte %00000000,%00100100,%00000000,$00 ; start gap
.byte %00000000,%00100100,%00000000,$00
.byte %00000000,%00100100,%00000000,$00
.byte %00000000,%00100100,%00000000,$00
.byte %00000000,%00100100,%00000000,$00
.byte %00000000,%00100100,%00000000,$00
.byte %00000000,%00100100,%00000000,$00
.byte %00000000,%00100100,%00000000,$00 ; end gap
.byte %00010000,%00100100,%00000000,$00
.byte %00010000,%00111100,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %00010000,%00000000,%00000000,$00
.byte %11110000,%11111111,%11111111,$00
Field0 = Playfield
Field1 = Playfield+1
Field2 = Playfield+2
PlayerBitmap
.byte %10000001
.byte %01000010
.byte %00100100
.byte %10011000
.byte %11100100
.byte %00100100
.byte %00011000
.byte %00111100
ORG $FFFA
.word Reset ; NMI
.word Reset ; RESET
.word Reset ; IRQ
END