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 ;* 15-MAR-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 program uses a 3D coordinate system with the position of our starship at 00212 ; its center 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 program 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 program 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 program is in game or 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 program 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)) 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)) 00526 ; 00527 ; $7A OLDMAXSPCOBJIND 00528 ; 00529 ; Maximum index of used space objects in the previous game loop 00530 ; iteration. Frequently used values are: 00531 ; $10 -> During regular cruise (5 PLAYER space objects + 12 PLAYFIELD 00532 ; space objects (stars)) 00533 ; $30 -> During explosion or hyperwarp (5 PLAYER space objects + 12 00534 ; PLAYFIELD space objects (stars) + 32 PLAYFIELD space objects 00535 ; (explosion fragments or stars of star trails)) 00536 ; 00537 ; $7B ISSTARBASESECT 00538 ; 00539 ; Indicates whether a starbase is in this sector. Used values are: 00540 ; $00 -> Sector contains no starbase 00541 ; $FF -> Sector contains starbase 00542 ; 00543 ; $7C ISTRACKCOMPON 00544 ; 00545 ; Indicates whether the Tracking Computer is on or off. Used values 00546 ; are: 00547 ; $00 -> Tracking Computer is off 00548 ; $FF -> Tracking Computer is on 00549 ; 00550 ; $7D DRAINSHIELDS 00551 ; 00552 ; Energy drain rate of the Shields per game loop iteration in energy 00553 ; subunits. See also subroutine UPDPANEL ($B804). Used values are: 00554 ; $00 -> Shields are off 00555 ; $08 -> Shields are on 00556 ; 00557 ; $7E DRAINATTCOMP 00558 ; 00559 ; Energy drain rate of the Attack Computer per game loop iteration in 00560 ; energy subunits. See also subroutine UPDPANEL ($B804). Used values 00561 ; are: 00562 ; $00 -> Attack Computer off 00563 ; $02 -> Attack Computer on 00564 ; 00565 ; $7F ENERGYCNT 00566 ; 00567 ; Running counter of consumed energy subunits (256 energy subunits = 1 00568 ; energy unit displayed by the 4-digit ENERGY readout of the Control 00569 ; Panel Display). Forms an invisible fractional or "decimals" part of 00570 ; the 4-digit ENERGY readout of the Control Panel Display. See also 00571 ; subroutine UPDPANEL ($B804). 00572 ; 00573 ; $80 DRAINENGINES 00574 ; 00575 ; Energy drain rate of our starship's Engines per game loop iteration 00576 ; in energy subunits (256 energy subunits = 1 energy unit displayed by 00577 ; the 4-digit ENERGY readout of the Control Panel Display). Values are 00578 ; picked from table DRAINRATETAB ($BAD3). See also subroutine UPDPANEL 00579 ; ($B804). 00580 ; 00581 ; $81 SHIELDSCOLOR 00582 ; 00583 ; Shields color. Used values are: 00584 ; $00 -> {BLACK} (Shields are off) 00585 ; $A0 -> {DARK GREEN} (Shields are on) 00586 ; 00587 ; $82 PL3HIT 00588 ; 00589 ; Collision register of PLAYER3 (usually our starship's photon torpedo 00590 ; 0) with other PLAYERs. Used values are: 00591 ; $00 -> No collision 00592 ; > $00 -> PLAYER3 has collided with another PLAYER space object. See 00593 ; subroutine COLLISION ($AF3D) for details which PLAYER has 00594 ; been hit by PLAYER3. 00595 ; 00596 ; $83 PL4HIT 00597 ; 00598 ; Collision register of PLAYER4 (usually our starship's photon torpedo 00599 ; 1) with other PLAYERs. Used values are: 00600 ; $00 -> No collision 00601 ; > $00 -> PLAYER4 has collided with another PLAYER space object. See 00602 ; subroutine COLLISION ($AF3D) for details which PLAYER has 00603 ; been hit by PLAYER4. 00604 ; 00605 ; $84 OLDTRIG0 00606 ; 00607 ; Joystick trigger state. Used values are: 00608 ; $00 -> Joystick trigger was pressed 00609 ; $01 -> Joystick trigger was not pressed 00610 ; $AA -> Joystick trigger was "virtually" pressed (will launch 00611 ; another of our starship's photon torpedoes, see subroutine 00612 ; TRIGGER ($AE29). 00613 ; 00614 ; $86 ISTRACKING 00615 ; 00616 ; Indicates whether one of our starship's photon torpedoes is currently 00617 ; tracking (homing in on) the target space object. Used values are: 00618 ; $00 -> No target space object tracked. Our starship's photon 00619 ; torpedoes will fly just straight ahead. 00620 ; > $00 -> Tracking a target space object. Our starship's photon 00621 ; torpedoes will home in on the tracked space object. 00622 ; 00623 ; $87 BARRELNR 00624 ; 00625 ; Barrel from which our starship's next photon torpedo will be 00626 ; launched. Used values are: 00627 ; $00 -> Left barrel 00628 ; $01 -> Right barrel 00629 ; 00630 ; $88 LOCKONLIFE 00631 ; 00632 ; Lifetime of target lock-on. A target remains in lock-on while 00633 ; LOCKONLIFE ($88) counts down from 12 to 0. It is decremented every 00634 ; game loop iteration. 00635 ; 00636 ; $89 PLTRACKED 00637 ; 00638 ; Index of currently tracked PLAYER. It is copied in subroutine TRIGGER 00639 ; ($AE29) from TRACKDIGIT ($095C). Used values are: 00640 ; $00 -> Track Zylon ship 0 00641 ; $01 -> Track Zylon ship 1 00642 ; $02 -> Track starbase during docking operations 00643 ; $03 -> Track Hyperwarp Target Marker during hyperwarp 00644 ; 00645 ; $8A HITBADNESS 00646 ; 00647 ; Severeness of a Zylon photon torpedo hit. Used values are: 00648 ; $00 -> NO HIT 00649 ; $7F -> SHIELDS HIT 00650 ; $FF -> STARSHIP DESTROYED 00651 ; 00652 ; $8B REDALERTLIFE 00653 ; 00654 ; Lifetime of red alert. It decreases from 255 to 0. It is decremented 00655 ; every game loop iteration. 00656 ; 00657 ; $8C WARPDEPRROW 00658 ; 00659 ; Departure hyperwarp marker row number on the Galactic Chart. It is 00660 ; given in Player/Missile pixels relative to the top Galactic Chart 00661 ; border. It is initialized to a value of $47 (vertical center of 00662 ; Galactic Chart). Divide this value by 16 to get the departure sector 00663 ; row number. Used values are: $00..$7F. 00664 ; 00665 ; $8D WARPDEPRCOLUMN 00666 ; 00667 ; Departure hyperwarp marker column number on the Galactic Chart. It is 00668 ; given in Player/Missile pixels relative to the left Galactic Chart 00669 ; border and initialized to a value of $43 (horizontal center of 00670 ; Galactic Chart). Divide this value by 8 to get the departure sector 00671 ; column number. Used values are: $00..$7F. 00672 ; 00673 ; $8E WARPARRVROW 00674 ; 00675 ; Arrival hyperwarp marker row number on the Galactic Chart in 00676 ; Player/Missile pixels relative to top Galactic Chart border. It is 00677 ; initialized to a value of $47 (vertical center of Galactic Chart). 00678 ; Divide this value by 16 to get the arrival sector row number. Used 00679 ; values are: $00..$7F. 00680 ; 00681 ; $8F WARPARRVCOLUMN 00682 ; 00683 ; Arrival hyperwarp marker column number on the Galactic Chart in 00684 ; Player/Missile pixels relative to left Galactic Chart border. It is 00685 ; initialized to a value of $43 (horizontal center of Galactic Chart). 00686 ; Divide this value by 8 to get the arrival sector column number. Used 00687 ; values are: $00..$7F. 00688 ; 00689 ; $90 CURRSECTOR 00690 ; 00691 ; Galactic Chart sector of the current location of our starship. At the 00692 ; start of the game it is initialized to a value of $48. Used values 00693 ; are: $00..$7F with, for example, 00694 ; $00 -> NORTHWEST corner sector 00695 ; $0F -> NORTHEAST corner sector 00696 ; $70 -> SOUTHWEST corner sector 00697 ; $7F -> SOUTHWEST corner sector 00698 ; 00699 ; See also ARRVSECTOR ($92). 00700 ; 00701 ; $91 WARPENERGY 00702 ; 00703 ; Energy required to hyperwarp between the departure and arrival 00704 ; hyperwarp marker locations on the Galactic Chart divided by 10. 00705 ; Values are picked from table WARPENERGYTAB ($BADD). Multiply this 00706 ; value by 10 to get the actual value in energy units displayed by the 00707 ; Galactic Chart Panel Display. 00708 ; 00709 ; $92 ARRVSECTOR 00710 ; 00711 ; Galactic Chart arrival sector of our starship after hyperwarp. Used 00712 ; values are: $00..$7F with, for example, 00713 ; $00 -> NORTHWEST corner sector 00714 ; $0F -> NORTHEAST corner sector 00715 ; $70 -> SOUTHWEST corner sector 00716 ; $7F -> SOUTHWEST corner sector 00717 ; 00718 ; See also CURRSECTOR ($90). 00719 ; 00720 ; $93 HUNTSECTOR 00721 ; 00722 ; Galactic Chart sector of the starbase toward which the Zylon units 00723 ; are currently moving. Used values are: $00..$7F with, for example, 00724 ; $00 -> NORTHWEST corner sector 00725 ; $0F -> NORTHEAST corner sector 00726 ; $70 -> SOUTHWEST corner sector 00727 ; $7F -> SOUTHWEST corner sector 00728 ; 00729 ; $94 HUNTSECTCOLUMN 00730 ; 00731 ; Galactic Chart sector column number of the starbase toward which the 00732 ; Zylon units are currently moving. Used values are: 0..15. 00733 ; 00734 ; $95 HUNTSECTROW 00735 ; 00736 ; Galactic Chart sector row number of the starbase toward which the 00737 ; Zylon units are currently moving. Used values are: 0..7. 00738 ; 00739 ; $96..$9E NEWZYLONDIST 00740 ; 00741 ; Table of distances between a Zylon unit and the hunted starbase when 00742 ; the Zylon unit is tentatively moved in one of the 9 possible 00743 ; directions NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST, EAST, 00744 ; NORTHEAST, CENTER. Used to decide into which sector the Zylon unit 00745 ; should move. 00746 ; 00747 ; $9E OLDZYLONDIST 00748 ; 00749 ; Current distance between the Zylon unit and the hunted starbase. 00750 ; 00751 ; $9F HUNTTIM 00752 ; 00753 ; Delay timer for Zylon units to decide on which starbase to hunt. It 00754 ; counts down from 7. It is decremented every game loop iteration. When 00755 ; the timer falls below 0 the Zylon units re-decide toward which 00756 ; starbase to move. 00757 ; 00758 ; $A0 BLIPCOLUMN 00759 ; 00760 ; Top-left screen pixel column number of blip shape displayed in the 00761 ; Attack Computer Display. Used in subroutine UPDATTCOMP ($A7BF). Used 00762 ; values are: 120..142. 00763 ; 00764 ; $A1 BLIPROW 00765 ; 00766 ; Top-left screen pixel row number of blip shape displayed in the 00767 ; Attack Computer Display. Used in subroutine UPDATTCOMP ($A7BF). Used 00768 ; values are: 71..81. 00769 ; 00770 ; $A2 BLIPCYCLECNT 00771 ; 00772 ; Blip cycle counter. It controls drawing the blip shape in the Attack 00773 ; Computer Display. Its value is incremented every game loop iteration. 00774 ; Used in subroutine UPDATTCOMP ($A7BF). Used values are: 00775 ; $00..$04 -> Draw 0..4th row of blip shape 00776 ; $05..$09 -> Do not draw blip shape (delay) 00777 ; $0A -> Recalculate blip shape position, erase Attack Computer 00778 ; Display 00779 ; 00780 ; $A3 ISINLOCKON 00781 ; 00782 ; Indicates whether the tracked space object is currently in full 00783 ; lock-on (horizontally and vertically centered as well as in range) in 00784 ; the Attack Computer Display. If so, all lock-on markers show up on 00785 ; the Attack Computer Display and our starship's launched photon 00786 ; torpedoes will home in on the tracked space object. Used values are: 00787 ; $00 -> Not in lock-on 00788 ; $A0 -> In lock-on 00789 ; 00790 ; $A4 DIRLEN 00791 ; 00792 ; Used to pass the direction and length of a single line to be drawn in 00793 ; the PLAYFIELD. Used in subroutines DRAWLINES ($A76F), DRAWLINE 00794 ; ($A782), and UPDATTCOMP ($A7BF). Used values are: 00795 ; Bit B7 = 0 -> Draw right 00796 ; Bit B7 = 1 -> Draw down 00797 ; Bits B6..0 -> Length of line in pixels. 00798 ; 00799 ; See also PENROW ($A5) and PENCOLUMN ($A6). 00800 ; 00801 ; $A5 PENROW 00802 ; 00803 ; Used to pass the start screen pixel row number of the line to be 00804 ; drawn in the PLAYFIELD. Used in subroutines DRAWLINES ($A76F), 00805 ; DRAWLINE ($A782), and UPDATTCOMP ($A7BF). 00806 ; 00807 ; $A6 PENCOLUMN 00808 ; 00809 ; Used to pass the start screen pixel column number of the line to be 00810 ; drawn in the PLAYFIELD. Used in subroutines DRAWLINES ($A76F), 00811 ; DRAWLINE ($A782), and UPDATTCOMP ($A7BF). 00812 ; 00813 ; $A7 CTRLDZYLON 00814 ; 00815 ; Index of Zylon ship currently controlled by the program. Used in 00816 ; subroutine MANEUVER ($AA79). The value is toggled every other game 00817 ; loop iteration. Used values are: 00818 ; $00 -> Control Zylon ship 0. 00819 ; $01 -> Control Zylon ship 1. 00820 ; 00821 ; $A8 ZYLONFLPAT0 00822 ; 00823 ; Flight pattern of Zylon ship 0. Used in subroutine MANEUVER ($AA79). 00824 ; Used values are: 00825 ; $00 -> Attack flight pattern "0" 00826 ; $01 -> Flight pattern "1" 00827 ; $04 -> Flight pattern "4" 00828 ; 00829 ; $A9 ZYLONFLPAT1 00830 ; 00831 ; Flight pattern of Zylon ship 1. Compare ZYLONFLPAT0 ($A8). 00832 ; 00833 ; $AA MILESTTIM0 00834 ; 00835 ; Delay timer of the milestone velocity indices of Zylon ship 0. Used 00836 ; in subroutine MANEUVER ($AA79). 00837 ; 00838 ; When Zylon ship 0 is active, this value is decremented every game 00839 ; loop iteration. If it falls below 0 then the milestone velocity 00840 ; indices of Zylon ship 0 are recalculated. When Zylon ship 0 is 00841 ; controlled by the computer for the first time, the timer is set to an 00842 ; initial value of 1, later to an initial value of 120. 00843 ; 00844 ; $AB MILESTTIM1 00845 ; 00846 ; Delay timer of the milestone velocity index vector of Zylon ship 1. 00847 ; Compare MILESTTIM0 ($AA). 00848 ; 00849 ; $AC MILESTVELINDZ0 00850 ; 00851 ; Milestone z-velocity index of Zylon ship 0. Used in subroutine 00852 ; MANEUVER ($AA79). The current z-velocity index of Zylon ship 0 00853 ; ZYLONVELINDZ0 ($B2) is compared with this index and gradually 00854 ; adjusted to it. Used values are: 0..15. 00855 ; 00856 ; $AD MILESTVELINDZ1 00857 ; 00858 ; Milestone z-velocity index of Zylon ship 1. Compare MILESTVELINDZ0 00859 ; ($AC). 00860 ; 00861 ; $AE MILESTVELINDX0 00862 ; 00863 ; Milestone x-velocity index of Zylon ship 0. Used in subroutine 00864 ; MANEUVER ($AA79). The current x-velocity index of Zylon ship 0 00865 ; ZYLONVELINDX0 ($B4) is compared with this index and gradually 00866 ; adjusted to it. Used values are: 0..15. 00867 ; 00868 ; $AF MILESTVELINDX1 00869 ; 00870 ; Milestone x-velocity index of Zylon ship 1. Compare MILESTVELINDX0 00871 ; ($AE). 00872 ; 00873 ; $B0 MILESTVELINDY0 00874 ; 00875 ; Milestone y-velocity index of Zylon ship 0. Used in subroutine 00876 ; MANEUVER ($AA79). The current y-velocity index of Zylon ship 0 00877 ; ZYLONVELINDY0 ($B6) is compared with this index and gradually 00878 ; adjusted to it. Used values are: 0..15. 00879 ; 00880 ; $B1 MILESTVELINDY1 00881 ; 00882 ; Milestone y-velocity index of Zylon ship 1. Compare MILESTVELINDY0 00883 ; ($B0). 00884 ; 00885 ; $B2 ZYLONVELINDZ0 00886 ; 00887 ; Current z-velocity index of Zylon ship 0. Used in subroutine MANEUVER 00888 ; ($AA79). It indexes velocity values in ZYLONVELTAB ($BF99). Used 00889 ; values are: 0..15. 00890 ; 00891 ; $B3 ZYLONVELINDZ1 00892 ; 00893 ; Current z-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0 00894 ; ($B2). 00895 ; 00896 ; $B4 ZYLONVELINDX0 00897 ; 00898 ; Current x-velocity index of Zylon ship 0. Compare ZYLONVELINDZ0 00899 ; ($B2). 00900 ; 00901 ; $B5 ZYLONVELINDX1 00902 ; 00903 ; Current x-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0 00904 ; ($B2). 00905 ; 00906 ; $B6 ZYLONVELINDY0 00907 ; 00908 ; Current y-velocity index of Zylon ship 0. Compare ZYLONVELINDZ0 00909 ; ($B2). 00910 ; 00911 ; $B7 ZYLONVELINDY1 00912 ; 00913 ; Current y-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0 00914 ; ($B2). 00915 ; 00916 ; $B8 ISBACKATTACK0 00917 ; 00918 ; Indicates whether Zylon ship 0 will attack our starship from the 00919 ; back. Used in subroutine MANEUVER ($AA79). Used values are: 00920 ; $00 -> Zylon ship 0 attacks from the front of our starship 00921 ; $01 -> Zylon ship 0 attacks from the front and back of our starship 00922 ; 00923 ; $B9 ISBACKATTACK1 00924 ; 00925 ; Indicates whether Zylon ship 1 will attack our starship from the 00926 ; back. Compare ISBACKATTACK0 ($B8). 00927 ; 00928 ; $BA ZYLONTIMX0 00929 ; 00930 ; Delay timer of the x-velocity index of Zylon ship 0. Used in 00931 ; subroutine MANEUVER ($AA79). It is decremented every game loop 00932 ; iteration. When the timer value falls below 0 the current velocity 00933 ; index ZYLONVELINDX0 ($B4) is adjusted depending on the current 00934 ; joystick position. The new timer value is set depending on the 00935 ; resulting new x-velocity index. Used values are: 0, 2, 4, ..., 14. 00936 ; 00937 ; $BB ZYLONTIMX1 00938 ; 00939 ; Delay timer of x-velocity index of Zylon ship 1. Compare ZYLONTIMX0 00940 ; ($BA). 00941 ; 00942 ; $BC ZYLONTIMY0 00943 ; 00944 ; Delay timer of y-velocity index of Zylon ship 0. Compare ZYLONTIMX0 00945 ; ($BA). 00946 ; 00947 ; $BD ZYLONTIMY1 00948 ; 00949 ; Delay timer of y-velocity index of Zylon ship 1. Compare ZYLONTIMX0 00950 ; ($BA). 00951 ; 00952 ; $BE TORPEDODELAY 00953 ; 00954 ; After a Zylon photon torpedo has hit our starship this delay timer is 00955 ; initialized to a value of 2. It is decremented every game loop 00956 ; iteration and so delays the launch of the next Zylon photon torpedo 00957 ; for 2 game loop iterations. 00958 ; 00959 ; $BF ZYLONATTACKER 00960 ; 00961 ; Index of the Zylon ship that launched the Zylon photon torpedo. It is 00962 ; used in GAMELOOP ($A1F3) to override the current tracking computer 00963 ; settings in order to track this Zylon ship first. Used values are: 00964 ; $00 -> Zylon photon torpedo was launched by Zylon ship 0 00965 ; $01 -> Zylon photon torpedo was launched by Zylon ship 1 00966 ; 00967 ; $C0 WARPSTATE 00968 ; 00969 ; Hyperwarp state. Used values are: 00970 ; $00 -> Hyperwarp not engaged 00971 ; $7F -> Hyperwarp engaged 00972 ; $FF -> In hyperspace 00973 ; 00974 ; $C1 VELOCITYHI 00975 ; 00976 ; Our starship's velocity (high byte) in . Used values are: 00977 ; $00 -> Not in hyperspace (regular cruise or accelerating to 00978 ; hyperspace velocity) 00979 ; $01 -> Hyperspace velocity 00980 ; 00981 ; See also VELOCITYLO ($70). 00982 ; 00983 ; $C2 TRAILDELAY 00984 ; 00985 ; Delay timer to create the next star trail. Its value is decremented 00986 ; from 3 to 0 every game loop iteration during the hyperwarp STAR TRAIL 00987 ; PHASE in subroutine INITTRAIL ($A9B4). 00988 ; 00989 ; $C3 TRAILIND 00990 ; 00991 ; Position vector index of the star trail's first star. Used in 00992 ; subroutine INITTRAIL ($A9B4) to initialize a star trail, which is 00993 ; then displayed during the hyperwarp STAR TRAIL PHASE. Used values 00994 ; are: 17..48 in wrap-around fashion. 00995 ; 00996 ; $C4 WARPTEMPCOLUMN 00997 ; 00998 ; Temporary arrival column number of our starship on the Galactic Chart 00999 ; at the begin of hyperspace. It is given in Player/Missile pixels 01000 ; relative to the left Galactic Chart border. Divide this value by 8 to 01001 ; get the sector column number. Used values are: $00..$7F. See also 01002 ; WARPARRVCOLUMN ($8F). 01003 ; 01004 ; $C5 WARPTEMPROW 01005 ; 01006 ; Temporary arrival row number of our starship on the Galactic Chart at 01007 ; the begin of hyperspace. It is given in Player/Missile pixels 01008 ; relative to top Galactic Chart border. Divide this value by 16 to get 01009 ; the sector row number. Used values are: $00..$7F. See also 01010 ; WARPARRVROW ($8E). 01011 ; 01012 ; $C6 VEERMASK 01013 ; 01014 ; Limits the veer-off velocity of the Hyperwarp Target Marker during 01015 ; the hyperwarp ACCELERATION PHASE in subroutine HYPERWARP ($A89B). 01016 ; Values are picked from table VEERMASKTAB ($BED7). 01017 ; 01018 ; Also used as a local variable. 01019 ; 01020 ; $C7 VICINITYMASK 01021 ; 01022 ; Mask to confine space objects' position vector components 01023 ; (coordinates) in a sector into a certain interval around our starship 01024 ; after its arrival from hyperspace. Values are picked from table 01025 ; VICINITYMASKTAB ($BFB3). 01026 ; 01027 ; $C8 JOYSTICKX 01028 ; 01029 ; Horizontal joystick direction. Values are picked from table 01030 ; STICKINCTAB ($BAF5). Used values are: 01031 ; $01 -> Right 01032 ; $00 -> Centered 01033 ; $FF -> Left 01034 ; 01035 ; $C9 JOYSTICKY 01036 ; 01037 ; Vertical joystick direction. Values are picked from table STICKINCTAB 01038 ; ($BAF5). Used values are: 01039 ; $01 -> Up 01040 ; $00 -> Centered 01041 ; $FF -> Down 01042 ; 01043 ; $CA KEYCODE 01044 ; 01045 ; Hardware keyboard code of the pressed key on the keyboard. Shift and 01046 ; Control key bits B7..6 are always set. 01047 ; 01048 ; $CB..$CC SCORE 01049 ; 01050 ; Internal 16-bit score of the game in low byte-high byte order 01051 ; 01052 ; $CD SCOREDRANKIND 01053 ; 01054 ; Scored Rank Index. It is translated with table RANKTAB ($BEE9) to a 01055 ; title phrase offset pointing to the rank string. Used values are: 01056 ; $00 -> GALACTIC COOK 01057 ; $01 -> GARBAGE SCOW CAPTAIN 01058 ; $02 -> GARBAGE SCOW CAPTAIN 01059 ; $03 -> ROOKIE 01060 ; $04 -> ROOKIE 01061 ; $05 -> NOVICE 01062 ; $06 -> NOVICE 01063 ; $07 -> ENSIGN 01064 ; $08 -> ENSIGN 01065 ; $09 -> PILOT 01066 ; $0A -> PILOT 01067 ; $0B -> ACE 01068 ; $0C -> LIEUTENANT 01069 ; $0D -> WARRIOR 01070 ; $0E -> CAPTAIN 01071 ; $0F -> COMMANDER 01072 ; $10 -> COMMANDER 01073 ; $11 -> STAR COMMANDER 01074 ; $12 -> STAR COMMANDER 01075 ; 01076 ; $CE SCOREDCLASSIND 01077 ; 01078 ; Scored Class Index. It is translated into a class number with table 01079 ; CLASSTAB ($BEFC). Used values are: 01080 ; $00 -> Class 5 01081 ; $01 -> Class 5 01082 ; $02 -> Class 5 01083 ; $03 -> Class 4 01084 ; $04 -> Class 4 01085 ; $05 -> Class 4 01086 ; $06 -> Class 4 01087 ; $07 -> Class 3 01088 ; $08 -> Class 3 01089 ; $09 -> Class 3 01090 ; $0A -> Class 2 01091 ; $0B -> Class 2 01092 ; $0C -> Class 2 01093 ; $0D -> Class 1 01094 ; $0E -> Class 1 01095 ; $0F -> Class 1 01096 ; 01097 ; $CF TITLELIFE 01098 ; 01099 ; Lifetime of title line. It is decremented every game loop iteration. 01100 ; Used initial values are: 01101 ; $3C -> When displaying regular title phrases 01102 ; $FE -> When displaying "STARBASE SURROUNDED", "STARBASE DESTOYED", 01103 ; and "RED ALERT" messages 01104 ; $FF -> Hide title line 01105 ; 01106 ; $D0 SHIPVIEW 01107 ; 01108 ; Current view of our starship. Values are picked from table 01109 ; VIEWMODETAB ($BE22). Used values are: 01110 ; $00 -> Front view 01111 ; $01 -> Aft view 01112 ; $40 -> Long-Range Scan view 01113 ; $80 -> Galactic Chart view 01114 ; 01115 ; $D1 TITLEPHR 01116 ; 01117 ; Title phrase offset for text phrase in title line. Used values are: 01118 ; $00..$7B -> Title phrase offset into PHRASETAB ($BBAA) 01119 ; $FF -> Hide title line 01120 ; 01121 ; See also NEWTITLEPHR ($65). 01122 ; 01123 ; $D2 BEEPFRQIND 01124 ; 01125 ; Beeper sound pattern: Running index into frequency table BEEPFRQTAB 01126 ; ($BF5C). See also BEEPFRQSTART ($D7). See also subroutines BEEP 01127 ; ($B3A6) and SOUND ($B2AB). 01128 ; 01129 ; $D3 BEEPREPEAT 01130 ; 01131 ; Beeper sound pattern: Number of times the beeper sound pattern is 01132 ; repeated - 1. See also subroutines BEEP ($B3A6) and SOUND ($B2AB). 01133 ; 01134 ; $D4 BEEPTONELIFE 01135 ; 01136 ; Beeper sound pattern: Lifetime of tone in TICKs - 1. See also 01137 ; subroutines BEEP ($B3A6) and SOUND ($B2AB). 01138 ; 01139 ; $D5 BEEPPAUSELIFE 01140 ; 01141 ; Beeper sound pattern: Lifetime of pause in TICKs - 1. Used values 01142 ; are: 01143 ; < $FF -> Number of TICKs - 1 to play 01144 ; $FF -> Skip playing pause 01145 ; 01146 ; See also subroutines BEEP ($B3A6) and SOUND ($B2AB). 01147 ; 01148 ; $D6 BEEPPRIORITY 01149 ; 01150 ; Beeper sound pattern: Pattern priority. Each beeper sound pattern has 01151 ; a priority. When a pattern of higher priority is about to be played 01152 ; the pattern that is currently playing is stopped. Used values are: 01153 ; $00 -> No pattern playing at the moment 01154 ; > $00 -> Pattern priority 01155 ; 01156 ; See also subroutines BEEP ($B3A6) and SOUND ($B2AB). 01157 ; 01158 ; $D7 BEEPFRQSTART 01159 ; 01160 ; Beeper sound pattern: Index to first byte of the pattern frequency in 01161 ; table BEEPFRQTAB ($BF5C). See also BEEPFRQIND ($D2). See also 01162 ; subroutines BEEP ($B3A6) and SOUND ($B2AB). 01163 ; 01164 ; $D8 BEEPLIFE 01165 ; 01166 ; Beeper sound pattern: Lifetime of the current tone or pause in TICKs. 01167 ; It is decremented every TICK. See also subroutines BEEP ($B3A6) and 01168 ; SOUND ($B2AB). 01169 ; 01170 ; $D9 BEEPTOGGLE 01171 ; 01172 ; Beeper sound pattern: Indicates that either a tone or a pause is 01173 ; currently played. Used values are: 01174 ; $00 -> Tone 01175 ; $01 -> Pause 01176 ; 01177 ; See also subroutines BEEP ($B3A6) and SOUND ($B2AB). 01178 ; 01179 ; $DA NOISETORPTIM 01180 ; 01181 ; Noise sound pattern: Delay timer for PHOTON TORPEDO LAUNCHED noise 01182 ; sound pattern. It is decremented every TICK. See also subroutines 01183 ; NOISE ($AEA8) and SOUND ($B2AB). 01184 ; 01185 ; $DB NOISEEXPLTIM 01186 ; 01187 ; Noise sound pattern: Delay timer for SHIELD EXPLOSION and ZYLON 01188 ; EXPLOSION noise sound pattern. It is decremented every TICK. See also 01189 ; subroutines NOISE ($AEA8) and SOUND ($B2AB). 01190 ; 01191 ; $DC NOISEAUDC2 01192 ; 01193 ; Noise sound pattern: Audio channel 1/2 control shadow register. See 01194 ; also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01195 ; 01196 ; $DD NOISEAUDC3 01197 ; 01198 ; Noise sound pattern: Audio channel 3 control shadow register. See 01199 ; also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01200 ; 01201 ; $DE NOISEAUDF1 01202 ; 01203 ; Noise sound pattern: Audio channel 1 frequency shadow register. See 01204 ; also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01205 ; 01206 ; $DF NOISEAUDF2 01207 ; 01208 ; Noise sound pattern: Audio channel 2 frequency shadow register. See 01209 ; also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01210 ; 01211 ; $E0 NOISEFRQINC 01212 ; 01213 ; Noise sound pattern: Audio channel 1/2 frequency increment. See also 01214 ; subroutines NOISE ($AEA8) and SOUND ($B2AB). 01215 ; 01216 ; $E1 NOISELIFE 01217 ; 01218 ; Noise sound pattern: Noise sound pattern lifetime. It is decremented 01219 ; every TICK. See also subroutines NOISE ($AEA8) and SOUND ($B2AB). 01220 ; 01221 ; $E2 NOISEZYLONTIM 01222 ; 01223 ; Delay timer to trigger the ZYLON EXPLOSION noise sound pattern. It is 01224 ; set in subroutine COLLISION ($AF3D) when an impact of one of our 01225 ; starship's photon torpedoes into a target is imminent. The timer is 01226 ; decremented every TICK during the execution of the Vertical Blank 01227 ; Interrupt handler VBIHNDLR ($A6D1). When the timer value reaches 0 01228 ; the ZYLON EXPLOSION noise sound pattern is played in subroutine SOUND 01229 ; ($B2AB). 01230 ; 01231 ; $E3 NOISEHITLIFE 01232 ; 01233 ; Lifetime of STARSHIP EXPLOSION noise when our starship was destroyed 01234 ; by a Zylon photon torpedo. It is set in routine GAMELOOP ($A1F3) to a 01235 ; value of 64 TICKs. It is decremented every TICK during the execution 01236 ; of the Vertical Blank Interrupt handler VBIHNDLR ($A6D1). 01237 ; 01238 ; $E4 PL0SHAPOFF 01239 ; 01240 ; PLAYER0 offset into shape table PLSHAP2TAB ($B9B1) 01241 ; 01242 ; $E5 PL1SHAPOFF 01243 ; 01244 ; PLAYER1 offset into shape table PLSHAP2TAB ($B9B1) 01245 ; 01246 ; $E6 PL2SHAPOFF 01247 ; 01248 ; PLAYER2 offset into shape table PLSHAP1TAB ($B8E4) 01249 ; 01250 ; $E7 PL3SHAPOFF 01251 ; 01252 ; PLAYER3 offset into shape table PLSHAP1TAB ($B8E4) 01253 ; 01254 ; $E8 PL4SHAPOFF 01255 ; 01256 ; PLAYER4 offset into shape table PLSHAP1TAB ($B8E4) 01257 ; 01258 ; $E9 PL0LIFE 01259 ; 01260 ; Lifetime of the space object represented by PLAYER0 (usually Zylon 01261 ; ship 0). Any value other than $FF is decremented with every game loop 01262 ; iteration. Used values are: 01263 ; $00 -> Space object not alive (= not in use) 01264 ; $01..$FE -> Values during lifetime countdown 01265 ; $FF -> Infinite lifetime (not counted down) 01266 ; 01267 ; $EA PL1LIFE 01268 ; 01269 ; Lifetime of a space object represented by PLAYER1 (usually Zylon ship 01270 ; 1). Compare PL0LIFE ($E9). 01271 ; 01272 ; $EB PL2LIFE 01273 ; 01274 ; Lifetime of a space object represented by PLAYER2 (usually the Zylon 01275 ; photon torpedo). Compare PL0LIFE ($E9). 01276 ; 01277 ; If this PLAYER represents a photon torpedo, its lifetime is 01278 ; decremented from an initial value of $FF. 01279 ; 01280 ; $EC PL3LIFE 01281 ; 01282 ; Lifetime of a space object represented by PLAYER3 (usually our 01283 ; starship's photon torpedo 0). Compare PL2LIFE ($EB). 01284 ; 01285 ; If this PLAYER represents a photon torpedo, its lifetime is 01286 ; decremented from an initial value of $FF. 01287 ; 01288 ; $ED PL4LIFE 01289 ; 01290 ; Lifetime of a space object represented by PLAYER4 (usually our 01291 ; starship's photon torpedo 1). Compare PL2LIFE ($EB). 01292 ; 01293 ; If this PLAYER represents a photon torpedo, its lifetime is 01294 ; decremented from an initial value of $FF. 01295 ; 01296 ; $EE PL0COLOR 01297 ; 01298 ; Color of PLAYER0 01299 ; 01300 ; $EF PL1COLOR 01301 ; 01302 ; Color of PLAYER1 01303 ; 01304 ; $F0 PL2COLOR 01305 ; 01306 ; Color of PLAYER2 01307 ; 01308 ; $F1 PL3COLOR 01309 ; 01310 ; Color of PLAYER3 01311 ; 01312 ; $F2 PF0COLOR 01313 ; 01314 ; Color of PLAYFIELD0 01315 ; 01316 ; $F3 PF1COLOR 01317 ; 01318 ; Color of PLAYFIELD1 01319 ; 01320 ; $F4 PF2COLOR 01321 ; 01322 ; Color of PLAYFIELD2 01323 ; 01324 ; $F5 PF3COLOR 01325 ; 01326 ; Color of PLAYFIELD3 01327 ; 01328 ; $F6 BGRCOLOR 01329 ; 01330 ; Color of BACKGROUND 01331 ; 01332 ; $F7 PF0COLORDLI 01333 ; 01334 ; Color of PLAYFIELD0 after DLI 01335 ; 01336 ; $F8 PF1COLORDLI 01337 ; 01338 ; Color of PLAYFIELD1 after DLI 01339 ; 01340 ; $F9 PF2COLORDLI 01341 ; 01342 ; Color of PLAYFIELD2 after DLI 01343 ; 01344 ; $FA PF3COLORDLI 01345 ; 01346 ; Color of PLAYFIELD3 after DLI 01347 ; 01348 ; $FB BGRCOLORDLI 01349 ; 01350 ; Color of BACKGROUND after DLI 01351 ; 01352 ; $0280..$02E9 DSPLST 01353 ; 01354 ; Display List 01355 ; 01356 ; $0300..$03FF PL4DATA 01357 ; 01358 ; PLAYER4 data area 01359 ; 01360 ; $0400..$04FF PL0DATA 01361 ; 01362 ; PLAYER0 data area 01363 ; 01364 ; $0500..$05FF PL1DATA 01365 ; 01366 ; PLAYER1 data area 01367 ; 01368 ; $0600..$06FF PL2DATA 01369 ; 01370 ; PLAYER2 data area 01371 ; 01372 ; $0700..$07FF PL3DATA 01373 ; 01374 ; PLAYER3 data area 01375 ; 01376 ; $0800..$0863 PFMEMROWLO 01377 ; 01378 ; Lookup table of start addresses (low byte) for each row of 01379 ; PLAYFIELD memory, which is located at PFMEM ($1000). The table 01380 ; contains 100 bytes for 100 rows (of which only 99 are shown by 01381 ; the Display List, the PLAYFIELD is 160 x 99 pixels). The 01382 ; addresses grow in increments of 40 (40 bytes = 160 pixels in 01383 ; GRAPHICS7 mode = 1 PLAYFIELD row of pixels). See also PFMEMROWHI 01384 ; ($0864). 01385 ; 01386 ; $0864..$08C7 PFMEMROWHI 01387 ; 01388 ; Lookup table of start addresses (high byte) of each row of 01389 ; PLAYFIELD memory. See also PFMEMROWLO ($0800). 01390 ; 01391 ; $08C9..$0948 GCMEMMAP 01392 ; 01393 ; Galactic Chart memory map (16 columns x 8 rows = 128 bytes) 01394 ; 01395 ; $0949..$0970 PANELTXT 01396 ; 01397 ; Memory of Control Panel Display (bottom text window) in Front 01398 ; view, Aft view, and Long-Range Scan view (20 characters x 2 rows 01399 ; = 40 bytes). 01400 ; 01401 ; $094A VELOCD1 01402 ; 01403 ; First digit (of 2) of the VELOCITY readout in Control Panel 01404 ; Display memory. 01405 ; 01406 ; $0950 KILLCNTD1 01407 ; 01408 ; First digit (of 2) of the KILL COUNTER readout in Control Panel 01409 ; Display memory. 01410 ; 01411 ; $0955 ENERGYD1 01412 ; 01413 ; First digit (of 4) of the ENERGY readout in Control Panel Display 01414 ; memory. 01415 ; 01416 ; $095A TRACKC1 01417 ; 01418 ; Character of the TRACKING readout 'T' or 'C' in Control Panel 01419 ; Display memory. 01420 ; 01421 ; $095C TRACKDIGIT 01422 ; 01423 ; Digit of the TRACKING readout in Control Panel Display memory. It 01424 ; is used to store the index of the currently tracked space object. 01425 ; Used values are: 01426 ; $00 -> Track Zylon ship 0 01427 ; $01 -> Track Zylon ship 1 01428 ; $02 -> Track starbase 01429 ; $03 -> Track Hyperwarp Target Marker 01430 ; 01431 ; $0960 THETAC1 01432 ; 01433 ; First character of the THETA readout in Control Panel Display 01434 ; memory. 01435 ; 01436 ; $0966 PHIC1 01437 ; 01438 ; First character of the PHI readout in Control Panel Display 01439 ; memory. 01440 ; 01441 ; $096C RANGEC1 01442 ; 01443 ; First character of the RANGE readout in Control Panel Display 01444 ; memory. 01445 ; 01446 ; $0971..$09AC GCTXT 01447 ; 01448 ; Memory of Galactic Chart Panel Display (bottom text window) of 01449 ; Galactic Chart view (20 characters x 3 rows = 60 bytes). 01450 ; 01451 ; $097D GCWARPD1 01452 ; 01453 ; First digit (of 4) of the HYPERWARP ENERGY readout in Galactic 01454 ; Chart Panel Display memory. 01455 ; 01456 ; $098D GCTRGCNT 01457 ; 01458 ; First target counter digit (of 2) in Galactic Chart Panel Display 01459 ; memory. 01460 ; 01461 ; $0992 GCSTATPHO 01462 ; 01463 ; Photon Torpedo status letter in Galactic Chart Panel Display 01464 ; memory. Used values are: 01465 ; %00****** -> OK 01466 ; %10****** -> Destroyed 01467 ; %11****** -> Damaged 01468 ; 01469 ; $0993 GCSTATENG 01470 ; 01471 ; Engines status letter in Galactic Chart Panel Display memory. 01472 ; Used values are: 01473 ; %00****** -> OK 01474 ; %10****** -> Destroyed 01475 ; %11****** -> Damaged 01476 ; 01477 ; $0994 GCSTATSHL 01478 ; 01479 ; Shields status letter in Galactic Chart Panel Display memory. 01480 ; Used values are: 01481 ; %00****** -> OK 01482 ; %10****** -> Destroyed 01483 ; %11****** -> Damaged 01484 ; 01485 ; $0995 GCSTATCOM 01486 ; 01487 ; Attack Computer status letter in Galactic Chart Panel Display 01488 ; memory. Used values are: 01489 ; %00****** -> OK 01490 ; %10****** -> Destroyed 01491 ; %11****** -> Damaged 01492 ; 01493 ; $0996 GCSTATLRS 01494 ; 01495 ; Long-Range Scan status letter in Galactic Chart Panel Display 01496 ; memory. Used values are: 01497 ; %00****** -> OK 01498 ; %10****** -> Destroyed 01499 ; %11****** -> Damaged 01500 ; 01501 ; $0997 GCSTATRAD 01502 ; 01503 ; Subspace Radio status letter in Galactic Chart Panel Display 01504 ; memory. Used values are: 01505 ; %00****** -> OK 01506 ; %10****** -> Destroyed 01507 ; %11****** -> Damaged 01508 ; 01509 ; $09A3 GCSTARDAT 01510 ; 01511 ; First (of 5) digits of the star date clock in the Galactic Chart 01512 ; Panel Display memory. 01513 ; 01514 ; $09AD..$09DD ZPOSSIGN 01515 ; 01516 ; Table containing the sign bit (B16) of position vector 01517 ; z-components (z-coordinate) (49 bytes). Bytes 0..4 belong to 01518 ; position vectors of PLAYER space objects (Zylon ships, photon 01519 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01520 ; PLAYFIELD space objects (stars, explosion fragments). Used values 01521 ; are: 01522 ; $00 -> Negative sign (behind our starship) 01523 ; $01 -> Positive sign (in front of our starship) 01524 ; 01525 ; See also "ON POSITION VECTORS". 01526 ; 01527 ; $09AD PL0ZPOSSIGN 01528 ; 01529 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01530 ; PLAYER0. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01531 ; VECTORS". 01532 ; 01533 ; $09AE PL1ZPOSSIGN 01534 ; 01535 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01536 ; PLAYER1. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01537 ; VECTORS". 01538 ; 01539 ; $09AF PL2ZPOSSIGN 01540 ; 01541 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01542 ; PLAYER2. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01543 ; VECTORS". 01544 ; 01545 ; $09B0 PL3ZPOSSIGN 01546 ; 01547 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01548 ; PLAYER3. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01549 ; VECTORS". 01550 ; 01551 ; $09B1 PL4ZPOSSIGN 01552 ; 01553 ; Sign bit (B16) of position vector z-component (z-coordinate) of 01554 ; PLAYER4. Compare ZPOSSIGN ($09AD). See also "ON POSITION 01555 ; VECTORS". 01556 ; 01557 ; $09DE..$0A0E XPOSSIGN 01558 ; 01559 ; Table containing the sign bit (B16) of position vector 01560 ; x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to 01561 ; position vectors of PLAYER space objects (Zylon ships, photon 01562 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01563 ; PLAYFIELD space objects (stars, explosion fragments). Used values 01564 ; are: 01565 ; $00 -> Negative sign (left) 01566 ; $01 -> Positive sign (right) 01567 ; 01568 ; See also "ON POSITION VECTORS". 01569 ; 01570 ; $09DE PL0XPOSSIGN 01571 ; 01572 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01573 ; PLAYER0. Compare XPOSSIGN ($09DE). See also "ON POSITION 01574 ; VECTORS". 01575 ; 01576 ; $09DF PL1XPOSSIGN 01577 ; 01578 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01579 ; PLAYER1. Compare XPOSSIGN ($09DE). See also "ON POSITION 01580 ; VECTORS". 01581 ; 01582 ; $09E0 PL2XPOSSIGN 01583 ; 01584 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01585 ; PLAYER2. Compare XPOSSIGN ($09DE). See also "ON POSITION 01586 ; VECTORS". 01587 ; 01588 ; $09E1 PL3XPOSSIGN 01589 ; 01590 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01591 ; PLAYER3. Compare XPOSSIGN ($09DE). See also "ON POSITION 01592 ; VECTORS". 01593 ; 01594 ; $09E2 PL4XPOSSIGN 01595 ; 01596 ; Sign bit (B16) of position vector x-component (x-coordinate) of 01597 ; PLAYER4. Compare XPOSSIGN ($09DE). See also "ON POSITION 01598 ; VECTORS". 01599 ; 01600 ; $0A0F..$0A3F YPOSSIGN 01601 ; 01602 ; Table containing the sign bit (B16) of position vector 01603 ; y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to 01604 ; position vectors of PLAYER space objects (Zylon ships, photon 01605 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01606 ; PLAYFIELD space objects (stars, explosion fragments). Used values 01607 ; are: 01608 ; $00 -> Negative sign (down) 01609 ; $01 -> Positive sign (up) 01610 ; 01611 ; See also "ON POSITION VECTORS". 01612 ; 01613 ; $0A0F PL0YPOSSIGN 01614 ; 01615 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01616 ; PLAYER0. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01617 ; VECTORS". 01618 ; 01619 ; $0A10 PL1YPOSSIGN 01620 ; 01621 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01622 ; PLAYER1. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01623 ; VECTORS". 01624 ; 01625 ; $0A11 PL2YPOSSIGN 01626 ; 01627 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01628 ; PLAYER2. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01629 ; VECTORS". 01630 ; 01631 ; $0A12 PL3YPOSSIGN 01632 ; 01633 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01634 ; PLAYER3. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01635 ; VECTORS". 01636 ; 01637 ; $0A13 PL4YPOSSIGN 01638 ; 01639 ; Sign bit (B16) of position vector y-component (y-coordinate) of 01640 ; PLAYER4. Compare YPOSSIGN ($0A0F). See also "ON POSITION 01641 ; VECTORS". 01642 ; 01643 ; $0A40..$0A70 ZPOSHI 01644 ; 01645 ; Table containing the high byte (B15..8) of position vector 01646 ; y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to 01647 ; position vectors of PLAYER space objects (Zylon ships, photon 01648 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01649 ; PLAYFIELD space objects (stars, explosion fragments). See also 01650 ; "ON POSITION VECTORS". 01651 ; 01652 ; $0A40 PL0ZPOSHI 01653 ; 01654 ; High byte (B15..8) of position vector z-component (z-coordinate) 01655 ; of PLAYER0. Compare ZPOSHI ($0A40). See also "ON POSITION 01656 ; VECTORS". 01657 ; 01658 ; $0A41 PL1ZPOSHI 01659 ; 01660 ; High byte (B15..8) of position vector z-component (z-coordinate) 01661 ; of PLAYER1. Compare ZPOSHI ($0A40). See also "ON POSITION 01662 ; VECTORS". 01663 ; 01664 ; $0A42 PL2ZPOSHI 01665 ; 01666 ; High byte (B15..8) of position vector z-component (z-coordinate) 01667 ; of PLAYER2. Compare ZPOSHI ($0A40). See also "ON POSITION 01668 ; VECTORS". 01669 ; 01670 ; $0A43 PL3ZPOSHI 01671 ; 01672 ; High byte (B15..8) of position vector z-component (z-coordinate) 01673 ; of PLAYER3. Compare ZPOSHI ($0A40). See also "ON POSITION 01674 ; VECTORS". 01675 ; 01676 ; $0A44 PL4ZPOSHI 01677 ; 01678 ; High byte (B15..8) of position vector z-component (z-coordinate) 01679 ; of PLAYER4. Compare ZPOSHI ($0A40). See also "ON POSITION 01680 ; VECTORS". 01681 ; 01682 ; $0A71..$0AA1 XPOSHI 01683 ; 01684 ; Table containing the high byte (B15..8) of position vector 01685 ; x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to 01686 ; position vectors of PLAYER space objects (Zylon ships, photon 01687 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01688 ; PLAYFIELD space objects (stars, explosion fragments). See also 01689 ; "ON POSITION VECTORS". 01690 ; 01691 ; $0A71 PL0XPOSHI 01692 ; 01693 ; High byte (B15..8) of position vector x-component (x-coordinate) 01694 ; of PLAYER0. Compare XPOSHI ($0A71). See also "ON POSITION 01695 ; VECTORS". 01696 ; 01697 ; $0A72 PL1XPOSHI 01698 ; 01699 ; High byte (B15..8) of position vector x-component (x-coordinate) 01700 ; of PLAYER1. Compare XPOSHI ($0A71). See also "ON POSITION 01701 ; VECTORS". 01702 ; 01703 ; $0A73 PL2XPOSHI 01704 ; 01705 ; High byte (B15..8) of position vector x-component (x-coordinate) 01706 ; of PLAYER2. Compare XPOSHI ($0A71). See also "ON POSITION 01707 ; VECTORS". 01708 ; 01709 ; $0A74 PL3XPOSHI 01710 ; 01711 ; High byte (B15..8) of position vector x-component (x-coordinate) 01712 ; of PLAYER3. Compare XPOSHI ($0A71). See also "ON POSITION 01713 ; VECTORS". 01714 ; 01715 ; $0A75 PL4XPOSHI 01716 ; 01717 ; High byte (B15..8) of position vector x-component (x-coordinate) 01718 ; of PLAYER4. Compare XPOSHI ($0A71). See also "ON POSITION 01719 ; VECTORS". 01720 ; 01721 ; $0AA2..$0AD2 YPOSHI 01722 ; 01723 ; Table containing the high byte (B15..8) of position vector 01724 ; y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to 01725 ; position vectors of PLAYER space objects (Zylon ships, photon 01726 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01727 ; PLAYFIELD space objects (stars, explosion fragments). See also 01728 ; "ON POSITION VECTORS". 01729 ; 01730 ; $0AA2 PL0YPOSHI 01731 ; 01732 ; High byte (B15..8) of position vector y-component (y-coordinate) 01733 ; of PLAYER0. Compare YPOSHI ($0AA2). See also "ON POSITION 01734 ; VECTORS". 01735 ; 01736 ; $0AA3 PL1YPOSHI 01737 ; 01738 ; High byte (B15..8) of position vector y-component (y-coordinate) 01739 ; of PLAYER1. Compare YPOSHI ($0AA2). See also "ON POSITION 01740 ; VECTORS". 01741 ; 01742 ; $0AA4 PL2YPOSHI 01743 ; 01744 ; High byte (B15..8) of position vector y-component (y-coordinate) 01745 ; of PLAYER2. Compare YPOSHI ($0AA2). See also "ON POSITION 01746 ; VECTORS". 01747 ; 01748 ; $0AA5 PL3YPOSHI 01749 ; 01750 ; High byte (B15..8) of position vector y-component (y-coordinate) 01751 ; of PLAYER3. Compare YPOSHI ($0AA2). See also "ON POSITION 01752 ; VECTORS". 01753 ; 01754 ; $0AA6 PL4YPOSHI 01755 ; 01756 ; High byte (B15..8) of position vector y-component (y-coordinate) 01757 ; of PLAYER4. Compare YPOSHI ($0AA2). See also "ON POSITION 01758 ; VECTORS". 01759 ; 01760 ; $0AD3..$0B03 ZPOSLO 01761 ; 01762 ; Table containing the low byte (B7..0) of position vector 01763 ; z-components (z-coordinate) (49 bytes). Bytes 0..4 belong to 01764 ; position vectors of PLAYER space objects (Zylon ships, photon 01765 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01766 ; PLAYFIELD space objects (stars, explosion fragments). See also 01767 ; "ON POSITION VECTORS". 01768 ; 01769 ; $0AD3 PL0ZPOSLO 01770 ; 01771 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01772 ; PLAYER0. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01773 ; 01774 ; $0AD4 PL1ZPOSLO 01775 ; 01776 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01777 ; PLAYER1. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01778 ; 01779 ; $0AD5 PL2ZPOSLO 01780 ; 01781 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01782 ; PLAYER2. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01783 ; 01784 ; $0AD6 PL3ZPOSLO 01785 ; 01786 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01787 ; PLAYER3. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01788 ; 01789 ; $0AD7 PL4ZPOSLO 01790 ; 01791 ; Low byte (B7..0) of position vector z-component (z-coordinate) of 01792 ; PLAYER4. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS". 01793 ; 01794 ; $0B04..$0B34 XPOSLO 01795 ; 01796 ; Table containing the low byte (B7..0) of position vector 01797 ; x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to 01798 ; position vectors of PLAYER space objects (Zylon ships, photon 01799 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01800 ; PLAYFIELD space objects (stars, explosion fragments). See also 01801 ; "ON POSITION VECTORS". 01802 ; 01803 ; $0B04 PL0XPOSLO 01804 ; 01805 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01806 ; PLAYER0. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01807 ; 01808 ; $0B05 PL1XPOSLO 01809 ; 01810 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01811 ; PLAYER1. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01812 ; 01813 ; $0B06 PL2XPOSLO 01814 ; 01815 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01816 ; PLAYER2. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01817 ; 01818 ; $0B07 PL3XPOSLO 01819 ; 01820 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01821 ; PLAYER3. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01822 ; 01823 ; $0B08 PL4XPOSLO 01824 ; 01825 ; Low byte (B7..0) of position vector x-component (x-coordinate) of 01826 ; PLAYER4. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS". 01827 ; 01828 ; $0B35..$0B65 YPOSLO 01829 ; 01830 ; Table containing the low byte (B7..0) of position vector 01831 ; y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to 01832 ; position vectors of PLAYER space objects (Zylon ships, photon 01833 ; torpedoes, etc.). Bytes 5..48 belong to position vectors of 01834 ; PLAYFIELD space objects (stars, explosion fragments). See also 01835 ; "ON POSITION VECTORS". 01836 ; 01837 ; $0B35 PL0YPOSLO 01838 ; 01839 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01840 ; PLAYER0. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01841 ; 01842 ; $0B36 PL1YPOSLO 01843 ; 01844 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01845 ; PLAYER1. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01846 ; 01847 ; $0B37 PL2YPOSLO 01848 ; 01849 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01850 ; PLAYER2. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01851 ; 01852 ; $0B38 PL3YPOSLO 01853 ; 01854 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01855 ; PLAYER3. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01856 ; 01857 ; $0B39 PL4YPOSLO 01858 ; 01859 ; Low byte (B7..0) of position vector y-component (y-coordinate) of 01860 ; PLAYER4. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 01861 ; 01862 ; $0B66..$0B96 ZVEL 01863 ; 01864 ; Table containing velocity vector z-components (z-velocities) (49 01865 ; bytes). Bytes 0..4 belong to velocity vectors of PLAYER space 01866 ; objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong 01867 ; to velocity vectors of PLAYFIELD space objects (stars, explosion 01868 ; fragments). Each z-velocity is stored in the binary format 01869 ; %sxxxxxxx where 01870 ; %s = 0 -> Positive sign (moving in flight direction) 01871 ; %s = 1 -> Negative sign (moving in reverse flight direction) 01872 ; %xxxxxxx -> Unsigned 7-bit velocity value in 01873 ; 01874 ; See also "ON VELOCITY VECTORS". 01875 ; 01876 ; $0B66 PL0ZVEL 01877 ; 01878 ; Velocity vector z-component (z-velocity) of PLAYER0. Compare ZVEL 01879 ; ($0B66). See also "ON VELOCITY VECTORS". 01880 ; 01881 ; $0B67 PL1ZVEL 01882 ; 01883 ; Velocity vector z-component (z-velocity) of PLAYER1. Compare ZVEL 01884 ; ($0B66). See also "ON VELOCITY VECTORS". 01885 ; 01886 ; $0B68 PL2ZVEL 01887 ; 01888 ; Velocity vector z-component (z-velocity) of PLAYER2. Compare ZVEL 01889 ; ($0B66). See also "ON VELOCITY VECTORS". 01890 ; 01891 ; $0B69 PL3ZVEL 01892 ; 01893 ; Velocity vector z-component (z-velocity) of PLAYER3. Compare ZVEL 01894 ; ($0B66). See also "ON VELOCITY VECTORS". 01895 ; 01896 ; $0B6A PL4ZVEL 01897 ; 01898 ; Velocity vector z-component (z-velocity) of PLAYER4. Compare ZVEL 01899 ; ($0B66). See also "ON VELOCITY VECTORS". 01900 ; 01901 ; $0B97..$0BC7 XVEL 01902 ; 01903 ; Table containing velocity vector x-components (x-velocities) (49 01904 ; bytes). Bytes 0..4 belong to velocity vectors of PLAYER space 01905 ; objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong 01906 ; to velocity vectors of PLAYFIELD space objects (stars, explosion 01907 ; fragments). Each x-velocity is stored in the binary format 01908 ; %sxxxxxxx where 01909 ; %s = 0 -> Positive sign (moving to the right) 01910 ; %s = 1 -> Negative sign (moving to the left) 01911 ; %xxxxxxx -> Unsigned 7-bit velocity value in 01912 ; 01913 ; See also "ON VELOCITY VECTORS". 01914 ; 01915 ; $0B97 PL0XVEL 01916 ; 01917 ; Velocity vector x-component (x-velocity) of PLAYER0. Compare XVEL 01918 ; ($0B97). See also "ON VELOCITY VECTORS". 01919 ; 01920 ; $0B98 PL1XVEL 01921 ; 01922 ; Velocity vector x-component (x-velocity) of PLAYER1. Compare XVEL 01923 ; ($0B97). See also "ON VELOCITY VECTORS". 01924 ; 01925 ; $0B99 PL2XVEL 01926 ; 01927 ; Velocity vector x-component (x-velocity) of PLAYER2. Compare XVEL 01928 ; ($0B97). See also "ON VELOCITY VECTORS". 01929 ; 01930 ; $0B9A PL3XVEL 01931 ; 01932 ; Velocity vector x-component (x-velocity) of PLAYER3. Compare XVEL 01933 ; ($0B97). See also "ON VELOCITY VECTORS". 01934 ; 01935 ; $0B9B PL4XVEL 01936 ; 01937 ; Velocity vector x-component (x-velocity) of PLAYER4. Compare XVEL 01938 ; ($0B97). See also "ON VELOCITY VECTORS". 01939 ; 01940 ; $0BC8..$0BF8 YVEL 01941 ; 01942 ; Table containing velocity vector y-components (y-velocities) (49 01943 ; bytes). Bytes 0..4 belong to velocity vectors of PLAYER space 01944 ; objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong 01945 ; to velocity vectors of PLAYFIELD space objects (stars, explosion 01946 ; fragments). Each y-velocity is stored in the binary format 01947 ; %sxxxxxxx where 01948 ; %s = 0 -> Positive sign (moving up) 01949 ; %s = 1 -> Negative sign (moving down) 01950 ; %xxxxxxx -> Unsigned 7-bit velocity value in 01951 ; 01952 ; See also "ON VELOCITY VECTORS". 01953 ; 01954 ; $0BC8 PL0YVEL 01955 ; 01956 ; Velocity vector y-component (y-velocity) of PLAYER0. Compare YVEL 01957 ; ($0BC8). See also "ON VELOCITY VECTORS". 01958 ; 01959 ; $0BC9 PL1YVEL 01960 ; 01961 ; Velocity vector y-component (y-velocity) of PLAYER1. Compare YVEL 01962 ; ($0BC8). See also "ON VELOCITY VECTORS". 01963 ; 01964 ; $0BCA PL2YVEL 01965 ; 01966 ; Velocity vector y-component (y-velocity) of PLAYER2. Compare YVEL 01967 ; ($0BC8). See also "ON VELOCITY VECTORS". 01968 ; 01969 ; $0BCB PL3YVEL 01970 ; 01971 ; Velocity vector y-component (y-velocity) of PLAYER3. Compare YVEL 01972 ; ($0BC8). See also "ON VELOCITY VECTORS". 01973 ; 01974 ; $0BCC PL4YVEL 01975 ; 01976 ; Velocity vector y-component (y-velocity) of PLAYER4. Compare YVEL 01977 ; ($0BC8). See also "ON VELOCITY VECTORS". 01978 ; 01979 ; $0BF9..$0C29 PIXELROWNEW 01980 ; 01981 ; Table containing the new pixel row number of space objects (49 01982 ; bytes). Bytes 0..4 belong to PLAYER space objects and contain 01983 ; Player/Missile (PM) pixel row numbers. They are counted from 01984 ; vertical PM position 0, which is offscreen. Bytes 5..48 belong to 01985 ; PLAYFIELD space objects (stars, explosion fragments) and contain 01986 ; PLAYFIELD pixel row numbers. They are counted from the top border 01987 ; of the PLAYFIELD and have values of 0..99. See also PIXELROW 01988 ; ($0C5B). 01989 ; 01990 ; $0BF9 PL0ROWNEW 01991 ; 01992 ; New pixel row number of PLAYER0 in Player/Missile pixels. See 01993 ; also PIXELROWNEW ($0BF9). 01994 ; 01995 ; $0BFA PL1ROWNEW 01996 ; 01997 ; New pixel row number of PLAYER1 in Player/Missile pixels. See 01998 ; also PIXELROWNEW ($0BF9). 01999 ; 02000 ; $0BFB PL2ROWNEW 02001 ; 02002 ; New pixel row number of PLAYER2 in Player/Missile pixels. See 02003 ; also PIXELROWNEW ($0BF9). 02004 ; 02005 ; $0BFC PL3ROWNEW 02006 ; 02007 ; New pixel row number of PLAYER3 in Player/Missile pixels. See 02008 ; also PIXELROWNEW ($0BF9). 02009 ; 02010 ; $0BFD PL4ROWNEW 02011 ; 02012 ; New pixel row number of PLAYER4 in Player/Missile pixels. See 02013 ; also PIXELROWNEW ($0BF9). 02014 ; 02015 ; $0C2A..$0C5A PIXELCOLUMN 02016 ; 02017 ; Table containing the pixel column number of space objects (49 02018 ; bytes). Bytes 0..4 belong to PLAYER space objects and contain 02019 ; Player/Missile (PM) pixel column numbers. They are counted from 02020 ; horizontal PM position 0, which is offscreen. Bytes 5..48 belong 02021 ; to PLAYFIELD space objects (stars, explosion fragments) and 02022 ; contain PLAYFIELD pixel column numbers. They are counted from the 02023 ; left border of the PLAYFIELD and have values of 0..159. 02024 ; 02025 ; $0C2A PL0COLUMN 02026 ; 02027 ; Pixel column number of PLAYER0 in Player/Missile pixels. See also 02028 ; PIXELCOLUMN ($0C2A). 02029 ; 02030 ; $0C2B PL1COLUMN 02031 ; 02032 ; Pixel column number of PLAYER1 in Player/Missile pixels. See also 02033 ; PIXELCOLUMN ($0C2A). 02034 ; 02035 ; $0C2C PL2COLUMN 02036 ; 02037 ; Pixel column number of PLAYER2 in Player/Missile pixels. See also 02038 ; PIXELCOLUMN ($0C2A). 02039 ; 02040 ; $0C2D PL3COLUMN 02041 ; 02042 ; Pixel column number of PLAYER3 in Player/Missile pixels. See also 02043 ; PIXELCOLUMN ($0C2A). 02044 ; 02045 ; $0C2E PL4COLUMN 02046 ; 02047 ; Pixel column number of PLAYER4 in Player/Missile pixels. See also 02048 ; PIXELCOLUMN ($0C2A). 02049 ; 02050 ; $0C5B..$0C8B PIXELROW 02051 ; 02052 ; Table containing the pixel row number of space objects (49 02053 ; bytes). Bytes 0..4 belong to PLAYER space objects and contain 02054 ; Player/Missile (PM) pixel row numbers. They are counted from 02055 ; vertical PM position 0, which is offscreen. Bytes 5..48 belong to 02056 ; PLAYFIELD space objects (stars, explosion fragments) and contain 02057 ; PLAYFIELD pixel row numbers. They are counted from the top border 02058 ; of the PLAYFIELD and have values of 0..99. See also PIXELROWNEW 02059 ; ($0BF9). 02060 ; 02061 ; $0C5B PL0ROW 02062 ; 02063 ; Pixel row number of PLAYER0 in Player/Missile pixels. See also 02064 ; PIXELROW ($0C5B). 02065 ; 02066 ; $0C5C PL1ROW 02067 ; 02068 ; Pixel row number of PLAYER1 in Player/Missile pixels. See also 02069 ; PIXELROW ($0C5B). 02070 ; 02071 ; $0C5D PL2ROW 02072 ; 02073 ; Pixel row number of PLAYER2 in Player/Missile pixels. See also 02074 ; PIXELROW ($0C5B). 02075 ; 02076 ; $0C5E PL3ROW 02077 ; 02078 ; Pixel row number of PLAYER3 in Player/Missile pixels. See also 02079 ; PIXELROW ($0C5B). 02080 ; 02081 ; $0C5F PL4ROW 02082 ; 02083 ; Pixel row number of PLAYER4 in Player/Missile pixels. See also 02084 ; PIXELROW ($0C5B). 02085 ; 02086 ; $0C8C..$0CBC PIXELBYTEOFF 02087 ; 02088 ; Table containing a byte offset into PLAYFIELD memory for each 02089 ; PLAYFIELD space object (stars, explosion fragments) (49 bytes): 02090 ; the number of bytes from the start of the PLAYFIELD row to the 02091 ; byte containing the space object pixel in the same PLAYFIELD row. 02092 ; In other words, the pixel column modulo 4 (1 byte = 4 GRAPHICS7 02093 ; pixels). 02094 ; 02095 ; NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in 02096 ; this way. Bytes 0..4 are used differently. See PL0SHAPTYPE 02097 ; ($0C8C)..PL4SHAPTYPE ($0C90). 02098 ; 02099 ; $0C8C PL0SHAPTYPE 02100 ; 02101 ; Shape type of PLAYER0. Used to index the PLAYER's set of shape 02102 ; cells in tables PLSHAPOFFTAB ($BE2F) and PLSHPHEIGHTTAB ($BE7F). 02103 ; Used values are: 02104 ; $00 -> PHOTON TORPEDO 02105 ; $10 -> ZYLON FIGHTER 02106 ; $20 -> STARBASE RIGHT 02107 ; $30 -> STARBASE CENTER 02108 ; $40 -> STARBASE LEFT 02109 ; $50 -> TRANSFER VESSEL 02110 ; $60 -> METEOR 02111 ; $70 -> ZYLON CRUISER 02112 ; $80 -> ZYLON BASESTAR 02113 ; $90 -> HYPERWARP TARGET MARKER 02114 ; 02115 ; $0C8D PL1SHAPTYPE 02116 ; 02117 ; Shape type of PLAYER1. Compare PL0SHAPTYPE ($0C8C). 02118 ; 02119 ; $0C8E PL2SHAPTYPE 02120 ; 02121 ; Shape type of PLAYER2. Compare PL0SHAPTYPE ($0C8C). 02122 ; 02123 ; $0C8F PL3SHAPTYPE 02124 ; 02125 ; Shape type of PLAYER3. Compare PL0SHAPTYPE ($0C8C). 02126 ; 02127 ; $0C90 PL4SHAPTYPE 02128 ; 02129 ; Shape type of PLAYER4. Compare PL0SHAPTYPE ($0C8C). 02130 ; 02131 ; $0CBD..$0CED PIXELSAVE 02132 ; 02133 ; Table containing the byte of PLAYFIELD memory before drawing the 02134 ; PLAYFIELD space object pixel into it (star, explosion fragments), 02135 ; for each PLAYFIELD space object (49 bytes). 02136 ; 02137 ; NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in 02138 ; this way. Bytes 0..4 are used differently. See PL0HEIGHT 02139 ; ($0CBD)..PL4HEIGHT ($0CC1). 02140 ; 02141 ; $0CBD PL0HEIGHT 02142 ; 02143 ; Shape height of PLAYER0 02144 ; 02145 ; $0CBE PL1HEIGHT 02146 ; 02147 ; Shape height of PLAYER1 02148 ; 02149 ; $0CBF PL2HEIGHT 02150 ; 02151 ; Shape height of PLAYER2 02152 ; 02153 ; $0CC0 PL3HEIGHT 02154 ; 02155 ; Shape height of PLAYER3 02156 ; 02157 ; $0CC1 PL4HEIGHT 02158 ; 02159 ; Shape height of PLAYER4 02160 ; 02161 ; $0CEE..$0D1E PIXELBYTE 02162 ; 02163 ; Table containing a 1-byte bit pattern for 4 pixels in the color 02164 ; of the space object's pixel, for each PLAYFIELD space object (49 02165 ; bytes). 02166 ; 02167 ; NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in 02168 ; this way. Bytes 0..4 are used differently. See PL0HEIGHTNEW 02169 ; ($0CEE)..PL4HEIGHTNEW ($0CF2). 02170 ; 02171 ; $0CEE PL0HEIGHTNEW 02172 ; 02173 ; New shape height of PLAYER0 02174 ; 02175 ; $0CEF PL1HEIGHTNEW 02176 ; 02177 ; New shape height of PLAYER1 02178 ; 02179 ; $0CF0 PL2HEIGHTNEW 02180 ; 02181 ; New shape height of PLAYER2 02182 ; 02183 ; $0CF1 PL3HEIGHTNEW 02184 ; 02185 ; New shape height of PLAYER3 02186 ; 02187 ; $0CF2 PL4HEIGHTNEW 02188 ; 02189 ; New shape height of PLAYER4 02190 ; 02191 ; $0D1F..$0D32 TITLETXT 02192 ; 02193 ; Title text line, contains ATASCII-coded characters (20 bytes) 02194 ; 02195 ; $0D35..$0DE8 GCPFMEM 02196 ; 02197 ; Galactic Chart PLAYFIELD memory (20 characters x 9 rows = 180 02198 ; bytes) 02199 ; 02200 ; $0DE9..$0EE8 MAPTO80 02201 ; 02202 ; Lookup table to convert values in $00..$FF to values of 0..80 02203 ; (255 bytes). Used to map position vector components (coordinates) 02204 ; to pixel row or column numbers relative to the PLAYFIELD center. 02205 ; 02206 ; $0EE9..$0FE8 MAPTOBCD99 02207 ; 02208 ; Lookup table to convert values in $00..$FF to BCD-values of 02209 ; 00..99 (255 bytes). Used in subroutines UPDPANEL ($B804) and 02210 ; SHOWDIGITS ($B8CD) to convert values to a 2-digit decimal readout 02211 ; value of the Control Panel Display. 02212 ; 02213 ; $1000..$1F77 PFMEM 02214 ; 02215 ; PLAYFIELD graphics memory (40 bytes x 100 rows = 4000 bytes, 1 02216 ; byte stores 4 pixels, 40 bytes = 160 pixels in GRAPHICS7 mode = 1 02217 ; PLAYFIELD row of pixels). 02218 ; 02219 ; NOTE: The Display List displays only PLAYFIELD rows 0..98. 02220 02221 ;******************************************************************************* 02222 ;* * 02223 ;* S Y S T E M S Y M B O L S * 02224 ;* * 02225 ;******************************************************************************* 02226 02227 VDSLST = $0200 ; Display List Interrupt (DLI) vector 02228 VIMIRQ = $0216 ; Interrupt request (IRQ) immediate vector 02229 VVBLKI = $0222 ; Vertical blank immediate vector 02230 HPOSP0 = $D000 ; Horizontal position of PLAYER0 02231 HPOSP1 = $D001 ; Horizontal position of PLAYER1 02232 HPOSP2 = $D002 ; Horizontal position of PLAYER2 02233 HPOSP3 = $D003 ; Horizontal position of PLAYER3 02234 HPOSM0 = $D004 ; Horizontal position of MISSILE0 02235 HPOSM1 = $D005 ; Horizontal position of MISSILE1 02236 HPOSM2 = $D006 ; Horizontal position of MISSILE2 02237 HPOSM3 = $D007 ; Horizontal position of MISSILE3 02238 M0PL = $D008 ; MISSILE0 to PLAYER collisions 02239 M1PL = $D009 ; MISSILE1 to PLAYER collisions 02240 M2PL = $D00A ; MISSILE2 to PLAYER collisions 02241 M3PL = $D00B ; MISSILE3 to PLAYER collisions 02242 P3PL = $D00F ; PLAYER3 to PLAYER collisions 02243 TRIG0 = $D010 ; Joystick 0 trigger 02244 COLPM0 = $D012 ; Color and brightness of PLAYER0 02245 COLPF0 = $D016 ; Color and brightness of PLAYFIELD0 02246 PRIOR = $D01B ; Priority selection register 02247 GRACTL = $D01D ; Graphics control register 02248 HITCLR = $D01E ; Clear collision register 02249 CONSOL = $D01F ; Function keys register 02250 AUDF1 = $D200 ; Audio channel 1 frequency 02251 AUDF2 = $D202 ; Audio channel 2 frequency 02252 AUDC2 = $D203 ; Audio channel 2 control 02253 AUDF3 = $D204 ; Audio channel 3 frequency 02254 AUDC3 = $D205 ; Audio channel 3 control 02255 AUDF4 = $D206 ; Audio channel 4 frequency 02256 AUDC4 = $D207 ; Audio channel 4 control 02257 AUDCTL = $D208 ; Audio control 02258 KBCODE = $D209 ; Keyboard code 02259 STIMER = $D209 ; Start POKEY timers 02260 RANDOM = $D20A ; Random number generator 02261 IRQEN = $D20E ; Interrupt request (IRQ) enable 02262 SKCTL = $D20F ; Serial port control 02263 PORTA = $D300 ; Port A 02264 PACTL = $D302 ; Port A control 02265 DMACTL = $D400 ; Direct Memory Access (DMA) control 02266 DLIST = $D402 ; Display List pointer 02267 PMBASE = $D407 ; Player/Missile base address (high byte) 02268 CHBASE = $D409 ; Character set base address (high byte) 02269 WSYNC = $D40A ; Wait for horizontal synchronization 02270 VCOUNT = $D40B ; Vertical line counter 02271 NMIEN = $D40E ; Non-maskable interrupt (NMI) enable 02272 ROMCHARSET = $E000 ; ROM character set 02273 02274 ;******************************************************************************* 02275 ;* * 02276 ;* G A M E S Y M B O L S * 02277 ;* * 02278 ;******************************************************************************* 02279 02280 MISSIONLEVEL = $62 02281 FKEYCODE = $63 02282 ISDEMOMODE = $64 02283 NEWTITLEPHR = $65 02284 IDLECNTHI = $66 02285 ISVBISYNC = $67 02286 MEMPTR = $68 02287 02288 DIVIDEND = $6A 02289 JOYSTICKDELTA = $6D 02290 02291 02292 VELOCITYLO = $70 02293 NEWVELOCITY = $71 02294 COUNT8 = $72 02295 EXPLLIFE = $73 02296 CLOCKTIM = $74 02297 DOCKSTATE = $75 02298 COUNT256 = $76 02299 IDLECNTLO = $77 02300 ZYLONUNITTIM = $78 02301 MAXSPCOBJIND = $79 02302 OLDMAXSPCOBJIND = $7A 02303 ISSTARBASESECT = $7B 02304 ISTRACKCOMPON = $7C 02305 DRAINSHIELDS = $7D 02306 DRAINATTCOMP = $7E 02307 ENERGYCNT = $7F 02308 DRAINENGINES = $80 02309 SHIELDSCOLOR = $81 02310 PL3HIT = $82 02311 PL4HIT = $83 02312 OLDTRIG0 = $84 02313 02314 ISTRACKING = $86 02315 BARRELNR = $87 02316 LOCKONLIFE = $88 02317 PLTRACKED = $89 02318 HITBADNESS = $8A 02319 REDALERTLIFE = $8B 02320 WARPDEPRROW = $8C 02321 WARPDEPRCOLUMN = $8D 02322 WARPARRVROW = $8E 02323 WARPARRVCOLUMN = $8F 02324 CURRSECTOR = $90 02325 WARPENERGY = $91 02326 ARRVSECTOR = $92 02327 HUNTSECTOR = $93 02328 HUNTSECTCOLUMN = $94 02329 HUNTSECTROW = $95 02330 NEWZYLONDIST = $96 02331 OLDZYLONDIST = $9E 02332 HUNTTIM = $9F 02333 BLIPCOLUMN = $A0 02334 BLIPROW = $A1 02335 BLIPCYCLECNT = $A2 02336 ISINLOCKON = $A3 02337 DIRLEN = $A4 02338 PENROW = $A5 02339 PENCOLUMN = $A6 02340 CTRLDZYLON = $A7 02341 ZYLONFLPAT0 = $A8 02342 ZYLONFLPAT1 = $A9 02343 MILESTTIM0 = $AA 02344 MILESTTIM1 = $AB 02345 MILESTVELINDZ0 = $AC 02346 MILESTVELINDZ1 = $AD 02347 MILESTVELINDX0 = $AE 02348 MILESTVELINDX1 = $AF 02349 MILESTVELINDY0 = $B0 02350 MILESTVELINDY1 = $B1 02351 ZYLONVELINDZ0 = $B2 02352 ZYLONVELINDZ1 = $B3 02353 ZYLONVELINDX0 = $B4 02354 ZYLONVELINDX1 = $B5 02355 ZYLONVELINDY0 = $B6 02356 ZYLONVELINDY1 = $B7 02357 ISBACKATTACK0 = $B8 02358 ISBACKATTACK1 = $B9 02359 ZYLONTIMX0 = $BA 02360 ZYLONTIMX1 = $BB 02361 ZYLONTIMY0 = $BC 02362 ZYLONTIMY1 = $BD 02363 TORPEDODELAY = $BE 02364 ZYLONATTACKER = $BF 02365 WARPSTATE = $C0 02366 VELOCITYHI = $C1 02367 TRAILDELAY = $C2 02368 TRAILIND = $C3 02369 WARPTEMPCOLUMN = $C4 02370 WARPTEMPROW = $C5 02371 VEERMASK = $C6 02372 VICINITYMASK = $C7 02373 JOYSTICKX = $C8 02374 JOYSTICKY = $C9 02375 KEYCODE = $CA 02376 SCORE = $CB 02377 SCOREDRANKIND = $CD 02378 SCOREDCLASSIND = $CE 02379 TITLELIFE = $CF 02380 SHIPVIEW = $D0 02381 TITLEPHR = $D1 02382 BEEPFRQIND = $D2 02383 BEEPREPEAT = $D3 02384 BEEPTONELIFE = $D4 02385 BEEPPAUSELIFE = $D5 02386 BEEPPRIORITY = $D6 02387 BEEPFRQSTART = $D7 02388 BEEPLIFE = $D8 02389 BEEPTOGGLE = $D9 02390 NOISETORPTIM = $DA 02391 NOISEEXPLTIM = $DB 02392 NOISEAUDC2 = $DC 02393 NOISEAUDC3 = $DD 02394 NOISEAUDF1 = $DE 02395 NOISEAUDF2 = $DF 02396 NOISEFRQINC = $E0 02397 NOISELIFE = $E1 02398 NOISEZYLONTIM = $E2 02399 NOISEHITLIFE = $E3 02400 PL0SHAPOFF = $E4 02401 PL1SHAPOFF = $E5 02402 PL2SHAPOFF = $E6 02403 PL3SHAPOFF = $E7 02404 PL4SHAPOFF = $E8 02405 PL0LIFE = $E9 02406 PL1LIFE = $EA 02407 PL2LIFE = $EB 02408 PL3LIFE = $EC 02409 PL4LIFE = $ED 02410 PL0COLOR = $EE 02411 PL1COLOR = $EF 02412 PL2COLOR = $F0 02413 PL3COLOR = $F1 02414 PF0COLOR = $F2 02415 PF1COLOR = $F3 02416 PF2COLOR = $F4 02417 PF3COLOR = $F5 02418 BGRCOLOR = $F6 02419 PF0COLORDLI = $F7 02420 PF1COLORDLI = $F8 02421 PF2COLORDLI = $F9 02422 PF3COLORDLI = $FA 02423 BGRCOLORDLI = $FB 02424 DSPLST = $0280 02425 PL4DATA = $0300 02426 PL0DATA = $0400 02427 PL1DATA = $0500 02428 PL2DATA = $0600 02429 PL3DATA = $0700 02430 PFMEMROWLO = $0800 02431 PFMEMROWHI = $0864 02432 GCMEMMAP = $08C9 02433 PANELTXT = $0949 02434 VELOCD1 = $094B 02435 KILLCNTD1 = $0950 02436 ENERGYD1 = $0955 02437 TRACKC1 = $095A 02438 TRACKDIGIT = $095C 02439 THETAC1 = $0960 02440 PHIC1 = $0966 02441 RANGEC1 = $096C 02442 GCTXT = $0971 02443 GCWARPD1 = $097D 02444 GCTRGCNT = $098D 02445 GCSTATPHO = $0992 02446 GCSTATENG = $0993 02447 GCSTATSHL = $0994 02448 GCSTATCOM = $0995 02449 GCSTATLRS = $0996 02450 GCSTATRAD = $0997 02451 GCSTARDAT = $09A3 02452 ZPOSSIGN = $09AD 02453 PL2ZPOSSIGN = $09AF 02454 PL3ZPOSSIGN = $09B0 02455 PL4ZPOSSIGN = $09B1 02456 XPOSSIGN = $09DE 02457 PL2XPOSSIGN = $09E0 02458 PL3XPOSSIGN = $09E1 02459 PL4XPOSSIGN = $09E2 02460 YPOSSIGN = $0A0F 02461 PL2YPOSSIGN = $0A11 02462 PL3YPOSSIGN = $0A12 02463 PL4YPOSSIGN = $0A13 02464 ZPOSHI = $0A40 02465 PL0ZPOSHI = $0A40 02466 PL2ZPOSHI = $0A42 02467 PL3ZPOSHI = $0A43 02468 PL4ZPOSHI = $0A44 02469 XPOSHI = $0A71 02470 PL2XPOSHI = $0A73 02471 PL3XPOSHI = $0A74 02472 PL4XPOSHI = $0A75 02473 YPOSHI = $0AA2 02474 PL2YPOSHI = $0AA4 02475 PL3YPOSHI = $0AA5 02476 PL4YPOSHI = $0AA6 02477 ZPOSLO = $0AD3 02478 PL2ZPOSLO = $0AD5 02479 PL3ZPOSLO = $0AD6 02480 PL4ZPOSLO = $0AD7 02481 XPOSLO = $0B04 02482 PL2XPOSLO = $0B06 02483 PL3XPOSLO = $0B07 02484 PL4XPOSLO = $0B08 02485 YPOSLO = $0B35 02486 PL2YPOSLO = $0B37 02487 PL3YPOSLO = $0B38 02488 PL4YPOSLO = $0B39 02489 ZVEL = $0B66 02490 PL0ZVEL = $0B66 02491 PL1ZVEL = $0B67 02492 PL2ZVEL = $0B68 02493 PL3ZVEL = $0B69 02494 PL4ZVEL = $0B6A 02495 XVEL = $0B97 02496 PL0XVEL = $0B97 02497 PL1XVEL = $0B98 02498 PL2XVEL = $0B99 02499 PL3XVEL = $0B9A 02500 PL4XVEL = $0B9B 02501 YVEL = $0BC8 02502 PL0YVEL = $0BC8 02503 PL1YVEL = $0BC9 02504 PL2YVEL = $0BCA 02505 PL3YVEL = $0BCB 02506 PL4YVEL = $0BCC 02507 PIXELROWNEW = $0BF9 02508 PL0ROWNEW = $0BF9 02509 PL1ROWNEW = $0BFA 02510 PL2ROWNEW = $0BFB 02511 PL3ROWNEW = $0BFC 02512 PL4ROWNEW = $0BFD 02513 PIXELCOLUMN = $0C2A 02514 PL0COLUMN = $0C2A 02515 PL1COLUMN = $0C2B 02516 PL2COLUMN = $0C2C 02517 PL3COLUMN = $0C2D 02518 PL4COLUMN = $0C2E 02519 PIXELROW = $0C5B 02520 PL0ROW = $0C5B 02521 PL1ROW = $0C5C 02522 PL2ROW = $0C5D 02523 PL3ROW = $0C5E 02524 PL4ROW = $0C5F 02525 PIXELBYTEOFF = $0C8C 02526 PL0SHAPTYPE = $0C8C 02527 PL1SHAPTYPE = $0C8D 02528 PL2SHAPTYPE = $0C8E 02529 PL3SHAPTYPE = $0C8F 02530 PL4SHAPTYPE = $0C90 02531 PIXELSAVE = $0CBD 02532 PL0HEIGHT = $0CBD 02533 PL1HEIGHT = $0CBE 02534 PL2HEIGHT = $0CBF 02535 PL3HEIGHT = $0CC0 02536 PL4HEIGHT = $0CC1 02537 PIXELBYTE = $0CEE 02538 PL0HEIGHTNEW = $0CEE 02539 PL1HEIGHTNEW = $0CEF 02540 PL2HEIGHTNEW = $0CF0 02541 PL3HEIGHTNEW = $0CF1 02542 PL4HEIGHTNEW = $0CF2 02543 TITLETXT = $0D1F 02544 GCPFMEM = $0D35 02545 MAPTO80 = $0DE9 02546 MAPTOBCD99 = $0EE9 02547 PFMEM = $1000 02548 02549 *= $A000 02550 02551 ;******************************************************************************* 02552 ;* * 02553 ;* G A M E D A T A ( P A R T 1 O F 2 ) * 02554 ;* * 02555 ;******************************************************************************* 02556 02557 ;*** Number of space objects *************************************************** 02558 02559 NUMSPCOBJ.PL = 5 ; Number of PLAYER space objects 02560 NUMSPCOBJ.STARS = 12 ; Number of PLAYFIELD space objects (stars only) 02561 NUMSPCOBJ.NORM = NUMSPCOBJ.PL+NUMSPCOBJ.STARS ; Normal number of space objects 02562 NUMSPCOBJ.ALL = 49 ; Maximum number of space objects 02563 02564 ;*** PLAYER shape data offsets ************************************************* 02565 02566 SHAP.TORPEDO = $00 ; Photon torpedo 02567 SHAP.ZFIGHTER = $10 ; Zylon fighter 02568 SHAP.STARBASEL = $20 ; Starbase (left part) 02569 SHAP.STARBASEC = $30 ; Starbase (center part) 02570 SHAP.STARBASER = $40 ; Starbase (right part) 02571 SHAP.TRANSVSSL = $50 ; Transfer vessel 02572 SHAP.METEOR = $60 ; Meteor 02573 SHAP.ZCRUISER = $70 ; Zylon cruiser 02574 SHAP.ZBASESTAR = $80 ; Zylon basestar 02575 SHAP.HYPERWARP = $90 ; Hyperwarp Target Marker 02576 02577 ;*** ROM character set constants *********************************************** 02578 ROM.SPC = $00 ; ROM character ' ' 02579 ROM.DOT = $0E ; ROM character '.' 02580 ROM.0 = $10 ; ROM character '0' 02581 ROM.1 = $11 ; ROM character '1' 02582 ROM.2 = $12 ; ROM character '2' 02583 ROM.3 = $13 ; ROM character '3' 02584 ROM.4 = $14 ; ROM character '4' 02585 ROM.5 = $15 ; ROM character '5' 02586 ROM.9 = $19 ; ROM character '9' 02587 ROM.COLON = $1A ; ROM character ':' 02588 ROM.A = $21 ; ROM character 'A' 02589 ROM.C = $23 ; ROM character 'C' 02590 ROM.D = $24 ; ROM character 'D' 02591 ROM.E = $25 ; ROM character 'E' 02592 ROM.G = $27 ; ROM character 'G' 02593 ROM.L = $2C ; ROM character 'L' 02594 ROM.N = $2E ; ROM character 'N' 02595 ROM.P = $30 ; ROM character 'P' 02596 ROM.R = $32 ; ROM character 'R' 02597 ROM.S = $33 ; ROM character 'S' 02598 ROM.T = $34 ; ROM character 'T' 02599 ROM.W = $37 ; ROM character 'W' 02600 ROM.Y = $39 ; ROM character 'Y' 02601 02602 ;*** Custom character set constants ******************************************** 02603 CCS.COL1 = $40 ; COLOR1 bits for text in GR1/2 text mode 02604 CCS.COL2 = $80 ; COLOR2 bits for text in GR1/2 text mode 02605 CCS.COL3 = $C0 ; COLOR3 bits for text in GR1/2 text mode 02606 02607 CCS.0 = 0 ; Custom character '0' 02608 CCS.1 = 1 ; Custom character '1' 02609 CCS.2 = 2 ; Custom character '2' 02610 CCS.3 = 3 ; Custom character '3' 02611 CCS.4 = 4 ; Custom character '4' 02612 CCS.5 = 5 ; Custom character '5' 02613 CCS.6 = 6 ; Custom character '6' 02614 CCS.7 = 7 ; Custom character '7' 02615 CCS.8 = 8 ; Custom character '8' 02616 CCS.9 = 9 ; Custom character '9' 02617 CCS.SPC = 10 ; Custom character ' ' 02618 CCS.COLON = 11 ; Custom character ':' 02619 CCS.BORDERSW = 12 ; Custom character 'BORDER SOUTHWEST' 02620 CCS.E = 13 ; Custom character 'E' 02621 CCS.INF = 14 ; Custom character 'INFINITY' 02622 CCS.MINUS = 15 ; Custom character '-' 02623 CCS.PLUS = 16 ; Custom character '+' 02624 CCS.PHI = 17 ; Custom character 'PHI' 02625 CCS.V = 18 ; Custom character 'V' 02626 CCS.R = 19 ; Custom character 'R' 02627 CCS.THETA = 20 ; Custom character 'THETA' 02628 CCS.K = 21 ; Custom character 'K' 02629 CCS.T = 22 ; Custom character 'T' 02630 CCS.C = 23 ; Custom character 'C' 02631 CCS.BORDERS = 24 ; Custom character 'BORDER SOUTH' 02632 CCS.BORDERW = 25 ; Custom character 'BORDER WEST' 02633 CCS.CORNERSW = 26 ; Custom character 'CORNER SOUTHWEST' 02634 CCS.STARBASE = 27 ; Custom character 'STARBASE SECTOR' 02635 CCS.4ZYLONS = 28 ; Custom character '4-ZYLON SECTOR' 02636 CCS.3ZYLONS = 29 ; Custom character '3-ZYLON SECTOR' 02637 CCS.2ZYLONS = 30 ; Custom character '2-ZYLON SECTOR' 02638 02639 ;*** Custom character set ****************************************************** 02640 ; 02641 ; 0 1 2 3 4 5 6 7 02642 ; ........ ........ ........ ........ ........ ........ ........ ........ 02643 ; .####### ..##.... .####... .####... .##..... .####... .####... .#####.. 02644 ; .#...### ...#.... ....#... ....#... .##..... .#...... .#..#... .#...#.. 02645 ; .#...### ...#.... ....#... ....#... .##..... .#...... .#...... .....#.. 02646 ; .#...### ...#.... .####... .#####.. .##.##.. .####... .#...... ...###.. 02647 ; .#...### ..###... .#...... ....##.. .#####.. ....#... .######. ...#.... 02648 ; .#...### ..###... .#...... ....##.. ....##.. ....#... .#....#. ...#.... 02649 ; .####### ..###... .####... .#####.. ....##.. .####... .######. ...#.... 02650 ; 02651 ; 8 9 10 11 12 13 14 15 02652 ; ........ ........ ........ ..###... #....... ........ ........ ........ 02653 ; ..###... .#####.. ........ ..###... #....... ..####.. .##..##. ........ 02654 ; ..#.#... .#...#.. ........ ..###... #....... ..#..... #..##..# ........ 02655 ; ..#.#... .#...#.. ........ ........ #....... ..#..... #..##..# .######. 02656 ; .#####.. .#####.. ........ ........ #....... .####... #..##..# ........ 02657 ; .##.##.. ....##.. ........ ..###... #....... .##..... .##..##. ........ 02658 ; .##.##.. ....##.. ........ ..###... #....... .##..... ........ ........ 02659 ; .#####.. ....##.. ........ ..###... ######## .#####.. ........ ........ 02660 ; 02661 ; 16 17 18 19 20 21 22 23 02662 ; ........ ........ .##..##. ........ ........ ........ #######. ######.. 02663 ; ...##... ...##... .##..##. .#####.. ...###.. .#...##. #..#..#. #...##.. 02664 ; ...##... .######. .##..##. .#...#.. ..#####. .#...##. ...#.... #...##.. 02665 ; ...##... ##.##.## .##..##. .#...#.. .##...## .#...#.. ...##... #....... 02666 ; .######. #..##..# .##..##. .#####.. .#.###.# .#####.. ...##... #....... 02667 ; ...##... ##.##.## ..#.##.. .##.#... .##...## .##..#.. ...##... #....... 02668 ; ...##... .######. ..###... .##.##.. ..#####. .##..##. ...##... #....#.. 02669 ; ...##... ...##... ..##.... .##.##.. ...###.. .##..##. ...##... ######.. 02670 ; 02671 ; 24 25 26 27 28 29 30 02672 ; ........ #....... ........ #....... #....... #....... #....... 02673 ; ........ #....... ........ #.#.#.#. #..##... #...###. #.##.... 02674 ; ........ #....... ........ #..###.. #....... #....... #..##... 02675 ; ........ #....... ........ #.#####. #.##.##. #.###... #.#####. 02676 ; ........ #....... ........ #..###.. #....... #....... #..##... 02677 ; ........ #....... ........ #.#.#.#. #...##.. #..###.. #.##.... 02678 ; ........ #....... ........ #....... #....... #....... #....... 02679 ; ######## #....... #....... ######## ######## ######## ######## 02680 02681 CHARSET .BYTE $00,$7F,$47,$47,$47,$47,$47,$7F ; Custom character '0' 02682 .BYTE $00,$30,$10,$10,$10,$38,$38,$38 ; Custom character '1' 02683 .BYTE $00,$78,$08,$08,$78,$40,$40,$78 ; Custom character '2' 02684 .BYTE $00,$78,$08,$08,$7C,$0C,$0C,$7C ; Custom character '3' 02685 .BYTE $00,$60,$60,$60,$6C,$7C,$0C,$0C ; Custom character '4' 02686 .BYTE $00,$78,$40,$40,$78,$08,$08,$78 ; Custom character '5' 02687 .BYTE $00,$78,$48,$40,$40,$7E,$42,$7E ; Custom character '6' 02688 .BYTE $00,$7C,$44,$04,$1C,$10,$10,$10 ; Custom character '7' 02689 .BYTE $00,$38,$28,$28,$7C,$6C,$6C,$7C ; Custom character '8' 02690 .BYTE $00,$7C,$44,$44,$7C,$0C,$0C,$0C ; Custom character '9' 02691 .BYTE $00,$00,$00,$00,$00,$00,$00,$00 ; Custom character ' ' 02692 .BYTE $38,$38,$38,$00,$00,$38,$38,$38 ; Custom character ':' 02693 .BYTE $80,$80,$80,$80,$80,$80,$80,$FF ; Custom character 'BORDER SOUTHWEST' 02694 .BYTE $00,$3C,$20,$20,$78,$60,$60,$7C ; Custom character 'E' 02695 .BYTE $00,$66,$99,$99,$99,$66,$00,$00 ; Custom character 'INFINITY' 02696 .BYTE $00,$00,$00,$7E,$00,$00,$00,$00 ; Custom character '-' 02697 .BYTE $00,$18,$18,$18,$7E,$18,$18,$18 ; Custom character '+' 02698 .BYTE $00,$18,$7E,$DB,$99,$DB,$7E,$18 ; Custom character 'PHI' 02699 .BYTE $66,$66,$66,$66,$66,$2C,$38,$30 ; Custom character 'V' 02700 .BYTE $00,$7C,$44,$44,$7C,$68,$6C,$6C ; Custom character 'R' 02701 .BYTE $00,$1C,$3E,$63,$5D,$63,$3E,$1C ; Custom character 'THETA' 02702 .BYTE $00,$46,$46,$44,$7C,$64,$66,$66 ; Custom character 'K' 02703 .BYTE $FE,$92,$10,$18,$18,$18,$18,$18 ; Custom character 'T' 02704 .BYTE $FC,$8C,$8C,$80,$80,$80,$84,$FC ; Custom character 'C' 02705 .BYTE $00,$00,$00,$00,$00,$00,$00,$FF ; Custom character 'BORDER SOUTH' 02706 .BYTE $80,$80,$80,$80,$80,$80,$80,$80 ; Custom character 'BORDER WEST' 02707 .BYTE $00,$00,$00,$00,$00,$00,$00,$80 ; Custom character 'CORNER SOUTHWEST' 02708 .BYTE $80,$AA,$9C,$BE,$9C,$AA,$80,$FF ; Custom character 'STARBASE SECTOR' 02709 .BYTE $80,$98,$80,$B6,$80,$8C,$80,$FF ; Custom character '4-ZYLON SECTOR' 02710 .BYTE $80,$8E,$80,$B8,$80,$9C,$80,$FF ; Custom character '3-CYCLON SECTOR' 02711 .BYTE $80,$B0,$98,$BE,$98,$B0,$80,$FF ; Custom character '2-ZYLON SECTOR' 02712 02713 ;*** Header text of Long-Range Scan view (shares spaces with following header) * 02714 LRSHEADER .BYTE $00,$00,$6C,$6F,$6E,$67,$00,$72 ; " LONG RANGE SCAN" 02715 .BYTE $61,$6E,$67,$65,$00,$73,$63,$61 02716 .BYTE $6E 02717 02718 ;*** Header text of Aft view (shares spaces with following header) ************* 02719 AFTHEADER .BYTE $00,$00,$00,$00,$00,$00,$61,$66 ; " AFT VIEW " 02720 .BYTE $74,$00,$76,$69,$65,$77,$00,$00 02721 .BYTE $00 02722 02723 ;*** Header text of Galactic Chart view **************************************** 02724 GCHEADER .BYTE $00,$00,$00,$67,$61,$6C,$61,$63 ; " GALACTIC CHART " 02725 .BYTE $74,$69,$63,$00,$63,$68,$61,$72 02726 .BYTE $74,$00,$00,$00 02727 02728 ;*** Display List of Galactic Chart view *************************************** 02729 DLSTGC .BYTE $60 ; BLK7 02730 .BYTE $46,GCHEADER ; GR2 @ GCHEADER 02731 .BYTE $F0 ; BLK8 + DLI 02732 .BYTE $47,GCPFMEM ; GR1 @ GCPFMEM 02733 .BYTE $07 ; GR1 02734 .BYTE $07 ; GR1 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 $80 ; BLK1 + DLI 02742 .BYTE $46,TITLETXT ; GR2 @ TITLETXT 02743 .BYTE $46,GCTXT ; GR2 @ GCTXT 02744 .BYTE $06 ; GR2 02745 .BYTE $06 ; GR2 02746 .BYTE $41,DSPLST ; JMP @ DSPLST 02747 02748 ;******************************************************************************* 02749 ;* * 02750 ;* G A M E C O D E * 02751 ;* * 02752 ;******************************************************************************* 02753 02754 ;******************************************************************************* 02755 ;* * 02756 ;* INITCOLD * 02757 ;* * 02758 ;* Initialize program (Cold start) * 02759 ;* * 02760 ;******************************************************************************* 02761 02762 ; DESCRIPTION 02763 ; 02764 ; Initializes the program, then continues into the game loop at GAMELOOP 02765 ; ($A1F3). 02766 ; 02767 ; There are four entry points to initialization: 02768 ; 02769 ; (1) INITCOLD ($A14A) is entered at initial cartridge startup (cold start). 02770 ; This initializes POKEY, resets the idle counter, sets the mission level 02771 ; to NOVICE mission, and clears the function key code. POKEY is enabled to 02772 ; receive keyboard input. Code execution continues into INITSELECT ($A15A) 02773 ; below. 02774 ; 02775 ; (2) INITSELECT ($A15A) is entered from GAMELOOP ($A1F3) after the SELECT 02776 ; function key has been pressed. This loads the title phrase offset for the 02777 ; copyright notice. Code execution continues into INITDEMO ($A15C) below. 02778 ; 02779 ; (3) INITDEMO ($A15C) is entered when the program switches into demo mode. 02780 ; This loads the demo mode flag. Code execution continues into INITSTART 02781 ; ($A15E) below. 02782 ; 02783 ; (4) INITSTART ($A15E) is entered from GAMELOOP ($A1F3) after the START 02784 ; function key has been pressed. This enqueues the new title phrase and 02785 ; enables or disables demo mode, depending on the preloaded value. 02786 ; 02787 ; Initialization continues with the following steps: 02788 ; 02789 ; (1) Clear the custom chip registers and zero-page program variables from 02790 ; ISVBISYNC ($0067) on. 02791 ; 02792 ; NOTE: Because of loop jamming there is a loop index overshoot. Instead of 02793 ; clearing memory at addresses $0067..$00FB, the memory at addresses 02794 ; $0067..$0166 is cleared. This does no harm because $0100..$0166 is a yet 02795 ; unused part of the 6502 CPU stack. 02796 ; 02797 ; NOTE: At address $A175 a hack is necessary in the source code to fake a 02798 ; STA ISVBISYNC,X instruction with a 16-bit address. ISVBISYNC ($0067) is a 02799 ; zero-page address and regular assemblers would translate STA ISVBISYNC,X 02800 ; into the byte sequence $95 $67, not $9D $67 $00. This indicates that the 02801 ; original ROM was maybe created using a special assembler, perhaps a 02802 ; cross-assembler. 02803 ; 02804 ; (2) Initialize the 6502 CPU (reset the stack pointer, disable decimal mode). 02805 ; 02806 ; (3) Clear program memory from $0200..$1FFF in subroutine CLRMEM ($AE0F). 02807 ; 02808 ; (4) Set the address vectors of the IRQ, VBI, and DLI handlers. 02809 ; 02810 ; (5) Enable input from Joystick 0. 02811 ; 02812 ; (6) Enable Player/Missile graphics, providing a fifth PLAYER. 02813 ; 02814 ; BUG (at $A1A6): The set PLAYER-PLAYFIELD priority arranges PLAYERs in 02815 ; front of the PLAYFIELD. This makes sense as space objects represented by 02816 ; PLAYERs (for example, Zylon ships, photon torpedoes, and meteors) move in 02817 ; front of the stars, which are part of the PLAYFIELD. However, PLAYERs 02818 ; also move in front of the cross hairs, which are also part of the 02819 ; PLAYFIELD. Suggested fix: None, technically not possible. 02820 ; 02821 ; (7) Do more initialization in subroutine INITIALIZE ($B3BA). 02822 ; 02823 ; (8) Set display to Front view. 02824 ; 02825 ; (9) Show or hide the Control Panel Display (bottom text window) in subroutine 02826 ; MODDLST ($ADF1), depending on the demo mode flag. 02827 ; 02828 ; (10) Initialize our starship's velocity equivalent to speed key '6'. 02829 ; 02830 ; (11) Enable the Display List. 02831 ; 02832 ; (12) Initialize the number of space objects to 16 (5 PLAYER space objects + 12 02833 ; PLAYFIELD space objects (stars)). 02834 ; 02835 ; (13) Set the title phrase to the selected mission level in subroutine SETTITLE 02836 ; ($B223). 02837 ; 02838 ; (14) Enable the IRQ, DLI, and VBI interrupts. 02839 ; 02840 ; Code execution continues into the game loop at GAMELOOP ($A1F3). 02841 02842 INITCOLD LDA #0 ; 02843 STA SKCTL ; POKEY: Initialization 02844 STA IDLECNTHI ; Reset idle counter 02845 STA MISSIONLEVEL ; Mission level := NOVICE mission 02846 STA FKEYCODE ; Clear function key code 02847 LDA #$03 ; POKEY: Enable keyboard scan and debounce 02848 STA SKCTL ; 02849 02850 ;*** Entry point when SELECT function key was pressed ************************** 02851 INITSELECT LDY #$2F ; Prep title phrase "COPYRIGHT ATARI 1979" 02852 02853 ;*** Entry point when program switches into demo mode ************************** 02854 INITDEMO LDA #$FF ; Prep demo mode flag 02855 02856 ;*** Entry point when START function key was pressed *************************** 02857 INITSTART STY NEWTITLEPHR ; Enqueue new title phrase 02858 STA ISDEMOMODE ; Store demo mode flag 02859 02860 ;*** More initialization ******************************************************* 02861 LDA #0 ; Clear custom chip registers, zero-page variables 02862 TAX ; 02863 LOOP001 STA HPOSP0,X ; Clear $D000..$D0FF (GTIA registers) 02864 STA DMACTL,X ; Clear $D400..$D4FF (ANTIC registers) 02865 CPX #$0F ; 02866 BCS SKIP001 ; 02867 STA AUDF1,X ; Clear $D200..$D20E (POKEY registers) 02868 02869 SKIP001 STA PORTA,X ; Clear $D300..$D3FF (PIA registers) 02870 ; Clear $0067..$0166 (zero-page program variables) 02871 .BYTE $9D ; HACK: Fake STA ISVBISYNC,X with 16-bit address 02872 .WORD ISVBISYNC ; 02873 INX ; 02874 BNE LOOP001 ; 02875 02876 DEX ; Reset 6502 CPU stack pointer 02877 TXS ; 02878 02879 CLD ; Clear 6502 CPU decimal mode 02880 02881 LDA #$02 ; Clear $0200..$1FFF (program memory) 02882 JSR CLRMEM ; 02883 02884 LDA #IRQHNDLR ; 02887 STA VIMIRQ+1 ; 02888 02889 LDA #VBIHNDLR ; 02894 STA VVBLKI+1 ; 02895 LDA #>DLSTHNDLR ; 02896 STA VDSLST+1 ; 02897 02898 LDA #$04 ; PIA: Enable PORTA (Joystick 0) 02899 STA PACTL ; 02900 LDA #$11 ; GTIA: Enable PLAYER4, prio: PLs > PFs > BGR (!) 02901 STA PRIOR ; (PLAYERs appear behind cross hairs) 02902 LDA #$03 ; GTIA: Enable DMA for PLAYERs and MISSILEs 02903 STA GRACTL ; 02904 02905 JSR INITIALIZE ; Init Display List, tables, Galactic Chart, etc. 02906 02907 LDX #$0A ; Set Front view 02908 JSR SETVIEW ; 02909 02910 LDA ISDEMOMODE ; If in/not in demo mode hide/show... 02911 AND #$80 ; ...Control Panel Display (bottom text window) 02912 TAY ; 02913 LDX #$5F ; 02914 LDA #$08 ; 02915 JSR MODDLST ; 02916 02917 LDA #32 ; Init our starship's velocity (= speed key '6') 02918 STA NEWVELOCITY ; 02919 02920 LDA #DSPLST ; 02923 STA DLIST+1 ; 02924 02925 LDA #$3E ; ANTIC: Enable Display List DMA, single-line PM 02926 STA DMACTL ; resolution, PM DMA, normal-width PLAYFIELD 02927 02928 LDA #0 ; ANTIC: Set PM memory base address 02929 STA PMBASE ; 02930 02931 LDA #NUMSPCOBJ.NORM-1 ; Set normal number of space objects 02932 STA MAXSPCOBJIND ; (5 PLAYER spc objs + 12 PLAYFIELD spc objs (stars)) 02933 02934 LDX MISSIONLEVEL ; Set title phrase 02935 LDY MISSIONPHRTAB,X ; NOVICE, PILOT, WARRIOR, or COMMANDER MISSION 02936 JSR SETTITLE ; 02937 02938 LDA #$40 ; POKEY: Enable keyboard interrupt (IRQ) 02939 STA IRQEN ; 02940 02941 CLI ; Enable all IRQs 02942 02943 LDA #$C0 ; ANTIC: Enable DLI and VBI 02944 STA NMIEN ; 02945 02946 ;******************************************************************************* 02947 ;* * 02948 ;* GAMELOOP * 02949 ;* * 02950 ;******************************************************************************* 02951 02952 ; DESCRIPTION 02953 ; 02954 ; The game loop is the main part of the program. It is basically an infinite 02955 ; loop that collects input, computes the game state, and updates the display. It 02956 ; executes the following steps: 02957 ; 02958 ; (1) Synchronize the start of the game loop with the vertical blank phase of 02959 ; the TV beam, which flagged by the Vertical Blank Interrupt handler 02960 ; VBIHNDLR ($A6D1). This prevents screen flicker while the PLAYFIELD is 02961 ; redrawn at the begin of the game loop, because during the vertical blank 02962 ; phase the TV beam is turned off and nothing is rendered on the TV 02963 ; display. 02964 ; 02965 ; (2) Erase all PLAYFIELD space objects (stars, explosion fragments) from the 02966 ; PLAYFIELD that were drawn in the previous game loop iteration. 02967 ; 02968 ; (3) Draw the updated PLAYFIELD space objects (stars, explosion fragments) 02969 ; into the PLAYFIELD (skip this if in hyperspace). 02970 ; 02971 ; (4) If the idle counter has reached its trigger value then clear the center 02972 ; of the PLAYFIELD, an 8 x 2 pixel rectangle with a top-left position at 02973 ; pixel column number 76 and pixel row number 49 (?). 02974 ; 02975 ; (5) Clear all PLAYER shapes. 02976 ; 02977 ; (6) Update the vertical position of all PLAYERs and update all PLAYER shapes. 02978 ; 02979 ; (7) Update the horizontal position of all PLAYERs. 02980 ; 02981 ; (8) Rotate the position vector of all space objects horizontally and 02982 ; vertically, according to the saved joystick position (skip this if in 02983 ; Galactic Chart view) using subroutine ROTATE ($B69B). 02984 ; 02985 ; (9) Move our starship forward in space. Our starship is always located at the 02986 ; center of the program's 3D coordinate system, so all space objects are 02987 ; moved along the z-axis toward our starship by subtracting a displacement 02988 ; from their z-coordinate. The amount of the displacement depends on our 02989 ; starship's velocity. 02990 ; 02991 ; BUG (at $A3C1): This operation is not applied to Photon torpedoes (?). 02992 ; Suggested fix: Remove LDA PL0SHAPTYPE,X and BEQ SKIP011. 02993 ; 02994 ; (10) Add the proper velocity vector of all space objects to their position 02995 ; vector (except for stars, which do not have any proper motion). 02996 ; 02997 ; BUG (at $A419): The correct maximum loop index is NUMSPCOBJ.ALL*3 = 147 02998 ; instead of 144. Suggested fix: Replace CMP #144 with CMP #147. 02999 ; 03000 ; (11) Correct the position vector components (coordinates) of all PLAYER space 03001 ; objects if they have over- or underflowed during the calculations of the 03002 ; previous steps. 03003 ; 03004 ; (12) Calculate the perspective projection of the position vectors of all space 03005 ; objects and from that their pixel row and column number (applies to Front 03006 ; and Aft view) using subroutines PROJECTION ($AA21), SCREENCOLUMN ($B6FB), 03007 ; and SCREENROW ($B71E). If a space object (star, explosion fragment) moved 03008 ; offscreen then a new space object is automatically created in subroutine 03009 ; SCREENCOLUMN ($B6FB). 03010 ; 03011 ; (13) Handle hyperwarp marker selection in the Galactic Chart view in 03012 ; subroutine SELECTWARP ($B162). 03013 ; 03014 ; (14) If in Long-Range Scan view, compute the pixel column number and the pixel 03015 ; row number of all PLAYFIELD space objects (stars, explosion fragments) on 03016 ; the plane established by the z and x axis of the 3D coordinate system 03017 ; using subroutines SCREENCOLUMN ($B6FB) and SCREENROW ($B71E). Our 03018 ; starship's shape is drawn using subroutine DRAWLINES ($A76F). If the 03019 ; Long-Range Scan is OK then PLAYFIELD space object pixel numbers are 03020 ; computed and drawn. This is skipped if the Long-Range Scan is destroyed. 03021 ; 03022 ; (15) Update all PLAYER shapes, heights, and colors (see detailed description 03023 ; below). 03024 ; 03025 ; (16) Flash a red alert when leaving hyperspace into a sector containing Zylon 03026 ; ships by setting appropriate colors to PLAYFIELD2 and BACKGROUND. 03027 ; 03028 ; (17) Update the color of all PLAYFIELD space objects (stars, explosion 03029 ; fragments). The color calculation is similar to that of the PLAYER color 03030 ; calculation in (15). It also computes a range index and uses the same 03031 ; color lookup table FOURCOLORPIXEL ($BA90). If a star in the Aft view 03032 ; became too distant (z-coordinate < -$F000 (-4096) ) its position is 03033 ; re-initialized in subroutine INITPOSVEC ($B764). 03034 ; 03035 ; (18) If in demo mode skip input handling and jump directly to function key 03036 ; handling (28). 03037 ; 03038 ; (19) Handle keyboard input in subroutine KEYBOARD ($AFFE). 03039 ; 03040 ; (20) Handle joystick input. Store the current joystick directions in JOYSTICKX 03041 ; ($C8) and JOYSTICKY ($C9). 03042 ; 03043 ; (21) Check if our starship's photon torpedoes have hit a target in subroutine 03044 ; COLLISION ($AF3D). This subroutine triggers a game over if all Zylon 03045 ; ships have been destroyed. 03046 ; 03047 ; (22) Handle the joystick trigger in subroutine TRIGGER ($AE29). 03048 ; 03049 ; (23) Handle the Attack Computer and Tracking Computer. If the Attack Computer 03050 ; is neither destroyed nor switched off then execute the following steps: 03051 ; 03052 ; o Update the Attack Computer Display's blip and lock-on markers in 03053 ; subroutine UPDATTCOMP ($A7BF) (if in Front view). 03054 ; 03055 ; o Update the tracking index of the currently tracked PLAYER space 03056 ; object. If a Zylon ship is tracked, then make sure to always track 03057 ; the Zylon ship that launched the last Zylon photon torpedo. If this 03058 ; Zylon ship is not alive then track the other Zylon ship - if alive. 03059 ; 03060 ; o If the Tracking Computer is on then switch to the view that shows the 03061 ; tracked PLAYER space object by emulating pressing the 'F' (Front 03062 ; view) or 'A' (Aft view) key (only if in Front or Aft view). 03063 ; 03064 ; (24) Handle docking at a starbase in subroutine DOCKING ($ACE6). 03065 ; 03066 ; (25) Handle maneuvering both of our starship's photon torpedoes, the single 03067 ; Zylon photon torpedo, and the attacking Zylon ships in subroutine 03068 ; MANEUVER ($AA79). This subroutine also automatically creates meteors and 03069 ; new Zylon ships. 03070 ; 03071 ; (26) Check if our starship was hit by a Zylon photon torpedo (skip this if in 03072 ; a starbase sector): Its x, y, and z coordinates must be within a range of 03073 ; -($0100)..+$00FF (-256..+255) of our starship. 03074 ; 03075 ; (27) If our starship was hit then execute the following steps: 03076 ; 03077 ; o Damage or destroy one of our starship's subsystems in subroutine 03078 ; DAMAGE ($AEE1). 03079 ; 03080 ; o Trigger an explosion in subroutine INITEXPL ($AC6B), 03081 ; 03082 ; o Store the severity of the hit. 03083 ; 03084 ; o End the lifetime of the Zylon photon torpedo. 03085 ; 03086 ; o Subtract 100 energy units for being hit by the Zylon photon torpedo 03087 ; in subroutine DECENERGY ($B86F). 03088 ; 03089 ; o Trigger the noise sound pattern SHIELD EXPLOSION in subroutine NOISE 03090 ; ($AEA8). 03091 ; 03092 ; If the Shields were down during the hit, our starship is destroyed. 03093 ; Execute the following steps: 03094 ; 03095 ; o Switch to Front view. 03096 ; 03097 ; o Flash the title phrase "SHIP DESTROYED BY ZYLON FIRE". 03098 ; 03099 ; o Add the mission bonus to the internal game score in subroutine 03100 ; GAMEOVER ($B10A). 03101 ; 03102 ; o Hide the Control Panel Display (bottom text window) in subroutine 03103 ; MODDLST ($ADF1). 03104 ; 03105 ; o Clear the PLAYFIELD in subroutine CLRPLAYFIELD ($AE0D). 03106 ; 03107 ; o Enable the STARSHIP EXPLOSION noise. 03108 ; 03109 ; (28) Handle the function keys START and SELECT. If SELECT has been pressed 03110 ; cycle through the next of the 4 mission levels. If either START or SELECT 03111 ; have been pressed, reset the idle counter, then jump to the corresponding 03112 ; program initialization subroutines INITSTART ($A15E) or INITSELECT 03113 ; ($A15A), respectively. 03114 ; 03115 ; (29) Update the Control Panel Display in subroutine UPDPANEL ($B804). 03116 ; 03117 ; (30) Handle hyperwarp in subroutine HYPERWARP ($A89B). 03118 ; 03119 ; (31) Update the text in the title line in subroutine UPDTITLE ($B216). 03120 ; 03121 ; (32) Move Zylon units, decrease lifetime of photon torpedoes, elapse game 03122 ; time, etc. in subroutine FLUSHGAMELOOP ($B4E4). This subroutine also 03123 ; triggers a game over if our starship's energy is zero. 03124 ; 03125 ; (33) Jump back to the start of the game loop for the next game loop iteration. 03126 03127 L.HEIGHTCNT = $6A ; Height counter during copying a PLAYER shape 03128 L.ZPOSOFF = $6E ; Offset to z-coordinate 03129 L.VELOCITYHI = $6B ; Velocity vector component (high byte) 03130 L.VECCOMPIND = $6A ; Position vector component index. Used values are: 03131 ; 0 -> z-component 03132 ; 1 -> x-component 03133 ; 2 -> y-component 03134 L.RANGEINDEX = $6A ; Range index for space object, computed from the 03135 ; distance to our starship. Used to pick the shape 03136 ; cell index of the PLAYERs shape data and shape 03137 ; height. Used values are: 0..15. 03138 L.FOURCOLORPIX = $6A ; 1-byte bit pattern for 4 pixels of same color 03139 L.COLORMASK = $6B ; Color/brightness to modify PLAYER color 03140 03141 ;*** (1) Synchronize game loop with execution of VBI *************************** 03142 GAMELOOP LDA ISVBISYNC ; Wait for execution of VBI 03143 BEQ GAMELOOP ; 03144 03145 LDA #0 ; VBI is executed, clear VBI sync flag 03146 STA ISVBISYNC ; 03147 03148 ;*** (2) Erase PLAYFIELD space objects (stars, explosion fragments) ************ 03149 LDA OLDMAXSPCOBJIND ; Skip if no space objects in use 03150 BEQ SKIP002 ; 03151 03152 LDX #NUMSPCOBJ.PL-1 ; Loop over all PLAYFIELD space objs (X index > 4) 03153 LOOP002 INX ; 03154 LDY PIXELROW,X ; Load pixel row number of PLAYFIELD space object 03155 03156 LDA PFMEMROWLO,Y ; Point MEMPTR to start of pixel's row... 03157 STA MEMPTR ; ...in PLAYFIELD memory 03158 LDA PFMEMROWHI,Y ; 03159 STA MEMPTR+1 ; 03160 03161 LDY PIXELBYTEOFF,X ; Get within-row-offset to byte with space obj pixel 03162 LDA PIXELSAVE,X ; Load saved byte 03163 STA (MEMPTR),Y ; Restore byte of PLAYFIELD memory 03164 03165 CPX OLDMAXSPCOBJIND ; 03166 BCC LOOP002 ; Next PLAYFIELD space object 03167 03168 LDA #0 ; Clear number of space objects 03169 STA OLDMAXSPCOBJIND ; 03170 03171 ;*** (3) Draw PLAYFIELD space objects (stars, explosion fragments) ************* 03172 SKIP002 LDA WARPSTATE ; Skip during hyperspace 03173 BMI SKIP003 ; 03174 03175 LDX MAXSPCOBJIND ; Update number of space objects 03176 STX OLDMAXSPCOBJIND ; 03177 03178 LOOP003 LDA PIXELROWNEW,X ; Loop over all PLAYFIELD space objs (X index > 4) 03179 STA PIXELROW,X ; Update pixel row number of PLAYFIELD space object 03180 03181 TAY ; 03182 LDA PFMEMROWLO,Y ; Point MEMPTR to start of pixel's row... 03183 STA MEMPTR ; ...in PLAYFIELD memory 03184 LDA PFMEMROWHI,Y ; 03185 STA MEMPTR+1 ; 03186 03187 LDA PIXELCOLUMN,X ; Convert pixel column number to within-row-offset 03188 LSR A ; ...of byte with space obj pixel (4 pixels = 1 byte) 03189 LSR A ; 03190 STA PIXELBYTEOFF,X ; Store within-row-offset 03191 03192 TAY ; 03193 LDA (MEMPTR),Y ; Load pixel's byte from PLAYFIELD memory 03194 STA PIXELSAVE,X ; Save it (for restoring it in next game loop) 03195 ORA PIXELBYTE,X ; Blend with pixel's color bit-pattern 03196 STA (MEMPTR),Y ; Store byte in PLAYFIELD memory 03197 03198 DEX ; 03199 CPX #NUMSPCOBJ.PL-1 ; 03200 BNE LOOP003 ; Next PLAYFIELD space object 03201 03202 ;*** (4) Clear PLAYFIELD center if idle counter is up (?) ********************** 03203 ; PLAYFIELD addresses of... 03204 PFMEM.C76R49 = PFMEM+49*40+76/4 ; ...pixel column number 76, row number 49 03205 PFMEM.C80R49 = PFMEM+49*40+80/4 ; ...pixel column number 80, row number 49 03206 PFMEM.C76R50 = PFMEM+50*40+76/4 ; ...pixel column number 76, row number 50 03207 PFMEM.C80R50 = PFMEM+50*40+80/4 ; ...pixel column number 80, row number 50 03208 03209 SKIP003 LDA IDLECNTHI ; Skip if idle counter not negative 03210 BPL SKIP004 ; 03211 03212 LDA #0 ; Clear pixels of 8 x 2 pixel rectangle... 03213 STA PFMEM.C76R50 ; ...@ column number 76, row number 49 (?) 03214 STA PFMEM.C80R50 ; 03215 STA PFMEM.C80R49 ; 03216 STA PFMEM.C76R49 ; 03217 03218 ;*** (5) Clear all PLAYER shapes *********************************************** 03219 SKIP004 LDA #0 ; Clear shape of PLAYER4 03220 LDY PL4ROW ; 03221 LDX PL4HEIGHT ; 03222 LOOP004 STA PL4DATA,Y ; 03223 INY ; 03224 DEX ; 03225 BPL LOOP004 ; 03226 03227 LDY PL3ROW ; Clear shape of PLAYER3 03228 LDX PL3HEIGHT ; 03229 LOOP005 STA PL3DATA,Y ; 03230 INY ; 03231 DEX ; 03232 BPL LOOP005 ; 03233 03234 LDY PL2ROW ; Clear shape of PLAYER2 03235 LDX PL2HEIGHT ; 03236 LOOP006 STA PL2DATA,Y ; 03237 INY ; 03238 DEX ; 03239 BPL LOOP006 ; 03240 03241 LDY PL1ROW ; Clear shape of PLAYER1 03242 LDX PL1HEIGHT ; 03243 LOOP007 STA PL1DATA,Y ; 03244 INY ; 03245 DEX ; 03246 BPL LOOP007 ; 03247 03248 LDY PL0ROW ; Clear shape of PLAYER0 03249 LDX PL0HEIGHT ; 03250 LOOP008 STA PL0DATA,Y ; 03251 INY ; 03252 DEX ; 03253 BPL LOOP008 ; 03254 03255 ;*** (6) Update PLAYER vertical positions and update PLAYER shapes ************* 03256 LDA PL4SHAPTYPE ; CARRY := PLAYER4 a PHOTON TORPEDO (shape type 0)? 03257 CMP #1 ; 03258 LDY PL4SHAPOFF ; Load PLAYER4 shape data offset 03259 03260 LDX PL4ROWNEW ; Update vertical position of PLAYER4 03261 STX PL4ROW ; 03262 03263 LDA PL4HEIGHTNEW ; Update PLAYER4 shape height 03264 STA L.HEIGHTCNT ; 03265 STA PL4HEIGHT ; 03266 03267 LOOP009 LDA PLSHAP1TAB,Y ; Load PLAYER4 shape byte from shape data table 03268 BCS SKIP005 ; Skip if PLAYER4 not PHOTON TORPEDO (shape type 0) 03269 AND RANDOM ; AND random bits to shape byte 03270 SKIP005 STA PL4DATA,X ; Store shape byte in PLAYER4 data area 03271 INY ; 03272 INX ; 03273 DEC L.HEIGHTCNT ; 03274 BPL LOOP009 ; Next row of PLAYER4 shape 03275 03276 LDA PL3SHAPTYPE ; Repeat above with PLAYER3 03277 CMP #1 ; 03278 LDY PL3SHAPOFF ; 03279 LDX PL3ROWNEW ; 03280 STX PL3ROW ; 03281 LDA PL3HEIGHTNEW ; 03282 STA L.HEIGHTCNT ; 03283 STA PL3HEIGHT ; 03284 LOOP010 LDA PLSHAP1TAB,Y ; 03285 BCS SKIP006 ; 03286 AND RANDOM ; 03287 SKIP006 STA PL3DATA,X ; 03288 INX ; 03289 INY ; 03290 DEC L.HEIGHTCNT ; 03291 BPL LOOP010 ; 03292 03293 LDA PL2SHAPTYPE ; Repeat above with PLAYER2 03294 CMP #1 ; 03295 LDY PL2SHAPOFF ; 03296 LDX PL2ROWNEW ; 03297 STX PL2ROW ; 03298 LDA PL2HEIGHTNEW ; 03299 STA L.HEIGHTCNT ; 03300 STA PL2HEIGHT ; 03301 LOOP011 LDA PLSHAP1TAB,Y ; 03302 BCS SKIP007 ; 03303 AND RANDOM ; 03304 SKIP007 STA PL2DATA,X ; 03305 INX ; 03306 INY ; 03307 DEC L.HEIGHTCNT ; 03308 BPL LOOP011 ; 03309 03310 LDY PL1SHAPOFF ; Repeat above with PLAYER1 (without torpedo part) 03311 LDX PL1ROWNEW ; 03312 STX PL1ROW ; 03313 LDA PL1HEIGHTNEW ; 03314 STA L.HEIGHTCNT ; 03315 STA PL1HEIGHT ; 03316 LOOP012 LDA PLSHAP2TAB,Y ; 03317 STA PL1DATA,X ; 03318 INX ; 03319 INY ; 03320 DEC L.HEIGHTCNT ; 03321 BPL LOOP012 ; 03322 03323 LDY PL0SHAPOFF ; Repeat above with PLAYER0 (without torpedo part) 03324 LDX PL0ROWNEW ; 03325 STX PL0ROW ; 03326 LDA PL0HEIGHTNEW ; 03327 STA L.HEIGHTCNT ; 03328 STA PL0HEIGHT ; 03329 LOOP013 LDA PLSHAP2TAB,Y ; 03330 STA PL0DATA,X ; 03331 INX ; 03332 INY ; 03333 DEC L.HEIGHTCNT ; 03334 BPL LOOP013 ; 03335 03336 ;*** (7) Update PLAYER horizontal positions ************************************ 03337 LDA PL0COLUMN ; Update horizontal position of PLAYER0 03338 STA HPOSP0 ; 03339 LDA PL1COLUMN ; Update horizontal position of PLAYER1 03340 STA HPOSP1 ; 03341 LDA PL2COLUMN ; Update horizontal position of PLAYER2 03342 STA HPOSP2 ; 03343 LDA PL3COLUMN ; Update horizontal position of PLAYER3 03344 STA HPOSP3 ; 03345 LDA PL4COLUMN ; Update horizontal position of PLAYER4 03346 STA HPOSM3 ; 03347 CLC ; 03348 ADC #2 ; 03349 STA HPOSM2 ; 03350 ADC #2 ; 03351 STA HPOSM1 ; 03352 ADC #2 ; 03353 STA HPOSM0 ; 03354 03355 ;*** (8) Rotate space objects horizontally and vertically ********************** 03356 BIT SHIPVIEW ; Skip if in Galactic Chart view 03357 BMI SKIP009 ; 03358 03359 ;*** Rotate horizontally ******************************************************* 03360 LDA JOYSTICKX ; Skip if joystick centered horizontally 03361 BEQ SKIP008 ; 03362 03363 STA JOYSTICKDELTA ; Save JOYSTICKX (used in subroutine ROTATE) 03364 LDY MAXSPCOBJIND ; Loop over all space objects in use 03365 LOOP014 STY L.ZPOSOFF ; Save offset to z-coordinate 03366 CLC ; 03367 03368 TYA ; 03369 TAX ; X := offset to z-coordinate 03370 ADC #NUMSPCOBJ.ALL ; 03371 TAY ; Y := offset to x-coordinate 03372 JSR ROTATE ; Calc new x-coordinate (horizontal rot @ y-axis) 03373 03374 TYA ; 03375 TAX ; X := offset to x-coordinate 03376 LDY L.ZPOSOFF ; Y := offset to z-coordinate 03377 JSR ROTATE ; Calc new z-coordinate (horizontal rot @ y-axis) 03378 DEY ; 03379 BPL LOOP014 ; Next space object 03380 03381 ;*** Rotate vertically ********************************************************* 03382 SKIP008 LDA JOYSTICKY ; Skip if joystick centered vertically 03383 BEQ SKIP009 ; 03384 03385 STA JOYSTICKDELTA ; Save JOYSTICKY (used in subroutine ROTATE) 03386 LDY MAXSPCOBJIND ; Loop over all space objects in use 03387 LOOP015 STY L.ZPOSOFF ; Save offset to z-coordinate 03388 CLC ; 03389 03390 TYA ; 03391 TAX ; X := offset to z-coordinate 03392 ADC #NUMSPCOBJ.ALL*2 ; 03393 TAY ; Y := offset to y-coordinate 03394 JSR ROTATE ; Calc new y-coordinate (vertical rot @ x-axis) 03395 03396 TYA ; 03397 TAX ; X := offset to y-coordinate 03398 LDY L.ZPOSOFF ; Y := offset to z-coordinate 03399 JSR ROTATE ; Calc new z-coordinate (vertical rot @ x-axis) 03400 DEY ; 03401 BPL LOOP015 ; Next space object 03402 03403 ;*** (9) Move all space objects along z-axis (toward our starship) ************* 03404 SKIP009 LDX MAXSPCOBJIND ; Loop over all space objects in use 03405 LOOP016 CPX #NUMSPCOBJ.PL ; Skip if PLAYFIELD space object (X index > 4) 03406 BCS SKIP010 ; 03407 03408 LDA PL0SHAPTYPE,X ; Skip if next PLAYER space obj is PHOTON TORPEDO (!) 03409 BEQ SKIP011 ; 03410 03411 SKIP010 SEC ; New z-coordinate := old z-coordinate - 03412 LDA ZPOSLO,X ; ...our starship's velocity 03413 SBC VELOCITYLO ; (signed 24-bit subtraction) 03414 STA ZPOSLO,X ; 03415 LDA ZPOSHI,X ; 03416 SBC VELOCITYHI ; 03417 STA ZPOSHI,X ; 03418 LDA ZPOSSIGN,X ; 03419 SBC #0 ; 03420 STA ZPOSSIGN,X ; 03421 03422 SKIP011 DEX ; 03423 BPL LOOP016 ; Next space object 03424 03425 ;*** (10) Add space object's velocity vector to space object's position vector * 03426 LDX MAXSPCOBJIND ; Loop over all space objects in use 03427 LOOP017 CPX #NUMSPCOBJ.NORM-1 ; Skip if space object is star (X index 5..16)... 03428 BNE SKIP012 ; ...because stars don't move by themselves 03429 LDX #4 ; 03430 03431 SKIP012 TXA ; 03432 LOOP018 TAY ; Loop over all 3 coordinates 03433 03434 LDA #0 ; Expand 8-bit velocity vector component to 16-bit: 03435 STA L.VELOCITYHI ; ...16-bit velocity (high byte) = L.VELOCITYHI := 0 03436 LDA ZVEL,Y ; ...16-bit velocity (low byte) = A := ZVEL,Y 03437 BPL SKIP013 ; Skip if 16-bit velocity >= 0 (positive) 03438 03439 EOR #$7F ; 16-bit velocity < 0 (negative)... 03440 CLC ; ...calculate two's-complement of 16-bit velocity 03441 ADC #1 ; 03442 BCS SKIP013 ; 03443 DEC L.VELOCITYHI ; 03444 03445 SKIP013 CLC ; New coordinate := old coordinate + 16-bit velocity 03446 ADC ZPOSLO,Y ; (signed 24-bit addition) 03447 STA ZPOSLO,Y ; 03448 LDA ZPOSHI,Y ; 03449 ADC L.VELOCITYHI ; 03450 STA ZPOSHI,Y ; 03451 LDA ZPOSSIGN,Y ; 03452 ADC L.VELOCITYHI ; 03453 STA ZPOSSIGN,Y ; 03454 03455 TYA ; 03456 CLC ; 03457 ADC #NUMSPCOBJ.ALL ; 03458 CMP #144 ; (!) 03459 BCC LOOP018 ; Next coordinate 03460 03461 DEX ; 03462 BPL LOOP017 ; Next space object 03463 03464 ;*** (11) Correct over/underflow of PLAYER space objects' position vector ****** 03465 LDY #NUMSPCOBJ.PL-1 ; 03466 LOOP019 TYA ; Loop over all PLAYER space objects (X index < 5) 03467 TAX ; 03468 03469 LDA #2 ; Loop over all 3 coordinates 03470 STA L.VECCOMPIND ; 03471 03472 LOOP020 LDA ZPOSSIGN,X ; Load sign of coordinate 03473 CMP #2 ; 03474 BCC SKIP015 ; Skip if sign = 0 (negative) or 1 (positive) 03475 03476 ASL A ; SUMMARY: Space object out-of-bounds correction 03477 LDA #0 ; If new coordinate > +65535 subtract 256 03478 STA ZPOSSIGN,X ; ...until new coordinate <= +65535 03479 BCS SKIP014 ; If new coordinate < -65536 add 256 03480 INC ZPOSSIGN,X ; ...until new coordinate >= -65536 03481 EOR #$FF ; 03482 SKIP014 STA ZPOSHI,X ; 03483 03484 SKIP015 TXA ; 03485 CLC ; 03486 ADC #NUMSPCOBJ.ALL ; 03487 TAX ; 03488 DEC L.VECCOMPIND ; 03489 BPL LOOP020 ; Next coordinate 03490 03491 DEY ; 03492 BPL LOOP019 ; Next space object 03493 03494 ;*** (12) Calc perspective projection of space objects ************************* 03495 LDA SHIPVIEW ; Skip if in Long-Range Scan or Galactic Chart view 03496 CMP #$02 ; 03497 BCS SKIP019 ; 03498 03499 LDX MAXSPCOBJIND ; Loop over all space objects in use 03500 LOOP021 LDA #255 ; Prep magic offscreen pixel number value 03501 LDY ZPOSSIGN,X ; Compare sign of z-coordinate with view mode 03502 CPY SHIPVIEW ; 03503 BEQ SKIP018 ; Equal? Space object is offscreen -> New space obj! 03504 03505 LDA YPOSSIGN,X ; Prepare projection division... 03506 BNE SKIP016 ; DIVIDEND (16-bit value) := ABS(y-coordinate) 03507 SEC ; (used in subroutine PROJECTION) 03508 LDA #0 ; 03509 SBC YPOSLO,X ; 03510 STA DIVIDEND ; 03511 LDA #0 ; 03512 SBC YPOSHI,X ; 03513 STA DIVIDEND+1 ; 03514 JMP JUMP001 ; 03515 SKIP016 LDA YPOSLO,X ; 03516 STA DIVIDEND ; 03517 LDA YPOSHI,X ; 03518 STA DIVIDEND+1 ; 03519 03520 JUMP001 JSR PROJECTION ; Calc pixel row number rel. to screen center 03521 JSR SCREENROW ; Calc pixel row number rel. to top-left of screen 03522 03523 LDA XPOSSIGN,X ; Prepare projection division... 03524 BNE SKIP017 ; DIVIDEND (16-bit value) := ABS(x-coordinate) 03525 SEC ; (used in subroutine PROJECTION) 03526 LDA #0 ; 03527 SBC XPOSLO,X ; 03528 STA DIVIDEND ; 03529 LDA #0 ; 03530 SBC XPOSHI,X ; 03531 STA DIVIDEND+1 ; 03532 JMP JUMP002 ; 03533 SKIP017 LDA XPOSLO,X ; 03534 STA DIVIDEND ; 03535 LDA XPOSHI,X ; 03536 STA DIVIDEND+1 ; 03537 03538 JUMP002 JSR PROJECTION ; Calc pixel column number rel. to screen center 03539 SKIP018 JSR SCREENCOLUMN ; Calc pixel column number rel. to top-left of screen 03540 DEX ; 03541 BPL LOOP021 ; Next space object 03542 03543 ;*** (13) Handle hyperwarp marker selection in Galactic Chart view ************* 03544 SKIP019 JSR SELECTWARP ; Handle hyperwarp marker in Galactic Chart view 03545 03546 ;*** (14) Compute and draw Long-Range Scan view star field on z-x plane ******** 03547 BIT SHIPVIEW ; Skip if not in Long-Range Scan view 03548 BVC SKIP022 ; 03549 03550 LDX #$31 ; Draw our starship's shape 03551 JSR DRAWLINES ; 03552 03553 BIT GCSTATLRS ; Skip if Long-Range Scan destroyed 03554 BVS SKIP022 ; 03555 03556 LDX MAXSPCOBJIND ; Loop over all space objects in use 03557 LOOP022 LDA ZPOSHI,X ; Load z-coordinate (high byte) 03558 LDY ZPOSSIGN,X ; Load sign of z-coordinate 03559 BNE SKIP020 ; 03560 EOR #$FF ; A := ABS(z-coordinate (high byte)) 03561 SKIP020 TAY ; 03562 LDA MAPTO80,Y ; Calc pixel row number rel. to screen center 03563 JSR SCREENROW ; Calc pixel row number rel. to top-left of screen 03564 03565 LDA XPOSHI,X ; Load x-coordinate (high byte) 03566 LDY XPOSSIGN,X ; Load sign of x-coordinate 03567 BNE SKIP021 ; 03568 EOR #$FF ; A := ABS(x-coordinate (high byte)) 03569 SKIP021 TAY ; 03570 LDA MAPTO80,Y ; Calc pixel column number rel. to screen center 03571 JSR SCREENCOLUMN ; Calc pixel column number rel. to top-left of screen 03572 03573 DEX ; 03574 BPL LOOP022 ; Next space object 03575 03576 ;*** (15) Update PLAYER shapes, heights, and colors **************************** 03577 03578 ; DESCRIPTION 03579 ; 03580 ; In a loop over all PLAYERs, the following steps are executed: 03581 ; 03582 ; o Clear the PLAYER shape offset and height. 03583 ; 03584 ; o If in Galactic Chart view or in Long-Range Scan view, preload a random 03585 ; color and a magic z-coordinate (distance value) for PLAYER3..4 03586 ; (representing hyperwarp markers in Galactic Chart view and blips in the 03587 ; Long-Range Scan view, like, for example, Zylon ships, meteors - or even 03588 ; the Hyperwarp Target Marker during hyperwarp!). 03589 ; 03590 ; o If in Front or Aft view, execute the following steps: 03591 ; 03592 ; o Skip dead PLAYERs. 03593 ; 03594 ; o Preload the distance value for the remaining live PLAYERs. 03595 ; 03596 ; o If we are in a starbase sector, combine PLAYER0..2 into a three-part 03597 ; starbase shape. Compute the pixel column numbers and pixel row 03598 ; numbers of PLAYER0..1 such that they are arranged left (PLAYER0) and 03599 ; right (PLAYER1) of PLAYER2. In addition, preload a color mask, a 03600 ; counter actually, that will make the starbase pulsate in brightness. 03601 ; 03602 ; BUG (at $A512): The code at $A512 that skips the combination operation for 03603 ; PLAYER2..4 jumps for PLAYER3..4 to SKIP025 at $A52A instead of SKIP026 at 03604 ; $A52E. Thus it stores a color mask which does not only make the starbase 03605 ; PLAYER0..2 pulsate in brightness but also PLAYER3..4 in a starbase sector, 03606 ; for example the transfer vessel, photon torpedoes, etc. - or even the 03607 ; Hyperwarp Target Marker when hyperwarping out of such a sector! Suggested 03608 ; fix: None, code hard to untwist. 03609 ; 03610 ; o After storing the color mask, check if the PLAYER shape is still above the 03611 ; bottom edge of the PLAYFIELD. 03612 ; 03613 ; BUG (at $A534): The test checks the vertical position of the top edge of 03614 ; the PLAYER against the bottom edge of the PLAYFIELD above the Console 03615 ; Panel Display (= Player/Missile pixel row number 204). This is not 03616 ; completely accurate as the Console Panel Display starts at PM pixel row 03617 ; number 208. For example, if you carefully navigate a starbase to the 03618 ; bottom edge of the PLAYFIELD, at a certain point the center of the 03619 ; starbase shape bleeds over the bottom edge of the PLAYFIELD (while 03620 ; sometimes even losing its left and right wings!). Suggested fix: None, as 03621 ; a more elaborate test may consume too many bytes of the cartridge ROM 03622 ; memory in order to fix a rarely noticed visual glitch. 03623 ; 03624 ; o Convert the preloaded distance value of a PLAYER space object closer than 03625 ; $2000 (8192) into a range index of 0..15. PLAYER space objects more 03626 ; distant than $2000 (8192) are skipped and not displayed. 03627 ; 03628 ; Later, this range index will pick not only the correct brightness for the 03629 ; PLAYER (the closer the space object the brighter its PLAYER) but also the 03630 ; correct PLAYER shape cell and height (the closer the space object the 03631 ; larger the PLAYER shape and height). 03632 ; 03633 ; o Update the PLAYER's shape offset and height. On the way to the shape 03634 ; offset and height add the PLAYER's shape type to the range index and 03635 ; divide it by 2 to arrive at the shape offset index and height index (the 03636 ; same value). Use this index to pick the correct shape data and shape 03637 ; heights from a set of shape cells and their corresponding heights, stored 03638 ; in tables PLSHAPOFFTAB ($BE2F) and PLSHPHEIGHTTAB ($BE7F), respectively. 03639 ; 03640 ; Remember that magic distance value used in the Galactic Chart and 03641 ; Long-Range Scan view? Its value of $F2 is actually part of a negative 03642 ; z-coordinate which is inverted to $0D00, leading to a range index of 13, 03643 ; which, after the division by 2, picks shape cell 6. Shape cell 6 (the 03644 ; seventh shape cell) of all space objects (except the starbase) is the 03645 ; Long-Range Scan blip's dot (see PLSHAPOFFTAB ($BE2F) and PLSHPHEIGHTTAB 03646 ; ($BE7F)). 03647 ; 03648 ; o Update the PLAYER's color/brightness by picking the appropriate values 03649 ; with the range index from lookup tables PLSHAPCOLORTAB ($BFD1) and 03650 ; PLSHAPBRITTAB ($BFDB). Apply some special effects to the color/brightness 03651 ; of certain PLAYERs, such as using random colors for Zylon basestars, or 03652 ; using the precomputed pulsating brightness value for a starbase. 03653 03654 SKIP022 LDX #NUMSPCOBJ.PL ; Loop over all PLAYER space objects (X index < 5) 03655 LOOP023 DEX ; 03656 BPL SKIP023 ; Jump into loop body below 03657 JMP JUMP003 ; Loop is finished, skip loop body 03658 03659 ;*** Clear PLAYER shape offsets and heights ************************************ 03660 SKIP023 LDA #0 ; 03661 STA PL0SHAPOFF,X ; Clear PLAYER shape offset 03662 STA PL0HEIGHTNEW,X ; Clear new PLAYER shape height 03663 03664 ;*** Preload stuff for hyperwarp markers and Long-Range Scan blips ************* 03665 BIT SHIPVIEW ; Skip if not in Galactic Chart view 03666 BPL SKIP024 ; 03667 03668 CPX #3 ; Next PLAYER space object if PLAYER0..2 03669 BCC LOOP023 ; 03670 03671 LOOP024 LDA RANDOM ; Prep random color mask for warp markers/LRS blips 03672 LDY #$F2 ; Prep magic z-coordinate for warp markers/LRS blips 03673 BMI SKIP026 ; Unconditional jump 03674 03675 SKIP024 CMP PL0LIFE,X ; Next PLAYER space object if this PLAYER not alive 03676 BEQ LOOP023 ; 03677 03678 BVS LOOP024 ; Skip back if in Long-Range Scan view 03679 03680 ;*** Preload stuff for other views ********************************************* 03681 03682 LDY PL0ZPOSHI,X ; Prep z-coordinate (high byte) 03683 03684 ;*** Combine PLAYER0..2 to starbase shape ************************************** 03685 BIT ISSTARBASESECT ; Skip if no starbase in this sector 03686 BVC SKIP026 ; 03687 03688 CPX #2 ; Skip if PLAYER2..4 03689 BCS SKIP025 ; (!) 03690 03691 LDA PL2COLUMN ; Calc new PM pixel column number for PLAYER0..1: 03692 CLC ; Load PLAYER2 (starbase center) pixel column number 03693 ADC PLSTARBAOFFTAB,X ; ...add PLAYER left/right offset (starbase wings) 03694 STA PL0COLUMN,X ; Store new PM pixel column number of starbase wing 03695 03696 LDA PL2ROWNEW ; Calc new PM pixel row number for PLAYER0..1: 03697 CLC ; Add vertical offset (= 4 PM pixels) to PLAYER2's 03698 ADC #4 ; 03699 STA PL0ROWNEW,X ; Store new PM pixel row number of starbase wing 03700 03701 LDY PL2ZPOSHI ; Prep Y with z-coordinate (high byte) of starbase 03702 03703 SKIP025 LDA COUNT256 ; Prep color mask with B3..0 of counter 03704 AND #$0F ; ...(= brightness bits cause pulsating brightness) 03705 03706 SKIP026 STA L.COLORMASK ; Store color mask 03707 03708 ;*** Check if PLAYER is below PLAYFIELD bottom edge **************************** 03709 TYA ; A := z-coordinate (high byte) 03710 03711 LDY PL0ROWNEW,X ; Next PLAYER space object if top of PM shape... 03712 CPY #204 ; ...is below PLAYFIELD bottom... (!) 03713 BCS LOOP023 ; ...(PM pixel row number >= 204) 03714 03715 ;*** Convert PLAYER z-coordinate to range index in 0..15 *********************** 03716 LDY SHIPVIEW ; Skip if in Front view... 03717 BEQ SKIP027 ; 03718 EOR #$FF ; ...else invert z-coordinate (high byte) 03719 03720 SKIP027 CMP #$20 ; Next PLAYER space object if this one too far away 03721 BCS LOOP023 ; ...(z-coordinate >= $20** (8192) ) 03722 03723 CMP #16 ; Load z-coordinate (high byte) and... 03724 BCC SKIP028 ; 03725 LDA #15 ; 03726 SKIP028 STA L.RANGEINDEX ; ...trim to range index in 0..15 03727 03728 ;*** Update PLAYER shape offset and height ************************************* 03729 ORA PL0SHAPTYPE,X ; Calc offset to shape table (shape type+range index) 03730 LSR A ; 03731 TAY ; Divide by 2 to get offset in 0..7 into shape data 03732 LDA PLSHAPOFFTAB,Y ; Update new PLAYER shape offset 03733 STA PL0SHAPOFF,X ; 03734 LDA PLSHPHEIGHTTAB,Y ; Update new PLAYER shape height 03735 STA PL0HEIGHTNEW,X ; 03736 03737 ;*** Calculate PLAYER color/brightness value *********************************** 03738 TYA ; Pick color (B7..4) using PLAYER shape type 03739 LSR A ; 03740 LSR A ; 03741 LSR A ; 03742 TAY ; 03743 LDA PLSHAPCOLORTAB,Y ; 03744 CPY #8 ; Pick random color if ZYLON BASESTAR (shape type 8) 03745 BNE SKIP029 ; 03746 EOR RANDOM ; 03747 SKIP029 LDY L.RANGEINDEX ; 03748 EOR PLSHAPBRITTAB,Y ; Pick brightness (B3..0) using range index and merge 03749 03750 EOR L.COLORMASK ; Modify color/brightness of PLAYER 03751 03752 LDY PLCOLOROFFTAB,X ; Get PLAYER color offset 03753 STA PL0COLOR,Y ; Store color in PLAYER color register 03754 JMP LOOP023 ; Next PLAYER space object 03755 03756 ;*** (16) Flash red alert ****************************************************** 03757 JUMP003 LDY #$AF ; Prep PLAYFIELD2 color {BRIGHT BLUE-GREEN} 03758 LDX SHIELDSCOLOR ; Prep Shields color {DARK GREEN} or {BLACK} 03759 03760 LDA REDALERTLIFE ; Skip if red alert is over 03761 BEQ SKIP030 ; 03762 03763 DEC REDALERTLIFE ; Decrement lifetime of red alert 03764 LDY #$4F ; Prep PLAYFIELD2 color {BRIGHT ORANGE} 03765 03766 AND #$20 ; Switch colors every 64 game loops 03767 BEQ SKIP030 ; 03768 03769 LDX #$42 ; Load BACKGROUND color {DARK ORANGE} 03770 LDY #$60 ; Load PLAYFIELD2 color {DARK PURPLE BLUE} 03771 03772 SKIP030 STY PF2COLOR ; Store PLAYFIELD2 color 03773 STX BGRCOLOR ; Store BACKGROUND color 03774 03775 ;*** (17) Update color of PLAYFIELD space objects (stars, explosion fragments) * 03776 LDX MAXSPCOBJIND ; Loop over all PLAYFIELD space objs (X index > 4) 03777 LOOP025 LDA ZPOSHI,X ; Prep z-coordinate (high byte) 03778 LDY SHIPVIEW ; 03779 CPY #1 ; Skip if not in Aft view 03780 BNE SKIP032 ; 03781 03782 CMP #$F0 ; Skip if star not too far (z < $F0** (-4096) ) 03783 BCS SKIP031 ; 03784 JSR INITPOSVEC ; Re-init position vector 03785 SKIP031 EOR #$FF ; Invert z-coordinate (high byte) 03786 03787 SKIP032 CMP #16 ; Convert z-coordinate (high byte) 03788 BCC SKIP033 ; ...into range index 0..15 03789 LDA #15 ; 03790 03791 SKIP033 ASL A ; Compute index to pixel color table: 03792 AND #$1C ; Use bits B3..1 from range index as B4..2. 03793 ORA COUNT8 ; Combine with random bits B3..0 from counter 03794 03795 TAY ; 03796 LDA FOURCOLORPIXEL,Y ; Load 1-byte bit pattern for 4 pixels of same color 03797 STA L.FOURCOLORPIX ; ...and temporarily save it 03798 03799 LDA PIXELCOLUMN,X ; Load pixel mask to mask 1 pixel out of 4 pixels: 03800 AND #$03 ; Use B1..0 from pixel column number... 03801 TAY ; 03802 LDA PIXELMASKTAB,Y ; ...to pick mask to filter pixel in byte 03803 AND L.FOURCOLORPIX ; ...AND with 1-byte bit pattern for 4 pixels 03804 STA PIXELBYTE,X ; ...store byte (used in repaint step of game loop) 03805 03806 DEX ; 03807 CPX #NUMSPCOBJ.PL ; 03808 BCS LOOP025 ; Next PLAYFIELD space object 03809 03810 ;*** (18) Skip input handling if in demo mode ********************************** 03811 BIT ISDEMOMODE ; If in demo mode skip to function keys 03812 BVC SKIP034 ; 03813 JMP SKIP040 ; 03814 03815 ;*** (19) Handle keyboard input ************************************************ 03816 SKIP034 JSR KEYBOARD ; Handle keyboard input 03817 03818 ;*** (20) Handle joystick input ************************************************ 03819 LDA PORTA ; Load Joystick 0 directions 03820 TAY ; ...Bits B0..3 -> Right, left, down, up. 03821 AND #$03 ; ...Bit = 0/1 -> Stick pressed/not pressed 03822 TAX ; JOYSTICKY := +1 -> Up 03823 LDA STICKINCTAB,X ; JOYSTICKY := 0 -> Centered 03824 STA JOYSTICKY ; JOYSTICKY := -1 -> Down 03825 TYA ; 03826 LSR A ; 03827 LSR A ; 03828 AND #$03 ; 03829 TAX ; JOYSTICKX := -1 -> Left 03830 LDA STICKINCTAB,X ; JOYSTICKX := 0 -> Centered 03831 STA JOYSTICKX ; JOYSTICKX := +1 -> Right 03832 03833 ;*** (21) Check if our starship's photon torpedoes have hit a target *********** 03834 JSR COLLISION ; Check if our starship's photon torpedoes have hit 03835 03836 ;*** (22) Handle joystick trigger ********************************************** 03837 JSR TRIGGER ; Handle joystick trigger 03838 03839 ;*** (23) Handle Attack Computer and Tracking Computer ************************* 03840 BIT GCSTATCOM ; Skip if Attack Computer destroyed 03841 BVS SKIP038 ; 03842 03843 LDA DRAINATTCOMP ; Skip if Attack Computer off 03844 BEQ SKIP038 ; 03845 03846 LDA SHIPVIEW ; Skip if not in Front view 03847 BNE SKIP035 ; 03848 03849 JSR UPDATTCOMP ; Update Attack Computer Display 03850 03851 SKIP035 LDX TRACKDIGIT ; Load index of tracked space object 03852 03853 LDA ZYLONATTACKER ; Skip if ship of current Zylon torpedo is tracked 03854 BMI SKIP036 ; 03855 TAX ; ...else override Tracking Computer... 03856 ORA #$80 ; 03857 STA ZYLONATTACKER ; ...and mark Zylon torpedo's ship as being tracked 03858 03859 SKIP036 LDA PL0LIFE,X ; Skip if tracked space object still alive 03860 BNE SKIP037 ; 03861 03862 TXA ; 03863 EOR #$01 ; 03864 TAX ; 03865 LDA PL0LIFE,X ; Check if other Zylon ship still alive 03866 BNE SKIP037 ; ...yes -> Keep new index 03867 LDX TRACKDIGIT ; ...no -> Revert to old index of tracked space obj 03868 03869 SKIP037 STX TRACKDIGIT ; Store index of tracked space object 03870 03871 LDA ISTRACKCOMPON ; Skip if tracking computer is turned off 03872 BEQ SKIP038 ; 03873 03874 LDA SHIPVIEW ; Skip if in Long-Range Scan or Galactic Chart view 03875 CMP #2 ; 03876 BCS SKIP038 ; 03877 03878 EOR #$01 ; 03879 CMP ZPOSSIGN,X ; Skip if tracked space object in our starship's... 03880 BEQ SKIP038 ; ...view direction 03881 03882 TAX ; 03883 LDA TRACKKEYSTAB,X ; Pick 'F' or 'A' (Front or Aft view) keyboard code 03884 STA KEYCODE ; ...and store it (= emulate pressing 'F' or 'A' key) 03885 03886 ;*** (24) Handle docking to starbase ******************************************* 03887 SKIP038 JSR DOCKING ; Handle docking to starbase 03888 03889 ;*** (25) Handle maneuvering *************************************************** 03890 JSR MANEUVER ; Handle maneuvering photon torpedoes and Zylon ships 03891 03892 ;*** (26) Was our starship hit by Zylon photon torpedo? ************************ 03893 LDA ISSTARBASESECT ; Skip hit check if in starbase sector 03894 BNE SKIP040 ; 03895 03896 LDA PL2LIFE ; Skip hit check if PLAYER2 (Zylon photon torpedo)... 03897 BEQ SKIP040 ; ...not alive 03898 03899 LDY PL2ZPOSHI ; Our starship was not hit if Zylon photon torpedo's 03900 INY ; ...z-coordinate is not in -256..255 or... 03901 CPY #$02 ; 03902 BCS SKIP040 ; 03903 03904 LDY PL2XPOSHI ; ...x-coordinate is not in -256..255 or... 03905 INY ; 03906 CPY #$02 ; 03907 BCS SKIP040 ; 03908 03909 LDY PL2YPOSHI ; ...y-coordinate is not in -256..255 . 03910 INY ; 03911 CPY #$02 ; 03912 BCS SKIP040 ; 03913 03914 ;*** (27) Our starship was hit! ************************************************ 03915 JSR DAMAGE ; Damage or destroy some subsystem 03916 03917 LDY #2 ; Trigger explosion at PLAYER2 (Zylon photon torpedo) 03918 JSR INITEXPL ; 03919 03920 LDX #$7F ; Prep HITBADNESS := SHIELDS HIT 03921 LDA SHIELDSCOLOR ; Skip if Shields are up (SHIELDSCOLOR not {BLACK}). 03922 BNE SKIP039 ; 03923 03924 LDX #$0A ; Set Front view 03925 JSR SETVIEW ; 03926 03927 LDY #$23 ; Set title phrase "SHIP DESTROYED BY ZYLON FIRE" 03928 LDX #8 ; Set mission bonus offset 03929 JSR GAMEOVER ; Game over 03930 03931 LDX #$5F ; Hide Control Panel Display (bottom text window) 03932 LDY #$80 ; 03933 LDA #$08 ; 03934 JSR MODDLST ; 03935 03936 JSR CLRPLAYFIELD ; Clear PLAYFIELD 03937 03938 LDX #64 ; Enable STARSHIP EXPLOSION noise (see SOUND) 03939 STX NOISEHITLIFE ; 03940 03941 LDX #$FF ; Prep HITBADNESS := STARSHIP DESTROYED 03942 03943 SKIP039 STX HITBADNESS ; Store HITBADNESS 03944 LDA #0 ; Zylon photon torpedo lifetime := 0 game loops 03945 STA PL2LIFE ; 03946 LDA #2 ; Init Zylon photon torpedo trigger 03947 STA TORPEDODELAY ; 03948 03949 LDX #1 ; ENERGY := ENERGY - 100 after photon torpedo hit 03950 JSR DECENERGY ; 03951 03952 LDX #$0A ; Play noise sound pattern SHIELD EXPLOSION 03953 JSR NOISE ; 03954 03955 ;*** (28) Handle function keys ************************************************* 03956 SKIP040 LDY FKEYCODE ; Prep old function key code 03957 LDA CONSOL ; POKEY: Load function key code 03958 03959 EOR #$FF ; Store inverted and masked function key code 03960 AND #$03 ; 03961 STA FKEYCODE ; 03962 BEQ SKIP042 ; Skip if no function key pressed 03963 03964 DEY ; 03965 BPL SKIP042 ; Skip if SELECT or START still pressed 03966 STA IDLECNTHI ; Reset idle counter to a value in 1..3 (?) 03967 CMP #2 ; Skip if SELECT function key pressed 03968 BCS SKIP041 ; 03969 03970 LDA #0 ; START function key pressed: 03971 TAY ; Prep empty title phrase offset 03972 JMP INITSTART ; Reenter game loop via INITSTART 03973 03974 SKIP041 INC MISSIONLEVEL ; SELECT function key pressed: 03975 LDA MISSIONLEVEL ; Cycle through next of 4 mission levels 03976 AND #$03 ; 03977 STA MISSIONLEVEL ; 03978 JMP INITSELECT ; Reenter game loop via INITSELECT 03979 03980 ;*** (29) Update Control Panel Display ***************************************** 03981 SKIP042 JSR UPDPANEL ; Update Control Panel Display 03982 03983 ;*** (30) Handle hyperwarp ***************************************************** 03984 JSR HYPERWARP ; Handle hyperwarp 03985 03986 ;*** (31) Update title line **************************************************** 03987 JSR UPDTITLE ; Update title line 03988 03989 ;*** (32) Flush game loop iteration ******************************************** 03990 JSR FLUSHGAMELOOP ; Move Zylon units, age torpedoes, elapse time 03991 03992 ;*** (33) Jump back to begin of game loop ************************************** 03993 JMP GAMELOOP ; Next game loop iteration 03994 03995 ;******************************************************************************* 03996 ;* * 03997 ;* VBIHNDLR * 03998 ;* * 03999 ;* Vertical Blank Interrupt Handler * 04000 ;* * 04001 ;******************************************************************************* 04002 04003 ; DESCRIPTION 04004 ; 04005 ; This subroutine is executed during the Vertical Blank Interrupt (VBI) when the 04006 ; TV beam has reached the bottom-right corner of the TV screen and is switched 04007 ; off to return to the top-left position. This situation is called the "vertical 04008 ; blank phase". 04009 ; 04010 ; This subroutine signals its execution with flag ISVBISYNC ($67) (which is 04011 ; examined by GAMELOOP ($A1F3) to synchronize the execution of the game loop 04012 ; with the start of this subroutine). Then it switches the character set to the 04013 ; ROM character set, sets the BACKGROUND color depending on the severity of a 04014 ; Zylon photon torpedo hit and view mode, copies PLAYER and PLAYFIELD color 04015 ; registers to their corresponding hardware registers, clears the Player/Missile 04016 ; collision registers, calls the sound effects code in subroutine SOUND ($B2AB), 04017 ; and increments the idle counter. If the idle counter reaches the value $8000 04018 ; the title phrase is cleared and the program is switched to demo mode. 04019 ; 04020 ; BUG (at $A6EC): Because the values of SHIPVIEW ($D0) are $00, $01, $40, and 04021 ; $80, a value of 3 overspecifies the comparison. Suggested fix: Replace CMP #3 04022 ; with CMP #2, which may make the code clearer. 04023 ; 04024 ; BUG (at $A712): Demo mode is entered via a JMP instruction, which proceeds 04025 ; directly into GAMELOOP ($A1F3). Thus code execution never returns to pop the 04026 ; registers pushed on the stack during entry of this subroutine. Suggested fix: 04027 ; None. 04028 04029 VBIHNDLR LDA #$FF ; Signals entering Vertical Blank Interrupt 04030 STA ISVBISYNC ; 04031 04032 LDA #>ROMCHARSET ; Switch character set to ROM character set 04033 STA CHBASE ; 04034 04035 LDX BGRCOLOR ; Preload BACKGROUND color 04036 LDA RANDOM ; Preload random number 04037 BIT HITBADNESS ; Check if our starship was hit 04038 BVC SKIP044 ; If HITBADNESS has a value of... 04039 BMI SKIP043 ; $00 -> NO HIT (BGR color := unchanged) 04040 AND #$72 ; $7F -> SHIELDS HIT (BGR color := %01rr00r0) 04041 ORA #$40 ; $FF -> STARSHIP DESTROYED (BGR color := %01rr00r0) 04042 SKIP043 TAX ; 04043 SKIP044 LDA SHIPVIEW ; Skip if in Front or Aft view 04044 CMP #3 ; (!) 04045 BCC SKIP045 ; 04046 LDX #$A0 ; Preload BACKGROUND color {DARK BLUE GREEN}... 04047 SKIP045 STX BGRCOLOR ; Store BACKGROUND color 04048 04049 LDX #8 ; Copy all color registers to hardware registers 04050 LOOP026 LDA PL0COLOR,X ; 04051 STA COLPM0,X ; 04052 DEX ; 04053 BPL LOOP026 ; 04054 04055 STA HITCLR ; Clear Player/Missile collision registers 04056 04057 JSR SOUND ; Call sound effects 04058 04059 INC IDLECNTLO ; Increment 16-bit idle counter 04060 BNE SKIP046 ; 04061 LDA IDLECNTHI ; 04062 BMI SKIP046 ; 04063 INC IDLECNTHI ; 04064 BPL SKIP046 ; Skip if idle counter value of $8000 not reached yet 04065 04066 LDY #$00 ; Prep empty title phrase offset 04067 JMP INITDEMO ; Enter demo mode (!) 04068 04069 SKIP046 JMP JUMP004 ; Return via DLI return code 04070 04071 ;******************************************************************************* 04072 ;* * 04073 ;* DLSTHNDLR * 04074 ;* * 04075 ;* Display List Interrupt Handler * 04076 ;* * 04077 ;******************************************************************************* 04078 04079 ; DESCRIPTION 04080 ; 04081 ; This subroutine is executed during the Display List Interrupt (DLI). It 04082 ; switches the character set to the ROM character set if the DLI occurs at ANTIC 04083 ; line 96 (video line 192), otherwise to the custom character set. The former 04084 ; happens in the Galactic Chart view where the ROM character set is used in the 04085 ; Galactic Chart Panel Display. 04086 ; 04087 ; Then, the DLI PLAYFIELD colors are copied to the corresponding hardware 04088 ; registers and the values of the collision hardware registers for PLAYER3..4 04089 ; (our starship's photon torpedoes) are copied to the corresponding zero-page 04090 ; variables PL3HIT ($82) and PL4HIT ($83). 04091 04092 DLSTHNDLR PHA ; Push A 04093 TXA ; 04094 PHA ; Push X 04095 TYA ; 04096 PHA ; Push Y 04097 04098 LDA #>ROMCHARSET ; Switch to ROM charset if ANTIC line counter = 96 04099 LDY VCOUNT ; ...else switch to custom character set 04100 CPY #96 ; 04101 BEQ SKIP047 ; 04102 LDA #>CHARSET ; 04103 SKIP047 STA CHBASE ; 04104 04105 LDX #4 ; Loop over all PLAYFIELD colors 04106 STA WSYNC ; Stop and wait for horizontal TV beam sync 04107 LOOP027 LDA PF0COLORDLI,X ; Copy DLI PLAYFIELD colors to hardware registers 04108 STA COLPF0,X ; 04109 DEX ; 04110 BPL LOOP027 ; Next PLAYFIELD color 04111 04112 LDA M0PL ; Merge MISSILE-to-PLAYER collision registers... 04113 ORA M1PL ; 04114 ORA M2PL ; 04115 ORA M3PL ; 04116 STA PL4HIT ; ...and store them in PL4HIT 04117 LDA P3PL ; Copy PLAYER3-to-PLAYER coll. register to PL3HIT 04118 STA PL3HIT ; 04119 04120 JUMP004 PLA ; Pop Y 04121 TAY ; 04122 PLA ; Pop X 04123 TAX ; 04124 PLA ; Pop A 04125 RTI ; Return from interrupt 04126 04127 ;******************************************************************************* 04128 ;* * 04129 ;* IRQHNDLR * 04130 ;* * 04131 ;* Interrupt Request (IRQ) Handler * 04132 ;* * 04133 ;******************************************************************************* 04134 04135 ; DESCRIPTION 04136 ; 04137 ; This subroutine is executed during immediate interrupt requests (IRQs), such 04138 ; as after pressing a key on the keyboard. It clears and disables all IRQs 04139 ; except the interrupt raised by a pressed key. If a key has been pressed, its 04140 ; hardware code is collected and the bits of the SHIFT and CONTROL keys are 04141 ; added. The resulting keyboard code is stored in KEYCODE ($CA). 04142 04143 IRQHNDLR PHA ; Push A 04144 LDA #0 ; POKEY: Disable all IRQs 04145 STA IRQEN ; 04146 LDA #$40 ; POKEY: Enable keyboard interrupt (IRQ) 04147 STA IRQEN ; 04148 LDA KBCODE ; POKEY: Load keyboard key code 04149 ORA #$C0 ; Combine with SHIFT and CONTROL key bits 04150 STA KEYCODE ; Store keyboard code 04151 PLA ; Pop A 04152 RTI ; Return from interrupt 04153 04154 ;******************************************************************************* 04155 ;* * 04156 ;* DRAWLINES * 04157 ;* * 04158 ;* Draw horizontal and vertical lines * 04159 ;* * 04160 ;******************************************************************************* 04161 04162 ; DESCRIPTION 04163 ; 04164 ; Draws the Attack Computer Display (in Front view), cross hairs (in Front and 04165 ; Aft view), and our starship's shape (in Long-Range Scan view) on the PLAYFIELD 04166 ; (if the Attack Computer is not destroyed) by being passed an offset to table 04167 ; DRAWLINESTAB ($BAF9). This table consists of a list of 3-byte elements, 04168 ; terminated by an end marker byte ($FE). Each such element defines a single 04169 ; horizontal or vertical line, and is passed via memory addresses DIRLEN ($A4), 04170 ; PENROW ($A5), and PENCOLUMN ($A6) to subroutine DRAWLINE ($A782), which 04171 ; executes the actual drawing. See subroutine DRAWLINE ($A782) and table 04172 ; DRAWLINESTAB ($BAF9) for a description of the 3-byte elements. 04173 ; 04174 ; With every call of this subroutine the blip cycle counter is initialized to 04175 ; the start of the DELAY phase (see subroutine UPDATTCOMP ($A7BF)). 04176 ; 04177 ; NOTE: The entry to this subroutine is in mid-code, not at the beginning. 04178 ; 04179 ; INPUT 04180 ; 04181 ; X = Offset into DRAWLINESTAB ($BAF9). Used values are: 04182 ; $00 -> Draw Attack Computer Display and cross hairs (Front view) 04183 ; $2A -> Draw Aft view cross hairs (Aft view) 04184 ; $31 -> Draw our starship's shape (Long-Range Scan view) 04185 04186 LOOP028 STA DIRLEN,Y ; Store byte of 3-byte element 04187 INX ; 04188 DEY ; 04189 BPL SKIP048 ; Next byte of 3-byte element until 3 bytes copied 04190 JSR DRAWLINE ; Draw line on PLAYFIELD 04191 04192 DRAWLINES LDA #5 ; Init blip cycle to DELAY phase... 04193 STA BLIPCYCLECNT ; ...delays drawing each row 04194 04195 BIT GCSTATCOM ; Return if Attack Computer destroyed 04196 BVS SKIP049 ; 04197 04198 LDY #2 ; 04199 SKIP048 LDA DRAWLINESTAB,X ; Load byte of 3-byte element 04200 CMP #$FE ; Loop until end marker byte ($FE) encountered 04201 BNE LOOP028 ; 04202 SKIP049 RTS ; Return 04203 04204 ;******************************************************************************* 04205 ;* * 04206 ;* DRAWLINE * 04207 ;* * 04208 ;* Draw a single horizontal or vertical line * 04209 ;* * 04210 ;******************************************************************************* 04211 04212 ; DESCRIPTION 04213 ; 04214 ; Draws a single horizontal or vertical transparent line. 04215 ; 04216 ; There are two entries to this subroutine: 04217 ; 04218 ; (1) DRAWLINE ($A782) is entered from subroutine DRAWLINES ($A76F) to draw a 04219 ; line in COLOR1. 04220 ; 04221 ; (2) DRAWLINE2 ($A784) is entered from subroutine UPDATTCOMP ($A7BF) to draw 04222 ; the blip in COLOR2 in the Attack Computer Display. 04223 ; 04224 ; The position, direction, and length of the line is defined by three bytes 04225 ; passed in memory addresses DIRLEN ($A4), PENROW ($A5), and PENCOLUMN ($A6). 04226 ; 04227 ; A drawing operation draws one transparent line. It uses both the color 04228 ; register number of the overwritten (old) and the overwriting (new) pixel to 04229 ; decide on the new pixel color register number. This results in a transparent 04230 ; drawing effect. See the table below for all resulting combinations of color 04231 ; registers. 04232 ; 04233 ; +-----------+---------------+ 04234 ; | | Old Color | 04235 ; | | Register | 04236 ; | New Color +---------------+ 04237 ; | Register | 0 | 1 | 2 | 3 | 04238 ; +-----------+---+---+---+---+ 04239 ; | 0 | 0 | 1 | 2 | 3 | 04240 ; +-----------+---+---+---+---+ 04241 ; | 1 | 1 | 1 | 3 | 3 | 04242 ; +-----------+---+---+---+---+ 04243 ; | 2 | 2 | 3 | 2 | 3 | 04244 ; +-----------+---+---+---+---+ 04245 ; | 3 | 3 | 3 | 3 | 3 | 04246 ; +-----------+---+---+---+---+ 04247 ; 04248 ; For example, COLOR1 overwritten by COLOR2 yields COLOR3. If you look closely 04249 ; at the blip (in COLOR2) on the Attack Computer Display (in COLOR1) the lines 04250 ; of the Attack Computer Display shine through (in COLOR3) where they overlap. 04251 ; 04252 ; INPUT 04253 ; 04254 ; DIRLEN ($A4) = B7 = 0 -> Draw line to the right 04255 ; B7 = 1 -> Draw line downward 04256 ; B6..0 -> Length of line in pixels 04257 ; PENROW ($A5) = Start pixel row number of line 04258 ; PENCOLUMN ($A6) = Start pixel column number of line 04259 04260 L.PIXELBYTEOFF = $6A ; Within-row-offset to byte with pixel in PLAYFIELD 04261 L.BITPAT = $6B ; 1-byte bit pattern for 4 pixels of same color 04262 L.DIRSAV = $6E ; Saves DIRLEN 04263 04264 DRAWLINE LDA #$55 ; Copy 1-byte bit pattern for 4 pixels of COLOR1 04265 DRAWLINE2 STA L.BITPAT ; 04266 LDA DIRLEN ; Copy direction (and length) of line 04267 STA L.DIRSAV ; 04268 AND #$7F ; Strip direction bit 04269 STA DIRLEN ; Store length of line 04270 04271 LOOP029 LDY PENROW ; Loop over length of line to be drawn 04272 LDA PFMEMROWLO,Y ; Point MEMPTR to start of pen's pixel row... 04273 STA MEMPTR ; ...in PLAYFIELD memory 04274 LDA PFMEMROWHI,Y ; 04275 STA MEMPTR+1 ; 04276 04277 LDA PENCOLUMN ; Calc and store pen's byte-within-row offset 04278 LSR A ; 04279 LSR A ; 04280 STA L.PIXELBYTEOFF ; 04281 04282 LDA PENCOLUMN ; Calc pixel-within-byte index 04283 AND #$03 ; 04284 TAY ; 04285 04286 LDA PIXELMASKTAB,Y ; Pick mask to filter pixel in byte 04287 AND L.BITPAT ; ...AND with bit pattern for 4 pixels of same color 04288 LDY L.PIXELBYTEOFF ; 04289 ORA (MEMPTR),Y ; Blend byte with new pixel and PLAYFIELD byte 04290 STA (MEMPTR),Y ; ...and store it back in PLAYFIELD memory 04291 04292 BIT L.DIRSAV ; Check direction bit B7 04293 BPL SKIP050 ; 04294 INC PENROW ; If B7 = 1 -> Increment pen's pixel row number 04295 BNE SKIP051 ; 04296 SKIP050 INC PENCOLUMN ; If B7 = 0 -> Increment pen's pixel column number 04297 04298 SKIP051 DEC DIRLEN ; 04299 BNE LOOP029 ; Next pixel of line 04300 RTS ; Return 04301 04302 ;******************************************************************************* 04303 ;* * 04304 ;* UPDATTCOMP * 04305 ;* * 04306 ;* Update Attack Computer Display * 04307 ;* * 04308 ;******************************************************************************* 04309 04310 ; DESCRIPTION 04311 ; 04312 ; Draws the blip of the tracked space object and the lock-on markers into the 04313 ; Attack Computer Display. The actual drawing follows a cycle of 11 game loop 04314 ; iterations (numbered by this subroutine as "blip cycles" 0..10), which can be 04315 ; divided into three phases: 04316 ; 04317 ; (1) Blip cycle 0..4: Draw blip shape row-by-row 04318 ; 04319 ; Draw the blip's shape into the Attack Computer Display, one row each blip 04320 ; cycle. After 5 blip cycles the blip shape is complete and completely 04321 ; visible because between blip cycles, that is, game loop iterations, the 04322 ; PLAYFIELD is not erased (only the PLAYFIELD space objects are). Drawing 04323 ; is executed by branching to entry DRAWLINE2 ($A784) of subroutine 04324 ; DRAWLINE ($A782). The blip shape is retrieved from table BLIPSHAPTAB 04325 ; ($BF6E). 04326 ; 04327 ; (2) Blip cycle 5..9: Delay 04328 ; 04329 ; Delay the execution of blip cycle 10. 04330 ; 04331 ; (3) Blip cycle 10: Update Attack Computer Display 04332 ; 04333 ; After verifying that the tracked space object is alive, calculate the 04334 ; blip's relative top-left pixel column and row number. Resulting values 04335 ; are in -11..11 and -6..4, relative to the blip's top-left reference 04336 ; position at pixel column number 131 and pixel row number 77, 04337 ; respectively. 04338 ; 04339 ; Filter the Attack Computer Display area: Only pixels of COLOR1 within the 04340 ; inner frame area (a 28 pixel wide x 15 pixel high rectangle with its 04341 ; top-left corner at pixel column number 120 and pixel row number 71) pass 04342 ; the filter operation. This effectively erases the blip. 04343 ; 04344 ; If the blip is within -2..+2 pixels off its horizontal reference position 04345 ; (pixel column numbers 129..132) then the tracked space object is in x 04346 ; lock-on. Draw the x lock-on marker. 04347 ; 04348 ; If the tracked space object is in x lock-on and the blip is within -2..+1 04349 ; pixels off its vertical reference position (pixel column numbers 75..78) 04350 ; then the tracked space object is in x and y lock-on. Draw also the y 04351 ; lock-on marker. 04352 ; 04353 ; If the tracked space object is in x and y lock-on and the tracked space 04354 ; object's z-coordinate < +3072 (+$0C**) then the tracked space object 04355 ; is in x, y and z lock-on. Draw also the z lock-on marker. 04356 ; 04357 ; If the tracked space object is in x, y, and z lock-on (and thus in 04358 ; optimal firing range) set the ISINLOCKON ($A3) flag. 04359 ; 04360 ; The following sketches show the Attack Computer Display area overlaid 04361 ; with the Attack Computer Display frame: 04362 ; 04363 ; 119 119 04364 ; 70 ############################## 70 ############################## 04365 ; # ....#.... # # # # 04366 ; # ....#.... # # # # 04367 ; # ....#.... # # # # 04368 ; # ....#.... # # # # 04369 ; # ############### # #......###############.......# 04370 ; #XXXX # ......... # XXXX# #......#.............#.......# 04371 ; # # ..$...... # # #......#....$........#.......# 04372 ; ######## ......... ######### ########.............######### 04373 ; # # ......... # # #......#.............#.......# 04374 ; # # ......... # # #YYYY..#.............#...YYYY# 04375 ; # ############### # #......###############.......# 04376 ; # ....#.... # #.............#..............# 04377 ; # ....#.... # # # # 04378 ; # ....#.... # # # # 04379 ; # ....#.... # # # # 04380 ; ############################## ############################## 04381 ; 04382 ; X = x lock-on marker Y = y lock-on marker 04383 ; . = x lock-on blip zone . = y lock-on blip zone 04384 ; $ = Blip's top-left reference $ = Blip's top-left reference 04385 ; position position 04386 ; 04387 ; 119 04388 ; 70 ############################## 04389 ; # # # 04390 ; # # # 04391 ; # # # 04392 ; # # # 04393 ; # ############### # 04394 ; # # # # 04395 ; # # $ # # 04396 ; ######## ######### 04397 ; # # # # 04398 ; # # # # 04399 ; # ############### # 04400 ; # # # 04401 ; # # # 04402 ; # ZZ # ZZ # 04403 ; # ZZ # ZZ # 04404 ; ############################## 04405 ; 04406 ; Z = z lock-on marker 04407 ; $ = Blip's top-left reference 04408 ; position 04409 04410 L.SHIFTSHAPE = $6C ; Saves shifted byte of blip shape bit pattern 04411 04412 UPDATTCOMP LDX TRACKDIGIT ; Load index of tracked space object 04413 LDY BLIPCYCLECNT ; Load blip cycle counter 04414 CPY #5 ; 04415 BCS SKIP054 ; Skip drawing blip if blip cycle > 5 04416 04417 ;*** Blip cycle 0..4: Draw blip shape one row each cycle *********************** 04418 LDA BLIPCOLUMN ; Init pen's pixel column number... 04419 STA PENCOLUMN ; ...with top position of blip shape 04420 LDA BLIPSHAPTAB,Y ; Load bit pattern of one row of blip shape 04421 LOOP030 ASL A ; Shift bit pattern one position to the left 04422 STA L.SHIFTSHAPE ; Temporarily save shifted shape byte 04423 BCC SKIP052 ; Skip if shifted-out bit = 0 04424 04425 LDA #$81 ; Store "draw a line of 1 pixel length downward" 04426 STA DIRLEN ; ...for call to DRAWLINE2 04427 04428 LDA BLIPROW ; Init pen's pixel row number... 04429 STA PENROW ; ...with leftmost position of blip shape 04430 LDA #$AA ; Load 1-byte bit pattern for 4 pixels of COLOR2 04431 JSR DRAWLINE2 ; Draw pixel on PLAYFIELD 04432 04433 SKIP052 INC PENCOLUMN ; Move pen one pixel to the right 04434 LDA L.SHIFTSHAPE ; Reload shifted shape byte 04435 BNE LOOP030 ; Next horizontal pixel of blip shape 04436 04437 INC BLIPROW ; Move pen one pixel downward 04438 SKIP053 INC BLIPCYCLECNT ; Increment blip cycle counter 04439 RTS ; Return 04440 04441 ;*** Blip cycle 5..9: Delay **************************************************** 04442 SKIP054 CPY #10 ; Return if blip cycle < 10 04443 BCC SKIP053 ; 04444 04445 ;*** Blip cycle 10: Calculate new blip pixel row and column numbers ************ 04446 LDA PL0LIFE,X ; Skip if tracked object not alive 04447 BEQ SKIP059 ; 04448 04449 LDA XPOSHI,X ; Map x-coordinate of tracked space obj to -11..11: 04450 LDY XPOSSIGN,X ; Skip if tracked object on left screen half (x >= 0) 04451 BEQ SKIP055 ; 04452 04453 CMP #12 ; Skip if x of tracked obj < +$0C** (< 3327) 04454 BCC SKIP056 ; 04455 LDA #11 ; Prep relative pixel column number of 11, skip 04456 BPL SKIP056 ; 04457 04458 SKIP055 CMP #-11 ; Skip if x of tracked obj >= -($0B**) (>=-2816) 04459 BCS SKIP056 ; 04460 LDA #-11 ; Prep relative pixel column number of -11 04461 04462 SKIP056 CLC ; Add 131 (= blip's top-left reference pixel column) 04463 ADC #131 ; 04464 STA BLIPCOLUMN ; BLIPCOLUMN := 131 + -11..11 04465 04466 LDA YPOSHI,X ; Map y-coordinate of tracked space obj to -6..4: 04467 EOR #$FF ; Mirror y-coordinate on y-axis (displacement of +1) 04468 LDY YPOSSIGN,X ; Skip if tracked obj on lower screen half (y < 0) 04469 BNE SKIP057 ; 04470 04471 CMP #5 ; Skip if mirrored y of tracked obj < +$05** 04472 BCC SKIP058 ; 04473 LDA #4 ; Prep relative pixel row number of 4, skip 04474 BPL SKIP058 ; 04475 04476 SKIP057 CMP #-6 ; Skip if mirrored y of tracked obj >= -($06**) 04477 BCS SKIP058 ; 04478 LDA #-6 ; Prep relative pixel row number of -6 04479 04480 SKIP058 CLC ; Add 77 (= blip's top-left ref. pixel row number) 04481 ADC #77 ; 04482 STA BLIPROW ; BLIPROW := 77 + -6..4 04483 04484 LDA #0 ; Reset blip cycle 04485 STA BLIPCYCLECNT ; 04486 04487 ;*** Filter Attack Computer Display frame area ********************************* 04488 ; PLAYFIELD address of top-left of Attack Computer 04489 PFMEM.C120R71 = PFMEM+71*40+120/4 ; Display's inner frame @ pixel column 120, row 71 04490 04491 SKIP059 LDA #PFMEM.C120R71 ; ...in PLAYFIELD memory 04494 STA MEMPTR+1 ; 04495 04496 LDX #14 ; Traverse a 28 x 15 pixel rect of PLAYFIELD memory 04497 LOOP031 LDY #6 ; 04498 LOOP032 LDA (MEMPTR),Y ; Load byte (4 pixels) from PLAYFIELD memory 04499 AND #$55 ; Filter COLOR1 pixels 04500 STA (MEMPTR),Y ; Store byte (4 pixels) back to PLAYFIELD memory 04501 DEY ; 04502 BPL LOOP032 ; Next 4 pixels in x-direction 04503 04504 CLC ; Add 40 to MEMPTR 04505 LDA MEMPTR ; (40 bytes = 160 pixels = 1 PLAYFIELD row of pixels) 04506 ADC #40 ; 04507 STA MEMPTR ; 04508 BCC SKIP060 ; 04509 INC MEMPTR+1 ; 04510 04511 SKIP060 DEX ; 04512 BPL LOOP031 ; Next row of pixels in y-direction 04513 04514 ;*** Prepare lock-on marker checks ********************************************* 04515 LDX TRACKDIGIT ; Preload index of tracked space obj to check z-range 04516 INY ; Y := 0, preloaded value of ISINLOCKON 04517 04518 ;*** Draw lock-on markers ****************************************************** 04519 ; PLAYFIELD addresses of 04520 PFMEM.C120R76 = PFMEM+76*40+120/4 ; ...x lock-on marker @ pixel column 120, row 76 04521 PFMEM.C144R76 = PFMEM+76*40+144/4 ; ...x lock-on marker @ pixel column 144, row 76 04522 PFMEM.C120R80 = PFMEM+80*40+120/4 ; ...y lock-on marker @ pixel column 120, row 80 04523 PFMEM.C144R80 = PFMEM+80*40+144/4 ; ...y lock-on marker @ pixel column 144, row 80 04524 PFMEM.C128R84 = PFMEM+84*40+128/4 ; ...z lock-on marker @ pixel column 128, row 84 04525 PFMEM.C128R85 = PFMEM+85*40+128/4 ; ...z lock-on marker @ pixel column 128, row 85 04526 PFMEM.C136R84 = PFMEM+84*40+136/4 ; ...z lock-on marker @ pixel column 136, row 84 04527 PFMEM.C136R85 = PFMEM+85*40+136/4 ; ...z lock-on marker @ pixel column 136, row 85 04528 04529 LDA LOCKONLIFE ; If lock-on lifetime expired redraw lock-on markers 04530 BEQ SKIP061 ; 04531 04532 DEC LOCKONLIFE ; else decr lock-on lifetime, skip drawing markers 04533 BNE SKIP062 ; 04534 04535 SKIP061 LDA BLIPCOLUMN ; Skip x, y, and z lock-on marker if blip's... 04536 CMP #129 ; ...top-left pixel column number not in 129..132 04537 BCC SKIP062 ; 04538 CMP #133 ; 04539 BCS SKIP062 ; 04540 04541 LDA #$AA ; Draw x lock-on marker (4 horiz. pixels of COLOR2) 04542 STA PFMEM.C120R76 ; ...at pixel column 120, row 76 04543 STA PFMEM.C144R76 ; ...at pixel column 144, row 76 04544 04545 LDA BLIPROW ; Skip y and z lock-on marker if blip's... 04546 CMP #75 ; ...top-left pixel row number not in 75...78 04547 BCC SKIP062 ; 04548 CMP #79 ; 04549 BCS SKIP062 ; 04550 04551 LDA #$AA ; Draw y lock-on marker (4 horiz. pixels of COLOR2) 04552 STA PFMEM.C120R80 ; ...at pixel column 120, row 80 04553 STA PFMEM.C144R80 ; ...at pixel column 144, row 80 04554 04555 LDA ZPOSHI,X ; Skip z lock-on marker if z >= +$0C** (>= 3072) 04556 CMP #12 ; 04557 BCS SKIP062 ; 04558 04559 LDY #$A0 ; Draw z lock-on marker (2 horiz. pixels of COLOR2) 04560 STY PFMEM.C128R84 ; ...at pixel column 128, row 84 (prep lock-on flag) 04561 STY PFMEM.C128R85 ; ...at pixel column 128, row 85 04562 STY PFMEM.C136R84 ; ...at pixel column 136, row 84 04563 STY PFMEM.C136R85 ; ...at pixel column 136, row 85 04564 04565 SKIP062 STY ISINLOCKON ; Store lock-on flag (> 0 -> Tracked obj locked on) 04566 RTS ; Return 04567 04568 ;******************************************************************************* 04569 ;* * 04570 ;* HYPERWARP * 04571 ;* * 04572 ;* Handle hyperwarp * 04573 ;* * 04574 ;******************************************************************************* 04575 04576 ; DESCRIPTION 04577 ; 04578 ; Handles the hyperwarp sequence, which transports our starship from one sector 04579 ; to another. It can be divided into four phases: 04580 ; 04581 ; (1) ACCELERATION PHASE 04582 ; 04583 ; The ACCELERATION PHASE is entered after the hyperwarp sequence has been 04584 ; engaged in subroutine KEYBOARD ($AFFE) by pressing the 'H' key. The 04585 ; Hyperwarp Target Marker appears and our starship begins to accelerate. 04586 ; When our starship's velocity reaches 128 (the VELOCITY readout of 04587 ; the Control Panel Display displays "50"), the STAR TRAIL phase is 04588 ; entered. 04589 ; 04590 ; The Hyperwarp Target Marker is represented by a space object some fixed 04591 ; distance away in front of our starship as PLAYER3. It has a lifetime of 04592 ; 144 game loop iterations and is tracked. Thus, tracking handling in 04593 ; subroutine UPDATTCOMP ($A7BF) provides drawing the x and y lock-on 04594 ; markers in the Attack Computer Display when the Hyperwarp Target Marker 04595 ; is centered. 04596 ; 04597 ; A temporary arrival location on the Galactic Chart was saved when the 04598 ; hyperwarp was engaged in subroutine KEYBOARD ($AFFE). During the 04599 ; ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE) this location is 04600 ; constantly updated depending on how much the Hyperwarp Target Marker 04601 ; veers off its center position. 04602 ; 04603 ; The actual arrival hyperwarp marker row and column numbers on the 04604 ; Galactic Chart are the sum of the temporary arrival hyperwarp marker row 04605 ; and column numbers stored when engaging the hyperwarp in subroutine 04606 ; KEYBOARD ($AFFE) and the number of Player/Missile (PM) pixels which the 04607 ; Hyperwarp Target Marker is off-center vertically and horizontally, 04608 ; respectively, at the end of the STAR TRAIL PHASE. 04609 ; 04610 ; NOTE: The used vertical center value of 119 PM pixels is the PM pixel row 04611 ; number of the top edge of the centered Hyperwarp Target Marker (from top 04612 ; to bottom: 8 PM pixels to the start of Display List + 16 PM pixels blank 04613 ; lines + 100 PM pixels to the vertical PLAYFIELD center - 5 PM pixels 04614 ; relative offset of the Hyperwarp Target Marker's shape center to the 04615 ; shape's top edge = 119 PM pixels). Recall also that PLAYERs at 04616 ; single-line resolution have PM pixels that are half as high as they are 04617 ; wide. 04618 ; 04619 ; NOTE: The used horizontal center value of 125 PM pixels is the PM pixel 04620 ; row number of the left edge of the centered Hyperwarp Target Marker (from 04621 ; left to right: 127 PM pixels to the PLAYFIELD center - 3 PM pixels 04622 ; relative offset of the Hyperwarp Target Marker's shape center to the 04623 ; shape's left edge = 125 PM pixels). 04624 ; 04625 ; If during the ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE) 04626 ; you switch the Front view to another view, the Hyperwarp Target Marker 04627 ; changes to a random position which results in arriving at a random 04628 ; destination sector. 04629 ; 04630 ; During the ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE) in 04631 ; all but NOVICE missions, the Hyperwarp Target Marker veers off with 04632 ; random velocity in x and y direction, which is changed during 6% of game 04633 ; loop iterations. Table VEERMASKTAB ($BED7) limits the maximum veer-off 04634 ; velocity depending on the mission level: 04635 ; 04636 ; +-----------+-----------------------------+ 04637 ; | Mission | Veer-Off Velocity | 04638 ; +-----------+-----------------------------+ 04639 ; | NOVICE | 0 | 04640 ; | PILOT | -63..-16, +16..+63 | 04641 ; | WARRIOR | -95..-16, +16..+95 | 04642 ; | COMMANDER | -127..-16, +16..+127 | 04643 ; +-----------+-----------------------------+ 04644 ; 04645 ; (2) STAR TRAIL PHASE 04646 ; 04647 ; When our starship's velocity reaches a velocity of 128 (the 04648 ; VELOCITY readout of the Control Panel Display displays "50"), in addition 04649 ; to all effects of the ACCELERATION PHASE, multiple star trails begin to 04650 ; appear while our starship continues to accelerate. Each star trail is 04651 ; initialized in subroutine INITTRAIL ($A9B4). 04652 ; 04653 ; (3) HYPERSPACE PHASE 04654 ; 04655 ; When our starship's velocity reaches a velocity of 254 (the 04656 ; VELOCITY readout of the Control Panel Display displays "99") our starship 04657 ; enters the HYPERSPACE PHASE (the VELOCITY readout of the Control Panel 04658 ; Display displays the infinity symbol). 04659 ; 04660 ; During the first pass of the HYPERSPACE PHASE the hyperwarp state is set 04661 ; to HYPERSPACE. This makes the stars and the Hyperwarp Target Marker 04662 ; disappear in GAMELOOP ($A1F3). Then, the beeper sound pattern HYPERWARP 04663 ; TRANSIT is played in subroutine BEEP ($B3A6), the hyperwarp distance and 04664 ; required hyperwarp energy is calculated in subroutine CALCWARP ($B1A7), 04665 ; and the title line is preloaded with "HYPERSPACE". Code execution returns 04666 ; via calling subroutine CLEANUPWARP ($A98D) where program variables are 04667 ; already initialized to their post-hyperwarp values. 04668 ; 04669 ; During subsequent passes of the HYPERSPACE PHASE, the calculated 04670 ; hyperwarp energy is decremented in chunks of 10 energy units. Code 04671 ; execution returns via calling subroutine DECENERGY ($B86F), which 04672 ; decrements our starship's energy. After the calculated hyperwarp energy 04673 ; is spent the DECELERATION PHASE is entered. 04674 ; 04675 ; (4) DECELERATION PHASE 04676 ; 04677 ; The title line flashes "HYPERWARP COMPLETE", the star field reappears and 04678 ; our starship decelerates to a stop. The Engines and the hyperwarp are 04679 ; disengaged and stopped in subroutine ENDWARP ($A987), the arrival 04680 ; coordinates on the Galactic Chart are initialized, as well as the 04681 ; vicinity mask. 04682 ; 04683 ; The vicinity mask limits the position vector components (coordinates) of 04684 ; space objects in the arrival sector relative to our starship. The 04685 ; vicinity mask is picked from table VICINITYMASKTAB ($BFB3) by an index 04686 ; calculated by the arrival y-coordinate modulo 8: The more you have placed 04687 ; the arrival hyperwarp marker in the vertical center of a sector on the 04688 ; Galactic Chart, the closer space objects in this sector will be to our 04689 ; starship. For example, if you placed the arrival hyperwarp marker exactly 04690 ; in the vertical middle of the sector the index will be 3, thus the space 04691 ; objects inside the arrival sector will be in the vicinity of <= 4095 04692 ; of our starship. The following table lists the possible coordinates 04693 ; depending on the calculated index: 04694 ; 04695 ; +-------+-----------------------+ 04696 ; | Index | ABS(Coordinate) | 04697 ; +-------+-----------------------+ 04698 ; | 0 | <= 65535 ($FF**) | 04699 ; | 1 | <= 65535 ($FF**) | 04700 ; | 2 | <= 16383 ($3F**) | 04701 ; | 3 | <= 4095 ($0F**) | 04702 ; | 4 | <= 16383 ($3F**) | 04703 ; | 5 | <= 32767 ($7F**) | 04704 ; | 6 | <= 65535 ($FF**) | 04705 ; | 7 | <= 65535 ($FF**) | 04706 ; +-------+-----------------------+ 04707 ; 04708 ; If there is a starbase in the arrival sector, its x and y coordinates are 04709 ; initialized to random values within the interval defined by the vicinity 04710 ; mask by using subroutine RNDINVXY ($B7BE). Its z-coordinate is forced to 04711 ; a value >= +$71** (+28928) . Its velocity vector components are set 04712 ; to 0 . 04713 ; 04714 ; If there are Zylon ships in the arrival sector then a red alert is 04715 ; initialized by setting the red alert lifetime to 255 game loop 04716 ; iterations, playing the beeper sound pattern RED ALERT in subroutine BEEP 04717 ; ($B3A6) and setting the title phrase to "RED ALERT". 04718 04719 HYPERWARP LDY WARPSTATE ; Return if hyperwarp not engaged 04720 BEQ SKIP066 ; 04721 04722 LDA VELOCITYLO ; If velocity >= 254 skip to HYPERSPACE PHASE 04723 CMP #254 ; 04724 BCS SKIP067 ; 04725 04726 CMP #128 ; If velocity < 128 skip to ACCELERATION PHASE 04727 BCC SKIP063 ; 04728 04729 ;*** STAR TRAIL PHASE ********************************************************** 04730 JSR INITTRAIL ; Init star trail 04731 04732 ;*** ACCELERATION PHASE ******************************************************** 04733 SKIP063 LDA #3 ; Track Hyperwarp Target Marker (PLAYER3) 04734 STA TRACKDIGIT ; 04735 04736 LDA #SHAP.HYPERWARP ; PLAYER3 is HYPERWARP TARGET MARKER (shape type 9) 04737 STA PL3SHAPTYPE ; 04738 STA PL3LIFE ; PLAYER3 lifetime := 144 game loops 04739 04740 LDA #$1F ; PLAYER3 z-coordinate := $1F** (7936..8191) 04741 STA PL3ZPOSHI ; 04742 04743 SEC ; New arrival hyperwarp marker row number is... 04744 LDA PL3ROWNEW ; WARPARRVROW := WARPTEMPROW + PL3ROWNEW... 04745 SBC #119 ; ... - 119 PM pixels (top edge of centered... 04746 CLC ; ...Hyperwarp Target Marker) 04747 ADC WARPTEMPROW ; 04748 AND #$7F ; Limit WARPARRVROW to 0..127 04749 STA WARPARRVROW ; 04750 04751 SEC ; New arrival hyperwarp marker column number is... 04752 LDA PL3COLUMN ; WARPARRVCOLUMN := WARPTEMPCOLUMN + PL3COLUMN... 04753 SBC #125 ; ... - 125 PM pixels (left edge of centered... 04754 CLC ; ...Hyperwarp Target Marker) 04755 ADC WARPTEMPCOLUMN ; 04756 AND #$7F ; Limit WARPARRVCOLUMN to 0..127 04757 STA WARPARRVCOLUMN ; 04758 04759 LDA MISSIONLEVEL ; Skip if NOVICE mission 04760 BEQ SKIP065 ; 04761 04762 LDA RANDOM ; Prep random number 04763 LDY SHIPVIEW ; Skip if in Front view 04764 BEQ SKIP064 ; 04765 04766 STA PL3COLUMN ; Randomize PM pixel row and column number... 04767 STA PL3ROWNEW ; ...of Hyperwarp Target Marker 04768 04769 SKIP064 CMP #16 ; Return in 94% (240:256) of game loops 04770 BCS SKIP066 ; 04771 04772 ;*** Veer off Hyperwarp Target Marker and return ******************************* 04773 SKIP065 LDA RANDOM ; Prep random x-velocity of Hyperwarp Target Marker 04774 ORA #$10 ; Velocity value >= 16 04775 AND VEERMASK ; Limit velocity value by mission level 04776 STA PL3XVEL ; PLAYER3 x-velocity := velocity value 04777 04778 LDA RANDOM ; Prep random y-velocity of Hyperwarp Target Marker 04779 ORA #$10 ; Velocity value >= 16 04780 AND VEERMASK ; Limit velocity value by mission level 04781 STA PL3YVEL ; PLAYER3 y-velocity := velocity value 04782 SKIP066 RTS ; Return 04783 04784 ;*** HYPERSPACE PHASE ********************************************************** 04785 SKIP067 TYA ; Skip if already in HYPERSPACE PHASE 04786 BMI SKIP068 ; 04787 04788 ;*** HYPERSPACE PHASE (First pass) ********************************************* 04789 LDA #$FF ; Set hyperwarp state to HYPERSPACE PHASE 04790 STA WARPSTATE ; 04791 04792 LDX #$00 ; Play beeper sound pattern HYPERWARP TRANSIT 04793 JSR BEEP ; 04794 04795 JSR CALCWARP ; Calc hyperwarp energy 04796 04797 LDY #$1B ; Prep title phrase "HYPERSPACE" 04798 JMP CLEANUPWARP ; Return via CLEANUPWARP 04799 04800 ;*** HYPERSPACE PHASE (Second and later passes) ******************************** 04801 SKIP068 DEC WARPENERGY ; Decrement energy in chunks of 10 energy units 04802 BEQ SKIP069 ; Skip to DECELERATION PHASE if hyperwarp energy zero 04803 04804 LDX #2 ; ENERGY := ENERGY - 10 and return 04805 JMP DECENERGY ; 04806 04807 ;*** DECELERATION PHASE ******************************************************** 04808 SKIP069 LDY #$19 ; Prep title phrase "HYPERWARP COMPLETE" 04809 JSR ENDWARP ; Stop our starship 04810 04811 LDA WARPARRVCOLUMN ; Make the arrival hyperwarp marker column number... 04812 STA WARPDEPRCOLUMN ; ...the departure hyperwarp marker column number 04813 LDA WARPARRVROW ; Make the arrival hyperwarp marker row number... 04814 STA WARPDEPRROW ; ...the departure hyperwarp marker row number 04815 04816 LSR A ; B3..1 of arrival hyperwarp marker row number... 04817 AND #$07 ; ...pick vicinity mask 04818 TAX ; 04819 LDA VICINITYMASKTAB,X ; 04820 STA VICINITYMASK ; Store vicinity mask (limits space obj coordinates) 04821 04822 LDY ARRVSECTOR ; Make the arrival sector the current sector 04823 STY CURRSECTOR ; 04824 04825 ;*** Init starbase in arrival sector ******************************************* 04826 LDA #0 ; Clear starbase-in-sector flag 04827 STA ISSTARBASESECT ; 04828 04829 LDX GCMEMMAP,Y ; Skip if no starbase in arrival sector 04830 BPL SKIP070 ; 04831 04832 LDA #$FF ; Set starbase-in-sector flag 04833 STA ISSTARBASESECT ; 04834 04835 ;*** Set position vector and velocity vector of starbase *********************** 04836 LDY #0 ; 04837 LOOP033 LDA #0 ; Loop over all coordinates of starbase 04838 STA PL2ZVEL,Y ; Starbase velocity vector component := 0 04839 LDA #1 ; 04840 STA PL2ZPOSSIGN,Y ; Starbase coordinate sign := + (positive) 04841 LDA RANDOM ; Prep random number... 04842 AND VICINITYMASK ; ...limit number range by vicinity mask, then... 04843 STA PL2ZPOSHI,Y ; ...store in starbase coordinate (high byte) 04844 04845 TYA ; 04846 CLC ; 04847 ADC #NUMSPCOBJ.ALL ; 04848 TAY ; 04849 CMP #NUMSPCOBJ.ALL*3 ; 04850 BCC LOOP033 ; Next starbase coordinate 04851 04852 LDA PL2ZPOSHI ; Force starbase z-coordinate >= +$71** 04853 ORA #$71 ; 04854 STA PL2ZPOSHI ; 04855 LDX #2 ; Randomly invert starbase x and y coordinates... 04856 JMP RNDINVXY ; ...and return 04857 04858 ;*** Flash red alert if Zylon sector entered *********************************** 04859 SKIP070 BEQ SKIP071 ; Skip if no Zylon ships in sector 04860 04861 LDA #255 ; Red alert lifetime := 255 game loops 04862 STA REDALERTLIFE ; 04863 04864 LDX #$06 ; Play beeper sound pattern RED ALERT 04865 JSR BEEP ; 04866 04867 LDY #$75 ; Set title phrase "RED ALERT" 04868 JSR SETTITLE ; 04869 04870 SKIP071 RTS ; Return 04871 04872 ;******************************************************************************* 04873 ;* * 04874 ;* ABORTWARP * 04875 ;* * 04876 ;* Abort hyperwarp * 04877 ;* * 04878 ;******************************************************************************* 04879 04880 ; DESCRIPTION 04881 ; 04882 ; Aborts hyperwarp. 04883 ; 04884 ; This subroutine is entered from subroutine KEYBOARD ($AFFE). It subtracts 100 04885 ; energy units for aborting the hyperwarp and preloads the title phrase with 04886 ; "HYPERWARP ABORTED". Code execution continues into subroutine ENDWARP 04887 ; ($A987). 04888 04889 ABORTWARP LDX #1 ; ENERGY := ENERGY - 100 after hyperwarp abort 04890 JSR DECENERGY ; 04891 04892 LDY #$17 ; Prep title phrase "HYPERWARP ABORTED" 04893 04894 ;******************************************************************************* 04895 ;* * 04896 ;* ENDWARP * 04897 ;* * 04898 ;* End hyperwarp * 04899 ;* * 04900 ;******************************************************************************* 04901 04902 ; DESCRIPTION 04903 ; 04904 ; Ends hyperwarp. 04905 ; 04906 ; This subroutine stops our starship's Engines and resets the hyperwarp state. 04907 ; Code execution continues into subroutine CLEANUPWARP ($A98D). 04908 04909 ENDWARP LDA #0 ; Stop Engines 04910 STA NEWVELOCITY ; 04911 STA WARPSTATE ; Disengage hyperwarp 04912 04913 ;******************************************************************************* 04914 ;* * 04915 ;* CLEANUPWARP * 04916 ;* * 04917 ;* Clean up hyperwarp variables * 04918 ;* * 04919 ;******************************************************************************* 04920 04921 ; DESCRIPTION 04922 ; 04923 ; Cleans up after a hyperwarp. 04924 ; 04925 ; This subroutine restores many hyperwarp related variables to their 04926 ; post-hyperwarp values: The number of used space objects is set to the regular 04927 ; value of 16 (5 PLAYER space objects + 12 PLAYFIELD space objects (stars)), our 04928 ; starship's velocity (high byte) is cleared as well as the explosion lifetime, 04929 ; the hit badness, the PLAYER3 shape type (Hyperwarp Target Marker), the Engines 04930 ; energy drain rate, and the lifetimes of the PLAYERs. The docking state is 04931 ; reset as well as the tracking digit. The title phrase is updated with either 04932 ; "HYPERSPACE" or "HYPERWARP ABORTED". 04933 ; 04934 ; INPUT 04935 ; 04936 ; Y = Title phrase offset. Used values are: 04937 ; $17 -> "HYPERWARP ABORTED" 04938 ; $1B -> "HYPERSPACE" 04939 04940 CLEANUPWARP LDA #NUMSPCOBJ.NORM-1 ; Set normal number of space objects 04941 STA MAXSPCOBJIND ; (5 PLAYER spc objs + 12 PLAYFIELD spc objs (stars)) 04942 04943 LDA #0 ; 04944 STA VELOCITYHI ; Turn off hyperwarp velocity 04945 STA EXPLLIFE ; Explosion lifetime := 0 game loops 04946 STA HITBADNESS ; HITBADNESS := NO HIT 04947 STA PL3SHAPTYPE ; Clear PLAYER3 shape type 04948 STA DRAINENGINES ; Clear Engines energy drain rate 04949 CPY #$17 ; Skip if hyperwarp was aborted 04950 BEQ SKIP072 ; 04951 04952 STA PL0LIFE ; Zylon ship 0 lifetime := 0 game loops 04953 STA PL1LIFE ; Zylon ship 1 lifetime := 0 game loops 04954 04955 SKIP072 STA PL2LIFE ; Zylon photon torpedo lifetime := 0 game loops 04956 STA PL3LIFE ; Hyperwarp Target Marker lifetime := 0 game loops 04957 STA PL4LIFE ; Photon torpedo 1 lifetime := 0 game loops 04958 STA DOCKSTATE ; DOCKSTATE := NO DOCKING 04959 STA TRACKDIGIT ; Clear index of tracked space object 04960 JMP SETTITLE ; Set title phrase and return 04961 04962 ;******************************************************************************* 04963 ;* * 04964 ;* INITTRAIL * 04965 ;* * 04966 ;* Initialize star trail during STAR TRAIL PHASE of hyperwarp * 04967 ;* * 04968 ;******************************************************************************* 04969 04970 ; DESCRIPTION 04971 ; 04972 ; BACKGROUND 04973 ; 04974 ; Star trails are displayed during the STAR TRAIL PHASE, that is, after the 04975 ; ACCELERATION PHASE and before the HYPERSPACE PHASE of the hyperwarp. 04976 ; 04977 ; A star trail is formed by 6 stars represented by 6 PLAYFIELD space objects 04978 ; with continuous position vector indices in 17..48 (indices are wrapped around 04979 ; when greater than 48). Between the creation of two star trails there is delay 04980 ; of 4 game loop iterations. 04981 ; 04982 ; DETAILS 04983 ; 04984 ; This subroutine first decrements this star trail creation delay, returning if 04985 ; the delay is still counting down. If the delay falls below 0 then it continues 04986 ; accelerating our starship's velocity toward hyperwarp speed and then creates a 04987 ; new star trail: 04988 ; 04989 ; First, it raises the maximum index of used space objects to 48 (increasing the 04990 ; number of displayed space objects to 49), resets the star trail creation delay 04991 ; to 4 game loop iterations, then forms a new star trail of 6 stars represented 04992 ; by 6 PLAYFIELD space objects. The x and y coordinates for all 6 stars are the 04993 ; same, picked randomly from tables WARPSTARXTAB ($BB3A) and WARPSTARYTAB 04994 ; ($BB3E), respectively, with their signs changed randomly. Their z-coordinates 04995 ; are computed in increasing depth from at least +4608 (+$12**) in 04996 ; intervals of +80 (+$0050) . Their velocity vector components are set to 0 04997 ; . 04998 04999 L.RANGE = $68 ; z-coordinate of star in star trail (16-bit value) 05000 L.TRAILCNT = $6E ; Star's index in star trail. Used values are: 0..5. 05001 05002 INITTRAIL DEC TRAILDELAY ; Decrement star trail delay 05003 BPL SKIP074 ; Return if delay still counting 05004 05005 LDA #1 ; Turn on hyperwarp velocity 05006 STA VELOCITYHI ; 05007 05008 LDA #NUMSPCOBJ.ALL-1 ; Max index of space objects (for star trail stars) 05009 STA MAXSPCOBJIND ; 05010 05011 LDA #3 ; Star trail delay := 3(+1) game loops 05012 STA TRAILDELAY ; 05013 05014 LDX TRAILIND ; Next avail. space obj index for star of star trail 05015 05016 LDA #$12 ; Star z-coordinate := >= +$12** (+4608) 05017 STA L.RANGE+1 ; 05018 05019 LDA RANDOM ; Calc random index to pick initial star coordinates 05020 AND #$03 ; 05021 TAY ; 05022 LDA WARPSTARXTAB,Y ; Pick x-coordinate (high byte) of star from table 05023 STA XPOSHI,X ; 05024 LDA WARPSTARYTAB,Y ; 05025 STA YPOSHI,X ; Pick y-coordinate (high byte) of star from table 05026 JSR RNDINVXY ; Randomize signs of x and y coordinates of star 05027 05028 TXA ; Save space object index 05029 TAY ; 05030 LDA #5 ; Loop over 5(+1) stars that form the star trail 05031 STA L.TRAILCNT ; Store star counter of star trail 05032 05033 LOOP034 CLC ; Place stars in z-coordinate intervals of +80 05034 LDA L.RANGE ; 05035 ADC #80 ; 05036 STA L.RANGE ; 05037 STA ZPOSLO,X ; 05038 LDA L.RANGE+1 ; 05039 ADC #0 ; 05040 STA L.RANGE+1 ; 05041 STA ZPOSHI,X ; 05042 05043 LDA #0 ; Star's velocity vector components := 0 05044 STA ZVEL,X ; 05045 STA XVEL,X ; 05046 STA YVEL,X ; 05047 LDA #1 ; Star's z-coordinate sign := + (= ahead of starship) 05048 STA ZPOSSIGN,X ; 05049 05050 LDA #99 ; Init pixel row and column numbers to magic... 05051 STA PIXELROWNEW,X ; ...offscreen value (triggers automatic recalc in... 05052 STA PIXELCOLUMN,X ; ...GAMELOOP's calls to SCREENCOLUMN and SCREENROW) 05053 05054 JSR COPYPOSXY ; Copy x and y coordinate from previous star in trail 05055 05056 DEX ; Decrement space object index to next star 05057 CPX #NUMSPCOBJ.NORM ; If index reaches minimum value... 05058 BCS SKIP073 ; 05059 LDX #NUMSPCOBJ.ALL-1 ; ...wrap-around to maximum space object index 05060 SKIP073 DEC L.TRAILCNT ; 05061 BPL LOOP034 ; Next star of star trail 05062 05063 STX TRAILIND ; Save space object index of star trail's last star 05064 SKIP074 RTS ; Return 05065 05066 ;******************************************************************************* 05067 ;* * 05068 ;* PROJECTION * 05069 ;* * 05070 ;* Calculate pixel column (or row) number from position vector * 05071 ;* * 05072 ;******************************************************************************* 05073 05074 ; Calculates the pixel column (or row) number of a position vector x (or y) 05075 ; component relative to the PLAYFIELD center by computing the perspective 05076 ; projection quotient 05077 ; 05078 ; QUOTIENT := DIVIDEND / DIVISOR * 128 05079 ; 05080 ; with 05081 ; 05082 ; DIVIDEND := ABS(x-coordinate (or y-coordinate)) / 2 05083 ; DIVISOR := ABS(z-coordinate) / 2 05084 ; 05085 ; If the QUOTIENT is in 0..255, it is used as an index to pick the pixel column 05086 ; (or row) number from table MAPTO80 ($0DE9), returning values in 0..80. 05087 ; 05088 ; If the QUOTIENT is larger than 255 ("dividend overflow") or if the 05089 ; z-coordinate = 0 ("division by zero") then the error value 255 is returned. 05090 ; 05091 ; INPUT 05092 ; 05093 ; X = Position vector index. Used values are: 0..48. 05094 ; DIVIDEND ($6A..$6B) = Dividend (positive 16-bit value), contains the 05095 ; absolute value of the x (or y) coordinate. 05096 ; 05097 ; OUTPUT 05098 ; 05099 ; A = Pixel column (or row) number relative to PLAYFIELD center. Used values 05100 ; are: 05101 ; 0..80 -> Pixel number 05102 ; 255 -> Error value indicating "dividend overflow" or "division by zero" 05103 05104 L.DIVISOR = $68 ; Divisor (16-bit value) 05105 L.QUOTIENT = $6D ; Division result (unsigned 8-bit value) 05106 L.LOOPCNT = $6E ; Division loop counter. Used values are: 7..0. 05107 05108 PROJECTION LDA #0 ; Init quotient result 05109 STA L.QUOTIENT ; 05110 05111 LDA #7 ; Init division loop counter 05112 STA L.LOOPCNT ; 05113 05114 LSR DIVIDEND+1 ; DIVIDEND := x-coordinate (or y-coordinate) / 2 05115 ROR DIVIDEND ; (division by 2 to make B15 = 0?) (?) 05116 05117 LDA SHIPVIEW ; Skip if in Aft view 05118 BNE SKIP075 ; 05119 05120 LDA ZPOSHI,X ; If in Front view -> DIVISOR := z-coordinate / 2 05121 LSR A ; (division by 2 to make B15 = 0?) (?) 05122 STA L.DIVISOR+1 ; 05123 LDA ZPOSLO,X ; 05124 ROR A ; 05125 STA L.DIVISOR ; 05126 JMP LOOP035 ; 05127 05128 SKIP075 SEC ; If in Aft view -> DIVISOR := - z-coordinate / 2 05129 LDA #0 ; (division by 2 to make B15 = 0?) (?) 05130 SBC ZPOSLO,X ; 05131 STA L.DIVISOR ; 05132 LDA #0 ; 05133 SBC ZPOSHI,X ; 05134 LSR A ; 05135 STA L.DIVISOR+1 ; 05136 ROR L.DIVISOR ; 05137 05138 LOOP035 ASL L.QUOTIENT ; QUOTIENT := DIVIDEND / DIVISOR * 128 05139 SEC ; 05140 LDA DIVIDEND ; 05141 SBC L.DIVISOR ; 05142 TAY ; 05143 LDA DIVIDEND+1 ; 05144 SBC L.DIVISOR+1 ; 05145 BCC SKIP076 ; 05146 05147 STA DIVIDEND+1 ; 05148 STY DIVIDEND ; 05149 INC L.QUOTIENT ; 05150 05151 SKIP076 ASL DIVIDEND ; 05152 ROL DIVIDEND+1 ; 05153 BCC SKIP077 ; 05154 05155 LDA #255 ; Return 255 if division by zero or dividend overflow 05156 RTS ; 05157 05158 SKIP077 DEC L.LOOPCNT ; 05159 BPL LOOP035 ; Next division loop iteration 05160 05161 LDY L.QUOTIENT ; Prep with quotient 05162 LDA MAPTO80,Y ; Pick and return pixel column (or row) number... 05163 SKIP078 RTS ; ...relative to PLAYFIELD center 05164 05165 ;******************************************************************************* 05166 ;* * 05167 ;* MANEUVER * 05168 ;* * 05169 ;* Maneuver our starship's and Zylon photon torpedoes and Zylon ships * 05170 ;* * 05171 ;******************************************************************************* 05172 05173 ; DESCRIPTION 05174 ; 05175 ; This subroutine maneuvers both of our starship's photon torpedoes, the single 05176 ; Zylon photon torpedo, and the one or two Zylon ships that are simultaneously 05177 ; displayed on the screen. It also creates meteors and new Zylon ships. This 05178 ; subroutine is executed only if our starship is not in a starbase sector and 05179 ; hyperwarp is not engaged. 05180 ; 05181 ; BACKGROUND 05182 ; 05183 ; When a Zylon ship is initialized, a "flight pattern" is assigned to it. There 05184 ; are 3 flight patterns (0, 1, and 4) which are picked from table ZYLONFLPATTAB 05185 ; ($BF91). 05186 ; 05187 ; The flight pattern determines the maximum velocity with which a Zylon ship can 05188 ; move along each axis of the 3D coordinate system, that is the maximum value of 05189 ; a velocity vector component. Velocity vector components for Zylon ships are 05190 ; picked from the Zylon velocity table ZYLONVELTAB ($BF99): 05191 ; 05192 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05193 ; | Velocity Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 05194 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05195 ; | Velocity | +62 | +30 | +16 | +8 | +4 | +2 | +1 | 0 | 05196 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05197 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05198 ; | Velocity Index | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 05199 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05200 ; | Velocity | 0 | -1 | -2 | -4 | -8 | -16 | -30 | -62 | 05201 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+ 05202 ; 05203 ; The index into the Zylon velocity table ZYLONVELTAB ($BF99) corresponding to 05204 ; the maximum velocity is called the "maximum velocity index". The following 05205 ; table shows the flight patterns, their maximum velocity indices, and their 05206 ; corresponding velocities: 05207 ; 05208 ; +----------------+------------------+------------------+ 05209 ; | Flight Pattern | Maximum Velocity | Maximum Velocity | 05210 ; | | Index | | 05211 ; +----------------+------------------+------------------+ 05212 ; | 0 | 0 | +62 | 05213 ; | 0 | 15 | -62 | 05214 ; | 1 | 1 | +30 | 05215 ; | 1 | 14 | -30 | 05216 ; | 4 | 4 | +4 | 05217 ; | 4 | 11 | -4 | 05218 ; +----------------+------------------+------------------+ 05219 ; 05220 ; Because flight pattern 0 produces the fastest-moving Zylon ships, which 05221 ; maneuver aggressively, it is called the "attack flight pattern". 05222 ; 05223 ; Each Zylon ship has a set of 3 maximum velocity indices, one for each of its 05224 ; velocity vector components. 05225 ; 05226 ; Each Zylon ship has also one more set of 3 velocity indices, called "Zylon 05227 ; velocity indices", one for each of its velocity vector components. They are 05228 ; used to pick the current values of the velocity vector components from the 05229 ; Zylon velocity table ZYLONVELTAB ($BF99). 05230 ; 05231 ; In order to maneuver Zylon ships this subroutine uses the concept of 05232 ; "milestone velocity indices". By using delay timers, called "Zylon timers", 05233 ; this subroutine gradually increases or decreases the Zylon velocity indices 05234 ; with every game loop iteration to eventually match the corresponding milestone 05235 ; velocity indices. By incrementing a Zylon velocity index a Zylon ship 05236 ; accelerates toward the negative direction of a coordinate axis. By 05237 ; decrementing a Zylon velocity index a Zylon ship accelerates toward the 05238 ; positive direction of a coordinate axis. If one milestone velocity index is 05239 ; matched or a "milestone timer" has counted down to 0, a new milestone velocity 05240 ; index is calculated and the matching of the current Zylon velocity indices 05241 ; with the new milestone velocity indices repeats. 05242 ; 05243 ; DETAILS 05244 ; 05245 ; For quick lookup, the following table lists the PLAYERs and what space objects 05246 ; they represent in this subroutine: 05247 ; 05248 ; +--------+---------------------------------+ 05249 ; | PLAYER | Represents | 05250 ; +--------+---------------------------------+ 05251 ; | 0 | Zylon Ship 0 | 05252 ; | 1 | Zylon Ship 1 | 05253 ; | 2 | Zylon Photon Torpedo, Meteor | 05254 ; | 3 | Our starship's Photon Torpedo 0 | 05255 ; | 4 | Our starship's Photon Torpedo 1 | 05256 ; +--------+---------------------------------+ 05257 ; 05258 ; This subroutine executes the following steps: 05259 ; 05260 ; (1) Update the x and y velocity vector components of both of our starship's 05261 ; photon torpedoes 0 and 1. 05262 ; 05263 ; The x and y velocity vector components of both of our starship's photon 05264 ; torpedoes 0 and 1 are only updated if they are tracking (homing in on) a 05265 ; target. 05266 ; 05267 ; To update the y-velocity vector components of both of our starship's 05268 ; photon torpedoes 0 and 1 the PLAYER row number difference between the 05269 ; PLAYER of tracked target space object and the current location of the 05270 ; PLAYER of our starship's photon torpedo 0 is passed to subroutine 05271 ; HOMINGVEL ($AECA). It returns the new y-velocity vector component value 05272 ; for both of our starship's photon torpedoes in . If the target is 05273 ; located below our starship's photon torpedo 0 a value of 0 is 05274 ; used. 05275 ; 05276 ; NOTE: The new y-velocity vector components depend only on the PLAYER row 05277 ; number of our starship's photon torpedo 0. 05278 ; 05279 ; To update the x-velocity vector components of both of our starship's 05280 ; photon torpedoes, the above calculation is repeated for the PLAYER column 05281 ; numbers of each of our starship's photon torpedoes 0 and 1. 05282 ; 05283 ; (2) Make the Zylon ships follow the rotation of our starship. 05284 ; 05285 ; If you rotate our starship away from Zylon ships they adjust their course 05286 ; such that they reappear in our starship's view. 05287 ; 05288 ; This is achieved by 4 Zylon timers, one for each of both Zylon ships' 05289 ; current x and y Zylon velocity indices. The Zylon timers are decremented 05290 ; every game loop iteration. If any of them reach a value of 0, the 05291 ; corresponding Zylon velocity index is incremented or decremented 05292 ; depending on the current joystick position. 05293 ; 05294 ; For example, if the Zylon timer for the x-velocity of Zylon ship 0 05295 ; reaches 0 and at the same time the joystick is pushed left then the 05296 ; x-Zylon velocity index of this Zylon ship is incremented. This 05297 ; accelerates the Zylon ship toward negative x-direction ("left"): The 05298 ; Zylon ship follows our starship's rotation. This works in Aft view, too, 05299 ; where the direction of change of the Zylon velocity index is reversed. 05300 ; After setting the new Zylon velocity index, it is used to pick a new 05301 ; Zylon timer value for this Zylon velocity index: 05302 ; 05303 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05304 ; | Velocity Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 05305 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05306 ; | Zylon Timer Value (Game Loops) | 0 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 05307 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05308 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05309 ; | Velocity Index | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 05310 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05311 ; | Zylon Timer Value (Game Loops) | 14 | 12 | 10 | 8 | 6 | 4 | 2 | 0 | 05312 ; +--------------------------------+----+----+----+----+----+----+----+----+ 05313 ; 05314 ; (3) Update the x and y velocity vector components of the single Zylon photon 05315 ; torpedo. 05316 ; 05317 ; If a Zylon photon torpedo is moving toward our starship then update its x 05318 ; and y velocity vector components. They are picked from table 05319 ; ZYLONHOMVELTAB ($BF85) and depend on the mission level. The signs of the 05320 ; velocity vector components are always set such that the Zylon photon 05321 ; torpedo is guided toward our starship. 05322 ; 05323 ; (4) Create a meteor? 05324 ; 05325 ; If PLAYER2, the PLAYER to represent a meteor, is either initial or not 05326 ; alive, then attempt in 7 out of 8 game loop iterations to create a new 05327 ; meteor. 05328 ; 05329 ; With a probability of 2% (4:256) a new meteor is created: Its shape type 05330 ; is set to METEOR, its position vector components to random coordinates in 05331 ; subroutine INITPOSVEC ($B764), its lifetime to 60 game loop iterations, 05332 ; and its velocity vector components (velocities) to x-velocity: 0 , 05333 ; y-velocity: 0 , z-velocity: -8 . Then code execution returns. 05334 ; 05335 ; (5) Toggle Zylon ship control. 05336 ; 05337 ; Every other game loop iteration, the program takes control of and 05338 ; maneuvers the other Zylon ship. 05339 ; 05340 ; (6) Create new Zylon ship? 05341 ; 05342 ; If the program-controlled Zylon ship is not alive, check if both Zylon 05343 ; ships are not alive and this is an empty sector. If so, then attempt to 05344 ; create a meteor. Otherwise create a new Zylon ship with infinite 05345 ; lifetime. Randomly pick its shape type from table ZYLONSHAPTAB ($BF89) 05346 ; (BASESTAR, ZYLON CRUISER, or ZYLON FIGHTER) and its flight pattern from 05347 ; table ZYLONFLPATTAB ($BF91) (attack flight pattern 0 is always picked in 05348 ; a NOVICE mission). Then set the milestone timer to 1 game loop iteration 05349 ; and the position vector of the Zylon ship to a position of at least 05350 ; +28928 (+$71**) in front of our starship. The y-coordinate depends 05351 ; on the value of VICINITYMASK ($C7). The x-coordinate is the sum of the 05352 ; y-coordinate plus at least 4864..5119 ($13**) . Randomly choose the 05353 ; signs of the x and y coordinates. 05354 ; 05355 ; (7) Set the current flight pattern to attack flight pattern? 05356 ; 05357 ; The current flight pattern of the Zylon ship will change to attack flight 05358 ; pattern if it is close enough (z-coordinate < +8192 (+$20**) ) and 05359 ; one of the following conditions is met: 05360 ; 05361 ; o The Zylon ship is located behind our starship. 05362 ; 05363 ; o The shape of the Zylon ship is not initial and does not currently 05364 ; appear as a blip in the Long-Range Scan view. 05365 ; 05366 ; (8) Update the back-attack flag and the milestone velocity indices. 05367 ; 05368 ; The milestone timer is decremented for the program-controlled Zylon ship. 05369 ; If this timer reaches a value of 0 the following steps are executed: 05370 ; 05371 ; o The milestone timer is reset to a value of 120 game loop iterations. 05372 ; 05373 ; o The back-attack flag is updated. It determines if the 05374 ; program-controlled Zylon ship not only attacks from the front of our 05375 ; starship but also from the back. A back-attack takes place with a 05376 ; probability of 19% (48:256) in WARRIOR or COMMANDER missions. 05377 ; 05378 ; o Course corrections are prepared for the program-controlled Zylon ship 05379 ; by computing the new milestone vector indices, resulting in new 05380 ; velocity vector components for this Zylon ship. The new milestone 05381 ; velocity indices for each velocity vector component are randomly 05382 ; chosen depending of the flight pattern. Recall that the Zylon 05383 ; velocity index is changed gradually to match the milestone velocity 05384 ; index. It corresponds to a maximum velocity vector component when 05385 ; using this index to pick a velocity vector component from Zylon 05386 ; velocity table ZYLONVELTAB ($BF99): 05387 ; 05388 ; +----------------+----------------+------------------+ 05389 ; | Flight Pattern | New Milestone | Maximum Velocity | 05390 ; | | Velocity Index | Vector Component | 05391 ; +----------------+----------------+------------------+ 05392 ; | 0 | 0 | +62 | 05393 ; | 0 | 15 | -62 | 05394 ; | 1 | 1 | +30 | 05395 ; | 1 | 14 | -30 | 05396 ; | 4 | 4 | +4 | 05397 ; | 4 | 11 | -4 | 05398 ; +----------------+----------------+------------------+ 05399 ; 05400 ; (9) Update milestone velocity indices in attack flight pattern. 05401 ; 05402 ; If a Zylon ship executes the attack flight pattern, its milestone 05403 ; velocity indices are changed depending on the current location of the 05404 ; Zylon ship as follows: 05405 ; 05406 ; +--------------+-------------+----------------+------------+----------------+ 05407 ; | x-Coordinate | Where on | Milestone | Velocity | Zylon Ship | 05408 ; | | Screen | Velocity Index | | Accelerates... | 05409 ; +--------------+-------------+----------------+------------+----------------+ 05410 ; | x < 0 | left half | 0 | +62 | to the right | 05411 ; | x >= 0 | right half | 15 | -62 | to the left | 05412 ; +--------------+-------------+----------------+------------+----------------+ 05413 ; +--------------+-------------+----------------+------------+----------------+ 05414 ; | y-Coordinate | Where on | Milestone | Velocity | Zylon Ship | 05415 ; | | Screen | Velocity Index | | Accelerates... | 05416 ; +--------------+-------------+----------------+------------+----------------+ 05417 ; | y < 0 | bottom half | 0 | +62 | up | 05418 ; | y >= 0 | top half | 15 | -62 | down | 05419 ; +--------------+-------------+----------------+------------+----------------+ 05420 ; 05421 ; Thus, with respect to its x and y coordinates, the Zylon ship oscillates 05422 ; around the center of the Front or Aft view. 05423 ; 05424 ; This is the behavior of the Zylon ship along the z-axis: 05425 ; 05426 ; If the Zylon ship attacks from the front: 05427 ; 05428 ; +--------------------------+----------------+------------+----------------+ 05429 ; | z-Coordinate | Milestone | Velocity | Zylon Ship | 05430 ; | | Velocity Index | | Accelerates... | 05431 ; +--------------------------+----------------+------------+----------------+ 05432 ; | z < +2560 (+$0A00) | 0 | +62 | outbound | 05433 ; | z >= +2560 (+$0A00) | 15 | -62 | inbound | 05434 ; +--------------------------+----------------+------------+----------------+ 05435 ; 05436 ; In other words, the Zylon ship accelerates into positive z-direction 05437 ; (outbound) up to a distance of +2560 (+$0A00) , then reverses its 05438 ; course and returns back to our starship (inbound). 05439 ; 05440 ; If the Zylon ship attacks from the back: 05441 ; 05442 ; +--------------------------+----------------+------------+----------------+ 05443 ; | z-Coordinate | Milestone | Velocity | Zylon Ship | 05444 ; | | Velocity Index | | Accelerates... | 05445 ; +--------------------------+----------------+------------+----------------+ 05446 ; | z < -2816 (-$F500) | 0 | +62 | inbound | 05447 ; | z >= -2816 (-$F500) | 15 | -62 | outbound | 05448 ; +--------------------------+----------------+------------+----------------+ 05449 ; 05450 ; In other words, the Zylon ship accelerates into negative z-direction 05451 ; (outbound) up to a distance of -2816 (-$(0B00)) , then reverses its 05452 ; course and returns back to our starship (inbound). 05453 ; 05454 ; (10) Change Zylon velocity index toward milestone velocity index. 05455 ; 05456 ; Compare all 3 Zylon velocity indices of the program-controlled Zylon ship 05457 ; with their corresponding milestone velocity indices. Increment or 05458 ; decrement the former to better match the latter. Use the new Zylon 05459 ; velocity indices to pick the current velocity values from Zylon velocity 05460 ; table ZYLONVELTAB ($BF99). 05461 ; 05462 ; (11) Launch a Zylon photon torpedo? 05463 ; 05464 ; Prepare launching a Zylon photon torpedo if either of the following 05465 ; conditions are met: 05466 ; 05467 ; o PLAYER2 is not used as a photon torpedo 05468 ; 05469 ; o The y-coordinate of the Zylon ship is in the range of -768..+767 05470 ; (-$0300..+$2FF) . 05471 ; 05472 ; or if 05473 ; 05474 ; o The Zylon photon torpedo is not alive 05475 ; 05476 ; o The corresponding Zylon photon torpedo delay timer has reached a 05477 ; value of 0 05478 ; 05479 ; o The y-coordinate of the Zylon ship is in the range of -768..+767 05480 ; (-$0300..+$2FF) . 05481 ; 05482 ; At this point the z-velocity vector component of the Zylon photon torpedo 05483 ; is preloaded with a value of -80 or +80 depending on the Zylon 05484 ; ship being in front or behind of our starship, respectively. 05485 ; 05486 ; Launch a Zylon photon torpedo if both of the following conditions are 05487 ; met: 05488 ; 05489 ; o The Zylon ship is in front or behind of our starship, with the 05490 ; exception of a Zylon ship behind our starship in a NOVICE mission 05491 ; (our starship will never be shot in the back in a NOVICE mission). 05492 ; 05493 ; o The z-coordinate of the Zylon ship (no matter if in front or behind 05494 ; our starship) is closer than 8192 ($20**) . 05495 ; 05496 ; Finally, the Zylon photon torpedo is launched with a lifetime of 62 game 05497 ; loop iterations. Its position vector is copied from the launching Zylon 05498 ; ship in subroutine COPYPOSVEC ($ACAF). In addition, the Zylon ship is 05499 ; earmarked for the tracking computer. 05500 05501 L.CTRLDZYLON = $6A ; Index of currently program-controlled Zylon ship. 05502 ; Used values are: 05503 ; 0 -> Control Zylon ship 0 05504 ; 1 -> Control Zylon ship 1 05505 NEG = $80 ; Negative sign bit for velocity vector component 05506 05507 MANEUVER LDA WARPSTATE ; Return if in starbase sector or hyperwarp engaged 05508 ORA ISSTARBASESECT ; 05509 BNE SKIP078 ; 05510 05511 ;*** Update x and y velocity of both our starship's photon torpedoes 0 and 1 *** 05512 LDA ISTRACKING ; Skip this if ship's torpedoes not tracking a target 05513 BEQ SKIP080 ; 05514 05515 LDX PLTRACKED ; Load PLAYER index of tracked target space object 05516 05517 SEC ; Prep A := PLAYER row number of target... 05518 LDA PL0ROWNEW,X ; ...- PLAYER row number photon torpedo 0 05519 SBC PL3ROWNEW ; 05520 BCC SKIP079 ; Skip if target above our starship's photon torpedo 05521 LDA #0 ; Prep A := 0 05522 SKIP079 JSR HOMINGVEL ; Get y-velocity for homing photon torpedo 0 and 1 05523 STA PL3YVEL ; Store y-velocity photon torpedo 0 05524 STA PL4YVEL ; Store y-velocity photon torpedo 1 05525 05526 SEC ; Prep A := PLAYER column number of target... 05527 LDA PL3COLUMN ; ...- PLAYER column number of photon torpedo 0 05528 SBC PL0COLUMN,X ; 05529 JSR HOMINGVEL ; Get x-velocity for homing photon torpedo 0 05530 STA PL3XVEL ; Store x-velocity of photon torpedo 0 05531 05532 SEC ; Prep A := PLAYER column number of target... 05533 LDA PL4COLUMN ; ...- PLAYER column number of photon torpedo 1 05534 SBC PL0COLUMN,X ; 05535 JSR HOMINGVEL ; Get x-velocity for homing photon torpedo 1 05536 STA PL4XVEL ; Store x-velocity of photon torpedo 1 05537 05538 ;*** Make Zylon ships follow rotation of our starship ************************** 05539 SKIP080 LDX #3 ; Loop over x and y velocity indices of both Zylons 05540 LOOP036 DEC ZYLONTIMX0,X ; Decrement Zylon timer 05541 BPL SKIP085 ; Next timer if this one still counting down 05542 05543 TXA ; Prep joystick (x or y) value in -1, 0, +1 05544 LSR A ; 05545 TAY ; 05546 LDA JOYSTICKX,Y ; 05547 05548 LDY SHIPVIEW ; Skip if in Front view 05549 BEQ SKIP081 ; 05550 05551 EOR #$FF ; Invert joystick value (when in Aft view) 05552 CLC ; (two's-complement) 05553 ADC #1 ; 05554 05555 SKIP081 CLC ; Add joystick value to Zylon velocity index 05556 ADC ZYLONVELINDX0,X ; 05557 BPL SKIP082 ; 05558 LDA #0 ; 05559 SKIP082 CMP #16 ; Limit new Zylon velocity index to 0..15 ... 05560 BCC SKIP083 ; 05561 LDA #15 ; 05562 SKIP083 STA ZYLONVELINDX0,X ; ...and store new Zylon velocity index 05563 05564 CMP #8 ; Calc new Zylon timer value in 0, 2, ..., 14 05565 BCC SKIP084 ; 05566 EOR #$0F ; 05567 SKIP084 ASL A ; 05568 STA ZYLONTIMX0,X ; ...and store new Zylon timer value 05569 05570 SKIP085 DEX ; 05571 BPL LOOP036 ; Next Zylon timer 05572 05573 ;*** Update x and y velocity of single Zylon photon torpedo ******************** 05574 LDA PL2SHAPTYPE ; Skip if PLAYER2 not PHOTON TORPEDO (shape type 0) 05575 BNE SKIP088 ; 05576 05577 LDY MISSIONLEVEL ; Depending on mission level... 05578 LDA ZYLONHOMVELTAB,Y ; ...pick (initially negative) Zylon torpedo velocity 05579 05580 LDX PL2YPOSHI ; If photon torpedo in upper screen half (y >= 0)... 05581 BPL SKIP086 ; ...don't toggle velocity sign -> torpedo goes down 05582 AND #$7F ; ...toggle velocity sign -> torpedo goes up 05583 SKIP086 STA PL2YVEL ; Store new y-velocity of Zylon photon torpedo 05584 05585 ORA #NEG ; Restore negative sign bit of velocity 05586 05587 LDX PL2XPOSHI ; If photon torpedo in right screen half (x >= 0)... 05588 BPL SKIP087 ; ...don't toggle velocity sign -> torpedo goes left 05589 AND #$7F ; ...toggle velocity sign -> torpedo goes right 05590 SKIP087 STA PL2XVEL ; Store new x-velocity of Zylon photon torpedo 05591 05592 ;*** Create new meteor? ******************************************************** 05593 SKIP088 LDA COUNT256 ; Attempt meteor creation in 7 out of 8 game loops 05594 AND #$03 ; 05595 BEQ SKIP092 ; 05596 05597 SKIP089 LDA PL2SHAPOFF ; If PLAYER2 shape is initial try to create a meteor 05598 BEQ SKIP090 ; 05599 05600 LDA PL2LIFE ; Return if PLAYER2 alive 05601 BNE SKIP091 ; 05602 05603 SKIP090 LDA RANDOM ; Return in 98% (252:256) (do not create meteor) 05604 CMP #4 ; 05605 BCS SKIP091 ; 05606 05607 ;*** Create new meteor! ******************************************************** 05608 LDA #SHAP.METEOR ; PLAYER2 is METEOR (shape type 6) 05609 STA PL2SHAPTYPE ; 05610 LDX #2 ; Randomize position vector of meteor 05611 JSR INITPOSVEC ; 05612 LDA #60 ; Meteor lifetime := 60 game loops 05613 STA PL2LIFE ; 05614 LDA #NEG!8 ; SUMMARY: 05615 STA PL2ZVEL ; x-velocity := 0 05616 LDA #0 ; y-velocity := 0 05617 STA PL2COLUMN ; z-velocity := -8 05618 STA PL2XVEL ; 05619 STA PL2YVEL ; PLAYER2 column number := 0 (offscreen) 05620 SKIP091 RTS ; Return 05621 05622 ;*** Toggle Zylon ship control ************************************************* 05623 SKIP092 LDA CTRLDZYLON ; Toggle control to the other Zylon ship 05624 EOR #$01 ; 05625 STA CTRLDZYLON ; 05626 05627 ;*** Create a new Zylon ship? ************************************************** 05628 TAX ; Save index of controlled Zylon ship 05629 LDA PL0LIFE,X ; Skip creating Zylon ship if its PLAYER still alive 05630 BNE SKIP094 ; 05631 05632 LDA PL0LIFE ; If both Zylon ships are not alive... 05633 ORA PL1LIFE ; 05634 AND #$01 ; 05635 LDY CURRSECTOR ; ...and this an empty sector... 05636 CMP GCMEMMAP,Y ; 05637 BCS SKIP089 ; ...attempt to create meteor and return 05638 05639 ;*** Create a new Zylon ship! ************************************************** 05640 LDA #255 ; Zylon ship lifetime := 255 game loops (infinite) 05641 STA PL0LIFE,X ; 05642 05643 LDA RANDOM ; Pick a Zylon ship shape type (1 out of 8) 05644 AND #$07 ; 05645 TAY ; 05646 LDA ZYLONSHAPTAB,Y ; 05647 STA PL0SHAPTYPE,X ; 05648 05649 LDA MISSIONLEVEL ; Init Zylon's flight pattern (0 if NOVICE mission) 05650 BEQ SKIP093 ; 05651 LDA ZYLONFLPATTAB,Y ; 05652 SKIP093 STA ZYLONFLPAT0,X ; 05653 05654 LDA #1 ; Zylon ship's milestone timer := 1 game loop 05655 STA MILESTTIM0,X ; 05656 05657 STA ZPOSSIGN,X ; Put Zylon ship in front of our starship 05658 LDA RANDOM ; 05659 AND VICINITYMASK ; y-coordinate (high byte) := RND(0..VICINITYMASK) 05660 STA YPOSHI,X ; 05661 ADC #19 ; x-coordinate (high byte) := y (high byte) + 19 05662 STA XPOSHI,X ; 05663 ORA #$71 ; z-coordinate (high byte) := >= +28928 (+$71**) 05664 STA ZPOSHI,X ; 05665 JSR RNDINVXY ; Randomly invert x and y coordinate of pos vector 05666 05667 ;*** Set current flight pattern to attack flight pattern? ********************** 05668 SKIP094 LDA ZPOSHI,X ; Skip if Zylon too distant (z >= +$20** ) 05669 CMP #$20 ; 05670 BCS SKIP096 ; 05671 05672 LDA ZPOSSIGN,X ; Set attack flight pattern if Zylon is behind 05673 BEQ SKIP095 ; 05674 05675 LDA PL0SHAPOFF,X ; Skip if Zylon shape initial 05676 BEQ SKIP096 ; 05677 05678 CMP #$29 ; Skip if Zylon shape is Long-Range Scan blip 05679 BEQ SKIP096 ; 05680 05681 SKIP095 LDA #0 ; Set attack flight pattern 05682 STA ZYLONFLPAT0,X ; 05683 05684 ;*** Update back-attack flag and milestone velocity indices ******************** 05685 SKIP096 DEC MILESTTIM0,X ; Skip if milestone timer still counting down 05686 BPL SKIP099 ; 05687 05688 LDA #120 ; Milestone timer := 120 game loops 05689 STA MILESTTIM0,X ; 05690 05691 LDA MISSIONLEVEL ; Back-attack flag := 1 in 19% (48:256) of... 05692 LDY RANDOM ; ...WARRIOR or COMMANDER missions 05693 CPY #48 ; ... := 0 otherwise 05694 BCC SKIP097 ; 05695 LSR A ; 05696 SKIP097 LSR A ; 05697 STA ISBACKATTACK0,X ; 05698 05699 ; Loop over all 3 milestone velocity indices 05700 LDA ZYLONFLPAT0,X ; Set new milestone velocity index: 05701 LOOP037 BIT RANDOM ; If Zylon flight pattern is... 05702 BPL SKIP098 ; ...0 -> milestone velocity index := either 0 or 15 05703 EOR #$0F ; ...1 -> milestone velocity index := either 1 or 14 05704 SKIP098 STA MILESTVELINDZ0,X ; ...4 -> milestone velocity index := either 4 or 11 05705 INX ; 05706 INX ; 05707 CPX #6 ; 05708 BCC LOOP037 ; Next Zylon milestone velocity index 05709 05710 ;*** Update milestone velocity indices in attack flight pattern **************** 05711 LDX CTRLDZYLON ; Reload index of controlled Zylon ship 05712 05713 SKIP099 LDA ZYLONFLPAT0,X ; Skip if not in attack flight pattern 05714 BNE SKIP105 ; 05715 05716 LDY CTRLDZYLON ; Reload index of controlled Zylon ship 05717 05718 ; Loop over all 3 milestone velocity indices 05719 LOOP038 CPY #$31 ; Skip to handle x and y velocity index 05720 BCS SKIP101 ; 05721 ; SUMMARY: 05722 LDA ISBACKATTACK0,Y ; Handle z-velocity index: 05723 LSR A ; 05724 LDA ZPOSHI,Y ; If Zylon attacks from front... 05725 BCS SKIP100 ; z < $0A00 -> mil vel index := 0 (+62 ) 05726 CMP #$0A ; z >= $0A00 -> mil vel index := 15 (-62 ) 05727 BCC SKIP103 ; 05728 BCS SKIP101 ; If Zylon attacks from back... 05729 SKIP100 CMP #$F5 ; z >= $F500 -> mil vel index := 15 (-62 ) 05730 BCS SKIP102 ; z < $F500 -> mil vel index := 0 (+62 ) 05731 05732 SKIP101 LDA ZPOSSIGN,Y ; Handle x and y velocity index: 05733 LSR A ; 05734 SKIP102 LDA #15 ; x >= 0 -> mil vel index := 15 (-62 ) 05735 BCS SKIP104 ; x < 0 -> mil vel index := 0 (+62 ) 05736 SKIP103 LDA #0 ; y >= 0 -> mil vel index := 15 (-62 ) 05737 SKIP104 STA MILESTVELINDZ0,X ; y < 0 -> mil vel index := 0 (+62 ) 05738 05739 CLC ; Adjust position vector component index 05740 TYA ; 05741 ADC #NUMSPCOBJ.ALL ; 05742 TAY ; 05743 05744 INX ; 05745 INX ; 05746 CPX #6 ; 05747 BCC LOOP038 ; Next milestone velocity index 05748 05749 ;*** Acceleration: Change Zylon velocity index toward milestone velocity index * 05750 LDX CTRLDZYLON ; Reload index of controlled Zylon ship 05751 SKIP105 LDY CTRLDZYLON ; Reload index of controlled Zylon ship 05752 05753 ; Loop over all 3 milestone velocity indices 05754 LOOP039 LDA ZYLONVELINDZ0,X ; Compare Zylon velocity index with milestone index 05755 CMP MILESTVELINDZ0,X ; 05756 BEQ SKIP107 ; Skip if equal 05757 BCS SKIP106 ; 05758 INC ZYLONVELINDZ0,X ; Increm. Zylon velocity index if < milestone index 05759 BCC SKIP107 ; 05760 SKIP106 DEC ZYLONVELINDZ0,X ; Decrem. Zylon velocity index if >= milestone index 05761 05762 SKIP107 STX L.CTRLDZYLON ; Save index of controlled Zylon ship 05763 TAX ; 05764 LDA ZYLONVELTAB,X ; Pick new velocity value by Zylon velocity index 05765 LDX L.CTRLDZYLON ; Reload index of controlled Zylon ship 05766 STA ZVEL,Y ; Store new velocity vector component of Zylon ship 05767 05768 TYA ; Next velocity vector component 05769 CLC ; 05770 ADC #NUMSPCOBJ.ALL ; 05771 TAY ; 05772 05773 INX ; 05774 INX ; 05775 CPX #6 ; 05776 BCC LOOP039 ; Next milestone velocity index 05777 05778 ;*** Launch Zylon photon torpedo? ********************************************** 05779 05780 ;*** Check PLAYER2 shape and lifetime ****************************************** 05781 LDX CTRLDZYLON ; Reload index of controlled Zylon ship 05782 05783 LDA PL2SHAPTYPE ; Skip if PLAYER2 not PHOTON TORPEDO (shape type 0) 05784 BNE SKIP109 ; 05785 05786 LDA PL2LIFE ; Return if Zylon photon torpedo still alive 05787 BNE SKIP108 ; 05788 05789 LDA TORPEDODELAY ; Count down Zylon photon torpedo delay timer... 05790 BEQ SKIP109 ; ...before launching next Zylon photon torpedo 05791 DEC TORPEDODELAY ; 05792 SKIP108 RTS ; Return 05793 05794 ;*** Check y-coordinate of Zylon ship ****************************************** 05795 SKIP109 CLC ; Return if Zylon ship's y-coordinate not... 05796 LDA YPOSHI,X ; ...in -768..+767 (-$(0300)..+$2FF) . 05797 ADC #2 ; 05798 CMP #5 ; 05799 BCS SKIP108 ; 05800 05801 ;*** Set Zylon photon torpedo's z-velocity ************************************* 05802 LDY #NEG!80 ; Prep Zylon torpedo's z-velocity := -80 05803 05804 LDA ZPOSSIGN,X ; Prep Zylon ship's sign of z-coordinate 05805 LSR A ; 05806 LDA ZPOSHI,X ; Prep Zylon ship's z-coordinate 05807 BCS SKIP110 ; Skip if Zylon ship in front... 05808 EOR #$FF ; ...else invert loaded Zylon ship's z-coordinate 05809 05810 LDY MISSIONLEVEL ; Return (no torpedo from back) if NOVICE mission 05811 BEQ SKIP108 ; 05812 05813 LDY #80 ; Preload Zylon torpedo's z-velocity := +80 05814 05815 ;*** Is Zylon ship in range? *************************************************** 05816 SKIP110 CMP #$20 ; Return if Zylon ship too far... 05817 BCS SKIP108 ; ... (ABS(z-coordinate) > 8192 ($20**) ) 05818 05819 STY PL2ZVEL ; Store Zylon photon torpedo's z-velocity 05820 05821 ;*** Launch Zylon photon torpedo! ********************************************** 05822 05823 LDA #0 ; PLAYER2 is PHOTON TORPEDO (shape type 0) 05824 STA PL2SHAPTYPE ; 05825 STA PL2COLUMN ; Zylon torpedo PLAYER column number := 0 (offscreen) 05826 LDA #62 ; 05827 STA PL2LIFE ; Zylon torpedo lifetime := 62 game loops 05828 05829 LDX #2 ; Prep source index for position vector copy 05830 LDY CTRLDZYLON ; Prep destination index for position vector copy 05831 STY ZYLONATTACKER ; Save Zylon ship index for tracking computer 05832 JMP COPYPOSVEC ; Copy position vector from Zylon ship to its torpedo 05833 05834 ;******************************************************************************* 05835 ;* * 05836 ;* INITEXPL * 05837 ;* * 05838 ;* Initialize explosion * 05839 ;* * 05840 ;******************************************************************************* 05841 05842 ; DESCRIPTION 05843 ; 05844 ; Initializes the explosion's lifetime, the explosion fragments' position and 05845 ; velocity vectors as well as their pixel row and column numbers. 05846 ; 05847 ; An explosion has a lifetime of 128 game loop iterations. It consists of 32 05848 ; explosion fragment space objects with indices 17..48. The position vector of 05849 ; each explosion fragment is copied from the exploding PLAYER space object. 05850 ; 05851 ; The pixel column number of each explosion fragment is initialized to 05852 ; 05853 ; PIXEL COLUMN NUMBER := PLAYER column number - 48 + RND(0..15) 05854 ; 05855 ; To convert PLAYER column numbers (in Player/Missile (PM) pixels) into pixel 05856 ; column numbers, the PLAYER column number of the left PLAYFIELD border (= 48) 05857 ; is subtracted and a random number is added. 05858 ; 05859 ; BUG (at $AC76): The added random number should not be in 0..15 but in 0..7 05860 ; because the exploding PLAYER is 8 pixels wide. The PLAYER column number 05861 ; represents the left edge of the PLAYER shape. When using a random number in 05862 ; 0..15, half of the pixels are located off to the right of the PLAYER, outside 05863 ; the PLAYER area. Suggested fix: Replace instruction AND #$0F with AND #$07. 05864 ; 05865 ; The pixel row number of each explosion fragment is initialized to 05866 ; 05867 ; PIXEL ROW NUMBER := (PLAYER row number - RND(0..15)) / 2 - 16 05868 ; 05869 ; BUG (at $AC88): To convert PLAYER row numbers (in PM pixels) into pixel row 05870 ; numbers, the PLAYER row number to the top PLAYFIELD border (= 16) should be 05871 ; subtracted first, then the division by 2 (instruction LRS A) should be applied 05872 ; to reduce the double-line PM resolution to the single-line PLAYFIELD 05873 ; resolution. Suggested fix: Swap instruction LRS A with SBC #16 which leads to 05874 ; the following formula for the pixel row number: 05875 ; 05876 ; PIXEL ROW NUMBER := (PLAYER row number - 16 + RND(0..15)) / 2 05877 ; 05878 ; Incidentally, adding a random number in 0..15 is correct. PLAYER row number 05879 ; represents the top edge of the PLAYER shape, which is typically 16 PM pixels 05880 ; tall when representing a close space object. 05881 ; 05882 ; The velocity vector of explosion fragments is set to random x, y, and z 05883 ; velocity vector components in -7..+7 . 05884 ; 05885 ; INPUT 05886 ; 05887 ; Y = PLAYER index from which the explosion originates. Used values are: 05888 ; 0 -> Explosion of PLAYER0 (Zylon ship 0) 05889 ; 1 -> Explosion of PLAYER1 (Zylon ship 1) 05890 ; 2 -> Explosion of PLAYER2 (Zylon photon torpedo, starbase, or meteor) 05891 05892 INITEXPL LDA #128 ; Explosion lifetime := 128 game loops 05893 STA EXPLLIFE ; 05894 05895 LDX #NUMSPCOBJ.ALL-1 ; Max index of space objects (for explosion frags) 05896 STX MAXSPCOBJIND ; 05897 05898 ; Loop over all explosion fragment position vectors 05899 ; (index 48..17) 05900 LOOP040 LDA RANDOM ; PIXEL COLUMN NUM := PLAYER column - 48 + RND(0..15) 05901 AND #$0F ; (!) 05902 ADC PL0COLUMN,Y ; 05903 SBC #48 ; 05904 STA PIXELCOLUMN,X ; 05905 05906 LDA RANDOM ; PIXEL ROW NUM := (PLAYER row + RND(0..15)) / 2 - 16 05907 AND #$0F ; 05908 ADC PL0ROWNEW,Y ; 05909 LSR A ; (!) 05910 SBC #16 ; 05911 STA PIXELROWNEW,X ; 05912 05913 JSR COPYPOSVEC ; Copy position vector of PLAYER to explosion frag 05914 05915 LDA RANDOM ; z-velocity := RND(-7..+7) 05916 AND #NEG!7 ; 05917 STA ZVEL,X ; 05918 LDA RANDOM ; x-velocity := RND(-7..+7) 05919 AND #NEG!7 ; 05920 STA XVEL,X ; 05921 LDA RANDOM ; y-velocity := RND(-7..+7) 05922 AND #NEG!7 ; 05923 STA YVEL,X ; 05924 05925 DEX ; Next explosion fragment position vector 05926 CPX #16 ; 05927 BNE LOOP040 ; 05928 RTS ; Return 05929 05930 ;******************************************************************************* 05931 ;* * 05932 ;* COPYPOSVEC * 05933 ;* * 05934 ;* Copy a position vector * 05935 ;* * 05936 ;******************************************************************************* 05937 05938 ; DESCRIPTION 05939 ; 05940 ; Copies a position vector. 05941 ; 05942 ; Actually, this subroutine copies the z-coordinate only, then code execution 05943 ; continues into subroutine COPYPOSXY ($ACC1) to copy the x and y coordinate. 05944 ; 05945 ; INPUT 05946 ; 05947 ; X = Destination position vector index. Used values are: 0..48. 05948 ; Y = Source position vector index. Used values are: 0..48. 05949 05950 COPYPOSVEC LDA ZPOSSIGN,Y ; 05951 STA ZPOSSIGN,X ; 05952 LDA ZPOSHI,Y ; 05953 STA ZPOSHI,X ; 05954 LDA ZPOSLO,Y ; 05955 STA ZPOSLO,X ; 05956 05957 ;******************************************************************************* 05958 ;* * 05959 ;* COPYPOSXY * 05960 ;* * 05961 ;* Copy x and y components (coordinates) of position vector * 05962 ;* * 05963 ;******************************************************************************* 05964 05965 ; DESCRIPTION 05966 ; 05967 ; Copies the x and y components (coordinates) of a position vector. 05968 ; 05969 ; INPUT 05970 ; 05971 ; X = Destination position vector index. Used values are: 0..48. 05972 ; Y = Source position vector index. Used values are: 0..48. 05973 05974 COPYPOSXY LDA XPOSSIGN,Y ; 05975 STA XPOSSIGN,X ; 05976 LDA XPOSHI,Y ; 05977 STA XPOSHI,X ; 05978 LDA YPOSSIGN,Y ; 05979 STA YPOSSIGN,X ; 05980 LDA YPOSHI,Y ; 05981 STA YPOSHI,X ; 05982 LDA XPOSLO,Y ; 05983 STA XPOSLO,X ; 05984 LDA YPOSLO,Y ; 05985 STA YPOSLO,X ; 05986 SKIP111 RTS ; Return 05987 05988 ;******************************************************************************* 05989 ;* * 05990 ;* DOCKING * 05991 ;* * 05992 ;* Handle docking at starbase, launch and return of transfer vessel * 05993 ;* * 05994 ;******************************************************************************* 05995 05996 ; DESCRIPTION 05997 ; 05998 ; Handles docking at a starbase, launching and returning the transfer vessel, 05999 ; and repairing our starship's subsystems. 06000 ; 06001 ; This subroutine changes, if in Front view, the PLAYER-PLAYFIELD priority such 06002 ; that PLAYERs like the starbase appear behind the cross hairs, which are part 06003 ; of the PLAYFIELD. 06004 ; 06005 ; BUG (at $ACEE): The starbase also appears behind the stars, which are also 06006 ; part of the PLAYFIELD - a rarely noticed glitch. In Aft view, the arrangement 06007 ; is reversed: PLAYERs are arranged in front of the PLAYFIELD. Then the starbase 06008 ; (and the transfer vessel) appear in front of the cross hairs! Suggested fix: 06009 ; None, technically not possible. 06010 ; 06011 ; The starbase is tracked and the PLAYER0..2 shape types are set to STARBASE 06012 ; RIGHT, STARBASE LEFT, and STARBASE CENTER, respectively, combining them into a 06013 ; 3-part starbase shape. 06014 ; 06015 ; If this sector is still marked as a starbase sector but no more so on the 06016 ; Galactic Chart (if in the meantime either Zylon units have surrounded this 06017 ; sector and destroyed the starbase or you have destroyed the starbase with a 06018 ; photon torpedo) then the noise sound pattern SHIELD EXPLOSION is played in 06019 ; subroutine NOISE ($AEA8) and code execution returns. 06020 ; 06021 ; Otherwise a minimum distance to the starbase of +32 (+$0020) is enforced 06022 ; and the conditions for a successful docking are checked: 06023 ; 06024 ; DOCKING CONDITIONS 06025 ; 06026 ; A docking is successful if all of the following conditions are met: 06027 ; 06028 ; (1) The PLAYER2 (STARBASE CENTER) column number is in 120..135. 06029 ; 06030 ; BUG (at $AD39): At first glance, the PLAYER column interval of 120..135 06031 ; corresponds to an almost symmetric interval of -8..+7 PM pixels relative 06032 ; to the horizontal center of the PLAYFIELD, at PLAYER column number 128 06033 ; (48 PM pixels offset to left PLAYFIELD border + 80 PM pixels to the 06034 ; PLAYFIELD center). This is correct only if the PLAYER column number were 06035 ; to designate the horizontal center of the PLAYER. However it designates 06036 ; its left edge! Thus the used pixel column number range 120..135 creates 06037 ; an asymmetric horizontal docking position: A docking is successful if the 06038 ; horizontal position of the starbase shape's center is roughly -5..+10 PM 06039 ; pixels relative to the horizontal center of the PLAYFIELD. Suggested fix: 06040 ; Replace SBC #120 with SBC #117. This leads to an interval of -8..+7 06041 ; pixels relative to the horizontal center of the PLAYFIELD and better 06042 ; symmetry in the horizontal docking position. 06043 ; 06044 ; (2) The PLAYER2 (STARBASE CENTER) row number is in 104..119. 06045 ; 06046 ; BUG (at $AD43): The PLAYER row interval of 104..119 corresponds to an 06047 ; asymmetric interval of -20..-5 PM pixels relative to the vertical center 06048 ; of the PLAYFIELD, at pixel row number 80 or PLAYER row number 124. It 06049 ; lets you dock at a starbase that "sits" on top of the horizontal cross 06050 ; hairs but not at one that "hangs" from them. Suggested fix: Replace SBC 06051 ; #104 with SBC #108. This leads to an interval of -8..+7 pixels relative 06052 ; to the vertical center of the PLAYFIELD (assuming a PLAYER2 shape of 16 06053 ; pixel height, which is typical during docking) and better symmetry in the 06054 ; vertical docking position. 06055 ; 06056 ; (3) The starbase is in correct distance in front of our starship: The 06057 ; starbase's z-coordinate must be < +512 (+$02**) . 06058 ; 06059 ; (4) Our starship is horizontally level with the starbase: The starbase's 06060 ; y-coordinate must be < +256 (+$01**) . 06061 ; 06062 ; (5) Our starship is at a complete halt. 06063 ; 06064 ; DOCKING SUCCESSFUL 06065 ; 06066 ; If the conditions for a successful docking are met, the subsequent docking and 06067 ; transfer operation can be divided in the following states, starting with state 06068 ; NOT DOCKED: 06069 ; 06070 ; (1) NOT DOCKED 06071 ; 06072 ; The docking state is set to ORBIT ESTABLISHED and the title line is 06073 ; updated with "ORBIT ESTABLISHED". 06074 ; 06075 ; (2) ORBIT ESTABLISHED 06076 ; 06077 ; After waiting until the title line "ORBIT ESTABLISHED" has disappeared, 06078 ; the transfer vessel is initialized and launched: The PLAYER4 shape type 06079 ; is set to TRANSFER VESSEL. Its position vector is set to a position above 06080 ; and in front of our starship, but behind the starbase: 06081 ; 06082 ; x-coordinate := +0..+255 (+$00**) 06083 ; y-coordinate := +256..+511 (+$01**) 06084 ; z-coordinate := +4096..+4351 (+$10**) 06085 ; 06086 ; Its velocity vector is set to 06087 ; 06088 ; x-velocity := +1 06089 ; y-velocity := -1 06090 ; z-velocity := -7 06091 ; 06092 ; This will move the transfer vessel from behind the starbase into a 06093 ; direction toward and a little to the lower right of our starship. The 06094 ; lifetime of the transfer vessel (and its return journey) is set to 129 06095 ; game loop iterations. Finally, the docking state is set to RETURN 06096 ; TRANSFER VESSEL. 06097 ; 06098 ; (3) RETURN TRANSFER VESSEL 06099 ; 06100 ; After checking if the transfer vessel has passed behind our starship, the 06101 ; beeper sound pattern ACKNOWLEDGE is played in subroutine BEEP ($B3A6), 06102 ; the title line is updated with "TRANSFER COMPLETE", our starship's 06103 ; subsystems are repaired, and our starship's ENERGY readout is restored to 06104 ; 9999 energy units. by inverting the z-velocity the velocity vector of the 06105 ; transfer vessel is changed to 06106 ; 06107 ; x-velocity := +1 06108 ; y-velocity := -1 06109 ; z-velocity := +7 06110 ; 06111 ; thus launching the transfer vessel on its return journey to the starbase. 06112 ; The docking state is set to TRANSFER COMPLETE. Finally, the screen is 06113 ; updated in subroutine UPDSCREEN ($B07B). 06114 ; 06115 ; (4) TRANSFER COMPLETE 06116 ; 06117 ; This docking state marks the end of a successful docking and transfer 06118 ; operation. 06119 ; 06120 ; DOCKING ABORTED 06121 ; 06122 ; If the docking conditions above are not met and the docking state is already 06123 ; ORBIT ESTABLISHED or RETURN TRANSFER VESSEL then the message "DOCKING ABORTED" 06124 ; is displayed and the docking state is set to NOT DOCKED. 06125 06126 DOCKING LDA ISSTARBASESECT ; Return if not in starbase sector 06127 BEQ SKIP111 ; 06128 06129 LDA SHIPVIEW ; Skip if not in Front view 06130 BNE SKIP112 ; 06131 LDA #$14 ; GTIA: enable PLAYER4, prio: PFs > PLs > BGR (!) 06132 STA PRIOR ; (Cross hairs appear behind PLAYERs) 06133 06134 SKIP112 LDA #2 ; Track starbase (PLAYER2) 06135 STA TRACKDIGIT ; 06136 06137 ;** Initialize starbase shape ************************************************** 06138 LDA #SHAP.STARBASEC ; PLAYER2 is STARBASE CENTER (shape type 3) 06139 STA PL2SHAPTYPE ; 06140 LDA #SHAP.STARBASEL ; PLAYER1 is STARBASE LEFT (shape type 2) 06141 STA PL1SHAPTYPE ; 06142 LDA #SHAP.STARBASER ; PLAYER0 is STARBASE RIGHT (shape type 4) 06143 STA PL0SHAPTYPE ; 06144 06145 LDA #255 ; Prep starbase lifetime := 255 game loops (infinite) 06146 06147 LDX CURRSECTOR ; Skip if starbase in current sector 06148 LDY GCMEMMAP,X ; 06149 BMI SKIP113 ; 06150 06151 LDA #0 ; Prep starbase lifetime := 0 game loops (fast death) 06152 06153 SKIP113 STA PL0LIFE ; PLAYER0 lifetime := either 0 or 255 game loops 06154 STA PL1LIFE ; PLAYER1 lifetime := either 0 or 255 game loops 06155 STA PL2LIFE ; PLAYER2 lifetime := either 0 or 255 game loops 06156 STA ISSTARBASESECT ; Store starbase-in-sector flag 06157 BMI SKIP114 ; Skip if starbase in current sector 06158 06159 LDY #2 ; Init explosion at PLAYER2 (STARBASE CENTER) 06160 JSR INITEXPL ; 06161 06162 LDX #$0A ; Play noise sound pattern SHIELD EXPLOSION and return 06163 JMP NOISE ; 06164 06165 ;*** Keep minimum distance to starbase ***************************************** 06166 SKIP114 LDA PL2ZPOSHI ; Skip if starbase z-coordinate > +255 (+$00**) 06167 BNE SKIP115 ; 06168 06169 LDA PL2ZPOSLO ; Approach starbase not closer than +32 (+$0020) 06170 CMP #32 ; 06171 BCS SKIP115 ; 06172 INC PL2ZPOSLO ; ...else push starbase back 06173 06174 ;*** Check if in docking range ************************************************* 06175 SKIP115 LDA PL2COLUMN ; Abort docking if PLAYER column number of... 06176 SEC ; ...PLAYER2 (STARBASE CENTER) not in 120..135. 06177 SBC #120 ; (!) 06178 CMP #16 ; 06179 BCS SKIP116 ; 06180 06181 LDA PL2ROWNEW ; Abort docking if PLAYER row number of... 06182 SEC ; ...PLAYER2 (STARBASE CENTER) not in 104..119. 06183 SBC #104 ; (!) 06184 CMP #16 ; 06185 BCS SKIP116 ; 06186 06187 LDA PL2ZPOSHI ; Abort docking if... 06188 CMP #2 ; ... z-coordinate of starbase >= +512 (+$02**) 06189 BCS SKIP116 ; 06190 06191 LDA PL2ZPOSSIGN ; Abort docking... 06192 AND PL2YPOSSIGN ; ...if starbase not in front and upper screen half 06193 EOR #$01 ; 06194 ORA VELOCITYLO ; ...if our starship's velocity not zero 06195 ORA PL2YPOSHI ; ...if starbase not roughly vertically centered 06196 ORA NEWVELOCITY ; ...if our starship's new velocity not zero 06197 BEQ SKIP119 ; Else skip and handle docking 06198 06199 ;*** Docking aborted *********************************************************** 06200 SKIP116 LDA DOCKSTATE ; Skip if DOCKSTATE is NOT DOCKED, TRANSFER COMPLETE 06201 CMP #2 ; 06202 BCC SKIP117 ; 06203 06204 LDY #$1F ; Set title phrase "DOCKING ABORTED" 06205 JSR SETTITLE ; 06206 06207 SKIP117 LDA #0 ; DOCKSTATE := NOT DOCKED 06208 STA DOCKSTATE ; 06209 SKIP118 RTS ; Return 06210 06211 ;*** Docking successful, check docking state *********************************** 06212 SKIP119 BIT DOCKSTATE ; Check DOCKSTATE 06213 BVS SKIP120 ; If DOCKSTATE = ORBIT ESTABLISHED hide title line 06214 BMI SKIP122 ; If DOCKSTATE = RETURN TRANSFER VESSEL return it 06215 LDA DOCKSTATE ; 06216 BNE SKIP118 ; Return if DOCKSTATE not NOT DOCKED 06217 DEC DOCKSTATE ; DOCKSTATE := ORBIT ESTABLISHED 06218 06219 LDY #$1C ; Set title phrase "ORBIT ESTABLISHED" and return 06220 JMP SETTITLE ; 06221 06222 ;*** Orbit established ********************************************************* 06223 SKIP120 LDX #0 ; Enqueue new, empty title phrase 06224 STX NEWTITLEPHR ; 06225 06226 LDY TITLEPHR ; Return if "ORBIT ESTABLISHED" still displayed 06227 BNE SKIP118 ; 06228 06229 ;*** Launch transfer vessel **************************************************** 06230 LDA #SHAP.TRANSVSSL ; PLAYER4 is TRANSFER VESSEL (shape 5) 06231 STA PL4SHAPTYPE ; 06232 06233 LDA #1 ; Place transfer vessel behind starbase: 06234 STA PL4ZPOSSIGN ; x-coordinate := +0..+255 (+$00**) 06235 STA PL4XPOSSIGN ; y-coordinate := +256..+511 (+$01**) 06236 STA PL4YPOSSIGN ; z-coordinate := +4096..+4351 (+$10**) 06237 STA PL4YPOSHI ; 06238 STA PL4XVEL ; Move transfer vessel toward our starship: 06239 LDA #$10 ; x-velocity := +1 06240 STA PL4ZPOSHI ; y-velocity := -1 06241 LDA #$00 ; z-velocity := -7 06242 STA PL4XPOSHI ; 06243 LDA #NEG!7 ; 06244 STA PL4ZVEL ; 06245 LDA #NEG!1 ; DOCKSTATE := RETURN TRANSFER VESSEL 06246 STA DOCKSTATE ; 06247 STA PL4YVEL ; 06248 STA PL4LIFE ; Transfer vessel lifetime := 129 game loops 06249 SKIP121 RTS ; Return 06250 06251 ;*** Return transfer vessel **************************************************** 06252 SKIP122 LDA PL4ZPOSSIGN ; Return if transfer vessel in front of our starship 06253 BNE SKIP121 ; 06254 06255 LDX #$0C ; Play beeper sound pattern ACKNOWLEGDE 06256 JSR BEEP ; 06257 06258 LDY #$21 ; Set title phrase "TRANSFER COMPLETE" 06259 JSR SETTITLE ; 06260 06261 LDX #5 ; Repair all 6 subsystems 06262 LOOP041 LDA PANELTXTTAB+73,X ; 06263 STA GCSTATPHO,X ; 06264 DEX ; 06265 BPL LOOP041 ; 06266 06267 LDA #CCS.COL2!CCS.9 ; Set starship's ENERGY readout to "9999" in COLOR2 06268 LDX #3 ; 06269 LOOP042 STA ENERGYD1,X ; 06270 DEX ; 06271 BPL LOOP042 ; 06272 06273 LDA #7 ; Move transfer vessel back toward starbase: 06274 STA PL4ZVEL ; x-velocity := -1 06275 LDA #NEG!1 ; y-velocity := +1 06276 STA PL4XVEL ; z-velocity := +7 06277 LDA #1 ; 06278 STA PL4YVEL ; 06279 06280 STA DOCKSTATE ; DOCKSTATE := TRANSFER COMPLETE 06281 JMP UPDSCREEN ; Update screen and return 06282 06283 ;******************************************************************************* 06284 ;* * 06285 ;* MODDLST * 06286 ;* * 06287 ;* Modify Display List * 06288 ;* * 06289 ;******************************************************************************* 06290 06291 ; DESCRIPTION 06292 ; 06293 ; Modifies the Display List to show and hide title, headers, and the Control 06294 ; Panel Display. 06295 ; 06296 ; INPUT 06297 ; 06298 ; A = Number of bytes to copy into the Display List 06299 ; X = Offset into Display List DSPLST ($0280) 06300 ; Y = Offset into Display List fragment table DLSTFRAG ($BA62). If Y = $80 06301 ; then no bytes are copied but the specified locations of the Display List 06302 ; are overwritten with Display List instruction $0D (one row of 06303 ; GRAPHICS7). 06304 ; 06305 ; Used values are: 06306 ; 06307 ; A X Y 06308 ; $08 $5F $00 -> Show Control Panel Display (bottom text window) 06309 ; $08 $5F $80 -> Hide Control Panel Display (bottom text window) 06310 ; $07 $0F $23 -> Show title line 06311 ; $07 $0F $80 -> Hide title line 06312 ; $08 $02 $1B -> Show Display List header line of Front view 06313 ; $08 $02 $13 -> Show Display List header line of Aft view 06314 ; $08 $02 $0B -> Show Display List header line of Long-Range Scan view 06315 ; $08 $02 $08 -> Show Display List header line of Galactic Chart view 06316 06317 L.NUMBYTES = $6A ; Number of bytes to copy 06318 06319 MODDLST SEI ; Disable IRQ 06320 STA L.NUMBYTES ; Save number of bytes to copy 06321 06322 LOOP043 LDA VCOUNT ; Wait for ANTIC line counter >= 124 (PLAYFIELD... 06323 CMP #124 ; ...bottom) before changing the Display List 06324 BCC LOOP043 ; 06325 06326 LOOP044 LDA DLSTFRAG,Y ; Load byte from Display List fragment table 06327 INY ; 06328 BPL SKIP123 ; Skip if fragment table index < $80 06329 LDA #$0D ; Prep Display List instruction $0D (GRAPHICS7) 06330 SKIP123 STA DSPLST,X ; Store byte in Display List 06331 INX ; 06332 DEC L.NUMBYTES ; 06333 BNE LOOP044 ; Copy next byte 06334 06335 CLI ; Enable IRQ 06336 RTS ; Return 06337 06338 ;******************************************************************************* 06339 ;* * 06340 ;* CLRPLAYFIELD * 06341 ;* * 06342 ;* Clear PLAYFIELD memory * 06343 ;* * 06344 ;******************************************************************************* 06345 06346 ; DESCRIPTION 06347 ; 06348 ; Clears PLAYFIELD memory from $1000 to $1FFF. 06349 ; 06350 ; This subroutine sets the start address of the memory to be cleared then code 06351 ; execution continues into subroutine CLRMEM ($AE0F) where the memory is 06352 ; actually cleared. 06353 06354 CLRPLAYFIELD LDA #$10 06355 06356 ;******************************************************************************* 06357 ;* * 06358 ;* CLRMEM * 06359 ;* * 06360 ;* Clear memory * 06361 ;* * 06362 ;******************************************************************************* 06363 06364 ; DESCRIPTION 06365 ; 06366 ; Clears memory from a given start address to memory address $1FFF. This 06367 ; subroutine is called in the following situations: 06368 ; 06369 ; (1) In routine INITCOLD ($A14A) at the beginning of the program to initialize 06370 ; the program's variables 06371 ; 06372 ; (2) In subroutine CLRPLAYFIELD ($AE0D) to clear PLAYFIELD memory. 06373 ; 06374 ; As a side effect this subroutine also clears the saved number of space objects 06375 ; and the lock-on flag. 06376 ; 06377 ; INPUT 06378 ; 06379 ; A = Start address (high byte) of memory to be cleared. Used values are: 06380 ; $02 -> Clear memory $0200..$1FFF during program initialization 06381 ; $10 -> Clear PLAYFIELD memory $1000..$1FFF 06382 06383 CLRMEM STA MEMPTR+1 ; Store start address (high byte) to be cleared 06384 LDA #0 ; Store start address (low byte) to be cleared 06385 TAY ; 06386 STA MEMPTR ; 06387 06388 STA ISINLOCKON ; Clear lock-on flag 06389 STA OLDMAXSPCOBJIND ; Clear saved number of space objects 06390 06391 LOOP045 STA (MEMPTR),Y ; Clear memory location 06392 INY ; 06393 BNE LOOP045 ; 06394 06395 INC MEMPTR+1 ; Next page (= 256-byte block) 06396 LDY MEMPTR+1 ; 06397 CPY #$20 ; 06398 TAY ; 06399 BCC LOOP045 ; Loop until memory address $2000 reached 06400 RTS ; Return 06401 06402 ;******************************************************************************* 06403 ;* * 06404 ;* TRIGGER * 06405 ;* * 06406 ;* Handle joystick trigger * 06407 ;* * 06408 ;******************************************************************************* 06409 06410 ; DESCRIPTION 06411 ; 06412 ; This subroutine handles the joystick trigger and launches one of our 06413 ; starship's photon torpedo. If a target is in full lock-on then a second photon 06414 ; torpedo is prepared for automatic launch in the next game loop iteration. 06415 ; 06416 ; DETAILS 06417 ; 06418 ; If the trigger is pressed then reset the idle counter and, if not in 06419 ; hyperwarp, launch a photon torpedo with the following steps: 06420 ; 06421 ; (1) If the trigger was pressed in this game loop iteration, a photon torpedo 06422 ; will be launched if a previously launched photon torpedo is already under 06423 ; way for at least 255 - 232 = 23 game loop iterations. This avoids firing 06424 ; photon torpedoes too rapidly. 06425 ; 06426 ; (2) Start tracking a space object. If it is in full lock-on, set up the 06427 ; lock-on timer, activate photon torpedo tracking, and tweak the last saved 06428 ; trigger state such that our other photon torpedo (if available) is 06429 ; launched automatically in the next game loop iteration. 06430 ; 06431 ; (3) If the Photon Torpedoes are destroyed, do nothing. 06432 ; 06433 ; (4) If the Photon Torpedoes are damaged, launch a photon torpedo from the 06434 ; same barrel than the previous one. 06435 ; 06436 ; (5) If the Photon Torpedoes are not damaged, launch a photon torpedo from the 06437 ; other barrel. 06438 ; 06439 ; (6) Set the lifetime of our starship's photon torpedo to infinite, set the 06440 ; PLAYER shape to PHOTON TORPEDO. 06441 ; 06442 ; (7) Initialize the position vector of our starship's photon torpedo to: 06443 ; 06444 ; x-coordinate := +256 (+$0100) (Right barrel) 06445 ; -256 (-$FF00) (Left barrel) 06446 ; y-coordinate := -256 (-$FF00) 06447 ; z-coordinate := +1 (+$0001) 06448 ; 06449 ; (8) Initialize the velocity vector of our starship's photon torpedo to: 06450 ; 06451 ; x-velocity := +0 06452 ; y-velocity := +0 06453 ; z-velocity := +102 (All views but Aft view) 06454 ; -102 (Aft view) 06455 ; 06456 ; (9) Subtract 10 energy units for launching our starship's photon torpedo. 06457 ; 06458 ; (10) Play the noise sound pattern PHOTON TORPEDO LAUNCHED by continuing code 06459 ; execution into subroutine NOISE ($AEA8). 06460 06461 TRIGGER LDA OLDTRIG0 ; Prep last trigger state 06462 06463 LDY TRIG0 ; Copy current trigger state 06464 STY OLDTRIG0 ; 06465 BNE SKIP124 ; Return if trigger currently not pressed 06466 06467 STY IDLECNTHI ; Reset idle counter 06468 06469 LDX WARPSTATE ; Return if hyperwarp engaged 06470 BNE SKIP124 ; 06471 06472 LDX BARRELNR ; Prep barrel number (0 -> left, 1 -> right) 06473 06474 CMP #1 ; If trigger is newly pressed -> handle tracking... 06475 BEQ SKIP125 ; ...and launch our starship's photon torpedo... 06476 BCS SKIP127 ; ...else launch our starship's photon torpedo only 06477 SKIP124 RTS ; Return 06478 06479 ;*** Set up our starship's photon torpedo tracking ***************************** 06480 SKIP125 LDA PL3LIFE,X ; Return if torpedo's lifetime >= 232 game loops 06481 CMP #232 ; 06482 BCS SKIP124 ; 06483 06484 LDY TRACKDIGIT ; Store index of tracked space object 06485 STY PLTRACKED ; 06486 06487 LDA #12 ; Prep lock-on lifetime := 12 game loops 06488 LDY ISINLOCKON ; If target is in full lock-on... 06489 STY ISTRACKING ; ...activate photon torpedo tracking 06490 06491 BEQ SKIP126 ; Skip if target not in full lock-on 06492 LDA #0 ; Prep lock-on lifetime := 0 game loops 06493 SKIP126 STA LOCKONLIFE ; Store lock-on lifetime (either 0 or 12 game loops) 06494 06495 ;*** Launch our starship's photon torpedo ************************************** 06496 SKIP127 STY OLDTRIG0 ; Update last trigger state 06497 BIT GCSTATPHO ; Return if Photon Torpedoes are destroyed 06498 BVS SKIP124 ; 06499 06500 BMI SKIP128 ; If Photon Torpedoes damaged launch from same barrel 06501 TXA ; ...else switch barrel from which to launch torpedo 06502 EOR #$01 ; 06503 STA BARRELNR ; 06504 06505 SKIP128 TXA ; SUMMARY: Our starship's photon torpedo's... 06506 STA PL3XPOSSIGN,X ; x-coordinate := +256 (+$0100) (right barrel) 06507 LDA BARRELXTAB,X ; x-coordinate := -256 (-$FF00) (left barrel) 06508 STA PL3XPOSHI,X ; y-coordinate := -256 (-$FF00) 06509 LDA #255 ; z-coordinate := +1 (+$0001) 06510 STA PL3LIFE,X ; ...lifetime := 255 game loops 06511 STA PL3YPOSHI,X ; 06512 LDA #0 ; 06513 STA PL3SHAPTYPE,X ; PLAYER3 or PLAYER4 is PHOTON TORPEDO (shape type 0) 06514 STA PL3ZPOSHI,X ; 06515 STA PL3XPOSLO,X ; 06516 STA PL3YPOSSIGN,X ; 06517 STA PL3YPOSLO,X ; 06518 LDA #1 ; 06519 STA PL3ZPOSSIGN,X ; 06520 STA PL3ZPOSLO,X ; 06521 06522 LDA SHIPVIEW ; SUMMARY: Our starship's photon torpedo's... 06523 LSR A ; x-velocity := +0 06524 ROR A ; y-velocity := +0 06525 ORA #102 ; z-velocity := +102 (Other views) 06526 STA PL3ZVEL,X ; z-velocity := -102 (Aft view) 06527 LDA #0 ; 06528 STA PL3XVEL,X ; 06529 STA PL3YVEL,X ; 06530 06531 LDX #2 ; ENERGY := ENERGY - 10 for launching photon torpedo 06532 JSR DECENERGY ; 06533 06534 LDX #$00 ; Play noise sound pattern PHOTON TORPEDO LAUNCHED 06535 06536 ;******************************************************************************* 06537 ;* * 06538 ;* NOISE * 06539 ;* * 06540 ;* Copy noise sound pattern * 06541 ;* * 06542 ;******************************************************************************* 06543 06544 ; DESCRIPTION 06545 ; 06546 ; Copies a 10-byte noise sound pattern from table NOISEPATTAB ($BF20). The first 06547 ; 8 bytes are copied to the noise sound pattern area NOISETORPTIM 06548 ; ($DA)..NOISELIFE ($E1), the remaining 2 bytes are copied to audio registers 06549 ; AUDCTL ($D208) and AUDF3 ($D204). The noise sound pattern is automatically 06550 ; played in subroutine SOUND ($B2AB). 06551 ; 06552 ; NOTE: the first 8 bytes of each pattern in table NOISEPATTAB ($BF20) are 06553 ; copied in reverse order from memory. See subroutine SOUND ($B2AB) for details 06554 ; on the noise sound patterns stored in NOISEPATTAB ($BF20). 06555 ; 06556 ; Playing a SHIELD EXPLOSION or ZYLON EXPLOSION noise sound pattern overrides a 06557 ; currently playing PHOTON TORPEDO LAUNCHED noise sound pattern. 06558 ; 06559 ; Playing a PHOTON TORPEDO LAUNCHED noise sound pattern overrides a currently 06560 ; playing PHOTON TORPEDO LAUNCHED noise sound pattern if the latter has < 24 06561 ; TICKs to play. 06562 ; 06563 ; INPUT 06564 ; 06565 ; X = Offset into table NOISEPATTAB ($BF20) to index noise sound patterns. 06566 ; Used values are: 06567 ; $00 -> PHOTON TORPEDO LAUNCHED 06568 ; $0A -> SHIELD EXPLOSION (either our starship or a starbase explodes) 06569 ; $14 -> ZYLON EXPLOSION 06570 06571 NOISE TXA ; Skip if SHIELD EXPLOSION or ZYLON EXPLOSION playing 06572 BNE SKIP129 ; 06573 06574 LDA NOISELIFE ; Return if PHOTON TORPEDO LAUNCHED noise sound pat. 06575 CMP #24 ; ...playing for yet more than 24 TICKs 06576 BCS SKIP130 ; 06577 06578 SKIP129 LDY #7 ; Copy noise sound pattern (in reverse order) 06579 LOOP046 LDA NOISEPATTAB,X ; 06580 STA NOISETORPTIM,Y ; 06581 INX ; 06582 DEY ; 06583 BPL LOOP046 ; 06584 06585 LDA NOISEPATTAB,X ; Copy AUDCTL from noise sound pattern table 06586 STA AUDCTL ; 06587 LDA NOISEPATTAB+1,X ; Copy AUDF3 from noise sound pattern table 06588 STA AUDF3 ; 06589 06590 SKIP130 RTS ; Return 06591 06592 ;******************************************************************************* 06593 ;* * 06594 ;* HOMINGVEL * 06595 ;* * 06596 ;* Calculate homing velocity of our starship's photon torpedo 0 or 1 * 06597 ;* * 06598 ;******************************************************************************* 06599 06600 ; DESCRIPTION 06601 ; 06602 ; Calculates the x (or y) velocity vector component of our starship's photon 06603 ; torpedo 0 or 1 when it is tracking (homing in on) a target space object. 06604 ; 06605 ; Our starship's photon torpedo's x (or y) velocity vector component depends on 06606 ; the PLAYER column (or row) number difference between the target PLAYER and our 06607 ; starship's photon torpedo PLAYER in Player/Missile (PM) pixels. This 06608 ; difference is used as an index to pick the new x (or y) velocity vector 06609 ; component of out starship's photon torpedo from table HOMVELTAB ($BFC9): 06610 ; 06611 ; +---------------+--------------+ 06612 ; | Difference in | New Velocity | 06613 ; | PM Pixels | Component | 06614 ; +---------------+--------------+ 06615 ; | >= +7 | -64 | 06616 ; | +6 | -56 | 06617 ; | +5 | -48 | 06618 ; | +4 | -40 | 06619 ; | +3 | -24 | 06620 ; | +2 | -16 | 06621 ; | +1 | -8 | 06622 ; | 0 | 0 | 06623 ; | -1 | +8 | 06624 ; | -2 | +16 | 06625 ; | -3 | +24 | 06626 ; | -4 | +40 | 06627 ; | -5 | +48 | 06628 ; | -6 | +56 | 06629 ; | <= -7 | +64 | 06630 ; +---------------+--------------+ 06631 ; 06632 ; INPUT 06633 ; 06634 ; A = PLAYER column (or row) number difference between the target PLAYER 06635 ; and our starship's photon torpedo PLAYER in Player/Missile pixels 06636 ; 06637 ; CARRY = Sign of the PLAYER column (or row) number difference. Used values 06638 ; are: 06639 ; 0 -> Negative difference (target PLAYER column (or row) number < our 06640 ; starship's photon torpedo PLAYER column (or row) number 06641 ; 1 -> Positive difference (target PLAYER column (or row) number >= our 06642 ; starship's photon torpedo PLAYER column (or row) number 06643 ; 06644 ; OUTPUT 06645 ; 06646 ; A = New velocity vector component of our starship's photon torpedo in 06647 06648 L.VELSIGN = $6A ; Saves velocity sign 06649 06650 HOMINGVEL LDY #NEG ; Preload negative velocity sign 06651 BCS SKIP131 ; Skip if difference is positive 06652 06653 EOR #$FF ; Invert to get absolute value of difference 06654 LDY #0 ; Preload positive velocity sign 06655 06656 SKIP131 STY L.VELSIGN ; Save velocity sign 06657 CMP #8 ; 06658 BCC SKIP132 ; 06659 LDA #7 ; Limit difference to 0..7 06660 SKIP132 TAY ; 06661 LDA L.VELSIGN ; Reload velocity sign 06662 ORA HOMVELTAB,Y ; Combine with homing velocity from table 06663 RTS ; Return 06664 06665 ;******************************************************************************* 06666 ;* * 06667 ;* DAMAGE * 06668 ;* * 06669 ;* Damage or destroy one of our starship's subsystems * 06670 ;* * 06671 ;******************************************************************************* 06672 06673 ; DESCRIPTION 06674 ; 06675 ; Damages or destroys one of our starship's subsystems. There are 6 subsystems: 06676 ; 06677 ; (1) Photon Torpedoes 06678 ; (2) Engines 06679 ; (3) Shields 06680 ; (4) Attack Computer 06681 ; (5) Long-Range Scan 06682 ; (6) Subspace Radio 06683 ; 06684 ; Their status is stored and displayed in the Galactic Chart Panel Display by 06685 ; the colored letters PESCLR. The color of each letter represents the 06686 ; subsystem's status: 06687 ; 06688 ; +---------------+------------------+ 06689 ; | Letter Color | Subsystem Status | 06690 ; +---------------+------------------+ 06691 ; | {LIGHT GREEN} | OK | 06692 ; | {CORN YELLOW} | Damaged | 06693 ; | {PINK} | Destroyed | 06694 ; +---------------+------------------+ 06695 ; 06696 ; This subroutine first makes sure that we are not in demo mode. Then it picks a 06697 ; random value in 0..255 and the damage probability value. The latter value 06698 ; depends on the mission level and is picked from table DAMAGEPROBTAB ($BF10): 06699 ; 06700 ; +-----------+-------------------+---------------+ 06701 ; | Mission | Damage | Damage | 06702 ; | Level | Probability Value | Probability | 06703 ; +-----------+-------------------+---------------+ 06704 ; | NOVICE | 0 | 0% ( 0:256) | 06705 ; | PILOT | 80 | 31% ( 80:256) | 06706 ; | WARRIOR | 180 | 70% (180:256) | 06707 ; | COMMANDER | 254 | 99% (254:256) | 06708 ; +-----------+-------------------+---------------+ 06709 ; 06710 ; If the random number is lower than the damage probability value, a randomly 06711 ; picked subsystem is about to get damaged (or destroyed). There is a built-in 06712 ; upfront probability of 25% (2:8) that no subsystem gets harmed. 06713 ; 06714 ; If the picked subsystem is already destroyed then another subsystem is picked. 06715 ; 06716 ; Then the title phrase offset is picked from table DAMAGEPHRTAB ($BF14) to 06717 ; display the damaged subsystem in the title line. Next, color bits are picked 06718 ; that indicate a damaged system. 06719 ; 06720 ; If the Zylon photon torpedo's lifetime >= 30 game loop iterations the 06721 ; subsystem will not only be damaged but destroyed. 06722 ; 06723 ; NOTE: The Zylon photon torpedo lifetime decreases from 62 to 0 game loop 06724 ; iterations. With a remaining lifetime >= 30 game loop iterations it is 06725 ; considered strong enough to destroy one of our starship's subsystems. There 06726 ; are two exceptions to this rule: If the Attack Computer was picked to be 06727 ; destroyed it will be damaged only - not destroyed - if the Long-Range Scan has 06728 ; been already destroyed, and vice versa. 06729 ; 06730 ; Then the title phrase offset from table DESTROYPHRTAB ($BF1A) is picked to 06731 ; display the destroyed subsystem in the title line. Next, color bits are picked 06732 ; that indicate a destroyed system. 06733 ; 06734 ; The color of the subsystem's status letter is adjusted in the Galactic Chart 06735 ; Panel Display. Next, the title phrase describing the subsystem's status is 06736 ; enqueued for display in the title line. If the Attack Computer has been 06737 ; destroyed it is switched off and the PLAYFIELD is cleared. The title line is 06738 ; updated with the "DAMAGE CONTROL" message. Finally, the beeper sound pattern 06739 ; DAMAGE REPORT is played in subroutine BEEP ($B3A6). 06740 06741 DAMAGE BIT ISDEMOMODE ; Return if in demo mode 06742 BMI SKIP137 ; 06743 06744 ;*** Damage some subsystem ***************************************************** 06745 LDX MISSIONLEVEL ; Prep mission level 06746 LOOP047 LDA RANDOM ; Return if random number >= damage probability 06747 CMP DAMAGEPROBTAB,X ; ...(the latter depends on mission level) 06748 BCS SKIP137 ; 06749 06750 AND #$07 ; Randomly pick 1 of 6 subsystems 06751 CMP #6 ; Return if no subsystem picked 06752 BCS SKIP137 ; 06753 06754 TAX ; 06755 LDA GCSTATPHO,X ; Get picked subsystem status letter 06756 ASL A ; Check bit B6 (= destroyed) of letter code 06757 BMI LOOP047 ; Try again if subsystem already destroyed 06758 06759 LDA PL2LIFE ; Load Zylon photon torpedo lifetime... 06760 CMP #30 ; ...and compare it to 30 game loops 06761 06762 LDA #CCS.COL2 ; Preload COLOR2 text color bits (= damaged status) 06763 LDY DAMAGEPHRTAB,X ; Preload title phrase offset of damaged subsystem 06764 06765 BCC SKIP135 ; Skip if Zylon torpedo lifetime < 30 game loops 06766 06767 CPX #3 ; Skip if selected subsystem not Attack Computer 06768 BNE SKIP133 ; 06769 BIT GCSTATLRS ; Skip if Long-Range Scan already destroyed 06770 BVS SKIP135 ; 06771 SKIP133 CPX #4 ; Skip if selected subsystem is not Long-Range Scan 06772 BNE SKIP134 ; 06773 BIT GCSTATCOM ; Skip if Attack Computer already destroyed 06774 BVS SKIP135 ; 06775 06776 SKIP134 LDA #CCS.COL3 ; Preload COLOR3 text color bits (= destroyed status) 06777 LDY DESTROYPHRTAB,X ; Preload title phrase offset of destroyed subsystem 06778 06779 SKIP135 ORA GCSTATPHO,X ; Combine status letter with new color 06780 STA GCSTATPHO,X ; 06781 STY NEWTITLEPHR ; Enqueue damage status title phrase 06782 BIT GCSTATCOM ; Skip if Attack Computer OK or damaged 06783 BVC SKIP136 ; 06784 06785 LDA #0 ; Switch Attack Computer off 06786 STA DRAINATTCOMP ; 06787 JSR CLRPLAYFIELD ; Clear PLAYFIELD 06788 06789 SKIP136 LDY #$52 ; Set title phrase "DAMAGE CONTROL..." 06790 JSR SETTITLE ; 06791 06792 LDX #$12 ; Play beeper sound pattern DAMAGE REPORT 06793 JSR BEEP ; 06794 06795 SKIP137 RTS ; Return 06796 06797 ;******************************************************************************* 06798 ;* * 06799 ;* COLLISION * 06800 ;* * 06801 ;* Detect a collision of our starship's photon torpedoes * 06802 ;* * 06803 ;******************************************************************************* 06804 06805 ; DESCRIPTION 06806 ; 06807 ; Both of our starship's photon torpedoes are checked if they have collided with 06808 ; a space object represented by PLAYER0..2, such as a Zylon ship, a Zylon photon 06809 ; torpedo, a starbase, or a meteor. 06810 ; 06811 ; For quick lookup, the following table lists the PLAYERs and what space objects 06812 ; they represent: 06813 ; 06814 ; +--------+--------------------------------------------------+ 06815 ; | PLAYER | Represents | 06816 ; +--------+--------------------------------------------------+ 06817 ; | 0 | Zylon ship 0, Starbase Left | 06818 ; | 1 | Zylon ship 1, Starbase Right | 06819 ; | 2 | Zylon photon torpedo, Starbase Center, Meteor | 06820 ; | 3 | Our starship's photon torpedo 0 | 06821 ; | 4 | Our starship's photon torpedo 1, Transfer Vessel | 06822 ; +--------+--------------------------------------------------+ 06823 ; 06824 ; NOTE: Only space objects represented by PLAYER0..2 are checked for collisions. 06825 ; The transfer vessel of the starbase, represented by PLAYER4, is not checked 06826 ; and therefore cannot be destroyed by one of our starship's photon torpedoes. 06827 ; 06828 ; This subroutine first checks if our starship's photon torpedoes are 06829 ; represented by alive PLAYERs with PHOTON TORPEDO shape. 06830 ; 06831 ; In order to detect a collision with a space object, our starship's photon 06832 ; torpedo must compare its x, y, and z coordinates with the ones of the space 06833 ; object. 06834 ; 06835 ; Instead of comparing the x and y coordinates, however, this subroutines uses a 06836 ; much more efficient method by inspecting the Player/Missile collision 06837 ; registers, as the x and y axis of the 3D coordinate system establish the plane 06838 ; in which the TV screen lies. Each of our starship's photon torpedoes has its 06839 ; own Player/Missile collision register: PL3HIT ($82) for our starship's photon 06840 ; torpedo 0 and PL4HIT ($83) for our starship's photon torpedo 1. By inspecting 06841 ; these registers the hit space object is determined: 06842 ; 06843 ; +---------------------------------------------------+-------------------------+ 06844 ; | Bits B2..0 of Collision Register | Hit PLAYER | 06845 ; | (0 -> Not Hit, 1 -> Hit) | | 06846 ; +-----------------+----------------+----------------+ | 06847 ; | PLAYER2 | PLAYER1 | PLAYER0 | | 06848 ; | (Zylon torpedo) | (Zylon ship 1) | (Zylon ship 0) | | 06849 ; +-----------------+----------------+----------------+-------------------------+ 06850 ; | 0 | 0 | 0 | None | 06851 ; | 0 | 0 | 1 | PLAYER0 (Zylon ship 0) | 06852 ; | 0 | 1 | 0 | PLAYER1 (Zylon ship 1) | 06853 ; | 0 | 1 | 1 | PLAYER1 (Zylon ship 1) | 06854 ; | 1 | 0 | 0 | PLAYER2 (Zylon torpedo) | 06855 ; | 1 | 0 | 1 | PLAYER2 (Zylon torpedo) | 06856 ; | 1 | 1 | 0 | PLAYER1 (Zylon ship 1) | 06857 ; | 1 | 1 | 1 | PLAYER1 (Zylon ship 1) | 06858 ; +-----------------+----------------+----------------+-------------------------+ 06859 ; 06860 ; If the lifetime of the hit space object has already expired, then the hit is 06861 ; ignored. 06862 ; 06863 ; A collision along the z-axis happens if the z-coordinate of our starship's 06864 ; photon torpedo is close enough to the z-coordinate of the space object: 06865 ; 06866 ; The absolute value of the z-coordinate of the space object is converted into a 06867 ; range index in 0..7. This index picks a minimum and a maximum z-coordinate 06868 ; from tables HITMINZTAB ($BF7D) and HITMAXZTAB ($BF75). If the absolute value 06869 ; of the z-coordinate of our starship's photon torpedo is inside this interval, 06870 ; then our starship's photon torpedo has hit the space object. The following 06871 ; table lists the relevant values: 06872 ; 06873 ; +-----------------------+-------+--------------------------+--------------------------+ 06874 ; | ABS(z-Coordinate) | Range | Min ABS(z-Coordinate) | Max ABS(z-Coordinate) | 06875 ; | of Space Object | Index | of Photon Torpedo to Hit | of Photon Torpedo to Hit | 06876 ; +-----------------------+-------+--------------------------+--------------------------+ 06877 ; | <= 511 ($01**) | 0 | 0 ($00**) | < 3328 ($0C**) | 06878 ; | <= 1023 ($03**) | 1 | 0 ($00**) | < 3328 ($0C**) | 06879 ; | <= 1535 ($05**) | 2 | 0 ($00**) | < 3328 ($0C**) | 06880 ; | <= 2047 ($07**) | 3 | 512 ($02**) | < 3328 ($0C**) | 06881 ; | <= 2559 ($09**) | 4 | 1024 ($04**) | < 3840 ($0E**) | 06882 ; | <= 3071 ($0B**) | 5 | 1536 ($06**) | < 3840 ($0E**) | 06883 ; | <= 3583 ($0D**) | 6 | 2048 ($08**) | < 3840 ($0E**) | 06884 ; | <= 65535 ($FF**) | 7 | 3072 ($0C**) | < 8448 ($20**) | 06885 ; +-----------------------+-------+--------------------------+--------------------------+ 06886 ; 06887 ; if a collision has been detected, the "age" (= initial lifetime - remaining 06888 ; lifetime) of our starship's photon torpedo is calculated. This age is used to 06889 ; delay playing the ZYLON EXPLOSION noise sound pattern but also to determine 06890 ; the strength of our starship's photon torpedo. Only photon torpedoes of an age 06891 ; < 15 game loop iterations can destroy a Zylon basestar. 06892 ; 06893 ; Some clean-up work is done before the actual explosion: The lock-on timer, our 06894 ; starship's photon torpedo lifetime, and the hit space object's PLAYER lifetime 06895 ; is set to 0. 06896 ; 06897 ; If a meteor or a Zylon photon torpedo have been hit, then the score is not 06898 ; changed, skipping right to the explosion part. Otherwise, our starship's 06899 ; photon torpedo tracking flag is cleared and the Galactic Chart Map is updated. 06900 ; If a starbase was destroyed, then 3 points are added to the score. If a Zylon 06901 ; ship was destroyed, then 6 points are added to the score and the Zylon KILL 06902 ; COUNTER readout of the Control Panel Display is incremented. Next, the 06903 ; explosion is initialized in subroutine INITEXPL ($AC6B). 06904 ; 06905 ; NOTE: This subroutine lacks proper explosion initialization if the starbase 06906 ; was hit. The actual explosion initialization is done in subroutine DOCKING 06907 ; ($ACE6) when the code finds out that the starbase sector is no more marked as 06908 ; such in the Galactic Chart. 06909 ; 06910 ; Finally, the Galactic Chart Map is searched for a remaining Zylon unit. If 06911 ; none is found then the mission is complete and code execution continues into 06912 ; subroutine GAMEOVER2 ($B121), ending the game. 06913 06914 L.PLHIT = $6B ; Saves PLAYER (and space object) index of hit PLAYER 06915 L.VIEWDIR = $6C ; Saves view direction. Used values are: 06916 ; $00 -> Front view 06917 ; $FF -> Aft view 06918 06919 COLLISION LDX #2 ; Loop over our starship's two photon torpedoes 06920 LOOP048 DEX ; 06921 BPL SKIP138 ; Branch into loop body below 06922 RTS ; Return 06923 06924 ;*** Photon torpedo sanity checks ********************************************** 06925 SKIP138 LDA PL3SHAPTYPE,X ; Next photon torpedo if PLAYER not a PHOTON TORPEDO 06926 BNE LOOP048 ; 06927 06928 LDA PL3LIFE,X ; Next photon torpedo if PLAYER not alive 06929 BEQ LOOP048 ; 06930 06931 ;*** Check if our starship's photon torpedo has hit in x-y plane *************** 06932 LDA PL3HIT,X ; Check Player/Missile collision register 06933 AND #$07 ; Next torpedo if no torpedo-to-PLAYER collision 06934 BEQ LOOP048 ; 06935 06936 LSR A ; Find out which of PLAYER0..2 was hit in PLAYFIELD 06937 CMP #3 ; 06938 BNE SKIP139 ; 06939 LSR A ; 06940 SKIP139 TAY ; Save resulting index of hit PLAYER 06941 06942 LDA PL0LIFE,Y ; Next torpedo if PLAYER0..2 (= targets) not alive 06943 BEQ LOOP048 ; 06944 06945 ;*** Has our starship's photon torpedo hit within valid z-coordinate interval? * 06946 LDA SHIPVIEW ; Skip if in Front view 06947 BEQ SKIP140 ; 06948 LDA #$FF ; Calculate range index... 06949 SKIP140 STA L.VIEWDIR ; Saves view direction 06950 EOR ZPOSHI,Y ; Calc ABS(z-coordinate (high byte)) of hit object 06951 CMP #16 ; Limit range index to 0..7 06952 BCC SKIP141 ; 06953 LDA #15 ; 06954 SKIP141 LSR A ; 06955 STY L.PLHIT ; Save index of hit PLAYER 06956 06957 TAY ; 06958 LDA L.VIEWDIR ; Reload view direction 06959 EOR PL3ZPOSHI,X ; Calc ABS(z-coordinate (high byte)) of torpedo 06960 06961 CMP HITMAXZTAB,Y ; Next torpedo if torpedo >= max hit z-coordinate 06962 BCS LOOP048 ; 06963 06964 CMP HITMINZTAB,Y ; Next torpedo if torpedo < min hit z-coordinate 06965 BCC LOOP048 ; 06966 06967 ;*** Our starship's photon torpedo has hit within valid z-coordinate interval! * 06968 LDY L.PLHIT ; Reload index of hit PLAYER 06969 SEC ; Calc "age" of photon torpedo in game loops to... 06970 LDA #255 ; delay playing ZYLON EXPLOSION noise sound pattern 06971 SBC PL3LIFE,X ; 06972 STA NOISEZYLONTIM ; 06973 06974 CMP #15 ; Skip if photon torpedo "age" < 15 06975 BCC SKIP142 ; 06976 LDA PL0SHAPTYPE,Y ; CARRY := PLAYER is ZYLON BASESTAR (shape type 8) 06977 CMP #SHAP.ZBASESTAR ; (and torpedo "age" good to destroy ZYLON BASESTAR) 06978 06979 ;*** Clean up our starship's photon torpedo and hit PLAYER ********************* 06980 SKIP142 LDA #0 ; Lock-on lifetime := 0 game loops 06981 STA LOCKONLIFE ; 06982 STA PL3LIFE,X ; Photon torpedo's lifetime := 0 game loops 06983 BCS SKIP144 ; If CARRY set do not score, just do explosion 06984 06985 STA PL0LIFE,Y ; Hit PLAYER lifetime := 0 game loops 06986 06987 LDA PL0SHAPTYPE,Y ; If hit PLAYER is... 06988 BEQ SKIP144 ; ...a PHOTON TORPEDO (shape type 0)... 06989 CMP #SHAP.METEOR ; ...or a METEOR (shape type 6)... 06990 BEQ SKIP144 ; ...do not score, just do explosion 06991 06992 LDA #0 ; Clear photon torpedo tracking flag 06993 STA ISTRACKING ; 06994 06995 ;*** Zylon ship (or starbase) destroyed! *************************************** 06996 LDX CURRSECTOR ; Decrement Zylon count on Galactic Chart 06997 DEC GCMEMMAP,X ; 06998 BPL SKIP143 ; Skip if destroyed space object was Zylon ship 06999 07000 ;*** Starbase destroyed! ******************************************************* 07001 LDA #0 ; Remove destroyed starbase from Galactic Chart 07002 STA GCMEMMAP,X ; 07003 SEC ; SCORE := SCORE - 3 for destroying starbase 07004 LDA SCORE ; 07005 SBC #3 ; 07006 STA SCORE ; 07007 LDA SCORE+1 ; 07008 SBC #0 ; 07009 STA SCORE+1 ; 07010 RTS ; Return 07011 07012 ;*** Zylon ship destroyed! ***************************************************** 07013 SKIP143 CLC ; SCORE := SCORE + 6 for destroying Zylon ship 07014 LDA SCORE ; 07015 ADC #6 ; 07016 STA SCORE ; 07017 LDA SCORE+1 ; 07018 ADC #0 ; 07019 STA SCORE+1 ; 07020 07021 LDX #1 ; Increment Zylon KILL COUNTER readout... 07022 LOOP049 INC KILLCNTD1,X ; ...of Control Panel Display 07023 LDA KILLCNTD1,X ; 07024 CMP #[CCS.COL1!CCS.9]+1 ; 07025 BCC SKIP144 ; 07026 LDA #[CCS.COL1!CCS.0] ; 07027 STA KILLCNTD1,X ; 07028 DEX ; 07029 BPL LOOP049 ; 07030 07031 SKIP144 JSR INITEXPL ; Init explosion at hit PLAYER 07032 07033 ;*** Any Zylon ships left? ***************************************************** 07034 LDX #127 ; Scan all sectors of Galactic Chart 07035 LOOP050 LDA GCMEMMAP,X ; 07036 BMI SKIP145 ; 07037 BNE SKIP146 ; Return if Zylon sector found 07038 SKIP145 DEX ; 07039 BPL LOOP050 ; 07040 07041 ;*** Game over (Mission Complete) ********************************************** 07042 LDY #$3F ; Set title phrase "MISSION COMPLETE" 07043 LDX #0 ; Set mission bonus offset 07044 JSR GAMEOVER2 ; Game over 07045 SKIP146 RTS ; Return 07046 07047 ;******************************************************************************* 07048 ;* * 07049 ;* KEYBOARD * 07050 ;* * 07051 ;* Handle Keyboard Input * 07052 ;* * 07053 ;******************************************************************************* 07054 07055 ; DESCRIPTION 07056 ; 07057 ; If a keyboard code has been collected during a keyboard IRQ in the Immediate 07058 ; Interrupt Request handler IRQHNDLR ($A751), the idle counter is reset and the 07059 ; PLAYER-PLAYFIELD priority arranges the PLAYERs in front of the PLAYFIELD. 07060 ; Then, the keyboard code is compared with keyboard codes of table KEYTAB 07061 ; ($BABE). If no match is found the "WHAT'S WRONG" message is displayed in the 07062 ; title line and code execution returns. 07063 ; 07064 ; If one of the speed keys '0'..'9' has been pressed, a pending hyperwarp is 07065 ; aborted in subroutine ABORTWARP ($A980) and code execution returns. Otherwise 07066 ; the Engines drain rate is adjusted as well as the new velocity of our 07067 ; starship. If the Engines are damaged, a maximum speed is possible equivalent 07068 ; to speed key '5'. 07069 ; 07070 ; If one of our starship's view keys 'F' (Front), 'A' (Aft), 'G' (Galactic 07071 ; Chart), or 'L' (Long-Range Scan) have been pressed, the Display List is 07072 ; modified accordingly in subroutine MODDLST ($ADF1) and a new star field of 12 07073 ; stars is created with the help of subroutine INITPOSVEC ($B764). Code 07074 ; execution returns via subroutine UPDSCREEN ($B07B). 07075 ; 07076 ; If one of the 'T' (Tracking Computer), 'S' (Shields) or 'C' (Attack Computer) 07077 ; keys have been pressed, the corresponding status bits are toggled and the 07078 ; title line is updated with the corresponding title phrase. The beeper sound 07079 ; pattern ACKNOWLEDGE is played in subroutine BEEP ($B3A6). The tracking letter 07080 ; of the Control Panel Display is updated and the PLAYFIELD is cleared in 07081 ; subroutine CLRPLAYFIELD ($AE0D). If the Attack Computer is on, the Front or 07082 ; Aft view cross hairs are drawn, depending on the current view of our starship, 07083 ; via subroutine DRAWLINES ($A76F). 07084 ; 07085 ; If the 'H' (Hyperwarp) key has been pressed then the hyperwarp is engaged. Our 07086 ; starship's velocity is set to the maximum value, the Engines drain rate is 07087 ; increased to the equivalent of speed key '7'. Star trails are prepared. The 07088 ; position vector of the Hyperwarp Target Marker (PLAYER3) is set to the 07089 ; following values: 07090 ; 07091 ; x-coordinate := +0 (+$0000) 07092 ; y-coordinate := +256 (+$0100) 07093 ; z-coordinate := + (+$****) (sign only) 07094 ; 07095 ; The velocity vector is set to the following values: 07096 ; 07097 ; x-velocity := (not initialized) 07098 ; y-velocity := (not initialized) 07099 ; z-velocity := +0 07100 ; 07101 ; The temporary arrival hyperwarp marker column and row numbers are saved. If 07102 ; not in a NOVICE mission, the maximum veer-off velocity of the Hyperwarp Target 07103 ; Marker during hyperwarp is picked from table VEERMASKTAB ($BED7). This value 07104 ; depends on the selected hyperwarp energy (and thus on the distance to 07105 ; hyperwarp). Finally, the title line displays the "HYPERWARP ENGAGED" message. 07106 ; 07107 ; If the 'M' (Manual target selector) key has been pressed, the tracked target 07108 ; space object is swapped and the corresponding digit of the Control Panel 07109 ; Display is toggled between 0 and 1. 07110 ; 07111 ; If the 'P' (Pause) key has been pressed, an endless loop waits until the 07112 ; joystick is pushed. 07113 ; 07114 ; BUG (at $B103): The endless loop branches back one instruction too far. 07115 ; Suggested fix: Branch to instruction LDA PORTA at $B0FE. 07116 ; 07117 ; If the 'INV' (Abort mission) key has been pressed, the mission is aborted by 07118 ; setting the mission bonus offset, then displaying the "MISSION ABORTED" 07119 ; message in the title line. Code execution continues into subroutine GAMEOVER 07120 ; ($B10A). 07121 ; 07122 ; NOTE: This subroutine has two additional entry points: 07123 ; 07124 ; (1) SETVIEW ($B045), which is used to enforce the Front view. It is entered 07125 ; from the game loop GAMELOOP ($A1F3) and subroutines INITSTART ($A15E) and 07126 ; DECENERGY ($B86F). 07127 ; 07128 ; (2) UPDSCREEN ($B07B), which draws the cross hairs, the Attack Computer 07129 ; Display and sets the tracking letter of the Control Panel Display. It is 07130 ; entered from subroutine DOCKING ($ACE6). 07131 07132 L.KEYCODE = $6A ; Saves pressed keyboard code 07133 07134 KEYBOARD LDA KEYCODE ; Return if no keyboard code collected 07135 BEQ SKIP150 ; 07136 07137 LDX #20 ; Prep keyboard code table loop index 07138 STA L.KEYCODE ; Save keyboard code 07139 07140 LDA #0 ; Reset idle counter 07141 STA IDLECNTHI ; 07142 STA KEYCODE ; Clear keyboard code 07143 07144 LDA #$11 ; GTIA: enable PLAYER4, prio: PLs > PFs > BGR 07145 STA PRIOR ; (PLAYERs appear behind cross hairs) 07146 07147 ;*** Search keyboard code in lookup table ************************************** 07148 07149 LOOP051 LDA KEYTAB,X ; Loop over all valid keyboard codes 07150 CMP L.KEYCODE ; 07151 BEQ SKIP147 ; Branch if matching entry found 07152 DEX ; 07153 BPL LOOP051 ; Next keyboard code 07154 07155 LDY #$10 ; No match found... 07156 JMP SETTITLE ; ...set title phrase "WHATS WRONG?" and return 07157 07158 ;*** Handle '0'..'9' keyboard keys (speed) ************************************* 07159 SKIP147 CPX #10 ; Skip section if keyboard code does not match 07160 BCS SKIP151 ; 07161 07162 LDA WARPSTATE ; Skip if hyperwarp disengaged... 07163 BEQ SKIP148 ; 07164 JMP ABORTWARP ; ...else abort hyperwarp 07165 07166 SKIP148 BIT GCSTATENG ; Skip if Engines are OK or destroyed 07167 BVC SKIP149 ; 07168 CPX #6 ; Allow max velocity equivalent to speed key '5' 07169 BCC SKIP149 ; 07170 LDX #5 ; 07171 07172 SKIP149 LDA DRAINRATETAB,X ; Set Engines energy drain rate 07173 STA DRAINENGINES ; 07174 LDA VELOCITYTAB,X ; Set new velocity 07175 STA NEWVELOCITY ; 07176 SKIP150 RTS ; Return 07177 07178 ;*** Handle 'F', 'A', 'L', 'G' keyboard keys (our starship's views) ************ 07179 SKIP151 CPX #14 ; Skip section if keyboard code does not match 07180 BCS SKIP152 ; 07181 07182 ;*** Entry to force Front view after program init and failed missions ********** 07183 SETVIEW LDA VIEWMODETAB-10,X ; Store our starship's view type 07184 STA SHIPVIEW ; 07185 07186 LDY DLSTFRAGOFFTAB-10,X ; Get DL fragment offset (Front, Aft, LRS, GC) 07187 LDX #$02 ; Switch to corresponding view 07188 LDA #$08 ; 07189 JSR MODDLST ; 07190 07191 LDX #NUMSPCOBJ.NORM-1 ; Create new star field of 12 stars 07192 LOOP052 JSR INITPOSVEC ; 07193 DEX ; 07194 CPX #NUMSPCOBJ.PL ; 07195 BCS LOOP052 ; 07196 07197 BCC UPDSCREEN ; Return via updating screen (below) 07198 07199 ;*** Handle 'T', 'S', 'C' keyboard keys (Tracking, Shields, Attack Computer) *** 07200 SKIP152 CPX #17 ; Skip section if keyboard code does not match 07201 BCS SKIP156 ; 07202 07203 LDY MSGOFFTAB-14,X ; Prep title phrase offset "... OFF" 07204 LDA ISTRACKCOMPON-14,X ; Toggle status bits (also energy consumption values) 07205 EOR MSGBITTAB-14,X ; 07206 STA ISTRACKCOMPON-14,X ; 07207 BEQ SKIP153 ; 07208 LDY MSGONTAB-14,X ; Prep title phrase offset "... ON" 07209 SKIP153 JSR SETTITLE ; Set title phrase to "... ON" or "... OFF" version 07210 07211 LDX #$0C ; Play beeper sound pattern ACKNOWLEDGE 07212 JSR BEEP ; 07213 07214 ;*** Update PLAYFIELD (Cross hairs, Attack Computer, set tracking letter) ****** 07215 UPDSCREEN LDX #CCS.T ; Get custom char 'T' (entry point TRANSFER COMPLETE) 07216 LDY ISTRACKCOMPON ; 07217 BEQ SKIP154 ; Skip if Tracking Computer is on 07218 07219 INX ; Get custom char 'C' 07220 07221 SKIP154 STX TRACKC1 ; Store tracking character in Control Panel Display 07222 JSR CLRPLAYFIELD ; Clear PLAYFIELD 07223 LDA DRAINATTCOMP ; Return if Attack Computer off 07224 BEQ SKIP150 ; 07225 07226 LDX SHIPVIEW ; If Aft view -> Draw Aft cross hairs and return 07227 BEQ SKIP155 ; If Front view -> Draw Front cross hairs and ... 07228 CPX #$01 ; ...Attack Computer and return 07229 BNE SKIP150 ; 07230 LDX #$2A ; 07231 SKIP155 JMP DRAWLINES ; 07232 07233 ;*** Handle 'H' keyboard key (Hyperwarp) *************************************** 07234 SKIP156 CPX #17 ; Skip if keyboard code does not match 07235 BNE SKIP158 ; 07236 07237 ;*** Engage Hyperwarp ********************************************************** 07238 LDA WARPSTATE ; Return if hyperwarp engaged 07239 BNE SKIP159 ; 07240 07241 LDA #$7F ; Engage hyperwarp 07242 STA WARPSTATE ; 07243 LDA #255 ; Set new velocity 07244 STA NEWVELOCITY ; 07245 LDA #30 ; Set Engines energy drain rate (= speed key '7') 07246 STA DRAINENGINES ; 07247 07248 LDA #NUMSPCOBJ.ALL-1 ; Set space obj index of first star of star trail 07249 STA TRAILIND ; 07250 LDA #0 ; Clear star trail delay 07251 STA TRAILDELAY ; 07252 07253 STA PL3XPOSHI ; Init position vector and velocity vector of... 07254 STA PL3XPOSLO ; ... Hyperwarp Target Marker (PLAYER3): 07255 STA PL3YPOSLO ; x-coordinate := +0 (+$0000) 07256 STA PL3ZVEL ; y-coordinate := +256 (+$0100) 07257 LDA #1 ; z-coordinate := + (+$****) (sign only) 07258 STA PL3ZPOSSIGN ; z-velocity := +0 07259 STA PL3XPOSSIGN ; 07260 STA PL3YPOSSIGN ; 07261 STA PL3YPOSHI ; 07262 07263 LDA WARPARRVCOLUMN ; Store temp arrival hyperwarp marker column number 07264 STA WARPTEMPCOLUMN ; 07265 LDA WARPARRVROW ; Store temp arrival hyperwarp marker row number 07266 STA WARPTEMPROW ; 07267 07268 LDA MISSIONLEVEL ; Skip if NOVICE mission 07269 BEQ SKIP157 ; 07270 07271 LDA WARPENERGY ; Bits B0..1 of hyperwarp energy index a table... 07272 ROL A ; ...containing the maximum value of how much the... 07273 ROL A ; ...Hyperwarp Target Marker will veer off during... 07274 ROL A ; ...hyperwarp 07275 AND #$03 ; 07276 TAY ; 07277 LDA VEERMASKTAB,Y ; 07278 07279 SKIP157 STA VEERMASK ; Store veer-off velocity limitation mask 07280 07281 LDY #$11 ; Set title phrase "HYPERWARP ENGAGED" and return 07282 JMP SETTITLE ; 07283 07284 ;*** Handle 'M' keyboard key (Manual Target Selector) key ********************** 07285 SKIP158 CPX #19 ; Skip if keyboard code does not match 07286 BCS SKIP160 ; 07287 07288 LDA TRACKDIGIT ; Toggle digit of tracked space object of... 07289 EOR #$01 ; ... Control Panel Display 07290 AND #$01 ; 07291 STA TRACKDIGIT ; 07292 SKIP159 RTS ; Return 07293 07294 ;*** Handle 'P' keyboard key (Pause) ******************************************* 07295 SKIP160 BNE SKIP161 ; Skip if keyboard code does not match 07296 07297 LDA PORTA ; Push joystick to resume action 07298 CMP #$FF ; 07299 BEQ SKIP160 ; (!) 07300 RTS ; Return 07301 07302 ;*** Handle 'INV' keyboard key (Abort Mission) ********************************* 07303 SKIP161 LDY #$76 ; Preload title phrase "MISSION ABORTED..." 07304 LDX #$04 ; Set mission bonus offset 07305 07306 ;******************************************************************************* 07307 ;* * 07308 ;* GAMEOVER * 07309 ;* * 07310 ;* Handle game over * 07311 ;* * 07312 ;******************************************************************************* 07313 07314 ; DESCRIPTION 07315 ; 07316 ; Handles game over, including calculating the scored rank and class. 07317 ; 07318 ; This subroutine has two entry points: 07319 ; 07320 ; (1) GAMEOVER ($B10A) is entered at the end of a failed mission (mission 07321 ; aborted, zero energy, or starship destroyed by Zylon fire). Essentially, 07322 ; our starship is shut down. Code execution continues into GAMEOVER2 07323 ; ($B121) below. 07324 ; 07325 ; (2) GAMEOVER2 ($B121) is entered at the end of a successful mission (all 07326 ; Zylon ships destroyed). It puts the program in demo mode, enqueues the 07327 ; corresponding game over message, and calculates the scored rank and 07328 ; class. 07329 ; 07330 ; The scored rank and class are based on the total score: the score 07331 ; accumulated during the game plus a mission bonus, which depends on the 07332 ; mission level and how the mission ended (mission complete, mission 07333 ; aborted, or starship destroyed by Zylon fire). The mission bonus is 07334 ; picked from table BONUSTAB ($BEDD). 07335 ; 07336 ; The scored rank index is taken from bits B8..4 of the total score and 07337 ; limited to values of 0..18. It indexes table RANKTAB ($BEE9) for the rank 07338 ; string. The rank string is displayed in subroutine SETTITLE ($B223). 07339 ; 07340 ; The scored class index is taken from bits B3..0 (for rank indices 0, 07341 ; 11..14) and computed from bits B4..1 (for rank indices 1..10 and 15..18). 07342 ; It takes values of 0..15. It indexes table CLASSTAB ($BEFC) for the class 07343 ; digit. The class digit is displayed in subroutine SETTITLE ($B223). 07344 ; 07345 ; For quick lookup, the following table lists rank and class from the total 07346 ; score. Pick the cell with the closest value <= your score then read the 07347 ; rank and class off the left and the top of the table, respectively. 07348 ; 07349 ; For example, a score of 90 results in a ranking of "Novice Class 4", a 07350 ; score of 161 results in a ranking of "Pilot Class 3". 07351 ; 07352 ; +------------------------------+---------------------------------------------------------------+ 07353 ; | Minimum Total Score | Class Index | 07354 ; | | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15| 07355 ; +-------+----------------------+---------------------------------------------------------------+ 07356 ; | Rank | | Class | 07357 ; | Index | Rank | 5 5 5 4 4 4 4 3 3 3 2 2 2 1 1 1| 07358 ; +-------+----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 07359 ; | 0 | Galactic Cook | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14| 15| 07360 ; | 1 | Garbage Scow Captain | 16| 18| 20| 22| 24| 26| 28| 30| | | | | | | | | 07361 ; | 2 | Garbage Scow Captain | | | | | | | | | 32| 34| 36| 38| 40| 42| 44| 46| 07362 ; | 3 | Rookie | 48| 50| 52| 54| 56| 58| 60| 62| | | | | | | | | 07363 ; | 4 | Rookie | | | | | | | | | 64| 66| 68| 70| 72| 74| 76| 78| 07364 ; | 5 | Novice | 80| 82| 84| 86| 88| 90| 92| 94| | | | | | | | | 07365 ; | 6 | Novice | | | | | | | | | 96| 98|100|102|104|106|108|110| 07366 ; | 7 | Ensign |112|114|116|118|120|122|124|126| | | | | | | | | 07367 ; | 8 | Ensign | | | | | | | | |128|130|132|134|136|138|140|142| 07368 ; | 9 | Pilot |144|146|148|150|152|154|156|158| | | | | | | | | 07369 ; | 10 | Pilot | | | | | | | | |160|162|164|166|168|170|172|174| 07370 ; | 11 | Ace |176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191| 07371 ; | 12 | Lieutenant |192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207| 07372 ; | 13 | Warrior |208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223| 07373 ; | 14 | Captain |224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239| 07374 ; | 15 | Commander |240|242|244|246|248|250|252|254| | | | | | | | | 07375 ; | 16 | Commander | | | | | | | | |256|258|260|262|264|266|268|270| 07376 ; | 17 | Star Commander |272|274|276|278|280|282|284|286| | | | | | | | | 07377 ; | 18 | Star Commander | | | | | | | | |288|290|292|294|296|298|300|302| 07378 ; +-------+----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 07379 ; 07380 ; NOTE: This subroutine also clears the vertical and horizontal joystick 07381 ; directions. 07382 ; 07383 ; INPUT 07384 ; 07385 ; X = Offset to index table BONUSTAB ($BEDD) of mission bonus values. Used 07386 ; values are: 07387 ; $00 -> Mission complete 07388 ; $04 -> Mission was aborted due to zero energy 07389 ; $08 -> Our starship was destroyed by Zylon fire 07390 ; 07391 ; Y = Title phrase offset. Used values are: 07392 ; $3F -> "MISSION COMPLETE" 07393 ; $31 -> "MISSION ABORTED ZERO ENERGY" 07394 ; $23 -> "SHIP DESTROYED BY ZYLON FIRE" 07395 07396 ;*** Game over (Mission failed) ************************************************ 07397 GAMEOVER LDA #0 ; 07398 STA PL3LIFE ; PLAYER3 lifetime := 0 game loops 07399 STA BEEPPRIORITY ; Mute beeper 07400 STA TITLEPHR ; Clear title line 07401 STA REDALERTLIFE ; Red alert flash lifetime := 0 game loops 07402 STA AUDC4 ; Mute audio channel 4 07403 STA NEWVELOCITY ; Shut down Engines 07404 STA SHIELDSCOLOR ; Set Shields color to {BLACK} 07405 STA DRAINSHIELDS ; Switch off Shields 07406 STA WARPSTATE ; Disengage hyperwarp 07407 STA VELOCITYHI ; Turn off hyperwarp velocity 07408 07409 ;*** Game over (Mission successful) ******************************************** 07410 GAMEOVER2 LDA #$FF ; Enter demo mode 07411 STA ISDEMOMODE ; 07412 07413 STY NEWTITLEPHR ; Enqueue title phrase 07414 07415 ;*** Calculate total score ***************************************************** 07416 TXA ; 07417 ORA MISSIONLEVEL ; 07418 TAX ; 07419 LDA BONUSTAB,X ; Retrieve mission bonus 07420 CLC ; Add mission bonus and game score 07421 ADC SCORE ; 07422 TAX ; 07423 LDA #0 ; 07424 07425 STA JOYSTICKY ; Clear vertical joystick delta 07426 STA JOYSTICKX ; Clear horizontal joystick delta 07427 07428 ADC SCORE+1 ; 07429 BMI SKIP165 ; Return if total score < 0 (= total score of 0) 07430 07431 ;*** Calculate scored rank ***************************************************** 07432 LSR A ; 07433 TXA ; 07434 ROR A ; 07435 LSR A ; 07436 LSR A ; 07437 LSR A ; Use bits B8..4 of total score as rank index 07438 CMP #19 ; Limit scored rank index to 0..18 07439 BCC SKIP162 ; 07440 LDA #18 ; 07441 LDX #15 ; Prep class index of 15 07442 SKIP162 STA SCOREDRANKIND ; Store scored rank index 07443 07444 ;*** Calculate scored class **************************************************** 07445 TAY ; 07446 TXA ; 07447 CPY #0 ; 07448 BEQ SKIP164 ; 07449 CPY #11 ; 07450 BCC SKIP163 ; 07451 CPY #15 ; 07452 BCC SKIP164 ; 07453 SKIP163 LSR A ; 07454 EOR #$08 ; 07455 SKIP164 AND #$0F ; 07456 STA SCOREDCLASSIND ; Store scored class index, is 0..15 07457 07458 SKIP165 RTS ; Return 07459 07460 ;******************************************************************************* 07461 ;* * 07462 ;* SELECTWARP * 07463 ;* * 07464 ;* Select hyperwarp arrival location on Galactic Chart * 07465 ;* * 07466 ;******************************************************************************* 07467 07468 ; DESCRIPTION 07469 ; 07470 ; This subroutine executes the following steps: 07471 ; 07472 ; (1) Check if we are in Galactic Chart view and not in hyperwarp. 07473 ; 07474 ; (2) Update the Galactic Chart in subroutine DRAWGC ($B4B9) if the Subspace 07475 ; Radio is not damaged. 07476 ; 07477 ; (3) Move the arrival hyperwarp marker (PLAYER4) across the Galactic Chart 07478 ; every other game loop iteration. The current location of our starship is 07479 ; indicated by the departure hyperwarp marker (PLAYER3). 07480 ; 07481 ; Code execution continues into subroutine CALCWARP ($B1A7) to calculate the 07482 ; required hyperwarp energy. 07483 ; 07484 ; NOTE: To calculate the horizontal position of PLAYER3..4 an offset of 61 is 07485 ; added (from left to right: 48 Player/Missile (PM) pixels to the left edge of 07486 ; the screen + 16 PM pixels to the left border of the Galactic Chart - 3 PM 07487 ; pixels relative offset of the PLAYER shape's horizontal center to its left 07488 ; edge = 61 PM pixels). 07489 ; 07490 ; NOTE: To calculate the vertical position of PLAYER3..4 an offset of 63 is 07491 ; added (from top to bottom: 8 Player/Missile (PM) pixels to the start of the 07492 ; Display List + 56 PM pixels to the first row of sectors - 1 PM pixel relative 07493 ; offset of the PLAYER shape's vertical center to its top edge (?) = 63 PM 07494 ; pixels). 07495 07496 SELECTWARP LDA WARPSTATE ; Return if hyperwarp engaged 07497 BNE SKIP166 ; 07498 07499 LDA SHIPVIEW ; Return if not in Galactic Chart view 07500 BMI SKIP167 ; 07501 SKIP166 RTS ; Return 07502 07503 SKIP167 BIT GCSTATRAD ; Skip if Subspace Radio is damaged or destroyed 07504 BMI SKIP168 ; 07505 07506 JSR DRAWGC ; Redraw Galactic Chart 07507 07508 SKIP168 LDA COUNT8 ; Move hyperwarp markers only every other game loop 07509 AND #$01 ; (slowing down movement of hyperwarp markers) 07510 BNE CALCWARP ; 07511 07512 ;*** Calc arrival hyperwarp marker column and row numbers, update PLAYER4 pos ** 07513 CLC ; 07514 LDA WARPARRVCOLUMN ; Load arrival hyperwarp marker column number 07515 ADC JOYSTICKX ; Add joystick x-delta 07516 AND #$7F ; Limit value to 0..127 07517 STA WARPARRVCOLUMN ; Save new arrival hyperwarp marker column number 07518 CLC ; 07519 ADC #61 ; Add offset of 61 07520 STA PL4COLUMN ; Store as PLAYER4 column number 07521 07522 CLC ; 07523 LDA WARPARRVROW ; Load arrival hyperwarp marker row number 07524 ADC JOYSTICKY ; Add joystick y-delta 07525 AND #$7F ; Limit value to 0..127 07526 STA WARPARRVROW ; Save new arrival hyperwarp marker row number 07527 CLC ; 07528 ADC #63 ; Add offset of 63 07529 STA PL4ROWNEW ; Store as PLAYER4 row number 07530 07531 ;*** Calc departure hyperwarp marker column and row numbers, update PLAYER3 pos 07532 LDA WARPDEPRROW ; Load departure hyperwarp marker row number 07533 CLC ; 07534 ADC #63 ; Add offset of 63 07535 STA PL3ROWNEW ; Store as PLAYER3 row number 07536 07537 LDA WARPDEPRCOLUMN ; Load departure hyperwarp marker column number 07538 CLC ; 07539 ADC #61 ; Add offset of 61 07540 STA PL3COLUMN ; Store as PLAYER3 column number 07541 07542 ;******************************************************************************* 07543 ;* * 07544 ;* CALCWARP * 07545 ;* * 07546 ;* Calculate and display hyperwarp energy * 07547 ;* * 07548 ;******************************************************************************* 07549 07550 ; DESCRIPTION 07551 ; 07552 ; Calculates and displays the hyperwarp energy in the Galactic Chart view. 07553 ; 07554 ; This subroutine executes the following steps: 07555 ; 07556 ; (1) Determine the arrival sector from the arrival hyperwarp marker position. 07557 ; 07558 ; (2) If the Subspace Radio is not destroyed, update the target number digit of 07559 ; the Galactic Chart Panel Display. 07560 ; 07561 ; (3) Calculate the hyperwarp energy that is required to hyperwarp from the 07562 ; departure hyperwarp marker to the arrival hyperwarp marker based on the 07563 ; "block-distance": 07564 ; 07565 ; DISTANCE := DELTAC + DELTAR / 2 07566 ; 07567 ; where 07568 ; 07569 ; DELTAC := ABS(WARPARRVCOLUMN - WARPDEPRCOLUMN) 07570 ; DELTAR := ABS(WARPARRVROW - WARPDEPRROW) 07571 ; 07572 ; NOTE: Dividing DELTAR by 2 is because PLAYERs at single-line resolution 07573 ; have Player/Missile pixels that are half as high as they are wide. 07574 ; 07575 ; The hyperwarp energy, divided by 10, is the sum of a value picked from 07576 ; the hyperwarp energy table WARPENERGYTAB ($BADD) indexed by DISTANCE / 8) 07577 ; plus a remainder computed from Bits B1..0 of DISTANCE. 07578 ; 07579 ; (4) Store the hyperwarp energy value in WARPENERGY ($91). 07580 ; 07581 ; (5) Update the HYPERWARP ENERGY readout of the Galactic Chart Panel Display. 07582 07583 L.WARPARRVCOL = $6A ; Saves arrival sector column number 07584 L.DIFFC = $6A ; Saves diff column value 07585 07586 ;*** Calculate arrival sector ************************************************** 07587 CALCWARP LDA WARPARRVCOLUMN ; 07588 LSR A ; 07589 LSR A ; 07590 LSR A ; 07591 STA L.WARPARRVCOL ; A := arrival sector column 0..15 07592 LDA WARPARRVROW ; 07593 AND #$70 ; A := arrival sector row (0..7) * 16 07594 ORA L.WARPARRVCOL ; 07595 STA ARRVSECTOR ; Save arrival sector (format %0rrrcccc) 07596 07597 ;*** Update target number digit of Galactic Chart Panel Display **************** 07598 TAX ; 07599 LDA GCMEMMAP,X ; Get number of Zylon ships in arrival sector 07600 BPL SKIP169 ; Skip if no starbase in arrival sector 07601 LDA #0 ; Clear number of Zylon ships 07602 SKIP169 ORA #CCS.COL2!ROM.0 ; Merge COLOR2 bits with number of Zylon ships 07603 BIT GCSTATRAD ; Skip if Subspace Radio destroyed 07604 BVS SKIP170 ; 07605 07606 STA GCTRGCNT ; Set target number digit of Galactic Chart Panel 07607 07608 ;*** Calculate energy to hyperwarp between hyperwarp markers ******************* 07609 SKIP170 SEC ; A := DIFFC := ABS(WARPARRVCOLUMN - WARPDEPRCOLUMN) 07610 LDA WARPARRVCOLUMN ; (Column value difference) 07611 SBC WARPDEPRCOLUMN ; 07612 BCS SKIP171 ; 07613 EOR #$FF ; 07614 ADC #1 ; 07615 SKIP171 STA L.DIFFC ; 07616 07617 SEC ; A := DIFFR := ABS(WARPARRVROW - WARPDEPRROW) 07618 LDA WARPARRVROW ; (Row value difference) 07619 SBC WARPDEPRROW ; 07620 BCS SKIP172 ; 07621 EOR #$FF ; 07622 ADC #1 ; 07623 07624 SKIP172 LSR A ; A := DISTANCE := DIFFR / 2 + DIFFC 07625 CLC ; 07626 ADC L.DIFFC ; 07627 07628 TAY ; Save DISTANCE 07629 LSR A ; Calc index into hyperwarp energy table 07630 LSR A ; 07631 LSR A ; 07632 TAX ; 07633 07634 TYA ; Load DISTANCE value 07635 AND #$03 ; Get DISTANCE bits B1..0 07636 CLC ; 07637 ADC WARPENERGYTAB,X ; Add hyperwarp energy from table 07638 STA WARPENERGY ; Save hyperwarp energy 07639 07640 ;*** Update HYPERWARP ENERGY readout of Galactic Chart Panel Display *********** 07641 TAY ; Prep with hyperwarp energy value 07642 07643 LDA #ROM.0 ; Set HYPERWARP ENERGY readout digit1..3 to '0' 07644 STA GCWARPD1 ; 07645 STA GCWARPD1+1 ; 07646 STA GCWARPD1+2 ; 07647 07648 LOOP053 LDX #2 ; Loop over HYPERWARP ENERGY readout digit3..1 07649 LOOP054 INC GCWARPD1,X ; Increment digit value 07650 LDA GCWARPD1,X ; 07651 CMP #ROM.9+1 ; 07652 BCC SKIP173 ; Skip if energy digit <= '9' 07653 07654 LDA #ROM.0 ; Replace energy digit with '0' 07655 STA GCWARPD1,X ; 07656 DEX ; 07657 BPL LOOP054 ; Next energy digit 07658 07659 SKIP173 DEY ; Decrement HYPERWARP ENERGY readout value 07660 BNE LOOP053 ; 07661 RTS ; Return 07662 07663 ;******************************************************************************* 07664 ;* * 07665 ;* UPDTITLE * 07666 ;* * 07667 ;* Update title line * 07668 ;* * 07669 ;******************************************************************************* 07670 07671 ; DESCRIPTION 07672 ; 07673 ; Updates the title phrase displayed in the title line. 07674 ; 07675 ; If no title phrase has been set then fetch the offset of the next ("enqueued") 07676 ; title phrase to be displayed. If one has been set then code execution 07677 ; continues into subroutine SETTITLE ($B223), otherwise code execution returns. 07678 ; 07679 ; If a title phrase has been set then decrement the lifetime of the currently 07680 ; displayed title phrase segment. If its lifetime has reached a value of 0 then 07681 ; branch to subroutine SETTITLE ($B223) to display the next segment. 07682 07683 UPDTITLE LDA TITLEPHR ; Skip if no title phrase set 07684 BEQ SKIP175 ; 07685 07686 DEC TITLELIFE ; Decrement title phrase segment lifetime 07687 BEQ SKIP176 ; If lifetime expired show next title segment 07688 07689 SKIP174 RTS ; Return 07690 07691 SKIP175 LDY NEWTITLEPHR ; Prep enqueued new title phrase 07692 BEQ SKIP174 ; Return if not set 07693 07694 ;******************************************************************************* 07695 ;* * 07696 ;* SETTITLE * 07697 ;* * 07698 ;* Set title phrase in title line * 07699 ;* * 07700 ;******************************************************************************* 07701 07702 ; DESCRIPTION 07703 ; 07704 ; Displays a title phrase in the title line. 07705 ; 07706 ; INTRODUCTION 07707 ; 07708 ; Title phrases are picked from the title phrase table PHRASETAB ($BBAA). They 07709 ; consist of one or more phrase tokens. Each token is a byte representing a word 07710 ; in word table WORDTAB ($BC2B). Two special tokens are placeholders for the 07711 ; scored class ($FC) and scored rank ($FD) strings. 07712 ; 07713 ; A title phrase is split up into one or more title phrase segments, each 07714 ; fitting into the title line. One title phrase segment is displayed after the 07715 ; other after a delay called the "title segment lifetime". 07716 ; 07717 ; Phrase tokens, except the tokens for the scored class ($FC) and for the scored 07718 ; rank ($FD), contain the number of a word in word table WORDTAB ($BC2B) and may 07719 ; contain an end-of-segment or end-of-phrase marker bit. 07720 ; 07721 ; DETAILS 07722 ; 07723 ; The Display List is modified by subroutine MODDLST ($ADF1) to display the 07724 ; title line. Then, the title line is cleared and the words of the title phrase 07725 ; are copied into it using the passed offset into title phrase table PHRASETAB 07726 ; ($BBAA). If the offset has a value of $FF the title line is hidden in 07727 ; subroutine MODDLST ($ADF1). 07728 ; 07729 ; INPUT 07730 ; 07731 ; Y = Offset into title phrase table PHRASETAB ($BBAA). Used values are: 07732 ; $FF -> Hide title line 07733 ; else -> Offset into title phrase table PHRASETAB ($BBAA), with explicitly 07734 ; used values: 07735 ; 07736 ; $01 -> "COMPUTER ON" 07737 ; $04 -> "COMPUTER OFF" 07738 ; $07 -> "SHIELDS ON" 07739 ; $09 -> "SHIELDS OFF" 07740 ; $0B -> "COMPUTER TRACKING ON" 07741 ; $0E -> "TRACKING OFF" 07742 ; $13 -> "STARBASE SURROUNDED" 07743 ; $15 -> "STARBASE DESTROYED" 07744 ; $1F -> "DOCKING ABORTED" 07745 ; $21 -> "TRANSFER COMPLETE" 07746 ; $4A -> "NOVICE MISSION" 07747 ; $4C -> "PILOT MISSION" 07748 ; $4E -> "WARRIOR MISSION" 07749 ; $50 -> "COMMANDER MISSION" 07750 ; $52 -> "DAMAGE CONTROL..." 07751 ; $75 -> "RED ALERT" 07752 07753 L.WORD = $6A ; Saves word number of WORDTAB ($BC2A). Used values 07754 ; are $00..$3F. 07755 L.COLUMNPOS = $6B ; Saves cursor column position during copying text 07756 ; into title line 07757 L.TOKEN = $6C ; Saves title phrase token from PHRASETAB ($BBAA), 07758 ; contains bit-encoded information about one word in 07759 ; the title phrase: 07760 ; B7..6 = %00 -> Copy next word to title line 07761 ; B7..6 = %01 -> End-of-phrase reached, apply short 07762 ; delay, then hide title line. Title 07763 ; segment lifetime = 60 game loops. 07764 ; B7..6 = %10 -> End-of-segment reached. Title 07765 ; segment lifetime = 60 game loops 07766 ; B7..6 = %11 -> End-of-phrase reached, apply long 07767 ; delay, then hide title line. Title 07768 ; segment lifetime = 254 game loops. 07769 ; Used with title phrases 07770 ; "STARBASE SURROUNDED" 07771 ; "STARBASE DESTROYED" 07772 ; "HYPERSPACE" 07773 ; "RED ALERT" 07774 ; B5..0 -> Word number of WORDTAB ($BC2A) 07775 07776 SETTITLE STY TITLEPHR ; Save title phrase offset 07777 07778 LDY #$23 ; Show title line 07779 LDX #$0F ; 07780 LDA #$07 ; 07781 JSR MODDLST ; 07782 07783 ;*** Init cursor column position and clear title line ************************** 07784 SKIP176 LDX #19 ; There are 19(+1) characters to clear 07785 LDA #0 ; 07786 STA L.COLUMNPOS ; Init cursor column position 07787 07788 LOOP055 STA TITLETXT,X ; Clear character in title line 07789 DEX ; 07790 BPL LOOP055 ; 07791 07792 ;*** If title phrase offset = $FF then hide title line ************************* 07793 SKIP177 LDX TITLEPHR ; Load title phrase offset 07794 INC TITLEPHR ; Prepare title phrase offset for next word 07795 BNE SKIP178 ; ...skip if it turned 0 07796 07797 LDX #$0F ; Remove title line and return 07798 LDY #$80 ; 07799 LDA #$07 ; 07800 JMP MODDLST ; 07801 07802 SKIP178 LDA PHRASETAB,X ; Get phrase token 07803 07804 ;*** Display scored class? ***************************************************** 07805 CMP #$FC ; Skip if not "scored class" token 07806 BNE SKIP179 ; 07807 07808 LDY SCOREDCLASSIND ; Get scored class index, is in 0..15 07809 LDA CLASSTAB,Y ; Load scored class number digit 07810 LDX L.COLUMNPOS ; Load cursor position 07811 STA TITLETXT,X ; Store class in title line 07812 LDA #60 ; Title segment lifetime := 60 game loops 07813 STA TITLELIFE ; 07814 RTS ; Return 07815 07816 ;*** Display scored rank? ****************************************************** 07817 SKIP179 CMP #$FD ; Skip if not "scored rank" token 07818 BNE SKIP180 ; 07819 07820 LDY SCOREDRANKIND ; Get scored rank index, is in 0..18 07821 LDA RANKTAB,Y ; Load rank word number 07822 07823 ;*** Search word of token in word table **************************************** 07824 SKIP180 STA L.TOKEN ; Save phrase token 07825 AND #$3F ; Strip bits B6..7 from phrase token 07826 STA L.WORD ; Store word number (bits B5..0) 07827 07828 LDA #<[WORDTAB-1] ; Point MEMPTR to WORDTAB-1 07829 STA MEMPTR ; 07830 LDA #>[WORDTAB-1] ; 07831 STA MEMPTR+1 ; 07832 07833 LOOP056 INC MEMPTR ; Increment MEMPTR 07834 BNE SKIP181 ; 07835 INC MEMPTR+1 ; 07836 07837 SKIP181 LDY #0 ; 07838 LDA (MEMPTR),Y ; Load character of word 07839 BPL LOOP056 ; Loop until end-of-word marker (bit B7) found 07840 DEC L.WORD ; 07841 BNE LOOP056 ; Loop until word found 07842 07843 ;*** Copy word to title line, add space **************************************** 07844 LOOP057 AND #$3F ; Strip color bits B6..7 from character 07845 EOR #CCS.COL2!$20 ; Merge COLOR2 bits and convert to ATASCII 07846 LDX L.COLUMNPOS ; Copy character to title line 07847 INC L.COLUMNPOS ; Increment cursor column position 07848 STA TITLETXT,X ; 07849 INY ; 07850 LDA (MEMPTR),Y ; Load next character of word 07851 BPL LOOP057 ; Next character of word if no end-of-word marker 07852 INC L.COLUMNPOS ; Word was copied. Add space after word. 07853 07854 ;*** Decide to copy another word, etc. ***************************************** 07855 LDA #60 ; SUMMARY: 07856 BIT L.TOKEN ; If bits B7..6 of phrase token... 07857 BPL SKIP182 ; %00 -> Copy next word to title line 07858 BVC SKIP183 ; %01 -> End-of-phrase, short delay, hide title line 07859 LDA #254 ; Title segment lifetime := 60 game loops 07860 SKIP182 BVC SKIP177 ; %10 -> End-of-segment. 07861 LDY #$FF ; Title segment lifetime := 60 game loops 07862 STY TITLEPHR ; %11 -> End-of-phrase, long delay, hide title line 07863 SKIP183 STA TITLELIFE ; Title segment lifetime := 254 game loops 07864 RTS ; Return 07865 07866 ;******************************************************************************* 07867 ;* * 07868 ;* SOUND * 07869 ;* * 07870 ;* Handles sound effects * 07871 ;* * 07872 ;******************************************************************************* 07873 07874 ; DESCRIPTION 07875 ; 07876 ; This subroutine handles the sound effects. It is called every vertical blank 07877 ; phase, that is, every TICK (1/60 s on an NTSC ATARI Home Computer system, 1/50 07878 ; s on a PAL ATARI Home Computer system) from the Vertical Blank Interrupt 07879 ; handler VBIHNDLR ($A6D1). 07880 ; 07881 ; The program uses all of the available 4 audio channels: Audio channels 1, 2, 07882 ; and 3 are shared among the Engines sound effects and the "noise sound 07883 ; patterns" (explosion and photon torpedo sound effects), while audio channel 4 07884 ; is used for "beeper sound patterns" (status report sound effects). The 07885 ; following sections explain the beeper sound patterns and the noise sound 07886 ; patterns: 07887 ; 07888 ; o BEEPER SOUND PATTERNS 07889 ; 07890 ; There are the following beeper sound patterns: 07891 ; 07892 ; (1) HYPERWARP TRANSIT 07893 ; (2) RED ALERT 07894 ; (3) ACKNOWLEDGE 07895 ; (4) DAMAGE REPORT 07896 ; (5) MESSAGE FROM STARBASE 07897 ; 07898 ; They are encoded in table BEEPPATTAB ($BF3E) in 6-byte long "beeper sound 07899 ; patterns". 07900 ; 07901 ; Another table, BEEPFRQTAB ($BF5C), stores the frequencies for the tones 07902 ; of each beeper sound pattern, terminated by a marker byte ($FF). 07903 ; 07904 ; BUG (at $BF5C): The pattern frequencies in table BEEPFRQTAB ($BF5C) at 07905 ; offset $00 are unused. Suggested Fix: Remove from code. 07906 ; 07907 ; Whenever the program calls subroutine BEEP ($B3A6), that subroutine sets 07908 ; up a beeper sound pattern for playing by copying 6 bytes from the pattern 07909 ; table BEEPPATTAB ($BF3E) to BEEPFRQIND ($D2)..BEEPFRQSTART ($D7). 07910 ; Subroutine SOUND ($B2AB) detects the copied beeper sound pattern and plays 07911 ; the encoded tones and pauses. 07912 ; 07913 ; The relevant variables for playing a beeper sound pattern are the 07914 ; following (see also figures at BEEPPATTAB ($BF3E)): 07915 ; 07916 ; BEEPFRQIND ($D2) = Running index into table BEEPFRQTAB ($BF5C) 07917 ; BEEPREPEAT ($D3) = Number of times that the beeper sound pattern is 07918 ; repeated - 1 07919 ; BEEPTONELIFE ($D4) = Lifetime of tone in TICKs - 1 07920 ; BEEPPAUSELIFE ($D5) = Lifetime of pause in TICKs - 1 ($FF -> No pause) 07921 ; BEEPPRIORITY ($D6) = Beeper sound pattern priority. A playing beeper 07922 ; sound pattern is stopped if a beeper sound pattern 07923 ; of higher priority is about to be played. A value 07924 ; of 0 indicates that no beeper sound pattern is 07925 ; playing at the moment. 07926 ; BEEPFRQSTART ($D7) = Index to first byte of the beeper sound pattern in 07927 ; table BEEPFRQTAB ($BF5C) 07928 ; 07929 ; BEEPLIFE ($D8) = Lifetime of the current tone or pause in TICKs 07930 ; BEEPTOGGLE ($D9) = Indicates that either a tone (0) or a pause (not 07931 ; 0) is currently playing. 07932 ; 07933 ; o NOISE SOUND PATTERNS 07934 ; 07935 ; There are the following noise sound patterns: 07936 ; 07937 ; (1) PHOTON TORPEDO LAUNCHED 07938 ; (2) SHIELD EXPLOSION 07939 ; (3) ZYLON EXPLOSION 07940 ; 07941 ; They are encoded in table NOISEPATTAB ($BF20) in 10-byte long "noise sound 07942 ; patterns". 07943 ; 07944 ; Whenever the program calls subroutine NOISE ($AEA8), that subroutine sets 07945 ; up a noise sound pattern for being played by copying 10 bytes from the 07946 ; pattern table NOISEPATTAB ($BF20) to NOISETORPTIM ($DA)..NOISELIFE ($E1) 07947 ; and hardware sound registers AUDCTL ($D208) and AUDF3 ($D204). 07948 ; 07949 ; The relevant variables for playing a noise sound pattern are the 07950 ; following: 07951 ; 07952 ; NOISETORPTIM ($DA) = Delay timer for PHOTON TORPEDO LAUNCHED noise 07953 ; sound pattern 07954 ; NOISEEXPLTIM ($DB) = Delay timer for SHIELD EXPLOSION and ZYLON 07955 ; EXPLOSION noise sound patterns 07956 ; NOISEAUDC2 ($DC) = Audio channel 1/2 control shadow register 07957 ; NOISEAUDC3 ($DD) = Audio channel 3 control shadow register 07958 ; NOISEAUDF1 ($DE) = Audio channel 1 frequency shadow register 07959 ; NOISEAUDF2 ($DF) = Audio channel 2 frequency shadow register 07960 ; NOISEFRQINC ($E0) = Audio channel 1/2 frequency increment 07961 ; NOISELIFE ($E1) = Noise sound pattern lifetime 07962 ; 07963 ; AUDCTL ($D208) = POKEY: Audio control 07964 ; AUDF3 ($D204) = POKEY: Audio channel 3 frequency audio register 07965 ; 07966 ; There are two more variables that trigger noise effects. They are not part 07967 ; of the noise sound pattern table: 07968 ; 07969 ; NOISEZYLONTIM ($E2) = Delay timer to trigger the ZYLON EXPLOSION noise 07970 ; sound pattern. It is set in subroutine COLLISION 07971 ; ($AF3D) when the impact of one of our starship's 07972 ; photon torpedoes with a target is imminent. The 07973 ; timer is decremented every TICK. When it reaches a 07974 ; value of 0 the ZYLON EXPLOSION noise sound pattern 07975 ; is played in subroutine SOUND ($B2AB). 07976 ; NOISEHITLIFE ($E3) = Lifetime of the STARSHIP EXPLOSION noise when our 07977 ; starship was destroyed by a Zylon photon torpedo. 07978 ; It is set in GAMELOOP ($A1F3) to a value of 64 07979 ; TICKs. When it reaches a value of 0 the STARSHIP 07980 ; EXPLOSION noise is played in subroutine SOUND 07981 ; ($B2AB). 07982 ; 07983 ; SUBROUTINE DETAILS 07984 ; 07985 ; This subroutine executes the following steps: 07986 ; 07987 ; (1) Play beeper sound pattern 07988 ; 07989 ; The playing of a beeper sound pattern is started, continued, or stopped. 07990 ; 07991 ; (2) Play ZYLON EXPLOSION noise sound pattern 07992 ; 07993 ; If the explosion of a target space object is imminent (subroutine 07994 ; COLLISION ($AF3D) has set NOISEZYLONTIM ($E2) to the number of game loop 07995 ; iterations that will pass until our starship's photon torpedo will hit 07996 ; the target), the timer NOISEZYLONTIM ($E2) is decremented every TICK. If 07997 ; it reaches a value of 0, then the noise sound pattern ZYLON EXPLOSION is 07998 ; played. 07999 ; 08000 ; (3) Play starship's Engines sound 08001 ; 08002 ; If the Engines are louder than the current noise sound pattern then the 08003 ; noise sound pattern is terminated and the values for the audio channels 08004 ; 1..3 are updated: 08005 ; 08006 ; The velocity of our starship determines the pitch and the volume of the 08007 ; Engines: the higher the velocity, the higher the pitch and the volume of 08008 ; the Engines. The incremented value of VELOCITYLO ($70) is used as a "base 08009 ; value" %abcdefgh. 08010 ; 08011 ; Audio channels 1 and 2 are combined to a 16-bit audio channel 1/2, 08012 ; clocked at 1.79 MHz. The inverted bits (represented by an overscore) 08013 ; B7..0 of the base value form bits B12..5 of the 16-bit frequency value of 08014 ; audio channel 1/2. Bits B7..4 of the base value form bits B3..0 of the 08015 ; volume of audio channel 1/2, with noise distortion bit B7 set: 08016 ; ________ 08017 ; AUDF1/2 ($D202..3) := %000abcdefgh00000 08018 ; AUDC2 ($D203) := %1000abcd 08019 ; 08020 ; Audio channel 3 is also clocked at 1.79 MHz. The inverted bits B7..0 of 08021 ; the base value form bits B7..0 of the frequency value of audio channel 3. 08022 ; Bits B6..4 of the base value form bits B3..0 of the volume of audio 08023 ; channel 3, with noise distortion bit B7 set: 08024 ; ________ 08025 ; AUDF3 ($D204) := %abcdefgh 08026 ; AUDC3 ($D205) := %10000bcd 08027 ; 08028 ; Code execution returns at this point. 08029 ; 08030 ; (4) Play ZYLON EXPLOSION or SHIELD EXPLOSION noise sound pattern 08031 ; 08032 ; If the ZYLON EXPLOSION or SHIELD EXPLOSION noise sound pattern was set 08033 ; up, the explosion noise timer NOISEEXPLTIM ($DB) is decremented every 08034 ; TICK. It starts either with a value of 4 TICKs with a ZYLON EXPLOSION 08035 ; noise sound pattern or with a value of 8 TICKs with a SHIELD EXPLOSION 08036 ; noise sound pattern, set up in subroutine NOISE ($AEA8). If it reaches a 08037 ; value of 0, then the shadow control register of audio channel 1/2 08038 ; switches to "noise distortion" at maximum volume. 08039 ; 08040 ; (5) Play PHOTON TORPEDO LAUNCHED noise sound pattern 08041 ; 08042 ; If the PHOTON TORPEDO LAUNCHED noise sound pattern was set up, the photon 08043 ; torpedo noise timer NOISETORPTIM ($DA) is decremented every TICK. It 08044 ; starts with a value of 8 TICKs, set in subroutine TRIGGER ($AE29). The 08045 ; noise distortion and volume for the shadow control register of audio 08046 ; channel 3 is picked from table NOISETORPVOLTAB ($BFEB), the noise 08047 ; frequency for audio channel 3 is picked from table NOISETORPFRQTAB 08048 ; ($BFF3). If the photon torpedo noise timer reaches a value of 0, then the 08049 ; shadow control registers of audio channel 1/2 switch to "tone distortion" 08050 ; at maximum volume and a frequency of $0202. 08051 ; 08052 ; NOTE: Using a real-time volume envelope stored in table NOISETORPVOLTAB 08053 ; ($BFEB) for a launched photon torpedo results in the distinctive 08054 ; "whooshing" photon torpedo sound. 08055 ; 08056 ; (6) Play STARSHIP EXPLOSION noise 08057 ; 08058 ; If our starship was hit by a Zylon photon torpedo then NOISEHITLIFE ($E3) 08059 ; was set to 64 TICKs in routine GAMELOOP ($A1F3). While this value is 08060 ; decremented every TICK, a random frequency value is stored to audio 08061 ; channel 3 and the distortion bit of the shadow control register of audio 08062 ; channel 3 is randomly toggled. 08063 ; 08064 ; (7) Increase audio channels 1/2 frequency 08065 ; 08066 ; The 16-bit frequency value of audio channels 1/2 (both shadow registers 08067 ; and audio registers) is increased every TICK by an increment picked from 08068 ; the currently playing noise sound pattern. 08069 ; 08070 ; (8) Mute audio channels gradually 08071 ; 08072 ; Toward the end of a noise sound pattern's lifetime all audio channels 08073 ; gradually mute their volume every other TICK until completely silent. 08074 08075 ;*** Play beeper sound pattern ************************************************* 08076 SOUND LDA BEEPPRIORITY ; Skip if beeper sound pattern not in use 08077 BEQ SKIP185 ; 08078 08079 DEC BEEPLIFE ; Decrement beeper lifetime 08080 BPL SKIP185 ; Skip if beeper lifetime still counting down 08081 08082 LDA BEEPTOGGLE ; Load tone/pause toggle 08083 BEQ LOOP058 ; Skip if a tone is playing or is to be played 08084 08085 LDA BEEPPAUSELIFE ; Load pause lifetime 08086 BMI LOOP058 ; Skip if duration = $FF (no pause) 08087 STA BEEPLIFE ; Store pause lifetime as beeper lifetime 08088 LDY #0 ; Prep AUDC4 (zero volume) 08089 BEQ SKIP184 ; Skip unconditionally 08090 08091 LOOP058 LDA BEEPTONELIFE ; Load tone lifetime 08092 STA BEEPLIFE ; Store tone lifetime as beeper lifetime 08093 LDX BEEPFRQIND ; Load frequency index 08094 INC BEEPFRQIND ; Increment frequency index 08095 LDA BEEPFRQTAB,X ; Store tone frequency from frequency table in AUDF4 08096 STA AUDF4 ; 08097 LDY #$A8 ; Prep AUDC4 (tone distortion + medium volume) 08098 CMP #$FF ; Skip if frequency not $FF (there are more tones) 08099 BNE SKIP184 ; 08100 08101 LDA BEEPFRQSTART ; Rewind pattern frequency pointer 08102 STA BEEPFRQIND ; 08103 DEC BEEPREPEAT ; Decrement sequence counter 08104 BPL LOOP058 ; Keep playing until sequence counter < 0 08105 08106 LDY #0 ; Prep AUDC4 with zero volume 08107 STY BEEPPRIORITY ; Stop playing beeper sound pattern 08108 08109 SKIP184 STY AUDC4 ; Store in AUDC4 08110 STY BEEPTOGGLE ; Store in BEEPTOGGLE 08111 08112 ;*** Play ZYLON EXPLOSION noise sound pattern ********************************** 08113 SKIP185 LDA NOISEZYLONTIM ; Skip if ZYLON EXPLOSION timer not in use 08114 BEQ SKIP186 ; 08115 08116 DEC NOISEZYLONTIM ; Decrement ZYLON EXPLOSION timer 08117 BNE SKIP186 ; Skip if ZYLON EXPLOSION timer still counting down 08118 08119 LDX #$14 ; Play noise sound pattern ZYLON EXPLOSION 08120 JSR NOISE ; 08121 08122 ;*** Play our starship's Engines sound ***************************************** 08123 SKIP186 LDX VELOCITYLO ; Skip if Engines softer than noise sound pattern 08124 TXA ; 08125 LSR A ; 08126 LSR A ; 08127 LSR A ; 08128 LSR A ; 08129 LSR A ; 08130 CMP NOISELIFE ; 08131 BCC SKIP187 ; 08132 08133 LDA #0 ; Terminate noise sound pattern 08134 STA NOISELIFE ; 08135 08136 INX ; 08137 TXA ; A := %abcdefgh = VELOCITYLO + 1 08138 EOR #$FF ; ________ 08139 STA AUDF3 ; AUDF3 := %abcdefgh 08140 08141 TAX ; ________ 08142 ASL A ; AUDF2/1 := %000abcdefgh00000 08143 ASL A ; 08144 ASL A ; 08145 ASL A ; 08146 ASL A ; 08147 STA AUDF1 ; 08148 TXA ; 08149 LSR A ; 08150 LSR A ; 08151 LSR A ; 08152 STA AUDF2 ; 08153 08154 LSR A ; AUDC2 := %1000abcd 08155 EOR #$8F ; (noise distortion + B7..B4 bits for volume) 08156 STA AUDC2 ; 08157 08158 AND #$87 ; AUDC3 := %10000bcd 08159 STA AUDC3 ; (noise distortion + B6..B4 bits for volume) 08160 08161 LDA #$70 ; Clock audio channel 1 and 3 @ 1.79 MHz and... 08162 STA AUDCTL ; ...combine audio channel 1/2 to 16-bit channel 08163 08164 RTS ; Return 08165 08166 ;*** Play ZYLON EXPLOSION or SHIELD EXPLOSION noise **************************** 08167 SKIP187 LDA NOISEEXPLTIM ; Skip if explosion noise timer not in use 08168 BEQ SKIP188 ; 08169 08170 DEC NOISEEXPLTIM ; Decrement explosion noise timer (4 or 8 TICKs long) 08171 BNE SKIP188 ; Skip if explosion noise timer still counting down 08172 08173 LDA #$8F ; Shadow register AUDC2 := (noise dist. + max volume) 08174 STA NOISEAUDC2 ; 08175 08176 ;*** Play PHOTON TORPEDO LAUNCHED noise sound ********************************** 08177 SKIP188 LDX NOISETORPTIM ; Skip if photon torpedo noise timer not in use 08178 BEQ SKIP190 ; 08179 08180 DEC NOISETORPTIM ; Decrement photon torpedo noise timer (8 TICKs long) 08181 BNE SKIP189 ; Skip if torpedo noise timer still counting down 08182 08183 LDA #$AF ; Shadow register AUDC2 := (tone dist. + max volume) 08184 STA NOISEAUDC2 ; 08185 LDA #$02 ; Set frequency $0202 to AUDF1/2's shadow... 08186 STA NOISEAUDF1 ; ...registers 08187 STA NOISEAUDF2 ; 08188 08189 SKIP189 LDA NOISETORPVOLTAB-1,X ; Pick torpedo noise + volume shape (X in 1..8)... 08190 STA NOISEAUDC3 ; ...and store it in AUDC3's shadow register 08191 LDA NOISETORPFRQTAB-1,X ; Pick photon torpedo noise frequency (X in 1..8)... 08192 STA AUDF3 ; ...and store it in AUDF3 08193 STA STIMER ; Reset POKEY audio timers 08194 08195 ;*** Play STARSHIP EXPLOSION noise when our starship is hit ******************** 08196 SKIP190 LDA NOISEHITLIFE ; Skip if STARSHIP EXPLOSION noise not in use 08197 BEQ SKIP191 ; 08198 08199 DEC NOISEHITLIFE ; Decrement STARSHIP EXPLOSION noise lifetime 08200 LDA RANDOM ; Set random frequency to AUDF3 08201 STA AUDF3 ; 08202 AND #$20 ; Toggle noise/tone dist. of AUDC3's shadow register 08203 EOR NOISEAUDC3 ; ...randomly 08204 STA NOISEAUDC3 ; 08205 08206 ;*** Increase 16-bit frequency of audio channels 1/2 (shadow registers also) *** 08207 SKIP191 CLC ; Increase 16-bit frequency value of AUDF1/2... 08208 LDA NOISEAUDF1 ; ...and its shadow register by... 08209 ADC NOISEFRQINC ; ...noise sound pattern frequency increment 08210 STA NOISEAUDF1 ; AUDF1/2 := NOISEAUDF1/2 := ... 08211 STA AUDF1 ; ...NOISEAUDF1/2 + NOISEFRQINC 08212 LDA NOISEAUDF2 ; 08213 ADC #0 ; 08214 STA NOISEAUDF2 ; 08215 STA AUDF2 ; 08216 08217 ;*** Gradually mute audio channels while noise sound pattern expires *********** 08218 LDX NOISEAUDC2 ; Prep AUDC2's shadow register value 08219 LDY NOISEAUDC3 ; Prep AUDC3's shadow register value 08220 08221 LDA COUNT8 ; Decrement volumes every other TICK 08222 LSR A ; 08223 BCC SKIP193 ; 08224 08225 LDA NOISELIFE ; Skip if noise sound pattern not in use 08226 BEQ SKIP193 ; 08227 08228 DEC NOISELIFE ; Decrement noise sound pattern lifetime 08229 08230 CMP #17 ; Mute noise sound pattern only in... 08231 BCS SKIP193 ; ...the last 16 TICKs of its lifetime 08232 08233 TXA ; Decrement volume of AUDC2's shadow register 08234 AND #$0F ; 08235 BEQ SKIP192 ; 08236 DEX ; 08237 STX NOISEAUDC2 ; 08238 08239 SKIP192 TYA ; Decrement volume of AUDC3's shadow register 08240 AND #$0F ; 08241 BEQ SKIP193 ; 08242 DEY ; 08243 STY NOISEAUDC3 ; 08244 08245 SKIP193 STX AUDC2 ; Store shadow register values to audio registers 08246 STY AUDC3 ; 08247 08248 RTS ; Return 08249 08250 ;******************************************************************************* 08251 ;* * 08252 ;* BEEP * 08253 ;* * 08254 ;* Copy beeper sound pattern * 08255 ;* * 08256 ;******************************************************************************* 08257 08258 ; DESCRIPTION 08259 ; 08260 ; Copies a 6-byte beeper sound pattern from beeper sound pattern table 08261 ; BEEPPATTAB ($BF3E) to BEEPFRQIND ($D2)..BEEPFRQSTART ($D7), provided that no 08262 ; beeper sound pattern with higher priority is currently playing. The beeper 08263 ; sound pattern will then be automatically played in subroutine SOUND ($B2AB). 08264 ; See subroutine SOUND ($B2AB) for more information on beeper sound patterns. 08265 ; 08266 ; NOTE: The bytes from table BEEPPATTAB ($BF3E) are copied in reverse order. 08267 ; 08268 ; INPUT 08269 ; 08270 ; X = Offset to beeper sound pattern in table BEEPPATTAB ($BF3E). Used values 08271 ; are: 08272 ; $00 -> HYPERWARP TRANSIT 08273 ; $06 -> RED ALERT 08274 ; $0C -> ACKNOWLEDGE 08275 ; $12 -> DAMAGE REPORT 08276 ; $18 -> MESSAGE FROM STARBASE 08277 08278 BEEP LDA BEEPPATTAB,X ; Return if beeper sound pattern of... 08279 CMP BEEPPRIORITY ; ...higher priority is playing 08280 BCC SKIP194 ; 08281 08282 LDY #5 ; Copy 6-byte beeper sound pattern (in reverse order) 08283 LOOP059 LDA BEEPPATTAB,X ; 08284 STA BEEPFRQIND,Y ; 08285 INX ; 08286 DEY ; 08287 BPL LOOP059 ; 08288 08289 SKIP194 RTS ; Return 08290 08291 ;******************************************************************************* 08292 ;* * 08293 ;* INITIALIZE * 08294 ;* * 08295 ;* More game initialization * 08296 ;* * 08297 ;******************************************************************************* 08298 08299 ; DESCRIPTION 08300 ; 08301 ; This subroutine executes the following initialization steps: 08302 ; 08303 ; (1) Set up Display List 08304 ; 08305 ; A Display List is created at DSPLST ($0280). It starts with 2 x 8 = 16 08306 ; blank video lines, followed by 90 GRAPHICS7 rows. After a deliberate gap 08307 ; in Display List instructions, which will be filled dynamically during the 08308 ; game by calls to subroutine MODDLST ($ADF1), it ends with a Display List 08309 ; wait-and-jump-back instruction to the start of the Display List at DSPLST 08310 ; ($0280). 08311 ; 08312 ; NOTE: The PLAYFIELD color table PFCOLORTAB ($BFA9) is copied to zero-page 08313 ; table PF0COLOR ($F2) by loop jamming. 08314 ; 08315 ; (2) Create lookup tables 08316 ; 08317 ; The first lookup table MAPTO80 ($0DE9) maps a byte value of 0..255 to 08318 ; 0..80. This table is used to map unsigned (absolute) position vector 08319 ; components (coordinates) to pixel (or PLAYER) row and column numbers. 08320 ; 08321 ; NOTE: The PLAYFIELD is 160 pixels wide. Pixel column numbers relative the 08322 ; horizontal PLAYFIELD center are in -80..79, hence the range of this 08323 ; lookup table. Pixel row numbers relative the vertical PLAYFIELD center 08324 ; are in -50..49, thus they also fit in the range of this lookup table. 08325 ; 08326 ; The second lookup table MAPTOBCD99 ($0EE9) maps a byte value of 0..255 to 08327 ; a BCD-encoded value in 00..99. This table is used to convert byte values 08328 ; into decimal 2-digit values displayed by the THETA (in "gradons"), PHI 08329 ; (in "gradons"), RANGE (in "centrons"), and VELOCITY (in "metrons per 08330 ; second") readouts of the Console Panel Display. 08331 ; 08332 ; The third and fourth lookup tables accelerate drawing of PLAYFIELD space 08333 ; objects: In combination they contain the 16-bit start addresses of each 08334 ; of the 100 rows of PLAYFIELD memory. The low bytes of the 16-bit 08335 ; addresses are stored in table PFMEMROWLO ($0800). The high bytes are 08336 ; stored in table PFMEMROWHI ($0864). 08337 ; 08338 ; NOTE: The address increment is 40 (40 bytes = 160 pixels in GRAPHICS7 08339 ; mode = 1 PLAYFIELD row of pixels). 08340 ; 08341 ; NOTE: The PLAYFIELD consists of 90 GRAPHICS7 rows when the Control Panel 08342 ; Display is displayed at the bottom. When the Control Panel Display is not 08343 ; displayed, for example in demo mode, the PLAYFIELD contains additional 08344 ; GRAPHICS7 rows. 08345 ; 08346 ; (3) Copy Control Panel Display and Galactic Chart Panel Display texts 08347 ; 08348 ; The texts of the Control Panel Display and the Galactic Chart Panel 08349 ; Display are copied to their respective locations in memory by loop 08350 ; jamming. 08351 ; 08352 ; (4) Initialize Zylon unit movement timer 08353 ; 08354 ; The timer that triggers the movement of Zylon units in the Galactic Chart 08355 ; is initialized to a value of 99. See subroutine FLUSHGAMELOOP ($B4E4) for 08356 ; more information on Zylon unit movement. 08357 ; 08358 ; (5) Create Galactic Chart 08359 ; 08360 ; The Galactic Chart memory map GCMEMMAP ($08C9) is initialized. It 08361 ; represents 16 columns x 8 rows of sectors. Each sector contains one of 08362 ; the 4 sector types stored in table SECTORTYPETAB ($BBA6) (starbase, 4 08363 ; Zylon ships, 3 Zylon ships, and 2 or 1 Zylon ships), and empty sectors. 08364 ; Before distributing the sector types, the initial position of our 08365 ; starship is blocked on the Galactic Chart at sector row 4, sector column 08366 ; 8, so that it will not be inadvertently occupied while other sector types 08367 ; are distributed. The number of each of the sector types to be distributed 08368 ; is the mission level plus 2. While Zylon units can be placed anywhere, 08369 ; starbases are placed neither at the borders of the Galactic Chart nor in 08370 ; a sector adjacent to an occupied sector. 08371 ; 08372 ; After having initialized the Galactic Chart memory map, the top border of 08373 ; the Galactic Chart is drawn with characters from the custom character 08374 ; set. 08375 ; 08376 ; Finally, the sector in which our starship is located and the arrival and 08377 ; departure hyperwarp marker column and row numbers are initialized. 08378 ; 08379 ; (6) Apply a final tweak 08380 ; 08381 ; The last entry of lookup table MAPTOBCD99 ($0EE9) is tweaked to a value 08382 ; of CCS.INF * 16 + CCS.SPC. It is used to display an infinity symbol by 08383 ; the RANGE readout of the Control Panel Display in subroutine SHOWCOORD 08384 ; ($B8A7). 08385 ; 08386 ; Code execution continues into subroutine DRAWGC ($B4B9), which draws the 08387 ; content of the Galactic Chart with characters from the custom character set. 08388 08389 L.MEMPTR1 = $68 ; 16-bit memory pointer 08390 L.MEMPTR2 = $6A ; 16-bit memory pointer 08391 L.SECTORTYPE = $6A ; Saves sector type. Used values are: 08392 ; $CF -> Sector contains starbase 08393 ; $04 -> Sector contains 4 Zylon ships 08394 ; $03 -> Sector contains 3 Zylon ships 08395 ; $02 -> Sector contains 2 or 1 Zylon ships 08396 L.SECTORCNT = $6B ; Saves number of sectors of the current sector type 08397 08398 ;*** Initialize Display List and copy color table ****************************** 08399 INITIALIZE LDX #89 ; Set 89(+1) GRAPHICS7 rows from DSPLST+5 on 08400 LOOP060 LDA #$0D ; Prep DL instruction $0D (one row of GRAPHICS7) 08401 STA DSPLST+5,X ; DSPLST+5,X := one row of GRAPHICS7 08402 CPX #10 ; 08403 BCS SKIP195 ; 08404 LDA PFCOLORTAB,X ; Copy PLAYFIELD color table to zero-page table 08405 STA PF0COLOR,X ; (loop jamming) 08406 SKIP195 DEX ; 08407 BPL LOOP060 ; 08408 08409 LDA #$70 ; DSPLST := BLK8 08410 STA DSPLST ; DSPLST+1 := BLK8 08411 STA DSPLST+1 ; 08412 LDA #$41 ; DSPLST+103 := WAITJMP @ DSPLST 08413 STA DSPLST+103 ; 08414 LDA #DSPLST ; 08417 STA DSPLST+105 ; 08418 08419 ;*** Calculate lookup tables *************************************************** 08420 LDX #0 ; Clear both 16-bit memory pointers 08421 STX L.MEMPTR1 ; 08422 STX L.MEMPTR1+1 ; 08423 STX L.MEMPTR2 ; 08424 STX L.MEMPTR2+1 ; 08425 08426 ;*** Calc MAPTO80 map (converts value of $00..$FF to value in 0..80) *********** 08427 LOOP061 CLC ; 08428 LDA L.MEMPTR1 ; 08429 ADC #81 ; 08430 STA L.MEMPTR1 ; 08431 LDA L.MEMPTR1+1 ; 08432 STA MAPTO80,X ; 08433 ADC #0 ; 08434 STA L.MEMPTR1+1 ; 08435 08436 ;*** Calc MAPTOBCD99 map (converts value of $00..$FF to BCD-value in 00..99) *** 08437 CLC ; 08438 LDA L.MEMPTR2 ; 08439 ADC #100 ; 08440 STA L.MEMPTR2 ; 08441 LDA L.MEMPTR2+1 ; 08442 STA MAPTOBCD99,X ; 08443 SED ; 08444 ADC #0 ; 08445 CLD ; 08446 STA L.MEMPTR2+1 ; 08447 INX ; 08448 BNE LOOP061 ; 08449 08450 ;*** Calculate PLAYFIELD memory row addresses, copy Panel Display texts ******** 08451 LDX #PFMEM ; 08454 STA L.MEMPTR1+1 ; 08455 08456 LOOP062 CLC ; 08457 LDA L.MEMPTR1 ; 08458 STA PFMEMROWLO,X ; Store 16-bit value of L.MEMPTR1 in PFMEMROWHI/LO 08459 ADC #40 ; Add 40 to L.MEMPTR 08460 STA L.MEMPTR1 ; (40 bytes = 160 pixels = 1 PLAYFIELD row) 08461 LDA L.MEMPTR1+1 ; 08462 STA PFMEMROWHI,X ; 08463 ADC #0 ; 08464 STA L.MEMPTR1+1 ; 08465 08466 LDA PANELTXTTAB,X ; Copy Control and Galactic Chart Panel Display texts 08467 STA PANELTXT,X ; (loop jamming) 08468 08469 INX ; 08470 CPX #100 ; 08471 BCC LOOP062 ; Loop 100 times 08472 08473 ;*** Set Zylon unit movement timer ********************************************* 08474 DEX ; 08475 STX ZYLONUNITTIM ; Init Zylon unit movement timer to 99 game loops 08476 08477 ;*** Create memory map of the Galactic Chart *********************************** 08478 LDX #3 ; Loop over all 3(+1) sector types 08479 STX GCMEMMAP+4*16+8 ; Block our starship's initial position at center of 08480 ; ...Galactic Chart (sector row 4, sector column 8) 08481 08482 LOOP063 LDA SECTORTYPETAB,X ; Prep sector type 08483 STA L.SECTORTYPE ; 08484 08485 LDY MISSIONLEVEL ; Number sectors of current type := mission level + 2 08486 INY ; 08487 INY ; 08488 STY L.SECTORCNT ; 08489 08490 LOOP064 LDA RANDOM ; Load random sector 0..127 from GC memory map 08491 AND #$7F ; 08492 TAY ; 08493 LDA GCMEMMAP,Y ; 08494 BNE LOOP064 ; If sector already occupied, pick another 08495 08496 LDA L.SECTORTYPE ; Reload sector type 08497 BPL SKIP196 ; Skip if sector not to be occupied by starbase 08498 08499 CPY #$10 ; Place starbase... 08500 BCC LOOP064 ; ...not in first sector row of Galactic Chart 08501 CPY #$70 ; 08502 BCS LOOP064 ; ...not in last sector row of Galactic Chart 08503 TYA ; 08504 AND #$0F ; 08505 BEQ LOOP064 ; ...not in first sector column of Galactic Chart 08506 CMP #15 ; 08507 BEQ LOOP064 ; ...not in last sector column of Galactic Chart 08508 LDA GCMEMMAP-1,Y ; ...not east of an occupied sector 08509 ORA GCMEMMAP+1,Y ; ...not west of an occupied sector 08510 ORA GCMEMMAP+16,Y ; ...not south of an occupied sector 08511 ORA GCMEMMAP-16,Y ; ...not north of an occupied sector 08512 BNE LOOP064 ; 08513 08514 LDA L.SECTORTYPE ; Reload sector type 08515 08516 SKIP196 STA GCMEMMAP,Y ; Store sector type in Galactic Chart memory map 08517 DEC L.SECTORCNT ; 08518 BPL LOOP064 ; Next sector 08519 DEX ; 08520 BPL LOOP063 ; Next sector type 08521 08522 ;*** Clear Galactic Chart and draw top border ********************************** 08523 LDX #180 ; Clear Galactic Chart PLAYFIELD 08524 LOOP065 LDA #CCS.SPC ; 08525 STA GCPFMEM-1,X ; 08526 DEX ; 08527 BNE LOOP065 ; 08528 08529 LDX #15 ; Draw top border (15(+1) characters) 08530 LOOP066 LDA #CCS.BORDERS ; 08531 STA GCPFMEM+2,X ; 08532 DEX ; 08533 BPL LOOP066 ; 08534 08535 LDA #CCS.CORNERSW ; Draw NORTHEAST corner (1 character) 08536 STA GCPFMEM+18 ; 08537 08538 LDA #0 ; Release starship's position at center of Galactic 08539 STA GCMEMMAP+4*16+8 ; ...Chart (sector row 4, sector column 8) 08540 08541 ;*** Initialize current sector and hyperwarp marker column and row numbers ***** 08542 LDA #$48 ; Place our starship's current sector at 08543 STA CURRSECTOR ; ...sector row 4, sector column 8 08544 LDA #$43 ; Init departure & arrival hyperwarp marker column 08545 STA WARPDEPRCOLUMN ; 08546 STA WARPARRVCOLUMN ; 08547 LDA #$47 ; Init departure & arrival hyperwarp marker row 08548 STA WARPARRVROW ; 08549 STA WARPDEPRROW ; 08550 08551 ;*** Tweak last entry of MAPTOBCD99 ******************************************** 08552 LDA #CCS.INF*16+CCS.SPC ; Last entry of MAPTOBCD99: 'INFINITY'+'SPACE' char 08553 STA MAPTOBCD99+255 ; 08554 08555 ;******************************************************************************* 08556 ;* * 08557 ;* DRAWGC * 08558 ;* * 08559 ;* Draw Galactic Chart * 08560 ;* * 08561 ;******************************************************************************* 08562 08563 ; DESCRIPTION 08564 ; 08565 ; Draws the content of the Galactic Chart memory map in GCMEMMAP ($08C9) to the 08566 ; Galactic Chart PLAYFIELD memory at GCPFMEM ($0D35). 08567 ; 08568 ; NOTE: CPU register X indexes the Galactic Chart memory map GCMEMMAP ($08C9) 08569 ; (16 x 8 bytes). CPU register Y indexes the Galactic Chart PLAYFIELD memory 08570 ; GCPFMEM ($0D35) (20 x 9 bytes). 08571 ; 08572 ; NOTE: Sectors with 1 or 2 Zylon ships display the same symbol in the Galactic 08573 ; Chart. 08574 08575 L.GCMEMMAPIND = $6A ; Saves Galactic Chart memory map index 08576 08577 DRAWGC LDY #0 ; Clear Galactic Chart PLAYFIELD memory index 08578 STY L.GCMEMMAPIND ; Clear Galactic Chart memory map index 08579 08580 LOOP067 LDX L.GCMEMMAPIND ; Load sector of Galactic Chart memory map 08581 LDA GCMEMMAP,X ; 08582 BPL SKIP197 ; Skip if not a starbase sector 08583 LDA #5 ; Prep sector character index for starbase 08584 08585 SKIP197 TAX ; Load sector character index 08586 LDA SECTORCHARTAB,X ; Load custom character set code from table... 08587 STA GCPFMEM+22,Y ; ...and store it in Galactic Chart PLAYFIELD memory 08588 INY ; Increment Galactic Chart PLAYFIELD memory index 08589 INC L.GCMEMMAPIND ; Increment Galactic Chart memory map index 08590 LDA L.GCMEMMAPIND ; 08591 AND #$0F ; 08592 BNE LOOP067 ; Next sector column until right border reached 08593 08594 LDA #CCS.BORDERW ; Draw right border 08595 STA GCPFMEM+22,Y ; 08596 08597 INY ; Adjust Galactic Chart PLAYFIELD memory index 08598 INY ; 08599 INY ; 08600 INY ; 08601 CPY #$A0 ; 08602 BCC LOOP067 ; Next sector until bottom-right sector reached 08603 08604 RTS ; Return 08605 08606 ;******************************************************************************* 08607 ;* * 08608 ;* FLUSHGAMELOOP * 08609 ;* * 08610 ;* Handle remaining tasks at the end of a game loop iteration * 08611 ;* * 08612 ;******************************************************************************* 08613 08614 ; DESCRIPTION 08615 ; 08616 ; This subroutine handles at the end of a game loop iteration the following 08617 ; tasks: 08618 ; 08619 ; (1) Increment counters COUNT256 ($76) and COUNT8 ($72). 08620 ; 08621 ; (2) If our starship's energy has dropped below 1000 units then flash a {PINK} 08622 ; alert that changes to {DARK GREY BLUE} and back to {PINK} every 128 game 08623 ; loop iterations. 08624 ; 08625 ; (3) Set the Shields color and the Control Panel background color every 8 game 08626 ; loop iterations: 08627 ; 08628 ; o If the Shields are up and OK then set the Shields color to {DARK 08629 ; GREEN} and the Control Panel background color to {DARK BLUE}. 08630 ; 08631 ; o If the Shields are up and damaged there is a probability of 78% 08632 ; (200:256) that the Shield color is not changed. 08633 ; 08634 ; o If the Shields are down, damaged, or destroyed then set the Shields 08635 ; color to {BLACK}. 08636 ; 08637 ; o If the Shields are destroyed then set the Control Panel background 08638 ; color to {ORANGE}. 08639 ; 08640 ; (4) Decrement the lifetime of our starship's and Zylon photon torpedoes. 08641 ; 08642 ; (5) Decrement the lifetime of an explosion. If the explosion lifetime is less 08643 ; than 112 game loop iterations, clear HITBADNESS ($8A) (thus the explosion 08644 ; cannot destroy our starship). If the explosion lifetime is less than 24 08645 ; (?) game loops decrement the number of explosion fragments. This makes 08646 ; explosion fragments disappear gradually toward the end of an explosion. 08647 ; 08648 ; (6) Increment every 40 game loop iterations the stardate clock of the 08649 ; Galactic Chart Panel Display. 08650 ; 08651 ; (7) Move Zylon units in the Galactic Chart. 08652 ; 08653 ; Every 50 game loop iterations (or 100 game loop iterations when a 08654 ; starbase is surrounded by Zylon units) decrement the score. 08655 ; 08656 ; Code execution continues if the program is not in demo mode with the following 08657 ; steps: 08658 ; 08659 ; (1) Search the Galactic Chart for starbases surrounded by Zylon units. 08660 ; Destroy any such starbase: Replace it with a 2-Zylon sector and subtract 08661 ; 18 points from the score. If the Subspace Radio was not destroyed, then 08662 ; flash the title phrase "STARBASE DESTROYED" and play the beeper sound 08663 ; pattern MESSAGE FROM STARBASE in subroutine BEEP ($B3A6). 08664 ; 08665 ; (2) Every 8 game loop iterations the Zylon units decide, which starbase to 08666 ; hunt: First, 128 randomly picked sectors are searched for a starbase. If 08667 ; no starbase was found in this way, the sectors of the Galactic Chart are 08668 ; scanned systematically left-to-right, top-to-bottom. If a starbase was 08669 ; found then its sector, sector column, and sector row are saved, otherwise 08670 ; code execution returns. 08671 ; 08672 ; (3) Now the Zylon units converge toward the sector of the hunted starbase: 08673 ; All sectors of the Galactic Chart are scanned. For any sector with a 08674 ; Zylon unit that was not moved yet (its sector does not have the temporary 08675 ; "already-moved" bit B5 set) its movement probability value is picked from 08676 ; table MOVEPROBTAB ($BFBB): 08677 ; 08678 ; +---------------+-------------+----------------+ 08679 ; | Sector Type | Movement | Movement | 08680 ; | | Probability | Probability | 08681 ; | | Value | | 08682 ; +---------------+-------------+----------------+ 08683 ; | Empty sector | 0 | 0% ( 0:256) | 08684 ; | 1 Zylon ship | 255 | 100% (255:256) | 08685 ; | 2 Zylon ships | 255 | 100% (255:256) | 08686 ; | 3 Zylon ships | 192 | 75% (192:256) | 08687 ; | 4 Zylon ships | 32 | 13% ( 32:256) | 08688 ; +---------------+-------------+----------------+ 08689 ; 08690 ; If this value is less or equal than a random number in 0..255 then the 08691 ; Zylon unit is moved to another sector. A Zylon unit that currently 08692 ; occupies the sector of our starship is not moved. 08693 ; 08694 ; BUG (at $B620): The instruction to check the marker bit B5 of the sector 08695 ; is CPY #$0A. This works, as sectors containing Zylon units that need to 08696 ; be moved have values of 2..4, see table SECTORTYPETAB ($BBA6). Suggested 08697 ; fix: Replace CPY #$0A with CPY #$20, which may make the code clearer. 08698 ; 08699 ; (4) For every Zylon unit that is about to be moved, 9 distances ("block 08700 ; distances") between the Zylon unit and the starbase are calculated by 08701 ; tentatively moving the Zylon unit into each of its 8 adjacent sectors - 08702 ; and by moving it not at all. The sector offsets are taken from table 08703 ; COMPASSOFFTAB ($BFC0) which stores direction offsets in the following 08704 ; order: NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST, EAST, 08705 ; NORTHEAST, CENTER. All 9 distances are stored in 9 consecutive bytes at 08706 ; NEWZYLONDIST ($96). 08707 ; 08708 ; NOTE: The last calculated distance is the current distance between Zylon 08709 ; unit and starbase. 08710 ; 08711 ; The Zylon unit moves to the first of the 8 adjacent sectors that matches 08712 ; the following conditions: 08713 ; 08714 ; (1) It is closer to the starbase than the Zylon unit's current sector. 08715 ; 08716 ; (2) It is located inside the Galactic Chart. 08717 ; 08718 ; (3) It is empty. 08719 ; 08720 ; (4) It is not the sector containing our starship. 08721 ; 08722 ; If a suitable new sector was found then the Zylon unit is moved to this 08723 ; sector, which is marked with the "already-moved" marker bit B5 in the 08724 ; Galactic Chart memory map. This marker bit prevents a Zylon unit that has 08725 ; been already moved from being moved again. The old Zylon unit sector is 08726 ; cleared. 08727 ; 08728 ; If no suitable new sector was found then the above distance calculations 08729 ; are repeated once again by adding 1 to the current distance between the 08730 ; Zylon unit and the starbase. This may provoke a Zylon unit to move that 08731 ; would not have moved in the previous set of distance calculations. 08732 ; 08733 ; After having moved all Zylon units the sectors are stripped of the 08734 ; "already-moved" marker bit B5. 08735 ; 08736 ; (5) If a starbase has been surrounded then the Zylon unit movement timer is 08737 ; reset to 99, buying our starship some time to destroy one of the 08738 ; surrounding Zylon units. If the Subspace Radio is not destroyed, then the 08739 ; message "STARBASE SURROUNDED" is flashed in the title line and the beeper 08740 ; sound pattern MESSAGE FROM STARBASE is played in subroutine BEEP ($B3A6). 08741 08742 L.ISDESTROYED = $6A ; Flags the destruction of a starbase. 08743 ; Used values are: 08744 ; $00 -> Starbase not destroyed 08745 ; $02 -> Starbase has been destroyed 08746 L.NEWSECTOR = $6A ; Sector to which the Zylon unit is tentatively moved 08747 L.ABSDIFFCOL = $6B ; Absolute difference between new Zylon and starbase 08748 ; column on Galactic Chart in PM pixels 08749 L.LOOPCNT2 = $6B ; Loop counter. Used values are: 0..1. 08750 L.DIRECTIONIND = $6A ; Compass rose direction index. 08751 ; Used values are: 0..7. 08752 08753 ;*** Increment counters and flash low-energy alert ***************************** 08754 FLUSHGAMELOOP INC COUNT256 ; Increment COUNT256 counter 08755 08756 LDX #$90 ; Prep DLI background color {DARK GREY BLUE} 08757 LDA COUNT256 ; 08758 BPL SKIP198 ; Skip if counter < 128. 08759 08760 LDY ENERGYD1 ; When energy drops below 1000 units... 08761 CPY #CCS.COL2!CCS.0 ; 08762 BNE SKIP198 ; 08763 LDX #$44 ; ...prep new DLI background color {PINK} 08764 08765 SKIP198 AND #$03 ; Increment COUNT8 08766 STA COUNT8 ; 08767 BNE SKIP202 ; Skip setting colors but every 8 game loops 08768 08769 ;*** Set Shields and Control Panel background color **************************** 08770 LDY DRAINSHIELDS ; Skip if Shields are off 08771 BEQ SKIP201 ; 08772 08773 LDY #$A0 ; Prep Shields color {DARK GREEN} 08774 BIT GCSTATSHL ; Skip if Shields are OK 08775 BPL SKIP200 ; 08776 BVS SKIP199 ; Skip if Shields are destroyed 08777 LDA RANDOM ; If Shields are damaged, Shields colors are... 08778 CMP #200 ; ...unchanged with probability of 78% (200:256) 08779 BCC SKIP201 ; 08780 08781 SKIP199 LDY #$00 ; Prep Shields color {BLACK} 08782 SKIP200 TYA ; 08783 BNE SKIP201 ; 08784 08785 LDX #$26 ; Prep Control Panel background color {ORANGE} 08786 08787 SKIP201 STY SHIELDSCOLOR ; Store Shields color 08788 STX BGRCOLORDLI ; Store Control Panel background color 08789 08790 ;*** Decrement lifetime of our starship's and Zylon photon torpedoes *********** 08791 SKIP202 LDX #2 ; Loop over PLAYER2..4 08792 08793 LOOP068 LDA PL2SHAPTYPE,X ; Next PLAYER if not PHOTON TORPEDO (shape type 0) 08794 BNE SKIP203 ; 08795 08796 LDA PL2LIFE,X ; Next PLAYER if this PLAYER not alive 08797 BEQ SKIP203 ; 08798 08799 DEC PL2LIFE,X ; Decrement photon torpedo PLAYER lifetime 08800 08801 SKIP203 DEX ; 08802 BPL LOOP068 ; Next PLAYER 08803 08804 ;*** Decrement lifetime of explosion ******************************************* 08805 LDA EXPLLIFE ; Skip if explosion lifetime expired 08806 BEQ SKIP206 ; 08807 08808 DEC EXPLLIFE ; Decrement explosion lifetime 08809 BNE SKIP204 ; Skip if explosion lifetime still counting 08810 08811 LDX #NUMSPCOBJ.NORM ; Explosion finished,... 08812 STX MAXSPCOBJIND ; ...restore normal number of space objects 08813 08814 SKIP204 CMP #112 ; Skip if explosion lifetime >= 112 game loops 08815 BCS SKIP205 ; 08816 08817 LDX #0 ; HITBADNESS := NO HIT 08818 STX HITBADNESS ; 08819 08820 SKIP205 CMP #24 ; Skip if explosion lifetime >= 24 game loops (?) 08821 BCS SKIP206 ; 08822 08823 DEC MAXSPCOBJIND ; Decrement number of explosion fragment space objs 08824 08825 ;*** Increment stardate clock ************************************************** 08826 SKIP206 DEC CLOCKTIM ; Decrement stardate clock timer 08827 BPL SKIP209 ; Return if timer is still counting 08828 08829 LDA #40 ; Reset stardate clock timer to 40 game loops 08830 STA CLOCKTIM ; 08831 08832 LDX #4 ; Increment stardate clock of Galactic Chart Panel 08833 LOOP069 INC GCSTARDAT,X ; 08834 LDA GCSTARDAT,X ; 08835 CMP #[CCS.COL3!ROM.9]+1 ; 08836 BCC SKIP208 ; 08837 LDA #[CCS.COL3!ROM.0] ; 08838 STA GCSTARDAT,X ; 08839 CPX #3 ; 08840 BNE SKIP207 ; 08841 DEX ; 08842 SKIP207 DEX ; 08843 BPL LOOP069 ; 08844 08845 ;*** Decrement Zylon unit movement timer *************************************** 08846 SKIP208 DEC ZYLONUNITTIM ; Decrement Zylon unit movement timer 08847 BMI SKIP210 ; If timer < 0 move Zylon units 08848 08849 SKIP209 RTS ; Return 08850 08851 ;*** Restore Zylon unit movement timer and decrement score ********************* 08852 SKIP210 LDA #49 ; Reset Zylon unit movement timer to 49 08853 STA ZYLONUNITTIM ; 08854 08855 LDA SCORE ; SCORE := SCORE - 1 08856 BNE SKIP211 ; 08857 DEC SCORE+1 ; 08858 SKIP211 DEC SCORE ; 08859 08860 LDX ISDEMOMODE ; Return if in demo mode 08861 BNE SKIP209 ; 08862 08863 ;*** Is starbase surrounded? *************************************************** 08864 STX L.ISDESTROYED ; Init L.ISDESTROYED with 0 (starbase not destroyed) 08865 LOOP070 LDA GCMEMMAP,X ; Loop over all sectors, load sector type 08866 BPL SKIP212 ; Skip if not a starbase sector 08867 08868 JSR ISSURROUNDED ; Skip if starbase sector not completely surrounded 08869 BEQ SKIP212 ; 08870 08871 ;*** Starbase is surrounded, destroy starbase ********************************** 08872 LDA #2 ; Replace starbase sector with 2-Zylon sector 08873 STA GCMEMMAP,X ; 08874 STA L.ISDESTROYED ; Flag destruction of starbase 08875 08876 SEC ; SCORE := SCORE - 18 08877 LDA SCORE ; 08878 SBC #18 ; 08879 STA SCORE ; 08880 LDA SCORE+1 ; 08881 SBC #0 ; 08882 STA SCORE+1 ; 08883 08884 SKIP212 INX ; 08885 BPL LOOP070 ; Next sector 08886 08887 ;*** Report starbase destruction *********************************************** 08888 LDA L.ISDESTROYED ; Skip if no starbase has been destroyed 08889 BEQ SKIP213 ; 08890 08891 BIT GCSTATRAD ; Skip notification if Subspace Radio destroyed 08892 BVS SKIP213 ; 08893 08894 LDY #$15 ; Set title phrase "STARBASE DESTROYED" 08895 JSR SETTITLE ; 08896 08897 LDX #$18 ; Play beeper sound pattern MESSAGE FROM STARBASE 08898 JSR BEEP ; 08899 08900 ;*** Pick new starbase to be hunted by Zylon units ***************************** 08901 SKIP213 DEC HUNTTIM ; Decrement hunting timer 08902 BMI SKIP214 ; If timer < 0 decide which starbase to hunt 08903 08904 LDX HUNTSECTOR ; Skip if Zylon units already picked starbase to hunt 08905 LDA GCMEMMAP,X ; 08906 BMI SKIP215 ; 08907 08908 SKIP214 LDA #7 ; Reset hunting timer 08909 STA HUNTTIM ; 08910 08911 LDY #127 ; Loop over 127(+1) randomly picked sectors 08912 LOOP071 LDA RANDOM ; 08913 AND #$7F ; 08914 TAX ; 08915 LDA GCMEMMAP,X ; Skip if starbase sector found 08916 BMI SKIP215 ; 08917 DEY ; 08918 BPL LOOP071 ; Next sector 08919 08920 LDX #127 ; Loop over all sectors of the Galactic Chart 08921 LOOP072 LDA GCMEMMAP,X ; 08922 BMI SKIP215 ; Skip if starbase sector found 08923 DEX ; 08924 BPL LOOP072 ; Next sector 08925 08926 RTS ; Return (no starbase sector found) 08927 08928 ;*** Store coordinates of starbase to be hunted ******************************** 08929 SKIP215 STX HUNTSECTOR ; Store hunted starbase sector column and row 08930 TXA ; 08931 AND #$0F ; 08932 STA HUNTSECTCOLUMN ; 08933 TXA ; 08934 LSR A ; 08935 LSR A ; 08936 LSR A ; 08937 LSR A ; 08938 STA HUNTSECTROW ; 08939 08940 ;*** Move all Zylon units toward hunted starbase ******************************* 08941 LDX #$FF ; 08942 LOOP073 INX ; Loop over all sectors to move Zylon units 08943 BPL SKIP218 ; Jump into loop body below 08944 08945 ;*** Strip marker bits from moved Zylon units ********************************** 08946 LDX #0 ; 08947 LOOP074 LDA GCMEMMAP,X ; Loop over all sectors 08948 AND #$DF ; 08949 STA GCMEMMAP,X ; Strip marker bit B5 from moved Zylon units 08950 INX ; 08951 BPL LOOP074 ; Next sector 08952 08953 ;*** Handle surrounded starbase ************************************************ 08954 BIT GCSTATRAD ; Return if Subspace Radio is destroyed 08955 BVS SKIP217 ; 08956 08957 LDX #0 ; Loop over all sectors 08958 LOOP075 LDA GCMEMMAP,X ; 08959 BPL SKIP216 ; Skip if not a starbase sector 08960 JSR ISSURROUNDED ; Skip if starbase not surrounded 08961 BEQ SKIP216 ; 08962 08963 LDA #99 ; Yes, starbase surrounded... 08964 STA ZYLONUNITTIM ; ...set Zylon unit movement timer to 99 08965 08966 LDY #$13 ; Set title phrase "STARBASE SURROUNDED" 08967 JSR SETTITLE ; 08968 08969 LDX #$18 ; Play beeper sound pattern MESSAGE FROM STARBASE... 08970 JMP BEEP ; ...and return 08971 08972 SKIP216 INX ; 08973 BPL LOOP075 ; Next sector 08974 08975 SKIP217 RTS ; Return 08976 08977 ;*** Move single Zylon unit **************************************************** 08978 SKIP218 LDY GCMEMMAP,X ; X contains current sector 08979 CPY #$0A ; Next sector if it has marker bit B5 set (!) 08980 BCS LOOP073 ; 08981 08982 LDA RANDOM ; Get random number 08983 CMP MOVEPROBTAB,Y ; Get movement probability 08984 BCS LOOP073 ; Next sector if movement probability < random number 08985 08986 CPX CURRSECTOR ; Next sector if this is our starship's sector 08987 BEQ LOOP073 ; 08988 08989 ;*** Compute distance to starbase by moving Zylon unit into 9 directions ******* 08990 LDY #8 ; Loop over 8(+1) possible directions 08991 LOOP076 CLC ; 08992 TXA ; 08993 ADC COMPASSOFFTAB,Y ; Add direction offset to current sector 08994 STA L.NEWSECTOR ; Store new sector 08995 08996 AND #$0F ; Calc distance ("block distance") between... 08997 SEC ; ...starbase sector and tentative new Zylon sector 08998 SBC HUNTSECTCOLUMN ; 08999 BCS SKIP219 ; 09000 EOR #$FF ; 09001 ADC #1 ; 09002 SKIP219 STA L.ABSDIFFCOL ; 09003 LDA L.NEWSECTOR ; 09004 LSR A ; 09005 LSR A ; 09006 LSR A ; 09007 LSR A ; 09008 SEC ; 09009 SBC HUNTSECTROW ; 09010 BCS SKIP220 ; 09011 EOR #$FF ; 09012 ADC #1 ; 09013 SKIP220 CLC ; 09014 ADC L.ABSDIFFCOL ; 09015 09016 STA NEWZYLONDIST,Y ; Store distance in distance array 09017 DEY ; 09018 BPL LOOP076 ; Next direction 09019 09020 ;*** Pick the shortest distance to starbase ************************************ 09021 LDA #1 ; Loop over compass rose directions twice to... 09022 STA L.LOOPCNT2 ; ...provoke movement regardless of truncation errors 09023 09024 LOOP077 LDY #7 ; 09025 LOOP078 LDA NEWZYLONDIST,Y ; Loop over all 7(+1) compass rose directions 09026 CMP OLDZYLONDIST ; 09027 BCS SKIP222 ; Next direction if new distance > current distance 09028 09029 CLC ; Calc new Galactic Chart sector for Zylon unit 09030 TXA ; 09031 ADC COMPASSOFFTAB,Y ; 09032 BMI SKIP222 ; Next direction if new sector outside Galactic Chart 09033 09034 STY L.DIRECTIONIND ; Save compass rose direction index 09035 TAY ; 09036 LDA GCMEMMAP,Y ; 09037 BNE SKIP221 ; Next direction if new sector not empty 09038 09039 LDA GCMEMMAP,X ; Preload Zylon sector type to be moved 09040 CPY CURRSECTOR ; 09041 BEQ SKIP221 ; Next direction if sector is our starship's sector 09042 09043 ORA #$20 ; New sector for Zylon unit found! 09044 STA GCMEMMAP,Y ; Temporarily mark that sector with marker bit B5 09045 LDA #0 ; 09046 STA GCMEMMAP,X ; Clear old Zylon unit sector 09047 BEQ SKIP223 ; Next sector (unconditional branch) 09048 09049 SKIP221 LDY L.DIRECTIONIND ; Restore compass rose direction index 09050 SKIP222 DEY ; Next compass rose direction 09051 BPL LOOP078 ; 09052 09053 INC OLDZYLONDIST ; Increment center distance 09054 DEC L.LOOPCNT2 ; 09055 BPL LOOP077 ; Loop over all compass rose directions one more time 09056 09057 SKIP223 JMP LOOP073 ; Next sector 09058 09059 ; ******************************************************************************* 09060 ; * * 09061 ; * ROTATE * 09062 ; * * 09063 ; * Rotate position vector component (coordinate) by fixed angle * 09064 ; * * 09065 ; ******************************************************************************* 09066 09067 ; DESCRIPTION 09068 ; 09069 ; This subroutine rotates a position vector component (coordinate) of a space 09070 ; object by a fixed angle around the center of the 3D coordinate system, the 09071 ; location of our starship. This is used in the Front, Aft, and Long-Range Scan 09072 ; views to rotate space objects in and out of the view. Although the code is 09073 ; deceptively short, there is some interesting math involved, so a more detailed 09074 ; discussion is in order. 09075 ; 09076 ; ROTATION MATHEMATICS 09077 ; 09078 ; The program uses a left-handed 3D coordinate system with the positive x-axis 09079 ; pointing to the right, the positive y-axis pointing up, and the positive 09080 ; z-axis pointing into flight direction. 09081 ; 09082 ; A rotation in this coordinate system around the y-axis (horizontal rotation) 09083 ; can be expressed as 09084 ; 09085 ; x' := cos(ry) * x + sin(ry) * z (1a) 09086 ; z' := - sin(ry) * x + cos(ry) * z (1b) 09087 ; 09088 ; where ry is the clockwise rotation angle around the y-axis, x and z are the 09089 ; coordinates before this rotation, and the primed coordinates x' and z' the 09090 ; coordinates after this rotation. The y-coordinate is not changed by this 09091 ; rotation. 09092 ; 09093 ; A rotation in this coordinate system around the x-axis (vertical rotation) can 09094 ; be expressed as 09095 ; 09096 ; z' := cos(rx) * z + sin(rx) * y (2a) 09097 ; y' := - sin(rx) * z + cos(rx) * y (2b) 09098 ; 09099 ; where rx is the clockwise rotation angle around the x-axis, z and y are the 09100 ; coordinates before this rotation, and the primed coordinates z' and y' the 09101 ; coordinates after this rotation. The x-coordinate is not changed by this 09102 ; rotation. 09103 ; 09104 ; SUBROUTINE IMPLEMENTATION OVERVIEW 09105 ; 09106 ; A single call of this subroutine is able to compute one of the four 09107 ; expressions (1a)-(2b). To compute all four expressions to get the new set of 09108 ; coordinates, this subroutine has to be called four times. This is done twice 09109 ; in pairs in GAMELOOP ($A1F3) at $A391 and $A398, and at $A3AE and $A3B5, 09110 ; respectively. 09111 ; 09112 ; The first pair of calls calculates the new x and z coordinates of a space 09113 ; object due to a horizontal (left/right) rotation of our starship around the 09114 ; y-axis following expressions (1a) and (1b). 09115 ; 09116 ; The second pair of calls calculates the new y and z coordinates of the same 09117 ; space object due to a vertical (up/down) rotation of our starship around the 09118 ; x-axis following expressions (2a) and (2b). 09119 ; 09120 ; If you look at the code, you may be wondering how this calculation is actually 09121 ; executed, as there is neither a sin() nor a cos() function call. What you'll 09122 ; actually find implemented are the following calculations: 09123 ; 09124 ; Joystick left Joystick right 09125 ; --------------------- --------------------- 09126 ; x := x + z / 64 (3a) x := x - z / 64 (4a) 09127 ; z := -x / 64 + z (3b) z := x / 64 + z (4b) 09128 ; 09129 ; Joystick down Joystick up 09130 ; --------------------- --------------------- 09131 ; y := y + z / 64 (5a) y := y - z / 64 (6a) 09132 ; z := -y / 64 + z (5b) z := y / 64 + z (6b) 09133 ; 09134 ; CORDIC ALGORITHM 09135 ; 09136 ; When you compare expressions (1a)-(2b) with (3a)-(6b), notice the similarity 09137 ; between the expressions if you substitute 09138 ; 09139 ; sin(ry) -> 1 / 64, 09140 ; cos(ry) -> 1, 09141 ; sin(rx) -> 1 / 64, and 09142 ; cos(rx) -> 1. 09143 ; 09144 ; From sin(ry) = 1 / 64 and sin(rx) = 1 / 64 you can derive that the rotation 09145 ; angles ry and rx by which the space object is rotated per game loop iteration 09146 ; have a constant value of 0.89 degrees, as arcsine(1 / 64) = 0.89 degrees. 09147 ; 09148 ; What about cos(ry) and cos(rx)? The substitution does not match our derived 09149 ; angle exactly, because cos(0.89 degrees) = 0.99988 and is not exactly 1. 09150 ; However, this value is so close to 1 that substituting cos(0.89 degrees) with 09151 ; 1 is a very good approximation, simplifying calculations significantly. 09152 ; 09153 ; Another significant simplification results from the division by 64, because 09154 ; the actual division operation can be replaced with a much faster bit shift 09155 ; operation. 09156 ; 09157 ; This calculation-friendly way of computing rotations is known as the "CORDIC 09158 ; (COordinate Rotation DIgital Computer)" algorithm. 09159 ; 09160 ; MINSKY ROTATION 09161 ; 09162 ; There is one more interesting mathematical subtlety: Did you notice that 09163 ; expressions (1a)-(2b) use a new (primed) pair of variables to store the 09164 ; resulting coordinates, whereas in the implemented expressions (3a)-(6b) the 09165 ; value of the first coordinate of a coordinate pair is overwritten with its new 09166 ; value and this value is used in the subsequent calculation of the second 09167 ; coordinate? For example, when the joystick is pushed left, the first call of 09168 ; this subroutine calculates the new value of x according to expression (3a), 09169 ; overwriting the old value of x. During the second call to calculate z 09170 ; according to expression (3b), the new value of x is used instead of the old 09171 ; one. Is this to save the memory needed to temporarily store the old value of 09172 ; x? But isn't this a bug? If so, why does the rotation calculation actually 09173 ; work? 09174 ; 09175 ; Have a look at the expression pair (3a) and (3b) (the other expression pairs 09176 ; (4a)-(6b) work in a similar fashion): 09177 ; 09178 ; x := x + z / 64 09179 ; z := -x / 64 + z 09180 ; 09181 ; With the substitution 1 / 64 -> e, we get 09182 ; 09183 ; x := x + e * z 09184 ; z := -e * x + z 09185 ; 09186 ; Note that x is calculated first and then used in the second expression. When 09187 ; using primed coordinates for the resulting coordinates after calculating the 09188 ; two expressions we get 09189 ; 09190 ; x' := x + e * z 09191 ; z' := -e * x' + z = -e * (x + e * z) + z = -e * x + (1 - e^2) * z 09192 ; 09193 ; or in matrix form 09194 ; 09195 ; |x'| := | 1 e | * |x| 09196 ; |z'| |-e (1 - e^2)| |z| 09197 ; 09198 ; Surprisingly, this turns out to be a rotation matrix, because its determinant 09199 ; is (1 * (1 - e^2) - (e * -e)) = 1. 09200 ; 09201 ; (Incidentally, the column vectors of this matrix do not form a orthogonal 09202 ; basis, as their scalar product is 1 * e + (-e * (1 - e^2)) = -e^2. 09203 ; Orthogonality holds for e = 0 only. 09204 ; 09205 ; This kind of rotation calculation is described by Marvin Minsky in ["AIM 239 09206 ; HAKMEM", Item 149, p. 73, MIT AI Lab, February 1972] and is called "Minsky 09207 ; Rotation". 09208 ; 09209 ; SUBROUTINE IMPLEMENTATION DETAILS 09210 ; 09211 ; To better understand how the implementation of this subroutine works, have 09212 ; again a look at expressions (3a)-(6b). If you rearrange the expressions a 09213 ; little their structure is always of the form 09214 ; 09215 ; TERM1 := TERM1 SIGN TERM2 / 64 09216 ; 09217 ; or shorter 09218 ; 09219 ; TERM1 := TERM1 SIGN TERM3 09220 ; 09221 ; where 09222 ; 09223 ; TERM3 := TERM2 / 64 09224 ; SIGN := + or - 09225 ; 09226 ; and where TERM1 and TERM2 are position vector components (coordinates). In 09227 ; fact, this is all this subroutine actually does: It simply adds (or subtracts) 09228 ; TERM2 divided by 64 to (from) TERM1. 09229 ; 09230 ; When calling this subroutine the correct indices for the appropriate position 09231 ; vector components (coordinates) TERM1 and TERM2 are passed in the Y and X 09232 ; registers, respectively. 09233 ; 09234 ; What about SIGN between TERM1 and TERM3? Have again a look at expressions 09235 ; (3a)-(6b). To compute the two new coordinates after a rotation, the SIGN 09236 ; toggles from plus to minus and vice versa. The SIGN is initialized by 09237 ; JOYSTICKDELTA ($6D) before actually calling subroutine ROTATE ($B69B) and is 09238 ; toggled in every subsequent call of this subroutine. The initial value of SIGN 09239 ; should be positive (+) if the rotation is clockwise (the joystick is pushed 09240 ; right or up) and negative if the rotation is counter-clockwise (the joystick 09241 ; is pushed left or down), respectively. Because SIGN is always toggled you have 09242 ; to pass the already toggled value with the first call. 09243 ; 09244 ; NOTE: Unclear still are three instructions starting at address $B6AD. They 09245 ; seem to set the two least significant bits of TERM3 in a random fashion. Could 09246 ; this be some quick hack to avoid messing with exact but potentially lengthy 09247 ; two-complement's arithmetic here? 09248 ; 09249 ; INPUT 09250 ; 09251 ; X = Position vector component index of TERM2. Used values are: 09252 ; $00..$30 -> z-component (z-coordinate) of position vector 0..48 09253 ; $31..$61 -> x-component (x-coordinate) of position vector 0..48 09254 ; $62..$92 -> y-component (y-coordinate) of position vector 0..48 09255 ; 09256 ; Y = Position vector component index of TERM1. Used values are: 09257 ; $00..$30 -> z-component (z-coordinate) of position vector 0..48 09258 ; $31..$61 -> x-component (x-coordinate) of position vector 0..48 09259 ; $62..$92 -> y-component (y-coordinate) of position vector 0..48 09260 ; 09261 ; JOYSTICKDELTA ($6D) = Initial value of SIGN. Used values are: 09262 ; $01 -> (= Positive) Rotate right or up 09263 ; $FF -> (= Negative) Rotate left or down 09264 09265 ; TERM3 is a 24-bit value, represented by 3 bytes as 09266 ; $(sign)(high byte)(low byte) 09267 L.TERM3LO = $6A ; TERM3 (high byte), where TERM3 := TERM2 / 64 09268 L.TERM3HI = $6B ; TERM3 (low byte), where TERM3 := TERM2 / 64 09269 L.TERM3SIGN = $6C ; TERM3 (sign), where TERM3 := TERM2 / 64 09270 09271 ROTATE LDA ZPOSSIGN,X ; 09272 EOR #$01 ; 09273 BEQ SKIP224 ; Skip if sign of TERM2 is positive 09274 LDA #$FF ; 09275 09276 SKIP224 STA L.TERM3HI ; If TERM2 pos. -> TERM3 := $0000xx (= TERM2 / 256) 09277 STA L.TERM3SIGN ; If TERM2 neg. -> TERM3 := $FFFFxx (= TERM2 / 256) 09278 LDA ZPOSHI,X ; where xx := TERM2 (high byte) 09279 STA L.TERM3LO ; 09280 09281 LDA RANDOM ; (?) Hack to avoid messing with two-complement's 09282 ORA #$BF ; (?) arithmetic? Provides two least significant 09283 EOR ZPOSLO,X ; (?) bits B1..0 in TERM3. 09284 09285 ASL A ; TERM3 := TERM3 * 4 (= TERM2 / 256 * 4 = TERM2 / 64) 09286 ROL L.TERM3LO ; 09287 ROL L.TERM3HI ; 09288 ASL A ; 09289 ROL L.TERM3LO ; 09290 ROL L.TERM3HI ; 09291 09292 LDA JOYSTICKDELTA ; Toggle SIGN for next call of ROTATE 09293 EOR #$FF ; 09294 STA JOYSTICKDELTA ; 09295 BMI SKIP225 ; If SIGN negative then subtract, else add TERM3 09296 09297 ;*** Addition ****************************************************************** 09298 CLC ; TERM1 := TERM1 + TERM3 09299 LDA ZPOSLO,Y ; (24-bit addition) 09300 ADC L.TERM3LO ; 09301 STA ZPOSLO,Y ; 09302 09303 LDA ZPOSHI,Y ; 09304 ADC L.TERM3HI ; 09305 STA ZPOSHI,Y ; 09306 09307 LDA ZPOSSIGN,Y ; 09308 ADC L.TERM3SIGN ; 09309 STA ZPOSSIGN,Y ; 09310 RTS ; 09311 09312 ;*** Subtraction *************************************************************** 09313 SKIP225 SEC ; TERM1 := TERM1 - TERM3 09314 LDA ZPOSLO,Y ; (24-bit subtraction) 09315 SBC L.TERM3LO ; 09316 STA ZPOSLO,Y ; 09317 09318 LDA ZPOSHI,Y ; 09319 SBC L.TERM3HI ; 09320 STA ZPOSHI,Y ; 09321 09322 LDA ZPOSSIGN,Y ; 09323 SBC L.TERM3SIGN ; 09324 STA ZPOSSIGN,Y ; 09325 RTS ; 09326 09327 ;******************************************************************************* 09328 ;* * 09329 ;* SCREENCOLUMN * 09330 ;* * 09331 ;* Calculate pixel column number from centered pixel column number * 09332 ;* * 09333 ;******************************************************************************* 09334 09335 ; DESCRIPTION 09336 ; 09337 ; Converts a pixel column number relative to the horizontal screen center to a 09338 ; pixel column number relative to the top-left corner of the screen and stores 09339 ; the result in table PIXELCOLUMN ($0C2A). The passed relative pixel column 09340 ; number is always positive. The sign is picked from the corresponding 09341 ; x-component of the position vector (x-coordinate). 09342 ; 09343 ; If the passed relative pixel column number is offscreen horizontally the 09344 ; calculation is skipped and code execution returns. If the position vector 09345 ; corresponding to this pixel represents a PLAYFIELD space object (star, 09346 ; explosion fragments) a new position vector is initialized before code 09347 ; execution returns. If it represents a PLAYER space object the PLAYER is pushed 09348 ; offscreen before code execution returns. 09349 ; 09350 ; NOTE: The horizontal screen center's pixel column number for PLAYFIELD space 09351 ; objects has a value of 80 = 160 PLAYFIELD pixels / 2. For PLAYER space objects 09352 ; it has a value of 125 Player/Missile (PM) pixels (from left to right: 128 PM 09353 ; pixels to the horizontal screen center - 3 PM pixels relative offset of the 09354 ; PLAYER shape's horizontal center to its left edge = 125 PM pixels). 09355 ; 09356 ; INPUT 09357 ; 09358 ; A = Pixel column number relative to the horizontal screen center, always 09359 ; positive. Used values are: 09360 ; 0..80 -> Regular values, pixel is onscreen 09361 ; $FF -> Pixel is offscreen 09362 ; 09363 ; X = Position vector index. Used values are: 09364 ; 0..4 -> Position vector of a PLAYER space object 09365 ; 5..48 -> Position vector of a PLAYFIELD space object 09366 09367 L.PIXELCOLUMN = $6D ; Saves relative pixel column number 09368 09369 SCREENCOLUMN CMP #80 ; If pixel is offscreen (A > 79)... 09370 BCS SKIP233 ; ...return via initializing a new position vector 09371 09372 STA L.PIXELCOLUMN ; Save relative pixel column number 09373 CENTERCOLUMN 09374 LDA #80 ; If PLAYFIELD space object -> A := CENTERCOL = 80 09375 CPX #NUMSPCOBJ.PL ; If PLAYER space object -> A := CENTERCOL = 125 09376 BCS SKIP226 ; 09377 LDA #125 ; 09378 09379 SKIP226 LDY XPOSSIGN,X ; Skip if x-coordinate positive 09380 BNE SKIP227 ; 09381 09382 SEC ; Pixel in left screen half (x-coordinate negative) 09383 INC L.PIXELCOLUMN ; 09384 SBC L.PIXELCOLUMN ; 09385 STA PIXELCOLUMN,X ; Pixel column := CENTERCOL - (rel. pixel column + 1) 09386 RTS ; Return 09387 09388 SKIP227 CLC ; Pixel in right screen half (x-coordinate positive) 09389 ADC L.PIXELCOLUMN ; 09390 STA PIXELCOLUMN,X ; Pixel column := CENTERCOL + relative pixel column 09391 RTS ; Return 09392 09393 ;******************************************************************************* 09394 ;* * 09395 ;* SCREENROW * 09396 ;* * 09397 ;* Calculate pixel row number from centered pixel row number * 09398 ;* * 09399 ;******************************************************************************* 09400 09401 ; Converts a pixel row number relative to the vertical screen center to a pixel 09402 ; row number relative to the top-left corner of the screen and stores the result 09403 ; in table PIXELROWNEW ($0BF9). The passed relative pixel row number is always 09404 ; positive. The sign is picked from the corresponding y-component of the 09405 ; position vector (y-coordinate). 09406 ; 09407 ; If the passed relative pixel row number is offscreen vertically the 09408 ; calculation is skipped and code execution returns. If the position vector 09409 ; corresponding to this pixel represents a PLAYFIELD space object (star, 09410 ; explosion fragments) a new position vector is initialized in subroutine 09411 ; INITPOSVEC ($B764) before code execution returns. If it represents a PLAYER 09412 ; space object the PLAYER is pushed offscreen before code execution returns. 09413 ; 09414 ; NOTE: The vertical screen center's pixel row number for PLAYFIELD space 09415 ; objects has a value of 50 = 100 PLAYFIELD pixels / 2. For PLAYER space objects 09416 ; it has a value of 122 Player/Missile (PM) pixels (from top to bottom: 8 PM 09417 ; pixels to start of Display List + 16 PM pixels to begin of PLAYFIELD + 100 PM 09418 ; pixels to vertical screen center - 2 PM pixels (?) = 122 PM pixels). 09419 ; 09420 ; NOTE: If the position vector corresponding to the pixel represents a PLAYER 09421 ; space object the passed pixel row number is doubled because 1 PLAYFIELD pixel 09422 ; has the same height as 2 PM pixels at single-line resolution. 09423 ; 09424 ; When in Long-Range Scan view the z-coordinate takes the place of the 09425 ; y-coordinate of the Front or Aft view. If the Long-Range Scan is damaged the 09426 ; passed pixel row number is treated randomly as a negative or positive value 09427 ; (mirror effect). 09428 ; 09429 ; INPUT 09430 ; 09431 ; A = Pixel row number relative to the vertical screen center, always 09432 ; positive. Used values are: 09433 ; 0..50 -> Regular values, pixel is onscreen 09434 ; $FF -> Pixel is offscreen 09435 ; 09436 ; X = Position vector index. Used values are: 09437 ; 0..4 -> Position vector of a PLAYER space object 09438 ; 5..48 -> Position vector of a PLAYFIELD space object 09439 09440 L.PIXELROW = $6D ; Saves relative pixel row number 09441 09442 SCREENROW CMP #50 ; If pixel is offscreen (A > 49)... 09443 BCS SKIP233 ; ...return via initializing a new position vector 09444 09445 STA L.PIXELROW ; Save relative pixel row number 09446 LDA #50 ; If PLAYFIELD space object -> A := CENTERROW = 50 09447 CPX #NUMSPCOBJ.PL ; 09448 BCS SKIP228 ; 09449 ASL L.PIXELROW ; If PLAYER space object -> Double pixel row number 09450 LDA #122 ; If PLAYER space object -> A := CENTERROW = 122 09451 09452 SKIP228 BIT SHIPVIEW ; Skip if not in Long-Range Scan view 09453 BVC SKIP230 ; 09454 09455 BIT GCSTATLRS ; Skip if Long-Range Scan OK 09456 BPL SKIP229 ; 09457 09458 BIT RANDOM ; Long-Range Scan damaged... 09459 BVC SKIP231 ; ...branch randomly to pixel row number calculation 09460 BVS SKIP232 ; ...(mirror effect) 09461 09462 SKIP229 LDY ZPOSSIGN,X ; 09463 BNE SKIP231 ; Skip if z-coordinate pos. (Long-Range Scan view) 09464 BEQ SKIP232 ; Skip if z-coordinate neg. (Long-Range Scan view) 09465 09466 SKIP230 LDY YPOSSIGN,X ; 09467 BEQ SKIP232 ; Skip if y-coordinate neg. (Front or Aft view) 09468 09469 SKIP231 SEC ; Pixel in upper screen half (z or y coordinate pos.) 09470 INC L.PIXELROW ; 09471 SBC L.PIXELROW ; 09472 STA PIXELROWNEW,X ; Pixel row := CENTERROW - (rel. pixel row + 1) 09473 RTS ; Return 09474 09475 SKIP232 CLC ; Pixel in lower screen half (y or z coordinate neg.) 09476 ADC L.PIXELROW ; 09477 STA PIXELROWNEW,X ; Pixel row := CENTERROW + relative pixel row 09478 RTS ; Return 09479 09480 SKIP233 CPX #NUMSPCOBJ.PL ; Space object is offscreen. If it is a... 09481 BCS INITPOSVEC ; ...PLAYFIELD space object -> New position vector 09482 LDA #251 ; ...PLAYER space object -> Push PLAYER offscreen 09483 STA PIXELROWNEW,X ; Why a value of 251 (?) 09484 SKIP234 RTS ; Return 09485 09486 ;******************************************************************************* 09487 ;* * 09488 ;* INITPOSVEC * 09489 ;* * 09490 ;* Initialize position vector of a space object * 09491 ;* * 09492 ;******************************************************************************* 09493 09494 ; DESCRIPTION 09495 ; 09496 ; Initializes the position vector of a space object. 09497 ; 09498 ; This subroutine executes the following steps: 09499 ; 09500 ; (1) Set the pixel row and column number to an offscreen value (= 99). 09501 ; 09502 ; (2) If the position vector represents an explosion fragment space object then 09503 ; return code execution immediately. This avoids generating new explosion 09504 ; fragment space objects. They are separately initialized in subroutine 09505 ; COPYPOSVEC ($ACAF), which is called from subroutine INITEXPL ($AC6B). 09506 ; 09507 ; (3) Assign default values (see below) to the position vector components 09508 ; (coordinates) depending on our starship's view. 09509 ; 09510 ; Code execution continues into subroutine RNDINVXY ($B7BE) where x and y 09511 ; coordinates are inverted randomly. 09512 ; 09513 ; After passing through this and the next subroutine RNDINVXY ($B7BE) the 09514 ; components of a position vector (coordinates) are assigned to one of the 09515 ; following values depending on our starship's view: 09516 ; 09517 ; o FRONT VIEW 09518 ; 09519 ; +------------+---------------------------------------+ 09520 ; | Coordinate | Values | 09521 ; +------------+---------------------------------------+ 09522 ; | x | -4095..+4095 (-($0***)..+$0***) | 09523 ; | y | -4095..+4095 (-($0***)..+$0***) | 09524 ; | z | +3840..+4095 ( +$0F**) | 09525 ; +------------+---------------------------------------+ 09526 ; 09527 ; o AFT VIEW 09528 ; 09529 ; +------------+---------------------------------------+ 09530 ; | Coordinate | Values | 09531 ; +------------+---------------------------------------+ 09532 ; | x | -3840..+3840 (-($0*00)..+$0*00) | 09533 ; | y | -3840..+3840 (-($0*00)..+$0*00) | 09534 ; | z | -3968.. -128 (-($0*80) ) | 09535 ; +------------+---------------------------------------+ 09536 ; Values of x, y, and z coordinates change in increments of 256. 09537 ; Second digit of z-coordinate is -MAX(RNDY,RNDX), where 09538 ; RNDY := RND($00..$0F), RNDX := RND($00..$0F). 09539 ; 09540 ; o LONG-RANGE SCAN VIEW 09541 ; 09542 ; +------------+---------------------------------------+ 09543 ; | Coordinate | Values | 09544 ; +------------+---------------------------------------+ 09545 ; | x | -65535..+65535 (-($****)..$****) | 09546 ; | y | -4095..+4095 (-($0***)..$0***) | 09547 ; | z | -65535..+65535 (-($****)..$****) | 09548 ; +------------+---------------------------------------+ 09549 ; 09550 ; INPUT 09551 ; 09552 ; X = Position vector index. Used values are: 0..48. 09553 09554 L.MAXRNDXY = $6A ; Saves MAX(new y-coordinate (high byte), ... 09555 ; ...new x-coordinate (high byte)) 09556 09557 INITPOSVEC LDA #99 ; Init to offscreen pixel row and column numbers 09558 STA PIXELROWNEW,X ; 09559 STA PIXELCOLUMN,X ; 09560 09561 CPX #NUMSPCOBJ.NORM ; Return if pos vector is explosion frag space obj 09562 BCS SKIP234 ; This avoids creating new explosion frag space objs 09563 09564 LDA RANDOM ; RNDY := RND($00..$0F) 09565 AND #$0F ; 09566 STA L.MAXRNDXY ; Save RNDY 09567 STA YPOSHI,X ; y-coordinate (high byte) := RNDY 09568 09569 LDA RANDOM ; RNDX := RND($00..$0F) 09570 AND #$0F ; 09571 CMP L.MAXRNDXY ; 09572 BCC SKIP235 ; 09573 STA L.MAXRNDXY ; Save MAX(RNDY,RNDX) 09574 SKIP235 STA XPOSHI,X ; x-coordinate (high byte) := RNDX 09575 09576 LDA #$0F ; z-coordinate (high byte) := $0F 09577 STA ZPOSHI,X ; 09578 09579 LDA SHIPVIEW ; z-coordinate (sign) := 1 or 0 (Front or Aft view) 09580 EOR #$01 ; 09581 AND #$01 ; 09582 STA ZPOSSIGN,X ; 09583 BNE SKIP236 ; Skip if in Front or Long-Range Scan view 09584 09585 ; Aft view only: 09586 STA XPOSLO,X ; x-coordinate (low byte) := 0 09587 STA YPOSLO,X ; y-coordinate (low byte) := 0 09588 SEC ; z-coordinate (high byte) := -MAX(RNDY,RNDX) 09589 SBC L.MAXRNDXY ; 09590 STA ZPOSHI,X ; 09591 LDA #$80 ; z-coordinate (low byte) := $80 09592 STA ZPOSLO,X ; 09593 09594 SKIP236 BIT SHIPVIEW ; If not in Long-Range Scan view skip to RNDINVXY 09595 BVC RNDINVXY ; 09596 09597 ; Long-Range Scan view only: 09598 LDA RANDOM ; x-coordinate (high byte) := RND($00..$FF) 09599 STA XPOSHI,X ; 09600 LDA RANDOM ; z-coordinate (high byte) := RND($00..$FF) 09601 STA ZPOSHI,X ; 09602 AND #$01 ; Invert z-coordinate randomly 09603 STA ZPOSSIGN,X ; 09604 09605 ;******************************************************************************* 09606 ;* * 09607 ;* RNDINVXY * 09608 ;* * 09609 ;* Randomly invert the x and y components of a position vector * 09610 ;* * 09611 ;******************************************************************************* 09612 09613 ; DESCRIPTION 09614 ; 09615 ; Randomly inverts the x and y components of a position vector (x and y 09616 ; coordinates). See also subroutine INITPOSVEC ($B764). 09617 ; 09618 ; INPUT 09619 ; 09620 ; X = Position vector index. Used values are: 0..48. 09621 09622 RNDINVXY LDA RANDOM ; Set sign of y-coordinate randomly 09623 AND #$01 ; 09624 STA YPOSSIGN,X ; 09625 BNE SKIP237 ; Skip if sign positive 09626 09627 SEC ; Sign negative -> Calc negative y-coordinate 09628 SBC YPOSLO,X ; (calculate two's-complement of 16-bit value) 09629 STA YPOSLO,X ; 09630 LDA #0 ; 09631 SBC YPOSHI,X ; 09632 STA YPOSHI,X ; 09633 09634 SKIP237 LDA RANDOM ; Set sign of x-coordinate randomly 09635 AND #$01 ; 09636 STA XPOSSIGN,X ; 09637 BNE SKIP238 ; Skip if sign positive 09638 09639 SEC ; Sign negative -> Calc negative x-coordinate 09640 SBC XPOSLO,X ; (calculate two's-complement of 16-bit value) 09641 STA XPOSLO,X ; 09642 LDA #0 ; 09643 SBC XPOSHI,X ; 09644 STA XPOSHI,X ; 09645 SKIP238 RTS ; Return 09646 09647 ;******************************************************************************* 09648 ;* * 09649 ;* ISSURROUNDED * 09650 ;* * 09651 ;* Check if a sector is surrounded by Zylon units * 09652 ;* * 09653 ;******************************************************************************* 09654 09655 ; DESCRIPTION 09656 ; 09657 ; Checks if a sector of the Galactic Chart is surrounded by Zylon units in the 09658 ; adjacent NORTH, EAST, SOUTH, and WEST sectors. 09659 ; 09660 ; INPUT 09661 ; 09662 ; X = Sector of Galactic Chart. Used values are: $00..$7F with, for example, 09663 ; $00 -> NORTHWEST corner sector 09664 ; $0F -> NORTHEAST corner sector 09665 ; $70 -> SOUTHWEST corner sector 09666 ; $7F -> SOUTHWEST corner sector 09667 ; 09668 ; OUTPUT 09669 ; 09670 ; A = Returns if the sector is surrounded by Zylon units in the adjacent 09671 ; NORTH, EAST, SOUTH, and WEST sectors. 09672 ; 0 -> Sector is not surrounded 09673 ; > 0 -> Sector is surrounded 09674 09675 ISSURROUNDED LDA GCMEMMAP-1,X ; Check WEST sector 09676 BEQ SKIP239 ; 09677 LDA GCMEMMAP+1,X ; Check EAST sector 09678 BEQ SKIP239 ; 09679 LDA GCMEMMAP-16,X ; Check NORTH sector 09680 BEQ SKIP239 ; 09681 LDA GCMEMMAP+16,X ; Check SOUTH sector 09682 SKIP239 RTS ; Return 09683 09684 ;******************************************************************************* 09685 ;* * 09686 ;* UPDPANEL * 09687 ;* * 09688 ;* Update Control Panel Display * 09689 ;* * 09690 ;******************************************************************************* 09691 09692 ; DESCRIPTION 09693 ; 09694 ; This subroutine executes the following steps: 09695 ; 09696 ; (1) Accelerate or decelerate our starship, update the VELOCITY readout 09697 ; 09698 ; If the new velocity value is different from the current one either 09699 ; increment or decrement the current velocity value toward the new one. 09700 ; 09701 ; If the Engines are damaged or destroyed (and hyperwarp is not engaged) 09702 ; then store a random value (less or equal than the current velocity) as 09703 ; the current velocity. 09704 ; 09705 ; Display the updated velocity by the VELOCITY readout of the Control Panel 09706 ; Display. 09707 ; 09708 ; (2) Update THETA, PHI, and RANGE readouts 09709 ; 09710 ; If the Attack Computer is working then display the x, y, and z 09711 ; coordinates of the currently tracked space object as THETA, PHI, and 09712 ; RANGE readout values of the Control Panel Display. 09713 ; 09714 ; (3) Calculate overall energy consumption 09715 ; 09716 ; Add the overall energy consumption per game loop iteration to the energy 09717 ; counter. This value is given in energy subunits (256 energy subunits = 1 09718 ; energy unit displayed by the 4-digit ENERGY readout of the Console Panel 09719 ; Display). It is the total of the following items: 09720 ; 09721 ; (1) 8 energy subunits if the Shields are up 09722 ; 09723 ; (2) 2 energy subunits if the Attack Computer is on 09724 ; 09725 ; (3) 1 energy subunit of the life support system 09726 ; 09727 ; (4) Our starship's Engines energy drain rate (depending on its velocity) 09728 ; 09729 ; If there is a carryover of the energy counter then decrement the ENERGY 09730 ; readout of the Control Panel Display by one energy unit after code 09731 ; execution has continued into subroutine DECENERGY ($B86F). 09732 09733 ;*** Accelerate or decelerate our starship ************************************* 09734 UPDPANEL LDX VELOCITYLO ; Skip if new velocity = current velocity 09735 CPX NEWVELOCITY ; 09736 BEQ SKIP241 ; 09737 09738 BCC SKIP240 ; In/decrement current velocity toward new velocity 09739 DEC VELOCITYLO ; 09740 BCS SKIP242 ; 09741 SKIP240 INC VELOCITYLO ; 09742 09743 SKIP241 LDA WARPSTATE ; Skip if hyperwarp engaged 09744 BNE SKIP242 ; 09745 09746 BIT GCSTATENG ; Skip if Engines are OK 09747 BPL SKIP242 ; 09748 09749 LDA NEWVELOCITY ; Store RND(0..current velocity) to current velocity 09750 AND RANDOM ; 09751 STA VELOCITYLO ; 09752 09753 SKIP242 LDY #VELOCD1-PANELTXT-1 ; Update digits of VELOCITY readout 09754 JSR SHOWDIGITS ; 09755 09756 ;*** Display coordinates of tracked space object of Control Panel Display ****** 09757 BIT GCSTATCOM ; Skip if Attack Computer damaged or destroyed 09758 BMI SKIP243 ; 09759 09760 LDA #$31 ; Update THETA readout (x-coordinate) 09761 LDY #THETAC1-PANELTXT ; 09762 JSR SHOWCOORD ; 09763 09764 LDA #$62 ; Update PHI readout (y-coordinate) 09765 LDY #PHIC1-PANELTXT ; 09766 JSR SHOWCOORD ; 09767 09768 LDA #$00 ; Update RANGE readout (z-coordinate) 09769 LDY #RANGEC1-PANELTXT ; 09770 JSR SHOWCOORD ; 09771 09772 LDA RANGEC1+2 ; Hack to clear RANGE digit 3 when in hyperwarp: 09773 STA RANGEC1+3 ; Copy RANGE digit 2 to digit 3 09774 CMP #CCS.9+1 ; Skip if digit character > '9' (= 'infinity' char) 09775 BCS SKIP243 ; 09776 09777 LDX TRACKDIGIT ; Get z-coordinate (low byte) of tracked space object 09778 LDA ZPOSLO,X ; 09779 LSR A ; ...divide it by 16... 09780 LSR A ; 09781 LSR A ; 09782 LSR A ; 09783 TAX ; 09784 LDA MAPTOBCD99,X ; ...map value of $00..$0F to BCD value 0..9 09785 STA RANGEC1+3 ; ...and store it to RANGE digit 3 09786 09787 ;*** Calculate overall energy consumption ************************************** 09788 SKIP243 CLC ; 09789 LDA ENERGYCNT ; Load energy counter 09790 ADC DRAINSHIELDS ; Add energy drain rate of Shields 09791 ADC DRAINENGINES ; Add energy drain rate of our starship's Engines 09792 ADC DRAINATTCOMP ; Add energy drain rate of Attack Computer 09793 ADC #$01 ; Add 1 energy subunit of life support system 09794 CMP ENERGYCNT ; 09795 STA ENERGYCNT ; 09796 BCS SKIP246 ; Return if no energy counter carryover 09797 09798 LDX #3 ; Will decrement third energy digit 09799 09800 ;******************************************************************************* 09801 ;* * 09802 ;* DECENERGY * 09803 ;* * 09804 ;* Decrease energy * 09805 ;* * 09806 ;******************************************************************************* 09807 09808 ; DESCRIPTION 09809 ; 09810 ; When not in demo mode, subtract energy from the 4-digit ENERGY readout of the 09811 ; Control Panel Display. If crossing a 100-energy-unit boundary during 09812 ; subtraction the score is decremented by one unit. If the energy is zero the 09813 ; game is over. 09814 ; 09815 ; INPUT 09816 ; 09817 ; X = ENERGY readout digit to be decremented. Used values are: 09818 ; 1 -> Subtract 100 units from ENERGY readout 09819 ; 2 -> Subtract 10 units from ENERGY readout 09820 ; 3 -> Subtract 1 unit from ENERGY readout 09821 09822 ;*** Display ENERGY readout **************************************************** 09823 DECENERGY BIT ISDEMOMODE ; Return if in demo mode 09824 BVS SKIP246 ; 09825 09826 DEC ENERGYD1,X ; Decrement energy digit character 09827 LDA ENERGYD1,X ; 09828 CMP #CCS.COL2!CCS.0 ; 09829 BCS SKIP246 ; Return if digit character >= '0' 09830 LDA #CCS.COL2!CCS.9 ; 09831 STA ENERGYD1,X ; Store digit character '9' 09832 09833 ;*** Decrement score when crossing a 100-energy-unit boundary while subtracting 09834 CPX #2 ; Skip if no crossing of 100-energy-unit boundary 09835 BNE SKIP245 ; 09836 09837 LDA SCORE ; SCORE := SCORE - 1 09838 BNE SKIP244 ; 09839 DEC SCORE+1 ; 09840 SKIP244 DEC SCORE ; 09841 09842 SKIP245 DEX ; 09843 BPL DECENERGY ; Next digit 09844 09845 ;*** Energy is zero, game over ************************************************* 09846 LDX #CCS.SPC ; Clear 4-digit ENERGY readout 09847 TXA ; 09848 LDY #3 ; 09849 LOOP079 STA ENERGYD1,Y ; 09850 DEY ; 09851 BPL LOOP079 ; 09852 09853 JSR SETVIEW ; Set Front view 09854 09855 LDY #$31 ; Set title phrase "MISSION ABORTED ZERO ENERGY" 09856 LDX #$04 ; Set mission bonus offset 09857 JSR GAMEOVER ; Game over 09858 09859 SKIP246 RTS ; Return 09860 09861 ;******************************************************************************* 09862 ;* * 09863 ;* SHOWCOORD * 09864 ;* * 09865 ;* Display a position vector component (coordinate) in Control Panel Display * 09866 ;* * 09867 ;******************************************************************************* 09868 09869 ; DESCRIPTION 09870 ; 09871 ; Displays a position vector component (coordinate) by one of the THETA, PHI, or 09872 ; RANGE readouts of the Control Panel Display. 09873 ; 09874 ; Write the sign to the Control Panel Display, then map the high byte of the 09875 ; respective coordinate (x -> THETA, y -> PHI, z -> RANGE) to a BCD-value in 09876 ; 00..99. Code execution continues into subroutine SHOWDIGITS ($B8CD) where the 09877 ; digits are actually stored in the Control Panel Display. 09878 ; 09879 ; NOTE: If the digits of either the THETA or PHI readout are to be displayed and 09880 ; the x or y position vector component (high byte) is $FF then tweak the value 09881 ; to $FE. This avoids accessing table MAPTOBCD99 ($0EE9) with an index of $FF 09882 ; that would return the special value $EA. This value represents the CCS.INF 09883 ; ($0E) and CCS.SPC ($0A) characters (see comments in subroutine INITIALIZE 09884 ; ($B3BA)) that are displayed by the RANGE readout only. 09885 ; 09886 ; INPUT 09887 ; 09888 ; A = Position vector component (coordinate) offset. Used values are: 09889 ; $00 -> z-coordinate 09890 ; $31 -> x-coordinate 09891 ; $62 -> y-coordinate 09892 ; 09893 ; Y = Offset into the Control Panel Display memory map. Used values are: 09894 ; $17 -> First character (sign) of THETA readout (x-coordinate of tracked 09895 ; space object) 09896 ; $1D -> First character (sign) of PHI readout (y-coordinate of tracked 09897 ; space object) 09898 ; $23 -> First character (sign) of RANGE readout (z-coordinate of tracked 09899 ; space object) 09900 09901 L.SIGNCHAR = $6A ; Saves sign character 09902 09903 SHOWCOORD CLC ; Add index of tracked space object... 09904 ADC TRACKDIGIT ; ...to position vector component offset 09905 TAX ; Save position vector component index 09906 09907 ;*** Display sign in Control Panel Display ************************************* 09908 LDA #CCS.PLUS ; Save '+' (CCS.PLUS) to sign character 09909 STA L.SIGNCHAR ; 09910 09911 LDA ZPOSSIGN,X ; Prep sign of coordinate 09912 LSR A ; 09913 LDA ZPOSHI,X ; Prep coordinate (high byte) 09914 BCS SKIP247 ; Skip if sign is positive 09915 09916 EOR #$FF ; Invert coordinate (high byte) 09917 DEC L.SIGNCHAR ; Change saved sign character to '-' (CCS.MINUS) 09918 09919 SKIP247 TAX ; Save coordinate (high byte) 09920 LDA L.SIGNCHAR ; Store sign character in Control Panel Display 09921 STA PANELTXT,Y ; 09922 09923 ;*** Get RANGE digits ********************************************************** 09924 TYA ; Skip if RANGE is to be displayed 09925 AND #$10 ; 09926 BEQ SHOWDIGITS ; 09927 09928 CPX #$FF ; If coordinate (high byte) = $FF decrement value 09929 BNE SHOWDIGITS ; This avoids output of CCS.INFINITY in... 09930 DEX ; ...THETA and PHI readouts 09931 09932 ;******************************************************************************* 09933 ;* * 09934 ;* SHOWDIGITS * 09935 ;* * 09936 ;* Display a value by a readout of the Control Panel Display * 09937 ;* * 09938 ;******************************************************************************* 09939 09940 ; DESCRIPTION 09941 ; 09942 ; Converts a binary value in $00..$FF to a BCD-value in 0..99 and displays it as 09943 ; a 2-digit number in the Control Panel Display. 09944 ; 09945 ; INPUT 09946 ; 09947 ; X = Value to be displayed as a 2-digit BCD-value. Used values are: $00..$FF. 09948 ; 09949 ; Y = Offset into the Control Panel Display memory map relative to the first 09950 ; character of the Control Panel Display (the 'V' of the VELOCITY 09951 ; readout). Used values are: 09952 ; $01 -> Character before first digit of VELOCITY readout 09953 ; $17 -> First character (sign) of THETA readout (x-coordinate of tracked 09954 ; space object) 09955 ; $1D -> First character (sign) of PHI readout (y-coordinate of tracked 09956 ; space object) 09957 ; $23 -> First character (sign) of RANGE readout (z-coordinate of tracked 09958 ; space object) 09959 09960 SHOWDIGITS LDA MAPTOBCD99,X ; Map binary value to BCD-value 09961 TAX ; 09962 AND #$0F ; 09963 STA PANELTXT+2,Y ; Store 'ones' digit in Control Panel Display 09964 TXA ; 09965 LSR A ; 09966 LSR A ; 09967 LSR A ; 09968 LSR A ; 09969 STA PANELTXT+1,Y ; Store 'tens' digit in Control Panel Display 09970 RTS ; Return 09971 09972 ;******************************************************************************* 09973 ;* * 09974 ;* G A M E D A T A ( P A R T 2 O F 2 ) * 09975 ;* * 09976 ;******************************************************************************* 09977 09978 ;*** Color register offsets of PLAYER0..4 ************************************** 09979 PLCOLOROFFTAB .BYTE 0 ; PLAYER0 09980 .BYTE 1 ; PLAYER1 09981 .BYTE 2 ; PLAYER2 09982 .BYTE 3 ; PLAYER3 09983 .BYTE 7 ; PLAYER4 09984 09985 ;*** Shape table 1 (PLAYER2..4) ************************************************ 09986 PLSHAP1TAB .BYTE $00 ; ........ 09987 .BYTE $18 ; ...##... 09988 .BYTE $3C ; ..####.. 09989 .BYTE $7E ; .######. 09990 .BYTE $7E ; .######. 09991 .BYTE $76 ; .###.##. 09992 .BYTE $F7 ; ####.### 09993 .BYTE $DF ; ##.##### 09994 .BYTE $DF ; ##.##### 09995 .BYTE $FF ; ######## 09996 .BYTE $FF ; ######## 09997 .BYTE $F7 ; ####.### 09998 .BYTE $76 ; .###.##. 09999 .BYTE $7E ; .######. 10000 .BYTE $7E ; .######. 10001 .BYTE $3C ; ..####.. 10002 .BYTE $18 ; ...##... 10003 .BYTE $10 ; ...#.... 10004 .BYTE $38 ; ..###... 10005 .BYTE $7C ; .#####.. 10006 .BYTE $7C ; .#####.. 10007 .BYTE $FE ; #######. 10008 .BYTE $DE ; ##.####. 10009 .BYTE $DA ; ##.##.#. 10010 .BYTE $FA ; #####.#. 10011 .BYTE $EE ; ###.###. 10012 .BYTE $EE ; ###.###. 10013 .BYTE $7C ; .#####.. 10014 .BYTE $7C ; .#####.. 10015 .BYTE $38 ; ..###... 10016 .BYTE $10 ; ...#.... 10017 .BYTE $18 ; ...##... 10018 .BYTE $3C ; ..####.. 10019 .BYTE $3C ; ..####.. 10020 .BYTE $7E ; .######. 10021 .BYTE $6E ; .##.###. 10022 .BYTE $7A ; .####.#. 10023 .BYTE $7E ; .######. 10024 .BYTE $76 ; .###.##. 10025 .BYTE $7E ; .######. 10026 .BYTE $3C ; ..####.. 10027 .BYTE $3C ; ..####.. 10028 .BYTE $18 ; ...##... 10029 .BYTE $10 ; ...#.... 10030 .BYTE $38 ; ..###... 10031 .BYTE $38 ; ..###... 10032 .BYTE $7C ; .#####.. 10033 .BYTE $74 ; .###.#.. 10034 .BYTE $7C ; .#####.. 10035 .BYTE $6C ; .##.##.. 10036 .BYTE $38 ; ..###... 10037 .BYTE $38 ; ..###... 10038 .BYTE $10 ; ...#.... 10039 .BYTE $10 ; ...#.... 10040 .BYTE $18 ; ...##... 10041 .BYTE $3C ; ..####.. 10042 .BYTE $2C ; ..#.##.. 10043 .BYTE $3C ; ..####.. 10044 .BYTE $3C ; ..####.. 10045 .BYTE $18 ; ...##... 10046 .BYTE $08 ; ....#... 10047 .BYTE $10 ; ...#.... 10048 .BYTE $38 ; ..###... 10049 .BYTE $38 ; ..###... 10050 .BYTE $28 ; ..#.#... 10051 .BYTE $38 ; ..###... 10052 .BYTE $10 ; ...#.... 10053 .BYTE $3C ; ..####.. 10054 .BYTE $3C ; ..####.. 10055 .BYTE $24 ; ..#..#.. 10056 .BYTE $3C ; ..####.. 10057 .BYTE $7E ; .######. 10058 .BYTE $7E ; .######. 10059 .BYTE $7E ; .######. 10060 .BYTE $5A ; .#.##.#. 10061 .BYTE $FF ; ######## 10062 .BYTE $FF ; ######## 10063 .BYTE $42 ; .#....#. 10064 .BYTE $42 ; .#....#. 10065 .BYTE $42 ; .#....#. 10066 .BYTE $42 ; .#....#. 10067 .BYTE $42 ; .#....#. 10068 .BYTE $42 ; .#....#. 10069 .BYTE $1C ; ...###.. 10070 .BYTE $1C ; ...###.. 10071 .BYTE $14 ; ...#.#.. 10072 .BYTE $3E ; ..#####. 10073 .BYTE $3E ; ..#####. 10074 .BYTE $3E ; ..#####. 10075 .BYTE $2A ; ..#.#.#. 10076 .BYTE $7F ; .####### 10077 .BYTE $7F ; .####### 10078 .BYTE $22 ; ..#...#. 10079 .BYTE $22 ; ..#...#. 10080 .BYTE $22 ; ..#...#. 10081 .BYTE $22 ; ..#...#. 10082 .BYTE $22 ; ..#...#. 10083 .BYTE $18 ; ...##... 10084 .BYTE $18 ; ...##... 10085 .BYTE $3C ; ..####.. 10086 .BYTE $3C ; ..####.. 10087 .BYTE $3C ; ..####.. 10088 .BYTE $3C ; ..####.. 10089 .BYTE $7E ; .######. 10090 .BYTE $24 ; ..#..#.. 10091 .BYTE $24 ; ..#..#.. 10092 .BYTE $24 ; ..#..#.. 10093 .BYTE $24 ; ..#..#.. 10094 .BYTE $10 ; ...#.... 10095 .BYTE $10 ; ...#.... 10096 .BYTE $38 ; ..###... 10097 .BYTE $38 ; ..###... 10098 .BYTE $38 ; ..###... 10099 .BYTE $7C ; .#####.. 10100 .BYTE $28 ; ..#.#... 10101 .BYTE $28 ; ..#.#... 10102 .BYTE $28 ; ..#.#... 10103 .BYTE $18 ; ...##... 10104 .BYTE $18 ; ...##... 10105 .BYTE $3C ; ..####.. 10106 .BYTE $18 ; ...##... 10107 .BYTE $18 ; ...##... 10108 .BYTE $10 ; ...#.... 10109 .BYTE $10 ; ...#.... 10110 .BYTE $38 ; ..###... 10111 .BYTE $10 ; ...#.... 10112 .BYTE $18 ; ...##... 10113 .BYTE $7E ; .######. 10114 .BYTE $FF ; ######## 10115 .BYTE $FF ; ######## 10116 .BYTE $FF ; ######## 10117 .BYTE $FF ; ######## 10118 .BYTE $FF ; ######## 10119 .BYTE $E7 ; ###..### 10120 .BYTE $E7 ; ###..### 10121 .BYTE $FF ; ######## 10122 .BYTE $FF ; ######## 10123 .BYTE $FF ; ######## 10124 .BYTE $FF ; ######## 10125 .BYTE $FF ; ######## 10126 .BYTE $7E ; .######. 10127 .BYTE $7E ; .######. 10128 .BYTE $00 ; ........ 10129 .BYTE $18 ; ...##... 10130 .BYTE $3C ; ..####.. 10131 .BYTE $7E ; .######. 10132 .BYTE $FF ; ######## 10133 .BYTE $FF ; ######## 10134 .BYTE $FF ; ######## 10135 .BYTE $E7 ; ###..### 10136 .BYTE $66 ; .##..##. 10137 .BYTE $FF ; ######## 10138 .BYTE $FF ; ######## 10139 .BYTE $FF ; ######## 10140 .BYTE $FF ; ######## 10141 .BYTE $7E ; .######. 10142 .BYTE $7E ; .######. 10143 .BYTE $00 ; ........ 10144 .BYTE $18 ; ...##... 10145 .BYTE $3C ; ..####.. 10146 .BYTE $7E ; .######. 10147 .BYTE $FF ; ######## 10148 .BYTE $FF ; ######## 10149 .BYTE $E7 ; ###..### 10150 .BYTE $66 ; .##..##. 10151 .BYTE $FF ; ######## 10152 .BYTE $FF ; ######## 10153 .BYTE $FF ; ######## 10154 .BYTE $FF ; ######## 10155 .BYTE $3C ; ..####.. 10156 .BYTE $18 ; ...##... 10157 .BYTE $3C ; ..####.. 10158 .BYTE $FF ; ######## 10159 .BYTE $FF ; ######## 10160 .BYTE $E7 ; ###..### 10161 .BYTE $66 ; .##..##. 10162 .BYTE $FF ; ######## 10163 .BYTE $FF ; ######## 10164 .BYTE $7E ; .######. 10165 .BYTE $3C ; ..####.. 10166 .BYTE $00 ; ........ 10167 .BYTE $18 ; ...##... 10168 .BYTE $3C ; ..####.. 10169 .BYTE $FF ; ######## 10170 .BYTE $FF ; ######## 10171 .BYTE $FF ; ######## 10172 .BYTE $3C ; ..####.. 10173 .BYTE $18 ; ...##... 10174 .BYTE $18 ; ...##... 10175 .BYTE $3C ; ..####.. 10176 .BYTE $FF ; ######## 10177 .BYTE $3C ; ..####.. 10178 .BYTE $18 ; ...##... 10179 .BYTE $28 ; ..#.#... 10180 .BYTE $28 ; ..#.#... 10181 .BYTE $28 ; ..#.#... 10182 .BYTE $28 ; ..#.#... 10183 .BYTE $EE ; ###.###. 10184 .BYTE $00 ; ........ 10185 .BYTE $00 ; ........ 10186 .BYTE $EE ; ###.###. 10187 .BYTE $28 ; ..#.#... 10188 .BYTE $28 ; ..#.#... 10189 .BYTE $28 ; ..#.#... 10190 .BYTE $28 ; ..#.#... 10191 10192 ;*** Shape table 2 (PLAYER0..1) ************************************************ 10193 PLSHAP2TAB .BYTE $00 ; ........ 10194 .BYTE $81 ; #......# 10195 .BYTE $81 ; #......# 10196 .BYTE $81 ; #......# 10197 .BYTE $81 ; #......# 10198 .BYTE $BD ; #.####.# 10199 .BYTE $FF ; ######## 10200 .BYTE $FF ; ######## 10201 .BYTE $BD ; #.####.# 10202 .BYTE $81 ; #......# 10203 .BYTE $81 ; #......# 10204 .BYTE $81 ; #......# 10205 .BYTE $81 ; #......# 10206 .BYTE $82 ; #.....#. 10207 .BYTE $82 ; #.....#. 10208 .BYTE $BA ; #.###.#. 10209 .BYTE $FE ; #######. 10210 .BYTE $FE ; #######. 10211 .BYTE $BA ; #.###.#. 10212 .BYTE $82 ; #.....#. 10213 .BYTE $82 ; #.....#. 10214 .BYTE $42 ; .#....#. 10215 .BYTE $5A ; .#.##.#. 10216 .BYTE $7E ; .######. 10217 .BYTE $7E ; .######. 10218 .BYTE $5A ; .#.##.#. 10219 .BYTE $42 ; .#....#. 10220 .BYTE $44 ; .#...#.. 10221 .BYTE $54 ; .#.#.#.. 10222 .BYTE $7C ; .#####.. 10223 .BYTE $7C ; .#####.. 10224 .BYTE $54 ; .#.#.#.. 10225 .BYTE $44 ; .#...#.. 10226 .BYTE $24 ; ..#..#.. 10227 .BYTE $3C ; ..####.. 10228 .BYTE $3C ; ..####.. 10229 .BYTE $24 ; ..#..#.. 10230 .BYTE $28 ; ..#.#... 10231 .BYTE $38 ; ..###... 10232 .BYTE $38 ; ..###... 10233 .BYTE $28 ; ..#.#... 10234 .BYTE $18 ; ...##... 10235 .BYTE $18 ; ...##... 10236 .BYTE $10 ; ...#.... 10237 .BYTE $10 ; ...#.... 10238 .BYTE $E0 ; ###..... 10239 .BYTE $F8 ; #####... 10240 .BYTE $F8 ; #####... 10241 .BYTE $FE ; #######. 10242 .BYTE $57 ; .#.#.### 10243 .BYTE $FE ; #######. 10244 .BYTE $F8 ; #####... 10245 .BYTE $F8 ; #####... 10246 .BYTE $C0 ; ##...... 10247 .BYTE $C0 ; ##...... 10248 .BYTE $F0 ; ####.... 10249 .BYTE $C0 ; ##...... 10250 .BYTE $F0 ; ####.... 10251 .BYTE $F0 ; ####.... 10252 .BYTE $FC ; ######.. 10253 .BYTE $BE ; #.#####. 10254 .BYTE $FC ; ######.. 10255 .BYTE $F0 ; ####.... 10256 .BYTE $80 ; #....... 10257 .BYTE $80 ; #....... 10258 .BYTE $C0 ; ##...... 10259 .BYTE $C0 ; ##...... 10260 .BYTE $F0 ; ####.... 10261 .BYTE $BC ; #.####.. 10262 .BYTE $F0 ; ####.... 10263 .BYTE $C0 ; ##...... 10264 .BYTE $07 ; .....### 10265 .BYTE $1F ; ...##### 10266 .BYTE $1F ; ...##### 10267 .BYTE $7F ; .####### 10268 .BYTE $EA ; ###.#.#. 10269 .BYTE $7F ; .####### 10270 .BYTE $1F ; ...##### 10271 .BYTE $1F ; ...##### 10272 .BYTE $03 ; ......## 10273 .BYTE $03 ; ......## 10274 .BYTE $0F ; ....#### 10275 .BYTE $03 ; ......## 10276 .BYTE $0F ; ....#### 10277 .BYTE $0F ; ....#### 10278 .BYTE $3F ; ..###### 10279 .BYTE $7D ; .#####.# 10280 .BYTE $3F ; ..###### 10281 .BYTE $0F ; ....#### 10282 .BYTE $01 ; .......# 10283 .BYTE $01 ; .......# 10284 .BYTE $03 ; ......## 10285 .BYTE $03 ; ......## 10286 .BYTE $0F ; ....#### 10287 .BYTE $3D ; ..####.# 10288 .BYTE $0F ; ....#### 10289 .BYTE $03 ; ......## 10290 .BYTE $18 ; ...##... 10291 .BYTE $3C ; ..####.. 10292 .BYTE $7E ; .######. 10293 .BYTE $7E ; .######. 10294 .BYTE $DB ; ##.##.## 10295 .BYTE $C3 ; ##....## 10296 .BYTE $81 ; #......# 10297 .BYTE $81 ; #......# 10298 .BYTE $81 ; #......# 10299 .BYTE $10 ; ...#.... 10300 .BYTE $38 ; ..###... 10301 .BYTE $7C ; .#####.. 10302 .BYTE $7C ; .#####.. 10303 .BYTE $D6 ; ##.#.##. 10304 .BYTE $C6 ; ##...##. 10305 .BYTE $82 ; #.....#. 10306 .BYTE $82 ; #.....#. 10307 .BYTE $18 ; ...##... 10308 .BYTE $3C ; ..####.. 10309 .BYTE $3C ; ..####.. 10310 .BYTE $66 ; .##..##. 10311 .BYTE $66 ; .##..##. 10312 .BYTE $42 ; .#....#. 10313 .BYTE $42 ; .#....#. 10314 .BYTE $10 ; ...#.... 10315 .BYTE $38 ; ..###... 10316 .BYTE $38 ; ..###... 10317 .BYTE $6C ; .##.##.. 10318 .BYTE $44 ; .#...#.. 10319 .BYTE $44 ; .#...#.. 10320 .BYTE $18 ; ...##... 10321 .BYTE $3C ; ..####.. 10322 .BYTE $24 ; ..#..#.. 10323 .BYTE $24 ; ..#..#.. 10324 .BYTE $10 ; ...#.... 10325 .BYTE $38 ; ..###... 10326 .BYTE $28 ; ..#.#... 10327 .BYTE $18 ; ...##... 10328 .BYTE $3C ; ..####.. 10329 .BYTE $7E ; .######. 10330 .BYTE $FF ; ######## 10331 .BYTE $18 ; ...##... 10332 .BYTE $18 ; ...##... 10333 .BYTE $FF ; ######## 10334 .BYTE $7E ; .######. 10335 .BYTE $3C ; ..####.. 10336 .BYTE $18 ; ...##... 10337 .BYTE $10 ; ...#.... 10338 .BYTE $38 ; ..###... 10339 .BYTE $7C ; .#####.. 10340 .BYTE $FE ; #######. 10341 .BYTE $38 ; ..###... 10342 .BYTE $38 ; ..###... 10343 .BYTE $FE ; #######. 10344 .BYTE $7C ; .#####.. 10345 .BYTE $38 ; ..###... 10346 .BYTE $10 ; ...#.... 10347 .BYTE $18 ; ...##... 10348 .BYTE $3C ; ..####.. 10349 .BYTE $7E ; .######. 10350 .BYTE $18 ; ...##... 10351 .BYTE $7E ; .######. 10352 .BYTE $3C ; ..####.. 10353 .BYTE $18 ; ...##... 10354 .BYTE $10 ; ...#.... 10355 .BYTE $38 ; ..###... 10356 .BYTE $7C ; .#####.. 10357 .BYTE $10 ; ...#.... 10358 .BYTE $7C ; .#####.. 10359 .BYTE $38 ; ..###... 10360 .BYTE $10 ; ...#.... 10361 .BYTE $18 ; ...##... 10362 .BYTE $3C ; ..####.. 10363 .BYTE $18 ; ...##... 10364 .BYTE $3C ; ..####.. 10365 .BYTE $18 ; ...##... 10366 .BYTE $10 ; ...#.... 10367 .BYTE $38 ; ..###... 10368 .BYTE $38 ; ..###... 10369 .BYTE $10 ; ...#.... 10370 10371 ;*** Display List fragments **************************************************** 10372 ; 10373 ; LOCAL VARIABLES 10374 PFMEM.C0R0 = PFMEM+0*40 ; Start address of PLAYFIELD row 0 10375 PFMEM.C0R5 = PFMEM+5*40 ; Start address of PLAYFIELD row 5 10376 PFMEM.C0R17 = PFMEM+17*40 ; Start address of PLAYFIELD row 17 10377 10378 ;*** Display List fragment for Control Panel Display (bottom text window) ****** 10379 DLSTFRAG .BYTE $8D ; GR7 + DLI 10380 .BYTE $00 ; BLK1 10381 .BYTE $46,PANELTXT ; GR1 @ PANELTXT 10382 .BYTE $20 ; BLK3 10383 .BYTE $06 ; GR1 10384 .BYTE $00 ; BLK1 10385 10386 ;*** Display List fragment for Galactic Chart view ***************************** 10387 DLSTFRAGGC .BYTE $01,DLSTGC ; JMP @ DLSTGC 10388 10389 ;*** Display List fragment for Long-Range Scan view **************************** 10390 DLSTFRAGLRS .BYTE $00 ; BLK1 10391 .BYTE $00 ; BLK1 10392 .BYTE $46,LRSHEADER ; GR1 @ LRSHEADER 10393 .BYTE $4D,PFMEM.C0R5 ; GR7 @ PFMEM.C0R5 10394 10395 ;*** Display List fragment for Aft view **************************************** 10396 DLSTFRAGAFT .BYTE $00 ; BLK1 10397 .BYTE $00 ; BLK1 10398 .BYTE $46,AFTHEADER ; GR1 @ AFTHEADER 10399 .BYTE $4D,PFMEM.C0R5 ; GR7 @ PFMEM.C0R5 10400 10401 ;*** Display List fragment for Front view and Title text line ****************** 10402 DLSTFRAGFRONT .BYTE $4D,PFMEM.C0R0 ; GR7 @ PFMEM.C0R0 10403 .BYTE $0D ; GR7 10404 .BYTE $0D ; GR7 10405 .BYTE $0D ; GR7 10406 .BYTE $0D ; GR7 10407 .BYTE $0D ; GR7 10408 .BYTE $30 ; BLK4 10409 .BYTE $46,TITLETXT ; GR1 @ TITLETXT 10410 .BYTE $4D,PFMEM.C0R17 ; GR7 @ PFMEM.C0R17 10411 10412 ;*** Display List fragment offsets relative to DLSTFRAG ************************ 10413 DLSTFRAGOFFTAB .BYTE DLSTFRAGFRONT-DLSTFRAG ; Front view 10414 .BYTE DLSTFRAGAFT-DLSTFRAG ; Aft view 10415 .BYTE DLSTFRAGLRS-DLSTFRAG ; Long-Range Scan view 10416 .BYTE DLSTFRAGGC-DLSTFRAG ; Galactic Chart view 10417 10418 ;*** 1-byte bit patterns for 4 pixels of same color for PLAYFIELD space objects 10419 FOURCOLORPIXEL .BYTE $FF ; COLOR3 10420 .BYTE $FF ; COLOR3 10421 .BYTE $FF ; COLOR3 10422 .BYTE $FF ; COLOR3 10423 .BYTE $AA ; COLOR2 10424 .BYTE $FF ; COLOR3 10425 .BYTE $AA ; COLOR2 10426 .BYTE $FF ; COLOR3 10427 .BYTE $AA ; COLOR2 10428 .BYTE $AA ; COLOR2 10429 .BYTE $AA ; COLOR2 10430 .BYTE $FF ; COLOR3 10431 .BYTE $AA ; COLOR2 10432 .BYTE $AA ; COLOR2 10433 .BYTE $AA ; COLOR2 10434 .BYTE $AA ; COLOR2 10435 .BYTE $AA ; COLOR2 10436 .BYTE $AA ; COLOR2 10437 .BYTE $AA ; COLOR2 10438 .BYTE $55 ; COLOR1 10439 .BYTE $55 ; COLOR1 10440 .BYTE $AA ; COLOR2 10441 .BYTE $55 ; COLOR1 10442 .BYTE $AA ; COLOR2 10443 .BYTE $55 ; COLOR1 10444 .BYTE $55 ; COLOR1 10445 .BYTE $55 ; COLOR1 10446 .BYTE $AA ; COLOR2 10447 .BYTE $55 ; COLOR1 10448 .BYTE $55 ; COLOR1 10449 .BYTE $55 ; COLOR1 10450 .BYTE $55 ; COLOR1 10451 10452 ;*** Masks to filter 1 pixel (2 bits) from 4 pixels (1 byte of PLAYFIELD memory) 10453 PIXELMASKTAB .BYTE $C0 ; ##...... 10454 .BYTE $30 ; ..##.... 10455 .BYTE $0C ; ....##.. 10456 .BYTE $03 ; ......## 10457 10458 ;*** Velocity table ************************************************************ 10459 VELOCITYTAB .BYTE 0 ; Speed 0 = 0 10460 .BYTE 1 ; Speed 1 = 1 10461 .BYTE 2 ; Speed 2 = 2 10462 .BYTE 4 ; Speed 3 = 4 10463 .BYTE 8 ; Speed 4 = 8 10464 .BYTE 16 ; Speed 5 = 16 10465 .BYTE 32 ; Speed 6 = 32 10466 .BYTE 64 ; Speed 7 = 64 10467 .BYTE 96 ; Speed 8 = 96 10468 .BYTE 112 ; Speed 9 = 112 10469 10470 ;*** Keyboard code lookup table ************************************************ 10471 KEYTAB .BYTE $F2 ; '0' - Speed 0 10472 .BYTE $DF ; '1' - Speed 1 10473 .BYTE $DE ; '2' - Speed 2 10474 .BYTE $DA ; '3' - Speed 3 10475 .BYTE $D8 ; '4' - Speed 4 10476 .BYTE $DD ; '5' - Speed 5 10477 .BYTE $DB ; '6' - Speed 6 10478 .BYTE $F3 ; '7' - Speed 7 10479 .BYTE $F5 ; '8' - Speed 8 10480 .BYTE $F0 ; '9' - Speed 9 10481 .BYTE $F8 ; 'F' - Front view 10482 .BYTE $FF ; 'A' - Aft view 10483 .BYTE $C0 ; 'L' - Long-Range Scan view 10484 .BYTE $FD ; 'G' - Galactic Chart view 10485 .BYTE $ED ; 'T' - Tracking on/off 10486 .BYTE $FE ; 'S' - Shields on/off 10487 .BYTE $D2 ; 'C' - Attack Computer on/off 10488 .BYTE $F9 ; 'H' - Hyperwarp 10489 .BYTE $E5 ; 'M' - Manual Target Selector 10490 .BYTE $CA ; 'P' - Pause 10491 .BYTE $E7 ; 'INV' - Abort Mission 10492 10493 ;*** Engines energy drain rates per game loop iteration in energy subunits ***** 10494 DRAINRATETAB .BYTE 0 ; 10495 .BYTE 4 ; 10496 .BYTE 6 ; 10497 .BYTE 8 ; 10498 .BYTE 10 ; 10499 .BYTE 12 ; 10500 .BYTE 14 ; 10501 .BYTE 30 ; 10502 .BYTE 45 ; 10503 .BYTE 60 ; 10504 10505 ;*** Hyperwarp energy depending on distance ************************************ 10506 WARPENERGYTAB .BYTE 10 ; = 100 energy units 10507 .BYTE 13 ; = 130 energy units 10508 .BYTE 16 ; = 160 energy units 10509 .BYTE 20 ; = 200 energy units 10510 .BYTE 23 ; = 230 energy units 10511 .BYTE 50 ; = 500 energy units 10512 .BYTE 70 ; = 700 energy units 10513 .BYTE 80 ; = 800 energy units 10514 .BYTE 90 ; = 900 energy units 10515 .BYTE 120 ; = 1200 energy units 10516 .BYTE 125 ; = 1250 energy units 10517 .BYTE 130 ; = 1300 energy units 10518 .BYTE 135 ; = 1350 energy units 10519 .BYTE 140 ; = 1400 energy units 10520 .BYTE 155 ; = 1550 energy units 10521 .BYTE 170 ; = 1700 energy units 10522 .BYTE 184 ; = 1840 energy units 10523 .BYTE 200 ; = 2000 energy units 10524 .BYTE 208 ; = 2080 energy units 10525 .BYTE 216 ; = 2160 energy units 10526 .BYTE 223 ; = 2230 energy units 10527 .BYTE 232 ; = 2320 energy units 10528 .BYTE 241 ; = 2410 energy units 10529 .BYTE 250 ; = 2500 energy units 10530 10531 ;*** Joystick increments ******************************************************* 10532 STICKINCTAB .BYTE 0 ; Centered 10533 .BYTE 1 ; Right or up 10534 .BYTE -1 ; Left or down 10535 .BYTE 0 ; Centered 10536 10537 ;*** 3-byte elements to draw cross hairs and Attack Computer Display *********** 10538 ; Byte 1 : Pixel column number of line start 10539 ; Byte 2 : Pixel row number of line start 10540 ; Byte 3 : B7 = 0 -> Draw line to the right 10541 ; B7 = 1 -> Draw line down 10542 ; B6..0 -> Length of line in pixels. Possible values are: 0..127. 10543 ; 10544 ; # 10545 ; # 4 10546 ; # ############################## 10547 ; #1 # # # 10548 ; # # #11 # 10549 ; # # # # 10550 ; # #5 # 8 #6 10551 ; # ############### # 10552 ; # # # # 10553 ; 15 16 # 7 # # 10 # 10554 ; ############### ############### ######## ######### 10555 ; # #12 # # 10556 ; # # #13 # 10557 ; # ############### # 10558 ; # # 9 # # 10559 ; # # # # 10560 ; # # #14 # 10561 ; # # 3 # # 10562 ; #2 ############################## 10563 ; # 10564 ; # 10565 ; 10566 ; Front/Aft Cross Hairs Attack Computer Display 10567 ; 10568 ; LOCAL VARIABLES 10569 DOWN = $80 10570 RIGHT = $00 10571 10572 DRAWLINESTAB .BYTE 80,40,DOWN!7 ; Line 1 10573 .BYTE 80,54,DOWN!7 ; Line 2 10574 10575 .BYTE 119,70,RIGHT!30 ; Line 3 10576 .BYTE 119,86,RIGHT!30 ; Line 4 10577 .BYTE 119,70,DOWN!17 ; Line 5 10578 .BYTE 148,70,DOWN!17 ; Line 6 10579 .BYTE 120,78,RIGHT!6 ; Line 7 10580 .BYTE 126,75,RIGHT!15 ; Line 8 10581 .BYTE 126,81,RIGHT!15 ; Line 9 10582 .BYTE 141,78,RIGHT!7 ; Line 10 10583 .BYTE 133,71,DOWN!4 ; Line 11 10584 .BYTE 126,76,DOWN!5 ; Line 12 10585 .BYTE 140,76,DOWN!5 ; Line 13 10586 .BYTE 133,82,DOWN!4 ; Line 14 10587 10588 .BYTE 62,50,RIGHT!15 ; Line 15 10589 .BYTE 84,50,RIGHT!15 ; Line 16 10590 .BYTE $FE ; End marker 10591 10592 ;*** 3-byte elements to draw our starship's shape in Long-Range Scan view ****** 10593 ; 10594 ; Line 17 18 19 20 21 10595 ; ## 10596 ; ## 10597 ; ## ## ## 10598 ; ## ## ## ## ## 10599 ; ## ## ## 10600 10601 .BYTE 78,53,DOWN!2 ; Line 17 10602 .BYTE 79,52,DOWN!2 ; Line 18 10603 .BYTE 80,50,DOWN!5 ; Line 19 10604 .BYTE 81,52,DOWN!2 ; Line 20 10605 .BYTE 82,53,DOWN!2 ; Line 21 10606 .BYTE $FE ; End marker 10607 10608 ;*** Initial x and y coordinates of a star during hyperwarp ******************** 10609 ; The following two tables are used to determine the initial x and y coordinates 10610 ; (high byte) of a star during hyperwarp. An index in 0..3 picks both the x and 10611 ; y coordinate, thus 4 pairs of coordinates are possible: 10612 ; 10613 ; Y +-------+----------------------------+----------------------------+ 10614 ; ^ | Index | x-coordinate | y-coordinate | 10615 ; | +-------+----------------------------+----------------------------+ 10616 ; |.32. | 0 | +1024..+1279 (+$04**) | +512..+767 (+$02**) | 10617 ; |...1 | 1 | +1024..+1279 (+$04**) | +768..+1023 (+$03**) | 10618 ; |...0 | 2 | +768..+1023 (+$03**) | +1024..+1279 (+$04**) | 10619 ; |.... | 3 | +512..+767 (+$02**) | +1024..+1279 (+$04**) | 10620 ; 0----->X +-------+----------------------------+----------------------------+ 10621 10622 ;*** Initial x-coordinate (high byte) of star in hyperwarp ********************* 10623 WARPSTARXTAB .BYTE $04 ; +1024..+1279 (+$04**) 10624 .BYTE $04 ; +1024..+1279 (+$04**) 10625 .BYTE $03 ; +768..+1023 (+$03**) 10626 .BYTE $02 ; +512..+767 (+$02**) 10627 10628 ;*** Initial y-coordinate (high byte) of star in hyperwarp ********************* 10629 WARPSTARYTAB .BYTE $02 ; +512..+767 (+$02**) 10630 .BYTE $03 ; +768..+1023 (+$03**) 10631 .BYTE $04 ; +1024..+1279 (+$04**) 10632 .BYTE $04 ; +1024..+1279 (+$04**) 10633 10634 ;*** Text of Control Panel Display (encoded in custom character set) *********** 10635 ; Row 1: "V:00 K:00 E:9999 T:0" 10636 ; Row 2: " O:-00 O:-00 R:-000 " 10637 10638 PANELTXTTAB .BYTE CCS.V 10639 .BYTE CCS.COLON 10640 .BYTE CCS.0 10641 .BYTE CCS.0 10642 .BYTE CCS.SPC 10643 .BYTE CCS.COL1!CCS.K 10644 .BYTE CCS.COL1!CCS.COLON 10645 .BYTE CCS.COL1!CCS.0 10646 .BYTE CCS.COL1!CCS.0 10647 .BYTE CCS.SPC 10648 .BYTE CCS.COL2!CCS.E 10649 .BYTE CCS.COL2!CCS.COLON 10650 .BYTE CCS.COL2!CCS.9 10651 .BYTE CCS.COL2!CCS.9 10652 .BYTE CCS.COL2!CCS.9 10653 .BYTE CCS.COL2!CCS.9 10654 .BYTE CCS.SPC 10655 .BYTE CCS.T 10656 .BYTE CCS.COLON 10657 .BYTE CCS.0 10658 10659 .BYTE CCS.SPC 10660 .BYTE CCS.THETA 10661 .BYTE CCS.COLON 10662 .BYTE CCS.MINUS 10663 .BYTE CCS.0 10664 .BYTE CCS.0 10665 .BYTE CCS.SPC 10666 .BYTE CCS.COL1!CCS.PHI 10667 .BYTE CCS.COL1!CCS.COLON 10668 .BYTE CCS.MINUS 10669 .BYTE CCS.0 10670 .BYTE CCS.0 10671 .BYTE CCS.SPC 10672 .BYTE CCS.COL2!CCS.R 10673 .BYTE CCS.COL2!CCS.COLON 10674 .BYTE CCS.MINUS 10675 .BYTE CCS.0 10676 .BYTE CCS.0 10677 .BYTE CCS.0 10678 .BYTE CCS.SPC 10679 10680 ;*** Text of Galactic Chart Panel Display ************************************** 10681 ; Row 1: "WARP ENERGY: 0 " 10682 ; Row 2: "TARGETS: DC:PESCLR " 10683 ; Row 3: "STAR DATE:00.00 " 10684 10685 .BYTE ROM.W 10686 .BYTE ROM.A 10687 .BYTE ROM.R 10688 .BYTE ROM.P 10689 .BYTE ROM.SPC 10690 .BYTE ROM.E 10691 .BYTE ROM.N 10692 .BYTE ROM.E 10693 .BYTE ROM.R 10694 .BYTE ROM.G 10695 .BYTE ROM.Y 10696 .BYTE ROM.COLON 10697 .BYTE ROM.SPC 10698 .BYTE ROM.SPC 10699 .BYTE ROM.SPC 10700 .BYTE ROM.0 10701 .BYTE ROM.SPC 10702 .BYTE ROM.SPC 10703 .BYTE ROM.SPC 10704 .BYTE ROM.SPC 10705 10706 .BYTE CCS.COL2!ROM.T 10707 .BYTE CCS.COL2!ROM.A 10708 .BYTE CCS.COL2!ROM.R 10709 .BYTE CCS.COL2!ROM.G 10710 .BYTE CCS.COL2!ROM.E 10711 .BYTE CCS.COL2!ROM.T 10712 .BYTE CCS.COL2!ROM.S 10713 .BYTE CCS.COL2!ROM.COLON 10714 .BYTE ROM.SPC 10715 .BYTE ROM.SPC 10716 .BYTE ROM.D 10717 .BYTE ROM.C 10718 .BYTE ROM.COLON 10719 .BYTE ROM.P 10720 .BYTE ROM.E 10721 .BYTE ROM.S 10722 .BYTE ROM.C 10723 .BYTE ROM.L 10724 .BYTE ROM.R 10725 .BYTE ROM.SPC 10726 10727 .BYTE CCS.COL3!ROM.S 10728 .BYTE CCS.COL3!ROM.T 10729 .BYTE CCS.COL3!ROM.A 10730 .BYTE CCS.COL3!ROM.R 10731 .BYTE ROM.SPC 10732 .BYTE CCS.COL3!ROM.D 10733 .BYTE CCS.COL3!ROM.A 10734 .BYTE CCS.COL3!ROM.T 10735 .BYTE CCS.COL3!ROM.E 10736 .BYTE CCS.COL3!ROM.COLON 10737 .BYTE CCS.COL3!ROM.0 10738 .BYTE CCS.COL3!ROM.0 10739 .BYTE CCS.COL3!ROM.DOT 10740 .BYTE CCS.COL3!ROM.0 10741 .BYTE CCS.COL3!ROM.0 10742 .BYTE ROM.SPC 10743 .BYTE ROM.SPC 10744 .BYTE ROM.SPC 10745 .BYTE ROM.SPC 10746 .BYTE ROM.SPC 10747 10748 ;*** Galactic Chart sector type table ****************************************** 10749 SECTORTYPETAB .BYTE $CF ; Starbase 10750 .BYTE $04 ; 4 Zylon ships 10751 .BYTE $03 ; 3 Zylon ships 10752 .BYTE $02 ; 1 or 2 Zylon ships 10753 10754 ;*** Phrase table ************************************************************** 10755 ; Phrases consist of phrase tokens. These are bytes that encode words, segments 10756 ; (multiple words that fit into a single line of text), and how they are displayed. 10757 ; 10758 ; LOCAL VARIABLES 10759 EOP = $40 ; End of phrase 10760 EOS = $80 ; End of segment 10761 LONG = $C0 ; Display title phrase for a long time 10762 10763 ; Title Phrase Offset, Text 10764 PHRASETAB .BYTE $00 ; (unused) 10765 .BYTE $05,$06,$02!EOP ; $01 "ATTACK COMPUTER ON" 10766 .BYTE $05,$06,$03!EOP ; $04 "ATTACK COMPUTER OFF" 10767 .BYTE $04,$02!EOP ; $07 "SHIELDS ON" 10768 .BYTE $04,$03!EOP ; $09 "SHIELDS OFF" 10769 .BYTE $06,$07,$02!EOP ; $0B "COMPUTER TRACKING ON" 10770 .BYTE $07,$03!EOP ; $0E "TRACKING OFF" 10771 .BYTE $08!EOP ; $10 "WHATS WRONG?" 10772 .BYTE $09,$0A!EOP ; $11 "HYPERWARP ENGAGED" 10773 .BYTE $0B,$0D!LONG ; $13 "STARBASE SURROUNDED" 10774 .BYTE $0B,$0C!LONG ; $15 "STARBASE DESTROYED" 10775 .BYTE $09,$0E!EOP ; $17 "HYPERWARP ABORTED" 10776 .BYTE $09,$0F!EOP ; $19 "HYPERWARP COMPLETE" 10777 .BYTE $10!LONG ; $1B "HYPERSPACE" 10778 .BYTE $11,$12!EOS ; $1C "ORBIT ESTABLISHED" 10779 .BYTE $16!EOP ; $1E "STANDBY" 10780 .BYTE $13,$0E!EOP ; $1F "DOCKING ABORTED" 10781 .BYTE $15,$0F!EOP ; $21 "TRANSFER COMPLETE" 10782 .BYTE $38!EOS ; $23 " " 10783 .BYTE $17!EOS ; $24 "STAR FLEET TO" 10784 .BYTE $19!EOS ; $25 "ALL UNITS" 10785 .BYTE $18!EOS ; $26 "STAR CRUISER 7" 10786 .BYTE $0C!EOS ; $27 "DESTROYED" 10787 .BYTE $1D!EOS ; $28 "BY ZYLON FIRE" 10788 .BYTE $1E,$1F!EOS ; $29 "POSTHUMOUS RANK IS:" 10789 .BYTE $FD ; $2B "" 10790 .BYTE $25,$FC ; $2C "CLASS " 10791 .BYTE $38!EOP ; $2E " " 10792 .BYTE $1B!EOS ; $2F "STAR RAIDERS" 10793 .BYTE $20!EOP ; $30 "COPYRIGHT ATARI 1979" 10794 .BYTE $38!EOS ; $31 " " 10795 .BYTE $17!EOS ; $32 "STAR FLEET TO" 10796 .BYTE $18!EOS ; $33 "STAR CRUISER 7" 10797 .BYTE $1A,$0E!EOS ; $34 "MISSION ABORTED" 10798 .BYTE $1C,$14!EOS ; $36 "ZERO ENERGY" 10799 .BYTE $24,$1F!EOS ; $38 "NEW RANK IS" 10800 .BYTE $FD ; $3A "" 10801 .BYTE $25,$FC ; $3B "CLASS " 10802 .BYTE $27!EOS ; $3D "REPORT TO BASE" 10803 .BYTE $28!EOP ; $3E "FOR TRAINING" 10804 .BYTE $38!EOS ; $3F " " 10805 .BYTE $17!EOS ; $40 "STAR FLEET TO" 10806 .BYTE $18!EOS ; $41 "STAR CRUISER 7" 10807 .BYTE $1A,$0F!EOS ; $42 "MISSION COMPLETE" 10808 .BYTE $24,$1F!EOS ; $44 "NEW RANK IS:" 10809 .BYTE $FD ; $46 "" 10810 .BYTE $25,$FC ; $47 "CLASS " 10811 .BYTE $26!EOP ; $49 "CONGRATULATIONS" 10812 .BYTE $2C,$1A!EOP ; $4A "NOVICE MISSION" 10813 .BYTE $2E,$1A!EOP ; $4C "PILOT MISSION" 10814 .BYTE $31,$1A!EOP ; $4E "WARRIOR MISSION" 10815 .BYTE $33,$1A!EOP ; $50 "COMMANDER MISSION" 10816 .BYTE $38!EOS ; $52 " " 10817 .BYTE $34,$36!EOP ; $53 "DAMAGE CONTROL" 10818 .BYTE $37,$35!EOS ; $55 "PHOTONS DAMAGED" 10819 .BYTE $38!EOP ; $57 " " 10820 .BYTE $37,$0C!EOS ; $58 "PHOTONS DESTROYED" 10821 .BYTE $38!EOP ; $5A " " 10822 .BYTE $23,$35!EOS ; $5B "ENGINES DAMAGED" 10823 .BYTE $38!EOP ; $5D " " 10824 .BYTE $23,$0C!EOS ; $5E "ENGINES DESTROYED" 10825 .BYTE $38!EOP ; $60 " " 10826 .BYTE $04,$35!EOS ; $61 "SHIELDS DAMAGED" 10827 .BYTE $38!EOP ; $63 " " 10828 .BYTE $04,$0C!EOS ; $64 "SHIELDS DESTROYED" 10829 .BYTE $38!EOP ; $66 " " 10830 .BYTE $06,$35!EOS ; $67 "COMPUTER DAMAGED" 10831 .BYTE $38!EOP ; $69 " " 10832 .BYTE $06,$0C!EOS ; $6A "COMPUTER DESTROYED" 10833 .BYTE $38!EOP ; $6C " " 10834 .BYTE $22!EOS ; $6D "SECTOR SCAN" 10835 .BYTE $35!EOP ; $6E "DAMAGED" 10836 .BYTE $22!EOS ; $6F "SECTOR SCAN" 10837 .BYTE $0C!EOP ; $70 "DESTROYED" 10838 .BYTE $21!EOS ; $71 "SUB-SPACE RADIO" 10839 .BYTE $35!EOP ; $72 "DAMAGED" 10840 .BYTE $21!EOS ; $73 "SUB-SPACE RADIO" 10841 .BYTE $0C!EOP ; $74 "DESTROYED" 10842 .BYTE $01!LONG ; $75 "RED ALERT" 10843 .BYTE $38!EOS ; $76 " " 10844 .BYTE $17!EOS ; $77 "STAR FLEET TO" 10845 .BYTE $18!EOS ; $78 "STAR CRUISER 7" 10846 .BYTE $1A,$0E!EOS ; $79 "MISSION ABORTED" 10847 .BYTE $24,$1F!EOS ; $7B "NEW RANK IS:" 10848 .BYTE $FD ; $7D "" 10849 .BYTE $25,$FC ; $7E "CLASS " 10850 .BYTE $26!EOP ; $80 "CONGRATULATIONS" 10851 10852 ;*** Word table **************************************************************** 10853 ; Bit B7 of the first byte of a word is the end-of-word marker of the preceding 10854 ; word 10855 ; 10856 ; LOCAL VARIABLES 10857 EOW = $80 ; End of word 10858 10859 WORDTAB .BYTE EOW!$20," RED ALERT" ; Word $01 10860 .BYTE EOW!'O,"N" ; Word $02 10861 .BYTE EOW!'O,"FF" ; Word $03 10862 .BYTE EOW!'S,"HIELDS" ; Word $04 10863 .BYTE EOW!'A,"TTACK" ; Word $05 10864 .BYTE EOW!'C,"OMPUTER" ; Word $06 10865 .BYTE EOW!'T,"RACKING" ; Word $07 10866 .BYTE EOW!'W,"HATS WRONG?" ; Word $08 10867 .BYTE EOW!'H,"YPERWARP" ; Word $09 10868 .BYTE EOW!'E,"NGAGED" ; Word $0A 10869 .BYTE EOW!'S,"TARBASE" ; Word $0B 10870 .BYTE EOW!'D,"ESTROYED" ; Word $0C 10871 .BYTE EOW!'S,"URROUNDED" ; Word $0D 10872 .BYTE EOW!'A,"BORTED" ; Word $0E 10873 .BYTE EOW!'C,"OMPLETE" ; Word $0F 10874 .BYTE EOW!'H,"YPERSPACE" ; Word $10 10875 .BYTE EOW!'O,"RBIT" ; Word $11 10876 .BYTE EOW!'E,"STABLISHED" ; Word $12 10877 .BYTE EOW!'D,"OCKING" ; Word $13 10878 .BYTE EOW!'E,"NERGY" ; Word $14 10879 .BYTE EOW!'T,"RANSFER" ; Word $15 10880 .BYTE EOW!'S,"TANDBY" ; Word $16 10881 .BYTE EOW!'S,"TAR FLEET TO" ; Word $17 10882 .BYTE EOW!'S,"TAR CRUISER 7" ; Word $18 10883 .BYTE EOW!'A,"LL UNITS" ; Word $19 10884 .BYTE EOW!'M,"ISSION" ; Word $1A 10885 .BYTE EOW!$20," STAR RAIDERS" ; Word $1B 10886 .BYTE EOW!'Z,"ERO" ; Word $1C 10887 .BYTE EOW!'B,"Y ZYLON FIRE" ; Word $1D 10888 .BYTE EOW!'P,"OSTHUMOUS" ; Word $1E 10889 .BYTE EOW!'R,"ANK IS:" ; Word $1F 10890 .BYTE EOW!'C,"OPYRIGHT ATARI 1979" ; Word $20 10891 .BYTE EOW!'S,"UB-SPACE RADIO" ; Word $21 10892 .BYTE EOW!'S,"ECTOR SCAN" ; Word $22 10893 .BYTE EOW!'E,"NGINES" ; Word $23 10894 .BYTE EOW!'N,"EW" ; Word $24 10895 .BYTE EOW!'C,"LASS" ; Word $25 10896 .BYTE EOW!'C,"ONGRATULATIONS" ; Word $26 10897 .BYTE EOW!'R,"EPORT TO BASE" ; Word $27 10898 .BYTE EOW!'F,"OR TRAINING" ; Word $28 10899 .BYTE EOW!'G,"ALACTIC COOK" ; Word $29 10900 .BYTE EOW!'G,"ARBAGE SCOW CAPTAIN" ; Word $2A 10901 .BYTE EOW!'R,"OOKIE" ; Word $2B 10902 .BYTE EOW!'N,"OVICE" ; Word $2C 10903 .BYTE EOW!'E,"NSIGN" ; Word $2D 10904 .BYTE EOW!'P,"ILOT" ; Word $2E 10905 .BYTE EOW!'A,"CE" ; Word $2F 10906 .BYTE EOW!'L,"IEUTENANT" ; Word $30 10907 .BYTE EOW!'W,"ARRIOR" ; Word $31 10908 .BYTE EOW!'C,"APTAIN" ; Word $32 10909 .BYTE EOW!'C,"OMMANDER" ; Word $33 10910 .BYTE EOW!'D,"AMAGE" ; Word $34 10911 .BYTE EOW!'D,"AMAGED" ; Word $35 10912 .BYTE EOW!'C,"ONTROL" ; Word $36 10913 .BYTE EOW!'P,"HOTONS" ; Word $37 10914 .BYTE EOW!$20 ; Word $38 10915 .BYTE EOW!'S,"TAR COMMANDER" ; Word $39 10916 .BYTE EOW!$00 ; 10917 10918 ;*** View modes **************************************************************** 10919 VIEWMODETAB .BYTE $00 ; Front view 10920 .BYTE $01 ; Aft view 10921 .BYTE $40 ; Long-Range Scan view 10922 .BYTE $80 ; Galactic Chart view 10923 10924 ;*** Title phrase offsets of "TRACKING OFF", "SHIELDS OFF", "COMPUTER OFF" ***** 10925 MSGOFFTAB .BYTE $0E ; "TRACKING OFF" 10926 .BYTE $09 ; "SHIELDS OFF" 10927 .BYTE $04 ; "COMPUTER OFF" 10928 10929 ;*** Masks to test if Tracking Computer, Shields, or Attack Computer are on **** 10930 MSGBITTAB .BYTE $FF ; Mask Tracking Computer 10931 .BYTE $08 ; Mask Shields 10932 .BYTE $02 ; Mask Attack Computer 10933 10934 ;*** Title phrase offsets of "COMPUTER TRACKING ON", "SHIELDS ON", "COMPUTER ON" 10935 MSGONTAB .BYTE $0B ; "COMPUTER TRACKING ON" 10936 .BYTE $07 ; "SHIELDS ON" 10937 .BYTE $01 ; "COMPUTER ON" 10938 10939 ;*** The following two tables encode the PLAYER shapes ************************* 10940 ; 10941 ; PHOTON TORPEDO (shape type 0, data in shape table PLSHAP1TAB) 10942 ; Numbers at top indicate the shape table offset of the first and last shape row 10943 ; 10944 ; $01..$10 $11..$1E $1F..$2A $2B..$34 $35..$3C $3D..$42 $75..$76 $7A..$7B 10945 ; ...##... ...#.... ...##... ...#.... ...#.... ...#.... ...##... ...#.... 10946 ; ..####.. ..###... ..####.. ..###... ...##... ..###... ...##... ...#.... 10947 ; .######. .#####.. ..####.. ..###... ..####.. ..###... 10948 ; .######. .#####.. .######. .#####.. ..#.##.. ..#.#... 10949 ; .###.##. #######. .##.###. .###.#.. ..####.. ..###... 10950 ; ####.### ##.####. .####.#. .#####.. ..####.. ...#.... 10951 ; ##.##### ##.##.#. .######. .##.##.. ...##... 10952 ; ##.##### #####.#. .###.##. ..###... ....#... 10953 ; ######## ###.###. .######. ..###... 10954 ; ######## ###.###. ..####.. ...#.... 10955 ; ####.### .#####.. ..####.. 10956 ; .###.##. .#####.. ...##... 10957 ; .######. ..###... 10958 ; .######. ...#.... 10959 ; ..####.. 10960 ; ...##... 10961 ; 10962 ; ZYLON FIGHTER (shape type 1, data in shape table PLSHAP2TAB) 10963 ; Numbers at top indicate the shape table offset of the first and last shape row 10964 ; 10965 ; $01..$0C $0D..$14 $15..$1A $1B..$20 $21..$24 $25..$28 $29..$2A $2B..$2C 10966 ; #......# #.....#. .#....#. .#...#.. ..#..#.. ..#.#... ...##... ...#.... 10967 ; #......# #.....#. .#.##.#. .#.#.#.. ..####.. ..###... ...##... ...#.... 10968 ; #......# #.###.#. .######. .#####.. ..####.. ..###... 10969 ; #......# #######. .######. .#####.. ..#..#.. ..#.#... 10970 ; #.####.# #######. .#.##.#. .#.#.#.. 10971 ; ######## #.###.#. .#....#. .#...#.. 10972 ; ######## #.....#. 10973 ; #.####.# #.....#. 10974 ; #......# 10975 ; #......# 10976 ; #......# 10977 ; #......# 10978 ; 10979 ; STARBASE RIGHT (shape type 2, data in shape table PLSHAP2TAB) 10980 ; Numbers at top indicate the shape table offset of the first and last shape row 10981 ; 10982 ; $2D..$36 $38..$40 $41..$46 $36..$38 $36 $00 $00 $00 10983 ; ###..... ##...... ##...... ##...... ##...... ........ ........ ........ 10984 ; #####... ####.... ##...... ####.... 10985 ; #####... ####.... ####.... ##...... 10986 ; #######. ######.. #.####.. 10987 ; #.#.### #.#####. ####.... 10988 ; #######. ######.. ##...... 10989 ; #####... ####.... 10990 ; #####... #....... 10991 ; ##...... #....... 10992 ; ##...... 10993 ; 10994 ; STARBASE CENTER (shape type 3, data in shape table PLSHAP1TAB) 10995 ; Numbers at top indicate the shape table offset of the first and last shape row 10996 ; 10997 ; $7E..$8D $8E..$9C $9D..$A9 $AA..$B3 $B4..$BB $BC..$C0 $7B..$7D $7A..$7B 10998 ; ...##... ........ ........ ...##... ........ ...##... ...#.... ...#.... 10999 ; .######. ...##... ...##... ..####.. ...##... ..####.. ..###... ...#.... 11000 ; ######## ..####.. ..####.. ######## ..####.. ######## ...#.... 11001 ; ######## .######. .######. ######## ######## ..####.. 11002 ; ######## ######## ######## ###..### ######## ...##... 11003 ; ######## ######## ######## .##..##. ######## 11004 ; ######## ######## ###..### ######## ..####.. 11005 ; ###..### ###..### .##..##. ######## ...##... 11006 ; ###..### .##..##. ######## .######. 11007 ; ######## ######## ######## ..####.. 11008 ; ######## ######## ######## 11009 ; ######## ######## ######## 11010 ; ######## ######## ..####.. 11011 ; ######## .######. 11012 ; .######. .######. 11013 ; .######. 11014 ; 11015 ; STARBASE LEFT (shape type 4, data in shape table PLSHAP2TAB) 11016 ; Numbers at top indicate the shape table offset of the first and last shape row 11017 ; 11018 ; $47..$50 $52..$5A $5B..$60 $50..$52 $50 $00 $00 $00 11019 ; .....### ......## ......## ......## ......## ........ ........ ........ 11020 ; ...##### ....#### ......## ....#### 11021 ; ...##### ....#### ....#### ......## 11022 ; .####### ..###### ..####.# 11023 ; ###.#.#. .#####.# ....#### 11024 ; .####### ..###### ......## 11025 ; ...##### ....#### 11026 ; ...##### .......# 11027 ; ......## .......# 11028 ; ......## 11029 ; 11030 ; TRANSFER VESSEL (shape type 5, data in shape table PLSHAP1TAB) 11031 ; Numbers at top indicate the shape table offset of the first and last shape row 11032 ; 11033 ; $43..$52 $53..$60 $61..$6B $6C..$74 $75..$79 $7A..$7D $75..$76 $7A..$7B 11034 ; ..####.. ...###.. ...##... ...#.... ...##... ...#.... ...##... ...#.... 11035 ; ..####.. ...###.. ...##... ...#.... ...##... ...#.... ...##... ...#.... 11036 ; ..#..#.. ...#.#.. ..####.. ..###... ..####.. ..###... 11037 ; ..####.. ..#####. ..####.. ..###... ...##... ...#.... 11038 ; .######. ..#####. ..####.. ..###... ...##... 11039 ; .######. ..#####. ..####.. .#####.. 11040 ; .######. ..#.#.#. .######. ..#.#... 11041 ; .#.##.#. .####### ..#..#.. ..#.#... 11042 ; ######## .####### ..#..#.. ..#.#... 11043 ; ######## ..#...#. ..#..#.. 11044 ; .#....#. ..#...#. ..#..#.. 11045 ; .#....#. ..#...#. 11046 ; .#....#. ..#...#. 11047 ; .#....#. ..#...#. 11048 ; .#....#. 11049 ; .#....#. 11050 ; 11051 ; METEOR (shape type 6, data in shape table PLSHAP1TAB) 11052 ; Numbers at top indicate the shape table offset of the first and last shape row 11053 ; 11054 ; $01..$10 $11..$1E $1F..$2A $2B..$34 $35..$3C $3D..$42 $75..$76 $7A..$7B 11055 ; ...##... ...#.... ...##... ...#.... ...#.... ...#.... ...##... ...#.... 11056 ; ..####.. ..###... ..####.. ..###... ...##... ..###... ...##... ...#.... 11057 ; .######. .#####.. ..####.. ..###... ..####.. ..###... 11058 ; .######. .#####.. .######. .#####.. ..#.##.. ..#.#... 11059 ; .###.##. #######. .##.###. .###.#.. ..####.. ..###... 11060 ; ####.### ##.####. .####.#. .#####.. ..####.. ...#.... 11061 ; ##.##### ##.##.#. .######. .##.##.. ...##... 11062 ; ##.##### #####.#. .###.##. ..###... ....#... 11063 ; ######## ###.###. .######. ..###... 11064 ; ######## ###.###. ..####.. ...#.... 11065 ; ####.### .#####.. ..####.. 11066 ; .###.##. .#####.. ...##... 11067 ; .######. ..###... 11068 ; .######. ...#.... 11069 ; ..####.. 11070 ; ...##... 11071 ; 11072 ; ZYLON CRUISER (shape type 7, data in shape table PLSHAP2TAB) 11073 ; Numbers at top indicate the shape table offset of the first and last shape row 11074 ; 11075 ; $61..$69 $6A..$71 $72..$78 $79..$7E $7F..$82 $83..$85 $29..$2A $2B..$2C 11076 ; ...##... ...#.... ...##... ...#.... ...##... ...#.... ...##... ...#.... 11077 ; ..####.. ..###... ..####.. ..###... ..####.. ..###... ...##... ...#.... 11078 ; .######. .#####.. ..####.. ..###... ..#..#.. ..#.#... 11079 ; .######. .#####.. .##..##. .##.##.. ..#..#.. 11080 ; ##.##.## ##.#.##. .##..##. .#...#.. 11081 ; ##....## ##...##. .#....#. .#...#.. 11082 ; #......# #.....#. .#....#. 11083 ; #......# #.....#. 11084 ; #......# 11085 ; 11086 ; ZYLON BASESTAR (shape type 8, data in shape table PLSHAP2TAB) 11087 ; Numbers at top indicate the shape table offset of the first and last shape row 11088 ; 11089 ; $86..$8F $90..$99 $9A..$A0 $A1..$A7 $A8..$AC $AD..$B0 $29..$2A $2B..$2C 11090 ; ...##... ...#.... ...##... ...#.... ...##... ...#.... ...##... ...#.... 11091 ; ..####.. ..###... ..####.. ..###... ..####.. ..###... ...##... ...#.... 11092 ; .######. .#####.. .######. .#####.. ...##... ..###... 11093 ; ######## #######. ...##... ...#.... ..####.. ...#.... 11094 ; ...##... ..###... .######. .#####.. ...##... 11095 ; ...##... ..###... ..####.. ..###... 11096 ; ######## #######. ...##... ...#.... 11097 ; .######. .#####.. 11098 ; ..####.. ..###... 11099 ; ...##... ...#.... 11100 ; 11101 ; HYPERWARP TARGET MARKER (shape type 9, data in shape table PLSHAP1TAB) 11102 ; Numbers at top indicate the shape table offset of the first and last shape row 11103 ; 11104 ; $C1..$CC $C1..$CC $C1..$CC $C1..$CC $C1..$CC $C1..$CC $75..$76 $C1..$CC 11105 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ...##... ..#.#... 11106 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ...##... ..#.#... 11107 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11108 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11109 ; ###.###. ###.###. ###.###. ###.###. ###.###. ###.###. ###.###. 11110 ; ........ ........ ........ ........ ........ ........ ........ 11111 ; ........ ........ ........ ........ ........ ........ ........ 11112 ; ###.###. ###.###. ###.###. ###.###. ###.###. ###.###. ###.###. 11113 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11114 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11115 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11116 ; ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... ..#.#... 11117 11118 ;*** Shape type 0..9 offset table (10 shape cell offsets of shape type...) ***** 11119 PLSHAPOFFTAB .BYTE $01,$11,$1F,$2B,$35,$3D,$75,$7A ; ...0 into PLSHAP1TAB 11120 .BYTE $01,$0D,$15,$1B,$21,$25,$29,$2B ; ...1 into PLSHAP2TAB 11121 .BYTE $2D,$38,$41,$36,$36,$00,$00,$00 ; ...2 into PLSHAP2TAB 11122 .BYTE $7E,$8E,$9D,$AA,$B4,$BC,$7B,$7A ; ...3 into PLSHAP1TAB 11123 .BYTE $47,$52,$5B,$50,$50,$00,$00,$00 ; ...4 into PLSHAP2TAB 11124 .BYTE $43,$53,$61,$6C,$75,$7A,$75,$7A ; ...5 into PLSHAP1TAB 11125 .BYTE $01,$11,$1F,$2B,$35,$3D,$75,$7A ; ...6 into PLSHAP1TAB 11126 .BYTE $61,$6A,$72,$79,$7F,$83,$29,$2B ; ...7 into PLSHAP2TAB 11127 .BYTE $86,$90,$9A,$A1,$A8,$AD,$29,$2B ; ...8 into PLSHAP2TAB 11128 .BYTE $C1,$C1,$C1,$C1,$C1,$C1,$75,$C1 ; ...9 into PLSHAP1TAB 11129 11130 ;*** Shape type 0..9 height table (10 shape cell heights of shape type...) ***** 11131 PLSHPHEIGHTTAB .BYTE $0F,$0D,$0B,$09,$07,$05,$01,$01 ; ...0 11132 .BYTE $0B,$07,$05,$05,$03,$03,$01,$01 ; ...1 11133 .BYTE $09,$08,$05,$02,$00,$00,$00,$00 ; ...2 11134 .BYTE $0F,$0E,$0C,$09,$07,$04,$02,$01 ; ...3 11135 .BYTE $09,$08,$05,$02,$00,$00,$00,$00 ; ...4 11136 .BYTE $0F,$0D,$0A,$08,$04,$03,$01,$01 ; ...5 11137 .BYTE $0F,$0D,$0B,$09,$07,$05,$01,$01 ; ...6 11138 .BYTE $08,$07,$06,$05,$03,$02,$01,$01 ; ...7 11139 .BYTE $09,$09,$06,$06,$04,$03,$01,$01 ; ...8 11140 .BYTE $0B,$0B,$0B,$0B,$0B,$0B,$01,$0B ; ...9 11141 11142 ;*** Keyboard codes to switch to Front or Aft view when Tracking Computer is on 11143 TRACKKEYSTAB .BYTE $F8 ; 'F' - Front view 11144 .BYTE $FF ; 'A' - Aft view 11145 11146 ;*** Galactic Chart sector character codes (encoded in custom character set) *** 11147 SECTORCHARTAB .BYTE CCS.BORDERSW ; Empty sector 11148 .BYTE CCS.2ZYLONS ; Sector contains 1 Zylon ship 11149 .BYTE CCS.2ZYLONS ; Sector contains 2 Zylon ships 11150 .BYTE CCS.3ZYLONS ; Sector contains 3 Zylon ships 11151 .BYTE CCS.4ZYLONS ; Sector contains 4 Zylon ships 11152 .BYTE CCS.STARBASE ; Sector contains starbase 11153 11154 ;*** Mask to limit veer-off velocity of Hyperwarp Target Marker in hyperwarp *** 11155 VEERMASKTAB .BYTE NEG!31 ; -31..+31 (unused) 11156 .BYTE NEG!63 ; -63..+63 PILOT mission 11157 .BYTE NEG!95 ; -95..+95 WARRIOR mission 11158 .BYTE NEG!127 ; -127..+127 COMMANDER mission 11159 11160 ;*** Horizontal PLAYER offsets for PLAYER0..1 (STARBASE LEFT, STARBASE RIGHT) ** 11161 PLSTARBAOFFTAB .BYTE -8 ; -8 Player/Missile pixels 11162 .BYTE 8 ; +8 Player/Missile pixels 11163 11164 ;*** Mission bonus table ******************************************************* 11165 BONUSTAB .BYTE 80 ; Mission complete NOVICE mission 11166 .BYTE 76 ; Mission complete PILOT mission 11167 .BYTE 60 ; Mission complete WARRIOR mission 11168 .BYTE 111 ; Mission complete COMMANDER mission 11169 11170 .BYTE 60 ; Mission aborted NOVICE mission 11171 .BYTE 60 ; Mission aborted PILOT mission 11172 .BYTE 50 ; Mission aborted WARRIOR mission 11173 .BYTE 100 ; Mission aborted COMMANDER mission 11174 11175 .BYTE 40 ; Starship destroyed NOVICE mission 11176 .BYTE 50 ; Starship destroyed PILOT mission 11177 .BYTE 40 ; Starship destroyed WARRIOR mission 11178 .BYTE 90 ; Starship destroyed COMMANDER mission 11179 11180 ;*** Title phrase offsets of scored class rank ********************************* 11181 RANKTAB .BYTE $29!EOS ; "GALACTIC COOK" 11182 .BYTE $2A!EOS ; "GARBAGE SCOW CAPTAIN" 11183 .BYTE $2A!EOS ; "GARBAGE SCOW CAPTAIN" 11184 .BYTE $2B!EOS ; "ROOKIE" 11185 .BYTE $2B!EOS ; "ROOKIE" 11186 .BYTE $2C!EOS ; "NOVICE" 11187 .BYTE $2C!EOS ; "NOVICE" 11188 .BYTE $2D!EOS ; "ENSIGN" 11189 .BYTE $2D!EOS ; "ENSIGN" 11190 .BYTE $2E!EOS ; "PILOT" 11191 .BYTE $2E!EOS ; "PILOT" 11192 .BYTE $2F!EOS ; "ACE" 11193 .BYTE $30!EOS ; "LIEUTENANT" 11194 .BYTE $31!EOS ; "WARRIOR" 11195 .BYTE $32!EOS ; "CAPTAIN" 11196 .BYTE $33!EOS ; "COMMANDER" 11197 .BYTE $33!EOS ; "COMMANDER" 11198 .BYTE $39!EOS ; "STAR COMMANDER" 11199 .BYTE $39!EOS ; "STAR COMMANDER" 11200 11201 ;*** Scored class number table ************************************************* 11202 CLASSTAB .BYTE CCS.COL2!ROM.5 ; Class 5 11203 .BYTE CCS.COL2!ROM.5 ; Class 5 11204 .BYTE CCS.COL2!ROM.5 ; Class 5 11205 .BYTE CCS.COL2!ROM.4 ; Class 4 11206 .BYTE CCS.COL2!ROM.4 ; Class 4 11207 .BYTE CCS.COL2!ROM.4 ; Class 4 11208 .BYTE CCS.COL2!ROM.4 ; Class 4 11209 .BYTE CCS.COL2!ROM.3 ; Class 3 11210 .BYTE CCS.COL2!ROM.3 ; Class 3 11211 .BYTE CCS.COL2!ROM.3 ; Class 3 11212 .BYTE CCS.COL2!ROM.2 ; Class 2 11213 .BYTE CCS.COL2!ROM.2 ; Class 2 11214 .BYTE CCS.COL2!ROM.2 ; Class 2 11215 .BYTE CCS.COL2!ROM.1 ; Class 1 11216 .BYTE CCS.COL2!ROM.1 ; Class 1 11217 .BYTE CCS.COL2!ROM.1 ; Class 1 11218 11219 ;*** Title phrase offsets of mission level ************************************* 11220 MISSIONPHRTAB .BYTE $4A ; "NOVICE MISSION" 11221 .BYTE $4C ; "PILOT MISSION" 11222 .BYTE $4E ; "WARRIOR MISSION" 11223 .BYTE $50 ; "COMMANDER MISSION" 11224 11225 ;*** Damage probability of subsystems depending on mission level *************** 11226 DAMAGEPROBTAB .BYTE 0 ; 0% ( 0:256) NOVICE mission 11227 .BYTE 80 ; 31% ( 80:256) PILOT mission 11228 .BYTE 180 ; 70% (180:256) WARRIOR mission 11229 .BYTE 254 ; 99% (254:256) COMMANDER mission 11230 11231 ;*** Title phrase offsets of damaged subsystems ******************************** 11232 DAMAGEPHRTAB .BYTE $55 ; "PHOTON TORPEDOS DAMAGED" 11233 .BYTE $5B ; "ENGINES DAMAGED" 11234 .BYTE $61 ; "SHIELDS DAMAGED" 11235 .BYTE $67 ; "COMPUTER DAMAGED" 11236 .BYTE $6D ; "LONG RANGE SCAN DAMAGED" 11237 .BYTE $71 ; "SUB-SPACE RADIO DAMAGED" 11238 11239 ;*** Title phrase offsets of destroyed subsystems ****************************** 11240 DESTROYPHRTAB .BYTE $58 ; "PHOTON TORPEDOS DESTROYED" 11241 .BYTE $5E ; "ENGINES DESTROYED" 11242 .BYTE $64 ; "SHIELDS DESTROYED" 11243 .BYTE $6A ; "COMPUTER DESTROYED" 11244 .BYTE $6F ; "LONG RANGE SCAN DESTROYED" 11245 .BYTE $73 ; "SUB-SPACE RADIO DESTROYED" 11246 11247 ;*** 3 x 10-byte noise sound patterns (bytes 0..7 stored in reverse order) ***** 11248 ; 11249 ; (9) AUDCTL ($D208) POKEY: Audio control 11250 ; (8) AUDF3 ($D204) POKEY: Audio channel 3 frequency 11251 ; (7) NOISETORPTIM ($DA) Timer for PHOTON TORPEDO LAUNCHED noise sound patterns 11252 ; (6) NOISEEXPLTIM ($DB) Timer for SHIELD and ZYLON EXPLOSION noise sound patterns 11253 ; (5) NOISEAUDC2 ($DC) Audio channel 1/2 control shadow register 11254 ; (4) NOISEAUDC3 ($DD) Audio channel 3 control shadow register 11255 ; (3) NOISEAUDF1 ($DE) Audio channel 1 frequency shadow register 11256 ; (2) NOISEAUDF2 ($DF) Audio channel 2 frequency shadow register 11257 ; (1) NOISEFRQINC ($E0) Audio channel 1/2 frequency increment 11258 ; (0) NOISELIFE ($E1) Noise sound pattern lifetime 11259 ; 11260 ; (0),(1),(2),(3),(4),(5),(6),(7),(8),(9) 11261 NOISEPATTAB .BYTE $18,$FF,$02,$00,$8A,$A0,$00,$08,$50,$00; PHOTON TORPEDO LAUNCHED 11262 .BYTE $40,$40,$01,$03,$88,$AF,$08,$00,$50,$04; SHIELD EXPLOSION 11263 .BYTE $30,$40,$01,$03,$84,$A8,$04,$00,$50,$04; ZYLON EXPLOSION 11264 11265 ;*** 5 x 6-byte beeper sound patterns (bytes 0..5 stored in reverse order) ***** 11266 ; 11267 ; (5) BEEPFRQIND ($D2) Running index into frequency table BEEPFRQTAB ($BF5C) 11268 ; (4) BEEPREPEAT ($D3) Number of times the beeper sound pattern sequence is repeated - 1 11269 ; (3) BEEPTONELIFE ($D4) Lifetime of tone in TICKs - 1 11270 ; (2) BEEPPAUSELIFE ($D5) Lifetime of pause in TICKs - 1 ($FF -> No pause) 11271 ; (1) BEEPPRIORITY ($D6) Beeper sound pattern priority. A playing beeper sound pattern is 11272 ; stopped if a beeper sound pattern of higher priority is about to be 11273 ; played. A value of 0 indicates that no beeper sound pattern is 11274 ; playing at the moment. 11275 ; (0) BEEPFRQSTART ($D7) Index to first byte of the beeper sound pattern frequency in table 11276 ; BEEPFRQTAB ($BF5C) 11277 ; 11278 ; Frequency-over-TICKs diagrams for all beeper sound patterns: 11279 ; 11280 ; HYPERWARP TRANSIT 11281 ; 11282 ; FRQ 11283 ; | 11284 ; $18 |-4-- 11285 ; | 11286 ; $00 | -3- 11287 ; +-------> TICKS 11288 ; <13 x > 11289 ; 11290 ; RED ALERT 11291 ; 11292 ; FRQ 11293 ; | 11294 ; $60 | --------17------- 11295 ; | 11296 ; $40 |--------17------- 11297 ; | 11298 ; +----------------------------------> TICKS 11299 ; <-------------- 8 x -------------> 11300 ; 11301 ; ACKNOWLEDGE 11302 ; 11303 ; FRQ 11304 ; | 11305 ; $10 |-3- -3- -3- 11306 ; | 11307 ; $00 | -3- -3- -3- 11308 ; +------------------> TICKS 11309 ; <------ 1 x -----> 11310 ; 11311 ; DAMAGE REPORT (not to scale) 11312 ; 11313 ; FRQ 11314 ; | 11315 ; $40 |------------33------------- 11316 ; | 11317 ; $20 | ------------33------------- 11318 ; | 11319 ; +------------------------------------------------------> TICKS 11320 ; <------------------------ 3 x -----------------------> 11321 ; 11322 ; MESSAGE FROM STARBASE (not to scale) 11323 ; 11324 ; FRQ 11325 ; | 11326 ; $51 | -----33----- 11327 ; $48 |-----33----- 11328 ; $40 | -----33----- 11329 ; | 11330 ; $00 | --9-- --9-- --9-- 11331 ; +----------------------------------------------------> TICKS 11332 ; <---------------------- 1 x ----------------------> 11333 ; 11334 ; (0),(1),(2),(3),(4),(5) 11335 BEEPPATTAB .BYTE $02,$02,$02,$03,$0C,$02 ; HYPERWARP TRANSIT 11336 .BYTE $04,$03,$FF,$10,$07,$04 ; RED ALERT 11337 .BYTE $07,$04,$02,$02,$00,$07 ; ACKNOWLEDGE 11338 .BYTE $0B,$05,$FF,$20,$02,$0B ; DAMAGE REPORT 11339 .BYTE $0E,$06,$08,$20,$00,$0E ; MESSAGE FROM STARBASE 11340 11341 ;*** Beeper sound pattern frequency table ************************************** 11342 BEEPFRQTAB .BYTE $10,$FF ; (unused) (!) 11343 .BYTE $18,$FF ; HYPERWARP TRANSIT 11344 .BYTE $40,$60,$FF ; RED ALERT 11345 .BYTE $10,$10,$10,$FF ; ACKNOWLEDGE 11346 .BYTE $40,$20,$FF ; DAMAGE REPORT 11347 .BYTE $48,$40,$51,$FF ; MESSAGE FROM STARBASE 11348 11349 ;*** Shape of blip in Attack Computer Display ********************************** 11350 BLIPSHAPTAB .BYTE $84 ; #....#.. 11351 .BYTE $B4 ; #.##.#.. 11352 .BYTE $FC ; ######.. 11353 .BYTE $B4 ; #.##.#.. 11354 .BYTE $84 ; #....#.. 11355 11356 ;*** Initial x-coordinate (high byte) of our starship's photon torpedo ********* 11357 BARRELXTAB .BYTE $FF ; Left barrel = -256 (-$FF00) 11358 .BYTE $01 ; Right barrel = +256 (+$0100) 11359 11360 ;*** Maximum photon torpedo hit z-coordinate (high byte) *********************** 11361 HITMAXZTAB .BYTE $0C ; < 3328 ($0C**) 11362 .BYTE $0C ; < 3328 ($0C**) 11363 .BYTE $0C ; < 3328 ($0C**) 11364 .BYTE $0C ; < 3328 ($0C**) 11365 .BYTE $0E ; < 3840 ($0E**) 11366 .BYTE $0E ; < 3840 ($0E**) 11367 .BYTE $0E ; < 3840 ($0E**) 11368 .BYTE $20 ; < 8448 ($20**) 11369 11370 ;*** Minimum photon torpedo hit z-coordinate (high byte) *********************** 11371 HITMINZTAB .BYTE $00 ; >= 0 ($00**) 11372 .BYTE $00 ; >= 0 ($00**) 11373 .BYTE $00 ; >= 0 ($00**) 11374 .BYTE $02 ; >= 512 ($02**) 11375 .BYTE $04 ; >= 1024 ($04**) 11376 .BYTE $06 ; >= 1536 ($06**) 11377 .BYTE $08 ; >= 2048 ($08**) 11378 .BYTE $0C ; >= 3072 ($0C**) 11379 11380 ;*** Velocity of homing Zylon photon torpedo *********************************** 11381 ZYLONHOMVELTAB .BYTE NEG!1 ; -1 NOVICE mission 11382 .BYTE NEG!4 ; -4 PILOT mission 11383 .BYTE NEG!8 ; -8 WARRIOR mission 11384 .BYTE NEG!20 ; -20 COMMANDER mission 11385 11386 ;*** Zylon shape type table **************************************************** 11387 ZYLONSHAPTAB .BYTE SHAP.ZBASESTAR ; ZYLON BASESTAR 11388 .BYTE SHAP.ZFIGHTER ; ZYLON FIGHTER 11389 .BYTE SHAP.ZFIGHTER ; ZYLON FIGHTER 11390 .BYTE SHAP.ZFIGHTER ; ZYLON FIGHTER 11391 .BYTE SHAP.ZCRUISER ; ZYLON CRUISER 11392 .BYTE SHAP.ZCRUISER ; ZYLON CRUISER 11393 .BYTE SHAP.ZCRUISER ; ZYLON CRUISER 11394 .BYTE SHAP.ZFIGHTER ; ZYLON FIGHTER 11395 11396 ;*** Zylon flight pattern table ************************************************ 11397 ZYLONFLPATTAB .BYTE 4 ; Flight pattern 4 11398 .BYTE 4 ; Flight pattern 4 11399 .BYTE 0 ; Attack Flight Pattern 0 11400 .BYTE 0 ; Attack Flight Pattern 0 11401 .BYTE 0 ; Attack Flight Pattern 0 11402 .BYTE 1 ; Flight pattern 1 11403 .BYTE 0 ; Attack Flight Pattern 0 11404 .BYTE 0 ; Attack Flight Pattern 0 11405 11406 ;*** Zylon velocity table ****************************************************** 11407 ZYLONVELTAB .BYTE 62 ; +62 11408 .BYTE 30 ; +30 11409 .BYTE 16 ; +16 11410 .BYTE 8 ; +8 11411 .BYTE 4 ; +4 11412 .BYTE 2 ; +2 11413 .BYTE 1 ; +1 11414 .BYTE 0 ; 0 11415 .BYTE 0 ; 0 11416 .BYTE NEG!1 ; -1 11417 .BYTE NEG!2 ; -2 11418 .BYTE NEG!4 ; -4 11419 .BYTE NEG!8 ; -8 11420 .BYTE NEG!16 ; -16 11421 .BYTE NEG!30 ; -30 11422 .BYTE NEG!62 ; -62 11423 11424 ;*** PLAYFIELD colors (including PLAYFIELD colors during DLI) ****************** 11425 PFCOLORTAB .BYTE $A6 ; PF0COLOR = {GREEN} 11426 .BYTE $AA ; PF1COLOR = {LIGHT GREEN} 11427 .BYTE $AF ; PF2COLOR = {VERY LIGHT GREEN} 11428 .BYTE $00 ; PF3COLOR = {BLACK} 11429 .BYTE $00 ; BGRCOLOR = {BLACK} 11430 .BYTE $B8 ; PF0COLORDLI = {LIGHT MINT} 11431 .BYTE $5A ; PF1COLORDLI = {MEDIUM PINK} 11432 .BYTE $FC ; PF2COLORDLI = {LIGHT ORANGE} 11433 .BYTE $5E ; PF3COLORDLI = {LIGHT PINK} 11434 .BYTE $90 ; BGRCOLORDLI = {DARK BLUE} 11435 11436 ;*** Vicinity mask table. Confines coordinates of space objects in sector ****** 11437 VICINITYMASKTAB .BYTE $FF ; <= 65535 ($FF**) 11438 .BYTE $FF ; <= 65535 ($FF**) 11439 .BYTE $3F ; <= 16383 ($3F**) 11440 .BYTE $0F ; <= 4095 ($0F**) 11441 .BYTE $3F ; <= 16383 ($3F**) 11442 .BYTE $7F ; <= 32767 ($7F**) 11443 .BYTE $FF ; <= 65535 ($FF**) 11444 .BYTE $FF ; <= 65535 ($FF**) 11445 11446 ;*** Movement probability of sector types in Galactic Chart ******************** 11447 MOVEPROBTAB .BYTE 0 ; Empty sector 0% ( 0:256) 11448 .BYTE 255 ; 1 Zylon ship 100% (255:256) 11449 .BYTE 255 ; 2 Zylon ships 100% (255:256) 11450 .BYTE 192 ; 3 Zylon ships 75% (192:256) 11451 .BYTE 32 ; 4 Zylon ships 13% ( 32:256) 11452 11453 ;*** Galactic Chart sector offset to adjacent sector *************************** 11454 COMPASSOFFTAB .BYTE -16 ; NORTH 11455 .BYTE -17 ; NORTHWEST 11456 .BYTE -1 ; WEST 11457 .BYTE 15 ; SOUTHWEST 11458 .BYTE 16 ; SOUTH 11459 .BYTE 17 ; SOUTHEAST 11460 .BYTE 1 ; EAST 11461 .BYTE -15 ; NORTHEAST 11462 .BYTE 0 ; CENTER 11463 11464 ;*** Homing velocities of photon torpedoes 0..1 depending on distance to target 11465 HOMVELTAB .BYTE 0 ; +0 11466 .BYTE 8 ; +8 11467 .BYTE 16 ; +16 11468 .BYTE 24 ; +24 11469 .BYTE 40 ; +40 11470 .BYTE 48 ; +48 11471 .BYTE 56 ; +56 11472 .BYTE 64 ; +64 11473 11474 ;*** PLAYER shape color table (bits B7..4 of color/brightness) ***************** 11475 PLSHAPCOLORTAB .BYTE $50 ; PHOTON TORPEDO = {PURPLE} 11476 .BYTE $00 ; ZYLON FIGHTER = {GRAY} 11477 .BYTE $20 ; STARBASE RIGHT = {ORANGE} 11478 .BYTE $20 ; STARBASE CENTER = {ORANGE} 11479 .BYTE $20 ; STARBASE LEFT = {ORANGE} 11480 .BYTE $00 ; TRANSFER VESSEL = {GRAY} 11481 .BYTE $A0 ; METEOR = {GREEN} 11482 .BYTE $00 ; ZYLON CRUISER = {GRAY} 11483 .BYTE $00 ; ZYLON BASESTAR = {GRAY} 11484 .BYTE $9F ; HYPERWARP TARGET MARKER = {SKY BLUE} 11485 11486 ;*** PLAYER shape brightness table (bits B3..0 of color/brightness) ************ 11487 PLSHAPBRITTAB .BYTE $0E ; ##############.. 11488 .BYTE $0E ; ##############.. 11489 .BYTE $0E ; ##############.. 11490 .BYTE $0C ; ############.... 11491 .BYTE $0C ; ############.... 11492 .BYTE $0C ; ############.... 11493 .BYTE $0A ; ##########...... 11494 .BYTE $0A ; ##########...... 11495 .BYTE $0A ; ##########...... 11496 .BYTE $08 ; ########........ 11497 .BYTE $08 ; ########........ 11498 .BYTE $08 ; ########........ 11499 .BYTE $06 ; ######.......... 11500 .BYTE $06 ; ######.......... 11501 .BYTE $04 ; ####............ 11502 .BYTE $04 ; ####............ 11503 11504 ;*** PHOTON TORPEDO LAUNCHED noise bit and volume (stored in reverse order) **** 11505 NOISETORPVOLTAB .BYTE $8A ; ##########..... 11506 .BYTE $8F ; ############### 11507 .BYTE $8D ; #############.. 11508 .BYTE $8B ; ###########.... 11509 .BYTE $89 ; #########...... 11510 .BYTE $87 ; #######........ 11511 .BYTE $85 ; ######......... 11512 .BYTE $83 ; ###............ 11513 11514 ;*** PHOTON TORPEDO LAUNCHED noise frequency table (stored in reverse order) *** 11515 NOISETORPFRQTAB .BYTE $00 ; 11516 .BYTE $04 ; 11517 .BYTE $01 ; 11518 .BYTE $04 ; 11519 .BYTE $01 ; 11520 .BYTE $04 ; 11521 .BYTE $01 ; 11522 .BYTE $04 ; 11523 11524 .BYTE $07 ; (unused) 11525 11526 .BYTE $00 ; Always 0 for cartridges 11527 .BYTE $80 ; On SYSTEM RESET jump to INITCOLD via 11528 .WORD INITCOLD ; Cartridge Initialization Address