123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614 |
- * 1830 040784
- *
- ** FSM.S **
- ** ASTEROIDS FOR THE ATARI 3600 **
- ** THIS FILE CONTAINS THE FINITE STATE MACHINE FOR ASTEROIDS. **
- ** GAME SEQUENCER TO HANDLE INDIVIDUAL PLAYER'S EVENT TIMING. **
- FSM:
- LDX PLAYER ;PLAYER MUST CONTAIN CURRENT PLAYER
- LDA STATE,X ;CURRENT STATE OF PLAYER
- BEQ CKCOMPLY ;CHECK IF COMP PLAY
- BPL DECTIMER ;IF IN ACTIVE STATE THEN TAKE ACTION
- RTS ;IF MINUS, RTS (I GUESS)
- DECTIMER:
- DEC TIMER,X ;DECREMENT EVENT TIMER
- CMP #BIRTH ;BIRTH STATE?
- BEQ BIRTHD
- CMP #HYPER ;HYPERSPACE STATE?
- BNE ZCKCOMP
- JMP HYPERD
- ZCKCOMP:
- CMP #COMPOVER ;COMP PLAY OVER?
- BNE ZCKDTH
- JMP COVERD
- ZCKDTH:
- CMP #DEATH ;DEATH STATE?
- BNE FSMRTS
- JMP DEATHD
- FSMRTS:
- RTS
- CKCOMPLY:
- LDA COMPFLAG ;CHECK IF ANYBODY DIED YET
- BEQ FSMRTS
- JSR CMPSCOR ;COMPARE SCORES
- BMI FSMRTS
- CMP PLAYER ;HISCORE = FIRST TO DIE?
- BNE FSMRTS ;YES, CONTINUE PLAY
- TAX
- LDA #COMPOVER
- STA STATE,X ;STATE IS REZ OUT VICTOR
- LDA #$FF
- STA COMPFLAG
- LDA #0
- STA MENLEFT,X ;NO MORE LIVES
- LDA #$0D
- STA FLASH
- LDA #$0
- JSR DOTUNE ;VICTOR REZOUT SOUND
- RTS
- CMPSCOR:
- LDX #0 ;COMPARE SCORES
- CMPSLOOP:
- LDA SCORE,X ;FIRST SCORE
- CMP SCORE2,X ;SECOND SCORE
- BCC P2BIGGR ;SCORE < SCORE2
- BEQ BUMPX
- BCS P1BIGGR ;SCORE > SCORE2
- BUMPX:
- INX ;LOOK AT NEXT BYTE
- CPX #5
- BNE CMPSLOOP
- LDA #$FF ;SCORE = SCORE2
- RTS
- P2BIGGR:
- LDA #1
- RTS
- P1BIGGR:
- LDA #0
- RTS
- ** BIRTH DISPACHER - HANDLES TIMING OF BIRTH EVENTS. **
- BIRTHD:
- LDY OFFPLAY2 ;IF PLAYER IS NOT THERE, DON'T
- LDA STATUS+24,Y ; DO REZ TWINKLE
- BMI ZNOREZ
- ;DO REZ TWINKLE
- LDA #$05 ;DEFAULT LUME FOR AUTOPLAY
- LDY GAMSTATE
- CPY #PLAYST
- BNE ZREZGO ;IF NOT IN PLAY STATE, DO AUTO REZ
- LDA FRMCNT ;USE FRAME COUNT LO BITS FOR LUME
- ASL
- ZREZGO:
- JSR PAINTSHP ;PAINT THE SHIP, BODY AND DEJAG COLORS
- LDX PLAYER
- ZNOREZ:
- LDA TIMER,X ;CHECK TIMER TO DISPATCH
- CMP #PMSGT ;TIME TO PUT UP PLAYER MESSAGE?
- BEQ PMSG ; YES, PUT IT UP
- CMP #PMSGOFFT ;TIME TO TAKE DOWN MESSAGE?
- BEQ PMSGOFF ; YES, TAKE IT DOWN
- CMP #RESINT ;TIME TO RES IN?
- BEQ RESIN ; YES, RES IN. IF LATER THAN RESINT,
- BCC OPTENTER ; CHECK FOR OPTIONAL ENTER (JSTICK)
- RTS ;OTHERWISE, JUST RTS
- * ROUTINE TO PUT UP THE PLAYER X MESSAGE IF NEEDED. *
- PMSG:
- LDA MODE ;NO MESSAGES IN TEAM MODES
- CMP #1
- BPL ZPLRTS
- JSR SETMSG
- ZPLRTS:
- RTS
- * ROUTINE TO TURN PLAYER X MESSAGE OFF. *
- PMSGOFF:
- LDA #$FF ;TURN OFF HIGH MESSAGE
- STA STATUS+34
- RTS
- * ROUTINE TO ENTER THE SHIP IF DESIRED OR NEEDED. *
- OPTENTER:
- LDA GAMSTATE ;DO ONLY IF GAMEPLAY STATE
- CMP #PLAYST
- BNE ZCKTIMM
- ;FIRST CHECK TO SEE IF PLAYER IS FORCING SHIP IN
- LDA FIREBUT1,X ;FIRE BUTTON
- AND HYPBUT1,X ;HYPERSPACE BUTTON
- BPL ENTSHIP ; IS PRESSED! ENTER HIM
- LDA SWCHA ;JOYSTICK
- EOR #$FF ; (INVERTED)
- AND JOYTBL,X ; (LOOK AT ONLY CORRECT PLAYER'S BITS)
- BNE ENTSHIP ; IS HIT! ENTER HIM
- ;NOW CHECK IF IT IS TIME, AND IS SAFE.
- ZCKTIMM:
- LDA TIMER,X ;CHECK TIMER
- CMP #ENTERT
- BCS ENTRTS ;NOT TIME YET, DON'T BOTHER
- LDA OFFPLAY2 ;CHECK SAFTEY
- CLC
- ADC #24
- TAX
- JSR ISSAFE ;CHECK IF AREA SAFE TO ENTER
- BEQ ENTSHIP ;YES, CONTINUE
- ;NOT SAFE, HOLD TIMER HERE INDEFINITELY
- LDX PLAYER
- INC TIMER,X
- ENTRTS:
- RTS
- ENTSHIP:
- LDA #2 ;KILL TWINKLING
- JSR KILLTUNE
- LDA #$3 ;ADD BUZZING IN
- JSR DOTUNE
- LDA PLAYER ;CHANGE BODY COLOR
- ASL
- ASL
- TAX
- LDA COLORS+2,X
- STA SOFTCOLR+2,X
- LDA COLORS+3,X
- STA SOFTCOLR+3,X
- LDX PLAYER
- LDA #1 ;DEBOUNCE ENTER/FIRE BUTTON
- STA FIRESTAT,X
- LDA #OK ;SET STATE AS OK
- STA STATE,X
- RTS
- ** ROUTINE TO RESIN AND TWINKLE SHIP AT ENTERING. **
- RESIN:
- LDA STATUS+25 ;CHECK STATUS OF UFO
- BMI ZGONOW ;DON'T BRING SHIP IN IF UFO
- INC TIMER,X
- RTS
- ZGONOW:
- LDA GAMSTATE ;DON'T DECREMENT IF AUTOPLAY
- CMP #AUTOST
- BEQ ZNODECM
- LDA MODE ;CHECK TO DEC FROM COMMON POOL
- CMP #1
- BNE ZNOPOOL
- LDA MENLEFTC ;CHECK: IF NO MENLEFT, JUST HANG OUT
- CMP #1 ; AND WAIT; PERHAPS OTHER PLAYER WILL
- BCS ZYESMEN ; BRING HIM IN A LIFE.
- INC TIMER,X ; (HOLD TIMER AT THIS POINT IN TIME)
- RTS
- ZYESMEN:
- LDX #2 ;2 = COMMON POOL
- ZNOPOOL:
- DEC MENLEFT,X ;DEC FROM PLAYERS LIVES
- JSR UPDATMEN
- ZNODECM:
- LDA #2 ;TWINKLING SOUND
- JSR DOTUNE
- ZINITPOS:
- LDX OFFPLAY2 ;INITIALIZE THE SHIP'S POSITION
- LDA #0
- STA XVELH+24,X
- STA YVELH+24,X
- STA XVELL+24,X
- STA YVELL+24,X
- STA GOATMILK ;??
- LDA MODE
- CMP #1
- BMI ZCENTERS
- LDY PLAYER
- LDA INITSX,Y ;GET X POS VALUE FOR PLAYER
- BPL ZSTORSX ;BPL = JMP HERE.
- ZCENTERS:
- LDA #$50
- ZSTORSX:
- STA XPOSH+24,X
- CLC
- ADC DELTAX+3 ;COULD SQUEEZE A BYTE HERE: USE IMMED.
- STA COLXPOSH+24,X
- LDA #$50
- STA YPOSH+24,X
- CLC
- ADC DELTAY+3 ;COULD SQUEEZE HERE TOO.
- STA COLYPOSH+24,X
- LDX PLAYER ;STORE FIRST ANIMATION
- LDA SHIPDIR,X
- LSR
- LSR
- LSR
- AND #$FE
- CLC
- ADC #SHIP1 & 255
- LDX OFFPLAY2
- STA ACYC+24,X
- LDA #SHIP ;STORE STATUS AS SHIP
- STA STATUS+24,X
- RTS
- INITSX:
- .DC.B $30,$70 ;XPOS VALUES FOR INITIAL SHIP POS
- JOYTBL:
- .DC.B $F0,$0F ;JSTICK MASKS, INDEXED BY PLAYER.
- ** HYPER SPACE DISPACHER - HANDLES TIMING OF HYPER SPACE EVENTS. **
- HYPERD:
- LDA TIMER,X ;CURRENT PLAYERS EVENT TIMER
- CMP #HYPERT ;TIME TO JUMP HYPERSPACE?
- BEQ HYPERGO ; YES, DO IT.
- CMP #HYPENDT ;TIME TO END HYPERSPACE
- BEQ HYPEND ; YES, DO IT.
- RTS ;OTHERWISE, JUST RTS
- * ROUTINE TO HANDLE THE JUMP TO HYPERSPACE. *
- HYPERGO:
- LDA #$01 ;SOUND
- JSR DOTUNE
- LDX OFFPLAY2 ;NULL OUT SHIP
- LDA #$FF
- STA STATUS+24,X
- LDA #0 ;NULL VELOCITY
- STA XVELL+24,X
- STA XVELH+24,X
- STA YVELL+24,X
- STA YVELH+24,X
- RTS
- * ROUTINE TO HANDLE THE RETURN FROM HYPERSPACE. *
- HYPEND:
- LDA #24
- CLC
- ADC OFFPLAY2
- TAX
- JSR NEWRAND ;GET NEW SHIP POSITION
- LSR ; AVOID EXTREME SIDES
- ADC #$D ; (BETWEEN $D AND $8C)
- STA XPOSH,X
- JSR NEWRAND ;GET Y POSITION; AVOID TOP AND BOTTOM
- LSR
- ADC #$10 ; (BETWEEN $10 AND $90)
- STA YPOSH,X
- JSR ISSAFE ;SAFE TO ENTER
- BEQ GOBIGRED ;YOU BET
- LDX PLAYER ;SORRY CHARLIE
- INC TIMER,X
- RTS
- GOBIGRED:
- JSR NEWRAND ;GET RANDOM VALUE
- CMP #50 ;SOMETIMES LET THE SHIP EXPLODE
- BCS NOBLOW ;OTHERWISE SET NEW POSITION
- ;EXPLODE HIM!
- LDA #24 ;WITHOUT THIS X = 'FF' SOMETIMES
- CLC
- ADC OFFPLAY2
- TAX
- LDA #$A3 ;BOOM !! SET HIGH BIT OF STATUS
- STA STATUS,X
- LDA ELBOUND+3 ;SET ANIMATION STAMP
- STA ACYC,X
- LDA #5 ;START SHIP EXPLOSION SOUND
- JSR DOTUNE
- LDX PLAYER
- BLOW:
- LDA #DEATH ;SET STATE
- LDX PLAYER
- STA STATE,X
- LDA #DIET+$28 ;ENTER TIMELINE AT TOP
- STA TIMER,X
- RTS
- NOBLOW:
- LDA #3 ;BUZZ SOUND
- JSR DOTUNE
- LDA #SHIP ;RESTORE SHIP
- LDX TEMP
- STA STATUS,X
- LDX PLAYER
- LDA #OK ;RETURN STATE TO OK.
- STA STATE,X
- RTS
- ** COMP PLAY OVER DISPACHER - HANDLES TAKING SHIP OUT. **
- COVERD:
- * LDX PLAYER
- LDA FLASH
- INC FLASH
- CMP #$20
- BEQ ZTAB
- CMP #$2E
- BNE CCONTIN ;ALL DONE
- JMP BLOW ;JUMP INTO HYPER CODE
- CCONTIN:
- BIT BPLOP
- BEQ DOPAINT
- EOR #$1F
- DOPAINT:
- JSR PAINTSHP
- RTS
- ZTAB:
- LDX OFFPLAY2 ;NUKE SHIP
- LDA #$FF
- STA STATUS+24,X
- RTS
- ** DEATH DISPACHER - HANDLES TIMING OF DEATH SEQUENCE. **
- DEATHD:
- LDA TIMER,X ;CURRENT PLAYERS EVENT TIMER
- CMP #DIET ;TOP OF DEATH TIMELINE?
- BEQ DIE ; YES, GO TO DIE HANDLER
- CMP #SWITCHT ;TIME TO SWITCH PLAYER?
- BNE ZCKPOT
- JMP SWITCH ; YES, SWITCH.
- ZCKPOT:
- CMP #POMSGT ;TIME TO DISPLAY PLAYERX OVER?
- BNE ZCOKE
- JMP POMSG ; YES, DO IT.
- ZCOKE:
- CMP #POMSGOFT ;TIME TO TURN OFF MESSAGE?
- BEQ POMSGOFF ; YES, DO IT.
- CMP #GOVERT ;TIME TO DISPLAY GAME OVER MESSAGE?
- BEQ GOVER ; YES, DO IT.
- CMP #NEWGAMET ;END OF DEATH TIMELINE?
- BNE DEATHRTS
- ;YES, SET UP FOR HIGH SCORE CART
- JSR CLEARTUN ;GET RID OF ANY TUNES
- JSR NULLOBJS ;GET RID OF ANY OBJECTS
- JSR HSCDOENT
- JMP DOTITLE
- DEATHRTS:
- RTS
- * ROUTINE TO TAKE DOWN THE ABOVE *
- POMSGOFF:
- LDA #$FF ;NULL OUT BOTH MESSAGES
- STA STATUS+34
- STA STATUS+35
- TXA ;CHECK OTHER PLAYER FOR GAME OVER COND.
- EOR #$01 ; HERE'S HOW IT WORKS: ONLY ONE PLAYER
- TAY ; ACTUALLY MAKES IT TO THE GAME OVER
- LDA #DEAD ; MESSAGE TIME. SO, THE FIRST PLAYER
- CMP STATE,Y ; TO MAKE IT TO POMSGOFF BECOMES DEAD
- BEQ DEATHRTS ; THE OTHER LIVES ON TO GET TO GOVER!
- STA STATE,X ;MAKE PLAYER DEAD, SINCE OTHER IS LIVE.
- LDA MODE ;IN TWO PLAYER MODE, SWITCH DATA NOW
- BNE DEATHRTS ; SO WE DON'T GET STUCK PLAYING
- JMP SWITCH ; A DEAD PLAYER (FSM WON'T RUN ON HIM)
- RTS
- * ROUTINE TO PUT UP GAME OVER MESSAGE *
- GOVER:
- LDX #2 ;GAME OVER MESSAGE
- JSR SETMSG
- JSR HIGHSCOR
- RTS
- * ROUTINE TO HANDLE DEATH OF A SHIP. *
- * ALL DEATHS GO HERE. THIS ROUTINE FIGURES OUT WHERE WE SHOULD BE GOING. *
- DIE:
- JSR INITHUMP ;REINIT THUMP RATE
- LDA #$11 ;KILL THRUST SOUND
- JSR KILLTUNE
- LDX PLAYER ;RESTORE X, TRASHED BY KILLTUNE
- ;HANDLE MODES DIFFERENTLY
- LDY MODE
- LDA MENLEFTC ;LOAD TEAMPLAY MENLEFT AS DEFAULT
- CPY #1
- BEQ ZDIEMN1 ;IF NOT TEAMPLAY MODE
- LDA MENLEFT,X ; USE CURRENT MENLEFT
- ZDIEMN1:
- CMP #1 ;IF WE HAVE NO MEN LEFT
- BCC NOMENLFT ; HANDLE THIS SITUATION
- CPY #0 ;ELSE IF NOT TWO PLAYER MODE
- BNE GIVEBRTH ; SIMPLY TRY TO GIVE BIRTH.
- TXA ;ELSE TWO PLAYER MODE:
- EOR #$01 ; CHECK OTHER PLAYER'S MENLEFT.
- TAX
- LDA MENLEFT,X
- CMP #1 ; IF HE HAS MEN LEFT THEN
- BCS DEATHRTS ; SIMPLY RTS. SWITCH WILL DO THE TRICK
- JMP GIVBRTH2 ; ELES SKIP THE SWITCH. GIVE BIRTH NOW
- NOMENLFT:
- CPY #$FF ;ELSE, IF ONE PLAYER MODE
- BEQ DIEGOVER ; DIE WITH SIMPLE GAMEOVER (NO PMSG)
- CPY #$1 ;ELSE, IF NOT IN TEAM PLAY MODE
- BNE DIEPOVER ; DIE WITH PLAYER OVER MESSAGE
- TXA ;ELSE CHECK OTHER PLAYER'S STATE
- EOR #$01 ; TO SEE WHETHER TO END THE GAME
- TAX
- LDA STATE,X
- CMP #BIRTH ; IF OTHER PLAYER IS NOT IN BIRTH
- BNE GIVEBRTH ; THEN TRY TO GIVE BIRTH.
- LDA OFFPLAY2 ; OTHERWISE,
- EOR #$08 ; (TOGGLE OFFPLAY2)
- TAY
- LDA STATUS+24,Y ; IF HE IS NOT YET BORN, THEN
- CMP #SHIP ; FORGET IT BUD. AIN'T NO LIVES LEFT
- BEQ GIVEBRTH ; FOR EITHER OF THEM.
- LDA #DEAD ; NUKE OTHER PLAYER OUT OF BIRTHST
- STA STATE,X ; TO PREVENT A NEW RACK FROM STARTING
- DIEGOVER:
- LDA #GOVERT+3 ;DIE WITH GAME OVER MESSAGE ONLY
- BNE ZDIEOVER ; BNE = JMP
- DIEPOVER:
- LDA #POMSGT+3 ;DIE WITH PLAYER N GAME OVER MESSAGE
- ZDIEOVER:
- LDX PLAYER
- STA TIMER,X
- RTS
- GIVEBRTH:
- LDX PLAYER
- LDA #BIRTH ;GIVE BIRTH
- STA STATE,X
- LDA #RESINT+3 ;AT TIMER RESIN+3
- STA TIMER,X
- RTS
- * ROUTINE TO PUT UP PLAYERX GAME OVER MESSAGE *
- POMSG:
- LDX PLAYER ;PLAYERX MESSAGE
- LDA COMPFLAG
- BMI PVICTOR
- BEQ PPLAYER
- JSR CMPSCOR ;COMPARE SCORES
- TAX
- BPL PVICTOR
- ; TIE SCORE
- LDA GOATMILK ;CHECK FLAG
- BNE PUNTTHIS ;SHIP TO SHIP
- LDX PLAYER ;NO, PUT MESSAGE FOR THIS GUY
- BPL PVICTOR ; = JMP
- PUNTTHIS:
- LDA #$FF ;RETURN W/OUT MSG IF EQUAL
- STA STATUS+34 ;TAKE MSG DOWN BEFORE SEEN
- STA STATUS+35
- RTS
- PPLAYER:
- JSR SETMSG
- LDX #2
- DOMSG:
- JSR SETMSG
- LDX MODE
- CPX #2
- BNE ZPORTS
- STX COMPFLAG
- ZPORTS:
- RTS
- PVICTOR:
- JSR SETMSG ;X HAS PLAYER
- LDX #3
- BPL DOMSG ;BPL = JMP
- * ROUTINE TO SWITCH THE TWO DATA SETS WHEN NEEDED. *
- SWITCH:
- TXA ;TOGGLE CURRENT PLAYER # AND OFFSET
- EOR #$01
- TAX
- STA PLAYER
- BEQ ZSTOFFP2
- LDA #8
- ZSTOFFP2:
- STA OFFPLAY2
- LDA #$FF ;NULL OUT SPACE OBJECTS
- LDX #7 ; (31-23=8 OBJECTS)
- SWCHNULL:
- STA STATUS+24,X
- DEX
- BPL SWCHNULL
- LDA #0
- STA RACKDLY ;NO DELAY AFTER SWITCH
- LDA #$50
- STA RTIMER ;RESET UFO FREQUENCY AND TIMER
- LDA #$92
- STA SDELAY
- STA EDELAY
- JSR CLEARTUN ;KILL TUNES, ESP. UFO
- LDY #23
- SWCHLOOP:
- LDX STATUS,Y
- LDA STATUS2,Y
- STA STATUS,Y
- TXA
- STA STATUS2,Y
- *
- LDX ACYC,Y
- LDA ACYC2,Y
- STA ACYC,Y
- TXA
- STA ACYC2,Y
- *
- LDX PALS,Y
- LDA PALS2,Y
- STA PALS,Y
- TXA
- STA PALS2,Y
- *
- LDX XVELH,Y
- LDA XVELH2,Y
- STA XVELH,Y
- TXA
- STA XVELH2,Y
- *
- LDX YVELH,Y
- LDA YVELH2,Y
- STA YVELH,Y
- TXA
- STA YVELH2,Y
- *
- LDX XVELL,Y
- LDA XVELL2,Y
- STA XVELL,Y
- TXA
- STA XVELL2,Y
- *
- LDX YVELL,Y
- LDA YVELL2,Y
- STA YVELL,Y
- TXA
- STA YVELL2,Y
- *
- LDX XPOSH,Y
- LDA XPOSH2,Y
- STA XPOSH,Y
- TXA
- STA XPOSH2,Y
- *
- LDX YPOSH,Y
- LDA YPOSH2,Y
- STA YPOSH,Y
- TXA
- STA YPOSH2,Y
- DEY
- BPL SWCHLOOP
- GIVBRTH2:
- LDX PLAYER ;GIVE BIRTH, TWO PLAYER STYLE (PMSG)
- LDA #BIRTH ;GIVE BIRTH
- STA STATE,X
- LDA #PMSGT+$20 ;AT TIMER PMSGT+20
- STA TIMER,X
- RTS
|