Skip to navigation

Elite on the BBC Micro and NES

Elite A encyclopedia source

[Elite-A]

ELITE A FILE
ORG CODE% LOAD_A% = LOAD%
Name: S% [Show more] Type: Workspace Address: &11E3 to &11F0 Category: Workspaces Summary: Entry points and vector addresses in the main docked code
Context: See this workspace on its own page References: No direct references to this workspace in this source file
.S% \ --- Mod: Code removed for Elite-A: ------------------> \ JMP DOENTRY \ Decrypt the main docked code and dock at the station \ \ JMP DOBEGIN \ Decrypt the main docked code and start a new game \ \ JMP CHPR \ 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 \ \ BRKV = P% - 2 \ The address of the destination address in the above \ \ JMP BRBR1 instruction. This ensures that any code that \ \ updates BRKV will update this instruction instead of \ \ the actual vector \ --- And replaced by: --------------------------------> JMP DOENTRY \ Initialise the encyclopedia and show the menu screen JMP DOENTRY \ Initialise the encyclopedia and show the menu screen JMP CHPR \ WRCHV is set to point here by elite-loader.asm EQUW IRQ1 \ IRQ1V is set to point here by elite-loader.asm JMP BRBR \ BRKV is set to point here by elite-loader.asm BRKV = P% - 2 \ The address of the destination address in the above \ JMP BRBR instruction. This ensures that any code that \ updates BRKV will update this instruction instead of \ the actual vector \ --- End of replacement ------------------------------>
Name: INBAY [Show more] Type: Subroutine Category: Loader Summary: Load and run the main docked code in 1.D
Context: See this subroutine on its own page References: This subroutine is called as follows: * escape calls INBAY
.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 launch 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 instead
Name: LTLI [Show more] Type: Variable Category: Loader Summary: The OS command string for loading the docked code in file 1.D
Context: See this variable on its own page References: This variable is used as follows: * INBAY uses LTLI * launch uses LTLI
.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 ------------------------------>
Name: launch [Show more] Type: Subroutine Category: Loader Summary: Load and run the main docked code in 1.D
Context: See this subroutine on its own page References: This subroutine is called as follows: * TT102 calls launch
\ --- Mod: Code added for Elite-A: --------------------> .launch LDA #'R' \ Set the first byte of LTLI to "R", so it changes from STA LTLI \ "L.1.D" into "R.1.D", so when we fall through into \ escape, we load and run the docked code in 1.D EQUB &2C \ Skip the next instruction by turning it into \ &2C &A9 &52, or BIT &52A9, which does nothing apart \ from affect the flags \ Fall through into escape to set KL+1 to the non-zero \ value in A before running the docking code (which will \ not show the docking tunnel and ship hangar, as KL+1 \ is now non-zero) \ --- End of added code ------------------------------->
Name: escape [Show more] Type: Subroutine Category: Start and end Summary: Load the main docked code so that it shows the docking tunnel
Context: See this subroutine on its own page References: This subroutine is called as follows: * BR1 calls escape * DK4 calls escape
\ --- Mod: Code added for Elite-A: --------------------> .escape LDA #0 \ Set the value of KL+1 to 0, so when the main docked STA KL+1 \ loads, we show the docking tunnel and ship hangar JMP INBAY \ Jump to INBAY to load the main docked code \ --- End of added code ------------------------------->
Name: DOENTRY [Show more] Type: Subroutine Category: Loader Summary: Initialise the encyclopedia and show the menu screen
Context: See this subroutine on its own page References: This subroutine is called as follows: * S% calls DOENTRY
\ --- Mod: Code added for Elite-A: --------------------> .DOENTRY JSR BRKBK \ Set the standard BRKV handler for the game IF _BUG_FIX JSR SwitchToCharSet \ Switch &C000 to the MOS character definitions ENDIF JSR RES2 \ Reset a number of flight variables and workspaces JMP BAY \ Go to the docking bay (i.e. show the Encyclopedia \ screen) \ --- End of added code ------------------------------->
Name: BRKBK [Show more] Type: Subroutine Category: Save and load Summary: Set the standard BRKV handler for the game
Context: See this subroutine on its own page References: This subroutine is called as follows: * DOENTRY calls BRKBK
.BRKBK LDA #LO(BRBR) \ Set BRKV to point to the BRBR routine STA BRKV LDA #HI(BRBR) STA BRKV+1 RTS \ Return from the subroutine
Name: write_msg3 [Show more] Type: Subroutine Category: Text Summary: Print an extended recursive token from the msg_3 token table Deep dive: The Encyclopedia Galactica
Context: See this subroutine on its own page References: This subroutine is called as follows: * controls calls write_msg3 * equip_data calls write_msg3 * menu calls write_msg3 * ships_ag calls write_msg3 * write_card calls write_msg3

Arguments: A The recursive token to be printed, in the range 0-255
Returns: A A is preserved Y Y is preserved V(1 0) V(1 0) is preserved
\ --- Mod: Code added for Elite-A: --------------------> .write_msg3 PHA \ Store A on the stack, so we can retrieve it later TAX \ Copy the token number from A into X TYA \ Store Y on the stack PHA LDA V \ Store V(1 0) on the stack PHA LDA V+1 PHA LDA #LO(msg_3) \ Set V to the low byte of msg_3 STA V LDA #HI(msg_3) \ Set A to the high byte of msg_3 BNE DTEN \ Call DTEN to print token number X from the msg_3 \ table and restore the values of A, Y and V(1 0) from \ the stack, returning from the subroutine using a tail \ call (this BNE is effectively a JMP as A is never \ zero) \ --- End of added code ------------------------------->
Name: MT27 [Show more] Type: Subroutine Category: Text Summary: Print the captain's name during mission briefings Deep dive: Extended text tokens The Constrictor mission
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls MT27

This routine prints the following tokens, depending on the galaxy number: * Token 217 ("CURRUTHERS") in galaxy 0 * Token 218 ("FOSDYKE SMYTHE") in galaxy 1 * Token 219 ("FORTESQUE") in galaxy 2 This is used when printing extended token 213 as part of the mission briefings, which looks like this when printed: Commander {commander name}, I am Captain {mission captain's name} of Her Majesty's Space Navy where {mission captain's name} is replaced by one of the names above.
.MT27 LDA #217 \ Set A = 217, so when we fall through into MT28, the \ 217 gets added to the current galaxy number, so the \ extended token that is printed is 217-219 (as this is \ only called in galaxies 0 through 2) EQUB &2C \ Skip the next instruction by turning it into \ &2C &A9 &DC, or BIT &DCA9, which does nothing apart \ from affect the flags
Name: MT28 [Show more] Type: Subroutine Category: Text Summary: Print the location hint during the mission 1 briefing Deep dive: Extended text tokens The Constrictor mission
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls MT28

This routine prints the following tokens, depending on the galaxy number: * Token 220 ("WAS LAST SEEN AT {single cap}REESDICE") in galaxy 0 * Token 221 ("IS BELIEVED TO HAVE JUMPED TO THIS GALAXY") in galaxy 1 This is used when printing extended token 10 as part of the mission 1 briefing, which looks like this when printed: It went missing from our ship yard on Xeer five months ago and {mission 1 location hint} where {mission 1 location hint} is replaced by one of the names above.
.MT28 LDA #220 \ Set A = galaxy number in GCNT + 220, which is in the CLC \ range 220-221, as this is only called in galaxies 0 ADC GCNT \ and 1 \ --- Mod: Code removed for Elite-A: ------------------> \ BNE DETOK \ Jump to DETOK to print extended token 220-221, \ \ returning from the subroutine using a tail call (this \ \ BNE is effectively a JMP as A is never zero) \ --- And replaced by: --------------------------------> \ Fall through into DETOK to print extended token \ 220-221 \ --- End of replacement ------------------------------>
Name: DETOK [Show more] Type: Subroutine Category: Text Summary: Print an extended recursive token from the TKN1 token table Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * DETOK2 calls DETOK * HME2 calls DETOK * MT17 calls DETOK * PDESC calls DETOK * TT102 calls DETOK * write_msg3 calls via DTEN

Arguments: A The recursive token to be printed, in the range 1-255
Returns: A A is preserved Y Y is preserved V(1 0) V(1 0) is preserved
Other entry points: DTEN Print recursive token number X from the token table pointed to by (A V), used to print tokens from the msg_3 table via calls to write_msg3
.DETOK PHA \ Store A on the stack, so we can retrieve it later TAX \ Copy the token number from A into X TYA \ Store Y on the stack PHA LDA V \ Store V(1 0) on the stack PHA LDA V+1 PHA LDA #LO(TKN1) \ Set V to the low byte of TKN1 STA V LDA #HI(TKN1) \ Set A to the high byte of TKN1, so when we fall \ through into DTEN, V(1 0) gets set to the address of \ the TKN1 token table .DTEN STA V+1 \ Set the high byte of V(1 0) to A, so V(1 0) now points \ to the start of the token table to use LDY #0 \ First, we need to work our way through the table until \ we get to the token that we want to print. Tokens are \ delimited by #VE, and VE EOR VE = 0, so we work our \ way through the table in, counting #VE delimiters \ until we have passed X of them, at which point we jump \ down to DTL2 to do the actual printing. So first, we \ set a counter Y to point to the character offset as we \ scan through the table .DTL1 LDA (V),Y \ Load the character at offset Y in the token table, \ which is the next character from the token table \ --- Mod: Code removed for Elite-A: ------------------> \ EOR #VE \ Tokens are stored in memory having been EOR'd with \ \ #VE, so we repeat the EOR to get the actual character \ \ in this token \ --- End of removed code -----------------------------> BNE DT1 \ If the result is non-zero, then this is a character \ in a token rather than the delimiter (which is #VE), \ so jump to DT1 DEX \ We have just scanned the end of a token, so decrement \ X, which contains the token number we are looking for BEQ DTL2 \ If X has now reached zero then we have found the token \ we are looking for, so jump down to DTL2 to print it .DT1 INY \ Otherwise this isn't the token we are looking for, so \ increment the character pointer BNE DTL1 \ If Y hasn't just wrapped around to 0, loop back to \ DTL1 to process the next character INC V+1 \ We have just crossed into a new page, so increment \ V+1 so that V points to the start of the new page BNE DTL1 \ Jump back to DTL1 to process the next character (this \ BNE is effectively a JMP as V+1 won't reach zero \ before we reach the end of the token table) .DTL2 INY \ We just detected the delimiter byte before the token \ that we want to print, so increment the character \ pointer to point to the first character of the token, \ rather than the delimiter BNE P%+4 \ If Y hasn't just wrapped around to 0, skip the next \ instruction INC V+1 \ We have just crossed into a new page, so increment \ V+1 so that V points to the start of the new page LDA (V),Y \ Load the character at offset Y in the token table, \ which is the next character from the token we want to \ print \ --- Mod: Code removed for Elite-A: ------------------> \ EOR #VE \ Tokens are stored in memory having been EOR'd with \ \ #VE, so we repeat the EOR to get the actual character \ \ in this token \ --- End of removed code -----------------------------> BEQ DTEX \ If the result is zero, then this is the delimiter at \ the end of the token to print (which is #VE), so jump \ to DTEX to return from the subroutine, as we are done \ printing JSR DETOK2 \ Otherwise call DETOK2 to print this part of the token JMP DTL2 \ Jump back to DTL2 to process the next character .DTEX PLA \ Restore V(1 0) from the stack, so it is preserved STA V+1 \ through calls to this routine PLA STA V PLA \ Restore Y from the stack, so it is preserved through TAY \ calls to this routine PLA \ Restore A from the stack, so it is preserved through \ calls to this routine RTS \ Return from the subroutine
Name: DETOK2 [Show more] Type: Subroutine Category: Text Summary: Print an extended text token (1-255) Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * DETOK calls DETOK2 * MT18 calls via DTS * write_card calls via DTS * write_card calls via DT3 * write_card calls via msg_pairs

Arguments: A The token to be printed (1-255)
Returns: A A is preserved Y Y is preserved V(1 0) V(1 0) is preserved
Other entry points: DTS Print a single letter in the correct case DT3 Print the jump token given in A (where A is in the range 0 to 31) msg_pairs Print the extended two-letter token in A (where A is in the range 215 to 255)
.DETOK2 CMP #32 \ If A < 32 then this is a jump token, so skip to DT3 to BCC DT3 \ process it BIT DTW3 \ If bit 7 of DTW3 is clear, then extended tokens are BPL DT8 \ enabled, so jump to DT8 to process them \ If we get there then this is not a jump token and \ extended tokens are not enabled, so we can call the \ standard text token routine at TT27 to print the token TAX \ Copy the token number from A into X TYA \ Store Y on the stack PHA LDA V \ Store V(1 0) on the stack PHA LDA V+1 PHA TXA \ Copy the token number from X back into A JSR TT27 \ Call TT27 to print the text token JMP DT7 \ Jump to DT7 to restore V(1 0) and Y from the stack and \ return from the subroutine .DT8 \ If we get here then this is not a jump token and \ extended tokens are enabled CMP #'[' \ If A < ASCII "[" (i.e. A <= ASCII "Z", or 90) then BCC DTS \ this is a printable ASCII character, so jump down to \ DTS to print it CMP #129 \ If A < 129, so A is in the range 91-128, jump down to BCC DT6 \ DT6 to print a randomised token from the MTIN table CMP #215 \ If A < 215, so A is in the range 129-214, jump to BCC DETOK \ DETOK as this is a recursive token, returning from the \ subroutine using a tail call \ If we get here then A >= 215, so this is a two-letter \ token from the extended TKN2/QQ16 table \ --- Mod: Code added for Elite-A: --------------------> .msg_pairs \ --- End of added code -------------------------------> SBC #215 \ Subtract 215 to get a token number in the range 0-12 \ (the C flag is set as we passed through the BCC above, \ so this subtraction is correct) ASL A \ Set A = A * 2, so it can be used as a pointer into the \ two-letter token tables at TKN2 and QQ16 PHA \ Store A on the stack, so we can restore it for the \ second letter below TAX \ Fetch the first letter of the two-letter token from LDA TKN2,X \ TKN2, which is at TKN2 + X JSR DTS \ Call DTS to print it PLA \ Restore A from the stack and transfer it into X TAX LDA TKN2+1,X \ Fetch the second letter of the two-letter token from \ TKN2, which is at TKN2 + X + 1, and fall through into \ DTS to print it .DTS CMP #'A' \ If A < ASCII "A", jump to DT9 to print this as ASCII BCC DT9 BIT DTW6 \ If bit 7 of DTW6 is set, then lower case has been BMI DT10 \ enabled by jump token 13, {lower case}, so jump to \ DT10 to apply the lower case and single cap masks BIT DTW2 \ If bit 7 of DTW2 is set, then we are not currently BMI DT5 \ printing a word, so jump to DT5 so we skip the setting \ of lower case in Sentence Case (which we only want to \ do when we are already printing a word) .DT10 ORA DTW1 \ Convert the character to lower case if DTW1 is \ %00100000 (i.e. if we are in {sentence case} mode) .DT5 AND DTW8 \ Convert the character to upper case if DTW8 is \ %11011111 (i.e. after a {single cap} token) .DT9 JMP DASC \ Jump to DASC to print the ASCII character in A, \ returning from the routine using a tail call .DT3 \ If we get here then the token number in A is in the \ range 1 to 32, so this is a jump token that should \ call the corresponding address in the jump table at \ JMTB TAX \ Copy the token number from A into X TYA \ Store Y on the stack PHA LDA V \ Store V(1 0) on the stack PHA LDA V+1 PHA TXA \ Copy the token number from X back into A ASL A \ Set A = A * 2, so it can be used as a pointer into the \ jump table at JMTB, though because the original range \ of values is 1-32, so the doubled range is 2-64, we \ need to take the offset into the jump table from \ JMTB-2 rather than JMTB TAX \ Copy the doubled token number from A into X LDA JMTB-2,X \ Set DTM(2 1) to the X-th address from the table at STA DTM+1 \ JTM-2, which modifies the JSR DASC instruction at LDA JMTB-1,X \ label DTM below so that it calls the subroutine at the STA DTM+2 \ relevant address from the JMTB table TXA \ Copy the doubled token number from X back into A LSR A \ Halve A to get the original token number .DTM JSR DASC \ Call the relevant JMTB subroutine, as this instruction \ will have been modified by the above to point to the \ relevant address .DT7 PLA \ Restore V(1 0) from the stack, so it is preserved STA V+1 \ through calls to this routine PLA STA V PLA \ Restore Y from the stack, so it is preserved through TAY \ calls to this routine RTS \ Return from the subroutine .DT6 \ If we get here then the token number in A is in the \ range 91-128, which means we print a randomly picked \ token from the token range given in the corresponding \ entry in the MTIN table STA SC \ Store the token number in SC TYA \ Store Y on the stack PHA LDA V \ Store V(1 0) on the stack PHA LDA V+1 PHA JSR DORND \ Set X to a random number TAX LDA #0 \ Set A to 0, so we can build a random number from 0 to \ 4 in A plus the C flag, with each number being equally \ likely CPX #51 \ Add 1 to A if X >= 51 ADC #0 CPX #102 \ Add 1 to A if X >= 102 ADC #0 CPX #153 \ Add 1 to A if X >= 153 ADC #0 CPX #204 \ Set the C flag if X >= 204 LDX SC \ Fetch the token number from SC into X, so X is now in \ the range 91-128 ADC MTIN-91,X \ Set A = MTIN-91 + token number (91-128) + random (0-4) \ = MTIN + token number (0-37) + random (0-4) JSR DETOK \ Call DETOK to print the extended recursive token in A JMP DT7 \ Jump to DT7 to restore V(1 0) and Y from the stack and \ return from the subroutine using a tail call
Name: MT1 [Show more] Type: Subroutine Category: Text Summary: Switch to ALL CAPS when printing extended tokens Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * controls calls MT1 * equip_data calls MT1 * JMTB calls MT1 * menu calls MT1 * ships_ag calls MT1 * write_card calls MT1

This routine sets the following: * DTW1 = %00000000 (do not change case to lower case) * DTW6 = %00000000 (lower case is not enabled)
.MT1 LDA #%00000000 \ Set A = %00000000, so when we fall through into MT2, \ both DTW1 and DTW6 get set to %00000000 EQUB &2C \ Skip the next instruction by turning it into \ &2C &A9 &20, or BIT &20A9, which does nothing apart \ from affect the flags
Name: MT2 [Show more] Type: Subroutine Category: Text Summary: Switch to Sentence Case when printing extended tokens Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * controls calls MT2 * equip_data calls MT2 * JMTB calls MT2 * menu calls MT2 * TTX66 calls MT2 * write_card calls MT2

This routine sets the following: * DTW1 = %00100000 (apply lower case to the second letter of a word onwards) * DTW6 = %00000000 (lower case is not enabled)
.MT2 LDA #%00100000 \ Set DTW1 = %00100000 STA DTW1 LDA #00000000 \ Set DTW6 = %00000000 STA DTW6 RTS \ Return from the subroutine
Name: column_16 [Show more] Type: Subroutine Category: Text Summary: Tab to column 16 and start a new word when printing extended tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls column_16
\ --- Mod: Code added for Elite-A: --------------------> .column_16 LDA #16 \ Set X to 16 so when we fall through into MT8 we move \ the text cursor to column 16 instead of 6 EQUB &2C \ Skip the next instruction by turning it into \ &2C &A9 &06, or BIT &06A9, which does nothing apart \ from affect the flags \ Fall through into MT8 to move the text cursor to \ column 16 and start a new word \ --- End of added code ------------------------------->
Name: MT8 [Show more] Type: Subroutine Category: Text Summary: Tab to column 6 and start a new word when printing extended tokens Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls MT8 * JMTB calls via set_token

This routine sets the following: * XC = 6 (tab to column 6) * DTW2 = %11111111 (we are not currently printing a word)
Other entry points: set_token Start a new word when printing extended tokens
.MT8 LDA #6 \ Move the text cursor to column 6 STA XC \ --- Mod: Code added for Elite-A: --------------------> .set_token \ --- End of added code -------------------------------> LDA #%11111111 \ Set all the bits in DTW2 STA DTW2 RTS \ Return from the subroutine
Name: MT9 [Show more] Type: Subroutine Category: Text Summary: Clear the screen and set the current view type to 1 Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls MT9

This routine sets the following: * XC = 1 (tab to column 1) before calling TT66 to clear the screen and set the view type to 1.
.MT9 LDA #1 \ Move the text cursor to column 1 STA XC JMP TT66 \ Jump to TT66 to clear the screen and set the current \ view type to 1, returning from the subroutine using a \ tail call
Name: MT13 [Show more] Type: Subroutine Category: Text Summary: Switch to lower case when printing extended tokens Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * equip_data calls MT13 * JMTB calls MT13 * MT29 calls MT13

This routine sets the following: * DTW1 = %00100000 (apply lower case to the second letter of a word onwards) * DTW6 = %10000000 (lower case is enabled)
.MT13 LDA #%10000000 \ Set DTW6 = %10000000 STA DTW6 LDA #%00100000 \ Set DTW1 = %00100000 STA DTW1 RTS \ Return from the subroutine
Name: clr_vdustat [Show more] Type: Subroutine Category: Text Summary: Switch to standard tokens in lower case
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls clr_vdustat
\ --- Mod: Code added for Elite-A: --------------------> .clr_vdustat LDA #%00000001 \ Set A to %00000001 so when we fall through into MT6 we \ set QQ17 to %00000001 instead of %10000000, so we \ switch to lower case instead of Sentence Case EQUB &2C \ Skip the next instruction by turning it into \ &2C &A9 &80, or BIT &80A9, which does nothing apart \ from affect the flags \ Fall through into MT6 to switch to standard tokens in \ lower case \ --- End of added code ------------------------------->
Name: MT6 [Show more] Type: Subroutine Category: Text Summary: Switch to standard tokens in Sentence Case Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls MT6

This routine sets the following: * QQ17 = %10000000 (set Sentence Case for standard tokens) * DTW3 = %11111111 (print standard tokens)
.MT6 LDA #%10000000 \ Set bit 7 of QQ17 to switch standard tokens to STA QQ17 \ Sentence Case LDA #%11111111 \ Set A = %11111111, so when we fall through into MT5, \ DTW3 gets set to %11111111 and calls to DETOK print \ standard tokens EQUB &2C \ Skip the next instruction by turning it into \ &2C &A9 &00, or BIT &00A9, which does nothing apart \ from affect the flags
Name: MT5 [Show more] Type: Subroutine Category: Text Summary: Switch to extended tokens Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls MT5

This routine sets the following: * DTW3 = %00000000 (print extended tokens)
.MT5 LDA #%00000000 \ Set DTW3 = %00000000, so that calls to DETOK print STA DTW3 \ extended tokens RTS \ Return from the subroutine
Name: MT14 [Show more] Type: Subroutine Category: Text Summary: Switch to justified text when printing extended tokens Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * HME2 calls MT14 * JMTB calls MT14

This routine sets the following: * DTW4 = %10000000 (justify text, print buffer on carriage return) * DTW5 = 0 (reset line buffer size)
.MT14 LDA #%10000000 \ Set A = %10000000, so when we fall through into MT15, \ DTW4 gets set to %10000000 EQUB &2C \ Skip the next instruction by turning it into \ &2C &A9 &00, or BIT &00A9, which does nothing apart \ from affect the flags
Name: MT15 [Show more] Type: Subroutine Category: Text Summary: Switch to left-aligned text when printing extended tokens Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * HME2 calls MT15 * JMTB calls MT15

This routine sets the following: * DTW4 = %00000000 (do not justify text, print buffer on carriage return) * DTW5 = 0 (reset line buffer size)
.MT15 LDA #0 \ Set DTW4 = %00000000 STA DTW4 ASL A \ Set DTW5 = 0 (even when we fall through from MT14 with STA DTW5 \ A set to %10000000) RTS \ Return from the subroutine
Name: MT17 [Show more] Type: Subroutine Category: Text Summary: Print the selected system's adjective, e.g. Lavian for Lave Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls MT17

The adjective for the current system is generated by taking the system name, removing the last character if it is a vowel, and adding "-ian" to the end, so: * Lave gives Lavian (as in "Lavian tree grub") * Leesti gives Leestian (as in "Leestian Evil Juice") This routine is called by jump token 17, {system name adjective}, and it can only be used when justified text is being printed - i.e. following jump token 14, {justify} - because the routine needs to use the line buffer to work.
.MT17 LDA QQ17 \ Set QQ17 = %10111111 to switch to Sentence Case AND #%10111111 STA QQ17 LDA #3 \ Print control code 3 (selected system name) into the JSR TT27 \ line buffer LDX DTW5 \ Load the last character of the line buffer BUF into A LDA BUF-1,X \ (as DTW5 contains the buffer size, so character DTW5-1 \ is the last character in the buffer BUF) JSR VOWEL \ Test whether the character is a vowel, in which case \ this will set the C flag BCC MT171 \ If the character is not a vowel, skip the following \ instruction DEC DTW5 \ The character is a vowel, so decrement DTW5, which \ removes the last character from the line buffer (i.e. \ it removes the trailing vowel from the system name) .MT171 LDA #153 \ Print extended token 153 ("IAN"), returning from the JMP DETOK \ subroutine using a tail call
Name: MT18 [Show more] Type: Subroutine Category: Text Summary: Print a random 1-8 letter word in Sentence Case Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls MT18
.MT18 JSR MT19 \ Call MT19 to capitalise the next letter (i.e. set \ Sentence Case for this word only) JSR DORND \ Set A and X to random numbers and reduce A to a AND #3 \ random number in the range 0-3 TAY \ Copy the random number into Y, so we can use Y as a \ loop counter to print 1-4 words (i.e. Y+1 words) .MT18L JSR DORND \ Set A and X to random numbers and reduce A to an even AND #62 \ random number in the range 0-62 (as bit 0 of 62 is 0) TAX \ Copy the random number into X, so X contains the table \ offset of a random extended two-letter token from 0-31 \ which we can now use to pick a token from the combined \ tables at TKN2+2 and QQ16 (we intentionally exclude \ the first token in TKN2, which contains a newline) LDA TKN2+2,X \ Print the first letter of the token at TKN2+2 + X JSR DTS LDA TKN2+3,X \ Print the second letter of the token at TKN2+2 + X JSR DTS DEY \ Decrement the loop counter BPL MT18L \ Loop back to MT18L to print another two-letter token \ until we have printed Y+1 of them RTS \ Return from the subroutine
Name: MT19 [Show more] Type: Subroutine Category: Text Summary: Capitalise the next letter Deep dive: Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * cmn calls MT19 * JMTB calls MT19 * MT18 calls MT19

This routine sets the following: * DTW8 = %11011111 (capitalise the next letter)
.MT19 LDA #%11011111 \ Set DTW8 = %11011111 STA DTW8 RTS \ Return from the subroutine
Name: VOWEL [Show more] Type: Subroutine Category: Text Summary: Test whether a character is a vowel
Context: See this subroutine on its own page References: This subroutine is called as follows: * MT17 calls VOWEL

Arguments: A The character to be tested
Returns: C flag The C flag is set if the character is a vowel, otherwise it is clear
.VOWEL ORA #%00100000 \ Set bit 5 of the character to make it lower case CMP #'a' \ If the letter is a vowel, jump to VRTS to return from BEQ VRTS \ the subroutine with the C flag set (as the CMP will CMP #'e' \ set the C flag if the comparison is equal) BEQ VRTS CMP #'i' BEQ VRTS CMP #'o' BEQ VRTS CMP #'u' BEQ VRTS CLC \ The character is not a vowel, so clear the C flag .VRTS RTS \ Return from the subroutine
Name: JMTB [Show more] Type: Variable Category: Text Summary: The extended token table for jump tokens 1-32 (DETOK) Deep dive: Extended text tokens
Context: See this variable on its own page References: This variable is used as follows: * DETOK2 uses JMTB
.JMTB EQUW MT1 \ Token 1: Switch to ALL CAPS EQUW MT2 \ Token 2: Switch to Sentence Case EQUW TT27 \ Token 3: Print the selected system name \ --- Mod: Code removed for Elite-A: ------------------> \ EQUW TT27 \ Token 4: Print the commander's name \ EQUW MT5 \ Token 5: Switch to extended tokens \ EQUW MT6 \ Token 6: Switch to standard tokens, in Sentence Case \ --- And replaced by: --------------------------------> EQUW MT6 \ Token 4: Switch to standard tokens, in Sentence Case EQUW MT5 \ Token 5: Switch to extended tokens EQUW set_token \ Token 6: Start a new word \ --- End of replacement ------------------------------> EQUW DASC \ Token 7: Beep EQUW MT8 \ Token 8: Tab to column 6 EQUW MT9 \ Token 9: Clear screen, tab to column 1, view type = 1 EQUW DASC \ Token 10: Line feed EQUW NLIN4 \ Token 11: Draw box around title (line at pixel row 19) EQUW DASC \ Token 12: Carriage return EQUW MT13 \ Token 13: Switch to lower case EQUW MT14 \ Token 14: Switch to justified text EQUW MT15 \ Token 15: Switch to left-aligned text EQUW MT16 \ Token 16: Print the character in DTW7 (drive number) EQUW MT17 \ Token 17: Print system name adjective in Sentence Case EQUW MT18 \ Token 18: Randomly print 1 to 4 two-letter tokens EQUW MT19 \ Token 19: Capitalise first letter of next word only EQUW DASC \ Token 20: Unused EQUW CLYNS \ Token 21: Clear the bottom few lines of the space view \ --- Mod: Code removed for Elite-A: ------------------> \ EQUW PAUSE \ Token 22: Display ship and wait for key press \ EQUW MT23 \ Token 23: Move to row 10, white text, set lower case \ EQUW PAUSE2 \ Token 24: Wait for a key press \ EQUW BRIS \ Token 25: Show incoming message screen, wait 2 seconds \ --- And replaced by: --------------------------------> EQUW column_16 \ Token 22: Tab to column 16 EQUW MT23 \ Token 23: Move to row 10, white text, set lower case EQUW clr_vdustat \ Token 24: Switch to standard tokens in lower case EQUW DASC \ Token 25: Unused \ --- End of replacement ------------------------------> EQUW MT26 \ Token 26: Fetch line input from keyboard (filename) EQUW MT27 \ Token 27: Print mission captain's name (217-219) EQUW MT28 \ Token 28: Print mission 1 location hint (220-221) EQUW MT29 \ Token 29: Column 6, white text, lower case in words EQUW DASC \ Token 30: Unused EQUW DASC \ Token 31: Unused EQUW DASC \ Token 32: Unused
Name: TKN2 [Show more] Type: Variable Category: Text Summary: The extended two-letter token lookup table Deep dive: Extended text tokens
Context: See this variable on its own page References: This variable is used as follows: * DETOK2 uses TKN2 * MT18 uses TKN2

Two-letter token lookup table for extended tokens 215-227.
.TKN2 EQUB 12, 10 \ Token 215 = {crlf} EQUS "AB" \ Token 216 EQUS "OU" \ Token 217 EQUS "SE" \ Token 218 EQUS "IT" \ Token 219 EQUS "IL" \ Token 220 EQUS "ET" \ Token 221 EQUS "ST" \ Token 222 EQUS "ON" \ Token 223 EQUS "LO" \ Token 224 EQUS "NU" \ Token 225 EQUS "TH" \ Token 226 EQUS "NO" \ Token 227
Name: QQ16 [Show more] Type: Variable Category: Text Summary: The two-letter token lookup table Deep dive: Printing text tokens
Context: See this variable on its own page References: This variable is used as follows: * TT43 uses QQ16

Two-letter token lookup table for tokens 128-159. See the deep dive on "Printing text tokens" for details of how the two-letter token system works.
.QQ16 EQUS "AL" \ Token 128 EQUS "LE" \ Token 129 EQUS "XE" \ Token 130 EQUS "GE" \ Token 131 EQUS "ZA" \ Token 132 EQUS "CE" \ Token 133 EQUS "BI" \ Token 134 EQUS "SO" \ Token 135 EQUS "US" \ Token 136 EQUS "ES" \ Token 137 EQUS "AR" \ Token 138 EQUS "MA" \ Token 139 EQUS "IN" \ Token 140 EQUS "DI" \ Token 141 EQUS "RE" \ Token 142 EQUS "A?" \ Token 143 EQUS "ER" \ Token 144 EQUS "AT" \ Token 145 EQUS "EN" \ Token 146 EQUS "BE" \ Token 147 EQUS "RA" \ Token 148 EQUS "LA" \ Token 149 EQUS "VE" \ Token 150 EQUS "TI" \ Token 151 EQUS "ED" \ Token 152 EQUS "OR" \ Token 153 EQUS "QU" \ Token 154 EQUS "AN" \ Token 155 EQUS "TE" \ Token 156 EQUS "IS" \ Token 157 EQUS "RI" \ Token 158 EQUS "ON" \ Token 159
Name: MVEIT (Part 1 of 9) [Show more] Type: Subroutine Category: Moving Summary: Move current ship: Tidy the orientation vectors Deep dive: Program flow of the ship-moving routine Scheduling tasks with the main loop counter
Context: See this subroutine on its own page References: This subroutine is called as follows: * ships_ag calls MVEIT

This routine has multiple stages. This stage does the following: * Tidy the orientation vectors for one of the ship slots
Arguments: INWK The current ship/planet/sun's data block XSAV The slot number of the current ship/planet/sun TYPE The type of the current ship/planet/sun
.MVEIT LDA INWK+31 \ If bit 5 of ship byte #31 is set, jump to MV3 as the AND #%00100000 \ ship is exploding, so we don't need to tidy its BNE MV3 \ orientation vectors LDA MCNT \ Fetch the main loop counter EOR XSAV \ Fetch the slot number of the ship we are moving, EOR AND #15 \ with the loop counter and apply mod 15 to the result. BNE MV3 \ The result will be zero when "counter mod 15" matches \ the slot number, so this makes sure we call TIDY 12 \ times every 16 main loop iterations, like this: \ \ Iteration 0, tidy the ship in slot 0 \ Iteration 1, tidy the ship in slot 1 \ Iteration 2, tidy the ship in slot 2 \ ... \ Iteration 11, tidy the ship in slot 11 \ Iteration 12, do nothing \ Iteration 13, do nothing \ Iteration 14, do nothing \ Iteration 15, do nothing \ Iteration 16, tidy the ship in slot 0 \ ... \ \ and so on JSR TIDY \ Call TIDY to tidy up the orientation vectors, to \ prevent the ship from getting elongated and out of \ shape due to the imprecise nature of trigonometry \ in assembly language .MV3 \ Fall through into part 7 (parts 2-6 are not required \ when we are docked)
Name: MVEIT (Part 7 of 9) [Show more] Type: Subroutine Category: Moving Summary: Move current ship: Rotate ship's orientation vectors by pitch/roll Deep dive: Orientation vectors Pitching and rolling
Context: See this subroutine on its own page References: No direct references to this subroutine in this source file

This routine has multiple stages. This stage does the following: * Rotate the ship's orientation vectors according to our pitch and roll As with the previous step, this is all about moving the other ships rather than us (even though we are the one doing the moving). So we rotate the current ship's orientation vectors (which defines its orientation in space), by the angles we are "moving" the rest of the sky through (alpha and beta, our roll and pitch), so the ship appears to us to be stationary while we rotate.
LDY #9 \ Apply our pitch and roll rotations to the current JSR MVS4 \ ship's nosev vector LDY #15 \ Apply our pitch and roll rotations to the current JSR MVS4 \ ship's roofv vector LDY #21 \ Apply our pitch and roll rotations to the current JSR MVS4 \ ship's sidev vector
Name: MVEIT (Part 8 of 9) [Show more] Type: Subroutine Category: Moving Summary: Move current ship: Rotate ship about itself by its own pitch/roll Deep dive: Orientation vectors Pitching and rolling by a fixed angle
Context: See this subroutine on its own page References: No direct references to this subroutine in this source file

This routine has multiple stages. This stage does the following: * If the ship we are processing is rolling or pitching itself, rotate it and apply damping if required
LDA INWK+30 \ Fetch the ship's pitch counter and extract the sign AND #%10000000 \ into RAT2 STA RAT2 LDA INWK+30 \ Fetch the ship's pitch counter and extract the value AND #%01111111 \ without the sign bit into A BEQ MV8 \ If the pitch counter is 0, then jump to MV8 to skip \ the following, as the ship is not pitching CMP #%01111111 \ If bits 0-6 are set in the pitch counter (i.e. the \ ship's pitch is not damping down), then the C flag \ will be set by this instruction SBC #0 \ Set A = A - 0 - (1 - C), so if we are damping then we \ reduce A by 1, otherwise it is unchanged ORA RAT2 \ Change bit 7 of A to the sign we saved in RAT2, so \ the updated pitch counter in A retains its sign STA INWK+30 \ Store the updated pitch counter in byte #30 LDX #15 \ Rotate (roofv_x, nosev_x) by a small angle (pitch) LDY #9 JSR MVS5 LDX #17 \ Rotate (roofv_y, nosev_y) by a small angle (pitch) LDY #11 JSR MVS5 LDX #19 \ Rotate (roofv_z, nosev_z) by a small angle (pitch) LDY #13 JSR MVS5 .MV8 LDA INWK+29 \ Fetch the ship's roll counter and extract the sign AND #%10000000 \ into RAT2 STA RAT2 LDA INWK+29 \ Fetch the ship's roll counter and extract the value AND #%01111111 \ without the sign bit into A BEQ MV5 \ If the roll counter is 0, then jump to MV5 to skip the \ following, as the ship is not rolling CMP #%01111111 \ If bits 0-6 are set in the roll counter (i.e. the \ ship's roll is not damping down), then the C flag \ will be set by this instruction SBC #0 \ Set A = A - 0 - (1 - C), so if we are damping then we \ reduce A by 1, otherwise it is unchanged ORA RAT2 \ Change bit 7 of A to the sign we saved in RAT2, so \ the updated roll counter in A retains its sign STA INWK+29 \ Store the updated pitch counter in byte #29 LDX #15 \ Rotate (roofv_x, sidev_x) by a small angle (roll) LDY #21 JSR MVS5 LDX #17 \ Rotate (roofv_y, sidev_y) by a small angle (roll) LDY #23 JSR MVS5 LDX #19 \ Rotate (roofv_z, sidev_z) by a small angle (roll) LDY #25 JSR MVS5
Name: MVEIT (Part 9 of 9) [Show more] Type: Subroutine Category: Moving Summary: Move current ship: Redraw on scanner, if it hasn't been destroyed
Context: See this subroutine on its own page References: No direct references to this subroutine in this source file

This routine has multiple stages. This stage does the following: * If the ship is exploding or being removed, hide it on the scanner * Otherwise redraw the ship on the scanner, now that it's been moved
.MV5 LDA INWK+31 \ Fetch the ship's exploding/killed state from byte #31 AND #%00100000 \ If we are exploding then jump to MVD1 to remove it BNE MVD1 \ from the scanner permanently LDA INWK+31 \ Set bit 4 to keep the ship visible on the scanner ORA #%00010000 STA INWK+31 .MVD1 LDA INWK+31 \ Clear bit 4 to hide the ship on the scanner AND #%11101111 STA INWK+31 RTS \ Return from the subroutine
Name: MVS4 [Show more] Type: Subroutine Category: Moving Summary: Apply pitch and roll to an orientation vector Deep dive: Orientation vectors Pitching and rolling
Context: See this subroutine on its own page References: This subroutine is called as follows: * MVEIT (Part 7 of 9) calls MVS4

Apply pitch and roll angles alpha and beta to the orientation vector in Y. Specifically, this routine rotates a point (x, y, z) around the origin by pitch alpha and roll beta, using the small angle approximation to make the maths easier, and incorporating the Minsky circle algorithm to make the rotation more stable (though more elliptic). If that paragraph makes sense to you, then you should probably be writing this commentary! For the rest of us, there's a detailed explanation of all this in the deep dive on "Pitching and rolling".
Arguments: Y Determines which of the INWK orientation vectors to transform: * Y = 9 rotates nosev: (nosev_x, nosev_y, nosev_z) * Y = 15 rotates roofv: (roofv_x, roofv_y, roofv_z) * Y = 21 rotates sidev: (sidev_x, sidev_y, sidev_z)
.MVS4 LDA ALPHA \ Set Q = alpha (the roll angle to rotate through) STA Q LDX INWK+2,Y \ Set (S R) = nosev_y STX R LDX INWK+3,Y STX S LDX INWK,Y \ These instructions have no effect as MAD overwrites STX P \ X and P when called, but they set X = P = nosev_x_lo LDA INWK+1,Y \ Set A = -nosev_x_hi EOR #%10000000 JSR MAD \ Set (A X) = Q * A + (S R) STA INWK+3,Y \ = alpha * -nosev_x_hi + nosev_y STX INWK+2,Y \ \ and store (A X) in nosev_y, so this does: \ \ nosev_y = nosev_y - alpha * nosev_x_hi STX P \ This instruction has no effect as MAD overwrites P, \ but it sets P = nosev_y_lo LDX INWK,Y \ Set (S R) = nosev_x STX R LDX INWK+1,Y STX S LDA INWK+3,Y \ Set A = nosev_y_hi JSR MAD \ Set (A X) = Q * A + (S R) STA INWK+1,Y \ = alpha * nosev_y_hi + nosev_x STX INWK,Y \ \ and store (A X) in nosev_x, so this does: \ \ nosev_x = nosev_x + alpha * nosev_y_hi STX P \ This instruction has no effect as MAD overwrites P, \ but it sets P = nosev_x_lo LDA BETA \ Set Q = beta (the pitch angle to rotate through) STA Q LDX INWK+2,Y \ Set (S R) = nosev_y STX R LDX INWK+3,Y STX S LDX INWK+4,Y STX P \ This instruction has no effect as MAD overwrites P, \ but it sets P = nosev_y LDA INWK+5,Y \ Set A = -nosev_z_hi EOR #%10000000 JSR MAD \ Set (A X) = Q * A + (S R) STA INWK+3,Y \ = beta * -nosev_z_hi + nosev_y STX INWK+2,Y \ \ and store (A X) in nosev_y, so this does: \ \ nosev_y = nosev_y - beta * nosev_z_hi STX P \ This instruction has no effect as MAD overwrites P, \ but it sets P = nosev_y_lo LDX INWK+4,Y \ Set (S R) = nosev_z STX R LDX INWK+5,Y STX S LDA INWK+3,Y \ Set A = nosev_y_hi JSR MAD \ Set (A X) = Q * A + (S R) STA INWK+5,Y \ = beta * nosev_y_hi + nosev_z STX INWK+4,Y \ \ and store (A X) in nosev_z, so this does: \ \ nosev_z = nosev_z + beta * nosev_y_hi RTS \ Return from the subroutine
Name: MVS5 [Show more] Type: Subroutine Category: Moving Summary: Apply a 3.6 degree pitch or roll to an orientation vector Deep dive: Orientation vectors Pitching and rolling by a fixed angle
Context: See this subroutine on its own page References: This subroutine is called as follows: * MVEIT (Part 8 of 9) calls MVS5

Pitch or roll a ship by a small, fixed amount (1/16 radians, or 3.6 degrees), in a specified direction, by rotating the orientation vectors. The vectors to rotate are given in X and Y, and the direction of the rotation is given in RAT2. The calculation is as follows: * If the direction is positive: X = X * (1 - 1/512) + Y / 16 Y = Y * (1 - 1/512) - X / 16 * If the direction is negative: X = X * (1 - 1/512) - Y / 16 Y = Y * (1 - 1/512) + X / 16 So if X = 15 (roofv_x), Y = 21 (sidev_x) and RAT2 is positive, it does this: roofv_x = roofv_x * (1 - 1/512) + sidev_x / 16 sidev_x = sidev_x * (1 - 1/512) - roofv_x / 16
Arguments: X The first vector to rotate: * If X = 15, rotate roofv_x * If X = 17, rotate roofv_y * If X = 19, rotate roofv_z * If X = 21, rotate sidev_x * If X = 23, rotate sidev_y * If X = 25, rotate sidev_z Y The second vector to rotate: * If Y = 9, rotate nosev_x * If Y = 11, rotate nosev_y * If Y = 13, rotate nosev_z * If Y = 21, rotate sidev_x * If Y = 23, rotate sidev_y * If Y = 25, rotate sidev_z RAT2 The direction of the pitch or roll to perform, positive or negative (i.e. the sign of the roll or pitch counter in bit 7)
.MVS5 LDA INWK+1,X \ Fetch roofv_x_hi, clear the sign bit, divide by 2 and AND #%01111111 \ store in T, so: LSR A \ STA T \ T = |roofv_x_hi| / 2 \ = |roofv_x| / 512 \ \ The above is true because: \ \ |roofv_x| = |roofv_x_hi| * 256 + roofv_x_lo \ \ so: \ \ |roofv_x| / 512 = |roofv_x_hi| * 256 / 512 \ + roofv_x_lo / 512 \ = |roofv_x_hi| / 2 LDA INWK,X \ Now we do the following subtraction: SEC \ SBC T \ (S R) = (roofv_x_hi roofv_x_lo) - |roofv_x| / 512 STA R \ = (1 - 1/512) * roofv_x \ \ by doing the low bytes first LDA INWK+1,X \ And then the high bytes (the high byte of the right SBC #0 \ side of the subtraction being 0) STA S LDA INWK,Y \ Set P = nosev_x_lo STA P LDA INWK+1,Y \ Fetch the sign of nosev_x_hi (bit 7) and store in T AND #%10000000 STA T LDA INWK+1,Y \ Fetch nosev_x_hi into A and clear the sign bit, so AND #%01111111 \ A = |nosev_x_hi| LSR A \ Set (A P) = (A P) / 16 ROR P \ = |nosev_x_hi nosev_x_lo| / 16 LSR A \ = |nosev_x| / 16 ROR P LSR A ROR P LSR A ROR P ORA T \ Set the sign of A to the sign in T (i.e. the sign of \ the original nosev_x), so now: \ \ (A P) = nosev_x / 16 EOR RAT2 \ Give it the sign as if we multiplied by the direction \ by the pitch or roll direction STX Q \ Store the value of X so it can be restored after the \ call to ADD JSR ADD \ (A X) = (A P) + (S R) \ = +/-nosev_x / 16 + (1 - 1/512) * roofv_x STA K+1 \ Set K(1 0) = (1 - 1/512) * roofv_x +/- nosev_x / 16 STX K LDX Q \ Restore the value of X from before the call to ADD LDA INWK+1,Y \ Fetch nosev_x_hi, clear the sign bit, divide by 2 and AND #%01111111 \ store in T, so: LSR A \ STA T \ T = |nosev_x_hi| / 2 \ = |nosev_x| / 512 LDA INWK,Y \ Now we do the following subtraction: SEC \ SBC T \ (S R) = (nosev_x_hi nosev_x_lo) - |nosev_x| / 512 STA R \ = (1 - 1/512) * nosev_x \ \ by doing the low bytes first LDA INWK+1,Y \ And then the high bytes (the high byte of the right SBC #0 \ side of the subtraction being 0) STA S LDA INWK,X \ Set P = roofv_x_lo STA P LDA INWK+1,X \ Fetch the sign of roofv_x_hi (bit 7) and store in T AND #%10000000 STA T LDA INWK+1,X \ Fetch roofv_x_hi into A and clear the sign bit, so AND #%01111111 \ A = |roofv_x_hi| LSR A \ Set (A P) = (A P) / 16 ROR P \ = |roofv_x_hi roofv_x_lo| / 16 LSR A \ = |roofv_x| / 16 ROR P LSR A ROR P LSR A ROR P ORA T \ Set the sign of A to the opposite sign to T (i.e. the EOR #%10000000 \ sign of the original -roofv_x), so now: \ \ (A P) = -roofv_x / 16 EOR RAT2 \ Give it the sign as if we multiplied by the direction \ by the pitch or roll direction STX Q \ Store the value of X so it can be restored after the \ call to ADD JSR ADD \ (A X) = (A P) + (S R) \ = -/+roofv_x / 16 + (1 - 1/512) * nosev_x STA INWK+1,Y \ Set nosev_x = (1-1/512) * nosev_x -/+ roofv_x / 16 STX INWK,Y LDX Q \ Restore the value of X from before the call to ADD LDA K \ Set roofv_x = K(1 0) STA INWK,X \ = (1-1/512) * roofv_x +/- nosev_x / 16 LDA K+1 STA INWK+1,X RTS \ Return from the subroutine
Name: UNIV [Show more] Type: Variable Category: Universe Summary: Table of pointers to the local universe's ship data blocks Deep dive: The local bubble of universe
Context: See this variable on its own page References: This variable is used as follows: * GINF uses UNIV

See the deep dive on "Ship data blocks" for details on ship data blocks, and the deep dive on "The local bubble of universe" for details of how Elite stores the local universe in K%, FRIN and UNIV.
.UNIV FOR I%, 0, NOSH EQUW K% + I% * NI% \ Address of block no. I%, of size NI%, in workspace K% NEXT
Save ELTA.bin
PRINT "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.F.ELTA ", ~CODE%, " ", ~P%, " ", ~LOAD%, " ", ~LOAD_A% \SAVE "3-assembled-output/F.ELTA.bin", CODE%, P%, LOAD%