This repository has been archived by the owner on Oct 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathMAIN.S
959 lines (711 loc) · 29.3 KB
/
MAIN.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
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
* MAIN.S
* THIS FILE IS FILLED WITH CRITICAL USEFUL ROUTINES.
; "STARTUP"-- COMES HERE ON POWERUP
; "POWERUP"-- HANDLES ALL ONE-TIME MEMORY INITIALIZATION
; "NEWGAME"-- CALLED TO INITIATE A NEWGAME FROM ANOTHER MODE
; "NEWRACK"-- CALLED WHEN A GAME RACK HAS JUST ENDED
; "GAME"-- CALLED FROM "GOD" WHEN MODE==MGAME
; "REPLAY"-- USED TO READ CONTROLLER VALUES FROM REPLAY TABLES
; "GAMEINIT"-- CALLED FROM "NEWGAME" TO DO ONE-TIME GAME STUFF
; "COLRINIT"-- SETS ALL PALETTES TO NORMAL GAME PALETTES
; ALL DLI HANDLERS FOR GAMEPLAY DISPLAY LISTS
;
GLBL NUMCHHIT,LASTPILE
GLBL MKPROMPT
GLBL GOD
GLBL STATDISP
GLBL GODPTR
GLBL SETMAPS
GLBL AWOLDRAW
GLBL CHUCK
GLBL CHEFMOVE
GLBL FOODMOVE
GLBL ICEMELT
GLBL FOODHIT
GLBL PILEHIT
GLBL HOLEHIT
GLBL CONEHIT
GLBL CHEFHIT
GLBL SCRAPALL,TUNIN
GLBL WAIT ; IN "FOODMOVE"
GLBL COLRINIT,NEWGAME
GLBL CLEARALL ; IN "LOGO.S"
GLBL GAME
GLBL PAUSE
GLBL DLLCOPY
GLBL DPPINIT,DPPSTORE
GLBL NMIRTN ; FROM "HISCORE.S"
GLBL GLCONT21
GLBL MPAUSE
GLBL REPLAY,DOGAME,NEWRACK
GLBL GAMEINIT
GLBL MKHISCOR
GLBL PREFRESH
GLBL RANDSEED,RANDK,RANDJ
GLBL HIGHSCOR,M160X2,MKLOGO
GLBL M320X1
GLBL TRUE,LOGO,FALSE
GLBL CHARINIT,RACKINIT,STATWON
GLBL STATDIE,STATBON,STATDIEH,STATINIT,STATWAIT,DEAD,WON
GLBL STATEND
GLBL STATENDR
GLBL PL0RACK,PL1RACK,PL0LIVES,PL1LIVES,PL0SCORE,PL1SCORE
GLBL PL0FIRST,PL1FIRST
GLBL PL0IRTIM,PL1IRTIM
GLBL PL0BONUS,PL1BONUS
GLBL PL0BCD,PL1BCD
GLBL PL0CARRY,PL1CARRY,CMAP1
GLBL CMAPHIGH,CMAP2,CLOWMAP1,CLOWMAP2,NULL2,NULLCHAR
GLBL PUTSCORE,BACKCOLR,STATLOGO
GLBL DLIST0,DLIST1,DLIST2,DLIST3,DLIST4,DLIST5,DLIST6
GLBL DLIST7,DLIST8,DLIST9,DLIST10
GLBL DLISTA,DLISTB
GLBL STATLIST,SCORELST
GLBL FINFO,POLE,TUNER,MLOADER
GLBL DLLRAM
GLBL MLOGO,MGAME,MATTRACT,MBLANK
GLBL MTEXT,MSELECT
GLBL CDIR
GLBL IRDIRA,IRDIRB,IRTHROW
GLBL IRDIRC,IRDIRD
GLBL AIRDIRA,AIRDIRB,AIRDIRC,AIRDIRD,AIRTHROW
GLBL ASET
GLBL IRTNDONE
GLBL DRIPTIME
GLBL DLI1,DLI4
GLBL COLORROM,COLORS,LISTTABL,LISTTABH,TOPZONE,DLLROM
GLBL SWLIST,NULLLIST,JOYTABLE,TRUEBUT
GLBL DIRTABL,DIRTABH,ADIRTABL,ADIRTABH,RACKWORD
GLBL FOODSTUF,FOODWORD
RAMDEF ; ZERO PAGE
ORG $FFF8
DB $FF,$E7 ; ADDRESSES START AT $A000
DB L(NMIVEC),H(NMIVEC) ; GO HERE FOR DLI
DB L(STRTHERE),H(STRTHERE) ; GO HERE ON RESET
DB L(NOTNMI),H(NOTNMI) ; SO THAT I CAN INITIATE A DLI
; FROM SOFTWARE
ORG $EFFA
STRTHERE JMP STARTUP
NOTNMI RTI
RSEG CODE1 ; WILL BE SET TO B000
; THE FOLLOWING BODY OF CODE IS THE POWER UP INITIALIZATION:
STARTUP SEI ; PERMANENT
MOVE #7,$01 ; LOCKS THE BASE UNIT INTO 3600 MODE
MOVE #$7F,CTRL color is on
CLD ; ALWAYS CLEARED
LDA #0 ; MAKE SURE BUTTONS WILL WORK
STA CTLSWA
STA CTLSWB
STA OFFSET ; OLD LOCATION OF "OFFSET"
; CAN'T USE "JSR" SINCE THIS ROUTINE ZEROS THE STACK
LDX #$FF ; STACK IN TOP OF ZERO PAGE
TXS ;SET STACK POINTER
JMP ZERORAM
ZRAMRTN
JSR SCRAPALL ; INITIALIZE SOUND
JSR COLRINIT ; INITIALIZE COLORS BEFORE LOGO
JSR POWERUP ; SETS DLL AND CTRL (STARTS DMA)
JMP MKLOGO ; THIS RETURNS TO "GOD"
********************************************************************************
; JMP HERE ANYTIME WE'RE ABOUT TO START A GAME.
; RESET THE STACK POINTER.
; FIRST OF ALL, MAKE SURE THAT THE FIRST DLIST DOESN'T SET THE WRITE MODE,
; SINCE THIS WILL HAPPEN ONCE IN THE VERY FIRST DLI1 AFTER POWERUP.
NEWGAME INC GAMECNT
LDX #$FF
TXS
MOVE #MGAME,MODE
NEWSTATE GAME
MOVE #FALSE,RUNLOAD
JSR CLEARALL ; IN LOGO.S
JSR SCRAPALL ; NO TUNES, PLEASE !
; ZERO OUT PLAYER SCORES BEFORE A NEW GAME--
LDA #0
LDX #3
ZGILP01 STA PL0SCORE,X
STA PL1SCORE,X
DEX
BPL ZGILP01
JSR GAMEINIT ; SETS APPROPRIATE VARIABLES
; JSR AWOLDRAW ; CALLED WHEN "SELECT" EXITS
JSR COLRINIT ; NECESSARY SINCE LOGO AND HISCORE
; CHANGE THE PALETTES
JSR CHARINIT ; SET UP THE RACK, FIRST TIME !
; THIS MEANS THERE'S NO NEED
; TO TEST FOR END OF GAME, WHICH
; "RACKINIT" DOES.
; JSR DPPINIT DMA turned on in HERODRAW
MOVE #TRUE,RUNLOAD
ENDCYCLE
; JSR HERE FOR A NEW RACK
NEWRACK
MOVE #FALSE,RUNLOAD ;Must be off after hero displays
;while fixed stuff initializes
JSR RACKINIT ; INITIALIZE EVERYTHING
; DMA is turned on there
MOVE #TRUE,RUNLOAD
RTS ; LET GOD PROCESS "GAME"
; THIS ROUTINE IS CALLED FROM GAME IF PERCHANCE CHARLIE CHUCK WERE TO DIE
; ON AN INSTANT REPLAY. BUT, AS WE ALL KNOW THIS IS IMPOSSIBLE (?).
IRDEATH MOVE #FALSE,DOITOVER
JSR SCRAPALL
LDA #27 ; PLAY FREE MAN TUNE.
JSR TUNIN
LDX CURRENT
INC PL0LIVES,X
INC PLLIVES
JSR STATDISP ; GIVE EXTRA C.C. & DISPLAY
LDA #4
JSR MKPROMPT
MOVE #WON,CSTATE
MOVE #TRUE,DOITOVER
JMP SKIPSKIP
; THIS ROUTINE IS CALLED FROM "GOD" IF WE'RE IN GAMEPLAY MODE.
; FIRST TEST TO SEE IF THIS IS THE WAIT AT THE END OF THE RACK-
GAME LDA STATUS
CMP #STATENDR
BNE GAME99 ; NOT A REPLAY
LDA CSTATE
CMP #DEAD ; DID CHUCK DIE IN IR ???
BEQ IRDEATH
LDA IRTNDONE ; IF FALSE, KEEP WAITING
BEQ GAME98
LDA DOITOVER
BPL SKIPTAG ; NOT AN IR TUNE
JSR SCRAPALL ; GET RID OF IR TUNE
MOVE #FALSE,DOITOVER ; SO THAT "TUNIN" FUNCTIONS
LDA #31 ; TAG AT END OF IR TUNE
JSR TUNIN
LDA #32
JSR TUNIN
MOVE #TRUE,DOITOVER
BNE SKIPSKIP a jump
SKIPTAG JSR SCRAPALL
SKIPSKIP MOVE #STATEND,STATUS ; SO THAT THIS CODE WILL WAIT
; FOR "WAITCNT" CYCLES
BPL GAME98 a jump
GAME99 CMP #STATEND ; END OF RACK BUT EITHER NOT REPLAY,
BNE GAME90 ; OR AFTER END OF REPLAY TUNE
DEC WAITCNT
BEQ GAME91
GAME98 JSR CHEFMOVE ; KEEP THEM REJOICING
ENDCYCLE
GAME91 JMP GLCONT21 ; END OF GAME ROUTINE TESTS
; TEST TO SEE IF I SHOULD GO INTO "PAUSE" MODE.
GAME90 LDA FPPAUSE ; TEST FOR PAUSE FIRST THING !
BEQ GAMEON1
GAME00 LDA PSREADY
BEQ GAMEON1 ; IF NOT READY, THEN GO AHEAD
; IF I REACH HERE, IT'S TIME TO GO INTO PAUSE MODE:
LDA #0
STA AUDV0
STA AUDV1
STA SYSCOUNT 18 minute timer
STA SYSCOUNT+1
STA PSREADY "FALSE" = 0
MOVE #MPAUSE,MODE
NEWSTATE PAUSE
ENDCYCLE
; Poll the select and reset buttons. Don't do this if the GAME OVER message
; is displayed.
; LDA MODE
; CMP #MTEXT
; BNE GAMEON1 not a message
; LDA TEMP4
; BNE GAMEON non-zero means GAME OVER message
GAMEON1 LDA FPSELECT
BEQ GAMEON2 ; BUTTON NOT PUSHED
LDA SELREADY ; IGNORE BUTTON UNLESS IT'S READY
BEQ GAMEON2
JMP MKLOGO
; TEST THE RESET BUTTON TO SEE IF I SHOULD START A NEW GAME--
GAMEON2 LDA FPRESET
BEQ GAMEON
LDA RESREADY
BEQ GAMEON
MOVE #FALSE,RESREADY
JMP NEWGAME
; SET THE "SOFT" CONTROLLER VALUES. THESE WILL
; BE COPIED FROM (1) THE "HARD" VALUES IF NOT INSTANT REPLAY;
; (2) THE INSTANT REPLAY TABLES IF THIS IS AN INSTANT REPLAY.
; ONLY DO THIS ON EVEN NUMBERED CYCLES, SO THAT I CUT THE RAM NEEDED
; FOR INSTANT REPLAY IN HALF.
; Change: only do this on every 4th cycle, to aid the diagonal problem
; and to cut IR RAM even more.
; IN EACH 60TH OF A SECOND, "NUMCYCLE = 1" ONLY ONCE.
GAMEON LDA NUMCYCLE ; MAKE SURE THAT TIMERS ARE STILL
CMP #1 ; BASED ON REAL (INTERRUPT) TIME
BNE SKIPINC
INC CYCLECNT ; MAKE SURE THIS IS ONLY ONCE
; PER FRAME
DEC DRIPTIME ; ICE CREAM CONE TIMER FOR ANIMATION
DEC SYSCOUNT ; GENERAL PURPOSE SYSTEM COUNTER
LDA CYCLECNT every even frame, update timer
LSR A
BCC NOFINFO
DEC FINFO cone timer
SKIPINC JMP DOGAME
NOFINFO LSR A every fourth frame, update direction
BCS SKIPINC and button values
; ONCE WE REACH HERE, EVERYTHING THAT FOLLOWS IS BEING EXECUTED ONCE
; EVERY FOUR FRAMES, REGARDLESS OF "MAXCYCLE"
GLCONT10 LDA DOITOVER
BNE DOREPLAY
MOVE HJOYDIR,JOYDIR
MOVE HTHROW,THROWBUT
; NOW SAVE AWAY VALUES IN THE INSTANT REPLAY TABLES :
; NOTE: DIRTAB CONTAINS POINTERS TO THE FOUR DIRECTION TABLES.
; EACH ONE OF THESE HAS 128 LOCATIONS, ACCOUNTING FOR 256
; VALUES OF CYCLEIDX; THIS REPRESENTS 8 SECONDS OF GAMEPLAY.
; CHANGED: each one now has 64 locations, accounting for 128 values
; of CYCLEIDX; this still represents 8 seconds of gameplay.
; 128 values of CYCLEIDX represents 128 x 4 cycles, or 512.
LDX CYCLEIDX+1
LDA DIRTABL,X
STA TEMP0
LDA DIRTABH,X
STA TEMP1
LDA CYCLEIDX
LSR A ; GET INDEX AS WELL AS NIBBLE
TAY
BCC ZUPNIB01 ; EVEN FRAME == UPPER NIBBLE
LDA (TEMP0),Y
ORA JOYDIR ; UPPER NIBBLE ALREADY IN A
STA (TEMP0),Y
JMP ZINSKIP1
ZUPNIB01 LDA JOYDIR
ASL A ; THIS ALSO ZEROS OUT THE VALUE
ASL A ; FROM THE LAST IR
ASL A
ASL A ; PUT INTO UPPER NIBBLE
STA (TEMP0),Y
; JOYSTICK STORAGE IS FINISHED-- DO THE BUTTON STORAGE
ZINSKIP1 LDA THROWBUT ; IF THE BUTTON IS UP, LEAVE A
BEQ POLLOVER ; ZERO IN THE BIT FOR THIS CYCLE
LDA CYCLEIDX
AND #$7 ; TELLS WHICH BIT OF IRTHROW
TAY
LDX THROWIDX ; INC'ED EVERY EIGHTH CYCLE
LDA TRUEBUT,Y ; SETS PROPER BIT
ORA IRTHROW,X ; ADDS IN THIS NEXT BIT
STA IRTHROW,X
JMP POLLOVER
DOREPLAY JSR REPLAY
; ONLY INCREMENT "CYCLEIDX" AND "THROWIDX" FOR CYCLES WHERE THE IR TABLES
; ARE WRITTEN TO.
POLLOVER INC CYCLEIDX each table holds $40 bytes, or
BPL ZDOGAME0 $80 values of CYCLEIDX
INC CYCLEIDX+1 ; GO TO NEXT BLOCK OF STORAGE
LDA #0
STA CYCLEIDX
ZDOGAME0 LDA CYCLEIDX
AND #$07
BNE DOGAME
INC THROWIDX ; INCREMENT EVERY 8 TIMES
; NOW WE'RE FINALLY DOING REAL GAMEPLAY !
; NOTE: FOR FINAL VERSION, FOR SPEED, TAKE OUT THESE "STATUS" TESTS
; AND CHANGE THE "RTS" IN THE ROUTINES WHICH SET STATUS TO
; POP THE STACK AND JMP TO A LOCATION HERE (GLCONT00, FOR EXAMPLE)
DOGAME
JSR CHUCK ; ALWAYS DO THESE
JSR CHEFMOVE
JSR FOODMOVE
LDA STATUS
CMP #STATWON ; NO INTERSECTS OR FOOD IF HE'S EATING
BEQ GLCONT00
JSR ICEMELT call this unless he's won. I can't
; place this call below because
; ICEMELT must be called even if the
; STATUS is STATDIEC
LDA STATUS
CMP #STATBON ; IF FOOD IS FLYING TO SCORE
BEQ GLCONT00
JSR FOODHIT ; IF FOOD IS FLYING AT SCORE
LDA STATUS
CMP #STATDIEH
BPL GLCONT00 ; ALL DEATH STATES ARE >= STATDIEH
CMP #STATINIT
BEQ GLCONT00
CMP #STATWAIT ; DON'T DO INTERSECTS IF CHEFS ARE
BEQ GLCONT00 ; RISING
JSR PILEHIT
JSR HOLEHIT
JSR CHEFHIT
JSR CONEHIT
; DON'T DO THE FOLLOWING TESTS IF WE'RE SUPPOSED TO BE WAITING BEFORE A RAKC
; END:
GLCONT00 LDA STATUS
CMP #STATEND
BNE GLCONT21
ENDCYCLE
; HERE I'LL NEED TO INSERT TESTS TO SEE IF THE RACK HAS ENDED:
; 1) TEST TO SEE IF CONE HAS MELTED;
; 2) TEST TO SEE IF HERO HAS REACHED THE CONE;
; 3) TEST TO SEE IF HERO HAS DIED.
; IF THE RACK HASN'T ENDED, CONTINUE THE MAIN GAME LOOP.
; NOTE: THIS MIGHT BE AN ATTRACT MODE. IF THE GAME ENDS, AND
; THIS IS AN ATTRACT MODE, THEN GO STRAIGHT TO THE HISCORE
; MODE BY CALLING "MKHISCOR" IN THE FILE "HISCORE.S"
GLCONT21 LDA CSTATE ; HERO'S STATE
CMP #DEAD
BNE GLCONT01
LDA MODE
CMP #MATTRACT
BEQ GLCONT20
GLCONT02 JSR NEWRACK
GLCONT03 ENDCYCLE
GLCONT20 JMP MKLOGO
GLCONT01 CMP #WON
BNE GLCONT03
; If we get here, we know the rack has ended, through either death or
; munching. If it's auto play, just go to the logo; else,
; do a new rack.
LDA MODE
CMP #MATTRACT
BEQ GLCONT20
BNE GLCONT02 a jump
; THIS ROUTINE IS CALLED FROM "NEWGAME" TO ZERO ALL OF RAM
ZERORAM
LDA #0
LDX #$00
ZM000 STA $00,X ; ZEROS OUT THE ZERO PAGE
DEX
CPX #$40 ; STOPS AT MARIA REGISTERS
BCS ZM000
; ZERO OUT THE FIRST PAGE
; Removed-- First Page only used for STACK
AZMFP LDA #H(LASTPILE) ; ZERO OUT MEMORY THAT WAS IN FIRST
STA $FF ; PAGE BEFORE IT WAS MOVED TO $2660-92
LDY #L(LASTPILE)
LDA #$00
; STA $FE ; THIS WAS ZEROED OUT ABOVE
ZMFP STA ($FE),Y
DEY
CPY #L(NUMCHHIT)
BCS ZMFP
; NOW ZERO OUT THE REST OF RAM, USING COUNTERS IN THE ZERO PAGE.
; ZERO OUT 1800-2000
; STA $FE ; USE THIS LOCATION BECAUSE
LDA #$18 ; IT'S NOT SHADOWED HIGHER UP
LDX #$08 ; 8 PAGES FROM 1800-2000
JSR ZMSUB
; NOW ZERO OUT 2200-2800 (6 PAGES)
; STA $FE ; USE THIS LOCATION BECAUSE
LDA #$22 ; IT'S NOT SHADOWED HIGHER UP
LDX #$06 ; 6 PAGES FROM 2200-2800
JSR ZMSUB
JMP ZRAMRTN
ZMSUB STA $FF
LDA #0
TAY
ZM999 STA ($FE),Y
DEY
BNE ZM999
INC $FF
DEX
BNE ZM999
RTS
DLLCOPY LDX #56 ; COPIES 57 BYTES-- 19 ENTRIES
ZPUPLOOP MOVE DLLROM,X,DLLRAM,X
DEX
BPL ZPUPLOOP
RTS
POWERUP
MOVEPTR DLI1,DLIADR ; SETUP FOR FIRST NMI INTERRUPT
JSR DLLCOPY ; GET DLLRAM CORRECT
LDX #0
STX PLAYNUM ; ONE PLAYER
STX ASET no instant replay tables yet
STX FOODSTUF
INX
STX HOWHARD ; MEDIUM DIFFICULTY
LDA #15 highest level allowed
STA HIGHEST is level 16
STA HIGHEST+1
LDX #6 make sure hero starts facing left
STX HJOYDIR
STX JOYDIR center the joystick for first game
; This loop starts with X = 6
ZPUPLP2 MOVE SWLIST,X,DLISTA,X ; COPY SWLIST AND NULLLIST
DEX
BPL ZPUPLP2
LDA #TRUE
STA PSREADY
STA RESREADY
STA SELREADY
; JMP DPPINIT same as JSR followed by RTS
; TURN DMA BACK ON AFTER SETTING DPPH
DPPINIT BIT MSTAT ; FIRST WAIT FOR ON-SCREEN
BMI DPPINIT
DPPINIT0 BIT MSTAT ; NOW WAIT FOR VBLANK
BPL DPPINIT0
DPPSTORE LDA #L(DLLRAM)
STA DPPL
LDA #H(DLLRAM)
STA DPPH
MOVE #M160X2,CTRL ; TURN DMA BACK ON, CORRECT VALU
RTS
GAMEINIT
LDX #0
STX PL0RACK
STX PL1RACK
STX PL0BONUS
STX PL0BONUS+3
STX PL1BONUS
STX PL1BONUS+3
STX PL0CARRY
STX PL1CARRY
STX PL0BCD
STX PL1BCD
STX PL0IRTIM
STX PL1IRTIM
STX CURRENT
DEX TRUE is $FF
STX PL0FIRST
STX PL1FIRST
INX level 1 is first
INX
STX PL0BCD+1
STX PL1BCD+1
INX bonus at 25000
STX PL0BONUS+1
STX PL1BONUS+1
INX three lives
STX PL0LIVES
STX PL1LIVES
LDA #$50 ; BCD FOR 50
STA PL0BONUS+2
STA PL1BONUS+2
LDX #0
LDA PLAYNUM
BEQ GI0010
INX
GI0010 STX OTHER
LDX #FALSE
STX DOITOVER ; FIRST RACK ISN'T INSTANT REPLAY
; PICK SOME RANDOM SEEDS:
LDA FRAMECNT ; WAS LDA #$33
STA RANDOM0
LDA CYCLECNT ; WAS LDA #$44
STA RANDOM1
ADC #55 ; WAS LDA #$55
STA RANDOM2
MOVE #$E8,CHARBASE ; SAME FOR NUMBERS AND HEADS
GIBYE RTS
; ALSO CALLED FROM "INIT.S" BEFORE THE FIRST LEVEL
SETMAPS MOVE #L(CMAP1),SCORELST ; PLAYER 1 SCORE
MOVE #$60,SCORELST+1
MOVE #H(CMAP1),SCORELST+2
MOVE #$B8,SCORELST+3 ; PALETTE 5, WIDTH 8
MOVE #08,SCORELST+4 ; HPOS
MOVE #L(CMAP2),SCORELST+5 ; PLAYER 2 SCORE
LDX #0
LDA PLAYNUM ; IF TRUE, THEN TWO PLAYER
BEQ ZGI022 ; IF FALSE
LDX #$60
ZGI022 STX SCORELST+6
MOVE #H(CMAP2),SCORELST+7
MOVE #$B8,SCORELST+8 ; PALETTE 5, WIDTH OF 8
MOVE #96,SCORELST+9 ; PLAYER 2 SCORE
LDY #00 keep 0 in Y for awhile
STY SCORELST+11 ; END OF LIST FLAG
LDX #$60 keep 60 in X
; SET UP CHARACTER MAPS FOR THE BOTTOM HALF ZONE (EXTRA LIVES HEADS):
MOVE #L(CLOWMAP1),STATLIST
STX STATLIST+1
MOVE #H(CLOWMAP1),STATLIST+2
MOVE #$0F,STATLIST+3 ; HERO PALETTE, WIDTH 17
MOVE #$5C,STATLIST+4 ; FLUSH WITH RIGHT BORDER
MOVE #L(CLOWMAP2),STATLIST+5
STX STATLIST+6
MOVE #H(CLOWMAP2),STATLIST+7
MOVE #$8E,STATLIST+8 ; PALETTE 4 (TOMATO), WIDTH 18
STY STATLIST+9 ; Y still has 0
STY STATLIST+11 ; END OF LIST
LDY #59
LDA #NULL2
ZCMINIT STA CMAP1,Y ; ALL NULL CHARACTERS
DEY
BPL ZCMINIT
; COPY THE INFORMATION FOR THE WORD "LEVEL" INTO "CLOWMAP2"
MOVEPTR RACKWORD,TEMP0
LDA FOODSTUF
BEQ NOFOODW
MOVEPTR FOODWORD,TEMP0
NOFOODW LDY #9
ZCMINIT0 LDA (TEMP0),Y
STA CLOWMAP2,Y
DEY
BPL ZCMINIT0
LDA CURRENT
ASL A
ASL A
TAY
JSR PUTSCORE ; DISPLAY SCORE FOR CURRENT PLAYER
LDA PLAYNUM
BEQ SMBYE
LDA OTHER
ASL A
ASL A
TAY
JSR PUTSCORE ; DISPLAY SCORE FOR OTHER PLAYER
SMBYE RTS
; Copies the table COLORROM into COLORS
COLRINIT
LDX #31
ZCLRLOOP LDA COLORROM,X
STA COLORS,X
DEX
BPL ZCLRLOOP
RTS
; refreshes the palettes every frame
PREFRESH
LDX #0
STX BACKGRND
ZCLR01 LDY #2
ZPRLOOP LDA COLORS,X
STA P0C1,X
INX
DEY
BPL ZPRLOOP
INX
CPX #31
BMI ZCLR01
RTS
NMIVEC PHA
TYA
PHA
TXA
PHA
CLD just in case decimal is set
JMP (DLIADR)
NMIRTN PLA
TAX
PLA
TAY
PLA
IRQVEC RTI
; ALL OF THE NMI HANDLERS FOLLOW.
DLI1 MOVEPTR DLI2,DLIADR ; SETUP FOR SCORE DLIST
MOVE #$E8,CHARBASE
MOVE #$50,CTRL ; 160X2, 2 BYTE CHARACTERS
; Setup palette 5 for the score:
MOVE #$19,P5C1 ; COLORS FOR TEXT (YELLOW)
MOVE #$15,P5C2
MOVE #$1F,P5C3
JMP NMIRTN
DLI2 STA WSYNC wait for end of scan line before
;changing color of score palette
MOVEPTR DLI3,DLIADR ; AFTER SCORE, BEFORE PLAYFIELD
STA WSYNC
; If the rack is in progress, use the banana colors here UNLESS the food
; is hitting the score with the bonus points displayed.
; Else, text is displayed; if TEMP4 is $80 it's an Instant Replay message
; and should cycle through all colors.
; If it's any other message, keep the palette as it was for score display.
LDA MODE
CMP #MGAME
BEQ BARF1
CMP #MATTRACT
BEQ BARF1
LDA TEMP4
CMP #$80
BNE NOFLASH
LDA TEMP5
STA P5C1
STA P5C2
STA P5C3
JMP NMIRTN
BARF1 MOVE #$13,P5C1 ; restore banana colors
MOVE #$18,P5C2
NOFLASH JMP NMIRTN if not IR, same colors as score text
DLI3 MOVE #M160X2,CTRL ; 1-BYTE CHARACTERS
MOVEPTR DLI4,DLIADR ; OCCURS RIGHT AFTER PLAYFIELD
; SO THAT LOADER CAN START DURING
; STATUS ZONE DISPLAY
; just moved all this from DLI4 to give the loader the extra 8+24 scan lines
; of off-screen time
INC FRAMECNT
LDA FRAMECNT
LSR A
BCC DONTLOAD
BIT RUNLOAD
BPL DONTLOAD ; IF SET TO "FALSE"
JSR MLOADER
DONTLOAD
JSR TUNER ; SOUND DRIVER
JMP NMIRTN
DLI4 STA WSYNC
LDA SWCHB ;;; TEMP FOR BREAKPOINT DETECTION
STA WSYNC
STA WSYNC ; NOW SHOULD BE IN VBLANK
JSR PREFRESH refresh the palettes and background
; IF MSTAT IS NEGATIVE, WE'RE IN VBLANK
DLI4TEST BIT MSTAT ; RETURN HERE UNTIL I GET TWO
BMI DLI4TST1 ; IDENTICAL VALUES
BIT MSTAT ; IF WE'RE NOT IN VBLANK, DON'T
BPL DLI4BYE ; CHANGE THE NMI VECTOR
JMP DLI4TEST ; IF WE DON'T GET THE SAME TWICE
DLI4TST1 BIT MSTAT ; IF WE DON'T GET THE SAME TWICE
BPL DLI4TEST
; ELSE, WE'RE IN VBLANK-- ALL IS WELL. RESET "DLIADR"
MOVEPTR DLI1,DLIADR
DLI4BYE JMP NMIRTN
; CALL THIS ROUTINE FROM BOTH "GAME" AND "ATTRACT"
; This routine will use a different set of tables
; if ASET is non-zero and the mode is ATTRACT. These tables
; should represent the last instant replay.
;
; ASET==0 : no tables; just go left
; ASET!=0 : use AIR tables
; this routine should not be called from ATTRACT unless ASET is not
; zero
REPLAY LDX CYCLEIDX+1
LDA MODE if not attract, use last IR
CMP #MATTRACT
BNE RGAME00
LDA ASET if ASET is 0, then just go
BNE DOAIR left
JMP RPBYE
DOAIR LDA ADIRTABL,X last completed instant replay
STA TEMP0
LDA ADIRTABH,X
STA TEMP1
JMP RGAME01
RGAME00 LDA DIRTABL,X this is an instant replay, or the
STA TEMP0 last death
LDA DIRTABH,X
STA TEMP1
RGAME01 LDA CYCLEIDX
LSR A
TAY
BCC ZUPNIB02
LDA (TEMP0),Y ; LOWER NIBBLE
AND #$0F
JMP ZSETD02
ZUPNIB02 LDA (TEMP0),Y
LSR A
LSR A
LSR A
LSR A
ZSETD02 STA JOYDIR
LDA CYCLEIDX
AND #7
TAY
LDA TRUEBUT,Y
LDX THROWIDX
LDY ASET Use the A tables if ASET and in
BEQ ZSETD001 attract mode
LDY MODE
CPY #MATTRACT
BNE ZSETD001
AND AIRTHROW,X
JMP ZSETD003
ZSETD001 AND IRTHROW,X
ZSETD003 BEQ ZNOTHROW ; IF 0, BUTTON IS UP
LDA #TRUE
JMP ZRPSETB
ZNOTHROW LDA #FALSE
ZRPSETB STA THROWBUT
RPBYE RTS
END