00001 ;******************************************************************************* 00002 ;* * 00003 ;* S T A R R A I D E R S * 00004 ;* * 00005 ;* for the Atari 8-bit Home Computer System * 00006 ;* * 00007 ;* Reverse-engineered and documented assembly language source code * 00008 ;* * 00009 ;* by * 00010 ;* * 00011 ;* Lorenz Wiest * 00012 ;* * 00013 ;* (lo.wiest(at)web.de) * 00014 ;* * 00015 ;* First Release * 00016 ;* 22-SEP-2015 * 00017 ;* * 00018 ;* Last Update * 00019 ;* 10-AUG-2016 * 00020 ;* * 00021 ;* STAR RAIDERS was created by Douglas Neubauer * 00022 ;* STAR RAIDERS was published by Atari Inc. * 00023 ;* * 00024 ;******************************************************************************* 00025 00026 ; I wrote this document out of my own curiosity. When STAR RAIDERS was released 00027 ; in 1979 it became the killer app for the Atari 8-bit Home Computer System. 00028 ; Since then I have always been wondering what made it tick and how its (at that 00029 ; time) spectacular 3D graphics worked, especially the rotating star field. 00030 ; Impressed by "The Atari BASIC Source Book" I decided to reverse-engineer the 00031 ; STAR RAIDERS 8KB ROM cartridge to recreate a fully documented assembly 00032 ; language source code file. I had no access to the original source code, so the 00033 ; only way to succeed was a combination of educated guesses, trial-and-error, 00034 ; and patience. Eventually, I made it. 00035 ; 00036 ; Essential in preparing this document were three programs I wrote: 00037 ; 00038 ; (1) A 6502-cross-assembler based on the syntax of the MAC/65 assembler for the 00039 ; Atari 8-bit Home Computer System to create the binary file that I verified 00040 ; against the binary of the original ROM cartridge. 00041 ; 00042 ; (2) A text formatter to layout the source code file with its copious comment 00043 ; sections. This was a big time saver, because as the documentation grew the 00044 ; source code had to be reformatted over and over again. 00045 ; 00046 ; (3) A symbol checker to verify that the ubiquitous symbol-value pairs in the 00047 ; documentation match the corresponding symbol values produced by the 00048 ; assembler. 00049 ; 00050 ; This assembly language source code file is compatible with the MAC/65 00051 ; assembler for the Atari 8-bit Home Computer System. I was able to assemble it 00052 ; on an emulated Atari running MAC/65, producing the identical binary of the ROM 00053 ; cartridge. 00054 ; 00055 ; Your feedback is welcome! Send feedback to lo.wiest(at)web.de. 00056 ; 00057 ; Enjoy! -- Lorenz 00058 00059 ;******************************************************************************* 00060 ;* * 00061 ;* N O T A T I O N * 00062 ;* * 00063 ;******************************************************************************* 00064 00065 ; BITS AND BYTES 00066 ; 00067 ; o A "byte" consists of 8 bits. They are numbered B7..0. Bit B0 is the least 00068 ; significant bit. 00069 ; 00070 ; o A "word" consists of 16 bits. They are numbered B15..B0. Bit B0 is the 00071 ; least significant bit. A word is stored in low-order then high-order byte 00072 ; order. 00073 ; 00074 ; o The high-order byte ("high byte") of a word consists of bits B15..8 of the 00075 ; word. 00076 ; 00077 ; o The low-order byte ("low byte") of a word consists of bits B7..0 of the 00078 ; word. 00079 ; 00080 ; NUMBERS 00081 ; 00082 ; o The dollar sign ($) prefixes hexadecimal numbers. 00083 ; Example: $101 is the decimal number 257. 00084 ; 00085 ; o The percent sign (%) prefixes binary numbers. 00086 ; Example: %101 is the decimal number 5. 00087 ; 00088 ; o The asterisk (*) is a wildcard character for a single hexadecimal or 00089 ; binary digit. 00090 ; Example: $0*00 is a placeholder for the numbers $0000, $0100, ..., $0F00. 00091 ; 00092 ; o The lowercase R (r) is a wildcard character for a single random 00093 ; hexadecimal or binary digit. The random digit r is chosen by a random 00094 ; number generator. 00095 ; Example: %00r0 is a placeholder for the numbers %0000 or %0010. 00096 ; 00097 ; OPERATORS 00098 ; 00099 ; o The exclamation mark (!) is the binary OR operator. 00100 ; Example: $01!$02 is $03. 00101 ; 00102 ; o The less-than sign (<) indicates bits B7..0 of a word. 00103 ; Example: <$1234 is $34. 00104 ; 00105 ; o The greater-than sign (>) indicates bits B15..8 of a word. 00106 ; Example: >$1234 is $12. 00107 ; 00108 ; o A pair of brackets ([]) groups mathematical expressions. 00109 ; Example: [3-1]*4 is 8. 00110 ; 00111 ; ASSEMBLY LANGUAGE 00112 ; 00113 ; o The uppercase A (A) indicates the accumulator register of the 6502 CPU. 00114 ; 00115 ; o The uppercase X (X) indicates the X register of the 6502 CPU. 00116 ; 00117 ; o The uppercase Y (Y) indicates the Y register of the 6502 CPU. 00118 ; 00119 ; o The prefix uppercase L and dot (L.) indicates a local variable, a memory 00120 ; location used temporarily in a subroutine. 00121 ; 00122 ; PSEUDO-FUNCTIONS 00123 ; 00124 ; o The function ABS() returns the absolute value of . 00125 ; Example: ABS(3) returns 3. 00126 ; Example: ABS(-3) returns 3. 00127 ; 00128 ; o The function RND(..) returns a random integer in 00129 ; ... 00130 ; Example: RND(3..5) returns a random number out of 3, 4, or 5. 00131 ; 00132 ; o The function MAX(,) returns the larger number of and 00133 ; . 00134 ; Example: MAX(2,4) returns 4. 00135 ; 00136 ; VECTORS 00137 ; 00138 ; o The lowercase X (x) indicates the x-axis of the 3D coordinate system. 00139 ; 00140 ; o The lowercase Y (y) indicates the y-axis of the 3D coordinate system. 00141 ; 00142 ; o The lowercase Z (z) indicates the z-axis of the 3D coordinate system. 00143 ; 00144 ; o Components of a position vector (called "coordinates") have the arbitrary 00145 ; unit ("kilometers"). 00146 ; 00147 ; o Components of a velocity vector have the arbitrary unit 00148 ; ("kilometers per hour"). 00149 ; 00150 ; o A positive component of a position vector (coordinate) in hexadecimal 00151 ; notation is written in the form +$ . is an unsigned 00152 ; integer value. 00153 ; Example: The starbase is +$1000 (or 4096) ahead of our starship. 00154 ; 00155 ; o A negative component of a position vector (coordinate) in hexadecimal 00156 ; notation is written in the form -($) . is an unsigned 00157 ; integer value. To calculate the actual bit pattern of this coordinate 00158 ; value compute the two's-complement of . See also "ON POSITION 00159 ; VECTORS". 00160 ; Example: The starbase is -($1000) (or -4096) behind our starship. 00161 ; 00162 ; o An absolute component of a position vector (coordinate) in hexadecimal 00163 ; notation is written in the form $ . is an unsigned 00164 ; integer value. 00165 ; Example: The Zylon fighter fires when it is closer than $1000 (or 4096) 00166 ; . 00167 ; 00168 ; DISPLAY LIST 00169 ; 00170 ; o The following notation is used for Display List instructions: 00171 ; 00172 ; BLK = Display blank video lines ( in 1..8) 00173 ; GR1 = Display one GRAPHICS 1 row of 20 text characters 00174 ; GR2 = Display one GRAPHICS 2 row of 20 text characters 00175 ; GR7 = Display one GRAPHICS 7 row of 160 pixels 00176 ; DLI = Trigger a Display List Interrupt 00177 ; ... @ = Point to screen memory at address 00178 ; JMP @ = Jump to next Display List instruction at address 00179 ; WAITJMP @ = Wait for vertical blank phase, then jump to next 00180 ; Display List instruction at address 00181 ; 00182 ; MISCELLANEOUS 00183 ; 00184 ; o Probabilities are written in the form % (:). 00186 ; Example: The probability to throw the number 3 with a die is 16% (1:6). 00187 ; 00188 ; o A "game loop iteration" (or "game loop") is a single execution of the game 00189 ; loop, the main program of the game. 00190 ; 00191 ; o A "TICK" is the time span it takes to update the TV screen (1/60 s on an 00192 ; NTSC TV system, 1/50 s on a PAL TV system). 00193 ; 00194 ; o A pair of braces ({}) encloses color names. 00195 ; Example: {BLACK} 00196 ; 00197 ; o A pair of parentheses enclosing a question mark ((?)) indicates code that 00198 ; is not well understood. 00199 ; 00200 ; o A pair of parentheses enclosing an exclamation mark ((!)) indicates a 00201 ; potential bug. 00202 00203 ;******************************************************************************* 00204 ;* * 00205 ;* O V E R V I E W * 00206 ;* * 00207 ;******************************************************************************* 00208 00209 ; ON POSITION VECTORS 00210 ; 00211 ; The game uses a 3D coordinate system with the position of our starship at the 00212 ; center of the coordinate system and the following coordinate axes: 00213 ; 00214 ; o The x-axis points to the right. 00215 ; o The y-axis points up. 00216 ; o The z-axis points in flight direction. 00217 ; 00218 ; By the way, this is called a "left-handed" coordinate system. 00219 ; 00220 ; The locations of all space objects (Zylon ships, meteors, photon torpedoes, 00221 ; starbase, transfer vessel, Hyperwarp Target Marker, stars, and explosion 00222 ; fragments) are described by a "position vector". 00223 ; 00224 ; A "position vector" is composed of an x, y, and z component. The values of the 00225 ; position vector components are called the x, y, and z "coordinates". They have 00226 ; the arbitrary unit . 00227 ; 00228 ; Each coordinate is a signed 17-bit integer number, which fits into 3 bytes: 00229 ; 00230 ; Sign Mantissa 00231 ; B16 B15...B8 B7....B0 00232 ; | | | | | 00233 ; 0000000* ******** ******** 00234 ; 00235 ; o B16 contains the sign bit. Used values are: 00236 ; 1 -> Positive sign 00237 ; 0 -> Negative sign 00238 ; o B15..0 contain the coordinate value (or "mantissa") as a two's-complement 00239 ; integer number. 00240 ; 00241 ; The range of a position vector component is -65536..+65535 . 00242 ; 00243 ; Examples: 00244 ; 00245 ; 00000001 11111111 11111111 = +65535 00246 ; 00000001 00010000 00000000 = +4096 00247 ; 00000001 00001111 11111111 = +4095 00248 ; 00000001 00000001 00000000 = +256 00249 ; 00000001 00000000 11111111 = +255 00250 ; 00000001 00000000 00010000 = +16 00251 ; 00000001 00000000 00001111 = +15 00252 ; 00000001 00000000 00000001 = +1 00253 ; 00000001 00000000 00000000 = +0 00254 ; 00255 ; 00000000 11111111 11111111 = -1 00256 ; 00000000 11111111 11111110 = -2 00257 ; 00000000 11111111 11110001 = -15 00258 ; 00000000 11111111 11110000 = -16 00259 ; 00000000 11111111 00000001 = -255 00260 ; 00000000 11111111 00000000 = -256 00261 ; 00000000 11110000 00000001 = -4095 00262 ; 00000000 11110000 00000000 = -4096 00263 ; 00000000 00000000 00000000 = -65536 00264 ; 00265 ; The position vector for each space object is stored in 9 tables: 00266 ; 00267 ; o XPOSSIGN ($09DE..$0A0E), XPOSHI ($0A71..$0AA1), and XPOSLO ($0B04..$0B34) 00268 ; o YPOSSIGN ($0A0F..$0A3F), YPOSHI ($0AA2..$0AD2), and YPOSLO ($0B35..$0B65) 00269 ; o ZPOSSIGN ($09AD..$09DD), ZPOSHI ($0A40..$0A70), and ZPOSLO ($0AD3..$0B03) 00270 ; 00271 ; There are up to 49 space objects used in the game simultaneously, thus each 00272 ; table is 49 bytes long. 00273 ; 00274 ; o Position vectors 0..4 belong to space objects represented by PLAYERs 00275 ; (Zylon ships, meteors, photon torpedoes, starbase, transfer vessel, and 00276 ; Hyperwarp Target Marker). 00277 ; o Position vectors 5..48 belong to space objects represented by PLAYFIELD 00278 ; pixels. Position vectors 5..16 (stars, explosion fragments) are used for 00279 ; stars, position vectors 17..48 are used for explosion fragments and star 00280 ; trails. 00281 ; 00282 ; INFO: The x and y coordinates of space objects are converted and displayed by 00283 ; the THETA and PHI readouts of the Control Panel Display in "gradons". The 00284 ; z-coordinate is converted and displayed by the RANGE readout in "centrons". 00285 ; The conversion takes place in subroutine SHOWDIGITS ($B8CD) where the high 00286 ; byte of a coordinate (with values $00..$FF) is transformed with lookup table 00287 ; MAPTOBCD99 ($0EE9) into a BCD value of 00..99 in "gradons" or "centrons". 00288 ; 00289 ; 00290 ; ON VELOCITY VECTORS 00291 ; 00292 ; The velocities of all space objects are described by a "velocity vector". The 00293 ; velocity vector is relative to our starship. 00294 ; 00295 ; A "velocity vector" is composed of an x, y, and z component. The values of the 00296 ; velocity vector components are called the x, y, and z "velocities". They have 00297 ; the arbitrary unit . 00298 ; 00299 ; Each velocity vector component is an 8-bit integer number, which fits into 1 00300 ; byte: 00301 ; 00302 ; B7 Sign 00303 ; | 00304 ; |B6...B0 Mantissa 00305 ; || | 00306 ; ******** 00307 ; 00308 ; o B7 contains the sign bit. Used values are: 00309 ; 0 -> Positive sign, movement along the positive coordinate axis 00310 ; (x-velocity: right, y-velocity: up, z-velocity: in flight direction) 00311 ; 1 -> Negative sign, movement along the negative coordinate axis 00312 ; (x-velocity: left, y-velocity: down, z-velocity: in reverse flight 00313 ; direction) 00314 ; o B6..B0 contain the velocity value (or "mantissa"). It is an unsigned 00315 ; number. 00316 ; 00317 ; The range of a velocity vector component is -127..+127 . 00318 ; 00319 ; Examples: 00320 ; 00321 ; 01111111 = +127 00322 ; 00010000 = +16 00323 ; 00001111 = +15 00324 ; 00000001 = +1 00325 ; 00000000 = +0 00326 ; 00327 ; 10000000 = -0 00328 ; 10000001 = -1 00329 ; 10001111 = +15 00330 ; 10010000 = +16 00331 ; 11111111 = -127 00332 ; 00333 ; The velocity vector for each space object stored in 3 tables: 00334 ; 00335 ; o XVEL ($0B97..$0BC7) 00336 ; o YVEL ($0BC8..$0BF8) 00337 ; o ZVEL ($0B66..$0B96) 00338 ; 00339 ; There are up to 49 space objects used in the game simultaneously, thus each 00340 ; table is 49 bytes long. 00341 ; 00342 ; o Velocity vectors 0..4 belong to space objects represented by PLAYERs 00343 ; (Zylon ships, meteors, photon torpedoes, starbase, transfer vessel, and 00344 ; Hyperwarp Target Marker). 00345 ; o Velocity vectors 5..48 belong to space objects represented by PLAYFIELD 00346 ; pixels. Velocity vectors 5..16 are used for stars, velocity vectors 17..48 00347 ; are used for explosion fragments and star trails. 00348 ; 00349 ; INFO: The velocity of our starship is converted and displayed by the VELOCITY 00350 ; readout of the Control Panel Display in "metrons per second" units. The 00351 ; conversion takes place in subroutine SHOWDIGITS ($B8CD) where our starship's 00352 ; velocity VELOCITYL ($70) (with values $00..$FF) is transformed with lookup 00353 ; table MAPTOBCD99 ($0EE9) into a BCD value of 00..99 in "metrons per second". 00354 00355 ;******************************************************************************* 00356 ;* * 00357 ;* M E M O R Y M A P * 00358 ;* * 00359 ;******************************************************************************* 00360 ; 00361 ; The following variables are not changed by a SYSTEM RESET: 00362 ; 00363 ; $62 MISSIONLEVEL 00364 ; 00365 ; Mission level. Used values are: 00366 ; $00 -> NOVICE mission 00367 ; $01 -> PILOT mission 00368 ; $02 -> WARRIOR mission 00369 ; $03 -> COMMANDER mission 00370 ; 00371 ; $63 FKEYCODE 00372 ; 00373 ; Function key code. Used values are: 00374 ; $00 -> No function key pressed 00375 ; $01 -> START function key pressed 00376 ; $02 -> SELECT function key pressed 00377 ; 00378 ; $64 ISDEMOMODE 00379 ; 00380 ; Indicates whether the game is in game or in demo mode. Used values 00381 ; are: 00382 ; $00 -> Game mode 00383 ; $FF -> Demo mode 00384 ; 00385 ; $65 NEWTITLEPHR 00386 ; 00387 ; New title phrase offset for the text in the title line. The new title 00388 ; phrase is not immediately displayed in the title line but only after 00389 ; the display time of the currently displayed title phrase has expired. 00390 ; Thus, setting a value to NEWTITLEPHR ($65) "enqueues" the display of 00391 ; new title phrase. Used values are: 00392 ; $00..$7B -> Title phrase offset into PHRASETAB ($BBAA) 00393 ; $FF -> Hide title line 00394 ; 00395 ; See also TITLEPHR ($D1). 00396 ; 00397 ; $66 IDLECNTHI 00398 ; 00399 ; Idle counter (high byte). Forms a 16-bit counter together with 00400 ; IDLECNTLO ($77), which is incremented during the execution of the 00401 ; Vertical Blank Interrupt handler VBIHNDLR ($A6D1). IDLECNTHI ($66) is 00402 ; reset to 0 when the joystick trigger or a keyboard key has been 00403 ; pressed, or to 1..3 when a function key has been pressed. When 00404 ; IDLECNTHI ($66) reaches a value of 128 (after about 10 min idle time) 00405 ; the game enters demo mode. 00406 ; 00407 ; The following variables are set to 0 after a SYSTEM RESET: 00408 ; 00409 ; $67 ISVBISYNC 00410 ; 00411 ; Indicates whether the Vertical Blank Interrupt handler VBIHNDLR 00412 ; ($A6D1) is executed. Used to synchronize the execution of a new game 00413 ; loop iteration in GAMELOOP ($A1F3) with the vertical blank phase. 00414 ; Used values are: 00415 ; $00 -> Halt execution at start of game loop and wait for VBI 00416 ; $FF -> Continue execution of game loop 00417 ; 00418 ; $68..$69 MEMPTR 00419 ; 00420 ; A 16-bit memory pointer. 00421 ; 00422 ; Also used as a local variable. 00423 ; 00424 ; $6A..$6B DIVIDEND 00425 ; 00426 ; A 16-bit dividend value passed in GAMELOOP ($A1F3) to subroutine 00427 ; PROJECTION ($AA21) to calculate a division. 00428 ; 00429 ; Also used as a local variable. 00430 ; 00431 ; $6C Used as a local variable. 00432 ; 00433 ; $6D JOYSTICKDELTA 00434 ; 00435 ; Used to pass joystick directions from GAMELOOP ($A1F3) to subroutine 00436 ; ROTATE ($B69B). Used values are: 00437 ; $01 -> Joystick pressed right or up 00438 ; $00 -> Joystick centered 00439 ; $FF -> Joystick pressed left or down 00440 ; 00441 ; Also used as a local variable. 00442 ; 00443 ; $6E Used as a local variable. 00444 ; 00445 ; $70 VELOCITYLO 00446 ; 00447 ; Our starship's current velocity (low byte) in . Forms a 16-bit 00448 ; value together with VELOCITYHI ($C1). In subroutine UPDPANEL ($B804), 00449 ; VELOCITYLO ($70) is mapped to a BCD-value in 00..99 and displayed by 00450 ; the VELOCITY readout of the Control Panel Display. See also 00451 ; NEWVELOCITY ($71). 00452 ; 00453 ; $71 NEWVELOCITY 00454 ; 00455 ; Our starship's new velocity (low byte) in . It is set by 00456 ; pressing one of the speed keys '0'..'9'. A pressed speed key is 00457 ; mapped to the new velocity value with VELOCITYTAB ($BAB4). 00458 ; 00459 ; $72 COUNT8 00460 ; 00461 ; Wrap-around counter. Counts from 0..7, then starts over at 0. It is 00462 ; incremented every game loop iteration. It is used to change the 00463 ; brightness of stars and explosion fragments more randomly in GAMELOOP 00464 ; ($A1F3) and to slow down the movement of the hyperwarp markers of the 00465 ; Galactic Chart in subroutine SELECTWARP ($B162). 00466 ; 00467 ; $73 EXPLLIFE 00468 ; 00469 ; Explosion lifetime. It is decremented every game loop iteration. Used 00470 ; values are: 00471 ; $00 -> Explosion is over 00472 ; < $18 -> Number of explosion fragment space objects is decremented 00473 ; < $70 -> HITBADNESS ($8A) is reset 00474 ; $80 -> Initial value at start of explosion 00475 ; 00476 ; $74 CLOCKTIM 00477 ; 00478 ; Star date clock delay timer. Counts down from 40 to 0. It is 00479 ; decremented every game loop iteration. When the timer falls below 0 00480 ; the last digit of the star date of the Galactic Chart Panel Display 00481 ; is increased and the timer is reset to a value of 40. 00482 ; 00483 ; $75 DOCKSTATE 00484 ; 00485 ; State of docking operation. Used values are: 00486 ; $00 -> NOT DOCKED 00487 ; $01 -> TRANSFER COMPLETE 00488 ; $81 -> RETURN TRANSFER VESSEL 00489 ; $FF -> ORBIT ESTABLISHED 00490 ; 00491 ; $76 COUNT256 00492 ; 00493 ; Wrap-around counter. Counts from 0..255, then starts over at 0. It is 00494 ; incremented every game loop iteration. It is used to make the 00495 ; starbase pulsate in brightness in GAMELOOP ($A1F3) and to decide on 00496 ; the creation of a meteor in subroutine MANEUVER ($AA79). 00497 ; 00498 ; $77 IDLECNTLO 00499 ; 00500 ; Idle counter (low byte). Forms a 16-bit counter together with 00501 ; IDLECNTHI ($66), which is incremented during the execution of the 00502 ; Vertical Blank Interrupt handler VBIHNDLR ($A6D1). 00503 ; 00504 ; NOTE: This variable is never properly initialized except at initial 00505 ; cartridge startup (cold start). 00506 ; 00507 ; $78 ZYLONUNITTIM 00508 ; 00509 ; Zylon unit movement timer. This delay timer triggers movement of 00510 ; Zylon units on the Galactic Chart. At the start of the game, the 00511 ; timer is initialized to a value of 100. It is decremented every 40 00512 ; game loop iterations. When the timer falls below 0 the Zylon units 00513 ; move on the Galactic Chart and the timer value is reset to 49. If a 00514 ; starbase is surrounded the timer is reset to 99 to buy you some extra 00515 ; time to destroy one of the surrounding Zylon units. 00516 ; 00517 ; $79 MAXSPCOBJIND 00518 ; 00519 ; Maximum index of used space objects in the current game loop 00520 ; iteration. Frequently used values are: 00521 ; $10 -> During regular cruise (5 PLAYER space objects + 12 PLAYFIELD 00522 ; space objects (stars), counted $00..$10) 00523 ; $30 -> During explosion or hyperwarp (5 PLAYER space objects + 12 00524 ; PLAYFIELD space objects (stars) + 32 PLAYFIELD space objects 00525 ; (explosion fragments or stars of star trails), counted 00526 ; $00..$30) 00527 ; 00528 ; $7A OLDMAXSPCOBJIND 00529 ; 00530 ; Maximum index of used space objects in the previous game loop 00531 ; iteration. Frequently used values are: 00532 ; $10 -> During regular cruise (5 PLAYER space objects + 12 PLAYFIELD 00533 ; space objects (stars), counted $00..$10) 00534 ; $30 -> During explosion or hyperwarp (5 PLAYER space objects + 12 00535 ; PLAYFIELD space objects (stars) + 32 PLAYFIELD space objects 00536 ; (explosion fragments or stars of star trails), counted 00537 ; $00..$30) 00538 ; 00539 ; $7B ISSTARBASESECT 00540 ; 00541 ; Indicates whether a starbase is in this sector. Used values are: 00542 ; $00 -> Sector contains no starbase 00543 ; $FF -> Sector contains starbase 00544 ; 00545 ; $7C ISTRACKCOMPON 00546 ; 00547 ; Indicates whether the Tracking Computer is on or off. Used values 00548 ; are: 00549 ; $00 -> Tracking Computer is off 00550 ; $FF -> Tracking Computer is on 00551 ; 00552 ; $7D DRAINSHIELDS 00553 ; 00554 ; Energy drain rate of the Shields per game loop iteration in energy 00555 ; subunits. See also subroutine UPDPANEL ($B804). Used values are: 00556 ; $00 -> Shields are off 00557 ; $08 -> Shields are on 00558 ; 00559 ; $7E DRAINATTCOMP 00560 ; 00561 ; Energy drain rate of the Attack Computer per game loop iteration in 00562 ; energy subunits. See also subroutine UPDPANEL ($B804). Used values 00563 ; are: 00564 ; $00 -> Attack Computer off 00565 ; $02 -> Attack Computer on 00566 ; 00567 ; $7F ENERGYCNT 00568 ; 00569 ; Running counter of consumed energy subunits (256 energy subunits = 1 00570 ; energy unit displayed by the 4-digit ENERGY readout of the Control 00571 ; Panel Display). Forms an invisible fractional or "decimals" part of 00572 ; the 4-digit ENERGY readout of the Control Panel Display. See also 00573 ; subroutine UPDPANEL ($B804). 00574 ; 00575 ; $80 DRAINENGINES 00576 ; 00577 ; Energy drain rate of our starship's Engines per game loop iteration 00578 ; in energy subunits (256 energy subunits = 1 energy unit displayed by 00579 ; the 4-digit ENERGY readout of the Control Panel Display). Values are 00580 ; picked from table DRAINRATETAB ($BAD3). See also subroutine UPDPANEL 00581 ; ($B804). 00582 ; 00583 ; $81 SHIELDSCOLOR 00584 ; 00585 ; Shields color. Used values are: 00586 ; $00 -> {BLACK} (Shields are off) 00587 ; $A0 -> {DARK GREEN} (Shields are on) 00588 ; 00589 ; $82 PL3HIT 00590 ; 00591 ; Collision register of PLAYER3 (usually our starship's photon torpedo 00592 ; 0) with other PLAYERs. Used values are: 00593 ; $00 -> No collision 00594 ; > $00 -> PLAYER3 has collided with another PLAYER space object. See 00595 ; subroutine COLLISION ($AF3D) for details which PLAYER has 00596 ; been hit by PLAYER3. 00597 ; 00598 ; $83 PL4HIT 00599 ; 00600 ; Collision register of PLAYER4 (usually our starship's photon torpedo 00601 ; 1) with other PLAYERs. Used values are: 00602 ; $00 -> No collision 00603 ; > $00 -> PLAYER4 has collided with another PLAYER space object. See 00604 ; subroutine COLLISION ($AF3D) for details which PLAYER has 00605 ; been hit by PLAYER4. 00606 ; 00607 ; $84 OLDTRIG0 00608 ; 00609 ; Joystick trigger state. Used values are: 00610 ; $00 -> Joystick trigger was pressed 00611 ; $01 -> Joystick trigger was not pressed 00612 ; $AA -> Joystick trigger was "virtually" pressed (will launch 00613 ; another of our starship's photon torpedoes, see subroutine 00614 ; TRIGGER ($AE29). 00615 ; 00616 ; $86 ISTRACKING 00617 ; 00618 ; Indicates whether one of our starship's photon torpedoes is currently 00619 ; tracking (homing in on) the target space object. Used values are: 00620 ; $00 -> No target space object tracked. Our starship's photon 00621 ; torpedoes will fly just straight ahead. 00622 ; > $00 -> Tracking a target space object. Our starship's photon 00623 ; torpedoes will home in on the tracked space object. 00624 ; 00625 ; $87 BARRELNR 00626 ; 00627 ; Barrel from which our starship's next photon torpedo will be 00628 ; launched. Used values are: 00629 ; $00 -> Left barrel 00630 ; $01 -> Right barrel 00631 ; 00632 ; $88 LOCKONLIFE 00633 ; 00634 ; Lifetime of target lock-on. A target remains in lock-on while 00635 ; LOCKONLIFE ($88) counts down from 12 to 0. It is decremented every 00636 ; game loop iteration. 00637 ; 00638 ; $89 PLTRACKED 00639 ; 00640 ; Index of currently tracked PLAYER. It is copied in subroutine TRIGGER 00641 ; ($AE29) from TRACKDIGIT ($095C). Used values are: 00642 ; $00 -> Track Zylon ship 0 00643 ; $01 -> Track Zylon ship 1 00644 ; $02 -> Track starbase during docking operations 00645 ; $03 -> Track Hyperwarp Target Marker during hyperwarp 00646 ; 00647 ; $8A HITBADNESS 00648 ; 00649 ; Severity of a Zylon photon torpedo hit. Used values are: 00650 ; $00 -> NO HIT 00651 ; $7F -> SHIELDS HIT 00652 ; $FF -> STARSHIP DESTROYED 00653 ; 00654 ; $8B REDALERTLIFE 00655 ; 00656 ; Lifetime of red alert. It decreases from 255 to 0. It is decremented 00657 ; every game loop iteration. 00658 ; 00659 ; $8C WARPDEPRROW 00660 ; 00661 ; Departure hyperwarp marker row number on the Galactic Chart. It is 00662 ; given in Player/Missile pixels relative to the top Galactic Chart 00663 ; border. It is initialized to a value of $47 (vertical center of 00664 ; Galactic Chart). Divide this value by 16 to get the departure sector 00665 ; row number. Used values are: $00..$7F. 00666 ; 00667 ; $8D WARPDEPRCOLUMN 00668 ; 00669 ; Departure hyperwarp marker column number on the Galactic Chart. It is 00670 ; given in Player/Missile pixels relative to the left Galactic Chart 00671 ; border and initialized to a value of $43 (horizontal center of 00672 ; Galactic Chart). Divide this value by 8 to get the departure sector 00673 ; column number. Used values are: $00..$7F. 00674 ; 00675 ; $8E WARPARRVROW 00676 ; 00677 ; Arrival hyperwarp marker row number on the Galactic Chart in 00678 ; Player/Missile pixels relative to top Galactic Chart border. It is 00679 ; initialized to a value of $47 (vertical center of Galactic Chart). 00680 ; Divide this value by 16 to get the arrival sector row number. Used 00681 ; values are: $00..$7F. 00682 ; 00683 ; $8F WARPARRVCOLUMN 00684 ; 00685 ; Arrival hyperwarp marker column number on the Galactic Chart in 00686 ; Player/Missile pixels relative to left Galactic Chart border. It is 00687 ; initialized to a value of $43 (horizontal center of Galactic Chart). 00688 ; Divide this value by 8 to get the arrival sector column number. Used 00689 ; values are: $00..$7F. 00690 ; 00691 ; $90 CURRSECTOR 00692 ; 00693 ; Galactic Chart sector of the current location of our starship. At the 00694 ; start of the game it is initialized to a value of $48. Used values 00695 ; are: $00..$7F with, for example, 00696 ; $00 -> NORTHWEST corner sector 00697 ; $0F -> NORTHEAST corner sector 00698 ; $70 -> SOUTHWEST corner sector 00699 ; $7F -> SOUTHWEST corner sector 00700 ; 00701 ; See also ARRVSECTOR ($92). 00702 ; 00703 ; $91 WARPENERGY 00704 ; 00705 ; Energy required to hyperwarp between the departure and arrival 00706 ; hyperwarp marker locations on the Galactic Chart divided by 10. 00707 ; Values are picked from table WARPENERGYTAB ($BADD). Multiply this 00708 ; value by 10 to get the actual value in energy units displayed by the 00709 ; Galactic Chart Panel Display. 00710 ; 00711 ; $92 ARRVSECTOR 00712 ; 00713 ; Galactic Chart arrival sector of our starship after hyperwarp. Used 00714 ; values are: $00..$7F with, for example, 00715 ; $00 -> NORTHWEST corner sector 00716 ; $0F -> NORTHEAST corner sector 00717 ; $70 -> SOUTHWEST corner sector 00718 ; $7F -> SOUTHWEST corner sector 00719 ; 00720 ; See also CURRSECTOR ($90). 00721 ; 00722 ; $93 HUNTSECTOR 00723 ; 00724 ; Galactic Chart sector of the starbase toward which the Zylon units 00725 ; are currently moving. Used values are: $00..$7F with, for example, 00726 ; $00 -> NORTHWEST corner sector 00727 ; $0F -> NORTHEAST corner sector 00728 ; $70 -> SOUTHWEST corner sector 00729 ; $7F -> SOUTHWEST corner sector 00730 ; 00731 ; $94 HUNTSECTCOLUMN 00732 ; 00733 ; Galactic Chart sector column number of the starbase toward which the 00734 ; Zylon units are currently moving. Used values are: 0..15. 00735 ; 00736 ; $95 HUNTSECTROW 00737 ; 00738 ; Galactic Chart sector row number of the starbase toward which the 00739 ; Zylon units are currently moving. Used values are: 0..7. 00740 ; 00741 ; $96..$9E NEWZYLONDIST 00742 ; 00743 ; Table of distances between a Zylon unit and the hunted starbase when 00744 ; the Zylon unit is tentatively moved in one of the 9 possible 00745 ; directions NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST, EAST, 00746 ; NORTHEAST, CENTER. Used to decide into which sector the Zylon unit 00747 ; should move. 00748 ; 00749 ; $9E OLDZYLONDIST 00750 ; 00751 ; Current distance between the Zylon unit and the hunted starbase. 00752 ; 00753 ; $9F HUNTTIM 00754 ; 00755 ; Delay timer for Zylon units to decide on which starbase to hunt. It 00756 ; counts down from 7. It is decremented every game loop iteration. When 00757 ; the timer falls below 0 the Zylon units re-decide toward which 00758 ; starbase to move. 00759 ; 00760 ; $A0 BLIPCOLUMN 00761 ; 00762 ; Top-left screen pixel column number of blip shape displayed in the 00763 ; Attack Computer Display. Used in subroutine UPDATTCOMP ($A7BF). Used 00764 ; values are: 120..142. 00765 ; 00766 ; $A1 BLIPROW 00767 ; 00768 ; Top-left screen pixel row number of blip shape displayed in the 00769 ; Attack Computer Display. Used in subroutine UPDATTCOMP ($A7BF). Used 00770 ; values are: 71..81. 00771 ; 00772 ; $A2 BLIPCYCLECNT 00773 ; 00774 ; Blip cycle counter. It controls drawing the blip shape in the Attack 00775 ; Computer Display. Its value is incremented every game loop iteration. 00776 ; Used in subroutine UPDATTCOMP ($A7BF). Used values are: 00777 ; $00..$04 -> Draw 0..4th row of blip shape 00778 ; $05..$09 -> Do not draw blip shape (delay) 00779 ; $0A -> Recalculate blip shape position, erase Attack Computer 00780 ; Display 00781 ; 00782 ; $A3 ISINLOCKON 00783 ; 00784 ; Indicates whether the tracked space object is currently in full 00785 ; lock-on (horizontally and vertically centered as well as in range) in 00786 ; the Attack Computer Display. If so, all lock-on markers show up on 00787 ; the Attack Computer Display and our starship's launched photon 00788 ; torpedoes will home in on the tracked space object. Used values are: 00789 ; $00 -> Not in lock-on 00790 ; $A0 -> In lock-on 00791 ; 00792 ; $A4 DIRLEN 00793 ; 00794 ; Used to pass the direction and length of a single line to be drawn in 00795 ; the PLAYFIELD. Used in subroutines DRAWLINES ($A76F), DRAWLINE 00796 ; ($A782), and UPDATTCOMP ($A7BF). Used values are: 00797 ; Bit B7 = 0 -> Draw right 00798 ; Bit B7 = 1 -> Draw down 00799 ; Bits B6..0 -> Length of line in pixels. 00800 ; 00801 ; See also PENROW ($A5) and PENCOLUMN ($A6). 00802 ; 00803 ; $A5 PENROW 00804 ; 00805 ; Used to pass the start screen pixel row number of the line to be 00806 ; drawn in the PLAYFIELD. Used in subroutines DRAWLINES ($A76F), 00807 ; DRAWLINE ($A782), and UPDATTCOMP ($A7BF). 00808 ; 00809 ; $A6 PENCOLUMN 00810 ; 00811 ; Used to pass the start screen pixel column number of the line to be 00812 ; drawn in the PLAYFIELD. Used in subroutines DRAWLINES ($A76F), 00813 ; DRAWLINE ($A782), and UPDATTCOMP ($A7BF). 00814 ; 00815 ; $A7 CTRLDZYLON 00816 ; 00817 ; Index of Zylon ship currently controlled by the game. Used in 00818 ; subroutine MANEUVER ($AA79). The value is toggled every other game 00819 ; loop iteration. Used values are: 00820 ; $00 -> Control Zylon ship 0. 00821 ; $01 -> Control Zylon ship 1. 00822 ; 00823 ; $A8 ZYLONFLPAT0 00824 ; 00825 ; Flight pattern of Zylon ship 0. Used in subroutine MANEUVER ($AA79). 00826 ; Used values are: 00827 ; $00 -> Attack flight pattern "0" 00828 ; $01 -> Flight pattern "1" 00829 ; $04 -> Flight pattern "4" 00830 ; 00831 ; $A9 ZYLONFLPAT1 00832 ; 00833 ; Flight pattern of Zylon ship 1. Compare ZYLONFLPAT0 ($A8). 00834 ; 00835 ; $AA MILESTTIM0 00836 ; 00837 ; Delay timer of the milestone velocity indices of Zylon ship 0. Used 00838 ; in subroutine MANEUVER ($AA79). 00839 ; 00840 ; When Zylon ship 0 is active, this value is decremented every game 00841 ; loop iteration. If it falls below 0 then the milestone velocity 00842 ; indices of Zylon ship 0 are recalculated. When Zylon ship 0 is 00843 ; controlled by the computer for the first time, the timer is set to an 00844 ; initial value of 1, later to an initial value of 120. 00845 ; 00846 ; $AB MILESTTIM1 00847 ; 00848 ; Delay timer of the milestone velocity index vector of Zylon ship 1. 00849 ; Compare MILESTTIM0 ($AA). 00850 ; 00851 ; $AC MILESTVELINDZ0 00852 ; 00853 ; Milestone z-velocity index of Zylon ship 0. Used in subroutine 00854 ; MANEUVER ($AA79). The current z-velocity index of Zylon ship 0 00855 ; ZYLONVELINDZ0 ($B2) is compared with this index and gradually 00856 ; adjusted to it. Used values are: 0..15. 00857 ; 00858 ; $AD MILESTVELINDZ1 00859 ; 00860 ; Milestone z-velocity index of Zylon ship 1. Compare MILESTVELINDZ0 00861 ; ($AC). 00862 ; 00863 ; $AE MILESTVELINDX0 00864 ; 00865 ; Milestone x-velocity index of Zylon ship 0. Used in subroutine 00866 ; MANEUVER ($AA79). The current x-velocity index of Zylon ship 0 00867 ; ZYLONVELINDX0 ($B4) is compared with this index and gradually 00868 ; adjusted to it. Used values are: 0..15. 00869 ; 00870 ; $AF MILESTVELINDX1 00871 ; 00872 ; Milestone x-velocity index of Zylon ship 1. Compare MILESTVELINDX0 00873 ; ($AE). 00874 ; 00875 ; $B0 MILESTVELINDY0 00876 ; 00877 ; Milestone y-velocity index of Zylon ship 0. Used in subroutine 00878 ; MANEUVER ($AA79). The current y-velocity index of Zylon ship 0 00879 ; ZYLONVELINDY0 ($B6) is compared with this index and gradually 00880 ; adjusted to it. Used values are: 0..15. 00881 ; 00882 ; $B1 MILESTVELINDY1 00883 ; 00884 ; Milestone y-velocity index of Zylon ship 1. Compare MILESTVELINDY0 00885 ; ($B0). 00886 ; 00887 ; $B2 ZYLONVELINDZ0 00888 ; 00889 ; Current z-velocity index of Zylon ship 0. Used in subroutine MANEUVER 00890 ; ($AA79). It indexes velocity values in ZYLONVELTAB ($BF99). Used 00891 ; values are: 0..15. 00892 ; 00893 ; $B3 ZYLONVELINDZ1 00894 ; 00895 ; Current z-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0 00896 ; ($B2). 00897 ; 00898 ; $B4 ZYLONVELINDX0 00899 ; 00900 ; Current x-velocity index of Zylon ship 0. Compare ZYLONVELINDZ0 00901 ; ($B2). 00902 ; 00903 ; $B5 ZYLONVELINDX1 00904 ; 00905 ; Current x-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0 00906 ; ($B2). 00907 ; 00908 ; $B6 ZYLONVELINDY0 00909 ; 00910 ; Current y-velocity index of Zylon ship 0. Compare ZYLONVELINDZ0 00911 ; ($B2). 00912 ; 00913 ; $B7 ZYLONVELINDY1 00914 ; 00915 ; Current y-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0 00916 ; ($B2). 00917 ; 00918 ; $B8 ISBACKATTACK0 00919 ; 00920 ; Indicates whether Zylon ship 0 will attack our starship from the 00921 ; back. Used in subroutine MANEUVER ($AA79). Used values are: 00922 ; $00 -> Zylon ship 0 attacks from the front of our starship 00923 ; $01 -> Zylon ship 0 attacks from the front and back of our starship 00924 ; 00925 ; $B9 ISBACKATTACK1 00926 ; 00927 ; Indicates whether Zylon ship 1 will attack our starship from the 00928 ; back. Compare ISBACKATTACK0 ($B8). 00929 ; 00930 ; $BA ZYLONTIMX0 00931 ; 00932 ; Delay timer of the x-velocity index of Zylon ship 0. Used in 00933 ; subroutine MANEUVER ($AA79). It is decremented every game loop 00934 ; iteration. When the timer value falls below 0 the current velocity 00935 ; index ZYLONVELINDX0 ($B4) is adjusted depending on the current 00936 ; joystick position. The new timer value is set depending on the 00937 ; resulting new x-velocity index. Used values are: 0, 2, 4, ..., 14. 00938 ; 00939 ; $BB ZYLONTIMX1 00940 ; 00941 ; Delay timer of x-velocity index of Zylon ship 1. Compare ZYLONTIMX0 00942 ; ($BA). 00943 ; 00944 ; $BC ZYLONTIMY0 00945 ; 00946 ; Delay timer of y-velocity index of Zylon ship 0. Compare ZYLONTIMX0 00947 ; ($BA). 00948 ; 00949 ; $BD ZYLONTIMY1 00950 ; 00951 ; Delay timer of y-velocity index of Zylon ship 1. Compare ZYLONTIMX0 00952 ; ($BA). 00953 ; 00954 ; $BE TORPEDODELAY 00955 ; 00956 ; After a Zylon photon torpedo has hit our starship this delay timer is 00957 ; initialized to a value of 2. It is decremented every game loop 00958 ; iteration and so delays the launch of the next Zylon photon torpedo 00959 ; for 2 game loop iterations. 00960 ; 00961 ; $BF ZYLONATTACKER 00962 ; 00963 ; Index of the Zylon ship that launched the Zylon photon torpedo. It is 00964 ; used in GAMELOOP ($A1F3) to override the current tracking computer 00965 ; settings in order to track this Zylon ship first. Used values are: 00966 ; $00 -> Zylon photon torpedo was launched by Zylon ship 0 00967 ; $01 -> Zylon photon torpedo was launched by Zylon ship 1 00968 ; 00969 ; $C0 WARPSTATE 00970 ; 00971 ; Hyperwarp state. Used values are: 00972 ; $00 -> Hyperwarp not engaged 00973 ; $7F -> Hyperwarp engaged 00974 ; $FF -> In hyperspace 00975 ; 00976 ; $C1 VELOCITYHI 00977 ; 00978 ; Our starship's velocity (high byte) in . Used values are: 00979 ; $00 -> Not in hyperspace (regular cruise or accelerating to 00980 ; hyperspace velocity) 00981 ; $01 -> Hyperspace velocity 00982 ; 00983 ; See also VELOCITYLO ($70). 00984 ; 00985 ; $C2 TRAILDELAY 00986 ; 00987 ; Delay timer to create the next star trail. Its value is decremented 00988 ; from 3 to 0 every game loop iteration during the hyperwarp STAR TRAIL 00989 ; PHASE in subroutine INITTRAIL ($A9B4). 00990 ; 00991 ; $C3 TRAILIND 00992 ; 00993 ; Position vector index of the star trail's first star. Used in 00994 ; subroutine INITTRAIL ($A9B4) to initialize a star trail, which is 00995 ; then displayed during the hyperwarp STAR TRAIL PHASE. Used values 00996 ; are: 17..48 in wrap-around fashion. 00997 ; 00998 ; $C4 WARPTEMPCOLUMN 00999 ; 01000 ; Temporary arrival column number of our starship on the Galactic Chart 01001 ; at the beginning of hyperspace. It is given in Player/Missile pixels 01002 ; relative to the left Galactic Chart border. Divide this value by 8 to 01003 ; get the sector column number. Used values are: $00..$7F. See also 01004 ; WARPARRVCOLUMN ($8F). 01005 ; 01006 ; $C5 WARPTEMPROW 01007 ; 01008 ; Temporary arrival row number of our starship on the Galactic Chart at 01009 ; the beginning of hyperspace. It is given in Player/Missile pixels 01010 ; relative to top Galactic Chart border. Divide this value by 16 to get 01011 ; the sector row number. Used values are: $00..$7F. See also 01012 ; WARPARRVROW ($8E). 01013 ; 01014 ; $C6 VEERMASK 01015 ; 01016 ; Limits the veer-off velocity of the Hyperwarp Target Marker during 01017 ; the hyperwarp ACCELERATION PHASE in subroutine HYPERWARP ($A89B). 01018 ; Values are picked from table VEERMASKTAB ($BED7). 01019 ; 01020 ; Also used as a local variable. 01021 ; 01022 ; $C7 VICINITYMASK 01023 ; 01024 ; Mask to confine space objects' position vector components 01025 ; (coordinates) in a sector into a certain interval around our starship 01026 ; after its arrival from hyperspace. Values are picked from table 01027 ; VICINITYMASKTAB ($BFB3). 01028 ; 01029 ; $C8 JOYSTICKX 01030 ; 01031 ; Horizontal joystick direction. Values are picked from table 01032 ; STICKINCTAB ($BAF5). Used values are: 01033 ; $01 -> Right 01034 ; $00 -> Centered 01035 ; $FF -> Left 01036 ; 01037 ; $C9 JOYSTICKY 01038 ; 01039 ; Vertical joystick direction. Values are picked from table STICKINCTAB 01040 ; ($BAF5). Used values are: 01041 ; $01 -> Up 01042 ; $00 -> Centered 01043 ; $FF -> Down 01044 ; 01045 ; $CA KEYCODE 01046 ; 01047 ; Hardware keyboard code of the pressed key on the keyboard. Shift and 01048 ; Control key bits B7..6 are always set. 01049 ; 01050 ; $CB..$CC SCORE 01051 ; 01052 ; Internal 16-bit score of the game in low byte-high byte order 01053 ; 01054 ; $CD SCOREDRANKIND 01055 ; 01056 ; Scored Rank Index. It is translated with table RANKTAB ($BEE9) to a 01057 ; title phrase offset pointing to the rank string. Used values are: 01058 ; $00 -> GALACTIC COOK 01059 ; $01 -> GARBAGE SCOW CAPTAIN 01060 ; $02 -> GARBAGE SCOW CAPTAIN 01061 ; $03 -> ROOKIE 01062 ; $04 -> ROOKIE 01063 ; $05 -> NOVICE 01064 ; $06 -> NOVICE 01065 ; $07 -> ENSIGN 01066 ; $08 -> ENSIGN 01067 ; $09 -> PILOT 01068 ; $0A -> PILOT 01069 ; $0B -> ACE 01070 ; $0C -> LIEUTENANT 01071 ; $0D -> WARRIOR 01072 ; $0E -> CAPTAIN 01073 ; $0F -> COMMANDER 01074 ; $10 -> COMMANDER 01075 ; $11 -> STAR COMMANDER 01076 ; $12 -> STAR COMMANDER 01077 ; 01078 ; $CE SCOREDCLASSIND 01079 ; 01080 ; Scored Class Index. It is translated into a class number with table 01081 ; CLASSTAB ($BEFC). Used values are: 01082 ; $00 -> Class 5 01083 ; $01 -> Class 5 01084 ; $02 -> Class 5 01085 ; $03 -> Class 4 01086 ; $04 -> Class 4 01087 ; $05 -> Class 4 01088 ; $06 -> Class 4 01089 ; $07 -> Class 3 01090 ; $08 -> Class 3 01091 ; $09 -> Class 3 01092 ; $0A -> Class 2 01093 ; $0B -> Class 2 01094 ; $0C -> Class 2 01095 ; $0D -> Class 1 01096 ; $0E -> Class 1 01097 ; $0F -> Class 1 01098 ; 01099 ; $CF TITLELIFE 01100 ; 01101 ; Lifetime of title line. It is decremented every game loop iteration. 01102 ; Used initial values are: 01103 ; $3C -> When displaying regular title phrases 01104 ; $FE -> When displaying "STARBASE SURROUNDED", "STARBASE DESTOYED", 01105 ; and "RED ALERT" messages 01106 ; $FF -> Hide title line 01107 ; 01108 ; $D0 SHIPVIEW 01109 ; 01110 ; Current view of our starship. Values are picked from table 01111 ; VIEWMODETAB ($BE22). Used values are: 01112 ; $00 -> Front view 01113 ; $01 -> Aft view 01114 ; $40 -> Long-Range Scan view 01115 ; $80 -> Galactic Chart view 01116 ; 01117 ; $D1 TITLEPHR 01118 ; 01119 ; Title phrase offset for text phrase in title line. Used values are: 01120 ; $00..$7B -> Title phrase offset into PHRASETAB ($BBAA) 01121 ; $FF -> Hide title line 01122 ; 01123 ; See also NEWTITLEPHR ($65). 01124 ; 01125 ; $D2 BEEPFRQIND 01126 ; 01127 ; Beeper sound pattern: Running index into frequency table BEEPFRQTAB 01128 ; ($BF5C). See also BEEPFRQSTART ($D7). See also subroutines BEEP 01129 ; ($B3A6) and SOUND ($B2AB). 01130 ; 01131 ; $D3 BEEPREPEAT 01132 ; 01133 ; Beeper sound pattern: Number of times the beeper sound pattern is 01134 ; repeated - 1. See also subroutines BEEP ($B3A6) and SOUND ($B2AB). 01135 ; 01136 ; $D4 BEEPTONELIFE 01137 ; 01138 ; Beeper sound pattern: Lifetime of tone in TICKs - 1. See also 01139 ; subroutines BEEP ($B3A6) and SOUND ($B2AB). 01140 ; 01141 ; $D5 BEEPPAUSELIFE 01142 ; 01143 ; Beeper sound pattern: Lifetime of pause in TICKs - 1. Used values 01144 ; are: 01145 ; < $FF -> Number of TICKs - 1 to play 01146 ; $FF -> Skip playing pause 01147 ; 01148 ; See also subroutines BEEP ($B3A6) and SOUND ($B2AB). 01149 ; 01150 ; $D6 BEEPPRIORITY 01151 ; 01152 ; Beeper sound pattern: Pattern priority. Each beeper sound pattern has 01153 ; a priority. When a pattern of higher priority is about to be played 01154 ; the pattern that is currently playing is stopped. Used values are: 01155 ; $00 -> No pattern playing at the moment 01156 ; > $00 -> Pattern priority 01157 ; 01158 ; See also subroutines BEEP ($B3A6) and SOUND ($B2AB). 01159 ; 01160 ; $D7 BEEPFRQSTART 01161 ; 01162 ; Beeper sound pattern: Index to first byte of the pattern frequency in 01163 ; table BEEPFRQTAB ($BF5C). See also BEEPFRQIND ($D2). See also 01164 ; subroutines BEEP ($B3A6) and SOUND ($B2AB). 01165 ; 01166 ; $D8 BEEPLIFE 01167 ; 01168 ; Beeper sound pattern: Lifetime of the current tone or pause in TICKs. 01169 ; It is decremented every TICK. See also subroutines BEEP ($B3A6) and 01170 ; SOUND ($B2AB). 01171 ; 01172 ; $D9 BEEPTOGGLE 01173 ; 01174 ; Beeper sound pattern: Indicates that either a tone or a pause is 01175 ; currently played. Used values are: 01176 ; $00 -> Tone 01177 ; $01 -> Pause 01178 ; 01179 ; See also subroutines BEEP ($B3A6) and SOUND ($B2AB). 01180 ; 01181 ; $DA NOISETORPTIM 01182 ; 01183 ; Noise sound pattern: Delay timer for PHOTON TORPEDO LAUNCHED noise 01184 ; sound pattern. It is decremented every TICK. See also subroutines 01185 ; NOISE ($AEA8) and SOUND ($B2AB). 01186 ; 01187 ; $DB NOISEEXPLTIM 01188 ; 01189 ; Noise sound pattern: Delay timer for SHIELD EXPLOSION and ZYLON 01190 ; EXPLOSION noise sound pattern. It is decremented every TICK. See also 01191 ; subroutines NOISE ($AEA8) and SOUND ($B2AB). 01192 ; 01193 ; $DC NOISEAUDC2 01194 ; 01195 ; Noise sound pattern: Audio channel 1/2 control shadow register. See 01196 ; also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01197 ; 01198 ; $DD NOISEAUDC3 01199 ; 01200 ; Noise sound pattern: Audio channel 3 control shadow register. See 01201 ; also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01202 ; 01203 ; $DE NOISEAUDF1 01204 ; 01205 ; Noise sound pattern: Audio channel 1 frequency shadow register. See 01206 ; also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01207 ; 01208 ; $DF NOISEAUDF2 01209 ; 01210 ; Noise sound pattern: Audio channel 2 frequency shadow register. See 01211 ; also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01212 ; 01213 ; $E0 NOISEFRQINC 01214 ; 01215 ; Noise sound pattern: Audio channel 1/2 frequency increment. See also 01216 ; subroutines NOISE ($AEA8) and SOUND ($B2AB). 01217 ; 01218 ; $E1 NOISELIFE 01219 ; 01220 ; Noise sound pattern: Noise sound pattern lifetime. It is decremented 01221 ; every TICK. See also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01222 ; 01223 ; $E2 NOISEZYLONTIM 01224 ; 01225 ; Delay timer to trigger the ZYLON EXPLOSION noise sound pattern. It is 01226 ; set in subroutine COLLISION ($AF3D) when an impact of one of our 01227 ; starship's photon torpedoes into a target is imminent. The timer is 01228 ; decremented every TICK during the execution of the Vertical Blank 01229 ; Interrupt handler VBIHNDLR ($A6D1). When the timer value reaches 0 01230 ; the ZYLON EXPLOSION noise sound pattern is played in subroutine SOUND 01231 ; ($B2AB). 01232 ; 01233 ; $E3 NOISEHITLIFE 01234 ; 01235 ; Lifetime of STARSHIP EXPLOSION noise when our starship was destroyed 01236 ; by a Zylon photon torpedo. It is set in routine GAMELOOP ($A1F3) to a 01237 ; value of 64 TICKs. It is decremented every TICK during the execution 01238 ; of the Vertical Blank Interrupt handler VBIHNDLR ($A6D1). 01239 ; 01240 ; $E4 PL0SHAPOFF 01241 ; 01242 ; PLAYER0 offset into shape table PLSHAP2TAB ($B9B1) 01243 ; 01244 ; $E5 PL1SHAPOFF 01245 ; 01246 ; PLAYER1 offset into shape table PLSHAP2TAB ($B9B1) 01247 ; 01248 ; $E6 PL2SHAPOFF 01249 ; 01250 ; PLAYER2 offset into shape table PLSHAP1TAB ($B8E4) 01251 ; 01252 ; $E7 PL3SHAPOFF 01253 ; 01254 ; PLAYER3 offset into shape table PLSHAP1TAB ($B8E4) 01255 ; 01256 ; $E8 PL4SHAPOFF 01257 ; 01258 ; PLAYER4 offset into shape table PLSHAP1TAB ($B8E4) 01259 ; 01260 ; $E9 PL0LIFE 01261 ; 01262 ; Lifetime of the space object represented by PLAYER0 (usually Zylon 01263 ; ship 0). Any value other than $FF is decremented with every game loop 01264 ; iteration. Used values are: 01265 ; $00 -> Space object not alive (= not in use) 01266 ; $01..$FE -> Values during lifetime countdown 01267 ; $FF -> Infinite lifetime (not counted down) 01268 ; 01269 ; $EA PL1LIFE 01270 ; 01271 ; Lifetime of a space object represented by PLAYER1 (usually Zylon ship 01272 ; 1). Compare PL0LIFE ($E9). 01273 ; 01274 ; $EB PL2LIFE 01275 ; 01276 ; Lifetime of a space object represented by PLAYER2 (usually the Zylon 01277 ; photon torpedo). Compare PL0LIFE ($E9). 01278 ; 01279 ; If this PLAYER represents a photon torpedo, its lifetime is 01280 ; decremented from an initial value of $FF. 01281 ; 01282 ; $EC PL3LIFE 01283 ; 01284 ; Lifetime of a space object represented by PLAYER3 (usually our 01285 ; starship's photon torpedo 0). Compare PL2LIFE ($EB). 01286 ; 01287 ; If this PLAYER represents a photon torpedo, its lifetime is 01288 ; decremented from an initial value of $FF. 01289 ; 01290 ; $ED PL4LIFE 01291 ; 01292 ; Lifetime of a space object represented by PLAYER4 (usually our 01293 ; starship's photon torpedo 1). Compare PL2LIFE ($EB). 01294 ; 01295 ; If this PLAYER represents a photon torpedo, its lifetime is 01296 ; decremented from an initial value of $FF. 01297 ; 01298 ; $EE PL0COLOR 01299 ; 01300 ; Color of PLAYER0 01301 ; 01302 ; $EF PL1COLOR 01303 ; 01304 ; Color of PLAYER1 01305 ; 01306 ; $F0 PL2COLOR 01307 ; 01308 ; Color of PLAYER2 01309 ; 01310 ; $F1 PL3COLOR 01311 ; 01312 ; Color of PLAYER3 01313 ; 01314 ; $F2 PF0COLOR 01315 ; 01316 ; Color of PLAYFIELD0 01317 ; 01318 ; $F3 PF1COLOR 01319 ; 01320 ; Color of PLAYFIELD1 01321 ; 01322 ; $F4 PF2COLOR 01323 ; 01324 ; Color of PLAYFIELD2 01325 ; 01326 ; $F5 PF3COLOR 01327 ; 01328 ; Color of PLAYFIELD3 01329 ; 01330 ; $F6 BGRCOLOR 01331 ; 01332 ; Color of BACKGROUND 01333 ; 01334 ; $F7 PF0COLORDLI 01335 ; 01336 ; Color of PLAYFIELD0 after DLI 01337 ; 01338 ; $F8 PF1COLORDLI 01339 ; 01340 ; Color of PLAYFIELD1 after DLI 01341 ; 01342 ; $F9 PF2COLORDLI 01343 ; 01344 ; Color of PLAYFIELD2 after DLI 01345 ; 01346 ; $FA PF3COLORDLI 01347 ; 01348 ; Color of PLAYFIELD3 after DLI 01349 ; 01350 ; $FB BGRCOLORDLI 01351 ; 01352 ; Color of BACKGROUND after DLI 01353 ; 01354 ; $0280..$02E9 DSPLST 01355 ; 01356 ; Display List 01357 ; 01358 ; $0300..$03FF PL4DATA 01359 ; 01360 ; PLAYER4 data area 01361 ; 01362 ; $0400..$04FF PL0DATA 01363 ; 01364 ; PLAYER0 data area 01365 ; 01366 ; $0500..$05FF PL1DATA 01367 ; 01368 ; PLAYER1 data area 01369 ; 01370 ; $0600..$06FF PL2DATA 01371 ; 01372 ; PLAYER2 data area 01373 ; 01374 ; $0700..$07FF PL3DATA 01375 ; 01376 ; PLAYER3 data area 01377 ; 01378 ; $0800..$0863 PFMEMROWLO 01379 ; 01380 ; Lookup table of start addresses (low byte) for each row of 01381 ; PLAYFIELD memory, which is located at PFMEM ($1000). The table 01382 ; contains 100 bytes for 100 rows (of which only 99 are shown by 01383 ; the Display List, the PLAYFIELD is 160 x 99 pixels). The 01384 ; addresses grow in increments of 40 (40 bytes = 160 pixels in 01385 ; GRAPHICS7 mode = 1 PLAYFIELD row of pixels). See also PFMEMROWHI 01386 ; ($0864). 01387 ; 01388 ; $0864..$08C7 PFMEMROWHI 01389 ; 01390 ; Lookup table of start addresses (high byte) of each row of 01391 ; PLAYFIELD memory. See also PFMEMROWLO ($0800). 01392 ; 01393 ; $08C9..$0948 GCMEMMAP 01394 ; 01395 ; Galactic Chart memory map (16 columns x 8 rows = 128 bytes) 01396 ; 01397 ; $0949..$0970 PANELTXT 01398 ; 01399 ; Memory of Control Panel Display (bottom text window) in Front 01400 ; view, Aft view, and Long-Range Scan view (20 characters x 2 rows 01401 ; = 40 bytes). 01402 ; 01403 ; $094A VELOCD1 01404 ; 01405 ; First digit (of 2) of the VELOCITY readout in Control Panel 01406 ; Display memory. 01407 ; 01408 ; $0950 KILLCNTD1 01409 ; 01410 ; First digit (of 2) of the KILL COUNTER readout in Control Panel 01411 ; Display memory. 01412 ; 01413 ; $0955 ENERGYD1 01414 ; 01415 ; First digit (of 4) of the ENERGY readout in Control Panel Display 01416 ; memory. 01417 ; 01418 ; $095A TRACKC1 01419 ; 01420 ; Character of the TRACKING readout 'T' or 'C' in Control Panel 01421 ; Display memory. 01422 ; 01423 ; $095C TRACKDIGIT 01424 ; 01425 ; Digit of the TRACKING readout in Control Panel Display memory. It 01426 ; is used to store the index of the currently tracked space object. 01427 ; Used values are: 01428 ; $00 -> Track Zylon ship 0 01429 ; $01 -> Track Zylon ship 1 01430 ; $02 -> Track starbase 01431 ; $03 -> Track Hyperwarp Target Marker 01432 ; 01433 ; $0960 THETAC1 01434 ; 01435 ; First character of the THETA readout in Control Panel Display 01436 ; memory. 01437 ; 01438 ; $0966 PHIC1 01439 ; 01440 ; First character of the PHI readout in Control Panel Display 01441 ; memory. 01442 ; 01443 ; $096C RANGEC1 01444 ; 01445 ; First character of the RANGE readout in Control Panel Display 01446 ; memory. 01447 ; 01448 ; $0971..$09AC GCTXT 01449 ; 01450 ; Memory of Galactic Chart Panel Display (bottom text window) of 01451 ; Galactic Chart view (20 characters x 3 rows = 60 bytes). 01452 ; 01453 ; $097D GCWARPD1 01454 ; 01455 ; First digit (of 4) of the HYPERWARP ENERGY readout in Galactic 01456 ; Chart Panel Display memory. 01457 ; 01458 ; $098D GCTRGCNT 01459 ; 01460 ; First target counter digit (of 2) in Galactic Chart Panel Display 01461 ; memory. 01462 ; 01463 ; $0992 GCSTATPHO 01464 ; 01465 ; Photon Torpedo status letter in Galactic Chart Panel Display 01466 ; memory. Used values are: 01467 ; %00****** -> OK 01468 ; %10****** -> Destroyed 01469 ; %11****** -> Damaged 01470 ; 01471 ; $0993 GCSTATENG 01472 ; 01473 ; Engines status letter in Galactic Chart Panel Display memory. 01474 ; Used values are: 01475 ; %00****** -> OK 01476 ; %10****** -> Destroyed 01477 ; %11****** -> Damaged 01478 ; 01479 ; $0994 GCSTATSHL 01480 ; 01481 ; Shields status letter in Galactic Chart Panel Display memory. 01482 ; Used values are: 01483 ; %00****** -> OK 01484 ; %10****** -> Destroyed 01485 ; %11****** -> Damaged 01486 ; 01487 ; $0995 GCSTATCOM 01488 ; 01489 ; Attack Computer status letter in Galactic Chart Panel Display 01490 ; memory. Used values are: 01491 ; %00****** -> OK 01492 ; %10****** -> Destroyed 01493 ; %11****** -> Damaged 01494 ; 01495 ; $0996 GCSTATLRS 01496 ; 01497 ; Long-Range Scan status letter in Galactic Chart Panel Display 01498 ; memory. Used values are: 01499 ; %00****** -> OK 01500 ; %10****** -> Destroyed 01501 ; %11****** -> Damaged 01502 ; 01503 ; $0997 GCSTATRAD 01504 ; 01505 ; Subspace Radio status letter in Galactic Chart Panel Display 01506 ; memory. Used values are: 01507 ; %00****** -> OK 01508 ; %10****** -> Destroyed 01509 ; %11****** -> Damaged 01510 ; 01511 ; $09A3 GCSTARDAT 01512 ; 01513 ; First (of 5) digits of the star date clock in the Galactic Chart 01514 ; Panel Display memory. 01515 ; 01516 ; $09AD..$09DD ZPOSSIGN 01517 ; 01518 ; Table containing the sign bit (B16) of position vector 01519 ; z-components (z-coordinate) (49 bytes). Bytes 0..4 belong to 01520 ; position vectors of PLAYER space objects (Zylon ships, photon 01521 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01522 ; PLAYFIELD space objects (stars, explosion fragments). Used values 01523 ; are: 01524 ; $00 -> Negative sign (behind our starship) 01525 ; $01 -> Positive sign (in front of our starship) 01526 ; 01527 ; See also "ON POSITION VECTORS". 01528 ; 01529 ; $09AD PL0ZPOSSIGN 01530 ; 01531 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01532 ; PLAYER0. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01533 ; VECTORS". 01534 ; 01535 ; $09AE PL1ZPOSSIGN 01536 ; 01537 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01538 ; PLAYER1. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01539 ; VECTORS". 01540 ; 01541 ; $09AF PL2ZPOSSIGN 01542 ; 01543 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01544 ; PLAYER2. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01545 ; VECTORS". 01546 ; 01547 ; $09B0 PL3ZPOSSIGN 01548 ; 01549 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01550 ; PLAYER3. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01551 ; VECTORS". 01552 ; 01553 ; $09B1 PL4ZPOSSIGN 01554 ; 01555 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01556 ; PLAYER4. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01557 ; VECTORS". 01558 ; 01559 ; $09DE..$0A0E XPOSSIGN 01560 ; 01561 ; Table containing the sign bit (B16) of position vector 01562 ; x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to 01563 ; position vectors of PLAYER space objects (Zylon ships, photon 01564 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01565 ; PLAYFIELD space objects (stars, explosion fragments). Used values 01566 ; are: 01567 ; $00 -> Negative sign (left) 01568 ; $01 -> Positive sign (right) 01569 ; 01570 ; See also "ON POSITION VECTORS". 01571 ; 01572 ; $09DE PL0XPOSSIGN 01573 ; 01574 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01575 ; PLAYER0. Compare XPOSSIGN ($09DE). See also "ON POSITION 01576 ; VECTORS". 01577 ; 01578 ; $09DF PL1XPOSSIGN 01579 ; 01580 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01581 ; PLAYER1. Compare XPOSSIGN ($09DE). See also "ON POSITION 01582 ; VECTORS". 01583 ; 01584 ; $09E0 PL2XPOSSIGN 01585 ; 01586 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01587 ; PLAYER2. Compare XPOSSIGN ($09DE). See also "ON POSITION 01588 ; VECTORS". 01589 ; 01590 ; $09E1 PL3XPOSSIGN 01591 ; 01592 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01593 ; PLAYER3. Compare XPOSSIGN ($09DE). See also "ON POSITION 01594 ; VECTORS". 01595 ; 01596 ; $09E2 PL4XPOSSIGN 01597 ; 01598 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01599 ; PLAYER4. Compare XPOSSIGN ($09DE). See also "ON POSITION 01600 ; VECTORS". 01601 ; 01602 ; $0A0F..$0A3F YPOSSIGN 01603 ; 01604 ; Table containing the sign bit (B16) of position vector 01605 ; y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to 01606 ; position vectors of PLAYER space objects (Zylon ships, photon 01607 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01608 ; PLAYFIELD space objects (stars, explosion fragments). Used values 01609 ; are: 01610 ; $00 -> Negative sign (down) 01611 ; $01 -> Positive sign (up) 01612 ; 01613 ; See also "ON POSITION VECTORS". 01614 ; 01615 ; $0A0F PL0YPOSSIGN 01616 ; 01617 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01618 ; PLAYER0. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01619 ; VECTORS". 01620 ; 01621 ; $0A10 PL1YPOSSIGN 01622 ; 01623 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01624 ; PLAYER1. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01625 ; VECTORS". 01626 ; 01627 ; $0A11 PL2YPOSSIGN 01628 ; 01629 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01630 ; PLAYER2. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01631 ; VECTORS". 01632 ; 01633 ; $0A12 PL3YPOSSIGN 01634 ; 01635 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01636 ; PLAYER3. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01637 ; VECTORS". 01638 ; 01639 ; $0A13 PL4YPOSSIGN 01640 ; 01641 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01642 ; PLAYER4. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01643 ; VECTORS". 01644 ; 01645 ; $0A40..$0A70 ZPOSHI 01646 ; 01647 ; Table containing the high byte (B15..8) of position vector 01648 ; y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to 01649 ; position vectors of PLAYER space objects (Zylon ships, photon 01650 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01651 ; PLAYFIELD space objects (stars, explosion fragments). See also 01652 ; "ON POSITION VECTORS". 01653 ; 01654 ; $0A40 PL0ZPOSHI 01655 ; 01656 ; High byte (B15..8) of position vector z-component (z-coordinate) 01657 ; of PLAYER0. Compare ZPOSHI ($0A40). See also "ON POSITION 01658 ; VECTORS". 01659 ; 01660 ; $0A41 PL1ZPOSHI 01661 ; 01662 ; High byte (B15..8) of position vector z-component (z-coordinate) 01663 ; of PLAYER1. Compare ZPOSHI ($0A40). See also "ON POSITION 01664 ; VECTORS". 01665 ; 01666 ; $0A42 PL2ZPOSHI 01667 ; 01668 ; High byte (B15..8) of position vector z-component (z-coordinate) 01669 ; of PLAYER2. Compare ZPOSHI ($0A40). See also "ON POSITION 01670 ; VECTORS". 01671 ; 01672 ; $0A43 PL3ZPOSHI 01673 ; 01674 ; High byte (B15..8) of position vector z-component (z-coordinate) 01675 ; of PLAYER3. Compare ZPOSHI ($0A40). See also "ON POSITION 01676 ; VECTORS". 01677 ; 01678 ; $0A44 PL4ZPOSHI 01679 ; 01680 ; High byte (B15..8) of position vector z-component (z-coordinate) 01681 ; of PLAYER4. Compare ZPOSHI ($0A40). See also "ON POSITION 01682 ; VECTORS". 01683 ; 01684 ; $0A71..$0AA1 XPOSHI 01685 ; 01686 ; Table containing the high byte (B15..8) of position vector 01687 ; x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to 01688 ; position vectors of PLAYER space objects (Zylon ships, photon 01689 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01690 ; PLAYFIELD space objects (stars, explosion fragments). See also 01691 ; "ON POSITION VECTORS". 01692 ; 01693 ; $0A71 PL0XPOSHI 01694 ; 01695 ; High byte (B15..8) of position vector x-component (x-coordinate) 01696 ; of PLAYER0. Compare XPOSHI ($0A71). See also "ON POSITION 01697 ; VECTORS". 01698 ; 01699 ; $0A72 PL1XPOSHI 01700 ; 01701 ; High byte (B15..8) of position vector x-component (x-coordinate) 01702 ; of PLAYER1. Compare XPOSHI ($0A71). See also "ON POSITION 01703 ; VECTORS". 01704 ; 01705 ; $0A73 PL2XPOSHI 01706 ; 01707 ; High byte (B15..8) of position vector x-component (x-coordinate) 01708 ; of PLAYER2. Compare XPOSHI ($0A71). See also "ON POSITION 01709 ; VECTORS". 01710 ; 01711 ; $0A74 PL3XPOSHI 01712 ; 01713 ; High byte (B15..8) of position vector x-component (x-coordinate) 01714 ; of PLAYER3. Compare XPOSHI ($0A71). See also "ON POSITION 01715 ; VECTORS". 01716 ; 01717 ; $0A75 PL4XPOSHI 01718 ; 01719 ; High byte (B15..8) of position vector x-component (x-coordinate) 01720 ; of PLAYER4. Compare XPOSHI ($0A71). See also "ON POSITION 01721 ; VECTORS". 01722 ; 01723 ; $0AA2..$0AD2 YPOSHI 01724 ; 01725 ; Table containing the high byte (B15..8) of position vector 01726 ; y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to 01727 ; position vectors of PLAYER space objects (Zylon ships, photon 01728 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01729 ; PLAYFIELD space objects (stars, explosion fragments). See also 01730 ; "ON POSITION VECTORS". 01731 ; 01732 ; $0AA2 PL0YPOSHI 01733 ; 01734 ; High byte (B15..8) of position vector y-component (y-coordinate) 01735 ; of PLAYER0. Compare YPOSHI ($0AA2). See also "ON POSITION 01736 ; VECTORS". 01737 ; 01738 ; $0AA3 PL1YPOSHI 01739 ; 01740 ; High byte (B15..8) of position vector y-component (y-coordinate) 01741 ; of PLAYER1. Compare YPOSHI ($0AA2). See also "ON POSITION 01742 ; VECTORS". 01743 ; 01744 ; $0AA4 PL2YPOSHI 01745 ; 01746 ; High byte (B15..8) of position vector y-component (y-coordinate) 01747 ; of PLAYER2. Compare YPOSHI ($0AA2). See also "ON POSITION 01748 ; VECTORS". 01749 ; 01750 ; $0AA5 PL3YPOSHI 01751 ; 01752 ; High byte (B15..8) of position vector y-component (y-coordinate) 01753 ; of PLAYER3. Compare YPOSHI ($0AA2). See also "ON POSITION 01754 ; VECTORS". 01755 ; 01756 ; $0AA6 PL4YPOSHI 01757 ; 01758 ; High byte (B15..8) of position vector y-component (y-coordinate) 01759 ; of PLAYER4. Compare YPOSHI ($0AA2). See also "ON POSITION 01760 ; VECTORS". 01761 ; 01762 ; $0AD3..$0B03 ZPOSLO 01763 ; 01764 ; Table containing the low byte (B7..0) of position vector 01765 ; z-components (z-coordinate) (49 bytes). Bytes 0..4 belong to 01766 ; position vectors of PLAYER space objects (Zylon ships, photon 01767 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01768 ; PLAYFIELD space objects (stars, explosion fragments). See also 01769 ; "ON POSITION VECTORS". 01770 ; 01771 ; $0AD3 PL0ZPOSLO 01772 ; 01773 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01774 ; PLAYER0. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01775 ; 01776 ; $0AD4 PL1ZPOSLO 01777 ; 01778 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01779 ; PLAYER1. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01780 ; 01781 ; $0AD5 PL2ZPOSLO 01782 ; 01783 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01784 ; PLAYER2. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01785 ; 01786 ; $0AD6 PL3ZPOSLO 01787 ; 01788 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01789 ; PLAYER3. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01790 ; 01791 ; $0AD7 PL4ZPOSLO 01792 ; 01793 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01794 ; PLAYER4. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01795 ; 01796 ; $0B04..$0B34 XPOSLO 01797 ; 01798 ; Table containing the low byte (B7..0) of position vector 01799 ; x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to 01800 ; position vectors of PLAYER space objects (Zylon ships, photon 01801 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01802 ; PLAYFIELD space objects (stars, explosion fragments). See also 01803 ; "ON POSITION VECTORS". 01804 ; 01805 ; $0B04 PL0XPOSLO 01806 ; 01807 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01808 ; PLAYER0. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01809 ; 01810 ; $0B05 PL1XPOSLO 01811 ; 01812 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01813 ; PLAYER1. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01814 ; 01815 ; $0B06 PL2XPOSLO 01816 ; 01817 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01818 ; PLAYER2. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01819 ; 01820 ; $0B07 PL3XPOSLO 01821 ; 01822 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01823 ; PLAYER3. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01824 ; 01825 ; $0B08 PL4XPOSLO 01826 ; 01827 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01828 ; PLAYER4. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01829 ; 01830 ; $0B35..$0B65 YPOSLO 01831 ; 01832 ; Table containing the low byte (B7..0) of position vector 01833 ; y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to 01834 ; position vectors of PLAYER space objects (Zylon ships, photon 01835 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01836 ; PLAYFIELD space objects (stars, explosion fragments). See also 01837 ; "ON POSITION VECTORS". 01838 ; 01839 ; $0B35 PL0YPOSLO 01840 ; 01841 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01842 ; PLAYER0. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01843 ; 01844 ; $0B36 PL1YPOSLO 01845 ; 01846 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01847 ; PLAYER1. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01848 ; 01849 ; $0B37 PL2YPOSLO 01850 ; 01851 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01852 ; PLAYER2. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01853 ; 01854 ; $0B38 PL3YPOSLO 01855 ; 01856 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01857 ; PLAYER3. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01858 ; 01859 ; $0B39 PL4YPOSLO 01860 ; 01861 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01862 ; PLAYER4. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01863 ; 01864 ; $0B66..$0B96 ZVEL 01865 ; 01866 ; Table containing velocity vector z-components (z-velocities) (49 01867 ; bytes). Bytes 0..4 belong to velocity vectors of PLAYER space 01868 ; objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong 01869 ; to velocity vectors of PLAYFIELD space objects (stars, explosion 01870 ; fragments). Each z-velocity is stored in the binary format 01871 ; %sxxxxxxx where 01872 ; %s = 0 -> Positive sign (moving in flight direction) 01873 ; %s = 1 -> Negative sign (moving in reverse flight direction) 01874 ; %xxxxxxx -> Unsigned 7-bit velocity value in 01875 ; 01876 ; See also "ON VELOCITY VECTORS". 01877 ; 01878 ; $0B66 PL0ZVEL 01879 ; 01880 ; Velocity vector z-component (z-velocity) of PLAYER0. Compare ZVEL 01881 ; ($0B66). See also "ON VELOCITY VECTORS". 01882 ; 01883 ; $0B67 PL1ZVEL 01884 ; 01885 ; Velocity vector z-component (z-velocity) of PLAYER1. Compare ZVEL 01886 ; ($0B66). See also "ON VELOCITY VECTORS". 01887 ; 01888 ; $0B68 PL2ZVEL 01889 ; 01890 ; Velocity vector z-component (z-velocity) of PLAYER2. Compare ZVEL 01891 ; ($0B66). See also "ON VELOCITY VECTORS". 01892 ; 01893 ; $0B69 PL3ZVEL 01894 ; 01895 ; Velocity vector z-component (z-velocity) of PLAYER3. Compare ZVEL 01896 ; ($0B66). See also "ON VELOCITY VECTORS". 01897 ; 01898 ; $0B6A PL4ZVEL 01899 ; 01900 ; Velocity vector z-component (z-velocity) of PLAYER4. Compare ZVEL 01901 ; ($0B66). See also "ON VELOCITY VECTORS". 01902 ; 01903 ; $0B97..$0BC7 XVEL 01904 ; 01905 ; Table containing velocity vector x-components (x-velocities) (49 01906 ; bytes). Bytes 0..4 belong to velocity vectors of PLAYER space 01907 ; objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong 01908 ; to velocity vectors of PLAYFIELD space objects (stars, explosion 01909 ; fragments). Each x-velocity is stored in the binary format 01910 ; %sxxxxxxx where 01911 ; %s = 0 -> Positive sign (moving to the right) 01912 ; %s = 1 -> Negative sign (moving to the left) 01913 ; %xxxxxxx -> Unsigned 7-bit velocity value in 01914 ; 01915 ; See also "ON VELOCITY VECTORS". 01916 ; 01917 ; $0B97 PL0XVEL 01918 ; 01919 ; Velocity vector x-component (x-velocity) of PLAYER0. Compare XVEL 01920 ; ($0B97). See also "ON VELOCITY VECTORS". 01921 ; 01922 ; $0B98 PL1XVEL 01923 ; 01924 ; Velocity vector x-component (x-velocity) of PLAYER1. Compare XVEL 01925 ; ($0B97). See also "ON VELOCITY VECTORS". 01926 ; 01927 ; $0B99 PL2XVEL 01928 ; 01929 ; Velocity vector x-component (x-velocity) of PLAYER2. Compare XVEL 01930 ; ($0B97). See also "ON VELOCITY VECTORS". 01931 ; 01932 ; $0B9A PL3XVEL 01933 ; 01934 ; Velocity vector x-component (x-velocity) of PLAYER3. Compare XVEL 01935 ; ($0B97). See also "ON VELOCITY VECTORS". 01936 ; 01937 ; $0B9B PL4XVEL 01938 ; 01939 ; Velocity vector x-component (x-velocity) of PLAYER4. Compare XVEL 01940 ; ($0B97). See also "ON VELOCITY VECTORS". 01941 ; 01942 ; $0BC8..$0BF8 YVEL 01943 ; 01944 ; Table containing velocity vector y-components (y-velocities) (49 01945 ; bytes). Bytes 0..4 belong to velocity vectors of PLAYER space 01946 ; objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong 01947 ; to velocity vectors of PLAYFIELD space objects (stars, explosion 01948 ; fragments). Each y-velocity is stored in the binary format 01949 ; %sxxxxxxx where 01950 ; %s = 0 -> Positive sign (moving up) 01951 ; %s = 1 -> Negative sign (moving down) 01952 ; %xxxxxxx -> Unsigned 7-bit velocity value in 01953 ; 01954 ; See also "ON VELOCITY VECTORS". 01955 ; 01956 ; $0BC8 PL0YVEL 01957 ; 01958 ; Velocity vector y-component (y-velocity) of PLAYER0. Compare YVEL 01959 ; ($0BC8). See also "ON VELOCITY VECTORS". 01960 ; 01961 ; $0BC9 PL1YVEL 01962 ; 01963 ; Velocity vector y-component (y-velocity) of PLAYER1. Compare YVEL 01964 ; ($0BC8). See also "ON VELOCITY VECTORS". 01965 ; 01966 ; $0BCA PL2YVEL 01967 ; 01968 ; Velocity vector y-component (y-velocity) of PLAYER2. Compare YVEL 01969 ; ($0BC8). See also "ON VELOCITY VECTORS". 01970 ; 01971 ; $0BCB PL3YVEL 01972 ; 01973 ; Velocity vector y-component (y-velocity) of PLAYER3. Compare YVEL 01974 ; ($0BC8). See also "ON VELOCITY VECTORS". 01975 ; 01976 ; $0BCC PL4YVEL 01977 ; 01978 ; Velocity vector y-component (y-velocity) of PLAYER4. Compare YVEL 01979 ; ($0BC8). See also "ON VELOCITY VECTORS". 01980 ; 01981 ; $0BF9..$0C29 PIXELROWNEW 01982 ; 01983 ; Table containing the new pixel row number of space objects (49 01984 ; bytes). Bytes 0..4 belong to PLAYER space objects and contain 01985 ; Player/Missile (PM) pixel row numbers. They are counted from 01986 ; vertical PM position 0, which is offscreen. Bytes 5..48 belong to 01987 ; PLAYFIELD space objects (stars, explosion fragments) and contain 01988 ; PLAYFIELD pixel row numbers. They are counted from the top border 01989 ; of the PLAYFIELD and have values of 0..99. See also PIXELROW 01990 ; ($0C5B). 01991 ; 01992 ; $0BF9 PL0ROWNEW 01993 ; 01994 ; New pixel row number of PLAYER0 in Player/Missile pixels. See 01995 ; also PIXELROWNEW ($0BF9). 01996 ; 01997 ; $0BFA PL1ROWNEW 01998 ; 01999 ; New pixel row number of PLAYER1 in Player/Missile pixels. See 02000 ; also PIXELROWNEW ($0BF9). 02001 ; 02002 ; $0BFB PL2ROWNEW 02003 ; 02004 ; New pixel row number of PLAYER2 in Player/Missile pixels. See 02005 ; also PIXELROWNEW ($0BF9). 02006 ; 02007 ; $0BFC PL3ROWNEW 02008 ; 02009 ; New pixel row number of PLAYER3 in Player/Missile pixels. See 02010 ; also PIXELROWNEW ($0BF9). 02011 ; 02012 ; $0BFD PL4ROWNEW 02013 ; 02014 ; New pixel row number of PLAYER4 in Player/Missile pixels. See 02015 ; also PIXELROWNEW ($0BF9). 02016 ; 02017 ; $0C2A..$0C5A PIXELCOLUMN 02018 ; 02019 ; Table containing the pixel column number of space objects (49 02020 ; bytes). Bytes 0..4 belong to PLAYER space objects and contain 02021 ; Player/Missile (PM) pixel column numbers. They are counted from 02022 ; horizontal PM position 0, which is offscreen. Bytes 5..48 belong 02023 ; to PLAYFIELD space objects (stars, explosion fragments) and 02024 ; contain PLAYFIELD pixel column numbers. They are counted from the 02025 ; left border of the PLAYFIELD and have values of 0..159. 02026 ; 02027 ; $0C2A PL0COLUMN 02028 ; 02029 ; Pixel column number of PLAYER0 in Player/Missile pixels. See also 02030 ; PIXELCOLUMN ($0C2A). 02031 ; 02032 ; $0C2B PL1COLUMN 02033 ; 02034 ; Pixel column number of PLAYER1 in Player/Missile pixels. See also 02035 ; PIXELCOLUMN ($0C2A). 02036 ; 02037 ; $0C2C PL2COLUMN 02038 ; 02039 ; Pixel column number of PLAYER2 in Player/Missile pixels. See also 02040 ; PIXELCOLUMN ($0C2A). 02041 ; 02042 ; $0C2D PL3COLUMN 02043 ; 02044 ; Pixel column number of PLAYER3 in Player/Missile pixels. See also 02045 ; PIXELCOLUMN ($0C2A). 02046 ; 02047 ; $0C2E PL4COLUMN 02048 ; 02049 ; Pixel column number of PLAYER4 in Player/Missile pixels. See also 02050 ; PIXELCOLUMN ($0C2A). 02051 ; 02052 ; $0C5B..$0C8B PIXELROW 02053 ; 02054 ; Table containing the pixel row number of space objects (49 02055 ; bytes). Bytes 0..4 belong to PLAYER space objects and contain 02056 ; Player/Missile (PM) pixel row numbers. They are counted from 02057 ; vertical PM position 0, which is offscreen. Bytes 5..48 belong to 02058 ; PLAYFIELD space objects (stars, explosion fragments) and contain 02059 ; PLAYFIELD pixel row numbers. They are counted from the top border 02060 ; of the PLAYFIELD and have values of 0..99. See also PIXELROWNEW 02061 ; ($0BF9). 02062 ; 02063 ; $0C5B PL0ROW 02064 ; 02065 ; Pixel row number of PLAYER0 in Player/Missile pixels. See also 02066 ; PIXELROW ($0C5B). 02067 ; 02068 ; $0C5C PL1ROW 02069 ; 02070 ; Pixel row number of PLAYER1 in Player/Missile pixels. See also 02071 ; PIXELROW ($0C5B). 02072 ; 02073 ; $0C5D PL2ROW 02074 ; 02075 ; Pixel row number of PLAYER2 in Player/Missile pixels. See also 02076 ; PIXELROW ($0C5B). 02077 ; 02078 ; $0C5E PL3ROW 02079 ; 02080 ; Pixel row number of PLAYER3 in Player/Missile pixels. See also 02081 ; PIXELROW ($0C5B). 02082 ; 02083 ; $0C5F PL4ROW 02084 ; 02085 ; Pixel row number of PLAYER4 in Player/Missile pixels. See also 02086 ; PIXELROW ($0C5B). 02087 ; 02088 ; $0C8C..$0CBC PIXELBYTEOFF 02089 ; 02090 ; Table containing a byte offset into PLAYFIELD memory for each 02091 ; PLAYFIELD space object (stars, explosion fragments) (49 bytes): 02092 ; the number of bytes from the start of the PLAYFIELD row to the 02093 ; byte containing the space object pixel in the same PLAYFIELD row. 02094 ; In other words, the pixel column modulo 4 (1 byte = 4 GRAPHICS7 02095 ; pixels). 02096 ; 02097 ; NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in 02098 ; this way. Bytes 0..4 are used differently. See PL0SHAPTYPE 02099 ; ($0C8C)..PL4SHAPTYPE ($0C90). 02100 ; 02101 ; $0C8C PL0SHAPTYPE 02102 ; 02103 ; Shape type of PLAYER0. Used to index the PLAYER's set of shape 02104 ; cells in tables PLSHAPOFFTAB ($BE2F) and PLSHAPHEIGHTTAB ($BE7F). 02105 ; Used values are: 02106 ; $00 -> PHOTON TORPEDO 02107 ; $10 -> ZYLON FIGHTER 02108 ; $20 -> STARBASE RIGHT 02109 ; $30 -> STARBASE CENTER 02110 ; $40 -> STARBASE LEFT 02111 ; $50 -> TRANSFER VESSEL 02112 ; $60 -> METEOR 02113 ; $70 -> ZYLON CRUISER 02114 ; $80 -> ZYLON BASESTAR 02115 ; $90 -> HYPERWARP TARGET MARKER 02116 ; 02117 ; $0C8D PL1SHAPTYPE 02118 ; 02119 ; Shape type of PLAYER1. Compare PL0SHAPTYPE ($0C8C). 02120 ; 02121 ; $0C8E PL2SHAPTYPE 02122 ; 02123 ; Shape type of PLAYER2. Compare PL0SHAPTYPE ($0C8C). 02124 ; 02125 ; $0C8F PL3SHAPTYPE 02126 ; 02127 ; Shape type of PLAYER3. Compare PL0SHAPTYPE ($0C8C). 02128 ; 02129 ; $0C90 PL4SHAPTYPE 02130 ; 02131 ; Shape type of PLAYER4. Compare PL0SHAPTYPE ($0C8C). 02132 ; 02133 ; $0CBD..$0CED PIXELSAVE 02134 ; 02135 ; Table containing the byte of PLAYFIELD memory before drawing the 02136 ; PLAYFIELD space object pixel into it (star, explosion fragments), 02137 ; for each PLAYFIELD space object (49 bytes). 02138 ; 02139 ; NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in 02140 ; this way. Bytes 0..4 are used differently. See PL0HEIGHT 02141 ; ($0CBD)..PL4HEIGHT ($0CC1). 02142 ; 02143 ; $0CBD PL0HEIGHT 02144 ; 02145 ; Shape height of PLAYER0 02146 ; 02147 ; $0CBE PL1HEIGHT 02148 ; 02149 ; Shape height of PLAYER1 02150 ; 02151 ; $0CBF PL2HEIGHT 02152 ; 02153 ; Shape height of PLAYER2 02154 ; 02155 ; $0CC0 PL3HEIGHT 02156 ; 02157 ; Shape height of PLAYER3 02158 ; 02159 ; $0CC1 PL4HEIGHT 02160 ; 02161 ; Shape height of PLAYER4 02162 ; 02163 ; $0CEE..$0D1E PIXELBYTE 02164 ; 02165 ; Table containing a 1-byte bit pattern for 4 pixels in the color 02166 ; of the space object's pixel, for each PLAYFIELD space object (49 02167 ; bytes). 02168 ; 02169 ; NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in 02170 ; this way. Bytes 0..4 are used differently. See PL0HEIGHTNEW 02171 ; ($0CEE)..PL4HEIGHTNEW ($0CF2). 02172 ; 02173 ; $0CEE PL0HEIGHTNEW 02174 ; 02175 ; New shape height of PLAYER0 02176 ; 02177 ; $0CEF PL1HEIGHTNEW 02178 ; 02179 ; New shape height of PLAYER1 02180 ; 02181 ; $0CF0 PL2HEIGHTNEW 02182 ; 02183 ; New shape height of PLAYER2 02184 ; 02185 ; $0CF1 PL3HEIGHTNEW 02186 ; 02187 ; New shape height of PLAYER3 02188 ; 02189 ; $0CF2 PL4HEIGHTNEW 02190 ; 02191 ; New shape height of PLAYER4 02192 ; 02193 ; $0D1F..$0D32 TITLETXT 02194 ; 02195 ; Title text line, contains ATASCII-coded characters (20 bytes) 02196 ; 02197 ; $0D35..$0DE8 GCPFMEM 02198 ; 02199 ; Galactic Chart PLAYFIELD memory (20 characters x 9 rows = 180 02200 ; bytes) 02201 ; 02202 ; $0DE9..$0EE8 MAPTO80 02203 ; 02204 ; Lookup table to convert values in $00..$FF to values of 0..80 02205 ; (255 bytes). Used to map position vector components (coordinates) 02206 ; to pixel row or column numbers relative to the PLAYFIELD center. 02207 ; 02208 ; $0EE9..$0FE8 MAPTOBCD99 02209 ; 02210 ; Lookup table to convert values in $00..$FF to BCD-values of 02211 ; 00..99 (255 bytes). Used in subroutines UPDPANEL ($B804) and 02212 ; SHOWDIGITS ($B8CD) to convert values to a 2-digit decimal readout 02213 ; value of the Control Panel Display. 02214 ; 02215 ; $1000..$1F77 PFMEM 02216 ; 02217 ; PLAYFIELD graphics memory (40 bytes x 100 rows = 4000 bytes, 1 02218 ; byte stores 4 pixels, 40 bytes = 160 pixels in GRAPHICS7 mode = 1 02219 ; PLAYFIELD row of pixels). 02220 ; 02221 ; NOTE: The Display List displays only PLAYFIELD rows 0..98. 02222 02223 ;******************************************************************************* 02224 ;* * 02225 ;* S Y S T E M S Y M B O L S * 02226 ;* * 02227 ;******************************************************************************* 02228 02229 VDSLST = $0200 ; Display List Interrupt (DLI) vector 02230 VIMIRQ = $0216 ; Interrupt request (IRQ) immediate vector 02231 VVBLKI = $0222 ; Vertical blank immediate vector 02232 HPOSP0 = $D000 ; Horizontal position of PLAYER0 02233 HPOSP1 = $D001 ; Horizontal position of PLAYER1 02234 HPOSP2 = $D002 ; Horizontal position of PLAYER2 02235 HPOSP3 = $D003 ; Horizontal position of PLAYER3 02236 HPOSM0 = $D004 ; Horizontal position of MISSILE0 02237 HPOSM1 = $D005 ; Horizontal position of MISSILE1 02238 HPOSM2 = $D006 ; Horizontal position of MISSILE2 02239 HPOSM3 = $D007 ; Horizontal position of MISSILE3 02240 M0PL = $D008 ; MISSILE0 to PLAYER collisions 02241 M1PL = $D009 ; MISSILE1 to PLAYER collisions 02242 M2PL = $D00A ; MISSILE2 to PLAYER collisions 02243 M3PL = $D00B ; MISSILE3 to PLAYER collisions 02244 P3PL = $D00F ; PLAYER3 to PLAYER collisions 02245 TRIG0 = $D010 ; Joystick 0 trigger 02246 COLPM0 = $D012 ; Color and brightness of PLAYER0 02247 COLPF0 = $D016 ; Color and brightness of PLAYFIELD0 02248 PRIOR = $D01B ; Priority selection register 02249 GRACTL = $D01D ; Graphics control register 02250 HITCLR = $D01E ; Clear collision register 02251 CONSOL = $D01F ; Function keys register 02252 AUDF1 = $D200 ; Audio channel 1 frequency 02253 AUDF2 = $D202 ; Audio channel 2 frequency 02254 AUDC2 = $D203 ; Audio channel 2 control 02255 AUDF3 = $D204 ; Audio channel 3 frequency 02256 AUDC3 = $D205 ; Audio channel 3 control 02257 AUDF4 = $D206 ; Audio channel 4 frequency 02258 AUDC4 = $D207 ; Audio channel 4 control 02259 AUDCTL = $D208 ; Audio control 02260 KBCODE = $D209 ; Keyboard code 02261 STIMER = $D209 ; Start POKEY timers 02262 RANDOM = $D20A ; Random number generator 02263 IRQEN = $D20E ; Interrupt request (IRQ) enable 02264 SKCTL = $D20F ; Serial port control 02265 PORTA = $D300 ; Port A 02266 PACTL = $D302 ; Port A control 02267 DMACTL = $D400 ; Direct Memory Access (DMA) control 02268 DLIST = $D402 ; Display List pointer 02269 PMBASE = $D407 ; Player/Missile base address (high byte) 02270 CHBASE = $D409 ; Character set base address (high byte) 02271 WSYNC = $D40A ; Wait for horizontal synchronization 02272 VCOUNT = $D40B ; Vertical line counter 02273 NMIEN = $D40E ; Non-maskable interrupt (NMI) enable 02274 ROMCHARSET = $E000 ; ROM character set 02275 02276 ;******************************************************************************* 02277 ;* * 02278 ;* G A M E S Y M B O L S * 02279 ;* * 02280 ;******************************************************************************* 02281 02282 MISSIONLEVEL = $62 02283 FKEYCODE = $63 02284 ISDEMOMODE = $64 02285 NEWTITLEPHR = $65 02286 IDLECNTHI = $66 02287 ISVBISYNC = $67 02288 MEMPTR = $68 02289 02290 DIVIDEND = $6A 02291 JOYSTICKDELTA = $6D 02292 02293 02294 VELOCITYLO = $70 02295 NEWVELOCITY = $71 02296 COUNT8 = $72 02297 EXPLLIFE = $73 02298 CLOCKTIM = $74 02299 DOCKSTATE = $75 02300 COUNT256 = $76 02301 IDLECNTLO = $77 02302 ZYLONUNITTIM = $78 02303 MAXSPCOBJIND = $79 02304 OLDMAXSPCOBJIND = $7A 02305 ISSTARBASESECT = $7B 02306 ISTRACKCOMPON = $7C 02307 DRAINSHIELDS = $7D 02308 DRAINATTCOMP = $7E 02309 ENERGYCNT = $7F 02310 DRAINENGINES = $80 02311 SHIELDSCOLOR = $81 02312 PL3HIT = $82 02313 PL4HIT = $83 02314 OLDTRIG0 = $84 02315 02316 ISTRACKING = $86 02317 BARRELNR = $87 02318 LOCKONLIFE = $88 02319 PLTRACKED = $89 02320 HITBADNESS = $8A 02321 REDALERTLIFE = $8B 02322 WARPDEPRROW = $8C 02323 WARPDEPRCOLUMN = $8D 02324 WARPARRVROW = $8E 02325 WARPARRVCOLUMN = $8F 02326 CURRSECTOR = $90 02327 WARPENERGY = $91 02328 ARRVSECTOR = $92 02329 HUNTSECTOR = $93 02330 HUNTSECTCOLUMN = $94 02331 HUNTSECTROW = $95 02332 NEWZYLONDIST = $96 02333 OLDZYLONDIST = $9E 02334 HUNTTIM = $9F 02335 BLIPCOLUMN = $A0 02336 BLIPROW = $A1 02337 BLIPCYCLECNT = $A2 02338 ISINLOCKON = $A3 02339 DIRLEN = $A4 02340 PENROW = $A5 02341 PENCOLUMN = $A6 02342 CTRLDZYLON = $A7 02343 ZYLONFLPAT0 = $A8 02344 ZYLONFLPAT1 = $A9 02345 MILESTTIM0 = $AA 02346 MILESTTIM1 = $AB 02347 MILESTVELINDZ0 = $AC 02348 MILESTVELINDZ1 = $AD 02349 MILESTVELINDX0 = $AE 02350 MILESTVELINDX1 = $AF 02351 MILESTVELINDY0 = $B0 02352 MILESTVELINDY1 = $B1 02353 ZYLONVELINDZ0 = $B2 02354 ZYLONVELINDZ1 = $B3 02355 ZYLONVELINDX0 = $B4 02356 ZYLONVELINDX1 = $B5 02357 ZYLONVELINDY0 = $B6 02358 ZYLONVELINDY1 = $B7 02359 ISBACKATTACK0 = $B8 02360 ISBACKATTACK1 = $B9 02361 ZYLONTIMX0 = $BA 02362 ZYLONTIMX1 = $BB 02363 ZYLONTIMY0 = $BC 02364 ZYLONTIMY1 = $BD 02365 TORPEDODELAY = $BE 02366 ZYLONATTACKER = $BF 02367 WARPSTATE = $C0 02368 VELOCITYHI = $C1 02369 TRAILDELAY = $C2 02370 TRAILIND = $C3 02371 WARPTEMPCOLUMN = $C4 02372 WARPTEMPROW = $C5 02373 VEERMASK = $C6 02374 VICINITYMASK = $C7 02375 JOYSTICKX = $C8 02376 JOYSTICKY = $C9 02377 KEYCODE = $CA 02378 SCORE = $CB 02379 SCOREDRANKIND = $CD 02380 SCOREDCLASSIND = $CE 02381 TITLELIFE = $CF 02382 SHIPVIEW = $D0 02383 TITLEPHR = $D1 02384 BEEPFRQIND = $D2 02385 BEEPREPEAT = $D3 02386 BEEPTONELIFE = $D4 02387 BEEPPAUSELIFE = $D5 02388 BEEPPRIORITY = $D6 02389 BEEPFRQSTART = $D7 02390 BEEPLIFE = $D8 02391 BEEPTOGGLE = $D9 02392 NOISETORPTIM = $DA 02393 NOISEEXPLTIM = $DB 02394 NOISEAUDC2 = $DC 02395 NOISEAUDC3 = $DD 02396 NOISEAUDF1 = $DE 02397 NOISEAUDF2 = $DF 02398 NOISEFRQINC = $E0 02399 NOISELIFE = $E1 02400 NOISEZYLONTIM = $E2 02401 NOISEHITLIFE = $E3 02402 PL0SHAPOFF = $E4 02403 PL1SHAPOFF = $E5 02404 PL2SHAPOFF = $E6 02405 PL3SHAPOFF = $E7 02406 PL4SHAPOFF = $E8 02407 PL0LIFE = $E9 02408 PL1LIFE = $EA 02409 PL2LIFE = $EB 02410 PL3LIFE = $EC 02411 PL4LIFE = $ED 02412 PL0COLOR = $EE 02413 PL1COLOR = $EF 02414 PL2COLOR = $F0 02415 PL3COLOR = $F1 02416 PF0COLOR = $F2 02417 PF1COLOR = $F3 02418 PF2COLOR = $F4 02419 PF3COLOR = $F5 02420 BGRCOLOR = $F6 02421 PF0COLORDLI = $F7 02422 PF1COLORDLI = $F8 02423 PF2COLORDLI = $F9 02424 PF3COLORDLI = $FA 02425 BGRCOLORDLI = $FB 02426 DSPLST = $0280 02427 PL4DATA = $0300 02428 PL0DATA = $0400 02429 PL1DATA = $0500 02430 PL2DATA = $0600 02431 PL3DATA = $0700 02432 PFMEMROWLO = $0800 02433 PFMEMROWHI = $0864 02434 GCMEMMAP = $08C9 02435 PANELTXT = $0949 02436 VELOCD1 = $094B 02437 KILLCNTD1 = $0950 02438 ENERGYD1 = $0955 02439 TRACKC1 = $095A 02440 TRACKDIGIT = $095C 02441 THETAC1 = $0960 02442 PHIC1 = $0966 02443 RANGEC1 = $096C 02444 GCTXT = $0971 02445 GCWARPD1 = $097D 02446 GCTRGCNT = $098D 02447 GCSTATPHO = $0992 02448 GCSTATENG = $0993 02449 GCSTATSHL = $0994 02450 GCSTATCOM = $0995 02451 GCSTATLRS = $0996 02452 GCSTATRAD = $0997 02453 GCSTARDAT = $09A3 02454 ZPOSSIGN = $09AD 02455 PL2ZPOSSIGN = $09AF 02456 PL3ZPOSSIGN = $09B0 02457 PL4ZPOSSIGN = $09B1 02458 XPOSSIGN = $09DE 02459 PL2XPOSSIGN = $09E0 02460 PL3XPOSSIGN = $09E1 02461 PL4XPOSSIGN = $09E2 02462 YPOSSIGN = $0A0F 02463 PL2YPOSSIGN = $0A11 02464 PL3YPOSSIGN = $0A12 02465 PL4YPOSSIGN = $0A13 02466 ZPOSHI = $0A40 02467 PL0ZPOSHI = $0A40 02468 PL2ZPOSHI = $0A42 02469 PL3ZPOSHI = $0A43 02470 PL4ZPOSHI = $0A44 02471 XPOSHI = $0A71 02472 PL2XPOSHI = $0A73 02473 PL3XPOSHI = $0A74 02474 PL4XPOSHI = $0A75 02475 YPOSHI = $0AA2 02476 PL2YPOSHI = $0AA4 02477 PL3YPOSHI = $0AA5 02478 PL4YPOSHI = $0AA6 02479 ZPOSLO = $0AD3 02480 PL2ZPOSLO = $0AD5 02481 PL3ZPOSLO = $0AD6 02482 PL4ZPOSLO = $0AD7 02483 XPOSLO = $0B04 02484 PL2XPOSLO = $0B06 02485 PL3XPOSLO = $0B07 02486 PL4XPOSLO = $0B08 02487 YPOSLO = $0B35 02488 PL2YPOSLO = $0B37 02489 PL3YPOSLO = $0B38 02490 PL4YPOSLO = $0B39 02491 ZVEL = $0B66 02492 PL0ZVEL = $0B66 02493 PL1ZVEL = $0B67 02494 PL2ZVEL = $0B68 02495 PL3ZVEL = $0B69 02496 PL4ZVEL = $0B6A 02497 XVEL = $0B97 02498 PL0XVEL = $0B97 02499 PL1XVEL = $0B98 02500 PL2XVEL = $0B99 02501 PL3XVEL = $0B9A 02502 PL4XVEL = $0B9B 02503 YVEL = $0BC8 02504 PL0YVEL = $0BC8 02505 PL1YVEL = $0BC9 02506 PL2YVEL = $0BCA 02507 PL3YVEL = $0BCB 02508 PL4YVEL = $0BCC 02509 PIXELROWNEW = $0BF9 02510 PL0ROWNEW = $0BF9 02511 PL1ROWNEW = $0BFA 02512 PL2ROWNEW = $0BFB 02513 PL3ROWNEW = $0BFC 02514 PL4ROWNEW = $0BFD 02515 PIXELCOLUMN = $0C2A 02516 PL0COLUMN = $0C2A 02517 PL1COLUMN = $0C2B 02518 PL2COLUMN = $0C2C 02519 PL3COLUMN = $0C2D 02520 PL4COLUMN = $0C2E 02521 PIXELROW = $0C5B 02522 PL0ROW = $0C5B 02523 PL1ROW = $0C5C 02524 PL2ROW = $0C5D 02525 PL3ROW = $0C5E 02526 PL4ROW = $0C5F 02527 PIXELBYTEOFF = $0C8C 02528 PL0SHAPTYPE = $0C8C 02529 PL1SHAPTYPE = $0C8D 02530 PL2SHAPTYPE = $0C8E 02531 PL3SHAPTYPE = $0C8F 02532 PL4SHAPTYPE = $0C90 02533 PIXELSAVE = $0CBD 02534 PL0HEIGHT = $0CBD 02535 PL1HEIGHT = $0CBE 02536 PL2HEIGHT = $0CBF 02537 PL3HEIGHT = $0CC0 02538 PL4HEIGHT = $0CC1 02539 PIXELBYTE = $0CEE 02540 PL0HEIGHTNEW = $0CEE 02541 PL1HEIGHTNEW = $0CEF 02542 PL2HEIGHTNEW = $0CF0 02543 PL3HEIGHTNEW = $0CF1 02544 PL4HEIGHTNEW = $0CF2 02545 TITLETXT = $0D1F 02546 GCPFMEM = $0D35 02547 MAPTO80 = $0DE9 02548 MAPTOBCD99 = $0EE9 02549 PFMEM = $1000 02550 02551 *= $A000 02552 02553 ;******************************************************************************* 02554 ;* * 02555 ;* G A M E D A T A ( P A R T 1 O F 2 ) * 02556 ;* * 02557 ;******************************************************************************* 02558 02559 ;*** Number of space objects *************************************************** 02560 02561 NUMSPCOBJ.PL = 5 ; Number of PLAYER space objects 02562 NUMSPCOBJ.STARS = 12 ; Number of PLAYFIELD space objects (stars) 02563 NUMSPCOBJ.NORM = NUMSPCOBJ.PL+NUMSPCOBJ.STARS ; Normal number of space objects 02564 NUMSPCOBJ.ALL = 49 ; Maximum number of space objects 02565 02566 ;*** PLAYER shape data offsets ************************************************* 02567 02568 SHAP.TORPEDO = $00 ; Photon torpedo 02569 SHAP.ZFIGHTER = $10 ; Zylon fighter 02570 SHAP.STARBASEL = $20 ; Starbase (left part) 02571 SHAP.STARBASEC = $30 ; Starbase (center part) 02572 SHAP.STARBASER = $40 ; Starbase (right part) 02573 SHAP.TRANSVSSL = $50 ; Transfer vessel 02574 SHAP.METEOR = $60 ; Meteor 02575 SHAP.ZCRUISER = $70 ; Zylon cruiser 02576 SHAP.ZBASESTAR = $80 ; Zylon basestar 02577 SHAP.HYPERWARP = $90 ; Hyperwarp Target Marker 02578 02579 ;*** ROM character set constants *********************************************** 02580 ROM.SPC = $00 ; ROM character ' ' 02581 ROM.DOT = $0E ; ROM character '.' 02582 ROM.0 = $10 ; ROM character '0' 02583 ROM.1 = $11 ; ROM character '1' 02584 ROM.2 = $12 ; ROM character '2' 02585 ROM.3 = $13 ; ROM character '3' 02586 ROM.4 = $14 ; ROM character '4' 02587 ROM.5 = $15 ; ROM character '5' 02588 ROM.9 = $19 ; ROM character '9' 02589 ROM.COLON = $1A ; ROM character ':' 02590 ROM.A = $21 ; ROM character 'A' 02591 ROM.C = $23 ; ROM character 'C' 02592 ROM.D = $24 ; ROM character 'D' 02593 ROM.E = $25 ; ROM character 'E' 02594 ROM.G = $27 ; ROM character 'G' 02595 ROM.L = $2C ; ROM character 'L' 02596 ROM.N = $2E ; ROM character 'N' 02597 ROM.P = $30 ; ROM character 'P' 02598 ROM.R = $32 ; ROM character 'R' 02599 ROM.S = $33 ; ROM character 'S' 02600 ROM.T = $34 ; ROM character 'T' 02601 ROM.W = $37 ; ROM character 'W' 02602 ROM.Y = $39 ; ROM character 'Y' 02603 02604 ;*** Custom character set constants ******************************************** 02605 CCS.COL1 = $40 ; COLOR1 bits for text in GR1/2 text mode 02606 CCS.COL2 = $80 ; COLOR2 bits for text in GR1/2 text mode 02607 CCS.COL3 = $C0 ; COLOR3 bits for text in GR1/2 text mode 02608 02609 CCS.0 = 0 ; Custom character '0' 02610 CCS.1 = 1 ; Custom character '1' 02611 CCS.2 = 2 ; Custom character '2' 02612 CCS.3 = 3 ; Custom character '3' 02613 CCS.4 = 4 ; Custom character '4' 02614 CCS.5 = 5 ; Custom character '5' 02615 CCS.6 = 6 ; Custom character '6' 02616 CCS.7 = 7 ; Custom character '7' 02617 CCS.8 = 8 ; Custom character '8' 02618 CCS.9 = 9 ; Custom character '9' 02619 CCS.SPC = 10 ; Custom character ' ' 02620 CCS.COLON = 11 ; Custom character ':' 02621 CCS.BORDERSW = 12 ; Custom character 'BORDER SOUTHWEST' 02622 CCS.E = 13 ; Custom character 'E' 02623 CCS.INF = 14 ; Custom character 'INFINITY' 02624 CCS.MINUS = 15 ; Custom character '-' 02625 CCS.PLUS = 16 ; Custom character '+' 02626 CCS.PHI = 17 ; Custom character 'PHI' 02627 CCS.V = 18 ; Custom character 'V' 02628 CCS.R = 19 ; Custom character 'R' 02629 CCS.THETA = 20 ; Custom character 'THETA' 02630 CCS.K = 21 ; Custom character 'K' 02631 CCS.T = 22 ; Custom character 'T' 02632 CCS.C = 23 ; Custom character 'C' 02633 CCS.BORDERS = 24 ; Custom character 'BORDER SOUTH' 02634 CCS.BORDERW = 25 ; Custom character 'BORDER WEST' 02635 CCS.CORNERSW = 26 ; Custom character 'CORNER SOUTHWEST' 02636 CCS.STARBASE = 27 ; Custom character 'STARBASE SECTOR' 02637 CCS.4ZYLONS = 28 ; Custom character '4-ZYLON SECTOR' 02638 CCS.3ZYLONS = 29 ; Custom character '3-ZYLON SECTOR' 02639 CCS.2ZYLONS = 30 ; Custom character '2-ZYLON SECTOR' 02640 02641 ;*** Custom character set ****************************************************** 02642 ; 02643 ; 0 1 2 3 4 5 6 7 02644 ; ........ ........ ........ ........ ........ ........ ........ ........ 02645 ; .####### ..##.... .####... .####... .##..... .####... .####... .#####.. 02646 ; .#...### ...#.... ....#... ....#... .##..... .#...... .#..#... .#...#.. 02647 ; .#...### ...#.... ....#... ....#... .##..... .#...... .#...... .....#.. 02648 ; .#...### ...#.... .####... .#####.. .##.##.. .####... .#...... ...###.. 02649 ; .#...### ..###... .#...... ....##.. .#####.. ....#... .######. ...#.... 02650 ; .#...### ..###... .#...... ....##.. ....##.. ....#... .#....#. ...#.... 02651 ; .####### ..###... .####... .#####.. ....##.. .####... .######. ...#.... 02652 ; 02653 ; 8 9 10 11 12 13 14 15 02654 ; ........ ........ ........ ..###... #....... ........ ........ ........ 02655 ; ..###... .#####.. ........ ..###... #....... ..####.. .##..##. ........ 02656 ; ..#.#... .#...#.. ........ ..###... #....... ..#..... #..##..# ........ 02657 ; ..#.#... .#...#.. ........ ........ #....... ..#..... #..##..# .######. 02658 ; .#####.. .#####.. ........ ........ #....... .####... #..##..# ........ 02659 ; .##.##.. ....##.. ........ ..###... #....... .##..... .##..##. ........ 02660 ; .##.##.. ....##.. ........ ..###... #....... .##..... ........ ........ 02661 ; .#####.. ....##.. ........ ..###... ######## .#####.. ........ ........ 02662 ; 02663 ; 16 17 18 19 20 21 22 23 02664 ; ........ ........ .##..##. ........ ........ ........ #######. ######.. 02665 ; ...##... ...##... .##..##. .#####.. ...###.. .#...##. #..#..#. #...##.. 02666 ; ...##... .######. .##..##. .#...#.. ..#####. .#...##. ...#.... #...##.. 02667 ; ...##... ##.##.## .##..##. .#...#.. .##...## .#...#.. ...##... #....... 02668 ; .######. #..##..# .##..##. .#####.. .#.###.# .#####.. ...##... #....... 02669 ; ...##... ##.##.## ..#.##.. .##.#... .##...## .##..#.. ...##... #....... 02670 ; ...##... .######. ..###... .##.##.. ..#####. .##..##. ...##... #....#.. 02671 ; ...##... ...##... ..##.... .##.##.. ...###.. .##..##. ...##... ######.. 02672 ; 02673 ; 24 25 26 27 28 29 30 02674 ; ........ #....... ........ #....... #....... #....... #....... 02675 ; ........ #....... ........ #.#.#.#. #..##... #...###. #.##.... 02676 ; ........ #....... ........ #..###.. #....... #....... #..##... 02677 ; ........ #....... ........ #.#####. #.##.##. #.###... #.#####. 02678 ; ........ #....... ........ #..###.. #....... #....... #..##... 02679 ; ........ #....... ........ #.#.#.#. #...##.. #..###.. #.##.... 02680 ; ........ #....... ........ #....... #....... #....... #....... 02681 ; ######## #....... #....... ######## ######## ######## ######## 02682 02683 CHARSET .BYTE $00,$7F,$47,$47,$47,$47,$47,$7F ; Custom character '0' 02684 .BYTE $00,$30,$10,$10,$10,$38,$38,$38 ; Custom character '1' 02685 .BYTE $00,$78,$08,$08,$78,$40,$40,$78 ; Custom character '2' 02686 .BYTE $00,$78,$08,$08,$7C,$0C,$0C,$7C ; Custom character '3' 02687 .BYTE $00,$60,$60,$60,$6C,$7C,$0C,$0C ; Custom character '4' 02688 .BYTE $00,$78,$40,$40,$78,$08,$08,$78 ; Custom character '5' 02689 .BYTE $00,$78,$48,$40,$40,$7E,$42,$7E ; Custom character '6' 02690 .BYTE $00,$7C,$44,$04,$1C,$10,$10,$10 ; Custom character '7' 02691 .BYTE $00,$38,$28,$28,$7C,$6C,$6C,$7C ; Custom character '8' 02692 .BYTE $00,$7C,$44,$44,$7C,$0C,$0C,$0C ; Custom character '9' 02693 .BYTE $00,$00,$00,$00,$00,$00,$00,$00 ; Custom character ' ' 02694 .BYTE $38,$38,$38,$00,$00,$38,$38,$38 ; Custom character ':' 02695 .BYTE $80,$80,$80,$80,$80,$80,$80,$FF ; Custom character 'BORDER SOUTHWEST' 02696 .BYTE $00,$3C,$20,$20,$78,$60,$60,$7C ; Custom character 'E' 02697 .BYTE $00,$66,$99,$99,$99,$66,$00,$00 ; Custom character 'INFINITY' 02698 .BYTE $00,$00,$00,$7E,$00,$00,$00,$00 ; Custom character '-' 02699 .BYTE $00,$18,$18,$18,$7E,$18,$18,$18 ; Custom character '+' 02700 .BYTE $00,$18,$7E,$DB,$99,$DB,$7E,$18 ; Custom character 'PHI' 02701 .BYTE $66,$66,$66,$66,$66,$2C,$38,$30 ; Custom character 'V' 02702 .BYTE $00,$7C,$44,$44,$7C,$68,$6C,$6C ; Custom character 'R' 02703 .BYTE $00,$1C,$3E,$63,$5D,$63,$3E,$1C ; Custom character 'THETA' 02704 .BYTE $00,$46,$46,$44,$7C,$64,$66,$66 ; Custom character 'K' 02705 .BYTE $FE,$92,$10,$18,$18,$18,$18,$18 ; Custom character 'T' 02706 .BYTE $FC,$8C,$8C,$80,$80,$80,$84,$FC ; Custom character 'C' 02707 .BYTE $00,$00,$00,$00,$00,$00,$00,$FF ; Custom character 'BORDER SOUTH' 02708 .BYTE $80,$80,$80,$80,$80,$80,$80,$80 ; Custom character 'BORDER WEST' 02709 .BYTE $00,$00,$00,$00,$00,$00,$00,$80 ; Custom character 'CORNER SOUTHWEST' 02710 .BYTE $80,$AA,$9C,$BE,$9C,$AA,$80,$FF ; Custom character 'STARBASE SECTOR' 02711 .BYTE $80,$98,$80,$B6,$80,$8C,$80,$FF ; Custom character '4-ZYLON SECTOR' 02712 .BYTE $80,$8E,$80,$B8,$80,$9C,$80,$FF ; Custom character '3-CYCLON SECTOR' 02713 .BYTE $80,$B0,$98,$BE,$98,$B0,$80,$FF ; Custom character '2-ZYLON SECTOR' 02714 02715 ;*** Header text of Long-Range Scan view (shares spaces with following header) * 02716 LRSHEADER .BYTE $00,$00,$6C,$6F,$6E,$67,$00,$72 ; " LONG RANGE SCAN" 02717 .BYTE $61,$6E,$67,$65,$00,$73,$63,$61 02718 .BYTE $6E 02719 02720 ;*** Header text of Aft view (shares spaces with following header) ************* 02721 AFTHEADER .BYTE $00,$00,$00,$00,$00,$00,$61,$66 ; " AFT VIEW " 02722 .BYTE $74,$00,$76,$69,$65,$77,$00,$00 02723 .BYTE $00 02724 02725 ;*** Header text of Galactic Chart view **************************************** 02726 GCHEADER .BYTE $00,$00,$00,$67,$61,$6C,$61,$63 ; " GALACTIC CHART " 02727 .BYTE $74,$69,$63,$00,$63,$68,$61,$72 02728 .BYTE $74,$00,$00,$00 02729 02730 ;*** Display List of Galactic Chart view *************************************** 02731 DLSTGC .BYTE $60 ; BLK7 02732 .BYTE $46,GCHEADER ; GR2 @ GCHEADER 02733 .BYTE $F0 ; BLK8 + DLI 02734 .BYTE $47,GCPFMEM ; GR1 @ GCPFMEM 02735 .BYTE $07 ; GR1 02736 .BYTE $07 ; GR1 02737 .BYTE $07 ; GR1 02738 .BYTE $07 ; GR1 02739 .BYTE $07 ; GR1 02740 .BYTE $07 ; GR1 02741 .BYTE $07 ; GR1 02742 .BYTE $07 ; GR1 02743 .BYTE $80 ; BLK1 + DLI 02744 .BYTE $46,TITLETXT ; GR2 @ TITLETXT 02745 .BYTE $46,GCTXT ; GR2 @ GCTXT 02746 .BYTE $06 ; GR2 02747 .BYTE $06 ; GR2 02748 .BYTE $41,DSPLST ; JMP @ DSPLST 02749 02750 ;******************************************************************************* 02751 ;* * 02752 ;* G A M E C O D E * 02753 ;* * 02754 ;******************************************************************************* 02755 02756 ;******************************************************************************* 02757 ;* * 02758 ;* INITCOLD * 02759 ;* * 02760 ;* Initialize game (Cold start) * 02761 ;* * 02762 ;******************************************************************************* 02763 02764 ; DESCRIPTION 02765 ; 02766 ; Initializes the game, then continues into the game loop at GAMELOOP ($A1F3). 02767 ; 02768 ; There are four entry points to initialization: 02769 ; 02770 ; (1) INITCOLD ($A14A) is entered at initial cartridge startup (cold start). 02771 ; This initializes POKEY, resets the idle counter, sets the mission level 02772 ; to NOVICE mission, and clears the function key code. POKEY is enabled to 02773 ; receive keyboard input. Code execution continues into INITSELECT ($A15A) 02774 ; below. 02775 ; 02776 ; (2) INITSELECT ($A15A) is entered from GAMELOOP ($A1F3) after the SELECT 02777 ; function key has been pressed. This loads the title phrase offset for the 02778 ; copyright notice. Code execution continues into INITDEMO ($A15C) below. 02779 ; 02780 ; (3) INITDEMO ($A15C) is entered when the game switches into demo mode. This 02781 ; loads the demo mode flag. Code execution continues into INITSTART ($A15E) 02782 ; below. 02783 ; 02784 ; (4) INITSTART ($A15E) is entered from GAMELOOP ($A1F3) after the START 02785 ; function key has been pressed. This enqueues the new title phrase and 02786 ; enables or disables demo mode, depending on the preloaded value. 02787 ; 02788 ; Initialization continues with the following steps: 02789 ; 02790 ; (1) Clear the custom chip registers and zero-page game variables from 02791 ; ISVBISYNC ($0067) on. 02792 ; 02793 ; NOTE: Because of loop jamming there is a loop index overshoot. Instead of 02794 ; clearing memory at addresses $0067..$00FB, the memory at addresses 02795 ; $0067..$0166 is cleared. This does no harm because $0100..$0166 is a yet 02796 ; unused part of the 6502 CPU stack. 02797 ; 02798 ; NOTE: At address $A175 a hack is necessary in the source code to fake a 02799 ; STA ISVBISYNC,X instruction with a 16-bit address. ISVBISYNC ($0067) is a 02800 ; zero-page address and regular assemblers would translate STA ISVBISYNC,X 02801 ; into the byte sequence $95 $67, not $9D $67 $00. This indicates that the 02802 ; original ROM was maybe created using a special assembler, perhaps a 02803 ; cross-assembler. 02804 ; 02805 ; (2) Initialize the 6502 CPU (reset the stack pointer, disable decimal mode). 02806 ; 02807 ; (3) Clear game memory from $0200..$1FFF in subroutine CLRMEM ($AE0F). 02808 ; 02809 ; (4) Set the address vectors of the IRQ, VBI, and DLI handlers. 02810 ; 02811 ; (5) Enable input from Joystick 0. 02812 ; 02813 ; (6) Enable Player/Missile graphics, providing a fifth PLAYER, and set 02814 ; PLAYER-PLAYFIELD priority. 02815 ; 02816 ; BUG (at $A1A6): The set PLAYER-PLAYFIELD priority arranges PLAYERs 02817 ; (PL0..4) in front of the PLAYFIELD (PF0..4) in this specific order, from 02818 ; front to back: 02819 ; 02820 ; PL0 > PL1 > PL2 > PL3 > PL4 > PF0, PF1, PF2 > PF4 (BGR) 02821 ; 02822 ; This makes sense as space objects represented by PLAYERs (for example, 02823 ; Zylon ships, photon torpedoes, and meteors) move in front of the stars, 02824 ; which are part of the PLAYFIELD. However, PLAYERs also move in front of 02825 ; the cross hairs, which are also part of the PLAYFIELD. Suggested fix: 02826 ; None, technically not possible. 02827 ; 02828 ; (7) Do more initialization in subroutine INITIALIZE ($B3BA). 02829 ; 02830 ; (8) Set display to Front view. 02831 ; 02832 ; (9) Show or hide the Control Panel Display (bottom text window) in subroutine 02833 ; MODDLST ($ADF1), depending on the demo mode flag. 02834 ; 02835 ; (10) Initialize our starship's velocity equivalent to speed key '6'. 02836 ; 02837 ; (11) Enable the Display List. 02838 ; 02839 ; (12) Initialize the number of space objects to 16 (5 PLAYER space objects + 12 02840 ; PLAYFIELD space objects (stars), counted 0..16). 02841 ; 02842 ; (13) Set the title phrase to the selected mission level in subroutine SETTITLE 02843 ; ($B223). 02844 ; 02845 ; (14) Enable the IRQ, DLI, and VBI interrupts. 02846 ; 02847 ; Code execution continues into the game loop at GAMELOOP ($A1F3). 02848 02849 INITCOLD LDA #0 ; 02850 STA SKCTL ; POKEY: Initialization 02851 STA IDLECNTHI ; Reset idle counter 02852 STA MISSIONLEVEL ; Mission level := NOVICE mission 02853 STA FKEYCODE ; Clear function key code 02854 LDA #$03 ; POKEY: Enable keyboard scan and debounce 02855 STA SKCTL ; 02856 02857 ;*** Entry point when SELECT function key was pressed ************************** 02858 INITSELECT LDY #$2F ; Prep title phrase "COPYRIGHT ATARI 1979" 02859 02860 ;*** Entry point when game switches into demo mode ***************************** 02861 INITDEMO LDA #$FF ; Prep demo mode flag 02862 02863 ;*** Entry point when START function key was pressed *************************** 02864 INITSTART STY NEWTITLEPHR ; Enqueue new title phrase 02865 STA ISDEMOMODE ; Store demo mode flag 02866 02867 ;*** More initialization ******************************************************* 02868 LDA #0 ; Clear custom chip registers, zero-page variables 02869 TAX ; 02870 LOOP001 STA HPOSP0,X ; Clear $D000..$D0FF (GTIA registers) 02871 STA DMACTL,X ; Clear $D400..$D4FF (ANTIC registers) 02872 CPX #$0F ; 02873 BCS SKIP001 ; 02874 STA AUDF1,X ; Clear $D200..$D20E (POKEY registers) 02875 02876 SKIP001 STA PORTA,X ; Clear $D300..$D3FF (PIA registers) 02877 ; Clear $0067..$0166 (zero-page game variables) 02878 .BYTE $9D ; HACK: Fake STA ISVBISYNC,X with 16-bit address 02879 .WORD ISVBISYNC ; (loop jamming) 02880 INX ; 02881 BNE LOOP001 ; 02882 02883 DEX ; Reset 6502 CPU stack pointer 02884 TXS ; 02885 02886 CLD ; Clear 6502 CPU decimal mode 02887 02888 LDA #$02 ; Clear $0200..$1FFF (game memory) 02889 JSR CLRMEM ; 02890 02891 LDA #IRQHNDLR ; 02894 STA VIMIRQ+1 ; 02895 02896 LDA #VBIHNDLR ; 02901 STA VVBLKI+1 ; 02902 LDA #>DLSTHNDLR ; 02903 STA VDSLST+1 ; 02904 02905 LDA #$04 ; PIA: Enable PORTA (Joystick 0) 02906 STA PACTL ; 02907 LDA #$11 ; GTIA: Enable PLAYER4, prio: PLs > PFs > BGR (!) 02908 STA PRIOR ; (PLAYERs in front of stars - and cross hairs) 02909 LDA #$03 ; GTIA: Enable DMA for PLAYERs and MISSILEs 02910 STA GRACTL ; 02911 02912 JSR INITIALIZE ; Init Display List, tables, Galactic Chart, etc. 02913 02914 LDX #$0A ; Set Front view 02915 JSR SETVIEW ; 02916 02917 LDA ISDEMOMODE ; If in/not in demo mode hide/show... 02918 AND #$80 ; ...Control Panel Display (bottom text window) 02919 TAY ; 02920 LDX #$5F ; 02921 LDA #$08 ; 02922 JSR MODDLST ; 02923 02924 LDA #32 ; Init our starship's velocity (= speed key '6') 02925 STA NEWVELOCITY ; 02926 02927 LDA #DSPLST ; 02930 STA DLIST+1 ; 02931 02932 LDA #$3E ; ANTIC: Enable Display List DMA, single-line PM 02933 STA DMACTL ; resolution, PM DMA, normal-width PLAYFIELD 02934 02935 LDA #0 ; ANTIC: Set PM memory base address 02936 STA PMBASE ; 02937 02938 LDA #NUMSPCOBJ.NORM-1 ; Set normal number of space objects 02939 STA MAXSPCOBJIND ; (5 PLAYER spc objs + 12 PLAYFIELD spc objs (stars)) 02940 02941 LDX MISSIONLEVEL ; Set title phrase 02942 LDY MISSIONPHRTAB,X ; NOVICE, PILOT, WARRIOR, or COMMANDER MISSION 02943 JSR SETTITLE ; 02944 02945 LDA #$40 ; POKEY: Enable keyboard interrupt (IRQ) 02946 STA IRQEN ; 02947 02948 CLI ; Enable all IRQs 02949 02950 LDA #$C0 ; ANTIC: Enable DLI and VBI 02951 STA NMIEN ; 02952 02953 ;******************************************************************************* 02954 ;* * 02955 ;* GAMELOOP * 02956 ;* * 02957 ;******************************************************************************* 02958 02959 ; DESCRIPTION 02960 ; 02961 ; The game loop is the main part of the game. It is basically an infinite loop 02962 ; that collects input, computes the game state, and updates the display. It 02963 ; executes the following steps: 02964 ; 02965 ; (1) Synchronize the start of the game loop with the vertical blank phase of 02966 ; the TV beam, which flagged by the Vertical Blank Interrupt handler 02967 ; VBIHNDLR ($A6D1). This prevents screen flicker while the PLAYFIELD is 02968 ; redrawn at the beginning of the game loop, because during the vertical 02969 ; blank phase the TV beam is turned off and nothing is rendered on the TV 02970 ; display. 02971 ; 02972 ; (2) Erase all PLAYFIELD space objects (stars, explosion fragments) from the 02973 ; PLAYFIELD that were drawn in the previous game loop iteration. 02974 ; 02975 ; (3) Draw the updated PLAYFIELD space objects (stars, explosion fragments) 02976 ; into the PLAYFIELD (skip this if in hyperspace). 02977 ; 02978 ; (4) If the idle counter has reached its trigger value then clear the center 02979 ; of the PLAYFIELD, an 8 x 2 pixel rectangle with a top-left position at 02980 ; pixel column number 76 and pixel row number 49 (?). 02981 ; 02982 ; (5) Clear all PLAYER shapes. 02983 ; 02984 ; (6) Update the vertical position of all PLAYERs and update all PLAYER shapes. 02985 ; 02986 ; (7) Update the horizontal position of all PLAYERs. 02987 ; 02988 ; (8) Rotate the position vector of all space objects horizontally and 02989 ; vertically, according to the saved joystick position (skip this if in 02990 ; Galactic Chart view) using subroutine ROTATE ($B69B). 02991 ; 02992 ; (9) Move our starship forward in space. Our starship is always located at the 02993 ; center of the game's 3D coordinate system, so all space objects are moved 02994 ; along the z-axis toward our starship by subtracting a displacement from 02995 ; their z-coordinate. The amount of the displacement depends on our 02996 ; starship's velocity. 02997 ; 02998 ; BUG (at $A3C1): This operation is not applied to Photon torpedoes (?). 02999 ; Suggested fix: Remove LDA PL0SHAPTYPE,X and BEQ SKIP011. 03000 ; 03001 ; (10) Add the proper velocity vector of all space objects to their position 03002 ; vector (except for stars, which do not have any proper motion). 03003 ; 03004 ; BUG (at $A419): The correct maximum loop index is NUMSPCOBJ.ALL*3 = 147 03005 ; instead of 144. Suggested fix: Replace CMP #144 with CMP #147. 03006 ; 03007 ; (11) Correct the position vector components (coordinates) of all PLAYER space 03008 ; objects if they have over- or underflowed during the calculations of the 03009 ; previous steps. 03010 ; 03011 ; (12) Calculate the perspective projection of the position vectors of all space 03012 ; objects and from that their pixel row and column number (applies to Front 03013 ; and Aft view) using subroutines PROJECTION ($AA21), SCREENCOLUMN ($B6FB), 03014 ; and SCREENROW ($B71E). If a space object (star, explosion fragment) moved 03015 ; offscreen then a new space object is automatically created in subroutine 03016 ; SCREENCOLUMN ($B6FB). 03017 ; 03018 ; (13) Handle hyperwarp marker selection in the Galactic Chart view in 03019 ; subroutine SELECTWARP ($B162). 03020 ; 03021 ; (14) If in Long-Range Scan view, compute the pixel column number and the pixel 03022 ; row number of all PLAYFIELD space objects (stars, explosion fragments) on 03023 ; the plane established by the z and x axis of the 3D coordinate system 03024 ; using subroutines SCREENCOLUMN ($B6FB) and SCREENROW ($B71E). Our 03025 ; starship's shape is drawn using subroutine DRAWLINES ($A76F). If the 03026 ; Long-Range Scan is OK then PLAYFIELD space object pixel numbers are 03027 ; computed and drawn. This is skipped if the Long-Range Scan is destroyed. 03028 ; 03029 ; (15) Update all PLAYER shapes, heights, and colors (see detailed description 03030 ; below). 03031 ; 03032 ; (16) Flash a red alert when leaving hyperspace into a sector containing Zylon 03033 ; ships by setting appropriate colors to PLAYFIELD2 and BACKGROUND. 03034 ; 03035 ; (17) Update the color of all PLAYFIELD space objects (stars, explosion 03036 ; fragments). The color calculation is similar to that of the PLAYER color 03037 ; calculation in (15). It also computes a range index and uses the same 03038 ; color lookup table FOURCOLORPIXEL ($BA90). If a star in the Aft view 03039 ; became too distant (z-coordinate < -$F000 (-4096) ) its position is 03040 ; re-initialized in subroutine INITPOSVEC ($B764). 03041 ; 03042 ; (18) If in demo mode skip input handling and jump directly to function key 03043 ; handling (28). 03044 ; 03045 ; (19) Handle keyboard input in subroutine KEYBOARD ($AFFE). 03046 ; 03047 ; (20) Handle joystick input. Store the current joystick directions in JOYSTICKX 03048 ; ($C8) and JOYSTICKY ($C9). 03049 ; 03050 ; (21) Check if our starship's photon torpedoes have hit a target in subroutine 03051 ; COLLISION ($AF3D). This subroutine triggers a game over if all Zylon 03052 ; ships have been destroyed. 03053 ; 03054 ; (22) Handle the joystick trigger in subroutine TRIGGER ($AE29). 03055 ; 03056 ; (23) Handle the Attack Computer and Tracking Computer. If the Attack Computer 03057 ; is neither destroyed nor switched off then execute the following steps: 03058 ; 03059 ; o Update the Attack Computer Display's blip and lock-on markers in 03060 ; subroutine UPDATTCOMP ($A7BF) (if in Front view). 03061 ; 03062 ; o Update the tracking index of the currently tracked PLAYER space 03063 ; object. If a Zylon ship is tracked, then make sure to always track 03064 ; the Zylon ship that launched the last Zylon photon torpedo. If this 03065 ; Zylon ship is not alive then track the other Zylon ship - if alive. 03066 ; 03067 ; o If the Tracking Computer is on then switch to the view that shows the 03068 ; tracked PLAYER space object by emulating pressing the 'F' (Front 03069 ; view) or 'A' (Aft view) key (only if in Front or Aft view). 03070 ; 03071 ; (24) Handle docking at a starbase in subroutine DOCKING ($ACE6). 03072 ; 03073 ; (25) Handle maneuvering both of our starship's photon torpedoes, the single 03074 ; Zylon photon torpedo, and the attacking Zylon ships in subroutine 03075 ; MANEUVER ($AA79). This subroutine also automatically creates meteors and 03076 ; new Zylon ships. 03077 ; 03078 ; (26) Check if our starship was hit by a Zylon photon torpedo (skip this if in 03079 ; a starbase sector): Its x, y, and z coordinates must be within a range of 03080 ; -($0100)..+$00FF (-256..+255) of our starship. 03081 ; 03082 ; (27) If our starship was hit then execute the following steps: 03083 ; 03084 ; o Damage or destroy one of our starship's subsystems in subroutine 03085 ; DAMAGE ($AEE1). 03086 ; 03087 ; o Trigger an explosion in subroutine INITEXPL ($AC6B), 03088 ; 03089 ; o Store the severity of the hit. 03090 ; 03091 ; o End the lifetime of the Zylon photon torpedo. 03092 ; 03093 ; o Subtract 100 energy units for being hit by the Zylon photon torpedo 03094 ; in subroutine DECENERGY ($B86F). 03095 ; 03096 ; o Trigger the noise sound pattern SHIELD EXPLOSION in subroutine NOISE 03097 ; ($AEA8). 03098 ; 03099 ; If the Shields were down during the hit, our starship is destroyed. 03100 ; Execute the following steps: 03101 ; 03102 ; o Switch to Front view. 03103 ; 03104 ; o Flash the title phrase "SHIP DESTROYED BY ZYLON FIRE". 03105 ; 03106 ; o Add the mission bonus to the internal game score in subroutine 03107 ; GAMEOVER ($B10A). 03108 ; 03109 ; o Hide the Control Panel Display (bottom text window) in subroutine 03110 ; MODDLST ($ADF1). 03111 ; 03112 ; o Clear the PLAYFIELD in subroutine CLRPLAYFIELD ($AE0D). 03113 ; 03114 ; o Enable the STARSHIP EXPLOSION noise. 03115 ; 03116 ; (28) Handle the function keys START and SELECT. If SELECT has been pressed 03117 ; cycle through the next of the 4 mission levels. If either START or SELECT 03118 ; have been pressed, reset the idle counter, then jump to the corresponding 03119 ; game initialization subroutines INITSTART ($A15E) or INITSELECT ($A15A), 03120 ; respectively. 03121 ; 03122 ; (29) Update the Control Panel Display in subroutine UPDPANEL ($B804). 03123 ; 03124 ; (30) Handle hyperwarp in subroutine HYPERWARP ($A89B). 03125 ; 03126 ; (31) Update the text in the title line in subroutine UPDTITLE ($B216). 03127 ; 03128 ; (32) Move Zylon units, decrease lifetime of photon torpedoes, elapse game 03129 ; time, etc. in subroutine FLUSHGAMELOOP ($B4E4). This subroutine also 03130 ; triggers a game over if our starship's energy is zero. 03131 ; 03132 ; (33) Jump back to the start of the game loop for the next game loop iteration. 03133 03134 L.HEIGHTCNT = $6A ; Height counter during copying a PLAYER shape 03135 L.ZPOSOFF = $6E ; Offset to z-coordinate 03136 L.VELOCITYHI = $6B ; Velocity vector component (high byte) 03137 L.VECCOMPIND = $6A ; Position vector component index. Used values are: 03138 ; 0 -> z-component 03139 ; 1 -> x-component 03140 ; 2 -> y-component 03141 L.RANGEINDEX = $6A ; Range index for space object, computed from the 03142 ; distance to our starship. Used to pick the shape 03143 ; cell index of the PLAYERs shape data and shape 03144 ; height. Used values are: 0..15. 03145 L.FOURCOLORPIX = $6A ; 1-byte bit pattern for 4 pixels of same color 03146 L.COLORMASK = $6B ; Color/brightness to modify PLAYER color 03147 03148 ;*** (1) Synchronize game loop with execution of VBI *************************** 03149 GAMELOOP LDA ISVBISYNC ; Wait for execution of VBI 03150 BEQ GAMELOOP ; 03151 03152 LDA #0 ; VBI is executed, clear VBI sync flag 03153 STA ISVBISYNC ; 03154 03155 ;*** (2) Erase PLAYFIELD space objects (stars, explosion fragments) ************ 03156 LDA OLDMAXSPCOBJIND ; Skip if no space objects in use 03157 BEQ SKIP002 ; 03158 03159 LDX #NUMSPCOBJ.PL-1 ; Loop over all PLAYFIELD space objs (X index > 4) 03160 LOOP002 INX ; 03161 LDY PIXELROW,X ; Load pixel row number of PLAYFIELD space object 03162 03163 LDA PFMEMROWLO,Y ; Point MEMPTR to start of pixel's row... 03164 STA MEMPTR ; ...in PLAYFIELD memory 03165 LDA PFMEMROWHI,Y ; 03166 STA MEMPTR+1 ; 03167 03168 LDY PIXELBYTEOFF,X ; Get within-row-offset to byte with space obj pixel 03169 LDA PIXELSAVE,X ; Load saved byte 03170 STA (MEMPTR),Y ; Restore byte of PLAYFIELD memory 03171 03172 CPX OLDMAXSPCOBJIND ; 03173 BCC LOOP002 ; Next PLAYFIELD space object 03174 03175 LDA #0 ; Clear number of space objects 03176 STA OLDMAXSPCOBJIND ; 03177 03178 ;*** (3) Draw PLAYFIELD space objects (stars, explosion fragments) ************* 03179 SKIP002 LDA WARPSTATE ; Skip during hyperspace 03180 BMI SKIP003 ; 03181 03182 LDX MAXSPCOBJIND ; Update number of space objects 03183 STX OLDMAXSPCOBJIND ; 03184 03185 LOOP003 LDA PIXELROWNEW,X ; Loop over all PLAYFIELD space objs (X index > 4) 03186 STA PIXELROW,X ; Update pixel row number of PLAYFIELD space object 03187 03188 TAY ; 03189 LDA PFMEMROWLO,Y ; Point MEMPTR to start of pixel's row... 03190 STA MEMPTR ; ...in PLAYFIELD memory 03191 LDA PFMEMROWHI,Y ; 03192 STA MEMPTR+1 ; 03193 03194 LDA PIXELCOLUMN,X ; Convert pixel column number to within-row-offset 03195 LSR A ; ...of byte with space obj pixel (4 pixels = 1 byte) 03196 LSR A ; 03197 STA PIXELBYTEOFF,X ; Store within-row-offset 03198 03199 TAY ; 03200 LDA (MEMPTR),Y ; Load pixel's byte from PLAYFIELD memory 03201 STA PIXELSAVE,X ; Save it (for restoring it in next game loop) 03202 ORA PIXELBYTE,X ; Blend with pixel's color bit-pattern 03203 STA (MEMPTR),Y ; Store byte in PLAYFIELD memory 03204 03205 DEX ; 03206 CPX #NUMSPCOBJ.PL-1 ; 03207 BNE LOOP003 ; Next PLAYFIELD space object 03208 03209 ;*** (4) Clear PLAYFIELD center if idle counter is up (?) ********************** 03210 ; PLAYFIELD addresses of... 03211 PFMEM.C76R49 = PFMEM+49*40+76/4 ; ...pixel column number 76, row number 49 03212 PFMEM.C80R49 = PFMEM+49*40+80/4 ; ...pixel column number 80, row number 49 03213 PFMEM.C76R50 = PFMEM+50*40+76/4 ; ...pixel column number 76, row number 50 03214 PFMEM.C80R50 = PFMEM+50*40+80/4 ; ...pixel column number 80, row number 50 03215 03216 SKIP003 LDA IDLECNTHI ; Skip if idle counter not negative 03217 BPL SKIP004 ; 03218 03219 LDA #0 ; Clear pixels of 8 x 2 pixel rectangle... 03220 STA PFMEM.C76R50 ; ...@ column number 76, row number 49 (?) 03221 STA PFMEM.C80R50 ; 03222 STA PFMEM.C80R49 ; 03223 STA PFMEM.C76R49 ; 03224 03225 ;*** (5) Clear all PLAYER shapes *********************************************** 03226 SKIP004 LDA #0 ; Clear shape of PLAYER4 03227 LDY PL4ROW ; 03228 LDX PL4HEIGHT ; 03229 LOOP004 STA PL4DATA,Y ; 03230 INY ; 03231 DEX ; 03232 BPL LOOP004 ; 03233 03234 LDY PL3ROW ; Clear shape of PLAYER3 03235 LDX PL3HEIGHT ; 03236 LOOP005 STA PL3DATA,Y ; 03237 INY ; 03238 DEX ; 03239 BPL LOOP005 ; 03240 03241 LDY PL2ROW ; Clear shape of PLAYER2 03242 LDX PL2HEIGHT ; 03243 LOOP006 STA PL2DATA,Y ; 03244 INY ; 03245 DEX ; 03246 BPL LOOP006 ; 03247 03248 LDY PL1ROW ; Clear shape of PLAYER1 03249 LDX PL1HEIGHT ; 03250 LOOP007 STA PL1DATA,Y ; 03251 INY ; 03252 DEX ; 03253 BPL LOOP007 ; 03254 03255 LDY PL0ROW ; Clear shape of PLAYER0 03256 LDX PL0HEIGHT ; 03257 LOOP008 STA PL0DATA,Y ; 03258 INY ; 03259 DEX ; 03260 BPL LOOP008 ; 03261 03262 ;*** (6) Update PLAYER vertical positions and update PLAYER shapes ************* 03263 LDA PL4SHAPTYPE ; CARRY := PLAYER4 a PHOTON TORPEDO (shape type 0)? 03264 CMP #1 ; 03265 LDY PL4SHAPOFF ; Load PLAYER4 shape data offset 03266 03267 LDX PL4ROWNEW ; Update vertical position of PLAYER4 03268 STX PL4ROW ; 03269 03270 LDA PL4HEIGHTNEW ; Update PLAYER4 shape height 03271 STA L.HEIGHTCNT ; 03272 STA PL4HEIGHT ; 03273 03274 LOOP009 LDA PLSHAP1TAB,Y ; Load PLAYER4 shape byte from shape data table 03275 BCS SKIP005 ; Skip if PLAYER4 not PHOTON TORPEDO (shape type 0) 03276 AND RANDOM ; AND random bits to shape byte 03277 SKIP005 STA PL4DATA,X ; Store shape byte in PLAYER4 data area 03278 INY ; 03279 INX ; 03280 DEC L.HEIGHTCNT ; 03281 BPL LOOP009 ; Next row of PLAYER4 shape 03282 03283 LDA PL3SHAPTYPE ; Repeat above with PLAYER3 03284 CMP #1 ; 03285 LDY PL3SHAPOFF ; 03286 LDX PL3ROWNEW ; 03287 STX PL3ROW ; 03288 LDA PL3HEIGHTNEW ; 03289 STA L.HEIGHTCNT ; 03290 STA PL3HEIGHT ; 03291 LOOP010 LDA PLSHAP1TAB,Y ; 03292 BCS SKIP006 ; 03293 AND RANDOM ; 03294 SKIP006 STA PL3DATA,X ; 03295 INX ; 03296 INY ; 03297 DEC L.HEIGHTCNT ; 03298 BPL LOOP010 ; 03299 03300 LDA PL2SHAPTYPE ; Repeat above with PLAYER2 03301 CMP #1 ; 03302 LDY PL2SHAPOFF ; 03303 LDX PL2ROWNEW ; 03304 STX PL2ROW ; 03305 LDA PL2HEIGHTNEW ; 03306 STA L.HEIGHTCNT ; 03307 STA PL2HEIGHT ; 03308 LOOP011 LDA PLSHAP1TAB,Y ; 03309 BCS SKIP007 ; 03310 AND RANDOM ; 03311 SKIP007 STA PL2DATA,X ; 03312 INX ; 03313 INY ; 03314 DEC L.HEIGHTCNT ; 03315 BPL LOOP011 ; 03316 03317 LDY PL1SHAPOFF ; Repeat above with PLAYER1 (without torpedo part) 03318 LDX PL1ROWNEW ; 03319 STX PL1ROW ; 03320 LDA PL1HEIGHTNEW ; 03321 STA L.HEIGHTCNT ; 03322 STA PL1HEIGHT ; 03323 LOOP012 LDA PLSHAP2TAB,Y ; 03324 STA PL1DATA,X ; 03325 INX ; 03326 INY ; 03327 DEC L.HEIGHTCNT ; 03328 BPL LOOP012 ; 03329 03330 LDY PL0SHAPOFF ; Repeat above with PLAYER0 (without torpedo part) 03331 LDX PL0ROWNEW ; 03332 STX PL0ROW ; 03333 LDA PL0HEIGHTNEW ; 03334 STA L.HEIGHTCNT ; 03335 STA PL0HEIGHT ; 03336 LOOP013 LDA PLSHAP2TAB,Y ; 03337 STA PL0DATA,X ; 03338 INX ; 03339 INY ; 03340 DEC L.HEIGHTCNT ; 03341 BPL LOOP013 ; 03342 03343 ;*** (7) Update PLAYER horizontal positions ************************************ 03344 LDA PL0COLUMN ; Update horizontal position of PLAYER0 03345 STA HPOSP0 ; 03346 LDA PL1COLUMN ; Update horizontal position of PLAYER1 03347 STA HPOSP1 ; 03348 LDA PL2COLUMN ; Update horizontal position of PLAYER2 03349 STA HPOSP2 ; 03350 LDA PL3COLUMN ; Update horizontal position of PLAYER3 03351 STA HPOSP3 ; 03352 LDA PL4COLUMN ; Update horizontal position of PLAYER4 03353 STA HPOSM3 ; 03354 CLC ; 03355 ADC #2 ; 03356 STA HPOSM2 ; 03357 ADC #2 ; 03358 STA HPOSM1 ; 03359 ADC #2 ; 03360 STA HPOSM0 ; 03361 03362 ;*** (8) Rotate space objects horizontally and vertically ********************** 03363 BIT SHIPVIEW ; Skip if in Galactic Chart view 03364 BMI SKIP009 ; 03365 03366 ;*** Rotate horizontally ******************************************************* 03367 LDA JOYSTICKX ; Skip if joystick centered horizontally 03368 BEQ SKIP008 ; 03369 03370 STA JOYSTICKDELTA ; Save JOYSTICKX (used in subroutine ROTATE) 03371 LDY MAXSPCOBJIND ; Loop over all space objects in use 03372 LOOP014 STY L.ZPOSOFF ; Save offset to z-coordinate 03373 CLC ; 03374 03375 TYA ; 03376 TAX ; X := offset to z-coordinate 03377 ADC #NUMSPCOBJ.ALL ; 03378 TAY ; Y := offset to x-coordinate 03379 JSR ROTATE ; Calc new x-coordinate (horizontal rot @ y-axis) 03380 03381 TYA ; 03382 TAX ; X := offset to x-coordinate 03383 LDY L.ZPOSOFF ; Y := offset to z-coordinate 03384 JSR ROTATE ; Calc new z-coordinate (horizontal rot @ y-axis) 03385 DEY ; 03386 BPL LOOP014 ; Next space object 03387 03388 ;*** Rotate vertically ********************************************************* 03389 SKIP008 LDA JOYSTICKY ; Skip if joystick centered vertically 03390 BEQ SKIP009 ; 03391 03392 STA JOYSTICKDELTA ; Save JOYSTICKY (used in subroutine ROTATE) 03393 LDY MAXSPCOBJIND ; Loop over all space objects in use 03394 LOOP015 STY L.ZPOSOFF ; Save offset to z-coordinate 03395 CLC ; 03396 03397 TYA ; 03398 TAX ; X := offset to z-coordinate 03399 ADC #NUMSPCOBJ.ALL*2 ; 03400 TAY ; Y := offset to y-coordinate 03401 JSR ROTATE ; Calc new y-coordinate (vertical rot @ x-axis) 03402 03403 TYA ; 03404 TAX ; X := offset to y-coordinate 03405 LDY L.ZPOSOFF ; Y := offset to z-coordinate 03406 JSR ROTATE ; Calc new z-coordinate (vertical rot @ x-axis) 03407 DEY ; 03408 BPL LOOP015 ; Next space object 03409 03410 ;*** (9) Move all space objects along z-axis (toward our starship) ************* 03411 SKIP009 LDX MAXSPCOBJIND ; Loop over all space objects in use 03412 LOOP016 CPX #NUMSPCOBJ.PL ; Skip if PLAYFIELD space object (X index > 4) 03413 BCS SKIP010 ; 03414 03415 LDA PL0SHAPTYPE,X ; Skip if next PLAYER space obj is PHOTON TORPEDO (!) 03416 BEQ SKIP011 ; 03417 03418 SKIP010 SEC ; New z-coordinate := old z-coordinate - 03419 LDA ZPOSLO,X ; ...our starship's velocity 03420 SBC VELOCITYLO ; (signed 24-bit subtraction) 03421 STA ZPOSLO,X ; 03422 LDA ZPOSHI,X ; 03423 SBC VELOCITYHI ; 03424 STA ZPOSHI,X ; 03425 LDA ZPOSSIGN,X ; 03426 SBC #0 ; 03427 STA ZPOSSIGN,X ; 03428 03429 SKIP011 DEX ; 03430 BPL LOOP016 ; Next space object 03431 03432 ;*** (10) Add space object's velocity vector to space object's position vector * 03433 LDX MAXSPCOBJIND ; Loop over all space objects in use 03434 LOOP017 CPX #NUMSPCOBJ.NORM-1 ; Skip if space object is star (X index 5..16)... 03435 BNE SKIP012 ; ...because stars don't move by themselves 03436 LDX #4 ; 03437 03438 SKIP012 TXA ; 03439 LOOP018 TAY ; Loop over all 3 coordinates 03440 03441 LDA #0 ; Expand 8-bit velocity vector component to 16-bit: 03442 STA L.VELOCITYHI ; ...16-bit velocity (high byte) = L.VELOCITYHI := 0 03443 LDA ZVEL,Y ; ...16-bit velocity (low byte) = A := ZVEL,Y 03444 BPL SKIP013 ; Skip if 16-bit velocity >= 0 (positive) 03445 03446 EOR #$7F ; 16-bit velocity < 0 (negative)... 03447 CLC ; ...calculate two's-complement of 16-bit velocity 03448 ADC #1 ; 03449 BCS SKIP013 ; 03450 DEC L.VELOCITYHI ; 03451 03452 SKIP013 CLC ; New coordinate := old coordinate + 16-bit velocity 03453 ADC ZPOSLO,Y ; (signed 24-bit addition) 03454 STA ZPOSLO,Y ; 03455 LDA ZPOSHI,Y ; 03456 ADC L.VELOCITYHI ; 03457 STA ZPOSHI,Y ; 03458 LDA ZPOSSIGN,Y ; 03459 ADC L.VELOCITYHI ; 03460 STA ZPOSSIGN,Y ; 03461 03462 TYA ; 03463 CLC ; 03464 ADC #NUMSPCOBJ.ALL ; 03465 CMP #144 ; (!) 03466 BCC LOOP018 ; Next coordinate 03467 03468 DEX ; 03469 BPL LOOP017 ; Next space object 03470 03471 ;*** (11) Correct over/underflow of PLAYER space objects' position vector ****** 03472 LDY #NUMSPCOBJ.PL-1 ; 03473 LOOP019 TYA ; Loop over all PLAYER space objects (X index < 5) 03474 TAX ; 03475 03476 LDA #2 ; Loop over all 3 coordinates 03477 STA L.VECCOMPIND ; 03478 03479 LOOP020 LDA ZPOSSIGN,X ; Load sign of coordinate 03480 CMP #2 ; 03481 BCC SKIP015 ; Skip if sign = 0 (negative) or 1 (positive) 03482 03483 ASL A ; SUMMARY: Space object out-of-bounds correction 03484 LDA #0 ; If new coordinate > +65535 subtract 256 03485 STA ZPOSSIGN,X ; ...until new coordinate <= +65535 03486 BCS SKIP014 ; If new coordinate < -65536 add 256 03487 INC ZPOSSIGN,X ; ...until new coordinate >= -65536 03488 EOR #$FF ; 03489 SKIP014 STA ZPOSHI,X ; 03490 03491 SKIP015 TXA ; 03492 CLC ; 03493 ADC #NUMSPCOBJ.ALL ; 03494 TAX ; 03495 DEC L.VECCOMPIND ; 03496 BPL LOOP020 ; Next coordinate 03497 03498 DEY ; 03499 BPL LOOP019 ; Next space object 03500 03501 ;*** (12) Calc perspective projection of space objects ************************* 03502 LDA SHIPVIEW ; Skip if in Long-Range Scan or Galactic Chart view 03503 CMP #$02 ; 03504 BCS SKIP019 ; 03505 03506 LDX MAXSPCOBJIND ; Loop over all space objects in use 03507 LOOP021 LDA #255 ; Prep magic offscreen pixel number value 03508 LDY ZPOSSIGN,X ; Compare sign of z-coordinate with view mode 03509 CPY SHIPVIEW ; 03510 BEQ SKIP018 ; Equal? Space object is offscreen -> New space obj! 03511 03512 LDA YPOSSIGN,X ; Prepare projection division... 03513 BNE SKIP016 ; DIVIDEND (16-bit value) := ABS(y-coordinate) 03514 SEC ; (used in subroutine PROJECTION) 03515 LDA #0 ; 03516 SBC YPOSLO,X ; 03517 STA DIVIDEND ; 03518 LDA #0 ; 03519 SBC YPOSHI,X ; 03520 STA DIVIDEND+1 ; 03521 JMP JUMP001 ; 03522 SKIP016 LDA YPOSLO,X ; 03523 STA DIVIDEND ; 03524 LDA YPOSHI,X ; 03525 STA DIVIDEND+1 ; 03526 03527 JUMP001 JSR PROJECTION ; Calc pixel row number rel. to screen center 03528 JSR SCREENROW ; Calc pixel row number rel. to top-left of screen 03529 03530 LDA XPOSSIGN,X ; Prepare projection division... 03531 BNE SKIP017 ; DIVIDEND (16-bit value) := ABS(x-coordinate) 03532 SEC ; (used in subroutine PROJECTION) 03533 LDA #0 ; 03534 SBC XPOSLO,X ; 03535 STA DIVIDEND ; 03536 LDA #0 ; 03537 SBC XPOSHI,X ; 03538 STA DIVIDEND+1 ; 03539 JMP JUMP002 ; 03540 SKIP017 LDA XPOSLO,X ; 03541 STA DIVIDEND ; 03542 LDA XPOSHI,X ; 03543 STA DIVIDEND+1 ; 03544 03545 JUMP002 JSR PROJECTION ; Calc pixel column number rel. to screen center 03546 SKIP018 JSR SCREENCOLUMN ; Calc pixel column number rel. to top-left of screen 03547 DEX ; 03548 BPL LOOP021 ; Next space object 03549 03550 ;*** (13) Handle hyperwarp marker selection in Galactic Chart view ************* 03551 SKIP019 JSR SELECTWARP ; Handle hyperwarp marker in Galactic Chart view 03552 03553 ;*** (14) Compute and draw Long-Range Scan view star field on z-x plane ******** 03554 BIT SHIPVIEW ; Skip if not in Long-Range Scan view 03555 BVC SKIP022 ; 03556 03557 LDX #$31 ; Draw our starship's shape 03558 JSR DRAWLINES ; 03559 03560 BIT GCSTATLRS ; Skip if Long-Range Scan destroyed 03561 BVS SKIP022 ; 03562 03563 LDX MAXSPCOBJIND ; Loop over all space objects in use 03564 LOOP022 LDA ZPOSHI,X ; Load z-coordinate (high byte) 03565 LDY ZPOSSIGN,X ; Load sign of z-coordinate 03566 BNE SKIP020 ; 03567 EOR #$FF ; A := ABS(z-coordinate (high byte)) 03568 SKIP020 TAY ; 03569 LDA MAPTO80,Y ; Calc pixel row number rel. to screen center 03570 JSR SCREENROW ; Calc pixel row number rel. to top-left of screen 03571 03572 LDA XPOSHI,X ; Load x-coordinate (high byte) 03573 LDY XPOSSIGN,X ; Load sign of x-coordinate 03574 BNE SKIP021 ; 03575 EOR #$FF ; A := ABS(x-coordinate (high byte)) 03576 SKIP021 TAY ; 03577 LDA MAPTO80,Y ; Calc pixel column number rel. to screen center 03578 JSR SCREENCOLUMN ; Calc pixel column number rel. to top-left of screen 03579 03580 DEX ; 03581 BPL LOOP022 ; Next space object 03582 03583 ;*** (15) Update PLAYER shapes, heights, and colors **************************** 03584 03585 ; DESCRIPTION 03586 ; 03587 ; In a loop over all PLAYERs, the following steps are executed: 03588 ; 03589 ; o Clear the PLAYER shape offset and height. 03590 ; 03591 ; o If in Galactic Chart view or in Long-Range Scan view, preload a random 03592 ; color and a magic z-coordinate (distance value) for PLAYER3..4 03593 ; (representing hyperwarp markers in Galactic Chart view and blips in the 03594 ; Long-Range Scan view, like, for example, Zylon ships, meteors - or even 03595 ; the Hyperwarp Target Marker during hyperwarp!). 03596 ; 03597 ; o If in Front or Aft view, execute the following steps: 03598 ; 03599 ; o Skip dead PLAYERs. 03600 ; 03601 ; o Preload the distance value for the remaining live PLAYERs. 03602 ; 03603 ; o If we are in a starbase sector, combine PLAYER0..2 into a three-part 03604 ; starbase shape. Compute the pixel column numbers and pixel row 03605 ; numbers of PLAYER0..1 such that they are arranged left (PLAYER0) and 03606 ; right (PLAYER1) of PLAYER2. In addition, preload a color mask, a 03607 ; counter actually, that will make the starbase pulsate in brightness. 03608 ; 03609 ; BUG (at $A512): The code at $A512 that skips the combination operation for 03610 ; PLAYER2..4 jumps for PLAYER3..4 to SKIP025 at $A52A instead of SKIP026 at 03611 ; $A52E. Thus it stores a color mask which does not only make the starbase 03612 ; PLAYER0..2 pulsate in brightness but also PLAYER3..4 in a starbase sector, 03613 ; for example the transfer vessel, photon torpedoes, etc. - or even the 03614 ; Hyperwarp Target Marker when hyperwarping out of such a sector! Suggested 03615 ; fix: None, code hard to untwist. 03616 ; 03617 ; o After storing the color mask, check if the PLAYER shape is still above the 03618 ; bottom edge of the PLAYFIELD. 03619 ; 03620 ; BUG (at $A534): The test checks the vertical position of the top edge of 03621 ; the PLAYER against the bottom edge of the PLAYFIELD above the Console 03622 ; Panel Display (= Player/Missile pixel row number 204). This is not 03623 ; completely accurate as the Console Panel Display starts at PM pixel row 03624 ; number 208. For example, if you carefully navigate a starbase to the 03625 ; bottom edge of the PLAYFIELD, at a certain point the center of the 03626 ; starbase shape bleeds over the bottom edge of the PLAYFIELD (while 03627 ; sometimes even losing its left and right wings!). Suggested fix: None, as 03628 ; a more elaborate test may consume too many bytes of the cartridge ROM 03629 ; memory in order to fix a rarely noticed visual glitch. 03630 ; 03631 ; o Convert the preloaded distance value of a PLAYER space object closer than 03632 ; $2000 (8192) into a range index of 0..15. PLAYER space objects more 03633 ; distant than $2000 (8192) are skipped and not displayed. 03634 ; 03635 ; Later, this range index will pick not only the correct brightness for the 03636 ; PLAYER (the closer the space object the brighter its PLAYER) but also the 03637 ; correct PLAYER shape cell and height (the closer the space object the 03638 ; larger the PLAYER shape and height). 03639 ; 03640 ; o Update the PLAYER's shape offset and height. On the way to the shape 03641 ; offset and height add the PLAYER's shape type to the range index and 03642 ; divide it by 2 to arrive at the shape offset index and height index (the 03643 ; same value). Use this index to pick the correct shape data and shape 03644 ; heights from a set of shape cells and their corresponding heights, stored 03645 ; in tables PLSHAPOFFTAB ($BE2F) and PLSHAPHEIGHTTAB ($BE7F), respectively. 03646 ; 03647 ; Remember that magic distance value used in the Galactic Chart and 03648 ; Long-Range Scan view? Its value of $F2 is actually part of a negative 03649 ; z-coordinate which is inverted to $0D00, leading to a range index of 13, 03650 ; which, after the division by 2, picks shape cell 6. Shape cell 6 (the 03651 ; seventh shape cell) of all space objects (except the starbase) is the 03652 ; Long-Range Scan blip's dot (see PLSHAPOFFTAB ($BE2F) and PLSHAPHEIGHTTAB 03653 ; ($BE7F)). 03654 ; 03655 ; o Update the PLAYER's color/brightness by picking the appropriate values 03656 ; with the range index from lookup tables PLSHAPCOLORTAB ($BFD1) and 03657 ; PLSHAPBRITTAB ($BFDB). Apply some special effects to the color/brightness 03658 ; of certain PLAYERs, such as using random colors for Zylon basestars, or 03659 ; using the precomputed pulsating brightness value for a starbase. 03660 03661 SKIP022 LDX #NUMSPCOBJ.PL ; Loop over all PLAYER space objects (X index < 5) 03662 LOOP023 DEX ; 03663 BPL SKIP023 ; Jump into loop body below 03664 JMP JUMP003 ; Loop is finished, skip loop body 03665 03666 ;*** Clear PLAYER shape offsets and heights ************************************ 03667 SKIP023 LDA #0 ; 03668 STA PL0SHAPOFF,X ; Clear PLAYER shape offset 03669 STA PL0HEIGHTNEW,X ; Clear new PLAYER shape height 03670 03671 ;*** Preload stuff for hyperwarp markers and Long-Range Scan blips ************* 03672 BIT SHIPVIEW ; Skip if not in Galactic Chart view 03673 BPL SKIP024 ; 03674 03675 CPX #3 ; Next PLAYER space object if PLAYER0..2 03676 BCC LOOP023 ; 03677 03678 LOOP024 LDA RANDOM ; Prep random color mask for warp markers/LRS blips 03679 LDY #$F2 ; Prep magic z-coordinate for warp markers/LRS blips 03680 BMI SKIP026 ; Unconditional jump 03681 03682 SKIP024 CMP PL0LIFE,X ; Next PLAYER space object if this PLAYER not alive 03683 BEQ LOOP023 ; 03684 03685 BVS LOOP024 ; Skip back if in Long-Range Scan view 03686 03687 ;*** Preload stuff for other views ********************************************* 03688 03689 LDY PL0ZPOSHI,X ; Prep z-coordinate (high byte) 03690 03691 ;*** Combine PLAYER0..2 to starbase shape ************************************** 03692 BIT ISSTARBASESECT ; Skip if no starbase in this sector 03693 BVC SKIP026 ; 03694 03695 CPX #2 ; Skip if PLAYER2..4 03696 BCS SKIP025 ; (!) 03697 03698 LDA PL2COLUMN ; Calc new PM pixel column number for PLAYER0..1: 03699 CLC ; Load PLAYER2 (starbase center) pixel column number 03700 ADC PLSTARBAOFFTAB,X ; ...add PLAYER left/right offset (starbase wings) 03701 STA PL0COLUMN,X ; Store new PM pixel column number of starbase wing 03702 03703 LDA PL2ROWNEW ; Calc new PM pixel row number for PLAYER0..1: 03704 CLC ; Add vertical offset (= 4 PM pixels) to PLAYER2's 03705 ADC #4 ; 03706 STA PL0ROWNEW,X ; Store new PM pixel row number of starbase wing 03707 03708 LDY PL2ZPOSHI ; Prep Y with z-coordinate (high byte) of starbase 03709 03710 SKIP025 LDA COUNT256 ; Prep color mask with B3..0 of counter 03711 AND #$0F ; ...(= brightness bits cause pulsating brightness) 03712 03713 SKIP026 STA L.COLORMASK ; Store color mask 03714 03715 ;*** Check if PLAYER is below PLAYFIELD bottom edge **************************** 03716 TYA ; A := z-coordinate (high byte) 03717 03718 LDY PL0ROWNEW,X ; Next PLAYER space object if top of PM shape... 03719 CPY #204 ; ...is below PLAYFIELD bottom... (!) 03720 BCS LOOP023 ; ...(PM pixel row number >= 204) 03721 03722 ;*** Convert PLAYER z-coordinate to range index in 0..15 *********************** 03723 LDY SHIPVIEW ; Skip if in Front view... 03724 BEQ SKIP027 ; 03725 EOR #$FF ; ...else invert z-coordinate (high byte) 03726 03727 SKIP027 CMP #$20 ; Next PLAYER space object if this one too far away 03728 BCS LOOP023 ; ...(z-coordinate >= $20** (8192) ) 03729 03730 CMP #16 ; Load z-coordinate (high byte) and... 03731 BCC SKIP028 ; 03732 LDA #15 ; 03733 SKIP028 STA L.RANGEINDEX ; ...trim to range index in 0..15 03734 03735 ;*** Update PLAYER shape offset and height ************************************* 03736 ORA PL0SHAPTYPE,X ; Calc offset to shape table (shape type+range index) 03737 LSR A ; 03738 TAY ; Divide by 2 to get offset in 0..7 into shape data 03739 LDA PLSHAPOFFTAB,Y ; Update new PLAYER shape offset 03740 STA PL0SHAPOFF,X ; 03741 LDA PLSHAPHEIGHTTAB,Y ; Update new PLAYER shape height 03742 STA PL0HEIGHTNEW,X ; 03743 03744 ;*** Calculate PLAYER color/brightness value *********************************** 03745 TYA ; Pick color (B7..4) using PLAYER shape type 03746 LSR A ; 03747 LSR A ; 03748 LSR A ; 03749 TAY ; 03750 LDA PLSHAPCOLORTAB,Y ; 03751 CPY #8 ; Pick random color if ZYLON BASESTAR (shape type 8) 03752 BNE SKIP029 ; 03753 EOR RANDOM ; 03754 SKIP029 LDY L.RANGEINDEX ; 03755 EOR PLSHAPBRITTAB,Y ; Pick brightness (B3..0) using range index and merge 03756 03757 EOR L.COLORMASK ; Modify color/brightness of PLAYER 03758 03759 LDY PLCOLOROFFTAB,X ; Get PLAYER color offset 03760 STA PL0COLOR,Y ; Store color in PLAYER color register 03761 JMP LOOP023 ; Next PLAYER space object 03762 03763 ;*** (16) Flash red alert ****************************************************** 03764 JUMP003 LDY #$AF ; Prep PLAYFIELD2 color {BRIGHT BLUE-GREEN} 03765 LDX SHIELDSCOLOR ; Prep Shields color {DARK GREEN} or {BLACK} 03766 03767 LDA REDALERTLIFE ; Skip if red alert is over 03768 BEQ SKIP030 ; 03769 03770 DEC REDALERTLIFE ; Decrement lifetime of red alert 03771 LDY #$4F ; Prep PLAYFIELD2 color {BRIGHT ORANGE} 03772 03773 AND #$20 ; Switch colors every 64 game loops 03774 BEQ SKIP030 ; 03775 03776 LDX #$42 ; Load BACKGROUND color {DARK ORANGE} 03777 LDY #$60 ; Load PLAYFIELD2 color {DARK PURPLE BLUE} 03778 03779 SKIP030 STY PF2COLOR ; Store PLAYFIELD2 color 03780 STX BGRCOLOR ; Store BACKGROUND color 03781 03782 ;*** (17) Update color of PLAYFIELD space objects (stars, explosion fragments) * 03783 LDX MAXSPCOBJIND ; Loop over all PLAYFIELD space objs (X index > 4) 03784 LOOP025 LDA ZPOSHI,X ; Prep z-coordinate (high byte) 03785 LDY SHIPVIEW ; 03786 CPY #1 ; Skip if not in Aft view 03787 BNE SKIP032 ; 03788 03789 CMP #$F0 ; Skip if star not too far (z < $F0** (-4096) ) 03790 BCS SKIP031 ; 03791 JSR INITPOSVEC ; Re-init position vector 03792 SKIP031 EOR #$FF ; Invert z-coordinate (high byte) 03793 03794 SKIP032 CMP #16 ; Convert z-coordinate (high byte) 03795 BCC SKIP033 ; ...into range index 0..15 03796 LDA #15 ; 03797 03798 SKIP033 ASL A ; Compute index to pixel color table: 03799 AND #$1C ; Use bits B3..1 from range index as B4..2. 03800 ORA COUNT8 ; Combine with random bits B3..0 from counter 03801 03802 TAY ; 03803 LDA FOURCOLORPIXEL,Y ; Load 1-byte bit pattern for 4 pixels of same color 03804 STA L.FOURCOLORPIX ; ...and temporarily save it 03805 03806 LDA PIXELCOLUMN,X ; Load pixel mask to mask 1 pixel out of 4 pixels: 03807 AND #$03 ; Use B1..0 from pixel column number... 03808 TAY ; 03809 LDA PIXELMASKTAB,Y ; ...to pick mask to filter pixel in byte 03810 AND L.FOURCOLORPIX ; ...AND with 1-byte bit pattern for 4 pixels 03811 STA PIXELBYTE,X ; ...store byte (used in repaint step of game loop) 03812 03813 DEX ; 03814 CPX #NUMSPCOBJ.PL ; 03815 BCS LOOP025 ; Next PLAYFIELD space object 03816 03817 ;*** (18) Skip input handling if in demo mode ********************************** 03818 BIT ISDEMOMODE ; If in demo mode skip to function keys 03819 BVC SKIP034 ; 03820 JMP SKIP040 ; 03821 03822 ;*** (19) Handle keyboard input ************************************************ 03823 SKIP034 JSR KEYBOARD ; Handle keyboard input 03824 03825 ;*** (20) Handle joystick input ************************************************ 03826 LDA PORTA ; Load Joystick 0 directions 03827 TAY ; ...Bits B0..3 -> Right, left, down, up. 03828 AND #$03 ; ...Bit = 0/1 -> Stick pressed/not pressed 03829 TAX ; JOYSTICKY := +1 -> Up 03830 LDA STICKINCTAB,X ; JOYSTICKY := 0 -> Centered 03831 STA JOYSTICKY ; JOYSTICKY := -1 -> Down 03832 TYA ; 03833 LSR A ; 03834 LSR A ; 03835 AND #$03 ; 03836 TAX ; JOYSTICKX := -1 -> Left 03837 LDA STICKINCTAB,X ; JOYSTICKX := 0 -> Centered 03838 STA JOYSTICKX ; JOYSTICKX := +1 -> Right 03839 03840 ;*** (21) Check if our starship's photon torpedoes have hit a target *********** 03841 JSR COLLISION ; Check if our starship's photon torpedoes have hit 03842 03843 ;*** (22) Handle joystick trigger ********************************************** 03844 JSR TRIGGER ; Handle joystick trigger 03845 03846 ;*** (23) Handle Attack Computer and Tracking Computer ************************* 03847 BIT GCSTATCOM ; Skip if Attack Computer destroyed 03848 BVS SKIP038 ; 03849 03850 LDA DRAINATTCOMP ; Skip if Attack Computer off 03851 BEQ SKIP038 ; 03852 03853 LDA SHIPVIEW ; Skip if not in Front view 03854 BNE SKIP035 ; 03855 03856 JSR UPDATTCOMP ; Update Attack Computer Display 03857 03858 SKIP035 LDX TRACKDIGIT ; Load index of tracked space object 03859 03860 LDA ZYLONATTACKER ; Skip if ship of current Zylon torpedo is tracked 03861 BMI SKIP036 ; 03862 TAX ; ...else override Tracking Computer... 03863 ORA #$80 ; 03864 STA ZYLONATTACKER ; ...and mark Zylon torpedo's ship as being tracked 03865 03866 SKIP036 LDA PL0LIFE,X ; Skip if tracked space object still alive 03867 BNE SKIP037 ; 03868 03869 TXA ; 03870 EOR #$01 ; 03871 TAX ; 03872 LDA PL0LIFE,X ; Check if other Zylon ship still alive 03873 BNE SKIP037 ; ...yes -> Keep new index 03874 LDX TRACKDIGIT ; ...no -> Revert to old index of tracked space obj 03875 03876 SKIP037 STX TRACKDIGIT ; Store index of tracked space object 03877 03878 LDA ISTRACKCOMPON ; Skip if tracking computer is turned off 03879 BEQ SKIP038 ; 03880 03881 LDA SHIPVIEW ; Skip if in Long-Range Scan or Galactic Chart view 03882 CMP #2 ; 03883 BCS SKIP038 ; 03884 03885 EOR #$01 ; 03886 CMP ZPOSSIGN,X ; Skip if tracked space object in our starship's... 03887 BEQ SKIP038 ; ...view direction 03888 03889 TAX ; 03890 LDA TRACKKEYSTAB,X ; Pick 'F' or 'A' (Front or Aft view) keyboard code 03891 STA KEYCODE ; ...and store it (= emulate pressing 'F' or 'A' key) 03892 03893 ;*** (24) Handle docking to starbase ******************************************* 03894 SKIP038 JSR DOCKING ; Handle docking to starbase 03895 03896 ;*** (25) Handle maneuvering *************************************************** 03897 JSR MANEUVER ; Handle maneuvering photon torpedoes and Zylon ships 03898 03899 ;*** (26) Was our starship hit by Zylon photon torpedo? ************************ 03900 LDA ISSTARBASESECT ; Skip hit check if in starbase sector 03901 BNE SKIP040 ; 03902 03903 LDA PL2LIFE ; Skip hit check if PLAYER2 (Zylon photon torpedo)... 03904 BEQ SKIP040 ; ...not alive 03905 03906 LDY PL2ZPOSHI ; Our starship was not hit if Zylon photon torpedo's 03907 INY ; ...z-coordinate is not in -256..255 or... 03908 CPY #$02 ; 03909 BCS SKIP040 ; 03910 03911 LDY PL2XPOSHI ; ...x-coordinate is not in -256..255 or... 03912 INY ; 03913 CPY #$02 ; 03914 BCS SKIP040 ; 03915 03916 LDY PL2YPOSHI ; ...y-coordinate is not in -256..255 . 03917 INY ; 03918 CPY #$02 ; 03919 BCS SKIP040 ; 03920 03921 ;*** (27) Our starship was hit! ************************************************ 03922 JSR DAMAGE ; Damage or destroy some subsystem 03923 03924 LDY #2 ; Trigger explosion at PLAYER2 (Zylon photon torpedo) 03925 JSR INITEXPL ; 03926 03927 LDX #$7F ; Prep HITBADNESS := SHIELDS HIT 03928 LDA SHIELDSCOLOR ; Skip if Shields are up (SHIELDSCOLOR not {BLACK}). 03929 BNE SKIP039 ; 03930 03931 LDX #$0A ; Set Front view 03932 JSR SETVIEW ; 03933 03934 LDY #$23 ; Set title phrase "SHIP DESTROYED BY ZYLON FIRE" 03935 LDX #8 ; Set mission bonus offset 03936 JSR GAMEOVER ; Game over 03937 03938 LDX #$5F ; Hide Control Panel Display (bottom text window) 03939 LDY #$80 ; 03940 LDA #$08 ; 03941 JSR MODDLST ; 03942 03943 JSR CLRPLAYFIELD ; Clear PLAYFIELD 03944 03945 LDX #64 ; Enable STARSHIP EXPLOSION noise (see SOUND) 03946 STX NOISEHITLIFE ; 03947 03948 LDX #$FF ; Prep HITBADNESS := STARSHIP DESTROYED 03949 03950 SKIP039 STX HITBADNESS ; Store HITBADNESS 03951 LDA #0 ; Zylon photon torpedo lifetime := 0 game loops 03952 STA PL2LIFE ; 03953 LDA #2 ; Init Zylon photon torpedo trigger 03954 STA TORPEDODELAY ; 03955 03956 LDX #1 ; ENERGY := ENERGY - 100 after photon torpedo hit 03957 JSR DECENERGY ; 03958 03959 LDX #$0A ; Play noise sound pattern SHIELD EXPLOSION 03960 JSR NOISE ; 03961 03962 ;*** (28) Handle function keys ************************************************* 03963 SKIP040 LDY FKEYCODE ; Prep old function key code 03964 LDA CONSOL ; POKEY: Load function key code 03965 03966 EOR #$FF ; Store inverted and masked function key code 03967 AND #$03 ; 03968 STA FKEYCODE ; 03969 BEQ SKIP042 ; Skip if no function key pressed 03970 03971 DEY ; 03972 BPL SKIP042 ; Skip if SELECT or START still pressed 03973 STA IDLECNTHI ; Reset idle counter to a value in 1..3 (?) 03974 CMP #2 ; Skip if SELECT function key pressed 03975 BCS SKIP041 ; 03976 03977 LDA #0 ; START function key pressed: 03978 TAY ; Prep empty title phrase offset 03979 JMP INITSTART ; Reenter game loop via INITSTART 03980 03981 SKIP041 INC MISSIONLEVEL ; SELECT function key pressed: 03982 LDA MISSIONLEVEL ; Cycle through next of 4 mission levels 03983 AND #$03 ; 03984 STA MISSIONLEVEL ; 03985 JMP INITSELECT ; Reenter game loop via INITSELECT 03986 03987 ;*** (29) Update Control Panel Display ***************************************** 03988 SKIP042 JSR UPDPANEL ; Update Control Panel Display 03989 03990 ;*** (30) Handle hyperwarp ***************************************************** 03991 JSR HYPERWARP ; Handle hyperwarp 03992 03993 ;*** (31) Update title line **************************************************** 03994 JSR UPDTITLE ; Update title line 03995 03996 ;*** (32) Flush game loop iteration ******************************************** 03997 JSR FLUSHGAMELOOP ; Move Zylon units, age torpedoes, elapse time 03998 03999 ;*** (33) Jump back to begin of game loop ************************************** 04000 JMP GAMELOOP ; Next game loop iteration 04001 04002 ;******************************************************************************* 04003 ;* * 04004 ;* VBIHNDLR * 04005 ;* * 04006 ;* Vertical Blank Interrupt Handler * 04007 ;* * 04008 ;******************************************************************************* 04009 04010 ; DESCRIPTION 04011 ; 04012 ; This subroutine is executed during the Vertical Blank Interrupt (VBI) when the 04013 ; TV beam has reached the bottom-right corner of the TV screen and is switched 04014 ; off to return to the top-left position. This situation is called the "vertical 04015 ; blank phase". 04016 ; 04017 ; This subroutine signals its execution with flag ISVBISYNC ($67) (which is 04018 ; examined by GAMELOOP ($A1F3) to synchronize the execution of the game loop 04019 ; with the start of this subroutine). Then it switches the character set to the 04020 ; ROM character set, sets the BACKGROUND color depending on the severity of a 04021 ; Zylon photon torpedo hit and view mode, copies PLAYER and PLAYFIELD color 04022 ; registers to their corresponding hardware registers, clears the Player/Missile 04023 ; collision registers, calls the sound effects code in subroutine SOUND ($B2AB), 04024 ; and increments the idle counter. If the idle counter reaches the value $8000 04025 ; the title phrase is cleared and the game is switched to demo mode. 04026 ; 04027 ; BUG (at $A6EC): Because the values of SHIPVIEW ($D0) are $00, $01, $40, and 04028 ; $80, a value of 3 overspecifies the comparison. Suggested fix: Replace CMP #3 04029 ; with CMP #2, which may make the code clearer. 04030 ; 04031 ; BUG (at $A712): Demo mode is entered via a JMP instruction, which proceeds 04032 ; directly into GAMELOOP ($A1F3). Thus code execution never returns to pop the 04033 ; registers pushed on the stack during entry of this subroutine. Suggested fix: 04034 ; None. 04035 04036 VBIHNDLR LDA #$FF ; Signals entering Vertical Blank Interrupt 04037 STA ISVBISYNC ; 04038 04039 LDA #>ROMCHARSET ; Switch character set to ROM character set 04040 STA CHBASE ; 04041 04042 LDX BGRCOLOR ; Preload BACKGROUND color 04043 LDA RANDOM ; Preload random number 04044 BIT HITBADNESS ; Check if our starship was hit 04045 BVC SKIP044 ; If HITBADNESS has a value of... 04046 BMI SKIP043 ; $00 -> NO HIT (BGR color := unchanged) 04047 AND #$72 ; $7F -> SHIELDS HIT (BGR color := %01rr00r0) 04048 ORA #$40 ; $FF -> STARSHIP DESTROYED (BGR color := %01rr00r0) 04049 SKIP043 TAX ; 04050 SKIP044 LDA SHIPVIEW ; Skip if in Front or Aft view 04051 CMP #3 ; (!) 04052 BCC SKIP045 ; 04053 LDX #$A0 ; Preload BACKGROUND color {DARK BLUE GREEN}... 04054 SKIP045 STX BGRCOLOR ; Store BACKGROUND color 04055 04056 LDX #8 ; Copy all color registers to hardware registers 04057 LOOP026 LDA PL0COLOR,X ; 04058 STA COLPM0,X ; 04059 DEX ; 04060 BPL LOOP026 ; 04061 04062 STA HITCLR ; Clear Player/Missile collision registers 04063 04064 JSR SOUND ; Call sound effects 04065 04066 INC IDLECNTLO ; Increment 16-bit idle counter 04067 BNE SKIP046 ; 04068 LDA IDLECNTHI ; 04069 BMI SKIP046 ; 04070 INC IDLECNTHI ; 04071 BPL SKIP046 ; Skip if idle counter value of $8000 not reached yet 04072 04073 LDY #$00 ; Prep empty title phrase offset 04074 JMP INITDEMO ; Enter demo mode (!) 04075 04076 SKIP046 JMP JUMP004 ; Return via DLI return code 04077 04078 ;******************************************************************************* 04079 ;* * 04080 ;* DLSTHNDLR * 04081 ;* * 04082 ;* Display List Interrupt Handler * 04083 ;* * 04084 ;******************************************************************************* 04085 04086 ; DESCRIPTION 04087 ; 04088 ; This subroutine is executed during the Display List Interrupt (DLI). It 04089 ; switches the character set to the ROM character set if the DLI occurs at ANTIC 04090 ; line 96 (video line 192), otherwise to the custom character set. The former 04091 ; happens in the Galactic Chart view where the ROM character set is used in the 04092 ; Galactic Chart Panel Display. 04093 ; 04094 ; Then, the DLI PLAYFIELD colors are copied to the corresponding hardware 04095 ; registers and the values of the collision hardware registers for PLAYER3..4 04096 ; (our starship's photon torpedoes) are copied to the corresponding zero-page 04097 ; variables PL3HIT ($82) and PL4HIT ($83). 04098 04099 DLSTHNDLR PHA ; Push A 04100 TXA ; 04101 PHA ; Push X 04102 TYA ; 04103 PHA ; Push Y 04104 04105 LDA #>ROMCHARSET ; Switch to ROM charset if ANTIC line counter = 96 04106 LDY VCOUNT ; ...else switch to custom character set 04107 CPY #96 ; 04108 BEQ SKIP047 ; 04109 LDA #>CHARSET ; 04110 SKIP047 STA CHBASE ; 04111 04112 LDX #4 ; Loop over all PLAYFIELD colors 04113 STA WSYNC ; Stop and wait for horizontal TV beam sync 04114 LOOP027 LDA PF0COLORDLI,X ; Copy DLI PLAYFIELD colors to hardware registers 04115 STA COLPF0,X ; 04116 DEX ; 04117 BPL LOOP027 ; Next PLAYFIELD color 04118 04119 LDA M0PL ; Merge MISSILE-to-PLAYER collision registers... 04120 ORA M1PL ; 04121 ORA M2PL ; 04122 ORA M3PL ; 04123 STA PL4HIT ; ...and store them in PL4HIT 04124 LDA P3PL ; Copy PLAYER3-to-PLAYER coll. register to PL3HIT 04125 STA PL3HIT ; 04126 04127 JUMP004 PLA ; Pop Y 04128 TAY ; 04129 PLA ; Pop X 04130 TAX ; 04131 PLA ; Pop A 04132 RTI ; Return from interrupt 04133 04134 ;******************************************************************************* 04135 ;* * 04136 ;* IRQHNDLR * 04137 ;* * 04138 ;* Interrupt Request (IRQ) Handler * 04139 ;* * 04140 ;******************************************************************************* 04141 04142 ; DESCRIPTION 04143 ; 04144 ; This subroutine is executed during immediate interrupt requests (IRQs), such 04145 ; as after pressing a key on the keyboard. It clears and disables all IRQs 04146 ; except the interrupt raised by a pressed key. If a key has been pressed, its 04147 ; hardware code is collected and the bits of the SHIFT and CONTROL keys are 04148 ; added. The resulting keyboard code is stored in KEYCODE ($CA). 04149 04150 IRQHNDLR PHA ; Push A 04151 LDA #0 ; POKEY: Disable all IRQs 04152 STA IRQEN ; 04153 LDA #$40 ; POKEY: Enable keyboard interrupt (IRQ) 04154 STA IRQEN ; 04155 LDA KBCODE ; POKEY: Load keyboard key code 04156 ORA #$C0 ; Combine with SHIFT and CONTROL key bits 04157 STA KEYCODE ; Store keyboard code 04158 PLA ; Pop A 04159 RTI ; Return from interrupt 04160 04161 ;******************************************************************************* 04162 ;* * 04163 ;* DRAWLINES * 04164 ;* * 04165 ;* Draw horizontal and vertical lines * 04166 ;* * 04167 ;******************************************************************************* 04168 04169 ; DESCRIPTION 04170 ; 04171 ; Draws the Attack Computer Display (in Front view), cross hairs (in Front and 04172 ; Aft view), and our starship's shape (in Long-Range Scan view) on the PLAYFIELD 04173 ; (if the Attack Computer is not destroyed) by being passed an offset to table 04174 ; DRAWLINESTAB ($BAF9). This table consists of a list of 3-byte elements, 04175 ; terminated by an end marker byte ($FE). Each such element defines a single 04176 ; horizontal or vertical line, and is passed via memory addresses DIRLEN ($A4), 04177 ; PENROW ($A5), and PENCOLUMN ($A6) to subroutine DRAWLINE ($A782), which 04178 ; executes the actual drawing. See subroutine DRAWLINE ($A782) and table 04179 ; DRAWLINESTAB ($BAF9) for a description of the 3-byte elements. 04180 ; 04181 ; With every call of this subroutine the blip cycle counter is initialized to 04182 ; the start of the DELAY phase (see subroutine UPDATTCOMP ($A7BF)). 04183 ; 04184 ; NOTE: The entry to this subroutine is in mid-code, not at the beginning. 04185 ; 04186 ; INPUT 04187 ; 04188 ; X = Offset into DRAWLINESTAB ($BAF9). Used values are: 04189 ; $00 -> Draw Attack Computer Display and cross hairs (Front view) 04190 ; $2A -> Draw Aft view cross hairs (Aft view) 04191 ; $31 -> Draw our starship's shape (Long-Range Scan view) 04192 04193 LOOP028 STA DIRLEN,Y ; Store byte of 3-byte element 04194 INX ; 04195 DEY ; 04196 BPL SKIP048 ; Next byte of 3-byte element until 3 bytes copied 04197 JSR DRAWLINE ; Draw line on PLAYFIELD 04198 04199 DRAWLINES LDA #5 ; Init blip cycle to DELAY phase... 04200 STA BLIPCYCLECNT ; ...delays drawing each row 04201 04202 BIT GCSTATCOM ; Return if Attack Computer destroyed 04203 BVS SKIP049 ; 04204 04205 LDY #2 ; 04206 SKIP048 LDA DRAWLINESTAB,X ; Load byte of 3-byte element 04207 CMP #$FE ; Loop until end marker byte ($FE) encountered 04208 BNE LOOP028 ; 04209 SKIP049 RTS ; Return 04210 04211 ;******************************************************************************* 04212 ;* * 04213 ;* DRAWLINE * 04214 ;* * 04215 ;* Draw a single horizontal or vertical line * 04216 ;* * 04217 ;******************************************************************************* 04218 04219 ; DESCRIPTION 04220 ; 04221 ; Draws a single horizontal or vertical transparent line. 04222 ; 04223 ; There are two entries to this subroutine: 04224 ; 04225 ; (1) DRAWLINE ($A782) is entered from subroutine DRAWLINES ($A76F) to draw a 04226 ; line in COLOR1. 04227 ; 04228 ; (2) DRAWLINE2 ($A784) is entered from subroutine UPDATTCOMP ($A7BF) to draw 04229 ; the blip in COLOR2 in the Attack Computer Display. 04230 ; 04231 ; The position, direction, and length of the line is defined by three bytes 04232 ; passed in memory addresses DIRLEN ($A4), PENROW ($A5), and PENCOLUMN ($A6). 04233 ; 04234 ; A drawing operation draws one transparent line. It uses both the color 04235 ; register number of the overwritten (old) and the overwriting (new) pixel to 04236 ; decide on the new pixel color register number. This results in a transparent 04237 ; drawing effect. See the table below for all resulting combinations of color 04238 ; registers. 04239 ; 04240 ; +-----------+---------------+ 04241 ; | | Old Color | 04242 ; | | Register | 04243 ; | New Color +---------------+ 04244 ; | Register | 0 | 1 | 2 | 3 | 04245 ; +-----------+---+---+---+---+ 04246 ; | 0 | 0 | 1 | 2 | 3 | 04247 ; +-----------+---+---+---+---+ 04248 ; | 1 | 1 | 1 | 3 | 3 | 04249 ; +-----------+---+---+---+---+ 04250 ; | 2 | 2 | 3 | 2 | 3 | 04251 ; +-----------+---+---+---+---+ 04252 ; | 3 | 3 | 3 | 3 | 3 | 04253 ; +-----------+---+---+---+---+ 04254 ; 04255 ; For example, COLOR1 overwritten by COLOR2 yields COLOR3. If you look closely 04256 ; at the blip (in COLOR2) on the Attack Computer Display (in COLOR1) the lines 04257 ; of the Attack Computer Display shine through (in COLOR3) where they overlap. 04258 ; 04259 ; INPUT 04260 ; 04261 ; DIRLEN ($A4) = B7 = 0 -> Draw line to the right 04262 ; B7 = 1 -> Draw line downward 04263 ; B6..0 -> Length of line in pixels 04264 ; PENROW ($A5) = Start pixel row number of line 04265 ; PENCOLUMN ($A6) = Start pixel column number of line 04266 04267 L.PIXELBYTEOFF = $6A ; Within-row-offset to byte with pixel in PLAYFIELD 04268 L.BITPAT = $6B ; 1-byte bit pattern for 4 pixels of same color 04269 L.DIRSAV = $6E ; Saves DIRLEN 04270 04271 DRAWLINE LDA #$55 ; Copy 1-byte bit pattern for 4 pixels of COLOR1 04272 DRAWLINE2 STA L.BITPAT ; 04273 LDA DIRLEN ; Copy direction (and length) of line 04274 STA L.DIRSAV ; 04275 AND #$7F ; Strip direction bit 04276 STA DIRLEN ; Store length of line 04277 04278 LOOP029 LDY PENROW ; Loop over length of line to be drawn 04279 LDA PFMEMROWLO,Y ; Point MEMPTR to start of pen's pixel row... 04280 STA MEMPTR ; ...in PLAYFIELD memory 04281 LDA PFMEMROWHI,Y ; 04282 STA MEMPTR+1 ; 04283 04284 LDA PENCOLUMN ; Calc and store pen's byte-within-row offset 04285 LSR A ; 04286 LSR A ; 04287 STA L.PIXELBYTEOFF ; 04288 04289 LDA PENCOLUMN ; Calc pixel-within-byte index 04290 AND #$03 ; 04291 TAY ; 04292 04293 LDA PIXELMASKTAB,Y ; Pick mask to filter pixel in byte 04294 AND L.BITPAT ; ...AND with bit pattern for 4 pixels of same color 04295 LDY L.PIXELBYTEOFF ; 04296 ORA (MEMPTR),Y ; Blend byte with new pixel and PLAYFIELD byte 04297 STA (MEMPTR),Y ; ...and store it back in PLAYFIELD memory 04298 04299 BIT L.DIRSAV ; Check direction bit B7 04300 BPL SKIP050 ; 04301 INC PENROW ; If B7 = 1 -> Increment pen's pixel row number 04302 BNE SKIP051 ; 04303 SKIP050 INC PENCOLUMN ; If B7 = 0 -> Increment pen's pixel column number 04304 04305 SKIP051 DEC DIRLEN ; 04306 BNE LOOP029 ; Next pixel of line 04307 RTS ; Return 04308 04309 ;******************************************************************************* 04310 ;* * 04311 ;* UPDATTCOMP * 04312 ;* * 04313 ;* Update Attack Computer Display * 04314 ;* * 04315 ;******************************************************************************* 04316 04317 ; DESCRIPTION 04318 ; 04319 ; Draws the blip of the tracked space object and the lock-on markers into the 04320 ; Attack Computer Display. The actual drawing follows a cycle of 11 game loop 04321 ; iterations (numbered by this subroutine as "blip cycles" 0..10), which can be 04322 ; divided into three phases: 04323 ; 04324 ; (1) Blip cycle 0..4: Draw blip shape row-by-row 04325 ; 04326 ; Draw the blip's shape into the Attack Computer Display, one row each blip 04327 ; cycle. After 5 blip cycles the blip shape is complete and completely 04328 ; visible because between blip cycles, that is, game loop iterations, the 04329 ; PLAYFIELD is not erased (only the PLAYFIELD space objects are). Drawing 04330 ; is executed by branching to entry DRAWLINE2 ($A784) of subroutine 04331 ; DRAWLINE ($A782). The blip shape is retrieved from table BLIPSHAPTAB 04332 ; ($BF6E). 04333 ; 04334 ; (2) Blip cycle 5..9: Delay 04335 ; 04336 ; Delay the execution of blip cycle 10. 04337 ; 04338 ; (3) Blip cycle 10: Update Attack Computer Display 04339 ; 04340 ; After verifying that the tracked space object is alive, calculate the 04341 ; blip's relative top-left pixel column and row number. The resulting 04342 ; values are in -11..11 and -6..4, relative to the blip's top-left 04343 ; reference position at pixel column number 131 and pixel row number 77, 04344 ; respectively. 04345 ; 04346 ; Filter the Attack Computer Display area: Only pixels of COLOR1 within the 04347 ; inner frame area (a 28 pixel wide x 15 pixel high rectangle with its 04348 ; top-left corner at pixel column number 120 and pixel row number 71) pass 04349 ; the filter operation. This effectively erases the blip. 04350 ; 04351 ; If the blip is within -2..+2 pixels off its horizontal reference position 04352 ; (pixel column numbers 129..132) then the tracked space object is in x 04353 ; lock-on. Draw the x lock-on marker. 04354 ; 04355 ; If the tracked space object is in x lock-on and the blip is within -2..+1 04356 ; pixels off its vertical reference position (pixel column numbers 75..78) 04357 ; then the tracked space object is in x and y lock-on. Draw also the y 04358 ; lock-on marker. 04359 ; 04360 ; If the tracked space object is in x and y lock-on and the tracked space 04361 ; object's z-coordinate < +3072 (+$0C**) then the tracked space object 04362 ; is in x, y and z lock-on. Draw also the z lock-on marker. 04363 ; 04364 ; If the tracked space object is in x, y, and z lock-on (and thus in 04365 ; optimal firing range) set the ISINLOCKON ($A3) flag. 04366 ; 04367 ; The following sketches show the Attack Computer Display area overlaid 04368 ; with the Attack Computer Display frame: 04369 ; 04370 ; 119 119 04371 ; 70 ############################## 70 ############################## 04372 ; # ....#.... # # # # 04373 ; # ....#.... # # # # 04374 ; # ....#.... # # # # 04375 ; # ....#.... # # # # 04376 ; # ############### # #......###############.......# 04377 ; #XXXX # ......... # XXXX# #......#.............#.......# 04378 ; # # ..$...... # # #......#....$........#.......# 04379 ; ######## ......... ######### ########.............######### 04380 ; # # ......... # # #......#.............#.......# 04381 ; # # ......... # # #YYYY..#.............#...YYYY# 04382 ; # ############### # #......###############.......# 04383 ; # ....#.... # #.............#..............# 04384 ; # ....#.... # # # # 04385 ; # ....#.... # # # # 04386 ; # ....#.... # # # # 04387 ; ############################## ############################## 04388 ; 04389 ; X = x lock-on marker Y = y lock-on marker 04390 ; . = x lock-on blip zone . = y lock-on blip zone 04391 ; $ = Blip's top-left reference $ = Blip's top-left reference 04392 ; position position 04393 ; 04394 ; 119 04395 ; 70 ############################## 04396 ; # # # 04397 ; # # # 04398 ; # # # 04399 ; # # # 04400 ; # ############### # 04401 ; # # # # 04402 ; # # $ # # 04403 ; ######## ######### 04404 ; # # # # 04405 ; # # # # 04406 ; # ############### # 04407 ; # # # 04408 ; # # # 04409 ; # ZZ # ZZ # 04410 ; # ZZ # ZZ # 04411 ; ############################## 04412 ; 04413 ; Z = z lock-on marker 04414 ; $ = Blip's top-left reference 04415 ; position 04416 04417 L.SHIFTSHAP = $6C ; Saves shifted byte of blip shape bit pattern 04418 04419 UPDATTCOMP LDX TRACKDIGIT ; Load index of tracked space object 04420 LDY BLIPCYCLECNT ; Load blip cycle counter 04421 CPY #5 ; 04422 BCS SKIP054 ; Skip drawing blip if blip cycle > 5 04423 04424 ;*** Blip cycle 0..4: Draw blip shape one row each cycle *********************** 04425 LDA BLIPCOLUMN ; Init pen's pixel column number... 04426 STA PENCOLUMN ; ...with top position of blip shape 04427 LDA BLIPSHAPTAB,Y ; Load bit pattern of one row of blip shape 04428 LOOP030 ASL A ; Shift bit pattern one position to the left 04429 STA L.SHIFTSHAP ; Temporarily save shifted shape byte 04430 BCC SKIP052 ; Skip if shifted-out bit = 0 04431 04432 LDA #$81 ; Store "draw a line of 1 pixel length downward" 04433 STA DIRLEN ; ...for call to DRAWLINE2 04434 04435 LDA BLIPROW ; Init pen's pixel row number... 04436 STA PENROW ; ...with leftmost position of blip shape 04437 LDA #$AA ; Load 1-byte bit pattern for 4 pixels of COLOR2 04438 JSR DRAWLINE2 ; Draw pixel on PLAYFIELD 04439 04440 SKIP052 INC PENCOLUMN ; Move pen one pixel to the right 04441 LDA L.SHIFTSHAP ; Reload shifted shape byte 04442 BNE LOOP030 ; Next horizontal pixel of blip shape 04443 04444 INC BLIPROW ; Move pen one pixel downward 04445 SKIP053 INC BLIPCYCLECNT ; Increment blip cycle counter 04446 RTS ; Return 04447 04448 ;*** Blip cycle 5..9: Delay **************************************************** 04449 SKIP054 CPY #10 ; Return if blip cycle < 10 04450 BCC SKIP053 ; 04451 04452 ;*** Blip cycle 10: Calculate new blip pixel row and column numbers ************ 04453 LDA PL0LIFE,X ; Skip if tracked object not alive 04454 BEQ SKIP059 ; 04455 04456 LDA XPOSHI,X ; Map x-coordinate of tracked space obj to -11..11: 04457 LDY XPOSSIGN,X ; Skip if tracked object on left screen half (x >= 0) 04458 BEQ SKIP055 ; 04459 04460 CMP #12 ; Skip if x of tracked obj < +$0C** (< 3327) 04461 BCC SKIP056 ; 04462 LDA #11 ; Prep relative pixel column number of 11, skip 04463 BPL SKIP056 ; 04464 04465 SKIP055 CMP #-11 ; Skip if x of tracked obj >= -($0B**) (>=-2816) 04466 BCS SKIP056 ; 04467 LDA #-11 ; Prep relative pixel column number of -11 04468 04469 SKIP056 CLC ; Add 131 (= blip's top-left reference pixel column) 04470 ADC #131 ; 04471 STA BLIPCOLUMN ; BLIPCOLUMN := 131 + -11..11 04472 04473 LDA YPOSHI,X ; Map y-coordinate of tracked space obj to -6..4: 04474 EOR #$FF ; Mirror y-coordinate on y-axis (displacement of +1) 04475 LDY YPOSSIGN,X ; Skip if tracked obj on lower screen half (y < 0) 04476 BNE SKIP057 ; 04477 04478 CMP #5 ; Skip if mirrored y of tracked obj < +$05** 04479 BCC SKIP058 ; 04480 LDA #4 ; Prep relative pixel row number of 4, skip 04481 BPL SKIP058 ; 04482 04483 SKIP057 CMP #-6 ; Skip if mirrored y of tracked obj >= -($06**) 04484 BCS SKIP058 ; 04485 LDA #-6 ; Prep relative pixel row number of -6 04486 04487 SKIP058 CLC ; Add 77 (= blip's top-left ref. pixel row number) 04488 ADC #77 ; 04489 STA BLIPROW ; BLIPROW := 77 + -6..4 04490 04491 LDA #0 ; Reset blip cycle 04492 STA BLIPCYCLECNT ; 04493 04494 ;*** Filter Attack Computer Display frame area ********************************* 04495 ; PLAYFIELD address of top-left of Attack Computer 04496 PFMEM.C120R71 = PFMEM+71*40+120/4 ; Display's inner frame @ pixel column 120, row 71 04497 04498 SKIP059 LDA #PFMEM.C120R71 ; ...in PLAYFIELD memory 04501 STA MEMPTR+1 ; 04502 04503 LDX #14 ; Traverse a 28 x 15 pixel rect of PLAYFIELD memory 04504 LOOP031 LDY #6 ; 04505 LOOP032 LDA (MEMPTR),Y ; Load byte (4 pixels) from PLAYFIELD memory 04506 AND #$55 ; Filter COLOR1 pixels 04507 STA (MEMPTR),Y ; Store byte (4 pixels) back to PLAYFIELD memory 04508 DEY ; 04509 BPL LOOP032 ; Next 4 pixels in x-direction 04510 04511 CLC ; Add 40 to MEMPTR 04512 LDA MEMPTR ; (40 bytes = 160 pixels = 1 PLAYFIELD row of pixels) 04513 ADC #40 ; 04514 STA MEMPTR ; 04515 BCC SKIP060 ; 04516 INC MEMPTR+1 ; 04517 04518 SKIP060 DEX ; 04519 BPL LOOP031 ; Next row of pixels in y-direction 04520 04521 ;*** Prepare lock-on marker checks ********************************************* 04522 LDX TRACKDIGIT ; Preload index of tracked space obj to check z-range 04523 INY ; Y := 0, preloaded value of ISINLOCKON 04524 04525 ;*** Draw lock-on markers ****************************************************** 04526 ; PLAYFIELD addresses of 04527 PFMEM.C120R76 = PFMEM+76*40+120/4 ; ...x lock-on marker @ pixel column 120, row 76 04528 PFMEM.C144R76 = PFMEM+76*40+144/4 ; ...x lock-on marker @ pixel column 144, row 76 04529 PFMEM.C120R80 = PFMEM+80*40+120/4 ; ...y lock-on marker @ pixel column 120, row 80 04530 PFMEM.C144R80 = PFMEM+80*40+144/4 ; ...y lock-on marker @ pixel column 144, row 80 04531 PFMEM.C128R84 = PFMEM+84*40+128/4 ; ...z lock-on marker @ pixel column 128, row 84 04532 PFMEM.C128R85 = PFMEM+85*40+128/4 ; ...z lock-on marker @ pixel column 128, row 85 04533 PFMEM.C136R84 = PFMEM+84*40+136/4 ; ...z lock-on marker @ pixel column 136, row 84 04534 PFMEM.C136R85 = PFMEM+85*40+136/4 ; ...z lock-on marker @ pixel column 136, row 85 04535 04536 LDA LOCKONLIFE ; If lock-on lifetime expired redraw lock-on markers 04537 BEQ SKIP061 ; 04538 04539 DEC LOCKONLIFE ; else decrem. lock-on lifetime, skip drawing markers 04540 BNE SKIP062 ; 04541 04542 SKIP061 LDA BLIPCOLUMN ; Skip x, y, and z lock-on marker if blip's... 04543 CMP #129 ; ...top-left pixel column number not in 129..132 04544 BCC SKIP062 ; 04545 CMP #133 ; 04546 BCS SKIP062 ; 04547 04548 LDA #$AA ; Draw x lock-on marker (4 horiz. pixels of COLOR2) 04549 STA PFMEM.C120R76 ; ...at pixel column 120, row 76 04550 STA PFMEM.C144R76 ; ...at pixel column 144, row 76 04551 04552 LDA BLIPROW ; Skip y and z lock-on marker if blip's... 04553 CMP #75 ; ...top-left pixel row number not in 75...78 04554 BCC SKIP062 ; 04555 CMP #79 ; 04556 BCS SKIP062 ; 04557 04558 LDA #$AA ; Draw y lock-on marker (4 horiz. pixels of COLOR2) 04559 STA PFMEM.C120R80 ; ...at pixel column 120, row 80 04560 STA PFMEM.C144R80 ; ...at pixel column 144, row 80 04561 04562 LDA ZPOSHI,X ; Skip z lock-on marker if z >= +$0C** (>= 3072) 04563 CMP #12 ; 04564 BCS SKIP062 ; 04565 04566 LDY #$A0 ; Draw z lock-on marker (2 horiz. pixels of COLOR2) 04567 STY PFMEM.C128R84 ; ...at pixel column 128, row 84 (prep lock-on flag) 04568 STY PFMEM.C128R85 ; ...at pixel column 128, row 85 04569 STY PFMEM.C136R84 ; ...at pixel column 136, row 84 04570 STY PFMEM.C136R85 ; ...at pixel column 136, row 85 04571 04572 SKIP062 STY ISINLOCKON ; Store lock-on flag (> 0 -> Tracked obj locked on) 04573 RTS ; Return 04574 04575 ;******************************************************************************* 04576 ;* * 04577 ;* HYPERWARP * 04578 ;* * 04579 ;* Handle hyperwarp * 04580 ;* * 04581 ;******************************************************************************* 04582 04583 ; DESCRIPTION 04584 ; 04585 ; Handles the hyperwarp sequence, which transports our starship from one sector 04586 ; to another. It can be divided into four phases: 04587 ; 04588 ; (1) ACCELERATION PHASE 04589 ; 04590 ; The ACCELERATION PHASE is entered after the hyperwarp sequence has been 04591 ; engaged in subroutine KEYBOARD ($AFFE) by pressing the 'H' key. 04592 ; 04593 ; The Hyperwarp Target Marker appears and our starship begins to 04594 ; accelerate. When our starship's velocity reaches 128 (the VELOCITY 04595 ; readout of the Control Panel Display displays "50"), the STAR TRAIL phase 04596 ; is entered. 04597 ; 04598 ; The Hyperwarp Target Marker is represented by a space object some fixed 04599 ; distance away in front of our starship as PLAYER3. It has a lifetime of 04600 ; 144 game loop iterations and is tracked. Thus, tracking handling in 04601 ; subroutine UPDATTCOMP ($A7BF) provides drawing the x and y lock-on 04602 ; markers in the Attack Computer Display when the Hyperwarp Target Marker 04603 ; is centered. 04604 ; 04605 ; A temporary arrival location on the Galactic Chart was saved when the 04606 ; hyperwarp was engaged in subroutine KEYBOARD ($AFFE). During the 04607 ; ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE) this location is 04608 ; constantly updated depending on how much the Hyperwarp Target Marker 04609 ; veers off its center position. 04610 ; 04611 ; The actual arrival hyperwarp marker row and column numbers on the 04612 ; Galactic Chart are the sum of the temporary arrival hyperwarp marker row 04613 ; and column numbers stored when engaging the hyperwarp in subroutine 04614 ; KEYBOARD ($AFFE) and the number of Player/Missile (PM) pixels which the 04615 ; Hyperwarp Target Marker is off-center vertically and horizontally, 04616 ; respectively, at the end of the STAR TRAIL PHASE. 04617 ; 04618 ; NOTE: The used vertical center value of 119 PM pixels is the PM pixel row 04619 ; number of the top edge of the centered Hyperwarp Target Marker (from top 04620 ; to bottom: 8 PM pixels to the start of Display List + 16 PM pixels blank 04621 ; lines + 100 PM pixels to the vertical PLAYFIELD center - 5 PM pixels 04622 ; relative offset of the Hyperwarp Target Marker's shape center to the 04623 ; shape's top edge = 119 PM pixels). Recall also that PLAYERs at 04624 ; single-line resolution have PM pixels that are half as high as they are 04625 ; wide. 04626 ; 04627 ; NOTE: The used horizontal center value of 125 PM pixels is the PM pixel 04628 ; row number of the left edge of the centered Hyperwarp Target Marker (from 04629 ; left to right: 127 PM pixels to the PLAYFIELD center - 3 PM pixels 04630 ; relative offset of the Hyperwarp Target Marker's shape center to the 04631 ; shape's left edge = 125 PM pixels). 04632 ; 04633 ; If during the ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE) 04634 ; you switch the Front view to another view, the Hyperwarp Target Marker 04635 ; changes to a random position which results in arriving at a random 04636 ; destination sector. 04637 ; 04638 ; During the ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE) in 04639 ; all but NOVICE missions, the Hyperwarp Target Marker veers off with 04640 ; random velocity in x and y direction, which is changed during 6% of game 04641 ; loop iterations. Table VEERMASKTAB ($BED7) limits the maximum veer-off 04642 ; velocity depending on the mission level: 04643 ; 04644 ; +-----------+-----------------------------+ 04645 ; | Mission | Veer-Off Velocity | 04646 ; +-----------+-----------------------------+ 04647 ; | NOVICE | 0 | 04648 ; | PILOT | -63..-16, +16..+63 | 04649 ; | WARRIOR | -95..-16, +16..+95 | 04650 ; | COMMANDER | -127..-16, +16..+127 | 04651 ; +-----------+-----------------------------+ 04652 ; 04653 ; (2) STAR TRAIL PHASE 04654 ; 04655 ; When our starship's velocity reaches a velocity of 128 (the 04656 ; VELOCITY readout of the Control Panel Display displays "50"), in addition 04657 ; to all effects of the ACCELERATION PHASE, multiple star trails begin to 04658 ; appear while our starship continues to accelerate. Each star trail is 04659 ; initialized in subroutine INITTRAIL ($A9B4). 04660 ; 04661 ; (3) HYPERSPACE PHASE 04662 ; 04663 ; When our starship's velocity reaches a velocity of 254 (the 04664 ; VELOCITY readout of the Control Panel Display displays "99") our starship 04665 ; enters the HYPERSPACE PHASE (the VELOCITY readout of the Control Panel 04666 ; Display displays the infinity symbol). 04667 ; 04668 ; During the first pass of the HYPERSPACE PHASE the hyperwarp state is set 04669 ; to HYPERSPACE. This makes the stars and the Hyperwarp Target Marker 04670 ; disappear in GAMELOOP ($A1F3). Then, the beeper sound pattern HYPERWARP 04671 ; TRANSIT is played in subroutine BEEP ($B3A6), the hyperwarp distance and 04672 ; required hyperwarp energy is calculated in subroutine CALCWARP ($B1A7), 04673 ; and the title line is preloaded with "HYPERSPACE". Code execution returns 04674 ; via calling subroutine CLEANUPWARP ($A98D) where game variables are 04675 ; already initialized to their post-hyperwarp values. 04676 ; 04677 ; During subsequent passes of the HYPERSPACE PHASE, the calculated 04678 ; hyperwarp energy is decremented in chunks of 10 energy units. Code 04679 ; execution returns via calling subroutine DECENERGY ($B86F), which 04680 ; decrements our starship's energy. After the calculated hyperwarp energy 04681 ; is spent the DECELERATION PHASE is entered. 04682 ; 04683 ; (4) DECELERATION PHASE 04684 ; 04685 ; The title line flashes "HYPERWARP COMPLETE", the star field reappears and 04686 ; our starship decelerates to a stop. The Engines and the hyperwarp are 04687 ; disengaged and stopped in subroutine ENDWARP ($A987), the arrival 04688 ; coordinates on the Galactic Chart are initialized, as well as the 04689 ; vicinity mask. 04690 ; 04691 ; The vicinity mask limits the position vector components (coordinates) of 04692 ; space objects in the arrival sector relative to our starship. The 04693 ; vicinity mask is picked from table VICINITYMASKTAB ($BFB3) by an index 04694 ; calculated by the arrival y-coordinate modulo 8: The more you have placed 04695 ; the arrival hyperwarp marker in the vertical center of a sector on the 04696 ; Galactic Chart, the closer space objects in this sector will be to our 04697 ; starship. For example, if you placed the arrival hyperwarp marker exactly 04698 ; in the vertical middle of the sector the index will be 3, thus the space 04699 ; objects inside the arrival sector will be in the vicinity of <= 4095 04700 ; of our starship. The following table lists the possible coordinates 04701 ; depending on the calculated index: 04702 ; 04703 ; +-------+-----------------------+ 04704 ; | Index | ABS(Coordinate) | 04705 ; +-------+-----------------------+ 04706 ; | 0 | <= 65535 ($FF**) | 04707 ; | 1 | <= 65535 ($FF**) | 04708 ; | 2 | <= 16383 ($3F**) | 04709 ; | 3 | <= 4095 ($0F**) | 04710 ; | 4 | <= 16383 ($3F**) | 04711 ; | 5 | <= 32767 ($7F**) | 04712 ; | 6 | <= 65535 ($FF**) | 04713 ; | 7 | <= 65535 ($FF**) | 04714 ; +-------+-----------------------+ 04715 ; 04716 ; If there is a starbase in the arrival sector, its x and y coordinates are 04717 ; initialized to random values within the interval defined by the vicinity 04718 ; mask by using subroutine RNDINVXY ($B7BE). Its z-coordinate is forced to 04719 ; a value >= +$71** (+28928) . Its velocity vector components are set 04720 ; to 0 . 04721 ; 04722 ; If there are Zylon ships in the arrival sector then a red alert is 04723 ; initialized by setting the red alert lifetime to 255 game loop 04724 ; iterations, playing the beeper sound pattern RED ALERT in subroutine BEEP 04725 ; ($B3A6) and setting the title phrase to "RED ALERT". 04726 04727 HYPERWARP LDY WARPSTATE ; Return if hyperwarp not engaged 04728 BEQ SKIP066 ; 04729 04730 LDA VELOCITYLO ; If velocity >= 254 skip to HYPERSPACE PHASE 04731 CMP #254 ; 04732 BCS SKIP067 ; 04733 04734 CMP #128 ; If velocity < 128 skip to ACCELERATION PHASE 04735 BCC SKIP063 ; 04736 04737 ;*** STAR TRAIL PHASE ********************************************************** 04738 JSR INITTRAIL ; Init star trail 04739 04740 ;*** ACCELERATION PHASE ******************************************************** 04741 SKIP063 LDA #3 ; Track Hyperwarp Target Marker (PLAYER3) 04742 STA TRACKDIGIT ; 04743 04744 LDA #SHAP.HYPERWARP ; PLAYER3 is HYPERWARP TARGET MARKER (shape type 9) 04745 STA PL3SHAPTYPE ; 04746 STA PL3LIFE ; PLAYER3 lifetime := 144 game loops 04747 04748 LDA #$1F ; PLAYER3 z-coordinate := $1F** (7936..8191) 04749 STA PL3ZPOSHI ; 04750 04751 SEC ; New arrival hyperwarp marker row number is... 04752 LDA PL3ROWNEW ; WARPARRVROW := WARPTEMPROW + PL3ROWNEW... 04753 SBC #119 ; ... - 119 PM pixels (top edge of centered... 04754 CLC ; ...Hyperwarp Target Marker) 04755 ADC WARPTEMPROW ; 04756 AND #$7F ; Limit WARPARRVROW to 0..127 04757 STA WARPARRVROW ; 04758 04759 SEC ; New arrival hyperwarp marker column number is... 04760 LDA PL3COLUMN ; WARPARRVCOLUMN := WARPTEMPCOLUMN + PL3COLUMN... 04761 SBC #125 ; ... - 125 PM pixels (left edge of centered... 04762 CLC ; ...Hyperwarp Target Marker) 04763 ADC WARPTEMPCOLUMN ; 04764 AND #$7F ; Limit WARPARRVCOLUMN to 0..127 04765 STA WARPARRVCOLUMN ; 04766 04767 LDA MISSIONLEVEL ; Skip if NOVICE mission 04768 BEQ SKIP065 ; 04769 04770 LDA RANDOM ; Prep random number 04771 LDY SHIPVIEW ; Skip if in Front view 04772 BEQ SKIP064 ; 04773 04774 STA PL3COLUMN ; Randomize PM pixel row and column number... 04775 STA PL3ROWNEW ; ...of Hyperwarp Target Marker 04776 04777 SKIP064 CMP #16 ; Return in 94% (240:256) of game loops 04778 BCS SKIP066 ; 04779 04780 ;*** Veer off Hyperwarp Target Marker and return ******************************* 04781 SKIP065 LDA RANDOM ; Prep random x-velocity of Hyperwarp Target Marker 04782 ORA #$10 ; Velocity value >= 16 04783 AND VEERMASK ; Limit velocity value by mission level 04784 STA PL3XVEL ; PLAYER3 x-velocity := velocity value 04785 04786 LDA RANDOM ; Prep random y-velocity of Hyperwarp Target Marker 04787 ORA #$10 ; Velocity value >= 16 04788 AND VEERMASK ; Limit velocity value by mission level 04789 STA PL3YVEL ; PLAYER3 y-velocity := velocity value 04790 SKIP066 RTS ; Return 04791 04792 ;*** HYPERSPACE PHASE ********************************************************** 04793 SKIP067 TYA ; Skip if already in HYPERSPACE PHASE 04794 BMI SKIP068 ; 04795 04796 ;*** HYPERSPACE PHASE (First pass) ********************************************* 04797 LDA #$FF ; Set hyperwarp state to HYPERSPACE PHASE 04798 STA WARPSTATE ; 04799 04800 LDX #$00 ; Play beeper sound pattern HYPERWARP TRANSIT 04801 JSR BEEP ; 04802 04803 JSR CALCWARP ; Calc hyperwarp energy 04804 04805 LDY #$1B ; Prep title phrase "HYPERSPACE" 04806 JMP CLEANUPWARP ; Return via CLEANUPWARP 04807 04808 ;*** HYPERSPACE PHASE (Second and later passes) ******************************** 04809 SKIP068 DEC WARPENERGY ; Decrement energy in chunks of 10 energy units 04810 BEQ SKIP069 ; Skip to DECELERATION PHASE if hyperwarp energy zero 04811 04812 LDX #2 ; ENERGY := ENERGY - 10 and return 04813 JMP DECENERGY ; 04814 04815 ;*** DECELERATION PHASE ******************************************************** 04816 SKIP069 LDY #$19 ; Prep title phrase "HYPERWARP COMPLETE" 04817 JSR ENDWARP ; Stop our starship 04818 04819 LDA WARPARRVCOLUMN ; Make the arrival hyperwarp marker column number... 04820 STA WARPDEPRCOLUMN ; ...the departure hyperwarp marker column number 04821 LDA WARPARRVROW ; Make the arrival hyperwarp marker row number... 04822 STA WARPDEPRROW ; ...the departure hyperwarp marker row number 04823 04824 LSR A ; B3..1 of arrival hyperwarp marker row number... 04825 AND #$07 ; ...pick vicinity mask 04826 TAX ; 04827 LDA VICINITYMASKTAB,X ; 04828 STA VICINITYMASK ; Store vicinity mask (limits space obj coordinates) 04829 04830 LDY ARRVSECTOR ; Make the arrival sector the current sector 04831 STY CURRSECTOR ; 04832 04833 ;*** Init starbase in arrival sector ******************************************* 04834 LDA #0 ; Clear starbase-in-sector flag 04835 STA ISSTARBASESECT ; 04836 04837 LDX GCMEMMAP,Y ; Skip if no starbase in arrival sector 04838 BPL SKIP070 ; 04839 04840 LDA #$FF ; Set starbase-in-sector flag 04841 STA ISSTARBASESECT ; 04842 04843 ;*** Set position vector and velocity vector of starbase *********************** 04844 LDY #0 ; 04845 LOOP033 LDA #0 ; Loop over all coordinates of starbase 04846 STA PL2ZVEL,Y ; Starbase velocity vector component := 0 04847 LDA #1 ; 04848 STA PL2ZPOSSIGN,Y ; Starbase coordinate sign := + (positive) 04849 LDA RANDOM ; Prep random number... 04850 AND VICINITYMASK ; ...limit number range by vicinity mask, then... 04851 STA PL2ZPOSHI,Y ; ...store in starbase coordinate (high byte) 04852 04853 TYA ; 04854 CLC ; 04855 ADC #NUMSPCOBJ.ALL ; 04856 TAY ; 04857 CMP #NUMSPCOBJ.ALL*3 ; 04858 BCC LOOP033 ; Next starbase coordinate 04859 04860 LDA PL2ZPOSHI ; Force starbase z-coordinate >= +$71** 04861 ORA #$71 ; 04862 STA PL2ZPOSHI ; 04863 LDX #2 ; Randomly invert starbase x and y coordinates... 04864 JMP RNDINVXY ; ...and return 04865 04866 ;*** Flash red alert if Zylon sector entered *********************************** 04867 SKIP070 BEQ SKIP071 ; Skip if no Zylon ships in sector 04868 04869 LDA #255 ; Red alert lifetime := 255 game loops 04870 STA REDALERTLIFE ; 04871 04872 LDX #$06 ; Play beeper sound pattern RED ALERT 04873 JSR BEEP ; 04874 04875 LDY #$75 ; Set title phrase "RED ALERT" 04876 JSR SETTITLE ; 04877 04878 SKIP071 RTS ; Return 04879 04880 ;******************************************************************************* 04881 ;* * 04882 ;* ABORTWARP * 04883 ;* * 04884 ;* Abort hyperwarp * 04885 ;* * 04886 ;******************************************************************************* 04887 04888 ; DESCRIPTION 04889 ; 04890 ; Aborts hyperwarp. 04891 ; 04892 ; This subroutine is entered from subroutine KEYBOARD ($AFFE). It subtracts 100 04893 ; energy units for aborting the hyperwarp and preloads the title phrase with 04894 ; "HYPERWARP ABORTED". Code execution continues into subroutine ENDWARP 04895 ; ($A987). 04896 04897 ABORTWARP LDX #1 ; ENERGY := ENERGY - 100 after hyperwarp abort 04898 JSR DECENERGY ; 04899 04900 LDY #$17 ; Prep title phrase "HYPERWARP ABORTED" 04901 04902 ;******************************************************************************* 04903 ;* * 04904 ;* ENDWARP * 04905 ;* * 04906 ;* End hyperwarp * 04907 ;* * 04908 ;******************************************************************************* 04909 04910 ; DESCRIPTION 04911 ; 04912 ; Ends hyperwarp. 04913 ; 04914 ; This subroutine stops our starship's Engines and resets the hyperwarp state. 04915 ; Code execution continues into subroutine CLEANUPWARP ($A98D). 04916 04917 ENDWARP LDA #0 ; Stop Engines 04918 STA NEWVELOCITY ; 04919 STA WARPSTATE ; Disengage hyperwarp 04920 04921 ;******************************************************************************* 04922 ;* * 04923 ;* CLEANUPWARP * 04924 ;* * 04925 ;* Clean up hyperwarp variables * 04926 ;* * 04927 ;******************************************************************************* 04928 04929 ; DESCRIPTION 04930 ; 04931 ; Cleans up after a hyperwarp. 04932 ; 04933 ; This subroutine restores many hyperwarp related variables to their 04934 ; post-hyperwarp values: The number of used space objects is set to the regular 04935 ; value of 16 (5 PLAYER space objects + 12 PLAYFIELD space objects (stars), 04936 ; counted 0..16), our starship's velocity (high byte) is cleared as well as the 04937 ; explosion lifetime, the hit badness, the PLAYER3 shape type (Hyperwarp Target 04938 ; Marker), the Engines energy drain rate, and the lifetimes of the PLAYERs. The 04939 ; docking state is reset as well as the tracking digit. The title phrase is 04940 ; updated with either "HYPERSPACE" or "HYPERWARP ABORTED". 04941 ; 04942 ; INPUT 04943 ; 04944 ; Y = Title phrase offset. Used values are: 04945 ; $17 -> "HYPERWARP ABORTED" 04946 ; $1B -> "HYPERSPACE" 04947 04948 CLEANUPWARP LDA #NUMSPCOBJ.NORM-1 ; Set normal number of space objects 04949 STA MAXSPCOBJIND ; (5 PLAYER spc objs + 12 PLAYFIELD spc objs (stars)) 04950 04951 LDA #0 ; 04952 STA VELOCITYHI ; Turn off hyperwarp velocity 04953 STA EXPLLIFE ; Explosion lifetime := 0 game loops 04954 STA HITBADNESS ; HITBADNESS := NO HIT 04955 STA PL3SHAPTYPE ; Clear PLAYER3 shape type 04956 STA DRAINENGINES ; Clear Engines energy drain rate 04957 CPY #$17 ; Skip if hyperwarp was aborted 04958 BEQ SKIP072 ; 04959 04960 STA PL0LIFE ; Zylon ship 0 lifetime := 0 game loops 04961 STA PL1LIFE ; Zylon ship 1 lifetime := 0 game loops 04962 04963 SKIP072 STA PL2LIFE ; Zylon photon torpedo lifetime := 0 game loops 04964 STA PL3LIFE ; Hyperwarp Target Marker lifetime := 0 game loops 04965 STA PL4LIFE ; Photon torpedo 1 lifetime := 0 game loops 04966 STA DOCKSTATE ; DOCKSTATE := NO DOCKING 04967 STA TRACKDIGIT ; Clear index of tracked space object 04968 JMP SETTITLE ; Set title phrase and return 04969 04970 ;******************************************************************************* 04971 ;* * 04972 ;* INITTRAIL * 04973 ;* * 04974 ;* Initialize star trail during STAR TRAIL PHASE of hyperwarp * 04975 ;* * 04976 ;******************************************************************************* 04977 04978 ; DESCRIPTION 04979 ; 04980 ; BACKGROUND 04981 ; 04982 ; Star trails are displayed during the STAR TRAIL PHASE, that is, after the 04983 ; ACCELERATION PHASE and before the HYPERSPACE PHASE of the hyperwarp. 04984 ; 04985 ; A star trail is formed by 6 stars represented by 6 PLAYFIELD space objects 04986 ; with continuous position vector indices in 17..48 (indices are wrapped around 04987 ; when greater than 48). Between the creations of two star trails there is delay 04988 ; of 4 game loop iterations. 04989 ; 04990 ; DETAILS 04991 ; 04992 ; This subroutine first decrements this star trail creation delay, returning if 04993 ; the delay is still counting down. If the delay falls below 0 then it continues 04994 ; accelerating our starship's velocity toward hyperwarp speed and then creates a 04995 ; new star trail: 04996 ; 04997 ; First, it raises the maximum index of used space objects to 48 (increasing the 04998 ; number of displayed space objects to 49), resets the star trail creation delay 04999 ; to 4 game loop iterations, and then forms a new star trail of 6 stars 05000 ; represented by 6 PLAYFIELD space objects. The x and y coordinates for all 6 05001 ; stars are the same, picked randomly from tables WARPSTARXTAB ($BB3A) and 05002 ; WARPSTARYTAB ($BB3E), respectively, with their signs changed randomly. Their 05003 ; z-coordinates are computed in increasing depth from at least +4608 (+$12**) 05004 ; in intervals of +80 (+$0050) . Their velocity vector components are 05005 ; set to 0 . 05006 05007 L.RANGE = $68 ; z-coordinate of star in star trail (16-bit value) 05008 L.TRAILCNT = $6E ; Star's index in star trail. Used values are: 0..5. 05009 05010 INITTRAIL DEC TRAILDELAY ; Decrement star trail delay 05011 BPL SKIP074 ; Return if delay still counting 05012 05013 LDA #1 ; Turn on hyperwarp velocity 05014 STA VELOCITYHI ; 05015 05016 LDA #NUMSPCOBJ.ALL-1 ; Max index of space objects (for star trail stars) 05017 STA MAXSPCOBJIND ; 05018 05019 LDA #3 ; Star trail delay := 3(+1) game loops 05020 STA TRAILDELAY ; 05021 05022 LDX TRAILIND ; Next avail. space obj index for star of star trail 05023 05024 LDA #$12 ; Star z-coordinate := >= +$12** (+4608) 05025 STA L.RANGE+1 ; 05026 05027 LDA RANDOM ; Calc random index to pick initial star coordinates 05028 AND #$03 ; 05029 TAY ; 05030 LDA WARPSTARXTAB,Y ; Pick x-coordinate (high byte) of star from table 05031 STA XPOSHI,X ; 05032 LDA WARPSTARYTAB,Y ; 05033 STA YPOSHI,X ; Pick y-coordinate (high byte) of star from table 05034 JSR RNDINVXY ; Randomize signs of x and y coordinates of star 05035 05036 TXA ; Save space object index 05037 TAY ; 05038 LDA #5 ; Loop over 5(+1) stars that form the star trail 05039 STA L.TRAILCNT ; Store star counter of star trail 05040 05041 LOOP034 CLC ; Place stars in z-coordinate intervals of +80 05042 LDA L.RANGE ; 05043 ADC #80 ; 05044 STA L.RANGE ; 05045 STA ZPOSLO,X ; 05046 LDA L.RANGE+1 ; 05047 ADC #0 ; 05048 STA L.RANGE+1 ; 05049 STA ZPOSHI,X ; 05050 05051 LDA #0 ; Star's velocity vector components := 0 05052 STA ZVEL,X ; 05053 STA XVEL,X ; 05054 STA YVEL,X ; 05055 LDA #1 ; Star's z-coordinate sign := + (= ahead of starship) 05056 STA ZPOSSIGN,X ; 05057 05058 LDA #99 ; Init pixel row and column numbers to magic... 05059 STA PIXELROWNEW,X ; ...offscreen value (triggers automatic recalc in... 05060 STA PIXELCOLUMN,X ; ...GAMELOOP's calls to SCREENCOLUMN and SCREENROW) 05061 05062 JSR COPYPOSXY ; Copy x and y coordinate from previous star in trail 05063 05064 DEX ; Decrement space object index to next star 05065 CPX #NUMSPCOBJ.NORM ; If index reaches minimum value... 05066 BCS SKIP073 ; 05067 LDX #NUMSPCOBJ.ALL-1 ; ...wrap-around to maximum space object index 05068 SKIP073 DEC L.TRAILCNT ; 05069 BPL LOOP034 ; Next star of star trail 05070 05071 STX TRAILIND ; Save space object index of star trail's last star 05072 SKIP074 RTS ; Return 05073 05074 ;******************************************************************************* 05075 ;* * 05076 ;* PROJECTION * 05077 ;* * 05078 ;* Calculate pixel column (or row) number from position vector * 05079 ;* * 05080 ;******************************************************************************* 05081 05082 ; Calculates the pixel column (or row) number of a position vector x (or y) 05083 ; component relative to the PLAYFIELD center by computing the perspective 05084 ; projection quotient 05085 ; 05086 ; QUOTIENT := DIVIDEND / DIVISOR * 128 05087 ; 05088 ; with 05089 ; 05090 ; DIVIDEND := ABS(x-coordinate (or y-coordinate)) / 2 05091 ; DIVISOR := ABS(z-coordinate) / 2 05092 ; 05093 ; If the QUOTIENT is in 0..255, it is used as an index to pick the pixel column 05094 ; (or row) number from table MAPTO80 ($0DE9), returning values in 0..80. 05095 ; 05096 ; If the QUOTIENT is larger than 255 ("dividend overflow") or if the 05097 ; z-coordinate = 0 ("division by zero") then the error value 255 is returned. 05098 ; 05099 ; INPUT 05100 ; 05101 ; X = Position vector index. Used values are: 0..48. 05102 ; DIVIDEND ($6A..$6B) = Dividend (positive 16-bit value), contains the 05103 ; absolute value of the x (or y) coordinate. 05104 ; 05105 ; OUTPUT 05106 ; 05107 ; A = Pixel column (or row) number relative to PLAYFIELD center. Used values 05108 ; are: 05109 ; 0..80 -> Pixel number 05110 ; 255 -> Error value indicating "dividend overflow" or "division by zero" 05111 05112 L.DIVISOR = $68 ; Divisor (16-bit value) 05113 L.QUOTIENT = $6D ; Division result (unsigned 8-bit value) 05114 L.LOOPCNT = $6E ; Division loop counter. Used values are: 7..0. 05115 05116 PROJECTION LDA #0 ; Init quotient result 05117 STA L.QUOTIENT ; 05118 05119 LDA #7 ; Init division loop counter 05120 STA L.LOOPCNT ; 05121 05122 LSR DIVIDEND+1 ; DIVIDEND := x-coordinate (or y-coordinate) / 2 05123 ROR DIVIDEND ; (division by 2 to make B15 = 0?) (?) 05124 05125 LDA SHIPVIEW ; Skip if in Aft view 05126 BNE SKIP075 ; 05127 05128 LDA ZPOSHI,X ; If in Front view -> DIVISOR := z-coordinate / 2 05129 LSR A ; (division by 2 to make B15 = 0?) (?) 05130 STA L.DIVISOR+1 ; 05131 LDA ZPOSLO,X ; 05132 ROR A ; 05133 STA L.DIVISOR ; 05134 JMP LOOP035 ; 05135 05136 SKIP075 SEC ; If in Aft view -> DIVISOR := - z-coordinate / 2 05137 LDA #0 ; (division by 2 to make B15 = 0?) (?) 05138 SBC ZPOSLO,X ; 05139 STA L.DIVISOR ; 05140 LDA #0 ; 05141 SBC ZPOSHI,X ; 05142 LSR A ; 05143 STA L.DIVISOR+1 ; 05144 ROR L.DIVISOR ; 05145 05146 LOOP035 ASL L.QUOTIENT ; QUOTIENT := DIVIDEND / DIVISOR * 128 05147 SEC ; 05148 LDA DIVIDEND ; 05149 SBC L.DIVISOR ; 05150 TAY ; 05151 LDA DIVIDEND+1 ; 05152 SBC L.DIVISOR+1 ; 05153 BCC SKIP076 ; 05154 05155 STA DIVIDEND+1 ; 05156 STY DIVIDEND ; 05157 INC L.QUOTIENT ; 05158 05159 SKIP076 ASL DIVIDEND ; 05160 ROL DIVIDEND+1 ; 05161 BCC SKIP077 ; 05162 05163 LDA #255 ; Return 255 if division by zero or dividend overflow 05164 RTS ; 05165 05166 SKIP077 DEC L.LOOPCNT ; 05167 BPL LOOP035 ; Next division loop iteration 05168 05169 LDY L.QUOTIENT ; Prep with quotient 05170 LDA MAPTO80,Y ; Pick and return pixel column (or row) number... 05171 SKIP078 RTS ; ...relative to PLAYFIELD center 05172 05173 ;******************************************************************************* 05174 ;* * 05175 ;* MANEUVER * 05176 ;* * 05177 ;* Maneuver our starship's and Zylon photon torpedoes and Zylon ships * 05178 ;* * 05179 ;******************************************************************************* 05180 05181 ; DESCRIPTION 05182 ; 05183 ; This subroutine maneuvers both of our starship's photon torpedoes, the single 05184 ; Zylon photon torpedo, and the one or two Zylon ships that are simultaneously 05185 ; displayed on the screen. It also creates meteors and new Zylon ships. This 05186 ; subroutine is executed only if our starship is not in a starbase sector and 05187 ; hyperwarp is not engaged. 05188 ; 05189 ; BACKGROUND 05190 ; 05191 ; When a Zylon ship is initialized, a "flight pattern" is assigned to it. There 05192 ; are 3 flight patterns (0, 1, and 4) which are picked from table ZYLONFLPATTAB 05193 ; ($BF91). 05194 ; 05195 ; The flight pattern determines the maximum velocity with which a Zylon ship can 05196 ; move along each axis of the 3D coordinate system, that is, the maximum value 05197 ; of a velocity vector component. Velocity vector components for Zylon ships are 05198 ; picked from the Zylon velocity table ZYLONVELTAB ($BF99): 05199 ; 05200 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05201 ; | Velocity Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 05202 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05203 ; | Velocity | +62 | +30 | +16 | +8 | +4 | +2 | +1 | 0 | 05204 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05205 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05206 ; | Velocity Index | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 05207 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05208 ; | Velocity | 0 | -1 | -2 | -4 | -8 | -16 | -30 | -62 | 05209 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05210 ; 05211 ; The index into the Zylon velocity table ZYLONVELTAB ($BF99) corresponding to 05212 ; the maximum velocity is called the "maximum velocity index". The following 05213 ; table shows the flight patterns, their maximum velocity indices, and their 05214 ; corresponding velocities: 05215 ; 05216 ; +----------------+------------------+------------------+ 05217 ; | Flight Pattern | Maximum Velocity | Maximum Velocity | 05218 ; | | Index | | 05219 ; +----------------+------------------+------------------+ 05220 ; | 0 | 0 | +62 | 05221 ; | 0 | 15 | -62 | 05222 ; | 1 | 1 | +30 | 05223 ; | 1 | 14 | -30 | 05224 ; | 4 | 4 | +4 | 05225 ; | 4 | 11 | -4 | 05226 ; +----------------+------------------+------------------+ 05227 ; 05228 ; Because flight pattern 0 produces the fastest-moving Zylon ships, which 05229 ; maneuver aggressively, it is called the "attack flight pattern". 05230 ; 05231 ; Each Zylon ship has a set of 3 maximum velocity indices, one for each of its 05232 ; velocity vector components. 05233 ; 05234 ; Each Zylon ship has also one more set of 3 velocity indices, called "Zylon 05235 ; velocity indices", one for each of its velocity vector components. They are 05236 ; used to pick the current values of the velocity vector components from the 05237 ; Zylon velocity table ZYLONVELTAB ($BF99). 05238 ; 05239 ; In order to maneuver Zylon ships this subroutine uses the concept of 05240 ; "milestone velocity indices". By using delay timers, called "Zylon timers", 05241 ; this subroutine gradually increases or decreases the Zylon velocity indices 05242 ; with every game loop iteration to eventually match the corresponding milestone 05243 ; velocity indices. By incrementing a Zylon velocity index a Zylon ship 05244 ; accelerates toward the negative direction of a coordinate axis. By 05245 ; decrementing a Zylon velocity index a Zylon ship accelerates toward the 05246 ; positive direction of a coordinate axis. If one milestone velocity index is 05247 ; matched or a "milestone timer" has counted down to 0, a new milestone velocity 05248 ; index is calculated and the matching of the current Zylon velocity indices 05249 ; with the new milestone velocity indices repeats. 05250 ; 05251 ; DETAILS 05252 ; 05253 ; For quick lookup, the following table lists the PLAYERs and what space objects 05254 ; they represent in this subroutine: 05255 ; 05256 ; +--------+---------------------------------+ 05257 ; | PLAYER | Represents | 05258 ; +--------+---------------------------------+ 05259 ; | 0 | Zylon Ship 0 | 05260 ; | 1 | Zylon Ship 1 | 05261 ; | 2 | Zylon Photon Torpedo, Meteor | 05262 ; | 3 | Our starship's Photon Torpedo 0 | 05263 ; | 4 | Our starship's Photon Torpedo 1 | 05264 ; +--------+---------------------------------+ 05265 ; 05266 ; This subroutine executes the following steps: 05267 ; 05268 ; (1) Update the x and y velocity vector components of both of our starship's 05269 ; photon torpedoes 0 and 1. 05270 ; 05271 ; The x and y velocity vector components of both of our starship's photon 05272 ; torpedoes 0 and 1 are only updated if they are tracking (homing in on) a 05273 ; target. 05274 ; 05275 ; To update the y-velocity vector components of both of our starship's 05276 ; photon torpedoes 0 and 1 the PLAYER row number difference between the 05277 ; PLAYER of tracked target space object and the current location of the 05278 ; PLAYER of our starship's photon torpedo 0 is passed to subroutine 05279 ; HOMINGVEL ($AECA). It returns the new y-velocity vector component value 05280 ; for both of our starship's photon torpedoes in . If the target is 05281 ; located below our starship's photon torpedo 0 a value of 0 is 05282 ; used. 05283 ; 05284 ; NOTE: The new y-velocity vector components depend only on the PLAYER row 05285 ; number of our starship's photon torpedo 0. 05286 ; 05287 ; To update the x-velocity vector components of both of our starship's 05288 ; photon torpedoes, the above calculation is repeated for the PLAYER column 05289 ; numbers of each of our starship's photon torpedoes 0 and 1. 05290 ; 05291 ; (2) Make the Zylon ships follow the rotation of our starship. 05292 ; 05293 ; If you rotate our starship away from Zylon ships they adjust their course 05294 ; such that they reappear in our starship's view. 05295 ; 05296 ; This is achieved by 4 Zylon timers, one for each of both Zylon ships' 05297 ; current x and y Zylon velocity indices. The Zylon timers are decremented 05298 ; every game loop iteration. If any of them reach a value of 0, the 05299 ; corresponding Zylon velocity index is incremented or decremented 05300 ; depending on the current joystick position. 05301 ; 05302 ; For example, if the Zylon timer for the x-velocity of Zylon ship 0 05303 ; reaches 0 and at the same time the joystick is pushed left then the 05304 ; x-Zylon velocity index of this Zylon ship is incremented. This 05305 ; accelerates the Zylon ship toward negative x-direction ("left"): The 05306 ; Zylon ship follows our starship's rotation. This works in Aft view, too, 05307 ; where the direction of change of the Zylon velocity index is reversed. 05308 ; After setting the new Zylon velocity index, it is used to pick a new 05309 ; Zylon timer value for this Zylon velocity index: 05310 ; 05311 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05312 ; | Velocity Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 05313 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05314 ; | Zylon Timer Value (Game Loops) | 0 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 05315 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05316 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05317 ; | Velocity Index | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 05318 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05319 ; | Zylon Timer Value (Game Loops) | 14 | 12 | 10 | 8 | 6 | 4 | 2 | 0 | 05320 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05321 ; 05322 ; (3) Update the x and y velocity vector components of the single Zylon photon 05323 ; torpedo. 05324 ; 05325 ; If a Zylon photon torpedo is moving toward our starship then update its x 05326 ; and y velocity vector components. They are picked from table 05327 ; ZYLONHOMVELTAB ($BF85) and depend on the mission level. The signs of the 05328 ; velocity vector components are always set such that the Zylon photon 05329 ; torpedo is guided toward our starship. 05330 ; 05331 ; (4) Create a meteor? 05332 ; 05333 ; If PLAYER2, the PLAYER to represent a meteor, is either initial or not 05334 ; alive, then attempt in 7 out of 8 game loop iterations to create a new 05335 ; meteor. 05336 ; 05337 ; With a probability of 2% (4:256) a new meteor is created: Its shape type 05338 ; is set to METEOR, its position vector components to random coordinates in 05339 ; subroutine INITPOSVEC ($B764), its lifetime to 60 game loop iterations, 05340 ; and its velocity vector components (velocities) to x-velocity: 0 , 05341 ; y-velocity: 0 , z-velocity: -8 . Then code execution returns. 05342 ; 05343 ; (5) Toggle Zylon ship control. 05344 ; 05345 ; Every other game loop iteration, the game takes control of and maneuvers 05346 ; the other Zylon ship. 05347 ; 05348 ; (6) Create new Zylon ship? 05349 ; 05350 ; If the game-controlled Zylon ship is not alive, check if both Zylon ships 05351 ; are not alive and this is an empty sector. If so, then attempt to create 05352 ; a meteor. Otherwise create a new Zylon ship with infinite lifetime. 05353 ; Randomly pick its shape type from table ZYLONSHAPTAB ($BF89) (ZYLON 05354 ; BASESTAR, ZYLON CRUISER, or ZYLON FIGHTER) and its flight pattern from 05355 ; table ZYLONFLPATTAB ($BF91) (attack flight pattern 0 is always picked in 05356 ; a NOVICE mission). Then set the milestone timer to 1 game loop iteration 05357 ; and the position vector of the Zylon ship to a position of at least 05358 ; +28928 (+$71**) in front of our starship. The y-coordinate depends 05359 ; on the value of VICINITYMASK ($C7). The x-coordinate is the sum of the 05360 ; y-coordinate plus at least 4864..5119 ($13**) . Randomly choose the 05361 ; signs of the x and y coordinates. 05362 ; 05363 ; (7) Set the current flight pattern to attack flight pattern? 05364 ; 05365 ; The current flight pattern of the Zylon ship will change to attack flight 05366 ; pattern if it is close enough (z-coordinate < +8192 (+$20**) ) and 05367 ; one of the following conditions is met: 05368 ; 05369 ; o The Zylon ship is located behind our starship. 05370 ; 05371 ; o The shape of the Zylon ship is not initial and does not currently 05372 ; appear as a blip in the Long-Range Scan view. 05373 ; 05374 ; (8) Update the back-attack flag and the milestone velocity indices. 05375 ; 05376 ; The milestone timer is decremented for the game-controlled Zylon ship. If 05377 ; this timer reaches a value of 0 the following steps are executed: 05378 ; 05379 ; o The milestone timer is reset to a value of 120 game loop iterations. 05380 ; 05381 ; o The back-attack flag is updated. It determines if the game-controlled 05382 ; Zylon ship not only attacks from the front of our starship but also 05383 ; from the back. A back-attack takes place with a probability of 19% 05384 ; (48:256) in WARRIOR or COMMANDER missions. 05385 ; 05386 ; o Course corrections are prepared for the game-controlled Zylon ship by 05387 ; computing the new milestone vector indices, resulting in new velocity 05388 ; vector components for this Zylon ship. The new milestone velocity 05389 ; indices for each velocity vector component are randomly chosen 05390 ; depending of the flight pattern. Recall that the Zylon velocity index 05391 ; is changed gradually to match the milestone velocity index. It 05392 ; corresponds to a maximum velocity vector component when using this 05393 ; index to pick a velocity vector component from Zylon velocity table 05394 ; ZYLONVELTAB ($BF99): 05395 ; 05396 ; +----------------+----------------+------------------+ 05397 ; | Flight Pattern | New Milestone | Maximum Velocity | 05398 ; | | Velocity Index | Vector Component | 05399 ; +----------------+----------------+------------------+ 05400 ; | 0 | 0 | +62 | 05401 ; | 0 | 15 | -62 | 05402 ; | 1 | 1 | +30 | 05403 ; | 1 | 14 | -30 | 05404 ; | 4 | 4 | +4 | 05405 ; | 4 | 11 | -4 | 05406 ; +----------------+----------------+------------------+ 05407 ; 05408 ; (9) Update milestone velocity indices in attack flight pattern. 05409 ; 05410 ; If a Zylon ship executes the attack flight pattern, its milestone 05411 ; velocity indices are changed depending on the current location of the 05412 ; Zylon ship as follows: 05413 ; 05414 ; +--------------+-------------+----------------+------------+----------------+ 05415 ; | x-Coordinate | Where on | Milestone | Velocity | Zylon Ship | 05416 ; | | Screen | Velocity Index | | Accelerates... | 05417 ; +--------------+-------------+----------------+------------+----------------+ 05418 ; | x < 0 | left half | 0 | +62 | to the right | 05419 ; | x >= 0 | right half | 15 | -62 | to the left | 05420 ; +--------------+-------------+----------------+------------+----------------+ 05421 ; +--------------+-------------+----------------+------------+----------------+ 05422 ; | y-Coordinate | Where on | Milestone | Velocity | Zylon Ship | 05423 ; | | Screen | Velocity Index | | Accelerates... | 05424 ; +--------------+-------------+----------------+------------+----------------+ 05425 ; | y < 0 | bottom half | 0 | +62 | up | 05426 ; | y >= 0 | top half | 15 | -62 | down | 05427 ; +--------------+-------------+----------------+------------+----------------+ 05428 ; 05429 ; Thus, with respect to its x and y coordinates, the Zylon ship oscillates 05430 ; around the center of the Front or Aft view. 05431 ; 05432 ; This is the behavior of the Zylon ship along the z-axis: 05433 ; 05434 ; If the Zylon ship attacks from the front: 05435 ; 05436 ; +--------------------------+----------------+------------+----------------+ 05437 ; | z-Coordinate | Milestone | Velocity | Zylon Ship | 05438 ; | | Velocity Index | | Accelerates... | 05439 ; +--------------------------+----------------+------------+----------------+ 05440 ; | z < +2560 (+$0A00) | 0 | +62 | outbound | 05441 ; | z >= +2560 (+$0A00) | 15 | -62 | inbound | 05442 ; +--------------------------+----------------+------------+----------------+ 05443 ; 05444 ; In other words, the Zylon ship accelerates into positive z-direction 05445 ; (outbound) up to a distance of +2560 (+$0A00) , then reverses its 05446 ; course and returns back to our starship (inbound). 05447 ; 05448 ; If the Zylon ship attacks from the back: 05449 ; 05450 ; +--------------------------+----------------+------------+----------------+ 05451 ; | z-Coordinate | Milestone | Velocity | Zylon Ship | 05452 ; | | Velocity Index | | Accelerates... | 05453 ; +--------------------------+----------------+------------+----------------+ 05454 ; | z < -2816 (-$F500) | 0 | +62 | inbound | 05455 ; | z >= -2816 (-$F500) | 15 | -62 | outbound | 05456 ; +--------------------------+----------------+------------+----------------+ 05457 ; 05458 ; In other words, the Zylon ship accelerates into negative z-direction 05459 ; (outbound) up to a distance of -2816 (-$(0B00)) , then reverses its 05460 ; course and returns back to our starship (inbound). 05461 ; 05462 ; (10) Change Zylon velocity index toward milestone velocity index. 05463 ; 05464 ; Compare all 3 Zylon velocity indices of the game-controlled Zylon ship 05465 ; with their corresponding milestone velocity indices. Increment or 05466 ; decrement the former to better match the latter. Use the new Zylon 05467 ; velocity indices to pick the current velocity values from Zylon velocity 05468 ; table ZYLONVELTAB ($BF99). 05469 ; 05470 ; (11) Launch a Zylon photon torpedo? 05471 ; 05472 ; Prepare launching a Zylon photon torpedo if either of the following 05473 ; conditions are met: 05474 ; 05475 ; o PLAYER2 is not used as a photon torpedo 05476 ; 05477 ; o The y-coordinate of the Zylon ship is in the range of -768..+767 05478 ; (-$0300..+$2FF) . 05479 ; 05480 ; or if 05481 ; 05482 ; o The Zylon photon torpedo is not alive 05483 ; 05484 ; o The corresponding Zylon photon torpedo delay timer has reached a 05485 ; value of 0 05486 ; 05487 ; o The y-coordinate of the Zylon ship is in the range of -768..+767 05488 ; (-$0300..+$2FF) . 05489 ; 05490 ; At this point the z-velocity vector component of the Zylon photon torpedo 05491 ; is preloaded with a value of -80 or +80 depending on the Zylon 05492 ; ship being in front or behind of our starship, respectively. 05493 ; 05494 ; Launch a Zylon photon torpedo if both of the following conditions are 05495 ; met: 05496 ; 05497 ; o The Zylon ship is in front or behind of our starship, with the 05498 ; exception of a Zylon ship behind our starship in a NOVICE mission 05499 ; (our starship will never be shot in the back in a NOVICE mission). 05500 ; 05501 ; o The z-coordinate of the Zylon ship (no matter if in front or behind 05502 ; our starship) is closer than 8192 ($20**) . 05503 ; 05504 ; Finally, the Zylon photon torpedo is launched with a lifetime of 62 game 05505 ; loop iterations. Its position vector is copied from the launching Zylon 05506 ; ship in subroutine COPYPOSVEC ($ACAF). In addition, the Zylon ship is 05507 ; earmarked for the tracking computer. 05508 05509 L.CTRLDZYLON = $6A ; Index of currently game-controlled Zylon ship. 05510 ; Used values are: 05511 ; 0 -> Control Zylon ship 0 05512 ; 1 -> Control Zylon ship 1 05513 NEG = $80 ; Negative sign bit for velocity vector component 05514 05515 MANEUVER LDA WARPSTATE ; Return if in starbase sector or hyperwarp engaged 05516 ORA ISSTARBASESECT ; 05517 BNE SKIP078 ; 05518 05519 ;*** Update x and y velocity of both our starship's photon torpedoes 0 and 1 *** 05520 LDA ISTRACKING ; Skip this if ship's torpedoes not tracking a target 05521 BEQ SKIP080 ; 05522 05523 LDX PLTRACKED ; Load PLAYER index of tracked target space object 05524 05525 SEC ; Prep A := PLAYER row number of target... 05526 LDA PL0ROWNEW,X ; ...- PLAYER row number photon torpedo 0 05527 SBC PL3ROWNEW ; 05528 BCC SKIP079 ; Skip if target above our starship's photon torpedo 05529 LDA #0 ; Prep A := 0 05530 SKIP079 JSR HOMINGVEL ; Get y-velocity for homing photon torpedo 0 and 1 05531 STA PL3YVEL ; Store y-velocity photon torpedo 0 05532 STA PL4YVEL ; Store y-velocity photon torpedo 1 05533 05534 SEC ; Prep A := PLAYER column number of target... 05535 LDA PL3COLUMN ; ...- PLAYER column number of photon torpedo 0 05536 SBC PL0COLUMN,X ; 05537 JSR HOMINGVEL ; Get x-velocity for homing photon torpedo 0 05538 STA PL3XVEL ; Store x-velocity of photon torpedo 0 05539 05540 SEC ; Prep A := PLAYER column number of target... 05541 LDA PL4COLUMN ; ...- PLAYER column number of photon torpedo 1 05542 SBC PL0COLUMN,X ; 05543 JSR HOMINGVEL ; Get x-velocity for homing photon torpedo 1 05544 STA PL4XVEL ; Store x-velocity of photon torpedo 1 05545 05546 ;*** Make Zylon ships follow rotation of our starship ************************** 05547 SKIP080 LDX #3 ; Loop over x and y velocity indices of both Zylons 05548 LOOP036 DEC ZYLONTIMX0,X ; Decrement Zylon timer 05549 BPL SKIP085 ; Next timer if this one still counting down 05550 05551 TXA ; Prep joystick (x or y) value in -1, 0, +1 05552 LSR A ; 05553 TAY ; 05554 LDA JOYSTICKX,Y ; 05555 05556 LDY SHIPVIEW ; Skip if in Front view 05557 BEQ SKIP081 ; 05558 05559 EOR #$FF ; Invert joystick value (when in Aft view) 05560 CLC ; (two's-complement) 05561 ADC #1 ; 05562 05563 SKIP081 CLC ; Add joystick value to Zylon velocity index 05564 ADC ZYLONVELINDX0,X ; 05565 BPL SKIP082 ; 05566 LDA #0 ; 05567 SKIP082 CMP #16 ; Limit new Zylon velocity index to 0..15 ... 05568 BCC SKIP083 ; 05569 LDA #15 ; 05570 SKIP083 STA ZYLONVELINDX0,X ; ...and store new Zylon velocity index 05571 05572 CMP #8 ; Calc new Zylon timer value in 0, 2, ..., 14 05573 BCC SKIP084 ; 05574 EOR #$0F ; 05575 SKIP084 ASL A ; 05576 STA ZYLONTIMX0,X ; ...and store new Zylon timer value 05577 05578 SKIP085 DEX ; 05579 BPL LOOP036 ; Next Zylon timer 05580 05581 ;*** Update x and y velocity of single Zylon photon torpedo ******************** 05582 LDA PL2SHAPTYPE ; Skip if PLAYER2 not PHOTON TORPEDO (shape type 0) 05583 BNE SKIP088 ; 05584 05585 LDY MISSIONLEVEL ; Depending on mission level... 05586 LDA ZYLONHOMVELTAB,Y ; ...pick (initially negative) Zylon torpedo velocity 05587 05588 LDX PL2YPOSHI ; If photon torpedo in upper screen half (y >= 0)... 05589 BPL SKIP086 ; ...don't toggle velocity sign -> torpedo goes down 05590 AND #$7F ; ...toggle velocity sign -> torpedo goes up 05591 SKIP086 STA PL2YVEL ; Store new y-velocity of Zylon photon torpedo 05592 05593 ORA #NEG ; Restore negative sign bit of velocity 05594 05595 LDX PL2XPOSHI ; If photon torpedo in right screen half (x >= 0)... 05596 BPL SKIP087 ; ...don't toggle velocity sign -> torpedo goes left 05597 AND #$7F ; ...toggle velocity sign -> torpedo goes right 05598 SKIP087 STA PL2XVEL ; Store new x-velocity of Zylon photon torpedo 05599 05600 ;*** Create new meteor? ******************************************************** 05601 SKIP088 LDA COUNT256 ; Attempt meteor creation in 7 out of 8 game loops 05602 AND #$03 ; 05603 BEQ SKIP092 ; 05604 05605 SKIP089 LDA PL2SHAPOFF ; If PLAYER2 shape is initial try to create a meteor 05606 BEQ SKIP090 ; 05607 05608 LDA PL2LIFE ; Return if PLAYER2 alive 05609 BNE SKIP091 ; 05610 05611 SKIP090 LDA RANDOM ; Return in 98% (252:256) (do not create meteor) 05612 CMP #4 ; 05613 BCS SKIP091 ; 05614 05615 ;*** Create new meteor! ******************************************************** 05616 LDA #SHAP.METEOR ; PLAYER2 is METEOR (shape type 6) 05617 STA PL2SHAPTYPE ; 05618 LDX #2 ; Randomize position vector of meteor 05619 JSR INITPOSVEC ; 05620 LDA #60 ; Meteor lifetime := 60 game loops 05621 STA PL2LIFE ; 05622 LDA #NEG!8 ; SUMMARY: 05623 STA PL2ZVEL ; x-velocity := 0 05624 LDA #0 ; y-velocity := 0 05625 STA PL2COLUMN ; z-velocity := -8 05626 STA PL2XVEL ; 05627 STA PL2YVEL ; PLAYER2 column number := 0 (offscreen) 05628 SKIP091 RTS ; Return 05629 05630 ;*** Toggle Zylon ship control ************************************************* 05631 SKIP092 LDA CTRLDZYLON ; Toggle control to the other Zylon ship 05632 EOR #$01 ; 05633 STA CTRLDZYLON ; 05634 05635 ;*** Create a new Zylon ship? ************************************************** 05636 TAX ; Save index of controlled Zylon ship 05637 LDA PL0LIFE,X ; Skip creating Zylon ship if its PLAYER still alive 05638 BNE SKIP094 ; 05639 05640 LDA PL0LIFE ; If both Zylon ships are not alive... 05641 ORA PL1LIFE ; 05642 AND #$01 ; 05643 LDY CURRSECTOR ; ...and this an empty sector... 05644 CMP GCMEMMAP,Y ; 05645 BCS SKIP089 ; ...attempt to create meteor and return 05646 05647 ;*** Create a new Zylon ship! ************************************************** 05648 LDA #255 ; Zylon ship lifetime := 255 game loops (infinite) 05649 STA PL0LIFE,X ; 05650 05651 LDA RANDOM ; Pick a Zylon ship shape type (1 out of 8) 05652 AND #$07 ; 05653 TAY ; 05654 LDA ZYLONSHAPTAB,Y ; 05655 STA PL0SHAPTYPE,X ; 05656 05657 LDA MISSIONLEVEL ; Init Zylon's flight pattern (0 if NOVICE mission) 05658 BEQ SKIP093 ; 05659 LDA ZYLONFLPATTAB,Y ; 05660 SKIP093 STA ZYLONFLPAT0,X ; 05661 05662 LDA #1 ; Zylon ship's milestone timer := 1 game loop 05663 STA MILESTTIM0,X ; 05664 05665 STA ZPOSSIGN,X ; Put Zylon ship in front of our starship 05666 LDA RANDOM ; 05667 AND VICINITYMASK ; y-coordinate (high byte) := RND(0..VICINITYMASK) 05668 STA YPOSHI,X ; 05669 ADC #19 ; x-coordinate (high byte) := y (high byte) + 19 05670 STA XPOSHI,X ; 05671 ORA #$71 ; z-coordinate (high byte) := >= +28928 (+$71**) 05672 STA ZPOSHI,X ; 05673 JSR RNDINVXY ; Randomly invert x and y coordinate of pos vector 05674 05675 ;*** Set current flight pattern to attack flight pattern? ********************** 05676 SKIP094 LDA ZPOSHI,X ; Skip if Zylon too distant (z >= +$20** ) 05677 CMP #$20 ; 05678 BCS SKIP096 ; 05679 05680 LDA ZPOSSIGN,X ; Set attack flight pattern if Zylon is behind 05681 BEQ SKIP095 ; 05682 05683 LDA PL0SHAPOFF,X ; Skip if Zylon shape initial 05684 BEQ SKIP096 ; 05685 05686 CMP #$29 ; Skip if Zylon shape is Long-Range Scan blip 05687 BEQ SKIP096 ; 05688 05689 SKIP095 LDA #0 ; Set attack flight pattern 05690 STA ZYLONFLPAT0,X ; 05691 05692 ;*** Update back-attack flag and milestone velocity indices ******************** 05693 SKIP096 DEC MILESTTIM0,X ; Skip if milestone timer still counting down 05694 BPL SKIP099 ; 05695 05696 LDA #120 ; Milestone timer := 120 game loops 05697 STA MILESTTIM0,X ; 05698 05699 LDA MISSIONLEVEL ; Back-attack flag := 1 in 19% (48:256) of... 05700 LDY RANDOM ; ...WARRIOR or COMMANDER missions 05701 CPY #48 ; ... := 0 otherwise 05702 BCC SKIP097 ; 05703 LSR A ; 05704 SKIP097 LSR A ; 05705 STA ISBACKATTACK0,X ; 05706 05707 ; Loop over all 3 milestone velocity indices 05708 LDA ZYLONFLPAT0,X ; Set new milestone velocity index: 05709 LOOP037 BIT RANDOM ; If Zylon flight pattern is... 05710 BPL SKIP098 ; ...0 -> milestone velocity index := either 0 or 15 05711 EOR #$0F ; ...1 -> milestone velocity index := either 1 or 14 05712 SKIP098 STA MILESTVELINDZ0,X ; ...4 -> milestone velocity index := either 4 or 11 05713 INX ; 05714 INX ; 05715 CPX #6 ; 05716 BCC LOOP037 ; Next Zylon milestone velocity index 05717 05718 ;*** Update milestone velocity indices in attack flight pattern **************** 05719 LDX CTRLDZYLON ; Reload index of controlled Zylon ship 05720 05721 SKIP099 LDA ZYLONFLPAT0,X ; Skip if not in attack flight pattern 05722 BNE SKIP105 ; 05723 05724 LDY CTRLDZYLON ; Reload index of controlled Zylon ship 05725 05726 ; Loop over all 3 milestone velocity indices 05727 LOOP038 CPY #$31 ; Skip to handle x and y velocity index 05728 BCS SKIP101 ; 05729 ; SUMMARY: 05730 LDA ISBACKATTACK0,Y ; Handle z-velocity index: 05731 LSR A ; 05732 LDA ZPOSHI,Y ; If Zylon attacks from front... 05733 BCS SKIP100 ; z < $0A00 -> mil vel index := 0 (+62 ) 05734 CMP #$0A ; z >= $0A00 -> mil vel index := 15 (-62 ) 05735 BCC SKIP103 ; 05736 BCS SKIP101 ; If Zylon attacks from back... 05737 SKIP100 CMP #$F5 ; z >= $F500 -> mil vel index := 15 (-62 ) 05738 BCS SKIP102 ; z < $F500 -> mil vel index := 0 (+62 ) 05739 05740 SKIP101 LDA ZPOSSIGN,Y ; Handle x and y velocity index: 05741 LSR A ; 05742 SKIP102 LDA #15 ; x >= 0 -> mil vel index := 15 (-62 ) 05743 BCS SKIP104 ; x < 0 -> mil vel index := 0 (+62 ) 05744 SKIP103 LDA #0 ; y >= 0 -> mil vel index := 15 (-62 ) 05745 SKIP104 STA MILESTVELINDZ0,X ; y < 0 -> mil vel index := 0 (+62 ) 05746 05747 CLC ; Adjust position vector component index 05748 TYA ; 05749 ADC #NUMSPCOBJ.ALL ; 05750 TAY ; 05751 05752 INX ; 05753 INX ; 05754 CPX #6 ; 05755 BCC LOOP038 ; Next milestone velocity index 05756 05757 ;*** Acceleration: Change Zylon velocity index toward milestone velocity index * 05758 LDX CTRLDZYLON ; Reload index of controlled Zylon ship 05759 SKIP105 LDY CTRLDZYLON ; Reload index of controlled Zylon ship 05760 05761 ; Loop over all 3 milestone velocity indices 05762 LOOP039 LDA ZYLONVELINDZ0,X ; Compare Zylon velocity index with milestone index 05763 CMP MILESTVELINDZ0,X ; 05764 BEQ SKIP107 ; Skip if equal 05765 BCS SKIP106 ; 05766 INC ZYLONVELINDZ0,X ; Increm. Zylon velocity index if < milestone index 05767 BCC SKIP107 ; 05768 SKIP106 DEC ZYLONVELINDZ0,X ; Decrem. Zylon velocity index if >= milestone index 05769 05770 SKIP107 STX L.CTRLDZYLON ; Save index of controlled Zylon ship 05771 TAX ; 05772 LDA ZYLONVELTAB,X ; Pick new velocity value by Zylon velocity index 05773 LDX L.CTRLDZYLON ; Reload index of controlled Zylon ship 05774 STA ZVEL,Y ; Store new velocity vector component of Zylon ship 05775 05776 TYA ; Next velocity vector component 05777 CLC ; 05778 ADC #NUMSPCOBJ.ALL ; 05779 TAY ; 05780 05781 INX ; 05782 INX ; 05783 CPX #6 ; 05784 BCC LOOP039 ; Next milestone velocity index 05785 05786 ;*** Launch Zylon photon torpedo? ********************************************** 05787 05788 ;*** Check PLAYER2 shape and lifetime ****************************************** 05789 LDX CTRLDZYLON ; Reload index of controlled Zylon ship 05790 05791 LDA PL2SHAPTYPE ; Skip if PLAYER2 not PHOTON TORPEDO (shape type 0) 05792 BNE SKIP109 ; 05793 05794 LDA PL2LIFE ; Return if Zylon photon torpedo still alive 05795 BNE SKIP108 ; 05796 05797 LDA TORPEDODELAY ; Count down Zylon photon torpedo delay timer... 05798 BEQ SKIP109 ; ...before launching next Zylon photon torpedo 05799 DEC TORPEDODELAY ; 05800 SKIP108 RTS ; Return 05801 05802 ;*** Check y-coordinate of Zylon ship ****************************************** 05803 SKIP109 CLC ; Return if Zylon ship's y-coordinate not... 05804 LDA YPOSHI,X ; ...in -768..+767 (-$(0300)..+$2FF) . 05805 ADC #2 ; 05806 CMP #5 ; 05807 BCS SKIP108 ; 05808 05809 ;*** Set Zylon photon torpedo's z-velocity ************************************* 05810 LDY #NEG!80 ; Prep Zylon torpedo's z-velocity := -80 05811 05812 LDA ZPOSSIGN,X ; Prep Zylon ship's sign of z-coordinate 05813 LSR A ; 05814 LDA ZPOSHI,X ; Prep Zylon ship's z-coordinate 05815 BCS SKIP110 ; Skip if Zylon ship in front... 05816 EOR #$FF ; ...else invert loaded Zylon ship's z-coordinate 05817 05818 LDY MISSIONLEVEL ; Return (no torpedo from back) if NOVICE mission 05819 BEQ SKIP108 ; 05820 05821 LDY #80 ; Preload Zylon torpedo's z-velocity := +80 05822 05823 ;*** Is Zylon ship in range? *************************************************** 05824 SKIP110 CMP #$20 ; Return if Zylon ship too far... 05825 BCS SKIP108 ; ... (ABS(z-coordinate) > 8192 ($20**) ) 05826 05827 STY PL2ZVEL ; Store Zylon photon torpedo's z-velocity 05828 05829 ;*** Launch Zylon photon torpedo! ********************************************** 05830 05831 LDA #0 ; PLAYER2 is PHOTON TORPEDO (shape type 0) 05832 STA PL2SHAPTYPE ; 05833 STA PL2COLUMN ; Zylon torpedo PLAYER column number := 0 (offscreen) 05834 LDA #62 ; 05835 STA PL2LIFE ; Zylon torpedo lifetime := 62 game loops 05836 05837 LDX #2 ; Prep source index for position vector copy 05838 LDY CTRLDZYLON ; Prep destination index for position vector copy 05839 STY ZYLONATTACKER ; Save Zylon ship index for tracking computer 05840 JMP COPYPOSVEC ; Copy position vector from Zylon ship to its torpedo 05841 05842 ;******************************************************************************* 05843 ;* * 05844 ;* INITEXPL * 05845 ;* * 05846 ;* Initialize explosion * 05847 ;* * 05848 ;******************************************************************************* 05849 05850 ; DESCRIPTION 05851 ; 05852 ; Initializes the explosion's lifetime, the explosion fragments' position and 05853 ; velocity vectors as well as their pixel row and column numbers. 05854 ; 05855 ; An explosion has a lifetime of 128 game loop iterations. It consists of 32 05856 ; explosion fragment space objects with indices 17..48. The position vector of 05857 ; each explosion fragment is copied from the exploding PLAYER space object. 05858 ; 05859 ; The pixel column number of each explosion fragment is initialized to 05860 ; 05861 ; PIXEL COLUMN NUMBER := PLAYER column number - 48 + RND(0..15) 05862 ; 05863 ; To convert PLAYER column numbers (in Player/Missile (PM) pixels) into pixel 05864 ; column numbers, the PLAYER column number of the left PLAYFIELD border (= 48) 05865 ; is subtracted and a random number is added. 05866 ; 05867 ; BUG (at $AC76): The added random number should not be in 0..15 but in 0..7 05868 ; because the exploding PLAYER is 8 pixels wide. The PLAYER column number 05869 ; represents the left edge of the PLAYER shape. When using a random number in 05870 ; 0..15, half of the pixels are located off to the right of the PLAYER, outside 05871 ; the PLAYER area. Suggested fix: Replace instruction AND #$0F with AND #$07. 05872 ; 05873 ; The pixel row number of each explosion fragment is initialized to 05874 ; 05875 ; PIXEL ROW NUMBER := (PLAYER row number - RND(0..15)) / 2 - 16 05876 ; 05877 ; BUG (at $AC88): To convert PLAYER row numbers (in PM pixels) into pixel row 05878 ; numbers, the PLAYER row number to the top PLAYFIELD border (= 16) should be 05879 ; subtracted first, then the division by 2 (instruction LRS A) should be applied 05880 ; to reduce the double-line PM resolution to the single-line PLAYFIELD 05881 ; resolution. Suggested fix: Swap instruction LRS A with SBC #16 which leads to 05882 ; the following formula for the pixel row number: 05883 ; 05884 ; PIXEL ROW NUMBER := (PLAYER row number - 16 + RND(0..15)) / 2 05885 ; 05886 ; Incidentally, adding a random number in 0..15 is correct. PLAYER row number 05887 ; represents the top edge of the PLAYER shape, which is typically 16 PM pixels 05888 ; tall when representing a close space object. 05889 ; 05890 ; The velocity vector of explosion fragments is set to random x, y, and z 05891 ; velocity vector components in -7..+7 . 05892 ; 05893 ; INPUT 05894 ; 05895 ; Y = PLAYER index from which the explosion originates. Used values are: 05896 ; 0 -> Explosion of PLAYER0 (Zylon ship 0) 05897 ; 1 -> Explosion of PLAYER1 (Zylon ship 1) 05898 ; 2 -> Explosion of PLAYER2 (Zylon photon torpedo, starbase, or meteor) 05899 05900 INITEXPL LDA #128 ; Explosion lifetime := 128 game loops 05901 STA EXPLLIFE ; 05902 05903 LDX #NUMSPCOBJ.ALL-1 ; Max index of space objects (for explosion frags) 05904 STX MAXSPCOBJIND ; 05905 05906 ; Loop over all explosion fragment position vectors 05907 ; (index 48..17) 05908 LOOP040 LDA RANDOM ; PIXEL COLUMN NUM := PLAYER column - 48 + RND(0..15) 05909 AND #$0F ; (!) 05910 ADC PL0COLUMN,Y ; 05911 SBC #48 ; 05912 STA PIXELCOLUMN,X ; 05913 05914 LDA RANDOM ; PIXEL ROW NUM := (PLAYER row + RND(0..15)) / 2 - 16 05915 AND #$0F ; 05916 ADC PL0ROWNEW,Y ; 05917 LSR A ; (!) 05918 SBC #16 ; 05919 STA PIXELROWNEW,X ; 05920 05921 JSR COPYPOSVEC ; Copy position vector of PLAYER to explosion frag 05922 05923 LDA RANDOM ; z-velocity := RND(-7..+7) 05924 AND #NEG!7 ; 05925 STA ZVEL,X ; 05926 LDA RANDOM ; x-velocity := RND(-7..+7) 05927 AND #NEG!7 ; 05928 STA XVEL,X ; 05929 LDA RANDOM ; y-velocity := RND(-7..+7) 05930 AND #NEG!7 ; 05931 STA YVEL,X ; 05932 05933 DEX ; Next explosion fragment position vector 05934 CPX #16 ; 05935 BNE LOOP040 ; 05936 RTS ; Return 05937 05938 ;******************************************************************************* 05939 ;* * 05940 ;* COPYPOSVEC * 05941 ;* * 05942 ;* Copy a position vector * 05943 ;* * 05944 ;******************************************************************************* 05945 05946 ; DESCRIPTION 05947 ; 05948 ; Copies a position vector. 05949 ; 05950 ; Actually, this subroutine copies the z-coordinate only, then code execution 05951 ; continues into subroutine COPYPOSXY ($ACC1) to copy the x and y coordinate. 05952 ; 05953 ; INPUT 05954 ; 05955 ; X = Destination position vector index. Used values are: 0..48. 05956 ; Y = Source position vector index. Used values are: 0..48. 05957 05958 COPYPOSVEC LDA ZPOSSIGN,Y ; 05959 STA ZPOSSIGN,X ; 05960 LDA ZPOSHI,Y ; 05961 STA ZPOSHI,X ; 05962 LDA ZPOSLO,Y ; 05963 STA ZPOSLO,X ; 05964 05965 ;******************************************************************************* 05966 ;* * 05967 ;* COPYPOSXY * 05968 ;* * 05969 ;* Copy x and y components (coordinates) of position vector * 05970 ;* * 05971 ;******************************************************************************* 05972 05973 ; DESCRIPTION 05974 ; 05975 ; Copies the x and y components (coordinates) of a position vector. 05976 ; 05977 ; INPUT 05978 ; 05979 ; X = Destination position vector index. Used values are: 0..48. 05980 ; Y = Source position vector index. Used values are: 0..48. 05981 05982 COPYPOSXY LDA XPOSSIGN,Y ; 05983 STA XPOSSIGN,X ; 05984 LDA XPOSHI,Y ; 05985 STA XPOSHI,X ; 05986 LDA YPOSSIGN,Y ; 05987 STA YPOSSIGN,X ; 05988 LDA YPOSHI,Y ; 05989 STA YPOSHI,X ; 05990 LDA XPOSLO,Y ; 05991 STA XPOSLO,X ; 05992 LDA YPOSLO,Y ; 05993 STA YPOSLO,X ; 05994 SKIP111 RTS ; Return 05995 05996 ;******************************************************************************* 05997 ;* * 05998 ;* DOCKING * 05999 ;* * 06000 ;* Handle docking at starbase, launch and return of transfer vessel * 06001 ;* * 06002 ;******************************************************************************* 06003 06004 ; DESCRIPTION 06005 ; 06006 ; Handles docking at a starbase, launching and returning the transfer vessel, 06007 ; and repairing our starship's subsystems. 06008 ; 06009 ; This subroutine changes, if in Front view, the PLAYER-PLAYFIELD priority such 06010 ; that PLAYERs like the starbase appear behind the cross hairs, which are part 06011 ; of the PLAYFIELD. 06012 ; 06013 ; BUG (at $ACEE): In Front view, the specific order of PLAYERs (PL0..4) and 06014 ; PLAYFIELD colors (PF0..4) is, from front to back: 06015 ; 06016 ; PL4 > PF0, PF1, PF2 > PL0 > PL1 > PL2 > PL3 > PF4 (BGR) 06017 ; 06018 ; This makes the starbase appear behind the cross hairs, but also behind the 06019 ; stars, as both cross hairs and stars are part of the PLAYFIELD - a rarely 06020 ; noticed glitch. 06021 ; 06022 ; Note also that, as an exception of the rule, PLAYER4 (transfer vessel) is 06023 ; displayed before the PLAYFIELD. Thus, the transfer vessel appears in front of 06024 ; the cross hairs! 06025 ; 06026 ; In Aft view, the arrangement is reversed: PLAYERs are arranged in front of the 06027 ; PLAYFIELD. The specific order of PLAYERs (PL0..4) and PLAYFIELD colors 06028 ; (PF0..4) is, from front to back: 06029 ; 06030 ; PL0 > PL1 > PL2 > PL3 > PL4 > PF0, PF1, PF2 > PF4 (BGR) 06031 ; 06032 ; In this case, both the starbase and the transfer vessel appear in front of the 06033 ; cross hairs! Suggested fix: None, technically not possible. 06034 ; 06035 ; 06036 ; The starbase is tracked and the PLAYER0..2 shape types are set to STARBASE 06037 ; RIGHT, STARBASE LEFT, and STARBASE CENTER, respectively, combining them into a 06038 ; 3-part starbase shape. 06039 ; 06040 ; If this sector is still marked as a starbase sector but no more so on the 06041 ; Galactic Chart (if in the meantime either Zylon units have surrounded this 06042 ; sector and destroyed the starbase or you have destroyed the starbase with a 06043 ; photon torpedo) then the noise sound pattern SHIELD EXPLOSION is played in 06044 ; subroutine NOISE ($AEA8) and code execution returns. 06045 ; 06046 ; Otherwise a minimum distance to the starbase of +32 (+$0020) is enforced 06047 ; and the conditions for a successful docking are checked: 06048 ; 06049 ; DOCKING CONDITIONS 06050 ; 06051 ; A docking is successful if all of the following conditions are met: 06052 ; 06053 ; (1) The PLAYER2 (STARBASE CENTER) column number is in 120..135. 06054 ; 06055 ; BUG (at $AD39): At first glance, the PLAYER column interval of 120..135 06056 ; corresponds to an almost symmetric interval of -8..+7 PM pixels relative 06057 ; to the horizontal center of the PLAYFIELD, at PLAYER column number 128 06058 ; (48 PM pixels offset to left PLAYFIELD border + 80 PM pixels to the 06059 ; PLAYFIELD center). This is correct only if the PLAYER column number were 06060 ; to designate the horizontal center of the PLAYER. However it designates 06061 ; its left edge! Thus the used pixel column number range 120..135 creates 06062 ; an asymmetric horizontal docking position: A docking is successful if the 06063 ; horizontal position of the starbase shape's center is roughly -5..+10 PM 06064 ; pixels relative to the horizontal center of the PLAYFIELD. Suggested fix: 06065 ; Replace SBC #120 with SBC #117. This leads to an interval of -8..+7 06066 ; pixels relative to the horizontal center of the PLAYFIELD and better 06067 ; symmetry in the horizontal docking position. 06068 ; 06069 ; (2) The PLAYER2 (STARBASE CENTER) row number is in 104..119. 06070 ; 06071 ; BUG (at $AD43): The PLAYER row interval of 104..119 corresponds to an 06072 ; asymmetric interval of -20..-5 PM pixels relative to the vertical center 06073 ; of the PLAYFIELD, at pixel row number 80 or PLAYER row number 124. It 06074 ; lets you dock at a starbase that "sits" on top of the horizontal cross 06075 ; hairs but not at one that "hangs" from them. Suggested fix: Replace SBC 06076 ; #104 with SBC #108. This leads to an interval of -8..+7 pixels relative 06077 ; to the vertical center of the PLAYFIELD (assuming a PLAYER2 shape of 16 06078 ; pixel height, which is typical during docking) and better symmetry in the 06079 ; vertical docking position. 06080 ; 06081 ; (3) The starbase is in correct distance in front of our starship: The 06082 ; starbase's z-coordinate must be < +512 (+$02**) . 06083 ; 06084 ; (4) Our starship is horizontally level with the starbase: The starbase's 06085 ; y-coordinate must be < +256 (+$01**) . 06086 ; 06087 ; (5) Our starship is at a complete halt. 06088 ; 06089 ; DOCKING SUCCESSFUL 06090 ; 06091 ; If the conditions for a successful docking are met, the subsequent docking and 06092 ; transfer operation can be divided in the following states, starting with state 06093 ; NOT DOCKED: 06094 ; 06095 ; (1) NOT DOCKED 06096 ; 06097 ; The docking state is set to ORBIT ESTABLISHED and the title line is 06098 ; updated with "ORBIT ESTABLISHED". 06099 ; 06100 ; (2) ORBIT ESTABLISHED 06101 ; 06102 ; After waiting until the title line "ORBIT ESTABLISHED" has disappeared, 06103 ; the transfer vessel is initialized and launched: The PLAYER4 shape type 06104 ; is set to TRANSFER VESSEL. Its position vector is set to a position above 06105 ; and in front of our starship, but behind the starbase: 06106 ; 06107 ; x-coordinate := +0..+255 (+$00**) 06108 ; y-coordinate := +256..+511 (+$01**) 06109 ; z-coordinate := +4096..+4351 (+$10**) 06110 ; 06111 ; Its velocity vector is set to 06112 ; 06113 ; x-velocity := +1 06114 ; y-velocity := -1 06115 ; z-velocity := -7 06116 ; 06117 ; This will move the transfer vessel from behind the starbase into a 06118 ; direction toward and a little to the lower right of our starship. The 06119 ; lifetime of the transfer vessel (and its return journey) is set to 129 06120 ; game loop iterations. Finally, the docking state is set to RETURN 06121 ; TRANSFER VESSEL. 06122 ; 06123 ; (3) RETURN TRANSFER VESSEL 06124 ; 06125 ; After checking if the transfer vessel has passed behind our starship, the 06126 ; beeper sound pattern ACKNOWLEDGE is played in subroutine BEEP ($B3A6), 06127 ; the title line is updated with "TRANSFER COMPLETE", our starship's 06128 ; subsystems are repaired, and our starship's ENERGY readout is restored to 06129 ; 9999 energy units. by inverting the z-velocity the velocity vector of the 06130 ; transfer vessel is changed to 06131 ; 06132 ; x-velocity := +1 06133 ; y-velocity := -1 06134 ; z-velocity := +7 06135 ; 06136 ; thus launching the transfer vessel on its return journey to the starbase. 06137 ; The docking state is set to TRANSFER COMPLETE. Finally, the screen is 06138 ; updated in subroutine UPDSCREEN ($B07B). 06139 ; 06140 ; (4) TRANSFER COMPLETE 06141 ; 06142 ; This docking state marks the end of a successful docking and transfer 06143 ; operation. 06144 ; 06145 ; DOCKING ABORTED 06146 ; 06147 ; If the docking conditions above are not met and the docking state is already 06148 ; ORBIT ESTABLISHED or RETURN TRANSFER VESSEL then the message "DOCKING ABORTED" 06149 ; is displayed and the docking state is set to NOT DOCKED. 06150 06151 DOCKING LDA ISSTARBASESECT ; Return if not in starbase sector 06152 BEQ SKIP111 ; 06153 06154 LDA SHIPVIEW ; Skip if not in Front view 06155 BNE SKIP112 ; 06156 LDA #$14 ; GTIA: Enable PLAYER4, prio: PFs > PLs > BGR (!) 06157 STA PRIOR ; (Cross hairs in front of PLAYERs) 06158 06159 SKIP112 LDA #2 ; Track starbase (PLAYER2) 06160 STA TRACKDIGIT ; 06161 06162 ;** Initialize starbase shape ************************************************** 06163 LDA #SHAP.STARBASEC ; PLAYER2 is STARBASE CENTER (shape type 3) 06164 STA PL2SHAPTYPE ; 06165 LDA #SHAP.STARBASEL ; PLAYER1 is STARBASE LEFT (shape type 2) 06166 STA PL1SHAPTYPE ; 06167 LDA #SHAP.STARBASER ; PLAYER0 is STARBASE RIGHT (shape type 4) 06168 STA PL0SHAPTYPE ; 06169 06170 LDA #255 ; Prep starbase lifetime := 255 game loops (infinite) 06171 06172 LDX CURRSECTOR ; Skip if starbase in current sector 06173 LDY GCMEMMAP,X ; 06174 BMI SKIP113 ; 06175 06176 LDA #0 ; Prep starbase lifetime := 0 game loops (fast death) 06177 06178 SKIP113 STA PL0LIFE ; PLAYER0 lifetime := either 0 or 255 game loops 06179 STA PL1LIFE ; PLAYER1 lifetime := either 0 or 255 game loops 06180 STA PL2LIFE ; PLAYER2 lifetime := either 0 or 255 game loops 06181 STA ISSTARBASESECT ; Store starbase-in-sector flag 06182 BMI SKIP114 ; Skip if starbase in current sector 06183 06184 LDY #2 ; Init explosion at PLAYER2 (STARBASE CENTER) 06185 JSR INITEXPL ; 06186 06187 LDX #$0A ; Play noise sound pattern SHIELD EXPLOSION, return 06188 JMP NOISE ; 06189 06190 ;*** Keep minimum distance to starbase ***************************************** 06191 SKIP114 LDA PL2ZPOSHI ; Skip if starbase z-coordinate > +255 (+$00**) 06192 BNE SKIP115 ; 06193 06194 LDA PL2ZPOSLO ; Approach starbase not closer than +32 (+$0020) 06195 CMP #32 ; 06196 BCS SKIP115 ; 06197 INC PL2ZPOSLO ; ...else push starbase back 06198 06199 ;*** Check if in docking range ************************************************* 06200 SKIP115 LDA PL2COLUMN ; Abort docking if PLAYER column number of... 06201 SEC ; ...PLAYER2 (STARBASE CENTER) not in 120..135. 06202 SBC #120 ; (!) 06203 CMP #16 ; 06204 BCS SKIP116 ; 06205 06206 LDA PL2ROWNEW ; Abort docking if PLAYER row number of... 06207 SEC ; ...PLAYER2 (STARBASE CENTER) not in 104..119. 06208 SBC #104 ; (!) 06209 CMP #16 ; 06210 BCS SKIP116 ; 06211 06212 LDA PL2ZPOSHI ; Abort docking if... 06213 CMP #2 ; ... z-coordinate of starbase >= +512 (+$02**) 06214 BCS SKIP116 ; 06215 06216 LDA PL2ZPOSSIGN ; Abort docking... 06217 AND PL2YPOSSIGN ; ...if starbase not in front and upper screen half 06218 EOR #$01 ; 06219 ORA VELOCITYLO ; ...if our starship's velocity not zero 06220 ORA PL2YPOSHI ; ...if starbase not roughly vertically centered 06221 ORA NEWVELOCITY ; ...if our starship's new velocity not zero 06222 BEQ SKIP119 ; Else skip and handle docking 06223 06224 ;*** Docking aborted *********************************************************** 06225 SKIP116 LDA DOCKSTATE ; Skip if DOCKSTATE is NOT DOCKED, TRANSFER COMPLETE 06226 CMP #2 ; 06227 BCC SKIP117 ; 06228 06229 LDY #$1F ; Set title phrase "DOCKING ABORTED" 06230 JSR SETTITLE ; 06231 06232 SKIP117 LDA #0 ; DOCKSTATE := NOT DOCKED 06233 STA DOCKSTATE ; 06234 SKIP118 RTS ; Return 06235 06236 ;*** Docking successful, check docking state *********************************** 06237 SKIP119 BIT DOCKSTATE ; Check DOCKSTATE 06238 BVS SKIP120 ; If DOCKSTATE = ORBIT ESTABLISHED hide title line 06239 BMI SKIP122 ; If DOCKSTATE = RETURN TRANSFER VESSEL return it 06240 LDA DOCKSTATE ; 06241 BNE SKIP118 ; Return if DOCKSTATE not NOT DOCKED 06242 DEC DOCKSTATE ; DOCKSTATE := ORBIT ESTABLISHED 06243 06244 LDY #$1C ; Set title phrase "ORBIT ESTABLISHED" and return 06245 JMP SETTITLE ; 06246 06247 ;*** Orbit established ********************************************************* 06248 SKIP120 LDX #0 ; Enqueue new, empty title phrase 06249 STX NEWTITLEPHR ; 06250 06251 LDY TITLEPHR ; Return if "ORBIT ESTABLISHED" still displayed 06252 BNE SKIP118 ; 06253 06254 ;*** Launch transfer vessel **************************************************** 06255 LDA #SHAP.TRANSVSSL ; PLAYER4 is TRANSFER VESSEL (shape 5) 06256 STA PL4SHAPTYPE ; 06257 06258 LDA #1 ; Place transfer vessel behind starbase: 06259 STA PL4ZPOSSIGN ; x-coordinate := +0..+255 (+$00**) 06260 STA PL4XPOSSIGN ; y-coordinate := +256..+511 (+$01**) 06261 STA PL4YPOSSIGN ; z-coordinate := +4096..+4351 (+$10**) 06262 STA PL4YPOSHI ; 06263 STA PL4XVEL ; Move transfer vessel toward our starship: 06264 LDA #$10 ; x-velocity := +1 06265 STA PL4ZPOSHI ; y-velocity := -1 06266 LDA #$00 ; z-velocity := -7 06267 STA PL4XPOSHI ; 06268 LDA #NEG!7 ; 06269 STA PL4ZVEL ; 06270 LDA #NEG!1 ; DOCKSTATE := RETURN TRANSFER VESSEL 06271 STA DOCKSTATE ; 06272 STA PL4YVEL ; 06273 STA PL4LIFE ; Transfer vessel lifetime := 129 game loops 06274 SKIP121 RTS ; Return 06275 06276 ;*** Return transfer vessel **************************************************** 06277 SKIP122 LDA PL4ZPOSSIGN ; Return if transfer vessel in front of our starship 06278 BNE SKIP121 ; 06279 06280 LDX #$0C ; Play beeper sound pattern ACKNOWLEGDE 06281 JSR BEEP ; 06282 06283 LDY #$21 ; Set title phrase "TRANSFER COMPLETE" 06284 JSR SETTITLE ; 06285 06286 LDX #5 ; Repair all 6 subsystems 06287 LOOP041 LDA PANELTXTTAB+73,X ; 06288 STA GCSTATPHO,X ; 06289 DEX ; 06290 BPL LOOP041 ; 06291 06292 LDA #CCS.COL2!CCS.9 ; Set starship's ENERGY readout to "9999" in COLOR2 06293 LDX #3 ; 06294 LOOP042 STA ENERGYD1,X ; 06295 DEX ; 06296 BPL LOOP042 ; 06297 06298 LDA #7 ; Move transfer vessel back toward starbase: 06299 STA PL4ZVEL ; x-velocity := -1 06300 LDA #NEG!1 ; y-velocity := +1 06301 STA PL4XVEL ; z-velocity := +7 06302 LDA #1 ; 06303 STA PL4YVEL ; 06304 06305 STA DOCKSTATE ; DOCKSTATE := TRANSFER COMPLETE 06306 JMP UPDSCREEN ; Update screen and return 06307 06308 ;******************************************************************************* 06309 ;* * 06310 ;* MODDLST * 06311 ;* * 06312 ;* Modify Display List * 06313 ;* * 06314 ;******************************************************************************* 06315 06316 ; DESCRIPTION 06317 ; 06318 ; Modifies the Display List to show and hide title, headers, and the Control 06319 ; Panel Display. 06320 ; 06321 ; INPUT 06322 ; 06323 ; A = Number of bytes to copy into the Display List 06324 ; X = Offset into Display List DSPLST ($0280) 06325 ; Y = Offset into Display List fragment table DLSTFRAG ($BA62). If Y = $80 06326 ; then no bytes are copied but the specified locations of the Display List 06327 ; are overwritten with Display List instruction $0D (one row of 06328 ; GRAPHICS7). 06329 ; 06330 ; Used values are: 06331 ; 06332 ; A X Y 06333 ; $08 $5F $00 -> Show Control Panel Display (bottom text window) 06334 ; $08 $5F $80 -> Hide Control Panel Display (bottom text window) 06335 ; $07 $0F $23 -> Show title line 06336 ; $07 $0F $80 -> Hide title line 06337 ; $08 $02 $1B -> Show Display List header line of Front view 06338 ; $08 $02 $13 -> Show Display List header line of Aft view 06339 ; $08 $02 $0B -> Show Display List header line of Long-Range Scan view 06340 ; $08 $02 $08 -> Show Display List header line of Galactic Chart view 06341 06342 L.NUMBYTES = $6A ; Number of bytes to copy 06343 06344 MODDLST SEI ; Disable IRQ 06345 STA L.NUMBYTES ; Save number of bytes to copy 06346 06347 LOOP043 LDA VCOUNT ; Wait for ANTIC line counter >= 124 (PLAYFIELD... 06348 CMP #124 ; ...bottom) before changing the Display List 06349 BCC LOOP043 ; 06350 06351 LOOP044 LDA DLSTFRAG,Y ; Load byte from Display List fragment table 06352 INY ; 06353 BPL SKIP123 ; Skip if fragment table index < $80 06354 LDA #$0D ; Prep Display List instruction $0D (GRAPHICS7) 06355 SKIP123 STA DSPLST,X ; Store byte in Display List 06356 INX ; 06357 DEC L.NUMBYTES ; 06358 BNE LOOP044 ; Copy next byte 06359 06360 CLI ; Enable IRQ 06361 RTS ; Return 06362 06363 ;******************************************************************************* 06364 ;* * 06365 ;* CLRPLAYFIELD * 06366 ;* * 06367 ;* Clear PLAYFIELD memory * 06368 ;* * 06369 ;******************************************************************************* 06370 06371 ; DESCRIPTION 06372 ; 06373 ; Clears PLAYFIELD memory from $1000 to $1FFF. 06374 ; 06375 ; This subroutine sets the start address of the memory to be cleared then code 06376 ; execution continues into subroutine CLRMEM ($AE0F) where the memory is 06377 ; actually cleared. 06378 06379 CLRPLAYFIELD LDA #$10 06380 06381 ;******************************************************************************* 06382 ;* * 06383 ;* CLRMEM * 06384 ;* * 06385 ;* Clear memory * 06386 ;* * 06387 ;******************************************************************************* 06388 06389 ; DESCRIPTION 06390 ; 06391 ; Clears memory from a given start address to memory address $1FFF. This 06392 ; subroutine is called in the following situations: 06393 ; 06394 ; (1) In routine INITCOLD ($A14A) at the beginning of the game to initialize 06395 ; the game's variables 06396 ; 06397 ; (2) In subroutine CLRPLAYFIELD ($AE0D) to clear PLAYFIELD memory. 06398 ; 06399 ; As a side effect this subroutine also clears the saved number of space objects 06400 ; and the lock-on flag. 06401 ; 06402 ; INPUT 06403 ; 06404 ; A = Start address (high byte) of memory to be cleared. Used values are: 06405 ; $02 -> Clear memory $0200..$1FFF during game initialization 06406 ; $10 -> Clear PLAYFIELD memory $1000..$1FFF 06407 06408 CLRMEM STA MEMPTR+1 ; Store start address (high byte) to be cleared 06409 LDA #0 ; Store start address (low byte) to be cleared 06410 TAY ; 06411 STA MEMPTR ; 06412 06413 STA ISINLOCKON ; Clear lock-on flag 06414 STA OLDMAXSPCOBJIND ; Clear saved number of space objects 06415 06416 LOOP045 STA (MEMPTR),Y ; Clear memory location 06417 INY ; 06418 BNE LOOP045 ; 06419 06420 INC MEMPTR+1 ; Next page (= 256-byte block) 06421 LDY MEMPTR+1 ; 06422 CPY #$20 ; 06423 TAY ; 06424 BCC LOOP045 ; Loop until memory address $2000 reached 06425 RTS ; Return 06426 06427 ;******************************************************************************* 06428 ;* * 06429 ;* TRIGGER * 06430 ;* * 06431 ;* Handle joystick trigger * 06432 ;* * 06433 ;******************************************************************************* 06434 06435 ; DESCRIPTION 06436 ; 06437 ; This subroutine handles the joystick trigger and launches one of our 06438 ; starship's photon torpedo. If a target is in full lock-on then a second photon 06439 ; torpedo is prepared for automatic launch in the next game loop iteration. 06440 ; 06441 ; DETAILS 06442 ; 06443 ; If the trigger is pressed then reset the idle counter and, if not in 06444 ; hyperwarp, launch a photon torpedo with the following steps: 06445 ; 06446 ; (1) If the trigger was pressed in this game loop iteration, a photon torpedo 06447 ; will be launched if a previously launched photon torpedo is already under 06448 ; way for at least 255 - 232 = 23 game loop iterations. This avoids firing 06449 ; photon torpedoes too rapidly. 06450 ; 06451 ; (2) Start tracking a space object. If it is in full lock-on, set up the 06452 ; lock-on timer, activate photon torpedo tracking, and tweak the last saved 06453 ; trigger state such that our other photon torpedo (if available) is 06454 ; launched automatically in the next game loop iteration. 06455 ; 06456 ; (3) If the Photon Torpedoes are destroyed, do nothing. 06457 ; 06458 ; (4) If the Photon Torpedoes are damaged, launch a photon torpedo from the 06459 ; same barrel than the previous one. 06460 ; 06461 ; (5) If the Photon Torpedoes are not damaged, launch a photon torpedo from the 06462 ; other barrel. 06463 ; 06464 ; (6) Set the lifetime of our starship's photon torpedo to infinite, set the 06465 ; PLAYER shape to PHOTON TORPEDO. 06466 ; 06467 ; (7) Initialize the position vector of our starship's photon torpedo to: 06468 ; 06469 ; x-coordinate := +256 (+$0100) (Right barrel) 06470 ; -256 (-$FF00) (Left barrel) 06471 ; y-coordinate := -256 (-$FF00) 06472 ; z-coordinate := +1 (+$0001) 06473 ; 06474 ; (8) Initialize the velocity vector of our starship's photon torpedo to: 06475 ; 06476 ; x-velocity := +0 06477 ; y-velocity := +0 06478 ; z-velocity := +102 (All views but Aft view) 06479 ; -102 (Aft view) 06480 ; 06481 ; (9) Subtract 10 energy units for launching our starship's photon torpedo. 06482 ; 06483 ; (10) Play the noise sound pattern PHOTON TORPEDO LAUNCHED by continuing code 06484 ; execution into subroutine NOISE ($AEA8). 06485 06486 TRIGGER LDA OLDTRIG0 ; Prep last trigger state 06487 06488 LDY TRIG0 ; Copy current trigger state 06489 STY OLDTRIG0 ; 06490 BNE SKIP124 ; Return if trigger currently not pressed 06491 06492 STY IDLECNTHI ; Reset idle counter 06493 06494 LDX WARPSTATE ; Return if hyperwarp engaged 06495 BNE SKIP124 ; 06496 06497 LDX BARRELNR ; Prep barrel number (0 -> left, 1 -> right) 06498 06499 CMP #1 ; If trigger is newly pressed -> handle tracking... 06500 BEQ SKIP125 ; ...and launch our starship's photon torpedo... 06501 BCS SKIP127 ; ...else launch our starship's photon torpedo only 06502 SKIP124 RTS ; Return 06503 06504 ;*** Set up our starship's photon torpedo tracking ***************************** 06505 SKIP125 LDA PL3LIFE,X ; Return if torpedo's lifetime >= 232 game loops 06506 CMP #232 ; 06507 BCS SKIP124 ; 06508 06509 LDY TRACKDIGIT ; Store index of tracked space object 06510 STY PLTRACKED ; 06511 06512 LDA #12 ; Prep lock-on lifetime := 12 game loops 06513 LDY ISINLOCKON ; If target is in full lock-on... 06514 STY ISTRACKING ; ...activate photon torpedo tracking 06515 06516 BEQ SKIP126 ; Skip if target not in full lock-on 06517 LDA #0 ; Prep lock-on lifetime := 0 game loops 06518 SKIP126 STA LOCKONLIFE ; Store lock-on lifetime (either 0 or 12 game loops) 06519 06520 ;*** Launch our starship's photon torpedo ************************************** 06521 SKIP127 STY OLDTRIG0 ; Update last trigger state 06522 BIT GCSTATPHO ; Return if Photon Torpedoes are destroyed 06523 BVS SKIP124 ; 06524 06525 BMI SKIP128 ; If Photon Torpedoes damaged launch from same barrel 06526 TXA ; ...else switch barrel from which to launch torpedo 06527 EOR #$01 ; 06528 STA BARRELNR ; 06529 06530 SKIP128 TXA ; SUMMARY: Our starship's photon torpedo's... 06531 STA PL3XPOSSIGN,X ; x-coordinate := +256 (+$0100) (right barrel) 06532 LDA BARRELXTAB,X ; x-coordinate := -256 (-$FF00) (left barrel) 06533 STA PL3XPOSHI,X ; y-coordinate := -256 (-$FF00) 06534 LDA #255 ; z-coordinate := +1 (+$0001) 06535 STA PL3LIFE,X ; ...lifetime := 255 game loops 06536 STA PL3YPOSHI,X ; 06537 LDA #0 ; 06538 STA PL3SHAPTYPE,X ; PLAYER3 or PLAYER4 is PHOTON TORPEDO (shape type 0) 06539 STA PL3ZPOSHI,X ; 06540 STA PL3XPOSLO,X ; 06541 STA PL3YPOSSIGN,X ; 06542 STA PL3YPOSLO,X ; 06543 LDA #1 ; 06544 STA PL3ZPOSSIGN,X ; 06545 STA PL3ZPOSLO,X ; 06546 06547 LDA SHIPVIEW ; SUMMARY: Our starship's photon torpedo's... 06548 LSR A ; x-velocity := +0 06549 ROR A ; y-velocity := +0 06550 ORA #102 ; z-velocity := +102 (Other views) 06551 STA PL3ZVEL,X ; z-velocity := -102 (Aft view) 06552 LDA #0 ; 06553 STA PL3XVEL,X ; 06554 STA PL3YVEL,X ; 06555 06556 LDX #2 ; ENERGY := ENERGY - 10 for launching photon torpedo 06557 JSR DECENERGY ; 06558 06559 LDX #$00 ; Play noise sound pattern PHOTON TORPEDO LAUNCHED 06560 06561 ;******************************************************************************* 06562 ;* * 06563 ;* NOISE * 06564 ;* * 06565 ;* Copy noise sound pattern * 06566 ;* * 06567 ;******************************************************************************* 06568 06569 ; DESCRIPTION 06570 ; 06571 ; Copies a 10-byte noise sound pattern from table NOISEPATTAB ($BF20). The first 06572 ; 8 bytes are copied to the noise sound pattern area NOISETORPTIM 06573 ; ($DA)..NOISELIFE ($E1), the remaining 2 bytes are copied to audio registers 06574 ; AUDCTL ($D208) and AUDF3 ($D204). The noise sound pattern is automatically 06575 ; played in subroutine SOUND ($B2AB). 06576 ; 06577 ; NOTE: The first 8 bytes of each pattern in table NOISEPATTAB ($BF20) are 06578 ; copied in reverse order from memory. See subroutine SOUND ($B2AB) for details 06579 ; on the noise sound patterns stored in NOISEPATTAB ($BF20). 06580 ; 06581 ; Playing a SHIELD EXPLOSION or ZYLON EXPLOSION noise sound pattern overrides a 06582 ; currently playing PHOTON TORPEDO LAUNCHED noise sound pattern. 06583 ; 06584 ; Playing a PHOTON TORPEDO LAUNCHED noise sound pattern overrides a currently 06585 ; playing PHOTON TORPEDO LAUNCHED noise sound pattern if the latter has < 24 06586 ; TICKs to play. 06587 ; 06588 ; INPUT 06589 ; 06590 ; X = Offset into table NOISEPATTAB ($BF20) to index noise sound patterns. 06591 ; Used values are: 06592 ; $00 -> PHOTON TORPEDO LAUNCHED 06593 ; $0A -> SHIELD EXPLOSION (either our starship or a starbase explodes) 06594 ; $14 -> ZYLON EXPLOSION 06595 06596 NOISE TXA ; Skip if SHIELD EXPLOSION or ZYLON EXPLOSION playing 06597 BNE SKIP129 ; 06598 06599 LDA NOISELIFE ; Return if PHOTON TORPEDO LAUNCHED noise sound pat. 06600 CMP #24 ; ...playing for yet more than 24 TICKs 06601 BCS SKIP130 ; 06602 06603 SKIP129 LDY #7 ; Copy noise sound pattern (in reverse order) 06604 LOOP046 LDA NOISEPATTAB,X ; 06605 STA NOISETORPTIM,Y ; 06606 INX ; 06607 DEY ; 06608 BPL LOOP046 ; 06609 06610 LDA NOISEPATTAB,X ; Copy AUDCTL from noise sound pattern table 06611 STA AUDCTL ; 06612 LDA NOISEPATTAB+1,X ; Copy AUDF3 from noise sound pattern table 06613 STA AUDF3 ; 06614 06615 SKIP130 RTS ; Return 06616 06617 ;******************************************************************************* 06618 ;* * 06619 ;* HOMINGVEL * 06620 ;* * 06621 ;* Calculate homing velocity of our starship's photon torpedo 0 or 1 * 06622 ;* * 06623 ;******************************************************************************* 06624 06625 ; DESCRIPTION 06626 ; 06627 ; Calculates the x (or y) velocity vector component of our starship's photon 06628 ; torpedo 0 or 1 when it is tracking (homing in on) a target space object. 06629 ; 06630 ; Our starship's photon torpedo's x (or y) velocity vector component depends on 06631 ; the PLAYER column (or row) number difference between the target PLAYER and our 06632 ; starship's photon torpedo PLAYER in Player/Missile (PM) pixels. This 06633 ; difference is used as an index to pick the new x (or y) velocity vector 06634 ; component of our starship's photon torpedo from table HOMVELTAB ($BFC9): 06635 ; 06636 ; +---------------+--------------+ 06637 ; | Difference in | New Velocity | 06638 ; | PM Pixels | Component | 06639 ; +---------------+--------------+ 06640 ; | >= +7 | -64 | 06641 ; | +6 | -56 | 06642 ; | +5 | -48 | 06643 ; | +4 | -40 | 06644 ; | +3 | -24 | 06645 ; | +2 | -16 | 06646 ; | +1 | -8 | 06647 ; | 0 | 0 | 06648 ; | -1 | +8 | 06649 ; | -2 | +16 | 06650 ; | -3 | +24 | 06651 ; | -4 | +40 | 06652 ; | -5 | +48 | 06653 ; | -6 | +56 | 06654 ; | <= -7 | +64 | 06655 ; +---------------+--------------+ 06656 ; 06657 ; INPUT 06658 ; 06659 ; A = PLAYER column (or row) number difference between the target PLAYER 06660 ; and our starship's photon torpedo PLAYER in Player/Missile pixels 06661 ; 06662 ; CARRY = Sign of the PLAYER column (or row) number difference. Used values 06663 ; are: 06664 ; 0 -> Negative difference (target PLAYER column (or row) number < our 06665 ; starship's photon torpedo PLAYER column (or row) number 06666 ; 1 -> Positive difference (target PLAYER column (or row) number >= our 06667 ; starship's photon torpedo PLAYER column (or row) number 06668 ; 06669 ; OUTPUT 06670 ; 06671 ; A = New velocity vector component of our starship's photon torpedo in 06672 06673 L.VELSIGN = $6A ; Saves velocity sign 06674 06675 HOMINGVEL LDY #NEG ; Preload negative velocity sign 06676 BCS SKIP131 ; Skip if difference is positive 06677 06678 EOR #$FF ; Invert to get absolute value of difference 06679 LDY #0 ; Preload positive velocity sign 06680 06681 SKIP131 STY L.VELSIGN ; Save velocity sign 06682 CMP #8 ; 06683 BCC SKIP132 ; 06684 LDA #7 ; Limit difference to 0..7 06685 SKIP132 TAY ; 06686 LDA L.VELSIGN ; Reload velocity sign 06687 ORA HOMVELTAB,Y ; Combine with homing velocity from table 06688 RTS ; Return 06689 06690 ;******************************************************************************* 06691 ;* * 06692 ;* DAMAGE * 06693 ;* * 06694 ;* Damage or destroy one of our starship's subsystems * 06695 ;* * 06696 ;******************************************************************************* 06697 06698 ; DESCRIPTION 06699 ; 06700 ; Damages or destroys one of our starship's subsystems. There are 6 subsystems: 06701 ; 06702 ; (1) Photon Torpedoes 06703 ; (2) Engines 06704 ; (3) Shields 06705 ; (4) Attack Computer 06706 ; (5) Long-Range Scan 06707 ; (6) Subspace Radio 06708 ; 06709 ; Their status is stored and displayed in the Galactic Chart Panel Display by 06710 ; the colored letters PESCLR. The color of each letter represents the 06711 ; subsystem's status: 06712 ; 06713 ; +---------------+------------------+ 06714 ; | Letter Color | Subsystem Status | 06715 ; +---------------+------------------+ 06716 ; | {LIGHT GREEN} | OK | 06717 ; | {CORN YELLOW} | Damaged | 06718 ; | {PINK} | Destroyed | 06719 ; +---------------+------------------+ 06720 ; 06721 ; This subroutine first makes sure that we are not in demo mode. Then it picks a 06722 ; random value in 0..255 and the damage probability value. The latter value 06723 ; depends on the mission level and is picked from table DAMAGEPROBTAB ($BF10): 06724 ; 06725 ; +-----------+-------------------+---------------+ 06726 ; | Mission | Damage | Damage | 06727 ; | Level | Probability Value | Probability | 06728 ; +-----------+-------------------+---------------+ 06729 ; | NOVICE | 0 | 0% ( 0:256) | 06730 ; | PILOT | 80 | 31% ( 80:256) | 06731 ; | WARRIOR | 180 | 70% (180:256) | 06732 ; | COMMANDER | 254 | 99% (254:256) | 06733 ; +-----------+-------------------+---------------+ 06734 ; 06735 ; If the random number is lower than the damage probability value, a randomly 06736 ; picked subsystem is about to get damaged (or destroyed). There is a built-in 06737 ; upfront probability of 25% (2:8) that no subsystem gets harmed. 06738 ; 06739 ; If the picked subsystem is already destroyed then another subsystem is picked. 06740 ; 06741 ; Then the title phrase offset is picked from table DAMAGEPHRTAB ($BF14) to 06742 ; display the damaged subsystem in the title line. Next, color bits are picked 06743 ; that indicate a damaged system. 06744 ; 06745 ; If the Zylon photon torpedo's lifetime >= 30 game loop iterations the 06746 ; subsystem will not only be damaged but destroyed. 06747 ; 06748 ; NOTE: The Zylon photon torpedo lifetime decreases from 62 to 0 game loop 06749 ; iterations. With a remaining lifetime >= 30 game loop iterations it is 06750 ; considered strong enough to destroy one of our starship's subsystems. There 06751 ; are two exceptions to this rule: If the Attack Computer was picked to be 06752 ; destroyed it will be damaged only - not destroyed - if the Long-Range Scan has 06753 ; been already destroyed, and vice versa. 06754 ; 06755 ; Then the title phrase offset from table DESTROYPHRTAB ($BF1A) is picked to 06756 ; display the destroyed subsystem in the title line. Next, color bits are picked 06757 ; that indicate a destroyed system. 06758 ; 06759 ; The color of the subsystem's status letter is adjusted in the Galactic Chart 06760 ; Panel Display. Next, the title phrase describing the subsystem's status is 06761 ; enqueued for display in the title line. If the Attack Computer has been 06762 ; destroyed it is switched off and the PLAYFIELD is cleared. The title line is 06763 ; updated with the "DAMAGE CONTROL" message. Finally, the beeper sound pattern 06764 ; DAMAGE REPORT is played in subroutine BEEP ($B3A6). 06765 06766 DAMAGE BIT ISDEMOMODE ; Return if in demo mode 06767 BMI SKIP137 ; 06768 06769 ;*** Damage some subsystem ***************************************************** 06770 LDX MISSIONLEVEL ; Prep mission level 06771 LOOP047 LDA RANDOM ; Return if random number >= damage probability 06772 CMP DAMAGEPROBTAB,X ; ...(the latter depends on mission level) 06773 BCS SKIP137 ; 06774 06775 AND #$07 ; Randomly pick 1 of 6 subsystems 06776 CMP #6 ; Return if no subsystem picked 06777 BCS SKIP137 ; 06778 06779 TAX ; 06780 LDA GCSTATPHO,X ; Get picked subsystem status letter 06781 ASL A ; Check bit B6 (= destroyed) of letter code 06782 BMI LOOP047 ; Try again if subsystem already destroyed 06783 06784 LDA PL2LIFE ; Load Zylon photon torpedo lifetime... 06785 CMP #30 ; ...and compare it to 30 game loops 06786 06787 LDA #CCS.COL2 ; Preload COLOR2 text color bits (= damaged status) 06788 LDY DAMAGEPHRTAB,X ; Preload title phrase offset of damaged subsystem 06789 06790 BCC SKIP135 ; Skip if Zylon torpedo lifetime < 30 game loops 06791 06792 CPX #3 ; Skip if selected subsystem not Attack Computer 06793 BNE SKIP133 ; 06794 BIT GCSTATLRS ; Skip if Long-Range Scan already destroyed 06795 BVS SKIP135 ; 06796 SKIP133 CPX #4 ; Skip if selected subsystem is not Long-Range Scan 06797 BNE SKIP134 ; 06798 BIT GCSTATCOM ; Skip if Attack Computer already destroyed 06799 BVS SKIP135 ; 06800 06801 SKIP134 LDA #CCS.COL3 ; Preload COLOR3 text color bits (= destroyed status) 06802 LDY DESTROYPHRTAB,X ; Preload title phrase offset of destroyed subsystem 06803 06804 SKIP135 ORA GCSTATPHO,X ; Combine status letter with new color 06805 STA GCSTATPHO,X ; 06806 STY NEWTITLEPHR ; Enqueue damage status title phrase 06807 BIT GCSTATCOM ; Skip if Attack Computer OK or damaged 06808 BVC SKIP136 ; 06809 06810 LDA #0 ; Switch Attack Computer off 06811 STA DRAINATTCOMP ; 06812 JSR CLRPLAYFIELD ; Clear PLAYFIELD 06813 06814 SKIP136 LDY #$52 ; Set title phrase "DAMAGE CONTROL..." 06815 JSR SETTITLE ; 06816 06817 LDX #$12 ; Play beeper sound pattern DAMAGE REPORT 06818 JSR BEEP ; 06819 06820 SKIP137 RTS ; Return 06821 06822 ;******************************************************************************* 06823 ;* * 06824 ;* COLLISION * 06825 ;* * 06826 ;* Detect a collision of our starship's photon torpedoes * 06827 ;* * 06828 ;******************************************************************************* 06829 06830 ; DESCRIPTION 06831 ; 06832 ; Both of our starship's photon torpedoes are checked if they have collided with 06833 ; a space object represented by PLAYER0..2, such as a Zylon ship, a Zylon photon 06834 ; torpedo, a starbase, or a meteor. 06835 ; 06836 ; For quick lookup, the following table lists the PLAYERs and what space objects 06837 ; they represent: 06838 ; 06839 ; +--------+--------------------------------------------------+ 06840 ; | PLAYER | Represents | 06841 ; +--------+--------------------------------------------------+ 06842 ; | 0 | Zylon ship 0, Starbase Left | 06843 ; | 1 | Zylon ship 1, Starbase Right | 06844 ; | 2 | Zylon photon torpedo, Starbase Center, Meteor | 06845 ; | 3 | Our starship's photon torpedo 0 | 06846 ; | 4 | Our starship's photon torpedo 1, Transfer Vessel | 06847 ; +--------+--------------------------------------------------+ 06848 ; 06849 ; NOTE: Only space objects represented by PLAYER0..2 are checked for collisions. 06850 ; The transfer vessel of the starbase, represented by PLAYER4, is not checked 06851 ; and therefore cannot be destroyed by one of our starship's photon torpedoes. 06852 ; 06853 ; This subroutine first checks if our starship's photon torpedoes are 06854 ; represented by alive PLAYERs with PHOTON TORPEDO shape. 06855 ; 06856 ; In order to detect a collision with a space object, our starship's photon 06857 ; torpedo must compare its x, y, and z coordinates with the ones of the space 06858 ; object. 06859 ; 06860 ; Instead of comparing the x and y coordinates, however, this subroutines uses a 06861 ; much more efficient method by inspecting the Player/Missile collision 06862 ; registers, as the x and y axis of the 3D coordinate system establish the plane 06863 ; in which the TV screen lies. Each of our starship's photon torpedoes has its 06864 ; own Player/Missile collision register: PL3HIT ($82) for our starship's photon 06865 ; torpedo 0 and PL4HIT ($83) for our starship's photon torpedo 1. By inspecting 06866 ; these registers the hit space object is determined: 06867 ; 06868 ; +---------------------------------------------------+-------------------------+ 06869 ; | Bits B2..0 of Collision Register | Hit PLAYER | 06870 ; | (0 -> Not Hit, 1 -> Hit) | | 06871 ; +-----------------+----------------+----------------+ | 06872 ; | PLAYER2 | PLAYER1 | PLAYER0 | | 06873 ; | (Zylon torpedo) | (Zylon ship 1) | (Zylon ship 0) | | 06874 ; +-----------------+----------------+----------------+-------------------------+ 06875 ; | 0 | 0 | 0 | None | 06876 ; | 0 | 0 | 1 | PLAYER0 (Zylon ship 0) | 06877 ; | 0 | 1 | 0 | PLAYER1 (Zylon ship 1) | 06878 ; | 0 | 1 | 1 | PLAYER1 (Zylon ship 1) | 06879 ; | 1 | 0 | 0 | PLAYER2 (Zylon torpedo) | 06880 ; | 1 | 0 | 1 | PLAYER2 (Zylon torpedo) | 06881 ; | 1 | 1 | 0 | PLAYER1 (Zylon ship 1) | 06882 ; | 1 | 1 | 1 | PLAYER1 (Zylon ship 1) | 06883 ; +-----------------+----------------+----------------+-------------------------+ 06884 ; 06885 ; If the lifetime of the hit space object has already expired, then the hit is 06886 ; ignored. 06887 ; 06888 ; A collision along the z-axis happens if the z-coordinate of our starship's 06889 ; photon torpedo is close enough to the z-coordinate of the space object. This 06890 ; is determined as follows: 06891 ; 06892 ; The absolute value of the z-coordinate of the space object is converted into a 06893 ; range index in 0..7. This index picks a minimum and a maximum z-coordinate 06894 ; from tables HITMINZTAB ($BF7D) and HITMAXZTAB ($BF75). If the absolute value 06895 ; of the z-coordinate of our starship's photon torpedo is inside this interval, 06896 ; then our starship's photon torpedo has hit the space object. The following 06897 ; table lists the relevant values: 06898 ; 06899 ; +-----------------------+-------+--------------------------+--------------------------+ 06900 ; | ABS(z-Coordinate) | Range | Min ABS(z-Coordinate) | Max ABS(z-Coordinate) | 06901 ; | of Space Object | Index | of Photon Torpedo to Hit | of Photon Torpedo to Hit | 06902 ; +-----------------------+-------+--------------------------+--------------------------+ 06903 ; | <= 511 ($01**) | 0 | 0 ($00**) | < 3328 ($0C**) | 06904 ; | <= 1023 ($03**) | 1 | 0 ($00**) | < 3328 ($0C**) | 06905 ; | <= 1535 ($05**) | 2 | 0 ($00**) | < 3328 ($0C**) | 06906 ; | <= 2047 ($07**) | 3 | 512 ($02**) | < 3328 ($0C**) | 06907 ; | <= 2559 ($09**) | 4 | 1024 ($04**) | < 3840 ($0E**) | 06908 ; | <= 3071 ($0B**) | 5 | 1536 ($06**) | < 3840 ($0E**) | 06909 ; | <= 3583 ($0D**) | 6 | 2048 ($08**) | < 3840 ($0E**) | 06910 ; | <= 65535 ($FF**) | 7 | 3072 ($0C**) | < 8448 ($20**) | 06911 ; +-----------------------+-------+--------------------------+--------------------------+ 06912 ; 06913 ; If a collision has been detected, the "age" (= initial lifetime - remaining 06914 ; lifetime) of our starship's photon torpedo is calculated. This age is used to 06915 ; delay playing the ZYLON EXPLOSION noise sound pattern. It is also used to 06916 ; determine the strength of our starship's photon torpedo. Only photon torpedoes 06917 ; of an age < 15 game loop iterations can destroy a Zylon basestar. 06918 ; 06919 ; Some clean-up work is done before the actual explosion: The lock-on timer, our 06920 ; starship's photon torpedo lifetime, and the hit space object's PLAYER lifetime 06921 ; is set to 0. 06922 ; 06923 ; If a meteor or a Zylon photon torpedo have been hit, then the score is not 06924 ; changed, skipping right to the explosion part. Otherwise, our starship's 06925 ; photon torpedo tracking flag is cleared and the Galactic Chart Map is updated. 06926 ; If a starbase was destroyed, then 3 points are subtracted from the score. If a 06927 ; Zylon ship was destroyed, then 6 points are added to the score and the Zylon 06928 ; KILL COUNTER readout of the Control Panel Display is incremented. Next, the 06929 ; explosion is initialized in subroutine INITEXPL ($AC6B). 06930 ; 06931 ; NOTE: This subroutine lacks proper explosion initialization if the starbase 06932 ; was hit. The actual explosion initialization is done in subroutine DOCKING 06933 ; ($ACE6) when the code finds out that the starbase sector is no more marked as 06934 ; such in the Galactic Chart. 06935 ; 06936 ; Finally, the Galactic Chart Map is searched for a remaining Zylon unit. If 06937 ; none is found then the mission is complete and code execution continues into 06938 ; subroutine GAMEOVER2 ($B121), ending the game. 06939 06940 L.PLHIT = $6B ; Saves PLAYER (and space object) index of hit PLAYER 06941 L.VIEWDIR = $6C ; Saves view direction. Used values are: 06942 ; $00 -> Front view 06943 ; $FF -> Aft view 06944 06945 COLLISION LDX #2 ; Loop over our starship's two photon torpedoes 06946 LOOP048 DEX ; 06947 BPL SKIP138 ; Branch into loop body below 06948 RTS ; Return 06949 06950 ;*** Photon torpedo sanity checks ********************************************** 06951 SKIP138 LDA PL3SHAPTYPE,X ; Next photon torpedo if PLAYER not a PHOTON TORPEDO 06952 BNE LOOP048 ; 06953 06954 LDA PL3LIFE,X ; Next photon torpedo if PLAYER not alive 06955 BEQ LOOP048 ; 06956 06957 ;*** Check if our starship's photon torpedo has hit in x-y plane *************** 06958 LDA PL3HIT,X ; Check Player/Missile collision register 06959 AND #$07 ; Next torpedo if no torpedo-to-PLAYER collision 06960 BEQ LOOP048 ; 06961 06962 LSR A ; Find out which of PLAYER0..2 was hit in PLAYFIELD 06963 CMP #3 ; 06964 BNE SKIP139 ; 06965 LSR A ; 06966 SKIP139 TAY ; Save resulting index of hit PLAYER 06967 06968 LDA PL0LIFE,Y ; Next torpedo if PLAYER0..2 (= targets) not alive 06969 BEQ LOOP048 ; 06970 06971 ;*** Has our starship's photon torpedo hit within valid z-coordinate interval? * 06972 LDA SHIPVIEW ; Skip if in Front view 06973 BEQ SKIP140 ; 06974 LDA #$FF ; Calculate range index... 06975 SKIP140 STA L.VIEWDIR ; Saves view direction 06976 EOR ZPOSHI,Y ; Calc ABS(z-coordinate (high byte)) of hit object 06977 CMP #16 ; Limit range index to 0..7 06978 BCC SKIP141 ; 06979 LDA #15 ; 06980 SKIP141 LSR A ; 06981 STY L.PLHIT ; Save index of hit PLAYER 06982 06983 TAY ; 06984 LDA L.VIEWDIR ; Reload view direction 06985 EOR PL3ZPOSHI,X ; Calc ABS(z-coordinate (high byte)) of torpedo 06986 06987 CMP HITMAXZTAB,Y ; Next torpedo if torpedo >= max hit z-coordinate 06988 BCS LOOP048 ; 06989 06990 CMP HITMINZTAB,Y ; Next torpedo if torpedo < min hit z-coordinate 06991 BCC LOOP048 ; 06992 06993 ;*** Our starship's photon torpedo has hit within valid z-coordinate interval! * 06994 LDY L.PLHIT ; Reload index of hit PLAYER 06995 SEC ; Calc "age" of photon torpedo in game loops to... 06996 LDA #255 ; delay playing ZYLON EXPLOSION noise sound pattern 06997 SBC PL3LIFE,X ; 06998 STA NOISEZYLONTIM ; 06999 07000 CMP #15 ; Skip if photon torpedo "age" < 15 07001 BCC SKIP142 ; 07002 LDA PL0SHAPTYPE,Y ; CARRY := PLAYER is ZYLON BASESTAR (shape type 8) 07003 CMP #SHAP.ZBASESTAR ; (and torpedo "age" good to destroy ZYLON BASESTAR) 07004 07005 ;*** Clean up our starship's photon torpedo and hit PLAYER ********************* 07006 SKIP142 LDA #0 ; Lock-on lifetime := 0 game loops 07007 STA LOCKONLIFE ; 07008 STA PL3LIFE,X ; Photon torpedo's lifetime := 0 game loops 07009 BCS SKIP144 ; If CARRY set do not score, just do explosion 07010 07011 STA PL0LIFE,Y ; Hit PLAYER lifetime := 0 game loops 07012 07013 LDA PL0SHAPTYPE,Y ; If hit PLAYER is... 07014 BEQ SKIP144 ; ...a PHOTON TORPEDO (shape type 0)... 07015 CMP #SHAP.METEOR ; ...or a METEOR (shape type 6)... 07016 BEQ SKIP144 ; ...do not score, just do explosion 07017 07018 LDA #0 ; Clear photon torpedo tracking flag 07019 STA ISTRACKING ; 07020 07021 ;*** Zylon ship (or starbase) destroyed! *************************************** 07022 LDX CURRSECTOR ; Decrement Zylon count on Galactic Chart 07023 DEC GCMEMMAP,X ; 07024 BPL SKIP143 ; Skip if destroyed space object was Zylon ship 07025 07026 ;*** Starbase destroyed! ******************************************************* 07027 LDA #0 ; Remove destroyed starbase from Galactic Chart 07028 STA GCMEMMAP,X ; 07029 SEC ; SCORE := SCORE - 3 for destroying starbase 07030 LDA SCORE ; 07031 SBC #3 ; 07032 STA SCORE ; 07033 LDA SCORE+1 ; 07034 SBC #0 ; 07035 STA SCORE+1 ; 07036 RTS ; Return 07037 07038 ;*** Zylon ship destroyed! ***************************************************** 07039 SKIP143 CLC ; SCORE := SCORE + 6 for destroying Zylon ship 07040 LDA SCORE ; 07041 ADC #6 ; 07042 STA SCORE ; 07043 LDA SCORE+1 ; 07044 ADC #0 ; 07045 STA SCORE+1 ; 07046 07047 LDX #1 ; Increment Zylon KILL COUNTER readout... 07048 LOOP049 INC KILLCNTD1,X ; ...of Control Panel Display 07049 LDA KILLCNTD1,X ; 07050 CMP #[CCS.COL1!CCS.9]+1 ; 07051 BCC SKIP144 ; 07052 LDA #[CCS.COL1!CCS.0] ; 07053 STA KILLCNTD1,X ; 07054 DEX ; 07055 BPL LOOP049 ; 07056 07057 SKIP144 JSR INITEXPL ; Init explosion at hit PLAYER 07058 07059 ;*** Any Zylon ships left? ***************************************************** 07060 LDX #127 ; Scan all sectors of Galactic Chart 07061 LOOP050 LDA GCMEMMAP,X ; 07062 BMI SKIP145 ; 07063 BNE SKIP146 ; Return if Zylon sector found 07064 SKIP145 DEX ; 07065 BPL LOOP050 ; 07066 07067 ;*** Game over (Mission Complete) ********************************************** 07068 LDY #$3F ; Set title phrase "MISSION COMPLETE" 07069 LDX #0 ; Set mission bonus offset 07070 JSR GAMEOVER2 ; Game over 07071 SKIP146 RTS ; Return 07072 07073 ;******************************************************************************* 07074 ;* * 07075 ;* KEYBOARD * 07076 ;* * 07077 ;* Handle Keyboard Input * 07078 ;* * 07079 ;******************************************************************************* 07080 07081 ; DESCRIPTION 07082 ; 07083 ; If a keyboard code has been collected during a keyboard IRQ in the Immediate 07084 ; Interrupt Request handler IRQHNDLR ($A751), the idle counter is reset and the 07085 ; PLAYER-PLAYFIELD priority arranges the PLAYERs in front of the PLAYFIELD. 07086 ; 07087 ; Then, the keyboard code is compared with keyboard codes of table KEYTAB 07088 ; ($BABE). If no match is found the "WHAT'S WRONG" message is displayed in the 07089 ; title line and code execution returns. 07090 ; 07091 ; If one of the speed keys '0'..'9' has been pressed, a pending hyperwarp is 07092 ; aborted in subroutine ABORTWARP ($A980) and code execution returns. Otherwise 07093 ; the Engines drain rate is adjusted as well as the new velocity of our 07094 ; starship. If the Engines are damaged, a maximum speed is possible equivalent 07095 ; to speed key '5'. 07096 ; 07097 ; If one of our starship's view keys 'F' (Front), 'A' (Aft), 'G' (Galactic 07098 ; Chart), or 'L' (Long-Range Scan) have been pressed, the Display List is 07099 ; modified accordingly in subroutine MODDLST ($ADF1) and a new star field of 12 07100 ; stars is created with the help of subroutine INITPOSVEC ($B764). Code 07101 ; execution returns via subroutine UPDSCREEN ($B07B). 07102 ; 07103 ; If one of the 'T' (Tracking Computer), 'S' (Shields) or 'C' (Attack Computer) 07104 ; keys have been pressed, the corresponding status bits are toggled and the 07105 ; title line is updated with the corresponding title phrase. The beeper sound 07106 ; pattern ACKNOWLEDGE is played in subroutine BEEP ($B3A6). The tracking letter 07107 ; of the Control Panel Display is updated and the PLAYFIELD is cleared in 07108 ; subroutine CLRPLAYFIELD ($AE0D). If the Attack Computer is on, the Front or 07109 ; Aft view cross hairs are drawn, depending on the current view of our starship, 07110 ; via subroutine DRAWLINES ($A76F). 07111 ; 07112 ; If the 'H' (Hyperwarp) key has been pressed then the hyperwarp is engaged. Our 07113 ; starship's velocity is set to the maximum value, the Engines drain rate is 07114 ; increased to the equivalent of speed key '7'. Star trails are prepared. The 07115 ; position vector of the Hyperwarp Target Marker (PLAYER3) is set to the 07116 ; following values: 07117 ; 07118 ; x-coordinate := +0 (+$0000) 07119 ; y-coordinate := +256 (+$0100) 07120 ; z-coordinate := + (+$****) (sign only) 07121 ; 07122 ; The velocity vector is set to the following values: 07123 ; 07124 ; x-velocity := (not initialized) 07125 ; y-velocity := (not initialized) 07126 ; z-velocity := +0 07127 ; 07128 ; The temporary arrival hyperwarp marker column and row numbers are saved. If we 07129 ; are not in a NOVICE mission, the maximum veer-off velocity of the Hyperwarp 07130 ; Target Marker during hyperwarp is picked from table VEERMASKTAB ($BED7). This 07131 ; value depends on the selected hyperwarp energy (and thus on the distance to 07132 ; hyperwarp). Finally, the title line displays the "HYPERWARP ENGAGED" message. 07133 ; 07134 ; If the 'M' (Manual target selector) key has been pressed, the tracked target 07135 ; space object is swapped and the corresponding digit of the Control Panel 07136 ; Display is toggled between 0 and 1. 07137 ; 07138 ; If the 'P' (Pause) key has been pressed, an endless loop waits until the 07139 ; joystick is pushed. 07140 ; 07141 ; BUG (at $B103): The endless loop branches back one instruction too far. 07142 ; Suggested fix: Branch to instruction LDA PORTA at $B0FE. 07143 ; 07144 ; If the 'INV' (Abort mission) key has been pressed, the mission is aborted by 07145 ; setting the mission bonus offset, then displaying the "MISSION ABORTED" 07146 ; message in the title line. Code execution continues into subroutine GAMEOVER 07147 ; ($B10A). 07148 ; 07149 ; NOTE: This subroutine has two additional entry points: 07150 ; 07151 ; (1) SETVIEW ($B045), which is used to enforce the Front view. It is entered 07152 ; from the game loop GAMELOOP ($A1F3) and subroutines INITSTART ($A15E) and 07153 ; DECENERGY ($B86F). 07154 ; 07155 ; (2) UPDSCREEN ($B07B), which draws the cross hairs and the Attack Computer 07156 ; Display, and then sets the tracking letter of the Control Panel Display. 07157 ; It is entered from subroutine DOCKING ($ACE6). 07158 07159 L.KEYCODE = $6A ; Saves pressed keyboard code 07160 07161 KEYBOARD LDA KEYCODE ; Return if no keyboard code collected 07162 BEQ SKIP150 ; 07163 07164 LDX #20 ; Prep keyboard code table loop index 07165 STA L.KEYCODE ; Save keyboard code 07166 07167 LDA #0 ; Reset idle counter 07168 STA IDLECNTHI ; 07169 STA KEYCODE ; Clear keyboard code 07170 07171 LDA #$11 ; GTIA: Enable PLAYER4, prio: PLs > PFs > BGR 07172 STA PRIOR ; (PLAYERs in front of stars - and cross hairs) 07173 07174 ;*** Search keyboard code in lookup table ************************************** 07175 07176 LOOP051 LDA KEYTAB,X ; Loop over all valid keyboard codes 07177 CMP L.KEYCODE ; 07178 BEQ SKIP147 ; Branch if matching entry found 07179 DEX ; 07180 BPL LOOP051 ; Next keyboard code 07181 07182 LDY #$10 ; No match found... 07183 JMP SETTITLE ; ...set title phrase "WHATS WRONG?" and return 07184 07185 ;*** Handle '0'..'9' keyboard keys (speed) ************************************* 07186 SKIP147 CPX #10 ; Skip section if keyboard code does not match 07187 BCS SKIP151 ; 07188 07189 LDA WARPSTATE ; Skip if hyperwarp disengaged... 07190 BEQ SKIP148 ; 07191 JMP ABORTWARP ; ...else abort hyperwarp 07192 07193 SKIP148 BIT GCSTATENG ; Skip if Engines are OK or destroyed 07194 BVC SKIP149 ; 07195 CPX #6 ; Allow max velocity equivalent to speed key '5' 07196 BCC SKIP149 ; 07197 LDX #5 ; 07198 07199 SKIP149 LDA DRAINRATETAB,X ; Set Engines energy drain rate 07200 STA DRAINENGINES ; 07201 LDA VELOCITYTAB,X ; Set new velocity 07202 STA NEWVELOCITY ; 07203 SKIP150 RTS ; Return 07204 07205 ;*** Handle 'F', 'A', 'L', 'G' keyboard keys (our starship's views) ************ 07206 SKIP151 CPX #14 ; Skip section if keyboard code does not match 07207 BCS SKIP152 ; 07208 07209 ;*** Entry to force Front view after game init and failed missions ************* 07210 SETVIEW LDA VIEWMODETAB-10,X ; Store our starship's view type 07211 STA SHIPVIEW ; 07212 07213 LDY DLSTFRAGOFFTAB-10,X ; Get DL fragment offset (Front, Aft, LRS, GC) 07214 LDX #$02 ; Switch to corresponding view 07215 LDA #$08 ; 07216 JSR MODDLST ; 07217 07218 LDX #NUMSPCOBJ.NORM-1 ; Create new star field of 12 stars 07219 LOOP052 JSR INITPOSVEC ; 07220 DEX ; 07221 CPX #NUMSPCOBJ.PL ; 07222 BCS LOOP052 ; 07223 07224 BCC UPDSCREEN ; Return via updating screen (below) 07225 07226 ;*** Handle 'T', 'S', 'C' keyboard keys (Tracking, Shields, Attack Computer) *** 07227 SKIP152 CPX #17 ; Skip section if keyboard code does not match 07228 BCS SKIP156 ; 07229 07230 LDY MSGOFFTAB-14,X ; Prep title phrase offset "... OFF" 07231 LDA ISTRACKCOMPON-14,X ; Toggle status bits (also energy consumption values) 07232 EOR MSGBITTAB-14,X ; 07233 STA ISTRACKCOMPON-14,X ; 07234 BEQ SKIP153 ; 07235 LDY MSGONTAB-14,X ; Prep title phrase offset "... ON" 07236 SKIP153 JSR SETTITLE ; Set title phrase to "... ON" or "... OFF" version 07237 07238 LDX #$0C ; Play beeper sound pattern ACKNOWLEDGE 07239 JSR BEEP ; 07240 07241 ;*** Update PLAYFIELD (Cross hairs, Attack Computer, set tracking letter) ****** 07242 UPDSCREEN LDX #CCS.T ; Get custom char 'T' (entry point TRANSFER COMPLETE) 07243 LDY ISTRACKCOMPON ; 07244 BEQ SKIP154 ; Skip if Tracking Computer is on 07245 07246 INX ; Get custom char 'C' 07247 07248 SKIP154 STX TRACKC1 ; Store tracking character in Control Panel Display 07249 JSR CLRPLAYFIELD ; Clear PLAYFIELD 07250 LDA DRAINATTCOMP ; Return if Attack Computer off 07251 BEQ SKIP150 ; 07252 07253 LDX SHIPVIEW ; If Aft view -> Draw Aft cross hairs and return 07254 BEQ SKIP155 ; If Front view -> Draw Front cross hairs and ... 07255 CPX #$01 ; ...Attack Computer and return 07256 BNE SKIP150 ; 07257 LDX #$2A ; 07258 SKIP155 JMP DRAWLINES ; 07259 07260 ;*** Handle 'H' keyboard key (Hyperwarp) *************************************** 07261 SKIP156 CPX #17 ; Skip if keyboard code does not match 07262 BNE SKIP158 ; 07263 07264 ;*** Engage Hyperwarp ********************************************************** 07265 LDA WARPSTATE ; Return if hyperwarp engaged 07266 BNE SKIP159 ; 07267 07268 LDA #$7F ; Engage hyperwarp 07269 STA WARPSTATE ; 07270 LDA #255 ; Set new velocity 07271 STA NEWVELOCITY ; 07272 LDA #30 ; Set Engines energy drain rate (= speed key '7') 07273 STA DRAINENGINES ; 07274 07275 LDA #NUMSPCOBJ.ALL-1 ; Set space obj index of first star of star trail 07276 STA TRAILIND ; 07277 LDA #0 ; Clear star trail delay 07278 STA TRAILDELAY ; 07279 07280 STA PL3XPOSHI ; Init position vector and velocity vector of... 07281 STA PL3XPOSLO ; ... Hyperwarp Target Marker (PLAYER3): 07282 STA PL3YPOSLO ; x-coordinate := +0 (+$0000) 07283 STA PL3ZVEL ; y-coordinate := +256 (+$0100) 07284 LDA #1 ; z-coordinate := + (+$****) (sign only) 07285 STA PL3ZPOSSIGN ; z-velocity := +0 07286 STA PL3XPOSSIGN ; 07287 STA PL3YPOSSIGN ; 07288 STA PL3YPOSHI ; 07289 07290 LDA WARPARRVCOLUMN ; Store temp arrival hyperwarp marker column number 07291 STA WARPTEMPCOLUMN ; 07292 LDA WARPARRVROW ; Store temp arrival hyperwarp marker row number 07293 STA WARPTEMPROW ; 07294 07295 LDA MISSIONLEVEL ; Skip if NOVICE mission 07296 BEQ SKIP157 ; 07297 07298 LDA WARPENERGY ; Bits B0..1 of hyperwarp energy index a table... 07299 ROL A ; ...containing the maximum value of how much the... 07300 ROL A ; ...Hyperwarp Target Marker will veer off during... 07301 ROL A ; ...hyperwarp 07302 AND #$03 ; 07303 TAY ; 07304 LDA VEERMASKTAB,Y ; 07305 07306 SKIP157 STA VEERMASK ; Store veer-off velocity limitation mask 07307 07308 LDY #$11 ; Set title phrase "HYPERWARP ENGAGED" and return 07309 JMP SETTITLE ; 07310 07311 ;*** Handle 'M' keyboard key (Manual Target Selector) key ********************** 07312 SKIP158 CPX #19 ; Skip if keyboard code does not match 07313 BCS SKIP160 ; 07314 07315 LDA TRACKDIGIT ; Toggle digit of tracked space object of... 07316 EOR #$01 ; ... Control Panel Display 07317 AND #$01 ; 07318 STA TRACKDIGIT ; 07319 SKIP159 RTS ; Return 07320 07321 ;*** Handle 'P' keyboard key (Pause) ******************************************* 07322 SKIP160 BNE SKIP161 ; Skip if keyboard code does not match 07323 07324 LDA PORTA ; Push joystick to resume action 07325 CMP #$FF ; 07326 BEQ SKIP160 ; (!) 07327 RTS ; Return 07328 07329 ;*** Handle 'INV' keyboard key (Abort Mission) ********************************* 07330 SKIP161 LDY #$76 ; Preload title phrase "MISSION ABORTED..." 07331 LDX #$04 ; Set mission bonus offset 07332 07333 ;******************************************************************************* 07334 ;* * 07335 ;* GAMEOVER * 07336 ;* * 07337 ;* Handle game over * 07338 ;* * 07339 ;******************************************************************************* 07340 07341 ; DESCRIPTION 07342 ; 07343 ; Handles game over, including calculating the scored rank and class. 07344 ; 07345 ; This subroutine has two entry points: 07346 ; 07347 ; (1) GAMEOVER ($B10A) is entered at the end of a failed mission (mission 07348 ; aborted, zero energy, or starship destroyed by Zylon fire), essentially 07349 ; shutting down our starship. Code execution continues into GAMEOVER2 07350 ; ($B121) below. 07351 ; 07352 ; (2) GAMEOVER2 ($B121) is entered at the end of a successful mission (all 07353 ; Zylon ships destroyed). It puts the game in demo mode, enqueues the 07354 ; corresponding game over message, and calculates the scored rank and 07355 ; class. 07356 ; 07357 ; The scored rank and class are based on the total score. This is the score 07358 ; accumulated during the game plus a mission bonus, which depends on the 07359 ; mission level and on how the mission ended (mission complete, mission 07360 ; aborted, or starship destroyed by Zylon fire). The mission bonus is 07361 ; picked from table BONUSTAB ($BEDD). 07362 ; 07363 ; The scored rank index is taken from bits B8..4 of the total score and 07364 ; limited to values of 0..18. It indexes table RANKTAB ($BEE9) for the rank 07365 ; string. The rank string is displayed in subroutine SETTITLE ($B223). 07366 ; 07367 ; The scored class index is taken from bits B3..0 (for rank indices 0, 07368 ; 11..14) and computed from bits B4..1 (for rank indices 1..10 and 15..18). 07369 ; It takes values of 0..15. It indexes table CLASSTAB ($BEFC) for the class 07370 ; digit. The class digit is displayed in subroutine SETTITLE ($B223). 07371 ; 07372 ; For quick lookup, the following table lists rank and class from the total 07373 ; score. Use the table as follows: Pick the cell with the closest value 07374 ; less or equal to your score then read the rank and class off the left and 07375 ; the top of the table, respectively. 07376 ; 07377 ; For example: A score of 90 results in a ranking of "Novice Class 4", a 07378 ; score of 161 results in a ranking of "Pilot Class 3". 07379 ; 07380 ; +------------------------------+---------------------------------------------------------------+ 07381 ; | Minimum Total Score | Class Index | 07382 ; | | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15| 07383 ; +-------+----------------------+---------------------------------------------------------------+ 07384 ; | Rank | | Class | 07385 ; | Index | Rank | 5 5 5 4 4 4 4 3 3 3 2 2 2 1 1 1| 07386 ; +-------+----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 07387 ; | 0 | Galactic Cook | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14| 15| 07388 ; | 1 | Garbage Scow Captain | 16| 18| 20| 22| 24| 26| 28| 30| | | | | | | | | 07389 ; | 2 | Garbage Scow Captain | | | | | | | | | 32| 34| 36| 38| 40| 42| 44| 46| 07390 ; | 3 | Rookie | 48| 50| 52| 54| 56| 58| 60| 62| | | | | | | | | 07391 ; | 4 | Rookie | | | | | | | | | 64| 66| 68| 70| 72| 74| 76| 78| 07392 ; | 5 | Novice | 80| 82| 84| 86| 88| 90| 92| 94| | | | | | | | | 07393 ; | 6 | Novice | | | | | | | | | 96| 98|100|102|104|106|108|110| 07394 ; | 7 | Ensign |112|114|116|118|120|122|124|126| | | | | | | | | 07395 ; | 8 | Ensign | | | | | | | | |128|130|132|134|136|138|140|142| 07396 ; | 9 | Pilot |144|146|148|150|152|154|156|158| | | | | | | | | 07397 ; | 10 | Pilot | | | | | | | | |160|162|164|166|168|170|172|174| 07398 ; | 11 | Ace |176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191| 07399 ; | 12 | Lieutenant |192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207| 07400 ; | 13 | Warrior |208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223| 07401 ; | 14 | Captain |224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239| 07402 ; | 15 | Commander |240|242|244|246|248|250|252|254| | | | | | | | | 07403 ; | 16 | Commander | | | | | | | | |256|258|260|262|264|266|268|270| 07404 ; | 17 | Star Commander |272|274|276|278|280|282|284|286| | | | | | | | | 07405 ; | 18 | Star Commander | | | | | | | | |288|290|292|294|296|298|300|302| 07406 ; +-------+----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 07407 ; 07408 ; NOTE: This subroutine also clears the vertical and horizontal joystick 07409 ; directions. 07410 ; 07411 ; INPUT 07412 ; 07413 ; X = Offset to index table BONUSTAB ($BEDD) of mission bonus values. Used 07414 ; values are: 07415 ; $00 -> Mission complete 07416 ; $04 -> Mission was aborted due to zero energy 07417 ; $08 -> Our starship was destroyed by Zylon fire 07418 ; 07419 ; Y = Title phrase offset. Used values are: 07420 ; $3F -> "MISSION COMPLETE" 07421 ; $31 -> "MISSION ABORTED ZERO ENERGY" 07422 ; $23 -> "SHIP DESTROYED BY ZYLON FIRE" 07423 07424 ;*** Game over (Mission failed) ************************************************ 07425 GAMEOVER LDA #0 ; 07426 STA PL3LIFE ; PLAYER3 lifetime := 0 game loops 07427 STA BEEPPRIORITY ; Mute beeper 07428 STA TITLEPHR ; Clear title line 07429 STA REDALERTLIFE ; Red alert flash lifetime := 0 game loops 07430 STA AUDC4 ; Mute audio channel 4 07431 STA NEWVELOCITY ; Shut down Engines 07432 STA SHIELDSCOLOR ; Set Shields color to {BLACK} 07433 STA DRAINSHIELDS ; Switch off Shields 07434 STA WARPSTATE ; Disengage hyperwarp 07435 STA VELOCITYHI ; Turn off hyperwarp velocity 07436 07437 ;*** Game over (Mission successful) ******************************************** 07438 GAMEOVER2 LDA #$FF ; Enter demo mode 07439 STA ISDEMOMODE ; 07440 07441 STY NEWTITLEPHR ; Enqueue title phrase 07442 07443 ;*** Calculate total score ***************************************************** 07444 TXA ; 07445 ORA MISSIONLEVEL ; 07446 TAX ; 07447 LDA BONUSTAB,X ; Retrieve mission bonus 07448 CLC ; Add mission bonus and game score 07449 ADC SCORE ; 07450 TAX ; 07451 LDA #0 ; 07452 07453 STA JOYSTICKY ; Clear vertical joystick delta 07454 STA JOYSTICKX ; Clear horizontal joystick delta 07455 07456 ADC SCORE+1 ; 07457 BMI SKIP165 ; Return if total score < 0 (= total score of 0) 07458 07459 ;*** Calculate scored rank ***************************************************** 07460 LSR A ; 07461 TXA ; 07462 ROR A ; 07463 LSR A ; 07464 LSR A ; 07465 LSR A ; Use bits B8..4 of total score as rank index 07466 CMP #19 ; Limit scored rank index to 0..18 07467 BCC SKIP162 ; 07468 LDA #18 ; 07469 LDX #15 ; Prep class index of 15 07470 SKIP162 STA SCOREDRANKIND ; Store scored rank index 07471 07472 ;*** Calculate scored class **************************************************** 07473 TAY ; 07474 TXA ; 07475 CPY #0 ; 07476 BEQ SKIP164 ; 07477 CPY #11 ; 07478 BCC SKIP163 ; 07479 CPY #15 ; 07480 BCC SKIP164 ; 07481 SKIP163 LSR A ; 07482 EOR #$08 ; 07483 SKIP164 AND #$0F ; 07484 STA SCOREDCLASSIND ; Store scored class index, is 0..15 07485 07486 SKIP165 RTS ; Return 07487 07488 ;******************************************************************************* 07489 ;* * 07490 ;* SELECTWARP * 07491 ;* * 07492 ;* Select hyperwarp arrival location on Galactic Chart * 07493 ;* * 07494 ;******************************************************************************* 07495 07496 ; DESCRIPTION 07497 ; 07498 ; This subroutine executes the following steps: 07499 ; 07500 ; (1) Check if we are in Galactic Chart view and not in hyperwarp. 07501 ; 07502 ; (2) Update the Galactic Chart in subroutine DRAWGC ($B4B9) if the Subspace 07503 ; Radio is not damaged. 07504 ; 07505 ; (3) Move the arrival hyperwarp marker (PLAYER4) across the Galactic Chart 07506 ; every other game loop iteration. The current location of our starship is 07507 ; indicated by the departure hyperwarp marker (PLAYER3). 07508 ; 07509 ; Code execution continues into subroutine CALCWARP ($B1A7) to calculate the 07510 ; required hyperwarp energy to hyperwarp from the departure hyperwarp marker 07511 ; position to the arrival hyperwarp marker position. 07512 ; 07513 ; NOTE: To calculate the horizontal position of PLAYER3..4 an offset of 61 is 07514 ; added (from left to right: 48 Player/Missile (PM) pixels to the left edge of 07515 ; the screen + 16 PM pixels to the left border of the Galactic Chart - 3 PM 07516 ; pixels relative offset of the PLAYER shape's horizontal center to its left 07517 ; edge = 61 PM pixels). 07518 ; 07519 ; NOTE: To calculate the vertical position of PLAYER3..4 an offset of 63 is 07520 ; added (from top to bottom: 8 Player/Missile (PM) pixels to the start of the 07521 ; Display List + 56 PM pixels to the first row of sectors - 1 PM pixel relative 07522 ; offset of the PLAYER shape's vertical center to its top edge (?) = 63 PM 07523 ; pixels). 07524 07525 SELECTWARP LDA WARPSTATE ; Return if hyperwarp engaged 07526 BNE SKIP166 ; 07527 07528 LDA SHIPVIEW ; Return if not in Galactic Chart view 07529 BMI SKIP167 ; 07530 SKIP166 RTS ; Return 07531 07532 SKIP167 BIT GCSTATRAD ; Skip if Subspace Radio is damaged or destroyed 07533 BMI SKIP168 ; 07534 07535 JSR DRAWGC ; Redraw Galactic Chart 07536 07537 SKIP168 LDA COUNT8 ; Move hyperwarp markers only every other game loop 07538 AND #$01 ; (slowing down movement of hyperwarp markers) 07539 BNE CALCWARP ; 07540 07541 ;*** Calc arrival hyperwarp marker column and row numbers, update PLAYER4 pos ** 07542 CLC ; 07543 LDA WARPARRVCOLUMN ; Load arrival hyperwarp marker column number 07544 ADC JOYSTICKX ; Add joystick x-delta 07545 AND #$7F ; Limit value to 0..127 07546 STA WARPARRVCOLUMN ; Save new arrival hyperwarp marker column number 07547 CLC ; 07548 ADC #61 ; Add offset of 61 07549 STA PL4COLUMN ; Store as PLAYER4 column number 07550 07551 CLC ; 07552 LDA WARPARRVROW ; Load arrival hyperwarp marker row number 07553 ADC JOYSTICKY ; Add joystick y-delta 07554 AND #$7F ; Limit value to 0..127 07555 STA WARPARRVROW ; Save new arrival hyperwarp marker row number 07556 CLC ; 07557 ADC #63 ; Add offset of 63 07558 STA PL4ROWNEW ; Store as PLAYER4 row number 07559 07560 ;*** Calc departure hyperwarp marker column and row numbers, update PLAYER3 pos 07561 LDA WARPDEPRROW ; Load departure hyperwarp marker row number 07562 CLC ; 07563 ADC #63 ; Add offset of 63 07564 STA PL3ROWNEW ; Store as PLAYER3 row number 07565 07566 LDA WARPDEPRCOLUMN ; Load departure hyperwarp marker column number 07567 CLC ; 07568 ADC #61 ; Add offset of 61 07569 STA PL3COLUMN ; Store as PLAYER3 column number 07570 07571 ;******************************************************************************* 07572 ;* * 07573 ;* CALCWARP * 07574 ;* * 07575 ;* Calculate and display hyperwarp energy * 07576 ;* * 07577 ;******************************************************************************* 07578 07579 ; DESCRIPTION 07580 ; 07581 ; Calculates and displays the hyperwarp energy in the Galactic Chart view. 07582 ; 07583 ; This subroutine executes the following steps: 07584 ; 07585 ; (1) Determine the arrival sector from the arrival hyperwarp marker position. 07586 ; 07587 ; (2) If the Subspace Radio is not destroyed, update the target number digit of 07588 ; the Galactic Chart Panel Display. 07589 ; 07590 ; (3) Calculate the hyperwarp energy that is required to hyperwarp from the 07591 ; departure hyperwarp marker to the arrival hyperwarp marker based on the 07592 ; "block-distance": 07593 ; 07594 ; DISTANCE := DELTAR / 2 + DELTAC 07595 ; 07596 ; where 07597 ; 07598 ; DELTAR := ABS(WARPARRVROW - WARPDEPRROW) 07599 ; DELTAC := ABS(WARPARRVCOLUMN - WARPDEPRCOLUMN) 07600 ; 07601 ; NOTE: Dividing DELTAR by 2 compensates for PLAYERs at single-line 07602 ; resolution having Player/Missile pixels that are half as high as they are 07603 ; wide. 07604 ; 07605 ; The hyperwarp energy, divided by 10, is the sum of a value picked from 07606 ; the hyperwarp energy table WARPENERGYTAB ($BADD) indexed by DISTANCE / 8) 07607 ; plus a remainder computed from Bits B1..0 of DISTANCE. 07608 ; 07609 ; (4) Store the hyperwarp energy value in WARPENERGY ($91). 07610 ; 07611 ; (5) Update the HYPERWARP ENERGY readout of the Galactic Chart Panel Display. 07612 07613 L.WARPARRVCOL = $6A ; Saves arrival sector column number 07614 L.DELTAC = $6A ; Saves diff column value 07615 07616 ;*** Calculate arrival sector ************************************************** 07617 CALCWARP LDA WARPARRVCOLUMN ; 07618 LSR A ; 07619 LSR A ; 07620 LSR A ; 07621 STA L.WARPARRVCOL ; A := arrival sector column 0..15 07622 LDA WARPARRVROW ; 07623 AND #$70 ; A := arrival sector row (0..7) * 16 07624 ORA L.WARPARRVCOL ; 07625 STA ARRVSECTOR ; Save arrival sector (format %0rrrcccc) 07626 07627 ;*** Update target number digit of Galactic Chart Panel Display **************** 07628 TAX ; 07629 LDA GCMEMMAP,X ; Get number of Zylon ships in arrival sector 07630 BPL SKIP169 ; Skip if no starbase in arrival sector 07631 LDA #0 ; Clear number of Zylon ships 07632 SKIP169 ORA #CCS.COL2!ROM.0 ; Merge COLOR2 bits with number of Zylon ships 07633 BIT GCSTATRAD ; Skip if Subspace Radio destroyed 07634 BVS SKIP170 ; 07635 07636 STA GCTRGCNT ; Set target number digit of Galactic Chart Panel 07637 07638 ;*** Calculate energy to hyperwarp between hyperwarp markers ******************* 07639 SKIP170 SEC ; A := DELTAC := ABS(WARPARRVCOLUMN - WARPDEPRCOLUMN) 07640 LDA WARPARRVCOLUMN ; (Column value difference) 07641 SBC WARPDEPRCOLUMN ; 07642 BCS SKIP171 ; 07643 EOR #$FF ; 07644 ADC #1 ; 07645 SKIP171 STA L.DELTAC ; 07646 07647 SEC ; A := DELTAR := ABS(WARPARRVROW - WARPDEPRROW) 07648 LDA WARPARRVROW ; (Row value difference) 07649 SBC WARPDEPRROW ; 07650 BCS SKIP172 ; 07651 EOR #$FF ; 07652 ADC #1 ; 07653 07654 SKIP172 LSR A ; A := DISTANCE := DELTAR / 2 + DELTAC 07655 CLC ; 07656 ADC L.DELTAC ; 07657 07658 TAY ; Save DISTANCE 07659 LSR A ; Calc index into hyperwarp energy table 07660 LSR A ; 07661 LSR A ; 07662 TAX ; 07663 07664 TYA ; Load DISTANCE value 07665 AND #$03 ; Get DISTANCE bits B1..0 07666 CLC ; 07667 ADC WARPENERGYTAB,X ; Add hyperwarp energy from table 07668 STA WARPENERGY ; Save hyperwarp energy 07669 07670 ;*** Update HYPERWARP ENERGY readout of Galactic Chart Panel Display *********** 07671 TAY ; Prep with hyperwarp energy value 07672 07673 LDA #ROM.0 ; Set HYPERWARP ENERGY readout digit1..3 to '0' 07674 STA GCWARPD1 ; 07675 STA GCWARPD1+1 ; 07676 STA GCWARPD1+2 ; 07677 07678 LOOP053 LDX #2 ; Loop over HYPERWARP ENERGY readout digit3..1 07679 LOOP054 INC GCWARPD1,X ; Increment digit value 07680 LDA GCWARPD1,X ; 07681 CMP #ROM.9+1 ; 07682 BCC SKIP173 ; Skip if energy digit <= '9' 07683 07684 LDA #ROM.0 ; Replace energy digit with '0' 07685 STA GCWARPD1,X ; 07686 DEX ; 07687 BPL LOOP054 ; Next energy digit 07688 07689 SKIP173 DEY ; Decrement HYPERWARP ENERGY readout value 07690 BNE LOOP053 ; 07691 RTS ; Return 07692 07693 ;******************************************************************************* 07694 ;* * 07695 ;* UPDTITLE * 07696 ;* * 07697 ;* Update title line * 07698 ;* * 07699 ;******************************************************************************* 07700 07701 ; DESCRIPTION 07702 ; 07703 ; Updates the title phrase displayed in the title line. 07704 ; 07705 ; If no title phrase has been set then fetch the offset of the next ("enqueued") 07706 ; title phrase to be displayed. If one has been set then code execution 07707 ; continues into subroutine SETTITLE ($B223), otherwise code execution returns. 07708 ; 07709 ; If a title phrase has been set then decrement the lifetime of the currently 07710 ; displayed title phrase segment. If its lifetime has reached a value of 0 then 07711 ; branch to subroutine SETTITLE ($B223) to display the next segment. 07712 07713 UPDTITLE LDA TITLEPHR ; Skip if no title phrase set 07714 BEQ SKIP175 ; 07715 07716 DEC TITLELIFE ; Decrement title phrase segment lifetime 07717 BEQ SKIP176 ; If lifetime expired show next title segment 07718 07719 SKIP174 RTS ; Return 07720 07721 SKIP175 LDY NEWTITLEPHR ; Prep enqueued new title phrase 07722 BEQ SKIP174 ; Return if not set 07723 07724 ;******************************************************************************* 07725 ;* * 07726 ;* SETTITLE * 07727 ;* * 07728 ;* Set title phrase in title line * 07729 ;* * 07730 ;******************************************************************************* 07731 07732 ; DESCRIPTION 07733 ; 07734 ; Displays a title phrase in the title line. 07735 ; 07736 ; INTRODUCTION 07737 ; 07738 ; Title phrases are picked from the title phrase table PHRASETAB ($BBAA). They 07739 ; consist of one or more phrase tokens. Each token is a byte representing a word 07740 ; in word table WORDTAB ($BC2B). Two special tokens are placeholders for the 07741 ; scored class string ($FC) and scored rank string ($FD). 07742 ; 07743 ; A title phrase is split up into one or more title phrase segments, each 07744 ; fitting into the title line. One title phrase segment is displayed after the 07745 ; other after a delay called the "title segment lifetime". 07746 ; 07747 ; Phrase tokens, except the tokens for the scored class ($FC) and for the scored 07748 ; rank ($FD), contain the number of a word in word table WORDTAB ($BC2B) and may 07749 ; contain an end-of-segment or end-of-phrase marker bit. 07750 ; 07751 ; DETAILS 07752 ; 07753 ; The Display List is modified by subroutine MODDLST ($ADF1) to display the 07754 ; title line. Then, the title line is cleared and the words of the title phrase 07755 ; are copied into it using the passed offset into title phrase table PHRASETAB 07756 ; ($BBAA). If the offset has a value of $FF the title line is hidden in 07757 ; subroutine MODDLST ($ADF1). 07758 ; 07759 ; INPUT 07760 ; 07761 ; Y = Offset into title phrase table PHRASETAB ($BBAA). Used values are: 07762 ; $FF -> Hide title line 07763 ; else -> Offset into title phrase table PHRASETAB ($BBAA), with explicitly 07764 ; used values: 07765 ; 07766 ; $01 -> "COMPUTER ON" 07767 ; $04 -> "COMPUTER OFF" 07768 ; $07 -> "SHIELDS ON" 07769 ; $09 -> "SHIELDS OFF" 07770 ; $0B -> "COMPUTER TRACKING ON" 07771 ; $0E -> "TRACKING OFF" 07772 ; $13 -> "STARBASE SURROUNDED" 07773 ; $15 -> "STARBASE DESTROYED" 07774 ; $1F -> "DOCKING ABORTED" 07775 ; $21 -> "TRANSFER COMPLETE" 07776 ; $4A -> "NOVICE MISSION" 07777 ; $4C -> "PILOT MISSION" 07778 ; $4E -> "WARRIOR MISSION" 07779 ; $50 -> "COMMANDER MISSION" 07780 ; $52 -> "DAMAGE CONTROL..." 07781 ; $75 -> "RED ALERT" 07782 07783 L.WORD = $6A ; Saves word number of WORDTAB ($BC2A). Used values 07784 ; are $00..$3F. 07785 L.COLUMNPOS = $6B ; Saves cursor column position during copying text 07786 ; into title line 07787 L.TOKEN = $6C ; Saves title phrase token from PHRASETAB ($BBAA), 07788 ; contains bit-encoded information about one word in 07789 ; the title phrase: 07790 ; B7..6 = %00 -> Copy next word to title line 07791 ; B7..6 = %01 -> End-of-phrase reached, apply short 07792 ; delay, then hide title line. Title 07793 ; segment lifetime = 60 game loops. 07794 ; B7..6 = %10 -> End-of-segment reached. Title 07795 ; segment lifetime = 60 game loops 07796 ; B7..6 = %11 -> End-of-phrase reached, apply long 07797 ; delay, then hide title line. Title 07798 ; segment lifetime = 254 game loops. 07799 ; Used with title phrases 07800 ; "STARBASE SURROUNDED" 07801 ; "STARBASE DESTROYED" 07802 ; "HYPERSPACE" 07803 ; "RED ALERT" 07804 ; B5..0 -> Word number of WORDTAB ($BC2A) 07805 07806 SETTITLE STY TITLEPHR ; Save title phrase offset 07807 07808 LDY #$23 ; Show title line 07809 LDX #$0F ; 07810 LDA #$07 ; 07811 JSR MODDLST ; 07812 07813 ;*** Init cursor column position and clear title line ************************** 07814 SKIP176 LDX #19 ; There are 19(+1) characters to clear 07815 LDA #0 ; 07816 STA L.COLUMNPOS ; Init cursor column position 07817 07818 LOOP055 STA TITLETXT,X ; Clear character in title line 07819 DEX ; 07820 BPL LOOP055 ; 07821 07822 ;*** If title phrase offset = $FF then hide title line ************************* 07823 SKIP177 LDX TITLEPHR ; Load title phrase offset 07824 INC TITLEPHR ; Prepare title phrase offset for next word 07825 BNE SKIP178 ; ...skip if it turned 0 07826 07827 LDX #$0F ; Remove title line and return 07828 LDY #$80 ; 07829 LDA #$07 ; 07830 JMP MODDLST ; 07831 07832 SKIP178 LDA PHRASETAB,X ; Get phrase token 07833 07834 ;*** Display scored class? ***************************************************** 07835 CMP #$FC ; Skip if not "scored class" token 07836 BNE SKIP179 ; 07837 07838 LDY SCOREDCLASSIND ; Get scored class index, is in 0..15 07839 LDA CLASSTAB,Y ; Load scored class number digit 07840 LDX L.COLUMNPOS ; Load cursor position 07841 STA TITLETXT,X ; Store class in title line 07842 LDA #60 ; Title segment lifetime := 60 game loops 07843 STA TITLELIFE ; 07844 RTS ; Return 07845 07846 ;*** Display scored rank? ****************************************************** 07847 SKIP179 CMP #$FD ; Skip if not "scored rank" token 07848 BNE SKIP180 ; 07849 07850 LDY SCOREDRANKIND ; Get scored rank index, is in 0..18 07851 LDA RANKTAB,Y ; Load rank word number 07852 07853 ;*** Search word of token in word table **************************************** 07854 SKIP180 STA L.TOKEN ; Save phrase token 07855 AND #$3F ; Strip bits B6..7 from phrase token 07856 STA L.WORD ; Store word number (bits B5..0) 07857 07858 LDA #<[WORDTAB-1] ; Point MEMPTR to WORDTAB-1 07859 STA MEMPTR ; 07860 LDA #>[WORDTAB-1] ; 07861 STA MEMPTR+1 ; 07862 07863 LOOP056 INC MEMPTR ; Increment MEMPTR 07864 BNE SKIP181 ; 07865 INC MEMPTR+1 ; 07866 07867 SKIP181 LDY #0 ; 07868 LDA (MEMPTR),Y ; Load character of word 07869 BPL LOOP056 ; Loop until end-of-word marker (bit B7) found 07870 DEC L.WORD ; 07871 BNE LOOP056 ; Loop until word found 07872 07873 ;*** Copy word to title line, add space **************************************** 07874 LOOP057 AND #$3F ; Strip color bits B6..7 from character 07875 EOR #CCS.COL2!$20 ; Merge COLOR2 bits and convert to ATASCII 07876 LDX L.COLUMNPOS ; Copy character to title line 07877 INC L.COLUMNPOS ; Increment cursor column position 07878 STA TITLETXT,X ; 07879 INY ; 07880 LDA (MEMPTR),Y ; Load next character of word 07881 BPL LOOP057 ; Next character of word if no end-of-word marker 07882 INC L.COLUMNPOS ; Word was copied. Add space after word. 07883 07884 ;*** Decide to copy another word, etc. ***************************************** 07885 LDA #60 ; SUMMARY: 07886 BIT L.TOKEN ; If bits B7..6 of phrase token... 07887 BPL SKIP182 ; %00 -> Copy next word to title line 07888 BVC SKIP183 ; %01 -> End-of-phrase, short delay, hide title line 07889 LDA #254 ; Title segment lifetime := 60 game loops 07890 SKIP182 BVC SKIP177 ; %10 -> End-of-segment. 07891 LDY #$FF ; Title segment lifetime := 60 game loops 07892 STY TITLEPHR ; %11 -> End-of-phrase, long delay, hide title line 07893 SKIP183 STA TITLELIFE ; Title segment lifetime := 254 game loops 07894 RTS ; Return 07895 07896 ;******************************************************************************* 07897 ;* * 07898 ;* SOUND * 07899 ;* * 07900 ;* Handle sound effects * 07901 ;* * 07902 ;******************************************************************************* 07903 07904 ; DESCRIPTION 07905 ; 07906 ; This subroutine handles the sound effects. It is called every vertical blank 07907 ; phase, that is, every TICK (1/60 s on an NTSC Atari 8-bit Home Computer 07908 ; system, 1/50 s on a PAL Atari 8-bit Home Computer system) from the Vertical 07909 ; Blank Interrupt handler VBIHNDLR ($A6D1). 07910 ; 07911 ; The game uses all of the available 4 audio channels: Audio channels 1, 2, and 07912 ; 3 are shared among the Engines sound effects and the "noise sound patterns" 07913 ; (explosion and photon torpedo sound effects), while audio channel 4 is used 07914 ; for "beeper sound patterns" (status report sound effects). The following 07915 ; sections explain the beeper sound patterns and the noise sound patterns: 07916 ; 07917 ; o BEEPER SOUND PATTERNS 07918 ; 07919 ; There are the following beeper sound patterns: 07920 ; 07921 ; (1) HYPERWARP TRANSIT 07922 ; (2) RED ALERT 07923 ; (3) ACKNOWLEDGE 07924 ; (4) DAMAGE REPORT 07925 ; (5) MESSAGE FROM STARBASE 07926 ; 07927 ; They are encoded in table BEEPPATTAB ($BF3E) in 6-byte long "beeper sound 07928 ; patterns". 07929 ; 07930 ; Another table, BEEPFRQTAB ($BF5C), stores the frequencies for the tones 07931 ; of each beeper sound pattern, terminated by a marker byte ($FF). 07932 ; 07933 ; BUG (at $BF5C): The pattern frequencies in table BEEPFRQTAB ($BF5C) at 07934 ; offset $00 are unused. Suggested Fix: Remove from code. 07935 ; 07936 ; Whenever the game calls subroutine BEEP ($B3A6), that subroutine sets up a 07937 ; beeper sound pattern for playing by copying 6 bytes from the pattern table 07938 ; BEEPPATTAB ($BF3E) to BEEPFRQIND ($D2)..BEEPFRQSTART ($D7). Subroutine 07939 ; SOUND ($B2AB) detects the copied beeper sound pattern and plays the 07940 ; encoded tones and pauses. 07941 ; 07942 ; The relevant variables for playing a beeper sound pattern are the 07943 ; following (see also figures at BEEPPATTAB ($BF3E)): 07944 ; 07945 ; BEEPFRQIND ($D2) = Running index into table BEEPFRQTAB ($BF5C) 07946 ; BEEPREPEAT ($D3) = Number of times that the beeper sound pattern is 07947 ; repeated - 1 07948 ; BEEPTONELIFE ($D4) = Lifetime of tone in TICKs - 1 07949 ; BEEPPAUSELIFE ($D5) = Lifetime of pause in TICKs - 1 ($FF -> No pause) 07950 ; BEEPPRIORITY ($D6) = Beeper sound pattern priority. A playing beeper 07951 ; sound pattern is stopped if a beeper sound pattern 07952 ; of higher priority is about to be played. A value 07953 ; of 0 indicates that no beeper sound pattern is 07954 ; playing at the moment. 07955 ; BEEPFRQSTART ($D7) = Index to first byte of the beeper sound pattern in 07956 ; table BEEPFRQTAB ($BF5C) 07957 ; 07958 ; BEEPLIFE ($D8) = Lifetime of the current tone or pause in TICKs 07959 ; BEEPTOGGLE ($D9) = Indicates that either a tone (0) or a pause (not 07960 ; 0) is currently playing. 07961 ; 07962 ; o NOISE SOUND PATTERNS 07963 ; 07964 ; There are the following noise sound patterns: 07965 ; 07966 ; (1) PHOTON TORPEDO LAUNCHED 07967 ; (2) SHIELD EXPLOSION 07968 ; (3) ZYLON EXPLOSION 07969 ; 07970 ; They are encoded in table NOISEPATTAB ($BF20) in 10-byte long "noise sound 07971 ; patterns". 07972 ; 07973 ; Whenever the game calls subroutine NOISE ($AEA8), that subroutine sets up 07974 ; a noise sound pattern for being played by copying 10 bytes from the 07975 ; pattern table NOISEPATTAB ($BF20) to NOISETORPTIM ($DA)..NOISELIFE ($E1) 07976 ; and hardware sound registers AUDCTL ($D208) and AUDF3 ($D204). 07977 ; 07978 ; The relevant variables for playing a noise sound pattern are the 07979 ; following: 07980 ; 07981 ; NOISETORPTIM ($DA) = Delay timer for PHOTON TORPEDO LAUNCHED noise 07982 ; sound pattern 07983 ; NOISEEXPLTIM ($DB) = Delay timer for SHIELD EXPLOSION and ZYLON 07984 ; EXPLOSION noise sound patterns 07985 ; NOISEAUDC2 ($DC) = Audio channel 1/2 control shadow register 07986 ; NOISEAUDC3 ($DD) = Audio channel 3 control shadow register 07987 ; NOISEAUDF1 ($DE) = Audio channel 1 frequency shadow register 07988 ; NOISEAUDF2 ($DF) = Audio channel 2 frequency shadow register 07989 ; NOISEFRQINC ($E0) = Audio channel 1/2 frequency increment 07990 ; NOISELIFE ($E1) = Noise sound pattern lifetime 07991 ; 07992 ; AUDCTL ($D208) = POKEY: Audio control 07993 ; AUDF3 ($D204) = POKEY: Audio channel 3 frequency audio register 07994 ; 07995 ; There are two more variables that trigger noise effects. They are not part 07996 ; of the noise sound pattern table: 07997 ; 07998 ; NOISEZYLONTIM ($E2) = Delay timer to trigger the ZYLON EXPLOSION noise 07999 ; sound pattern. It is set in subroutine COLLISION 08000 ; ($AF3D) when the impact of one of our starship's 08001 ; photon torpedoes with a target is imminent. The 08002 ; timer is decremented every TICK. When it reaches a 08003 ; value of 0 the ZYLON EXPLOSION noise sound pattern 08004 ; is played in subroutine SOUND ($B2AB). 08005 ; NOISEHITLIFE ($E3) = Lifetime of the STARSHIP EXPLOSION noise when our 08006 ; starship was destroyed by a Zylon photon torpedo. 08007 ; It is set in GAMELOOP ($A1F3) to a value of 64 08008 ; TICKs. When it reaches a value of 0 the STARSHIP 08009 ; EXPLOSION noise is played in subroutine SOUND 08010 ; ($B2AB). 08011 ; 08012 ; SUBROUTINE DETAILS 08013 ; 08014 ; This subroutine executes the following steps: 08015 ; 08016 ; (1) Play beeper sound pattern 08017 ; 08018 ; The playing of a beeper sound pattern is started, continued, or stopped. 08019 ; 08020 ; (2) Play ZYLON EXPLOSION noise sound pattern 08021 ; 08022 ; If the explosion of a target space object is imminent (subroutine 08023 ; COLLISION ($AF3D) has set NOISEZYLONTIM ($E2) to the number of game loop 08024 ; iterations that will pass until our starship's photon torpedo will hit 08025 ; the target), the timer NOISEZYLONTIM ($E2) is decremented every TICK. If 08026 ; it reaches a value of 0, then the noise sound pattern ZYLON EXPLOSION is 08027 ; played. 08028 ; 08029 ; (3) Play starship's Engines sound 08030 ; 08031 ; If the Engines are louder than the current noise sound pattern then the 08032 ; noise sound pattern is terminated and the values for the audio channels 08033 ; 1..3 are updated: 08034 ; 08035 ; The velocity of our starship determines the pitch and the volume of the 08036 ; Engines: the higher the velocity, the higher the pitch and the volume of 08037 ; the Engines. The incremented value of VELOCITYLO ($70) is used as a "base 08038 ; value" %abcdefgh. 08039 ; 08040 ; Audio channels 1 and 2 are combined to a 16-bit audio channel 1/2, 08041 ; clocked at 1.79 MHz. The inverted bits (represented by an overscore) 08042 ; B7..0 of the base value form bits B12..5 of the 16-bit frequency value of 08043 ; audio channel 1/2. Bits B7..4 of the base value form bits B3..0 of the 08044 ; volume of audio channel 1/2, with noise distortion bit B7 set: 08045 ; ________ 08046 ; AUDF1/2 ($D202..3) := %000abcdefgh00000 08047 ; AUDC2 ($D203) := %1000abcd 08048 ; 08049 ; Audio channel 3 is also clocked at 1.79 MHz. The inverted bits B7..0 of 08050 ; the base value form bits B7..0 of the frequency value of audio channel 3. 08051 ; Bits B6..4 of the base value form bits B3..0 of the volume of audio 08052 ; channel 3, with noise distortion bit B7 set: 08053 ; ________ 08054 ; AUDF3 ($D204) := %abcdefgh 08055 ; AUDC3 ($D205) := %10000bcd 08056 ; 08057 ; Code execution returns at this point. 08058 ; 08059 ; (4) Play ZYLON EXPLOSION or SHIELD EXPLOSION noise sound pattern 08060 ; 08061 ; If the ZYLON EXPLOSION or SHIELD EXPLOSION noise sound pattern was set 08062 ; up, the explosion noise timer NOISEEXPLTIM ($DB) is decremented every 08063 ; TICK. It starts either with a value of 4 TICKs with a ZYLON EXPLOSION 08064 ; noise sound pattern or with a value of 8 TICKs with a SHIELD EXPLOSION 08065 ; noise sound pattern, set up in subroutine NOISE ($AEA8). If it reaches a 08066 ; value of 0, then the shadow control register of audio channel 1/2 08067 ; switches to "noise distortion" at maximum volume. 08068 ; 08069 ; (5) Play PHOTON TORPEDO LAUNCHED noise sound pattern 08070 ; 08071 ; If the PHOTON TORPEDO LAUNCHED noise sound pattern was set up, the photon 08072 ; torpedo noise timer NOISETORPTIM ($DA) is decremented every TICK. It 08073 ; starts with a value of 8 TICKs, set in subroutine TRIGGER ($AE29). The 08074 ; noise distortion and volume for the shadow control register of audio 08075 ; channel 3 is picked from table NOISETORPVOLTAB ($BFEB), the noise 08076 ; frequency for audio channel 3 is picked from table NOISETORPFRQTAB 08077 ; ($BFF3). If the photon torpedo noise timer reaches a value of 0, then the 08078 ; shadow control registers of audio channel 1/2 switch to "tone distortion" 08079 ; at maximum volume and a frequency of $0202. 08080 ; 08081 ; NOTE: Using a real-time volume envelope stored in table NOISETORPVOLTAB 08082 ; ($BFEB) for a launched photon torpedo results in producing the 08083 ; distinctive "whooshing" photon torpedo sound. 08084 ; 08085 ; (6) Play STARSHIP EXPLOSION noise 08086 ; 08087 ; If our starship was hit by a Zylon photon torpedo then NOISEHITLIFE ($E3) 08088 ; was set to 64 TICKs in routine GAMELOOP ($A1F3). While this value is 08089 ; decremented every TICK, a random frequency value is stored to audio 08090 ; channel 3 and the distortion bit of the shadow control register of audio 08091 ; channel 3 is randomly toggled. 08092 ; 08093 ; (7) Increase audio channels 1/2 frequency 08094 ; 08095 ; The 16-bit frequency value of audio channels 1/2 (both shadow registers 08096 ; and audio registers) is increased every TICK by an increment picked from 08097 ; the currently playing noise sound pattern. 08098 ; 08099 ; (8) Mute audio channels gradually 08100 ; 08101 ; Toward the end of a noise sound pattern's lifetime all audio channels 08102 ; gradually mute their volume every other TICK until completely silent. 08103 08104 ;*** Play beeper sound pattern ************************************************* 08105 SOUND LDA BEEPPRIORITY ; Skip if beeper sound pattern not in use 08106 BEQ SKIP185 ; 08107 08108 DEC BEEPLIFE ; Decrement beeper lifetime 08109 BPL SKIP185 ; Skip if beeper lifetime still counting down 08110 08111 LDA BEEPTOGGLE ; Load tone/pause toggle 08112 BEQ LOOP058 ; Skip if a tone is playing or is to be played 08113 08114 LDA BEEPPAUSELIFE ; Load pause lifetime 08115 BMI LOOP058 ; Skip if duration = $FF (no pause) 08116 STA BEEPLIFE ; Store pause lifetime as beeper lifetime 08117 LDY #0 ; Prep AUDC4 (zero volume) 08118 BEQ SKIP184 ; Skip unconditionally 08119 08120 LOOP058 LDA BEEPTONELIFE ; Load tone lifetime 08121 STA BEEPLIFE ; Store tone lifetime as beeper lifetime 08122 LDX BEEPFRQIND ; Load frequency index 08123 INC BEEPFRQIND ; Increment frequency index 08124 LDA BEEPFRQTAB,X ; Store tone frequency from frequency table in AUDF4 08125 STA AUDF4 ; 08126 LDY #$A8 ; Prep AUDC4 (tone distortion + medium volume) 08127 CMP #$FF ; Skip if frequency not $FF (there are more tones) 08128 BNE SKIP184 ; 08129 08130 LDA BEEPFRQSTART ; Rewind pattern frequency pointer 08131 STA BEEPFRQIND ; 08132 DEC BEEPREPEAT ; Decrement sequence counter 08133 BPL LOOP058 ; Keep playing until sequence counter < 0 08134 08135 LDY #0 ; Prep AUDC4 with zero volume 08136 STY BEEPPRIORITY ; Stop playing beeper sound pattern 08137 08138 SKIP184 STY AUDC4 ; Store in AUDC4 08139 STY BEEPTOGGLE ; Store in BEEPTOGGLE 08140 08141 ;*** Play ZYLON EXPLOSION noise sound pattern ********************************** 08142 SKIP185 LDA NOISEZYLONTIM ; Skip if ZYLON EXPLOSION timer not in use 08143 BEQ SKIP186 ; 08144 08145 DEC NOISEZYLONTIM ; Decrement ZYLON EXPLOSION timer 08146 BNE SKIP186 ; Skip if ZYLON EXPLOSION timer still counting down 08147 08148 LDX #$14 ; Play noise sound pattern ZYLON EXPLOSION 08149 JSR NOISE ; 08150 08151 ;*** Play our starship's Engines sound ***************************************** 08152 SKIP186 LDX VELOCITYLO ; Skip if Engines softer than noise sound pattern 08153 TXA ; 08154 LSR A ; 08155 LSR A ; 08156 LSR A ; 08157 LSR A ; 08158 LSR A ; 08159 CMP NOISELIFE ; 08160 BCC SKIP187 ; 08161 08162 LDA #0 ; Terminate noise sound pattern 08163 STA NOISELIFE ; 08164 08165 INX ; 08166 TXA ; A := %abcdefgh = VELOCITYLO + 1 08167 EOR #$FF ; ________ 08168 STA AUDF3 ; AUDF3 := %abcdefgh 08169 08170 TAX ; ________ 08171 ASL A ; AUDF2/1 := %000abcdefgh00000 08172 ASL A ; 08173 ASL A ; 08174 ASL A ; 08175 ASL A ; 08176 STA AUDF1 ; 08177 TXA ; 08178 LSR A ; 08179 LSR A ; 08180 LSR A ; 08181 STA AUDF2 ; 08182 08183 LSR A ; AUDC2 := %1000abcd 08184 EOR #$8F ; (noise distortion + B7..B4 bits for volume) 08185 STA AUDC2 ; 08186 08187 AND #$87 ; AUDC3 := %10000bcd 08188 STA AUDC3 ; (noise distortion + B6..B4 bits for volume) 08189 08190 LDA #$70 ; Clock audio channel 1 and 3 @ 1.79 MHz and... 08191 STA AUDCTL ; ...combine audio channel 1/2 to 16-bit channel 08192 08193 RTS ; Return 08194 08195 ;*** Play ZYLON EXPLOSION or SHIELD EXPLOSION noise **************************** 08196 SKIP187 LDA NOISEEXPLTIM ; Skip if explosion noise timer not in use 08197 BEQ SKIP188 ; 08198 08199 DEC NOISEEXPLTIM ; Decrement explosion noise timer (4 or 8 TICKs long) 08200 BNE SKIP188 ; Skip if explosion noise timer still counting down 08201 08202 LDA #$8F ; Shadow register AUDC2 := (noise dist. + max volume) 08203 STA NOISEAUDC2 ; 08204 08205 ;*** Play PHOTON TORPEDO LAUNCHED noise sound ********************************** 08206 SKIP188 LDX NOISETORPTIM ; Skip if photon torpedo noise timer not in use 08207 BEQ SKIP190 ; 08208 08209 DEC NOISETORPTIM ; Decrement photon torpedo noise timer (8 TICKs long) 08210 BNE SKIP189 ; Skip if torpedo noise timer still counting down 08211 08212 LDA #$AF ; Shadow register AUDC2 := (tone dist. + max volume) 08213 STA NOISEAUDC2 ; 08214 LDA #$02 ; Set frequency $0202 to AUDF1/2's shadow... 08215 STA NOISEAUDF1 ; ...registers 08216 STA NOISEAUDF2 ; 08217 08218 SKIP189 LDA NOISETORPVOLTAB-1,X ; Pick torpedo noise + volume shape (X in 1..8)... 08219 STA NOISEAUDC3 ; ...and store it in AUDC3's shadow register 08220 LDA NOISETORPFRQTAB-1,X ; Pick photon torpedo noise frequency (X in 1..8)... 08221 STA AUDF3 ; ...and store it in AUDF3 08222 STA STIMER ; Reset POKEY audio timers 08223 08224 ;*** Play STARSHIP EXPLOSION noise when our starship is hit ******************** 08225 SKIP190 LDA NOISEHITLIFE ; Skip if STARSHIP EXPLOSION noise not in use 08226 BEQ SKIP191 ; 08227 08228 DEC NOISEHITLIFE ; Decrement STARSHIP EXPLOSION noise lifetime 08229 LDA RANDOM ; Set random frequency to AUDF3 08230 STA AUDF3 ; 08231 AND #$20 ; Toggle noise/tone dist. of AUDC3's shadow register 08232 EOR NOISEAUDC3 ; ...randomly 08233 STA NOISEAUDC3 ; 08234 08235 ;*** Increase 16-bit frequency of audio channels 1/2 (shadow registers also) *** 08236 SKIP191 CLC ; Increase 16-bit frequency value of AUDF1/2... 08237 LDA NOISEAUDF1 ; ...and its shadow register by... 08238 ADC NOISEFRQINC ; ...noise sound pattern frequency increment 08239 STA NOISEAUDF1 ; AUDF1/2 := NOISEAUDF1/2 := ... 08240 STA AUDF1 ; ...NOISEAUDF1/2 + NOISEFRQINC 08241 LDA NOISEAUDF2 ; 08242 ADC #0 ; 08243 STA NOISEAUDF2 ; 08244 STA AUDF2 ; 08245 08246 ;*** Gradually mute audio channels while noise sound pattern expires *********** 08247 LDX NOISEAUDC2 ; Prep AUDC2's shadow register value 08248 LDY NOISEAUDC3 ; Prep AUDC3's shadow register value 08249 08250 LDA COUNT8 ; Decrement volumes every other TICK 08251 LSR A ; 08252 BCC SKIP193 ; 08253 08254 LDA NOISELIFE ; Skip if noise sound pattern not in use 08255 BEQ SKIP193 ; 08256 08257 DEC NOISELIFE ; Decrement noise sound pattern lifetime 08258 08259 CMP #17 ; Mute noise sound pattern only in... 08260 BCS SKIP193 ; ...the last 16 TICKs of its lifetime 08261 08262 TXA ; Decrement volume of AUDC2's shadow register 08263 AND #$0F ; 08264 BEQ SKIP192 ; 08265 DEX ; 08266 STX NOISEAUDC2 ; 08267 08268 SKIP192 TYA ; Decrement volume of AUDC3's shadow register 08269 AND #$0F ; 08270 BEQ SKIP193 ; 08271 DEY ; 08272 STY NOISEAUDC3 ; 08273 08274 SKIP193 STX AUDC2 ; Store shadow register values to audio registers 08275 STY AUDC3 ; 08276 08277 RTS ; Return 08278 08279 ;******************************************************************************* 08280 ;* * 08281 ;* BEEP * 08282 ;* * 08283 ;* Copy beeper sound pattern * 08284 ;* * 08285 ;******************************************************************************* 08286 08287 ; DESCRIPTION 08288 ; 08289 ; Copies a 6-byte beeper sound pattern from beeper sound pattern table 08290 ; BEEPPATTAB ($BF3E) to BEEPFRQIND ($D2)..BEEPFRQSTART ($D7), provided that no 08291 ; beeper sound pattern with higher priority is currently playing. The beeper 08292 ; sound pattern will then be automatically played in subroutine SOUND ($B2AB). 08293 ; See subroutine SOUND ($B2AB) for more information on beeper sound patterns. 08294 ; 08295 ; NOTE: The bytes from table BEEPPATTAB ($BF3E) are copied in reverse order. 08296 ; 08297 ; INPUT 08298 ; 08299 ; X = Offset to beeper sound pattern in table BEEPPATTAB ($BF3E). Used values 08300 ; are: 08301 ; $00 -> HYPERWARP TRANSIT 08302 ; $06 -> RED ALERT 08303 ; $0C -> ACKNOWLEDGE 08304 ; $12 -> DAMAGE REPORT 08305 ; $18 -> MESSAGE FROM STARBASE 08306 08307 BEEP LDA BEEPPATTAB,X ; Return if beeper sound pattern of... 08308 CMP BEEPPRIORITY ; ...higher priority is playing 08309 BCC SKIP194 ; 08310 08311 LDY #5 ; Copy 6-byte beeper sound pattern (in reverse order) 08312 LOOP059 LDA BEEPPATTAB,X ; 08313 STA BEEPFRQIND,Y ; 08314 INX ; 08315 DEY ; 08316 BPL LOOP059 ; 08317 08318 SKIP194 RTS ; Return 08319 08320 ;******************************************************************************* 08321 ;* * 08322 ;* INITIALIZE * 08323 ;* * 08324 ;* More game initialization * 08325 ;* * 08326 ;******************************************************************************* 08327 08328 ; DESCRIPTION 08329 ; 08330 ; This subroutine executes the following initialization steps: 08331 ; 08332 ; (1) Set up Display List 08333 ; 08334 ; A Display List is created at DSPLST ($0280). It starts with 2 x 8 = 16 08335 ; blank video lines, followed by 90 GRAPHICS7 rows. After a deliberate gap 08336 ; in Display List instructions, which will be filled dynamically during the 08337 ; game by calls to subroutine MODDLST ($ADF1), it ends with a Display List 08338 ; wait-and-jump-back instruction to the start of the Display List at DSPLST 08339 ; ($0280). 08340 ; 08341 ; NOTE: The PLAYFIELD color table PFCOLORTAB ($BFA9) is copied to zero-page 08342 ; table PF0COLOR ($F2) by loop jamming. 08343 ; 08344 ; (2) Create lookup tables 08345 ; 08346 ; The first lookup table MAPTO80 ($0DE9) maps a byte value of 0..255 to 08347 ; 0..80. This table is used to map unsigned (absolute) position vector 08348 ; components (coordinates) to pixel (or PLAYER) row and column numbers. 08349 ; 08350 ; NOTE: The PLAYFIELD is 160 pixels wide. Pixel column numbers relative the 08351 ; horizontal PLAYFIELD center are in -80..79, hence the range of this 08352 ; lookup table. Pixel row numbers relative the vertical PLAYFIELD center 08353 ; are in -50..49, thus they also fit in the range of this lookup table. 08354 ; 08355 ; The second lookup table MAPTOBCD99 ($0EE9) maps a byte value of 0..255 to 08356 ; a BCD-encoded value in 00..99. This table is used to convert byte values 08357 ; into decimal 2-digit values displayed by the THETA (in "gradons"), PHI 08358 ; (in "gradons"), RANGE (in "centrons"), and VELOCITY (in "metrons per 08359 ; second") readouts of the Console Panel Display. 08360 ; 08361 ; The third and fourth lookup tables accelerate drawing of PLAYFIELD space 08362 ; objects: In combination they contain the 16-bit start addresses of each 08363 ; of the 100 rows of PLAYFIELD memory. The low bytes of the 16-bit 08364 ; addresses are stored in table PFMEMROWLO ($0800). The high bytes are 08365 ; stored in table PFMEMROWHI ($0864). 08366 ; 08367 ; NOTE: The address increment is 40 (40 bytes = 160 pixels in GRAPHICS7 08368 ; mode = 1 PLAYFIELD row of pixels). 08369 ; 08370 ; NOTE: The PLAYFIELD consists of 90 GRAPHICS7 rows when the Control Panel 08371 ; Display is displayed at the bottom. When the Control Panel Display is not 08372 ; displayed, for example in demo mode, the PLAYFIELD contains additional 08373 ; GRAPHICS7 rows. 08374 ; 08375 ; (3) Copy Control Panel Display and Galactic Chart Panel Display texts 08376 ; 08377 ; The texts of the Control Panel Display and the Galactic Chart Panel 08378 ; Display are copied to their respective locations in memory by loop 08379 ; jamming. 08380 ; 08381 ; (4) Initialize Zylon unit movement timer 08382 ; 08383 ; The timer that triggers the movement of Zylon units in the Galactic Chart 08384 ; is initialized to a value of 99. See subroutine FLUSHGAMELOOP ($B4E4) for 08385 ; more information on Zylon unit movement. 08386 ; 08387 ; (5) Create Galactic Chart 08388 ; 08389 ; The Galactic Chart memory map GCMEMMAP ($08C9) is initialized. It 08390 ; represents 16 columns x 8 rows of sectors. Each sector contains one of 08391 ; the 4 sector types stored in table SECTORTYPETAB ($BBA6) (starbase, 4 08392 ; Zylon ships, 3 Zylon ships, and 2 or 1 Zylon ships), and empty sectors. 08393 ; Before distributing the sector types, the initial position of our 08394 ; starship is blocked on the Galactic Chart at sector row 4, sector column 08395 ; 8, so that it will not be inadvertently occupied while other sector types 08396 ; are distributed. The number of each of the sector types to be distributed 08397 ; is the mission level plus 2. While Zylon units can be placed anywhere, 08398 ; starbases are placed neither at the borders of the Galactic Chart nor in 08399 ; a sector adjacent to an occupied sector. 08400 ; 08401 ; After having initialized the Galactic Chart memory map, the top border of 08402 ; the Galactic Chart is drawn with characters from the custom character 08403 ; set. 08404 ; 08405 ; Finally, the sector in which our starship is located and the arrival and 08406 ; departure hyperwarp marker column and row numbers are initialized. 08407 ; 08408 ; (6) Apply a final tweak 08409 ; 08410 ; The last entry of lookup table MAPTOBCD99 ($0EE9) is tweaked to a value 08411 ; of CCS.INF * 16 + CCS.SPC. It is used to display an infinity symbol by 08412 ; the RANGE readout of the Control Panel Display in subroutine SHOWCOORD 08413 ; ($B8A7). 08414 ; 08415 ; Code execution continues into subroutine DRAWGC ($B4B9), which draws the 08416 ; content of the Galactic Chart with characters from the custom character set. 08417 08418 L.MEMPTR1 = $68 ; 16-bit memory pointer 08419 L.MEMPTR2 = $6A ; 16-bit memory pointer 08420 L.SECTORTYPE = $6A ; Saves sector type. Used values are: 08421 ; $CF -> Sector contains starbase 08422 ; $04 -> Sector contains 4 Zylon ships 08423 ; $03 -> Sector contains 3 Zylon ships 08424 ; $02 -> Sector contains 2 or 1 Zylon ships 08425 L.SECTORCNT = $6B ; Saves number of sectors of the current sector type 08426 08427 ;*** Initialize Display List and copy color table ****************************** 08428 INITIALIZE LDX #89 ; Set 89(+1) GRAPHICS7 rows from DSPLST+5 on 08429 LOOP060 LDA #$0D ; Prep DL instruction $0D (one row of GRAPHICS7) 08430 STA DSPLST+5,X ; DSPLST+5,X := one row of GRAPHICS7 08431 CPX #10 ; 08432 BCS SKIP195 ; 08433 LDA PFCOLORTAB,X ; Copy PLAYFIELD color table to zero-page table 08434 STA PF0COLOR,X ; (loop jamming) 08435 SKIP195 DEX ; 08436 BPL LOOP060 ; 08437 08438 LDA #$70 ; DSPLST := BLK8 08439 STA DSPLST ; DSPLST+1 := BLK8 08440 STA DSPLST+1 ; 08441 LDA #$41 ; DSPLST+103 := WAITJMP @ DSPLST 08442 STA DSPLST+103 ; 08443 LDA #DSPLST ; 08446 STA DSPLST+105 ; 08447 08448 ;*** Calculate lookup tables *************************************************** 08449 LDX #0 ; Clear both 16-bit memory pointers 08450 STX L.MEMPTR1 ; 08451 STX L.MEMPTR1+1 ; 08452 STX L.MEMPTR2 ; 08453 STX L.MEMPTR2+1 ; 08454 08455 ;*** Calc MAPTO80 map (converts value of $00..$FF to value in 0..80) *********** 08456 LOOP061 CLC ; 08457 LDA L.MEMPTR1 ; 08458 ADC #81 ; 08459 STA L.MEMPTR1 ; 08460 LDA L.MEMPTR1+1 ; 08461 STA MAPTO80,X ; 08462 ADC #0 ; 08463 STA L.MEMPTR1+1 ; 08464 08465 ;*** Calc MAPTOBCD99 map (converts value of $00..$FF to BCD-value in 00..99) *** 08466 CLC ; 08467 LDA L.MEMPTR2 ; 08468 ADC #100 ; 08469 STA L.MEMPTR2 ; 08470 LDA L.MEMPTR2+1 ; 08471 STA MAPTOBCD99,X ; 08472 SED ; 08473 ADC #0 ; 08474 CLD ; 08475 STA L.MEMPTR2+1 ; 08476 INX ; 08477 BNE LOOP061 ; 08478 08479 ;*** Calculate PLAYFIELD memory row addresses, copy Panel Display texts ******** 08480 LDX #PFMEM ; 08483 STA L.MEMPTR1+1 ; 08484 08485 LOOP062 CLC ; 08486 LDA L.MEMPTR1 ; 08487 STA PFMEMROWLO,X ; Store 16-bit value of L.MEMPTR1 in PFMEMROWHI/LO 08488 ADC #40 ; Add 40 to L.MEMPTR 08489 STA L.MEMPTR1 ; (40 bytes = 160 pixels = 1 PLAYFIELD row) 08490 LDA L.MEMPTR1+1 ; 08491 STA PFMEMROWHI,X ; 08492 ADC #0 ; 08493 STA L.MEMPTR1+1 ; 08494 08495 LDA PANELTXTTAB,X ; Copy Control and Galactic Chart Panel Display texts 08496 STA PANELTXT,X ; (loop jamming) 08497 08498 INX ; 08499 CPX #100 ; 08500 BCC LOOP062 ; Loop 100 times 08501 08502 ;*** Set Zylon unit movement timer ********************************************* 08503 DEX ; 08504 STX ZYLONUNITTIM ; Init Zylon unit movement timer to 99 game loops 08505 08506 ;*** Create memory map of the Galactic Chart *********************************** 08507 LDX #3 ; Loop over all 3(+1) sector types 08508 STX GCMEMMAP+4*16+8 ; Block our starship's initial position at center of 08509 ; ...Galactic Chart (sector row 4, sector column 8) 08510 08511 LOOP063 LDA SECTORTYPETAB,X ; Prep sector type 08512 STA L.SECTORTYPE ; 08513 08514 LDY MISSIONLEVEL ; Number sectors of current type := mission level + 2 08515 INY ; 08516 INY ; 08517 STY L.SECTORCNT ; 08518 08519 LOOP064 LDA RANDOM ; Load random sector 0..127 from GC memory map 08520 AND #$7F ; 08521 TAY ; 08522 LDA GCMEMMAP,Y ; 08523 BNE LOOP064 ; If sector already occupied, pick another 08524 08525 LDA L.SECTORTYPE ; Reload sector type 08526 BPL SKIP196 ; Skip if sector not to be occupied by starbase 08527 08528 CPY #$10 ; Place starbase... 08529 BCC LOOP064 ; ...not in first sector row of Galactic Chart 08530 CPY #$70 ; 08531 BCS LOOP064 ; ...not in last sector row of Galactic Chart 08532 TYA ; 08533 AND #$0F ; 08534 BEQ LOOP064 ; ...not in first sector column of Galactic Chart 08535 CMP #15 ; 08536 BEQ LOOP064 ; ...not in last sector column of Galactic Chart 08537 LDA GCMEMMAP-1,Y ; ...not east of an occupied sector 08538 ORA GCMEMMAP+1,Y ; ...not west of an occupied sector 08539 ORA GCMEMMAP+16,Y ; ...not south of an occupied sector 08540 ORA GCMEMMAP-16,Y ; ...not north of an occupied sector 08541 BNE LOOP064 ; 08542 08543 LDA L.SECTORTYPE ; Reload sector type 08544 08545 SKIP196 STA GCMEMMAP,Y ; Store sector type in Galactic Chart memory map 08546 DEC L.SECTORCNT ; 08547 BPL LOOP064 ; Next sector 08548 DEX ; 08549 BPL LOOP063 ; Next sector type 08550 08551 ;*** Clear Galactic Chart and draw top border ********************************** 08552 LDX #180 ; Clear Galactic Chart PLAYFIELD 08553 LOOP065 LDA #CCS.SPC ; 08554 STA GCPFMEM-1,X ; 08555 DEX ; 08556 BNE LOOP065 ; 08557 08558 LDX #15 ; Draw top border (15(+1) characters) 08559 LOOP066 LDA #CCS.BORDERS ; 08560 STA GCPFMEM+2,X ; 08561 DEX ; 08562 BPL LOOP066 ; 08563 08564 LDA #CCS.CORNERSW ; Draw NORTHEAST corner (1 character) 08565 STA GCPFMEM+18 ; 08566 08567 LDA #0 ; Release starship's position at center of Galactic 08568 STA GCMEMMAP+4*16+8 ; ...Chart (sector row 4, sector column 8) 08569 08570 ;*** Initialize current sector and hyperwarp marker column and row numbers ***** 08571 LDA #$48 ; Place our starship's current sector at 08572 STA CURRSECTOR ; ...sector row 4, sector column 8 08573 LDA #$43 ; Init departure & arrival hyperwarp marker column 08574 STA WARPDEPRCOLUMN ; 08575 STA WARPARRVCOLUMN ; 08576 LDA #$47 ; Init departure & arrival hyperwarp marker row 08577 STA WARPARRVROW ; 08578 STA WARPDEPRROW ; 08579 08580 ;*** Tweak last entry of MAPTOBCD99 ******************************************** 08581 LDA #CCS.INF*16+CCS.SPC ; Last entry of MAPTOBCD99: 'INFINITY'+'SPACE' char 08582 STA MAPTOBCD99+255 ; 08583 08584 ;******************************************************************************* 08585 ;* * 08586 ;* DRAWGC * 08587 ;* * 08588 ;* Draw Galactic Chart * 08589 ;* * 08590 ;******************************************************************************* 08591 08592 ; DESCRIPTION 08593 ; 08594 ; Draws the content of the Galactic Chart memory map in GCMEMMAP ($08C9) to the 08595 ; Galactic Chart PLAYFIELD memory at GCPFMEM ($0D35). 08596 ; 08597 ; NOTE: CPU register X indexes the Galactic Chart memory map GCMEMMAP ($08C9) 08598 ; (16 x 8 bytes). CPU register Y indexes the Galactic Chart PLAYFIELD memory 08599 ; GCPFMEM ($0D35) (20 x 9 bytes). 08600 ; 08601 ; NOTE: Sectors with 1 or 2 Zylon ships display the same symbol in the Galactic 08602 ; Chart. 08603 08604 L.GCMEMMAPIND = $6A ; Saves Galactic Chart memory map index 08605 08606 DRAWGC LDY #0 ; Clear Galactic Chart PLAYFIELD memory index 08607 STY L.GCMEMMAPIND ; Clear Galactic Chart memory map index 08608 08609 LOOP067 LDX L.GCMEMMAPIND ; Load sector of Galactic Chart memory map 08610 LDA GCMEMMAP,X ; 08611 BPL SKIP197 ; Skip if not a starbase sector 08612 LDA #5 ; Prep sector character index for starbase 08613 08614 SKIP197 TAX ; Load sector character index 08615 LDA SECTORCHARTAB,X ; Load custom character set code from table... 08616 STA GCPFMEM+22,Y ; ...and store it in Galactic Chart PLAYFIELD memory 08617 INY ; Increment Galactic Chart PLAYFIELD memory index 08618 INC L.GCMEMMAPIND ; Increment Galactic Chart memory map index 08619 LDA L.GCMEMMAPIND ; 08620 AND #$0F ; 08621 BNE LOOP067 ; Next sector column until right border reached 08622 08623 LDA #CCS.BORDERW ; Draw right border 08624 STA GCPFMEM+22,Y ; 08625 08626 INY ; Adjust Galactic Chart PLAYFIELD memory index 08627 INY ; 08628 INY ; 08629 INY ; 08630 CPY #$A0 ; 08631 BCC LOOP067 ; Next sector until bottom-right sector reached 08632 08633 RTS ; Return 08634 08635 ;******************************************************************************* 08636 ;* * 08637 ;* FLUSHGAMELOOP * 08638 ;* * 08639 ;* Handle remaining tasks at the end of a game loop iteration * 08640 ;* * 08641 ;******************************************************************************* 08642 08643 ; DESCRIPTION 08644 ; 08645 ; This subroutine handles at the end of a game loop iteration the following 08646 ; tasks: 08647 ; 08648 ; (1) Increment counters COUNT256 ($76) and COUNT8 ($72). 08649 ; 08650 ; (2) If our starship's energy has dropped below 1000 units then flash a {PINK} 08651 ; alert that changes to {DARK GREY BLUE} and back to {PINK} every 128 game 08652 ; loop iterations. 08653 ; 08654 ; (3) Set the Shields color and the Control Panel background color every 8 game 08655 ; loop iterations: 08656 ; 08657 ; o If the Shields are up and OK then set the Shields color to {DARK 08658 ; GREEN} and the Control Panel background color to {DARK BLUE}. 08659 ; 08660 ; o If the Shields are up and damaged there is a probability of 78% 08661 ; (200:256) that the Shield color is not changed. 08662 ; 08663 ; o If the Shields are down, damaged, or destroyed then set the Shields 08664 ; color to {BLACK}. 08665 ; 08666 ; o If the Shields are destroyed then set the Control Panel background 08667 ; color to {ORANGE}. 08668 ; 08669 ; (4) Decrement the lifetime of our starship's and Zylon photon torpedoes. 08670 ; 08671 ; (5) Decrement the lifetime of an explosion. If the explosion lifetime is less 08672 ; than 112 game loop iterations, clear HITBADNESS ($8A) (thus the explosion 08673 ; cannot destroy our starship). If the explosion lifetime is less than 24 08674 ; (?) game loops decrement the number of explosion fragments. This makes 08675 ; explosion fragments disappear gradually toward the end of an explosion. 08676 ; 08677 ; (6) Increment every 40 game loop iterations the stardate clock of the 08678 ; Galactic Chart Panel Display. 08679 ; 08680 ; (7) Move Zylon units in the Galactic Chart. 08681 ; 08682 ; Every 50 game loop iterations (or 100 game loop iterations when a 08683 ; starbase is surrounded by Zylon units) decrement the score. 08684 ; 08685 ; Code execution continues if the game is not in demo mode with the following 08686 ; steps: 08687 ; 08688 ; (1) Search the Galactic Chart for starbases surrounded by Zylon units. 08689 ; Destroy any such starbase: Replace it with a 2-Zylon sector and subtract 08690 ; 18 points from the score. If the Subspace Radio was not destroyed, then 08691 ; flash the title phrase "STARBASE DESTROYED" and play the beeper sound 08692 ; pattern MESSAGE FROM STARBASE in subroutine BEEP ($B3A6). 08693 ; 08694 ; (2) Every 8 game loop iterations the Zylon units decide, which starbase to 08695 ; hunt: First, 128 randomly picked sectors are searched for a starbase. If 08696 ; no starbase was found in this way, the sectors of the Galactic Chart are 08697 ; scanned systematically left-to-right, top-to-bottom. If a starbase was 08698 ; found then its sector, sector column, and sector row are saved, otherwise 08699 ; code execution returns. 08700 ; 08701 ; (3) Now the Zylon units converge toward the sector of the hunted starbase: 08702 ; All sectors of the Galactic Chart are scanned. For any sector with a 08703 ; Zylon unit that was not moved yet (its sector does not have the temporary 08704 ; "already-moved" bit B5 set) its movement probability value is picked from 08705 ; table MOVEPROBTAB ($BFBB): 08706 ; 08707 ; +---------------+-------------+----------------+ 08708 ; | Sector Type | Movement | Movement | 08709 ; | | Probability | Probability | 08710 ; | | Value | | 08711 ; +---------------+-------------+----------------+ 08712 ; | Empty sector | 0 | 0% ( 0:256) | 08713 ; | 1 Zylon ship | 255 | 100% (255:256) | 08714 ; | 2 Zylon ships | 255 | 100% (255:256) | 08715 ; | 3 Zylon ships | 192 | 75% (192:256) | 08716 ; | 4 Zylon ships | 32 | 13% ( 32:256) | 08717 ; +---------------+-------------+----------------+ 08718 ; 08719 ; If this value is less or equal than a random number in 0..255 then the 08720 ; Zylon unit is moved to another sector. A Zylon unit that currently 08721 ; occupies the sector of our starship is not moved. 08722 ; 08723 ; BUG (at $B620): The instruction to check the marker bit B5 of the sector 08724 ; is CPY #$0A. This works, as sectors containing Zylon units that need to 08725 ; be moved have values of 2..4, see table SECTORTYPETAB ($BBA6). Suggested 08726 ; fix: Replace CPY #$0A with CPY #$20, which may make the code clearer. 08727 ; 08728 ; (4) For every Zylon unit that is about to be moved, 9 distances ("block 08729 ; distances") between the Zylon unit and the starbase are calculated by 08730 ; tentatively moving the Zylon unit into each of its 8 adjacent sectors - 08731 ; and by moving it not at all. The sector offsets are taken from table 08732 ; COMPASSOFFTAB ($BFC0) which stores direction offsets in the following 08733 ; order: NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST, EAST, 08734 ; NORTHEAST, CENTER. All 9 distances are stored in 9 consecutive bytes at 08735 ; NEWZYLONDIST ($96). 08736 ; 08737 ; NOTE: The last calculated distance is the current distance between Zylon 08738 ; unit and starbase. 08739 ; 08740 ; The Zylon unit moves to the first of the 8 adjacent sectors that matches 08741 ; the following conditions: 08742 ; 08743 ; (1) It is closer to the starbase than the Zylon unit's current sector. 08744 ; 08745 ; (2) It is located inside the Galactic Chart. 08746 ; 08747 ; (3) It is empty. 08748 ; 08749 ; (4) It is not the sector containing our starship. 08750 ; 08751 ; If a suitable new sector was found then the Zylon unit is moved to this 08752 ; sector, which is marked with the "already-moved" marker bit B5 in the 08753 ; Galactic Chart memory map. This marker bit prevents a Zylon unit that has 08754 ; been already moved from being moved again. The old Zylon unit sector is 08755 ; cleared. 08756 ; 08757 ; If no suitable new sector was found then the above distance calculations 08758 ; are repeated once again by adding 1 to the current distance between the 08759 ; Zylon unit and the starbase. This may provoke a Zylon unit to move that 08760 ; would not have moved in the previous set of distance calculations. 08761 ; 08762 ; After having moved all Zylon units the sectors are stripped of the 08763 ; "already-moved" marker bit B5. 08764 ; 08765 ; (5) If a starbase has been surrounded then the Zylon unit movement timer is 08766 ; reset to 99, buying our starship some time to destroy one of the 08767 ; surrounding Zylon units. If the Subspace Radio is not destroyed, then the 08768 ; message "STARBASE SURROUNDED" is flashed in the title line and the beeper 08769 ; sound pattern MESSAGE FROM STARBASE is played in subroutine BEEP ($B3A6). 08770 08771 L.ISDESTROYED = $6A ; Flags the destruction of a starbase. 08772 ; Used values are: 08773 ; $00 -> Starbase not destroyed 08774 ; $02 -> Starbase has been destroyed 08775 L.NEWSECTOR = $6A ; Sector to which the Zylon unit is tentatively moved 08776 L.ABSDIFFCOLUMN = $6B ; Absolute difference between new Zylon and starbase 08777 ; column on Galactic Chart in PM pixels 08778 L.LOOPCNT2 = $6B ; Loop counter. Used values are: 0..1. 08779 L.DIRECTIONIND = $6A ; Compass rose direction index. 08780 ; Used values are: 0..7. 08781 08782 ;*** Increment counters and flash low-energy alert ***************************** 08783 FLUSHGAMELOOP INC COUNT256 ; Increment COUNT256 counter 08784 08785 LDX #$90 ; Prep DLI background color {DARK GREY BLUE} 08786 LDA COUNT256 ; 08787 BPL SKIP198 ; Skip if counter < 128. 08788 08789 LDY ENERGYD1 ; When energy drops below 1000 units... 08790 CPY #CCS.COL2!CCS.0 ; 08791 BNE SKIP198 ; 08792 LDX #$44 ; ...prep new DLI background color {PINK} 08793 08794 SKIP198 AND #$03 ; Increment COUNT8 08795 STA COUNT8 ; 08796 BNE SKIP202 ; Skip setting colors but every 8 game loops 08797 08798 ;*** Set Shields and Control Panel background color **************************** 08799 LDY DRAINSHIELDS ; Skip if Shields are off 08800 BEQ SKIP201 ; 08801 08802 LDY #$A0 ; Prep Shields color {DARK GREEN} 08803 BIT GCSTATSHL ; Skip if Shields are OK 08804 BPL SKIP200 ; 08805 BVS SKIP199 ; Skip if Shields are destroyed 08806 LDA RANDOM ; If Shields are damaged, Shields colors are... 08807 CMP #200 ; ...unchanged with probability of 78% (200:256) 08808 BCC SKIP201 ; 08809 08810 SKIP199 LDY #$00 ; Prep Shields color {BLACK} 08811 SKIP200 TYA ; 08812 BNE SKIP201 ; 08813 08814 LDX #$26 ; Prep Control Panel background color {ORANGE} 08815 08816 SKIP201 STY SHIELDSCOLOR ; Store Shields color 08817 STX BGRCOLORDLI ; Store Control Panel background color 08818 08819 ;*** Decrement lifetime of our starship's and Zylon photon torpedoes *********** 08820 SKIP202 LDX #2 ; Loop over PLAYER2..4 08821 08822 LOOP068 LDA PL2SHAPTYPE,X ; Next PLAYER if not PHOTON TORPEDO (shape type 0) 08823 BNE SKIP203 ; 08824 08825 LDA PL2LIFE,X ; Next PLAYER if this PLAYER not alive 08826 BEQ SKIP203 ; 08827 08828 DEC PL2LIFE,X ; Decrement photon torpedo PLAYER lifetime 08829 08830 SKIP203 DEX ; 08831 BPL LOOP068 ; Next PLAYER 08832 08833 ;*** Decrement lifetime of explosion ******************************************* 08834 LDA EXPLLIFE ; Skip if explosion lifetime expired 08835 BEQ SKIP206 ; 08836 08837 DEC EXPLLIFE ; Decrement explosion lifetime 08838 BNE SKIP204 ; Skip if explosion lifetime still counting 08839 08840 LDX #NUMSPCOBJ.NORM ; Explosion finished,... 08841 STX MAXSPCOBJIND ; ...restore normal number of space objects 08842 08843 SKIP204 CMP #112 ; Skip if explosion lifetime >= 112 game loops 08844 BCS SKIP205 ; 08845 08846 LDX #0 ; HITBADNESS := NO HIT 08847 STX HITBADNESS ; 08848 08849 SKIP205 CMP #24 ; Skip if explosion lifetime >= 24 game loops (?) 08850 BCS SKIP206 ; 08851 08852 DEC MAXSPCOBJIND ; Decrement number of explosion fragment space objs 08853 08854 ;*** Increment stardate clock ************************************************** 08855 SKIP206 DEC CLOCKTIM ; Decrement stardate clock timer 08856 BPL SKIP209 ; Return if timer is still counting 08857 08858 LDA #40 ; Reset stardate clock timer to 40 game loops 08859 STA CLOCKTIM ; 08860 08861 LDX #4 ; Increment stardate clock of Galactic Chart Panel 08862 LOOP069 INC GCSTARDAT,X ; 08863 LDA GCSTARDAT,X ; 08864 CMP #[CCS.COL3!ROM.9]+1 ; 08865 BCC SKIP208 ; 08866 LDA #[CCS.COL3!ROM.0] ; 08867 STA GCSTARDAT,X ; 08868 CPX #3 ; 08869 BNE SKIP207 ; 08870 DEX ; 08871 SKIP207 DEX ; 08872 BPL LOOP069 ; 08873 08874 ;*** Decrement Zylon unit movement timer *************************************** 08875 SKIP208 DEC ZYLONUNITTIM ; Decrement Zylon unit movement timer 08876 BMI SKIP210 ; If timer < 0 move Zylon units 08877 08878 SKIP209 RTS ; Return 08879 08880 ;*** Restore Zylon unit movement timer and decrement score ********************* 08881 SKIP210 LDA #49 ; Reset Zylon unit movement timer to 49 08882 STA ZYLONUNITTIM ; 08883 08884 LDA SCORE ; SCORE := SCORE - 1 08885 BNE SKIP211 ; 08886 DEC SCORE+1 ; 08887 SKIP211 DEC SCORE ; 08888 08889 LDX ISDEMOMODE ; Return if in demo mode 08890 BNE SKIP209 ; 08891 08892 ;*** Is starbase surrounded? *************************************************** 08893 STX L.ISDESTROYED ; Init L.ISDESTROYED with 0 (starbase not destroyed) 08894 LOOP070 LDA GCMEMMAP,X ; Loop over all sectors, load sector type 08895 BPL SKIP212 ; Skip if not a starbase sector 08896 08897 JSR ISSURROUNDED ; Skip if starbase sector not completely surrounded 08898 BEQ SKIP212 ; 08899 08900 ;*** Starbase is surrounded, destroy starbase ********************************** 08901 LDA #2 ; Replace starbase sector with 2-Zylon sector 08902 STA GCMEMMAP,X ; 08903 STA L.ISDESTROYED ; Flag destruction of starbase 08904 08905 SEC ; SCORE := SCORE - 18 08906 LDA SCORE ; 08907 SBC #18 ; 08908 STA SCORE ; 08909 LDA SCORE+1 ; 08910 SBC #0 ; 08911 STA SCORE+1 ; 08912 08913 SKIP212 INX ; 08914 BPL LOOP070 ; Next sector 08915 08916 ;*** Report starbase destruction *********************************************** 08917 LDA L.ISDESTROYED ; Skip if no starbase has been destroyed 08918 BEQ SKIP213 ; 08919 08920 BIT GCSTATRAD ; Skip notification if Subspace Radio destroyed 08921 BVS SKIP213 ; 08922 08923 LDY #$15 ; Set title phrase "STARBASE DESTROYED" 08924 JSR SETTITLE ; 08925 08926 LDX #$18 ; Play beeper sound pattern MESSAGE FROM STARBASE 08927 JSR BEEP ; 08928 08929 ;*** Pick new starbase to be hunted by Zylon units ***************************** 08930 SKIP213 DEC HUNTTIM ; Decrement hunting timer 08931 BMI SKIP214 ; If timer < 0 decide which starbase to hunt 08932 08933 LDX HUNTSECTOR ; Skip if Zylon units already picked starbase to hunt 08934 LDA GCMEMMAP,X ; 08935 BMI SKIP215 ; 08936 08937 SKIP214 LDA #7 ; Reset hunting timer 08938 STA HUNTTIM ; 08939 08940 LDY #127 ; Loop over 127(+1) randomly picked sectors 08941 LOOP071 LDA RANDOM ; 08942 AND #$7F ; 08943 TAX ; 08944 LDA GCMEMMAP,X ; Skip if starbase sector found 08945 BMI SKIP215 ; 08946 DEY ; 08947 BPL LOOP071 ; Next sector 08948 08949 LDX #127 ; Loop over all sectors of the Galactic Chart 08950 LOOP072 LDA GCMEMMAP,X ; 08951 BMI SKIP215 ; Skip if starbase sector found 08952 DEX ; 08953 BPL LOOP072 ; Next sector 08954 08955 RTS ; Return (no starbase sector found) 08956 08957 ;*** Store coordinates of starbase to be hunted ******************************** 08958 SKIP215 STX HUNTSECTOR ; Store hunted starbase sector column and row 08959 TXA ; 08960 AND #$0F ; 08961 STA HUNTSECTCOLUMN ; 08962 TXA ; 08963 LSR A ; 08964 LSR A ; 08965 LSR A ; 08966 LSR A ; 08967 STA HUNTSECTROW ; 08968 08969 ;*** Move all Zylon units toward hunted starbase ******************************* 08970 LDX #$FF ; 08971 LOOP073 INX ; Loop over all sectors to move Zylon units 08972 BPL SKIP218 ; Jump into loop body below 08973 08974 ;*** Strip marker bits from moved Zylon units ********************************** 08975 LDX #0 ; 08976 LOOP074 LDA GCMEMMAP,X ; Loop over all sectors 08977 AND #$DF ; 08978 STA GCMEMMAP,X ; Strip marker bit B5 from moved Zylon units 08979 INX ; 08980 BPL LOOP074 ; Next sector 08981 08982 ;*** Handle surrounded starbase ************************************************ 08983 BIT GCSTATRAD ; Return if Subspace Radio is destroyed 08984 BVS SKIP217 ; 08985 08986 LDX #0 ; Loop over all sectors 08987 LOOP075 LDA GCMEMMAP,X ; 08988 BPL SKIP216 ; Skip if not a starbase sector 08989 JSR ISSURROUNDED ; Skip if starbase not surrounded 08990 BEQ SKIP216 ; 08991 08992 LDA #99 ; Yes, starbase surrounded... 08993 STA ZYLONUNITTIM ; ...set Zylon unit movement timer to 99 08994 08995 LDY #$13 ; Set title phrase "STARBASE SURROUNDED" 08996 JSR SETTITLE ; 08997 08998 LDX #$18 ; Play beeper sound pattern MESSAGE FROM STARBASE... 08999 JMP BEEP ; ...and return 09000 09001 SKIP216 INX ; 09002 BPL LOOP075 ; Next sector 09003 09004 SKIP217 RTS ; Return 09005 09006 ;*** Move single Zylon unit **************************************************** 09007 SKIP218 LDY GCMEMMAP,X ; X contains current sector 09008 CPY #$0A ; Next sector if it has marker bit B5 set (!) 09009 BCS LOOP073 ; 09010 09011 LDA RANDOM ; Get random number 09012 CMP MOVEPROBTAB,Y ; Get movement probability 09013 BCS LOOP073 ; Next sector if movement probability < random number 09014 09015 CPX CURRSECTOR ; Next sector if this is our starship's sector 09016 BEQ LOOP073 ; 09017 09018 ;*** Compute distance to starbase by moving Zylon unit into 9 directions ******* 09019 LDY #8 ; Loop over 8(+1) possible directions 09020 LOOP076 CLC ; 09021 TXA ; 09022 ADC COMPASSOFFTAB,Y ; Add direction offset to current sector 09023 STA L.NEWSECTOR ; Store new sector 09024 09025 AND #$0F ; Calc distance ("block distance") between... 09026 SEC ; ...starbase sector and tentative new Zylon sector 09027 SBC HUNTSECTCOLUMN ; 09028 BCS SKIP219 ; 09029 EOR #$FF ; 09030 ADC #1 ; 09031 SKIP219 STA L.ABSDIFFCOLUMN ; 09032 LDA L.NEWSECTOR ; 09033 LSR A ; 09034 LSR A ; 09035 LSR A ; 09036 LSR A ; 09037 SEC ; 09038 SBC HUNTSECTROW ; 09039 BCS SKIP220 ; 09040 EOR #$FF ; 09041 ADC #1 ; 09042 SKIP220 CLC ; 09043 ADC L.ABSDIFFCOLUMN ; 09044 09045 STA NEWZYLONDIST,Y ; Store distance in distance array 09046 DEY ; 09047 BPL LOOP076 ; Next direction 09048 09049 ;*** Pick the shortest distance to starbase ************************************ 09050 LDA #1 ; Loop over compass rose directions twice to... 09051 STA L.LOOPCNT2 ; ...provoke movement regardless of truncation errors 09052 09053 LOOP077 LDY #7 ; 09054 LOOP078 LDA NEWZYLONDIST,Y ; Loop over all 7(+1) compass rose directions 09055 CMP OLDZYLONDIST ; 09056 BCS SKIP222 ; Next direction if new distance > current distance 09057 09058 CLC ; Calc new Galactic Chart sector for Zylon unit 09059 TXA ; 09060 ADC COMPASSOFFTAB,Y ; 09061 BMI SKIP222 ; Next direction if new sector outside Galactic Chart 09062 09063 STY L.DIRECTIONIND ; Save compass rose direction index 09064 TAY ; 09065 LDA GCMEMMAP,Y ; 09066 BNE SKIP221 ; Next direction if new sector not empty 09067 09068 LDA GCMEMMAP,X ; Preload Zylon sector type to be moved 09069 CPY CURRSECTOR ; 09070 BEQ SKIP221 ; Next direction if sector is our starship's sector 09071 09072 ORA #$20 ; New sector for Zylon unit found! 09073 STA GCMEMMAP,Y ; Temporarily mark that sector with marker bit B5 09074 LDA #0 ; 09075 STA GCMEMMAP,X ; Clear old Zylon unit sector 09076 BEQ SKIP223 ; Next sector (unconditional branch) 09077 09078 SKIP221 LDY L.DIRECTIONIND ; Restore compass rose direction index 09079 SKIP222 DEY ; Next compass rose direction 09080 BPL LOOP078 ; 09081 09082 INC OLDZYLONDIST ; Increment center distance 09083 DEC L.LOOPCNT2 ; 09084 BPL LOOP077 ; Loop over all compass rose directions one more time 09085 09086 SKIP223 JMP LOOP073 ; Next sector 09087 09088 ; ******************************************************************************* 09089 ; * * 09090 ; * ROTATE * 09091 ; * * 09092 ; * Rotate position vector component (coordinate) by fixed angle * 09093 ; * * 09094 ; ******************************************************************************* 09095 09096 ; DESCRIPTION 09097 ; 09098 ; This subroutine rotates a position vector component (coordinate) of a space 09099 ; object by a fixed angle around the center of the 3D coordinate system, the 09100 ; location of our starship. This is used in the Front, Aft, and Long-Range Scan 09101 ; views to rotate space objects in and out of the view. Although the code is 09102 ; deceptively short, there is some interesting math involved, so a more detailed 09103 ; discussion is in order. 09104 ; 09105 ; ROTATION MATHEMATICS 09106 ; 09107 ; The game uses a left-handed 3D coordinate system with the positive x-axis 09108 ; pointing to the right, the positive y-axis pointing up, and the positive 09109 ; z-axis pointing into flight direction. 09110 ; 09111 ; A rotation in this coordinate system around the y-axis (horizontal rotation) 09112 ; can be expressed as 09113 ; 09114 ; x' := cos(ry) * x + sin(ry) * z (1a) 09115 ; z' := - sin(ry) * x + cos(ry) * z (1b) 09116 ; 09117 ; where ry is the clockwise rotation angle around the y-axis, x and z are the 09118 ; coordinates before this rotation, and the primed coordinates x' and z' the 09119 ; coordinates after this rotation. The y-coordinate is not changed by this 09120 ; rotation. 09121 ; 09122 ; A rotation in this coordinate system around the x-axis (vertical rotation) can 09123 ; be expressed as 09124 ; 09125 ; z' := cos(rx) * z + sin(rx) * y (2a) 09126 ; y' := - sin(rx) * z + cos(rx) * y (2b) 09127 ; 09128 ; where rx is the clockwise rotation angle around the x-axis, z and y are the 09129 ; coordinates before this rotation, and the primed coordinates z' and y' the 09130 ; coordinates after this rotation. The x-coordinate is not changed by this 09131 ; rotation. 09132 ; 09133 ; SUBROUTINE IMPLEMENTATION OVERVIEW 09134 ; 09135 ; A single call of this subroutine is able to compute one of the four 09136 ; expressions (1a)-(2b). To compute all four expressions to get the new set of 09137 ; coordinates, this subroutine has to be called four times. This is done twice 09138 ; in pairs in GAMELOOP ($A1F3) at $A391 and $A398, and at $A3AE and $A3B5, 09139 ; respectively. 09140 ; 09141 ; The first pair of calls calculates the new x and z coordinates of a space 09142 ; object due to a horizontal (left/right) rotation of our starship around the 09143 ; y-axis following expressions (1a) and (1b). 09144 ; 09145 ; The second pair of calls calculates the new y and z coordinates of the same 09146 ; space object due to a vertical (up/down) rotation of our starship around the 09147 ; x-axis following expressions (2a) and (2b). 09148 ; 09149 ; If you look at the code, you may be wondering how this calculation is actually 09150 ; executed, as there is neither a sin() nor a cos() function call. What you'll 09151 ; actually find implemented, however, are the following calculations: 09152 ; 09153 ; Joystick left Joystick right 09154 ; --------------------- --------------------- 09155 ; x := x + z / 64 (3a) x := x - z / 64 (4a) 09156 ; z := -x / 64 + z (3b) z := x / 64 + z (4b) 09157 ; 09158 ; Joystick down Joystick up 09159 ; --------------------- --------------------- 09160 ; y := y + z / 64 (5a) y := y - z / 64 (6a) 09161 ; z := -y / 64 + z (5b) z := y / 64 + z (6b) 09162 ; 09163 ; CORDIC ALGORITHM 09164 ; 09165 ; When you compare expressions (1a)-(2b) with (3a)-(6b), notice the similarity 09166 ; between the expressions if you substitute 09167 ; 09168 ; sin(ry) -> 1 / 64, 09169 ; cos(ry) -> 1, 09170 ; sin(rx) -> 1 / 64, and 09171 ; cos(rx) -> 1. 09172 ; 09173 ; From sin(ry) = 1 / 64 and sin(rx) = 1 / 64 you can derive that the rotation 09174 ; angles ry and rx by which the space object is rotated per game loop iteration 09175 ; have a constant value of 0.89 degrees, as arcsine(1 / 64) = 0.89 degrees. 09176 ; 09177 ; What about cos(ry) and cos(rx)? The substitution does not match our derived 09178 ; angle exactly, because cos(0.89 degrees) = 0.99988 and is not exactly 1. 09179 ; However, this value is so close to 1 that substituting cos(0.89 degrees) with 09180 ; 1 is a very good approximation, simplifying calculations significantly. 09181 ; 09182 ; Another significant simplification results from the division by 64, because 09183 ; the actual division operation can be replaced with a much faster bit shift 09184 ; operation. 09185 ; 09186 ; This calculation-friendly way of computing rotations is known as the "CORDIC 09187 ; (COordinate Rotation DIgital Computer)" algorithm. 09188 ; 09189 ; MINSKY ROTATION 09190 ; 09191 ; There is one more interesting mathematical subtlety: Did you notice that 09192 ; expressions (1a)-(2b) use a new (primed) pair of variables to store the 09193 ; resulting coordinates, whereas in the implemented expressions (3a)-(6b) the 09194 ; value of the first coordinate of a coordinate pair is overwritten with its new 09195 ; value and this value is used in the subsequent calculation of the second 09196 ; coordinate? For example, when the joystick is pushed left, the first call of 09197 ; this subroutine calculates the new value of x according to expression (3a), 09198 ; overwriting the old value of x. During the second call to calculate z 09199 ; according to expression (3b), the new value of x is used instead of the old 09200 ; one. Is this to save the memory needed to temporarily store the old value of 09201 ; x? Is this a bug? If so, why does the rotation calculation actually work? 09202 ; 09203 ; Have a look at the expression pair (3a) and (3b) (the other expression pairs 09204 ; (4a)-(6b) work in a similar fashion): 09205 ; 09206 ; x := x + z / 64 09207 ; z := -x / 64 + z 09208 ; 09209 ; With the substitution 1 / 64 -> e, we get 09210 ; 09211 ; x := x + e * z 09212 ; z := -e * x + z 09213 ; 09214 ; Note that x is calculated first and then used in the second expression. When 09215 ; using primed coordinates for the resulting coordinates after calculating the 09216 ; two expressions we get 09217 ; 09218 ; x' := x + e * z 09219 ; z' := -e * x' + z = -e * (x + e * z) + z = -e * x + (1 - e^2) * z 09220 ; 09221 ; or in matrix form 09222 ; 09223 ; |x'| := | 1 e | * |x| 09224 ; |z'| |-e (1 - e^2)| |z| 09225 ; 09226 ; Surprisingly, this turns out to be a rotation matrix, because its determinant 09227 ; is (1 * (1 - e^2) - (e * -e)) = 1. 09228 ; 09229 ; (Incidentally, the column vectors of this matrix do not form an orthogonal 09230 ; basis, as their scalar product is 1 * e + (-e * (1 - e^2)) = -e^2. 09231 ; Orthogonality holds for e = 0 only.) 09232 ; 09233 ; This kind of rotation calculation is described by Marvin Minsky in ["AIM 239 09234 ; HAKMEM", Item 149, p. 73, MIT AI Lab, February 1972] and is called "Minsky 09235 ; Rotation". 09236 ; 09237 ; SUBROUTINE IMPLEMENTATION DETAILS 09238 ; 09239 ; To better understand how the implementation of this subroutine works, have 09240 ; again a look at expressions (3a)-(6b). If you rearrange the expressions a 09241 ; little their structure is always of the form 09242 ; 09243 ; TERM1 := TERM1 SIGN TERM2 / 64 09244 ; 09245 ; or shorter 09246 ; 09247 ; TERM1 := TERM1 SIGN TERM3 09248 ; 09249 ; where 09250 ; 09251 ; TERM3 := TERM2 / 64 09252 ; SIGN := + or - 09253 ; 09254 ; and where TERM1 and TERM2 are position vector components (coordinates). In 09255 ; fact, this is all this subroutine actually does: It simply adds TERM2 divided 09256 ; by 64 to TERM1 or subtracts TERM2 divided by 64 from TERM1. 09257 ; 09258 ; When calling this subroutine the correct indices for the appropriate position 09259 ; vector components (coordinates) TERM1 and TERM2 are passed in the Y and X 09260 ; registers, respectively. 09261 ; 09262 ; What about SIGN between TERM1 and TERM3? Have again a look at expressions 09263 ; (3a)-(6b). To compute the two new coordinates after a rotation, the SIGN 09264 ; toggles from plus to minus and vice versa. The SIGN is initialized with 09265 ; JOYSTICKDELTA ($6D) before calling subroutine ROTATE ($B69B) and is toggled 09266 ; inside every call of this subroutine before the addition or subtraction of the 09267 ; terms takes place there. The initial value of SIGN should be positive (+) if 09268 ; the rotation is clockwise (the joystick is pushed right or up) and negative 09269 ; (-) if the rotation is counter-clockwise (the joystick is pushed left or 09270 ; down), respectively. Because SIGN is always toggled inside the subroutine 09271 ; before the addition or subtraction of the terms actually happens there, you 09272 ; have to pass the already toggled value with the first call. 09273 ; 09274 ; NOTE: Unclear still are three instructions starting at address $B6AD. They 09275 ; seem to set the two least significant bits of TERM3 in a random fashion. Could 09276 ; this be some quick hack to avoid messing with exact but potentially lengthy 09277 ; two-complement's arithmetic here? 09278 ; 09279 ; INPUT 09280 ; 09281 ; X = Position vector component index of TERM2. Used values are: 09282 ; $00..$30 -> z-component (z-coordinate) of position vector 0..48 09283 ; $31..$61 -> x-component (x-coordinate) of position vector 0..48 09284 ; $62..$92 -> y-component (y-coordinate) of position vector 0..48 09285 ; 09286 ; Y = Position vector component index of TERM1. Used values are: 09287 ; $00..$30 -> z-component (z-coordinate) of position vector 0..48 09288 ; $31..$61 -> x-component (x-coordinate) of position vector 0..48 09289 ; $62..$92 -> y-component (y-coordinate) of position vector 0..48 09290 ; 09291 ; JOYSTICKDELTA ($6D) = Initial value of SIGN. Used values are: 09292 ; $01 -> (= Positive) Rotate right or up 09293 ; $FF -> (= Negative) Rotate left or down 09294 09295 ; TERM3 is a 24-bit value, represented by 3 bytes as 09296 ; $(sign)(high byte)(low byte) 09297 L.TERM3LO = $6A ; TERM3 (high byte), where TERM3 := TERM2 / 64 09298 L.TERM3HI = $6B ; TERM3 (low byte), where TERM3 := TERM2 / 64 09299 L.TERM3SIGN = $6C ; TERM3 (sign), where TERM3 := TERM2 / 64 09300 09301 ROTATE LDA ZPOSSIGN,X ; 09302 EOR #$01 ; 09303 BEQ SKIP224 ; Skip if sign of TERM2 is positive 09304 LDA #$FF ; 09305 09306 SKIP224 STA L.TERM3HI ; If TERM2 pos. -> TERM3 := $0000xx (= TERM2 / 256) 09307 STA L.TERM3SIGN ; If TERM2 neg. -> TERM3 := $FFFFxx (= TERM2 / 256) 09308 LDA ZPOSHI,X ; where xx := TERM2 (high byte) 09309 STA L.TERM3LO ; 09310 09311 LDA RANDOM ; (?) Hack to avoid messing with two-complement's 09312 ORA #$BF ; (?) arithmetic? Provides two least significant 09313 EOR ZPOSLO,X ; (?) bits B1..0 in TERM3. 09314 09315 ASL A ; TERM3 := TERM3 * 4 (= TERM2 / 256 * 4 = TERM2 / 64) 09316 ROL L.TERM3LO ; 09317 ROL L.TERM3HI ; 09318 ASL A ; 09319 ROL L.TERM3LO ; 09320 ROL L.TERM3HI ; 09321 09322 LDA JOYSTICKDELTA ; Toggle SIGN for next call of ROTATE 09323 EOR #$FF ; 09324 STA JOYSTICKDELTA ; 09325 BMI SKIP225 ; If SIGN negative then subtract, else add TERM3 09326 09327 ;*** Addition ****************************************************************** 09328 CLC ; TERM1 := TERM1 + TERM3 09329 LDA ZPOSLO,Y ; (24-bit addition) 09330 ADC L.TERM3LO ; 09331 STA ZPOSLO,Y ; 09332 09333 LDA ZPOSHI,Y ; 09334 ADC L.TERM3HI ; 09335 STA ZPOSHI,Y ; 09336 09337 LDA ZPOSSIGN,Y ; 09338 ADC L.TERM3SIGN ; 09339 STA ZPOSSIGN,Y ; 09340 RTS ; 09341 09342 ;*** Subtraction *************************************************************** 09343 SKIP225 SEC ; TERM1 := TERM1 - TERM3 09344 LDA ZPOSLO,Y ; (24-bit subtraction) 09345 SBC L.TERM3LO ; 09346 STA ZPOSLO,Y ; 09347 09348 LDA ZPOSHI,Y ; 09349 SBC L.TERM3HI ; 09350 STA ZPOSHI,Y ; 09351 09352 LDA ZPOSSIGN,Y ; 09353 SBC L.TERM3SIGN ; 09354 STA ZPOSSIGN,Y ; 09355 RTS ; 09356 09357 ;******************************************************************************* 09358 ;* * 09359 ;* SCREENCOLUMN * 09360 ;* * 09361 ;* Calculate pixel column number from centered pixel column number * 09362 ;* * 09363 ;******************************************************************************* 09364 09365 ; DESCRIPTION 09366 ; 09367 ; Converts a pixel column number relative to the horizontal screen center to a 09368 ; pixel column number relative to the top-left corner of the screen and stores 09369 ; the result in table PIXELCOLUMN ($0C2A). The passed relative pixel column 09370 ; number is always positive. The sign is picked from the corresponding 09371 ; x-component of the position vector (x-coordinate). 09372 ; 09373 ; If the passed relative pixel column number is offscreen horizontally the 09374 ; calculation is skipped and code execution returns. If the position vector 09375 ; corresponding to this pixel represents a PLAYFIELD space object (star, 09376 ; explosion fragments) a new position vector is initialized before code 09377 ; execution returns. If it represents a PLAYER space object the PLAYER is pushed 09378 ; offscreen before code execution returns. 09379 ; 09380 ; NOTE: The horizontal screen center's pixel column number for PLAYFIELD space 09381 ; objects has a value of 80 = 160 PLAYFIELD pixels / 2. For PLAYER space objects 09382 ; it has a value of 125 Player/Missile (PM) pixels (from left to right: 128 PM 09383 ; pixels to the horizontal screen center - 3 PM pixels relative offset of the 09384 ; PLAYER shape's horizontal center to its left edge = 125 PM pixels). 09385 ; 09386 ; INPUT 09387 ; 09388 ; A = Pixel column number relative to the horizontal screen center, always 09389 ; positive. Used values are: 09390 ; 0..80 -> Regular values, pixel is onscreen 09391 ; $FF -> Pixel is offscreen 09392 ; 09393 ; X = Position vector index. Used values are: 09394 ; 0..4 -> Position vector of a PLAYER space object 09395 ; 5..48 -> Position vector of a PLAYFIELD space object 09396 09397 L.PIXELCOLUMN = $6D ; Saves relative pixel column number 09398 09399 SCREENCOLUMN CMP #80 ; If pixel is offscreen (A > 79)... 09400 BCS SKIP233 ; ...return via initializing a new position vector 09401 09402 STA L.PIXELCOLUMN ; Save relative pixel column number 09403 LDA #80 ; If PLAYFIELD space object -> A := CENTERCOL = 80 09404 CPX #NUMSPCOBJ.PL ; If PLAYER space object -> A := CENTERCOL = 125 09405 BCS SKIP226 ; 09406 LDA #125 ; 09407 09408 SKIP226 LDY XPOSSIGN,X ; Skip if x-coordinate positive 09409 BNE SKIP227 ; 09410 09411 SEC ; Pixel in left screen half (x-coordinate negative) 09412 INC L.PIXELCOLUMN ; 09413 SBC L.PIXELCOLUMN ; 09414 STA PIXELCOLUMN,X ; Pixel column := CENTERCOL - (rel. pixel column + 1) 09415 RTS ; Return 09416 09417 SKIP227 CLC ; Pixel in right screen half (x-coordinate positive) 09418 ADC L.PIXELCOLUMN ; 09419 STA PIXELCOLUMN,X ; Pixel column := CENTERCOL + relative pixel column 09420 RTS ; Return 09421 09422 ;******************************************************************************* 09423 ;* * 09424 ;* SCREENROW * 09425 ;* * 09426 ;* Calculate pixel row number from centered pixel row number * 09427 ;* * 09428 ;******************************************************************************* 09429 09430 ; Converts a pixel row number relative to the vertical screen center to a pixel 09431 ; row number relative to the top-left corner of the screen and stores the result 09432 ; in table PIXELROWNEW ($0BF9). The passed relative pixel row number is always 09433 ; positive. The sign is picked from the corresponding y-component of the 09434 ; position vector (y-coordinate). 09435 ; 09436 ; If the passed relative pixel row number is offscreen vertically the 09437 ; calculation is skipped and code execution returns. If the position vector 09438 ; corresponding to this pixel represents a PLAYFIELD space object (star, 09439 ; explosion fragments) a new position vector is initialized in subroutine 09440 ; INITPOSVEC ($B764) before code execution returns. If it represents a PLAYER 09441 ; space object the PLAYER is pushed offscreen before code execution returns. 09442 ; 09443 ; NOTE: The vertical screen center's pixel row number for PLAYFIELD space 09444 ; objects has a value of 50 = 100 PLAYFIELD pixels / 2. For PLAYER space objects 09445 ; it has a value of 122 Player/Missile (PM) pixels (from top to bottom: 8 PM 09446 ; pixels to start of Display List + 16 PM pixels to begin of PLAYFIELD + 100 PM 09447 ; pixels to vertical screen center - 2 PM pixels (?) = 122 PM pixels). 09448 ; 09449 ; NOTE: If the position vector corresponding to the pixel represents a PLAYER 09450 ; space object the passed pixel row number is doubled because 1 PLAYFIELD pixel 09451 ; has the same height as 2 PM pixels at single-line resolution. 09452 ; 09453 ; When in Long-Range Scan view the z-coordinate takes the place of the 09454 ; y-coordinate of the Front or Aft view. If the Long-Range Scan is damaged the 09455 ; passed pixel row number is treated randomly as a negative or positive value 09456 ; (mirror effect). 09457 ; 09458 ; INPUT 09459 ; 09460 ; A = Pixel row number relative to the vertical screen center, always 09461 ; positive. Used values are: 09462 ; 0..50 -> Regular values, pixel is onscreen 09463 ; $FF -> Pixel is offscreen 09464 ; 09465 ; X = Position vector index. Used values are: 09466 ; 0..4 -> Position vector of a PLAYER space object 09467 ; 5..48 -> Position vector of a PLAYFIELD space object 09468 09469 L.PIXELROW = $6D ; Saves relative pixel row number 09470 09471 SCREENROW CMP #50 ; If pixel is offscreen (A > 49)... 09472 BCS SKIP233 ; ...return via initializing a new position vector 09473 09474 STA L.PIXELROW ; Save relative pixel row number 09475 LDA #50 ; If PLAYFIELD space object -> A := CENTERROW = 50 09476 CPX #NUMSPCOBJ.PL ; 09477 BCS SKIP228 ; 09478 ASL L.PIXELROW ; If PLAYER space object -> Double pixel row number 09479 LDA #122 ; If PLAYER space object -> A := CENTERROW = 122 09480 09481 SKIP228 BIT SHIPVIEW ; Skip if not in Long-Range Scan view 09482 BVC SKIP230 ; 09483 09484 BIT GCSTATLRS ; Skip if Long-Range Scan OK 09485 BPL SKIP229 ; 09486 09487 BIT RANDOM ; Long-Range Scan damaged... 09488 BVC SKIP231 ; ...branch randomly to pixel row number calculation 09489 BVS SKIP232 ; ...(mirror effect) 09490 09491 SKIP229 LDY ZPOSSIGN,X ; 09492 BNE SKIP231 ; Skip if z-coordinate pos. (Long-Range Scan view) 09493 BEQ SKIP232 ; Skip if z-coordinate neg. (Long-Range Scan view) 09494 09495 SKIP230 LDY YPOSSIGN,X ; 09496 BEQ SKIP232 ; Skip if y-coordinate neg. (Front or Aft view) 09497 09498 SKIP231 SEC ; Pixel in upper screen half (z or y coordinate pos.) 09499 INC L.PIXELROW ; 09500 SBC L.PIXELROW ; 09501 STA PIXELROWNEW,X ; Pixel row := CENTERROW - (rel. pixel row + 1) 09502 RTS ; Return 09503 09504 SKIP232 CLC ; Pixel in lower screen half (y or z coordinate neg.) 09505 ADC L.PIXELROW ; 09506 STA PIXELROWNEW,X ; Pixel row := CENTERROW + relative pixel row 09507 RTS ; Return 09508 09509 SKIP233 CPX #NUMSPCOBJ.PL ; Space object is offscreen. If it is a... 09510 BCS INITPOSVEC ; ...PLAYFIELD space object -> New position vector 09511 LDA #251 ; ...PLAYER space object -> Push PLAYER offscreen 09512 STA PIXELROWNEW,X ; Why a value of 251 (?) 09513 SKIP234 RTS ; Return 09514 09515 ;******************************************************************************* 09516 ;* * 09517 ;* INITPOSVEC * 09518 ;* * 09519 ;* Initialize position vector of a space object * 09520 ;* * 09521 ;******************************************************************************* 09522 09523 ; DESCRIPTION 09524 ; 09525 ; Initializes the position vector of a space object. 09526 ; 09527 ; This subroutine executes the following steps: 09528 ; 09529 ; (1) Set the pixel row and column number to an offscreen value (= 99). 09530 ; 09531 ; (2) If the position vector represents an explosion fragment space object then 09532 ; return code execution immediately. This avoids generating new explosion 09533 ; fragment space objects. They are separately initialized in subroutine 09534 ; COPYPOSVEC ($ACAF), which is called from subroutine INITEXPL ($AC6B). 09535 ; 09536 ; (3) Assign default values (see below) to the position vector components 09537 ; (coordinates) depending on our starship's view. 09538 ; 09539 ; Code execution continues into subroutine RNDINVXY ($B7BE) where x and y 09540 ; coordinates are inverted randomly. 09541 ; 09542 ; After passing through this and the next subroutine RNDINVXY ($B7BE) the 09543 ; components of a position vector (coordinates) are assigned to one of the 09544 ; following values depending on our starship's view: 09545 ; 09546 ; o FRONT VIEW 09547 ; 09548 ; +------------+---------------------------------------+ 09549 ; | Coordinate | Values | 09550 ; +------------+---------------------------------------+ 09551 ; | x | -4095..+4095 (-($0***)..+$0***) | 09552 ; | y | -4095..+4095 (-($0***)..+$0***) | 09553 ; | z | +3840..+4095 ( +$0F**) | 09554 ; +------------+---------------------------------------+ 09555 ; 09556 ; o AFT VIEW 09557 ; 09558 ; +------------+---------------------------------------+ 09559 ; | Coordinate | Values | 09560 ; +------------+---------------------------------------+ 09561 ; | x | -3840..+3840 (-($0*00)..+$0*00) | 09562 ; | y | -3840..+3840 (-($0*00)..+$0*00) | 09563 ; | z | -3968.. -128 (-($0*80) ) | 09564 ; +------------+---------------------------------------+ 09565 ; Values of x, y, and z coordinates change in increments of 256. 09566 ; Second digit of z-coordinate is -MAX(RNDY,RNDX), where 09567 ; RNDY := RND($00..$0F), RNDX := RND($00..$0F). 09568 ; 09569 ; o LONG-RANGE SCAN VIEW 09570 ; 09571 ; +------------+---------------------------------------+ 09572 ; | Coordinate | Values | 09573 ; +------------+---------------------------------------+ 09574 ; | x | -65535..+65535 (-($****)..$****) | 09575 ; | y | -4095..+4095 (-($0***)..$0***) | 09576 ; | z | -65535..+65535 (-($****)..$****) | 09577 ; +------------+---------------------------------------+ 09578 ; 09579 ; INPUT 09580 ; 09581 ; X = Position vector index. Used values are: 0..48. 09582 09583 L.MAXRNDXY = $6A ; Saves MAX(new y-coordinate (high byte), ... 09584 ; ...new x-coordinate (high byte)) 09585 09586 INITPOSVEC LDA #99 ; Init to offscreen pixel row and column numbers 09587 STA PIXELROWNEW,X ; 09588 STA PIXELCOLUMN,X ; 09589 09590 CPX #NUMSPCOBJ.NORM ; Return if pos vector is explosion frag space obj 09591 BCS SKIP234 ; This avoids creating new explosion frag space objs 09592 09593 LDA RANDOM ; RNDY := RND($00..$0F) 09594 AND #$0F ; 09595 STA L.MAXRNDXY ; Save RNDY 09596 STA YPOSHI,X ; y-coordinate (high byte) := RNDY 09597 09598 LDA RANDOM ; RNDX := RND($00..$0F) 09599 AND #$0F ; 09600 CMP L.MAXRNDXY ; 09601 BCC SKIP235 ; 09602 STA L.MAXRNDXY ; Save MAX(RNDY,RNDX) 09603 SKIP235 STA XPOSHI,X ; x-coordinate (high byte) := RNDX 09604 09605 LDA #$0F ; z-coordinate (high byte) := $0F 09606 STA ZPOSHI,X ; 09607 09608 LDA SHIPVIEW ; z-coordinate (sign) := 1 or 0 (Front or Aft view) 09609 EOR #$01 ; 09610 AND #$01 ; 09611 STA ZPOSSIGN,X ; 09612 BNE SKIP236 ; Skip if in Front or Long-Range Scan view 09613 09614 ; Aft view only: 09615 STA XPOSLO,X ; x-coordinate (low byte) := 0 09616 STA YPOSLO,X ; y-coordinate (low byte) := 0 09617 SEC ; z-coordinate (high byte) := -MAX(RNDY,RNDX) 09618 SBC L.MAXRNDXY ; 09619 STA ZPOSHI,X ; 09620 LDA #$80 ; z-coordinate (low byte) := $80 09621 STA ZPOSLO,X ; 09622 09623 SKIP236 BIT SHIPVIEW ; If not in Long-Range Scan view skip to RNDINVXY 09624 BVC RNDINVXY ; 09625 09626 ; Long-Range Scan view only: 09627 LDA RANDOM ; x-coordinate (high byte) := RND($00..$FF) 09628 STA XPOSHI,X ; 09629 LDA RANDOM ; z-coordinate (high byte) := RND($00..$FF) 09630 STA ZPOSHI,X ; 09631 AND #$01 ; Invert z-coordinate randomly 09632 STA ZPOSSIGN,X ; 09633 09634 ;******************************************************************************* 09635 ;* * 09636 ;* RNDINVXY * 09637 ;* * 09638 ;* Randomly invert the x and y components of a position vector * 09639 ;* * 09640 ;******************************************************************************* 09641 09642 ; DESCRIPTION 09643 ; 09644 ; Randomly inverts the x and y components of a position vector (x and y 09645 ; coordinates). See also subroutine INITPOSVEC ($B764). 09646 ; 09647 ; INPUT 09648 ; 09649 ; X = Position vector index. Used values are: 0..48. 09650 09651 RNDINVXY LDA RANDOM ; Set sign of y-coordinate randomly 09652 AND #$01 ; 09653 STA YPOSSIGN,X ; 09654 BNE SKIP237 ; Skip if sign positive 09655 09656 SEC ; Sign negative -> Calc negative y-coordinate 09657 SBC YPOSLO,X ; (calculate two's-complement of 16-bit value) 09658 STA YPOSLO,X ; 09659 LDA #0 ; 09660 SBC YPOSHI,X ; 09661 STA YPOSHI,X ; 09662 09663 SKIP237 LDA RANDOM ; Set sign of x-coordinate randomly 09664 AND #$01 ; 09665 STA XPOSSIGN,X ; 09666 BNE SKIP238 ; Skip if sign positive 09667 09668 SEC ; Sign negative -> Calc negative x-coordinate 09669 SBC XPOSLO,X ; (calculate two's-complement of 16-bit value) 09670 STA XPOSLO,X ; 09671 LDA #0 ; 09672 SBC XPOSHI,X ; 09673 STA XPOSHI,X ; 09674 SKIP238 RTS ; Return 09675 09676 ;******************************************************************************* 09677 ;* * 09678 ;* ISSURROUNDED * 09679 ;* * 09680 ;* Check if a sector is surrounded by Zylon units * 09681 ;* * 09682 ;******************************************************************************* 09683 09684 ; DESCRIPTION 09685 ; 09686 ; Checks if a sector of the Galactic Chart is surrounded by Zylon units in the 09687 ; adjacent NORTH, EAST, SOUTH, and WEST sectors. 09688 ; 09689 ; INPUT 09690 ; 09691 ; X = Sector of Galactic Chart. Used values are: $00..$7F with, for example, 09692 ; $00 -> NORTHWEST corner sector 09693 ; $0F -> NORTHEAST corner sector 09694 ; $70 -> SOUTHWEST corner sector 09695 ; $7F -> SOUTHWEST corner sector 09696 ; 09697 ; OUTPUT 09698 ; 09699 ; A = Returns if the sector is surrounded by Zylon units in the adjacent 09700 ; NORTH, EAST, SOUTH, and WEST sectors. 09701 ; 0 -> Sector is not surrounded 09702 ; > 0 -> Sector is surrounded 09703 09704 ISSURROUNDED LDA GCMEMMAP-1,X ; Check WEST sector 09705 BEQ SKIP239 ; 09706 LDA GCMEMMAP+1,X ; Check EAST sector 09707 BEQ SKIP239 ; 09708 LDA GCMEMMAP-16,X ; Check NORTH sector 09709 BEQ SKIP239 ; 09710 LDA GCMEMMAP+16,X ; Check SOUTH sector 09711 SKIP239 RTS ; Return 09712 09713 ;******************************************************************************* 09714 ;* * 09715 ;* UPDPANEL * 09716 ;* * 09717 ;* Update Control Panel Display * 09718 ;* * 09719 ;******************************************************************************* 09720 09721 ; DESCRIPTION 09722 ; 09723 ; This subroutine executes the following steps: 09724 ; 09725 ; (1) Accelerate or decelerate our starship, update the VELOCITY readout 09726 ; 09727 ; If the new velocity value is different from the current one either 09728 ; increment or decrement the current velocity value toward the new one. 09729 ; 09730 ; If the Engines are damaged or destroyed (and hyperwarp is not engaged) 09731 ; then store a random value (less or equal than the current velocity) as 09732 ; the current velocity. 09733 ; 09734 ; Display the updated velocity by the VELOCITY readout of the Control Panel 09735 ; Display. 09736 ; 09737 ; (2) Update THETA, PHI, and RANGE readouts. 09738 ; 09739 ; If the Attack Computer is working then display the x, y, and z 09740 ; coordinates of the currently tracked space object as THETA, PHI, and 09741 ; RANGE readout values of the Control Panel Display. 09742 ; 09743 ; (3) Calculate overall energy consumption. 09744 ; 09745 ; Add the overall energy consumption per game loop iteration to the energy 09746 ; counter. This value is given in energy subunits (256 energy subunits = 1 09747 ; energy unit displayed by the 4-digit ENERGY readout of the Console Panel 09748 ; Display). It is the total of the following items: 09749 ; 09750 ; (1) 8 energy subunits if the Shields are up 09751 ; 09752 ; (2) 2 energy subunits if the Attack Computer is on 09753 ; 09754 ; (3) 1 energy subunit of the life support system 09755 ; 09756 ; (4) Our starship's Engines energy drain rate (depending on its velocity) 09757 ; 09758 ; If there is a carryover of the energy counter then decrement the ENERGY 09759 ; readout of the Control Panel Display by one energy unit after code 09760 ; execution has continued into subroutine DECENERGY ($B86F). 09761 09762 ;*** Accelerate or decelerate our starship ************************************* 09763 UPDPANEL LDX VELOCITYLO ; Skip if new velocity = current velocity 09764 CPX NEWVELOCITY ; 09765 BEQ SKIP241 ; 09766 09767 BCC SKIP240 ; In/decrement current velocity toward new velocity 09768 DEC VELOCITYLO ; 09769 BCS SKIP242 ; 09770 SKIP240 INC VELOCITYLO ; 09771 09772 SKIP241 LDA WARPSTATE ; Skip if hyperwarp engaged 09773 BNE SKIP242 ; 09774 09775 BIT GCSTATENG ; Skip if Engines are OK 09776 BPL SKIP242 ; 09777 09778 LDA NEWVELOCITY ; Store RND(0..current velocity) to current velocity 09779 AND RANDOM ; 09780 STA VELOCITYLO ; 09781 09782 SKIP242 LDY #VELOCD1-PANELTXT-1 ; Update digits of VELOCITY readout 09783 JSR SHOWDIGITS ; 09784 09785 ;*** Display coordinates of tracked space object of Control Panel Display ****** 09786 BIT GCSTATCOM ; Skip if Attack Computer damaged or destroyed 09787 BMI SKIP243 ; 09788 09789 LDA #$31 ; Update THETA readout (x-coordinate) 09790 LDY #THETAC1-PANELTXT ; 09791 JSR SHOWCOORD ; 09792 09793 LDA #$62 ; Update PHI readout (y-coordinate) 09794 LDY #PHIC1-PANELTXT ; 09795 JSR SHOWCOORD ; 09796 09797 LDA #$00 ; Update RANGE readout (z-coordinate) 09798 LDY #RANGEC1-PANELTXT ; 09799 JSR SHOWCOORD ; 09800 09801 LDA RANGEC1+2 ; Hack to clear RANGE digit 3 when in hyperwarp: 09802 STA RANGEC1+3 ; Copy RANGE digit 2 to digit 3 09803 CMP #CCS.9+1 ; Skip if digit character > '9' (= 'infinity' char) 09804 BCS SKIP243 ; 09805 09806 LDX TRACKDIGIT ; Get z-coordinate (low byte) of tracked space object 09807 LDA ZPOSLO,X ; 09808 LSR A ; ...divide it by 16... 09809 LSR A ; 09810 LSR A ; 09811 LSR A ; 09812 TAX ; 09813 LDA MAPTOBCD99,X ; ...map value of $00..$0F to BCD value 0..9 09814 STA RANGEC1+3 ; ...and store it to RANGE digit 3 09815 09816 ;*** Calculate overall energy consumption ************************************** 09817 SKIP243 CLC ; 09818 LDA ENERGYCNT ; Load energy counter 09819 ADC DRAINSHIELDS ; Add energy drain rate of Shields 09820 ADC DRAINENGINES ; Add energy drain rate of our starship's Engines 09821 ADC DRAINATTCOMP ; Add energy drain rate of Attack Computer 09822 ADC #$01 ; Add 1 energy subunit of life support system 09823 CMP ENERGYCNT ; 09824 STA ENERGYCNT ; 09825 BCS SKIP246 ; Return if no energy counter carryover 09826 09827 LDX #3 ; Will decrement third energy digit 09828 09829 ;******************************************************************************* 09830 ;* * 09831 ;* DECENERGY * 09832 ;* * 09833 ;* Decrease energy * 09834 ;* * 09835 ;******************************************************************************* 09836 09837 ; DESCRIPTION 09838 ; 09839 ; When not in demo mode, subtract energy from the 4-digit ENERGY readout of the 09840 ; Control Panel Display. If crossing a 100-energy-unit boundary during 09841 ; subtraction the score is decremented by one unit. If the energy is zero the 09842 ; game is over. 09843 ; 09844 ; INPUT 09845 ; 09846 ; X = ENERGY readout digit to be decremented. Used values are: 09847 ; 1 -> Subtract 100 units from ENERGY readout 09848 ; 2 -> Subtract 10 units from ENERGY readout 09849 ; 3 -> Subtract 1 unit from ENERGY readout 09850 09851 ;*** Display ENERGY readout **************************************************** 09852 DECENERGY BIT ISDEMOMODE ; Return if in demo mode 09853 BVS SKIP246 ; 09854 09855 DEC ENERGYD1,X ; Decrement energy digit character 09856 LDA ENERGYD1,X ; 09857 CMP #CCS.COL2!CCS.0 ; 09858 BCS SKIP246 ; Return if digit character >= '0' 09859 LDA #CCS.COL2!CCS.9 ; 09860 STA ENERGYD1,X ; Store digit character '9' 09861 09862 ;*** Decrement score when crossing a 100-energy-unit boundary while subtracting 09863 CPX #2 ; Skip if no crossing of 100-energy-unit boundary 09864 BNE SKIP245 ; 09865 09866 LDA SCORE ; SCORE := SCORE - 1 09867 BNE SKIP244 ; 09868 DEC SCORE+1 ; 09869 SKIP244 DEC SCORE ; 09870 09871 SKIP245 DEX ; 09872 BPL DECENERGY ; Next digit 09873 09874 ;*** Energy is zero, game over ************************************************* 09875 LDX #CCS.SPC ; Clear 4-digit ENERGY readout 09876 TXA ; 09877 LDY #3 ; 09878 LOOP079 STA ENERGYD1,Y ; 09879 DEY ; 09880 BPL LOOP079 ; 09881 09882 JSR SETVIEW ; Set Front view 09883 09884 LDY #$31 ; Set title phrase "MISSION ABORTED ZERO ENERGY" 09885 LDX #$04 ; Set mission bonus offset 09886 JSR GAMEOVER ; Game over 09887 09888 SKIP246 RTS ; Return 09889 09890 ;******************************************************************************* 09891 ;* * 09892 ;* SHOWCOORD * 09893 ;* * 09894 ;* Display a position vector component (coordinate) in Control Panel Display * 09895 ;* * 09896 ;******************************************************************************* 09897 09898 ; DESCRIPTION 09899 ; 09900 ; Displays a position vector component (coordinate) by one of the THETA, PHI, or 09901 ; RANGE readouts of the Control Panel Display. 09902 ; 09903 ; Write the sign to the Control Panel Display, then map the high byte of the 09904 ; respective coordinate (x -> THETA, y -> PHI, z -> RANGE) to a BCD-value in 09905 ; 00..99. Code execution continues into subroutine SHOWDIGITS ($B8CD) where the 09906 ; digits are actually stored in the Control Panel Display. 09907 ; 09908 ; NOTE: If the digits of either the THETA or PHI readout are to be displayed and 09909 ; the x or y position vector component (high byte) is $FF then tweak the value 09910 ; to $FE. This avoids accessing table MAPTOBCD99 ($0EE9) with an index of $FF 09911 ; that would return the special value $EA. This value represents the CCS.INF 09912 ; ($0E) and CCS.SPC ($0A) characters (see comments in subroutine INITIALIZE 09913 ; ($B3BA)) that are displayed by the RANGE readout only. 09914 ; 09915 ; INPUT 09916 ; 09917 ; A = Position vector component (coordinate) offset. Used values are: 09918 ; $00 -> z-coordinate 09919 ; $31 -> x-coordinate 09920 ; $62 -> y-coordinate 09921 ; 09922 ; Y = Offset into the Control Panel Display memory map. Used values are: 09923 ; $17 -> First character (sign) of THETA readout (x-coordinate of tracked 09924 ; space object) 09925 ; $1D -> First character (sign) of PHI readout (y-coordinate of tracked 09926 ; space object) 09927 ; $23 -> First character (sign) of RANGE readout (z-coordinate of tracked 09928 ; space object) 09929 09930 L.SIGNCHAR = $6A ; Saves sign character 09931 09932 SHOWCOORD CLC ; Add index of tracked space object... 09933 ADC TRACKDIGIT ; ...to position vector component offset 09934 TAX ; Save position vector component index 09935 09936 ;*** Display sign in Control Panel Display ************************************* 09937 LDA #CCS.PLUS ; Save '+' (CCS.PLUS) to sign character 09938 STA L.SIGNCHAR ; 09939 09940 LDA ZPOSSIGN,X ; Prep sign of coordinate 09941 LSR A ; 09942 LDA ZPOSHI,X ; Prep coordinate (high byte) 09943 BCS SKIP247 ; Skip if sign is positive 09944 09945 EOR #$FF ; Invert coordinate (high byte) 09946 DEC L.SIGNCHAR ; Change saved sign character to '-' (CCS.MINUS) 09947 09948 SKIP247 TAX ; Save coordinate (high byte) 09949 LDA L.SIGNCHAR ; Store sign character in Control Panel Display 09950 STA PANELTXT,Y ; 09951 09952 ;*** Get RANGE digits ********************************************************** 09953 TYA ; Skip if RANGE is to be displayed 09954 AND #$10 ; 09955 BEQ SHOWDIGITS ; 09956 09957 CPX #$FF ; If coordinate (high byte) = $FF decrement value 09958 BNE SHOWDIGITS ; This avoids output of CCS.INFINITY in... 09959 DEX ; ...THETA and PHI readouts 09960 09961 ;******************************************************************************* 09962 ;* * 09963 ;* SHOWDIGITS * 09964 ;* * 09965 ;* Display a value by a readout of the Control Panel Display * 09966 ;* * 09967 ;******************************************************************************* 09968 09969 ; DESCRIPTION 09970 ; 09971 ; Converts a binary value in $00..$FF to a BCD-value in 0..99 and displays it as 09972 ; a 2-digit number in the Control Panel Display. 09973 ; 09974 ; INPUT 09975 ; 09976 ; X = Value to be displayed as a 2-digit BCD-value. Used values are: $00..$FF. 09977 ; 09978 ; Y = Offset into the Control Panel Display memory map relative to the first 09979 ; character of the Control Panel Display (the 'V' of the VELOCITY 09980 ; readout). Used values are: 09981 ; $01 -> Character before first digit of VELOCITY readout 09982 ; $17 -> First character (sign) of THETA readout (x-coordinate of tracked 09983 ; space object) 09984 ; $1D -> First character (sign) of PHI readout (y-coordinate of tracked 09985 ; space object) 09986 ; $23 -> First character (sign) of RANGE readout (z-coordinate of tracked 09987 ; space object) 09988 09989 SHOWDIGITS LDA MAPTOBCD99,X ; Map binary value to BCD-value 09990 TAX ; 09991 AND #$0F ; 09992 STA PANELTXT+2,Y ; Store 'ones' digit in Control Panel Display 09993 TXA ; 09994 LSR A ; 09995 LSR A ; 09996 LSR A ; 09997 LSR A ; 09998 STA PANELTXT+1,Y ; Store 'tens' digit in Control Panel Display 09999 RTS ; Return 10000 10001 ;******************************************************************************* 10002 ;* * 10003 ;* G A M E D A T A ( P A R T 2 O F 2 ) * 10004 ;* * 10005 ;******************************************************************************* 10006 10007 ;*** Color register offsets of PLAYER0..4 ************************************** 10008 PLCOLOROFFTAB .BYTE 0 ; PLAYER0 10009 .BYTE 1 ; PLAYER1 10010 .BYTE 2 ; PLAYER2 10011 .BYTE 3 ; PLAYER3 10012 .BYTE 7 ; PLAYER4 10013 10014 ;*** Shape table 1 (PLAYER2..4) ************************************************ 10015 PLSHAP1TAB .BYTE $00 ; ........ 10016 .BYTE $18 ; ...##... 10017 .BYTE $3C ; ..####.. 10018 .BYTE $7E ; .######. 10019 .BYTE $7E ; .######. 10020 .BYTE $76 ; .###.##. 10021 .BYTE $F7 ; ####.### 10022 .BYTE $DF ; ##.##### 10023 .BYTE $DF ; ##.##### 10024 .BYTE $FF ; ######## 10025 .BYTE $FF ; ######## 10026 .BYTE $F7 ; ####.### 10027 .BYTE $76 ; .###.##. 10028 .BYTE $7E ; .######. 10029 .BYTE $7E ; .######. 10030 .BYTE $3C ; ..####.. 10031 .BYTE $18 ; ...##... 10032 .BYTE $10 ; ...#.... 10033 .BYTE $38 ; ..###... 10034 .BYTE $7C ; .#####.. 10035 .BYTE $7C ; .#####.. 10036 .BYTE $FE ; #######. 10037 .BYTE $DE ; ##.####. 10038 .BYTE $DA ; ##.##.#. 10039 .BYTE $FA ; #####.#. 10040 .BYTE $EE ; ###.###. 10041 .BYTE $EE ; ###.###. 10042 .BYTE $7C ; .#####.. 10043 .BYTE $7C ; .#####.. 10044 .BYTE $38 ; ..###... 10045 .BYTE $10 ; ...#.... 10046 .BYTE $18 ; ...##... 10047 .BYTE $3C ; ..####.. 10048 .BYTE $3C ; ..####.. 10049 .BYTE $7E ; .######. 10050 .BYTE $6E ; .##.###. 10051 .BYTE $7A ; .####.#. 10052 .BYTE $7E ; .######. 10053 .BYTE $76 ; .###.##. 10054 .BYTE $7E ; .######. 10055 .BYTE $3C ; ..####.. 10056 .BYTE $3C ; ..####.. 10057 .BYTE $18 ; ...##... 10058 .BYTE $10 ; ...#.... 10059 .BYTE $38 ; ..###... 10060 .BYTE $38 ; ..###... 10061 .BYTE $7C ; .#####.. 10062 .BYTE $74 ; .###.#.. 10063 .BYTE $7C ; .#####.. 10064 .BYTE $6C ; .##.##.. 10065 .BYTE $38 ; ..###... 10066 .BYTE $38 ; ..###... 10067 .BYTE $10 ; ...#.... 10068 .BYTE $10 ; ...#.... 10069 .BYTE $18 ; ...##... 10070 .BYTE $3C ; ..####.. 10071 .BYTE $2C ; ..#.##.. 10072 .BYTE $3C ; ..####.. 10073 .BYTE $3C ; ..####.. 10074 .BYTE $18 ; ...##... 10075 .BYTE $08 ; ....#... 10076 .BYTE $10 ; ...#.... 10077 .BYTE $38 ; ..###... 10078 .BYTE $38 ; ..###... 10079 .BYTE $28 ; ..#.#... 10080 .BYTE $38 ; ..###... 10081 .BYTE $10 ; ...#.... 10082 .BYTE $3C ; ..####.. 10083 .BYTE $3C ; ..####.. 10084 .BYTE $24 ; ..#..#.. 10085 .BYTE $3C ; ..####.. 10086 .BYTE $7E ; .######. 10087 .BYTE $7E ; .######. 10088 .BYTE $7E ; .######. 10089 .BYTE $5A ; .#.##.#. 10090 .BYTE $FF ; ######## 10091 .BYTE $FF ; ######## 10092 .BYTE $42 ; .#....#. 10093 .BYTE $42 ; .#....#. 10094 .BYTE $42 ; .#....#. 10095 .BYTE $42 ; .#....#. 10096 .BYTE $42 ; .#....#. 10097 .BYTE $42 ; .#....#. 10098 .BYTE $1C ; ...###.. 10099 .BYTE $1C ; ...###.. 10100 .BYTE $14 ; ...#.#.. 10101 .BYTE $3E ; ..#####. 10102 .BYTE $3E ; ..#####. 10103 .BYTE $3E ; ..#####. 10104 .BYTE $2A ; ..#.#.#. 10105 .BYTE $7F ; .####### 10106 .BYTE $7F ; .####### 10107 .BYTE $22 ; ..#...#. 10108 .BYTE $22 ; ..#...#. 10109 .BYTE $22 ; ..#...#. 10110 .BYTE $22 ; ..#...#. 10111 .BYTE $22 ; ..#...#. 10112 .BYTE $18 ; ...##... 10113 .BYTE $18 ; ...##... 10114 .BYTE $3C ; ..####.. 10115 .BYTE $3C ; ..####.. 10116 .BYTE $3C ; ..####.. 10117 .BYTE $3C ; ..####.. 10118 .BYTE $7E ; .######. 10119 .BYTE $24 ; ..#..#.. 10120 .BYTE $24 ; ..#..#.. 10121 .BYTE $24 ; ..#..#.. 10122 .BYTE $24 ; ..#..#.. 10123 .BYTE $10 ; ...#.... 10124 .BYTE $10 ; ...#.... 10125 .BYTE $38 ; ..###... 10126 .BYTE $38 ; ..###... 10127 .BYTE $38 ; ..###... 10128 .BYTE $7C ; .#####.. 10129 .BYTE $28 ; ..#.#... 10130 .BYTE $28 ; ..#.#... 10131 .BYTE $28 ; ..#.#... 10132 .BYTE $18 ; ...##... 10133 .BYTE $18 ; ...##... 10134 .BYTE $3C ; ..####.. 10135 .BYTE $18 ; ...##... 10136 .BYTE $18 ; ...##... 10137 .BYTE $10 ; ...#.... 10138 .BYTE $10 ; ...#.... 10139 .BYTE $38 ; ..###... 10140 .BYTE $10 ; ...#.... 10141 .BYTE $18 ; ...##... 10142 .BYTE $7E ; .######. 10143 .BYTE $FF ; ######## 10144 .BYTE $FF ; ######## 10145 .BYTE $FF ; ######## 10146 .BYTE $FF ; ######## 10147 .BYTE $FF ; ######## 10148 .BYTE $E7 ; ###..### 10149 .BYTE $E7 ; ###..### 10150 .BYTE $FF ; ######## 10151 .BYTE $FF ; ######## 10152 .BYTE $FF ; ######## 10153 .BYTE $FF ; ######## 10154 .BYTE $FF ; ######## 10155 .BYTE $7E ; .######. 10156 .BYTE $7E ; .######. 10157 .BYTE $00 ; ........ 10158 .BYTE $18 ; ...##... 10159 .BYTE $3C ; ..####.. 10160 .BYTE $7E ; .######. 10161 .BYTE $FF ; ######## 10162 .BYTE $FF ; ######## 10163 .BYTE $FF ; ######## 10164 .BYTE $E7 ; ###..### 10165 .BYTE $66 ; .##..##. 10166 .BYTE $FF ; ######## 10167 .BYTE $FF ; ######## 10168 .BYTE $FF ; ######## 10169 .BYTE $FF ; ######## 10170 .BYTE $7E ; .######. 10171 .BYTE $7E ; .######. 10172 .BYTE $00 ; ........ 10173 .BYTE $18 ; ...##... 10174 .BYTE $3C ; ..####.. 10175 .BYTE $7E ; .######. 10176 .BYTE $FF ; ######## 10177 .BYTE $FF ; ######## 10178 .BYTE $E7 ; ###..### 10179 .BYTE $66 ; .##..##. 10180 .BYTE $FF ; ######## 10181 .BYTE $FF ; ######## 10182 .BYTE $FF ; ######## 10183 .BYTE $FF ; ######## 10184 .BYTE $3C ; ..####.. 10185 .BYTE $18 ; ...##... 10186 .BYTE $3C ; ..####.. 10187 .BYTE $FF ; ######## 10188 .BYTE $FF ; ######## 10189 .BYTE $E7 ; ###..### 10190 .BYTE $66 ; .##..##. 10191 .BYTE $FF ; ######## 10192 .BYTE $FF ; ######## 10193 .BYTE $7E ; .######. 10194 .BYTE $3C ; ..####.. 10195 .BYTE $00 ; ........ 10196 .BYTE $18 ; ...##... 10197 .BYTE $3C ; ..####.. 10198 .BYTE $FF ; ######## 10199 .BYTE $FF ; ######## 10200 .BYTE $FF ; ######## 10201 .BYTE $3C ; ..####.. 10202 .BYTE $18 ; ...##... 10203 .BYTE $18 ; ...##... 10204 .BYTE $3C ; ..####.. 10205 .BYTE $FF ; ######## 10206 .BYTE $3C ; ..####.. 10207 .BYTE $18 ; ...##... 10208 .BYTE $28 ; ..#.#... 10209 .BYTE $28 ; ..#.#... 10210 .BYTE $28 ; ..#.#... 10211 .BYTE $28 ; ..#.#... 10212 .BYTE $EE ; ###.###. 10213 .BYTE $00 ; ........ 10214 .BYTE $00 ; ........ 10215 .BYTE $EE ; ###.###. 10216 .BYTE $28 ; ..#.#... 10217 .BYTE $28 ; ..#.#... 10218 .BYTE $28 ; ..#.#... 10219 .BYTE $28 ; ..#.#... 10220 10221 ;*** Shape table 2 (PLAYER0..1) ************************************************ 10222 PLSHAP2TAB .BYTE $00 ; ........ 10223 .BYTE $81 ; #......# 10224 .BYTE $81 ; #......# 10225 .BYTE $81 ; #......# 10226 .BYTE $81 ; #......# 10227 .BYTE $BD ; #.####.# 10228 .BYTE $FF ; ######## 10229 .BYTE $FF ; ######## 10230 .BYTE $BD ; #.####.# 10231 .BYTE $81 ; #......# 10232 .BYTE $81 ; #......# 10233 .BYTE $81 ; #......# 10234 .BYTE $81 ; #......# 10235 .BYTE $82 ; #.....#. 10236 .BYTE $82 ; #.....#. 10237 .BYTE $BA ; #.###.#. 10238 .BYTE $FE ; #######. 10239 .BYTE $FE ; #######. 10240 .BYTE $BA ; #.###.#. 10241 .BYTE $82 ; #.....#. 10242 .BYTE $82 ; #.....#. 10243 .BYTE $42 ; .#....#. 10244 .BYTE $5A ; .#.##.#. 10245 .BYTE $7E ; .######. 10246 .BYTE $7E ; .######. 10247 .BYTE $5A ; .#.##.#. 10248 .BYTE $42 ; .#....#. 10249 .BYTE $44 ; .#...#.. 10250 .BYTE $54 ; .#.#.#.. 10251 .BYTE $7C ; .#####.. 10252 .BYTE $7C ; .#####.. 10253 .BYTE $54 ; .#.#.#.. 10254 .BYTE $44 ; .#...#.. 10255 .BYTE $24 ; ..#..#.. 10256 .BYTE $3C ; ..####.. 10257 .BYTE $3C ; ..####.. 10258 .BYTE $24 ; ..#..#.. 10259 .BYTE $28 ; ..#.#... 10260 .BYTE $38 ; ..###... 10261 .BYTE $38 ; ..###... 10262 .BYTE $28 ; ..#.#... 10263 .BYTE $18 ; ...##... 10264 .BYTE $18 ; ...##... 10265 .BYTE $10 ; ...#.... 10266 .BYTE $10 ; ...#.... 10267 .BYTE $E0 ; ###..... 10268 .BYTE $F8 ; #####... 10269 .BYTE $F8 ; #####... 10270 .BYTE $FE ; #######. 10271 .BYTE $57 ; .#.#.### 10272 .BYTE $FE ; #######. 10273 .BYTE $F8 ; #####... 10274 .BYTE $F8 ; #####... 10275 .BYTE $C0 ; ##...... 10276 .BYTE $C0 ; ##...... 10277 .BYTE $F0 ; ####.... 10278 .BYTE $C0 ; ##...... 10279 .BYTE $F0 ; ####.... 10280 .BYTE $F0 ; ####.... 10281 .BYTE $FC ; ######.. 10282 .BYTE $BE ; #.#####. 10283 .BYTE $FC ; ######.. 10284 .BYTE $F0 ; ####.... 10285 .BYTE $80 ; #....... 10286 .BYTE $80 ; #....... 10287 .BYTE $C0 ; ##...... 10288 .BYTE $C0 ; ##...... 10289 .BYTE $F0 ; ####.... 10290 .BYTE $BC ; #.####.. 10291 .BYTE $F0 ; ####.... 10292 .BYTE $C0 ; ##...... 10293 .BYTE $07 ; .....### 10294 .BYTE $1F ; ...##### 10295 .BYTE $1F ; ...##### 10296 .BYTE $7F ; .####### 10297 .BYTE $EA ; ###.#.#. 10298 .BYTE $7F ; .####### 10299 .BYTE $1F ; ...##### 10300 .BYTE $1F ; ...##### 10301 .BYTE $03 ; ......## 10302 .BYTE $03 ; ......## 10303 .BYTE $0F ; ....#### 10304 .BYTE $03 ; ......## 10305 .BYTE $0F ; ....#### 10306 .BYTE $0F ; ....#### 10307 .BYTE $3F ; ..###### 10308 .BYTE $7D ; .#####.# 10309 .BYTE $3F ; ..###### 10310 .BYTE $0F ; ....#### 10311 .BYTE $01 ; .......# 10312 .BYTE $01 ; .......# 10313 .BYTE $03 ; ......## 10314 .BYTE $03 ; ......## 10315 .BYTE $0F ; ....#### 10316 .BYTE $3D ; ..####.# 10317 .BYTE $0F ; ....#### 10318 .BYTE $03 ; ......## 10319 .BYTE $18 ; ...##... 10320 .BYTE $3C ; ..####.. 10321 .BYTE $7E ; .######. 10322 .BYTE $7E ; .######. 10323 .BYTE $DB ; ##.##.## 10324 .BYTE $C3 ; ##....## 10325 .BYTE $81 ; #......# 10326 .BYTE $81 ; #......# 10327 .BYTE $81 ; #......# 10328 .BYTE $10 ; ...#.... 10329 .BYTE $38 ; ..###... 10330 .BYTE $7C ; .#####.. 10331 .BYTE $7C ; .#####.. 10332 .BYTE $D6 ; ##.#.##. 10333 .BYTE $C6 ; ##...##. 10334 .BYTE $82 ; #.....#. 10335 .BYTE $82 ; #.....#. 10336 .BYTE $18 ; ...##... 10337 .BYTE $3C ; ..####.. 10338 .BYTE $3C ; ..####.. 10339 .BYTE $66 ; .##..##. 10340 .BYTE $66 ; .##..##. 10341 .BYTE $42 ; .#....#. 10342 .BYTE $42 ; .#....#. 10343 .BYTE $10 ; ...#.... 10344 .BYTE $38 ; ..###... 10345 .BYTE $38 ; ..###... 10346 .BYTE $6C ; .##.##.. 10347 .BYTE $44 ; .#...#.. 10348 .BYTE $44 ; .#...#.. 10349 .BYTE $18 ; ...##... 10350 .BYTE $3C ; ..####.. 10351 .BYTE $24 ; ..#..#.. 10352 .BYTE $24 ; ..#..#.. 10353 .BYTE $10 ; ...#.... 10354 .BYTE $38 ; ..###... 10355 .BYTE $28 ; ..#.#... 10356 .BYTE $18 ; ...##... 10357 .BYTE $3C ; ..####.. 10358 .BYTE $7E ; .######. 10359 .BYTE $FF ; ######## 10360 .BYTE $18 ; ...##... 10361 .BYTE $18 ; ...##... 10362 .BYTE $FF ; ######## 10363 .BYTE $7E ; .######. 10364 .BYTE $3C ; ..####.. 10365 .BYTE $18 ; ...##... 10366 .BYTE $10 ; ...#.... 10367 .BYTE $38 ; ..###... 10368 .BYTE $7C ; .#####.. 10369 .BYTE $FE ; #######. 10370 .BYTE $38 ; ..###... 10371 .BYTE $38 ; ..###... 10372 .BYTE $FE ; #######. 10373 .BYTE $7C ; .#####.. 10374 .BYTE $38 ; ..###... 10375 .BYTE $10 ; ...#.... 10376 .BYTE $18 ; ...##... 10377 .BYTE $3C ; ..####.. 10378 .BYTE $7E ; .######. 10379 .BYTE $18 ; ...##... 10380 .BYTE $7E ; .######. 10381 .BYTE $3C ; ..####.. 10382 .BYTE $18 ; ...##... 10383 .BYTE $10 ; ...#.... 10384 .BYTE $38 ; ..###... 10385 .BYTE $7C ; .#####.. 10386 .BYTE $10 ; ...#.... 10387 .BYTE $7C ; .#####.. 10388 .BYTE $38 ; ..###... 10389 .BYTE $10 ; ...#.... 10390 .BYTE $18 ; ...##... 10391 .BYTE $3C ; ..####.. 10392 .BYTE $18 ; ...##... 10393 .BYTE $3C ; ..####.. 10394 .BYTE $18 ; ...##... 10395 .BYTE $10 ; ...#.... 10396 .BYTE $38 ; ..###... 10397 .BYTE $38 ; ..###... 10398 .BYTE $10 ; ...#.... 10399 10400 ;*** Display List fragments **************************************************** 10401 ; 10402 ; LOCAL VARIABLES 10403 PFMEM.C0R0 = PFMEM+0*40 ; Start address of PLAYFIELD row 0 10404 PFMEM.C0R5 = PFMEM+5*40 ; Start address of PLAYFIELD row 5 10405 PFMEM.C0R17 = PFMEM+17*40 ; Start address of PLAYFIELD row 17 10406 10407 ;*** Display List fragment for Control Panel Display (bottom text window) ****** 10408 DLSTFRAG .BYTE $8D ; GR7 + DLI 10409 .BYTE $00 ; BLK1 10410 .BYTE $46,PANELTXT ; GR1 @ PANELTXT 10411 .BYTE $20 ; BLK3 10412 .BYTE $06 ; GR1 10413 .BYTE $00 ; BLK1 10414 10415 ;*** Display List fragment for Galactic Chart view ***************************** 10416 DLSTFRAGGC .BYTE $01,DLSTGC ; JMP @ DLSTGC 10417 10418 ;*** Display List fragment for Long-Range Scan view **************************** 10419 DLSTFRAGLRS .BYTE $00 ; BLK1 10420 .BYTE $00 ; BLK1 10421 .BYTE $46,LRSHEADER ; GR1 @ LRSHEADER 10422 .BYTE $4D,PFMEM.C0R5 ; GR7 @ PFMEM.C0R5 10423 10424 ;*** Display List fragment for Aft view **************************************** 10425 DLSTFRAGAFT .BYTE $00 ; BLK1 10426 .BYTE $00 ; BLK1 10427 .BYTE $46,AFTHEADER ; GR1 @ AFTHEADER 10428 .BYTE $4D,PFMEM.C0R5 ; GR7 @ PFMEM.C0R5 10429 10430 ;*** Display List fragment for Front view and Title text line ****************** 10431 DLSTFRAGFRONT .BYTE $4D,PFMEM.C0R0 ; GR7 @ PFMEM.C0R0 10432 .BYTE $0D ; GR7 10433 .BYTE $0D ; GR7 10434 .BYTE $0D ; GR7 10435 .BYTE $0D ; GR7 10436 .BYTE $0D ; GR7 10437 .BYTE $30 ; BLK4 10438 .BYTE $46,TITLETXT ; GR1 @ TITLETXT 10439 .BYTE $4D,PFMEM.C0R17 ; GR7 @ PFMEM.C0R17 10440 10441 ;*** Display List fragment offsets relative to DLSTFRAG ************************ 10442 DLSTFRAGOFFTAB .BYTE DLSTFRAGFRONT-DLSTFRAG ; Front view 10443 .BYTE DLSTFRAGAFT-DLSTFRAG ; Aft view 10444 .BYTE DLSTFRAGLRS-DLSTFRAG ; Long-Range Scan view 10445 .BYTE DLSTFRAGGC-DLSTFRAG ; Galactic Chart view 10446 10447 ;*** 1-byte bit patterns for 4 pixels of same color for PLAYFIELD space objects 10448 FOURCOLORPIXEL .BYTE $FF ; COLOR3 10449 .BYTE $FF ; COLOR3 10450 .BYTE $FF ; COLOR3 10451 .BYTE $FF ; COLOR3 10452 .BYTE $AA ; COLOR2 10453 .BYTE $FF ; COLOR3 10454 .BYTE $AA ; COLOR2 10455 .BYTE $FF ; COLOR3 10456 .BYTE $AA ; COLOR2 10457 .BYTE $AA ; COLOR2 10458 .BYTE $AA ; COLOR2 10459 .BYTE $FF ; COLOR3 10460 .BYTE $AA ; COLOR2 10461 .BYTE $AA ; COLOR2 10462 .BYTE $AA ; COLOR2 10463 .BYTE $AA ; COLOR2 10464 .BYTE $AA ; COLOR2 10465 .BYTE $AA ; COLOR2 10466 .BYTE $AA ; COLOR2 10467 .BYTE $55 ; COLOR1 10468 .BYTE $55 ; COLOR1 10469 .BYTE $AA ; COLOR2 10470 .BYTE $55 ; COLOR1 10471 .BYTE $AA ; COLOR2 10472 .BYTE $55 ; COLOR1 10473 .BYTE $55 ; COLOR1 10474 .BYTE $55 ; COLOR1 10475 .BYTE $AA ; COLOR2 10476 .BYTE $55 ; COLOR1 10477 .BYTE $55 ; COLOR1 10478 .BYTE $55 ; COLOR1 10479 .BYTE $55 ; COLOR1 10480 10481 ;*** Masks to filter 1 pixel (2 bits) from 4 pixels (1 byte of PLAYFIELD memory) 10482 PIXELMASKTAB .BYTE $C0 ; ##...... 10483 .BYTE $30 ; ..##.... 10484 .BYTE $0C ; ....##.. 10485 .BYTE $03 ; ......## 10486 10487 ;*** Velocity table ************************************************************ 10488 VELOCITYTAB .BYTE 0 ; Speed 0 = 0 10489 .BYTE 1 ; Speed 1 = 1 10490 .BYTE 2 ; Speed 2 = 2 10491 .BYTE 4 ; Speed 3 = 4 10492 .BYTE 8 ; Speed 4 = 8 10493 .BYTE 16 ; Speed 5 = 16 10494 .BYTE 32 ; Speed 6 = 32 10495 .BYTE 64 ; Speed 7 = 64 10496 .BYTE 96 ; Speed 8 = 96 10497 .BYTE 112 ; Speed 9 = 112 10498 10499 ;*** Keyboard code lookup table ************************************************ 10500 KEYTAB .BYTE $F2 ; '0' - Speed 0 10501 .BYTE $DF ; '1' - Speed 1 10502 .BYTE $DE ; '2' - Speed 2 10503 .BYTE $DA ; '3' - Speed 3 10504 .BYTE $D8 ; '4' - Speed 4 10505 .BYTE $DD ; '5' - Speed 5 10506 .BYTE $DB ; '6' - Speed 6 10507 .BYTE $F3 ; '7' - Speed 7 10508 .BYTE $F5 ; '8' - Speed 8 10509 .BYTE $F0 ; '9' - Speed 9 10510 .BYTE $F8 ; 'F' - Front view 10511 .BYTE $FF ; 'A' - Aft view 10512 .BYTE $C0 ; 'L' - Long-Range Scan view 10513 .BYTE $FD ; 'G' - Galactic Chart view 10514 .BYTE $ED ; 'T' - Tracking on/off 10515 .BYTE $FE ; 'S' - Shields on/off 10516 .BYTE $D2 ; 'C' - Attack Computer on/off 10517 .BYTE $F9 ; 'H' - Hyperwarp 10518 .BYTE $E5 ; 'M' - Manual Target Selector 10519 .BYTE $CA ; 'P' - Pause 10520 .BYTE $E7 ; 'INV' - Abort Mission 10521 10522 ;*** Engines energy drain rates per game loop iteration in energy subunits ***** 10523 DRAINRATETAB .BYTE 0 ; 10524 .BYTE 4 ; 10525 .BYTE 6 ; 10526 .BYTE 8 ; 10527 .BYTE 10 ; 10528 .BYTE 12 ; 10529 .BYTE 14 ; 10530 .BYTE 30 ; 10531 .BYTE 45 ; 10532 .BYTE 60 ; 10533 10534 ;*** Hyperwarp energy depending on distance ************************************ 10535 WARPENERGYTAB .BYTE 10 ; = 100 energy units 10536 .BYTE 13 ; = 130 energy units 10537 .BYTE 16 ; = 160 energy units 10538 .BYTE 20 ; = 200 energy units 10539 .BYTE 23 ; = 230 energy units 10540 .BYTE 50 ; = 500 energy units 10541 .BYTE 70 ; = 700 energy units 10542 .BYTE 80 ; = 800 energy units 10543 .BYTE 90 ; = 900 energy units 10544 .BYTE 120 ; = 1200 energy units 10545 .BYTE 125 ; = 1250 energy units 10546 .BYTE 130 ; = 1300 energy units 10547 .BYTE 135 ; = 1350 energy units 10548 .BYTE 140 ; = 1400 energy units 10549 .BYTE 155 ; = 1550 energy units 10550 .BYTE 170 ; = 1700 energy units 10551 .BYTE 184 ; = 1840 energy units 10552 .BYTE 200 ; = 2000 energy units 10553 .BYTE 208 ; = 2080 energy units 10554 .BYTE 216 ; = 2160 energy units 10555 .BYTE 223 ; = 2230 energy units 10556 .BYTE 232 ; = 2320 energy units 10557 .BYTE 241 ; = 2410 energy units 10558 .BYTE 250 ; = 2500 energy units 10559 10560 ;*** Joystick increments ******************************************************* 10561 STICKINCTAB .BYTE 0 ; Centered 10562 .BYTE 1 ; Right or up 10563 .BYTE -1 ; Left or down 10564 .BYTE 0 ; Centered 10565 10566 ;*** 3-byte elements to draw cross hairs and Attack Computer Display *********** 10567 ; Byte 1 : Pixel column number of line start 10568 ; Byte 2 : Pixel row number of line start 10569 ; Byte 3 : B7 = 0 -> Draw line to the right 10570 ; B7 = 1 -> Draw line down 10571 ; B6..0 -> Length of line in pixels. Possible values are: 0..127. 10572 ; 10573 ; # 10574 ; # 4 10575 ; # ############################## 10576 ; #1 # # # 10577 ; # # #11 # 10578 ; # # # # 10579 ; # #5 # 8 #6 10580 ; # ############### # 10581 ; # # # # 10582 ; 15 16 # 7 # # 10 # 10583 ; ############### ############### ######## ######### 10584 ; # #12 # # 10585 ; # # #13 # 10586 ; # ############### # 10587 ; # # 9 # # 10588 ; # # # # 10589 ; # # #14 # 10590 ; # # 3 # # 10591 ; #2 ############################## 10592 ; # 10593 ; # 10594 ; 10595 ; Front/Aft Cross Hairs Attack Computer Display 10596 ; 10597 ; LOCAL VARIABLES 10598 DOWN = $80 10599 RIGHT = $00 10600 10601 DRAWLINESTAB .BYTE 80,40,DOWN!7 ; Line 1 10602 .BYTE 80,54,DOWN!7 ; Line 2 10603 10604 .BYTE 119,70,RIGHT!30 ; Line 3 10605 .BYTE 119,86,RIGHT!30 ; Line 4 10606 .BYTE 119,70,DOWN!17 ; Line 5 10607 .BYTE 148,70,DOWN!17 ; Line 6 10608 .BYTE 120,78,RIGHT!6 ; Line 7 10609 .BYTE 126,75,RIGHT!15 ; Line 8 10610 .BYTE 126,81,RIGHT!15 ; Line 9 10611 .BYTE 141,78,RIGHT!7 ; Line 10 10612 .BYTE 133,71,DOWN!4 ; Line 11 10613 .BYTE 126,76,DOWN!5 ; Line 12 10614 .BYTE 140,76,DOWN!5 ; Line 13 10615 .BYTE 133,82,DOWN!4 ; Line 14 10616 10617 .BYTE 62,50,RIGHT!15 ; Line 15 10618 .BYTE 84,50,RIGHT!15 ; Line 16 10619 .BYTE $FE ; End marker 10620 10621 ;*** 3-byte elements to draw our starship's shape in Long-Range Scan view ****** 10622 ; 10623 ; Line 17 18 19 20 21 10624 ; ## 10625 ; ## 10626 ; ## ## ## 10627 ; ## ## ## ## ## 10628 ; ## ## ## 10629 10630 .BYTE 78,53,DOWN!2 ; Line 17 10631 .BYTE 79,52,DOWN!2 ; Line 18 10632 .BYTE 80,50,DOWN!5 ; Line 19 10633 .BYTE 81,52,DOWN!2 ; Line 20 10634 .BYTE 82,53,DOWN!2 ; Line 21 10635 .BYTE $FE ; End marker 10636 10637 ;*** Initial x and y coordinates of a star during hyperwarp ******************** 10638 ; The following two tables are used to determine the initial x and y coordinates 10639 ; (high byte) of a star during hyperwarp. An index in 0..3 picks both the x and 10640 ; y coordinate, thus 4 pairs of coordinates are possible: 10641 ; 10642 ; Y +-------+----------------------------+----------------------------+ 10643 ; ^ | Index | x-coordinate | y-coordinate | 10644 ; | +-------+----------------------------+----------------------------+ 10645 ; |.32. | 0 | +1024..+1279 (+$04**) | +512..+767 (+$02**) | 10646 ; |...1 | 1 | +1024..+1279 (+$04**) | +768..+1023 (+$03**) | 10647 ; |...0 | 2 | +768..+1023 (+$03**) | +1024..+1279 (+$04**) | 10648 ; |.... | 3 | +512..+767 (+$02**) | +1024..+1279 (+$04**) | 10649 ; 0----->X +-------+----------------------------+----------------------------+ 10650 10651 ;*** Initial x-coordinate (high byte) of star in hyperwarp ********************* 10652 WARPSTARXTAB .BYTE $04 ; +1024..+1279 (+$04**) 10653 .BYTE $04 ; +1024..+1279 (+$04**) 10654 .BYTE $03 ; +768..+1023 (+$03**) 10655 .BYTE $02 ; +512..+767 (+$02**) 10656 10657 ;*** Initial y-coordinate (high byte) of star in hyperwarp ********************* 10658 WARPSTARYTAB .BYTE $02 ; +512..+767 (+$02**) 10659 .BYTE $03 ; +768..+1023 (+$03**) 10660 .BYTE $04 ; +1024..+1279 (+$04**) 10661 .BYTE $04 ; +1024..+1279 (+$04**) 10662 10663 ;*** Text of Control Panel Display (encoded in custom character set) *********** 10664 ; Row 1: "V:00 K:00 E:9999 T:0" 10665 ; Row 2: " O:-00 O:-00 R:-000 " 10666 10667 PANELTXTTAB .BYTE CCS.V 10668 .BYTE CCS.COLON 10669 .BYTE CCS.0 10670 .BYTE CCS.0 10671 .BYTE CCS.SPC 10672 .BYTE CCS.COL1!CCS.K 10673 .BYTE CCS.COL1!CCS.COLON 10674 .BYTE CCS.COL1!CCS.0 10675 .BYTE CCS.COL1!CCS.0 10676 .BYTE CCS.SPC 10677 .BYTE CCS.COL2!CCS.E 10678 .BYTE CCS.COL2!CCS.COLON 10679 .BYTE CCS.COL2!CCS.9 10680 .BYTE CCS.COL2!CCS.9 10681 .BYTE CCS.COL2!CCS.9 10682 .BYTE CCS.COL2!CCS.9 10683 .BYTE CCS.SPC 10684 .BYTE CCS.T 10685 .BYTE CCS.COLON 10686 .BYTE CCS.0 10687 10688 .BYTE CCS.SPC 10689 .BYTE CCS.THETA 10690 .BYTE CCS.COLON 10691 .BYTE CCS.MINUS 10692 .BYTE CCS.0 10693 .BYTE CCS.0 10694 .BYTE CCS.SPC 10695 .BYTE CCS.COL1!CCS.PHI 10696 .BYTE CCS.COL1!CCS.COLON 10697 .BYTE CCS.MINUS 10698 .BYTE CCS.0 10699 .BYTE CCS.0 10700 .BYTE CCS.SPC 10701 .BYTE CCS.COL2!CCS.R 10702 .BYTE CCS.COL2!CCS.COLON 10703 .BYTE CCS.MINUS 10704 .BYTE CCS.0 10705 .BYTE CCS.0 10706 .BYTE CCS.0 10707 .BYTE CCS.SPC 10708 10709 ;*** Text of Galactic Chart Panel Display ************************************** 10710 ; Row 1: "WARP ENERGY: 0 " 10711 ; Row 2: "TARGETS: DC:PESCLR " 10712 ; Row 3: "STAR DATE:00.00 " 10713 10714 .BYTE ROM.W 10715 .BYTE ROM.A 10716 .BYTE ROM.R 10717 .BYTE ROM.P 10718 .BYTE ROM.SPC 10719 .BYTE ROM.E 10720 .BYTE ROM.N 10721 .BYTE ROM.E 10722 .BYTE ROM.R 10723 .BYTE ROM.G 10724 .BYTE ROM.Y 10725 .BYTE ROM.COLON 10726 .BYTE ROM.SPC 10727 .BYTE ROM.SPC 10728 .BYTE ROM.SPC 10729 .BYTE ROM.0 10730 .BYTE ROM.SPC 10731 .BYTE ROM.SPC 10732 .BYTE ROM.SPC 10733 .BYTE ROM.SPC 10734 10735 .BYTE CCS.COL2!ROM.T 10736 .BYTE CCS.COL2!ROM.A 10737 .BYTE CCS.COL2!ROM.R 10738 .BYTE CCS.COL2!ROM.G 10739 .BYTE CCS.COL2!ROM.E 10740 .BYTE CCS.COL2!ROM.T 10741 .BYTE CCS.COL2!ROM.S 10742 .BYTE CCS.COL2!ROM.COLON 10743 .BYTE ROM.SPC 10744 .BYTE ROM.SPC 10745 .BYTE ROM.D 10746 .BYTE ROM.C 10747 .BYTE ROM.COLON 10748 .BYTE ROM.P 10749 .BYTE ROM.E 10750 .BYTE ROM.S 10751 .BYTE ROM.C 10752 .BYTE ROM.L 10753 .BYTE ROM.R 10754 .BYTE ROM.SPC 10755 10756 .BYTE CCS.COL3!ROM.S 10757 .BYTE CCS.COL3!ROM.T 10758 .BYTE CCS.COL3!ROM.A 10759 .BYTE CCS.COL3!ROM.R 10760 .BYTE ROM.SPC 10761 .BYTE CCS.COL3!ROM.D 10762 .BYTE CCS.COL3!ROM.A 10763 .BYTE CCS.COL3!ROM.T 10764 .BYTE CCS.COL3!ROM.E 10765 .BYTE CCS.COL3!ROM.COLON 10766 .BYTE CCS.COL3!ROM.0 10767 .BYTE CCS.COL3!ROM.0 10768 .BYTE CCS.COL3!ROM.DOT 10769 .BYTE CCS.COL3!ROM.0 10770 .BYTE CCS.COL3!ROM.0 10771 .BYTE ROM.SPC 10772 .BYTE ROM.SPC 10773 .BYTE ROM.SPC 10774 .BYTE ROM.SPC 10775 .BYTE ROM.SPC 10776 10777 ;*** Galactic Chart sector type table ****************************************** 10778 SECTORTYPETAB .BYTE $CF ; Starbase 10779 .BYTE $04 ; 4 Zylon ships 10780 .BYTE $03 ; 3 Zylon ships 10781 .BYTE $02 ; 1 or 2 Zylon ships 10782 10783 ;*** Phrase table ************************************************************** 10784 ; Phrases consist of phrase tokens. These are bytes that encode words, segments 10785 ; (multiple words that fit into a single line of text), and how they are displayed. 10786 ; 10787 ; LOCAL VARIABLES 10788 EOP = $40 ; End of phrase 10789 EOS = $80 ; End of segment 10790 LONG = $C0 ; Display title phrase for a long time 10791 10792 ; Title Phrase Offset, Text 10793 PHRASETAB .BYTE $00 ; (unused) 10794 .BYTE $05,$06,$02!EOP ; $01 "ATTACK COMPUTER ON" 10795 .BYTE $05,$06,$03!EOP ; $04 "ATTACK COMPUTER OFF" 10796 .BYTE $04,$02!EOP ; $07 "SHIELDS ON" 10797 .BYTE $04,$03!EOP ; $09 "SHIELDS OFF" 10798 .BYTE $06,$07,$02!EOP ; $0B "COMPUTER TRACKING ON" 10799 .BYTE $07,$03!EOP ; $0E "TRACKING OFF" 10800 .BYTE $08!EOP ; $10 "WHATS WRONG?" 10801 .BYTE $09,$0A!EOP ; $11 "HYPERWARP ENGAGED" 10802 .BYTE $0B,$0D!LONG ; $13 "STARBASE SURROUNDED" 10803 .BYTE $0B,$0C!LONG ; $15 "STARBASE DESTROYED" 10804 .BYTE $09,$0E!EOP ; $17 "HYPERWARP ABORTED" 10805 .BYTE $09,$0F!EOP ; $19 "HYPERWARP COMPLETE" 10806 .BYTE $10!LONG ; $1B "HYPERSPACE" 10807 .BYTE $11,$12!EOS ; $1C "ORBIT ESTABLISHED" 10808 .BYTE $16!EOP ; $1E "STANDBY" 10809 .BYTE $13,$0E!EOP ; $1F "DOCKING ABORTED" 10810 .BYTE $15,$0F!EOP ; $21 "TRANSFER COMPLETE" 10811 .BYTE $38!EOS ; $23 " " 10812 .BYTE $17!EOS ; $24 "STAR FLEET TO" 10813 .BYTE $19!EOS ; $25 "ALL UNITS" 10814 .BYTE $18!EOS ; $26 "STAR CRUISER 7" 10815 .BYTE $0C!EOS ; $27 "DESTROYED" 10816 .BYTE $1D!EOS ; $28 "BY ZYLON FIRE" 10817 .BYTE $1E,$1F!EOS ; $29 "POSTHUMOUS RANK IS:" 10818 .BYTE $FD ; $2B "" 10819 .BYTE $25,$FC ; $2C "CLASS " 10820 .BYTE $38!EOP ; $2E " " 10821 .BYTE $1B!EOS ; $2F "STAR RAIDERS" 10822 .BYTE $20!EOP ; $30 "COPYRIGHT ATARI 1979" 10823 .BYTE $38!EOS ; $31 " " 10824 .BYTE $17!EOS ; $32 "STAR FLEET TO" 10825 .BYTE $18!EOS ; $33 "STAR CRUISER 7" 10826 .BYTE $1A,$0E!EOS ; $34 "MISSION ABORTED" 10827 .BYTE $1C,$14!EOS ; $36 "ZERO ENERGY" 10828 .BYTE $24,$1F!EOS ; $38 "NEW RANK IS" 10829 .BYTE $FD ; $3A "" 10830 .BYTE $25,$FC ; $3B "CLASS " 10831 .BYTE $27!EOS ; $3D "REPORT TO BASE" 10832 .BYTE $28!EOP ; $3E "FOR TRAINING" 10833 .BYTE $38!EOS ; $3F " " 10834 .BYTE $17!EOS ; $40 "STAR FLEET TO" 10835 .BYTE $18!EOS ; $41 "STAR CRUISER 7" 10836 .BYTE $1A,$0F!EOS ; $42 "MISSION COMPLETE" 10837 .BYTE $24,$1F!EOS ; $44 "NEW RANK IS:" 10838 .BYTE $FD ; $46 "" 10839 .BYTE $25,$FC ; $47 "CLASS " 10840 .BYTE $26!EOP ; $49 "CONGRATULATIONS" 10841 .BYTE $2C,$1A!EOP ; $4A "NOVICE MISSION" 10842 .BYTE $2E,$1A!EOP ; $4C "PILOT MISSION" 10843 .BYTE $31,$1A!EOP ; $4E "WARRIOR MISSION" 10844 .BYTE $33,$1A!EOP ; $50 "COMMANDER MISSION" 10845 .BYTE $38!EOS ; $52 " " 10846 .BYTE $34,$36!EOP ; $53 "DAMAGE CONTROL" 10847 .BYTE $37,$35!EOS ; $55 "PHOTONS DAMAGED" 10848 .BYTE $38!EOP ; $57 " " 10849 .BYTE $37,$0C!EOS ; $58 "PHOTONS DESTROYED" 10850 .BYTE $38!EOP ; $5A " " 10851 .BYTE $23,$35!EOS ; $5B "ENGINES DAMAGED" 10852 .BYTE $38!EOP ; $5D " " 10853 .BYTE $23,$0C!EOS ; $5E "ENGINES DESTROYED" 10854 .BYTE $38!EOP ; $60 " " 10855 .BYTE $04,$35!EOS ; $61 "SHIELDS DAMAGED" 10856 .BYTE $38!EOP ; $63 " " 10857 .BYTE $04,$0C!EOS ; $64 "SHIELDS DESTROYED" 10858 .BYTE $38!EOP ; $66 " " 10859 .BYTE $06,$35!EOS ; $67 "COMPUTER DAMAGED" 10860 .BYTE $38!EOP ; $69 " " 10861 .BYTE $06,$0C!EOS ; $6A "COMPUTER DESTROYED" 10862 .BYTE $38!EOP ; $6C " " 10863 .BYTE $22!EOS ; $6D "SECTOR SCAN" 10864 .BYTE $35!EOP ; $6E "DAMAGED" 10865 .BYTE $22!EOS ; $6F "SECTOR SCAN" 10866 .BYTE $0C!EOP ; $70 "DESTROYED" 10867 .BYTE $21!EOS ; $71 "SUB-SPACE RADIO" 10868 .BYTE $35!EOP ; $72 "DAMAGED" 10869 .BYTE $21!EOS ; $73 "SUB-SPACE RADIO" 10870 .BYTE $0C!EOP ; $74 "DESTROYED" 10871 .BYTE $01!LONG ; $75 "RED ALERT" 10872 .BYTE $38!EOS ; $76 " " 10873 .BYTE $17!EOS ; $77 "STAR FLEET TO" 10874 .BYTE $18!EOS ; $78 "STAR CRUISER 7" 10875 .BYTE $1A,$0E!EOS ; $79 "MISSION ABORTED" 10876 .BYTE $24,$1F!EOS ; $7B "NEW RANK IS:" 10877 .BYTE $FD ; $7D "" 10878 .BYTE $25,$FC ; $7E "CLASS " 10879 .BYTE $26!EOP ; $80 "CONGRATULATIONS" 10880 10881 ;*** Word table **************************************************************** 10882 ; Bit B7 of the first byte of a word is the end-of-word marker of the preceding 10883 ; word 10884 ; 10885 ; LOCAL VARIABLES 10886 EOW = $80 ; End of word 10887 10888 WORDTAB .BYTE EOW!$20," RED ALERT" ; Word $01 10889 .BYTE EOW!'O,"N" ; Word $02 10890 .BYTE EOW!'O,"FF" ; Word $03 10891 .BYTE EOW!'S,"HIELDS" ; Word $04 10892 .BYTE EOW!'A,"TTACK" ; Word $05 10893 .BYTE EOW!'C,"OMPUTER" ; Word $06 10894 .BYTE EOW!'T,"RACKING" ; Word $07 10895 .BYTE EOW!'W,"HATS WRONG?" ; Word $08 10896 .BYTE EOW!'H,"YPERWARP" ; Word $09 10897 .BYTE EOW!'E,"NGAGED" ; Word $0A 10898 .BYTE EOW!'S,"TARBASE" ; Word $0B 10899 .BYTE EOW!'D,"ESTROYED" ; Word $0C 10900 .BYTE EOW!'S,"URROUNDED" ; Word $0D 10901 .BYTE EOW!'A,"BORTED" ; Word $0E 10902 .BYTE EOW!'C,"OMPLETE" ; Word $0F 10903 .BYTE EOW!'H,"YPERSPACE" ; Word $10 10904 .BYTE EOW!'O,"RBIT" ; Word $11 10905 .BYTE EOW!'E,"STABLISHED" ; Word $12 10906 .BYTE EOW!'D,"OCKING" ; Word $13 10907 .BYTE EOW!'E,"NERGY" ; Word $14 10908 .BYTE EOW!'T,"RANSFER" ; Word $15 10909 .BYTE EOW!'S,"TANDBY" ; Word $16 10910 .BYTE EOW!'S,"TAR FLEET TO" ; Word $17 10911 .BYTE EOW!'S,"TAR CRUISER 7" ; Word $18 10912 .BYTE EOW!'A,"LL UNITS" ; Word $19 10913 .BYTE EOW!'M,"ISSION" ; Word $1A 10914 .BYTE EOW!$20," STAR RAIDERS" ; Word $1B 10915 .BYTE EOW!'Z,"ERO" ; Word $1C 10916 .BYTE EOW!'B,"Y ZYLON FIRE" ; Word $1D 10917 .BYTE EOW!'P,"OSTHUMOUS" ; Word $1E 10918 .BYTE EOW!'R,"ANK IS:" ; Word $1F 10919 .BYTE EOW!'C,"OPYRIGHT ATARI 1979" ; Word $20 10920 .BYTE EOW!'S,"UB-SPACE RADIO" ; Word $21 10921 .BYTE EOW!'S,"ECTOR SCAN" ; Word $22 10922 .BYTE EOW!'E,"NGINES" ; Word $23 10923 .BYTE EOW!'N,"EW" ; Word $24 10924 .BYTE EOW!'C,"LASS" ; Word $25 10925 .BYTE EOW!'C,"ONGRATULATIONS" ; Word $26 10926 .BYTE EOW!'R,"EPORT TO BASE" ; Word $27 10927 .BYTE EOW!'F,"OR TRAINING" ; Word $28 10928 .BYTE EOW!'G,"ALACTIC COOK" ; Word $29 10929 .BYTE EOW!'G,"ARBAGE SCOW CAPTAIN" ; Word $2A 10930 .BYTE EOW!'R,"OOKIE" ; Word $2B 10931 .BYTE EOW!'N,"OVICE" ; Word $2C 10932 .BYTE EOW!'E,"NSIGN" ; Word $2D 10933 .BYTE EOW!'P,"ILOT" ; Word $2E 10934 .BYTE EOW!'A,"CE" ; Word $2F 10935 .BYTE EOW!'L,"IEUTENANT" ; Word $30 10936 .BYTE EOW!'W,"ARRIOR" ; Word $31 10937 .BYTE EOW!'C,"APTAIN" ; Word $32 10938 .BYTE EOW!'C,"OMMANDER" ; Word $33 10939 .BYTE EOW!'D,"AMAGE" ; Word $34 10940 .BYTE EOW!'D,"AMAGED" ; Word $35 10941 .BYTE EOW!'C,"ONTROL" ; Word $36 10942 .BYTE EOW!'P,"HOTONS" ; Word $37 10943 .BYTE EOW!$20 ; Word $38 10944 .BYTE EOW!'S,"TAR COMMANDER" ; Word $39 10945 .BYTE EOW!$00 ; 10946 10947 ;*** View modes **************************************************************** 10948 VIEWMODETAB .BYTE $00 ; Front view 10949 .BYTE $01 ; Aft view 10950 .BYTE $40 ; Long-Range Scan view 10951 .BYTE $80 ; Galactic Chart view 10952 10953 ;*** Title phrase offsets of "TRACKING OFF", "SHIELDS OFF", "COMPUTER OFF" ***** 10954 MSGOFFTAB .BYTE $0E ; "TRACKING OFF" 10955 .BYTE $09 ; "SHIELDS OFF" 10956 .BYTE $04 ; "COMPUTER OFF" 10957 10958 ;*** Masks to test if Tracking Computer, Shields, or Attack Computer are on **** 10959 MSGBITTAB .BYTE $FF ; Mask Tracking Computer 10960 .BYTE $08 ; Mask Shields 10961 .BYTE $02 ; Mask Attack Computer 10962 10963 ;*** Title phrase offsets of "COMPUTER TRACKING ON", "SHIELDS ON", "COMPUTER ON" 10964 MSGONTAB .BYTE $0B ; "COMPUTER TRACKING ON" 10965 .BYTE $07 ; "SHIELDS ON" 10966 .BYTE $01 ; "COMPUTER ON" 10967 10968 ;*** The following two tables encode the PLAYER shapes ************************* 10969 ; 10970 ; PHOTON TORPEDO (shape type 0, data in shape table PLSHAP1TAB) 10971 ; Numbers at top indicate the shape table offset of the first and last shape row 10972 ; 10973 ; $01..$10 $11..$1E $1F..$2A $2B..$34 $35..$3C $3D..$42 $75..$76 $7A..$7B 10974 ; ...##... ...#.... ...##... ...#.... ...#.... ...#.... ...##... ...#.... 10975 ; ..####.. ..###... ..####.. ..###... ...##... ..###... ...##... ...#.... 10976 ; .######. .#####.. ..####.. ..###... ..####.. ..###... 10977 ; .######. .#####.. .######. .#####.. ..#.##.. ..#.#... 10978 ; .###.##. #######. .##.###. .###.#.. ..####.. ..###... 10979 ; ####.### ##.####. .####.#. .#####.. ..####.. ...#.... 10980 ; ##.##### ##.##.#. .######. .##.##.. ...##... 10981 ; ##.##### #####.#. .###.##. ..###... ....#... 10982 ; ######## ###.###. .######. ..###... 10983 ; ######## ###.###. ..####.. ...#.... 10984 ; ####.### .#####.. ..####.. 10985 ; .###.##. .#####.. ...##... 10986 ; .######. ..###... 10987 ; .######. ...#.... 10988 ; ..####.. 10989 ; ...##... 10990 ; 10991 ; ZYLON FIGHTER (shape type 1, data in shape table PLSHAP2TAB) 10992 ; Numbers at top indicate the shape table offset of the first and last shape row 10993 ; 10994 ; $01..$0C $0D..$14 $15..$1A $1B..$20 $21..$24 $25..$28 $29..$2A $2B..$2C 10995 ; #......# #.....#. .#....#. .#...#.. ..#..#.. ..#.#... ...##... ...#.... 10996 ; #......# #.....#. .#.##.#. .#.#.#.. ..####.. ..###... ...##... ...#.... 10997 ; #......# #.###.#. .######. .#####.. ..####.. ..###... 10998 ; #......# #######. .######. .#####.. ..#..#.. ..#.#... 10999 ; #.####.# #######. .#.##.#. .#.#.#.. 11000 ; ######## #.###.#. .#....#. .#...#.. 11001 ; ######## #.....#. 11002 ; #.####.# #.....#. 11003 ; #......# 11004 ; #......# 11005 ; #......# 11006 ; #......# 11007 ; 11008 ; STARBASE RIGHT (shape type 2, data in shape table PLSHAP2TAB) 11009 ; Numbers at top indicate the shape table offset of the first and last shape row 11010 ; 11011 ; $2D..$36 $38..$40 $41..$46 $36..$38 $36 $00 $00 $00 11012 ; ###..... ##...... ##...... ##...... ##...... ........ ........ ........ 11013 ; #####... ####.... ##...... ####.... 11014 ; #####... ####.... ####.... ##...... 11015 ; #######. ######.. #.####.. 11016 ; #.#.### #.#####. ####.... 11017 ; #######. ######.. ##...... 11018 ; #####... ####.... 11019 ; #####... #....... 11020 ; ##...... #....... 11021 ; ##...... 11022 ; 11023 ; STARBASE CENTER (shape type 3, data in shape table PLSHAP1TAB) 11024 ; Numbers at top indicate the shape table offset of the first and last shape row 11025 ; 11026 ; $7E..$8D $8E..$9C $9D..$A9 $AA..$B3 $B4..$BB $BC..$C0 $7B..$7D $7A..$7B 11027 ; ...##... ........ ........ ...##... ........ ...##... ...#.... ...#.... 11028 ; .######. ...##... ...##... ..####.. ...##... ..####.. ..###... ...#.... 11029 ; ######## ..####.. ..####.. ######## ..####.. ######## ...#.... 11030 ; ######## .######. .######. ######## ######## ..####.. 11031 ; ######## ######## ######## ###..### ######## ...##... 11032 ; ######## ######## ######## .##..##. ######## 11033 ; ######## ######## ###..### ######## ..####.. 11034 ; ###..### ###..### .##..##. ######## ...##... 11035 ; ###..### .##..##. ######## .######. 11036 ; ######## ######## ######## ..####.. 11037 ; ######## ######## ######## 11038 ; ######## ######## ######## 11039 ; ######## ######## ..####.. 11040 ; ######## .######. 11041 ; .######. .######. 11042 ; .######. 11043 ; 11044 ; STARBASE LEFT (shape type 4, data in shape table PLSHAP2TAB) 11045 ; Numbers at top indicate the shape table offset of the first and last shape row 11046 ; 11047 ; $47..$50 $52..$5A $5B..$60 $50..$52 $50 $00 $00 $00 11048 ; .....### ......## ......## ......## ......## ........ ........ ........ 11049 ; ...##### ....#### ......## ....#### 11050 ; ...##### ....#### ....#### ......## 11051 ; .####### ..###### ..####.# 11052 ; ###.#.#. .#####.# ....#### 11053 ; .####### ..###### ......## 11054 ; ...##### ....#### 11055 ; ...##### .......# 11056 ; ......## .......# 11057 ; ......## 11058 ; 11059 ; TRANSFER VESSEL (shape type 5, data in shape table PLSHAP1TAB) 11060 ; Numbers at top indicate the shape table offset of the first and last shape row 11061 ; 11062 ; $43..$52 $53..$60 $61..$6B $6C..$74 $75..$79 $7A..$7D $75..$76 $7A..$7B 11063 ; ..####.. ...###.. ...##... ...#.... ...##... ...#.... ...##... ...#.... 11064 ; ..####.. ...###.. ...##... ...#.... ...##... ...#.... ...##... ...#.... 11065 ; ..#..#.. ...#.#.. ..####.. ..###... ..####.. ..###... 11066 ; ..####.. ..#####. ..####.. ..###... ...##... ...#.... 11067 ; .######. ..#####. ..####.. ..###... ...##... 11068 ; .######. ..#####. ..####.. .#####.. 11069 ; .######. ..#.#.#. .######. ..#.#... 11070 ; .#.##.#. .####### ..#..#.. ..#.#... 11071 ; ######## .####### ..#..#.. ..#.#... 11072 ; ######## ..#...#. ..#..#.. 11073 ; .#....#. ..#...#. ..#..#.. 11074 ; .#....#. ..#...#. 11075 ; .#....#. ..#...#. 11076 ; .#....#. ..#...#. 11077 ; .#....#. 11078 ; .#....#. 11079 ; 11080 ; METEOR (shape type 6, data in shape table PLSHAP1TAB) 11081 ; Numbers at top indicate the shape table offset of the first and last shape row 11082 ; 11083 ; $01..$10 $11..$1E $1F..$2A $2B..$34 $35..$3C $3D..$42 $75..$76 $7A..$7B 11084 ; ...##... ...#.... ...##... ...#.... ...#.... ...#.... ...##... ...#.... 11085 ; ..####.. ..###... ..####.. ..###... ...##... ..###... ...##... ...#.... 11086 ; .######. .#####.. ..####.. ..###... ..####.. ..###... 11087 ; .######. .#####.. .######. .#####.. ..#.##.. ..#.#... 11088 ; .###.##. #######. .##.###. .###.#.. ..####.. ..###... 11089 ; ####.### ##.####. .####.#. .#####.. ..####.. ...#.... 11090 ; ##.##### ##.##.#. .######. .##.##.. ...##... 11091 ; ##.##### #####.#. .###.##. ..###... ....#... 11092 ; ######## ###.###. .######. ..###... 11093 ; ######## ###.###. ..####.. ...#.... 11094 ; ####.### .#####.. ..####.. 11095 ; .###.##. .#####.. ...##... 11096 ; .######. ..###... 11097 ; .######. ...#.... 11098 ; ..####.. 11099 ; ...##... 11100 ; 11101 ; ZYLON CRUISER (shape type 7, data in shape table PLSHAP2TAB) 11102 ; Numbers at top indicate the shape table offset of the first and last shape row 11103 ; 11104 ; $61..$69 $6A..$71 $72..$78 $79..$7E $7F..$82 $83..$85 $29..$2A $2B..$2C 11105 ; ...##... ...#.... ...##... ...#.... ...##... ...#.... ...##... ...#.... 11106 ; ..####.. ..###... ..####.. ..###... ..####.. ..###... ...##... ...#.... 11107 ; .######. .#####.. ..####.. ..###... ..#..#.. ..#.#... 11108 ; .######. .#####.. .##..##. .##.##.. ..#..#.. 11109 ; ##.##.## ##.#.##. .##..##. .#...#.. 11110 ; ##....## ##...##. .#....#. .#...#.. 11111 ; #......# #.....#. .#....#. 11112 ; #......# #.....#. 11113 ; #......# 11114 ; 11115 ; ZYLON BASESTAR (shape type 8, data in shape table PLSHAP2TAB) 11116 ; Numbers at top indicate the shape table offset of the first and last shape row 11117 ; 11118 ; $86..$8F $90..$99 $9A..$A0 $A1..$A7 $A8..$AC $AD..$B0 $29..$2A $2B..$2C 11119 ; ...##... ...#.... ...##... ...#.... ...##... ...#.... ...##... ...#.... 11120 ; ..####.. ..###... ..####.. ..###... ..####.. ..###... ...##... ...#.... 11121 ; .######. .#####.. .######. .#####.. ...##... ..###... 11122 ; ######## #######. ...##... ...#.... ..####.. ...#.... 11123 ; ...##... ..###... .######. .#####.. ...##... 11124 ; ...##... ..###... ..####.. ..###... 11125 ; ######## #######. ...##... ...#.... 11126 ; .######. .#####.. 11127 ; ..####.. ..###... 11128 ; ...##... ...#.... 11129 ; 11130 ; HYPERWARP TARGET MARKER (shape type 9, data in shape table PLSHAP1TAB) 11131 ; Numbers at top indicate the shape table offset of the first and last shape row 11132 ; 11133 ; $C1..$CC $C1..$CC $C1..$CC $C1..$CC $C1..$CC $C1..$CC $75..$76 $C1..$CC 11134 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ...##... ..#.#... 11135 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ...##... ..#.#... 11136 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11137 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11138 ; ###.###. ###.###. ###.###. ###.###. ###.###. ###.###. ###.###. 11139 ; ........ ........ ........ ........ ........ ........ ........ 11140 ; ........ ........ ........ ........ ........ ........ ........ 11141 ; ###.###. ###.###. ###.###. ###.###. ###.###. ###.###. ###.###. 11142 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11143 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11144 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11145 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11146 11147 ;*** Shape type 0..9 offset table (10 shape cell offsets of shape type...) ***** 11148 PLSHAPOFFTAB .BYTE $01,$11,$1F,$2B,$35,$3D,$75,$7A ; ...0 into PLSHAP1TAB 11149 .BYTE $01,$0D,$15,$1B,$21,$25,$29,$2B ; ...1 into PLSHAP2TAB 11150 .BYTE $2D,$38,$41,$36,$36,$00,$00,$00 ; ...2 into PLSHAP2TAB 11151 .BYTE $7E,$8E,$9D,$AA,$B4,$BC,$7B,$7A ; ...3 into PLSHAP1TAB 11152 .BYTE $47,$52,$5B,$50,$50,$00,$00,$00 ; ...4 into PLSHAP2TAB 11153 .BYTE $43,$53,$61,$6C,$75,$7A,$75,$7A ; ...5 into PLSHAP1TAB 11154 .BYTE $01,$11,$1F,$2B,$35,$3D,$75,$7A ; ...6 into PLSHAP1TAB 11155 .BYTE $61,$6A,$72,$79,$7F,$83,$29,$2B ; ...7 into PLSHAP2TAB 11156 .BYTE $86,$90,$9A,$A1,$A8,$AD,$29,$2B ; ...8 into PLSHAP2TAB 11157 .BYTE $C1,$C1,$C1,$C1,$C1,$C1,$75,$C1 ; ...9 into PLSHAP1TAB 11158 11159 ;*** Shape type 0..9 height table (10 shape cell heights of shape type...) ***** 11160 PLSHAPHEIGHTTAB .BYTE $0F,$0D,$0B,$09,$07,$05,$01,$01 ; ...0 11161 .BYTE $0B,$07,$05,$05,$03,$03,$01,$01 ; ...1 11162 .BYTE $09,$08,$05,$02,$00,$00,$00,$00 ; ...2 11163 .BYTE $0F,$0E,$0C,$09,$07,$04,$02,$01 ; ...3 11164 .BYTE $09,$08,$05,$02,$00,$00,$00,$00 ; ...4 11165 .BYTE $0F,$0D,$0A,$08,$04,$03,$01,$01 ; ...5 11166 .BYTE $0F,$0D,$0B,$09,$07,$05,$01,$01 ; ...6 11167 .BYTE $08,$07,$06,$05,$03,$02,$01,$01 ; ...7 11168 .BYTE $09,$09,$06,$06,$04,$03,$01,$01 ; ...8 11169 .BYTE $0B,$0B,$0B,$0B,$0B,$0B,$01,$0B ; ...9 11170 11171 ;*** Keyboard codes to switch to Front or Aft view when Tracking Computer is on 11172 TRACKKEYSTAB .BYTE $F8 ; 'F' - Front view 11173 .BYTE $FF ; 'A' - Aft view 11174 11175 ;*** Galactic Chart sector character codes (encoded in custom character set) *** 11176 SECTORCHARTAB .BYTE CCS.BORDERSW ; Empty sector 11177 .BYTE CCS.2ZYLONS ; Sector contains 1 Zylon ship 11178 .BYTE CCS.2ZYLONS ; Sector contains 2 Zylon ships 11179 .BYTE CCS.3ZYLONS ; Sector contains 3 Zylon ships 11180 .BYTE CCS.4ZYLONS ; Sector contains 4 Zylon ships 11181 .BYTE CCS.STARBASE ; Sector contains starbase 11182 11183 ;*** Mask to limit veer-off velocity of Hyperwarp Target Marker in hyperwarp *** 11184 VEERMASKTAB .BYTE NEG!31 ; -31..+31 (unused) 11185 .BYTE NEG!63 ; -63..+63 PILOT mission 11186 .BYTE NEG!95 ; -95..+95 WARRIOR mission 11187 .BYTE NEG!127 ; -127..+127 COMMANDER mission 11188 11189 ;*** Horizontal PLAYER offsets for PLAYER0..1 (STARBASE LEFT, STARBASE RIGHT) ** 11190 PLSTARBAOFFTAB .BYTE -8 ; -8 Player/Missile pixels 11191 .BYTE 8 ; +8 Player/Missile pixels 11192 11193 ;*** Mission bonus table ******************************************************* 11194 BONUSTAB .BYTE 80 ; Mission complete NOVICE mission 11195 .BYTE 76 ; Mission complete PILOT mission 11196 .BYTE 60 ; Mission complete WARRIOR mission 11197 .BYTE 111 ; Mission complete COMMANDER mission 11198 11199 .BYTE 60 ; Mission aborted NOVICE mission 11200 .BYTE 60 ; Mission aborted PILOT mission 11201 .BYTE 50 ; Mission aborted WARRIOR mission 11202 .BYTE 100 ; Mission aborted COMMANDER mission 11203 11204 .BYTE 40 ; Starship destroyed NOVICE mission 11205 .BYTE 50 ; Starship destroyed PILOT mission 11206 .BYTE 40 ; Starship destroyed WARRIOR mission 11207 .BYTE 90 ; Starship destroyed COMMANDER mission 11208 11209 ;*** Title phrase offsets of scored class rank ********************************* 11210 RANKTAB .BYTE $29!EOS ; "GALACTIC COOK" 11211 .BYTE $2A!EOS ; "GARBAGE SCOW CAPTAIN" 11212 .BYTE $2A!EOS ; "GARBAGE SCOW CAPTAIN" 11213 .BYTE $2B!EOS ; "ROOKIE" 11214 .BYTE $2B!EOS ; "ROOKIE" 11215 .BYTE $2C!EOS ; "NOVICE" 11216 .BYTE $2C!EOS ; "NOVICE" 11217 .BYTE $2D!EOS ; "ENSIGN" 11218 .BYTE $2D!EOS ; "ENSIGN" 11219 .BYTE $2E!EOS ; "PILOT" 11220 .BYTE $2E!EOS ; "PILOT" 11221 .BYTE $2F!EOS ; "ACE" 11222 .BYTE $30!EOS ; "LIEUTENANT" 11223 .BYTE $31!EOS ; "WARRIOR" 11224 .BYTE $32!EOS ; "CAPTAIN" 11225 .BYTE $33!EOS ; "COMMANDER" 11226 .BYTE $33!EOS ; "COMMANDER" 11227 .BYTE $39!EOS ; "STAR COMMANDER" 11228 .BYTE $39!EOS ; "STAR COMMANDER" 11229 11230 ;*** Scored class number table ************************************************* 11231 CLASSTAB .BYTE CCS.COL2!ROM.5 ; Class 5 11232 .BYTE CCS.COL2!ROM.5 ; Class 5 11233 .BYTE CCS.COL2!ROM.5 ; Class 5 11234 .BYTE CCS.COL2!ROM.4 ; Class 4 11235 .BYTE CCS.COL2!ROM.4 ; Class 4 11236 .BYTE CCS.COL2!ROM.4 ; Class 4 11237 .BYTE CCS.COL2!ROM.4 ; Class 4 11238 .BYTE CCS.COL2!ROM.3 ; Class 3 11239 .BYTE CCS.COL2!ROM.3 ; Class 3 11240 .BYTE CCS.COL2!ROM.3 ; Class 3 11241 .BYTE CCS.COL2!ROM.2 ; Class 2 11242 .BYTE CCS.COL2!ROM.2 ; Class 2 11243 .BYTE CCS.COL2!ROM.2 ; Class 2 11244 .BYTE CCS.COL2!ROM.1 ; Class 1 11245 .BYTE CCS.COL2!ROM.1 ; Class 1 11246 .BYTE CCS.COL2!ROM.1 ; Class 1 11247 11248 ;*** Title phrase offsets of mission level ************************************* 11249 MISSIONPHRTAB .BYTE $4A ; "NOVICE MISSION" 11250 .BYTE $4C ; "PILOT MISSION" 11251 .BYTE $4E ; "WARRIOR MISSION" 11252 .BYTE $50 ; "COMMANDER MISSION" 11253 11254 ;*** Damage probability of subsystems depending on mission level *************** 11255 DAMAGEPROBTAB .BYTE 0 ; 0% ( 0:256) NOVICE mission 11256 .BYTE 80 ; 31% ( 80:256) PILOT mission 11257 .BYTE 180 ; 70% (180:256) WARRIOR mission 11258 .BYTE 254 ; 99% (254:256) COMMANDER mission 11259 11260 ;*** Title phrase offsets of damaged subsystems ******************************** 11261 DAMAGEPHRTAB .BYTE $55 ; "PHOTON TORPEDOS DAMAGED" 11262 .BYTE $5B ; "ENGINES DAMAGED" 11263 .BYTE $61 ; "SHIELDS DAMAGED" 11264 .BYTE $67 ; "COMPUTER DAMAGED" 11265 .BYTE $6D ; "LONG RANGE SCAN DAMAGED" 11266 .BYTE $71 ; "SUB-SPACE RADIO DAMAGED" 11267 11268 ;*** Title phrase offsets of destroyed subsystems ****************************** 11269 DESTROYPHRTAB .BYTE $58 ; "PHOTON TORPEDOS DESTROYED" 11270 .BYTE $5E ; "ENGINES DESTROYED" 11271 .BYTE $64 ; "SHIELDS DESTROYED" 11272 .BYTE $6A ; "COMPUTER DESTROYED" 11273 .BYTE $6F ; "LONG RANGE SCAN DESTROYED" 11274 .BYTE $73 ; "SUB-SPACE RADIO DESTROYED" 11275 11276 ;*** 3 x 10-byte noise sound patterns (bytes 0..7 stored in reverse order) ***** 11277 ; 11278 ; (9) AUDCTL ($D208) POKEY: Audio control 11279 ; (8) AUDF3 ($D204) POKEY: Audio channel 3 frequency 11280 ; (7) NOISETORPTIM ($DA) Timer for PHOTON TORPEDO LAUNCHED noise sound patterns 11281 ; (6) NOISEEXPLTIM ($DB) Timer for SHIELD and ZYLON EXPLOSION noise sound patterns 11282 ; (5) NOISEAUDC2 ($DC) Audio channel 1/2 control shadow register 11283 ; (4) NOISEAUDC3 ($DD) Audio channel 3 control shadow register 11284 ; (3) NOISEAUDF1 ($DE) Audio channel 1 frequency shadow register 11285 ; (2) NOISEAUDF2 ($DF) Audio channel 2 frequency shadow register 11286 ; (1) NOISEFRQINC ($E0) Audio channel 1/2 frequency increment 11287 ; (0) NOISELIFE ($E1) Noise sound pattern lifetime 11288 ; 11289 ; (0),(1),(2),(3),(4),(5),(6),(7),(8),(9) 11290 NOISEPATTAB .BYTE $18,$FF,$02,$00,$8A,$A0,$00,$08,$50,$00; PHOTON TORPEDO LAUNCHED 11291 .BYTE $40,$40,$01,$03,$88,$AF,$08,$00,$50,$04; SHIELD EXPLOSION 11292 .BYTE $30,$40,$01,$03,$84,$A8,$04,$00,$50,$04; ZYLON EXPLOSION 11293 11294 ;*** 5 x 6-byte beeper sound patterns (bytes 0..5 stored in reverse order) ***** 11295 ; 11296 ; (5) BEEPFRQIND ($D2) Running index into frequency table BEEPFRQTAB ($BF5C) 11297 ; (4) BEEPREPEAT ($D3) Number of times the beeper sound pattern sequence is repeated - 1 11298 ; (3) BEEPTONELIFE ($D4) Lifetime of tone in TICKs - 1 11299 ; (2) BEEPPAUSELIFE ($D5) Lifetime of pause in TICKs - 1 ($FF -> No pause) 11300 ; (1) BEEPPRIORITY ($D6) Beeper sound pattern priority. A playing beeper sound pattern is 11301 ; stopped if a beeper sound pattern of higher priority is about to be 11302 ; played. A value of 0 indicates that no beeper sound pattern is 11303 ; playing at the moment. 11304 ; (0) BEEPFRQSTART ($D7) Index to first byte of the beeper sound pattern frequency in table 11305 ; BEEPFRQTAB ($BF5C) 11306 ; 11307 ; Frequency-over-TICKs diagrams for all beeper sound patterns: 11308 ; 11309 ; HYPERWARP TRANSIT 11310 ; 11311 ; FRQ 11312 ; | 11313 ; $18 |-4-- 11314 ; | 11315 ; $00 | -3- 11316 ; +-------> TICKS 11317 ; <13 x > 11318 ; 11319 ; RED ALERT 11320 ; 11321 ; FRQ 11322 ; | 11323 ; $60 | --------17------- 11324 ; | 11325 ; $40 |--------17------- 11326 ; | 11327 ; +----------------------------------> TICKS 11328 ; <-------------- 8 x -------------> 11329 ; 11330 ; ACKNOWLEDGE 11331 ; 11332 ; FRQ 11333 ; | 11334 ; $10 |-3- -3- -3- 11335 ; | 11336 ; $00 | -3- -3- -3- 11337 ; +------------------> TICKS 11338 ; <------ 1 x -----> 11339 ; 11340 ; DAMAGE REPORT (not to scale) 11341 ; 11342 ; FRQ 11343 ; | 11344 ; $40 |------------33------------- 11345 ; | 11346 ; $20 | ------------33------------- 11347 ; | 11348 ; +------------------------------------------------------> TICKS 11349 ; <------------------------ 3 x -----------------------> 11350 ; 11351 ; MESSAGE FROM STARBASE (not to scale) 11352 ; 11353 ; FRQ 11354 ; | 11355 ; $51 | -----33----- 11356 ; $48 |-----33----- 11357 ; $40 | -----33----- 11358 ; | 11359 ; $00 | --9-- --9-- --9-- 11360 ; +----------------------------------------------------> TICKS 11361 ; <---------------------- 1 x ----------------------> 11362 ; 11363 ; (0),(1),(2),(3),(4),(5) 11364 BEEPPATTAB .BYTE $02,$02,$02,$03,$0C,$02 ; HYPERWARP TRANSIT 11365 .BYTE $04,$03,$FF,$10,$07,$04 ; RED ALERT 11366 .BYTE $07,$04,$02,$02,$00,$07 ; ACKNOWLEDGE 11367 .BYTE $0B,$05,$FF,$20,$02,$0B ; DAMAGE REPORT 11368 .BYTE $0E,$06,$08,$20,$00,$0E ; MESSAGE FROM STARBASE 11369 11370 ;*** Beeper sound pattern frequency table ************************************** 11371 BEEPFRQTAB .BYTE $10,$FF ; (unused) (!) 11372 .BYTE $18,$FF ; HYPERWARP TRANSIT 11373 .BYTE $40,$60,$FF ; RED ALERT 11374 .BYTE $10,$10,$10,$FF ; ACKNOWLEDGE 11375 .BYTE $40,$20,$FF ; DAMAGE REPORT 11376 .BYTE $48,$40,$51,$FF ; MESSAGE FROM STARBASE 11377 11378 ;*** Shape of blip in Attack Computer Display ********************************** 11379 BLIPSHAPTAB .BYTE $84 ; #....#.. 11380 .BYTE $B4 ; #.##.#.. 11381 .BYTE $FC ; ######.. 11382 .BYTE $B4 ; #.##.#.. 11383 .BYTE $84 ; #....#.. 11384 11385 ;*** Initial x-coordinate (high byte) of our starship's photon torpedo ********* 11386 BARRELXTAB .BYTE $FF ; Left barrel = -256 (-$FF00) 11387 .BYTE $01 ; Right barrel = +256 (+$0100) 11388 11389 ;*** Maximum photon torpedo hit z-coordinate (high byte) *********************** 11390 HITMAXZTAB .BYTE $0C ; < 3328 ($0C**) 11391 .BYTE $0C ; < 3328 ($0C**) 11392 .BYTE $0C ; < 3328 ($0C**) 11393 .BYTE $0C ; < 3328 ($0C**) 11394 .BYTE $0E ; < 3840 ($0E**) 11395 .BYTE $0E ; < 3840 ($0E**) 11396 .BYTE $0E ; < 3840 ($0E**) 11397 .BYTE $20 ; < 8448 ($20**) 11398 11399 ;*** Minimum photon torpedo hit z-coordinate (high byte) *********************** 11400 HITMINZTAB .BYTE $00 ; >= 0 ($00**) 11401 .BYTE $00 ; >= 0 ($00**) 11402 .BYTE $00 ; >= 0 ($00**) 11403 .BYTE $02 ; >= 512 ($02**) 11404 .BYTE $04 ; >= 1024 ($04**) 11405 .BYTE $06 ; >= 1536 ($06**) 11406 .BYTE $08 ; >= 2048 ($08**) 11407 .BYTE $0C ; >= 3072 ($0C**) 11408 11409 ;*** Velocity of homing Zylon photon torpedo *********************************** 11410 ZYLONHOMVELTAB .BYTE NEG!1 ; -1 NOVICE mission 11411 .BYTE NEG!4 ; -4 PILOT mission 11412 .BYTE NEG!8 ; -8 WARRIOR mission 11413 .BYTE NEG!20 ; -20 COMMANDER mission 11414 11415 ;*** Zylon shape type table **************************************************** 11416 ZYLONSHAPTAB .BYTE SHAP.ZBASESTAR ; ZYLON BASESTAR 11417 .BYTE SHAP.ZFIGHTER ; ZYLON FIGHTER 11418 .BYTE SHAP.ZFIGHTER ; ZYLON FIGHTER 11419 .BYTE SHAP.ZFIGHTER ; ZYLON FIGHTER 11420 .BYTE SHAP.ZCRUISER ; ZYLON CRUISER 11421 .BYTE SHAP.ZCRUISER ; ZYLON CRUISER 11422 .BYTE SHAP.ZCRUISER ; ZYLON CRUISER 11423 .BYTE SHAP.ZFIGHTER ; ZYLON FIGHTER 11424 11425 ;*** Zylon flight pattern table ************************************************ 11426 ZYLONFLPATTAB .BYTE 4 ; Flight pattern 4 11427 .BYTE 4 ; Flight pattern 4 11428 .BYTE 0 ; Attack Flight Pattern 0 11429 .BYTE 0 ; Attack Flight Pattern 0 11430 .BYTE 0 ; Attack Flight Pattern 0 11431 .BYTE 1 ; Flight pattern 1 11432 .BYTE 0 ; Attack Flight Pattern 0 11433 .BYTE 0 ; Attack Flight Pattern 0 11434 11435 ;*** Zylon velocity table ****************************************************** 11436 ZYLONVELTAB .BYTE 62 ; +62 11437 .BYTE 30 ; +30 11438 .BYTE 16 ; +16 11439 .BYTE 8 ; +8 11440 .BYTE 4 ; +4 11441 .BYTE 2 ; +2 11442 .BYTE 1 ; +1 11443 .BYTE 0 ; 0 11444 .BYTE 0 ; 0 11445 .BYTE NEG!1 ; -1 11446 .BYTE NEG!2 ; -2 11447 .BYTE NEG!4 ; -4 11448 .BYTE NEG!8 ; -8 11449 .BYTE NEG!16 ; -16 11450 .BYTE NEG!30 ; -30 11451 .BYTE NEG!62 ; -62 11452 11453 ;*** PLAYFIELD colors (including PLAYFIELD colors during DLI) ****************** 11454 PFCOLORTAB .BYTE $A6 ; PF0COLOR = {GREEN} 11455 .BYTE $AA ; PF1COLOR = {LIGHT GREEN} 11456 .BYTE $AF ; PF2COLOR = {VERY LIGHT GREEN} 11457 .BYTE $00 ; PF3COLOR = {BLACK} 11458 .BYTE $00 ; BGRCOLOR = {BLACK} 11459 .BYTE $B8 ; PF0COLORDLI = {LIGHT MINT} 11460 .BYTE $5A ; PF1COLORDLI = {MEDIUM PINK} 11461 .BYTE $FC ; PF2COLORDLI = {LIGHT ORANGE} 11462 .BYTE $5E ; PF3COLORDLI = {LIGHT PINK} 11463 .BYTE $90 ; BGRCOLORDLI = {DARK BLUE} 11464 11465 ;*** Vicinity mask table. Confines coordinates of space objects in sector ****** 11466 VICINITYMASKTAB .BYTE $FF ; <= 65535 ($FF**) 11467 .BYTE $FF ; <= 65535 ($FF**) 11468 .BYTE $3F ; <= 16383 ($3F**) 11469 .BYTE $0F ; <= 4095 ($0F**) 11470 .BYTE $3F ; <= 16383 ($3F**) 11471 .BYTE $7F ; <= 32767 ($7F**) 11472 .BYTE $FF ; <= 65535 ($FF**) 11473 .BYTE $FF ; <= 65535 ($FF**) 11474 11475 ;*** Movement probability of sector types in Galactic Chart ******************** 11476 MOVEPROBTAB .BYTE 0 ; Empty sector 0% ( 0:256) 11477 .BYTE 255 ; 1 Zylon ship 100% (255:256) 11478 .BYTE 255 ; 2 Zylon ships 100% (255:256) 11479 .BYTE 192 ; 3 Zylon ships 75% (192:256) 11480 .BYTE 32 ; 4 Zylon ships 13% ( 32:256) 11481 11482 ;*** Galactic Chart sector offset to adjacent sector *************************** 11483 COMPASSOFFTAB .BYTE -16 ; NORTH 11484 .BYTE -17 ; NORTHWEST 11485 .BYTE -1 ; WEST 11486 .BYTE 15 ; SOUTHWEST 11487 .BYTE 16 ; SOUTH 11488 .BYTE 17 ; SOUTHEAST 11489 .BYTE 1 ; EAST 11490 .BYTE -15 ; NORTHEAST 11491 .BYTE 0 ; CENTER 11492 11493 ;*** Homing velocities of photon torpedoes 0..1 depending on distance to target 11494 HOMVELTAB .BYTE 0 ; +0 11495 .BYTE 8 ; +8 11496 .BYTE 16 ; +16 11497 .BYTE 24 ; +24 11498 .BYTE 40 ; +40 11499 .BYTE 48 ; +48 11500 .BYTE 56 ; +56 11501 .BYTE 64 ; +64 11502 11503 ;*** PLAYER shape color table (bits B7..4 of color/brightness) ***************** 11504 PLSHAPCOLORTAB .BYTE $50 ; PHOTON TORPEDO = {PURPLE} 11505 .BYTE $00 ; ZYLON FIGHTER = {GRAY} 11506 .BYTE $20 ; STARBASE RIGHT = {ORANGE} 11507 .BYTE $20 ; STARBASE CENTER = {ORANGE} 11508 .BYTE $20 ; STARBASE LEFT = {ORANGE} 11509 .BYTE $00 ; TRANSFER VESSEL = {GRAY} 11510 .BYTE $A0 ; METEOR = {GREEN} 11511 .BYTE $00 ; ZYLON CRUISER = {GRAY} 11512 .BYTE $00 ; ZYLON BASESTAR = {GRAY} 11513 .BYTE $9F ; HYPERWARP TARGET MARKER = {SKY BLUE} 11514 11515 ;*** PLAYER shape brightness table (bits B3..0 of color/brightness) ************ 11516 PLSHAPBRITTAB .BYTE $0E ; ##############.. 11517 .BYTE $0E ; ##############.. 11518 .BYTE $0E ; ##############.. 11519 .BYTE $0C ; ############.... 11520 .BYTE $0C ; ############.... 11521 .BYTE $0C ; ############.... 11522 .BYTE $0A ; ##########...... 11523 .BYTE $0A ; ##########...... 11524 .BYTE $0A ; ##########...... 11525 .BYTE $08 ; ########........ 11526 .BYTE $08 ; ########........ 11527 .BYTE $08 ; ########........ 11528 .BYTE $06 ; ######.......... 11529 .BYTE $06 ; ######.......... 11530 .BYTE $04 ; ####............ 11531 .BYTE $04 ; ####............ 11532 11533 ;*** PHOTON TORPEDO LAUNCHED noise bit and volume (stored in reverse order) **** 11534 NOISETORPVOLTAB .BYTE $8A ; ##########..... 11535 .BYTE $8F ; ############### 11536 .BYTE $8D ; #############.. 11537 .BYTE $8B ; ###########.... 11538 .BYTE $89 ; #########...... 11539 .BYTE $87 ; #######........ 11540 .BYTE $85 ; ######......... 11541 .BYTE $83 ; ###............ 11542 11543 ;*** PHOTON TORPEDO LAUNCHED noise frequency table (stored in reverse order) *** 11544 NOISETORPFRQTAB .BYTE $00 ; 11545 .BYTE $04 ; 11546 .BYTE $01 ; 11547 .BYTE $04 ; 11548 .BYTE $01 ; 11549 .BYTE $04 ; 11550 .BYTE $01 ; 11551 .BYTE $04 ; 11552 11553 .BYTE $07 ; (unused) 11554 11555 .BYTE $00 ; Always 0 for cartridges 11556 .BYTE $80 ; On SYSTEM RESET jump to INITCOLD via 11557 .WORD INITCOLD ; Cartridge Initialization Address