]> github.com/historicalsource and other repositories - asteroids-7800.git/blob - UTILS.S
Initial import.
[asteroids-7800.git] / UTILS.S
1 *         1850    030784\r
2 *\r
3 ** UTILS.S *\r
4 ** ASTEROIDS FOR THE ATARI 3600 **\r
5 ** THIS FILE CONTAINS UTILITY PROGRAMS. **\r
6 *\r
7 ** PRESENTLY CONTAINS - \r
8 *\r
9 *         GAME PLAY LOOP                 *\r
10 *         DIFFICULTY LEVEL INC ROUTINE   *\r
11 *         RANDOM NUMBER ROUTINES         *\r
12 *         SAFETY BOX CHECK ROUTINE       *\r
13 *         FLIP PLAYER ROUTINE            *\r
14 *         STAR TWINKLER                  *\r
15 *         ICON SETUP ROUTINE             *\r
16 *         PAINT SHIP ROUTINE             *\r
17 *         WAIT FOR LOADER ROUTINE        *\r
18 *\r
19 \r
20 \r
21 ** BASIC GAME PLAY LOOP. **\r
22 \r
23 GAMELOOP:\r
24         ;SET DIFFICULTY LEVELS\r
25         LDX     PLAYER\r
26         LDA     LEVEL,X\r
27         STA     MINYVEL         ;SET MINYVEL AND MINXVEL\r
28         LSR\r
29         STA     MINXVEL\r
30 \r
31         LDA     ROCKTOT,X       ;CONTINUE UNTIL ROCKTOT = 0\r
32         BNE     GAMEPLAY\r
33         LDA     STATUS+25       ;WAIT FOR UFO TO LEAVE BEFORE NEW RACK\r
34         CMP     #$FF            ;FF = NON-EXISTANT\r
35         BNE     GAMEPLAY        ;IF HE EXISTS, JUST WAIT IN GAMEPLAY\r
36         LDA     STATE           ;IF EITHER PLAYER IS IN STATE 0 OR 1\r
37         AND     STATE+1         ; (THAT IS, OK OR BIRTH)\r
38         CMP     #2              ; THEN THIS 'AND' WILL BE LESS THAN 2\r
39         BCS     GAMEPLAY        ; IF IT ISN'T, THEN WAIT IN GAMEPLAY\r
40         LDA     MODE\r
41         BNE     ZDECRDLY        ;IN TWO PLAYER, DON'T CREATE ROCKS\r
42         LDY     OFFPLAY2        ; IF CURRENT PLAYER IS DEAD, SO AS\r
43         LDA     STATUS+24,Y     ; NOT TO CREATE ROCKS AND IMMEDIATELY\r
44         BMI     GAMEPLAY        ; SWITCH THEM OUT.\r
45 ZDECRDLY:\r
46         DEC     RACKDLY         ;DON'T DO NEW RACK 'TILL DLY OVER\r
47         BPL     GAMEPLAY        ;LET THE SHOW GO ON !\r
48         LDA     #RACKDLYC       ;PRIME TIMER FOR NEXT RACK\r
49         STA     RACKDLY\r
50         INC     RACKNUM,X       ;WHEN =0 NEW RACK\r
51 \r
52         LDA     RACKNUM,X       ;SET NUM OF ROCKS TO BE RACKNUM\r
53         CLC\r
54         ADC     #2              ;  PLUS TW0\r
55         ADC     DIFF            ;  PLUS DIFF (NOVICE=0,EXPERT=3)\r
56         STA     ROCKTOT,X\r
57         LDY     DIFF            ;DETERMINE MAX NUMBER OF ROCKS\r
58         LDA     MAXROCKS,Y\r
59         CMP     ROCKTOT,X       ; UP TO A MAXIMUM\r
60         BCS     NEWRACK\r
61         STA     ROCKTOT,X\r
62 \r
63 NEWRACK:\r
64         STA     STARTNUM,X\r
65         JSR     LOADSTAR        ;LOAD STARS INTO DISPLAY HEADERS.\r
66 \r
67         LDA     #1              ;TYPE 1 INCREMENT FOR RACK\r
68         JSR     INCLVL\r
69 \r
70         LDA     #$50            ;5.2 SEC COUNTER FOR UFO\r
71         STA     RTIMER\r
72         LDX     DIFF\r
73         LDA     UTIMES,X        ;UFO\r
74         LDX     PLAYER\r
75         SEC\r
76         SBC     RACKNUM,X\r
77         SBC     RACKNUM,X\r
78         SBC     RACKNUM,X\r
79         STA     SDELAY\r
80         STA     EDELAY\r
81 \r
82         LDA     #9\r
83         STA     UFOACC          ;SET ACCURACY DOWN TO MINIMUM\r
84         LDA     #$28            ;INITIALIZE UFO SHOT COUNTDOWN\r
85         STA     USHOTCNT\r
86 \r
87         JSR     INITHUMP        ;RESET THE HUMP RATE.\r
88         JSR     INITROCK        ;INITIALIZE THE ROCKS\r
89 \r
90 \r
91 GAMEPLAY:\r
92         JSR     FSM             ;FINITE STATE MACHINE\r
93         JSR     JOY             ;EXECUTE JOYSTICK INPUTS\r
94         LDA     MODE            ;REPEAT FOR TEAM PLAY MODES\r
95         CMP     #1\r
96         BMI     NOTEAM\r
97         JSR     FLIPPLAY        ;FLIP PLAYER\r
98         JSR     FSM             ;REPEAT FOR OTHER PLAYER\r
99         JSR     JOY\r
100         JSR     FLIPPLAY\r
101 NOTEAM:\r
102         JSR     ROCKMOVE        ;UPDATE OBJECT MOVEMENT\r
103         JSR     SHOTMOVE        ;UPDATE SHOT MOVEMENT\r
104         JSR     COLLIDE         ;CHECK COLLISIONS\r
105         JSR     EXPLODE         ;CHECK EXPLOSIONS\r
106         JSR     UFO             ;UPDATE UFO\r
107         JSR     BACKSNDS        ;ADD BACKGROUND SOUNDS\r
108         RTS\r
109 \r
110 MAXROCKS:\r
111         .DC.B   8,12,14,16      ;MAX NUM ROCKS FOR EACH DIFF\r
112 UTIMES:\r
113         .DC.B   0,$A7,$95,$8F\r
114 \r
115 ** DIFFICULTY LEVEL INCREMENT ROUTINE **\r
116 ** CALLED WITH TYPE OF INCREMENT IN AC, TRASHES Y **\r
117 **         TYPES: 0 = POINTS, 1 = RACKS, 2 = MR. BILL, 3 = SLUGGO **\r
118 INCLVL:\r
119         TAY\r
120         LDA     LVLINC,Y\r
121         LDY     PLAYER\r
122         CLC\r
123         ADC     LEVEL,Y\r
124         CMP     MAXLVL          ;THERE IS ONLY ONE MAX FOR BOTH PLAYERS\r
125         BCC     LVLOK\r
126         LDA     MAXLVL\r
127 LVLOK:\r
128         STA     LEVEL,Y\r
129         RTS\r
130 \r
131 ** RANDOM NUMBER ROUTINES, >NOT< PREVIOUSLY IN RANDOM.S **\r
132 * NEWRAND: A WHOLESOME RANDOM NUMBER JENERATER FROM KNUTH (NOTABLE PEDIGREE)\r
133 NEWRAND:\r
134         LDY     RANDPTR0        ;LOAD Y WITH CONTENTS OF RANDPTR0\r
135         LDA     RAND,Y          ;LOAD AC WITH RAND INDEXED BY Y\r
136         CLC                     ;CLEAR THE CARRY\r
137         LDY     RANDPTR1        ;LOAD Y WITH CONTENTS OF RANDPTR1\r
138         ADC     RAND,Y          ;ADD RAND INDEXED BY Y TO AC\r
139         LDY     RANDPTR0        ;GET THE DRIFT?\r
140         STA     RAND,Y\r
141         DEC     RANDPTR0\r
142         BPL     ZR1\r
143         LDY     #54\r
144         STY     RANDPTR0\r
145 ZR1:\r
146         DEC     RANDPTR1\r
147         BPL     ZR2\r
148         LDY     #54\r
149         STY     RANDPTR1\r
150 ZR2:\r
151         RTS\r
152 \r
153 \r
154 RANDPOS:\r
155         JSR     NEWRAND\r
156         LSR\r
157         BCC     HBORDER\r
158 \r
159         LDA     #YPOSMAX\r
160         STA     YPOSH,X\r
161 XRANDLOP:\r
162         JSR     NEWRAND\r
163         CMP     #XPOSMAX-6\r
164         BCS     XRANDLOP\r
165         STA     XPOSH,X\r
166         RTS\r
167 \r
168 HBORDER:\r
169         LDA     #XPOSMAX\r
170         STA     XPOSH,X\r
171 YRANDLOP:\r
172         JSR     NEWRAND\r
173         CMP     #YPOSMAX\r
174         BCS     YRANDLOP\r
175         STA     YPOSH,X\r
176         RTS\r
177 \r
178 RANDVEL:\r
179         JSR     NEWRAND\r
180         ROL                     ;USE SIGN BIT FOR DIRECTION (L OR R)\r
181         BCC     RNDVXPOS        ;X VELOCITY IS POSITIVE\r
182         SBC     MINXVEL         ;ADD IN MINIMUM VELOCITY\r
183         STA     XVELL,X\r
184         LDA     #$FF            ;VELOCITY IS NEGATIVE\r
185         SBC     #0              ;TAKE AWAY THE BORROW, IF ANY\r
186         STA     XVELH,X\r
187         BCS     RANDVY          ;UNCOND. BRANCH\r
188 RNDVXPOS:\r
189         ADC     MINXVEL         ;ADD IN MINIMUM VELOCITY\r
190         STA     XVELL,X\r
191         LDA     #0\r
192         ROL                     ;ROL IN THE CARRY, IF ANY\r
193         STA     XVELH,X\r
194 \r
195 RANDVY:\r
196         JSR     NEWRAND\r
197         ROL\r
198         BCC     RNDVYPOS\r
199         SBC     MINYVEL\r
200         STA     YVELL,X\r
201         LDA     #$FF\r
202         SBC     #0\r
203         STA     YVELH,X\r
204         BCS     RANDVRTS\r
205 RNDVYPOS:\r
206         ADC     MINYVEL\r
207         STA     YVELL,X\r
208         LDA     #0\r
209         ROL\r
210         STA     YVELH,X\r
211 \r
212 RANDVRTS:\r
213         RTS\r
214 \r
215 \r
216 * CHECK IF ANY OBJECT IS IN SAFETY BOX.\r
217 * RETURNS WITH ZERO (Z) BIT SET IF ALL IS CLEAR.\r
218 * WE DON'T WORRY ABOUT CARRIES (LOW PRECISION).\r
219 * DESTROYS: X, Y, AND FIRST 7 BYTES OF TEMP\r
220 * TEMP LAYOUT:    TEMP              X (OBJECT INDEX)\r
221 *                 TEMP+1                  BOXR (RIGHT HAND BOUNDARY)\r
222 *                 TEMP+2                  BOXL (LEFT HAND BOUNDARY)\r
223 *                 TEMP+3                  BOXTOP (TOP BOUNDARY)\r
224 *                 TEMP+4                  BOXBOT (BOTTOM BOUNDARY)\r
225 *                 TEMP+5                  X WRAP FLAG (1 = WRAP)\r
226 *                 TEMP+6                  Y WRAP FLAG (1 = WRAP)\r
227 \r
228 ISSAFE:\r
229         STX     TEMP            ;SAVE X WHERE IT MAY BE COMPARED TO Y\r
230 \r
231         LDA     #0              ;0 MEANS "NO WRAP OF BOX"\r
232         STA     TEMP+5\r
233         STA     TEMP+6\r
234 \r
235         LDA     XPOSH,X         ;CHECK RIGHT HAND SIDE OF BOX.\r
236         ADC     BOXWIDTH        ; (SHOULD CLC HERE....)\r
237         STA     TEMP+1          ;BOXR\r
238         SBC     #XPOSMAX        ;CHECK FOR WRAPAROUND.\r
239         BCC     BOXROK          ; BOX'S RIGHT HAND SIDE: NO WRAP.\r
240         INC     TEMP+5          ; YES WRAP: SET FLAG\r
241         STA     TEMP+1\r
242 BOXROK:\r
243 \r
244         LDA     XPOSH,X         ;CHECK LEFT HAND SIDE OF BOX.\r
245         SBC     BOXWIDTH\r
246         BCS     BOXLOK          ;CHECK FOR WRAPAROUND.\r
247         INC     TEMP+5          ; YES WRAP: SET FLAG\r
248         ADC     #XPOSMAX        ; MOD INTO RANGE\r
249 BOXLOK:\r
250         STA     TEMP+2          ;  AND SAVE IT (BOXL).\r
251 \r
252 \r
253         LDA     YPOSH,X         ;CHECK TOP OF BOX.\r
254         ADC     BOXHIGHT\r
255         STA     TEMP+3\r
256         SBC     #YPOSMAX\r
257         BCC     BOXTOK\r
258         INC     TEMP+6\r
259         STA     TEMP+3\r
260 BOXTOK:\r
261 \r
262         LDA     YPOSH,X         ;CHECK BOTTOM OF BOX.\r
263         SBC     BOXHIGHT\r
264         BCS     BOXBOK\r
265         INC     TEMP+6\r
266         ADC     #YPOSMAX\r
267 BOXBOK:\r
268         STA     TEMP+4\r
269 \r
270 \r
271         LDX     #32             ;START WITH LAST OBJECT (#32)\r
272 NEXTSAFE:\r
273         LDA     STATUS,X        ;CHECK ITS STATUS:\r
274         BMI     SAFEOK          ; IF OBJECT DOESN'T EXIST, IT IS SAFE.\r
275 \r
276         ;FIRST CHECK X COORDS\r
277         LDA     #0              ;CLEAR OUT COMPARISON REGISTER "A"\r
278         LDY     XPOSH,X         ;GET OBJECT X'S HORIZ. POSITION\r
279         CPY     TEMP+1          ;COMPARE TO BOXR\r
280         ROL                     ;ROL BIT INTO A\r
281         CPY     TEMP+2          ;COMPARE TO BOXL\r
282         ADC     #0              ;ADD BIT INTO A\r
283         EOR     TEMP+5          ;FLIP LOW BIT WITH X WRAP BIT\r
284         ROR                     ;ROR BIT INTO CARRY\r
285         BCC     SAFEOK          ;NO BIT MEANS SAFE (OUTSIDE OF BOX).\r
286 \r
287         ;THEN CHECK Y COORDS\r
288         LDA     #0\r
289         LDY     YPOSH,X\r
290         CPY     TEMP+3\r
291         ROL\r
292         CPY     TEMP+4\r
293         ADC     #0\r
294         EOR     TEMP+6\r
295         ROR\r
296         BCC     SAFEOK\r
297 \r
298         ;FINALLY, CHECK IF IT IS THE OBJECT SPECIFIED ITSELF.\r
299         CPX     TEMP\r
300         BEQ     SAFEOK\r
301 \r
302         ;OBJECT IN BOX!  UNSAFE TO ENTER!\r
303 ;       LDY     #1              ;CLEAR Z BIT TO SIGNIFY NOT CLEAR.\r
304                                 ;NOT NEEDED (BEQ ABOVE)\r
305         RTS\r
306 \r
307 SAFEOK:\r
308         DEX                     ;GET NEXT OBJECT\r
309         BPL     NEXTSAFE        ;AND CONTINUE CHECKING\r
310 \r
311         LDY     #0              ;SET Z BIT TO SIGNIFY ALL CLEAR.\r
312         RTS\r
313 \r
314 BOXWIDTH:\r
315         .DC.B   $10\r
316 BOXHIGHT:\r
317         .DC.B   $1A\r
318 \r
319 * ROUTINE TO PUT UP SCORES.  WHATEVER IS IN PLAYER OR HIGH SCORES GOES. *\r
320 DOSCORE:\r
321         JSR     CLSCORE         ;ERASE ALL SCORES FIRST\r
322 \r
323         JSR     PUTHISCR        ;HIGH SCORE UP\r
324 \r
325         LDA     MODE\r
326         CMP     #1              ;COMBINED SCORE\r
327         BNE     ZPLRSCOR\r
328         LDA     #2\r
329         STA     SCORER\r
330         JSR     PUTSCORE\r
331         JSR     PUTMEN\r
332         LDA     #0\r
333         STA     SCORER\r
334         JSR     PUTSCORE\r
335         LDA     #1\r
336         STA     SCORER\r
337         JSR     PUTSCORE\r
338         RTS\r
339 \r
340 ZPLRSCOR:\r
341         LDA     #0\r
342         STA     SCORER\r
343         JSR     PUTSCORE        ;PLAYER 1 SCORE UP\r
344         JSR     PUTMEN\r
345 \r
346         LDA     MODE\r
347         BMI     NOP2SCOR\r
348         LDA     #1\r
349         STA     SCORER\r
350         JSR     PUTSCORE        ;PLAYER 2 SCORE UP\r
351         JSR     PUTMEN\r
352 \r
353 NOP2SCOR:\r
354         RTS\r
355 \r
356 * ROUTINE TO ERASE SCORES. *\r
357 CLSCORE:\r
358         LDX     #56             ;CLEAR MAPS\r
359         LDA     #0\r
360 ZCLRLOOP:\r
361         STA     CHARMAPS,X\r
362         DEX\r
363 BPLOP:\r
364         BPL     ZCLRLOOP        ;LABLED TO ACCESS BPL OPCODE ($10)\r
365         RTS\r
366 \r
367 ** ROUTINE USED IN GAME LOOP TO TOGGLE PLAYER BACK AND FORTH. **\r
368 FLIPPLAY:\r
369         LDA     PLAYER          ;CHANGE PLAYER\r
370         EOR     #1\r
371         STA     PLAYER\r
372         BEQ     STOROFF         ;ESTABLISH DATA OFFSET\r
373         LDA     #8              ;SECOND PLAYER POINTS TO END\r
374 STOROFF:\r
375         STA     OFFPLAY2\r
376         RTS\r
377 \r
378 * ROTATE THROUGH THE COLORS TO TWINKLE THE STARS.\r
379 TWINKLE:\r
380         JSR     NEWRAND         ;DECIDE WHICH STARS TO TW'INC'LE\r
381         LSR\r
382         BCC     NOINC2\r
383         LSR\r
384         BCC     NOINC2\r
385         INC     SOFTCOLR+14\r
386 \r
387 NOINC2:\r
388         LSR\r
389         BCC     LOGODO\r
390         LSR\r
391         BCC     LOGODO\r
392         INC     SOFTCOLR+15\r
393 \r
394 LOGODO:\r
395         LDA     GAMSTATE        ;DON'T DO LOGOBARS WHILE PLAYING\r
396         CMP     #PLAYST\r
397         BEQ     LOGORTS\r
398         CMP     #AUTOST\r
399         BEQ     LOGORTS\r
400 \r
401 LOGOBARS:\r
402         LDA     FRMCNT          ;DO IT ONLY ON EVEN FRAMES\r
403         LSR\r
404         BCS     LOGORTS\r
405         INC     TEMP+11         ;MOVE THIS!!\r
406         LDA     TEMP+11\r
407         BIT     BPLOP           ;(BPLOP: OPCODE $10 IS BPL)\r
408         BNE     LOGOGO\r
409         EOR     #$1F\r
410 LOGOGO:\r
411         STA     SOFTCOLR+10     ;UPDATE HARDWARE REGISTER\r
412 LOGORTS:\r
413         RTS\r
414 \r
415 \r
416 * SET UP AN ICON:\r
417 *           ON ENTRY: Y SHOULD CONTAIN ICON NUMBER\r
418 *                   X SHOULD CONTAIN INDEX NUMBER OF NEW OBJECT\r
419 DOICON:\r
420         LDA     ICONACYC,Y\r
421         STA     ACYC,X\r
422         LDA     ICONXPOS,Y\r
423         STA     XPOSH,X\r
424         LDA     ICONYPOS,Y\r
425         STA     YPOSH,X\r
426         LDA     ICONPALS,Y\r
427         STA     PALS,X\r
428         LDA     #ICON\r
429         CPY     #22             ;ICONS > 22 ARE SHIPS\r
430         BCC     ZISICON\r
431         LDA     #SHIP\r
432 ZISICON:\r
433         STA     STATUS,X\r
434         RTS\r
435 \r
436 * PAINTSHP -- PAINT THE SHIP, BODY AND DEJAG AND FLAME COLORS\r
437 *           ARGUMENTS: X CONTAINS THE PLAYER TO PAINT\r
438 *               A CONTAINS THE DESIRED LUME OF THE BODY\r
439 PAINTSHP:\r
440         AND     #$0F            ;KNOCK OFF EXTRANEOUS BITS\r
441         ORA     BODYHUES,X      ;OR IN THE CORRECT BODY HUE\r
442         PHA                     ;PUSH BODY COLOR\r
443         LSR                     ;LOWER INTENSITY FOR DEJAG LUME\r
444         AND     #$07            ;KNOCK OFF EXTRANEOUS BITS\r
445         ORA     BODYHUES,X      ;OR IN THE CORRECT BODY HUE\r
446         CPX     #0              ;WHICH PLAYER?\r
447         BEQ     ZPAINTGO        ;FOR 1ST PLAYER, USE 1ST PALETTE\r
448         LDX     #4              ;FOR 2ND PLAYER, USE 2ND PALETTE\r
449 ZPAINTGO:\r
450         STA     SOFTCOLR+3,X    ;STORE DEJAG COLOR\r
451         PLA                     ;PULL BODY COLOR\r
452         STA     SOFTCOLR+2,X    ;STORE BODY COLOR\r
453         LDA     #0              ;TURN OFF SHIP'S THRUST FLAME\r
454         STA     SOFTCOLR+1,X\r
455         RTS\r
456 \r
457 * REFRESH COLOR RAM, UPPER 4 PALETTES FROM ROM, LOWER 4 FROM RAM\r
458 REFRESH:\r
459         LDX     #$1F\r
460 ZEFRESH:\r
461         LDA     COLORS,X\r
462         STA     BACKGRND,X\r
463         DEX\r
464         LDA     COLORS,X\r
465         STA     BACKGRND,X\r
466         DEX\r
467         LDA     COLORS,X\r
468         STA     BACKGRND,X\r
469         DEX\r
470         DEX                     ;SKIP OVER OTHER HARDWARE REGISTERS\r
471         CPX     #$10            ;$10 - $1F FROM ROM (COLORS)\r
472         BCS     ZEFRESH\r
473 * NOW DO RAM PART:\r
474 Z2FRESH:\r
475         LDA     SOFTCOLR,X\r
476         STA     BACKGRND,X\r
477         DEX\r
478         LDA     SOFTCOLR,X\r
479         STA     BACKGRND,X\r
480         DEX\r
481         LDA     SOFTCOLR,X\r
482         STA     BACKGRND,X\r
483         DEX\r
484         DEX                     ;SKIP OVER OTHER HARDWARE REGISTERS\r
485         BPL     Z2FRESH\r
486         INX                     ;$FF + 1 = $00\r
487         STX     BACKGRND        ;FORCE BLACK BACKGROUND\r
488         RTS\r
489 \r
490 WAITLOAD:\r
491         LDA     #1              ;SET LOAD FLAG\r
492         STA     LOADFLAG\r
493 ZWAIT:\r
494         LDA     LOADFLAG        ;WAIT FOR LOADER TO FINISH\r
495         BEQ     ZWRTS           ;IF LOADER FINISHED THEN RTS\r
496         BIT     MSTAT           ;IF OFF SCREEN FORCE LOAD\r
497         BPL     ZWAIT\r
498         BIT     MSTAT           ;PROTECTION\r
499         BPL     ZWAIT\r
500         JSR     REFRESH         ;MAKE SURE COLORS ARE RIGHT FIRST\r
501         JSR     LOADER\r
502 ZWRTS:\r
503         RTS\r