Skip to navigation


Elite I source

[Apple II version]

ELITE I FILE Produces the binary file ELTI.bin that gets loaded by elite-bcfs.asm.
CODE_I% = P% LOAD_I% = LOAD% + P% - CODE%
Name: yetanotherrts [Show more] Type: Subroutine Category: Tactics Summary: Contains an RTS
Context: See this subroutine on its own page References: This subroutine is called as follows: * SFRMIS calls yetanotherrts

This routine contains an RTS so we can return from the SFRMIS subroutine with a branch instruction. It also contains the DEMON label, which is left over from the 6502 Second Processor version, where it implements the demo (there is no demo in this version of Elite).
.yetanotherrts .DEMON RTS ; Return from the subroutine
Name: ECMOF [Show more] Type: Subroutine Category: Sound Summary: Switch off the E.C.M.
Context: See this subroutine on its own page References: This subroutine is called as follows: * Main flight loop (Part 16 of 16) calls ECMOF * RES2 calls ECMOF

Switch the E.C.M. off, turn off the dashboard bulb and make the sound of the E.C.M. switching off).
.ECMOF LDA #0 ; Set ECMA and ECMP to 0 to indicate that no E.C.M. is STA ECMA ; currently running STA ECMP JMP ECBLB ; Update the E.C.M. indicator bulb on the dashboard and ; return from the subroutine using a tail call
Name: SFRMIS [Show more] Type: Subroutine Category: Tactics Summary: Add an enemy missile to our local bubble of universe
Context: See this subroutine on its own page References: This subroutine is called as follows: * TACTICS (Part 5 of 7) calls SFRMIS

An enemy has fired a missile, so add the missile to our universe if there is room, and if there is, make the appropriate warnings and noises.
.SFRMIS LDX #MSL ; Set X to the ship type of a missile, and call SFS1-2 JSR SFS1-2 ; to add the missile to our universe with an AI flag ; of %11111110 (AI enabled, hostile, no E.C.M.) BCC yetanotherrts ; The C flag will be set if the call to SFS1-2 was a ; success, so if it's clear, jump to yetanotherrts to ; return from the subroutine (as yetanotherrts contains ; an RTS) LDA #120 ; Print recursive token 120 ("INCOMING MISSILE") as an JSR MESS ; in-flight message LDY #50 ; Call the SOHISS routine with Y = 50 to make the sound JMP SOHISS ; of the missile being launched and return from the ; subroutine using a tail call
Name: EXNO2 [Show more] Type: Subroutine Category: Status Summary: Process us making a kill Deep dive: Combat rank
Context: See this subroutine on its own page References: This subroutine is called as follows: * Main flight loop (Part 5 of 16) calls EXNO2 * Main flight loop (Part 11 of 16) calls EXNO2 * TACTICS (Part 1 of 7) calls EXNO2

We have killed a ship, so increase the kill tally, displaying an iconic message of encouragement if the kill total is a multiple of 256, and then make a nearby explosion sound.
Arguments: X The type of the ship that was killed
.EXNO2 LDA TALLYL ; We now add the fractional kill count to our tally, CLC ; starting with the fractional bytes: ADC KWL%-1,X ; STA TALLYL ; TALLYL = TALLYL + fractional kill count ; ; where the fractional kill count is taken from the ; KWL% table, according to the ship's type (we look up ; the X-1-th value from KWL% because ship types start ; at 1 rather than 0) LDA TALLY ; And then we add the low byte of TALLY(1 0): ADC KWH%-1,X ; STA TALLY ; TALLY = TALLY + carry + integer kill count ; ; where the integer kill count is taken from the KWH% ; table in the same way BCC davidscockup ; If there is no carry, jump to davidscockup to skip the ; following three instructions, as we have not earned ; a "RIGHT ON COMMANDER!" message INC TALLY+1 ; Increment the high byte of the kill count in TALLY LDA #101 ; The kill total is a multiple of 256, so it's time JSR MESS ; for a pat on the back, so print recursive token 101 ; ("RIGHT ON COMMANDER!") as an in-flight message .davidscockup LDY #55 ; Call the SOEXPL routine with Y = 55 to make the sound BNE SOEXPL ; of a ship exploding, returning from the subroutine ; using a tail call
Name: EXNO [Show more] Type: Subroutine Category: Sound Summary: Make the sound of a laser strike or ship explosion
Context: See this subroutine on its own page References: This subroutine is called as follows: * Main flight loop (Part 11 of 16) calls EXNO

Make the two-part explosion sound of us making a laser strike, or of another ship exploding.
.EXNO LDY #15 ; Call the SOEXPL routine with Y = 15 to make the sound BNE SOEXPL ; of us making a hit or kill and return from the ; subroutine using a tail call (this BNE is effectively ; a JMP as Y is never zero)
Name: BOOP [Show more] Type: Subroutine Category: Sound Summary: Make a long, low beep
Context: See this subroutine on its own page References: This subroutine is called as follows: * diskerror calls BOOP * dn2 calls BOOP * HME2 calls BOOP * Main flight loop (Part 3 of 16) calls BOOP * WARP calls BOOP
.BOOP LDY #99 ; Set the length of the loop below to 99 clicks, so we ; make a total of 100 clicks in the call to SOBEEP, to ; give a long beep LDX #255 ; Set the period of the sound at 255 for a low beep BNE SOBEEP ; Jump to SOBEEP to make a long, low beep (this BNE is ; effectively a JMP as X is never zero)
Name: SOHISS [Show more] Type: Subroutine Category: Sound Summary: Make the sound of a launch from the station, hyperspace or missile launch
Context: See this subroutine on its own page References: This subroutine is called as follows: * FRMIS calls SOHISS * HFS2 calls SOHISS * LAUN calls SOHISS * SFRMIS calls SOHISS

Arguments: Y The type of sound (i.e. the length of the explosion): * 0 = start of a launch from a station (called twice in succession from LAUN, with the 0 indicating a sound length of 256) * 10 = launch or hyperspace tunnel (called each time we draw a tunnel ring in HFS2) * 50 = enemy missile launch (SFRMIS) * 120 = our missile launch (FRMIS)
.SOHISS BIT DNOIZ ; If bit 7 of DNOIZ is non-zero, then sound is disabled, BMI SOUR ; so return from the subroutine (as SOUR contains an ; RTS) .SOHISS2 LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch ; We now make a hissing sound by making Y clicks on the ; speaker, and pausing for a random amount of time ; between each successive click JSR DORND ; Set A and X to random numbers DEX ; Decrement the random number in X NOP ; Wait for four CPU cycles (as each NOP takes two CPU NOP ; cycles) BNE P%-3 ; If X is non-zero then loop back to repeat the DEX and ; NOP instructions, so this waits for a total of 4 * X ; CPU cycles DEY ; Decrement the sound length in Y BNE SOHISS2 ; Loop back to make another click and wait for a random ; amount of time between clicks, until we have made a ; sound consisting of Y clicks ; ; An argument of Y = 0 will therefore make 256 clicks in ; the above loop LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch RTS ; Return from the subroutine
Name: EXNO3 [Show more] Type: Subroutine Category: Sound Summary: Make the sound of a collision, or an exploding cargo canister or missile
Context: See this subroutine on its own page References: This subroutine is called as follows: * Main flight loop (Part 10 of 16) calls EXNO3 * OOPS calls EXNO3 * TACTICS (Part 1 of 7) calls EXNO3
.EXNO3 LDY #40 ; Set Y = 40 and fall through into SOEXPL to make the ; sound of a collision, or an exploding cargo canister ; or missile
Name: SOEXPL [Show more] Type: Subroutine Category: Sound Summary: Make an explosion sound
Context: See this subroutine on its own page References: This subroutine is called as follows: * DEATH calls SOEXPL * EXNO calls SOEXPL * EXNO2 calls SOEXPL

Arguments: Y The type of sound (i.e. the length of the explosion): * 15 = the sound of a laser strike on another ship (EXNO) * 40 = the sound of a collision, or an exploding cargo canister or missile (EXNO3) * 55 = the sound of a ship exploding (EXNO2) * 210 = the sound of us dying (DEATH)
.SOEXPL BIT DNOIZ ; If bit 7 of DNOIZ is non-zero, then sound is disabled, BMI SOUR ; so return from the subroutine (as SOUR contains an ; RTS) LDX #50 ; Set T3 = 50 to use as the starting period for this STX T3 ; sound (which increases as the sound continues, which ; spaces out the clicks and makes the sound of the ; explosion dissipate .BEEPL4 LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch INC T3 ; Increment the period in T3 LDX T3 ; Loop around for T3 iterations, waiting for four cycles DEX ; in each iteration, so as the sound continues and T3 NOP ; increases, the wait gets longer and the frequency of NOP ; the explosion tone lowers into a dissipated explosion BNE P%-3 ; noise JSR DORND ; Set A and X to random numbers DEX ; Decrement the random number in X NOP ; Wait for two CPU cycles BNE P%-2 ; If X is non-zero then loop back to repeat the DEX and ; NOP instructions, so this waits for a total of 2 * X ; CPU cycles DEY ; Decrement the sound length in Y BNE BEEPL4 ; Loop back to make another click and wait for a random ; and (on average) increasing amount of time between ; clicks, until we have made a sound consisting of Y ; clicks LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch RTS ; Return from the subroutine
Name: BEEP [Show more] Type: Subroutine Category: Sound Summary: Make a short, high beep
Context: See this subroutine on its own page References: This subroutine is called as follows: * Main flight loop (Part 11 of 16) calls BEEP * R5 calls BEEP * BOOP calls via SOBEEP * LASNOISE calls via SOUR * SOBLIP calls via SOUR * SOBOMB calls via SOUR * SOEXPL calls via SOUR * SOHISS calls via SOUR

Other entry points: SOBEEP Make a beep as follows: * X = the period of the beep (a bigger value means a lower pitch) * Y = the length of the beep SOUR Contains an RTS
.BEEP LDY #30 ; Set the length of the loop below to 30 clicks, so we ; make a total of 31 clicks in the following LDX #110 ; Set the period of the sound at 110 for a high beep .SOBEEP BIT DNOIZ ; If bit 7 of DNOIZ is non-zero, then sound is disabled, BMI SOUR ; so return from the subroutine (as SOUR contains an ; RTS) STX T3 ; Store the period in T3 .BEEPL1 LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch LDX T3 ; Loop around for T3 iterations, so the higher the DEX ; period in X, the longer the wait BNE P%-1 DEY ; Decrement the sound length in Y BNE BEEPL1 ; Loop back to make another click until we have made a ; sound consisting of Y clicks LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch .SOUR RTS ; Return from the subroutine
Name: SOBLIP [Show more] Type: Subroutine Category: Sound Summary: Make the sound of the hyperspace drive being engaged, or the sound of the E.C.M.
Context: See this subroutine on its own page References: This subroutine is called as follows: * LL164 calls SOBLIP * Main flight loop (Part 16 of 16) calls SOBLIP

Arguments: X The period of the sound (a bigger value means a lower pitch) Y The type of sound (i.e. the length of the sound): * 20 = the sound of the E.C.M going off (part 16 of the main flight loop) * 90 = the sound of the hyperspace drive being engaged (LL164)
.SOBLIP BIT DNOIZ ; If bit 7 of DNOIZ is non-zero, then sound is disabled, BMI SOUR ; so return from the subroutine (as SOUR contains an ; RTS) STX T3 ; Store the period in T3 .BEEPL2 LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch DEC T3 ; Decrement the period in T3 LDX T3 ; Loop around for T3 iterations, waiting for two cycles DEX ; in each iteration, so as the sound continues and T3 NOP ; decreases, the wait gets shorter and the frequency of BNE P%-2 ; the sound rises DEY ; Decrement the sound length in Y BNE BEEPL2 ; Loop back to make another click and wait for a ; decreasing amount of time between clicks, until we ; have made a sound consisting of Y clicks LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch RTS ; Return from the subroutine
Name: LASNOISE [Show more] Type: Subroutine Category: Sound Summary: Make the sound of our laser firing or the sound of us being hit by lasers
Context: See this subroutine on its own page References: This subroutine is called as follows: * Main flight loop (Part 3 of 16) calls LASNOISE * TACTICS (Part 6 of 7) calls LASNOISE
.LASNOISE LDY #11 ; Set the length of the loop below to 11 clicks, so we ; make a total of 12 clicks in the following LDX #150 ; Set the period of the sound at 150, which increases ; as the sound progresses .SOBLOP BIT DNOIZ ; If bit 7 of DNOIZ is non-zero, then sound is disabled, BMI SOUR ; so return from the subroutine (as SOUR contains an ; RTS) STX T3 ; Store the period in T3 .BEEPL3 LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch INC T3 ; Increment the period in T3 twice, so the tone of the INC T3 ; sound falls rapidly LDX T3 ; Loop around for T3 iterations, so as the sound DEX ; continues and T3 increases, the wait gets longer and BNE P%-1 ; the frequency of the laser tone lowers into a ; dissipated explosion noise DEY ; Decrement the sound length in Y BNE BEEPL3 ; Loop back to make another click and wait for a rapidly ; increasing amount of time between clicks, until we ; have made a sound consisting of Y clicks LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch RTS ; Return from the subroutine
Name: LASNOISE2 [Show more] Type: Subroutine Category: Sound Summary: An unused routine that makes the sound of the energy bomb going off
Context: See this subroutine on its own page References: No direct references to this subroutine in this source file
.LASNOISE2 LDY #11 ; Set Y = 11, though this has no effect as Y is set to ; 25 in the following LDX #130 ; Set X = 130, though this has no effect as X is ; overwritten with a random number before it is used ; Fall through into SOBOMB to make the sound of an ; energy bomb going off ; ; The above variables make no difference to the sound ; made by SOBOMB, but given the title of the routine, ; it was presumably designed to jump to the SOBLOP entry ; point to make a higher-pitched variation of the laser ; sound, rather than falling in to SOBOMB ; ; All that is missing is a BNE SOBLOP instruction to do ; the jump
Name: SOBOMB [Show more] Type: Subroutine Category: Sound Summary: Make the sound of an energy bomb going off
Context: See this subroutine on its own page References: This subroutine is called as follows: * BOMBEFF2 calls SOBOMB
.SOBOMB BIT DNOIZ ; If bit 7 of DNOIZ is non-zero, then sound is disabled, BMI SOUR ; so return from the subroutine (as SOUR contains an ; RTS) LDY #25 ; Set the length of the loop below to 25 clicks, so we ; make a total of 26 clicks in the following .SOHISS4 LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch JSR DORND ; Set A and X to random numbers AND #31 ; Reduce A to a random number in the range 0 to 31 ORA #$E0 ; Increase A to a random number in the range 224 to 255 TAX ; Set X to our random number in the range 224 to 255, ; which we now use as the period for our sound (so this ; is a low toned explosion sound with a random element ; of white noise, like a dissipated explosion) DEX ; Decrement the random number in X NOP ; Wait for two CPU cycles BNE P%-2 ; If X is non-zero then loop back to repeat the DEX and ; NOP instructions, so this waits for a total of 2 * X ; CPU cycles DEY ; Decrement the sound length in Y BNE SOHISS4 ; Loop back to make another click and wait for a random ; amount of time between clicks, until we have made a ; sound consisting of Y clicks LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch RTS ; Return from the subroutine
Name: CLICK [Show more] Type: Subroutine Category: Sound Summary: Toggle the state of the speaker (i.e. move it in or out) to make a single click
Context: See this subroutine on its own page References: This subroutine is called as follows: * BOMBOFF calls CLICK
.CLICK BIT DNOIZ ; If bit 7 of DNOIZ is non-zero, then sound is disabled, BMI SOUR2 ; so jump to SOUR2 to return from the subroutine LDA $C030 ; Toggle the state of the speaker (i.e. move it in or ; out) by reading the SPEAKER soft switch .SOUR2 RTS ; Return from the subroutine
Name: COLD [Show more] Type: Subroutine Category: Loader Summary: Initialise the screen mode, clear memory and set up interrupt handlers
Context: See this subroutine on its own page References: This subroutine is called as follows: * S% calls COLD
.COLD JSR HGR ; Switch to the high-resolution graphics screen mode ; We start by zeroing two pages of memory from $0800 ; to $09FF, so that zeroes the following: ; ; * The disk sector buffer from $0800 to $08FF ; ; * The disk 6-bit nibble buffer from $0900 to $09FF ; ; So this initialises the disk buffers at buffer and ; buffer2 LDA #8 ; Set the high byte of SC(1 0) to 8 STA SC+1 LDX #2 ; Set X = 2 to act as a page counter, so we zero two ; whole pages of memory LDA #0 ; Set A = 0 so we can use this to zero memory locations STA SC ; Set the low byte of SC(1 0) to zero, so SC is now set ; to $0800 TAY ; Set Y = 0 to act as a byte counter within each page .zerowksploop STA (SC),Y ; Zero the Y-th byte of SC(1 0) INY ; Increment the byte counter BNE zerowksploop ; Loop back until we have zeroed a whole page of memory INC SC+1 ; Increment the high byte of SC(1 0) to point to the ; next page in memory DEX ; Decrement the page counter in X BNE zerowksploop ; Loop back until we have zeroed all three pages ; Next, we zero the page of memory from $0200 to $02FF, ; so that zeroes the following: ; ; * The UP from workspace $0200 to $02FF (though it ; doesn't zero the last two bytes of the workspace ; at $0300 and $0301) ; ; At this point Y = 0, so we can use that as a byte ; counter .zerowkl2 STA $0200,Y ; Zero the Y-th byte of $0200 DEY ; Decrement the byte counter BNE zerowkl2 ; Loop back until we have zeroed the whole page LDA #LO(NMIpissoff) ; Set the NMI interrupt vector in NMIV to point to the STA NMIV ; NMIpissoff routine, which acknowledges NMI interrupts LDA #HI(NMIpissoff) ; and ignores them STA NMIV+1 LDA #LO(CHPR2) ; Set the CHRV interrupt vector in CHRV to point to the STA CHRV ; CHPR2 routine, which prints valid ASCII characters LDA #HI(CHPR2) ; using the CHPR routine (so this replaces the normal STA CHRV+1 ; text-printing routine with Elite's own CHPR routine) SEI ; Disable interrupts (though they will be re-enabled by ; the first non-maskable interrupt that is handled by ; NMIpissoff, so this probably won't disable interrupts ; for long) RTS ; Return from the subroutine
Name: NMIpissoff [Show more] Type: Subroutine Category: Loader Summary: Acknowledge NMI interrupts and ignore them
Context: See this subroutine on its own page References: This subroutine is called as follows: * COLD calls NMIpissoff
.NMIpissoff CLI ; Enable interrupts, so we acknowledge the NMI and ; basically ignore it RTI ; Return from the interrupt
Save ELTI.bin
PRINT "ELITE I" PRINT "Assembled at ", ~CODE_I% PRINT "Ends at ", ~P% PRINT "Code size is ", ~(P% - CODE_I%) PRINT "Execute at ", ~LOAD% PRINT "Reload at ", ~LOAD_I% PRINT "S.ELTI ", ~CODE_I%, " ", ~P%, " ", ~LOAD%, " ", ~LOAD_H% SAVE "3-assembled-output/ELTI.bin", CODE_I%, P%, LOAD%