* 2100 030784 * * ** MAIN.S ** ** ASTEROIDS FOR THE ATARI 3600 * ** THIS FILE CONTAINS THE MAIN DRIVER. ** .ORG $D000 ;MUST BE ON ODD (BLANK HOLY DMA) 4K PAG CODE: ASTEROID: SEI ;AND AWAY WE GO..... CLD LDA #$13 ;LOCK INTO MARIA MODE, base unit rom ; *AND* DISCHARGE PADDLE INPUT CAPS STA PTCTRL ;STORE TO INPTCTRL LDX #$FF ;SET UP THE STACK POINTER TXS LDX #$60 STX CTRL ;OFF DMA LDA #$14 ;SET JOYSTICK DIRECTION REGISTER STA CTLSWB ;TO SELECT TWO BUTTON MODE LDA #0 STA BACKGRND ;BLACK BACKGROUND STA OFFSET ;FOR FUTURE EXPANSION STA SWCHB ;SELECT TWO BUTTON MODE ; JSR ZERORAM ;ZERO OUT RAM LDA INTIM ;SEED RANDOM PTRS FROM TIMER AND #31 ; ROUGHLY RANGE IT (NOTE: PTR1 MAY GO STA RANDPTR0 ; OUT OF RANGE HERE, BUT IT'S OK AS CLC ; LONG AS PTR0 DOESN'T GO OUT OF RANGE) ADC #31 ;31 IS A GOOD NUMBER FOR THIS STA RANDPTR1 LDX #54 ;DROP SOME CODE IN TO INIT RAND ARRAY DROPCODE: LDA CODE,X ;CODE IS PRETTY RANDOM. STA RAND,X ;AT LEAST OURS IS. DEX BPL DROPCODE LDA #1 ;SET UP MODE/DIFF STA DIFF STX MODE * JSR HSCSUCK ;SUCK IN HIGH SCORE, IF POSSIBLE JSR INITSCOR ;INITIALIZE SCORES JSR LOADSTAR LDA #$00 ;UNLOCK DISCHARGE TRANSISTOR FROM STA $0001 ; PADDLE INPUT CAPS. LDA #TITLEST ;INITIALIZE GAME STATE ;FALL THROUGH INTO.... * PROGRAM DRIVER STATE CHANGER: JMP HERE WITH NEW GAME STATE IN AC. NEWDRVR: STA GAMSTATE LDX #$FF ;MASH OUT THE STACK POINTER TXS INX ;INITIALIZE DTIMER ; ; LDX #0 ; STX DTIMER STX DTIMER+1 JSR INITPALS ;PUT UP STANDARD COLORS JSR CLEARTUN ;CLEAR OUT ALL TUNES JSR NULLOBJS ;NULL OUT ALL OBJECTS. JSR WAITLOAD ;WAIT FOR LOADER TO UPDATE JSR INITDMA ;BUILD DLLS FOR MARIA2 ; AND STARTS DMA DURING VBLANK ;FALL THROUGH INTO.... * PROGRAM DRIVER: NEEDED TO HANDLE THE VARIOUS PROGRAM STATES. DRIVER: LDA FRMCNT ;INSURE THAT FRMCNT IS EVEN HERE AND #$FE STA FRMCNT LDA GAMSTATE ; FRAME COUNT AIN'T INC'ED DURING HSC CMP #HSCST BEQ PASTINCF FRAMSYNC: LDA FRMCNT ;MAKE SURE AT LEAST ONE FRAME HAS SEC ; GONE BY SINCE LAST FRAME SYNCH. SBC LASTFRMC CMP #2 BCC FRAMSYNC LDA FRMCNT STA LASTFRMC ;UPDATE LAST FRAME COUNT PASTINCF: INC DTIMER+1 ;INCREMENT THE TWO BYTE TIMER BNE ZZNOINC9 INC DTIMER ZZNOINC9: JSR CKJOY ;GET FRESH JOYSTICK INPUTS. JSR CKBUTS ;GET FRESH BUTTON INPUTS (DEBOUNCED). JSR TWINKLE ;TWINKLE STARS ETC. LDA GAMSTATE ;CHECK GAME STATE CMP #PLAYST ;GAMEPLAY STATE BEQ PLAYD CMP #AUTOST ;AUTO PLAY STATE BEQ AUTOD CMP #MENUST ;MENU STATE BEQ MENUD CMP #TITLEST ;TITLE STATE BEQ TITLED CMP #HSCST ;HIGH SCORE CART STATE BEQ HSCD BNE DRIVER ;SAFETY TO PREVENT GOING ASTRAY ;NOT NEEDED IF WORKS PROPERLY SINCE ;MUST BE IN ONE OF THE ABOVE STATES. ** DRIVER DISPACHER ROUTINES. ** ** TITLE PAGE STATE DISPACHER - HANDLES TIMING DURING TITLE PAGE. ** TITLED: LDA FIREBUT2 BMI HESDEAD LDX #$FF STX TURKEY DEX STX CHICKEN HESDEAD: LDA SWCHBITS AND #$08 BEQ JIM LDA SWCHA ORA CHICKEN AND TURKEY STA TURKEY SEC ROL CHICKEN CMP #$F0 BNE JIM JMP GO4IT JIM: LDA DTIMER ;CHECK TIMER ; ; CMP #TITLEONT ;TIME TO TURN TITLE ON? ; BNE ZCKTOFF JSR ONTITLE ;YES JSR CLSCORE ;TAKE OFF THE SCORES ZSEEJOY: JSR SEEJOY BCC DRIVER ;BCC = JMP ZCKTOFF: CMP #TITLEOFT BNE ZSEEJOY JMP DOHSC ;FROM TITLE TO HSC ** AUTO STATE DISPACHER. ** AUTOD: LDA DTIMER CMP #AUTOOFFT ;DONE WITH AUTO PLAY YET? BNE AUTOGO MENUTOUT: JMP DOTITLE ;COME HERE AFTER AUTO OR MENU TIME OUT AUTOGO: JSR GAMELOOP JSR SEEJOY JMP DRIVER ** HIGH SCORE CART DISPATCHER. HSCD: JSR HSCSHOW ;PUT UP ONE TABLE LDX TEMP ;ADVANCE TO NEXT ENTRY INX CPX #12 ;12 ENTRIES BCS OVERHSC STX TEMP TAX ;TEST AC BITS: BNE HSCD ; IF AC NON-ZERO, THEN TRY AGAIN JSR SEEJOY ;CHECK FOR USER ACTIONS. JMP DRIVER OVERHSC: JMP DOAUTO ;FROM HSC TO AUTOPLAY ** PLAY STATE DISPATCHER. ** PLAYD: JSR GAMELOOP ;DO ONE TIME THRU GAME PLAY JSR SEEPAUZ ;CHANGE TO PAUSE IF PAUSE BUT. HIT JSR SEEBUTS JMP DRIVER ** MENU STATE DISPATCHER. ** MENUD: LDA DTIMER CMP #MENUOFFT BEQ MENUTOUT ;MENU TIMED OUT JSR SELCHK ;READ SELECT INPUT, SET MODES JSR ONTITLE ;PUT UP THE LOGO ;PUT UP DIFFICULTY LEVEL ICON LDX #10 TXA CLC ADC DIFF TAY JSR DOICON ;PUT UP MODE ICON LDX #11 LDA #15 CLC ADC MODE TAY JSR DOICON ;PUT UP SCORES JSR DOSCORE ;NULL OUT BOTH SHIP ICONS LDA #$FF STA STATUS+12 STA STATUS+13 ;PUT UP SHIP ICONS LDX #12 LDY #22 LDA MODE BMI MENU1PL ;ONE PLAYER INY LDA MODE BEQ MENU2PL ;TWO PLAYER INDIVIDUAL CMP #2 BNE MENUTEAM MENUCOMP: INY ;TWO PLAYER COMPETITION INY MENUTEAM: INY ;TWO PLAYER TEAM PLAY INY MENU2PL: JSR DOICON INY INX MENU1PL: JSR DOICON ;CHECK FOR START GAME BUTTONS ;CAN'T USE SEEJOY HERE; DON'T WANT TO DO DOMENU, ETC. LDA INPT4 BPL ZDOPLAYS ;JOYSTICK BUTTON HIT LDA INPT4A BMI ZDOPLAYS LDA SWCHBITS LSR BCS ZDOPLAYS ;RESET BUTTON HIT JMP DRIVER ;NOTHING HIT: CONTINUE ZDOPLAYS: JMP DOPLAY *************************************** ** ROUTINES USED BY THE DISPATCHERS. ** *************************************** * ROUTINE TO PUT TITLE ON ONTITLE: LDX #9 ;PUT UP THE FIRST 10 ICONS LDY #9 TITLELOP: JSR DOICON ;PUT UP ICON Y IN SLOT X DEY DEX BPL TITLELOP LDA #$0E ;CHANGE COLOR FOR NAME STA SOFTCOLR+9 LDA #$07 STA SOFTCOLR+11 ; LDA #$75 ;BACKGROUND BARS WILL BE CYCLED ; STA SOFTCOLR+10 RTS ** MENU SELECT ROUTINES ** * CHECK THE PAUSE BUTTON: HANG OUT HERE IF PRESSED, AND PERFORM PAUSE STUFF SEEPAUZ: LDA SWCHBITS ;CHECK PAUSE BUTTON AND #$08 BEQ PAUZRTS ;WE NOW PAUSE FOR STATION IDENTIFICATION... DOPAUZ: LDA #PAUZST ;SHUT OFF TUNER ETC. STA GAMSTATE LDA #0 STA AUDV0 STA AUDV1 STA DTIMER ;RESET TIMER FOR VIDEO OUT STA DTIMER+1 PAUZLOOP: BIT MSTAT ;SYNCH BMI PAUZLOOP ; WAIT 'TILL ON SCREEN ; BIT MSTAT ; PROTECT AGAINST FLAKEY MSTAT ; BMI PAUZLOOP ZPOSLOOP: BIT MSTAT BPL ZPOSLOOP ; WAIT 'TILL OFF SCREEN (IN VBLANK) ; BIT MSTAT ; BPL ZPOSLOOP INC DTIMER+1 ;BUMP TIMER BNE ZZNOINC7 INC DTIMER BMI VIDOFF ;TURN VIDEO OFF WHEN CLOCK ROLLS AROUND ZZNOINC7: JSR CKBUTS ;CHECK PAUSE BUTTON AND #$08 BEQ PAUZCKJY ;PAUSE MODE IS OVER LDA #PLAYST STA GAMSTATE ;RESTORE TUNER LDA #$40 ;TURN ON DMA STA CTRL PAUZRTS: RTS PAUZCKJY: LDA SWCHA EOR #$FF BNE VIDON ;TURN VIDEO ON WHEN JOYSTICK OR LDA INPT4 ; EITHER PLAYER'S BUTTONS ARE HIT. AND INPT5 ; (AND HI BITS, ACTIVE LO) BPL VIDON JSR SEEBUTS ;CHECK FOR SELECT & RESET BCC PAUZLOOP ;BCC = JMP VIDOFF: LDA #$60 ; 60 = STOP DMA BNE VIDSTOR ; BNE = JMP VIDON: LDA #$40 ; 40 = START DMA VIDSTOR: STA CTRL BNE DOPAUZ ; BNE = JMP * CHECK BUTTONS (PAUSE, RESET, SELECT) SAVING STATE FOR DEBOUNCING. * SETS ONES IN EACH BIT OF SWCHBITS ON POSITIVE TRANSITIONS. CKBUTS: LDX SWCHB TXA EOR SWCHBVAL ;GET ALL BITS WHICH HAVE CHANGED AND SWCHBVAL STA SWCHBITS ;SAVE OLD VALUES OF CHANGED BITS STX SWCHBVAL ;SAVE NEW VALUES OF ALL BITS RTS * CHECK JOYSTICK/BUTTONS ETC. FOR CHANGE OF STATE SEEJOY: LDA STARTBUT ;CHECK FIRE BUTTON, NOT SET IN AUTOST ;NEEDED TO PREVENT GOING FROM AUTOST BPL DOPLAY LDA SWCHA ;CHECK JOYSTICK MOTION AND #$F0 EOR #$F0 BNE DOMENU SEEBUTS: LDA SWCHBITS ;CHECK SELECT AND RESET BUTTONS LSR BCS DOPLAY LSR BCS DOMENU RTS ;ENTER HSC STATE DOHSC: LDA #0 ;LOWEST GAME OPTION FOR HSC STA TEMP LDA #HSCST JMP NEWDRVR ;ENTER MENU STATE DOMENU: LDA #SELDLY ;DEBOUNCE SELECTER STA SELCNT LDA #0 ;CLEAR MENLEFT STA MENLEFT STA MENLEFT2 STA MENLEFTC LDA #MENUST ;JUMP INTO MENU STATE JMP NEWDRVR ;ENTER PLAY STATE DOPLAY: JSR INITSCOR JSR INITPLAY JSR DOSCORE LDA #PLAYST ;GOTO PLAY STATE NOW JMP NEWDRVR ;ENTER TITLE PAGE STATE DOTITLE: LDA #TITLEST JMP NEWDRVR ;ENTER AUTOPLAY STATE DOAUTO: LDA #0 ;CLEAR MENLEFT STA MENLEFT STA MENLEFT2 STA MENLEFTC JSR DOSCORE JSR INITPLAY ;INITIALIZE FOR GAMEPLAY LDA #AUTOST ;BUT ITS AUTOPLAY JMP NEWDRVR SELCHK: LDA SWCHA ;P1 JSTICK AND #$F0 EOR #$F0 BNE SELJOY LDA SWCHB ;SELECT BUTTON AND #$02 BEQ SELBUT LDA #0 STA SELCNT RTS SELBUT: DEC SELCNT BPL SELRTS LDX #SELDLY STX SELCNT JSR INCDIFF BNE SELRTS ;INC WORKED OK LDA #MINDIFF ;INC HAD NO EFFECT, WRAP AROUND STA DIFF JSR INCMODE BNE SELRTS ;INC WORKED OK LDA #MINMODE STA MODE BNE SELCHNG ;MINMODE = $FF HERE, SO BNE = JMP SELJOY: DEC SELCNT BPL SELRTS LDX #SELDLY STX SELCNT ASL BCS INCDIFF ASL BCS DECDIFF ASL BCS DECMODE * FALL THROUGH TO... INCMODE: LDX MODE ;INCREMENT GAMEPLAY MODE CPX #1 ;HACK: WE STOP AT 1 BEQ SELRTS INX ;BIGGER HACK: PUSH X INTO RANGE. LDA ZHACKMOD+2,X ;BIGGEST HACK: TABLE LOOKUP NEXT MODE. STA MODE BPL SELCHNG INCDIFF: LDA DIFF ;INCREMENT INITIAL GAME DIFFICULTY CMP #MAXDIFF BEQ SELRTS INC DIFF BPL SELCHNG DECDIFF: LDA DIFF ;DECREMENT DIFFICULTY CMP #MINDIFF BEQ SELRTS DEC DIFF BPL SELCHNG DECMODE: LDX MODE ;DECREMENT MODE CPX #MINMODE BEQ SELRTS LDA ZHACKMOD,X STA MODE SELCHNG: LDA #0 ;HOLD DRIVER CLOCK AT ZERO STA DTIMER STA DTIMER+1 * JSR HSCSUCK ;SUCK IN A NEW HIGH SCORE FOR THIS LVL LDA #17 ;JUST TO KNOCK OFF THE 'EQ' BIT SELRTS: RTS ZHACKMOD: .DC.B $FF,2,0,2,17,1 ;TABLE OF "NEXT MODES" TO KLUDGE IN. GO4IT: LDX #8 LDY #LARGE+$80 ZSNARD: STY STATUS,X LDA PALTAB,X STA PALS,X LDA ELBOUND+2 STA ACYC,X DEX BPL ZSNARD STAY4IT: LDA FRMCNT AND #$03 ;EVERY 4 BNE ZEATME LDA FRMCNT PHA LSR STA FRMCNT JSR EXPLODE PLA STA FRMCNT ZEATME: JSR WAITLOAD LDA #114 STA YPOSH+9 LDA #BEAG&255 STA ACYC+9 LDA #$4A STA PALS+9 JSR LOGOBARS JSR CKJOY JSR CKBUTS JSR SEEJOY BCC STAY4IT ;BCC = JMP * NMI HANDLER: HANDLES NMI'S GENERATED EACH FRAME BY MARIA AT END OF VISIBLE. NMI: PHA ;SAVE STATE TXA PHA TYA PHA CLD LDA NMICTRL ;SEE IF WE ARE DOING HISCORE CART LOGO BEQ NMIHNDL ; NO. DO NORMAL HANDLER bne NMIOVER ;br always 1-Sept-88 *** Dave *** * STA CTRL ; YES. SET READ MODE BITS OF CTRL EOR #$03 ; INVERT THE BITS STA NMICTRL AND #$03 ; IF <> 0 (ENTERING VBLANK) BNE NMIINCFR ; BUMP FRAME COUNT JSR HSCSETRS ;SET UP HSC REGISTERS (REFRESH COLORS) JMP NMIOVER NMIHNDL: LDA FRMCNT LSR BCC NOLOAD ;EVERY OTHER FRAME, DON'T CALL LOADER JSR LOADER NOLOAD: JSR TUNER ;DO TUNES NMIINCFR: INC FRMCNT ;BUMP FRAME COUNT JSR REFRESH ;REFRESH OUR COLORS NMIOVER: PLA ;RESTORE STATE TAY PLA TAX PLA IRQ: RTI ;VECTOR IRQ'S TO THIS LABEL