revolution-x/GX.ASM

4474 lines
113 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

.MLIB "GXMACS.LIB"
.FILE "GX.ASM"
.TITLE " <<< GENERATION X -- VERSION 1.0 >>>"
.WIDTH 132
.OPTION B,D,L,T
.MNOLIST
HDW_KLUDGE .set 0
TEST_FIXTURE .EQU 0
;;; XUNIT changes
;;;
;;; intenb --> INTENB, vcount --> VCOUNT
;;; DMATPLFT --> DMAWINDOW, SYSCTRL, DMACTRL
;;;
**************************************************************************
* *
* REVOLUTION X THE GAME *
* --------------------- *
* *
* STARTED: 08/10/92 *
* RELEASED: ??/??/?? *
* *
* DIRECTED & *
* PRODUCED BY: GEORGE N. PETRO *
* JACK E. HAEGER *
* *
* GAME DESIGN: GEORGE N. PETRO *
* JACK E. HAEGER *
* BILL DABELSTEIN *
* WARREN B. DAVIS *
* STEVE BERAN *
* MARTIN MARTINEZ *
* *
* ARTWORK, *
* ANIMATIONS: JACK E. HAEGER *
* STEVE BERAN *
* MARTIN MARTINEZ *
* JOHN VOGEL *
* *
* GAME PROGRAM: BILL DABELSTEIN *
* WARREN DAVIS *
* GEORGE N. PETRO *
* *
* SOUNDS & MUSIC: CHRIS GRANNER *
* *
* HARDWARE: RAY MACIKA *
* STEVE CORRELL *
* MARK LOFFREDO *
* CARY MEDNICK *
* PAT COX *
* *
* SOUND SYSTEM: MATT BOOTY *
* RK140 *
* *
* MECHANICS, *
* CABINET: TED VALAVANIS *
* MATT DAVIS *
* BOB *
* *
* SUPPORT: AL LASKO *
* DR. SHERIDAN OURSLER *
* *
* COPYRIGHT (C) 1994 MIDWAY MANUFACTURING COMPANY. *
* ALL RIGHTS RESERVED. *
* *
**************************************************************************
**************************************************************************
* *
* REVISION HISTORY *
* ---------------- *
* *
* DATE REV DESCRIPTION *
* ---- --- ----------- *
* 9/1/93 - Name changed from GENERATION X to REVOLUTION X *
* 3/17/94 TA1 ACME show, first showing, 2500 sold *
* 4/1/94 TA2 First weekend test, $424.00 in 3 days *
* 4/15/94 TA3 Second weekend test, $189.00 in 1.5 days *
* 4/22/94 TA4 Installed 4/22/94 10:00pm at Times Square *
* 5/5/94 TA5 Put out the weekend before releasing *
* *
**************************************************************************
*
* GET THE SYSTEM STUFF
*
.INCLUDE "GX.INC"
.INCLUDE "GXSTRING.H"
.INCLUDE "IMGTBL.GLO"
.INCLUDE "BGNDTBL.GLO"
.IF DEBUG
.ref CLIPTIM,SCALETIM,VELTIM,PROCTIM
.ENDIF
.DEF POWERUP, MAIN_INIT, MAIN_GO, SWAVE
.DEF SETUP, GPLAYD, WIPEOUT, PLAYER_DELETE, PLAYER
.DEF GAME_OVER, WAVE_END, SWITCH_ESCAPE
.DEF INC_PLAYER_TIMERS, ATSTRT, CLR_PEXTRAS, CLR_PSTARTESC
.DEF POWERRET, WARMSET, PCMOSRET, CLSCRACH, EXEC_LP
.DEF WAVE_PLAYERS, WAIT_WAVE_END
.DEF DUXNOFADE, START_WAVE_MUSIC
.DEF WAVE_START, GAME_INTRO, GRAMINIT, GAME_DIFFICULTY
.DEF SLEEP_SWITCHX, INITDATA, IDATALEN, PLAYER_CLR
.DEF ALLOW_CONTINUE, PLAYER_KILL, WAVE_RESET
.DEF WEND_SND_TAB, ATT_WAVE_START, BUSNOFADE
.DEF MOVIE_KILL, SWITCH_SPOKEN, PLAYER_BONUS_RESTART
.def CLR_ALL_PDATA
.REF INIT_TAB, FOREGROUND
.REF SET_AVGWAVE
*SYMBOLS IN GXCMOS.ASM
.REF ADD_DUMP, CMOS_VAL, FAC_SET, GET_AUD, STORE_AUDIT
*SYMBOLS IN GXATT.ASM
.REF ATTRACT_MODE, ATT_MODE_GAME_OVER
.REF AMODE_LOOPS, ON_CRED
; .REF GAME_CREDITS
*SYMBOLS IN GXSCOR.ASM
.REF SCORPROC, SCORE_GAME_OVER, UPDSL, OUTSCR, LEVEL_UPDATE
.REF G_CREDONLY
*SYMBOLS IN GXRAM.ASM
.REF COLRTEMP, SKYCOLOR, SEC_FLAG, A2D_COPY, GUNS_OFF
.REF WDIFF_RAM_ST, WDIFF_RAM_END
.REF GDIFF_RAM_ST, GDIFF_RAM_END
.REF SPLAYER_NUM, SPLAYER_COL, ENEMIES_LEFT, VIOLENCE_LEVEL
.REF WAVE_MUSIC, WAVE_IPLANE, WAVE_SCROLL, WAVE_SUB
.REF DISPATCH_TABLE, ENERGY_SHIFT, DO_CREDITS
.REF WAVE_INTRO, WAVE_EXIT, ENEMY_BONUS_ST, ENEMY_BONUS_END
.REF DMACFIGCOPY,BONUS_DIRECTION, BUYIN_RESETS, BTIME
.REF VALIDATOR, T2_KIT
*SYMBOLS IN GXPLAYER.ASM
.REF START_INVINCIBILITY, P_LED_OFF, P_LED_ON
*SYMBOLS IN GXENEMY.ASM
.REF LOAD_ENEMIES_LEFT, MASTERDP, ENEMY_WAIT
*SYMBOLS IN GXCOIN.ASM
.REF COINFLAG, TIMEINIT, GAMEUNITS
.REF LCOIN, RCOIN, CCOIN, XCOIN, SCOIN, SLAM, COININT
.REF P_START, P_CONT, CR_STRTP, CR_CONTP, GET_CSTR
.REF COUNTER_ON, COUNTER_OFF
*SYMBOLS IN GXDTST.ASM
.REF READ_DIP, POWERTST, POWERCMOS
*SYMBOLS IN GXDUTL.ASM
.REF STRING, DSCRCLR, INITCOLR, STRINGCENTER
*SYMBOLS IN GXMENU.ASM
.REF DIAG, CKDIAG
*SYMBOLS IN GXBGDATA.ASM
.REF START_BONUS, StrtBgnd
*SYMBOLS IN GXGUN.ASM
.REF PFIRE, PBOMB, GUN_CALIBRATE, PLAYER_CURSOR
.REF INITIALIZE_CALIBRATION, PLAYER_RECOIL_OFF, RECOIL_OFF
*SYMBOLS IN GXPOWER.ASM
.REF CLR_HEADS_UP, CLR_PLAYER_TEXT, INIT_SBOMB_PAGE
.REF DO_HEADS_UP
.REF ALTWEAP_TAB_3P, ALTWEAP_TAB_2P
*SYMBOLS IN GXWAVE.ASM
.REF WAVE_DIFF_TAB, GAME_DIFF_TAB, WAVE_TABLE
*SYMBOLS IN GXHSTD.ASM
.REF HS_ENTRY_SCRN, CLEAR_HSCOLORS, ON_HSTD
*SYMBOLS IN GXMISC.ASM
.REF SECURITY, COLOR_START, BUYINWIN, SKYUP
.REF SKYDOWN, DUMP_IT
*SYMBOLS IN GXTV.ASM
.REF ROMTRAP
*Symbols in GXSND.ASM
.REF LINT2_SERVICE
*SYMBOLS IN GXPRNT.ASM
.IF PRINTER
.REF PRINTP, T2ALIVE, DOGGYPRINT, LASTSTACK, LASTA0
.REF PGAMESTART, PGAMEEND, PGAMEBUYIN, PGAMECONT, PIDIED
.REF PGAMELEVEL
.ENDIF
*SYMBOLS IN GXBONUS.ASM
.REF GO_BONUS
*SYMBOLS DEFINED IN GX.CMD
.GLOBAL code_start, code_end, code_dest, vector_start, vector_end
.GLOBAL vector_dest
.BSS EXECLED,16
.BSS IRQLED,16
**** .BSS IRQCOILCNT,16 ;COIL SAFETY COUNTER
**** .BSS SINTRAM,16 ;TEMP FOR LAST SCORE AREA INTERRUPT LINE
**** .BSS HSINTRAM,16 ;LAST HALF SCREEN INTERRUPT LINE
.BSS DIPSW,16 ;RAM FAKE FOR NON-EXISTANT DIP SWITCHES
.BSS SWITCH_ESCAPE,16 ;SWITCH ESCAPE FLAG USED BY SLEEP_SWITCHX
.BSS SWITCH_SPOKEN,16 ;SWITCH SPEAK FLAG
.BSS DMASKIPBOG,16 ;Flag to skip BOG calculator for one frame
.BSS CALLPRAM,16,1 ;STORAGE FOR PLAYER CALLS
.BSS NO_WAVE_INTRO,16 ;flag the intro to stay away
; .bss filler,16 ; to keep it long word aligned
.TEXT
.STRING "CCCCOOOOPPPPYYYYRRRRIIIIGGGGHHHHTTTT ((((cccc)))) "
.STRING "1111999999994444 MMMMIIIIDDDDWWWWAAAAYYYY "
.STRING "MMMMAAAANNNNUUUUFFFFAAAACCCCTTTTUUUURRRRIIIINNNNGGGG "
.STRING "CCCCOOOOMMMMPPPPAAAANNNNYYYY.... "
.STRING "DDDDEEEESSSSIIIIGGGGNNNNEEEEDDDD BBBBYYYY "
.STRING "GGGGEEEEOOOORRRRGGGGEEEE NNNN.... PPPPEEEETTTTRRRROOOO "
.STRING "JJJJAAAACCCCKKKK EEEE.... HHHHAAAAEEEEGGGGEEEERRRR "
.STRING "WWWWAAAARRRRRRRREEEENNNN BBBB.... DDDDAAAAVVVVIIIISSSS "
.STRING "BBBBIIIILLLLLLLL FFFF.... DDDDAAAABBBBEEEELLLLSSSSTTTTEEEEIIIINNNN "
.STRING "SSSSTTTTEEEEVVVVEEEE AAAA.... BBBBEEEERRRRAAAANNNN.... "
.STRING "YYYYAAAAHHHH MMMMOOOONNNN,,,, DDDDIIIISSSS BBBBEEEE"
.STRING " FFFFIIIIEEEERRRRCCCCEEEE!!!!"
.EVEN
**************************************************************************
* *
* POWERUP *
* *
* This section of code is Loaded and Executed from the Image *
* ROM area. Not only will it handle power-on diagnostics, *
* but it will also copy the program into RAM space. *
* *
* The 020 will have to be initialized properly and once *
* the copying is done, the DMA must get priority over the *
* image ROM. *
* *
**************************************************************************
.sect "COLDSTRT"
POWERUP
DINT
SETF 16,1,0 ;WORD SIGN EXTEND
SETF 32,1,1 ;LONG WORD
move @INT_REG,a8,1 ;Read Status Register
not a8 ;Invert it
andi 040000000h,a8 ;Mask off all but watchdog reset stat
srl 30,a8 ;Get it into bit 0
move a8,@DPYMSK,W ;Shove it into the DPYMSK Reg (WHAT???)
;NOTE - This register is NOT initialized by the INITDATA so it is protected
;from being overwritten. Also this register is ONLY used when midline-reload
;screen refresh cycles (which our hardware can NOT do) are enabled. So I am
;using it as temporary storage for the watchdog reset status. If the value
;is 0 (zero), the reset condition was normal, if it is 1 (one) the reset was
;caused by a watchdog timeout.
CLR A14
MOVE A14,@DMAGOREG,L
MOVE A14,@DMAGOREG,L ;DMA off for sure
MOVI INITDATA,B0
MOVI VESYNC,B2
MOVI IDATALEN,B7
BLMOVE 1,1 ;TRANSFER I/O REGS
movi DPYSTRT0,a14
move a14,@DPYST,L ;Make sure we're viewing the right one
.IF PRINTER
MOVE SP,@LASTSTACK,L ; PRESERVE VALUE OF THIS SUCKER
MOVE A0,@LASTA0,L ; A0 GONNA GET WASTED, TOO
.ENDIF
MOVI STCKST,SP,L
*
* Manual sound board reset. Yes, you will get the dongs.
*
.IF USING_UART
MOVI SYSC_COLD|(SND_RESET<<8),A0
MOVE A0,@SYSCTRL0,L ;Setup system control and
SRL 8,A0
MOVE A0,@SYSCTRL1,L ;Tug the sound board reset line
MSECWT 10 ;Wait for sound board to catch it
MOVI SYSC_COLD,A0
SRL 8,A0
MOVE A0,@SYSCTRL1,L ;Release the reset line
.ELSE
MOVI SYSC_COLD,A0 ;Grab cold start values
MOVE A0,@SYSCTRL0,L
srl 8,a0
MOVE A0,@SYSCTRL1,L
MOVI 0FE00H,A0 ;HIT RESET BIT
MOVE A0,@SOUND
MOVI (10*MICRO_SECOND)/2,A0 ;WAIT FOR SOUND BOARD TO CATCH
MOVI 0FFFFh,A0 ;LET IT GO
MOVE A0,@SOUND
.ENDIF
*
*Go do the Power On CPU test, make sure it doesn't touch the INT_REG.
*
.IF TEST_FIXTURE
JRUC POWERRET
.ENDIF
JAUC POWERTST ;DO THE PATENTED POWER UP TEST
POWERRET:
FCALL INITCOLR,B5 ; FIX UP THE COLORS
FCALL DSCRCLR,B6 ; MAKE SURE OF SCREEN
MOVI MESS_LOAD,A0
FCALL STRINGCENTER,B6 ; GET WIDTH OF STRING
ADDI [30,0],A1
CLR A2
MOVI COLOR_RED,A3
FCALL STRING,B6
MOVE A0,@WDOG_BONE ;Make the dog happy
* Load code here
MOVI vector_start,B0
MOVI vector_dest,B2
MOVI vector_end,B7
SUB B0,B7
BLMOVE 1,1 ;TRANSFER VECTORS
MOVE A0,@WDOG_BONE ;Make the dog happy
MOVI code_start,B0
MOVI code_dest,B2
MOVI code_end,B7
SUB B0,B7
BLMOVE 1,1 ;TRANSFER CODE, ZZZZZZ
*CHECK FOR A WATCH DOG SITUATION
; MOVE @INT_REG,A0,L ;XUNIT CHECK IF WATCHDOG WAS REAL
; BTST B_WDOG,A0 ;BIT SHOULD BE LOW IF DOG FIRED
; JRNZ NEWSETUP ;BR = VALID RESET, NOT WATCHDOG
;OK, now check the saved off version of the watchdog reset status - NOTE
;the saved off version is stored in the DPYMSK I/O register. This register
;is not used by us because it is only used for midline-reload screen refreshes
;which our hardware does NOT support. The value here will be 1 (one) if the
;reset was caused by a watchdog reset.
MOVE A0,@WDOG_BONE ;Make the dog happy
MOVE @DPYMSK,A0,W ;Veeerrry Interesting!!!!
JAZ WARMSET ;BR = VALID RESET, NOT WATCHDOG
JAUC DOG_SET ;Jump out of the nether regions
MESS_LOAD
.STRING "LOADING PROGRAM...",0
.EVEN
*
*End of COLD_START section
*
.TEXT
**************************************************************************
* *
* Warm start entry: Power on test are done, and code is loaded *
* *
**************************************************************************
*
* Come here to setup if we were the victim of a Watch Dog bite
*
DOG_SET
MOVI STCKST,SP,L
CLR A14
MOVE A14,@DMAGOREG,L
MOVE A14,@DMAGOREG,L ;DMA off for sure, for sure
MOVI SYSCINIT,A0 ;Make it so we can work, girl
MOVE A0,@SYSCOPY ;KEEP A COPY IN RAM
MOVE A0,@SYSCTRL0,L
srl 8,a0
MOVE A0,@SYSCTRL1,L
AUDIT AUDDOGGY ;CLICK A WATCH DOG RESET
MOVK 2,A14
getpc B14 ;Show where we are
CALLA DUMP_IT
.IF PRINTER
CALLA DOGGYPRINT ;LOG THE WATCH DOG TO THE PRINTER
.ENDIF
*
* Normal warm start
*
SETUP
WARMSET:
DINT
SETF 16,1,0 ;WORD SIGN EXTEND
SETF 32,1,1 ;LONG WORD
CLR A14
MOVE A14,@DMAGOREG,L
MOVE A14,@DMAGOREG,L ;DMA off for sure
MOVI STCKST,SP,L
*CLEAR SCRATCHPAD
CALLR CLSCRACH
MOVI SYSCINIT,A0 ;
MOVE A0,@SYSCOPY ; GET EVERYBODY HAPPY
MOVE A0,@SYSCTRL0,L ; XUNIT
srl 8,a0 ; XUNIT
move a0,@SYSCTRL1,L ; XUNIT
.IF TEST_FIXTURE
JRUC PCMOSRET ;****** TEST FIXTURE LINE ******
.ENDIF
**** JRUC PCMOSRET ;****** TEST FIXTURE LINE ******
**** .IF DEBUG
**** .ELSE
CALLR DIPINIT
JAUC POWERCMOS ;VERIFY CMOS AND PRINT OPENING MESSAGE
**** .ENDIF
PCMOSRET
CALLR MAIN_INIT ;DO NORMAL INITIALIZATIONS
CALLA TIMEINIT ;WHY MUST WE DO THIS?
EINT ;ENABLE INTERRUPTS AND WE'RE OFF
DISPON ;ENABLE THE DISPLAY SYSTEM
.if HDW_KLUDGE+TEST_FIXTURE
JRUC MAIN_GO ;****** TEST FIXTURE LINE ******
.endif
CALLA CKDIAG ;ARE ANY OF THE DIAG SWITCHES CLOSED?
JRZ MAIN_GUN ;BR = NO, CHECK THE GUN STUFF
CREATE PID_DIAG,DIAG ;FIRE OFF THE DIAG PROCESS
JRUC EXEC_LP ;AND THEN DISPATCH IT.
MAIN_GUN
CALLA INITIALIZE_CALIBRATION ;INITIALIZE THE CALIBRATION PARAMS
JRZ MAIN_GO ;BR = ALL IS WELL
CREATE PID_DIAG,GUN_CALIBRATE
JRUC EXEC_LP
MAIN_GO
CLR A0
MOVE A0,@COINFLAG,W ; NOT ON COIN PAGE YET
.IF PRINTER
CALLA T2ALIVE ; PRINT OUT "ALIVE" MESSAGE
.ENDIF
CALLA ATSTRT ;START ATTRACT MODE
**************************************************************************
* *
* START OF EXECUTIVE LOOP *
* *
**************************************************************************
EXEC_LP:
CALLA PRCDSP ;DISPATCH PROCESSES
MOVE A13,A13 ;DID PROCESS EXECUTE CORRECTLY?
JRZ EXEC_POK ;BR = YES
LOCKUP ;REPORT THE SITUATION
EXEC_POK:
CALLA SNDPRC ;DISPATCH AND TIME THE SOUND CALLS
; CALLA DRIVER_UPDATE ;TIME THE COILS
*
*UNSTACK THE VALID SWITCH CLOSURES AND ACTIVATE PROCESSES
*
MOVI ACTIVE,A13,L
MOVE @SWSTACK,A3,L
EXEC_UNSTKLP:
CMPI SWSTST,A3,L ;STACK AT START?
JREQ EXEC_UNSTKX ;YES, EXIT
MOVE @FREE,A0,L
JRZ EXEC_UNSTKX ;NO PROCESSES LEFT, TRY NEXT TIME AROUND
MOVE *A3+,A0,W ;GET ENTRY
MOVE A3,@SWSTACK,L ;UPDATE STACK
MOVE A0,A2
ADD A0,A2
ADD A0,A2 ;MULT BY 3
SLL 4,A2 ;ADJUST FOR WORD SIZE (16)
ADDI SWTAB,A2
MOVE *A2+,A1 ;GET PID
MOVE *A2+,A7,L ;GET STARTING ADDR
JREQ EXEC_UNSTKLP ;NULL ENTRY
MOVE @PAUSE_GAME,A0,W ;IS THE GAME IN PAUSE MODE?
JRZ EXEC_SWITCH_CREATE ;BR = NO, CONTINUE AS NORMAL
MOVE A1,A0 ;ANY DESTRUCTIBLE PROCESSES WILL
ZEXT A0 ;BE PAUSED BY THIS FLAG
SRL 13,A0
JRZ EXEC_UNSTKLP
EXEC_SWITCH_CREATE:
CALLA GETPRC
JRUC EXEC_UNSTKLP
EXEC_UNSTKX:
CALLA RANDOM ;RESEED THE RANDOM NUMBER GENERATOR
MOVE @EXECLED,A0,W
INC A0
MOVE A0,@EXECLED,W
CMPI 5,A0
JRLT EXEC_LP ;BR = NOT TIME TO BLINK THE EXEC LED
CLR A0
MOVE A0,@EXECLED,W
PUSHST
DINT
*
*DO SOME SYSCTRL STUFF WHILE INTERRUPTS ARE OFF
*
; MOVE @SYSCOPY,A0 ;BLINK L.E.D. TO ACK OPERATION
; XORI LED_ON<<8,A0 ; XUNIT
; MOVE A0,@SYSCOPY ; XUNIT
; srl 8,a0 ; XUNIT
; MOVE A0,@SYSCTRL1,L ; XUNIT
MOVB @SYSCOPY+8,A0 ;Blink L.E.D. to acknowledge exec XUNIT
XORI LED_ON,A0
MOVB A0,@SYSCOPY+8
MOVE A0,@SYSCTRL1,L
POPST
CALLR StCpuLft
JRUC EXEC_LP
**************************************************************************
* *
* END OF EXECUTIVE LOOP *
* *
**************************************************************************
**************************************************************************
* *
* StCpuLft - ROUTINE TO CALCULATE CPU TIME LEFT *
* *
**************************************************************************
StCpuLft:
move @TIMER,A0,W
jrz NoBog
movi EOSINT,a1
clr A1
jruc GotTime
NoBog:
movi EOSINT,A1
move @VCOUNT,A0
sub A0,A1
JRN StCpuLft_aBoRt ;BR = Something is strange with the value
movi 1000*10000H/EOSINT,A0
mpyu A0,A1
srl 16,A1
GotTime:
move A1,@CPULEFT,W
MOVE @CPULOW,A0,W
CMP A0,A1
JRGE NO_NEWLOW
MOVE A1,@CPULOW,W
NO_NEWLOW
MOVE @CPUHI,A0,W
CMP A0,A1
JRLE NO_NEWHI
MOVE A1,@CPUHI,W
NO_NEWHI
srl 3,A1
move @CPUAVG,A0,W
move A0,A2
srl 3,A2
sub A2,A0
add A0,A1
move A1,@CPUAVG,W
StCpuLft_aBoRt
rets
**************************************************************************
* *
* MAIN_INIT - CUMBERSOME SYSTEM INITIALIZATION STUFF, USED TO BRING *
* UP THE SYSTEM COLD. *
* RAM MUST BE O.K., STACK POINTER VALID AND FIELDS SET. *
* RETURNS *
* A13 = PROCESS ACTIVE LIST *
* *
**************************************************************************
MAIN_INIT
PUSH A0
MOVI INAMODE,A0
MOVE A0,@GAME_STATE,W
MOVI 0FFFFH,A0
MOVE A0,@SOUND_COPY,W ;INITIALIZE THE SOUND PORT COPY
MOVE A0,@A2D_COPY,W ;INITIALIZE THE A/D COPY
CALLR INITIO ;INITIALIZE THE I/O REGS
CALLR INIT_DMACONFIG ;INITIALIZE DMACONFIG REGISTER
*SET UP TI PIXEL PROCESSING REGS
CALLA SETPPROC
*INIT COLOR RAM
CLR A0
MOVE A0,@DMAGOREG,L ; XUNIT
MOVE A0,@DMAGOREG,L ; XUNIT OFF DMA
MOVE A0,@CMAPSEL ;CLEAR COLOR MAP SELECT
MOVE A0,@IRQLED
MOVE A0,@EXECLED
*CLEAR THE SCREEN
CALLA SCRCLR
*INITIALIZE RANDOM SEED
MOVI 81261A8CH,A0
MOVE A0,@RAND,L
*ENABLE DISPLAY INTERRUPT
MOVI DIE|X2E,A0
MOVE A0,@INTENB ;enable display interrupts
*Initialize the System interrupt register
MOVIM LINT2_INTS,@INT_REG,L
*INITIALIZE SWITCH STACK
MOVI SWSTST,A0
MOVE A0,@SWSTACK,L
*INITIALIZE SYSTEM CONTROL REGISTER
MOVI SYSCINIT,A0
MOVE A0,@SYSCOPY ;KEEP A COPY IN RAM
MOVE A0,@SYSCTRL0,L ; XUNIT
srl 8,a0 ; XUNIT
MOVE A0,@SYSCTRL1,L ; XUNIT
*INITIALIZE INTERRUPT RAM
**** MOVI SCOREINT,A0
**** MOVE A0,@SINTRAM,W ;SCORE AREA INTERRUPT
**** MOVI HSINT,A0
**** MOVE A0,@HSINTRAM,W ;HALF SCREEN INTERRUPT
*INITIALIZE DIP SWITCH OPTIONS
CALLR DIPINIT
*CLEAR ALL PLAYER DATA AREAS
CALLR CLR_ALL_PDATA
*RESET THE FLASH LAMPS
CALLA DRIVER_CLR
*INITIALIZE PROCESS AND DISPLAY LISTS AND START THE SYSTEM
CALLA PINIT ;INIT PROCESS LIST
CALLA OINIT ;DO THIS FIRST FOR THE DMA'S SAKE
CALLA MYOINIT ;INITIALIZE THE OBJECT LIST
CALLA CLEAR_PAGE2 ;Clear video bit map page 2
CALLA CLEAR_PAGE3 ;Clear video bit map page 3
*RESET THE SOUND BOARD - Must be called after the process system is init'd
; .if BILL
CALLA QSNDRST
; .else
; CALLA SNDRES
; .endif
PULL A0
RETS
**************************************************************************
* *
* INIT_DMACONFIG - INITIALIZE THE DMACONFIG *
* *
* CALL DIS UPON POWER UP *
* *
**************************************************************************
INIT_DMACONFIG
; MOVIM YMINTBL+SIZYMINTBL,@YMINPTR,L
; XUNIT ST
; PUSHST
; DINT
MOVIM DMACF4,@DMACONFIG,L ;ADJUST WINDOW RIGHT/LEFT BORDER
; .if CENTER_SCREEN
; MOVIM 511*10000H+0,@DMAWINDOW,L
; .else
; MOVIM SCRRGT*10000H+SCRLFT,@DMAWINDOW,L
; .endif
MOVIM (SCRRGT)*10000H+SCRLFT,@DMAWINDOW,L
MOVI DMAWIN|DMACF4,A14
MOVE A14,@DMACFIGCOPY,L
MOVE A14,@DMACONFIG,L ;LEAVE CONFIG'D FOR TOP/BOT ADJUSTMENT
; XUNIT END
; POPST
RETS
**************************************************************************
* *
* DIPINIT - INITIALIZE OPTIONS VIA DIP SWITCH SETTINGS *
* *
**************************************************************************
DIPINIT:
MMTM SP,A0,A1
CALLA READ_DIP ;LOAD UP THE CURRENT DIP SWITCH BITS
MOVE A0,A1 ;STORE FOR MULTIPLE USES
ANDI DPPLAYERS,A0 ;AQUIRE THE NUMBER OF PLAYERS
SRL 9,A0
ADDI PLNUM,A0
MOVB *A0,A0
MOVE A0,@NPLAYERS,W
MOVE A1,A0
ANDI DPMIRROR,A0 ;CHECK FOR NO MIRROR SETTING
JRZ DI_MIRRORNOT
MOVK 1,A0
DI_MIRRORNOT
MOVE A0,@NO_MIRROR,W
MOVE A1,A0
ANDI DPVALIDATOR,A0 ;Check for bill validator
JRZ DI_VALIDATOR_NOT ;BR = none
MOVK 1,A0
DI_VALIDATOR_NOT
MOVE A0,@VALIDATOR,W
MOVE A1,A0
ANDI DPKIT,A0 ;Check for T2 retrofit
JRZ DI_KIT_NOT ;BR = not this guy
MOVK 1,A0
DI_KIT_NOT
MOVE A0,@T2_KIT,W
MMFM SP,A0,A1
RETS
PLNUM .BYTE 2,1,0,0
.EVEN
**************************************************************************
* *
* ATSTRT - START THE ATTRACT MODE PROCESS *
* *
**************************************************************************
ATSTRT
MMTM SP,A0,A1,A7
MOVI INAMODE,A1
MOVE A1,@GAME_STATE,W
**** SOUNDOFF ;NO SOUNDS DURING A-MODE
.if HDW_KLUDGE
CREATE P1PID|PSTRTPID,PLAYER_START
.elseif TEST_FIXTURE
CREATE PID_PRINT,COIL_START ;****** TEST FIXTURE CODE *****
.ELSE
CREATE PID_INDW,ATTRACT_MODE
.endif
MMFM SP,A0,A1,A7
DUMRETS:
DUMCOL:
RETS
.IF TEST_FIXTURE
TEST1_MASK .EQU 1
TEST2_MASK .EQU 2
TEST3_MASK .EQU 4
COIL1_MASK .EQU 10H
COIL2_MASK .EQU 20H
COIL3_MASK .EQU 40H
.BSS CUR_COIL_TEST,16
**************************************************************************
* *
* COIL_START - PROCESS FOR Q.A. COIL TEST. *
* USES DIPSWITCHES TO SELECT TEST AND ACTIVATE COILS *
* *
* DS0 - 1 = 50% duty cycle all coils hit at once *
* DS0 - 2 = 33% duty cycle all coils hit at once *
* DS0 - 3 = Random coil test *
* DS0 - 4 = Not used *
* DS0 - 5 = Activate left coil (PLAYER 1) *
* DS0 - 6 = Activate middle coil (PLAYER 2) *
* DS0 - 7 = Activate right coil (PLAYER 3) *
* *
**************************************************************************
COIL_START
MOVI COIL1_MASK,A9
MOVI [GUN_COIL_ON,P1_RECOIL],A10
CREATE PID_PRINT,CT_HOLD ;START LEFT TEST
MOVE A0,*A13(PDATA),L
MOVI COIL2_MASK,A9
MOVI [GUN_COIL_ON,P2_RECOIL],A10
CREATE PID_PRINT,CT_HOLD ;START MIDDLE TEST
MOVE A0,*A13(PDATA+20H),L
MOVI COIL3_MASK,A9
MOVI [GUN_COIL_ON,P3_RECOIL],A10
CREATE PID_PRINT,CT_HOLD ;START RIGHT TEST
MOVE A0,*A13(PDATA+40H),L
CS_WAIT
SLEEP 2
CALLA READ_DIP ;LOAD UP THE CURRENT DIP SWITCH BITS
MOVI CT_TEST1,A9
MOVE A0,A11
ANDI TEST1_MASK,A11
JRNZ CS_DO_TEST
MOVI CT_TEST2,A9
MOVE A0,A11
ANDI TEST2_MASK,A11
JRNZ CS_DO_TEST
MOVI CT_TEST3,A9
MOVE A0,A11
ANDI TEST3_MASK,A11
JRNZ CS_DO_TEST
MOVE @CUR_COIL_TEST,A14,W
JRZ CS_WAIT
CLRM @CUR_COIL_TEST,W
CALLR HOLD_TEST
SLOOP 8,CS_WAIT
CS_DO_TEST
MOVE @CUR_COIL_TEST,A14,W
CMP A11,A14 ;Same test?
JREQ CS_WAIT ;BR = Yes
MOVE @CUR_COIL_TEST,A14,W
JRZ CS_XFER_TEST
CALLR HOLD_TEST
SLEEP 10 ;Finish off all old processing
CS_XFER_TEST
MOVE A11,@CUR_COIL_TEST,W
MOVE A9,A7 ;Start new test
MOVE *A13(PDATA),A0,L
CALLA PUTWAKE
MOVE *A13(PDATA+20H),A0,L
CALLA PUTWAKE
MOVE *A13(PDATA+40H),A0,L
CALLA PUTWAKE
JRUC CS_WAIT
HOLD_TEST
MOVI CT_HOLD,A7 ;Hold all procs
MOVE *A13(PDATA),A0,L
CALLA PUTWAKE
MOVE *A13(PDATA+20H),A0,L
CALLA PUTWAKE
MOVE *A13(PDATA+40H),A0,L
JAUC PUTWAKE
*
*COIL TEST HOLDING PEN
*
CT_HOLD
SLOOP 100,CT_HOLD
*
*DUTY CYCLE COIL AT FASTEST POSSIBLE RATE DURING GAME PLAY
*
CT_TEST1
CALLA READ_DIP
AND A9,A0
JRZ CTT1_SKIP
MOVE A10,A0
CALLA COIL_DRIVE
CTT1_SKIP
SLOOP GUN_COIL_ON+2,CT_TEST1
*
*DUTY CYCLE COIL AT 50% OF FASTEST POSSIBLE RATE DURING GAME PLAY
*
CT_TEST2
CALLA READ_DIP
AND A9,A0
JRZ CTT2_SKIP
MOVE A10,A0
CALLA COIL_DRIVE
CTT2_SKIP
SLOOP GUN_COIL_ON+4,CT_TEST2
*
*RANDOM COIL DUTY CYCLE
*
CT_TEST3
CALLA READ_DIP
AND A9,A0
JRZ CTT3_SKIP
MOVE A10,A0
CALLA COIL_DRIVE
CTT3_SKIP
MOVK GUN_COIL_ON+2,A0
MOVK GUN_COIL_ON+6,A1
CALLA RANGERND
SLOOPR A0,CT_TEST3
.ENDIF
**************************************************************************
* *
* PLAYER_START - PROCESS TO START A PLAYER INTO THE GAME. IF THE GAME *
* IS IN ATTRACT MODE, OR GAME OVER, THEN WE WILL START *
* A FRESH GAME. OTHERWISE, THE PLAYER WILL BE ADDED TO *
* THE CURRENT GAME. *
* *
**************************************************************************
PLAYER_START:
.IF TEST_FIXTURE
DIE
.ENDIF
INCM @SWITCH_ESCAPE,W
MOVE *A13(PROCID),A4,W
MOVE A4,A0
CALLA EXISTP_ALL
JRNE PLAYER_X ;BR = PROCESS ALREADY HERE, BYE
MOVE A4,A0
SLL PNUM_SLL,A0
SRL PNUM_SRL,A0
DEC A0
MOVE @NPLAYERS,A1,W
CMP A1,A0 ; CHECK FOR GAME CONFIG PLAYERS
JRHI PLAYER_X ; CAN'T START, DUDE!
MOVE A0,A9
CALLA GPLAYD ;GET THE PLAYER'S DATA AREA
MOVE @GAME_STATE,A3,W
CMPI INDIAG,A3
JREQ PLAYER_FLAG_X ;TEST MODE, NO DICE, CLAY.
CMPI INEPILOG,A3
JREQ PLAYER_FLAG_X ;NO STARTS DURING EPILOG
CMPI INAMODE,A3 ;IN ATTRACT MODE?
JREQ PLAYER_START_GAME ;GO RIGHT FOR THE THROAT
CMPI INGAMEOV,A3 ;IN GAME OVER
JREQ PLAYER_START_GAME ;GO RIGHT FOR THE THROAT
MOVE *A2(POBJ),A8,L ;DOES HE ALREADY EXIST?
JRNE PLAYER_FLAG_X ;BR = YES, AND FLAG THE ESCAPE
MOVE @OFREECNT,A14,W ;ARE THERE OBJECTS TO BE HAD?
JRZ PLAYER_FLAG_X ;BR = NO, WE WILL NOT ATTEMPT
MOVE *A2(PSTARTS),A1,W ;GET THE NUMBER OF STARTS
JRNZ PLAYER_CONT ;BR = NOT STARTING, CONTINUING
*
* This is the players first start, and he's joining a game in progress
*
PLAYER_INSTANT:
CALLA CR_STRTP
JRLO PLAYER_BUYIN_X ;BR = NOT ENOUGH CREDITS, JUST XIT
CALLA P_START ;TAKE A CREDIT
.IF PRINTER
CALLA PGAMESTART
.ENDIF
JRUC PLAYER_COOL
*
* Game is currently in Game Over, start a new one!
*
PLAYER_START_GAME
CALLA CR_STRTP
JRLO PLAYER_X_NO_CRED ;BR = NOT ENOUGH CREDITS, MAKE SOUND
CALLA P_START ;TAKE A CREDIT
.IF PRINTER
CALLA PGAMESTART
.ENDIF
JRUC PLAYER_COOL
*
* Player is continuing a game he's already been part of
*
PLAYER_CONT:
CALLA ALLOW_CONTINUE ;IS CONTINUE ALLOWED?
JRZ PLAYER_X ;BR = NO
CALLA CR_CONTP ;DOES HE HAVE ENOUGH TO CONTINUE?
JRLO PLAYER_BUYIN_X ;BR = NO
CALLA P_CONT ;DECREMENT COST OF CONTINUE
.IF PRINTER
CALLA PGAMECONT
.ENDIF
*
*A2 = PLAYER DATA
*A3 = GAME STATE
*A9 = PLAYER NUMBER
PLAYER_COOL:
CALLR LOAD_LIVES
MOVK 1,A0
MOVE A0,*A2(PENTER),W ;MARK THIS DUDE READY TO ENTER
MOVE @GAME_STATE,A0,W
CMPI INAMODE,A0
JREQ PLAYER_1ST ;AHHH THE FIRST TO PLAY, WELCOME
CMPI INGAMEOV,A0
JREQ PLAYER_1ST ;RESTART THE GAME, HOW INTERESTING
CLRM *A2(PDEAD),W
CMPI ININTRO,A0
JREQ PLAYER_STARTLP ;NO HILITE IN THE INTRO SEQUENCE
CMPI INGAME,A0
JRNE PLAYER_SOUND
PLAYER_HILITE:
CALLA UPDSL
PLAYER_SOUND:
SOUND1 SND_PLAYER_START ;Make it know that we are here man.
PLAYER_STARTLP:
MOVE @GAME_STATE,A0,W ;WAIT FOR GAME PLAY TO COMMENCE
CMPI INPLAY,A0
JREQ PLAYER_ADD
CMPI INGAMEOV,A0 ;HAVE WE SOMEHOW GOTTEN INTO GAMEOVER
JREQ PLAYER_CLRLIFE_X ;BR = YES
MOVE A2,A8 ;WAIT FOR GAME TO START OR END
SLEEP 4
MOVE A8,A2
JRUC PLAYER_STARTLP
PLAYER_1ST:
PUSHP A2 ;STARTING FROM AMODE OR GAME OVER
.IF DEBUG
JSRP GAME_START
.ELSE
FCALL SECURITY,B0
MOVE @SEC_FLAG,A14,W
JRZ P1ST_SEC_OK
AUDIT AUDSECURITY ;SHOW THE SECURITY BREECH
CALLR ATSTRT
DIE
P1ST_SEC_OK
MOVE *A12,A2,L ;RETRIEVE PLAYER DATA PTR
JSRP GAME_START
.ENDIF
PULLP A2
PLAYER_ADD:
CALLR PLAYER ;MUST CALL THIS BEFORE YOU INC PWAVEST
JRZ PLAYER_CLRLIFE_X ;COULDN'T CREATE THE DUDE
MOVE *A2(PSTARTS),A0,W ;HAVE WE STARTED BEFORE?
JRNZ PLAYER_BUYIN ;BR = NON-VIRGIN
*DO THIS STUFF ON INITIAL PLAYER START ONLY
INC A0
MOVE A0,*A2(PSTARTS),W
AUDIT AUDSTART
JRUC PLAYER_INIT
*DO THIS STUFF ON BUY-IN ONLY
PLAYER_BUYIN:
INC A0
MOVE A0,*A2(PSTARTS),W
AUDIT AUDCONTTAKEN ;CLICK A CONTINUE TAKEN
*
* Give Bozo message if player is not firing enough CDs
*
MOVE *A2(PROCKSFIRED),A1,W
CMPK 5,A1 ;DID HE ACTUALLY FIRE SOME BOMBS?
JRHI PLAYER_INIT ;BR = YES
MOVI ALTWEAP_TAB_3P,A0
MOVI ALTWEAP_TAB_2P,A1
CALLA DO_HEADS_UP ;FLASH A MESSAGE IN HIS FACE
*THINGS TO RE-INITIALIZE EVERY TIME SOMEONE STARTS OR BUYS IN
PLAYER_INIT:
INCM @CURPLYRS,W ;INCREMENT THE PLAYER COUNT
INCM *A2(PWAVEST),W ;INCREMENT THE STARTS THIS WAVE
CLRM *A2(PROCKSFIRED),W ;ANOTHER CHANCE TO WAIL
*EXTRA MAN BULLSHIT
ADJUST ADJNUMEXTRA ;SOCIALIST OPERATOR?
JRNZ PLAYER_FIXED_EXTRA ;BR = YES
MOVI 7FFFH,A0 ;A MILLION!
PLAYER_FIXED_EXTRA
MOVE A0,*A2(PEXTRAS),W ;NO EXTRA MEN SO FAR
ADJUST ADJEXTRA
MOVE *A2(PSCORE),A1,L
ADD A1,A0
MOVE A0,*A2(PNEXTREP),L ;AND STORE IT
CALLA UPDSL ;UPDATE THE STATUS AREA OF THIS PLAYER
*
*PLAYER EXIT POINT
*
PLAYER_X:
DIE
*
*PLAYER EXITS BECAUSE HE HAS NO CREDITS, AND IT'S GAME OVER
*
PLAYER_X_NO_CRED
MOVE @GAME_STATE,A0,W
CMPI INAMODE,A0
JRNE PLAYER_X
ADJUST ADJMUSIC ;SOUNDS IN ATTRACT MODE?
JRNZ PLAYER_X ;BR = NO BABY
MOVE @SWITCH_SPOKEN,A0,W ;HAS HE SPOKEN LATELY?
JRNZ PXNC_NOSPEAK ;BR = YES, THEN DO NOT SPEAK AGAIN
MOVKM 1,@SWITCH_SPOKEN,W
CLRM @AMODE_LOOPS,W
SOUNDON
SOUND1 START_SWITCH_X_SND
PXNC_NOSPEAK
DIE
*EXIT HERE IF START FAILURE AFTER LIFE HAS BEEN GIVEN
*A2 = PTR TO PLAYER DATA AREA
PLAYER_CLRLIFE_X:
CLR A0
MOVE A0,*A2(PLIVES),L
JRUC PLAYER_X
*
*EXIT HERE IF YOU WISH TO MAKE IT KNOWN THAT THE START BUTTON WAS PRESSED
*A2 = PTR TO PLAYER DATA AREA
PLAYER_FLAG_X
MOVK 1,A0
MOVE A0,*A2(PSTARTESC),W
JRUC PLAYER_X
*
* Exit here if player was attempting to buy-in to a game in progress
*
PLAYER_BUYIN_X
MOVE @BUYNOW,A14,W
JRZ PLAYER_X ;BR = Not in Buy-in mode
MOVE @BUYIN_RESETS,A14,W
JRZ PLAYER_X ;Br = No Buy-in resets left
DEC A14
MOVE A14,@BUYIN_RESETS,W ;We just did another one
MOVIM BUYTIME,@BTIME,W ;Reset the Buy-in timer
JRUC PLAYER_X
*
*PLAYER START SOUND TABLE
*
SND_PLAYER_START
.WORD 0F2FDH,41,0880AH,0 ;"Let's Go!"
*SOUND TO BE MADE WHEN PERSON HITS THE START BUTTON WITH TOO FEW CREDS.
START_SWITCH_X_SND
.WORD 0F305H,23,082AEH,0 ;"Hey"
**************************************************************************
* *
* PLAYER - ROUTINE TO START A PLAYER OBJECT AN ADD IT TO THE DISPLAY. *
* A2 = INDEX TO PLAYER DATA AREA UPON CREATION. *
* RETURNS: *
* Z = FAILURE TO CREATE, NO PLAYER ADDED *
* NZ = SUCCESS *
* A8 = PLAYER OBJECT *
* NOTE: TRASHES A14 *
* *
**************************************************************************
PLAYER:
MMTM SP,A1,A7,A10,A11
MOVE *A2(PINITAB),A5,L ;GET THE INITIALIZATION TABLE
CALLA CREATE_OBJ
JRZ PLAYERX ;BR = WE FAILED TO GET AN OBJECT
MOVE A0,*A2(POBJ),L
MOVE A0,A8
MOVE *A2(PCURSORXY),A3,L
CALLA OBJ_TO_PNT
MOVIM PIZPOS,*A8(OZPOS),W ;STUFF THE FRONT Z
MOVE @GAME_STATE,A14,W
CMPI INGAMEOV,A14
JREQ PLAYER_INSERT ;BR = High score entry
CMPI INBONUS,A14
JREQ PLAYER_INSERT ;BR = Player wave select screen
CALLR GUNPOWER_TO_MAX
CLR A0
MOVE A0,*A2(PDEAD),W
MOVE A0,*A2(PENTER),W
MOVE A0,*A2(PINVINCIBLE),W ;THIS MUST BE ZERO'D IN CASE OF ERROR
MOVE A0,*A2(PFIRING),W ;NO LONGER DOES HE FIRE
MOVE A0,*A2(PPOWERHEADS),W ;RE-ACTIVATE HEADS-UP DESCRIPTIONS
MOVB A0,*A2(PROCKCNT)
MOVE @WAVEIRQS,A0,L
MOVE A0,*A2(PTRACETIME),L ;TIME OF LAST TRACER CREATION
MOVE *A2(PPID),A0,W
ORI PID_SHUTDOWN,A0
CALLA KILLPROC_ALL ;KILL THE SHUTDOWN PROCESS
MOVI 400,A10
CALLA START_INVINCIBILITY
CALLA CLR_HEADS_UP ;KILL ANY PLAYER HEADS UP MESSAGES
PLAYER_INSERT
CALLA INSERT_OBJ
MOVE A8,A8
PLAYERX
MMFM SP,A1,A7,A10,A11
RETS
*
*PLAYER OBJECT INITIALIZATION TABLES
*
P1INIT
.LONG p1sight,DUMCOLL
.WORD OID_P1, DMAWNZ, M_SCRNOBJ|M_NOSCALE, 0
.LONG C_PSIGHT
P2INIT
.LONG p2sight,DUMCOLL
.WORD OID_P2, DMAWNZ, M_SCRNOBJ|M_NOSCALE, 0
.LONG C_PSIGHT
P3INIT
.LONG p3sight,DUMCOLL
.WORD OID_P3, DMAWNZ, M_SCRNOBJ|M_NOSCALE, 0
.LONG C_PSIGHT
*
*CREATE FUNC FOR PLAYER SIGHT
*
C_PSIGHT
MOVIM 0F0FH,*A0(OCONST),W
RETS
**************************************************************************
* *
* PLAYER_KILL - PROCESS TO KILL A PLAYER. HANDLES THE BUY-IN WINDOW AND *
* ALL THE FIXINS'. *
* A11 = PTR TO PLAYER DATA AREA *
* *
* NOTE: MAKE ABSOLUTELY SURE THAT THE PROCID HAS THE "WAVE END WAIT" AND *
* "WAVE END WILL NOT KILL" BITS SET. *
* *
**************************************************************************
PLAYER_KILL
CREATE PID_INDW,SCORE_GAME_OVER
SOUND1 PLAYER_KILL_SND
MOVE A11,A2
CALLR PLAYER_DELETE ;DELETE THIS PLAYER
JRNE PK_DIE ;GAMES NOT OVER
CALLR ALLOW_CONTINUE ;DO WE ALLOW CONTINUES?
JAZ GAME_OVER ;BR = NO
PK_BUY_CREATE_LP
CREATE PID_BUYIN,BUYINWIN ;CREATE BUYIN WINDOW
JRNZ PK_BUY_FLAG
SLOOP 4,PK_BUY_CREATE_LP
PK_BUY_FLAG
MOVK 1,A0
MOVE A0,@BUYNOW,W
PK_BUY_WAIT
*WAIT ON BUYIN MESSAGE TO CRUISE
MOVE @BUYNOW,A0,W
JRZ PK_BUY_DONE ;BR = WINDOW IS GONE.
SLOOP 1,PK_BUY_WAIT
PK_BUY_DONE
MOVE @CURPLYRS,A0,W ;IS THERE A NEW DUDE?
JAZ GAME_OVER ;BR = NO
PK_DIE
DIE
PLAYER_KILL_SND
.WORD 0F3F0H,58,0881FH,0 ;"Don't give up!"
**************************************************************************
* *
* PLAYER_DELETE - DELETE THIS PLAYER'S OBJECT AND REMOVE HIM FROM THE *
* GAME, YEAH BOY! *
* A2 = PTR TO PLAYER DATA AREA *
* *
**************************************************************************
PLAYER_DELETE
MMTM SP,A0,A1,A11
MOVE *A2(PPID),A0,W
MOVI M_INDESTRUCT|MASK_PLAYER,A1
CALLA KILALL ;KILL THE PLAYER PROCESSES
MOVE *A2(POBJ),A0,L
CALLA DELOBJ ;REMOVE THE SHIT
CALLR PLAYER_CLR ;CLEAR OUT PLAYER GAME DATA
CALLR ALLOW_CONTINUE
JRZ PD_NOBUYIN
AUDIT AUDCONTOFFER ;CLICK A CONTINUE OFFERED
PD_NOBUYIN
MOVE @CURPLYRS,A0,W
DEC A0 ;KNOCK DOWN THE PLAYER COUNT
MOVE A0,@CURPLYRS,W
MMFM SP,A0,A1,A11
RETS
**************************************************************************
* *
* ALLOW_CONTINUE - ROUTINE TO DETERMINE IF WE SHOULD ALLOW THIS GUY TO *
* CONTINUE. *
* A2 = PTR TO PLAYER DATA AREA *
* RETURNS *
* Z = NOT ALLOWED *
* NZ = ALLOWED *
* NOTE: TRASHES A14 *
* *
**************************************************************************
ALLOW_CONTINUE
PUSH A0
ADJUST ADJBUYIN ;ARE GAME CONTINUES ALLOWED?
PULL A0
RETS
**************************************************************************
* *
* PLAYER_CLR - ROUTINE TO CLEAR THE PLAYER ACTIVE FIELDS. *
* A2 = PTR TO THE PLAYER *
* *
**************************************************************************
PLAYER_CLR
MMTM SP,A0,A1,A7,A11
CLR A0
MOVE A0,*A2(POBJ),L ;CLEAR THIS OUT
MOVE A0,*A2(PENTER),W ;CLEAR THE GAME ENTRANCE WAITING FLAG
MOVE A0,*A2(PLIVES),L ;JUST TO MAKE SURE HE IS DEAD
MOVE A0,*A2(PFIRING),W ;CLEAR THE PLAYER FIRING FLAG
MOVE A0,*A2(PLASTLPLOT),L
MOVB A0,*A2(PROCKCNT)
CALLA PLAYER_RECOIL_OFF
**** MOVE *A2(PSCORE),A0,L
**** CALLA UPDSL ;TURN IT DOWN MANG!
CALLR DELETE_PSTATUS
CALLR GPLAYNUM
SLL 4,A0
ADDI P_TRIG_TAB,A0
MOVE *A0,A1,W
CLR A0
BSET A1,A0
ORM A0,@SWTEMP1,L
ORM A0,@SWTEMP2,L ;CLEAR THE SWITCH DEBOUNCE TO RE-TRIGGER
MMFM SP,A0,A1,A7,A11
RETS
*TABLE OF PLAYER TRIGGER SWITCH VALUES
P_TRIG_TAB
.WORD P1TRIGGER,P2TRIGGER,P3TRIGGER
**************************************************************************
* *
* PLAYER_RESET_RESTART *
* *
* Same as PLAYER_RESTART, except does not clear the bonus *
* counters. *
* *
* A2 = Ptr to player *
* *
**************************************************************************
PLAYER_RESET_RESTART
PUSH A0
CLR A0
JRUC PRS_NOCLEAR
**************************************************************************
* *
* PLAYER_RESTART - RESTART A PLAYER IF HE EXISTED BEFORE. THIS IS *
* USED FOR STARTING A NEW WAVE. *
* A2 = PLAYER INDEX *
* NOTE: CALL ONLY AFTER RE-INITIALIZING THE DISPLAY SYSTEM *
* *
**************************************************************************
PLAYER_RESTART:
PUSH A0
CLR A0
MOVE A0,*A2(PWAVEDEATHS),W
MOVE A0,*A2(PWAVETIME),L ;START FROM ZERO
MOVB A0,*A2(PCASUALTY)
MOVE A0,*A2(PDAMAGE),W
MOVE A0,*A2(PGIRLS_SAVED),W
MOVE A0,*A2(PMAMMY),W
PRS_NOCLEAR
MOVE *A2(POBJ),A0,L
JREQ PLAYER_RSX ;BR = THIS GUY WAS NOT AROUND
CALLR PLAYER ;MUST CALL THIS BEFORE YOU INC PWAVEST
INCM *A2(PWAVEST),W ;INCREMENT THE START COUNT
PLAYER_RSX:
PULL A0
RETS
*
* PLAYER_BONUS_RESTART
*
* Special routine to star the player's for wave selection during
* the bonus screen.
*
* A2 = Ptr to player data block
*
PLAYER_BONUS_RESTART:
MOVE *A2(POBJ),A14,L
JREQ PLAYER_BRSX ;BR = THIS GUY WAS NOT AROUND
CALLR PLAYER ;MUST CALL THIS BEFORE YOU INC PWAVEST
PLAYER_BRSX:
RETS
.IF DEBUG
SWAVE .WORD 2 ;TEST STARTING WAVE NUMBER
.ELSE
SWAVE .WORD 1 ;REAL STARTING WAVE
.ENDIF
**************************************************************************
* *
* GAME_START - START OF GAME ROUTINE, THIS WILL HANDLE ALL THINGS THAT *
* MUST BE DONE. *
* A2 = PLAYER DATA AREA OF PLAYER STARTING THE GAME *
* NOTE: NO REGISTERS ARE GUARANTEED *
* CALL WITH JSRP *
* *
**************************************************************************
GAME_START:
calla INIT_LINKED_LIST ; init bg univ links
AUDIT AUDGSTARTS ;Audit the game starting
MOVI PID_TFADE,A0
CALLA KILLPROC_ALL ;Kill the music fader
CALLA QSNDRST
CALLR WIPEOUT ;WIPE OUT THE WORLD
CALLR GRAMINIT ;INITIALIZE GAME RAM
CALLR GAME_DIFFICULTY ;INITIALIZE GAME DIFFICULTY PARAMS
CALLR CLR_ALL_PDATA ;INITIALIZE PLAYER DATA AREAS
CALLA CLEAR_HSCOLORS ; CLEAR HIGHSCORE COLORS
MOVK 1,A0 ;THESE 2 INSTRUCTIONS AFTER CLR_ALL_PDATA
MOVE A0,*A2(PENTER),W ;YEAH! YEAH! DUDE IS READY TO PLAY!
.IF DEBUG
MOVE @SWAVE,A0,W
CMPK 1,A0
JREQ GS_SET_SWAVE
ADJUST ADJSWAVE
INC A0
GS_SET_SWAVE
MOVE A0,@WAVE,W
.ELSE
ADJUST ADJSWAVE ;Grab the starting wave
MOVE A0,@WAVE,W
.ENDIF
; MOVE @SWAVE,@WAVE,W ;WAVE TO START
CALLR LOAD_LIVES
DISPON ;DISPLAY SYSTEM BACKON
MOVI ININTRO,A0
MOVE A0,@GAME_STATE,W ;SECRETARY OF STATE
JSRP GAME_INTRO
CREATE PID_INDW,SCORPROC ;START UP THE PUSH PLAYER START PROCESS
MOVI INGAME,A0
MOVE A0,@GAME_STATE,W
CLRM @NO_WAVE_INTRO,W
JSRP WAVE_START ;DO THE WAVE INITIALIZATION
RETP
**************************************************************************
* *
* GAME_DIFFICULTY - SETUP GAME DIFFICULTY PARAMETERS *
* USES THE THE GAME ADJUSTMENT ADJDIFF AS THE CURRENT DIFFICULTY *
* *
**************************************************************************
GAME_DIFFICULTY:
MMTM SP,A0,A1,A2,A3,A4,A6,A7,A8
ADJUST ADJDIFF ;GET MASTER DIFFICULTY
CMPI MAXDIFF,A0
JRLS GDIFF_OK ;BR = DIFFICULTY SETTING IS O.K.
MOVI MAXDIFF,A0 ;INSERT MAXIMUM ALLOWED DIFFICULTY
GDIFF_OK:
SUBK 2,A0
MOVI GDIFF_RAM_ST,A2
MOVI GAME_DIFF_TAB,A3
GDIFF_LP:
MOVE *A3+,A7,W ;GET DIFFICULTY DELTA
MOVE *A3+,A6,W ;GET MIN
MOVE *A3+,A4,W ;GET MAX
MOVE *A3+,A8,W ;GET GAME VALUE
MPYS A0,A7
ADD A7,A8 ;ADD IN DELTA
CMP A8,A6
JRLE GDIFF_MIN ;CHECK FOR MIN
MOVE A6,A8
JRUC GDIFF_MAX
GDIFF_MIN:
CMP A8,A4 ;CHECK FOR MAX
JRGE GDIFF_MAX
MOVE A4,A8
GDIFF_MAX:
MOVE A8,*A2+,W ;STORE IT AWAY
CMPI GDIFF_RAM_END,A2
JRLO GDIFF_LP ;NOT DONE
MMFM SP,A0,A1,A2,A3,A4,A6,A7,A8
RETS
**************************************************************************
* *
* GAME_INTRO - INTRODUCTION AT GAME START *
* A2 = PTR TO PLAYER THAT STARTED THIS GAME. *
* EXPECTATIONS: *
* - DISPLAY SYSTEM ON *
* - ALL DISPLAY LISTS CLEAR *
* - ALL DISPLAY PAGES CLEAR *
* - AUTO ERASE OFF *
* NOTE: A8,A9,A10,A11 ARE DESTROYED *
* ALSO TRASHES PTEMP1 & PTEMP2. *
* CALL WITH JSRP *
* *
**************************************************************************
GAME_INTRO:
*PRINT THE PREVIEW MESSAGE
**** DISPOFF
.if BILL
.else
SOUND1 GAMEINTRO1_SND
.endif
**** CALLA SINGLE_PLANE ;START US ONE PLANE OF FOREGROUND
**** CLRM @SCRNTL,L ;RE-ADJUST SCREEN BOUNDRIES
**** MOVKM 3,@GAMERASE,W ;AUTO-ERASE FULL
**** MOVIM 01E0H,@SKYCOLOR,W
**** MOVI PREVIEW_MESS,A8
**** JSRP LM_PRINTF
**** MOVI 800H,A9
**** CREATE PID_SKY,SKYUP
**** CLR A0 ;FADE ALL PALETTES AT THIS TIME
**** CALLA FADEINS
**** DISPON
**** SLEEP 60
**** MOVI 60,A0
**** JSRP SLEEP_SWITCHX
**** CLR A0
**** CALLA FADEOUT
**** MOVI 1000H,A9
**** CREATE PID_SKY,SKYDOWN
**** SLEEP 15
**** CALLA CLRTEXT
**** SLEEP 5
MOVI SCRNST,A0,L ;INIT SCREEN TOP LEFT [Y,X]
MOVE A0,@SCRNTL,L
MOVI SCRNEND,A0,L ;INIT SCREEN LOWER RIGHT [Y,X]
MOVE A0,@SCRNBR,L
CLRM @GAMERASE,W
CALLA MYOINIT
DISPON
*END OF PREVIEW MESSAGE
CALLA SCORAREA
CALLA GET_CSTR
CALLA G_CREDONLY ;UPDATE THE WAVE DISPLAY
*INTIALIZE GLOBAL START PLAYER VARIABLES
CALLR GPLAYNUM
MOVE A0,@SPLAYER_NUM,W ;STORE FOR THE REST OF THE WORLD
MOVE A0,A5
SLL 4,A5
ADDI HBOX_COLORS,A5
MOVE *A5,A5,W
MOVE A5,@SPLAYER_COL,W
SLEEP 2 ;Let all of the DMAs clear
PUSHP A2
JSRP INIT_SBOMB_PAGE
PULLP A2
; PUSHP A2
; SLEEP 40
; PULLP A2
RETP
GAMEINTRO1_SND
.WORD 0F1FDH,40,8310H,0
*
*HELP BOX DUXPAL COLOR ASSIGNMENTS FOR EACH PLAYER
HBOX_COLORS:
.WORD COLOR_RED, COLOR_BLUE, COLOR_YELLOW
**************************************************************************
* *
* ATT_WAVE_START - ATTRACT MODE WAVE START ROUTINE. SAME AS WAVE *
* START EXCEPT YOU PROVIDE THE TABLE. *
* A0 = PTR TO WAVE TABLE *
* NOTE:CALL WITH JSPR *
* *
**************************************************************************
ATT_WAVE_START
CALLA WRAMINIT
CALLR WAVE_DIFFICULTY
MOVKM 1,@WAVE,W
JRUC WAVE_START_IMM
**************************************************************************
* *
* WAVE_START - ROUTINE TO CALL AT THE BEGINNING OF EACH WAVE. *
* THIS WILL LEAD THE GAME INTO PLAY (GAME_STATE = INPLAY). *
* EXPECTATIONS: *
* - DISPLAY SYSTEM ON *
* - PAGE FLIPPING OFF or ON *
* - ALL DISPLAY LISTS CLEAR *
* - ALL DISPLAY PAGES CLEAR *
* - AUTO ERASE OFF *
* @WAVE = WAVE # JUST STARTING *
* NOTE: CALL WITH JSRP *
* *
**************************************************************************
WAVE_START:
CALLA INIT_LINKED_LIST ;Initialize the Background links
CALLA WRAMINIT
CALLR WAVE_DIFFICULTY
ADJUST ADJVIOLENCE ;Load the level of violence.
DEC A0 ;Done here in case of attract mode
MOVE A0,@VIOLENCE_LEVEL ;game play.
MOVE @WAVE,A0,W
; CMPI RESET_WAVES,A0 ;IS THIS A RESET WAVE?
; JRHS WAVE_START_NORM ;BR = YES
; MOVE @GAME_STATE,A1
; CMPI INAMODE,A1
; JREQ WAVE_START_NORM ;BR = In attract mode, just do it
; CMPI LAST_WAVE,A0
; JRLE WAVE_START_NORM
; JRUC WAVE_LAST_DUDE
; MOVI LAST_WAVE,A0 ;STICK AT THE TOP WAVE
;WAVE_START_NORM:
DEC A0
SLL 5,A0
ADDI WAVE_TABLE,A0
MOVE *A0,A0,L ;WE HAVE THE TABLE FOR THIS WAVE
*A0 = PTR TO WAVE TABLE
WAVE_START_IMM
*LOAD WAVE DISPATCH TABLE
MOVE *A0+,A1,L
MOVE A1,@DISPATCH_TABLE,L ;NEW DISPATCH TABLE
*LOAD WAVE TUNE SCRIPT
MOVE *A0+,A1,L
MOVE A1,@WAVE_MUSIC,L ;CALL THIS LATER
*LOAD STARTING WORLDX
MOVE *A0+,A1,L
; MOVE A1,@WORLDX,L ;Until we find a better way
*LOAD BACKGROUND INFINITY PLANE
MOVE *A0+,A1,L
MOVE A1,@WAVE_IPLANE,L
*LOAD SCROLL ROUTINE
MOVE *A0+,A1,L
MOVE A1,@WAVE_SCROLL,L
*LOAD PORTAL TABLE
MOVE *A0+,A1,L
MOVE A1,@WAVE_PORTAL_TBL,L
*LOAD INITIAL UNIVERSE VECTOR TABLE
MOVE *A0+,A1,L
MOVE A1,@WVT_PTR,L
.if DEBUG
MOVE *A0+,A1,L
MOVE A1,@YWORLD,L
MOVE *A0+,A1,L
MOVE A1,@YHALF,W
MOVE *A0+,A1,L
SLL ZFRAC,A1 ; convert to hi res
MOVE A1,@ZREL_OFF,L
MOVE *A0+,A1,L
MOVE A1,@YREL_OFF,L
.else
clr a14
move a14,@ZREL_OFF,L
move a14,@YREL_OFF,L
.endif
*LOAD UNIVERSE
MOVE *A0+,A1,L
MOVE A1,@WAVE_UNIV,L
*LOAD UNIVERSE X
MOVE *A0+,A1,L
MOVE A1,@XBASE,L
*LOAD UNIVERSE Y
MOVE *A0+,A1,L
MOVE A1,@YBASE,L
*LOAD UNIVERSE Z
MOVE *A0+,A1,L
MOVE A1,@ZBASE,L
sll ZFRAC,a1
MOVE A1,@ZBASE_HR,L
*LOAD NEXT SUB-WAVE
MOVE *A0+,A1,L
MOVE A1,@WAVE_SUB,L
*LOAD WAVE INTRO SEQUENCE
MOVE *A0+,A1,L
MOVE A1,@WAVE_INTRO,L ;INSTRUCTIONS TO POST THIS WAVE
*LOAD WAVE EXIT SEQUENCE
MOVE *A0+,A1,L
MOVE A1,@WAVE_EXIT,L ;POST WAVE SHOW
*LOAD ENEMY QUOTAS
CALLA LOAD_ENEMIES_LEFT
*DON'T SLEEP 'TIL AFTER THE CALL
CALLA GET_CSTR
CALLA G_CREDONLY ;UPDATE THE WAVE DISPLAY
DISPOFF
* DUE WAVE INTRO HERE
CLRM @IRQSKYE,W ;CLEAR TO BLACK
ALLPLYR CLR_PWAVEST ;CLEAR WAVE START FLAG
ALLPLYR CLR_PFIRING ;HE'S NOT FIRING
ALLPLYR CLR_PHEADS_UP ;CLEAR ALL OF THE HEADS UP STUFF
ALLPLYR UPDATE_P_LED ;Make sure Player LED is correct
MOVE @WAVE_UNIV,A0,L
JRZ WS_NOUNIV
.if DEBUG
MOVE @ZREL_OFF,A10,L
SRA ZFRAC,A10 ; convert to LOW res
MOVE @YREL_OFF,A11,L
JSRP START_UNIVERSE0 ;BIG BANG
.else
JSRP START_UNIVERSE ;BIG BANG
.endif
sleep 20
WS_NOUNIV
MOVE @WAVE_IPLANE,A10,L
JRZ WS_NOIPLANE
CALLA StrtBgnd ;FIRE UP THE BACKGROUND INFINITY PLANE
WS_NOIPLANE
SLEEP 3
; MOVK 1,A0
; MOVE A0,@GAMERASE,W ;AUTO ERASE ON
MOVI DUXNOFADE,A0
CALLA FADEBLAK ;TURN THE PALETTES DOWN
SLEEP 3
DISPON
; MOVK 1,A0
; MOVE A0,@GAMERASE,W ;ONCE MORE FOR THOSE THAT MISSED IT
MOVE @NO_WAVE_INTRO,A0,W
JRNZ WAVE_START_NO_INTRO
MOVE @WAVE_INTRO,A0,L
JRZ WAVE_START_NO_INTRO
JSRPR A0
CLRM @WAVETIME,L ;RESET THE WAVE TIMER, FUDGE, FUDGE, FUDGE
JRUC WAVE_START_SKIP_FADE
WAVE_START_NO_INTRO
MOVI 800H,A9
CREATE PID_SKY,SKYUP
MOVI DUXNOFADE,A0
CALLA FADEIN
WAVE_START_SKIP_FADE
CALLR START_WAVE_MUSIC
MOVE @GAME_STATE,A14,W
CMPI INAMODE,A14 ;ARE WE IN ATTRACT MODE?
JREQ WAVE_START_ATTRACTION
MOVI INPLAY,A0 ;CAUTION: DO NOT SLEEP AFTER THIS
MOVE A0,@GAME_STATE,W
WAVE_START_ATTRACTION
CALLA RECOIL_OFF ;MAKE SURE RECOILS ARE OFF
**** CALLA COLL_START ;START THE COLLISION ROUTINE
CREATE PID_IND,LEVEL_UPDATE ;START THE ENERGY LEVEL WATCHERS
CREATE PID_MASTERDP,MASTERDP ;START THE ENEMY DISPATCH
CALLA START_SCROLL
CREATEP PID_CURSOR,PLAYER_CURSOR ;START THE CURSOR TRACKER
RETP
*
*EXCLUDE THESE PALETTES WHEN FADING UP THE BACKGROUND
*
DUXNOFADE:
.LONG T2FIXED
BUSNOFADE:
.long BLUPLAYR, REDPLAYR, YELPLAYR, TEXTPAL, 0
*
*EXCLUDE THESE PALETTES WHEN FADING BACK IN AFTER BONUS SLAM
*
BONUSNOFADE
.LONG T2FIXED, BLUPLAYR, REDPLAYR, TEXTPAL, 0
MAXDIFF .EQU 3
**************************************************************************
* *
* WAVE_DIFFICULTY - SETUP WAVE DIFFICULTY PARAMETERS *
* USES THE THE GAME ADJUSTMENT ADJDIFF AS THE CURRENT DIFFICULTY *
* *
**************************************************************************
WAVE_DIFFICULTY:
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11
ADJUST ADJDIFF ;GET MASTER DIFFICULTY
CMPI MAXDIFF,A0
JRLS WDIFF_OK ;BR = DIFFICULTY SETTING IS O.K.
MOVI MAXDIFF,A0 ;INSERT MAXIMUM ALLOWED DIFFICULTY
WDIFF_OK:
MOVE @WAVE,A1,W
MOVE A1,A9
CMPI NWAVES,A1
JRLE WDIFF_PARAMS
MOVI NWAVES,A1 ;STICK AT TOP WAVE
WDIFF_PARAMS:
SLL 4,A1 ;MULTIPLY BY 16
SUBK 2,A0
MOVI WDIFF_RAM_ST,A2
MOVI WAVE_DIFF_TAB,A3
WDIFF_LP:
MOVE A3,A5
MOVE *A5+,A7,W ;GET DIFFICULTY DELTA
MOVE *A5+,A6,W ;GET MIN
MOVE *A5+,A4,W ;GET MAX
ADD A1,A5
MOVE *A5,A8,W ;GET WAVE VALUE
MPYS A0,A7
ADD A7,A8 ;ADD IN DELTA
CMP A8,A6
JRLE WDIFF_MIN ;CHECK FOR MIN
MOVE A6,A8
JRUC WDIFF_MAX
WDIFF_MIN:
CMP A8,A4 ;CHECK FOR MAX
JRGE WDIFF_MAX
MOVE A4,A8
WDIFF_MAX:
MOVE A8,*A2+,W ;STORE IT AWAY
ADDI (NWAVES + 4)*16,A3 ;OFFSET TO NEXT TABLE ENTRY
CMPI WDIFF_RAM_END,A2
JRLO WDIFF_LP ;NOT DONE
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11
RETS
**************************************************************************
* *
* START_WAVE_MUSIC - ROUTINE TO START OR RESTART THE REQUIRED WAVE *
* MUSIC. *
* *
**************************************************************************
START_WAVE_MUSIC
PUSH A0
MOVE @WAVE_MUSIC,A0,L ;GET THE MUSIC FOR THIS WAVE
JRZ SWM_X ;BR = NO MUSIC THIS WAVE
CALLA ONESND
SWM_X
PULLQ A0
RETS
**************************************************************************
* *
* WAVE_END - JUMP HERE TO END THE WAVE. THIS WILL CHANGE THE GAME_STATE *
* TO INGAME AND HANDLE BONUS STUFF. FINALLY IT WILL INCREMENT *
* WAVE AND CALL WAVE_START TO START THE NEXT WAVE. *
* *
**************************************************************************
WAVE_END:
MOVE @WAVE_WAIT,A0,W
JRZ WE_NOWAIT ;BR = DON'T WAIT FOR SCROLLER
WE_WAIT
SLEEP 1
MOVE @WAVE_SUB,A0,L ;SHALL WE GO A LEVEL DEEPER?
JRZ WE_WAIT ;BR = NOT YET WAIT FOR SCROLLER
JRUC WE_CONT
WE_NOWAIT
MOVE @WAVE_SUB,A0,L ;SHALL WE GO A LEVEL DEEPER?
JRZ WAVE_END_IMM ;BR = NO, THIS 'AM THE END
WE_CONT
*LOAD NEXT PORTION OF WAVE
INCM @SUBWAVE,W
*LOAD SUB-WAVE DISPATCH TABLE
MOVE *A0+,A1,L
MOVE A1,@DISPATCH_TABLE,L ;NEW DISPATCH TABLE
*LOAD NEXT SUB-WAVE
MOVE *A0+,A1,L
MOVE A1,@WAVE_SUB,L
CALLA LOAD_ENEMIES_LEFT
MOVI PID_MASTERDP,A0
CALLA KILLPROC_ALL
CREATE PID_MASTERDP,MASTERDP ;START THE ENEMY DISPATCH
**** CALLA START_SCROLL
DIE
*THE REAL WAVE END
WAVE_END_IMM
;
; Commented 3/10/94 cause things are not fucking working, yet.
;
; JSRP ENEMY_WAIT ;FIRST WAIT ON ENEMIES TO LEAVE
**** SLEEP 60 ;HOLD BEFORE KILLING ALL
MOVE @GAME_STATE,A0,W
CMPI INGAMEOV,A0
JAEQ SUCIDE
MOVI INGAME,A0
MOVE A0,@GAME_STATE,W
JSRP WAIT_WAVE_END
MOVE @GAME_STATE,A0,W
CMPI INGAMEOV,A0
JAEQ SUCIDE
CALLA CLEAR_OPLINKS ;CLEAR OBJECT OPLINKS
MOVI PID_CURSOR,A0
CALLA KILLPROC_ALL ;KILL THE CURSOR DOOLIES
CALLA STOPOBJS
CLR A0
MOVI 0A000h,A1
CALLA KILALL ;KILL ALL BUT INDIES AND WAVE INDIES
CALLA RECOIL_OFF ;MAKE SURE COILS ARE OFF
CALLA CLEAR_ANIMS ;Clear all animations
; MOVE @WAVE,A14,W
; CMPK LAST_WAVE,A14
; JREQ WAVE_END_ALWAYS ;BR = We've hit the finale
*MAKE SURE SOUND IS NOT LONGER THAN 70*16 msec OR IT WILL GET CHOPPED
; SOUND1 WAVE_END_XITION
ALLPLYR CLR_HEADS_UP ;CLEAR ALL HEADS UP DISPLAYS
ALLPLYR CLR_PLAYER_TEXT ;CLEAR ANY CURRENT PLAYER TEXT
MOVI 01000H,A9
CREATE PID_SKY,SKYDOWN
MOVI DUXNOFADE,A0 ;FADE OUT ALL EXCEPT DUXNOFADE LIST
CALLA FADEOUT
SLEEP 60
MOVI PID_UNIV,A0
CALLA KILLPROC_ALL ;KILL UNIVERSE PROCESSES
MOVI PID_BGND,A0
MOVI 0FF00H,A1
CALLA KILALL ;KILL BLIMP PROCESSES
CALLA OINIT
CALLA FADEBLAK_TEXT
SLEEP 8
CALLA FADEIN_TEXT ;FADE IN 'DA WAVE END MESSAGE
MOVE @WAVE,A8,W
DEC A8
SLL 5,A8
ADDI WAVE_END_TAB,A8
MOVE *A8,A8,L
JRZ WE_SKIP_MESS
JSRP LM_PRINTF
SLEEP 60
RANDENT WEND_SND_TAB,NUM_WEND_SNDS,5,L
CALLA ONESND
SLEEP 70
WE_SKIP_MESS
CALLA FADEBLAK_TEXT
SLEEP 8
CALLA OINIT
SLEEP 10
* Do bonus screen here
*INSERT BONUS COUNT HERE
MOVE @BONUS_DIRECTION,A1,W
JSRP GO_BONUS
CLR A0
MOVE A0,@GAMERASE,W
SLEEP 2
CALLA MYOINIT
DISPON
CALLA SINGLE_PLANE ;START US ONE PLANE OF FOREGROUND
MOVE @WAVE,A14,W
CMPK LAST_WAVE,A14
JRHS WAVE_END_NOMFADE ;BR = Don't fade music
CLR A8
CLR A10
MOVI 60,A11
CREATE PID_IND,TRACK_FADE_OUT_FULL_PROC
WAVE_END_NOMFADE
SLEEP 60
WE_FADE_BLAK
*CLEAR BONUSES FOR NEXT COUNT
MOVI ENEMY_BONUS_ST,A1
MOVI ENEMY_BONUS_END,A2
CALLA CLRBLOCK
; SOUND1 SND_ALLOFF
; SLEEP 3
; SOUND1 VOLUMEF ;MAKE SURE THE VOLUME IS FULL
SLEEP 3
WAVE_END_ALWAYS
DISPOFF
CALLA DMAQWAIT ;WAIT ON ALL TO FINISH
CALLA MYOINIT
DISPON
*DO A POST WAVE SHOW IF WE NEED ONE.
MOVE @WAVE_EXIT,A0,L
JRZ WAVE_END_NO_SHOW
JSRPR A0
WAVE_END_NO_SHOW
DISPOFF
CALLA DMAQWAIT ;WAIT ON ALL TO FINISH
CALLA MYOINIT
DISPON
; MOVE @WAVE,A14,W
; CMPK LAST_WAVE,A14
; JREQ WAVE_END_NOCLRP ;BR = DON'T CLEAR PLAYFIELD
CALLA CLRPLAY
WAVE_END_NOCLRP
ALLPLYR CLR_PSTATOBJS
ALLPLYR GUNPOWER_TO_MAX ;MAX OUT THE GUNS
ALLPLYR CLR_PLASTLPLOT ;MAKE SURE LIFE GETS REPLOTTED
ALLPLYR CLR_PHEADS_UP ;CLEAR ALL OF THE HEADS UP STUFF
CALLA MYOINIT
DISPON
CALLA SCORAREA ;SHOW THE SCORE
CALLA CLRSNDDB
MOVI M_INDESTRUCT,A1
MOVE A1,A0
CALLA EXISTP ;ARE THERE INDESTRUCTIBLES?
JRNZ WE_NOPINIT ;BR = YES, DO NOT PINIT
*MAJOR PROCESS SYSTEM RESET HERE
MOVE *A13(PROCID),A1,W
CALLA PINIT
MOVI WAVE_NEXT,A7
MOVI STCKST,SP,L ;RESET THE SYSTEM STACK
CALLA GETPRC ;GET THE PROCESS
JAUC EXEC_LP ;AND DO SOME EXEC LOOP SHIT
*JUST KILL ALL BUT THE INDESTRUCTIBLES
WE_NOPINIT
CALLA KILL_DESTRUCTIBLES
*NOW CONTINUE TO THE NEXT WAVE
WAVE_NEXT:
*
*IF ANY PROCESSES NEED TO BE RE-STARTED, DO IT HERE
*
CALLA COLOR_START ;RE-START THE COLORS AFTER BLOW-OUT
CREATE PID_INDW,SCORPROC ;RE-START UP THE PUSH PLAYER START PROCESS
*
*ANY PROCESSES THAT NEED TO BE RE-STARTED SHOULD HAVE DONE SO BY NOW
*
MOVI AUDMAXWAVE,A0
CALLA GET_AUD
MOVE @WAVE,A2,W
CMP A1,A2
JRLE WAVE_END_NO_AUD
MOVE A2,A1
CALLA STORE_AUDIT
WAVE_END_NO_AUD:
MOVE @WAVE,A0,W
CMPK LAST_WAVE,A0
JRHS WAVE_LAST_DUDE
CLRM @NO_WAVE_INTRO,W
INCM @WAVE,W
JSRP WAVE_START ;\ DO NOT SLEEP BETWEEN THESE
ALLPLYR PLAYER_RESTART ;/ TWO CALLS. IT WOULD BE DANGEROUS
DIE
*
* This is where we come to put up the game finished message
*
WAVE_LAST_DUDE
AUDIT AUDFINISH ;YES WE HAVE FINISHED
DISPOFF
CALLA OINIT
DISPON
CALLA SINGLE_PLANE ;START US ONE PLANE OF FOREGROUND
CLR A0
NOT A0
MOVE A0,@GAMERASE,W ;AUTO ERASE ON
; SOUND1 SND_SWEET_VOCALS
; CALLA FADEBLAK_TEXT
; SLEEP 8
; CALLA FADEIN_TEXT ;FADE IN 'DA WAVE END MESSAGE
; MOVI MESS_GAME_END,A8
; JSRP LM_PRINTF
; SLEEP 240
CALLA FADEOUT_TEXT
SLEEP 10
MOVKM 1,@DO_CREDITS,W
; JSRP GAME_CREDITS
; CALLA OINIT
; SLEEP 3
JAUC GAME_OVER
SND_SWEET_VOCALS
.WORD 0F0FDH,1,08021H,0
*MUSIC TRANSITION FOR WAVE END
WAVE_END_XITION
.WORD 0F2D0H,2,08010H,030H,0808FH,0 ;WAVE END TRANSITION
*
* Sound calls for after wave end message comes up
*
WEND_SND_TAB
.LONG SND_WAVE_END1,SND_WAVE_END2,SND_WAVE_END3,SND_WAVE_END4
.LONG SND_WAVE_END5,SND_WAVE_END6,SND_WAVE_END7
NUM_WEND_SNDS .EQU 7
SND_WAVE_END1
.WORD 0F3D0H,59,08820H,0 ;"You're doing great"
SND_WAVE_END2
.WORD 0F3D0H,41,08818H,0 ;"Awesome"
SND_WAVE_END3
.WORD 0F3D0H,58,08817H,0 ;"Way to go"
SND_WAVE_END4
.WORD 0F3D0H,54,08816H,0 ;"Yeah!"
SND_WAVE_END5
.WORD 0F3D0H,56,0881AH,0 ;"Alright!"
SND_WAVE_END6
.WORD 0F3D0H,79,08816H,0 ;"Rock n Roll"
SND_WAVE_END7
.WORD 0F3D0H,56,08822H,0 ;"Keep it up!"
WAVE_END_TAB
.IF DEBUG
.LONG MESS_CLUBX
.ENDIF
.LONG MESS_CLUBX, MESS_LA, MESS_JUNGLE, MESS_JAPAN
.LONG MESS_BUS, 0, 0, 0
MESS_CLUBX
MESS_MAC RD15FONT,3,200,70+SKYTOPOF,COLOR_PWHITE,STRCNRMOS,OID_TEXT
.STRING "The Club is history\a.\a\n\n"
.STRING "Now it's time to stop\n"
.STRING "the New Order!",0
.WORD 60
.WORD 0
.EVEN
MESS_LA
MESS_MAC RD15FONT,3,200,80+SKYTOPOF,COLOR_PWHITE,STRCNRMOS,OID_TEXT
.STRING "Aerosmith's car..\a.\a\n"
.STRING "Cool!",0
.WORD 30
.WORD 0
.EVEN
MESS_JUNGLE
MESS_MAC RD15FONT,3,200,80+SKYTOPOF,COLOR_PWHITE,STRCNRMOS,OID_TEXT
.STRING "No more mind control\n"
.STRING "by the New Order!",0
.EVEN
MESS_JAPAN
MESS_MAC RD15FONT,3,200,80+SKYTOPOF,COLOR_PWHITE,STRCNRMOS,OID_TEXT
.STRING "The New Order's days of\n"
.STRING "mass production are over!",0
.EVEN
MESS_BUS
MESS_MAC RD15FONT,3,200,80+SKYTOPOF,COLOR_PWHITE,STRCNRMOS,OID_TEXT
.STRING "School's Out\a!\a\n"
.STRING "Forever!",0
.WORD 30
.WORD 0
.EVEN
;MESS_GAME_END
; MESS_MAC RD15FONT,2,197,67+SKYTOPOF,COLOR_PWHITE,STRCNRMO,OID_TEXT
; .STRING "Thank you for playing\nthis special\nSneak Preview.\n\n"
; .STRING "Revolution X - coming soon.",0
.EVEN
**************************************************************************
* *
* WAIT_WAVE_END - ROUTINE THAT RETURNS WHEN ALL OF THE WAVE END *
* WAIT PROCESSES ARE GONE. *
* NOTE: CALL WITH JSRP *
* *
**************************************************************************
WAIT_WAVE_END:
SLEEP 1
MOVE @BUYNOW,A14,W ;IS THE WINDOW UP?
JRNE WAIT_WAVE_END ;BR = YES, WAIT FOR IT TO CRUISE
PUSHP A11
MOVI 600,A11 ;TIME-OUT FOR BOGUSNESS
WWE_LP
SLEEP 1
MOVI M_WAVEWAIT,A0
MOVE A0,A1
CALLA EXISTP ;WAVE END WAIT PROCESSES?
JRZ WWE_CONT ;BR = NO, THEN START THE PARTY
DSJ A11,WWE_LP
.IF DEBUG
JRUC $
.ENDIF
WWE_CONT:
PULLP A11
RETP
**************************************************************************
* *
* DEL_SCRNOBJ - FUNCTION TO DELETE OBJECTS ON AN OBJECT LIST THAT *
* HAVE THE M_SCRNOBJ BIT SET. *
* A0 = PTR TO LIST *
* *
**************************************************************************
DEL_SCRNOBJS
MMTM SP,A0,A5,A8
MOVE A0,A5
MOVE *A0,A0,L ;GET THE FIRST
CMP A0,A5
JREQ DNS_X ;BR = LIST IS EMPTY
DNS_LP
MOVE *A0,A8,L ;GET NEXT
MOVB *A0(OFLAGS+B_SCRNOBJ-7),A14 ;IS THIS A NO SCROLL?
JRNN DNS_NEXT ;BR = NO
CALLA ZAPOBJ ;DELETE THIS ONE
DNS_NEXT
MOVE A8,A0 ;WAS NEXT END?
CMP A0,A5
JRNE DNS_LP ;BR = NO
DNS_X
MMFM SP,A0,A5,A8
RETS
**************************************************************************
* *
* WAVE_END_QUICK - JUMP HERE TO END THE WAVE AND START THE NEXT ONE *
* WITH OUT ERASING THE SCREEN OR ANYTHING. *
* *
**************************************************************************
WAVE_END_QUICK
MOVE @GAME_STATE,A0,W
CMPI INGAMEOV,A0
JAEQ SUCIDE
MOVI INGAME,A0
MOVE A0,@GAME_STATE,W
CLR A14
MOVE A14,@XSCROLL,L
MOVE A14,@YSCROLL,L
MOVE A14,@ZSCROLL,L
CALLA CLEAR_OPLINKS ;CLEAR OBJECT OPLINKS
MOVI PID_CURSOR,A0
CALLA KILLPROC_ALL ;KILL THE CURSOR DOOLIES
CALLA STOPOBJS
CLR A0
MOVI 0A000h,A1
CALLA KILALL ;KILL ALL BUT INDIES AND WAVE INDIES
CALLA RECOIL_OFF ;MAKE SURE COILS ARE OFF
*MAKE SURE SOUND IS NOT LONGER THAN 70*16 msec OR IT WILL GET CHOPPED
; SOUND1 WAVE_END_XITION
CLR A0
MOVE A0,@GAMERASE,W
MOVI DUXNOFADE,A0
CALLA FADE_FULL2HALF ;DROP THE PLAYFIELD BRIGHTNESS
CALLA FADEBLAK_TEXT
SLEEP 16
CALLA FADEIN_TEXT ;FADE IN 'DA WAVE END MESSAGE
MOVE @WAVE,A8,W
SLL 5,A8
ADDI WAVE_END_TAB,A8
MOVE *A8,A8,L
JSRP LM_PRINTF
SLEEP 60
MOVI DUXNOFADE,A0
CALLA FADE_HALF2BLAK
CALLA FADEBLAK_TEXT
SLEEP 25
MOVKM 1,@GAMERASE,W
SOUND1 SND_ALLOFF
SLEEP 3
; SOUND1 VOLUMEF ;MAKE SURE THE VOLUME IS FULL
SLEEP 3
JRUC WAVE_END_ALWAYS
**************************************************************************
* *
* WAVE_RESET - JUMP HERE TO RESET THE WAVE FROM ANYWHERE. ITS QUICK, *
* FAST AND DIRTY. *
* *
**************************************************************************
WAVE_RESET
MOVE @GAME_STATE,A0,W
CMPI INGAMEOV,A0
JAEQ SUCIDE
MOVI INGAME,A0
MOVE A0,@GAME_STATE,W
CLR A14
MOVE A14,@XSCROLL,L
MOVE A14,@YSCROLL,L
MOVE A14,@ZSCROLL,L
CALLA CLEAR_OPLINKS ;CLEAR OBJECT OPLINKS
MOVI PID_CURSOR,A0
CALLA KILLPROC_ALL ;KILL THE CURSOR DOOLIES
CALLA STOPOBJS
CLR A0
MOVI 0A000h,A1
CALLA KILALL ;KILL ALL BUT INDIES AND WAVE INDIES
CALLA RECOIL_OFF ;MAKE SURE COILS ARE OFF
CALLA CLEAR_ANIMS ;Clear all animations
CLR A0
MOVE A0,@GAMERASE,W
MOVI 01000H,A9
CREATE PID_SKY,SKYDOWN
MOVI DUXNOFADE,A0
CALLA FADE_HALF2BLAK
sleep 80
CALLA FADEBLAK_TEXT
SLEEP 30
SOUND1 SND_ALLOFF
SLEEP 30
CALLA CLRPLAY
; SOUND1 VOLUMEF ;MAKE SURE THE VOLUME IS FULL
; SLEEP 3
CALLA FADEFULL_TEXT ;BRING THE TEXT UP
DISPOFF
CALLA DMAQWAIT ;WAIT ON ALL TO FINISH
CALLA MYOINIT
DISPON
ALLPLYR CLR_PSTATOBJS
ALLPLYR GUNPOWER_TO_MAX ;MAX OUT THE GUNS
ALLPLYR CLR_PLASTLPLOT ;MAKE SURE LIFE GETS REPLOTTED
ALLPLYR CLR_PHEADS_UP ;CLEAR ALL OF THE HEADS UP STUFF
CALLA SCORAREA ;SHOW THE SCORE
CALLA CLRSNDDB
sleep 20
MOVI M_INDESTRUCT,A1
MOVE A1,A0
CALLA EXISTP ;ARE THERE INDESTRUCTIBLES?
JRNZ WER_NOPINIT ;BR = YES, DO NOT PINIT
*MAJOR PROCESS SYSTEM RESET HERE
MOVE *A13(PROCID),A1,W
CALLA PINIT
MOVI WAVER_NEXT,A7
MOVI STCKST,SP,L ;RESET THE SYSTEM STACK
CALLA GETPRC ;GET THE PROCESS
JAUC EXEC_LP ;AND DO SOME EXEC LOOP SHIT
*JUST KILL ALL BUT THE INDESTRUCTIBLES
WER_NOPINIT
CALLA KILL_DESTRUCTIBLES
*NOW CONTINUE TO THE NEXT WAVE
WAVER_NEXT:
*
*IF ANY PROCESSES NEED TO BE RE-STARTED, DO IT HERE
*
CALLA COLOR_START ;RE-START THE COLORS AFTER BLOW-OUT
CREATE PID_INDW,SCORPROC ;RE-START UP THE PUSH PLAYER START PROCESS
*
*ANY PROCESSES THAT NEED TO BE RE-STARTED SHOULD HAVE DONE SO BY NOW
*
MOVKM 1,@NO_WAVE_INTRO,W
JSRP WAVE_START ;\ DO NOT SLEEP BETWEEN THESE
ALLPLYR PLAYER_RESET_RESTART ;/ TWO CALLS. IT WOULD BE DANGEROUS
DIE
**************************************************************************
* *
* GAME_OVER - THE GAME OVER PROCESS, JUMP HERE FROM CURRENT PROCESS. *
* IT WILL TAKE CONTROL. *
* A11 = PTR TO PLAYER ENDING THIS GAME *
* *
**************************************************************************
GAME_OVER
MOVE @WAVE,A1,W ; SET THE AVERAGE WAVE NUMBER
CALLA SET_AVGWAVE
.IF PRINTER
CALLA PGAMEEND
.ENDIF
CLR A1
MOVE A1,@GAMEUNITS,W ; CLEAR IT OUT FOR NEXT TIME
CALLA RECOIL_OFF ;MAKE SURE RECOILS ARE OFF
MOVKM 1,@GUNS_OFF,W
SOUNDOFF
MOVI INGAMEOV,A0
MOVE A0,@GAME_STATE,W ;SET STATE
JSRP GAMEOTEXT ;OUTPUT THE TEXT FOR GAME OVER
SLEEP 84
SOUNDON
SOUND1 SND_BGND3_OFF
SOUND1 SND_GAME_OVER
SOUNDOFF ;SUPPRESS ANY FURTHER SOUNDS
SLEEP 115
SOUND1 SND_BGND1_OFF
SOUND1 SND_BGND2_OFF
SOUND1 SND_CHAN1_OFF
SOUND1 SND_CHAN2_OFF
JSRP HS_ENTRY_SCRN ;DO THE HIGH SCORE THINGY
MOVKM 1,@GUNS_OFF,W
SOUNDOFF
NOHI MOVI M_INDESTRUCT,A1
MOVE A1,A0
CALLA EXISTP ;ARE THERE INDESTRUCTIBLES?
JRZ GAMEO_PINIT ;BR = NO, RE-INITIALIZE THE PROCESSES
CALLA WIPEOUT
JRUC GAMEO_NEXT
*MAJOR PROCESS SYSTEM RESET HERE
GAMEO_PINIT:
CALLA WIPEOUT
MOVE *A13(PROCID),A1,W
CALLA PINIT
MOVI GAMEO_NEXT,A7
MOVI STCKST,SP,L ;RESET THE SYSTEM STACK
CALLA GETPRC ;GET THE PROCESS
JAUC EXEC_LP ;AND DO SOME EXEC LOOP SHIT
*NOW CONTINUE TO THE NEXT WAVE
GAMEO_NEXT:
*GET INTO ATTRACT MODE
MOVI INAMODE,A1
MOVE A1,@GAME_STATE,W
CREATE PID_IND,ATT_MODE_GAME_OVER
DIE
SND_GAME_OVER
.WORD 0F3FDH,118,882FH,0 ;"Re-Vo-Lu-Tion Xssss"
**************************************************************************
* *
* GAMEOTEXT - PROCESS SUBROUTINE TO OUTPUT THE GAME OVER MESSAGE, AND *
* WAIT FOR READABILITIES SAKE. *
* NOTE: CALL WITH JSRP *
* *
**************************************************************************
GAMEOTEXT:
MMTM A12,A8,A9,A10,A11
MOVI GAMEOMESS,A8
JSRP LM_PRINTF
MMFM A12,A8,A9,A10,A11
RETP
.IF GERMAN
GAMEOMESS:
MESS_MAC RD20FONT,2,197,83+SKYTOPOF,COLOR_PLF,STRCNRMOS,OID_GAMEOVER
.STRING "Spielende",0
.EVEN
.ELSE
GAMEOMESS:
MESS_MAC RD20FONT,2,197,83+SKYTOPOF,COLOR_PLF,STRCNRMOS,OID_GAMEOVER
.STRING "Game Over",0
.EVEN
.ENDIF
**************************************************************************
* *
* CLR_ALL_PDATA - CLEAR ALL PLAYER DATA AREAS *
* *
**************************************************************************
CLR_ALL_PDATA
MMTM SP,A2,A7
ALLPLYR CLR_PDATA
MMFM SP,A2,A7
RETS
**************************************************************************
* *
* CALLPLAY - CALL A ROUTINE ON ALL ALLOWED PLAYERS. *
* A7 = ROUTINE ADDRESS *
* NOTE: SENDS PLAYER DATA AREA IN A2 *
* DESTROYS A14 *
* *
**************************************************************************
CALLPLAY
PUSH A2
MOVE @NPLAYERS,@CALLPRAM,W
MOVI P1DATA,A2
CALLPL
CALL A7
ADDI PDSIZE,A2
DECM @CALLPRAM,W
JRNN CALLPL
PULL A2
RETS
**************************************************************************
* *
* CLR_PDATA - CLEAR THE PLAYER DATA AREA OF IT'S STATUS *
* A2 = PLAYER DATA AREA *
* *
**************************************************************************
CLR_PDATA
MMTM SP,A0,A1,A3,A4,A6
CLR A0
MOVE A2,A1
MOVI PDSIZE,A3
SRL 5,A3
JRNC CLRPD1 ;BR = EVENLY DIVISIBLE BY 32
MOVE A0,*A1+,W ;KNOCK OFF ODD MAN
MOVE A3,A3
CLRPD1
JRZ CLRPD2
CLRPDL
MOVE A0,*A1+,L ;CLEAR THE WHOLE BLOCK
DSJS A3,CLRPDL
CLRPD2
CMPI P1DATA,A2
JRNE CLRPD3
MOVI P1PID,A1
MOVI P1INIT,A3
MOVI P1STATUSXY,A4
JRUC CLRPD4
CLRPD3
CMPI P2DATA,A2
JRNE CLRPD3a
MOVI P2PID,A1
MOVE @NPLAYERS,A0,W ;Get number of allowed players
DEC A0
JRGT CPD_P23PLAY ;BR = 3 or more players allowed
MOVI P3INIT,A3
MOVI P2STATUSXY2,A4 ;1 or 2 player positioning
JRUC CLRPD4
CPD_P23PLAY
MOVI P2INIT,A3
MOVI P2STATUSXY,A4
JRUC CLRPD4
CLRPD3a
CMPI P3DATA,A2
JRNE CLRPD_X
MOVI P3PID,A1
MOVI P3INIT,A3
MOVI P3STATUSXY,A4
CLRPD4
MOVE A1,*A2(PPID),W
MOVE A3,*A2(PINITAB),L
MOVE A4,*A2(PSTATUSXY),L
MOVE *A3(NEWIIMG),A3,L ;LET'S FIND THE PLAYER PALETTE I.D.
MOVE *A3(ICMAP),A3,L
MOVE A3,*A2(PPALID),L
*GET CORRECT SCORE BOX EQUATE BASED ON MAX NUMBER OF PLAYERS
MOVE @NPLAYERS,A0,W
SLL 6,A0 ; * 64
ADDI PSCTAB,A0
MOVE A0,A6 ; SAVE BASE TABLE OFFSET
CALLA GPLAYNUM
SLL 5,A0
ADD A6,A0 ; TABLE PLUS REFERENCE
MOVE *A0(0),*A2(PSCRAD),L ;STORE ACTUAL SCREEN ADDRESS
*GET CORRECT HIT BOX EQUATES BASED ON MAX NUMBER OF PLAYERS
MOVE @NPLAYERS,A0,W
SLL 7,A0 ;* 128
ADDI PHITTAB,A0
MOVE A0,A6 ;SAVE BASE TABLE OFFSET
CALLA GPLAYNUM
SLL 6,A0 ;* 64
ADD A6,A0 ; TABLE PLUS REFERENCE
MOVE *A0+,A14,L
MOVE A14,*A2(PHITBOXUL),L ;STORE CORRECT SCREEN HIT BOX
MOVE *A0(0),*A2(PHITBOXLR),L
*GET CORRECT TRACER LAUNCH POSITION BASED ON NPLAYERS
MOVE @NPLAYERS,A0,W
SLL 6,A0 ;* 64
ADDI PLAUNCHTAB,A0
MOVE A0,A6 ;SAVE BASE TABLE OFFSET
CALLA GPLAYNUM
SLL 5,A0
ADD A6,A0 ;TABLE PLUS REFERENCE
MOVE *A0(0),*A2(PLAUNCHPOS),L ;STORE ACTUAL SCREEN ADDRESS
MOVE *A0,A1,L
MOVE A1,*A2(PLAUNCHPOS),L ;STORE ACTUAL SCREEN ADDRESS
MOVI ZMAX_REAL,A14 ;ROCKET LAUNCHING Z
SEXT A1,W ;NO MORE Y
SUBI HALFX,A1 ;TRANSLATE SCREEN TO WORLD
MPYS A14,A1
SRL 8,A1 ;PACK IT UP!
MOVE A1,*A2(PRLAUNCHX),W
*DO THESE THINGS TO ALL PLAYERS ALIKE
ADJUST ADJEXTRA
MOVE A0,*A2(PNEXTREP),L
ADJUST ADJENERGY ;GET THE INITIAL AMOUNT OF ENERGY
MOVE A0,A1
MOVE A0,A3
SLL 16,A1
MOVI NENERGY,A0 ;GET THE SCALE SIZE
DIVU A0,A1 ;GET THE UNIT SIZE
MOVE A1,*A2(PENRGSIZ),L ;STORE ENERGY MULTIPLIER
ADJUST ADJMINTIME ;GET THE MINIMUM TIME IN SECONDS
MOVE A3,*A2(PINITLIFE),W ;STORE FOR INVERTING LIFE READING
SLL 16,A3
DIVU A0,A3 ;GET SECONDS PER LIFE UNIT
MOVE A3,*A2(PSECLIFE),L ;STORE AWAY FOR FUTURE USE
MOVKM GUN_COIL_OFF,*A2(PGUNOFFTIME),W ;Set default gun off time
CLRM *A2(PWINGS),W ;Clear the wing count
MOVE A14,*A2(PSHIELD),L ;Clear the shields
CALLA P_LED_OFF
CLRPD_X
MMFM SP,A0,A1,A3,A4,A6
RETS
*
*TABLE OF PSCRAD VALUES
*1st LINE WHEN NPLAYERS = 0, 2nd WHEN NPLAYERS = 1, etc.
PSCTAB
.LONG N1P1SCRAD,N2P2SCRAD ;NPLAYERS = 1
.LONG N2P1SCRAD,N2P2SCRAD ;NPLAYERS = 2
.LONG N3P1SCRAD,N3P2SCRAD,N3P3SCRAD ;NPLAYERS = 3
*
*TABLE OF PHITBOX VALUES
*1st LINE WHEN NPLAYERS = 0, 2nd WHEN NPLAYERS = 1, etc.
PHITTAB
.LONG N1P1HITBOX_UL,N1P1HITBOX_LR,N2P2HITBOX_UL,N2P2HITBOX_LR
.LONG N2P1HITBOX_UL,N2P1HITBOX_LR,N2P2HITBOX_UL,N2P2HITBOX_LR
.LONG N3P1HITBOX_UL,N3P1HITBOX_LR,N3P2HITBOX_UL,N3P2HITBOX_LR,N3P3HITBOX_UL,N3P3HITBOX_LR
*
*TABLE OF PLAUNCHPOS VALUES
*1st LINE WHEN NPLAYERS = 0, 2nd WHEN NPLAYERS = 1, etc.
PLAUNCHTAB
.LONG [SCREEN_HEIGHT,SCREEN_WIDTH/2],[SCREEN_HEIGHT,SCREEN_WIDTH/2]
.LONG [SCREEN_HEIGHT,SCREEN_WIDTH/4],[SCREEN_HEIGHT,(SCREEN_WIDTH*3)/4]
.LONG [SCREEN_HEIGHT,SCREEN_WIDTH/4],[SCREEN_HEIGHT,(SCREEN_WIDTH*2)/4],[SCREEN_HEIGHT,(SCREEN_WIDTH*3)/4]
**************************************************************************
* *
* LOAD_LIVES - GET THE AMOUNT OF PLAYER LIFE FROM CMOS AND STORE IT *
* IN THE PLAYER DATA AREA. *
* A2 = PTR TO PLAYER DATA AREA *
* NOTE: TRASHES A14 *
* *
**************************************************************************
LOAD_LIVES
PUSH A0
ADJUST ADJENERGY ;GET AMOUNT OF ENERGY FROM CMOS
SLL 16,A0
MOVE A0,*A2(PLIVES),L ;GIVE THIS DUDE HIS LIFE
MOVE *A2(PSTARTS),A14,W
JRNZ LL_BOMBA ;BR = This is not the first time
MOVE @ENERGY_SHIFT,A14,W
NEG A14
SRA A14,A0
SLL 16,A0 ;Add another 50% for the first cred
ADDRM A0,*A2(PLIVES),L
LL_BOMBA
ADJUST ADJBOMBS
ADDRM A0,*A2(PBOMB1),W ;ADD SOME MORE BOMBS
CALLA P_LED_ON
PULL A0
RETS
**************************************************************************
* *
* CLR_PENTER - CLEAR THE PLAYERS PENTER FLAG *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* NOTE: TRASHES A14 *
* *
**************************************************************************
CLR_PENTER:
CLRM *A2(PENTER),W
RETS
**************************************************************************
* *
* CLR_PWAVEST - CLEAR THE PLAYERS PWAVEST COUNTER *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* NOTE: TRASHES A14 *
* *
**************************************************************************
CLR_PWAVEST:
CLRM *A2(PWAVEST),W
RETS
**************************************************************************
* *
* CLR_PDEAD - CLEAR THE PLAYERS PDEAD FLAG *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* *
**************************************************************************
CLR_PDEAD:
MMTM SP,A0,A1
MOVE *A2(PPID),A0,W
ORI PINITIALPID,A0
CALLA EXISTP_ALL
JRNZ CLR_PDEAD_X
CLR A0
MOVE A0,*A2(PDEAD),W
CLR_PDEAD_X:
MMFM SP,A0,A1
RETS
**************************************************************************
* *
* CLR_PEXTRAS - CLEAR THE PLAYERS EXTRA MENABILITY. *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* NOTE: TRASHES A14 *
* *
**************************************************************************
CLR_PEXTRAS:
CLRM *A2(PEXTRAS),W
RETS
**************************************************************************
* *
* CLR_PFIRING - CLEAR THE PLAYER FIRING FLAG. *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* NOTE: TRASHES A14 *
* *
**************************************************************************
CLR_PFIRING
CLRM *A2(PFIRING),W
RETS
**************************************************************************
* *
* CLR_PSTARTESC - CLEAR THE START BUTTON ESCAPE FLAG. *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* NOTE: TRASHES A14 *
* *
**************************************************************************
CLR_PSTARTESC
CLRM *A2(PSTARTESC),W
RETS
**************************************************************************
* *
* CLR_PSTATOBJS - CLEAR ALL THE PLAYER STATUS OBJECT POINTERS. *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* *
**************************************************************************
CLR_PSTATOBJS
MMTM SP,A1,A2
MOVE A2,A1
ADDI PEBAROBJ,A1
; ADDI PCURSOROBJ+20H,A2
ADDI PGMODEOBJ+20H,A2
CALLA CLRBLOCK
MMFM SP,A1,A2
RETS
**************************************************************************
* *
* DELETE_PSTATUS - DELETE ALL OF THE STATUS OBJECTS THAT CURRENTLY EXIST *
* FOR A PLAYER. *
* A2 = PTR TO PLAYER DATA AREA *
* *
**************************************************************************
DELETE_PSTATUS
MMTM SP,A2,A6,A8
ADDI PEBAROBJ,A2
MOVK NSTATUSOBJS,A6
DP_LP
MOVE *A2,A8,L
JRZ DP_SKIP
CALLA DELETE_OBJ
CLR A8
MOVE A8,*A2,L
DP_SKIP
ADDK 32,A2
DSJ A6,DP_LP
MMFM SP,A2,A6,A8
RETS
**************************************************************************
* *
* CLR_PHEADS_UP - CLEAR A PLAYERS HEADS UP VARIABLES. *
* A2 = PTR TO PLAYER *
* *
**************************************************************************
CLR_PHEADS_UP
CLR A14
MOVE A14,*A2(PDTIME),W
MOVE A14,*A2(PDPRIORITY),W
MOVE A14,*A2(PDOBJ),L
RETS
**************************************************************************
* *
* UPDATE_P_LED *
* *
* Make sure a players LED is correct. *
* *
* A2 = Ptr to player *
* *
**************************************************************************
UPDATE_P_LED
MOVE *A2(PBOMB1),A14,W
JRNZ UPL_ON
MOVE *A2(PBOMB2),A14,W
JRNZ UPL_ON
CALLA P_LED_OFF
RETS
UPL_ON
CALLA P_LED_ON
RETS
**************************************************************************
* *
* INC_PLAYER_TIMERS - INCREMENT PLAYER TIMERS *
* A0 = AMOUNT TO INCREMENT *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* NOTE: TRASHES A14 *
* *
**************************************************************************
INC_PLAYER_TIMERS:
MOVE *A2(POBJ),A14,L
JRZ INC_PTX ;INCREMENT ONLY IF HE'S ALIVE
ADDRM A0,*A2(PLASTDTH),L
ADDRM A0,*A2(PWAVETIME),L
INC_PTX:
RETS
**************************************************************************
* *
* GUNPOWER_TO_MAX - SET A PLAYERS GUN POWER TO THE MAXIMUM *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* NOTE: TRASHES A14 *
* *
**************************************************************************
GUNPOWER_TO_MAX
MOVIM CLIP_ROUNDS,*A2(PBULLETS),W
RETS
**************************************************************************
* *
* CLR_PLASTLPLOT - CLEAR LAST LIFE PLOT VARI. *
* A2 = PTR TO PLAYER DATA STRUCTURE *
* NOTE: TRASHES A14 *
* *
**************************************************************************
CLR_PLASTLPLOT
CLRM *A2(PLASTLPLOT),L ;WE WILL PLOT
RETS
**************************************************************************
* *
* GPLAYNUM - GET THE PLAYER'S # (0-3), BASED ON PxDATA ADDRESS. *
* A2 = PLAYER DATA BLOCK *
* RETURNS: *
* A0 = PLAYER # *
* *
**************************************************************************
GPLAYNUM
CMPI P1DATA,A2
JRNE GPN_CK2
CLR A0
RETS
GPN_CK2
CMPI P2DATA,A2
JRNE GPN_CK3
MOVK 1,A0
RETS
GPN_CK3
MOVK 2,A0
RETS
**************************************************************************
* *
* GPLAYD - GET THE PLAYERS DATA AREA BASED ON HIS #. *
* A0 = PLAYER # *
* RETURNS: *
* A2 = PLAYER DATA AREA *
* *
**************************************************************************
GPLAYD
MOVE A0,A2
SLL 5,A2
ADDI PDTAB,A2
MOVE *A2,A2,L
RETS
PDTAB .LONG P1DATA,P2DATA,P3DATA
**************************************************************************
* *
* WAVE_PLAYERS - RETURN THE NUMBER OF PLAYERS THAT PLAYED THIS WAVE. *
* RETURNS: *
* A0 = # OF PLAYERS THIS WAVE *
* *
**************************************************************************
WAVE_PLAYERS:
MMTM SP,A1,A2,A3
CLR A0
MOVE @NPLAYERS,A1,W
MOVI P1DATA,A2
WAVE_P_LP:
MOVE *A2(PWAVEST),A3,W
JRZ WAVE_P_NXT
INC A0
WAVE_P_NXT:
ADDI PDSIZE,A2
DEC A1
JRNN WAVE_P_LP
MMFM SP,A1,A2,A3
RETS
**************************************************************************
* *
* WIPEOUT - WIPES THE SYSTEM CLEAR OF ALL OTHER PROCESSES, OBJECTS *
* AND COORDINATES. *
* IT RETURNS WITH THE DISPLAY SYSTEM AND AUTO-ERASE SHUT OFF, *
* COLOR RAM CLEARED, AND THE BIT MAP WIPED CLEAN. *
* THIS IS NICE TO USE WHEN SWITCHING BETWEEN STUFF. *
* ALSO, NULLS POBJ IN BOTH PLAYERS, SO DON'T USE THIS *
* DURING GAME PLAY! *
* NOTE: TRASHES A14 *
* *
**************************************************************************
WIPEOUT
MMTM SP,A0,A1,A7
CLR A0
MOVE A0,@P1DATA+POBJ,L
MOVE A0,@P2DATA+POBJ,L
MOVE A0,@P3DATA+POBJ,L
MOVE A0,@PAGE,W
MOVE A0,@COINFLAG,W ;NOT ON COIN PAGE YET
MOVE A0,@PAUSE_GAME,W ;TURN OFF GAME PAUSE
MOVE A0,@ON_HSTD,W ;NOT ON HIGH SCORE PAGE
MOVE A0,@ON_CRED,W ;NOT ON CREDITS PAGE
MOVE A0,@NOPGFLIP,W ;ALLOW PAGE FLIPPING
MOVE A0,@SWITCH_SPOKEN,W ;SWITCH SPEAK FLAG
MOVE A0,@OBJENEMIES,W ;Clear this global enemy thang
CALLR KILL_DESTRUCTIBLES
CALLA CLRSNDDB ;RESET THE SOUND DATA BASE
CALLA DRIVER_CLR ;CLEAR THOSE FLASH COILS
CLR A0
MOVE A0,@GAMERASE,W
CLR A0
MOVE A0,@DISPLAYON,W ;TURN THE DISPLAY PROCESSOR OFF
CALLA CLRDMAQ ;RESET THE Q
CALLA DMAWAIT ;WAIT ON DMA TO FINISH
PUSHST
DINT
CALLA CLRSWPRC
CALLA MYOINIT ;RE-INIT THE OBJECT LIST
CALLR SYSINITL
MOVE @INTPEND,A1,W ;CLEAR INTERRUPT PENDING
ANDNI DIE,A1
MOVE A1,@INTPEND,W
POPST
CALLA CLR_SCRN ;WIPE OUT THE BIT MAP
CALLA IAUTOE ;INITIALIZE THE AUTO ERASE AREA
CLR A0
MOVE A0,@IRQSKYE,W ;CLR THE AUTO-ERASE COLOR
CLR A0
MOVE A0,@IRQGNDE,W ;CLR THE AUTO-ERASE COLOR
MOVE @SUPRESS_PAGE_FLIP,A14,W
JRNZ WO_NO_PF
MOVI DPYSTRT0,A0
MOVE A0,@DPYST,L ;XUNIT RESET DISPLAY START POINT
WO_NO_PF
MMFM SP,A0,A1,A7
RETS
**************************************************************************
* *
* KILL_DESTRUCTIBLES - KILL ALL OF THE DESTRUCTIBLE PROCESSES CURRENTLY *
* ACTIVE. *
* *
**************************************************************************
KILL_DESTRUCTIBLES
MMTM SP,A0,A1,A7
CLR A0
MOVI M_INDESTRUCT,A1
CALLA KILALL ;KILL ALL BUT THE INDESTRUCTIBLES
ALLPLYR CLR_PFIRING ;HE'S NOT FIRING
CALLA RECOIL_OFF ;MAKE SURE COILS ARE OFF
CALLA COLOR_START ;RE-START THE COLOR PROCESSES
MMFM SP,A0,A1,A7
RETS
*
* Almost same as above, called from DECOMPRESSion routine
*
MOVIE_KILL
CLR A0
MOVI M_INDESTRUCT,A1
CALLA KILALL ;KILL ALL BUT THE INDESTRUCTIBLES
ALLPLYR CLR_PFIRING ;HE'S NOT FIRING
CALLA RECOIL_OFF ;MAKE SURE COILS ARE OFF
RETS
FREEZE_SW .EQU 14
FREEZE_DIP .EQU 14
**************************************************************************
* *
* FREEZE_ABSOLUTE - PROCESS TO FREEZE THE GAME ACTION WHEN THE FREEZE BU *
* GOES FROM OFF TO ON. GAME RESUMES WHEN THE BUTTON IS RELEASED. *
* *
**************************************************************************
FREEZE_ABSOLUTE
MOVE @GAME_STATE,A0
CMPI INDIAG,A0
JAEQ SUCIDE ;NO FREEZE SHIT DURING DIAGNOSTICS
MOVE @SKIPDISP,A8,W
MOVK 1,A14
MOVE A14,@SKIPDISP,W
MOVE @DISPLAYON,A9,W
CLR A14
MOVE A14,@DISPLAYON,W
CALLA DMAQWAIT ;Make sure all images are gone
PUSHST
DINT ;No interrupts, at all.
FREEZE_LP:
MOVE @COINS,A0,W ;GET THE COIN DOOR SWITCHES
BTST FREEZE_SW,A0
JREQ FREEZE_LP ;LOOP 'TIL BUTTON COMES UP
MOVE @DIPSWITCH,A0,W
BTST FREEZE_DIP,A0
JREQ FREEZE_LP
POPST
MOVE A9,@DISPLAYON,W
MOVE A8,@SKIPDISP,W
DIE
**************************************************************************
* *
* SLEEP_SWITCHX - SLEEP THE GIVEN NUMBER OF TICKS ESCAPING IF *
* A CONTROL PANEL BUTTON IS PRESSED. USE THIS *
* TO SLEEP DURING LENGTHY INTRO SCREENS. *
* A0 = # OF TICKS TO SLEEP *
* RETURNS: *
* Z = NO ESCAPE SWITCH DETECTED DURING SLEEP *
* NZ = ESCAPE SWITCH DETECTED *
* NOTE: CALL WITH JSRP *
* *
**************************************************************************
SLEEP_SWITCHX:
PUSHP A11
MOVE A0,A11
CLRM @SWITCH_ESCAPE,W
SLEEP_SWITCHX_LP:
SLEEP 1
MOVE @SWITCH_ESCAPE,A0,W
JRNE SLEEP_SWITCHX_ESC
DSJS A11,SLEEP_SWITCHX_LP
SETZ ;ALL IS WELL
SLEEP_SWITCHX_X
PULLP A11
RETP
SLEEP_SWITCHX_ESC:
CLRZ ;FLAG THE ESCAPE
JRUC SLEEP_SWITCHX_X
**************************************************************************
* *
* CLRSWPRC - MAKE ALL SWITCH TRIGGERED PROCESSES DUMDIE ENTRIES *
* NOTE: CALL WHEN INTERRUPTS ARE TURNED OFF *
* *
**************************************************************************
CLRSWPRC
MMTM SP,A0,A1,A3
MOVI 48,A1 ;USE SWTAB ENTRY 48 FOR DUMDIE PROC
MOVE @SWSTACK,A3,L
CLRSTKL CMPI SWSTST,A3,L ;STACK AT START?
JREQ CLRSTKX ;YES, EXIT
MOVE *A3+,A0,W
CMPI 63,A0
JRLS CLRSTKL ;THIS ENTRY IS A REAL SWITCH
MOVE A1,*A3(-10H),W ;STORE THE DUMDIE CALL
JRUC CLRSTKL
CLRSTKX
MMFM SP,A0,A1,A3
RETS
; WDOGDIS is gone. XUNIT
**************************************************************************
* *
* CLSCRACH *
* *
* Clear all of scratch pad RAM. *
* *
* NOTE: A0,A1,A2 and A3 are trashed. *
* This is very destructive. Make sure you setup *
* all relevant variables after calling this. *
* *
**************************************************************************
CLSCRACH
PULL A3
*CLEAR SCRATCHPAD RAM
CLR A0
MOVI SCRATCH,A1,L
MOVI (SCRATCH_END-SCRATCH)/32,A2,L ;CLEAR LONGS
SCTLP MOVE A0,*A1+,L
DSJS A2,SCTLP
JUMP A3
**************************************************************************
* *
* SYSTEM ROUTINES AND PROCESSES *
* *
**************************************************************************
*GAME RAM INITIALIZATION
GRAMINIT
MMTM SP,A0,A1,A2
MOVI GRAMSTRT,A1
MOVI GRAMEND,A2
JRUC RAMINIT
*WAVE RAM INITIALIZATION
WRAMINIT
MMTM SP,A0,A1,A2
MOVI WRAMSTRT,A1
MOVI WRAMEND,A2
RAMINIT
CLR A0
RAMLOOP
MOVE A0,*A1+,W ;16 BITS AT A TIME, NO EXTRANEOUS CLEARS
CMP A2,A1 ;DONE?
JRLO RAMLOOP ;NO!
MMFM SP,A0,A1,A2
RETS
**************************************************************************
* *
* SYSINITL - INITIALIZE LOW BYTE OF SYSTEM CONTROL REGISTER *
* *
**************************************************************************
SYSINITL
PUSH A0
MOVI SYSCINIT,A0
MOVE A0,@SYSCOPY ;RE-INITIALIZE SYSTEM CONTROL REG
MOVE A0,@SYSCTRL0,L ; XUNIT
srl 8,a0 ; XUNIT
MOVE A0,@SYSCTRL1,L ; XUNIT
MOVI 700H,A0
MOVE A0,@SECCHIP,L ; WHAT TO DO BOUT THIS ???XUNIT???
MOVE A0,@SECCHIP,L
PULL A0
RETS
**************************************************************************
* *
* IAUTOE - ROUTINE TO INITIALIZE THE TWO AUTO-ERASE LINES TO THEIR *
* DEFAULT COLOR. *
* *
**************************************************************************
IAUTOE
PUSH A0
movi ERASECOL,A0 ;color 63, pal 0
move A0,@NewAECol
dec A0
move A0,@OldAECol
movi GNDERACOL,A0 ;color 62, pal 0
move A0,@NewGNDCol
dec A0
move A0,@OldGNDCol
PULLQ A0
rets
;IAUTOE
; PUSH A0
; movi ERASECOL*10000H,A0 ;color 63, pal 0
; move A0,@NewAECol,L
; dec A0
; move A0,@OldAECol,L
; movi GNDERACOL*10000H,A0 ;color 62, pal 0
; move A0,@NewGNDCol,L
; dec A0
; move A0,@OldGNDCol,L
; PULLQ A0
; rets
**************************************************************************
* *
* SRT_CLR - ROUTINE TO CLEAR SCREEN BEFORE NEXT PLOT *
* NOTE: TRASHES MANY A AND B FILE REGISTERS *
* DON'T EXPLICITLY USE B11 - B13 UNLESS DMA INTERRUPT IS OFF. *
* *
**************************************************************************
SRT_CLR:
* color to clear to stored in Lines 510 and 511
.if HDW_KLUDGE
.else
MOVE @SKIPDISP,A0,W
JRNZ SRT_CLRX
MOVE @NOAUTOE,A0,W
JRNE SRT_CLRX ;DON'T ERASE
movi 255,B2 ;GET AUTO ERASE LINE
MOVE @GAMERASE,B9,W ;GET THE CURRENT AUTO-ERASE SCHEME
JREQ SRT_CLRX ;BR = AUTO-ERASE IS OFF
jrn HORIZON_CLEAR ; use two color method
SLL 6,B9
ADDI GAMERASE_TAB,B9
MOVE *B9+,B8,L ;GET THE SIZE
MOVE *B9,B7,L ;GET THE SIZE
callr SRT_CORE
SRT_CLRX:
.endif
rets
*
* (SCRNTL+16) = first line of SKY (OldAECol)
* HORIZON = first line of GROUND (OldGNDCol)
*
HORIZON_CLEAR:
move @(SCRNTL+16),b8 ; line number of sky top (0 or SKYTOPOF)
MOVE @SRT_HORIZON,B7
callr SRT_CORE2
move @SRT_HORIZON,b8 ; becomes start line
movi SCRBOT+1,b7
movi 254,B2 ;GET AUTO ERASE LINE
callr SRT_CORE2
rets
*
* B2 = VLINE where erase color is found
* B8 = START VLINE
* B7 = num_lines
*
SRT_CORE2:
sub b8,b7 ; line difference
srl 1,b7 ; divided by 2
sll 16,b7 ; placed in Y half
inc b7 ; 1 placed in X half
*
* B2 = VLINE where erase color is found
* B8 = START VLINE
* B7 = [num_lines : 1]
*
SRT_CORE:
sll 12,b8 ;convert start line to linear
move @CONVDP,A12,W
movk 012H,B9
move B9,@CONVDP ;Move to CONVDP io register
* Set SRT=1. This converts pixel accesses to VRAM SR transfer cycles.
MOVE @DPYCTL,B10,W ;Copy display control reg.
move B10,A13 ; save in A file
ANDNI SRE+ENV,B10 ;Turn off screen refresh
ORI CST,B10 ; XUNIT Enable SR transfers
;SrtDmaWt:
; move @DMAGOREG,A0,L ; XUNIT
; jrn SrtDmaWt
MOVI (4096*MICRO_SECOND)/4,A0 ;MAX WAIT FOR 400X256 DMA
SrtDmaWt
MOVE @DMAGOREG,A14,L ;DMA STILL BUSY?
JRNN SRT_DMA_READY ;BR = NO, READY
DSJS A0,SrtDmaWt
CLR A14
MOVE A14,@DMAGOREG,L
MOVE A14,@DMAGOREG,L ;DMA off for sure
CALLA CLRDMAQ
SRT_DMA_READY
*
*WARNING! KEEP INTERRUPTS OFF UNTIL AFTER THE FILL INSTRUCTION
* ASYNCHRONOUS BREAKS MAY CAUSE DMA INTERRUPT TO OCCUR
* DURING FILL INSTRUCTION TRASHING THE B REGISTERS THAT
* DETERMINE FILL RESTART AFTER INTERRUPT.
* WHEN DEBUGGING THIS CAUSES SPURIOUS ILLEGAL OPCODES AND TRASHING
* OF CODE SPACE.
*
PUSHST
DINT
MOVE B10,@DPYCTL,0 ;Load new display control
; MOVE @DPYCTL,B10,0 ;Read back to be safe!
movi SCRN_PTCH*2,B3 ;Get Screen Pitch
* Load frame buffer for 1st line into VRAM shift registers.
CLR B4 ;Origin at start of memory
sll 13,b2 ; change line number into address
MOVK 1,A14
MOVE A14,@SECCHIP,L ;Hack for Steve and his bogus VRAMs
PIXT *B2,B2 ;Load VRAM shift registers
* Transfer contents of VRAM shift registers to rest of frame buffer.
move @PAGEADDR,B4,L
clr B2
movx b2,b4 ; clear out X
SRL 4,B4 ; convert from XY to linear
ADD B8,B4
MMTM SP,B11,B12,B13
FILL XY ;200 SR-to-memory transfers
MMFM SP,B11,B12,B13
CLR A14
MOVE A14,@SECCHIP,L ;De-Hack for Steve and his bogus VRAMs
POPST
*END OF INTERRUPT DISABLE
* Restore previous contents of registers.
move A12,@CONVDP,W
MOVE A13,@DPYCTL,W ;Copy display control reg.
rets
**************************************************************************
* *
* TABLE OF SCREEN ERASE PARAMS *
* ENTRY: *
* .LONG OFFSET TO START ERASE CLEAR *
* .LONG LENGTH OF ERASE DOMAIN *
* *
**************************************************************************
ERA_ENT .macro TOP,BOTTOM
.LONG :TOP:
.LONG [((:BOTTOM:)-(:TOP:)+1)>>1,1]
.endm
GAMERASE_TAB
ERA_ENT SCRTOP,SCRBOT
ERA_ENT SCRTOP+SKYTOPOF,SCRBOT
ERA_ENT SCRTOP,SCRHGHT/2 + SCRHGHT/8 - SCRTOP
ERA_ENT SCRTOP,SCRBOT
**************************************************************************
.IF 0
SwapPgA:
;CALLED AT START OF DISPLAY INTERRUPT TO CHANGE PLOTTING TO UNVIEWED PAGE
MOVE @NOPGFLIP,A0,W
JRNZ DoPageA0
MOVE @SKIPDISP,A0,W
jrnz PageAX
;**** PAGE 1 starts on the 256th line of the video ram
movk 1,A0 ;Assume Page 1 first
movi PAGE1ADR,A1
move @PAGE,A14,W
jrz SetPgAd
;**** PAGE 0 starts on the 0th line of the video ram
DoPageA0
clr A0 ;PLOT ON PAGE 0 now
movi PAGE0ADR,A1
SetPgAd move A1,@PAGEADDR,L
move A0,@PAGE,W
PageAX:
rets
**************************************************************************
**************************************************************************
SwapPgB:
;CALLED AT END OF DISPLAY INTERRUPT TO CHANGE VIEWED PAGE TO PAGE PLOTTED
MOVE @SKIPDISP,A0,W
jrnz PageBX
;**** PAGE 1 starts on the 256th line of the video ram
movi DPYSTRT1,A0 ;DISPLAY PAGE 1 next frame
move @PAGE,A14,W
jrnz SetStrt
;**** PAGE 0 starts on the 0th line of the video ram
movi DPYSTRT0,A0 ;DISPLAY PAGE 0 next frame
SetStrt:
move A0,@DPYST,L ; XUNIT
PageBX:
rets
.ENDIF
*CALLED AT VERTICAL BLANK WHEN IT IS KNOWN THAT THE DMA IS FINISHED.
* IT WILL SWAP THE PLOT AND VIEWED PAGES, REPLACES SwapPgA AND SwapPgB.
SWAP_PAGES
MOVE @SUPRESS_PAGE_FLIP,A0,W ;Totally blow off all page changing?
JRNZ SWAP_PageAX ;BR = Yes
MOVE @NOPGFLIP,A0,W
JRZ SWAP_ME
*NO PAGE FLIPPING, JUST STICK IT ON PAGE 0
clr A0 ;PLOT ON PAGE 0 now
movi PAGE0ADR,A1
movi DPYSTRT0,A2 ;DISPLAY PAGE 0 now
JRUC SWAP_SetPgAd
SWAP_ME
MOVE @SKIPDISP,A0,W
jrnz SWAP_PageAX
;**** PAGE 1 starts on the 256th line of the video ram
movk 1,A0 ;Assume Page 1
movi PAGE1ADR,A1
movi DPYSTRT0,A2 ;DISPLAY PAGE 0
move @PAGE,A14,W
jrz SWAP_SetPgAd
;**** PAGE 0 starts on the 0th line of the video ram
clr A0 ;PLOT ON PAGE 0 now
movi PAGE0ADR,A1
movi DPYSTRT1,A2 ;DISPLAY PAGE 1 now
SWAP_SetPgAd
move A1,@PAGEADDR,L
move A0,@PAGE,W
;XUNIT move a2,@DPYADR ;Override DPYSTRT
move a2,@DPYST,L ; XUNIT Stuff our new DPYST to be cool
MOVE A2,@DPYNX,L ; XUNIT Override DPYST and take effect immeadiately
SWAP_PageAX:
rets
**************************************************************************
**************************************************************************
* *
* DIRQ - DISPLAY IRQ, USES THE VALUE STORED @DPYINT TO DETERMINE *
* WHICH INTERRUPT WE HAVE RECEIVED. *
* *
**************************************************************************
DIRQ:
MMTM SP,A0,A1
SETF 1,0,0
CLR A1
MOVE A1,@INTPEND+DIP ;CLEAR STUPID INTERRUPT PENDING
MOVE A1,@INTENB+DIP ;DISABLE DISPLAY INTERRUPT
*REMOVED OLD WAY OF CLEARING THOSE BITS
SETF 16,1,0 ;WORD SIGN EXTEND
EINT ;ENABLE OTHER INTERRUPTS
.IF NOTFINAL
MOVE *SP(20H+40H),A0,L
MOVE A0,@INTADDR,L
.ENDIF
.IF DEBUG
GETPC A1
MOVE *A1,A0,W
SRL 2,A0
SLL 2,A0
CMPI 0F0H,A0
JREQ $
.ENDIF
move @DPYINT,A0,W
cmpi EOSINT,A0 ;is this DIRQ or DIRQ2?
jrne DIRQ2
MOVE @DIAG_DFLAG,A0,W ;SPECIAL DIRQ FOR GSP DIAGS?
JRNZ DIAG_DIRQ ;BR = YES
**************************************************************************
* *
* END OF SCREEN INTERRUPT. DISPLAY PROCESSING, SWITCHES, COINS *
* COLORS, ETC. *
* *
**************************************************************************
MMTM SP,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14
MMTM SP,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B14
*CODE TO HANDLE OVERLOAD SITUATIONS WHICH
*WILL RESULT IN A FRAME RATE REDUCTION
MOVE B13,B0
CMP B12,B0 ;IS THE DMA Q EMPTY?
JRLE DIRQ_CKMP ;BR = Yes
;XUNIT ST SETF 1,0,0 ;KEEP DMA RUNNING
; MOVK 1,A1
; MOVE A1,@DPYCTL+B_CST,0 ; XUNIT
; CLR A1
; PIXT *A1,A2
; MOVE A1,@DPYCTL+B_CST,0 ; XUNIT
;XUNIT END SETF 16,1,0 ;WORD SIGN EXTEND
*
*DMA appears to be overloaded here. Use this hook to do some stuff
* during DEBUG mode only.
*
.IF DEBUG
INCM @WAVEDMABOG,L ;Chalk this audit
**** MOVI (4096*MICRO_SECOND)/4,A1 ;MAX WAIT FOR 400X256 DMA
****DIRQ_DQWAIT
**** CMP B13,B0 ;DMA Q CHANGE?
**** JRNE DIRQ_60HZ ;BR = YES, WE'RE OK
**** DSJS A1,DIRQ_DQWAIT
****
**** LOCKUP ;DMA Q IS FROZEN?
.ENDIF
MOVKM 1,@DMASKIPBOG,W ;Skip the bog check next time
MOVE @INTENB,A1,W
BTST B_X1E,A1
JRZ DIRQ_OVERLOAD ;BR = DMA not running
MOVI (4096*MICRO_SECOND)/4,A1 ;MAX WAIT FOR 400X256 DMA
DIRQ_DQWAIT
CMP B13,B0 ;DMA Q CHANGE?
JRNE DIRQ_OVERLOAD ;BR = YES, WE'RE OK
DSJS A1,DIRQ_DQWAIT
LOCKUP ;DMA Q IS FROZEN?
CLR A14
MOVE A14,@DMAGOREG,L
MOVE A14,@DMAGOREG,L ;DMA off for sure
CALLA CLRDMAQ
JRUC DIRQ_OVERLOAD
DIRQ_CKMP
MOVE @DMASKIPBOG,A14,W ;Should we skip the DMA bog checker?
JREQ DIRQ_CKMP2 ;BR = No
CLR A14
MOVE A14,@DMASKIPBOG,W ;We use this stuff to skip the bog
NOT A14 ;calculator because of massive DMA
MOVE A14,@DMATMP,W ;overload.
DIRQ_CKMP2
MOVE @TIMER,A1,W ;Are the processes done?
JRZ DIRQ_OK ;BR = Yes
*
*CPU appears to be overloaded here.
*
INCM @WAVECPUBOG,L ;Chalk this audit
MOVE @WAVEIRQS,A14,L
BTST 0,A14
JRZ DIRQ_OK
**************************************************************************
* COMMENT THE FOLLOWING JUMP TO SEE THE EFFECT OF CPU BOG ON THE DISPLAY.*
; JRUC DIRQ_OK
**************************************************************************
*Any overload will get you here.
DIRQ_OVERLOAD
CALLA DRIVER_UPDATE ;Update coils.
CALLA VELADD ;Always do the Velocity add
JRUC DIRQ_60HZ ;Skip the display processor for some headroom
*
*No overload detected here. Do things normally
*
DIRQ_OK
CALLR SWAP_PAGES
callr SRT_CLR
*
* XUNIT st
*UPDATE NORMAL CYCLING COLOR RAM
MOVI COLRTEMP+COLROFFST,A0 ;GET NEW COLORS
MOVI CYCOLORS+(COLROFFST*2),A1 ;GET ADDRESS OF CYCLE COLORS
MOVK COLRCNT,A6
COLORUP:
MOVE *A0+,a14
move a14,*A1+,L
DSJS A6,COLORUP
* XUNIT END
MOVE @IRQSKYE,@ERASELOC,W ;MOVE IN THE CORRECT COLOR
MOVE @IRQGNDE,@GNDERALOC,W ;MOVE IN THE CORRECT COLOR
CALLA PALTRANS ;XFER NEW PALETTES IF NECESSARY
CALLA DRIVER_UPDATE ;Update coils.
; move @PRIORITY,A0,W ;ARE WE PROCESSING THE PRIORITY LIST?
; jrnz SkSetPri ;BR = YES
; movi -1,A0
; move A0,@PRIORITY,W ;MAKE SURE IT IS PROCESSED IMMEADIATELY
;SkSetPri:
INCM @WAVEDISPS,W ;CLICK THE WAVE DISPLAY PROC CALLS
CALLA DISPLAY ;GOT TO MAKE THE DONUTS
*
*Everything from here to the end of the IRQ code must
* be executed every tick.
*
DIRQ_60HZ
move @DMATMP,a1 ;Let's see where the DMA ended
jrn not_qued ;BR = Do not do a timing check now
MOVE @DMASKIPBOG,A14 ;Is this an overload read?
JRZ DIRQ_DMA_NORM ;BR = No
clr a0 ;Force no time left
jruc DIRQ_DMA_COMPUTE
DIRQ_DMA_NORM
movi EOSINT,A0
sub A1,A0
JRN not_qued ;BR = Something is strange with the value
DIRQ_DMA_COMPUTE
movi 1000*10000H/EOSINT,A1
mpyu A0,A1
srl 16,A1 ;DMA time left is on a scale of
move a1,@DMALFT ;0 to 1000 for this frame.
srl 3,A1
move @DMAAVG,A0,W
move A0,A2
srl 3,A2
sub A2,A0
add A0,A1
move A1,@DMAAVG,W ;Average value to make it useful
not_qued
CLR A14
NOT A14
move a14,@DMATMP
MOVE @TIMER,A1 ;HIT PROCESS TIMER
INC A1
MOVE A1,@TIMER
.IF DEBUG
.ELSE
CMPI 200,A1
JRLO NO_IRQDOG ;NOTHING IS HUNG
DINT
JRUC $ ;HANG AND LET THE DOG BITE.
NO_IRQDOG
.ENDIF
CALLA COININT ;HANDLE SOME COINS!
CALLR SWSCAN ;SCAN SWITCHES TO TRIGGER PROCS.
; CALLA DRIVER_UPDATE ;Update coils. Must be called after TIMER increment.
MOVE @PAUSE_GAME,A14,W
JRNZ IRQ_SKIP_WI ;NO TIMING DURING GLOBAL PAUSE MODE
INCM @WAVEIRQS,L ;CLICK THE WAVE DIRQ COUNT
IRQ_SKIP_WI
DINT
SETF 1,0,0
MOVK 1,A0
MOVE A0,@INTENB+DIP ;ENABLE DISPLAY INTERRUPT
SETF 16,1,0
MOVE @IRQLED,A0,W
INC A0
MOVE A0,@IRQLED,W
CMPI 8,A0
JRLT DIRQX
*
*DO EVERYTHING FROM HERE TO DIRQX EVERY 8 TICKS
*
CLR A0
MOVE A0,@IRQLED,W
; MOVE @SYSCOPY,A0 ;BLINK L.E.D. TO ACK OPERATION
; XORI LED_ON<<8,A0
; MOVE A0,@SYSCOPY ; XUNIT
; srl 8,a0 ; XUNIT
; MOVE A0,@SYSCTRL1,L ; XUNIT
MOVB @SYSCOPY+8,A0 ;Blink L.E.D. to acknowledge IRQ XUNIT
XORI LED_ON,A0
MOVB A0,@SYSCOPY+8
MOVE A0,@SYSCTRL1,L
*HONEY! WOULD YOU FEED THE DOG?
MOVE a0,@WDOG_BONE ; XUNIT THROW ROVER A BONE
DIRQX:
.IF NOTFINAL
move @INTADDR,@LASTINT,L
clr A0
move A0,@INTADDR,L
.ENDIF
*
*CHECK IF AUTO-ERASE COLORS HAVE CHANGED, IF SO
*CREATE A NEW INTERRUPT TO STORE DATA
*
move @NewAECol,A0,L
move @OldAECol,A1,L
cmp A0,A1
JRne SetAEInt
move @NewGNDCol,A0,L
move @OldGNDCol,A1,L
cmp A0,A1
JREQ SkAEInt
SetAEInt
movi DIRQ2INT,A0 ;STUFF DPYINT FOR DIRQ2 (CHANGE AUTOERASE COL)
move A0,@DPYINT,W
SkAEInt
MMFM SP,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B14
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14
RETI
**************************************************************************
* *
* SPECIAL DISPLAY INTERRUPT FOR DIAGNOSTIC TEST THAT DO ALL DRAWING *
* WITH THE DMA(i.e. SWITCH TEST, DIPSWITCH TEST, etc.) *
* FEEDS WATCHDOG AND INCS TIMER *
* *
**************************************************************************
DIAG_DIRQ
MOVE A0,@WDOG_BONE ; XUNIT THROW ROVER A BONE
MOVE @TIMER,A0 ;HIT PROCESS TIMER
INC A0
MOVE A0,@TIMER
DINT
SETF 1,0,0
MOVK 1,A0
MOVE A0,@INTENB+DIP ;ENABLE DISPLAY INTERRUPT
mmfm SP,A0,A1
RETI
**************************************************************************
* *
* DIRQ2 - USED TO CHANGE THE COLOR OF THE AUTO-ERASE LINES. IF THE DMA *
* IS NOT CURRENTLY BUSY. IF IT IS, WE'LL TRY NEXT SCREEN. *
* *
**************************************************************************
BULLSHIT .set 1
DIRQ2:
movi EOSINT,A0 ;STUFF DPYINT FOR NEXT INTERRUPT
move A0,@DPYINT,W
cmp B12,B13 ;Is Q Non-Empty?
jrgt DIRQ2X
MOVE @DMAGOREG,A0,L ; XUNIT DMA BUSY?
JRN DIRQ2X
.if BULLSHIT==1
;*** SET UP DMA TRANSFER TO RESTUFF AUTOERASE COLOR ***
move @NewAECol,A1,W
move @OldAECol,A0,W
cmp A0,A1
jreq CkGNDAE
move A1,@OldAECol,W
;*** STUFF CORRECT COLOR IN AUTOERASE LINES ***
movi DMAREGS,A1
MOVI 01FF01FEH,A0
MOVE A0,*A1,L ;WINDOW BOTTOM - TOP
MOVI 01000100H,A0
MOVE A0,-*A1,L ;Y-SCALE:X-SCALE
move @OldAECol,A0
sll 16,a0
MOVE A0,-*A1,L ;CONST:PALETTE
movi [2,SCRWIDTH],A0
MOVE A0,-*A1,L ;VSIZE:HSIZE
movi [510,CENTER_XSHIFT],A0
jruc StufHook
CkGNDAE:
move @NewGNDCol,A1,W
move @OldGNDCol,A0,W
cmp A0,A1
jreq SkSetAE
move A1,@OldGNDCol,W
StufColr:
;*** STUFF CORRECT COLOR IN AUTOERASE LINES ***
movi DMAREGS,A1
MOVI 01FD01FCH,A0
MOVE A0,*A1,L ;WINDOW BOTTOM - TOP
MOVI 01000100H,A0
MOVE A0,-*A1,L ;Y-SCALE:X-SCALE
move @OldGNDCol,A0
sll 16,a0
MOVE A0,-*A1,L ;CONST:PALETTE
movi [2,SCRWIDTH],A0
MOVE A0,-*A1,L ;VSIZE:HSIZE
movi [508,CENTER_XSHIFT],A0
StufHook:
move A0,-*A1,L ;DESTINATION Y:X
movi IROM,A0 ; XUNIT
MOVE A0,-*A1,L ;IMAGE SAG
movi DMACAL<<16,A0
MOVE A0,-*A1,L ;STUFF THE CONTROL:OFFSET
SkSetAE:
.else
PUSH A2
;*** SET UP DMA TRANSFER TO RESTUFF AUTOERASE COLOR ***
move @NewAECol,A1
move @OldAECol,A0
cmp A0,A1
jreq CkGNDAE
move A1,@OldAECol
sll 16,a1
MOVI 01FF01FEH,A0
movi [510,0],A2
jruc StufColr
CkGNDAE:
move @NewGNDCol,A1
move @OldGNDCol,A0
cmp A0,A1
jreq SkSetAE
move A1,@OldGNDCol
sll 16,a1
MOVI 01FD01FCH,A0
movi [508,0],A2
StufColr:
;*** STUFF CORRECT COLOR IN AUTOERASE LINES ***
PUSH a1
movi DMAREGS,A1
MOVE A0,*A1,L ;WINDOW BOTTOM - TOP
MOVI 01000100H,A0
MOVE A0,-*A1,L ;Y-SCALE:X-SCALE
PULLQ a0
MOVE A0,-*A1,L ;CONST:PALETTE
movi [2,SCRWIDTH],A0
MOVE A0,-*A1,L ;VSIZE:HSIZE
move a2,a0
move A0,-*A1,L ;DESTINATION Y:X
movi 02000000H,A0
MOVE A0,-*A1,L ;IMAGE SAG
movi DMACAL<<16,A0
MOVE A0,-*A1,L ;STUFF THE CONTROL:OFFSET
SkSetAE:
PULLQ A2
.endif
DIRQ2X
DINT
**** MOVE @INTENB,A0,W ;ENABLE DISPLAY INTERRUPT
**** ORI DIE,A0
**** MOVE A0,@INTENB,W
SETF 1,0,0
MOVK 1,A0
MOVE A0,@INTENB+DIP ;ENABLE DISPLAY INTERRUPT
mmfm SP,A0,A1
RETI
*
*SWITCHES SCANNED HERE WILL ACTIVATE THE PROCESSES IN THE SWITCH PROCESS
*TABLE.
*BASHES A0,A1,A2 & A3 SO BEWARE!
SWSCAN:
move @SWITCH,a0 ; XUNIT ST
; move @COINS,a14
move @SWITCH2,a14
sll 16,a14
movy a14,a0 ; XUNIT END
MOVE @SWTEMP1,A1,L ;PREVIOUS STATE T=N-1
MOVE @SWTEMP2,A2,L ;PREVIOUS PREVIOUS T=N-2
MOVE A1,@SWTEMP2,L ;NEW PREVIOUS PREVIOUS
MOVE A0,@SWTEMP1,L ;NEW PREVIOUS
AND A1,A2
ANDN A0,A2 ;LOOK FOR 110
JREQ SWITCH2_CHECK ;NO SWITCHES
MOVE @SWSTACK,A3,L ;SWITCH ACTIVATION STACK
SWSCLP: ;FIND BIT SET
CMPI SWSTMN,A3 ;SWITCH STACK OVERFLOW?
JREQ SWSCX1 ;YEP, QUIT
LMO A2,A0 ;1'S COMP LEFTMOST BIT
RL A0,A2 ;GET RID OF BIT
SLL 1,A2
MOVK 31,A1 ;CALC TRUE BIT #
SUB A0,A1
MOVE A1,-*A3 ;PUSH SWITCH NUMBER ON STACK (0-15)
RL A1,A2 ;RESTORE SWITCH WORD WITHOUT BIT
JRNE SWSCLP
SWSCX1:
MOVE A3,@SWSTACK,L ;RESTORE SWITCH STACK
*
SWITCH2_CHECK:
move @COINS,a0
; move @SWITCH2,a0 ; XUNIT ST
move @DIPSWITCH,a14
sll 16,a14
movy a14,a0 ; XUNIT END
MOVE @SW2TEMP1,A1,L ;PREVIOUS STATE T=N-1
MOVE @SW2TEMP2,A2,L ;PREVIOUS PREVIOUS T=N-2
MOVE A1,@SW2TEMP2,L ;NEW PREVIOUS PREVIOUS
MOVE A0,@SW2TEMP1,L ;NEW PREVIOUS
AND A1,A2
ANDN A0,A2 ;LOOK FOR 110
JREQ SWSCX ;NO SWITCHES
MOVE @SWSTACK,A3,L ;SWITCH ACTIVATION STACK
SW2SCLP: ;FIND BIT SET
CMPI SWSTMN,A3 ;SWITCH STACK OVERFLOW?
JREQ SW2SCX1 ;YEP, QUIT
LMO A2,A0 ;1'S COMP LEFTMOST BIT
RL A0,A2 ;GET RID OF BIT
SLL 1,A2
MOVI 63,A1
SUB A0,A1
MOVE A1,-*A3 ;PUSH SWITCH NUMBER ON STACK (0-15)
RL A1,A2 ;RESTORE SWITCH WORD WITHOUT BIT
JRNE SW2SCLP
SW2SCX1:
MOVE A3,@SWSTACK,L ;RESTORE SWITCH STACK
SWSCX:
RETS
**************************************************************************
* *
* INITIO - INITIALIZE THE GSP I/O REGISTERS *
* *
**************************************************************************
INITIO
MMTM SP,B0,B2,B7
;*INITIALIZE I/O
; MOVI VESYNC,B2,L ; XUNIT
; MOVI INITDATA,B0,L
; MOVI (IDATAEND-INITDATA)/16,B7
;INITIOS:
; MOVE *B0+,*B2+
; DSJS B7,INITIOS
MOVI INITDATA,B0
MOVI VESYNC,B2
MOVI IDATALEN,B7
BLMOVE 1,1 ;TRANSFER I/O REGS
movi DPYSTRT0,a14 ; XUNIT
move a14,@DPYST,L ; XUNIT
MMFM SP,B0,B2,B7
RETS
*
*DUMMY FOR THE SWITCHES
DUMDIE JAUC SUCIDE ;NOTHING PROCESS
**************************************************************************
* *
* BADTRAP - COME HERE WHEN A TRAP IS HIT THAT IS NOT DEFINED AND LOG IT. *
* *
**************************************************************************
BADTRAP
MOVI 1,A14
move *SP(20h),B14,L ;Send the return address, we know its bad
CALLA DUMP_IT
AUDIT AUDBADTRAP ;CLICK A SOFTWARE TRAP
DINT
JRUC $ ;LET THE WATCH DOG CATCH US
**************************************************************************
* *
* Switch process activation table for Revolution X. *
* Used in conjunction with the IRQ switch scanner. *
* *
* .WORD PROCESS ID *
* .LONG STARTING ADDR *
* *
**************************************************************************
SWTAB:
*
*Players 1 and 2 start here, read at location SWITCH
*
.WORD 0 ;PROCESS ID SWITCH 0 -- Not Used (JAMMA P1 Up)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 1 -- Not Used (JAMMA P1 Down)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 2 -- Not Used (JAMMA P1 Left)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 3 -- Not Used (JAMMA P1 Right)
.LONG 0
.WORD P1PID|PFIREPID|400H ;PROCESS ID SWITCH 4 -- PLAYER 1 FIRE
.LONG PFIRE
.WORD P1PID|PBOMBPID|500H ;PROCESS ID SWITCH 5 -- PLAYER 1 BOMB
.LONG PBOMB
.WORD 0 ;PROCESS ID SWITCH 6 -- Not Used (JAMMA P1 C)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 7 -- Not Used (JAMMA P1 D)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 8 -- Not Used (JAMMA P2 Up)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 9 -- Not Used (JAMMA P2 Down)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 10 -- Not Used (JAMMA P2 Left)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 11 -- Not Used (JAMMA P2 Right)
.LONG 0
.WORD P2PID|PFIREPID|0C00H ;PROCESS ID SWITCH 12 -- PLAYER 2 FIRE
.LONG PFIRE
.WORD P2PID|PBOMBPID|0D00H ;PROCESS ID SWITCH 13 -- PLAYER 2 BOMB
.LONG PBOMB
.WORD 0 ;PROCESS ID SWITCH 14 -- Not Used (JAMMA P2 C)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 15 -- Not Used (JAMMA P2 D)
.LONG 0
*
*Players 3 and 4 start here, read at location SWITCH2
*
.WORD 0 ;PROCESS ID SWITCH 16 -- Not Used (JAMMA P3 Up)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 17 -- Not Used (JAMMA P3 Down)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 18 -- Not Used (JAMMA P3 Left)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 19 -- Not Used (JAMMA P3 Right)
.LONG 0
.WORD P3PID|PFIREPID|1400H ;PROCESS ID SWITCH 20 -- Player 3 Fire
.LONG PFIRE ;STARTING ADDR
.WORD P3PID|PBOMBPID|1500H ;PROCESS ID SWITCH 21 -- Player 3 Bomb
.LONG PBOMB ;STARTING ADDR
.WORD 0 ;PROCESS ID SWITCH 22 -- Not Used (JAMMA P3 C)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 23 -- Not Used (JAMMA P3 D)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 24 -- Not Used (JAMMA P4 Up)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 25 -- Not Used (JAMMA P4 Down)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 26 -- Not Used (JAMMA P4 Left)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 27 -- Not Used (JAMMA P4 Right)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 28 -- Not Used (JAMMA P4 A)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 29 -- Not Used (JAMMA P4 B)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 30 -- Not Used (JAMMA P4 C)
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 31 -- Not Used (JAMMA P4 D)
.LONG 0
*
*Coins and misc start here, read at location COINS
*
.WORD PID_LC ;PROCESS ID SWITCH 32 -- Left Coin
.LONG LCOIN
.WORD PID_RC ;PROCESS ID SWITCH 33 -- Right Coin
.LONG RCOIN
.WORD P1PID|PSTRTPID ;PROCESS ID SWITCH 34 -- Player 1 Start
.LONG PLAYER_START
.WORD PID_SLAM ;PROCESS ID SWITCH 35 -- SLAM!
.LONG SLAM
.WORD PID_DIAG ;PROCESS ID SWITCH 36 -- Diagnostics
.LONG DIAG
.WORD P2PID|PSTRTPID ;PROCESS ID SWITCH 37 -- Player 2 Start
.LONG PLAYER_START
.WORD PID_LC ;PROCESS ID SWITCH 38 -- Service Credit
.LONG SCOIN
.WORD PID_CC ;PROCESS ID SWITCH 39 -- Center Coin
.LONG CCOIN
.WORD PID_XC ;PROCESS ID SWITCH 40 -- Fourth Coin
.LONG XCOIN
.WORD P3PID|PSTRTPID ;PROCESS ID SWITCH 41 -- Player 3 Start
.LONG PLAYER_START
.WORD 0 ;PROCESS ID SWITCH 42 -- Player 4 Start
.LONG 0
.WORD PID_VOLUME ;PROCESS ID SWITCH 43 -- Volume Down
.LONG SWITCH_VOLUME_DOWN
.WORD PID_VOLUME ;PROCESS ID SWITCH 44 -- Volume Up
.LONG SWITCH_VOLUME_UP
.WORD 0 ;PROCESS ID SWITCH 45 -- UNUSED
.LONG 0
.WORD PID_INDW ;PROCESS ID SWITCH 46 -- Freeze Switch
.LONG FREEZE_ABSOLUTE
.WORD PID_XC ;PROCESS ID SWITCH 47 -- Bill acceptor
.LONG XCOIN
*
*DIP switches start here, read at location DIPSWITCH
*
.WORD 0 ;PROCESS ID SWITCH 48 -- SWITCH 48 U105 - 1
.LONG 0 ;USED BY CLRSWPRC
.WORD 0 ;PROCESS ID SWITCH 49 -- SWITCH 49 U105 - 2
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 50 -- SWITCH 50 U105 - 3
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 51 -- SWITCH 51 U105 - 4
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 52 -- SWITCH 52 U105 - 5
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 53 -- SWITCH 53 U105 - 6
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 54 -- SWITCH 54 U105 - 7
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 55 -- SWITCH 55 U105 - 8
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 56 -- SWITCH 56 U108 - 1
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 57 -- SWITCH 57 U108 - 2
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 58 -- SWITCH 58 U108 - 3
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 59 -- SWITCH 59 U108 - 4
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 60 -- SWITCH 60 U108 - 5
.LONG 0
.WORD 0 ;PROCESS ID SWITCH 61 -- SWITCH 61 U108 - 6
.LONG 0
.WORD PID_INDW ;PROCESS ID SWITCH 62 -- VIDEO FREEZE U108 - 7
.LONG FREEZE_ABSOLUTE
.WORD PID_DIAG ;PROCESS ID SWITCH 63 -- TEST SWITCH U108 - 8
.LONG DIAG ; *** START OF DIPSWITCHES ***
* VIDEO CONTROL REGISTERS INITIAL VALUES
.sect "COLDSTRT"
INITDATA:
.IF NTSC
.WORD 0003H*2 ;>C0000000 -- vesync
;OLD .WORD 00029H ;>C0000010 -- hesync
.WORD 0002BH ;>C0000010 -- hesync
.WORD 0014H ;>C0000020 -- veblnk
.WORD 0065H ;>C0000030 -- heblnk
.WORD 0112H ;>C0000040 -- vsblnk
.WORD 01f5H ;>C0000050 -- hsblnk
.WORD 0120H ;>C0000060 -- vtotal
;OLD .WORD 001ffH ;>C0000070 -- htotal
.WORD 001f9H ;>C0000070 -- htotal
.ELSEIF WIDESCREEN
.WORD 0003H*2 ;>C0000000 -- vesync
.word 01Ch ;>C0000010 -- hesync
.WORD ENDVBLNK ;>C0000020 -- VEBLNK
.word 03Dh ;>C0000030 -- heblnk
.WORD 0100H+(ENDVBLNK-2) ;>C0000040 -- VSBLNK
.word 013Dh ;>C0000050 -- hsblnk
.WORD 0120H ;>C0000060 -- vtotal
.word 0150h ;>C0000070 -- htotal
.ELSE
.WORD 0003H*2 ;>C0000000 -- vesync
;OLD .WORD 00029H ;>C0000010 -- hesync
.WORD 0002BH ;>C0000010 -- hesync
.WORD ENDVBLNK ;>C0000020 -- VEBLNK
.WORD 00065H ;>C0000030 -- heblnk
.WORD 0100H+(ENDVBLNK-2) ;>C0000040 -- VSBLNK
.WORD 001f5H ;>C0000050 -- hsblnk
.WORD 0120H ;>C0000060 -- vtotal
;OLD .WORD 001ffH ;>C0000070 -- htotal
.WORD 001f9H ;>C0000070 -- htotal
.ENDIF
.WORD 0D007H ;>C0000080 -- DPYCTL
.WORD 0 ;>C0000090 -- dpystrt
.WORD EOSINT ;>C00000A0 -- dpyint * INITIALLY HALF SCREEN
.WORD INI_CTRL ;>C00000B0 -- control
.WORD 04h ;>C00000C0 -- hstdata
.WORD 00h ;>C00000D0 -- hstadrl
.WORD 00h ;>C00000E0 -- hstadrh
.WORD 00h ;>C00000F0 -- hstctll
.WORD 00h ;>C0000100 -- hstctlh
.WORD 00h ;>C0000110 -- intenbl
.WORD 00h ;>C0000120 -- intpend
.WORD 00h ;>C0000130 -- convsp
.WORD CONV_PTCH ;>C0000140 -- convdp
.WORD PXSIZE ;>C0000150 -- psize
.WORD 00h ;>C0000160 -- pmaskl
.WORD 00h ;>C0000170 -- pmaskh
.WORD 00h ;>C0000180 -- CONVMP
.WORD INI_CTRL ;>C0000190 -- CONTROL
.WORD 01108h ;>C00001A0 -- CONFIG
.WORD 00h ;0C00001B0H -- DPYTAP
.WORD 04h ;>C00001C0 -- VCOUNT
.WORD 00h ;>C00001D0 -- HCOUNT
.WORD 00h ;>C00001E0 -- DPYADR
.WORD 00h ;>C00001F0 -- REFADR
.WORD 00h ;>C0000200 -- REG200
.WORD 00h ;>C0000210 -- REG210
.WORD 00h ;>C0000220 -- REG220
.WORD 00h ;>C0000230 -- REG230
.WORD 1000h ;>C0000240 -- DINC
.WORD 00h ;>C0000250 -- REG250
.WORD 00h ;>C0000260 -- REG260
;OLD .WORD 00D5h ;>C0000270 -- HESERR
.WORD 01D5h ;>C0000270 -- HESERR
;IDATAEND:
;IDATALEN EQU (IDATAEND-INITDATA)/16
IDATALEN EQU $-INITDATA ;Bit length of I/O init table
*
*INITIALIZE ALL 32 TRAP VECTORS
*
.SECT "VECTORS"
.LONG BADTRAP ;TRAP 31
.LONG BADTRAP ;TRAP 30 ILLOP --- Illegal Opcode
.LONG BADTRAP ;TRAP 29
.LONG BADTRAP ;TRAP 28
.LONG BADTRAP ;TRAP 27
.LONG BADTRAP ;TRAP 26
.LONG BADTRAP ;TRAP 25
.LONG BADTRAP ;TRAP 24
.LONG BADTRAP ;TRAP 23
.LONG BADTRAP ;TRAP 22
.LONG BADTRAP ;TRAP 21
.LONG BADTRAP ;TRAP 20
.LONG BADTRAP ;TRAP 19
.LONG BADTRAP ;TRAP 18
.LONG BADTRAP ;TRAP 17
.LONG BADTRAP ;TRAP 16
.LONG BADTRAP ;TRAP 15
.LONG BADTRAP ;TRAP 14
.LONG BADTRAP ;TRAP 13
.LONG BADTRAP ;TRAP 12
.LONG BADTRAP ;TRAP 11 WV --- Window Violation
.LONG DIRQ ;TRAP 10 DI --- Display Interrupt
.LONG BADTRAP ;TRAP 9 HI --- Host Interrupt
.LONG BADTRAP ;TRAP 8 NMI -- NonMaskable Interrupt
.LONG BADTRAP ;TRAP 7
.LONG BADTRAP ;TRAP 6
.LONG BADTRAP ;TRAP 5
.LONG BADTRAP ;TRAP 4
.LONG BADTRAP ;TRAP 3
.LONG LINT2_SERVICE ;TRAP 2 INT2 --- External Interrupt 2
.LONG DMAINT ;TRAP 1 INT1 --- External Interrupt 1
.LONG POWERUP ;TRAP 0 Reset
.END