forked from videogamepreservation/asteroids-7800
-
Notifications
You must be signed in to change notification settings - Fork 1
/
UTILS.S
503 lines (446 loc) · 10.1 KB
/
UTILS.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
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
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
* 1850 030784
*
** UTILS.S *
** ASTEROIDS FOR THE ATARI 3600 **
** THIS FILE CONTAINS UTILITY PROGRAMS. **
*
** PRESENTLY CONTAINS -
*
* GAME PLAY LOOP *
* DIFFICULTY LEVEL INC ROUTINE *
* RANDOM NUMBER ROUTINES *
* SAFETY BOX CHECK ROUTINE *
* FLIP PLAYER ROUTINE *
* STAR TWINKLER *
* ICON SETUP ROUTINE *
* PAINT SHIP ROUTINE *
* WAIT FOR LOADER ROUTINE *
*
** BASIC GAME PLAY LOOP. **
GAMELOOP:
;SET DIFFICULTY LEVELS
LDX PLAYER
LDA LEVEL,X
STA MINYVEL ;SET MINYVEL AND MINXVEL
LSR
STA MINXVEL
LDA ROCKTOT,X ;CONTINUE UNTIL ROCKTOT = 0
BNE GAMEPLAY
LDA STATUS+25 ;WAIT FOR UFO TO LEAVE BEFORE NEW RACK
CMP #$FF ;FF = NON-EXISTANT
BNE GAMEPLAY ;IF HE EXISTS, JUST WAIT IN GAMEPLAY
LDA STATE ;IF EITHER PLAYER IS IN STATE 0 OR 1
AND STATE+1 ; (THAT IS, OK OR BIRTH)
CMP #2 ; THEN THIS 'AND' WILL BE LESS THAN 2
BCS GAMEPLAY ; IF IT ISN'T, THEN WAIT IN GAMEPLAY
LDA MODE
BNE ZDECRDLY ;IN TWO PLAYER, DON'T CREATE ROCKS
LDY OFFPLAY2 ; IF CURRENT PLAYER IS DEAD, SO AS
LDA STATUS+24,Y ; NOT TO CREATE ROCKS AND IMMEDIATELY
BMI GAMEPLAY ; SWITCH THEM OUT.
ZDECRDLY:
DEC RACKDLY ;DON'T DO NEW RACK 'TILL DLY OVER
BPL GAMEPLAY ;LET THE SHOW GO ON !
LDA #RACKDLYC ;PRIME TIMER FOR NEXT RACK
STA RACKDLY
INC RACKNUM,X ;WHEN =0 NEW RACK
LDA RACKNUM,X ;SET NUM OF ROCKS TO BE RACKNUM
CLC
ADC #2 ; PLUS TW0
ADC DIFF ; PLUS DIFF (NOVICE=0,EXPERT=3)
STA ROCKTOT,X
LDY DIFF ;DETERMINE MAX NUMBER OF ROCKS
LDA MAXROCKS,Y
CMP ROCKTOT,X ; UP TO A MAXIMUM
BCS NEWRACK
STA ROCKTOT,X
NEWRACK:
STA STARTNUM,X
JSR LOADSTAR ;LOAD STARS INTO DISPLAY HEADERS.
LDA #1 ;TYPE 1 INCREMENT FOR RACK
JSR INCLVL
LDA #$50 ;5.2 SEC COUNTER FOR UFO
STA RTIMER
LDX DIFF
LDA UTIMES,X ;UFO
LDX PLAYER
SEC
SBC RACKNUM,X
SBC RACKNUM,X
SBC RACKNUM,X
STA SDELAY
STA EDELAY
LDA #9
STA UFOACC ;SET ACCURACY DOWN TO MINIMUM
LDA #$28 ;INITIALIZE UFO SHOT COUNTDOWN
STA USHOTCNT
JSR INITHUMP ;RESET THE HUMP RATE.
JSR INITROCK ;INITIALIZE THE ROCKS
GAMEPLAY:
JSR FSM ;FINITE STATE MACHINE
JSR JOY ;EXECUTE JOYSTICK INPUTS
LDA MODE ;REPEAT FOR TEAM PLAY MODES
CMP #1
BMI NOTEAM
JSR FLIPPLAY ;FLIP PLAYER
JSR FSM ;REPEAT FOR OTHER PLAYER
JSR JOY
JSR FLIPPLAY
NOTEAM:
JSR ROCKMOVE ;UPDATE OBJECT MOVEMENT
JSR SHOTMOVE ;UPDATE SHOT MOVEMENT
JSR COLLIDE ;CHECK COLLISIONS
JSR EXPLODE ;CHECK EXPLOSIONS
JSR UFO ;UPDATE UFO
JSR BACKSNDS ;ADD BACKGROUND SOUNDS
RTS
MAXROCKS:
.DC.B 8,12,14,16 ;MAX NUM ROCKS FOR EACH DIFF
UTIMES:
.DC.B 0,$A7,$95,$8F
** DIFFICULTY LEVEL INCREMENT ROUTINE **
** CALLED WITH TYPE OF INCREMENT IN AC, TRASHES Y **
** TYPES: 0 = POINTS, 1 = RACKS, 2 = MR. BILL, 3 = SLUGGO **
INCLVL:
TAY
LDA LVLINC,Y
LDY PLAYER
CLC
ADC LEVEL,Y
CMP MAXLVL ;THERE IS ONLY ONE MAX FOR BOTH PLAYERS
BCC LVLOK
LDA MAXLVL
LVLOK:
STA LEVEL,Y
RTS
** RANDOM NUMBER ROUTINES, >NOT< PREVIOUSLY IN RANDOM.S **
* NEWRAND: A WHOLESOME RANDOM NUMBER JENERATER FROM KNUTH (NOTABLE PEDIGREE)
NEWRAND:
LDY RANDPTR0 ;LOAD Y WITH CONTENTS OF RANDPTR0
LDA RAND,Y ;LOAD AC WITH RAND INDEXED BY Y
CLC ;CLEAR THE CARRY
LDY RANDPTR1 ;LOAD Y WITH CONTENTS OF RANDPTR1
ADC RAND,Y ;ADD RAND INDEXED BY Y TO AC
LDY RANDPTR0 ;GET THE DRIFT?
STA RAND,Y
DEC RANDPTR0
BPL ZR1
LDY #54
STY RANDPTR0
ZR1:
DEC RANDPTR1
BPL ZR2
LDY #54
STY RANDPTR1
ZR2:
RTS
RANDPOS:
JSR NEWRAND
LSR
BCC HBORDER
LDA #YPOSMAX
STA YPOSH,X
XRANDLOP:
JSR NEWRAND
CMP #XPOSMAX-6
BCS XRANDLOP
STA XPOSH,X
RTS
HBORDER:
LDA #XPOSMAX
STA XPOSH,X
YRANDLOP:
JSR NEWRAND
CMP #YPOSMAX
BCS YRANDLOP
STA YPOSH,X
RTS
RANDVEL:
JSR NEWRAND
ROL ;USE SIGN BIT FOR DIRECTION (L OR R)
BCC RNDVXPOS ;X VELOCITY IS POSITIVE
SBC MINXVEL ;ADD IN MINIMUM VELOCITY
STA XVELL,X
LDA #$FF ;VELOCITY IS NEGATIVE
SBC #0 ;TAKE AWAY THE BORROW, IF ANY
STA XVELH,X
BCS RANDVY ;UNCOND. BRANCH
RNDVXPOS:
ADC MINXVEL ;ADD IN MINIMUM VELOCITY
STA XVELL,X
LDA #0
ROL ;ROL IN THE CARRY, IF ANY
STA XVELH,X
RANDVY:
JSR NEWRAND
ROL
BCC RNDVYPOS
SBC MINYVEL
STA YVELL,X
LDA #$FF
SBC #0
STA YVELH,X
BCS RANDVRTS
RNDVYPOS:
ADC MINYVEL
STA YVELL,X
LDA #0
ROL
STA YVELH,X
RANDVRTS:
RTS
* CHECK IF ANY OBJECT IS IN SAFETY BOX.
* RETURNS WITH ZERO (Z) BIT SET IF ALL IS CLEAR.
* WE DON'T WORRY ABOUT CARRIES (LOW PRECISION).
* DESTROYS: X, Y, AND FIRST 7 BYTES OF TEMP
* TEMP LAYOUT: TEMP X (OBJECT INDEX)
* TEMP+1 BOXR (RIGHT HAND BOUNDARY)
* TEMP+2 BOXL (LEFT HAND BOUNDARY)
* TEMP+3 BOXTOP (TOP BOUNDARY)
* TEMP+4 BOXBOT (BOTTOM BOUNDARY)
* TEMP+5 X WRAP FLAG (1 = WRAP)
* TEMP+6 Y WRAP FLAG (1 = WRAP)
ISSAFE:
STX TEMP ;SAVE X WHERE IT MAY BE COMPARED TO Y
LDA #0 ;0 MEANS "NO WRAP OF BOX"
STA TEMP+5
STA TEMP+6
LDA XPOSH,X ;CHECK RIGHT HAND SIDE OF BOX.
ADC BOXWIDTH ; (SHOULD CLC HERE....)
STA TEMP+1 ;BOXR
SBC #XPOSMAX ;CHECK FOR WRAPAROUND.
BCC BOXROK ; BOX'S RIGHT HAND SIDE: NO WRAP.
INC TEMP+5 ; YES WRAP: SET FLAG
STA TEMP+1
BOXROK:
LDA XPOSH,X ;CHECK LEFT HAND SIDE OF BOX.
SBC BOXWIDTH
BCS BOXLOK ;CHECK FOR WRAPAROUND.
INC TEMP+5 ; YES WRAP: SET FLAG
ADC #XPOSMAX ; MOD INTO RANGE
BOXLOK:
STA TEMP+2 ; AND SAVE IT (BOXL).
LDA YPOSH,X ;CHECK TOP OF BOX.
ADC BOXHIGHT
STA TEMP+3
SBC #YPOSMAX
BCC BOXTOK
INC TEMP+6
STA TEMP+3
BOXTOK:
LDA YPOSH,X ;CHECK BOTTOM OF BOX.
SBC BOXHIGHT
BCS BOXBOK
INC TEMP+6
ADC #YPOSMAX
BOXBOK:
STA TEMP+4
LDX #32 ;START WITH LAST OBJECT (#32)
NEXTSAFE:
LDA STATUS,X ;CHECK ITS STATUS:
BMI SAFEOK ; IF OBJECT DOESN'T EXIST, IT IS SAFE.
;FIRST CHECK X COORDS
LDA #0 ;CLEAR OUT COMPARISON REGISTER "A"
LDY XPOSH,X ;GET OBJECT X'S HORIZ. POSITION
CPY TEMP+1 ;COMPARE TO BOXR
ROL ;ROL BIT INTO A
CPY TEMP+2 ;COMPARE TO BOXL
ADC #0 ;ADD BIT INTO A
EOR TEMP+5 ;FLIP LOW BIT WITH X WRAP BIT
ROR ;ROR BIT INTO CARRY
BCC SAFEOK ;NO BIT MEANS SAFE (OUTSIDE OF BOX).
;THEN CHECK Y COORDS
LDA #0
LDY YPOSH,X
CPY TEMP+3
ROL
CPY TEMP+4
ADC #0
EOR TEMP+6
ROR
BCC SAFEOK
;FINALLY, CHECK IF IT IS THE OBJECT SPECIFIED ITSELF.
CPX TEMP
BEQ SAFEOK
;OBJECT IN BOX! UNSAFE TO ENTER!
; LDY #1 ;CLEAR Z BIT TO SIGNIFY NOT CLEAR.
;NOT NEEDED (BEQ ABOVE)
RTS
SAFEOK:
DEX ;GET NEXT OBJECT
BPL NEXTSAFE ;AND CONTINUE CHECKING
LDY #0 ;SET Z BIT TO SIGNIFY ALL CLEAR.
RTS
BOXWIDTH:
.DC.B $10
BOXHIGHT:
.DC.B $1A
* ROUTINE TO PUT UP SCORES. WHATEVER IS IN PLAYER OR HIGH SCORES GOES. *
DOSCORE:
JSR CLSCORE ;ERASE ALL SCORES FIRST
JSR PUTHISCR ;HIGH SCORE UP
LDA MODE
CMP #1 ;COMBINED SCORE
BNE ZPLRSCOR
LDA #2
STA SCORER
JSR PUTSCORE
JSR PUTMEN
LDA #0
STA SCORER
JSR PUTSCORE
LDA #1
STA SCORER
JSR PUTSCORE
RTS
ZPLRSCOR:
LDA #0
STA SCORER
JSR PUTSCORE ;PLAYER 1 SCORE UP
JSR PUTMEN
LDA MODE
BMI NOP2SCOR
LDA #1
STA SCORER
JSR PUTSCORE ;PLAYER 2 SCORE UP
JSR PUTMEN
NOP2SCOR:
RTS
* ROUTINE TO ERASE SCORES. *
CLSCORE:
LDX #56 ;CLEAR MAPS
LDA #0
ZCLRLOOP:
STA CHARMAPS,X
DEX
BPLOP:
BPL ZCLRLOOP ;LABLED TO ACCESS BPL OPCODE ($10)
RTS
** ROUTINE USED IN GAME LOOP TO TOGGLE PLAYER BACK AND FORTH. **
FLIPPLAY:
LDA PLAYER ;CHANGE PLAYER
EOR #1
STA PLAYER
BEQ STOROFF ;ESTABLISH DATA OFFSET
LDA #8 ;SECOND PLAYER POINTS TO END
STOROFF:
STA OFFPLAY2
RTS
* ROTATE THROUGH THE COLORS TO TWINKLE THE STARS.
TWINKLE:
JSR NEWRAND ;DECIDE WHICH STARS TO TW'INC'LE
LSR
BCC NOINC2
LSR
BCC NOINC2
INC SOFTCOLR+14
NOINC2:
LSR
BCC LOGODO
LSR
BCC LOGODO
INC SOFTCOLR+15
LOGODO:
LDA GAMSTATE ;DON'T DO LOGOBARS WHILE PLAYING
CMP #PLAYST
BEQ LOGORTS
CMP #AUTOST
BEQ LOGORTS
LOGOBARS:
LDA FRMCNT ;DO IT ONLY ON EVEN FRAMES
LSR
BCS LOGORTS
INC TEMP+11 ;MOVE THIS!!
LDA TEMP+11
BIT BPLOP ;(BPLOP: OPCODE $10 IS BPL)
BNE LOGOGO
EOR #$1F
LOGOGO:
STA SOFTCOLR+10 ;UPDATE HARDWARE REGISTER
LOGORTS:
RTS
* SET UP AN ICON:
* ON ENTRY: Y SHOULD CONTAIN ICON NUMBER
* X SHOULD CONTAIN INDEX NUMBER OF NEW OBJECT
DOICON:
LDA ICONACYC,Y
STA ACYC,X
LDA ICONXPOS,Y
STA XPOSH,X
LDA ICONYPOS,Y
STA YPOSH,X
LDA ICONPALS,Y
STA PALS,X
LDA #ICON
CPY #22 ;ICONS > 22 ARE SHIPS
BCC ZISICON
LDA #SHIP
ZISICON:
STA STATUS,X
RTS
* PAINTSHP -- PAINT THE SHIP, BODY AND DEJAG AND FLAME COLORS
* ARGUMENTS: X CONTAINS THE PLAYER TO PAINT
* A CONTAINS THE DESIRED LUME OF THE BODY
PAINTSHP:
AND #$0F ;KNOCK OFF EXTRANEOUS BITS
ORA BODYHUES,X ;OR IN THE CORRECT BODY HUE
PHA ;PUSH BODY COLOR
LSR ;LOWER INTENSITY FOR DEJAG LUME
AND #$07 ;KNOCK OFF EXTRANEOUS BITS
ORA BODYHUES,X ;OR IN THE CORRECT BODY HUE
CPX #0 ;WHICH PLAYER?
BEQ ZPAINTGO ;FOR 1ST PLAYER, USE 1ST PALETTE
LDX #4 ;FOR 2ND PLAYER, USE 2ND PALETTE
ZPAINTGO:
STA SOFTCOLR+3,X ;STORE DEJAG COLOR
PLA ;PULL BODY COLOR
STA SOFTCOLR+2,X ;STORE BODY COLOR
LDA #0 ;TURN OFF SHIP'S THRUST FLAME
STA SOFTCOLR+1,X
RTS
* REFRESH COLOR RAM, UPPER 4 PALETTES FROM ROM, LOWER 4 FROM RAM
REFRESH:
LDX #$1F
ZEFRESH:
LDA COLORS,X
STA BACKGRND,X
DEX
LDA COLORS,X
STA BACKGRND,X
DEX
LDA COLORS,X
STA BACKGRND,X
DEX
DEX ;SKIP OVER OTHER HARDWARE REGISTERS
CPX #$10 ;$10 - $1F FROM ROM (COLORS)
BCS ZEFRESH
* NOW DO RAM PART:
Z2FRESH:
LDA SOFTCOLR,X
STA BACKGRND,X
DEX
LDA SOFTCOLR,X
STA BACKGRND,X
DEX
LDA SOFTCOLR,X
STA BACKGRND,X
DEX
DEX ;SKIP OVER OTHER HARDWARE REGISTERS
BPL Z2FRESH
INX ;$FF + 1 = $00
STX BACKGRND ;FORCE BLACK BACKGROUND
RTS
WAITLOAD:
LDA #1 ;SET LOAD FLAG
STA LOADFLAG
ZWAIT:
LDA LOADFLAG ;WAIT FOR LOADER TO FINISH
BEQ ZWRTS ;IF LOADER FINISHED THEN RTS
BIT MSTAT ;IF OFF SCREEN FORCE LOAD
BPL ZWAIT
BIT MSTAT ;PROTECTION
BPL ZWAIT
JSR REFRESH ;MAKE SURE COLORS ARE RIGHT FIRST
JSR LOADER
ZWRTS:
RTS