Skip to navigation

Elite on the BBC Micro

Elite C encyclopedia source [Elite-A]

ELITE C FILE
CODE_C% = P% LOAD_C% = LOAD% +P% - CODE%
Name: SQUA [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Clear bit 7 of A and calculate (A P) = A * A
Context: See this subroutine on its own page References: This subroutine is called as follows: * NORM calls SQUA

Do the following multiplication of unsigned 8-bit numbers, after first clearing bit 7 of A: (A P) = A * A
.SQUA AND #%01111111 \ Clear bit 7 of A and fall through into SQUA2 to set \ (A P) = A * A
Name: SQUA2 [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate (A P) = A * A
Context: See this subroutine on its own page References: This subroutine is called as follows: * SUN (Part 1 of 4) calls SQUA2 * SUN (Part 3 of 4) calls SQUA2 * TT111 calls SQUA2

Do the following multiplication of unsigned 8-bit numbers: (A P) = A * A
.SQUA2 STA P \ Copy A into P and X TAX BNE MU11 \ If X = 0 fall through into MU1 to return a 0, \ otherwise jump to MU11 to return P * X
Name: MU1 [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Copy X into P and A, and clear the C flag
Context: See this subroutine on its own page References: This subroutine is called as follows: * MULTU calls MU1

Used to return a 0 result quickly from MULTU below.
.MU1 CLC \ Clear the C flag STX P \ Copy X into P and A TXA RTS \ Return from the subroutine
Name: MULTU [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate (A P) = P * Q
Context: See this subroutine on its own page References: This subroutine is called as follows: * TT24 calls MULTU

Do the following multiplication of unsigned 8-bit numbers: (A P) = P * Q
.MULTU LDX Q \ Set X = Q BEQ MU1 \ If X = Q = 0, jump to MU1 to copy X into P and A, \ clear the C flag and return from the subroutine using \ a tail call \ Otherwise fall through into MU11 to set (A P) = P * X
Name: MU11 [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate (A P) = P * X Deep dive: Shift-and-add multiplication
Context: See this subroutine on its own page References: This subroutine is called as follows: * SQUA2 calls MU11

Do the following multiplication of two unsigned 8-bit numbers: (A P) = P * X This uses the same shift-and-add approach as MULT1, but it's simpler as we are dealing with unsigned numbers in P and X. See the deep dive on "Shift-and-add multiplication" for a discussion of how this algorithm works.
.MU11 DEX \ Set T = X - 1 STX T \ \ We subtract 1 as the C flag will be set when we want \ to do an addition in the loop below LDA #0 \ Set A = 0 so we can start building the answer in A LDX #8 \ Set up a counter in X to count the 8 bits in P LSR P \ Set P = P >> 1 \ and C flag = bit 0 of P \ We are now going to work our way through the bits of \ P, and do a shift-add for any bits that are set, \ keeping the running total in A. We just did the first \ shift right, so we now need to do the first add and \ loop through the other bits in P .MUL6 BCC P%+4 \ If C (i.e. the next bit from P) is set, do the ADC T \ addition for this bit of P: \ \ A = A + T + C \ = A + X - 1 + 1 \ = A + X ROR A \ Shift A right to catch the next digit of our result, \ which the next ROR sticks into the left end of P while \ also extracting the next bit of P ROR P \ Add the overspill from shifting A to the right onto \ the start of P, and shift P right to fetch the next \ bit for the calculation into the C flag DEX \ Decrement the loop counter BNE MUL6 \ Loop back for the next bit until P has been rotated \ all the way RTS \ Return from the subroutine
Name: FMLTU2 [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate A = K * sin(A) Deep dive: The sine, cosine and arctan tables
Context: See this subroutine on its own page References: This subroutine is called as follows: * CIRCLE2 calls FMLTU2

Calculate the following: A = K * sin(A) Because this routine uses the sine lookup table SNE, we can also call this routine to calculate cosine multiplication. To calculate the following: A = K * cos(B) call this routine with B + 16 in the accumulator, as sin(B + 16) = cos(B).
.FMLTU2 AND #%00011111 \ Restrict A to bits 0-5 (so it's in the range 0-31) TAX \ Set Q = sin(A) * 256 LDA SNE,X STA Q LDA K \ Set A to the radius in K \ Fall through into FMLTU to do the following: \ \ (A ?) = A * Q \ = K * sin(A) * 256 \ \ which is equivalent to: \ \ A = K * sin(A)
Name: FMLTU [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate A = A * Q / 256
Context: See this subroutine on its own page References: This subroutine is called as follows: * LL51 calls FMLTU * LL9 (Part 5 of 12) calls FMLTU

Do the following multiplication of two unsigned 8-bit numbers, returning only the high byte of the result: (A ?) = A * Q or, to put it another way: A = A * Q / 256
.FMLTU EOR #%11111111 \ Flip the bits in A, set the C flag and rotate right, SEC \ so the C flag now contains bit 0 of A inverted, and P ROR A \ contains A inverted and shifted right by one, with bit STA P \ 7 set to a 1. We can now use P as our source of bits \ to shift right, just as in MU11, just with the logic \ reversed LDA #0 \ Set A = 0 so we can start building the answer in A .MUL3 BCS MU7 \ If C (i.e. the next bit from P) is set, do not do the \ addition for this bit of P, and instead skip to MU7 \ to just do the shifts ADC Q \ Do the addition for this bit of P: \ \ A = A + Q + C \ = A + Q ROR A \ Shift A right to catch the next digit of our result. \ If we were interested in the low byte of the result we \ would want to save the bit that falls off the end, but \ we aren't, so we can ignore it LSR P \ Shift P right to fetch the next bit for the \ calculation into the C flag BNE MUL3 \ Loop back to MUL3 if P still contains some set bits \ (so we loop through the bits of P until we get to the \ 1 we inserted before the loop, and then we stop) RTS \ Return from the subroutine .MU7 LSR A \ Shift A right to catch the next digit of our result, \ pushing a 0 into bit 7 as we aren't adding anything \ here (we can't use a ROR here as the C flag is set, so \ a ROR would push a 1 into bit 7) LSR P \ Fetch the next bit from P into the C flag BNE MUL3 \ Loop back to MUL3 if P still contains some set bits \ (so we loop through the bits of P until we get to the \ 1 we inserted before the loop, and then we stop) RTS \ Return from the subroutine
Name: MULT1 [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate (A P) = Q * A Deep dive: Shift-and-add multiplication
Context: See this subroutine on its own page References: This subroutine is called as follows: * MAD calls MULT1 * MULT12 calls MULT1

Do the following multiplication of two 8-bit sign-magnitude numbers: (A P) = Q * A
.MULT1 TAX \ Store A in X AND #%01111111 \ Set P = |A| >> 1 LSR A \ and C flag = bit 0 of A STA P TXA \ Restore argument A EOR Q \ Set bit 7 of A and T if Q and A have different signs, AND #%10000000 \ clear bit 7 if they have the same signs, 0 all other STA T \ bits, i.e. T contains the sign bit of Q * A LDA Q \ Set A = |Q| AND #%01111111 BEQ mu10 \ If |Q| = 0 jump to mu10 (with A set to 0) TAX \ Set T1 = |Q| - 1 DEX \ STX T1 \ We subtract 1 as the C flag will be set when we want \ to do an addition in the loop below \ We are now going to work our way through the bits of \ P, and do a shift-add for any bits that are set, \ keeping the running total in A. We already set up \ the first shift at the start of this routine, as \ P = |A| >> 1 and C = bit 0 of A, so we now need to set \ up a loop to sift through the other 7 bits in P LDA #0 \ Set A = 0 so we can start building the answer in A LDX #7 \ Set up a counter in X to count the 7 bits remaining \ in P .MUL4 BCC P%+4 \ If C (i.e. the next bit from P) is set, do the ADC T1 \ addition for this bit of P: \ \ A = A + T1 + C \ = A + |Q| - 1 + 1 \ = A + |Q| ROR A \ As mentioned above, this ROR shifts A right and \ catches bit 0 in C - giving another digit for our \ result - and the next ROR sticks that bit into the \ left end of P while also extracting the next bit of P \ for the next addition ROR P \ Add the overspill from shifting A to the right onto \ the start of P, and shift P right to fetch the next \ bit for the calculation DEX \ Decrement the loop counter BNE MUL4 \ Loop back for the next bit until P has been rotated \ all the way LSR A \ Rotate (A P) once more to get the final result, as ROR P \ we only pushed 7 bits through the above process ORA T \ Set the sign bit of the result that we stored in T RTS \ Return from the subroutine .mu10 STA P \ If we get here, the result is 0 and A = 0, so set \ P = 0 so (A P) = 0 RTS \ Return from the subroutine
Name: MULT12 [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate (S R) = Q * A
Context: See this subroutine on its own page References: This subroutine is called as follows: * TIDY calls MULT12 * TIS3 calls MULT12

Calculate: (S R) = Q * A
.MULT12 JSR MULT1 \ Set (A P) = Q * A STA S \ Set (S R) = (A P) LDA P STA R RTS \ Return from the subroutine
Name: MAD [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate (A X) = Q * A + (S R)
Context: See this subroutine on its own page References: This subroutine is called as follows: * MVS4 calls MAD * TIS1 calls MAD * TIS3 calls MAD

Calculate (A X) = Q * A + (S R)
.MAD JSR MULT1 \ Call MULT1 to set (A P) = Q * A \ Fall through into ADD to do: \ \ (A X) = (A P) + (S R) \ = Q * A + (S R)
Name: ADD [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate (A X) = (A P) + (S R) Deep dive: Adding sign-magnitude numbers
Context: See this subroutine on its own page References: This subroutine is called as follows: * MVS5 calls ADD

Add two 16-bit sign-magnitude numbers together, calculating: (A X) = (A P) + (S R)
.ADD STA T1 \ Store argument A in T1 AND #%10000000 \ Extract the sign (bit 7) of A and store it in T STA T EOR S \ EOR bit 7 of A with S. If they have different bit 7s BMI MU8 \ (i.e. they have different signs) then bit 7 in the \ EOR result will be 1, which means the EOR result is \ negative. So the AND, EOR and BMI together mean "jump \ to MU8 if A and S have different signs" \ If we reach here, then A and S have the same sign, so \ we can add them and set the sign to get the result LDA R \ Add the least significant bytes together into X: CLC \ ADC P \ X = P + R TAX LDA S \ Add the most significant bytes together into A. We ADC T1 \ stored the original argument A in T1 earlier, so we \ can do this with: \ \ A = A + S + C \ = T1 + S + C ORA T \ If argument A was negative (and therefore S was also \ negative) then make sure result A is negative by \ OR-ing the result with the sign bit from argument A \ (which we stored in T) RTS \ Return from the subroutine .MU8 \ If we reach here, then A and S have different signs, \ so we can subtract their absolute values and set the \ sign to get the result LDA S \ Clear the sign (bit 7) in S and store the result in AND #%01111111 \ U, so U now contains |S| STA U LDA P \ Subtract the least significant bytes into X: SEC \ SBC R \ X = P - R TAX LDA T1 \ Restore the A of the argument (A P) from T1 and AND #%01111111 \ clear the sign (bit 7), so A now contains |A| SBC U \ Set A = |A| - |S| \ At this point we have |A P| - |S R| in (A X), so we \ need to check whether the subtraction above was the \ the right way round (i.e. that we subtracted the \ smaller absolute value from the larger absolute \ value) BCS MU9 \ If |A| >= |S|, our subtraction was the right way \ round, so jump to MU9 to set the sign \ If we get here, then |A| < |S|, so our subtraction \ above was the wrong way round (we actually subtracted \ the larger absolute value from the smaller absolute \ value). So let's subtract the result we have in (A X) \ from zero, so that the subtraction is the right way \ round STA U \ Store A in U TXA \ Set X = 0 - X using two's complement (to negate a EOR #&FF \ number in two's complement, you can invert the bits ADC #1 \ and add one - and we know the C flag is clear as we TAX \ didn't take the BCS branch above, so the ADC will do \ the correct addition) LDA #0 \ Set A = 0 - A, which we can do this time using a SBC U \ a subtraction with the C flag clear ORA #%10000000 \ We now set the sign bit of A, so that the EOR on the \ next line will give the result the opposite sign to \ argument A (as T contains the sign bit of argument \ A). This is the same as giving the result the same \ sign as argument S (as A and S have different signs), \ which is what we want, as S has the larger absolute \ value .MU9 EOR T \ If we get here from the BCS above, then |A| >= |S|, \ so we want to give the result the same sign as \ argument A, so if argument A was negative, we flip \ the sign of the result with an EOR (to make it \ negative) RTS \ Return from the subroutine
Name: TIS1 [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate (A ?) = (-X * A + (S R)) / 96 Deep dive: Shift-and-subtract division
Context: See this subroutine on its own page References: This subroutine is called as follows: * TIDY calls TIS1

Calculate the following expression between sign-magnitude numbers, ignoring the low byte of the result: (A ?) = (-X * A + (S R)) / 96 This uses the same shift-and-subtract algorithm as TIS2, just with the quotient A hard-coded to 96. Returns: Q Gets set to the value of argument X
.TIS1 STX Q \ Set Q = X EOR #%10000000 \ Flip the sign bit in A JSR MAD \ Set (A X) = Q * A + (S R) \ = X * -A + (S R) .DVID96 TAX \ Set T to the sign bit of the result AND #%10000000 STA T TXA \ Set A to the high byte of the result with the sign bit AND #%01111111 \ cleared, so (A ?) = |X * A + (S R)| \ The following is identical to TIS2, except Q is \ hard-coded to 96, so this does A = A / 96 LDX #254 \ Set T1 to have bits 1-7 set, so we can rotate through STX T1 \ 7 loop iterations, getting a 1 each time, and then \ getting a 0 on the 8th iteration... and we can also \ use T1 to catch our result bits into bit 0 each time .DVL3 ASL A \ Shift A to the left CMP #96 \ If A < 96 skip the following subtraction BCC DV4 SBC #96 \ Set A = A - 96 \ \ Going into this subtraction we know the C flag is \ set as we passed through the BCC above, and we also \ know that A >= 96, so the C flag will still be set \ once we are done .DV4 ROL T1 \ Rotate the counter in T1 to the left, and catch the \ result bit into bit 0 (which will be a 0 if we didn't \ do the subtraction, or 1 if we did) BCS DVL3 \ If we still have set bits in T1, loop back to DVL3 to \ do the next iteration of 7 LDA T1 \ Fetch the result from T1 into A ORA T \ Give A the sign of the result that we stored above RTS \ Return from the subroutine
Name: PDESC [Show more] Type: Subroutine Category: Text Summary: Print the system's extended description or a mission 1 directive Deep dive: Extended system descriptions Extended text tokens
Context: See this subroutine on its own page References: This subroutine is called as follows: * TT25 calls entry point PD1

This prints a specific system's extended description. This is called the "pink volcanoes string" in a comment in the original source, and the "goat soup" recipe by Ian Bell on his website (where he also refers to the species string as the "pink felines" string). For some special systems, when you are docked at them, the procedurally generated extended description is overridden and a text token from the RUTOK table is shown instead. If mission 1 is in progress, then a number of systems along the route of that mission's story will show custom mission-related directives in place of that system's normal "goat soup" phrase. Arguments: ZZ The system number (0-255) Other entry points: PD1 Print the standard "goat soup" description without checking for overrides
.PDESC \ --- Mod: Original Acornsoft code removed: -----------> \ LDA QQ8 \ If either byte in QQ18(1 0) is non-zero, meaning that \ ORA QQ8+1 \ the distance from the current system to the selected \ BNE PD1 \ is non-zero, jump to PD1 to show the standard "goat \ \ soup" description \ \ If we get here, then the current system is the same as \ \ the selected system and we are docked, so now to check \ \ whether there is a special override token for this \ \ system \ LDY #NRU% \ Set Y as a loop counter as we work our way through the \ \ system numbers in RUPLA, starting at NRU% (which is \ \ the number of entries in RUPLA, 26) and working our \ \ way down to 1 \.PDL1 \ LDA RUPLA-1,Y \ Fetch the Y-th byte from RUPLA-1 into A (we use \ \ RUPLA-1 because Y is looping from 26 to 1 \ CMP ZZ \ If A doesn't match the system whose description we \ BNE PD2 \ are printing (in ZZ), junp to PD2 to keep looping \ \ through the system numbers in RUPLA \ \ If we get here we have found a match for this system \ \ number in RUPLA \ LDA RUGAL-1,Y \ Fetch the Y-th byte from RUGAL-1 into A \ AND #%01111111 \ Extract bits 0-6 of A \ CMP GCNT \ If the result does not equal the current galaxy \ BNE PD2 \ number, jump to PD2 to keep looping through the system \ \ numbers in RUPLA \ LDA RUGAL-1,Y \ Fetch the Y-th byte from RUGAL-1 into A, once again \ BMI PD3 \ If bit 7 is set, jump to PD3 to print the extended \ \ token in A from the second table in RUTOK \ LDA TP \ Fetch bit 0 of TP into the C flag, and skip to PD1 if \ LSR A \ it is clear (i.e. if mission 1 is not in progress) to \ BCC PD1 \ print the "goat soup" extended description \ \ If we get here then mission 1 is in progress, so we \ \ print out the corresponding token from RUTOK \ JSR MT14 \ Call MT14 to switch to justified text \ LDA #1 \ Set A = 1 so that extended token 1 (an empty string) \ \ gets printed below instead of token 176, followed by \ \ the Y-th token in RUTOK \ EQUB &2C \ Skip the next instruction by turning it into \ \ &2C &A9 &B0, or BIT &B0A9, which does nothing apart \ \ from affect the flags \.PD3 \ LDA #176 \ Print extended token 176 ("{lower case}{justify} \ JSR DETOK2 \ {single cap}") \ TYA \ Print the extended token in Y from the second table \ JSR DETOK3 \ in RUTOK \ LDA #177 \ Set A = 177 so when we jump to PD4 in the next \ \ instruction, we print token 177 (".{cr}{left align}") \ BNE PD4 \ Jump to PD4 to print the extended token in A and \ \ return from the subroutine using a tail call \.PD2 \ DEY \ Decrement the byte counter in Y \ BNE PDL1 \ Loop back to check the next byte in RUPLA until we \ \ either find a match for the system in ZZ, or we fall \ \ through into the "goat soup" extended description \ \ routine \ --- End of removed code -----------------------------> .PD1 \ We now print the "goat soup" extended description LDX #3 \ We now want to seed the random number generator with \ the s1 and s2 16-bit seeds from the current system, so \ we get the same extended description for each system \ every time we call PDESC, so set a counter in X for \ copying 4 bytes { .PDL1 \ This label is a duplicate of the label above (which is \ why we need to surround it with braces, as BeebAsm \ doesn't allow us to redefine labels, unlike BBC BASIC) LDA QQ15+2,X \ Copy QQ15+2 to QQ15+5 (s1 and s2) to RAND to RAND+3 STA RAND,X DEX \ Decrement the loop counter BPL PDL1 \ Loop back to PDL1 until we have copied all LDA #5 \ Set A = 5, so we print extended token 5 in the next \ instruction ("{lower case}{justify}{single cap}[86-90] \ IS [140-144].{cr}{left align}" } .PD4 JMP DETOK \ Print the extended token given in A, and return from \ the subroutine using a tail call
Name: MT23 [Show more] Type: Subroutine Category: Text Summary: Move to row 10, switch to white text, and 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: * JMTB calls MT23
.MT23 LDA #10 \ Set A = 10, so when we fall through into MT29, the \ text cursor gets moved to row 10 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 MT29 to move to the row in A, switch \ to white text, and switch to lower case
Name: MT29 [Show more] Type: Subroutine Category: Text Summary: Move to row 6, switch to white text, and 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: * JMTB calls MT29

This routine sets the following: * YC = 6 (move to row 6) Then it calls WHITETEXT to switch to white text, before jumping to MT13 to switch to lower case when printing extended tokens.
.MT29 LDA #6 \ Move the text cursor to row 6 STA YC JMP MT13 \ Jump to MT13 to set bit 7 of DTW6 and bit 5 of DTW1, \ returning from the subroutine using a tail call
Name: PAUSE2 [Show more] Type: Subroutine Category: Keyboard Summary: Wait until a key is pressed, ignoring any existing key press
Context: See this subroutine on its own page References: This subroutine is called as follows: * trading calls PAUSE2

Returns: X The internal key number of the key that was pressed
.PAUSE2 JSR RDKEY \ Scan the keyboard for a key press and return the \ internal key number in X (or 0 for no key press) BNE PAUSE2 \ If a key was already being held down when we entered \ this routine, keep looping back up to PAUSE2, until \ the key is released \ --- Mod: Code added for Elite-A: --------------------> .l_out \ --- End of added code -------------------------------> JSR RDKEY \ Any pre-existing key press is now gone, so we can \ start scanning the keyboard again, returning the \ internal key number in X (or 0 for no key press) \ --- Mod: Original Acornsoft code removed: -----------> \ BEQ PAUSE2 \ Keep looping up to PAUSE2 until a key is pressed \ --- And replaced by: --------------------------------> BEQ l_out \ Keep looping up to l_out until a key is pressed \ --- End of replacement ------------------------------> RTS \ Return from the subroutine
Name: TT66 [Show more] Type: Subroutine Category: Utility routines Summary: Clear the screen and set the current view type
Context: See this subroutine on its own page References: This subroutine is called as follows: * MT9 calls TT66 * TT22 calls TT66 * TT23 calls TT66 * TT25 calls TT66 * controls calls TT66 * equip_data calls TT66 * menu calls TT66 * ships_ag calls TT66

Clear the top part of the screen, draw a white border, and set the current view type in QQ11 to A. Arguments: A The type of the new current view (see QQ11 for a list of view types)
.TT66 STA QQ11 \ Set the current view type in QQ11 to A \ Fall through into TTX66 to clear the screen and draw a \ white border
Name: TTX66 [Show more] Type: Subroutine Category: Utility routines Summary: Clear the top part of the screen and draw a white border
Context: See this subroutine on its own page References: This subroutine is called as follows: * CHPR calls TTX66

Clear the top part of the screen (the space view) and draw a white border along the top and sides. Other entry points: BOL1-1 Contains an RTS
.TTX66 JSR MT2 \ Switch to Sentence Case when printing extended tokens LDA #%10000000 \ Set bit 7 of QQ17 to switch to Sentence Case STA QQ17 STA DTW2 \ Set bit 7 of DTW2 to indicate we are not currently \ printing a word ASL A \ Set LASCT to 0, as 128 << 1 = %10000000 << 1 = 0. This STA LASCT \ stops any laser pulsing STA DLY \ Set the delay in DLY to 0, to indicate that we are \ no longer showing an in-flight message, so any new \ in-flight messages will be shown instantly STA de \ Clear de, the flag that appends " DESTROYED" to the \ end of the next text token, so that it doesn't LDX #&60 \ Set X to the screen memory page for the top row of the \ screen (as screen memory starts at &6000) .BOL1 JSR ZES1 \ Call ZES1 to zero-fill the page in X, which clears \ that character row on the screen INX \ Increment X to point to the next page, i.e. the next \ character row CPX #&78 \ Loop back to BOL1 until we have cleared page &7700, BNE BOL1 \ the last character row in the space view part of the \ screen (the top part) LDY #1 \ Move the text cursor to row 1 STY YC LDA QQ11 \ If this is not a space view, jump to tt66 to skip BNE tt66 \ displaying the view name LDY #11 \ Move the text cursor to row 11 STY XC LDA VIEW \ Load the current view into A: \ \ 0 = front \ 1 = rear \ 2 = left \ 3 = right ORA #&60 \ OR with &60 so we get a value of &60 to &63 (96 to 99) JSR TT27 \ Print recursive token 96 to 99, which will be in the \ range "FRONT" to "RIGHT" JSR TT162 \ Print a space LDA #175 \ Print recursive token 15 ("VIEW ") JSR TT27 .tt66 LDX #0 \ Set (X1, Y1) to (0, 0) STX X1 STX Y1 STX QQ17 \ Set QQ17 = 0 to switch to ALL CAPS DEX \ Set X2 = 255 STX X2 JSR HLOIN \ Draw a horizontal line from (X1, Y1) to (X2, Y1), so \ that's (0, 0) to (255, 0), along the very top of the \ screen LDA #2 \ Set X1 = X2 = 2 STA X1 STA X2 JSR BOS2 \ Call BOS2 below, which will call BOS1 twice, and then \ fall through into BOS2 again, so we effectively do \ BOS1 four times, decrementing X1 and X2 each time \ before calling LOIN, so this whole loop-within-a-loop \ mind-bender ends up drawing these four lines: \ \ (1, 0) to (1, 191) \ (0, 0) to (0, 191) \ (255, 0) to (255, 191) \ (254, 0) to (254, 191) \ \ So that's a 2-pixel wide vertical border along the \ left edge of the upper part of the screen, and a \ 2-pixel wide vertical border along the right edge .BOS2 JSR BOS1 \ Call BOS1 below and then fall through into it, which \ ends up running BOS1 twice. This is all part of the \ loop-the-loop border-drawing mind-bender explained \ above .BOS1 LDA #0 \ Set Y1 = 0 STA Y1 LDA #2*Y-1 \ Set Y2 = 2 * #Y - 1. The constant #Y is 96, the STA Y2 \ y-coordinate of the mid-point of the space view, so \ this sets Y2 to 191, the y-coordinate of the bottom \ pixel row of the space view DEC X1 \ Decrement X1 and X2 DEC X2 JMP LOIN \ Draw a line from (X1, Y1) to (X2, Y2), and return from \ the subroutine using a tail call
Name: DELAY [Show more] Type: Subroutine Category: Utility routines Summary: Wait for a specified time, in 1/50s of a second
Context: See this subroutine on its own page References: This subroutine is called as follows: * DKS3 calls DELAY * Main game loop (Part 5 of 6) calls DELAY * TT217 calls DELAY * dn2 calls DELAY

Wait for the number of vertical syncs given in Y, so this effectively waits for Y/50 of a second (as the vertical sync occurs 50 times a second). Arguments: Y The number of vertical sync events to wait for
.DELAY JSR WSCAN \ Call WSCAN to wait for the vertical sync, so the whole \ screen gets drawn DEY \ Decrement the counter in Y BNE DELAY \ If Y isn't yet at zero, jump back to DELAY to wait \ for another vertical sync RTS \ Return from the subroutine
Name: CLYNS [Show more] Type: Subroutine Category: Utility routines Summary: Clear the bottom three text rows of the mode 4 screen
Context: See this subroutine on its own page References: This subroutine is called as follows: * JMTB calls CLYNS * TT102 calls CLYNS * hm calls CLYNS * menu calls CLYNS

This routine clears some space at the bottom of the screen and moves the text cursor to column 1, row 21. Specifically, it zeroes the following screen locations: &7507 to &75F0 &7607 to &76F0 &7707 to &77F0 which clears the three bottom text rows of the mode 4 screen (rows 21 to 23), clearing each row from text column 1 to 30 (so it doesn't overwrite the box border in columns 0 and 32, or the last usable column in column 31). Returns: A A is set to 0 Y Y is set to 0
.CLYNS LDA #%11111111 \ Set DTW2 = %11111111 to denote that we are not STA DTW2 \ currently printing a word LDA #20 \ Move the text cursor to row 20, near the bottom of STA YC \ the screen JSR TT67 \ Print a newline, which will move the text cursor down \ a line (to row 21) and back to column 1 LDA #&75 \ Set the two-byte value in SC to &7507 STA SC+1 LDA #7 STA SC LDA #0 \ Call LYN to clear the pixels from &7507 to &75F0 JSR LYN INC SC+1 \ Increment SC+1 so SC points to &7607 JSR LYN \ Call LYN to clear the pixels from &7607 to &76F0 INC SC+1 \ Increment SC+1 so SC points to &7707 INY \ Move the text cursor to column 1 (as LYN sets Y to 0) STY XC \ Fall through into LYN to clear the pixels from &7707 \ to &77F0
Name: LYN [Show more] Type: Subroutine Category: Utility routines Summary: Clear most of a row of pixels
Context: See this subroutine on its own page References: This subroutine is called as follows: * CLYNS calls LYN

Set pixels 0-233 to the value in A, starting at the pixel pointed to by SC. Arguments: A The value to store in pixels 1-233 (the only value that is actually used is A = 0, which clears those pixels) Returns: Y Y is set to 0 Other entry points: SC5 Contains an RTS
.LYN LDY #233 \ Set up a counter in Y to count down from pixel 233 .EE2 STA (SC),Y \ Store A in the Y-th byte after the address pointed to \ by SC DEY \ Decrement Y BNE EE2 \ Loop back until Y is zero .SC5 RTS \ Return from the subroutine
Name: WSCAN [Show more] Type: Subroutine Category: Screen mode Summary: Wait for the vertical sync
Context: See this subroutine on its own page References: This subroutine is called as follows: * DELAY calls WSCAN * DK4 calls WSCAN * TT16 calls WSCAN * ships_ag calls WSCAN

Wait for vertical sync to occur on the video system - in other words, wait for the screen to start its refresh cycle, which it does 50 times a second (50Hz).
.WSCAN LDA #0 \ Set DL to 0 STA DL LDA DL \ Loop round these two instructions until DL is no BEQ P%-2 \ longer 0 (DL gets set to 30 in the LINSCN routine, \ which is run when vertical sync has occurred on the \ video system, so DL will change to a non-zero value \ at the start of each screen refresh) RTS \ Return from the subroutine
Save ELTC.bin
PRINT "ELITE C" PRINT "Assembled at ", ~CODE_C% PRINT "Ends at ", ~P% PRINT "Code size is ", ~(P% - CODE_C%) PRINT "Execute at ", ~LOAD% PRINT "Reload at ", ~LOAD_C% PRINT "S.F.ELTC ", ~CODE_C%, " ", ~P%, " ", ~LOAD%, " ", ~LOAD_C% SAVE "3-assembled-output/F.ELTC.bin", CODE_C%, P%, LOAD%