-
Notifications
You must be signed in to change notification settings - Fork 0
/
pong.asm
440 lines (361 loc) · 10.3 KB
/
pong.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
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
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Pong
; James Danielson, GeekyLink
;
; Help from Kirk Israel's Moving Dot demo
; Also help from Nukey Shay for tip on improving display kernel
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
processor 6502
include vcs.h
include macro.h
org $F000
BallY = $80 ; Ypos of the ball
VisibleBallLine = $81 ; Line of the ball
BallX = $82 ; Ball X
; Player lines
Player0Line = $83
Player1Line = $84
; Paddle Y
Paddle0Y = $85;
Paddle1Y = $86;
;;; Directions
VDire = #$88 ; Vertical
HDire = #$89 ; Horizontal
;;; Score kinda...
P0Score = #$8A
P1Score = #$8B
;;; Score to play to
PlayToScore = #$8C
ScoreSet = #$8D
SelectReleased = #$8E
Start
SEI
CLD
LDX #$FF
TXS
LDA #0
;;; Clears memory
ClearMem
STA 0,X
DEX
BNE ClearMem
LDA #1
STA PlayToScore
STA SelectReleased
LDA #0
STA ScoreSet
SetupVars
LDA PlayToScore
STA P0Score
STA P1Score
LDA #$50
STA BallY ; Sets first Y pos for ball
LDA #$80
STA BallX ; Sets ball's first X, only used for comparing really
; Sets top value for Paddle 0 and 1
LDA #$3A
STA Paddle0Y ; 0
STA Paddle1Y ; 1
LDA #$10
STA HDire ; Sets first H direction
LDA #$06
STA VDire ; Sets first V direction
LDA #$00
STA COLUBK ; Background color
LDA #$0E
STA COLUP0 ; Player and Missle 0
STA COLUP1 ; Player and Missle 1
LDA #%00100111 ; Load size for missle and paddle
STA NUSIZ0 ; Sets the size for Player and Missle 0
STA NUSIZ1 ; Sets the size for Player and Missle 1
;;; Sets the ball's first spot
STA WSYNC
LDX #12
PositionLoop
dex
bne PositionLoop
STA RESM0
MainLoop
LDA #2
STA VSYNC
STA WSYNC
STA WSYNC
STA WSYNC
LDA #43
STA TIM64T
LDA #0
STA VSYNC
;;; Score setter
;;; This only runs once, and when it does
;;; it skips the rest of the code
LDA ScoreSet
BNE SkipStartUp ; Only run this the first time
LDA #%00000010 ; Select button
BIT SWCHB
BNE SkipChangeScore ; Skips down if button not pressed
LDX #1
CPX SelectReleased
BEQ DoneWithChangeScore ; Used to see if the reset button has been released
STX SelectReleased ; Used to keep the select button running a ton
INC PlayToScore ; Increases the score limit
LDX #20
CPX PlayToScore
BNE DoneWithChangeScore ; If the score is greater than 20
LDA #1
STA PlayToScore ; Reset it to 1
DoneWithChangeScore
LDA PlayToScore ; Make sure the paddle's are the right size
STA P0Score ; So that the player can see how large they are
STA P1Score
JMP WaitForVblankEnd ; Displays the screen
SkipChangeScore
LDA #0
STA SelectReleased ; This is used so we can tell the switch was released
JMP WaitForVblankEnd ; Displays the screen
SkipStartUp
;;; Checks if a player won. If they did then disable everthing
;;; Makes it only possible for one player to win
;;; Sees if Player 0 won
LDA P0Score
BNE SkipP0Win
STA HMM0
LDA #$72
STA COLUBK
JMP WaitForVblankEnd
SkipP0Win
;;; Sees if Player 1 won
LDA P1Score
BNE SkipP1Win
STA HMM0
LDA #$D2
STA COLUBK
JMP WaitForVblankEnd
SkipP1Win
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sees which direction to move the ball ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDX #$5F ; Loads the value to check
CPX VDire ; Checks it against VDire
BEQ SkipMoveDown ; If VDire != #$BF
INC BallY ; Increase YPos
JMP SkipVMoves ; Skip over the decrease
SkipMoveDown ; Else if Vdire == #$BF
DEC BallY ; Decrease Ypos
SkipVMoves ; End of move check
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Start of keeping dot on screen ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Checks up and down
LDX BallY ; Loads the Ypos first
;;; Check if it is going too far down
CPX #$05
BNE SKIPDOWNCHECK ;If BallY < 10
LDA #$06
STA BallY ; Resets it back a step
STA VDire ; Stores the new vertical direction
SKIPDOWNCHECK
;;; Check if it is going too far up
CPX #$60
BNE SKIPUPCHECK ;If BallY > 192
LDA #$5F
STA BallY ; Resets it back a step
STA VDire ; Stores the new vertical direction
SKIPUPCHECK
;;;
;;; Collision
;;;
;;; Checks Player 1
LDA #%10000000
BIT CXM0P
BEQ SkipP1Check ; If not colliding try other
JMP HandleChanges ; If it is colliding jump straight to changes
SkipP1Check
;;; Checks Player 0
LDA #%01000000
BIT CXM0P
BEQ NoCollision ; If not hit, then no collision at all
;;; Handle changing the direction
HandleChanges
LDX #$10 ; Load up #$10 for comparing
CPX HDire ; Compare with HDire
BEQ OtherChange ; If HDire != #$10
STX HDire ; HDire = #$10
JMP NoCollision ; Skip to end so that the other change doesn't affect it
OtherChange ; Else if HDire == #$10
LDX #$F0
STX HDire ; HDire = #$F0
NoCollision ; End of Collision
LDX HDire
BPL MoveRightX
INC BallX
JMP EndMoveX
MoveRightX
DEC BallX
EndMoveX
STX HMM0 ; Sets H movement for ball based on HDire
STA CXCLR ; Resets collision
LDX BallX
CPX #$98
BEQ SwitchMe
LDA BallX
BNE EndSwitch
DEC P1Score ; Makes P1's paddle smaller
JMP HandleSwitchChanges
SwitchMe
DEC P0Score ; Makes P0's paddle smaller
HandleSwitchChanges
;;; Resets the info
LDA #$10
STA HDire ; Move ball left
LDA #$80
STA BallX ; reset the BallX counter
STA WSYNC ; Set up WSYNC for positioning
LDX #12 ; Sets up time to wait
PositionLoop2 ; Waits for time to pass
dex
bne PositionLoop2
STA RESM0 ; Resets the ball's X
EndSwitch
;;;;;;;;;;;;;;;;;;;
;; Control Check ;;
;;;;;;;;;;;;;;;;;;;
;;; COntrols for paddle 1
;;; Up button
LDA #%00000001 ; Up, P1
BIT SWCHA
BNE SkipUp1 ; If up button is held
INC Paddle1Y ; Increase value in Paddle1Y
SkipUp1
;;; Down button
LDA #%00000010 ; Down, P1
BIT SWCHA
BNE SkipDown1 ; If down button is held
DEC Paddle1Y ; Decrease value in Paddle1Y
SkipDown1
;;; Controls for Paddle 0
;;; Up button
LDA #%00010000 ; Up, P0
BIT SWCHA
BNE SkipUp0 ; If up button is held
INC Paddle0Y ; Increase value in Paddle0Y
SkipUp0
;;; Down button
LDA #%00100000 ; Down, P0
BIT SWCHA
BNE SkipDown0 ; If down button is held
DEC Paddle0Y ; Decrease value in Paddle0Y
SkipDown0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Start of keeping paddle on screen ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Paddle 0
;;; Checks up and down
LDX Paddle0Y ; Loads the Ypos first
;;; Check if it is going too far down
CPX P0Score
BNE SkipDownPaddle0Check ;If Paddle0Y < 0
INC Paddle0Y
SkipDownPaddle0Check
;;; Check if it is going too far up
CPX #$60
BNE SkipUpPaddle0Check ;If Paddle0Y > 96
LDA #$5F
STA Paddle0Y ; Resets it back a step
SkipUpPaddle0Check
;;; Paddle 1
;;; Checks up and down
LDX Paddle1Y ; Loads the Ypos first
;;; Check if it is going too far down
CPX P1Score
BNE SkipDownPaddle1Check ;If Paddle1Y < 0
INC Paddle1Y
SkipDownPaddle1Check
;;; Check if it is going too far up
CPX #$60
BNE SkipUpPaddle1Check ;If Paddle1Y > 96
LDA #$5F
STA Paddle1Y ; Resets it back a step
SkipUpPaddle1Check
;;;;;;;;;;;;;;;;
;; WaitForVBL ;;
;;;;;;;;;;;;;;;;
WaitForVblankEnd
LDA INTIM
BNE WaitForVblankEnd
LDY #95
STA WSYNC
STA VBLANK
STA WSYNC
STA HMOVE ; Moves our stuff horizontally
;;; Loop to handle graphics
ScanLoop
STA WSYNC
CPY BallY ; Compare Y and BallY
BNE SkipActivateBall ; If BallY == Y
LDA #4 ; Load #8
STA VisibleBallLine ; Store #8 in line counter
SkipActivateBall
;;; Turn off the ball
LDA #0
STA ENAM0
LDA VisibleBallLine ; Load Ball line counter
BEQ FinishBall ; If BallLineCounter != 0
LDA #2 ; Load #2
STA ENAM0 ; Use it to activate ball
DEC VisibleBallLine ; Decrease remaining lines for ball
FinishBall
;;; Sets height of Paddle 0
CPY Paddle0Y ; Compare Paddle Y
BNE SkipPaddle0 ; If PaddleY == Y
LDA P0Score
STA Player0Line ; Store the height of paddle
SkipPaddle0
;;; Sets height of Paddle 1
CPY Paddle1Y ; Compare Paddle Y
BNE SkipPaddle1 ; If PaddleY == Y
LDA P1Score
STA Player1Line ; Store the height of paddle
SkipPaddle1
LDA #2
STA WSYNC
;;; De-activates Player 0 and 1
LDA #0
STA GRP0 ; 0
STA GRP1 ; 1
LDX #2 ; Use for activating Player 0 and 1
;;; Paddle 0
LDA Player0Line ; Load the Paddle's line counter
BEQ FinishPlayer0 ; If PaddleLineCounter != 0
STX GRP0 ; Activate Paddle with LDX above
DEC Player0Line ; Decrease lines left in paddle
FinishPlayer0
;;; Paddle 1
LDA Player1Line ; Load the Paddle's line counter
BEQ FinishPlayer1 ; If PaddleLineCounter != 0
STX GRP1 ; Activate Paddle with LDX above
DEC Player1Line; Decrease lines left in paddle
FinishPlayer1
DEY ; Decrease Y
BNE ScanLoop ; Loop till Y == 0
;;; Kill remaining WSYNCs
LDA #2
STA WSYNC
STA VBLANK
LDX #30
OverScanWait
STA WSYNC
DEX
BNE OverScanWait
;;; If reset button is pushed, reset all the shit
LDA #%00000001 ; Reset button
BIT SWCHB
BNE SkipReset ; If Reset button is held
LDA #1
STA ScoreSet
JMP SetupVars ; Jump back to setup
SkipReset
JMP MainLoop
;;; System start to program start
org $FFFC
.word Start
.word Start