ORG CODE% LOAD_A% = LOAD%ELITE A FILE.S% \ --- Mod: Code removed for Elite-A: ------------------> \JMP DEEOR \ Decrypt the main flight code and join the main loop \ \JMP DEEOR \ Decrypt the main flight code and start a new game \ \JMP TT26 \ WRCHV is set to point here by elite-loader3.asm \ \EQUW IRQ1 \ IRQ1V is set to point here by elite-loader3.asm \ \JMP BRBR1 \ BRKV is set to point here by elite-loader3.asm \ --- And replaced by: --------------------------------> JMP RSHIPS \ Load a new set of ship blueprints, set the space view \ and jump into the main game loop JMP RSHIPS \ Load a new set of ship blueprints, set the space view \ and jump into the main game loop JMP TT26 \ WRCHV is set to point here by elite-loader.asm EQUW IRQ1 \ IRQ1V is set to point here by elite-loader.asm JMP BRBR1 \ BRKV is set to point here by elite-loader.asm \ --- End of replacement ------------------------------> PRINT "S% workspace (flight) from ", ~S%, "to ", ~P%-1, "inclusive"Name: S% [Show more] Type: Workspace Address: &11E3 to &11F0 Category: Workspaces Summary: Entry points and vector addresses in the main flight codeContext: See this workspace on its own page References: No direct references to this workspace in this source file.INBAY LDX #LO(LTLI) \ Set (Y X) to point to LTLI ("L.1.D", which gets LDY #HI(LTLI) \ modified to "R.1.D" in the DOENTRY routine) JSR OSCLI \ Call OSCLI to run the OS command in LTLI, which *RUNs \ the main docked code in 1.D \ \ Note that this is a JSR rather than a JMP, so if LTLI \ is still set to "L.1.D" (rather than "R.1.D"), \ then once the command has been run and the docked code \ has loaded, execution will continue from the next \ instruction \ \ By this point the 1.D binary has loaded over the \ top of this one, so we don't fall through into the \ LTLI variable (as that's in the flight code), but \ instead we fall through into the DOBEGIN routine in \ the docked code) \ \ This means that if the LTLI command is unchanged, then \ we load the docked code and fall through into DOBEGIN \ to restart the game from the title screen, so by \ default, loading the docked code will restart the game \ \ However if we call DOENTRY in the flight code first, \ then the command in LTLI is changed to the "R.1.D" \ version, which *RUNs the docked code and starts \ execution from the start of the docked binary at S%, \ which contains a JMP DOENTRY instruction that docks at \ the station insteadName: INBAY [Show more] Type: Subroutine Category: Loader Summary: Load and run the main docked code in 1.DContext: See this subroutine on its own page References: This subroutine is called as follows: * DEATH2 calls INBAY.LTLI \ --- Mod: Code removed for Elite-A: ------------------> \EQUS "L.T.CODE" \ This is short for "*LOAD T.CODE" \EQUB 13 \ --- And replaced by: --------------------------------> EQUS "L.1.D" \ This is short for "*LOAD 1.D" EQUB 13 \ --- End of replacement ------------------------------>\ --- Mod: Code removed for Elite-A: ------------------> \.DEEOR \ \IF _STH_DISC OR _IB_DISC \ \LDY #0 \ We're going to work our way through a large number of \ \ encrypted bytes, so we set Y to 0 to be the index of \ \ the current byte within its page in memory \ \STY SC \ Set the low byte of SC(1 0) to 0 \ \LDX #&13 \ Set X to &13 to be the page number of the current \ \ byte, so we start the decryption with the first byte \ \ of page &13 \ \.DEEORL \ \STX SCH \ Set the high byte of SC(1 0) to X, so SC(1 0) now \ \ points to the first byte of page X \ \TYA \ Set A to Y, so A now contains the index of the current \ \ byte within its page \ \EOR (SC),Y \ EOR the current byte with its index within the page \ \EOR #&33 \ EOR the current byte with &33 \ \STA (SC),Y \ Update the current byte \ \ \ The current byte is in page X at offset Y, and SC(1 0) \ \ points to the first byte of page X, so we just did \ \ this: \ \ \ \ (X Y) = (X Y) EOR Y EOR &33 \ \DEY \ Decrement the index in Y to point to the next byte \ \BNE DEEORL \ Loop back to DEEORL to decrypt the next byte until we \ \ have done the whole page \ \INX \ Increment X to point to the next page in memory \ \CPX #&56 \ Loop back to DEEORL to decrypt the next page until we \BNE DEEORL \ reach the start of page &56 \ \JMP RSHIPS \ Call RSHIPS to launch from the station, load a new set \ \ of ship blueprints and jump into the main game loop \ \ELIF _SRAM_DISC \ \JMP RSHIPS \ Call RSHIPS to launch from the station, load a new set \ \ of ship blueprints and jump into the main game loop \ \ENDIF \ --- End of removed code ----------------------------->Name: DEEOR, Removed [Show more] Type: Subroutine Category: Loader Summary: Decrypt the main flight code between &1300 and &55FF and jump into the main game loopContext: See this subroutine on its own page References: No direct references to this subroutine in this source file.DOENTRY LDA #'R' \ Modify the command in LTLI from "L.1.D" to "R.1.D" so STA LTLI \ it *RUNs the code rather than loading it \ \ This ensures that when we load the docked code, then \ instead of continuing execution following a *LOAD, \ which would restart the game by falling through into \ the DOBEGIN routine in the docked code, we instead \ jump to the start of the docked code at S%, which \ jumps to the docked DOENTRY routine to dock with the \ space station \ Fall into DEATH2 to reset most variables and *RUN the \ docked codeName: DOENTRY [Show more] Type: Subroutine Category: Loader Summary: Load and run the docked codeContext: See this subroutine on its own page References: This subroutine is called as follows: * Main flight loop (Part 9 of 16) calls DOENTRY.DEATH2 JSR RES2 \ Reset a number of flight variables and workspaces \ and fall through into the entry code for the game \ to restart from the title screen \ --- Mod: Code removed for Elite-A: ------------------> \JSR CATD \ Call CATD to reload the disc catalogue \ \BNE INBAY \ Jump to INBAY to load the docked code (this BNE is \ \ effectively a JMP) \ --- And replaced by: --------------------------------> BMI INBAY \ Jump to INBAY to load the docked code (this BMI is \ effectively a JMP) \ --- End of replacement ------------------------------>Name: DEATH2 [Show more] Type: Subroutine Category: Start and end Summary: Reset most of the game and restart from the title screenContext: See this subroutine on its own page References: This subroutine is called as follows: * DEATH calls DEATH2 * DK4 calls DEATH2
This routine is called following death, and when the game is quit by pressing ESCAPE when paused..M% LDA K% \ We want to seed the random number generator with a \ pretty random number, so fetch the contents of K%, \ which is the x_lo coordinate of the planet. This value \ will be fairly unpredictable, so it's a pretty good \ candidate STA RAND \ Store the seed in the first byte of the four-byte \ random number seed that's stored in RANDName: Main flight loop (Part 1 of 16) [Show more] Type: Subroutine Category: Main loop Summary: Seed the random number generator Deep dive: Program flow of the main game loop Generating random numbersContext: See this subroutine on its own page References: This subroutine is called as follows: * DEATH calls via M% * Main game loop (Part 2 of 6) calls via M%
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Seed the random number generator
Other entry points: M% The entry point for the main flight loopLDX JSTX \ Set X to the current rate of roll in JSTX \ --- Mod: Code added for Elite-A: --------------------> CPX new_max \ If X < new_max (where new_max is our current ship's BCC n_highx \ maximum roll rate), then jump to n_highx to skip the \ following instruction LDX new_max \ X is at least new_max, so set X to new_max so it is \ never higher than our current ship's maximum roll rate .n_highx CPX new_min \ If X >= new_min (where new_min is our current ship's BCS n_lowx \ minimum roll rate), then jump to n_lowx to skip the \ following instruction LDX new_min \ X is less than new_min, so set X to new_min so it is \ never lower than our current ship's minimum roll rate .n_lowx \ --- End of added code -------------------------------> JSR cntr \ Apply keyboard damping twice (if enabled) so the roll JSR cntr \ rate in X creeps towards the centre by 2 \ The roll rate in JSTX increases if we press ">" (and \ the RL indicator on the dashboard goes to the right) \ \ This rolls our ship to the right (clockwise), but we \ actually implement this by rolling everything else \ to the left (anti-clockwise), so a positive roll rate \ in JSTX translates to a negative roll angle alpha TXA \ Set A and Y to the roll rate but with the sign bit EOR #%10000000 \ flipped (i.e. set them to the sign we want for alpha) TAY AND #%10000000 \ Extract the flipped sign of the roll rate and store STA ALP2 \ in ALP2 (so ALP2 contains the sign of the roll angle \ alpha) STX JSTX \ Update JSTX with the damped value that's still in X EOR #%10000000 \ Extract the correct sign of the roll rate and store STA ALP2+1 \ in ALP2+1 (so ALP2+1 contains the flipped sign of the \ roll angle alpha) TYA \ Set A to the roll rate but with the sign bit flipped BPL P%+7 \ If the value of A is positive, skip the following \ three instructions EOR #%11111111 \ A is negative, so change the sign of A using two's CLC \ complement so that A is now positive and contains ADC #1 \ the absolute value of the roll rate, i.e. |JSTX| LSR A \ Divide the (positive) roll rate in A by 4 LSR A CMP #8 \ If A >= 8, skip the following instruction BCS P%+3 LSR A \ A < 8, so halve A again STA ALP1 \ Store A in ALP1, so we now have: \ \ ALP1 = |JSTX| / 8 if |JSTX| < 32 \ \ ALP1 = |JSTX| / 4 if |JSTX| >= 32 \ \ This means that at lower roll rates, the roll angle is \ reduced closer to zero than at higher roll rates, \ which gives us finer control over the ship's roll at \ lower roll rates \ \ Because JSTX is in the range -127 to +127, ALP1 is \ in the range 0 to 31 ORA ALP2 \ Store A in ALPHA, but with the sign set to ALP2 (so STA ALPHA \ ALPHA has a different sign to the actual roll rate) LDX JSTY \ Set X to the current rate of pitch in JSTY \ --- Mod: Code added for Elite-A: --------------------> CPX new_max \ If X < new_max (where new_max is our current ship's BCC n_highy \ maximum pitch rate), then jump to n_highy to skip the \ following instruction LDX new_max \ X is at least new_max, so set X to new_max so it is \ never higher than our current ship's maximum pitch \ rate .n_highy CPX new_min \ If X >= new_min (where new_min is our current ship's BCS n_lowy \ minimum pitch rate), then jump to n_lowy to skip the \ following instruction LDX new_min \ X is less than new_min, so set X to new_min so it is \ never lower than our current ship's minimum pitch rate .n_lowy \ --- End of added code -------------------------------> JSR cntr \ Apply keyboard damping so the pitch rate in X creeps \ towards the centre by 1 TXA \ Set A and Y to the pitch rate but with the sign bit EOR #%10000000 \ flipped TAY AND #%10000000 \ Extract the flipped sign of the pitch rate into A STX JSTY \ Update JSTY with the damped value that's still in X STA BET2+1 \ Store the flipped sign of the pitch rate in BET2+1 EOR #%10000000 \ Extract the correct sign of the pitch rate and store STA BET2 \ it in BET2 TYA \ Set A to the pitch rate but with the sign bit flipped BPL P%+4 \ If the value of A is positive, skip the following \ instruction EOR #%11111111 \ A is negative, so flip the bits ADC #4 \ Add 4 to the (positive) pitch rate, so the maximum \ value is now up to 131 (rather than 127) LSR A \ Divide the (positive) pitch rate in A by 16 LSR A LSR A LSR A CMP #3 \ If A >= 3, skip the following instruction BCS P%+3 LSR A \ A < 3, so halve A again STA BET1 \ Store A in BET1, so we now have: \ \ BET1 = |JSTY| / 32 if |JSTY| < 48 \ \ BET1 = |JSTY| / 16 if |JSTY| >= 48 \ \ This means that at lower pitch rates, the pitch angle \ is reduced closer to zero than at higher pitch rates, \ which gives us finer control over the ship's pitch at \ lower pitch rates \ \ Because JSTY is in the range -131 to +131, BET1 is in \ the range 0 to 8 ORA BET2 \ Store A in BETA, but with the sign set to BET2 (so STA BETA \ BETA has the same sign as the actual pitch rate) \ --- Mod: Code removed for Elite-A: ------------------> \LDA BSTK \ If BSTK = 0 then the Bitstik is not configured, so \BEQ BS2 \ jump to BS2 to skip the following \ \LDX #3 \ Call OSBYTE with A = 128 to fetch the 16-bit value \LDA #128 \ from ADC channel 3 (the Bitstik rotation value), \JSR OSBYTE \ returning the value in (Y X) \ \TYA \ Copy Y to A, so the result is now in (A X) \ \LSR A \ Divide A by 4 \LSR A \ \CMP #40 \ If A < 40, skip the following instruction \BCC P%+4 \ \LDA #40 \ Set A = 40, which ensures a maximum speed of 40 \ \STA DELTA \ Update our speed in DELTA \ \BNE MA4 \ If the speed we just set is non-zero, then jump to MA4 \ \ to skip the following, as we don't need to check the \ \ keyboard for speed keys, otherwise do check the \ \ keyboard (so Bitstik users can still use the keyboard \ \ for speed adjustments if they twist the stick to zero) \ --- End of removed code ----------------------------->Name: Main flight loop (Part 2 of 16) [Show more] Type: Subroutine Category: Main loop Summary: Calculate the alpha and beta angles from the current pitch and roll of our ship Deep dive: Program flow of the main game loop Pitching and rollingContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Calculate the alpha and beta angles from the current pitch and roll Here we take the current rate of pitch and roll, as set by the joystick or keyboard, and convert them into alpha and beta angles that we can use in the matrix functions to rotate space around our ship. The alpha angle covers roll, while the beta angle covers pitch (there is no yaw in this version of Elite). The angles are in radians, which allows us to use the small angle approximation when moving objects in the sky (see the MVEIT routine for more on this). Also, the signs of the two angles are stored separately, in both the sign and the flipped sign, as this makes calculations easier.\ --- Mod: Code removed for Elite-A: ------------------> \.BS2 \ --- End of removed code -----------------------------> LDA KY2 \ If Space is being pressed, keep going, otherwise jump BEQ MA17 \ down to MA17 to skip the following \ --- Mod: Code removed for Elite-A: ------------------> \LDA DELTA \ The "go faster" key is being pressed, so first we \CMP #40 \ fetch the current speed from DELTA into A, and if \BCS MA17 \ A >= 40, we are already going at full pelt, so jump \ \ down to MA17 to skip the following \ \INC DELTA \ We can go a bit faster, so increment the speed in \ \ location DELTA \ --- And replaced by: --------------------------------> LDA DELTA \ The "go faster" key is being pressed, so first we CMP new_speed \ fetch the current speed from DELTA into A, and if BCC speed_up \ A < new_speed (the maximum speed of our current ship), \ then we can go a bit faster, so jump to speed_up to \ accelerate \ --- End of replacement ------------------------------> .MA17 LDA KY1 \ If "?" is being pressed, keep going, otherwise jump BEQ MA4 \ down to MA4 to skip the following DEC DELTA \ The "slow down" key is being pressed, so we decrement \ the current ship speed in DELTA BNE MA4 \ If the speed is still greater than zero, jump to MA4 \ --- Mod: Code added for Elite-A: --------------------> .speed_up \ --- End of added code -------------------------------> INC DELTA \ Otherwise we just braked a little too hard, so bump \ the speed back up to the minimum value of 1 .MA4 LDA KY15 \ If "U" is being pressed and the number of missiles AND NOMSL \ in NOMSL is non-zero, keep going, otherwise jump down BEQ MA20 \ to MA20 to skip the following LDY #&EE \ The "disarm missiles" key is being pressed, so call JSR ABORT \ ABORT to disarm the missile and update the missile \ indicators on the dashboard to green/cyan (Y = &EE) \ --- Mod: Code removed for Elite-A: ------------------> \LDA #40 \ Call the NOISE routine with A = 40 to make a low, \JSR NOISE \ long beep to indicate the missile is now disarmed \ \.MA31 \ --- And replaced by: --------------------------------> JSR WA1 \ Call the WA1 routine to make a low, long beep to \ indicate the missile is now disarmed \ --- End of replacement ------------------------------> LDA #0 \ Set MSAR to 0 to indicate that no missiles are STA MSAR \ currently armed .MA20 LDA MSTG \ If MSTG is positive (i.e. it does not have bit 7 set), BPL MA25 \ then it indicates we already have a missile locked on \ a target (in which case MSTG contains the ship number \ of the target), so jump to MA25 to skip targeting. Or \ to put it another way, if MSTG = &FF, which means \ there is no current target lock, keep going LDA KY14 \ If "T" is being pressed, keep going, otherwise jump BEQ MA25 \ down to MA25 to skip the following LDX NOMSL \ If the number of missiles in NOMSL is zero, jump down BEQ MA25 \ to MA25 to skip the following STA MSAR \ The "target missile" key is being pressed and we have \ at least one missile, so set MSAR = &FF to denote that \ our missile is currently armed (we know A has the \ value &FF, as we just loaded it from MSTG and checked \ that it was negative) \ --- Mod: Code removed for Elite-A: ------------------> \LDY #&E0 \ Change the leftmost missile indicator to yellow/white \JSR MSBAR \ on the missile bar (this call changes the leftmost \ \ indicator because we set X to the number of missiles \ \ in NOMSL above, and the indicators are numbered from \ \ right to left, so X is the number of the leftmost \ \ indicator) \ --- And replaced by: --------------------------------> LDY #&E0 \ Change the leftmost missile indicator to yellow/white DEX \ on the missile bar (this call changes the leftmost JSR MSBAR \ indicator because we set X to the number of missiles \ in NOMSL above, and the indicators are numbered from \ right to left, starting at 0, so X - 1 is the number \ of the leftmost indicator) \ --- End of replacement ------------------------------> .MA25 LDA KY16 \ If "M" is being pressed, keep going, otherwise jump BEQ MA24 \ down to MA24 to skip the following LDA MSTG \ If MSTG = &FF then there is no target lock, so jump to BMI MA64 \ MA64 to skip the following (also skipping the checks \ for TAB, ESCAPE, "J" and "E") JSR FRMIS \ The "fire missile" key is being pressed and we have \ a missile lock, so call the FRMIS routine to fire \ the missile .MA24 \ --- Mod: Code removed for Elite-A: ------------------> \LDA KY12 \ If TAB is being pressed, keep going, otherwise jump \BEQ MA76 \ down to MA76 to skip the following \ \ASL BOMB \ The "energy bomb" key is being pressed, so double \ \ the value in BOMB. If we have an energy bomb fitted, \ \ BOMB will contain &7F (%01111111) before this shift \ \ and will contain &FE (%11111110) after the shift; if \ \ we don't have an energy bomb fitted, BOMB will still \ \ contain 0. The bomb explosion is dealt with in the \ \ MAL1 routine below - this just registers the fact that \ \ we've set the bomb ticking \ --- And replaced by: --------------------------------> LDA KY12 \ If TAB is not being pressed (i.e. KY12 = 0) and we do AND BOMB \ not have a hyperspace unit fitted (i.e. BOMB = 0), BEQ MA76 \ jump down to MA76 to skip the following INC BOMB \ The "hyperspace unit" key is being pressed and we have \ a hyperspace unit fitted, so increment BOMB from &FF \ (hyperspace unit fitted) to 0 (hyperspace unit not \ fitted), as it is a single-use item and we are now \ using it INC new_hold \ Free up one tonne of space in the hold, as we have \ just used up the hyperspace unit JSR DORND \ Set A and X to random numbers STA QQ9 \ Set (QQ9, QQ10) to (A, X), so we jump to a random STX QQ10 \ point in the galaxy JSR TT111 \ Select the system closest to galactic coordinates \ (QQ9, QQ10) JSR hyper_snap \ Call hyper_snap to perform a hyperspace, but without \ using up any fuel \ --- End of replacement ------------------------------> .MA76 \ --- Mod: Code removed for Elite-A: ------------------> \LDA KY20 \ If "P" is being pressed, keep going, otherwise skip \BEQ MA78 \ the next two instructions \ \LDA #0 \ The "cancel docking computer" key is bring pressed, \STA auto \ so turn it off by setting auto to 0 \ --- And replaced by: --------------------------------> LDA KY19 \ If "C" is being pressed, and we have a docking AND DKCMP \ computer fitted, then KY19 and DKCMP will both be &FF, BNE dock_toggle \ so jump down to dock_toggle with A set to &FF LDA KY20 \ If "P" is being pressed, keep going, otherwise skip BEQ MA78 \ the next two instructions LDA #0 \ The "cancel docking computer" key is bring pressed, \ so turn it off by setting A to 0, so we set auto to 0 \ in the next instruction .dock_toggle STA auto \ Set auto to the value in A, which will be &FF if we \ just turned on the docking computer, or 0 if we just \ turned it off \ --- End of replacement ------------------------------> .MA78 LDA KY13 \ If ESCAPE is being pressed and we have an escape pod AND ESCP \ fitted, keep going, otherwise jump to noescp to skip BEQ noescp \ the following instructions JMP ESCAPE \ The button is being pressed to launch an escape pod \ and we have an escape pod fitted, so jump to ESCAPE to \ launch it, and exit the main flight loop using a tail \ call .noescp LDA KY18 \ If "J" is being pressed, keep going, otherwise skip BEQ P%+5 \ the next instruction JSR WARP \ Call the WARP routine to do an in-system jump LDA KY17 \ If "E" is being pressed and we have an E.C.M. fitted, AND ECM \ keep going, otherwise jump down to MA64 to skip the BEQ MA64 \ following LDA ECMA \ If ECMA is non-zero, that means an E.C.M. is already BNE MA64 \ operating and is counting down (this can be either \ our E.C.M. or an opponent's), so jump down to MA64 to \ skip the following (as we can't have two E.C.M. \ systems operating at the same time) DEC ECMP \ The E.C.M. button is being pressed and nobody else \ is operating their E.C.M., so decrease the value of \ ECMP to make it non-zero, to denote that our E.C.M. \ is now on JSR ECBLB2 \ Call ECBLB2 to light up the E.C.M. indicator bulb on \ the dashboard, set the E.C.M. countdown timer to 32, \ and start making the E.C.M. sound .MA64 \ --- Mod: Code removed for Elite-A: ------------------> \LDA KY19 \ If "C" is being pressed, and we have a docking \AND DKCMP \ computer fitted, keep going, otherwise jump down to \BEQ MA68 \ MA68 to skip the following \ \STA auto \ Set auto to the non-zero value of A, so the docking \ \ computer is activated \ --- End of removed code -----------------------------> .MA68 LDA #0 \ Set LAS = 0, to switch the laser off while we do the STA LAS \ following logic STA DELT4 \ Take the 16-bit value (DELTA 0) - i.e. a two-byte LDA DELTA \ number with DELTA as the high byte and 0 as the low LSR A \ byte - and divide it by 4, storing the 16-bit result ROR DELT4 \ in DELT4(1 0). This has the effect of storing the LSR A \ current speed * 64 in the 16-bit location DELT4(1 0) ROR DELT4 STA DELT4+1 LDA LASCT \ If LASCT is zero, keep going, otherwise the laser is BNE MA3 \ a pulse laser that is between pulses, so jump down to \ MA3 to skip the following LDA KY7 \ If "A" is being pressed, keep going, otherwise jump BEQ MA3 \ down to MA3 to skip the following LDA GNTMP \ If the laser temperature >= 242 then the laser has CMP #242 \ overheated, so jump down to MA3 to skip the following BCS MA3 LDX VIEW \ If the current space view has a laser fitted (i.e. the LDA LASER,X \ laser power for this view is greater than zero), then BEQ MA3 \ keep going, otherwise jump down to MA3 to skip the \ following \ If we get here, then the "fire" button is being \ pressed, our laser hasn't overheated and isn't already \ being fired, and we actually have a laser fitted to \ the current space view, so it's time to hit me with \ those laser beams PHA \ Store the current view's laser power on the stack \ --- Mod: Code removed for Elite-A: ------------------> \AND #%01111111 \ Set LAS and LAS2 to bits 0-6 of the laser power \STA LAS \STA LAS2 \ --- And replaced by: --------------------------------> AND #%01111111 \ Set LAS and LAS2 to bits 0-6 of the laser power STA LAS2 STA LAS \ --- End of replacement ------------------------------> LDA #0 \ Call the NOISE routine with A = 0 to make the sound JSR NOISE \ of our laser firing JSR LASLI \ Call LASLI to draw the laser lines PLA \ Restore the current view's laser power into A BPL ma1 \ If the laser power has bit 7 set, then it's an "always \ on" laser rather than a pulsing laser, so keep going, \ otherwise jump down to ma1 to skip the following \ instruction LDA #0 \ This is an "always on" laser (i.e. a beam laser or a \ military laser), so set A = 0, which will be stored in \ LASCT to denote that this is not a pulsing laser .ma1 \ --- Mod: Code removed for Elite-A: ------------------> \AND #%11111010 \ LASCT will be set to 0 for beam lasers, and to the \STA LASCT \ laser power AND %11111010 for pulse lasers, which \ \ comes to 10 (as pulse lasers have a power of 15). See \ \ MA23 below for more on laser pulsing and LASCT \ --- And replaced by: --------------------------------> STA LASCT \ LASCT will be set to 0 for beam lasers, and to the \ laser power (15) for pulse lasers. See MS23 below \ for more on laser pulsing and LASCT \ --- End of replacement ------------------------------>Name: Main flight loop (Part 3 of 16) [Show more] Type: Subroutine Category: Main loop Summary: Scan for flight keys and process the results Deep dive: Program flow of the main game loop The key loggerContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Scan for flight keys and process the results Flight keys are logged in the key logger at location KY1 onwards, with a non-zero value in the relevant location indicating a key press. See the deep dive on "The key logger" for more details. The key presses that are processed are as follows: * Space and "?" to speed up and slow down * "U", "T" and "M" to disarm, arm and fire missiles * TAB to activate the hyperspace unit * ESCAPE to launch an escape pod * "J" to initiate an in-system jump * "E" to deploy E.C.M. anti-missile countermeasures * "C" to use the docking computer * "A" to fire lasers.MA3 LDX #0 \ We're about to work our way through all the ships in \ our local bubble of universe, so set a counter in X, \ starting from 0, to refer to each ship slot in turn .MAL1 STX XSAV \ Store the current slot number in XSAV LDA FRIN,X \ Fetch the contents of this slot into A. If it is 0 BNE P%+5 \ then this slot is empty and we have no more ships to JMP MA18 \ process, so jump to MA18 below, otherwise A contains \ the type of ship that's in this slot, so skip over the \ JMP MA18 instruction and keep going STA TYPE \ Store the ship type in TYPE JSR GINF \ Call GINF to fetch the address of the ship data block \ for the ship in slot X and store it in INF. The data \ block is in the K% workspace, which is where all the \ ship data blocks are stored \ Next we want to copy the ship data block from INF to \ the zero-page workspace at INWK, so we can process it \ more efficiently LDY #NI%-1 \ There are NI% bytes in each ship data block (and in \ the INWK workspace, so we set a counter in Y so we can \ loop through them .MAL2 LDA (INF),Y \ Load the Y-th byte of INF and store it in the Y-th STA INWK,Y \ byte of INWK DEY \ Decrement the loop counter BPL MAL2 \ Loop back for the next byte until we have copied the \ last byte from INF to INWK LDA TYPE \ If the ship type is negative then this indicates a BMI MA21 \ planet or sun, so jump down to MA21, as the next bit \ sets up a pointer to the ship blueprint, which doesn't \ apply to planets and suns ASL A \ Set Y = ship type * 2 TAY LDA XX21-2,Y \ The ship blueprints at XX21 start with a lookup STA XX0 \ table that points to the individual ship blueprints, \ so this fetches the low byte of this particular ship \ type's blueprint and stores it in XX0 LDA XX21-1,Y \ Fetch the high byte of this particular ship type's STA XX0+1 \ blueprint and store it in XX0+1 \ We now go straight to part 6, omitting part 5 from the \ original disc version, as part 5 implements the energy \ bomb, and Elite-A replaces the energy bomb with the \ hyperspace unitName: Main flight loop (Part 4 of 16) [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: Copy the ship's data block from K% to the zero-page workspace at INWK Deep dive: Program flow of the main game loop Ship data blocksContext: See this subroutine on its own page References: This subroutine is called as follows: * KS1 calls via MAL1 * Main flight loop (Part 12 of 16) calls via MAL1
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Start looping through all the ships in the local bubble, and for each one: * Copy the ship's data block from K% to INWK * Set XX0 to point to the ship's blueprint (if this is a ship)
Other entry points: MAL1 Marks the beginning of the ship analysis loop, so we can jump back here from part 12 of the main flight loop to work our way through each ship in the local bubble. We also jump back here when a ship is removed from the bubble, so we can continue processing from the next ship\ --- Mod: Code removed for Elite-A: ------------------> \LDA BOMB \ If we set off our energy bomb (see MA24 above), then \BPL MA21 \ BOMB is now negative, so this skips to MA21 if our \ \ energy bomb is not going off \ \CPY #2*SST \ If the ship in Y is the space station, jump to BA21 \BEQ MA21 \ as energy bombs are useless against space stations \ \LDA INWK+31 \ If the ship we are checking has bit 5 set in its ship \AND #%00100000 \ byte #31, then it is already exploding, so jump to \BNE MA21 \ BA21 as ships can't explode more than once \ \ASL INWK+31 \ The energy bomb is killing this ship, so set bit 7 of \SEC \ the ship byte #31 to indicate that it has now been \ROR INWK+31 \ killed \ \JSR EXNO2 \ Call EXNO2 to process the fact that we have killed a \ \ ship (so increase the kill tally, make an explosion \ \ sound and possibly display "RIGHT ON COMMANDER!") \ --- End of removed code ----------------------------->Name: Main flight loop (Part 5 of 16), Removed [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: If an energy bomb has been set off, potentially kill this ship Deep dive: Program flow of the main game loopContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Continue looping through all the ships in the local bubble, and for each one: * If an energy bomb has been set off and this ship can be killed, kill it and increase the kill tally.MA21 JSR MVEIT \ Call MVEIT to move the ship we are processing in space \ Now that we are done processing this ship, we need to \ copy the ship data back from INWK to the correct place \ in the K% workspace. We already set INF in part 4 to \ point to the ship's data block in K%, so we can simply \ do the reverse of the copy we did before, this time \ copying from INWK to INF LDY #NI%-1 \ Set a counter in Y so we can loop through the NI% \ bytes in the ship data block .MAL3 LDA INWK,Y \ Load the Y-th byte of INWK and store it in the Y-th STA (INF),Y \ byte of INF DEY \ Decrement the loop counter BPL MAL3 \ Loop back for the next byte, until we have copied the \ last byte from INWK back to INFName: Main flight loop (Part 6 of 16) [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: Move the ship in space and copy the updated INWK data block back to K% Deep dive: Program flow of the main game loop Program flow of the ship-moving routine Ship data blocksContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Continue looping through all the ships in the local bubble, and for each one: * Move the ship in space * Copy the updated ship's data block from INWK back to K%LDA INWK+31 \ Fetch the status of this ship from bits 5 (is ship AND #%10100000 \ exploding?) and bit 7 (has ship been killed?) from \ ship byte #31 into A JSR MAS4 \ Or this value with x_hi, y_hi and z_hi BNE MA65 \ If this value is non-zero, then either the ship is \ far away (i.e. has a non-zero high byte in at least \ one of the three axes), or it is already exploding, \ or has been flagged as being killed - in which case \ jump to MA65 to skip the following, as we can't dock \ scoop or collide with it LDA INWK \ Set A = (x_lo OR y_lo OR z_lo), and if bit 7 of the ORA INWK+3 \ result is set, the ship is still a fair distance ORA INWK+6 \ away (further than 127 in at least one axis), so jump BMI MA65 \ to MA65 to skip the following, as it's too far away to \ dock, scoop or collide with LDX TYPE \ If the current ship type is negative then it's either BMI MA65 \ a planet or a sun, so jump down to MA65 to skip the \ following, as we can't dock with it or scoop it CPX #SST \ If this ship is the space station, jump to ISDK to BEQ ISDK \ check whether we are docking with it AND #%11000000 \ If bit 6 of (x_lo OR y_lo OR z_lo) is set, then the BNE MA65 \ ship is still a reasonable distance away (further than \ 63 in at least one axis), so jump to MA65 to skip the \ following, as it's too far away to dock, scoop or \ collide with CPX #MSL \ If this ship is a missile, jump down to MA65 to skip BEQ MA65 \ the following, as we can't scoop or dock with a \ missile, and it has its own dedicated collision \ checks in the TACTICS routine LDA BST \ If we have fuel scoops fitted then BST will be &FF, \ otherwise it will be 0 AND INWK+5 \ Ship byte #5 contains the y_sign of this ship, so a \ negative value here means the canister is below us, \ which means the result of the AND will be negative if \ the canister is below us and we have a fuel scoop \ fitted BPL MA58 \ If the result is positive, then we either have no \ scoop or the canister is above us, and in both cases \ this means we can't scoop the item, so jump to MA58 \ to process a collisionName: Main flight loop (Part 7 of 16) [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: Check whether we are docking, scooping or colliding with it Deep dive: Program flow of the main game loopContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Continue looping through all the ships in the local bubble, and for each one: * Check how close we are to this ship and work out if we are docking, scooping or colliding with itCPX #OIL \ If this is a cargo canister, jump to oily to randomly BEQ oily \ decide the canister's contents LDY #0 \ Fetch byte #0 of the ship's blueprint LDA (XX0),Y LSR A \ Shift it right four times, so A now contains the high LSR A \ nibble (i.e. bits 4-7) LSR A LSR A BEQ MA58 \ If A = 0, jump to MA58 to skip all the docking and \ scooping checks \ Only the Thargon, alloy plate, splinter and escape pod \ have non-zero high nibbles in their blueprint byte #0 \ so if we get here, our ship is one of those, and the \ high nibble gives the market item number of the item \ when scooped, less 1 ADC #1 \ Add 1 to the high nibble to get the market item \ number BNE slvy2 \ Skip to slvy2 so we scoop the ship as a market item .oily \ --- Mod: Code removed for Elite-A: ------------------> \JSR DORND \ Set A and X to random numbers and reduce A to a \AND #7 \ random number in the range 0-7 \ --- And replaced by: --------------------------------> JSR DORND \ Set A and X to random numbers and reduce A to a AND #15 \ random number in the range 0-15 \ --- End of replacement ------------------------------> .slvy2 \ --- Mod: Code removed for Elite-A: ------------------> \ \ By the time we get here, we are scooping, and A \ \ contains the type of item we are scooping (a random \ \ number 0-7 if we are scooping a cargo canister, 3 if \ \ we are scooping an escape pod, or 16 if we are \ \ scooping a Thargon). These numbers correspond to the \ \ relevant market items (see QQ23 for a list), so a \ \ cargo canister can contain anything from food to \ \ computers, while escape pods contain slaves, and \ \ Thargons become alien items when scooped \ \JSR tnpr1 \ Call tnpr1 with the scooped cargo type stored in A \ \ to work out whether we have room in the hold for one \ \ tonne of this cargo (A is set to 1 by this call, and \ \ the C flag contains the result) \ \LDY #78 \ This instruction has no effect, so presumably it used \ \ to do something, but didn't get removed \ \BCS MA59 \ If the C flag is set then we have no room in the hold \ \ for the scooped item, so jump down to MA59 make a \ \ sound to indicate failure, before destroying the \ \ canister \ \LDY QQ29 \ Scooping was successful, so set Y to the type of \ \ item we just scooped, which we stored in QQ29 above \ \ADC QQ20,Y \ Add A (which we set to 1 above) to the number of items \STA QQ20,Y \ of type Y in the cargo hold, as we just successfully \ \ scooped one canister of type Y \ \TYA \ Print recursive token 48 + Y as an in-flight token, \ADC #208 \ which will be in the range 48 ("FOOD") to 64 ("ALIEN \JSR MESS \ ITEMS"), so this prints the scooped item's name \ \ASL NEWB \ The item has now been scooped, so set bit 7 of its \SEC \ NEWB flags to indicate this \ROR NEWB \ --- And replaced by: --------------------------------> \ By the time we get here, we are scooping, and A \ contains the type of item we are scooping (a random \ number 0-15 if we are scooping a cargo canister, 3 if \ we are scooping an escape pod, or 16 if we are \ scooping a Thargon). These numbers correspond to the \ relevant market items (see QQ23 for a list), so a \ cargo canister can contain anything from food to \ gem-stones, while escape pods contain slaves, and \ Thargons become alien items when scooped TAX \ Copy the type of cargo we are scooping into X JSR tnpr1 \ Call tnpr1 to work out whether we have room in the \ hold for the scooped item (the C flag contains the \ result) BCS MA58 \ If the C flag is set then we have no room in the hold \ for the scooped item, so jump down to MA58 to skip all \ the docking and scooping checks INC QQ20,X \ Scooping was successful, so increment the number of \ items of type X that we have in the hold TXA \ Print recursive token 48 + X as an in-flight token, ADC #208 \ which will be in the range 48 ("FOOD") to 64 ("ALIEN JSR MESS \ ITEMS"), so this prints the scooped item's name JSR top_6a \ The item has now been scooped, so call top_6a to set \ bit 7 of its NEWB flags to indicate this \ --- End of replacement ------------------------------> .MA65 JMP MA26 \ If we get here, then the ship we are processing was \ too far away to be scooped, docked or collided with, \ so jump to MA26 to skip over the collision routines \ and move on to missile targetingName: Main flight loop (Part 8 of 16) [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: Process us potentially scooping this item Deep dive: Program flow of the main game loopContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Continue looping through all the ships in the local bubble, and for each one: * Process us potentially scooping this item.ISDK LDA K%+NI%+36 \ 1. Fetch the NEWB flags (byte #36) of the second ship AND #%00000100 \ in the ship data workspace at K%, which is reserved BNE MA62 \ for the sun or the space station (in this case it's \ the latter), and if bit 2 is set, meaning the station \ is hostile, jump down to MA62 to fail docking (so \ trying to dock at a station that we have annoyed does \ not end well) LDA INWK+14 \ 2. If nosev_z_hi < 214, jump down to MA62 to fail CMP #214 \ docking, as the angle of approach is greater than 26 BCC MA62 \ degrees \ --- Mod: Code removed for Elite-A: ------------------> \JSR SPS1 \ Call SPS1 to calculate the vector to the planet and \ \ store it in XX15 \ --- And replaced by: --------------------------------> LDY #NI% \ Set Y = NI% so the following call to SPS1 calculates \ the vector to the space station rather than the planet JSR SPS1 \ Call SPS1 to calculate the vector to the space station \ and store it in XX15 \ --- End of replacement ------------------------------> LDA XX15+2 \ Set A to the z-axis of the vector \ This version of Elite omits check 3 (which would check \ the sign of the z-axis) CMP #86 \ 4. If z-axis < 86, jump to MA62 to fail docking, as BCC MA62 \ we are not in the 26.3 degree safe cone of approach LDA INWK+16 \ 5. If |roofv_x_hi| < 80, jump to MA62 to fail docking, AND #%01111111 \ as the slot is more than 36.6 degrees from horizontal CMP #80 BCC MA62 .GOIN \ If we arrive here, we just docked successfully JSR RES2 \ Reset a number of flight variables and workspaces LDA #8 \ Set the step size for the launch tunnel rings to 8, so \ there are fewer sections in the rings and they are \ quite polygonal (compared to the step size of 4 used \ in the much rounder hyperspace rings) JSR HFS2 \ Call HFS2 to draw the launch tunnel rings JMP DOENTRY \ Go to the docking bay (i.e. show the ship hangar) .MA62 \ If we arrive here, docking has just failed \ --- Mod: Code removed for Elite-A: ------------------> \LDA DELTA \ If the ship's speed is < 5, jump to MA67 to register \CMP #5 \ some damage, but not a huge amount \BCC MA67 \ \JMP DEATH \ Otherwise we have just crashed into the station, so \ \ process our death \ --- And replaced by: --------------------------------> LDA DELTA \ If the ship's speed is >= 5, jump to n_crunch to CMP #5 \ register a fair amount of damage to our shields (128) BCS n_crunch \ Otherwise we have just crashed gently into the \ station, so we need to check whether it's our fault or \ the docking computer \ --- End of replacement ------------------------------>Name: Main flight loop (Part 9 of 16) [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: If it is a space station, check whether we are successfully docking with it Deep dive: Program flow of the main game loop Docking checksContext: See this subroutine on its own page References: This subroutine is called as follows: * ESCAPE calls via GOIN
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Process docking with a space station For details on the various docking checks in this routine, see the deep dive on "Docking checks".
Other entry points: GOIN We jump here from part 3 of the main flight loop if the docking computer is activated by pressing "C"\ --- Mod: Code removed for Elite-A: ------------------> \.MA59 \ \ \ If we get here then scooping failed \ \JSR EXNO3 \ Make the sound of the cargo canister being destroyed \ \ and fall through into MA60 to remove the canister \ \ from our local bubble \ \.MA60 \ \ \ If we get here then scooping was successful \ \ASL INWK+31 \ Set bit 7 of the scooped or destroyed item, to denote \SEC \ that it has been killed and should be removed from \ROR INWK+31 \ the local bubble \ \.MA61 \ \BNE MA26 \ Jump to MA26 to skip over the collision routines and \ \ to move on to missile targeting (this BNE is \ \ effectively a JMP as A will never be zero) \ \.MA67 \ \ \ If we get here then we have collided with something, \ \ but not fatally \ \LDA #1 \ Set the speed in DELTA to 1 (i.e. a sudden stop) \STA DELTA \ \LDA #5 \ Set the amount of damage in A to 5 (a small dent) and \BNE MA63 \ jump down to MA63 to process the damage (this BNE is \ \ effectively a JMP as A will never be zero) \ \.MA58 \ \ \ If we get here, we have collided with something in a \ \ potentially fatal way \ \ASL INWK+31 \ Set bit 7 of the ship we just collided with, to \SEC \ denote that it has been killed and should be removed \ROR INWK+31 \ from the local bubble \ \LDA INWK+35 \ Load A with the energy level of the ship we just hit \ \SEC \ Set the amount of damage in A to 128 + A / 2, so \ROR A \ this is quite a big dent, and colliding with higher \ \ energy ships will cause more damage \ --- And replaced by: --------------------------------> LDA auto \ If the docking computer is on, then auto will be &FF, AND #%00000100 \ so this will set A = 1, a tiny amount of damage EOR #%00000101 \ \ If the docking computer is off, then auto will be 0, \ so this will set A = 5, a small amount of damage BNE MA63 \ Jump to MA63 to process the damage in A (this BNE is \ effectively a JMP as A will never be zero) .MA58 \ If we get here, we have collided with something in a \ potentially fatal way LDA #64 \ Call n_hit to apply a hit of strength 64 to the ship JSR n_hit \ we just collided with JSR anger_8c \ Call anger_8c to make the ship angry .n_crunch \ If we get here, we have collided with something, so we \ need to take a hit to our shields LDA #128 \ Set A = 128 to indicate a fairly large amount of \ damage \ --- End of replacement ------------------------------> .MA63 JSR OOPS \ The amount of damage is in A, so call OOPS to reduce \ our shields, and if the shields are gone, there's a \ chance of cargo loss or even death JSR EXNO3 \ Make the sound of colliding with the other ship and \ fall through into MA26 to try targeting a missileName: Main flight loop (Part 10 of 16) [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: Remove if scooped, or process collisions Deep dive: Program flow of the main game loopContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Continue looping through all the ships in the local bubble, and for each one: * Remove scooped item after both successful and failed scooping attempts * Process collisions.MA26 LDA NEWB \ If bit 7 of the ship's NEWB flags is clear, skip the BPL P%+5 \ following instruction JSR SCAN \ Bit 7 of the ship's NEWB flags is set, which means the \ ship has docked or been scooped, so we draw the ship \ on the scanner, which has the effect of removing it LDA QQ11 \ If this is not a space view, jump to MA15 to skip BNE MA15 \ missile and laser locking LDX VIEW \ Load the current view into X BEQ P%+5 \ If the current view is the front view, skip the \ following instruction, as the geometry in INWK is \ already correct JSR PU1 \ Call PU1 to update the geometric axes in INWK to \ match the view (front, rear, left, right) JSR HITCH \ Call HITCH to see if this ship is in the crosshairs, BCC MA8 \ in which case the C flag will be set (so if there is \ no missile or laser lock, we jump to MA8 to skip the \ following) LDA MSAR \ We have missile lock, so check whether the leftmost BEQ MA47 \ missile is currently armed, and if not, jump to MA47 \ to process laser fire, as we can't lock an unarmed \ missile JSR BEEP \ We have missile lock and an armed missile, so call \ the BEEP subroutine to make a short, high beep LDX XSAV \ Call ABORT2 to store the details of this missile LDY #&0E \ lock, with the targeted ship's slot number in X JSR ABORT2 \ (which we stored in XSAV at the start of this ship's \ loop at MAL1), and set the colour of the missile \ indicator to the colour in Y (red = &0E) .MA47 \ If we get here then the ship is in our sights, but \ we didn't lock a missile, so let's see if we're \ firing the laser LDA LAS \ If we are firing the laser then LAS will contain the BEQ MA8 \ laser power (which we set in MA68 above), so if this \ is zero, jump down to MA8 to skip the following LDX #15 \ We are firing our laser and the ship in INWK is in JSR EXNO \ the crosshairs, so call EXNO to make the sound of \ us making a laser strike on another ship \ --- Mod: Code removed for Elite-A: ------------------> \LDA TYPE \ Did we just hit the space station? If so, jump to \CMP #SST \ MA14+2 to make the station hostile, skipping the \BEQ MA14+2 \ following as we can't destroy a space station \ \CMP #CON \ If the ship we hit is not a Constrictor, jump to BURN \BNE BURN \ to skip the following \ \LDA LAS \ Set A to the power of the laser we just used to hit \ \ the ship (i.e. the laser in the current view) \ \CMP #(Armlas AND 127) \ If the laser is not a military laser, jump to MA8 \BNE MA8 \ to skip the following, as only military lasers have \ \ any effect on the Constrictor \ \LSR LAS \ Divide the laser power of the current view by 4, so \LSR LAS \ the damage inflicted on the super-ship is a quarter of \ \ the damage our military lasers would inflict on a \ \ normal ship \ \.BURN \ \LDA INWK+35 \ Fetch the hit ship's energy from byte #35 and subtract \SEC \ our current laser power, and if the result is greater \SBC LAS \ than zero, the other ship has survived the hit, so \BCS MA14 \ jump down to MA14 to make it angry \ \ASL INWK+31 \ Set bit 7 of the ship byte #31 to indicate that it has \SEC \ now been killed \ROR INWK+31 \ \LDA TYPE \ Did we just kill an asteroid? If not, jump to nosp, \CMP #AST \ otherwise keep going \BNE nosp \ \LDA LAS \ Did we kill the asteroid using mining lasers? If not, \CMP #Mlas \ jump to nosp, otherwise keep going \BNE nosp \ --- And replaced by: --------------------------------> LDA LAS \ Set A to the power of the laser we just used to hit \ the ship (i.e. the laser in the current view) LDY TYPE \ Did we just hit the space station? If so, jump to CPY #SST \ MA14 to make it angry BEQ MA14 CPY #CON \ If the ship we hit is not a Constrictor, jump to BURN BNE BURN \ to skip the following LSR A \ Divide the laser power of the current view by 2, so \ the damage inflicted on the Constrictor is half of the \ damage our military lasers would inflict on a normal \ ship .BURN LSR A \ Divide the laser power of the current view by 2 JSR n_hit \ Call n_hit to apply a laser strike of strength A to \ the enemy ship BCS MA14 \ If the C flag is set then the enemy ship survived the \ hit, so jump down to MA14 to make it angry LDA TYPE \ Did we just kill an asteroid? If not, jump to nosp, CMP #AST \ otherwise keep going BNE nosp LDA LAS \ Did we kill the asteroid using mining lasers? If so, CMP new_mining \ then our current laser strength in LAS will match the BNE nosp \ strength of mining lasers when fitted to our current \ ship type, which is stored in new_mining. If they \ don't match, which means we didn't use mining lasers, \ then jump to nosp, otherwise keep going \ --- End of replacement ------------------------------> JSR DORND \ Set A and X to random numbers LDX #SPL \ Set X to the ship type for a splinter AND #3 \ Reduce the random number in A to the range 0-3 JSR SPIN2 \ Call SPIN2 to spawn A items of type X (i.e. spawn \ 0-3 splinters) .nosp LDY #PLT \ Randomly spawn some alloy plates JSR SPIN LDY #OIL \ Randomly spawn some cargo canisters JSR SPIN JSR EXNO2 \ Call EXNO2 to process the fact that we have killed a \ ship (so increase the kill tally, make an explosion \ sound and so on) .MA14 \ --- Mod: Code removed for Elite-A: ------------------> \STA INWK+35 \ Store the hit ship's updated energy in ship byte #35 \ \LDA TYPE \ Call ANGRY to make this ship hostile, now that we \JSR ANGRY \ have hit it \ --- And replaced by: --------------------------------> JSR anger_8c \ Call anger_8c to make this ship hostile angry, now \ that we have hit it \ --- End of replacement ------------------------------>Name: Main flight loop (Part 11 of 16) [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: Process missile lock and firing our laser Deep dive: Program flow of the main game loop Flipping axes between space viewsContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Continue looping through all the ships in the local bubble, and for each one: * If this is not the front space view, flip the axes of the ship's coordinates in INWK * Process missile lock * Process our laser firing.MA8 JSR LL9 \ Call LL9 to draw the ship we're processing on-screen .MA15 LDY #35 \ Fetch the ship's energy from byte #35 and copy it to LDA INWK+35 \ byte #35 in INF (so the ship's data in K% gets STA (INF),Y \ updated) LDA NEWB \ If bit 7 of the ship's NEWB flags is set, which means BMI KS1S \ the ship has docked or been scooped, jump to KS1S to \ skip the following, as we can't get a bounty for a \ ship that's no longer around LDA INWK+31 \ If bit 7 of the ship's byte #31 is clear, then the BPL MAC1 \ ship hasn't been killed by collision or laser fire, \ so jump to MAC1 to skip the following AND #%00100000 \ If bit 5 of the ship's byte #31 is clear then the BEQ MAC1 \ ship is no longer exploding, so jump to MAC1 to skip \ the following \ --- Mod: Code removed for Elite-A: ------------------> \LDA NEWB \ Extract bit 6 of the ship's NEWB flags, so A = 64 if \AND #%01000000 \ bit 6 is set, or 0 if it is clear. Bit 6 is set if \ \ this ship is a cop, so A = 64 if we just killed a \ \ policeman, otherwise it is 0 \ \ORA FIST \ Update our FIST flag ("fugitive/innocent status") to \STA FIST \ at least the value in A, which will instantly make us \ \ a fugitive if we just shot the sheriff, but won't \ \ affect our status if the enemy wasn't a copper \ --- And replaced by: --------------------------------> \ We now update our FIST flag ("fugitive/innocent \ status") by 1 if we didn't kill a cop, or by a large \ amount if we did - specifically, if we killed a cop, \ then the most significant bit in FIST that is \ currently clear will be set, which means we increase \ FIST by the highest multiple of 2 that we can add and \ still fit the result in a byte \ \ Also, at this point, we know that A = %00100000 (as we \ didn't take the BEQ branch) BIT NEWB \ If bit 6 of the ship's NEWB flags is set, then this BVS n_badboy \ ship is a cop, so jump to n_badboy as we just killed a \ policeman BEQ n_goodboy \ The BIT NEWB instruction sets the Z flag according to \ the result of: \ \ A AND NEWB = %00100000 AND NEWB \ \ so this jumps to n_goodboy if bit 5 of NEWB is clear, \ so in other words, if the ship is no longer exploding, \ we don't update FIST LDA #%10000000 \ Set A so that the shift and rotate instructions we're \ about to do set A = %00000001, so we increase our FIST \ status by just 1 .n_badboy \ We get here with two possible values of A: \ \ * A = %00100000 if we just killed a cop \ * A = %10000000 otherwise ASL A \ Shift and rotate A so that we get: ROL A \ \ * A = %10000000 if we just killed a cop \ * A = %00000001 otherwise .n_bitlegal LSR A \ We now shift A to the right and AND it with FIST, BIT FIST \ repeating the process until the single set bit in A BNE n_bitlegal \ matches a clear bit in FIST, so this shifts A right \ so that the set bit matches the highest clear bit in \ FIST (if we just killed a cop), or it sets A to 0 and \ sets the C flag (if we didn't) ADC FIST \ Set A = A + C + FIST, so: \ \ * A = A + 0 + FIST if we just killed a cop \ * A = 0 + 1 + FIST otherwise \ \ so if we just killed a cop, this will effectively set \ the highest clear bit in FIST, otherwise we just add 1 \ to FIST BCS KS1S \ If the addition overflowed, jump to KS1S to skip \ showing an on-screen bounty for this kill, and without \ updating FIST first (as we are too bad to get any \ worse) STA FIST \ Otherwise update the value of FIST to the new value BCC KS1S \ Jump to KS1S to skip showing an on-screen bounty for \ this kill (the BCC is effectively a JMP as we just \ passed through a BCS) .n_goodboy \ --- End of replacement ------------------------------> LDA DLY \ If we already have an in-flight message on-screen (in ORA MJ \ which case DLY > 0), or we are in witchspace (in BNE KS1S \ which case MJ > 0), jump to KS1S to skip showing an \ on-screen bounty for this kill \ --- Mod: Code removed for Elite-A: ------------------> \LDY #10 \ Fetch byte #10 of the ship's blueprint, which is the \LDA (XX0),Y \ low byte of the bounty awarded when this ship is \BEQ KS1S \ killed (in Cr * 10), and if it's zero jump to KS1S as \ \ there is no on-screen bounty to display \ --- And replaced by: --------------------------------> LDY #10 \ Fetch byte #10 of the ship's blueprint, which is the LDA (XX0),Y \ low byte of the bounty awarded when this ship is \ killed (in Cr * 10) \ --- End of replacement ------------------------------> TAX \ Put the low byte of the bounty into X INY \ Fetch byte #11 of the ship's blueprint, which is the LDA (XX0),Y \ high byte of the bounty awarded (in Cr * 10), and put TAY \ it into Y JSR MCASH \ Call MCASH to add (Y X) to the cash pot LDA #0 \ Print control code 0 (current cash, right-aligned to JSR MESS \ width 9, then " CR", newline) as an in-flight message .KS1S JMP KS1 \ Process the killing of this ship (which removes this \ ship from its slot and shuffles all the other ships \ down to close up the gap) \ --- Mod: Code added for Elite-A: --------------------> .n_hit \ If we get here then we need to apply a hit of strength \ A to the enemy ship STA T \ Store the strength of the hit in T SEC \ Set the C flag so we can do some subtraction LDY #14 \ Fetch byte #14 of the enemy ship's blueprint into A, LDA (XX0),Y \ which gives the ship's maximum energy/shields AND #7 \ Reduce the maximum energy/shields figure to the range \ 0-7 SBC T \ Subtract the hit strength from the maximum shields, so \ A = ship energy - hit strength BCS n_kill \ If the subtraction didn't underflow, then the hit was \ weaker than the ship's shields, so jump to n_kill \ with the C flag set to indicate that the ship has \ survived the attack \BCC n_defense \ These instructions are commented out in the original \LDA #&FF \ source \.n_defense CLC \ Otherwise the hit was stronger than the enemy shields, ADC INWK+35 \ so the ship's energy level needs to register some STA INWK+35 \ damage. A contains a negative number whose magnitude \ is the amount by which the attack is greater than the \ shield defence, so we can simply add this figure to \ the ship's energy levels in the ship's byte #35 to \ reduce the energy by the amount that the attack was \ stronger than the defence (i.e. the shields absorb the \ amount of energy that is defined in the blueprint, and \ the rest of the hit makes it through to damage the \ energy levels) BCS n_kill \ Adding this negative number is the same as subtracting \ a positive number, so having the C flag set indicates \ that the subtraction didn't underflow - in other words \ the damage isn't greater than the energy levels, and \ the ship has survived the hit. In this case we jump to \ n_kill with the C flag set to indicate that the ship \ has survived the attack JSR TA87+3 \ If we get here then the ship has not survived the \ attack, so call TA87+3 to set bit 7 of the ship's byte \ #31, which marks the ship as being killed .n_kill RTS \ Return from the subroutine with the C flag set if the \ ship has survived the onslaught, or clear if it has \ been destroyed \ --- End of added code -------------------------------> .MAC1 LDA TYPE \ If the ship we are processing is a planet or sun, BMI MA27 \ jump to MA27 to skip the following two instructions JSR FAROF \ If the ship we are processing is a long way away (its BCC KS1S \ distance in any one direction is > 224, jump to KS1S \ to remove the ship from our local bubble, as it's just \ left the building .MA27 LDY #31 \ Fetch the ship's explosion/killed state from byte #31 LDA INWK+31 \ and copy it to byte #31 in INF (so the ship's data in STA (INF),Y \ K% gets updated) LDX XSAV \ We're done processing this ship, so fetch the ship's \ slot number, which we saved in XSAV back at the start \ of the loop INX \ Increment the slot number to move on to the next slot JMP MAL1 \ And jump back up to the beginning of the loop to get \ the next ship in the local bubble for processingName: Main flight loop (Part 12 of 16) [Show more] Type: Subroutine Category: Main loop Summary: For each nearby ship: Draw the ship, remove if killed, loop back Deep dive: Program flow of the main game loop Drawing shipsContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Continue looping through all the ships in the local bubble, and for each one: * Draw the ship * Process removal of killed ships * Loop back up to MAL1 to move onto the next ship in the local bubble.MA18 \ --- Mod: Code removed for Elite-A: ------------------> \LDA BOMB \ If we set off our energy bomb (see MA24 above), then \BPL MA77 \ BOMB is now negative, so this skips to MA21 if our \ \ energy bomb is not going off \ \ASL BOMB \ We set off our energy bomb, so rotate BOMB to the \ \ left by one place. BOMB was rotated left once already \ \ during this iteration of the main loop, back at MA24, \ \ so if this is the first pass it will already be \ \ %11111110, and this will shift it to %11111100 - so \ \ if we set off an energy bomb, it stays activated \ \ (BOMB > 0) for four iterations of the main loop \ \JSR WSCAN \ Call WSCAN to wait for the vertical sync, so the whole \ \ screen gets drawn and the following palette change \ \ won't kick in while the screen is still refreshing \ \LDA #%00110000 \ Set the palette byte at SHEILA &21 to map logical \STA VIA+&21 \ colour 0 to physical colour 7 (white), but with only \ \ one mapping (rather than the 7 mappings required to \ \ do the mapping properly). This makes the space screen \ \ flash with black and white stripes. See p.382 of the \ \ Advanced User Guide for details of why this single \ \ palette change creates a special effect \ --- End of removed code -----------------------------> .MA77 LDA MCNT \ Fetch the main loop counter and calculate MCNT mod 8, AND #7 \ jumping to MA22 if it is non-zero (so the following BNE MA22 \ code only runs every 8 iterations of the main loop) LDX ENERGY \ Fetch our ship's energy levels and skip to b if bit 7 BPL b \ is not set, i.e. only charge the shields from the \ energy banks if they are at more than 50% charge LDX ASH \ Call SHD to recharge our aft shield and update the JSR SHD \ shield status in ASH STX ASH LDX FSH \ Call SHD to recharge our forward shield and update JSR SHD \ the shield status in FSH STX FSH .b SEC \ Set A = ENERGY + ENGY + 1, so our ship's energy LDA ENGY \ level goes up by the correct amount for our current ADC ENERGY \ ship, depending on whether we have an energy unit \ fitted BCS P%+5 \ If the value of A did not overflow (the maximum STA ENERGY \ energy level is &FF), then store A in ENERGYName: Main flight loop (Part 13 of 16) [Show more] Type: Subroutine Category: Main loop Summary: Charge shields and energy banks Deep dive: Program flow of the main game loop Scheduling tasks with the main loop counterContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Charge shields and energy banks (every 7 iterations of the main loop)LDA MJ \ If we are in witchspace, jump down to MA23S to skip BNE MA23S \ the following, as there are no space stations in \ witchspace LDA MCNT \ Fetch the main loop counter and calculate MCNT mod 32, AND #31 \ jumping to MA93 if it is on-zero (so the following BNE MA93 \ code only runs every 32 iterations of the main loop) LDA SSPR \ If we are inside the space station safe zone, jump to BNE MA23S \ MA23S to skip the following, as we already have a \ space station and don't need another TAY \ Set Y = A = 0 (A is 0 as we didn't branch with the \ previous BNE instruction) JSR MAS2 \ Call MAS2 to calculate the largest distance to the BNE MA23S \ planet in any of the three axes, and if it's \ non-zero, jump to MA23S to skip the following, as we \ are too far from the planet to bump into a space \ station \ We now want to spawn a space station, so first we \ need to set up a ship data block for the station in \ INWK that we can then pass to NWSPS to add a new \ station to our bubble of universe. We do this by \ copying the planet data block from K% to INWK so we \ can work on it, but we only need the first 29 bytes, \ as we don't need to worry about bytes #29 to #35 \ for planets (as they don't have rotation counters, \ AI, explosions, missiles, a ship line heap or energy \ levels) LDX #28 \ So we set a counter in X to copy 29 bytes from K%+0 \ to K%+28 .MAL4 LDA K%,X \ Load the X-th byte of K% and store in the X-th byte STA INWK,X \ of the INWK workspace DEX \ Decrement the loop counter BPL MAL4 \ Loop back for the next byte until we have copied the \ first 28 bytes of K% to INWK \ We now check the distance from our ship (at the \ origin) towards the point where we will spawn the \ space station if we are close enough \ \ This point is calculated by starting at the planet's \ centre and adding 2 * nosev, which takes us to a point \ above the planet's surface, at an altitude that \ matches the planet's radius \ \ This point pitches and rolls around the planet as the \ nosev vector rotates with the planet, and if our ship \ is within a distance of (192 0) from this point in all \ three axes, then we spawn the space station at this \ point, with the station's slot facing towards the \ planet, along the nosev vector \ \ This works because in the following, we calculate the \ station's coordinates one axis at a time, and store \ the results in the INWK block, so by the time we have \ calculated and checked all three, the ship data block \ is set up with the correct spawning coordinates INX \ Set X = 0 (as we ended the above loop with X as &FF) LDY #9 \ Call MAS1 with X = 0, Y = 9 to do the following: JSR MAS1 \ \ (x_sign x_hi x_lo) += (nosev_x_hi nosev_x_lo) * 2 \ \ A = |x_sign| BNE MA23S \ If A > 0, jump to MA23S to skip the following, as we \ are too far from the planet in the x-direction to \ bump into a space station LDX #3 \ Call MAS1 with X = 3, Y = 11 to do the following: LDY #11 \ JSR MAS1 \ (y_sign y_hi y_lo) += (nosev_y_hi nosev_y_lo) * 2 \ \ A = |y_sign| BNE MA23S \ If A > 0, jump to MA23S to skip the following, as we \ are too far from the planet in the y-direction to \ bump into a space station LDX #6 \ Call MAS1 with X = 6, Y = 13 to do the following: LDY #13 \ JSR MAS1 \ (z_sign z_hi z_lo) += (nosev_z_hi nosev_z_lo) * 2 \ \ A = |z_sign| BNE MA23S \ If A > 0, jump to MA23S to skip the following, as we \ are too far from the planet in the z-direction to \ bump into a space station LDA #192 \ Call FAROF2 to compare x_hi, y_hi and z_hi with 192, JSR FAROF2 \ which will set the C flag if all three are < 192, or \ clear the C flag if any of them are >= 192 BCC MA23S \ Jump to MA23S if any one of x_hi, y_hi or z_hi are \ >= 192 (i.e. they must all be < 192 for us to be near \ enough to the planet to bump into a space station) JSR WPLS \ Call WPLS to remove the sun from the screen, as we \ can't have both the sun and the space station at the \ same time JSR NWSPS \ Add a new space station to our local bubble of \ universe .MA23S JMP MA23 \ Jump to MA23 to skip the following planet and sun \ altitude checksName: Main flight loop (Part 14 of 16) [Show more] Type: Subroutine Category: Main loop Summary: Spawn a space station if we are close enough to the planet Deep dive: Program flow of the main game loop Scheduling tasks with the main loop counter Ship data blocks The space station safe zoneContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Spawn a space station if we are close enough to the planet (every 32 iterations of the main loop).MA22 LDA MJ \ If we are in witchspace, jump down to MA23S to skip BNE MA23S \ the following, as there are no planets or suns to \ bump into in witchspace LDA MCNT \ Fetch the main loop counter and calculate MCNT mod 32, AND #31 \ which tells us the position of this loop in each block \ of 32 iterations .MA93 CMP #10 \ If this is the tenth iteration in this block of 32, BNE MA29 \ do the following, otherwise jump to MA29 to skip the \ planet altitude check and move on to the sun distance \ check LDA #50 \ If our energy bank status in ENERGY is >= 50, skip CMP ENERGY \ printing the following message (so the message is BCC P%+6 \ only shown if our energy is low) ASL A \ Print recursive token 100 ("ENERGY LOW{beep}") as an JSR MESS \ in-flight message LDY #&FF \ Set our altitude in ALTIT to &FF, the maximum STY ALTIT INY \ Set Y = 0 JSR m \ Call m to calculate the maximum distance to the \ planet in any of the three axes, returned in A BNE MA23 \ If A > 0 then we are a fair distance away from the \ planet in at least one axis, so jump to MA23 to skip \ the rest of the altitude check JSR MAS3 \ Set A = x_hi^2 + y_hi^2 + z_hi^2, so using Pythagoras \ we now know that A now contains the square of the \ distance between our ship (at the origin) and the \ centre of the planet at (x_hi, y_hi, z_hi) BCS MA23 \ If the C flag was set by MAS3, then the result \ overflowed (was greater than &FF) and we are still a \ fair distance from the planet, so jump to MA23 as we \ haven't crashed into the planet SBC #36 \ Subtract 36 from x_hi^2 + y_hi^2 + z_hi^2 \ \ When we do the 3D Pythagoras calculation, we only use \ the high bytes of the coordinates, so that's x_hi, \ y_hi and z_hi and \ \ The planet radius is (0 96 0), as defined in the \ PLANET routine, so the high byte is 96 \ \ When we square the coordinates above and add them, \ the result gets divided by 256 (otherwise the result \ wouldn't fit into one byte), so if we do the same for \ the planet's radius, we get: \ \ 96 * 96 / 256 = 36 \ \ So for the planet, the equivalent figure to test the \ sum of the _hi bytes against is 36, so A now contains \ the high byte of our altitude above the planet \ surface, squared BCC MA28 \ If A < 0 then jump to MA28 as we have crashed into \ the planet STA R \ We are getting close to the planet, so we need to JSR LL5 \ work out how close. We know from the above that A \ contains our altitude squared, so we store A in R \ and call LL5 to calculate: \ \ Q = SQRT(R Q) = SQRT(A Q) \ \ Interestingly, Q doesn't appear to be set to 0 for \ this calculation, so presumably this doesn't make a \ difference LDA Q \ Store the result in ALTIT, our altitude STA ALTIT BNE MA23 \ If our altitude is non-zero then we haven't crashed, \ so jump to MA23 to skip to the next section .MA28 JMP DEATH \ If we get here then we just crashed into the planet \ or got too close to the sun, so jump to DEATH to start \ the funeral preparations and return from the main \ flight loop using a tail call .MA29 CMP #15 \ If this is the 15th iteration in this block of 32, BNE MA33 \ do the following, otherwise jump to MA33 to skip the \ docking computer manoeuvring LDA auto \ If auto is zero, then the docking computer is not BEQ MA23 \ activated, so jump to MA23 to skip to the next \ section LDA #123 \ Set A = 123 and jump down to MA34 to print token 123 BNE MA34 \ ("DOCKING COMPUTERS ON") as an in-flight message .MA33 CMP #20 \ If this is the 20th iteration in this block of 32, BNE MA23 \ do the following, otherwise jump to MA23 to skip the \ sun altitude check LDA #30 \ Set CABTMP to 30, the cabin temperature in deep space STA CABTMP \ (i.e. one notch on the dashboard bar) LDA SSPR \ If we are inside the space station safe zone, jump to BNE MA23 \ MA23 to skip the following, as we can't have both the \ sun and space station at the same time, so we clearly \ can't be flying near the sun LDY #NI% \ Set Y to NI%, which is the offset in K% for the sun's \ data block, as the second block at K% is reserved for \ the sun (or space station) JSR MAS2 \ Call MAS2 to calculate the largest distance to the BNE MA23 \ sun in any of the three axes, and if it's non-zero, \ jump to MA23 to skip the following, as we are too far \ from the sun for scooping or temperature changes JSR MAS3 \ Set A = x_hi^2 + y_hi^2 + z_hi^2, so using Pythagoras \ we now know that A now contains the square of the \ distance between our ship (at the origin) and the \ heart of the sun at (x_hi, y_hi, z_hi) EOR #%11111111 \ Invert A, so A is now small if we are far from the \ sun and large if we are close to the sun, in the \ range 0 = far away to &FF = extremely close, ouch, \ hot, hot, hot! ADC #30 \ Add the minimum cabin temperature of 30, so we get \ one of the following: \ \ * If the C flag is clear, A contains the cabin \ temperature, ranging from 30 to 255, that's hotter \ the closer we are to the sun \ \ * If the C flag is set, the addition has rolled over \ and the cabin temperature is over 255 STA CABTMP \ Store the updated cabin temperature BCS MA28 \ If the C flag is set then jump to MA28 to die, as \ our temperature is off the scale CMP #224 \ If the cabin temperature < 224 then jump to MA23 to BCC MA23 \ skip fuel scooping, as we aren't close enough LDA BST \ If we don't have fuel scoops fitted, jump to BA23 to BEQ MA23 \ skip fuel scooping, as we can't scoop without fuel \ scoops LDA DELT4+1 \ We are now successfully fuel scooping, so it's time LSR A \ to work out how much fuel we're scooping. Fetch the \ high byte of DELT4, which contains our current speed \ divided by 4, and halve it to get our current speed \ divided by 8 (so it's now a value between 1 and 5, as \ our speed is normally between 1 and 40). This gives \ us the amount of fuel that's being scooped in A, so \ the faster we go, the more fuel we scoop, and because \ the fuel levels are stored as 10 * the fuel in light \ years, that means we just scooped between 0.1 and 0.5 \ light years of free fuel ADC QQ14 \ Set A = A + the current fuel level * 10 (from QQ14) \ --- Mod: Code removed for Elite-A: ------------------> \CMP #70 \ If A > 70 then set A = 70 (as 70 is the maximum fuel \BCC P%+4 \ level, or 7.0 light years) \LDA #70 \ --- And replaced by: --------------------------------> CMP new_range \ If A > new_range then set A = new_range (as new_range BCC P%+5 \ is the maximum fuel level for our current ship LDA new_range \ --- End of replacement ------------------------------> STA QQ14 \ Store the updated fuel level in QQ14 LDA #160 \ Set A to token 160 ("FUEL SCOOPS ON") .MA34 JSR MESS \ Print the token in A as an in-flight messageName: Main flight loop (Part 15 of 16) [Show more] Type: Subroutine Category: Main loop Summary: Perform altitude checks with the planet and sun and process fuel scooping if appropriate Deep dive: Program flow of the main game loop Scheduling tasks with the main loop counterContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Perform an altitude check with the planet (every 32 iterations of the main loop, on iteration 10 of each 32) * Perform an altitude check with the sun and process fuel scooping (every 32 iterations of the main loop, on iteration 20 of each 32).MA23 LDA LAS2 \ If the current view has no laser, jump to MA16 to skip BEQ MA16 \ the following LDA LASCT \ If LASCT >= 8, jump to MA16 to skip the following, so CMP #8 \ for a pulse laser with a LASCT between 8 and 10, the BCS MA16 \ laser stays on, but for a LASCT of 7 or less it gets \ turned off and stays off until LASCT reaches zero and \ the next pulse can start (if the fire button is still \ being pressed) \ \ For pulse lasers, LASCT gets set to 10 in ma1 above, \ and it decrements every vertical sync (50 times a \ second), so this means it pulses five times a second, \ with the laser being on for the first 3/10 of each \ pulse and off for the rest of the pulse \ \ If this is a beam laser, LASCT is 0 so we always keep \ going here. This means the laser doesn't pulse, but it \ does get drawn and removed every cycle, in a slightly \ different place each time, so the beams still flicker \ around the screen JSR LASLI2 \ Redraw the existing laser lines, which has the effect \ of removing them from the screen LDA #0 \ Set LAS2 to 0 so if this is a pulse laser, it will STA LAS2 \ skip over the above until the next pulse (this has no \ effect if this is a beam laser) .MA16 LDA ECMP \ If our E.C.M is not on, skip to MA69, otherwise keep BEQ MA69 \ going to drain some energy JSR DENGY \ Call DENGY to deplete our energy banks by 1 BEQ MA70 \ If we have no energy left, jump to MA70 to turn our \ E.C.M. off .MA69 LDA ECMA \ If an E.C.M is going off (ours or an opponent's) then BEQ MA66 \ keep going, otherwise skip to MA66 DEC ECMA \ Decrement the E.C.M. countdown timer, and if it has BNE MA66 \ reached zero, keep going, otherwise skip to MA66 .MA70 JSR ECMOF \ If we get here then either we have either run out of \ energy, or the E.C.M. timer has run down, so switch \ off the E.C.M. .MA66 LDA QQ11 \ If this is not a space view (i.e. QQ11 is non-zero) BNE oh \ then jump to oh to return from the main flight loop \ (as oh is an RTS) JMP STARS \ This is a space view, so jump to the STARS routine to \ process the stardust, and return from the main flight \ loop using a tail callName: Main flight loop (Part 16 of 16) [Show more] Type: Subroutine Category: Main loop Summary: Process laser pulsing, E.C.M. energy drain, call stardust routine Deep dive: Program flow of the main game loopContext: See this subroutine on its own page References: No direct references to this subroutine in this source file
The main flight loop covers most of the flight-specific aspects of Elite. This section covers the following: * Process laser pulsing * Process E.C.M. energy drain * Jump to the stardust routine if we are in a space view * Return from the main flight loop.SPIN JSR DORND \ Fetch a random number, and jump to oh if it is BPL oh \ positive (50% chance) PHA \ Store A on the stack so we can restore it after the \ following transfers TYA \ Copy the cargo type from Y into A and X TAX PLA \ Restore A from the stack LDY #0 \ Fetch the first byte of the hit ship's blueprint, AND (XX0),Y \ which determines the maximum number of bits of \ debris shown when the ship is destroyed, and AND \ with the random number we just fetched AND #15 \ Reduce the random number in A to the range 0-15 .SPIN2 STA CNT \ Store the result in CNT, so CNT contains a random \ number between 0 and the maximum number of bits of \ debris that this ship will release when destroyed \ (to a maximum of 15 bits of debris) .spl BEQ oh \ We're going to go round a loop using CNT as a counter \ so this checks whether the counter is zero and jumps \ to oh when it gets there (which might be straight \ away) LDA #0 \ Call SFS1 to spawn the specified cargo from the now JSR SFS1 \ deceased parent ship, giving the spawned canister an \ AI flag of 0 (no AI, no E.C.M., non-hostile) DEC CNT \ Decrease the loop counter BNE spl+2 \ Jump back up to the LDA &0 instruction above (this BPL \ is effectively a JMP as CNT will never be negative) .oh RTS \ Return from the subroutineName: SPIN [Show more] Type: Subroutine Category: Universe Summary: Randomly spawn cargo from a destroyed shipContext: See this subroutine on its own page References: This subroutine is called as follows: * Main flight loop (Part 11 of 16) calls SPIN * Main flight loop (Part 16 of 16) calls via oh * Main flight loop (Part 11 of 16) calls via SPIN2
Arguments: Y The type of cargo to consider spawning (typically #PLT or #OIL)
Other entry points: oh Contains an RTS SPIN2 Remove any randomness: spawn cargo of a specific type (given in X), and always spawn the number given in APRINT "ELITE A" PRINT "Assembled at ", ~CODE% PRINT "Ends at ", ~P% PRINT "Code size is ", ~(P% - CODE%) PRINT "Execute at ", ~LOAD% PRINT "Reload at ", ~LOAD_A% PRINT "S.D.ELTA ", ~CODE%, " ", ~P%, " ", ~LOAD%, " ", ~LOAD_A% \SAVE "3-assembled-output/D.ELTA.bin", CODE%, P%, LOAD%Save ELTA.bin
[X]
Subroutine ABORT (category: Dashboard)
Disarm missiles and update the dashboard indicators
[X]
Subroutine ABORT2 (category: Dashboard)
Set/unset the lock target for a missile and update the dashboard
[X]
Configuration variable AST
Ship blueprint position for the asteroid
[X]
Subroutine BEEP (category: Sound)
Make a short, high beep
[X]
Configuration variable BRBR1
The address of the main break handler, which BRKV points to as set in elite-loader.asm
[X]
Label BURN in subroutine Main flight loop (Part 11 of 16)
[X]
Configuration variable CON
Ship blueprint position for the Constrictor
[X]
Subroutine DEATH (category: Start and end)
Display the death screen
[X]
Subroutine DENGY (category: Flight)
Drain some energy from the energy banks
[X]
Subroutine DOENTRY (category: Loader)
Load and run the docked code
[X]
Subroutine DORND (category: Maths (Arithmetic))
Generate random numbers
[X]
Subroutine ECBLB2 (category: Dashboard)
Start up the E.C.M. (light up the indicator, start the countdown and make the E.C.M. sound)
[X]
Subroutine ECMOF (category: Sound)
Switch off the E.C.M.
[X]
Subroutine ESCAPE (category: Flight)
Launch our escape pod
[X]
Subroutine EXNO (category: Sound)
Make the sound of a laser strike or ship explosion
[X]
Subroutine EXNO2 (category: Status)
Process us making a kill
[X]
Subroutine EXNO3 (category: Sound)
Make an explosion sound
[X]
Subroutine FAROF (category: Maths (Geometry))
Compare x_hi, y_hi and z_hi with 224
[X]
Subroutine FAROF2 (category: Maths (Geometry))
Compare x_hi, y_hi and z_hi with A
[X]
Subroutine FRMIS (category: Tactics)
Fire a missile from our ship
[X]
Subroutine GINF (category: Universe)
Fetch the address of a ship's data block into INF
[X]
Subroutine HFS2 (category: Drawing circles)
Draw the launch or hyperspace tunnel
[X]
Subroutine HITCH (category: Tactics)
Work out if the ship in INWK is in our crosshairs
[X]
Subroutine INBAY (category: Loader)
Load and run the main docked code in 1.D
[X]
Configuration variable IRQ1
The address of the IRQ1 routine that implements the split screen interrupt handler, as set in elite-loader.asm
[X]
Label ISDK in subroutine Main flight loop (Part 9 of 16)
[X]
Workspace K% (category: Workspaces)
Ship data blocks and ship line heaps
[X]
Subroutine KS1 (category: Universe)
Remove the current ship from our local bubble of universe
[X]
Label KS1S in subroutine Main flight loop (Part 12 of 16)
[X]
Subroutine LASLI (category: Drawing lines)
Draw the laser lines for when we fire our lasers
[X]
Subroutine LL5 (category: Maths (Arithmetic))
Calculate Q = SQRT(R Q)
[X]
Subroutine LL9 (Part 1 of 12) (category: Drawing ships)
Draw ship: Check if ship is exploding, check if ship is in front
[X]
Variable LTLI (category: Loader)
The OS command string for loading the docked code in file 1.D
[X]
Label MA14 in subroutine Main flight loop (Part 11 of 16)
[X]
Label MA15 in subroutine Main flight loop (Part 12 of 16)
[X]
Label MA16 in subroutine Main flight loop (Part 16 of 16)
[X]
Label MA17 in subroutine Main flight loop (Part 3 of 16)
[X]
Label MA18 in subroutine Main flight loop (Part 13 of 16)
[X]
Label MA20 in subroutine Main flight loop (Part 3 of 16)
[X]
Label MA21 in subroutine Main flight loop (Part 6 of 16)
[X]
Label MA22 in subroutine Main flight loop (Part 15 of 16)
[X]
Label MA23 in subroutine Main flight loop (Part 16 of 16)
[X]
Label MA23S in subroutine Main flight loop (Part 14 of 16)
[X]
Label MA24 in subroutine Main flight loop (Part 3 of 16)
[X]
Label MA25 in subroutine Main flight loop (Part 3 of 16)
[X]
Label MA26 in subroutine Main flight loop (Part 11 of 16)
[X]
Label MA27 in subroutine Main flight loop (Part 12 of 16)
[X]
Label MA28 in subroutine Main flight loop (Part 15 of 16)
[X]
Label MA29 in subroutine Main flight loop (Part 15 of 16)
[X]
Label MA3 in subroutine Main flight loop (Part 4 of 16)
[X]
Label MA33 in subroutine Main flight loop (Part 15 of 16)
[X]
Label MA34 in subroutine Main flight loop (Part 15 of 16)
[X]
Label MA4 in subroutine Main flight loop (Part 3 of 16)
[X]
Label MA47 in subroutine Main flight loop (Part 11 of 16)
[X]
Label MA58 in subroutine Main flight loop (Part 10 of 16)
[X]
Label MA62 in subroutine Main flight loop (Part 9 of 16)
[X]
Label MA63 in subroutine Main flight loop (Part 10 of 16)
[X]
Label MA64 in subroutine Main flight loop (Part 3 of 16)
[X]
Label MA65 in subroutine Main flight loop (Part 8 of 16)
[X]
Label MA66 in subroutine Main flight loop (Part 16 of 16)
[X]
Label MA69 in subroutine Main flight loop (Part 16 of 16)
[X]
Label MA70 in subroutine Main flight loop (Part 16 of 16)
[X]
Label MA76 in subroutine Main flight loop (Part 3 of 16)
[X]
Label MA78 in subroutine Main flight loop (Part 3 of 16)
[X]
Label MA8 in subroutine Main flight loop (Part 12 of 16)
[X]
Label MA93 in subroutine Main flight loop (Part 15 of 16)
[X]
Label MAC1 in subroutine Main flight loop (Part 12 of 16)
[X]
Entry point MAL1 in subroutine Main flight loop (Part 4 of 16) (category: Main loop)
Marks the beginning of the ship analysis loop, so we can jump back here from part 12 of the main flight loop to work our way through each ship in the local bubble. We also jump back here when a ship is removed from the bubble, so we can continue processing from the next ship
[X]
Label MAL2 in subroutine Main flight loop (Part 4 of 16)
[X]
Label MAL3 in subroutine Main flight loop (Part 6 of 16)
[X]
Label MAL4 in subroutine Main flight loop (Part 14 of 16)
[X]
Subroutine MAS1 (category: Maths (Geometry))
Add an orientation vector coordinate to an INWK coordinate
[X]
Subroutine MAS2 (category: Maths (Geometry))
Calculate a cap on the maximum distance to the planet or sun
[X]
Subroutine MAS3 (category: Maths (Arithmetic))
Calculate A = x_hi^2 + y_hi^2 + z_hi^2 in the K% block
[X]
Subroutine MAS4 (category: Maths (Geometry))
Calculate a cap on the maximum distance to a ship
[X]
Subroutine MCASH (category: Maths (Arithmetic))
Add an amount of cash to the cash pot
[X]
Subroutine MESS (category: Flight)
Display an in-flight message
[X]
Subroutine MSBAR (category: Dashboard)
Draw a specific indicator in the dashboard's missile bar
[X]
Configuration variable MSL
Ship blueprint position for the missile
[X]
Subroutine MVEIT (Part 1 of 9) (category: Moving)
Move current ship: Tidy the orientation vectors
[X]
Configuration variable NI%
The number of bytes in each ship's data block (as stored in INWK and K%)
[X]
Subroutine NOISE (category: Sound)
Make the sound whose number is in A
[X]
Subroutine NWSPS (category: Universe)
Add a new space station to our local bubble of universe
[X]
Configuration variable OIL
Ship blueprint position for the cargo canister
[X]
Subroutine OOPS (category: Flight)
Take some damage
[X]
Configuration variable OSCLI
The address for the OSCLI routine
[X]
Configuration variable PLT
Ship blueprint position for the alloy plate
[X]
Subroutine PU1 (category: Flight)
Flip the coordinate axes for the four different views
[X]
Subroutine RES2 (category: Start and end)
Reset a number of flight variables and workspaces
[X]
Subroutine RSHIPS (category: Loader)
Launch from the station, load a new set of ship blueprints and jump into the main game loop
[X]
Subroutine SCAN (category: Dashboard)
Display the current ship on the scanner
[X]
Subroutine SFS1 (category: Universe)
Spawn a child ship from the current (parent) ship
[X]
Subroutine SHD (category: Flight)
Charge a shield and drain some energy from the energy banks
[X]
Subroutine SPIN (category: Universe)
Randomly spawn cargo from a destroyed ship
[X]
Configuration variable SPL
Ship blueprint position for the splinter
[X]
Subroutine SPS1 (category: Maths (Geometry))
Calculate the vector to the planet, sun or station and store it in XX15
[X]
Configuration variable SST
Ship blueprint position for the space station
[X]
Subroutine STARS (category: Stardust)
The main routine for processing the stardust
[X]
Entry point TA87+3 in subroutine TACTICS (Part 1 of 7) (category: Tactics)
Set bit 7 of the ship's byte #31, which marks the ship as being killed, and return from the subroutine
[X]
Subroutine TT111 (category: Universe)
Set the current system to the nearest system to a point
[X]
Subroutine TT26 (category: Text)
Print a character at the text cursor by poking into screen memory
[X]
Subroutine WARP (category: Flight)
Perform an in-system jump
[X]
Subroutine WPLS (category: Drawing suns)
Remove the sun from the screen
[X]
Temporary storage, used to store the address of a ship blueprint. For example, it is used when we add a new ship to the local bubble in routine NWSHP, and it contains the address of the current ship's blueprint as we loop through all the nearby ships in the main flight loop
[X]
Configuration variable XX21
The address of the ship blueprints lookup table, where the chosen ship blueprints file is loaded
[X]
Subroutine anger_8c (category: Tactics)
Make the current ship angry
[X]
Label b in subroutine Main flight loop (Part 13 of 16)
[X]
Subroutine cntr (category: Dashboard)
Apply damping to the pitch or roll dashboard indicator
[X]
Label dock_toggle in subroutine Main flight loop (Part 3 of 16)
[X]
Entry point hyper_snap in subroutine TT18 (category: Flight)
Perform a hyperspace, but without using up any fuel
[X]
Label ma1 in subroutine Main flight loop (Part 3 of 16)
[X]
Label n_badboy in subroutine Main flight loop (Part 12 of 16)
[X]
Label n_bitlegal in subroutine Main flight loop (Part 12 of 16)
[X]
Label n_crunch in subroutine Main flight loop (Part 10 of 16)
[X]
Label n_goodboy in subroutine Main flight loop (Part 12 of 16)
[X]
Label n_highx in subroutine Main flight loop (Part 2 of 16)
[X]
Label n_highy in subroutine Main flight loop (Part 2 of 16)
[X]
Label n_hit in subroutine Main flight loop (Part 12 of 16)
[X]
Label n_kill in subroutine Main flight loop (Part 12 of 16)
[X]
Label n_lowx in subroutine Main flight loop (Part 2 of 16)
[X]
Label n_lowy in subroutine Main flight loop (Part 2 of 16)
[X]
Variable new_mining in workspace UP
The power level of mining lasers when fitted to our current ship type
[X]
Label noescp in subroutine Main flight loop (Part 3 of 16)
[X]
Label nosp in subroutine Main flight loop (Part 11 of 16)
[X]
Label oily in subroutine Main flight loop (Part 8 of 16)
[X]
Label slvy2 in subroutine Main flight loop (Part 8 of 16)
[X]
Label speed_up in subroutine Main flight loop (Part 3 of 16)
[X]
[X]
Subroutine tnpr1 (category: Market)
Work out if we have space for one tonne of cargo