;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Armor Attack
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Memory Usage:
;
;;;;;;;;;;;;;;;
;
; XTMR0(C82E): Delay before play action starts
; XTMR1(C82F): Delay before starting more tanks
; XTMR2(C830): Delay before processing helecopter
; SATUS(C867): Sound mask:
; bit 0 - slow tank sound
; bit 1 - fast tank sound
; bit 2 - helecopter??
; bit 3 - missile fired
; bit 4 -
; bit 5 -
; bit 6 -
; bit 7 -
; FEAST(C871): Set but never referenced.
; LASRAM(C880): Indicates whether slow tanks(1)
; or fast tanks (2) are in use.
; SJOY(C881): Max # of tanks for this level
; C882 :
; ETMP1(C883): Controls when helecopter resyncs
; the player's position.
; ETMP2(C884): Controls course/fine tuning of the
; angle between a player and a tank
; or helecopter. As levels get harder
; this mask does less course tuning of
; the angle value.
; ETMP3(C885): Mask; controls how often the helecopter's
; angle of travel is updated:
; 0x03 = moderate update rate
; 0x01 = fast update rate
; 0x00 = update every pass
; ETMP4(C886): Controls when the helecopter and tanks
; will attempt to fire a missile.
; ETMP5(C887): Index into level-specific data array.
; ETMP6(C888): Tanks are slow (1) or fast (2)
; ETMP7(C889): Tank body angle delta
; ETMP8(C88A): Incrementing flag, used primarily to
; signal when level-specific data should
; be initialized.
; ETMP9(C88B): # of tanks currently visible
; ETMP10(C88C): y position of helecopter target.
; C88D : x position of helecopter target.
; TEMP3(C891): Controls which missile movement deltas
; are used: -1=large, 1=small
; Toggles on every other iteration.
; TEMP4(C892): Helecopter intensity
; TEMP5(C893): Helecopter scale
; C894-C8A6 : Helecopter data
; C8A7-C8C6 : Helecopter body vlists
; C8C7 : # of players still alive
; C8C8 : # of players
; C8C9 : Another scale factor
; C8CA : Scale factor used to move, when
; drawing ____.
; C8CB : Work variable
; C8CC-C8CD : Function pointer
; C8CD : (1) # of tanks to start up
; : (2) Angle from helecopter to player
; : (3) Helecopter's desired angle of travel
; C8CE : Proximity of helecopter to player
; C8CF : (1) Angle from tank to player
; (2) Helecopter angle delta (+-1)
; C8D0 : Proximity of tank to player
; C8D2 : Missile processing loop counter
; C8DA : Used during missile processing:
; 2 = player 1
; 3 = player 2
; 4 = helecopter/tank
; Used when player fires missile to
; index into missile vlist array:
; 0 = player 1
; 2 = player 2
; C8DE-C8DF : Helecopter processing delay
; C8E0 : Tank startup delay counter
; C8E1 : Startup delay counter
; C8E2 : # of jeeps remaining
; C8E3 : Award for 1st tank hit (BCD 0200)
; C8E4 : Award for 2nd tank hit (BCD 0300)
; C8E5 : Value to add to player 1 score.
; C8E6 : Value to add to player 2 score.
; C8E7 : Placeholder for tank/helecopter
; score updates.
; C8E8 : 1/2 target size; used during hit
; detection; size = 2nx2n
; C8E9 : Controls display of # jeeps & score
; >= 0 - Display score & # jeeps
; < 0 - Don't display
; C8EB : Mask; when tank sounds are enabled,
; indicates which sound is made:
; bit 0 = slow tanks
; bit 1 = fast tanks
; C8EC : Enable mask; used to control which,
; if any, tank sound is made:
; bit 0 = slow tanks
; bit 1 = fast tanks
; C8ED : -1 (game active) or 0 (display "END")
; C8EE : Counts # of passes thru main loop
; C8EF : Used by sound code; flags that helecopter
; is exploding (-1), so all other sounds
; are disabled.
; C8F0 : Btn mask; controls whether a button is
; continuous read (bit = 0) or
; press/release (bit = 1).
; C900-C93F : Tank 1 data
; C940-C97F : Tank 2 data
; C980-C9BF : Tank 3 data
; C9C0-C9C6 : Player 1 1st missile data
; C9C7-C9CD : Player 1 2nd missile data
; C9CE-C9D4 : Player 2 1st missile data
; C9D5-C9DB : Player 2 2nd missile data
; C9DC-C9E2 : Helecopter missile data
; C9E3-C9E9 : Tank 1 missile data
; C9EA-C9F0 : Tank 2 missile data
; C9F1-C9F7 : Tank 3 missile data
; CA00-CA26 : Player 1 data
; CA27-CA4D : Player 2 data
; CA4E-CA55 : Button & Joystick state info
; CA56-CA5F : Player 1 1st missile vlist
; CA60-CA69 : Player 1 2nd missile vlist
; CA6A-CA73 : Player 2 1st missile vlist
; CA74-CA7D : Player 2 2nd missile vlist
; CA7E-CA87 : Rotated missile vlist
; CA88-CA89 : Position for plyr 1 score str
; CA8A-CA90 : Player 1 score string
; CA91-CA92 : Position for plyr 2 score str
; CA93-CA99 : Player 2 score string
; CA9A-CAF9 : Helecopter rotor vlists; 4 sets
; of 12 vectors.
; CB00-CB1F : Array of points; used during the
; drawing of an exploding missile,
; when drawing tank flames, or when
; the helecopter is hit.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Data Structures
;
;;;;;;;;;;;;;;;;;
;
; Button/Joystick Information (CA4E-CA55)
; (The joystick left/right information is)
; (merged in with the key 0 & key 1 data)
;
; ----------------
; 0 | Key 0 (left) | \
; ---------------- |
; 1 | Key 1 (right)| |
; ---------------- | Player 1
; 2 | Key 2 (move) | |
; ---------------- |
; 3 | Key 3 (fire) | /
; ----------------
; 4 | Key 0 (left) | \
; ---------------- |
; 5 | Key 1 (right)| |
; ---------------- | Player 2
; 6 | Key 2 (move) | |
; ---------------- |
; 7 | Key 3 (fire) | /
; ----------------
;
; Missile (C9C0-C9C6)
;
; -----------------------
; 0 | State flag | -> -1 = In use
; ----------------------- 0 = Inactive
; 1 | y pos | >0 = Exploding
; -----------------------
; 2 | x pos |
; -----------------------
; 3 | dwell (exploding) |
; | y delta (in use) |
; -----------------------
; 4 | scale (exploding) |
; | x delta (in use) |
; -----------------------
; 5 | diffy dot vlist ptr | -> Exploding
; -- -or- --
; 6 | (y,x) small deltas | -> In use
; -----------------------
;
; Player Data (CA00-CA26) [RAMMES]
;
; -----------------------
; 0 | State Flag | -> 0 = Inactive/dead
; ----------------------- >0 = Alive
; 1 | Address of first | <0 = Exploding
; -- --
; 2 | missile data block |
; -----------------------
; 3 |firing delay (alive) |
; |Expl scale (expldng) |
; -----------------------
; 4 | y delta (alive) |
; |scale delta (expldng)|
; -----------------------
; 5 | x delta |
; -----------------------
; 6 | 16-bit y |
; -- --
; 7 | position |
; -----------------------
; 8 | 16-bit x |
; -- --
; 9 | position |
; -----------------------
; 10 | angle |
; -----------------------
; 11 | Packet |
; . | jeep |
; 38 | vlist |
; -----------------------
;
; When player is alive, the embedded vlist is drawn.
; When player is exploding, vlist at 0xCA9A is drawn.
; When player is first hit, state is set to 0x80, and
; value is then counted up until it reaches 0.
;
; Tank Data (C900-C93F)
;
; -----------------------
; 0 | State Flag | -> 0 = Inactive/dead
; ----------------------- >0 = Alive
; 1 | # of hits | <0 = Burning
; -----------------------
; 2 |Fire missile counter |
; -----------------------
; 3 | |
; -----------------------
; 4 | |
; -----------------------
; 5 |Tank body angle delta|
; -----------------------
; 6 | Turret angle |
; -----------------------
; 7 | |
; -----------------------
; 8 | |
; -----------------------
; 9 | |
; -----------------------
; 10 | Ptr to array of | -> Only when burning?
; -- --
; 11 | flame locations |
; -----------------------
; 12 | Scale factor |
; -----------------------
; 13 | Flames array index |
; -----------------------
; 14 | y position |
; -----------------------
; 15 | x position |
; -----------------------
; 16 | y delta |
; -----------------------
; 17 | x delta |
; -----------------------
; 18 | Tank body angle |
; -----------------------
; 19 | Tank |
; -- --
; . | body |
; -- --
; 37 | vlist |
; -----------------------
; 38 | Tank |
; -- --
; . | turret |
; -- --
; 62 | vlist |
; -----------------------
;
; When tank is first hit, state is set to 0x80, and
; value is then counted up until it reaches 0.
;
; Helecopter Data (C894-C8A6)
;
; -----------------------
; 0 | State Flag | TEMP6
; -----------------------
; 1 | index - controls | TEMP7 -> 0 = try to fire
; | firing -vs- tracking| 1 = update position
; -----------------------
; 2 | counter - track | TEMP8 -> Resync when counts
; | players new position| down to 0.
; -----------------------
; 3 | counter - update | TEMP9 -> Update when 0
; | angle of travel |
; -----------------------
; 4 |Update body vlist flg| TEMP10 -> -1 = update needed
; ----------------------- 0 = update not needed
; 5 | | C899
; -----------------------
; 6 |Fire missile counter | C89A
; -----------------------
; 7 | Pointer to player | ACTPLY
; -- --
; 8 | being stalked | TMR1
; -----------------------
; 9 | Body y position | T1FUNC
; -----------------------
; 10 | Body x position | C89E
; -----------------------
; 11 | Body y offset | TMR2
; -----------------------
; 12 | Body x offset | T2FUNC
; -----------------------
; 13 | Heading delta (y) | C8A1
; -----------------------
; 14 | Heading delta (x) | TMR3
; -----------------------
; 15 | Movement delta (y) | T3FUNC
; -----------------------
; 16 | Movement delta (x) | C8A4
; -----------------------
; 17 | Angle of fire | TMR4
; -----------------------
; 18 | Body rotation angle | T4FUNC
; -----------------------
; 19 | Helecopter |
; -- --
; . | body |
; -- --
; 50 | vlist |
; -----------------------
;
; When the helecopter is started, the (y,x) position
; is randomly set to one of the following: (0,7F),
; (0,81), (7F,0) or (81,0).
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include "osmapV2.h"
include "fnmapV2.h"
; Bogus jump point back into the OS ROM
;
PF000 equ $F000
org 0x0000;
db "g GCE 1982",0x80
dw 0xFD81;
db 0xF8 ; height
db 0x50 ; width
db 0x20 ; rel y
db 0xC0 ; rel x
db "ARMOR ATTACK",0x80,0x00
P001F: ldx #LASRAM ; Clear 0xC880-0xCAFF
ldd #0x0280
jsr CLRBLK
ldd #0x0203 ; Get # of players (max 2)
jsr SELOPT ; Get game # (3 choices)
jsr DPRAM
lda #0xFF ; Set line pattern used
sta DASH ; when drawing buildings.
ldb #0xBB ; Button state mask:
; Btns 1,2,4: press/release
; Btn 3: continous
lda OPTION ; Which game was choosen?
cmpa #0x01 ; Game 1?
beq P0045 ; Branch if game 1
ldb #0x88 ; Button state mask:
; Btn 4: press/release
; Btns 1,2,3: continous
cmpa #0x02 ; Game 2?
beq P0045 ; Branch if game 2
inc DASH ; Use invisible buildings
P0045: stb 0xC8F0 ; Store game specific btn mask
clr EPOT1 ; Disable up/down movement
clr EPOT3 ; for both console jsticks.
ldd #0x7F7F
std 0xC8C9 ; Init two scale factors
RestartGame:
lda PLAYRS
sta 0xC8C8 ; Save copy of # of players
clr ETMP5 ; Index into level-specific
; data; init to 0.
; Initialize some OS variables
lda #0x10
sta POTRES ; Set jstick resolution limit
ldd #0xFA38
std SIZRAS ; Set font cell size (-6x56)
; Initialize some game specific variables
ldx #0xC8DE ; Initialize some variables,
ldu #Defaults; by copying the default
lda #0x07 ; values from ROM into the
jsr CopyUtoX ; appropriate RAM locations.
; Initialize player 1 score string
ldx #0xCA88 ; Ptr to player 1 score str
ldd #0x7888 ; Position to display score
std ,x++ ; Init player 1 score and
jsr SCLR ; its display position.
; Initialize player 2 score string
leax 7,x ; Ptr to player 2 score str
ldd #0x7838 ; Position to display score
std ,x++ ; Init player 2 score and
jsr SCLR ; its display position.
jsr INTREQ ; Initialize sound stuff
lda #0xFF;
sta FEAST ; Set, but never referenced!
sta ETMP8 ; Init flag to -1
sta 0xC8E9 ; Disable disp of #jeeps & score
sta 0xC8ED ; Disable "END" display
sta TEMP3 ; Start with big missile deltas
; Create 4 sets of 12 vectors, representing
; the rotating helecopter rotors.
ldx #HelecopterRotorVlist ; Src bufr
ldu #0xCA9A ; dest buffer
ldb #0x02 ; Vector count - 1 (3)
jsr CreateHelecopterRotors;
P0099: lda 0xC8E1 ; Set delay controlling when
sta XTMR0 ; play action starts.
lda 0xC8E0 ; Set delay controlling when
sta XTMR1 ; tanks are started up.
lda 0xC8DE ; Set the delay controlling
sta XTMR2 ; helecopter processing.
jsr InitPlayerData;
P00A8: jsr DisableAllTanks;
clr TEMP6 ; Disable the helecopter
ldx #0xC9C0 ; Disable all 8 missiles
ldd #0x0807 ; Count=8, obj size=7 bytes
jsr DisableObjects;
clr SATUS ; Disable all sounds
lda 0xC8E2 ; Any jeeps left?
bne P00DD ; Branch if some left
ldx #0xCA8A ; Get ptr to player 1 score
leau 9,x ; Get ptr to player 2 score
jsr WINNER ; Determine which player won
cmpa #0x02 ; Player 2 have hi score?
bne P00CA ; Jump if player 1 hi
leax ,u ; Player 2 has hi score
P00CA: ldu #HISCOR
jsr HISCR ; Save new high score
clr 0xC8ED ; Enable display of "END"
ldd #0x0BFF ; Set the counter controlling
std XTMR4 ; auto-restart of a new game.
lda 0xC8C8 ; Get # of players
sta 0xC8E9 ; Enable score/# jeeps display
bra IdleLoop;
P00DD: lda 0xC8C7 ; Any players still alive?
bne MainLoop ; Branch if yes
lda XTMR0 ; Branch if play action timer
beq P0099 ; already expired.
lda 0xC8C8 ; Get # of players
sta 0xC8E9 ; Enable score/# jeeps display
dec XTMR0 ; Decr play action counter
bne IdleLoop ; Branch if not ready to start
com 0xC8E9 ; Disable score/# jeeps display
MainLoop:
ldb 0xC8C7 ; Any players still alive?
beq P00A8 ; Branch if not
lda ETMP8 ; This flag starts at -1, and
bpl P010F ; the first pass thru, will
nega ; signal that the level-specific
sta ETMP8 ; initialization is needed. As
anda #0x03 ; tanks & helecopters start, its
cmpa #0x01 ; value will become 2, then 3.
bne P010F ; Branch if initialization done.
ldb ETMP5 ; Get level-specific index
ldu #LevelSpecificData ; Get ptr to
leau b,u ; level specific values.
ldx #LASRAM ; Initialize level-specific
lda #0x08 ; values by copying them from
jsr CopyUtoX ; ROM into RAM.
P010F: jsr CheckForMissileHits;
jsr ProcessHelecopter;
jsr ProcessTanks;
jsr ProcessBtnsBothPlayers;
; Draw visuals and make sounds. If the game
; is active, then goto the mainloop, to
; continue normal processing. Otherwise, do
; a soft game restart (using current # players)
; if the user presses a button before the two
; step idle loop counter expires.
IdleLoop:
inc 0xC8EE ; Incr mainloop counter
jsr MakeSounds ; Process active sounds
jsr DrawVisuals; Draw active objects
lda 0xC8ED ; Is game over?
bmi MainLoop ; Branch if not
ldb TRIGGR ; Get button states
lbne RestartGame; Restart if btn pressed
dec XTMR5 ; Decr the 2-step auto
bne IdleLoop ; restart counter. Stay
dec XTMR4 ; in the idle loop until
bne IdleLoop ; 2-step counter expires.
; Do a hard game restart (start from the
; game intro screen) after either the user
; presses a button, or the restart counter
; counts down to 0.
ldd #0x06FF ; Reset XTMR4, to control
std XTMR4 ; the hard restart loop.
P013A: jsr FRWAIT ; Wait for frame beginning
jsr INPUT ; Read controller buttons
jsr DPRAM ; Set DP ptr to RAM
ldx XTMR4 ; Stay in this loop, until
leax -1,x ; either a btn is pressed,
stx XTMR4 ; or XTMR4 counts down to
beq P0150 ; 0; then restart game.
lda TRIGGR ; Get button states
beq P013A ; Loop if no btns pressed.
P0150: jmp PF000 ; Restart from intro screen
; FDT - May be a bug; did not
; do right thing on a multi-
; cart.
; MoveDrawDashed()
;
; Entry: a = scale factor for moving
; u = ptr to rel (y,x) position
; x = ptr to diffy vlist
; s+0 = # of iterations remaining
; s+1 = vector count
;
; Used to draw the buildings. The dashed line pattern
; is used, to allow the walls to be visible (solid line)
; or invisible (line pattern turned off).
;
MoveDrawDashed:
sta T1LOLC ; Set scale factor (move)
ldd ,u++ ; Get pos to move to
jsr POSITN ; Move to rel (y,x) pos
lda #0x3F
sta T1LOLC ; Set scale factor (0x3F)
lda 3,s ; Retrieve vector count
sta LIST ; Save vector count
jsr DASHDF ; Draw dashed lines
dec 2,s ; Decr vlist counter
rts;
; DrawAtMultipleLocations()
;
; Entry: u = ptr to the following:
; byte 0 = iteration counter (?)
; byte 1 = vector count (?)
; byte 2,3 = rel (y,x) for pass 1
; byte x,x+1 = rel (y,x) for pass n
; x = ptr to diffy vlist
;
; Draw a given diffy vlist multiple times, at the
; specified set of locations.
;
DrawAtMultipleLocations:
ldd ,u++ ; Get iteration & vector counts
pshs a,b,x ; Save on stack
P016D: ldx 2,s ; Get ptr to vlist
lda 0xC8CA ; Load 'move' scale factor
bsr MoveDrawDashed ; Draw vlist
bne P016D ; More iterations?
puls a,b,x,pc ; All done
; DrawMultipleVlists()
;
; Entry: u = ptr to the following:
; byte 0 = # of vlists (?)
; byte 1 = vector count (?)
; byte 2,3 = rel (y,x) for vlist 1
; byte x,x+1 = rel (y,x) for vlist n
; x = ptr to set of diffy vlists
;
; Draw a set of diffy vlist, at the
; specified set of locations.
;
DrawMultipleVlists:
ldd ,u++ ; Get vlist & vector counts
pshs a,b ; Save on stack
P017C: lda 0xC8C9 ; Load 'move' scale factor
bsr MoveDrawDashed ; Draw vlist
bne P017C ; More iterations?
puls a,b,pc ; All done
; DrawVisuals()
;
; Takes care of drawing all buildings and outer boundaries,
; jeeps, tanks, the helecopter and any missiles. Also
; displays the score and # of jeeps, when enabled.
;
DrawVisuals:
inc ZSKIP;
jsr FRWAIT ; DP comes back set to IO
jsr REQOUT ; Output sound chip values
jsr INT3Q ; Use 3/4 intensity
; Draw the outer boundary area and the
; enclosed buildings. The attribute list
; provides details like the number of vlists
; to draw, the vector count and the (y,x)
; position for each vlist.
ldx #OuterBoundaryVlists;
ldu #AllVlistAttrs;
bsr DrawMultipleVlists;
ldx #LgSquareBuildingVlist;
bsr DrawAtMultipleLocations;
leax 12,x ; SmSquareBuildingVlist
bsr DrawAtMultipleLocations;
leax 8,x ; LBuildingVlists
bsr DrawMultipleVlists;
clr ZSKIP;
leas -10,s ; Allocate some work space
; Draw any active tanks (upto 3)
ldu #0xC900 ; Get ptr to array of tanks
ldd #ProcessArrayEntry;
std ,s ; Set array iterator proc
ldd #DrawTank; Primary processing proc
std 2,s ; Save primary proc addr
lda SJOY ; Loop cntr - max # tanks
ldb #0x40 ; Size of each array entry
jsr CallProcMultipleTimes;
; Draw each player's jeep
; Reuses iterator set above
ldu #RAMMES ; Get ptr to player 1 data
ldd #DrawJeep; Primary processing proc
std 2,s ; Save primary proc addr
lda 0xC8C8 ; Loop cntr - # of players
ldb #0x27 ; Size of each array entry
jsr CallProcMultipleTimes;
; Draw any active missiles (upto 8)
; Reuses iterator set above
ldu #0xC9C0 ; Get ptr to 1st missile
ldd #DrawMissile; Primary processing proc
std 2,s ; Save primary proc addr
ldy #0xCA56 ; Ptr to 1st missile vlist
ldd #0x0807 ; Loop cntr(8); entry size(7)
jsr CallProcMultipleTimes;
; Draw the helecopter
; Reuses iterator set above
ldu #TEMP6 ; Get ptr to helecopter data
ldd #DrawHelecopter; Primary processing proc
std 2,s ; Save primary proc addr
lda #0x01 ; Loop counter (1)
jsr CallProcMultipleTimes;
; Add any score updates (due to hits on tanks
; or helecopters) to each player's score
ldd #UpdateScore
std ,s ; Set array iterator proc
ldx #0xCA8A ; Ptr to player 1 score
ldu #0xC8E5 ; Ptr to plyr1 score additions
lda 0xC8C8 ; Loop cntr - # of players
jsr CallProcMultipleTimes;
; Set new intensity & scale for remaining drawing
ldd #0x7E7F
stb T1LOLC ; Set scale = 0x7F
jsr INTENS ; Set intensity = 0x7E
; If still in the startup delay, display the score
lda 0xC8E9 ; Is game play active?
bmi P021A ; Branch if yes
lda 0xC8C8 ; Loop cntr - # of players
ldx #RSTPOS ; Proc to display score
stx ,s ; Set array iterator proc
ldu #0xCA88 ; Addr of player 1 score
jsr CallProcMultipleTimes;
; If still in the startup delay, display the #
; of remaining jeeps, or, if none, then the
; "END" string.
P021A: leas 10,s ; Free up work space
lda 0xC8E9 ; Is game play active?
bmi ProcessInput; Branch if yes
ldx #0x78EF ; Set relative (y,x) pos
ldb 0xC8E2 ; Get # of remaining jeeps
lda #0x60 ; Jeep symbol char code
jsr DSHIP ; Draw remaining tanks
lda 0xC8ED ; Is the game over?
bne ProcessInput; Branch if not
ldu #EndString;
jsr RSTPOS ; Display "END" string
; Load the jstick/btn storage area with the
; current button states. Then, adjust the
; values for btn 0 (left) or btn 1 (right)
; depending upon the joystick setting.
ProcessInput:
lda 0xC8F0 ; Load button state mask
jsr DBNCE ; Read console buttons
jsr JOYBIT ; Read joysticks
lda 0xC8C8 ; Skip if no players
beq P026F;
ldx #0xCA4E ; Ptr to jstick/btn storage area
ldu #KEY0 ; Ptr to current button states
ldy #POT0 ; Ptr to current jstick states
P024F: pshs a,x ; Save loop cntr & data ptr
ldd ,u++ ; Get btn 1 & 2 states
std ,x+ ; Save btn 1 & 2 states
ldd ,u++ ; Get btn 3 & 4 states
std 1,x ; Save btn 3 & 4 states
clrb
lda ,y++ ; Load L/R jstick value
beq P0268 ; Do nothing if centered
rola ; Get a's sign bit into b
rolb
beq P0264 ; Branch if 'a' was +
coma ; Make 'a' positive
negb ; Set 'b' to -1
P0264: ora b,x ; Adj L/R value, based on the
sta b,x ; jstick position.
P0268: puls a,x ; Restore loop cntr & data ptr
leax 4,x ; Pt to player 2's storage area
deca ; Decrement loop counter
bne P024F ; Branch if more iterations
P026F: jsr ZERGND;
jmp DPRAM;
;
; DrawTank()
;
; Entry: u = ptr to tank data
;
; Draws a tank
;
DrawTank:
leax 14,u ; Get ptr to (y,x) pos
jsr POSIT1 ; Move there
leax 3,x ; Get ptr to tank body vlist
ldb #0x30 ; Set scale factor
jsr TPACK ; Draw the packet vlist
leax 0x26,u ; Get ptr to turret vlist
ldb #0x20 ; Set scale factor
jsr TPACK ; Draw the packet vlist
lda ,u ; Get tank's state flag
bpl P02AF ; Branch if still alive
jsr ZERGND;
jsr INTMAX ; Set maximum intensity
leax 14,u ; Get ptr to (y,x) pos
jsr POSIT1 ; Move there
ldx 10,u ; Get ptr to 'move' pos
ldb 13,u ; Calc offset (b * 6)
lda #0x06
mul
abx ; Add offset to 'move' ptr
ldb 12,u ; Load scale factor
jsr POSITB ; Move to pos pointed by x
lda #0x01 ; Set vector count -1 (2)
ldb 12,u ; Load scale factor
jsr TDIFFY ; Draw diffy vlist
jsr INT3Q ; Set intensity to 75%
P02AF: jmp ZERGND;
; DrawMissile()
;
; Entry: u = ptr to missile data
; y = ptr to missile vlist
;
; Draw a missile
;
DrawMissile:
leax 1,u ; Get ptr to (y,x) pos
jsr POSIT1 ; Move there
ldb ,u ; Get mode flag
bmi P02CD ; Branch if flag < 0
ldd 3,u ; Extract scale & dwell
sta DWELL ; Set dot dwell time
stb T1LOLC ; Set scale factor
lda #0x03 ; Vector count - 1
sta LIST ; Set vector count - 1
ldx 5,u ; Set diffy dot list ptr
jsr DIFDOT ; Draw the dots
rts;
P02CD: incb ; Is flag -1?
bmi P02DA ; Branch if flag < -1
lda #0x08 ; Load fixed dot dwell time
sta DWELL ; Set dot dwell time
jsr DOT ; Draw a single dot
bra P02E2;
P02DA: ldd #0x0428 ; vcount=5 & scale=0x28
leax ,y ; Get ptr to alt vlist
jsr TDIFFY ; Draw diffy vlist
P02E2: jsr ZERGND;
rts;
; DrawJeep()
;
; Entry: u = ptr to player data
;
; Draw a player's jeep, or an explosion
;
DrawJeep:
leax 6,u ; Ptr to 16-bit (y,x) pos
jsr POSWID ; Move to specified pos
lda ,u ; Get player's state flag
bpl P0301 ; Branch if alive
ldb 3,u ; Load scale factor
stb T1LOLC ; Set scale factor
ldx #0xCA9A ; Get ptr to explosion vlist
P02F6: lda #0x0B ; Load vector count - 1 (12)
sta LIST ; Set vector count - 1
jsr LDIFFY ; Draw diffy vlist
P02FE: jmp ZERGND;
P0301: leax 11,u ; Ptr to Jeep vlist
ldb #0x28 ; Set scale factor
jmp DrawPacketVlist;
; DrawHelecopter()
;
; Entry: u = ptr to helecopter data
;
; Draws the helecopter
;
DrawHelecopter:
leax 9,u ; Get ptr to (y,x) pos
ldd ,x ; Load (y,x) position
adda 2,x ; Add y body offset
bvs P0314 ; Branch if overflow
addb 3,x ; Add x body offset
bvc P0315 ; Branch if no overflow
P0314: rts;
P0315: jsr POSIT1 ; Move to pos pointed by x
jsr POSIT1 ; Offset by x & y body offsets
ldx #0xC8A7 ; Ptr to body vlists
lda ,u ; Get helecopter state flag
bmi P0336 ; Branch if exploding
ldb #0x20 ; Load scale factor
jsr TPACK ; Draw helecopter body
ldb #0x20 ; Load scale factor
stb T1LOLC ; Set scale factor
ldx #0xCA9A ; Ptr to rotor vlist array
ldb 5,u ; Calc offset into vlist
lda #0x18 ; offset = b * 24
mul
abx ; Add offset to vlist ptr
bra P02F6 ; Draw the rotors
; Helecopter is exploding
P0336: leay -2,u ; Ptr to intensity & scale
ldu #0xCB00 ; Get ptr to 'move' pos
lda ,y ; Load intensity value
exg u,x
jsr INTENS ; Set intensity
ldb 1,y ; Load scale factor
aslb ; Adjust scale factor
jsr POSITB ; Move to pos pointed by x
exg x,u ; Get vlist ptr into x
ldb #0x20 ; Load scale factor
jsr TPACK ; Draw 1st piece of hele body
ldb 1,y ; Load scale factor
exg u,x ; Get ptr to 'move' pos
jsr POSITB ; Move to pos pointed by x
exg x,u ; Get ptr to scale & vlist
ldb ,x+ ; Load scale factor
jsr TPACK ; Draw 2nd piece of hele body
ldx #0xCA9A ; Ptr to rotor vlist array
ldb 7,y ; Calc vlist offset
lda #0x18 ; offset = b * 24
mul
abx ; Add vlist offset
ldb #0x04
stb -5,s ; Set loop counter (4)
P036A: ldb 1,y ; Load scale factor
stb T1LOLC ; Set scale factor
ldd ,u++ ; Load 'move' pos
jsr POSITN ; Move to pos in 'd'
ldb #0x20 ; Set scale factor
lda #0x02 ; Set vector count - 1 (3)
jsr TDIFFY ; Draw rotors
dec -5,s ; Decrement loop counter
bne P036A ; Branch if more iterations
jmp ZERGND;
; CallProcMultipleTimes()
;
; Entry: s,s+1 = Ptr to iterator function
; a = # of times to call function
; b = Function specific value
;
; Invokes the specified function a given number
; of times. When the specified function is
; called, the stack has been set up as follows:
;
; ---------------
; top | a (counter) |
; ---------------
; | b |
; ---------------
; | Return |
; -- --
; | Address |
; ---------------
; | Iterator |
; -- --
; | Function |
; ---------------
; | Processing |
; -- --
; | Function |
; ---------------
;
CallProcMultipleTimes:
pshs a,b ; Save loop cntr & b(?)
tsta ; Check loop counter
beq P038D ; Bail if already 0
P0386: jsr [ 0x04,s ] ; Invoke function
dec ,s ; Decrement loop cntr
bne P0386 ; Jump if > 0
P038D: puls a,b,pc ; Clean up
; ProcessArrayEntry()
;
; Entry: s+3 = Size of each array entry
; s+6,s+7 = Ptr to processing function
; u = ptr to an array of objects to be
; processed.
; y = Function specific value; only used to
; hold a ptr to the missile vlists.
;
; Invokes the specified processing function on an
; array object, if the object is active (its
; state != 0). Afterwards, it updates the array
; pointer, so that the next time it is called, it
; will be referring to the next object to be
; processed.
;
; When the specified processing function is called,
; the stack has been set up as follows:
;
; ---------------
; top | Return |
; -- --
; | Address |
; ---------------
; | a (counter) |
; ---------------
; | b (array sz)|
; ---------------
; | Return |
; -- --
; | Address |
; ---------------
; | Iterator |
; -- --
; | Function |
; ---------------
; | Processing |
; -- --
; | Function |
; ---------------
;
; This is an iterator function.
;
ProcessArrayEntry:
lda ,u ; Get object's state flag
beq P0396 ; Branch if inactive
jsr [ 0x08,s ] ; Invoke processing function
P0396: ldb 3,s ; Get array object size
leau b,u ; Offset to next array object
leay 10,y ; Point to next missile vlist
rts;
; ProcessTanks()
;
ProcessTanks:
lda #0xFC ; Disable tank movement
anda SATUS ; sounds.
sta SATUS
lda XTMR1 ; Get tank startup delay cntr
lbeq P0448 ; Branch if already expired
dec XTMR1 ; Decr tank delay counter
bne P03E9 ; Branch if not expired
com ETMP8 ; Flag tanks are being processed
ldx #0xCB00 ; Init explosion endpoints
ldu #SmSquareBuildingVlist ; Src info
lda #0x04 ; Loop counter
pshs a ; Save loop counter
P03B9: ldd #0x0408 ; a=offset mask; b=byte cnt
jsr CopyRandomArrayData ; Copy data
dec ,s ; Decr loop counter
bne P03B9 ; Branch if more iterations
puls a ; Clean up stack
lda LASRAM ; Load the slow/fast tank mask
sta ETMP6 ; Save it
cmpa #0x01 ; Are slow tank sounds enabled?
bne P03D2 ; Branch if not
ldd #0x01FD ; Init slow tank sound mask
bra P03D5;
P03D2: ldd #0x02FE ; Init fast tank sound mask
P03D5: std 0xC8EB ; Save the sound masks
jsr DisableAllTanks;
lda 0xC882
sta ETMP7 ; Set tank body angle delta
ldx #0xC900 ; Get ptr to tank 1 data
ldb SJOY ; Get max # tanks allowed
stb ETMP9 ; Set # of visible tanks
P03E5: stb 0xC8CD ; Save # of tanks to start
bne P03EA ; Branch if more to start
P03E9: rts;
P03EA: lda #0x09 ; Locate the default
mul ; attributes associated
ldu #DftTankAttrsBase ; with this tank.
leau b,u;
inca ; Set to '1'
sta ,x+ ; Flag tank as active
lda #0x08 ; Loop counter
P03F7: clr ,x+ ; Clear the next 8 bytes
deca ; of the tank data.
bne P03F7 ; Branch if more bytes left
jsr RAND3 ; Get random # -> 'a'
anda #0x03 ; Force in range 0-3
sta ,x+ ;
lda #0x09 ; Copy in some default attrs
jsr CopyUtoX ; for this tank.
P0408: leau -2,x ; Get ptr to delta x value
lda ,u ; Retrieve delta x value
bne P0410 ; Branch if != 0
lda ,-u ; Retrieve delta y value
P0410: ldb ETMP6 ; 1=slow tanks, 2=fast tanks
mul ; Calculate the real movement
negb ; delta, based on whether the
stb ,u ; tanks are fast or slow.
ldb -10,x;
beq P0427;
leau -5,x ; Get ptr to tank's (y,x) pos
coma;
P041D: nega;
leau a,u;
neg ,u;
neg 2,u;
decb;
bne P041D;
P0427: clra;
P0428: tfr d,y;
ldd -5,x ; Get tanks's (y,x) pos
jsr CalcAngle3;Calc turret angle
sta -13,x ; Set turret angle
lda -1,x ; Get body rotation angle
leau ,x ; Set destination bufr
ldx #TankBodyVlist ; Packet vlist to rotate
jsr PROT ; Rotate the vlist
lda 0xE0,u ; Get turret rotation angle
jsr PROT ; Rotate turret vlist
leax 1,u;
ldb 0xC8CD ; Get # of tanks to start
decb ; Decr the new tank counter
bra P03E5;
P0448: lda ETMP9 ; Any tanks still visible?
bne P0451 ; Branch if yes
lda 0xC8E0 ; Get dflt tank startup counter
sta XTMR1 ; Reset tank startup counter
rts;
P0451: ldb 0xC900 ; Get tank 1 mode flag
bgt P0464 ; Branch if active
ldb 0xC940 ; Get tank 2 mode flag
bgt P0464 ; Branch if active
ldb 0xC980 ; Get tank 3 mode flag
bgt P0464 ; Branch if active
lda #0xFC ; Disable all tank
sta 0xC8EC ; sounds.
P0464: lda SATUS ; Make sure that the
ora 0xC8EB ; appropriate tank sounds,
anda 0xC8EC ; if any, are enabled (none,
sta SATUS ; slow or fast).
ldx #0xC8C8 ; Get base ptr for tank data
ldb 0xC88E ;
P0471: incb ; Generate a value in the
andb #0x03 ; the range 1-3 (will be used
stb 0xC88E ; to index in tank array).
beq P0471 ; Try again, if value = 0
lda #0x40 ; Create offset into array;
mul ; each array entry is 0x40
abx ; bytes.
lda -8,x ; Load tank's state flag
beq P048B ; Branch if not visible
bmi TankBurning ; Branch if burning
ldb -7,x ; Get # of hits on tank
bne TankHit ; Branch if hits > 0
tsta ; Is tank alive?
lbne TankIsAlive ; Branch if yes
P048B: rts;
; Tank has been hit; from now on, draw it
; as burning.
TankHit:
lda #0x80 ; Flag tank as burning, by
sta -8,x ; setting the state flag.
ldu #0xCB00 ; Set ptr to the flames
stu 2,x ; positioning array.
ldb #0x10 ; Get flames scale factor
lda 10,x ; Load tank body angle
stb 4,x ; Set scale factor
clr 5,x ; Set flames array offset=0
leau 11,x ; Set dest bufr
ldx #DestroyedTankBodyVlist ; Src bufr
jmp PROT ; Rotate tank body vlist
; Tank is burning.
; Once the state field (burn counter) increments
; to 0, the tank has burned up and will be
; deactivated.
TankBurning:
inc -8,x ; Incr burn counter
bne StillBurning ; Branch if != 0
clr -7,x ; Clear # hits on tank
dec ETMP9 ; Decr # of visible tanks
bne P04B1 ; Branch if more tanks visible
clr 0xC8EB ; Disable tank sounds
P04B1: rts;
; The tank is still burning.
; As we approach the end of the burn stage,
; we need to make the flames appear to grow.
; If the tank has taken a 2nd hit, then it
; will now be completely disabled.
StillBurning:
cmpa #0xF8 ; Cnt up time < -8?
blt P04BC ; Branch if yes
lda #0x02 ; Incr scale factor used to
adda 4,x ; draw flames; makes flames
sta 4,x ; look larger.
P04BC: jsr UpdateVlistIndex; Update flames vlist idx
ldb -7,x ; Get # hits on tank
decb ; Does tank only have 1 hit?
beq TurretActive ; Branch if yes
ldu #DestroyedTurretVlist
leax 0x1E,x ; Switch to using the disabled
lda #0x19 ; turret vlist
jmp CopyUtoX
; Tank has 1 hit, which means the tank body is
; disabled, but the turret is still active, and
; thus, can track the user and fire.
TurretActive:
dec -6,x ; Decr 'attempt to fire' counter
bgt TankTrackPlayer ; Branch if not time to fire
ldu #0xC9DC ; Get base ptr to system missiles
ldb 0xC88E ; Get ptr to the missile
lda #0x07 ; associated with this tank.
mul;
leau b,u;
ldb ,u ; Get missile state flag
bne TankTrackPlayer ; Branch if already in use
ldd 6,x ; Get tank's (y,x) pos
std 1,u ; Save as missile's pos
ldb -2,x ; Get turret angle
lda ETMP4 ; Reset counter controlling
sta -6,x ; when tank tries to fire.
CalcMovementDelta:
lda #0x07 ; Velocity = 7
jsr LROT90 ; Calc missile move deltas
std 3,u ; Save delta y & delta x
asra ; The next block takes
asrb ; the deltas we just
std 5,u ; calculated, divides them
ldd 3,u ; by 2, and then saves the
suba 5,u ; new values.
subb 6,u
std 3,u ; New values saved here
dec ,u ; Set missile state = in use
P0500: rts;
; TankTrackPlayer()
;
; Determine which player is closer, and head towards
; that player.
;
TankTrackPlayer:
lda #0x7F ; Initialize the proximity
sta 0xC8D0 ; value to max distance.
ldu #0xCA06 ; Get ptr to player 1 pos
lda -6,u ; Get player 1 state flag
ble P0517 ; Branch if not visible or dying
ldd 6,x ; Get tank's (y,x) pos
jsr CalcAngle2; Calc angle to player's jeep
cmpb #0x04 ; Did they collide?
blt TankCollidedWithPlayer; Branch if yes
std 0xC8CF ; Save angle & proximity
P0517: lda 0xC8C8 ; Get # of players
deca ; > 1 player?
beq P0530 ; Branch if not
leau 0x27,u ; Get ptr to player 2 pos
lda -6,u ; Get player 2 state flag
; FDT: bug - should be ble!
blt P0530 ; Branch if being destroyed
ldd 6,x ; Get tank's (y,x) pos
jsr CalcAngle2; Calc angle to player's jeep
cmpb #0x04 ; Did they collide?
blt TankCollidedWithPlayer; Branch if yes
cmpb 0xC8D0 ; Are we closer to player 2?
blt P0532 ; Branch if yes
P0530: lda 0xC8CF ; Track player 1 (closer)
P0532: anda ETMP2 ; Course tune the angle
cmpa -2,x ; Does turret angle need to
beq P0500 ; change? Branch if not.
ldb 0xC8EE ; Update only on every
bitb #0x01 ; other pass.
beq P0500 ; No update on this pass
sta -2,x ; Save updated turret angle
leau 0x1E,x ; Set destination bufr
ldx #TankTurretVlist ; Src packet vlist
jmp PROT ; Rotate turret vlist
; TankCollidedWithPlayer()
;
; When a tank and a player collide, both are destroyed.
; Mark the tank as having taken 2 hits (thus disabling
; it) and mark the jeep as destroyed.
;
TankCollidedWithPlayer:
lda #0x02
sta -7,x ; Force tank to have 2 hits
lda #0x80
sta -6,u ; Flag player as hit
rts;
; TankIsAlive()
;
; Entry: x = pointer to tank data (+8)
;
TankIsAlive:
lda ,x;
beq P0568;
suba ETMP7 ;
sta ,x;
lda 10,x ; Get current tank body angle
adda -3,x ; Update it (add delta)
sta 10,x ; Save updated rotation angle
leau 11,x ; Set destination bufr
ldx #TankBodyVlist ; Packet vlist to rotate
jmp PROT ; Rotate the vlist
; Entry: x = pointer to tank data (+8)
;
P0568: ldy #S0DA0;
lda 5,x;
lbeq P0600;
leau 0x40,x ; Get ptr to next tank (secondary)
cmpu #0xC9C8 ; Do we need to wrap?
bne P057E ; Branch if no wrap needed
ldu #0xC908 ; Wrap back to tank 1
P057E: lda -8,u ; Get secondary tank state flag
ble P05DD ; Branch if inactive or burning
ldd 6,u ; Get secondary tank's (y,x) pos
suba 6,x ; Subtract primary tank's y pos
bvs P05DD ; Branch if invalid (overflow)
subb 7,x ; Subtract primary tank's x pos
bvs P05DD ; Branch if invalid (overflow)
jsr ABSAB ; Get abs val of the pos deltas
std 0xC8CB ; Save y & x delta values
tsta ; Are tanks at same y pos?
beq P0597 ; Branch if yes
tstb ; Are tanks at same x pos?
bne P05DD ; Branch if not
P0597: adda 0xC8CC ; Add deltas, to get proximity
cmpa #0x0C ; Are the tanks close (w/in 12 units)?
bgt P05DD ; Branch if not
lda 3,x;
cmpa 2,x;
beq P05DD;
deca;
ldb #0x08;
mul;
leay 4,y;
leay d,y;
ldb 4,x;
lda b,y;
suba 5,x;
beq P05DD;
sta 5,x;
addb #0x02;
andb #0x03;
stb 4,x ; Set scale factor
leay -4,y;
incb;
andb #0x03;
lda b,y;
bne P05CF;
incb;
incb;
andb #0x03;
lda b,y;
bne P05CF;
incb;
andb #0x03;
P05CF: stb -4,x;
neg 8,x ; Reverse y delta dir
neg 9,x ; Reverse x delta dir
clr -1,x;
ldd 2,x ; Swap the 2 bytes
sta 3,x;
stb 2,x;
P05DD: lda 5,x;
suba ETMP6 ; 1=slow tanks, 2=fast tanks
bpl P05F3;
leay 9,x ; Get ptr to x delta
ldb ,y ; Get x delta value
bne P05EB;
ldb ,-y ; Get y delta value
P05EB: bpl P05EE;
nega;
P05EE: adda ,--y ; Add current x or y pos
sta ,y ; Save new x or y pos
clra;
P05F3: sta 5,x;
ldd 6,x ; Get tank's (y,x) pos
adda 8,x ; Add y delta
addb 9,x ; Add x delta
std 6,x ; Save updated position
jmp TurretActive;
P0600: lda -5,x;
beq P0618;
ldb #0x08;
stb 5,x;
suba 1,x;
anda #0x03;
sta 1,x;
lda -5,x;
anda #0x02;
asra;
sta 4,x ; Update scale factor
clr -5,x;
rts;
P0618: lda 2,x;
deca;
ldb #0x08;
mul;
leay d,y;
ldb -4,x;
bmi P0628;
com -4,x;
bsr P065F;
P0628: ldb -2,x ; Get turret angle
lsrb ; Divide it by 16
lsrb
lsrb
lsrb
cmpb 1,x;
bne P0633;
negb;
P0633: addb 1,x;
cmpb #0x04;
bne P063B;
ldb #0x02;
P063B: andb #0x03;
tfr b,a;
inca;
pshs a,b;
jsr RANDOM ; Get random # -> a
puls a,b;
bhs P064B;
exg a,b;
P064B: sta 0xC8CB ;
bsr P065F;
ldb 0xC8CB ;
bsr P065F;
ldb 4,x;
bsr P065F;
ldb #0x03;
P0659: bsr P065F;
decb;
bpl P0659;
rts;
; Entry: y = ptr to data (0x0DA0)
; b = ?
; x = ptr to data (+8)
P065F: andb #0x03;
lda b,y;
beq P066D;
cmpa 3,x;
bne P066E;
tst -1,x;
beq P0672;
P066D: rts;
P066E: clr -1,x;
bra P0674;
P0672: inc -1,x;
P0674: std ,s++;
cmpa 2,x;
bne P0683;
rorb;
blo P067F;
addb #0x02;
P067F: addb #0x02;
stb -5,x;
P0683: lda 2,x;
sta 3,x;
ldd -2,s;
sta 2,x;
leay b,y;
lda 4,y;
sta 5,x;
tfr b,a;
subb 4,x;
andb #0x03;
beq P06A5;
sta 4,x;
cmpb #0x02;
bne P06A6;
ldd 8,x ; Load tank's y & x deltas
nega ; Reverse y direction
P06A2: negb ; Reverse x direction
P06A3: std 8,x; ; Update tank's y & x deltas
P06A5: rts;
P06A6: lda #0x10;
sta ,x;
lda 1,x;
rora;
bhs P06B3;
addb #0x02;
andb #0x03;
P06B3: lda ETMP7 ; Get dflt tank body angle delta
sta -3,x ; Save it
lda 9,x ; Get tank's x delta
pshs b;
ldb 8,x ; Get tank's y delta
dec ,s+;
beq P06A2;
nega ; Reverse x delta direction
neg -3,x ; Reverse tank body angle delta
bra P06A3;
; ProcessBtnsBothPlayers()
;
; Process the buttons and joystick for each player,
; adjusting position and angle as requested, and
; firing a missile when requested (and one is
; available).
;
ProcessBtnsBothPlayers:
ldx #RAMMES ; Get ptr to player 1 data
clra ; Plyr 1 missile vlist offset=0
sta 0xC8DA ; Save missile vlist offset
ldy #0xCA4E ; Ptr to player 1 btn state info
P06D0: bsr ProcessBtnsOnePlayer;
lda #0x02 ; Plyr 2 missile vlist offset=2
sta 0xC8DA ; Save missile vlist offset
leay 4,y ; Ptr to player 2 btn state info
leax 0x27,x ; Ptr to player 2 data
cmpx #0xCA4E ; All done?
bne P06D0 ; Branch if not
rts
; ProcessExplodingJeep()
;
; Entry: x = ptr to player data
; a = player's state flag
;
ProcessExplodingJeep:
ldb 3,x ; Get explosion scale factor
cmpa #0x80 ; Was jeep just hit?
bne P06EF ; Branch if not
ldb #0x02 ; Set the explosion scale
stb 4,x ; factor delta.
ldb #0x01 ; Set the initial explosion
stb 3,x ; scale factor.
P06EF: inca ; Incr player's state (counter
sta ,x ; controlling explosion duration.
bne P06FB ; Branch if not explosion done
dec 0xC8C7 ; Decr # of players still alive
bne P06FA ; Branch if >= 1 player still alive
dec 0xC8E2 ; Decr # of jeeps remaining
P06FA: rts;
P06FB: cmpa #0xC2 ; State counted down to -62?
bne P0701 ; Branch if not
P06FF: neg 4,x ; Negate explosion scale factor delta
P0701: asra ; Skip the following code every
blo P06FA ; other pass.
addb 4,x ; Add explosion scale factor delta
stb 3,x ; to the current scale factor.
rts
; UpdateVlistIndex()
;
; Entry: x = ptr to object data
;
UpdateVlistIndex:
lda 5,x ; Get current vlist index
inca ; Increment the index
anda #0x03 ; Force in range 0-3
sta 5,x ; Save update value
P0710: rts
; ProcessBtnsOnePlayer()
;
; Entry: x = ptr to player data
; y = ptr to btn state info
; C8DA = 0 - player 1
; 2 - player 2
;
ProcessBtnsOnePlayer:
lda ,x ; Get player's state
bmi ProcessExplodingJeep ; Exploding
beq P0710 ; Branch if not active
pshs x;
lda 3,x ; Get firing delay
beq P0721 ; Proceed if expired
dec 3,x ; Decr firing delay
bne ProcessBtns ; Branch if not expired
P0721: lda 3,y ; Get state of firing btn
beq ProcessBtns ; Branch if not pressed
ldb 0xC8DA ; Get missile vlist base index
ldu 1,x ; Get ptr to player's 1st missile
lda ,u ; Is missile in use?
beq MissileAvailable ; Branch if available
incb ; Incr missile vlist index
leau 7,u ; Get ptr to missile 2
lda ,u ; Is missile in use?
bne ProcessBtns ; Branch if already in use
MissileAvailable:
stb 0xC8CB ; Save index of available missile
dec ,u ; Flag missile as in use
lda #0x10 ; Enable missile firing sound
ora SATUS
sta SATUS
lda 6,x ; Get player's y pos
ldb 8,x ; Get player's x pos
std 1,u ; Save as initial missile pos
ldb 10,x ; Get jeep's rotation angle
jsr CalcMovementDelta;
lda #0x08 ; Get default firing delay
sta 3,x ; Reset player's firing delay
ldb #0x0A ; Calculate the address of
lda 0xC8CB ; of the missile vlist to use.
mul
ldu #0xCA56
leau b,u ; Get ptr to missile vlist
lda 10,x ; Get jeep's rotation angle
ldx #MissileVlist ; Src vlist to rotate
ldb #0x04 ; Vector count - 1 (5)
jsr DROT ; Rotate the missile vlist
lda 0xC8EF ; Is helecopter exploding?
bmi P076F ; Branch if yes.
lda #0x80;
ora SATUS;
sta SATUS;
lda #0x20;
sta 0xC8EF ;
P076F: puls x,pc;
; ProcessBtns()
;
; Entry: y = ptr to player's button/joystick info
; x = ptr to player data
;
; Process the buttons and joystick, to determine
; the jeeps position or direction of travel needs
; to change. Also checks if the player has run
; into a wall.
;
ProcessBtns:
lda 2,y ; Get state of 'move' btn
beq P07CD ; Branch if not pressed
ldb 4,x ; Get y delta
sex ; Convert to 16-bits, and
aslb ; multiply by 8.
rola
aslb
rola
aslb
rola
std 0xC8CB ; Save 16-bit y delta
addd 6,x ; Add player's current y pos
std 6,x ; Save new position
ldb 5,x ; Get x delta
sex ; Convert to 16-bits, and
aslb ; multiply by 8.
rola
aslb
rola
aslb
rola
std 0xC8CD ; Save 16-bit x delta
addd 8,x ; Add player's current x pos
std 8,x ; Save new position
clrb ; Used to track sign of y & x
lda 6,x ; Load new y pos (hi byte)
bpl P079A ; Get absolute value
nega ; Make positive
incb ; Flag it was negative
P079A: sta 0xC8DB ; Save absolute y pos
lda 8,x ; Load new x pos (hi byte)
bpl P07A3 ; Get absolute value
nega ; Make positive
orb #0x02 ; Flag it was negative
P07A3: sta 0xC8DC ; Save absolute x pos
pshs b ; Save +/- sign flags
ldb 0xC8DB ; Load absolute y value
ldu #HorizontalWalls; Check if user is
bsr CheckForWallContact; up against a
bvc P07B2 ; horizontal wall.
stb 0xC8DB ; Store updated abs y val
P07B2: ldb 0xC8DC ; Load absolute x value
ldu #VerticalWalls; Check if user is
bsr CheckForWallContact; up against a
bvc P07BD ; vertical wall.
stb 0xC8DC ; Store updated abs x val
P07BD: ldd 0xC8DB ; Get updated (y,x) values
ror ,s ; Restore the original
bhs P07C4 ; +/- sign for the y
nega ; value.
P07C4: sta 6,x ; Save updated signed y value
ror ,s+ ; Restore the original
bhs P07CB ; +/- sign for the x
negb ; value;
P07CB: stb 8,x ; Save updated signed x value
P07CD: clra ; Clear the rotation adjustment
ldb ,y ; Get state of 'rotate left' btn
beq P07D3 ; Skip if not pressed
inca ; Rotate left (add +1)
P07D3: ldb 1,y ; Get state of 'rotate right' btn
beq P07D8 ; Skip if not pressed
deca ; Rotate right (add -1)
P07D8: tsta ; Do nothing if both pressed, or
beq P07FA ; neither btn pressed.
adda 10,x ; Update jeep's angle of travel
anda #0x3F ; Make angle 0-360
sta 10,x ; Save new angle
tfr a,b ; Load rotation angle
lda #0x20 ; Velocity = 32
jsr LROT90 ; Calc new movement deltas
std 4,x ; Save new movement deltas
lda 0xC8DA ; 0=plyr1, 2=plyr2
ldb #0x0E ; Half size of each element
mul ; Calc offset into vlist set
lda 10,x ; Get rotation angle
leau 11,x ; Set destination bufr
ldx #JeepVlists ; Set vlist to rotate
abx ; Add in the offset (plyr1/plyr2)
jsr PROT ; Rotate the packet vlist
P07FA: puls x,pc;
; This appears to be dead code!
P07FC: ldb -13,x;
lda #0x02;
sta -13,x;
leax ,u;
subb #0x02;
bmi P080E;
lda #0x80;
sta ,x;
puls x,pc;
P080E: ldd 6,x;
subd 0xC8CB ;
std 6,x;
ldd 8,x;
subd 0xC8CD ;
std 8,x;
bra P07CD;
; CheckForWallContact()
;
; Entry: b = absolute value of x or y position
; u = ptr to horizontal (y) or vertical (x)
; wall data
; C8DB = absolute value(y pos)
; C8DC = absolute value(x pos)
;
; Exit: cc: 1 = contact occurred
; 0 = no contact
; b : if contact, updated y or x position;
; prevent jeep from passing thru wall.
;
; Uses the coordinate to generate a table offset,
; which is then used to get a list of walls within
; range of the coordinate. If the coordinate is
; within the bounds of a wall, then the cc is set,
; and an updated coordinate is returned in b (this
; prevents a jeep from passing thru a wall).
;
; The coordinate ranges for each table offset are
; as follows:
;
; 0x0A-0x19 => 0x00
; 0x1A-0x29 => 0x02
; 0x2A-0x39 => 0x04
; 0x3A-0x49 => 0x06
; 0x4A-0x59 => 0x08
; 0x5A-0x69 => 0x0A
; 0x6A-0x79 => 0x0C
;
CheckForWallContact:
subb #0x0A ; Subtract 10 from the position
bmi P084A ; Branch if orig value <= 9
andb #0x70 ; Get 3 most significant bits
asrb ; Shift right 3 bits, to
asrb ; form a table offset in the
asrb ; lower nibble (0x00-0x0C).
ldd b,u ; Set a=offset, b=loop cntr
leau a,u ; Get ptr to wall data
stb 0xC8DD ; Save loop counter
P082B: ldd 0xC8DB ; Get object's (y,x) pos
suba ,u ; Check if y falls within the
bmi P0842 ; bounds of the current wall;
cmpa 1,u ; move onto the next wall,
bgt P0842 ; if not.
subb 2,u ; Check if x falls within the
bmi P0842 ; bounds of the current wall;
cmpb 3,u ; move onto the next wall,
bgt P0842 ; if not.
ldb 4,u ; Return updated y or x pos
orcc #0x02 ; Set overflow bit, to signal
rts ; wall contact occurred.
P0842: leau 5,u ; Point to next wall data block
dec 0xC8DD ; More walls to process?
bne P082B ; Branch if yes
andcc #0xFD ; Clear overflow bit, to signal
P084A: rts ; no wall contact occurred.
; InitPlayerData()
;
; Initializes the player data associated with each
; active player.
;
InitPlayerData:
ldu #RAMMES ; Set destination bufr
ldy #0xC9C0 ; Save ptr to 1st missile
ldx #JeepVlists ; Packet vlist to rotate
lda 0xC8C8 ; Get # of players
sta 0xC8C7 ; Save as # players still alive
ldb #0x20 ; Player 1 starting y pos
P085B: pshs a,b ; Save for later use
sta ,u+ ; Init the state flag
sty ,u++ ; Save addr of 1st missile
ldb #0x08 ; Clear the next 8 bytes
P0864: clr ,u+ ; of the user data.
decb ; More bytes?
bne P0864 ; Branch if yes
ldd ,s ; Load x delta & y position
std -6,u ; Save x delta & y position
jsr PROT ; Rotate packet vlist
leay 14,y ; Point to next player
puls a,b ; Restore saved values
negb ; Init player 2 starting y pos
deca ; Another player?
bne P085B ; Branch if yes
rts;
; HelecopterExploding()
;
; Entry: x = ptr to helecopter position (C89D)
; a = Helecopter mode flag (TEMP6)
;
HelecopterExploding:
nega ; Check if helecopter was just
bvc P088D ; hit; branch if not
deca ; Decr helecopter intensity,
clrb ; and clear scale; save the
std TEMP4 ; updated values.
asr T3FUNC ; Decrease y movement delta
asr 0xC8A4 ; Decrease x movement delta
decb ; Set to -1
stb 0xC8EF ; Flag helecopter exploding
lda #0x80 ; Enable a sound (helecopter
ora SATUS ; hit/exploding??)
sta SATUS
P088D: inc TEMP6 ; Increment helecopter state
bne ContinueExplosion ; Branch if not done
; exploding
clr 0xC8EF ; Clear helecopter exploding
lda #0xF7 ; Disable a sound (helecopter
anda SATUS ; exploding??)
sta SATUS;
rts;
; ContinueExplosion()
;
; Every few passes through this function, we will
; increase the allowed angle of fire for the next
; helecopter, and we will alter the angle used to
; draw the destroyed helecopter. We will also
; decrease the intensity used to draw the helecopter,
; and update the vector list.
;
ContinueExplosion:
rora
bhs P08B7 ; Branch if bit 7 = 0
inc TMR4 ; Increase angle of fire
; allowed for next helecopter.
dec T4FUNC ; Decr helecopter rotation angle
rora
bhs P08A8 ; Branch if bit 6 = 0
dec TEMP4 ; Decr helecopter intensity
inc TEMP5 ; Incr helecopter scale
P08A8: lda T4FUNC ; Get helecopter rotation angle
leau 10,x ; Set destination bufr
ldx #DestroyedHelecopterVlists ; Src vlist
jsr PROT ; Rotate packet vlist
lda T4FUNC ; Get helecopter rotation angle
jsr PROT ; Rotate packet vlist
P08B7: jmp ValidateHelePos
; ProcessHelecopter()
;
ProcessHelecopter:
ldx XTMR2 ; Get startup counter
beq CheckHelecopter ; Skip if already processed (0)
leax -1,x ; Decrement the counter and
stx XTMR2 ; save updated value.
bne P0910 ; Branch if not counted down to 0
lda #0xF7 ; Start a helecopter
anda SATUS;
sta SATUS;
com ETMP8 ; Flag helecopter being processed
ldx #TEMP6 ; Clear the first 25 bytes
ldb #0x19 ; of the helecopter data
jsr BCLR ; structure.
lda #0x00;
sta FEAST ; Set, but never referenced!
lda #0x02;
sta TEMP6 ; Set the helecopter state flag
deca ; Don't have the helecopter fire
sta TEMP7 ; a missile yet.
ldd #RAMMES ; Config to initially stalk
std ACTPLY ; player 1.
lda ETMP1 ; Set counter controlling when
sta TEMP8 ; to requery player's position.
lda ETMP4 ; Set counter controlling when
sta 0xC89A ; to fire a missile.
leax 9,x;
jsr RANDOM ; Load random # -> a; determines
clrb ; edge helecopter enters from:
rola ; bit 7: 0=top/bottom(set y pos)
; 1=left/right(set x pox)
rolb ; bit 6: 0=right(x)/top(y)
; 1=left(x)/bottom(y)
leax b,x ; Get ptr to y or x position
stb 0xC8CB ; (0 or 1)
ldb #0x7F ; Starting position
rola ; If bit 6=1, then negate position
bhs P08FE ; to start from left (if x) or
negb ; bottom (if y).
P08FE: stb ,x ; Save initial y or x position
asrb ; Initialize the body offset
asrb ; to be the initial position/4.
stb 2,x ; Save initial body offset.
lda #0x07;
suba 0xC8CB ; (0 or 1)
suba 0xC8CB ; (0 or 1)
P090A: leax a,x;
inc ,x;
com TEMP10 ; Flag vlist needs updating
P0910: rts;
; CheckHelecopter()
;
CheckHelecopter:
ldx #TEMP6 ; Get ptr to helecopter data
jsr UpdateVlistIndex ; Update rotor index
leax 9,x ; Get ptr to hele (y,x) pos
lda TEMP6 ; Get helecopter state flag
lbmi HelecopterExploding
bne HelecopterActive;
std ETMP10 ; Reset target position
ldd 0xC8DE ; Reset helecopter processing
std XTMR2 ; delay counter.
rts;
; HelecopterActive()
;
; Entry: x = ptr to helecopter data (+9)
HelecopterActive:
lda #0x08;
ora SATUS;
sta SATUS;
ldb TEMP10 ; Branch if helecopter body
bpl TrackPlayer ; vlist doesn't need updating.
leau 10,x ; Set dest bufr
ldx #HelecopterBodyVlist ; Src vlist
lda T4FUNC ; Get helecopter rotation angle
jsr PROT ; Rotate packet vlist
clr TEMP10 ; Clear 'needs update' flag
bra ValidateHelePos
; TrackPlayer()
;
; Entry: x = pointer to helecopter data (+ 9)
;
TrackPlayer:
ldd ETMP10 ; Get pos of player to track
tfr d,y ; Xfer pos to y register
jsr CalcAngle1; Get angle to player
anda ETMP2 ; Course tune the angle
std 0xC8CD ; Store angle & proximity
leax 9,x ; Get ptr to angle of travel
cmpb #0x08 ; Is player close (w/in 8 units)?
bls P0959 ; Branch if yes
suba T4FUNC ; Sub helecopter rotation angle
beq P0959 ; Branch if already heading in
; the desired direction.
bsr UpdateTravelAngle ; Update angle of travel
dec TEMP10 ; Flag that vlist needs updating
P0959: leax -1,x;
lda TEMP7 ; Based on whether the helecopter
anda #0x01 ; is supposed to fire or just move,
asla ; call the appropriate processing
ldu #HelecopterActionTable ; function.
jsr [ a,u ]
; ValidateHelePos()
;
; See if the helecopter has reached the boundary of the
; playing area, and if so, force it back in.
;
ValidateHelePos:
ldd #0x78FF ; Edge coordinate = 0x78; delta = -1
leax -6,x ; Get ptr to (y,x) offset
cmpa ,x+ ; Is 'y' in range?
blt P097E ; Branch if out of range
cmpa ,x+ ; Is 'x' in range?
blt P097E ; Branch if out of range
nega ; Edge coordinate = -0x78
negb ; Delta = +1
leax -2,x ; Get ptr to (y,x) offset
cmpa ,x+ ; Is 'y' in range?
bgt P097E ; Branch if out of range
cmpa ,x+ ; Is 'x' in range?
blt P0980 ; Branch if in range
P097E: stb 3,x ; Set the movement delta for the
; out of range coordinate.
P0980: ldd TMR2 ; Get helecopter y/x pos offset
adda T3FUNC ; Add y movement delta
addb 0xC8A4 ; Add x movement delta
std TMR2 ; Save updated y/x pos offset
rts;
; UpdateTravelAngle()
;
; Entry: a = difference between the current angle of
; travel, and the desired angle of travel.
; x = pointer to helecopter's angle of travel.
; C8CD = desired angle of travel.
;
; Determines whether CW or CCW rotation is needed to
; bring the helecopter to the desired angle of travel.
; Updates the helecopter's angle of travel in the
; necessary direction.
;
UpdateTravelAngle:
anda #0x3F ; Make 0<=angle<360
ldb #0x01 ; Assume CCW angle delta
cmpa #0x20 ; Angle delta <= 180 degrees?
ble P0992 ; Branch if yes
negb ; Use CW angle delta
P0992: stb 0xC8CF ; Save angle delta value
addb ,x ; Add current angle of travel
andb #0x3F ; Make 0<=angle<360
cmpb 0xC8CD ; Match desired angle of travel?
beq P09A0 ; Branch if yes
addb 0xC8CF ; Add angle delta a second time
andb #0x3F ; Make 0<=angle<360
P09A0: stb ,x ; Save updated angle of travel
rts
; UpdateHelecopterHeading()
;
; Update the helecopter's angle of travel, as we
; track the player.
;
UpdateHelecopterHeading:
lda TEMP8 ; Is it time to get an update
deca ; on the player's position?
bne P09AA ; Branch if not
bsr GetPlayerPos ; Get player's current pos
P09AA: lda #0x02;
sta FEAST ; Set, but never referenced!
ldd T1FUNC ; Get hele's nose (y,x) offset
jsr CalcAngle3; Get angle to player & proximity
cmpb #0x04 ; Are they really close?
ble EnableMissileFire ; Allow firing, if so
tfr a,b ; Set rotation angle
lda #0x01 ; Velocity = 1
jsr LROT90 ; Calc heading change deltas
std 0xC8A1 ; Save heading change deltas
adda T1FUNC ; Add helecopter's y position
addb 0xC89E ; Add helecopter's x position
std T1FUNC ; Update hele's (y,x) position
rts;
; EnableMissileFire()
;
; If we an update position for the player, then enable
; missile firing.
;
EnableMissileFire:
lda TEMP8 ; Have we already updated the
bne AdjTargetPos ; player's pos? Branch if not.
sta TEMP7 ; Prepare hele to fire missile
rts;
; AdjTargetPos()
;
; Rather than firing directly where the player was, add
; some random adjustments to the target location, so give
; the player a chance.
;
AdjTargetPos:
dec TEMP8 ; Decr 'update' counter, and
beq GetPlayerPos ; Update player's pos if 0.
jsr RANDOM ; 'Adjust' the perceived 'y'
adda ETMP10 ; location of the player we're
sta ETMP10 ; targeting.
rola ; 'Adjust' the perceived 'x'
rola ; location of the player we
coma ; are targeting. In other words,
adda 0xC88D ; allow for some randomness when
sta 0xC88D ; targeting a missile.
rts
; GetPlayerPos()
;
; Entry: ACTPLY = ptr to player being stalked
;
; Exit: ETMP10 = player's position
; cc = 0 (no position set)
; 1 (ETMP10 updated with pos)
; ACTPLY = ptr to player to stalk
;
; If player 1 is alive, get his position.
; Otherwise, set up to return player 2's
; position the next time we are called.
;
GetPlayerPos:
ldu ACTPLY ; Get ptr to player being stalked
lda ,u ; Get player's state flag
bgt P09F5 ; Branch if alive
ldu #0xCA27 ; Get ptr to player 2 data
stu ACTPLY ; Save as player being stalked
lda #0x01 ; Don't have the helecopter
sta TEMP7 ; fire yet.
inc TEMP8 ; Force another update later
orcc #0x02 ; Flag no position set
rts;
P09F5: lda 6,u ; Get player's y pos
ldb 8,u ; Get player's x pos
std ETMP10 ; Save position
andcc #0xFE ; Flag that position was set
P09FD: rts;
; FireHelecopterMissile()
;
FireHelecopterMissile:
lda #0x01;
sta FEAST ; Set, but never referenced!
jsr GetPlayerPos ; Get player's position
bvs P09FD ; Branch if no player found
std T1FUNC ; Update hele's nose offset
ldd 0xC8CD ; Load angle & proximity to player
suba TMR4 ; Subtract allowed angle of fire
beq P0A26 ; Branch if target within allowed
; angle of fire.
cmpb #0x10 ; Is player close?
bls P0A26 ; Branch if yes
ldb TEMP9 ; Update counter controlling
incb ; when helecopter angle of
andb ETMP3 ; travel should be updated.
stb TEMP9 ; Save updated value
bne P0A26 ; Update only when = 0
jsr UpdateTravelAngle;
lda #0x02 ; Velocity = 2
jsr LROT90 ; Calc movement deltas
std T3FUNC ; Save movement deltas
P0A26: dec 0xC89A ; Time to fire?
bgt P09FD ; Branch if not
ldu #0xC9DC ; Ptr to missile data
lda ,u ; Missile in use already?
bne P09FD ; Branch if yes
ldd T1FUNC ; Get hele's nose offset
adda TMR2 ; Add y position offset
bvs P09FD ; Skip if overflow
addb T2FUNC ; Add x position offset
bvs P09FD ; Skip if overflow
std 1,u ; Save starting position
lda ETMP4 ; Reset cntr for next
sta 0xC89A ; attempt to fire.
dec ,u ; Flag missile as active
ldb T4FUNC ; Get hele rotation angle
jsr CalcMovementDelta;
lda T4FUNC ; Get hele rotation angle
ldu #0xCA7E ; Missile vlist buffer
ldx #MissileVlist ; Src vlist to rotate
ldb #0x04 ; Vector count-1 (5)
jmp DROT ; Rotate the vlist
HelecopterActionTable:
dw FireHelecopterMissile
dw UpdateHelecopterHeading
; CheckForMissileHits()
;
CheckForMissileHits:
neg TEMP3 ; Toggle between using big &
; small missile movement deltas.
ldy #0xC8E3 ; Ptr to player 1 bonus info
clr 2,y ; Clear player 1 bonus
clr 3,y ; Clear player 2 bonus
lda #0x02 ; Flag we're processing
sta 0xC8DA ; player 1's missiles.
ldx #0xC9C0 ; Ptr to 1st missile
ldd #CheckForHelecopterHit;
std 0xC8CC ; Set processing function
ldb #0x08 ; Loop cntr (8 missiles)
P0A71: stb 0xC8D2 ; Save/update loop cntr
lda ,x ; Get missile state
bmi UpdateMissilePos ; Branch if active
beq P0A92 ; Branch if not in use
ldu #0xCB00 ; Ptr to expl position array
deca ; Decr state counter
sta ,x ; Store updated value
anda #0x03 ; Every 4th pass, double
bne P0A8B ; the scale factor use to
ldb 4,x ; draw the explosion, and
addb 4,x ; decrement the dwell (intens).
stb 4,x ; Store update scale factor
dec 3,x ; Decrement the dwell value
P0A8B: ldb #0x08 ; Create an offset into the
mul ; array of explosion locations.
leau b,u ; Get ptr to explosion data
stu 5,x ; Update explsn vlist ptr
P0A92: leax 7,x ; Point to next missile
ldb 0xC8D2 ; Get loop counter
decb ; Decrement it
beq P0AAC ; Branch if all processed
cmpb #0x06 ; Player 2's 1st missile?
bne P0A9F ; Branch if not
inc 0xC8DA ; Flag plyr 2 processing
P0A9F: cmpb #0x04 ; Helecopter missile?
bne P0A71 ; Branch if not
ldu #CheckForSystemMissileHits;
stu 0xC8CC ; Set processing function
inc 0xC8DA ; Flag we're processing
bra P0A71 ; system missiles.
P0AAC: rts;
; UpdateMissilePos()
;
; Entry: x = ptr to missile data
;
UpdateMissilePos:
lda TEMP3 ; Use big (-1) or small (1)
adda #0x04 ; missile movement deltas.
leau a,x ; Get ptr to y & x deltas
ldd 1,x ; Get missile's (y,x) pos
adda ,u ; Update y pos
addb 1,u ; Update x pos
std 1,x ; Save updated position
jsr ABSAB ; Get abs val of a & b
std 0xC8DB ; Save new values
cmpa #0x78 ; Explode the missile if
bhs ExplodeMissile ; it has reached
cmpb #0x78 ; the outer bounds of the
bhs ExplodeMissile ; playing area.
ldu #VerticalWalls ; Check if missile
jsr CheckForWallContact ; has hit a
bvs ExplodeMissile ; vertical wall.
ldb 0xC8DB ; Get missile's x pos
ldu #HorizontalWalls ; Check if missile
jsr CheckForWallContact ; has hit a
bvs ExplodeMissile ; horizontal wall.
ldu #0xC900 ; Ptr to tank 1 data
ldb SJOY ; Get max # tanks allowed
P0ADF: stb 0xC8CB ; Save/update loop cntr
subb 0xC8D2 ; Sub missile loop cntr
addb #0x03;
subb SJOY;
beq P0B0B;
ldd ,u;
tsta ; Check tank's state flag
beq P0B0B ; Skip if tank is not active
cmpb #0x02 ; Skip if the tank is disabled;
bge P0B0B ; i.e. already has 2 hits.
lda #0x05 ; Set the target half size
sta 0xC8E8 ; for the tank (10x10).
ldd 14,u ; Get tank's position
bsr CheckForMissileHit
bvc P0B0B ; Branch if no hit
ldb 1,u ; Get # hits on tank
lda b,y ; Load bonus value for hit
ldb 0xC8DA ; Do a BCD add of the new
adda b,y ; bonus value to the player's
daa ; cumulative bonus value, and
sta b,y ; save it.
inc 1,u ; Register hit on the tank
bra ExplodeMissile ; Explode the missile
P0B0B: leau 0x40,u ; Get ptr to next tank
ldb 0xC8CB ; Get loop counter
decb ; Decr loop counter
bne P0ADF ; Branch if more tanks
jsr [ 0xC8CC ] ; Call processing proc
lbvc P0A92 ; Branch if no hit
ExplodeMissile:
lda #0x08 ; Set missile state flag
sta ,x ; to show it's exploding.
ldd #0x090A ; Set dwell (0x09) and
std 3,x ; scale factor (0x0A).
ldd #0xCB00 ; Explosion end points
std 5,x ; Set explosion vlist
jmp P0A92;
; CheckForSystemMissileHits()
;
CheckForSystemMissileHits:
ldu #RAMMES ; Ptr to player 1 data
P0B2F: lda ,u ; Get player's state flag
ble P0B46 ; Branch if dead/exploding
lda #0x02 ; Set the target size of
sta 0xC8E8 ; the player (4x4).
lda 6,u ; Get player's y pos
ldb 8,u ; Get player's x pos
bsr CheckForMissileHit
bvc P0B46 ; Branch if no hit
lda #0x80 ; Flag the player as
sta ,u ; being hit.
orcc #0x02 ; Signal a hit occurred.
rts
P0B46: leau 0x27,u ; Get ptr to next player
cmpu #0xCA4E ; All done?
bne P0B2F ; Branch if not done
andcc #0xFD ; Signal no hit occurred.
rts
; CheckForMissileHit()
;
; Entry: x = ptr to missile data
; a = target y
; b = target x
; C8E8 = target half size
;
CheckForMissileHit:
suba 1,x ; Get delta between missile
bvs P0B6B ; and target y; branch if
bpl P0B59 ; overflow. Else, get abs
nega ; value of the delta.
P0B59: subb 2,x ; Get delta between missile
bvs P0B6B ; and target x; branch if
bpl P0B60 ; overflow. Else, get abs
negb ; value of the delta.
P0B60: cmpa 0xC8E8 ; Is y within the target?
bgt P0B6B ; Branch if not
cmpb 0xC8E8 ; Is x within the target?
bgt P0B6B ; Branch if not
orcc #0x02 ; Signal a hit occurred
rts
P0B6B: andcc #0xFD ; Signal no hit occurred
rts
; CheckForHelecopterHit()
;
; Entry: x = Ptr to missile data
; y = ptr to player 1 bonus info (-2)
;
CheckForHelecopterHit:
lda TEMP6 ; Get Helecopter state flag
ble P0BCD ; Branch if inactive/exploding
ldd T1FUNC ; Get hele's (y,x) offset
adda TMR2 ; Add y offset position
bvs P0BCD ; Branch if invalid (overflow)
addb T2FUNC ; Add x offset position
bvs P0BCD ; Branch if invalid (overflow)
suba 1,x ; Subtract missile y
bvs P0BCD ; Branch if invalid (overflow)
subb 2,x ; Subtract missile x
bvs P0BCD ; Branch if invalid (overflow)
asra ; Divide y difference by 2
asrb ; Divide x difference by 2
std 0xC8CF ; Save y & x differences
ldb T4FUNC ; Get helecopter rotation angle
subb #0x40 ; Adjust angle
andb #0x3F ; Force in 0-360 range
jsr LNROT ; Rotate single line
std 0xC8CE ; Save rotated (y,x) endpt
lda 0xC8D0 ; Velocity
ldb ANGLE ; Get angle of travel
jsr LROT90 ; Calc movement deltas
adda 0xC8CE ; Take into account the hele's
; pending y movement.
bpl P0B9F ; Branch if positive
nega ; Make positive
P0B9F: addb 0xC8CF ; Take into account the hele's
; pending x movement.
bpl P0BA4 ; Branch if positive
negb ; Make positive
P0BA4: cmpa #0x02 ; Is missile within 2 y units?
bgt P0BCD ; Branch if not
cmpb #0x04 ; Is missile within 4 x units?
bgt P0BCD ; Branch if not
lda #0x80 ; Set helecopter state flag
sta TEMP6 ; to signal it's been hit.
ldb 0xC8DA ; Based on whose missile it
lda b,y ; was, add a 1000 point
adda #0x0A ; bonus to the appropriate
daa ; player's bonus area.
sta b,y ; Save the new bonus value
ldb 1,y ; Get the current bonus for
incb ; the second tank hit. Incr it.
cmpb #0x08 ; Has it reached 800 points?
bne P0BC8 ; Branch if not
inc 0xC8E2 ; Award a bonus jeep
bne P0BC6 ; Are they now at 0 jeeps?
dec 0xC8E2 ; If so, then remove bonus jeep;
; player must have just died also.
P0BC6: ldb #0x02 ; Reset 2nd hit bonus to 200 points
P0BC8: stb 1,y ; Save updated 2nd hit bonus
orcc #0x02 ; Signal a hit occurred
rts
P0BCD: andcc #0xFD ; Signal no hit occurred
rts
P0BD0: jmp EXPLOD ; Make explosion noise
; MakeSounds()
;
MakeSounds:
ldu #ExplosionSounds ; Load ptr to sound
lda 0xC8EF ; Helecopter exploding?
beq P0BE5 ; Branch if not
bmi P0BD0 ; Branch if yes
dec 0xC8EF ;
leau 4,u ; Ptr to alt explosion snd
jsr EXPLOD ; Make explosion sound
bra P0C33;
P0BE5: lda #0x0F;
sta REQ5 ; Channel A amplitude
sta REQ4 ; Channel B amplitude
sta REQ3 ; Channel C amplitude
ldb REQ6 ; Tone/Noise enables
lda SATUS ; Check if tank sounds
anda #0x03 ; are enabled.
beq P0C2F ; Branch if not
andb #0xF9 ; Enable tone chans B&C
orb #0x30 ; Disable noise chans B&C
stb REQ6 ; Tone/Noise enables
adda BACON;
sta BACON;
bita #0x08;
bne P0C07;
orb #0x04 ; Disable tone channel C
stb REQ6 ; Tone/Noise enables
P0C07: bita #0x10;
bne P0C0D;
eora #0x07;
P0C0D: anda #0x07;
adda #0x10;
sta REQ9 ; Channel C fine tone period
clr REQ8 ; Channel C course tone period
lda #0x08;
sta REQ3 ; Channel C amplitude
lda SATUS;
bita #0x01 ; Slow tank sounds?
beq P0C24 ; Branch if not (then fast tanks)
ldd #0x0FFF ; Chan B course/fine tone period
bra P0C27;
; Fast moving tanks sounds
P0C24: ldd #0x0BFF ; Chan B course/fine tone period
P0C27: std REQA ; Channel B course tone period (a)
; Channel B fine tone period (b)
lda #0x0E ; New Chan B amplitude
std REQ4 ; Channel B amplitude (a)
; Channel A amplitude (b)
bra P0C33;
P0C2F: orb #0x36 ; Disable noise & tone chans B&C
stb REQ6 ; Tone/Noise enables
P0C33: ldb REQ6 ; Tone/Noise enables
lda SATUS ; Is the helecopter flying sound
bita #0x08 ; enabled?
beq P0C59 ; Branch if not
inc GAP;
lda GAP;
bita #0x02;
beq P0C59;
andb #0xF7 ; Enable noise channel A
stb REQ6 ; Tone/Noise enables
rora;
ldb #0x20;
blo P0C4D;
lsrb;
P0C4D: clra;
std REQC ; Channel A course tone period
; Channel A fine tone period
ldb #0x03;
stb REQ7 ; Noise period
lda #0x0D;
sta REQ5 ; Channel A amplitude
rts;
P0C59: orb #0x09 ; Disable noise & tone chan A
stb REQ6 ; Noise/Tone enables
rts;
ExplosionSounds:
db 0x3B ; Channel enables
db 0x00 ; Sweep freq (up)
db 0x00 ; Sweep vol (up)
db 0x01 ; Explosion duration
db 0x36 ; Channel enables
db 0x78 ; Sweep freq (down)
db 0x00 ; Sweep vol (up)
db 0x04 ; Explosion duration
; CalcAngle1()
;
; Entry: x = ptr to tracker's (y,x) position
; y = target (player) position
;
; Exit: a = angle from tracker to target
; b = sum of abs(delta y + delta x)
; (for proximity testing).
;
; Calculates the angle from the tracker to the
; target.
;
CalcAngle1:
ldd ,x ; Get tracker's (y,x) pos
asra ; Divide y by 2
asrb ; Divide x by 2
std -2,s ; Save results on stack
ldd 2,x ; Get tracker's movement deltas
asra ; Divide y delta by 2
asrb ; Divide x delta by 2
adda -2,s ; Add adjusted y delta to y pos
addb -1,s ; Add adjusted x delta to x pos
bra P0C82
; CalcAngle2()
;
; Entry: u = ptr to player's (y,x) position
; d = trackers (y,x) position
;
; Exit: a = angle from tracker to target
; b = sum of abs(delta y + delta x)
; (for proximity testing).
;
; Calculates the angle from the tracker to the
; target.
;
CalcAngle2:
pshs a,b ; Save tank's (y,x) pos
lda ,u ; Get player's y pos
ldb 2,u ; Get player's x pos
tfr d,y ; Xfer position to y register
puls a,b ; Restore tank's (y,x) pos
; CalcAngle3()
;
; Entry: d = Tracker's (y,x) position
; y = target (player) position
;
; Exit: a = angle from tracker to target
; b = sum of abs(delta y + delta x)
; (for proximity testing).
;
; Calculates the angle from the tracker to the
; target. This appears to be used to do a gradual
; angle adjustment, since it halves the tracker's
; angle, before doing the calculation.
;
CalcAngle3:
asra ; Divide y by 2
asrb ; Divide x by 2
P0C82: pshs a,b ; Save tracker's updated pos
tfr y,d ; Get target's position
asra ; Divide y by 2
asrb ; Divide x by 2
suba ,s+ ; Get delta between the y's
subb ,s+ ; Get delta between the x's
pshs a,b ; Save the delta values
jsr CMPASS ; Use the result to calc the
; angle from the tracker to
; the target.
puls a,b ; Restore the delta values
jsr ABSAB ; Get abs val of the deltas
pshs a ; Sum the abs value of the 2
orb ,s+ ; deltas, to get proximity val
lda ANGLE ; Load calculated angle
rts;
; DrawPacketVlist()
;
; Entry: b = scale factor
; x = packet vlist pointer
;
DrawPacketVlist:
jsr TPACK ; Draw packet vlist
jmp ZERGND;
; UpdateScore()
;
; This is an iterator function.
;
UpdateScore:
lda ,u+ ; Get upper BCD score byte
clrb ; Lower BCD score byte = "00"
jsr SCRADD ; Add "xx00" to score str
leax 9,x ; Pt to next score str
rts;
; CreateHelecopterRotors()
;
; Entry: x = ptr to diffy rotor vlist
; u = ptr to destination buffer
; b = vector count - 1
;
; Takes the source rotor vlist (3 vectors) and
; creates four copies, each rotated at 90 degrees
; from the each other, to produce a set of rotors.
; It does this four times, to produce 4 complete
; sets of rotors, each at a slightly different
; rotation angle. These will be used to produce
; the effect of rotating helecopter rotors.
; The 4 sets of 12 vectors are stored into the
; destination buffer.
;
CreateHelecopterRotors:
leay ,x ; Save ptr to rotor diffy vlist
lda #0x04 ; Outer loop counter
pshs a,b ; Save loop cntr & # vectors
ldb #0x04 ; b = angle (22.5 degrees)
pshs a,b ; a = inner loop counter
P0CB6: lda 1,s ; Get rotation angle
P0CB8: adda #0x10 ; Adjust: add 90 degrees
sta 1,s ; Save updated value
ldb 3,s ; Set vector count -1
jsr DROT ; Rotate rotor diffy vlist
leax ,y ; Restore ptr to rotor vlist
dec ,s ; Decr inner loop counter
bne P0CB6 ; Branch if more iterations
lda #0x04 ; Reset inner
sta ,s ; loop counter.
adda 1,s ; Adj angle (add 22.5 degrees)
dec 2,s ; Decr outer loop counter
bne P0CB8 ; Branch if more iterations
leas 4,s ; Clean up stack
rts
; DisableAllTanks()
;
; Disables all tanks, by setting their state flag
; to 0.
;
DisableAllTanks:
ldx #0xC900 ; Ptr to 1st tank bufr
ldd #0x0340 ; a=loop cnt; b=bufr size
; DisableObjects()
;
; Entry: x = ptr to first object to be disabled
; a = # of objects to disable
; b = size of each object
;
DisableObjects:
clr ,x ; Disable this object
abx ; Point to next object
deca ; Decrement loop counter
bne DisableObjects ; More interations?
rts
; CopyRandomArrayData()
;
; Entry: a = offset mask
; u = ptr to source array
; x = ptr to destination
; b = # of bytes to copy
;
; Generates a random number, which is then masked
; using the specified offset mask. The result is
; used to index into the specified array. Each
; byte in the source array is divided by 4, and
; then copied into the destination buffer. The
; specified number of bytes are copied.
;
CopyRandomArrayData:
pshs a,b;
jsr RANDOM ; Load random # -> a
anda ,s+ ; Mask with offset mask
leau a,u ; Offset into src array
puls a ; Get # bytes to copy
P0CEC: ldb ,u+ ; Get next byte
asrb ; Divide the value
asrb ; by 4.
stb ,x+ ; Store in dest buffer
deca ; Decr loop counter
bne P0CEC ; Branch if more bytes
rts
; CopyUtoX()
;
; Entry: u = ptr to source buffer
; x = ptr to destination buffer
; a = # bytes to copy
;
CopyUtoX:
ldb ,u+ ; Get next byte
stb ,x+ ; Save in dest buffer
deca ; Decr loop counter
bne CopyUtoX ; Branch if more bytes
rts
db 0x12;
; Values used to initialize C880-C887
LevelSpecificData:
db 0x01 ; Use slow tank sounds
db 0x01 ; Max # of tanks
db 0x02 ; Tank body angle delta
db 0x06 ; Resync plyr's pos counter
db 0xFC ; Course tuning angle mask
db 0x03 ; Hele angle update mask
db 0x20 ; Delay before firing missile
db 0x08 ; Index to level-specific data
db 0x01 ; Use slow tank sounds
db 0x02 ; Max # of tanks
db 0x02 ; Tank body angle delta
db 0x04 ; Resync plyr's pos counter
db 0xFD ; Course tuning angle mask
db 0x01 ; Hele angle update mask
db 0x20 ; Delay before firing missile
db 0x10 ; Index to level-specific data
db 0x01 ; Use slow tank sounds
db 0x02 ; Max # of tanks
db 0x02 ; Tank body angle delta
db 0x02 ; Resync plyr's pos counter
db 0xFD ; Course tuning angle mask
db 0x01 ; Hele angle update mask
db 0x20 ; Delay before firing missile
db 0x18 ; Index to level-specific data
db 0x01 ; Use slow tank sounds
db 0x03 ; Max # of tanks
db 0x02 ; Tank body angle delta
db 0x02 ; Resync plyr's pos counter
db 0xFD ; Course tuning angle mask
db 0x01 ; Hele angle update mask
db 0x1C ; Delay before firing missile
db 0x20 ; Index to level-specific data
db 0x01 ; Use slow tank sounds
db 0x03 ; Max # of tanks
db 0x02 ; Tank body angle delta
db 0x02 ; Resync plyr's pos counter
db 0xFE ; Course tuning angle mask
db 0x01 ; Hele angle update mask
db 0x1C ; Delay before firing missile
db 0x28 ; Index to level-specific data
db 0x02 ; Use fast tank sounds
db 0x03 ; Max # of tanks
db 0x02 ; Tank body angle delta
db 0x01 ; Resync plyr's pos counter
db 0xFE ; Course tuning angle mask
db 0x01 ; Hele angle update mask
db 0x1C ; Delay before firing missile
db 0x30 ; Index to level-specific data
db 0x02 ; Use fast tank sounds
db 0x03 ; Max # of tanks
db 0x02 ; Tank body angle delta
db 0x01 ; Resync plyr's pos counter
db 0xFF ; Course tuning angle mask
db 0x00 ; Hele angle update mask
db 0x1C ; Delay before firing missile
db 0x38 ; Index to level-specific data
db 0x02 ; Use fast tank sounds
db 0x03 ; Max # of tanks
db 0x04 ; Tank body angle delta
db 0x01 ; Resync plyr's pos counter
db 0xFF ; Course tuning angle mask
db 0x00 ; Hele angle update mask
db 0x14 ; Delay before firing missile
db 0x38 ; Index to level-specific data
Defaults:
db 0x02 ; Counter - delay before
db 0x00 ; processing helecopter.
db 0x30 ; Counter - tank startup delay
db 0xFF ; Counter - startup delay
db 0x05 ; Starting jeep count
db 0x02 ; Value for 1st tank hit (0200)
db 0x03 ; Value for 2nd tank hit (0300)
JeepVlists:
Jeep1: db 0x00, 0x08, 0x0C
db 0xFF, 0xF0, 0x00
db 0xFF, 0x00, 0xE8
db 0xFF, 0x10, 0x00
db 0xFF, 0x00, 0x18
db 0x00, 0xF4, 0x00
db 0xFF, 0xFC, 0xF6
db 0xFF, 0x10, 0x00
db 0xFF, 0xFC, 0x0A
db 0x01
Jeep2: db 0x00, 0x08, 0x0C
db 0xFF, 0xF0, 0x00
db 0xFF, 0x00, 0xE8
db 0xFF, 0x10, 0x00
db 0xFF, 0x00, 0x18
db 0xFF, 0xF0, 0xF6
db 0xFF, 0x10, 0x00
db 0xFF, 0xF0, 0x0A
db 0x01
MissileVlist:
db 0x00
DftTankAttrsBase:
db 0x1B
db 0x00
db 0xEE
db 0x03
db 0xFD
db 0xFA
db 0x00
db 0x03
db 0x03
DftTankAttrs:
Tank1: db 0x0F ;
db 0x0F ;
db 0x02 ; scale
db 0x08 ; index
db 0x18 ; y
db 0x78 ; x
db 0x00 ; delta y
db 0x01 ; delta x
db 0x30 ; angle
Tank2: db 0x0A ;
db 0x0A ;
db 0x02 ; scale
db 0x08 ; index
db 0x38 ; y
db 0x78 ; x
db 0x00 ; delta y
db 0x01 ; delta x
db 0x30 ; angle
Tank3: db 0x06 ;
db 0x06 ;
db 0x03 ; scale
db 0x08 ; index
db 0x78 ; y
db 0x38 ; x
db 0x01 ; delta y
db 0x00 ; delta x
db 0x00 ; angle
S0DA0: db 0x00
db 0x02
db 0x01
db 0x01
db 0x00
db 0x20
db 0x08
db 0x08
db 0x0B
db 0x03
db 0x02
db 0x01
db 0x30
db 0x30
db 0x08
db 0x20
db 0x04
db 0x00
db 0x03
db 0x02
db 0x10
db 0x00
db 0x08
db 0x30
db 0x00
db 0x05
db 0x03
db 0x00
db 0x00
db 0x18
db 0x10
db 0x00
db 0x06
db 0x00
db 0x00
db 0x04
db 0x20
db 0x00
db 0x00
db 0x18
db 0x00
db 0x00
db 0x05
db 0x07
db 0x00
db 0x00
db 0x20
db 0x18
db 0x08
db 0x06
db 0x00
db 0x0B
db 0x20
db 0x18
db 0x00
db 0x30
db 0x00
db 0x00
db 0x07
db 0x09
db 0x00
db 0x00
db 0x20
db 0x20
db 0x0A
db 0x08
db 0x00
db 0x0C
db 0x18
db 0x20
db 0x00
db 0x10
db 0x00
db 0x00
db 0x09
db 0x0F
db 0x00
db 0x00
db 0x18
db 0x20
db 0x0C
db 0x07
db 0x02
db 0x00
db 0x20
db 0x30
db 0x30
db 0x00
db 0x00
db 0x09
db 0x0B
db 0x0D
db 0x00
db 0x10
db 0x20
db 0x10
db 0x0F
db 0x0C
db 0x00
db 0x0E
db 0x18
db 0x10
db 0x00
db 0x10
db 0x00
db 0x0D
db 0x00
db 0x0E
db 0x00
db 0x10
db 0x00
db 0x08
db 0x00
db 0x0A
db 0x0D
db 0x00
db 0x00
db 0x20
db 0x18
db 0x00
; Pairs of (y,x) values
OuterBoundaryVlists:
db 0x30, 0x00
db 0x00, 0x60
db 0xD0, 0x00
db 0x00, 0x40
db 0xC0, 0x00
db 0x00, 0x30
db 0xA0, 0x00
db 0x00, 0xD0
db 0xC0, 0x00
db 0x00, 0x30
db 0xA0, 0x00
db 0x00, 0xD0
db 0xC0, 0x00
db 0x00, 0xC0
db 0xD0, 0x00
db 0x00, 0xA0
db 0x30, 0x00
db 0x00, 0xC0
db 0xD0, 0x00
db 0x00, 0xA0
db 0x30, 0x00
db 0x00, 0xC0
db 0x40, 0x00
db 0x00, 0xD0
db 0x60, 0x00
db 0x00, 0x30
db 0x40, 0x00
db 0x00, 0xD0
db 0x60, 0x00
db 0x00, 0x30
db 0x40, 0x00
db 0x00, 0x40
db 0x30, 0x00
db 0x00, 0x60
db 0xD0, 0x00
db 0x00, 0x40
; Pairs of (y,x) values
LgSquareBuildingVlist:
db 0x00, 0x40
db 0xC0, 0x00
db 0xC0, 0x00
db 0x00, 0xC0
db 0x40, 0x00
db 0x40, 0x00
; Pairs of (y,x) values
SmSquareBuildingVlist:
db 0x00, 0x20
db 0x40, 0x00
db 0x00, 0xE0
db 0xC0, 0x00
; Pairs of (y,x) values
LBuildingVlists:
db 0x00, 0x40
db 0x48, 0x00
db 0x00, 0xE0
db 0xD8, 0x00
db 0x00, 0xE0
db 0xE0, 0x00
db 0x20, 0x00
db 0x00, 0xE0
db 0x28, 0x00
db 0x00, 0xE0
db 0xB8, 0x00
db 0x00, 0x40
db 0xE0, 0x00
db 0x00, 0xE0
db 0xD8, 0x00
db 0x00, 0xE0
db 0x48, 0x00
db 0x00, 0x40
db 0x00, 0x40
db 0xB8, 0x00
db 0x00, 0xE0
db 0x28, 0x00
db 0x00, 0xE0
db 0x20, 0x00
AllVlistAttrs:
db 0x04 ; # of vlists
db 0x08 ; Vector count - 1
db 0x60 ; relative y1
db 0x10 ; relative x1
db 0xF0 ; relative y2
db 0x60 ; relative x2
db 0xA0 ; relative y3
db 0xF0 ; relative x3
db 0x10 ; relative y4
db 0xA0 ; relative x4
; Attributes for LgSquareBuildingVlist
db 0x02 ; # of iterations
db 0x05 ; vector count - 1
db 0x20 ; relative y1
db 0x20 ; relative x1
db 0x20 ; relative y2
db 0xC0 ; relative x2
; Attributes for SmSquareBuildingVlist
db 0x04 ; # of iterations
db 0x03 ; vector count - 1
db 0x30 ; relative y1
db 0x40 ; relative x1
db 0x30 ; relative y2
db 0xB0 ; relative x2
db 0xB0 ; relative y3
db 0xB0 ; relative x3
db 0xB0 ; relative y4
db 0x40 ; relative x4
; Attributes for LBuildingVlists
db 0x04 ; # of vlists
db 0x05 ; vector count - 1
db 0x40 ; relative y1
db 0x10 ; relative x1
db 0x40 ; relative y2
db 0xF0 ; relative x2
db 0xC0 ; relative y3
db 0xF0 ; relative x3
db 0xC0 ; relative y4
db 0x10 ; relative x4
TankBodyVlist:
db 0x00, 0x0C, 0x08
db 0xFF, 0x00, 0xF0
db 0xFF, 0xE8, 0x00
db 0xFF, 0x00, 0x10
db 0xFF, 0x18, 0x00
db 0x00, 0xF4, 0xF8
db 0x01
TankTurretVlist:
db 0xFF, 0x04, 0x00
db 0xFF, 0x04, 0xFC
db 0xFF, 0xFC, 0xF0
db 0xFF, 0xF8, 0x00
db 0xFF, 0xFC, 0x10
db 0xFF, 0x04, 0x04
db 0xFF, 0x04, 0x00
db 0xFF, 0x00, 0x28
db 0x01
DestroyedTankBodyVlist:
db 0x00, 0x0A, 0x05
db 0xFF, 0x04, 0xF0
db 0xFF, 0xEF, 0x06
db 0xFF, 0xF7, 0xFD
db 0xFF, 0xFD, 0x11
db 0xFF, 0x0F, 0xF7
db 0x01
DestroyedTurretVlist:
db 0xFF, 0x06, 0xFA
db 0xFF, 0xFE, 0xFC
db 0xFF, 0x02, 0xF8
db 0xFF, 0xFA, 0xFE
db 0xFF, 0xFC, 0x06
db 0xFF, 0x08, 0x10
db 0xFF, 0xFE, 0x14
db 0xFF, 0x02, 0x14
db 0x01
; Vertical wall boundaries
;
; | * *
; | * *
;70 + * *
; | * *
; | * *
; | * *
;60 + * * * * *
; | * * *
; | * * *
; | * * *
;50 + * * *
; | * * * * * *
; | * * * * *
; | * * * * *
;40 + * * * * *
; | * * *
; | * * *
; | * * *
;30 + * * *
; | *
; | *
; | *
;20 + *
; | * * *
; | * * *
; | * * *
;10 + * * *
; | * * * *
; | * * *
; | * * *
;00 +---+---*---+--*+---+---*---+--
; 00 10 20 30 40 50 60 70
;
VerticalWalls:
db 0x0E ; offset (0x0A-0x19)
db 0x02 ; # of walls
db 0x18 ; offset (0x1A-0x29)
db 0x02 ; # of walls
db 0x22 ; offset (0x2A-0x39)
db 0x01 ; # of walls
db 0x27 ; offset (0x3A-0x49)
db 0x03 ; # of walls
db 0x36 ; offset (0x4A-0x59)
db 0x01 ; # of walls
db 0x3B ; offset (0x5A-0x69)
db 0x02 ; # of walls
db 0x45 ; offset (0x6A-0x79)
db 0x01 ; # of walls
db 0x60 ; min y
db 0x1C ; max y delta
db 0x0C ; min x
db 0x04 ; max x delta
db 0x10 ; updated x pos
db 0x40 ; min y
db 0x10 ; max y delta
db 0x10 ; min x
db 0x04 ; max x delta
db 0x10 ; updated x pos
db 0x4C ; min y
db 0x18 ; max y delta
db 0x20 ; min x
db 0x04 ; max x delta
db 0x20 ; updated x pos
db 0x00 ; min y
db 0x20 ; max y delta
db 0x20 ; min x
db 0x04 ; max x delta
db 0x20 ; updated x pos
db 0x40 ; min y
db 0x24 ; max y delta
db 0x2C ; min x
db 0x04 ; max x delta
db 0x30 ; updated x pos
db 0x60 ; min y
db 0x1C ; max y delta
db 0x40 ; min x
db 0x04 ; max x delta
db 0x40 ; updated x pos
db 0x30 ; min y
db 0x20 ; max y delta
db 0x40 ; min x
db 0x04 ; max x delta
db 0x40 ; updated x pos
db 0x00 ; min y
db 0x20 ; max y delta
db 0x3C ; min x
db 0x04 ; max x delta
db 0x40 ; updated x pos
db 0x30 ; min y
db 0x20 ; max y delta
db 0x4C ; min x
db 0x04 ; max x delta
db 0x50 ; updated x pos
db 0x40 ; min y
db 0x24 ; max y delta
db 0x60 ; min x
db 0x04 ; max x delta
db 0x60 ; updated x pos
db 0x00 ; min y
db 0x10 ; max y delta
db 0x60 ; min x
db 0x04 ; max x delta
db 0x60 ; updated x pos
db 0x0C ; min y
db 0x34 ; max y delta
db 0x78 ; min x
db 0x04 ; max x delta
db 0x78 ; updated x pos
; Horizontal wall boundaries
; FDT - Note bug, marked by 'xx'; this
; wall invisibly extends 8 units
; beyond where the physical wall
; really is!
;
; | **************
; |
;70 +
; |
; |
; |
;60 **** **** **********
; |
; |
; |
;50 +
; | ****** ****
; |
; |
;40 + ********xx *******
; |
; |
; |
;30 + ****
; |
; |
; |
;20 +
; | ********
; |
; |
;10 +
; | *******
; |
; |
;00 +---+---+---+---+---+---+---+--
; 00 10 20 30 40 50 60 70
;
HorizontalWalls:
db 0x0E ; offset (0x0A-0x19)
db 0x01 ; # of walls
db 0x13 ; offset (0x1A-0x29)
db 0x01 ; # of walls
db 0x18 ; offset (0x2A-0x39)
db 0x01 ; # of walls
db 0x1D ; offset (0x3A-0x49)
db 0x02 ; # of walls
db 0x27 ; offset (0x4A-0x59)
db 0x02 ; # of walls
db 0x31 ; offset (0x5A-0x69)
db 0x03 ; # of walls
db 0x40 ; offset (0x6A-0x79)
db 0x01 ; # of walls
db 0x0C ; min y
db 0x04 ; max y delta
db 0x60 ; min x
db 0x1C ; max x delta
db 0x10 ; updated y pos
db 0x1C ; min y
db 0x04 ; max y delta
db 0x20 ; min x
db 0x20 ; max x delta
db 0x20 ; updated y pos
db 0x30 ; min y
db 0x04 ; max y delta
db 0x40 ; min x
db 0x10 ; max x delta
db 0x30 ; updated y pos
db 0x40 ; min y
db 0x04 ; max y delta
db 0x10 ; min x
db 0x28 ; max x delta
db 0x40 ; updated y pos
db 0x40 ; min y
db 0x03 ; max y delta
db 0x60 ; min x
db 0x1C ; max x delta
db 0x40 ; updated y pos
db 0x4C ; min y
db 0x04 ; max y delta
db 0x10 ; min x
db 0x14 ; max x delta
db 0x50 ; updated y pos
db 0x4C ; min y
db 0x04 ; max y delta
db 0x40 ; min x
db 0x10 ; max x delta
db 0x50 ; updated y pos
db 0x60 ; min y
db 0x04 ; max y delta
db 0x00 ; min x
db 0x10 ; max x delta
db 0x60 ; updated y pos
db 0x60 ; min y
db 0x04 ; max y delta
db 0x20 ; min x
db 0x10 ; max x delta
db 0x64 ; updated y pos
db 0x60 ; min y
db 0x04 ; max y delta
db 0x40 ; min x
db 0x24 ; max x delta
db 0x60 ; updated y pos
db 0x78 ; min y
db 0x04 ; max y delta
db 0x0C ; min x
db 0x38 ; max x delta
db 0x78 ; updated y pos
HelecopterBodyVlist:
db 0x00, 0x00, 0x1C
db 0xFF, 0x0C, 0xF4
db 0xFF, 0x00, 0xE0
db 0xFF, 0xF8, 0xF4
db 0xFF, 0xFC, 0xCC
db 0xFF, 0xFC, 0x34
db 0xFF, 0xF8, 0x0C
db 0xFF, 0x00, 0x20
db 0xFF, 0x0C, 0x0C
db 0x00, 0x00, 0xE4
db 0x01
DestroyedHelecopterVlists:
db 0x00, 0x0C, 0x10
db 0xFF, 0xF4, 0x0C
db 0xFF, 0xF4, 0xF4
db 0xFF, 0x00, 0xD0
db 0x20
db 0x00, 0xE8, 0xE4
db 0xFF, 0x08, 0x0C
db 0xFF, 0x04, 0xCC
db 0xFF, 0x04, 0x34
db 0xFF, 0x08, 0x0C
db 0xFF, 0x00, 0x30
db 0x01
; Pairs of (y,x) points
HelecopterRotorVlist:
db 0x30, 0x00
db 0x00, 0xF8
db 0xD0, 0x08
EndString:
db 0x00
db 0xF0
db "END",0x80
db 0x03
db 0x97
db 0x68
db 0x0F
db 0x67
S0FFF: db 0x39
               (
geocities.com/fredtaft)