* 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