LDA KY2 ; If Space is being pressed, keep going, otherwise jump BEQ MA17 ; down to MA17 to skip the following 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 .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 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 #GREEN2 ; 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 (Y = $EE) LDY #sfxboop ; Call the NOISE routine with Y = sfxboop to make a low, JSR NOISE ; long beep to indicate the missile is now disarmed 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) LDY #YELLOW2 ; Change the leftmost missile indicator to yellow 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) .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 "C=", left arrow, "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 LDA KY12 ; If "C=" 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 BEQ MA76 ; If BOMB now contains 0, then the bomb is not going off ; any more (or it never was), so skip the following ; instruction LDY #%11010000 ; Set bit 4 of moonflower so the screen jumps from STY moonflower ; standard bitmap mode to multicolour bitmap mode, as ; the IRQ handler sets VIC+$16 to the value of ; moonflower, and bit 4 of VIC+$16 controls multicolour ; mode ; ; This makes the space view turn into a coloured mess of ; double-width pixels while the energy bomb is going off LDY #sfxbomb ; Call the NOISE routine with Y = sfxbomb to make the JSR NOISE ; sound of the energy bomb going off .MA76 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 JSR stopbd ; Stop playing the docking music (if it is playing) .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 LDA MJ ; If we are in witchspace, we can't launch our escape BNE noescp ; pod, so jump down to noescp 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 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 EOR KLO+$29 ; If "X" is also being pressed, then the "C" we just BEQ MA68 ; detected is likely to be a ghost key press, caused by ; the player actually holding down "A", "S" and "X" ; (i.e. up, down and fire) ; ; Ghost key presses can occur on the Commodore 64 when ; three keys are held down that form a right angle in ; the keyboard scan matrix, in which case a fourth key ; can also appear to be "pressed" ; ; There is a comment in the original source of "kill ; phantom Cs" that seems to confirm this STA auto ; Set auto to the non-zero value of A, so the docking ; computer is activated JSR startbd ; Start playing the docking music .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 AND #%01111111 ; Set LAS and LAS2 to bits 0-6 of the laser power STA LAS STA LAS2 ; We now set Y to the correct sound to pass to the NOISE ; routine to make the sound of the laser firing LDY #sfxplas ; Set Y to the sound of a pulse laser firing PLA ; Set A to the current view's laser power, which we PHA ; stored on the stack above (and leave the value on ; the stack) BMI bmorarm ; If A >= 128, jump to bmorarm to check whether this is ; a beam laser or a military laser CMP #Mlas ; If A is not the power for a mining laser, skip the BNE P%+4 ; following instruction (and then jump to custard with ; Y still set to the sound of a pulse laser firing) LDY #sfxmlas ; Set Y to the sound of a mining laser firing BNE custard ; Jump to custard to make the sound in Y, i.e. a pulse ; or mining laser (this BNE is effectively a JMP as ; either Y is never zero, or we jumped here with a BNE) .bmorarm CMP #Armlas ; If this is a military laser, skip the following two BEQ P%+5 ; instructions to set Y to the sound of a military laser LDY #sfxblas ; This is not a military laser, so it must be a beam ; laser, so set Y to the sound of a beam laser firing EQUB $2C ; Skip the next instruction by turning it into ; $2C $A0 $0B, or BIT $0BA0, which does nothing apart ; from affect the flags LDY #sfxalas ; Set Y to the sound of a military laser firing .custard JSR NOISE ; Call NOISE to make the sound of the appropriate laser ; firing (pulse, beam, mining or military) 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 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 LASCTName: 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 in context in the source code 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 * "C=" to fire an energy bomb * Left arrow 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
[X]
Subroutine ABORT (category: Dashboard)
Disarm missiles and update the dashboard indicators
[X]
Configuration variable Armlas = INT(128.5 + 1.5*POW)
Military laser power
[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 ESCAPE (category: Flight)
Launch our escape pod
[X]
Subroutine FRMIS (category: Tactics)
Fire a missile from our ship
[X]
Configuration variable GREEN2 = $57
A multicolour bitmap mode palette byte for screen RAM that sets green (5) for %01 in the bitmap and yellow (7) for %10 in the bitmap, for displaying a green missile indicator
[X]
Subroutine LASLI (category: Drawing lines)
Draw the laser lines for when we fire our lasers
[X]
Label MA17 is local to this routine
[X]
Label MA20 is local to this routine
[X]
Label MA24 is local to this routine
[X]
Label MA25 is local to this routine
[X]
Label MA3 in subroutine Main flight loop (Part 4 of 16)
[X]
Label MA4 is local to this routine
[X]
Label MA64 is local to this routine
[X]
Label MA68 is local to this routine
[X]
Label MA76 is local to this routine
[X]
Label MA78 is local to this routine
[X]
Subroutine MSBAR (category: Dashboard)
Draw a specific indicator in the dashboard's missile bar
[X]
Configuration variable Mlas = 50
Mining laser power
[X]
Subroutine NOISE (category: Sound)
Make the sound whose number is in Y
[X]
Subroutine WARP (category: Flight)
Perform an in-system jump
[X]
Configuration variable YELLOW2 = $87
A multicolour bitmap mode palette byte for screen RAM that sets orange (8) for %01 in the bitmap and yellow (7) for %10 in the bitmap, for displaying an orange missile indicator
[X]
Label bmorarm is local to this routine
[X]
Label custard is local to this routine
[X]
Label ma1 is local to this routine
[X]
Variable moonflower (category: Drawing the screen)
Controls the energy bomb effect by switching between multicolour and standard mode
[X]
Label noescp is local to this routine
[X]
Configuration variable sfxalas = 11
Sound 11 = Military lasers fired by us
[X]
Configuration variable sfxblas = 10
Sound 10 = Beam lasers fired by us
[X]
Configuration variable sfxbomb = 13
Sound 13 = Energy bomb
[X]
Configuration variable sfxboop = 6
Sound 6 = Long, low beep
[X]
Configuration variable sfxmlas = 12
Sound 12 = Mining lasers fired by us
[X]
Configuration variable sfxplas = 0
Sound 0 = Pulse lasers fired by us
[X]
Subroutine startbd (category: Sound)
Start playing the docking music, if configured
[X]
Subroutine stopbd (category: Sound)
Stop playing the docking music