BBC Micro Elite

# Elite D source

``` ELITE D FILE

Produces the binary file ELTD.bin that gets loaded by elite-bcfs.asm.

CODE_D% = P%

Name: tnpr                                            [View individually]
Type: Subroutine
Category: Market
Summary: Work out if we have space for a specific amount of cargo

Given a market item and an amount, work out whether there is room in the
cargo hold for this item.

For standard tonne canisters, the limit is given by the type of cargo hold we
have, with a standard cargo hold having a capacity of 20t and an extended
cargo bay being 35t.

For items measured in kg (gold, platinum), g (gem-stones) and alien items,
the individual limit on each of these is 200 units.

Arguments:

A                    The number of units of this market item

QQ29                 The type of market item (see QQ23 for a list of market
item numbers)

Returns:

A                    A is preserved

C flag               Returns the result:

* Set if there is no room for this item

* Clear if there is room for this item

.tnpr
{
PHA                    \ Store A on the stack

LDX #12                \ If QQ29 > 12 then jump to kg below, as this cargo
CPX QQ29               \ type is gold, platinum, gem-stones or alien items,
BCC kg                 \ and they have different cargo limits to the standard
\ tonne canisters

.Tml

\ Here we count the tonne canisters we have in the hold
\ and add to A to see if we have enough room for A more
\ tonnes of cargo, using X as the loop counter, starting
\ with X = 12

ADC QQ20,X             \ Set A = A + the number of tonnes we have in the hold
\ of market item number X. Note that the first time we
\ go round this loop, the C flag is set (as we didn't
\ branch with the BCC above, so the effect of this loop
\ is to count the number of tonne canisters in the hold,

DEX                    \ Decrement the loop counter

BPL Tml                \ Loop back to add in the next market item in the hold,
\ until we have added up all market items from 12
\ (minerals) down to 0 (food)

CMP CRGO               \ If A < CRGO then the C flag will be clear (we have
\ room in the hold)
\
\ If A >= CRGO then the C flag will be set (we do not
\ have room in the hold)
\
\ This works because A contains the number of canisters
\ plus 1, while CRGO contains our cargo capacity plus 2,
\ so if we actually have "a" canisters and a capacity
\ of "c", then:
\
\ A < CRGO means: a+1 <  c+2
\                 a   <  c+1
\                 a   <= c
\
\ So this is why the value in CRGO is 2 higher than the
\ actual cargo bay size, i.e. it's 22 for the standard
\ 20-tonne bay, and 37 for the large 35-tonne bay

PLA                    \ Restore A from the stack

RTS                    \ Return from the subroutine

.kg

\ Here we count the number of items of this type that
\ we already have in the hold, and add to A to see if
\ we have enough room for A more units

LDY QQ29               \ Set Y to the item number we want to add

ADC QQ20,Y             \ Set A = A + the number of units of this item that we
\ already have in the hold

CMP #200               \ Is the result greater than 200 (the limit on
\ individual stocks of gold, platinum, gem-stones and
\ alien items)?
\
\ If so, this sets the C flag (no room)
\
\ Otherwise it is clear (we have room)

PLA                    \ Restore A from the stack

RTS                    \ Return from the subroutine
}

Name: TT20                                            [View individually]
Type: Subroutine
Category: Universe
Summary: Twist the selected system's seeds four times

Twist the three 16-bit seeds in QQ15 (selected system) four times, to
generate the next system.

.TT20
{
JSR P%+3               \ This line calls the line below as a subroutine, which
\ does two twists before returning here, and then we
\ fall through to the line below for another two
\ twists, so the net effect of these two consecutive
\ JSR calls is four twists, not counting the ones

JSR P%+3               \ This line calls TT54 as a subroutine to do a twist,
\ and then falls through into TT54 to do another twist
\ before returning from the subroutine
}

Name: TT54                                            [View individually]
Type: Subroutine
Category: Universe
Summary: Twist the selected system's seeds

This routine twists the three 16-bit seeds in QQ15 once.

.TT54
{
LDA QQ15               \ X = tmp_lo = w0_lo + w1_lo
CLC
TAX

LDA QQ15+1             \ Y = tmp_hi = w1_hi + w1_hi + C
TAY

LDA QQ15+2             \ w0_lo = w1_lo
STA QQ15

LDA QQ15+3             \ w0_hi = w1_hi
STA QQ15+1

LDA QQ15+5             \ w1_hi = w2_hi
STA QQ15+3

LDA QQ15+4             \ w1_lo = w2_lo
STA QQ15+2

CLC                    \ w2_lo = X + w1_lo
TXA
STA QQ15+4

TYA                    \ w2_hi = Y + w1_hi + C
STA QQ15+5

RTS                    \ The twist is complete so return from the subroutine
}

Name: TT146                                           [View individually]
Type: Subroutine
Category: Text
Summary: Print the distance to the selected system in light years

If it is non-zero, print the distance to the selected system in light years.
If it is zero, just move the text cursor down a line.

Specifically, if the distance in QQ8 is non-zero, print token 31 ("DISTANCE"),
then a colon, then the distance to one decimal place, then token 35 ("LIGHT
YEARS"). If the distance is zero, move the cursor down one line.

.TT146
{
LDA QQ8                \ Take the two bytes of the 16-bit value in QQ8 and
ORA QQ8+1              \ OR them together to check whether there are any
BNE TT63               \ non-zero bits, and if so, jump to TT63 to print the
\ distance

INC YC                 \ The distance is zero, so we just move the text cursor
RTS                    \ in YC down by one line and return from the subroutine

.TT63

LDA #191               \ Print recursive token 31 ("DISTANCE") followed by
JSR TT68               \ a colon

LDX QQ8                \ Load (Y X) from QQ8, which contains the 16-bit
LDY QQ8+1              \ distance we want to show

SEC                    \ Set the C flag so that the call to pr5 will include a
\ decimal point, and display the value as (Y X) / 10

JSR pr5                \ Print (Y X) to 5 digits, including a decimal point

LDA #195               \ Set A to the recursive token 35 (" LIGHT YEARS") and
\ fall through into TT60 to print the token followed
\ by a paragraph break
}

Name: TT60                                            [View individually]
Type: Subroutine
Category: Text
Summary: Print a text token and a paragraph break

Print a text token (i.e. a character, control code, two-letter token or
recursive token). Then print a paragraph break (a blank line between
paragraphs) by moving the cursor down a line, setting Sentence Case, and then
printing a newline.

Arguments:

A                    The text token to be printed

.TT60
{
JSR TT27               \ Print the text token in A and fall through into TTX69
\ to print the paragraph break
}

Name: TTX69                                           [View individually]
Type: Subroutine
Category: Text
Summary: Print a paragraph break

Print a paragraph break (a blank line between paragraphs) by moving the cursor
down a line, setting Sentence Case, and then printing a newline.

.TTX69
{
INC YC                 \ Move the text cursor down a line

\ Fall through into TT69 to set Sentence Case and print
\ a newline
}

Name: TT69                                            [View individually]
Type: Subroutine
Category: Text
Summary: Set Sentence Case and print a newline

.TT69
{
LDA #%10000000         \ Set bit 7 of QQ17 to switch to Sentence Case
STA QQ17

\ Fall through into TT67 to print a newline
}

Name: TT67                                            [View individually]
Type: Subroutine
Category: Text
Summary: Print a newline

.TT67
{
LDA #13                \ Load a newline character into A

JMP TT27               \ Print the text token in A and return from the
\ subroutine using a tail call
}

Name: TT70                                            [View individually]
Type: Subroutine
Category: Text

This subroutine is called by TT25 when displaying a system's economy.

.TT70
{
LDA #173               \ Print recursive token 13 ("MAINLY ")
JSR TT27

JMP TT72               \ Jump to TT72 to continue printing system data as part
\ of routine TT25
}

Name: spc                                             [View individually]
Type: Subroutine
Category: Text
Summary: Print a text token followed by a space

Print a text token (i.e. a character, control code, two-letter token or
recursive token) followed by a space.

Arguments:

A                    The text token to be printed

.spc
{
JSR TT27               \ Print the text token in A

JMP TT162              \ Print a space and return from the subroutine using a
\ tail call
}

Name: TT25                                            [View individually]
Type: Subroutine
Category: Universe
Summary: Show the Data on System screen (red key f6)

Other entry points:

TT72                 Used by TT70 to re-enter the routine after displaying
"MAINLY" for the economy type

.TT25
{
JSR TT66-2             \ Clear the top part of the screen, draw a white border,
\ and set the current view type in QQ11 to 1

LDA #9                 \ Set the text cursor XC to column 9
STA XC

LDA #163               \ Print recursive token 3 as a title in capitals at
JSR TT27               \ the top ("DATA ON {selected system name}")

JSR NLIN               \ Draw a horizontal line underneath the title

JSR TTX69              \ Print a paragraph break and set Sentence Case

INC YC                 \ Move the text cursor down one more line

JSR TT146              \ If the distance to this system is non-zero, print
\ "DISTANCE", then the distance, "LIGHT YEARS" and a
\ paragraph break, otherwise just move the cursor down
\ a line

LDA #194               \ Print recursive token 34 ("ECONOMY") followed by
JSR TT68               \ a colon

LDA QQ3                \ The system economy is determined by the value in QQ3,
\ so fetch it into A. First we work out the system's
\ prosperity as follows:
\
\   QQ3 = 0 or 5 = %000 or %101 = Rich
\   QQ3 = 1 or 6 = %001 or %110 = Average
\   QQ3 = 2 or 7 = %010 or %111 = Poor
\   QQ3 = 3 or 4 = %011 or %100 = Mainly

CLC                    \ If (QQ3 + 1) >> 1 = %10, i.e. if QQ3 = %011 or %100
ADC #1                 \ (3 or 4), then call TT70, which prints "MAINLY " and
LSR A                  \ jumps down to TT72 to print the type of economy
CMP #%00000010
BEQ TT70

LDA QQ3                \ The LSR A above shifted bit 0 of QQ3 into the C flag,
BCC TT71               \ so this jumps to TT71 if bit 0 of QQ3 is 0, in other
\ words if QQ3 = %000, %001 or %010 (0, 1 or 2)

SBC #5                 \ Here QQ3 = %101, %110 or %111 (5, 6 or 7), so subtract
CLC                    \ 5 to bring it down to 0, 1 or 2 (the C flag is already
\ set so the SBC will be correct)

.TT71

ADC #170               \ A is now 0, 1 or 2, so print recursive token 10 + A.
JSR TT27               \ This means that:
\
\   QQ3 = 0 or 5 prints token 10 ("RICH ")
\   QQ3 = 1 or 6 prints token 11 ("AVERAGE ")
\   QQ3 = 2 or 7 prints token 12 ("POOR ")

.^TT72

LDA QQ3                \ Now to work out the type of economy, which is
LSR A                  \ determined by bit 2 of QQ3, as follows:
LSR A                  \
\   QQ3 bit 2 = 0 = Industrial
\   QQ3 bit 2 = 1 = Agricultural
\
\ So we fetch QQ3 into A and set A = bit 2 of QQ3 using
\ two right shifts (which will work as QQ3 is only a
\ 3-bit number)

CLC                    \ Print recursive token 8 + A, followed by a paragraph
ADC #168               \ break and Sentence Case, so:
JSR TT60               \
\   QQ3 bit 2 = 0 prints token 8 ("INDUSTRIAL")
\   QQ3 bit 2 = 1 prints token 9 ("AGRICULTURAL")

LDA #162               \ Print recursive token 2 ("GOVERNMENT") followed by
JSR TT68               \ a colon

LDA QQ4                \ The system economy is determined by the value in QQ4,
\ so fetch it into A

CLC                    \ Print recursive token 17 + A, followed by a paragraph
ADC #177               \ break and Sentence Case, so:
JSR TT60               \
\   QQ4 = 0 prints token 17 ("ANARCHY")
\   QQ4 = 1 prints token 18 ("FEUDAL")
\   QQ4 = 2 prints token 19 ("MULTI-GOVERNMENT")
\   QQ4 = 3 prints token 20 ("DICTATORSHIP")
\   QQ4 = 4 prints token 21 ("COMMUNIST")
\   QQ4 = 5 prints token 22 ("CONFEDERACY")
\   QQ4 = 6 prints token 23 ("DEMOCRACY")
\   QQ4 = 7 prints token 24 ("CORPORATE STATE")

LDA #196               \ Print recursive token 36 ("TECH.LEVEL") followed by a
JSR TT68               \ colon

LDX QQ5                \ Fetch the tech level from QQ5 and increment it, as it
INX                    \ is stored in the range 0-14 but the displayed range
\ should be 1-15

CLC                    \ Call pr2 to print the technology level as a 3-digit
JSR pr2                \ number without a decimal point (by clearing the C
\ flag)

JSR TTX69              \ Print a paragraph break and set Sentence Case

LDA #192               \ Print recursive token 32 ("POPULATION") followed by a
JSR TT68               \ colon

SEC                    \ Call pr2 to print the population as a 3-digit number
LDX QQ6                \ with a decimal point (by setting the C flag), so the
JSR pr2                \ number printed will be population / 10

LDA #198               \ Print recursive token 38 (" BILLION"), followed by a
JSR TT60               \ paragraph break and Sentence Case

LDA #'('               \ Print an opening bracket
JSR TT27

LDA QQ15+4             \ Now to calculate the species, so first check bit 7 of
BMI TT75               \ w2_lo, and if it is set, jump to TT75 as this is an
\ alien species

LDA #188               \ Bit 7 of w2_lo is clear, so print recursive token 28
JSR TT27               \ ("HUMAN COLONIAL")

JMP TT76               \ Jump to TT76 to print "S)" and a paragraph break, so
\ the whole species string is "(HUMAN COLONIALS)"

.TT75

LDA QQ15+5             \ This is an alien species, and we start with the first
LSR A                  \ adjective, so fetch bits 2-7 of w2_hi into A and push
LSR A                  \ onto the stack so we can use this later
PHA

AND #%00000111         \ Set A = bits 0-2 of A (so that's bits 2-4 of w2_hi)

BCS TT205

ADC #227               \ Otherwise A = 0, 1 or 2, so print recursive token
JSR spc                \ 67 + A, followed by a space, so:
\
\   A = 0 prints token 67 ("LARGE") and a space
\   A = 1 prints token 67 ("FIERCE") and a space
\   A = 2 prints token 67 ("SMALL") and a space

.TT205

PLA                    \ Now for the second adjective, so restore A to bits
LSR A                  \ 2-7 of w2_hi, and throw away bits 2-4 to leave
LSR A                  \ A = bits 5-7 of w2_hi
LSR A

BCS TT206

ADC #230               \ Otherwise A = 0 to 5, so print recursive token
JSR spc                \ 70 + A, followed by a space, so:
\
\   A = 0 prints token 70 ("GREEN") and a space
\   A = 1 prints token 71 ("RED") and a space
\   A = 2 prints token 72 ("YELLOW") and a space
\   A = 3 prints token 73 ("BLUE") and a space
\   A = 4 prints token 74 ("BLACK") and a space
\   A = 5 prints token 75 ("HARMLESS") and a space

.TT206

LDA QQ15+3             \ Now for the third adjective, so EOR the high bytes of
EOR QQ15+1             \ w0 and w1 and extract bits 0-2 of the result:
AND #%00000111         \
STA QQ19               \   A = (w0_hi EOR w1_hi) AND %111
\
\ storing the result in QQ19 so we can use it later

BCS TT207

ADC #236               \ Otherwise A = 0 to 5, so print recursive token
JSR spc                \ 76 + A, followed by a space, so:
\
\   A = 0 prints token 76 ("SLIMY") and a space
\   A = 1 prints token 77 ("BUG-EYED") and a space
\   A = 2 prints token 78 ("HORNED") and a space
\   A = 3 prints token 79 ("BONY") and a space
\   A = 4 prints token 80 ("FAT") and a space
\   A = 5 prints token 81 ("FURRY") and a space

.TT207

LDA QQ15+5             \ Now for the actual species, so take bits 0-1 of
AND #%00000011         \ w2_hi, add this to the value of A that we used for
CLC                    \ the third adjective, and take bits 0-2 of the result
AND #%00000111

ADC #242               \ A = 0 to 7, so print recursive token 82 + A, so:
JSR TT27               \
\   A = 0 prints token 76 ("RODENT")
\   A = 1 prints token 76 ("FROG")
\   A = 2 prints token 76 ("LIZARD")
\   A = 3 prints token 76 ("LOBSTER")
\   A = 4 prints token 76 ("BIRD")
\   A = 5 prints token 76 ("HUMANOID")
\   A = 6 prints token 76 ("FELINE")
\   A = 7 prints token 76 ("INSECT")

.TT76

LDA #'S'               \ Print an "S" to pluralise the species
JSR TT27

LDA #')'               \ And finally, print a closing bracket, followed by a
JSR TT60               \ paragraph break and Sentence Case, to end the species
\ section

LDA #193               \ Print recursive token 33 ("GROSS PRODUCTIVITY"),
JSR TT68               \ followed by colon

LDX QQ7                \ Fetch the 16-bit productivity value from QQ7 into
LDY QQ7+1              \ (Y X)

JSR pr6                \ Print (Y X) to 5 digits with no decimal point

JSR TT162              \ Print a space

LDA #0                 \ Set QQ17 = 0 to switch to ALL CAPS
STA QQ17

LDA #'M'               \ Print "M"
JSR TT27

LDA #226               \ Print recursive token 66 (" CR"), followed by a
JSR TT60               \ paragraph break and Sentence Case

LDA #250               \ Print recursive token 90 ("AVERAGE RADIUS"), followed
JSR TT68               \ by a colon

\ The average radius is calculated like this:
\
\   ((w2_hi AND %1111) + 11) * 256 + w1_hi
\
\ or, in terms of memory locations:
\
\   ((QQ15+5 AND %1111) + 11) * 256 + QQ15+3
\
\ Because the multiplication is by 256, this is the
\ same as saying a 16-bit number, with high byte:
\
\   (QQ15+5 AND %1111) + 11
\
\ and low byte:
\
\   QQ15+3
\
\ so we can set this up in (Y X) and call the pr5
\ routine to print it out

LDA QQ15+5             \ Set A = QQ15+5
LDX QQ15+3             \ Set X = QQ15+3

AND #%00001111         \ Set Y = (A AND %1111) + 11
CLC
TAY

JSR pr5                \ Print (Y X) to 5 digits, not including a decimal
\ point, as the C flag will be clear (as the maximum
\ radius will always fit into 16 bits)

JSR TT162              \ Print a space

LDA #'k'               \ Print "km", returning from the subroutine using a
JSR TT26               \ tail call
LDA #'m'
JMP TT26
}

Name: TT24                                            [View individually]
Type: Subroutine
Category: Universe
Summary: Calculate system data from the system seeds

Calculate system data from the seeds in QQ15 and store them in the relevant
locations. Specifically, this routine calculates the following from the three
16-bit seeds in QQ15 (using only w0_hi, w1_hi and w1_lo):

QQ3 = economy (0-7)
QQ4 = government (0-7)
QQ5 = technology level (0-14)
QQ6 = population * 10 (1-71)
QQ7 = productivity (96-62480)

The ranges of the various values are shown in brackets. Note that the radius
and type of inhabitant are calculated on-the-fly in the TT25 routine when
the system data gets displayed, so they aren't calculated here.

.TT24
{
LDA QQ15+1             \ Fetch w0_hi and extract bits 0-2 to determine the
AND #%00000111         \ system's economy, and store in QQ3
STA QQ3

LDA QQ15+2             \ Fetch w1_lo and extract bits 3-5 to determine the
LSR A                  \ system's government, and store in QQ4
LSR A
LSR A
AND #%00000111
STA QQ4

LSR A                  \ If government isn't anarchy or feudal, skip to TT77,
BNE TT77               \ as we need to fix the economy of anarchy and feudal
\ systems so they can't be rich

LDA QQ3                \ Set bit 1 of the economy in QQ3 to fix the economy
ORA #%00000010         \ for anarchy and feudal governments
STA QQ3

.TT77

LDA QQ3                \ Now to work out the tech level, which we do like this:
EOR #%00000111         \
CLC                    \   flipped_economy + (w1_hi AND %11) + (government / 2)
STA QQ5                \
\ or, in terms of memory locations:
\
\   QQ5 = (QQ3 EOR %111) + (QQ15+3 AND %11) + (QQ4 / 2)
\
\ We start by setting QQ5 = QQ3 EOR %111

LDA QQ15+3             \ We then take the first 2 bits of w1_hi (QQ15+3) and
AND #%00000011         \ add it into QQ5
STA QQ5

LDA QQ4                \ And finally we add QQ4 / 2 and store the result in
LSR A                  \ QQ5, using LSR then ADC to divide by 2, which rounds
ADC QQ5                \ up the result for odd-numbered government types
STA QQ5

ASL A                  \ Now to work out the population, like so:
ASL A                  \
ADC QQ3                \   (tech level * 4) + economy + government + 1
ADC #1                 \ or, in terms of memory locations:
STA QQ6                \
\   QQ6 = (QQ5 * 4) + QQ3 + QQ4 + 1

LDA QQ3                \ Finally, we work out productivity, like this:
EOR #%00000111         \
ADC #3                 \  (flipped_economy + 3) * (government + 4)
STA P                  \                        * population
LDA QQ4                \                        * 8
STA Q                  \ or, in terms of memory locations:
JSR MULTU              \
\   QQ7 = (QQ3 EOR %111 + 3) * (QQ4 + 4) * QQ6 * 8
\
\ We do the first step by setting P to the first
\ expression in brackets and Q to the second, and
\ calling MULTU, so now (A P) = P * Q. The highest this
\ can be is 10 * 11 (as the maximum values of economy
\ and government are 7), so the high byte of the result
\ will always be 0, so we actually have:
\
\   P = P * Q
\     = (flipped_economy + 3) * (government + 4)

LDA QQ6                \ We now take the result in P and multiply by the
STA Q                  \ population to get the productivity, by setting Q to
JSR MULTU              \ the population from QQ6 and calling MULTU again, so
\ now we have:
\
\   (A P) = P * population

ASL P                  \ Next we multiply the result by 8, as a 16-bit number,
ROL A                  \ so we shift both bytes to the left three times, using
ASL P                  \ the C flag to carry bits from bit 7 of the low byte
ROL A                  \ into bit 0 of the high byte
ASL P
ROL A

STA QQ7+1              \ Finally, we store the productivity in two bytes, with
LDA P                  \ the low byte in QQ7 and the high byte in QQ7+1
STA QQ7

RTS                    \ Return from the subroutine
}

Name: TT22                                            [View individually]
Type: Subroutine
Category: Charts
Summary: Show the Long-range Chart (red key f4)

.TT22
{
LDA #64                \ Clear the top part of the screen, draw a white border,
JSR TT66               \ and set the current view type in QQ11 to 32 (Long-
\ range Chart)

LDA #7                 \ Move the text cursor to column 7
STA XC

JSR TT81               \ Set the seeds in QQ15 to those of system 0 in the
\ current galaxy (i.e. copy the seeds from QQ21 to QQ15)

LDA #199               \ Print recursive token 39 ("GALACTIC CHART{galaxy
JSR TT27               \ number right-aligned to width 3}")

JSR NLIN               \ Draw a horizontal line at pixel row 23 to box in the
\ title and act as the top frame of the chart, and move
\ the text cursor down one line

LDA #152               \ Draw a screen-wide horizontal line at pixel row 152
JSR NLIN2              \ for the bottom edge of the chart, so the chart itself
\ is 128 pixels high, starting on row 24 and ending on
\ row 151

JSR TT14               \ Call TT14 to draw a circle with crosshairs at the
\ current system's galactic coordinates

LDX #0                 \ We're now going to plot each of the galaxy's systems,
\ so set up a counter in X for each system, starting at
\ 0 and looping through to 255

.TT83

STX XSAV               \ Store the counter in XSAV

LDX QQ15+3             \ Fetch the w1_hi seed into X, which gives us the
\ galactic x-coordinate of this system

LDY QQ15+4             \ Fetch the w2_lo seed and clear all the bits apart
TYA                    \ from bits 4 and 6, storing the result in ZZ to give a
ORA #%01010000         \ random number out of 0, &10, &40 or &50 (but which
STA ZZ                 \ will always be the same for this system). We use this
\ value to determine the size of the point for this
\ system on the chart by passing it as the distance
\ argument to the PIXEL routine below

LDA QQ15+1             \ Fetch the w0_hi seed into A, which gives us the
\ galactic y-coordinate of this system

LSR A                  \ We halve the y-coordinate because the galaxy in
\ in Elite is rectangular rather than square, and is
\ twice as wide (x-axis) as it is high (y-axis), so the
\ chart is 256 pixels wide and 128 high

CLC                    \ Add 24 to the halved y-coordinate and store in XX15+1
ADC #24                \ (as the top of the chart is on pixel row 24, just
STA XX15+1             \ below the line we drew on row 23 above)

JSR PIXEL              \ Call PIXEL to draw a point at (X, A), with the size of
\ the point dependent on the distance specified in ZZ
\ (so a high value of ZZ will produce a 1-pixel point,
\ a medium value will produce a 2-pixel dash, and a
\ small value will produce a 4-pixel square)

JSR TT20               \ We want to move on to the next system, so call TT20
\ to twist the three 16-bit seeds in QQ15

LDX XSAV               \ Restore the loop counter from XSAV

INX                    \ Increment the counter

BNE TT83               \ If X > 0 then we haven't done all 256 systems yet, so
\ loop back up to TT83

LDA QQ9                \ Set QQ19 to the selected system's x-coordinate
STA QQ19

LDA QQ10               \ Set QQ19+1 to the selected system's y-coordinate,
LSR A                  \ halved to fit it into the chart
STA QQ19+1

LDA #4                 \ Set QQ19+2 to size 4 for the crosshairs size
STA QQ19+2

\ Fall through into TT15 to draw crosshairs of size 4 at
\ the selected system's coordinates
}

Name: TT15                                            [View individually]
Type: Subroutine
Category: Drawing lines
Summary: Draw a set of crosshairs

For all views except the Short-range Chart, the centre is drawn 24 pixels to
the right of the y-coordinate given.

Arguments:

QQ19                 The pixel x-coordinate of the centre of the crosshairs

QQ19+1               The pixel y-coordinate of the centre of the crosshairs

QQ19+2               The size of the crosshairs

.TT15
{
LDA #24                \ Set A to 24, which we will use as the minimum
\ screen indent for the crosshairs (i.e. the minimum
\ distance from the top-left corner of the screen)

LDX QQ11               \ If the current view is not the Short-range Chart,
BPL P%+4               \ which is the only view with bit 7 set, then skip the
\ following instruction

LDA #0                 \ This is the Short-range Chart, so set A to 0, so the
\ crosshairs can go right up against the screen edges

STA QQ19+5             \ Set QQ19+5 to A, which now contains the correct indent
\ for this view

LDA QQ19               \ Set A = crosshairs x-coordinate - crosshairs size
SEC                    \ to get the x-coordinate of the left edge of the
SBC QQ19+2             \ crosshairs

BCS TT84               \ If the above subtraction didn't underflow, then A is
\ positive, so skip the next instruction

LDA #0                 \ The subtraction underflowed, so set A to 0 so the
\ crosshairs don't spill out of the left of the screen

.TT84

\ In the following, the authors have used XX15 for
\ temporary storage. XX15 shares location with X1, Y1,
\ X2 and Y2, so in the following, you can consider
\ the variables like this:
\
\   XX15   is the same as X1
\   XX15+1 is the same as Y1
\   XX15+2 is the same as X2
\   XX15+3 is the same as Y2
\
\ Presumably this routine was written at a different
\ time to the line-drawing routine, before the two
\ workspaces were merged to save space

STA XX15               \ Set XX15 (X1) = A (the x-coordinate of the left edge
\ of the crosshairs)

LDA QQ19               \ Set A = crosshairs x-coordinate + crosshairs size
CLC                    \ to get the x-coordinate of the right edge of the

BCC P%+4               \ If the above addition didn't overflow, then A is
\ correct, so skip the next instruction

LDA #255               \ The addition overflowed, so set A to 255 so the
\ crosshairs don't spill out of the right of the screen
\ (as 255 is the x-coordinate of the rightmost pixel
\ on-screen)

STA XX15+2             \ Set XX15+2 (X2) = A (the x-coordinate of the right
\ edge of the crosshairs)

LDA QQ19+1             \ Set XX15+1 (Y1) = crosshairs y-coordinate + indent
CLC                    \ to get the y-coordinate of the centre of the
STA XX15+1

JSR HLOIN              \ Draw a horizontal line from (X1, Y1) to (X2, Y1),
\ which will draw from the left edge of the crosshairs
\ to the right edge, through the centre of the
\ crosshairs

LDA QQ19+1             \ Set A = crosshairs y-coordinate - crosshairs size
SEC                    \ to get the y-coordinate of the top edge of the
SBC QQ19+2             \ crosshairs

BCS TT86               \ If the above subtraction didn't underflow, then A is
\ correct, so skip the next instruction

LDA #0                 \ The subtraction underflowed, so set A to 0 so the
\ crosshairs don't spill out of the top of the screen

.TT86

CLC                    \ Set XX15+1 (Y1) = A + indent to get the y-coordinate
ADC QQ19+5             \ of the top edge of the indented crosshairs
STA XX15+1

LDA QQ19+1             \ Set A = crosshairs y-coordinate + crosshairs size
CLC                    \ + indent to get the y-coordinate of the bottom edge
ADC QQ19+2             \ of the indented crosshairs

CMP #152               \ If A < 152 then skip the following, as the crosshairs
BCC TT87               \ won't spill out of the bottom of the screen

LDX QQ11               \ A >= 152, so we need to check whether this will fit in
\ this view, so fetch the view number

BMI TT87               \ If this is the Short-range Chart then the y-coordinate

LDA #151               \ Otherwise this is the Long-range Chart, so we need to
\ clip the crosshairs at a maximum y-coordinate of 151

.TT87

STA XX15+3             \ Set XX15+3 (Y2) = A (the y-coordinate of the bottom
\ edge of the crosshairs)

LDA QQ19               \ Set XX15 (X1) = the x-coordinate of the centre of the
STA XX15               \ crosshairs

STA XX15+2             \ Set XX15+2 (X2) = the x-coordinate of the centre of
\ the crosshairs

JMP LL30               \ Draw a vertical line (X1, Y1) to (X2, Y2), which will
\ draw from the top edge of the crosshairs to the bottom
\ edge, through the centre of the crosshairs, returning
\ from the subroutine using a tail call
}

Name: TT14                                            [View individually]
Type: Subroutine
Category: Drawing circles
Summary: Draw a circle with crosshairs on a chart

Draw a circle with crosshairs at the current system's galactic coordinates.

{
.TT126

LDA #104               \ Set QQ19 = 104, for the x-coordinate of the centre of
STA QQ19               \ the fixed circle on the Short-range Chart

LDA #90                \ Set QQ19+1 = 90, for the y-coordinate of the centre of
STA QQ19+1             \ the fixed circle on the Short-range Chart

LDA #16                \ Set QQ19+2 = 16, the size of the crosshairs on the
STA QQ19+2             \ Short-range Chart

JSR TT15               \ Draw the set of crosshairs defined in QQ19, at the
\ exact coordinates as this is the Short-range Chart

LDA QQ14               \ Set K to the fuel level from QQ14, so this can act as
STA K                  \ the circle's radius (70 being a full tank)

JMP TT128              \ Jump to TT128 to draw a circle with the centre at the
\ same coordinates as the crosshairs, (QQ19, QQ19+1),
\ and radius K that reflects the current fuel levels,
\ returning from the subroutine using a tail call

.^TT14

LDA QQ11               \ If the current view is the Short-range Chart, which
BMI TT126              \ is the only view with bit 7 set, then jump up to TT126
\ to draw the crosshairs and circle for that view

\ Otherwise this is the Long-range Chart, so we draw the
\ crosshairs and circle for that view instead

LDA QQ14               \ Set K to the fuel level from QQ14 divided by 4, so
LSR A                  \ this can act as the circle's radius (70 being a full
LSR A                  \ tank, which divides down to a radius of 17)
STA K

LDA QQ0                \ Set QQ19 to the x-coordinate of the current system,
STA QQ19               \ which will be the centre of the circle and crosshairs
\ we draw

LDA QQ1                \ Set QQ19+1 to the y-coordinate of the current system,
LSR A                  \ halved because the galactic chart is half as high as
STA QQ19+1             \ it is wide, which will again be the centre of the
\ circle and crosshairs we draw

LDA #7                 \ Set QQ19+2 = 7, the size of the crosshairs on the
STA QQ19+2             \ Long-range Chart

JSR TT15               \ Draw the set of crosshairs defined in QQ19, which will
\ be drawn 24 pixels to the right of QQ19+1

LDA QQ19+1             \ Add 24 to the y-coordinate of the crosshairs in QQ19+1
CLC                    \ so that the centre of the circle matches the centre
ADC #24                \ of the crosshairs
STA QQ19+1

\ Fall through into TT128 to draw a circle with the
\ centre at the same coordinates as the crosshairs,
\ (QQ19, QQ19+1),  and radius K that reflects the
\ current fuel levels
}

Name: TT128                                           [View individually]
Type: Subroutine
Category: Drawing circles
Summary: Draw a circle on a chart

Draw a circle with the centre at (QQ19, QQ19+1) and radius K.

Arguments:

QQ19                 The x-coordinate of the centre of the circle

QQ19+1               The y-coordinate of the centre of the circle

K                    The radius of the circle

.TT128
{
LDA QQ19               \ Set K3 = the x-coordinate of the centre
STA K3

LDA QQ19+1             \ Set K4 = the y-coordinate of the centre
STA K4

LDX #0                 \ Set the high bytes of K3(1 0) and K4(1 0) to 0
STX K4+1
STX K3+1

\STX LSX                \ This instruction is commented out in the original
\ source

INX                    \ Set LSP = 1 to reset the ball line heap
STX LSP

LDX #2                 \ Set STP = 2, the step size for the circle
STX STP

JSR CIRCLE2            \ Call CIRCLE2 to draw a circle with the centre at
\ (K3(1 0), K4(1 0)) and radius K

\LDA #&FF               \ These instructions are commented out in the original
\STA LSX                \ source

RTS                    \ Return from the subroutine
}

Name: TT219                                           [View individually]
Type: Subroutine
Category: Market
Summary: Show the Buy Cargo screen (red key f1)

Other entry points:

BAY2                 Jump into the main loop at FRCE, setting the key
"pressed" to red key f9 (so we show the Inventory
screen)

.TT219
{
\LDA#2                  \ This instruction is commented out in the original
\ source. Perhaps this view originally had a QQ11 value
\ of 2, but it turned out not to need its own unique ID,
\ so the authors found they could just use a view value
\ of 1 and save an instruction at the same time?

JSR TT66-2             \ Clear the top part of the screen, draw a white border,
\ and set the current view type in QQ11 to 1

JSR TT163              \ Print the column headers for the prices table

LDA #%10000000         \ Set bit 7 of QQ17 to switch to Sentence Case, with the
STA QQ17               \ next letter in capitals

\JSR FLKB               \ This instruction is commented out in the original
\ source. It calls a routine to flush the keyboard
\ buffer (FLKB) that isn't present in the cassette
\ version but is in the disc version

LDA #0                 \ We're going to loop through all the available market
STA QQ29               \ items, so we set up a counter in QQ29 to denote the
\ current item and start it at 0

.TT220

JSR TT151              \ Call TT151 to print the item name, market price and
\ availability of the current item, and set QQ24 to the
\ item's price / 4, QQ25 to the quantity available and
\ QQ19+1 to byte #1 from the market prices table for
\ this item

LDA QQ25               \ If there are some of the current item available, jump
BNE TT224              \ to TT224 below to see if we want to buy any

JMP TT222              \ Otherwise there are none available, so jump down to
\ TT222 to skip this item

.TQ4

LDY #176               \ Set Y to the recursive token 16 ("QUANTITY")

.Tc

JSR TT162              \ Print a space

TYA                    \ Print the recursive token in Y followed by a question
JSR prq                \ mark

.TTX224

JSR dn2                \ Call dn2 to make a short, high beep and delay for 1
\ second

.TT224

JSR CLYNS              \ Clear the bottom three text rows of the upper screen,
\ and move the text cursor to column 1 on row 21, i.e.
\ the start of the top row of the three bottom rows

LDA #204               \ Print recursive token 44 ("QUANTITY OF ")
JSR TT27

LDA QQ29               \ Print recursive token 48 + QQ29, which will be in the
CLC                    \ range 48 ("FOOD") to 64 ("ALIEN ITEMS"), so this
ADC #208               \ prints the current item's name
JSR TT27

LDA #'/'               \ Print "/"
JSR TT27

JSR TT152              \ Print the unit ("t", "kg" or "g") for the current item
\ (as the call to TT151 above set QQ19+1 with the
\ appropriate value)

LDA #'?'               \ Print "?"
JSR TT27

JSR TT67               \ Print a newline

LDX #0                 \ These instructions have no effect, as they are
STX R                  \ repeated at the start of gnum, which we call next.
LDX #12                \ Perhaps they were left behind when code was moved from
STX T1                 \ here into gnum, and weren't deleted?

\.TT223                 \ This label is commented out in the original source,
\ and is a duplicate of a label in gnum, so this could
\ also be a remnant if the code in gnum was originally
\ here, but got moved into the gnum subroutine

JSR gnum               \ Call gnum to get a number from the keyboard, which
\ will be the quantity of this item we want to purchase,
\ returning the number entered in A and R

BCS TQ4                \ If gnum set the C flag, the number entered is greater
\ then the quantity available, so jump up to TQ4 to
\ display a "Quantity?" error, beep, clear the number
\ and try again

STA P                  \ Otherwise we have a valid purchase quantity entered,
\ so store the amount we want to purchase in P

JSR tnpr               \ Call tnpr to work out whether there is room in the
\ cargo hold for this item

LDY #206               \ If the C flag is set, then there is no room in the
BCS Tc                 \ cargo hold, so set Y to the recursive token 46
\ (" CARGO{switch to sentence case}") and jump up to
\ Tc to print a "Cargo?" error, beep, clear the number
\ and try again

LDA QQ24               \ There is room in the cargo hold, so now to check
STA Q                  \ whether we have enough cash, so fetch the item's
\ price / 4, which was returned in QQ24 by the call
\ to TT151 above and store it in Q

JSR GCASH              \ Call GCASH to calculate
\
\   (Y X) = P * Q * 4
\
\ which will be the total price of this transaction
\ (as P contains the purchase quantity and Q contains
\ the item's price / 4)

JSR LCASH              \ Subtract (Y X) cash from the cash pot in CASH

LDY #197               \ If the C flag is clear, we didn't have enough cash,
BCC Tc                 \ so set Y to the recursive token 37 ("CASH") and jump
\ up to Tc to print a "Cash?" error, beep, clear the
\ number and try again

LDY QQ29               \ Fetch the current market item number from QQ29 into Y

LDA R                  \ Set A to the number of items we just purchased (this
\ was set by gnum above)

PHA                    \ Store the quantity just purchased on the stack

CLC                    \ Add the number purchased to the Y-th byte of QQ20,
ADC QQ20,Y             \ which contains the number of items of this type in
STA QQ20,Y             \ our hold (so this transfers the bought items into our
\ cargo hold)

LDA AVL,Y              \ Subtract the number of items from the Y-th byte of
SEC                    \ AVL, which contains the number of items of this type
SBC R                  \ that are available on the market
STA AVL,Y

PLA                    \ Restore the quantity just purchased

\ following instruction

JSR dn                 \ Call dn to print the amount of cash left in the cash
\ pot, then make a short, high beep to confirm the
\ purchase, and delay for 1 second

.TT222

LDA QQ29               \ Move the text cursor to row QQ29 + 5 (where QQ29 is
CLC                    \ the item number, starting from 0)
STA YC

LDA #0                 \ Move the text cursor to column 0
STA XC

INC QQ29               \ Increment QQ29 to point to the next item

LDA QQ29               \ If QQ29 >= 17 then jump to BAY2 as we have done the
CMP #17                \ last item
BCS BAY2

JMP TT220              \ Otherwise loop back to TT220 to print the next market
\ item

.^BAY2

LDA #f9                \ Jump into the main loop at FRCE, setting the key
JMP FRCE               \ "pressed" to red key f9 (so we show the Inventory
\ screen)
}

Name: gnum                                            [View individually]
Type: Subroutine
Category: Market
Summary: Get a number from the keyboard

Get a number from the keyboard, up to the maximum number in QQ25. Pressing a
key with an ASCII code less than ASCII "0" will return a 0 in A (so that
includes pressing Space or Return), while pressing a key with an ASCII code
greater than ASCII "9" will jump to the Inventory screen (so that includes
all letters and most punctuation).

Arguments:

QQ25                 The maximum number allowed

Returns:

A                    The number entered

R                    Also contains the number entered

C flag               Set if the number is too large (> QQ25), clear otherwise

.gnum
{
LDX #0                 \ We will build the number entered in R, so initialise
STX R                  \ it with 0

LDX #12                \ We will check for up to 12 key presses, so set a
STX T1                 \ counter in T1

.TT223

JSR TT217              \ Scan the keyboard until a key is pressed, and return
\ the key's ASCII code in A (and X)

STA Q                  \ Store the key pressed in Q

SEC                    \ Subtract ASCII '0' from the key pressed, to leave the
SBC #'0'               \ numeric value of the key in A (if it was a number key)

BCC OUT                \ If A < 0, jump to OUT to return from the subroutine
\ with a result of 0, as the key pressed was not a
\ number or letter and is less than ASCII "0"

CMP #10                \ If A >= 10, jump to BAY2 to display the Inventory
BCS BAY2               \ screen, as the key pressed was a letter or other
\ non-digit and is greater than ASCII "9"

STA S                  \ Store the numeric value of the key pressed in S

LDA R                  \ Fetch the result so far into A

CMP #26                \ If A >= 26, where A is the number entered so far, then
BCS OUT                \ adding a further digit will make it bigger than 256,
\ so jump to OUT to return from the subroutine with the
\ result in R (i.e. ignore the last key press)

ASL A                  \ Set A = (A * 2) + (A * 8) = A * 10
STA T
ASL A
ASL A

ADC S                  \ Add the pressed digit to A and store in R, so R now
STA R                  \ contains its previous value with the new key press
\ tacked onto the end

CMP QQ25               \ If the result in R = the maximum allowed in QQ25, jump
BEQ TT226              \ to TT226 to print the key press and keep looping (the
\ BEQ is needed because the BCS below would jump to OUT
\ if R >= QQ25, which we don't want)

BCS OUT                \ If the result in R > QQ25, jump to OUT to return from
\ the subroutine with the result in R

.TT226

LDA Q                  \ Print the character in Q (i.e. the key that was
JSR TT26               \ pressed, as we stored the ASCII value in Q earlier)

DEC T1                 \ Decrement the loop counter

BNE TT223              \ Loop back to TT223 until we have checked for 12 digits

.OUT

LDA R                  \ Set A to the result we have been building in R

RTS                    \ Return from the subroutine
}

Name: TT208                                           [View individually]
Type: Subroutine
Category: Market
Summary: Show the Sell Cargo screen (red key f2)

.TT208
{
LDA #4                 \ Clear the top part of the screen, draw a white border,
JSR TT66               \ and set the current view type in QQ11 to 4 (Sell
\ Cargo screen)

LDA #4                 \ Move the text cursor to row 4, column 4
STA YC
STA XC

\JSR FLKB               \ This instruction is commented out in the original
\ source. It calls a routine to flush the keyboard
\ buffer (FLKB) that isn't present in the cassette
\ version but is in the disc version

LDA #205               \ Print recursive token 45 ("SELL")
JSR TT27

LDA #206               \ Print recursive token 46 (" CARGO{switch to sentence
JSR TT68               \ case}") followed by a colon

\ Fall through into TT210 to show the Inventory screen
\ with the option to sell
}

Name: TT210                                           [View individually]
Type: Subroutine
Category: Inventory
Summary: Show a list of current cargo in our hold, optionally to sell

Show a list of current cargo in our hold, either with the ability to sell (the
Sell Cargo screen) or without (the Inventory screen), depending on the current
view.

Arguments:

QQ11                 The current view:

* 4 = Sell Cargo

* 8 = Inventory

.TT210
{
LDY #0                 \ We're going to loop through all the available market
\ items and check whether we have any in the hold (and,
\ if we are in the Sell Cargo screen, whether we want
\ to sell any items), so we set up a counter in Y to
\ denote the current item and start it at 0

.TT211

STY QQ29               \ Store the current item number in QQ29

LDX QQ20,Y             \ Fetch into X the amount of the current item that we
BEQ TT212              \ have in our cargo hold, which is stored in QQ20+Y,
\ and if there are no items of this type in the hold,

TYA                    \ Set Y = Y * 4, so this will act as an index into the
ASL A                  \ market prices table at QQ23 for this item (as there
ASL A                  \ are four bytes per item in the table)
TAY

LDA QQ23+1,Y           \ Fetch byte #1 from the market prices table for the
STA QQ19+1             \ current item and store it in QQ19+1, for use by the
\ call to TT152 below

TXA                    \ Store the amount of item in the hold (in X) on the
PHA                    \ stack

JSR TT69               \ Call TT69 to set Sentence Case and print a newline

CLC                    \ Print recursive token 48 + QQ29, which will be in the
LDA QQ29               \ range 48 ("FOOD") to 64 ("ALIEN ITEMS"), so this
ADC #208               \ prints the current item's name
JSR TT27

LDA #14                \ Set the text cursor to column 14, for the item's
STA XC                 \ quantity

PLA                    \ Restore the amount of item in the hold into X
TAX

CLC                    \ Print the 8-bit number in X to 3 digits, without a
JSR pr2                \ decimal point

JSR TT152              \ Print the unit ("t", "kg" or "g") for the market item
\ whose byte #1 from the market prices table is in
\ QQ19+1 (which we set up above)

LDA QQ11               \ If the current view type in QQ11 is not 4 (Sell Cargo
CMP #4                 \ screen), jump to TT212 to skip the option to sell
BNE TT212              \ items

LDA #205               \ Set A to recursive token 45 ("SELL")

JSR TT214              \ Call TT214 to print "Sell(Y/N)?" and return the
\ response in the C flag

BCC TT212              \ If the response was "no", jump to TT212 to move on to
\ the next item

LDA QQ29               \ We are selling this item, so fetch the item number
\ from QQ29

LDX #255               \ Set QQ17 = 255 to disable printing
STX QQ17

JSR TT151              \ Call TT151 to set QQ24 to the item's price / 4 (the
\ routine doesn't print the item details, as we just
\ disabled printing)

LDY QQ29               \ Set P to the amount of this item we have in our cargo
LDA QQ20,Y             \ hold (which is the amount to sell)
STA P

LDA QQ24               \ Set Q to the item's price / 4
STA Q

JSR GCASH              \ Call GCASH to calculate
\
\   (Y X) = P * Q * 4
\
\ which will be the total price we make from this sale
\ (as P contains the quantity we're selling and Q
\ contains the item's price / 4)

JSR MCASH              \ Add (Y X) cash to the cash pot in CASH

LDA #0                 \ We've made the sale, so set the amount
LDY QQ29               \ item index
STA QQ20,Y             \ ship cargo count

STA QQ17               \ Set QQ17 = 0, which enables printing again

.TT212

LDY QQ29               \ Fetch the item number from QQ29 into Y, and increment
INY                    \ Y to point to the next item

CPY #17                \ If A >= 17 then skip the next instruction as we have
BCS P%+5               \ done the last item

JMP TT211              \ Otherwise loop back to TT211 to print the next item
\ in the hold

LDA QQ11               \ If the current view type in QQ11 is not 4 (Sell Cargo
CMP #4                 \ screen), skip the next two instructions and just
BNE P%+8               \ return from the subroutine

JSR dn2                \ This is the Sell Cargo screen, so call dn2 to make a
\ short, high beep and delay for 1 second

JMP BAY2               \ And then jump to BAY2 to display the Inventory
\ screen, as we have finished selling cargo

RTS                    \ Return from the subroutine
}

Name: TT213                                           [View individually]
Type: Subroutine
Category: Inventory
Summary: Show the Inventory screen (red key f9)

.TT213
{
LDA #8                 \ Clear the top part of the screen, draw a white border,
JSR TT66               \ and set the current view type in QQ11 to 8 (Inventory
\ screen)

LDA #11                \ Move the text cursor to column 11 to print the screen
STA XC                 \ title

LDA #164               \ Print recursive token 4 ("INVENTORY{crlf}") followed
JSR TT60               \ by a paragraph break and Sentence Case

JSR NLIN4              \ Draw a horizontal line at pixel row 19 to box in the
\ title. The authors could have used a call to NLIN3
\ instead and saved the above call to TT60, but you
\ just can't optimise everything

JSR fwl                \ Call fwl to print the fuel and cash levels on two
\ separate lines

LDA CRGO               \ If our ship's cargo capacity is < 26 (i.e. we do not
CMP #26                \ have a cargo bay extension), skip the following two
BCC P%+7               \ instructions

LDA #107               \ We do have a cargo bay extension, so print recursive
JSR TT27               \ token 107 ("LARGE CARGO{switch to sentence case}
\ BAY")

JMP TT210              \ Jump to TT210 to print the contents of our cargo bay
\ and return from the subroutine using a tail call
}

Name: TT214                                           [View individually]
Type: Subroutine
Category: Inventory
Summary: Ask a question with a "Y/N?" prompt and return the response

Arguments:

A                    The text token to print before the "Y/N?" prompt

Returns:

C flag               Set if the response was "yes", clear otherwise

.TT214
{
PHA                    \ Print a space, using the stack to preserve the value
JSR TT162              \ of A
PLA

.TT221

JSR TT27               \ Print the text token in A

LDA #225               \ Print recursive token 65 ("(Y/N)?")
JSR TT27

JSR TT217              \ Scan the keyboard until a key is pressed, and return
\ the key's ASCII code in A and X

ORA #%00100000         \ Set bit 5 in the value of the key pressed, which
\ converts it to lower case

BEQ TT218

LDA #'n'               \ Otherwise jump to TT26 to print "n" and return from
JMP TT26               \ the subroutine using a tail call (so all other
\ responses apart from "y" indicate a no)

.TT218

JSR TT26               \ Print the character in A, i.e. print "y"

SEC                    \ Set the C flag to indicate a "yes" response

RTS
}

Name: TT16                                            [View individually]
Type: Subroutine
Category: Charts
Summary: Move the crosshairs on a chart

Move the chart crosshairs by the amount in X and Y.

Arguments:

X                    The amount to move the crosshairs in the x-axis

Y                    The amount to move the crosshairs in the y-axis

.TT16
{
TXA                    \ Push the change in X onto the stack (let's call this
PHA                    \ the x-delta)

DEY                    \ Negate the change in Y and push it onto the stack
TYA                    \ (let's call this the y-delta)
EOR #255
PHA

JSR WSCAN              \ Call WSCAN to wait for the vertical sync, so the whole
\ screen gets drawn and we can move the crosshairs with
\ no screen flicker

JSR TT103              \ Draw small crosshairs at coordinates (QQ9, QQ10),
\ which will erase the crosshairs currently there

PLA                    \ Store the y-delta in QQ19+3 and fetch the current
STA QQ19+3             \ y-coordinate of the crosshairs from QQ10 into A, ready
LDA QQ10               \ for the call to TT123

JSR TT123              \ Call TT123 to move the selected system's galactic
\ y-coordinate by the y-delta, putting the new value in
\ QQ19+4

LDA QQ19+4             \ Store the updated y-coordinate in QQ10 (the current
STA QQ10               \ y-coordinate of the crosshairs)

STA QQ19+1             \ This instruction has no effect, as QQ19+1 is
\ overwritten below, both in TT103 and TT105

PLA                    \ Store the x-delta in QQ19+3 and fetch the current
STA QQ19+3             \ x-coordinate of the crosshairs from QQ10 into A, ready
LDA QQ9                \ for the call to TT123

JSR TT123              \ Call TT123 to move the selected system's galactic
\ x-coordinate by the x-delta, putting the new value in
\ QQ19+4

LDA QQ19+4             \ Store the updated x-coordinate in QQ9 (the current
STA QQ9                \ x-coordinate of the crosshairs)

STA QQ19               \ This instruction has no effect, as QQ19 is overwritten
\ below, both in TT103 and TT105

\ Now we've updated the coordinates of the crosshairs,
\ fall through into TT103 to redraw them at their new
\ location
}

Name: TT103                                           [View individually]
Type: Subroutine
Category: Charts
Summary: Draw a small set of crosshairs on a chart

Draw a small set of crosshairs on a galactic chart at the coordinates in
(QQ9, QQ10).

.TT103
{
LDA QQ11               \ If this is a space view, return from the subroutine
BEQ TT180              \ (as TT180 contains an RTS), as there are no moveable
\ crosshairs in space

BMI TT105              \ If this is the Short-range Chart screen, jump to TT105

LDA QQ9                \ Store the crosshairs x-coordinate in QQ19
STA QQ19

LDA QQ10               \ Halve the crosshairs y-coordinate and store it in QQ19
LSR A                  \ (we halve it because the Long-range Chart is half as
STA QQ19+1             \ high as it is wide)

LDA #4                 \ Set QQ19+2 to 4 denote crosshairs of size 4
STA QQ19+2

JMP TT15               \ Jump to TT15 to draw crosshairs of size 4 at the
\ crosshairs coordinates, returning from the subroutine
\ using a tail call
}

Name: TT123                                           [View individually]
Type: Subroutine
Category: Charts
Summary: Move galactic coordinates by a signed delta

Move an 8-bit galactic coordinate by a certain distance in either direction
(i.e. a signed 8-bit delta), but only if it doesn't cause the coordinate to
overflow. The coordinate is in a single axis, so it's either an x-coordinate
or a y-coordinate.

Arguments:

A                    The galactic coordinate to update

QQ19+3               The delta (can be positive or negative)

Returns:

QQ19+4               The updated coordinate after moving by the delta (this
will be the same as A if moving by the delta overflows)

Other entry points:

TT180                Contains an RTS

.TT123
{
STA QQ19+4             \ Store the original coordinate in temporary storage at
\ QQ19+4

CLC                    \ Set A = A + QQ19+3, so A now contains the original
ADC QQ19+3             \ coordinate, moved by the delta

BMI TT124

BCC TT125              \ If the C flag is clear, then the above addition didn't

RTS                    \ Otherwise the C flag is set and the above addition
\ overflowed, so do not update the return value

.TT124

BCC TT180              \ If the C flag is clear, then because the delta is
\ negative, this indicates the addition (which is
\ TT180 to return from the subroutine without updating
\ the return value

.TT125

STA QQ19+4             \ Store the updated coordinate in QQ19+4

.^TT180

RTS                    \ Return from the subroutine
}

Name: TT105                                           [View individually]
Type: Subroutine
Category: Charts
Summary: Draw crosshairs on the Short-range Chart, with clipping

Check whether the crosshairs are close enough to the current system to appear
on the Short-range Chart, and if so, draw them.

.TT105
{
LDA QQ9                \ Set A = QQ9 - QQ0, the horizontal distance between the
SEC                    \ crosshairs (QQ9) and the current system (QQ0)
SBC QQ0

CMP #38                \ If the horizontal distance in A is < 38, then the
BCC TT179              \ crosshairs are close enough to the current system to
\ check the vertical distance

CMP #230               \ If the horizontal distance in A is < -26, then the
BCC TT180              \ crosshairs are too far from the current system to
\ return from the subroutine (as TT180 contains an RTS)

.TT179

ASL A                  \ Set QQ19 = 104 + A * 4
ASL A                  \
CLC                    \ 104 is the x-coordinate of the centre of the chart,
ADC #104               \ so this sets QQ19 to the screen pixel x-coordinate
STA QQ19               \ of the crosshairs

LDA QQ10               \ Set A = QQ10 - QQ1, the vertical distance between the
SEC                    \ crosshairs (QQ10) and the current system (QQ1)
SBC QQ1

CMP #38                \ If the vertical distance in A is < 38, then the
BCC P%+6               \ crosshairs are close enough to the current system to
\ appear in the Short-range Chart, so skip the next two
\ instructions

CMP #220               \ If the horizontal distance in A is < -36, then the
BCC TT180              \ crosshairs are too far from the current system to
\ return from the subroutine (as TT180 contains an RTS)

ASL A                  \ Set QQ19+1 = 90 + A * 2
CLC                    \
ADC #90                \ 90 is the y-coordinate of the centre of the chart,
STA QQ19+1             \ so this sets QQ19+1 to the screen pixel x-coordinate
\ of the crosshairs

LDA #8                 \ Set QQ19+2 to 8 denote crosshairs of size 8
STA QQ19+2

JMP TT15               \ Jump to TT15 to draw crosshairs of size 8 at the
\ crosshairs coordinates, returning from the subroutine
\ using a tail call
}

Name: TT23                                            [View individually]
Type: Subroutine
Category: Charts
Summary: Show the Short-range Chart (red key f5)

.TT23
{
LDA #128               \ Clear the top part of the screen, draw a white border,
JSR TT66               \ and set the current view type in QQ11 to 128 (Short-
\ range Chart)

LDA #7                 \ Move the text cursor to column 7
STA XC

LDA #190               \ Print recursive token 30 ("SHORT RANGE CHART") and
JSR NLIN3              \ draw a horizontal line at pixel row 19 to box in the
\ title

JSR TT14               \ Call TT14 to draw a circle with crosshairs at the
\ current system's galactic coordinates

JSR TT103              \ Draw small crosshairs at coordinates (QQ9, QQ10),
\ i.e. at the selected system

JSR TT81               \ Set the seeds in QQ15 to those of system 0 in the
\ current galaxy (i.e. copy the seeds from QQ21 to QQ15)

LDA #0                 \ Set A = 0, which we'll use below to zero out the INWK
\ workspace

STA XX20               \ We're about to start working our way through each of
\ the galaxy's systems, so set up a counter in XX20 for
\ each system, starting at 0 and looping through to 255

LDX #24                \ First, though, we need to zero out the 25 bytes at
\ INWK so we can use them to work out which systems have
\ room for a label, so set a counter in X for 25 bytes

.EE3

STA INWK,X             \ Set the X-th byte of INWK to zero

DEX                    \ Decrement the counter

BPL EE3                \ Loop back to EE3 for the next byte until we've zeroed
\ all 25 bytes

\ We now loop through every single system in the galaxy
\ and check the distance from the current system whose
\ coordinates are in (QQ0, QQ1). We get the galactic
\ coordinates of each system from the system's seeds,
\ like this:
\
\   x = w1_hi (which is stored in QQ15+3)
\   y = w0_hi (which is stored in QQ15+1)
\
\ so the following loops through each system in the
\ galaxy in turn and calculates the distance between
\ (QQ0, QQ1) and (w1_hi, w0_hi) to find the closest one

.TT182

LDA QQ15+3             \ Set A = w1_hi - QQ0, the horizontal distance between
SEC                    \ (w1_hi, w0_hi) and (QQ0, QQ1)
SBC QQ0

BCS TT184              \ If a borrow didn't occur, i.e. w1_hi >= QQ0, then the
\ following two instructions

EOR #&FF               \ Otherwise negate the result in A, so A is always
ADC #1                 \ positive (i.e. A = |w1_hi - QQ0|)

.TT184

CMP #20                \ If the horizontal distance in A is >= 20, then this
BCS TT187              \ system is too far away from the current system to
\ move on to the next system

LDA QQ15+1             \ Set A = w0_hi - QQ1, the vertical distance between
SEC                    \ (w1_hi, w0_hi) and (QQ0, QQ1)
SBC QQ1

BCS TT186              \ If a borrow didn't occur, i.e. w0_hi >= QQ1, then the
\ following two instructions

EOR #&FF               \ Otherwise negate the result in A, so A is always
ADC #1                 \ positive (i.e. A = |w0_hi - QQ1|)

.TT186

CMP #38                \ If the vertical distance in A is >= 38, then this
BCS TT187              \ system is too far away from the current system to
\ move on to the next system

\ This system should be shown on the Short-range Chart,
\ so now we need to work out where the label should go,
\ and set up the various variables we need to draw the
\ system's filled circle on the chart

LDA QQ15+3             \ Set A = w1_hi - QQ0, the horizontal distance between
SEC                    \ this system and the current system, where |A| < 20.
SBC QQ0                \ Let's call this the x-delta, as it's the horizontal
\ difference between the current system at the centre of
\ the chart, and this system (and this time we keep the
\ sign of A, so it can be negative if it's to the left
\ of the chart's centre, or positive if it's to the
\ right)

ASL A                  \ Set XX12 = 104 + x-delta * 4
ASL A                  \
ADC #104               \ 104 is the x-coordinate of the centre of the chart,
STA XX12               \ so this sets XX12 to the centre 104 +/- 76, the pixel
\ x-coordinate of this system

LSR A                  \ Move the text cursor to column x-delta / 2 + 1
LSR A                  \ which will be in the range 1-10
LSR A
STA XC
INC XC

LDA QQ15+1             \ Set A = w0_hi - QQ1, the vertical distance between
SEC                    \ this system and the current system, where |A| < 38.
SBC QQ1                \ Let's call this the y-delta, as it's the vertical
\ difference between the current system at the centre of
\ the chart, and this system (and this time we keep the
\ sign of A, so it can be negative if it's above the
\ chart's centre, or positive if it's below)

ASL A                  \ Set K4 = 90 + y-delta * 2
STA K4                 \ 90 is the y-coordinate of the centre of the chart,
\ so this sets K4 to the centre 90 +/- 74, the pixel
\ y-coordinate of this system

LSR A                  \ Set Y = K4 / 8, so Y contains the number of the text
LSR A                  \ row that contains this system
LSR A
TAY

\ Now to see if there is room for this system's label.
\ Ideally we would print the system name on the same
\ text row as the system, but we only want to print one
\ label per row, to prevent overlap, so now we check
\ this system's row, and if that's already occupied,
\ the row above, and if that's already occupied, the
\ row below... and if that's already occupied, we give
\ up and don't print a label for this system

LDX INWK,Y             \ If the value in INWK+Y is 0 (i.e. the text row
BEQ EE4                \ containing this system does not already have another
\ system's label on this row

INY                    \ If the value in INWK+Y+1 is 0 (i.e. the text row below
LDX INWK,Y             \ the one containing this system does not already have
BEQ EE4                \ another system's label on it), jump to EE4 to store
\ this system's label on this row

DEY                    \ If the value in INWK+Y-1 is 0 (i.e. the text row above
DEY                    \ the one containing this system does not already have
LDX INWK,Y             \ another system's label on it), fall through into to
BNE ee1                \ EE4 to store this system's label on this row,
\ this system (as there simply isn't room)

.EE4

STY YC                 \ Now to print the label, so move the text cursor to row
\ Y (which contains the row where we can print this
\ system's label)

CPY #3                 \ If Y < 3, then the label would clash with the chart
BCC TT187              \ title, so jump to TT187 to skip printing the label

DEX                    \ We entered the EE4 routine with X = 0, so this stores
STX INWK,Y             \ &FF in INWK+Y, to denote that this row is now occupied
\ so we don't try to print another system's label on
\ this row

LDA #%10000000         \ Set bit 7 of QQ17 to switch to Sentence Case
STA QQ17

JSR cpl                \ Call cpl to print out the system name for the seeds
\ in QQ15 (which now contains the seeds for the current
\ system)

.ee1

LDA #0                 \ Now to plot the star, so set the high bytes of K, K3
STA K3+1               \ and K4 to 0
STA K4+1
STA K+1

LDA XX12               \ Set the low byte of K3 to XX12, the pixel x-coordinate
STA K3                 \ of this system

LDA QQ15+5             \ Fetch w2_hi for this system from QQ15+5, extract bit 0
AND #1                 \ and add 2 to get the size of the star, which we store
ADC #2                 \ in K. This will be either 2, 3 or 4, depending on the
STA K                  \ value of bit 0, and whether the C flag is set (which
\ will vary depending on what happens in the above call
\ to cpl). Incidentally, the planet's average radius
\ also uses w2_hi, bits 0-3 to be precise, but that
\ doesn't mean the two sizes affect each other

\ We now have the following:
\
\   K(1 0)  = radius of star (2, 3 or 4)
\
\   K3(1 0) = pixel x-coordinate of system
\
\   K4(1 0) = pixel y-coordinate of system
\
\ which we can now pass to the SUN routine to draw a
\ small "sun" on the Short-range Chart for this system

JSR FLFLLS             \ Call FLFLLS to reset the LSO block

JSR SUN                \ Call SUN to plot a sun with radius K at pixel
\ coordinate (K3, K4)

JSR FLFLLS             \ Call FLFLLS to reset the LSO block

.TT187

JSR TT20               \ We want to move on to the next system, so call TT20
\ to twist the three 16-bit seeds in QQ15

INC XX20               \ Increment the counter

BEQ TT111-1            \ If X = 0 then we have done all 256 systems, so return
\ from the subroutine (as TT111-1 contains an RTS)

JMP TT182              \ Otherwise jump back up to TT182 to process the next
\ system
}

Name: TT81                                            [View individually]
Type: Subroutine
Category: Universe
Summary: Set the selected system's seeds to those of system 0

Copy the three 16-bit seeds for the current galaxy's system 0 (QQ21) into the
seeds for the selected system (QQ15) - in other words, set the selected
system's seeds to those of system 0.

.TT81
{
LDX #5                 \ Set up a counter in X to copy six bytes (for three
\ 16-bit numbers)

LDA QQ21,X             \ Copy the X-th byte in QQ21 to the X-th byte in QQ15
STA QQ15,X

DEX                    \ Decrement the counter

BPL TT81+2             \ Loop back up to the LDA instruction if we still have
\ more bytes to copy

RTS                    \ Return from the subroutine
}

Name: TT111                                           [View individually]
Type: Subroutine
Category: Universe
Summary: Set the current system to the nearest system to a point

Given a set of galactic coordinates in (QQ9, QQ10), find the nearest system
to this point in the galaxy, and set this as the currently selected system.

Arguments:

QQ9                  The x-coordinate near which we want to find a system

QQ10                 The y-coordinate near which we want to find a system

Returns:

QQ8(1 0)             The distance from the current system to the nearest
system to the original coordinates

QQ9                  The x-coordinate of the nearest system to the original
coordinates

QQ10                 The y-coordinate of the nearest system to the original
coordinates

QQ15 to QQ15+5       The three 16-bit seeds of the nearest system to the
original coordinates

Other entry points:

TT111-1              Contains an RTS

.TT111
{
JSR TT81               \ Set the seeds in QQ15 to those of system 0 in the
\ current galaxy (i.e. copy the seeds from QQ21 to QQ15)

\ We now loop through every single system in the galaxy
\ and check the distance from (QQ9, QQ10). We get the
\ galactic coordinates of each system from the system's
\ seeds, like this:
\
\   x = w1_hi (which is stored in QQ15+3)
\   y = w0_hi (which is stored in QQ15+1)
\
\ so the following loops through each system in the
\ galaxy in turn and calculates the distance between
\ (QQ9, QQ10) and (w1_hi, w0_hi) to find the closest one

LDY #127               \ Set Y = T = 127 to hold the shortest distance we've
STY T                  \ found so far, which we initially set to half the
\ distance across the galaxy, or 127, as our coordinate
\ system ranges from (0,0) to (255, 255)

LDA #0                 \ Set A = U = 0 to act as a counter for each system in
STA U                  \ the current galaxy, which we start at system 0 and
\ loop through to 255, the last system

.TT130

LDA QQ15+3             \ Set A = w1_hi - QQ9, the horizontal distance between
SEC                    \ (w1_hi, w0_hi) and (QQ9, QQ10)
SBC QQ9

BCS TT132              \ If a borrow didn't occur, i.e. w1_hi >= QQ9, then the
\ following two instructions

EOR #&FF               \ Otherwise negate the result in A, so A is always
ADC #1                 \ positive (i.e. A = |w1_hi - QQ9|)

.TT132

LSR A                  \ Set S = A / 2
STA S                  \       = |w1_hi - QQ9| / 2

LDA QQ15+1             \ Set A = w0_hi - QQ10, the vertical distance between
SEC                    \ (w1_hi, w0_hi) and (QQ9, QQ10)
SBC QQ10

BCS TT134              \ If a borrow didn't occur, i.e. w0_hi >= QQ10, then the
\ following two instructions

EOR #&FF               \ Otherwise negate the result in A, so A is always
ADC #1                 \ positive (i.e. A = |w0_hi - QQ10|)

.TT134

LSR A                  \ Set A = S + A / 2
CLC                    \       = |w1_hi - QQ9| / 2 + |w0_hi - QQ10| / 2
\ So A now contains the sum of the horizontal and
\ vertical distances, both divided by 2 so the result
\ fits into one byte, and although this doesn't contain
\ the actual distance between the systems, it's a good
\ enough approximation to use for comparing distances

CMP T                  \ If A >= T, then this system's distance is bigger than
BCS TT135              \ our "minimum distance so far" stored in T, so it's no
\ closer than the systems we have already found, so

STA T                  \ This system is the closest to (QQ9, QQ10) so far, so
\ update T with the new "distance" approximation

LDX #5                 \ As this system is the closest we have found yet, we
\ want to store the system's seeds in case it ends up
\ being the closest of all, so we set up a counter in X
\ to copy six bytes (for three 16-bit numbers)

.TT136

LDA QQ15,X             \ Copy the X-th byte in QQ15 to the X-th byte in QQ19,
STA QQ19,X             \ where QQ15 contains the seeds for the system we just
\ found to be the closest so far, and QQ19 is temporary
\ storage

DEX                    \ Decrement the counter

BPL TT136              \ Loop back to TT136 if we still have more bytes to
\ copy

.TT135

JSR TT20               \ We want to move on to the next system, so call TT20
\ to twist the three 16-bit seeds in QQ15

INC U                  \ Increment the system counter in U

BNE TT130              \ If U > 0 then we haven't done all 256 systems yet, so
\ loop back up to TT130

\ We have now finished checking all the systems in the
\ galaxy, and the seeds for the closest system are in
\ QQ19, so now we want to copy these seeds to QQ15,
\ to set the selected system to this closest system

LDX #5                 \ So we set up a counter in X to copy six bytes (for
\ three 16-bit numbers)

.TT137

LDA QQ19,X             \ Copy the X-th byte in QQ19 to the X-th byte in QQ15,
STA QQ15,X

DEX                    \ Decrement the counter

BPL TT137              \ Loop back to TT137 if we still have more bytes to
\ copy

LDA QQ15+1             \ The y-coordinate of the system described by the seeds
STA QQ10               \ in QQ15 is in QQ15+1 (w0_hi), so we copy this to QQ10
\ as this is where we store the selected system's
\ y-coordinate

LDA QQ15+3             \ The x-coordinate of the system described by the seeds
STA QQ9                \ in QQ15 is in QQ15+3 (w1_hi), so we copy this to QQ9
\ as this is where we store the selected system's
\ x-coordinate

\ We have now found the closest system to (QQ9, QQ10)
\ and have set it as the selected system, so now we
\ need to work out the distance between the selected
\ system and the current system

SEC                    \ Set A = QQ9 - QQ0, the horizontal distance between
SBC QQ0                \ the selected system's x-coordinate (QQ9) and the
\ current system's x-coordinate (QQ0)

BCS TT139              \ If a borrow didn't occur, i.e. QQ9 >= QQ0, then the
\ following two instructions

EOR #&FF               \ Otherwise negate the result in A, so A is always
ADC #1                 \ positive (i.e. A = |QQ9 - QQ0|)

\ A now contains the difference between the two
\ systems' x-coordinates, with the sign removed. We
\ will refer to this as the x-delta ("delta" means
\ change or difference in maths)

.TT139

JSR SQUA2              \ Set (A P) = A * A
\           = |QQ9 - QQ0| ^ 2
\           = x_delta ^ 2

STA K+1                \ Store (A P) in K(1 0)
LDA P
STA K

LDA QQ10               \ Set A = QQ10 - QQ1, the vertical distance between the
SEC                    \ selected system's y-coordinate (QQ10) and the current
SBC QQ1                \ system's y-coordinate (QQ1)

BCS TT141              \ If a borrow didn't occur, i.e. QQ10 >= QQ1, then the
\ following two instructions

EOR #&FF               \ Otherwise negate the result in A, so A is always
ADC #1                 \ positive (i.e. A = |QQ10 - QQ1|)

.TT141

LSR A                  \ Set A = A / 2

\ A now contains the difference between the two
\ systems' y-coordinates, with the sign removed, and
\ halved. We halve the value because the galaxy in
\ in Elite is rectangular rather than square, and is
\ twice as wide (x-axis) as it is high (y-axis), so to
\ get a distance that matches the shape of the
\ long-range galaxy chart, we need to halve the
\ distance between the vertical y-coordinates. We will
\ refer to this as the y-delta

JSR SQUA2              \ Set (A P) = A * A
\           = (|QQ10 - QQ1| / 2) ^ 2
\           = y_delta ^ 2

\ By this point we have the following results:
\
\   K(1 0) = x_delta ^ 2
\    (A P) = y_delta ^ 2
\
\ so to find the distance between the two points, we
\ can use Pythagoras - so first we need to add the two
\ results together, and then take the square root

PHA                    \ Store the high byte of the y-axis value on the stack,
\ so we can use A for another purpose

LDA P                  \ Set Q = P + K, which adds the low bytes of the two
CLC                    \ calculated values
STA Q

PLA                    \ Restore the high byte of the y-axis value from the
\ stack into A again

ADC K+1                \ Set R = A + K+1, which adds the high bytes of the two
STA R                  \ calculated values, so we now have:
\
\   (R Q) = K(1 0) + (A P)
\         = (x_delta ^ 2) + (y_delta ^ 2)

JSR LL5                \ Set Q = SQRT(R Q), so Q now contains the distance
\ between the two systems, in terms of coordinates

\ We now store the distance to the selected system * 4
\ in the two-byte location QQ8, by taking (0 Q) and
\ shifting it left twice, storing it in (QQ8+1 QQ8)

LDA Q                  \ First we shift the low byte left by setting
ASL A                  \ A = Q * 2, with bit 7 of A going into the C flag

LDX #0                 \ Now we set the high byte in QQ8+1 to 0 and rotate
STX QQ8+1              \ the C flag into bit 0 of QQ8+1
ROL QQ8+1

ASL A                  \ And then we repeat the shift left of (QQ8+1 A)
ROL QQ8+1

STA QQ8                \ And store A in the low byte, QQ8, so QQ8(1 0) now
\ contains Q * 4. Given that the width of the galaxy is
\ 256 in coordinate terms, the width of the galaxy
\ would be 1024 in the units we store in QQ8

JMP TT24               \ Call TT24 to calculate system data from the seeds in
\ QQ15 and store them in the relevant locations, so our
\ new selected system is fully set up, and return from
\ the subroutine using a tail call
}

Name: hy6                                             [View individually]
Type: Subroutine
Category: Flight
Summary: Print a message to say no hyperspacing inside the station

Print "Docked" at the bottom of the screen to indicate we can't hyperspace
when docked.

.hy6
{
JSR CLYNS              \ Clear the bottom three text rows of the upper screen,
\ and move the text cursor to column 1 on row 21, i.e.
\ the start of the top row of the three bottom rows

LDA #15                \ Move the text cursor to column 15 (the middle of the
STA XC                 \ screen), setting A to 15 at the same time for the
\ following call to TT27

JMP TT27               \ Print recursive token 129 ("{switch to sentence case}
\ DOCKED") and return from the subroutine using a tail
\ call
}

Name: hyp                                             [View individually]
Type: Subroutine
Category: Flight
Summary: Start the hyperspace process

Called when "H" or CTRL-H is pressed during flight. Checks the following:

* We are in space

* We are not already in a hyperspace countdown

If CTRL is being held down, we jump to Ghy to engage the galactic hyperdrive,
otherwise we check that:

* The selected system is not the current system

* We have enough fuel to make the jump

and if all the pre-jump checks are passed, we print the destination on-screen
and start the countdown.

.hyp
{
LDA QQ12               \ If we are docked (QQ12 = &FF) then jump to hy6 to
BNE hy6                \ print an error message and return from the subroutine
\ using a tail call (as we can't hyperspace when docked)

LDA QQ22+1             \ Fetch QQ22+1, which contains the number that's shown
\ on-screen during hyperspace countdown

BNE zZ+1               \ If it is non-zero, return from the subroutine (as zZ+1
\ contains an RTS), as there is already a countdown in
\ progress

JSR CTRL               \ Scan the keyboard to see if CTRL is currently pressed

BMI Ghy                \ If it is, then the galactic hyperdrive has been

JSR hm                 \ Set the system closest to galactic coordinates (QQ9,
\ QQ10) as the selected system

LDA QQ8                \ If both bytes of the distance to the selected system
ORA QQ8+1              \ in QQ8 are zero, return from the subroutine (as zZ+1
BEQ zZ+1               \ contains an RTS), as the selected system is the
\ current system

LDA #7                 \ Move the text cursor to column 7, row 23 (in the
STA XC                 \ middle of the bottom text row)
LDA #23
STA YC

LDA #0                 \ Set QQ17 = 0 to switch to ALL CAPS
STA QQ17

LDA #189               \ Print recursive token 29 ("HYPERSPACE ")
JSR TT27

LDA QQ8+1              \ If the high byte of the distance to the selected
BNE TT147              \ system in QQ8 is > 0, then it is definitely too far to
\ jump (as our maximum range is 7.0 light years, or a
\ value of 70 in QQ8(1 0), so jump to TT147 to print
\ "RANGE?" and return from the subroutine using a tail
\ call

LDA QQ14               \ Fetch our current fuel level from Q114 into A

CMP QQ8                \ If our fuel reserves are less than the distance to the
BCC TT147              \ selected system, then we don't have enough fuel for
\ return from the subroutine using a tail call

LDA #'-'               \ Print a hyphen
JSR TT27

JSR cpl                \ Call cpl to print the name of the selected system

\ Fall through into wW to start the hyperspace
\ countdown
}

Name: wW                                              [View individually]
Type: Subroutine
Category: Flight
Summary: Start a hyperspace countdown

Start the hyperspace countdown (for both inter-system hyperspace and the
galactic hyperdrive).

.wW
{
LDA #15                \ The hyperspace countdown starts from 15, so set A to
\ to 15 so we can set the two hyperspace counters

STA QQ22+1             \ Set the number in QQ22+1 to 15, which is the number
\ that's shown on-screen during the hyperspace countdown

STA QQ22               \ Set the number in QQ22 to 15, which is the internal
\ counter that counts down by 1 each iteration of the
\ main game loop, and each time it reaches zero, the
\ on-screen counter gets decremented, and QQ22 gets set
\ to 5, so setting QQ22 to 15 here makes the first tick
\ of the hyperspace counter longer than subsequent ticks

TAX                    \ Print the 8-bit number in X (i.e. 15) at text location
JMP ee3                \ (0, 1), padded to 5 digits, so it appears in the top
\ left corner of the screen, and return from the
\ subroutine using a tail call

\hy5                    \ This instruction and the hy5 label are commented out
\RTS                    \ in the original - they can actually be found at the
\ end of the jmp routine below, so perhaps this is where
\ they were originally, but the authors realised they
\ could save a byte by using a tail call instead of an
\ RTS?
}

Name: Ghy                                             [View individually]
Type: Subroutine
Category: Flight
Summary: Perform a galactic hyperspace jump

Engage the galactic hyperdrive. Called from the hyp routine above if CTRL-H is
being pressed.

This routine also updates the galaxy seeds to point to the next galaxy. Using
a galactic hyperdrive rotates each seed byte to the left, rolling each byte
left within itself like this:

01234567 -> 12345670

to get the seeds for the next galaxy. So after 8 galactic jumps, the seeds
roll round to those of the first galaxy again.

We always arrive in a new galaxy at galactic coordinates (96, 96), and then
find the nearest system and set that as our location.

Other entry points:

zZ+1                 Contains an RTS

.Ghy
{
\JSR TT111              \ This instruction is commented out in the original
\ source, and appears in the text cassette code source
\ (ELITED.TXT) but not in the BASIC source file on the
\ source disc (ELITED). It finds the closest system to
\ coordinates (QQ9, QQ10)

LDX GHYP               \ Fetch GHYP, which tells us whether we own a galactic
BEQ hy5                \ hyperdrive, and if it is zero, which means we don't,
\ return from the subroutine (as hy5 contains an RTS)

INX                    \ We own a galactic hyperdrive, so X is &FF, so this
\ instruction sets X = 0

STX QQ8                \ Set the distance to the selected system in (QQ8+1 QQ8)
STX QQ8+1              \ to 0

STX GHYP               \ The galactic hyperdrive is a one-use item, so set GHYP
\ to 0 so we no longer have one fitted

STX FIST               \ Changing galaxy also clears our criminal record, so
\ set our legal status in FIST to 0 ("clean")

JSR wW                 \ Call wW to start the hyperspace countdown

LDX #5                 \ To move galaxy, we rotate the galaxy's seeds left, so
\ set a counter in X for the 6 seed bytes

INC GCNT               \ Increment the current galaxy number in GCNT

LDA GCNT               \ Set GCNT = GCNT mod 8, so we jump from galaxy 7 back
AND #7                 \ to galaxy 0 (shown in-game as going from galaxy 8 back
STA GCNT               \ to the starting point in galaxy 1)

.G1

LDA QQ21,X             \ Load the X-th seed byte into A

ASL A                  \ Set the C flag to bit 7 of the seed

ROL QQ21,X             \ Rotate the seed in memory, which will add bit 7 back
\ in as bit 0, so this rolls the seed around on itself

DEX                    \ Decrement the counter

BPL G1                 \ Loop back for the next seed byte, until we have
\ rotated them all

\JSR DORND              \ This instruction is commented out in the original
\ source, and would set A and X to random numbers, so
\ perhaps the original plan was to arrive in each new
\ galaxy in a random place?

.^zZ

LDA #&60               \ Set (QQ9, QQ10) to (96, 96), which is where we always
STA QQ9                \ arrive in a new galaxy (the selected system will be
STA QQ10               \ set to the nearest actual system later on)

JSR TT110              \ Call TT110 to show the front space view

LDA #116               \ Print recursive token 116 (GALACTIC HYPERSPACE ")
JSR MESS               \ as an in-flight message

\ Fall through into jmp to set the system to the
\ current system and return from the subroutine there
}

Name: jmp                                             [View individually]
Type: Subroutine
Category: Universe
Summary: Set the current system to the selected system

Returns:

(QQ0, QQ1)           The galactic coordinates of the new system

Other entry points:

hy5                  Contains an RTS

.jmp
{
LDA QQ9                \ Set the current system's galactic x-coordinate to the
STA QQ0                \ x-coordinate of the selected system

LDA QQ10               \ Set the current system's galactic y-coordinate to the
STA QQ1                \ y-coordinate of the selected system

.^hy5

RTS                    \ Return from the subroutine
}

Name: ee3                                             [View individually]
Type: Subroutine
Category: Text
Summary: Print the hyperspace countdown in the top-left of the screen

Print the 8-bit number in X at text location (0, 1). Print the number to
5 digits, left-padding with spaces for numbers with fewer than 3 digits (so
numbers < 10000 are right-aligned), with no decimal point.

Arguments:

X                    The number to print

.ee3
{
LDY #1                 \ Set YC = 1 (first row)
STY YC

DEY                    \ Set XC = 0 (first character)
STY XC

\ Fall through into pr6 to print X to 5 digits
}

Name: pr6                                             [View individually]
Type: Subroutine
Category: Text
Summary: Print 16-bit number, left-padded to 5 digits, no point

Print the 16-bit number in (Y X) to 5 digits, left-padding with spaces for
numbers with fewer than 3 digits (so numbers < 10000 are right-aligned),
with no decimal point.

Arguments:

X                    The low byte of the number to print

Y                    The high byte of the number to print

.pr6
{
CLC                    \ Do not display a decimal point when printing

\ Fall through into pr5 to print X to 5 digits
}

Name: pr5                                             [View individually]
Type: Subroutine
Category: Text
Summary: Print a 16-bit number, left-padded to 5 digits, and optional point

Print the 16-bit number in (Y X) to 5 digits, left-padding with spaces for
numbers with fewer than 3 digits (so numbers < 10000 are right-aligned).
Optionally include a decimal point.

Arguments:

X                    The low byte of the number to print

Y                    The high byte of the number to print

C flag               If set, include a decimal point

.pr5
{
LDA #5                 \ Set the number of digits to print to 5

JMP TT11               \ Call TT11 to print (Y X) to 5 digits and return from
\ the subroutine using a tail call
}

Name: TT147                                           [View individually]
Type: Subroutine
Category: Text
Summary: Print an error when a system is out of hyperspace range

Print "RANGE?" for when the hyperspace distance is too far

.TT147
{
LDA #202               \ Load A with token 42 ("RANGE") and fall through into
\ prq to print it, followed by a question mark
}

Name: prq                                             [View individually]
Type: Subroutine
Category: Text
Summary: Print a text token followed by a question mark

Arguments:

A                    The text token to be printed

.prq
{
JSR TT27               \ Print the text token in A

LDA #'?'               \ Print a question mark and return from the
JMP TT27               \ subroutine using a tail call
}

Name: TT151                                           [View individually]
Type: Subroutine
Category: Market
Summary: Print the name, price and availability of a market item

Arguments:

A                    The number of the market item to print, 0-16 (see QQ23
for details of item numbers)

Results:

QQ19+1               Byte #1 from the market prices table for this item

QQ24                 The item's price / 4

QQ25                 The item's availability

.TT151
{
PHA                    \ Store the item number on the stack and in QQ14+4
STA QQ19+4

ASL A                  \ Store the item number * 4 in QQ19, so this will act as
ASL A                  \ an index into the market prices table at QQ23 for this
STA QQ19               \ item (as there are four bytes per item in the table)

LDA #1                 \ Set the text cursor to column 1, for the item's name
STA XC

PLA                    \ Restore the item number

ADC #208               \ Print recursive token 48 + A, which will be in the
JSR TT27               \ range 48 ("FOOD") to 64 ("ALIEN ITEMS"), so this
\ prints the item's name

LDA #14                \ Set the text cursor to column 14, for the price
STA XC

LDX QQ19               \ Fetch byte #1 from the market prices table (units and
LDA QQ23+1,X           \ economic_factor) for this item and store in QQ19+1
STA QQ19+1

LDA QQ26               \ Fetch the random number for this system visit and
AND QQ23+3,X           \ AND with byte #3 from the market prices table (mask)
\ to give:
\
\   A = random AND mask

CLC                    \ Add byte #0 from the market prices table (base_price),
ADC QQ23,X             \ so we now have:
STA QQ24               \
\   A = base_price + (random AND mask)

JSR TT152              \ Call TT152 to print the item's unit ("t", "kg" or
\ "g"), padded to a width of two characters

JSR var                \ Call var to set QQ19+3 = economy * |economic_factor|
\ (and set the availability of Alien Items to 0)

LDA QQ19+1             \ Fetch the byte #1 that we stored above and jump to
BMI TT155              \ TT155 if it is negative (i.e. if the economic_factor
\ is negative)

LDA QQ24               \ Set A = QQ24 + QQ19+3
\       = base_price + (random AND mask)
\         + (economy * |economic_factor|)
\
\ which is the result we want, as the economic_factor
\ is positive

JMP TT156              \ Jump to TT156 to multiply the result by 4

.TT155

LDA QQ24               \ Set A = QQ24 - QQ19+3
SEC                    \
SBC QQ19+3             \       = base_price + (random AND mask)
\         - (economy * |economic_factor|)
\
\ which is the result we want, as economic_factor
\ is negative

.TT156

STA QQ24               \ Store the result in QQ24 and P
STA P

LDA #0                 \ Set A = 0 and call GC2 to calculate (Y X) = (A P) * 4,
JSR GC2                \ which is the same as (Y X) = P * 4 because A = 0

SEC                    \ We now have our final price, * 10, so we can call pr5
JSR pr5                \ to print (Y X) to 5 digits, including a decimal
\ point, as the C flag is set

LDY QQ19+4             \ We now move on to availability, so fetch the market
\ item number that we stored in QQ19+4 at the start

LDA #5                 \ Set A to 5 so we can print the availability to 5

LDX AVL,Y              \ Set X to the item's availability, which is given in
\ the AVL table

STX QQ25               \ Store the availability in QQ25

CLC                    \ Clear the C flag

BEQ TT172              \ If none are available, jump to TT172 to print a tab
\ and a "-"

JSR pr2+2              \ Otherwise print the 8-bit number in X to 5 digits,
\ right-aligned with spaces. This works because we set
\ A to 5 above, and we jump into the pr2 routine just
\ after the first instruction, which would normally
\ set the number of digits to 3

JMP TT152              \ Print the unit ("t", "kg" or "g") for the market item,
\ with a following space if required to make it two
\ characters long

.TT172

LDA XC                 \ Move the text cursor in XC to the right by 4 columns,
ADC #4                 \ so the cursor is where the last digit would be if we
STA XC                 \ were printing a 5-digit availability number

LDA #'-'               \ Print a "-" character by jumping to TT162+2, which
BNE TT162+2            \ contains JMP TT27 (this BNE is effectively a JMP as A
\ will never be zero), and return from the subroutine
\ using a tail call
}

Name: TT152                                           [View individually]
Type: Subroutine
Category: Market
Summary: Print the unit ("t", "kg" or "g") for a market item

Print the unit ("t", "kg" or "g") for the market item whose byte #1 from the
market prices table is in QQ19+1, right-padded with spaces to a width of two
characters (so that's "t ", "kg" or "g ").

.TT152
{
LDA QQ19+1             \ Fetch the economic_factor from QQ19+1

AND #96                \ If bits 5 and 6 are both clear, jump to TT160 to
BEQ TT160              \ print "t" for tonne, followed by a space, and return
\ from the subroutine using a tail call

CMP #32                \ If bit 5 is set, jump to TT161 to print "kg" for
BEQ TT161              \ kilograms, and return from the subroutine using a tail
\ call

JSR TT16a              \ Otherwise call TT16a to print "g" for grams, and fall
\ through into TT162 to print a space and return from
\ the subroutine
}

Name: TT162                                           [View individually]
Type: Subroutine
Category: Text
Summary: Print a space

Other entry points:

.TT162
{
LDA #' '               \ Load a space character into A

JMP TT27               \ Print the text token in A and return from the
\ subroutine using a tail call
}

Name: TT160                                           [View individually]
Type: Subroutine
Category: Market
Summary: Print "t" (for tonne) and a space

.TT160
{
LDA #'t'               \ Load a "t" character into A

JSR TT26               \ Print the character, using TT216 so that it doesn't
\ change the character case

BCC TT162              \ Jump to TT162 to print a space and return from the
\ subroutine using a tail call (this BCC is effectively
\ a JMP as the C flag is cleared by TT26)
}

Name: TT161                                           [View individually]
Type: Subroutine
Category: Market
Summary: Print "kg" (for kilograms)

.TT161
{
LDA #'k'               \ Load a "k" character into A

JSR TT26               \ Print the character, using TT216 so that it doesn't
\ change the character case, and fall through into
\ TT16a to print a "g" character
}

Name: TT16a                                           [View individually]
Type: Subroutine
Category: Market
Summary: Print "g" (for grams)

.TT16a
{
LDA #&67               \ Load a "k" character into A

JMP TT26               \ Print the character, using TT216 so that it doesn't
\ change the character case, and return from the
\ subroutine using a tail call
}

Name: TT163                                           [View individually]
Type: Subroutine
Category: Market
Summary: Print the headers for the table of market prices

Print the column headers for the prices table in the Buy Cargo and Market
Price screens.

.TT163
{
LDA #17                \ Move the text cursor in XC to column 17
STA XC

LDA #255               \ Print recursive token 95 token ("UNIT  QUANTITY
BNE TT162+2            \ {crlf} PRODUCT   UNIT PRICE FOR SALE{crlf}{lf}") by
\ jumping to TT162+2, which contains JMP TT27 (this BNE
\ is effectively a JMP as A will never be zero), and
\ return from the subroutine using a tail call
}

Name: TT167                                           [View individually]
Type: Subroutine
Category: Market
Summary: Show the Market Price screen (red key f7)

.TT167
{
LDA #16                \ Clear the top part of the screen, draw a white border,
JSR TT66               \ and set the current view type in QQ11 to 16 (Market
\ Price screen)

LDA #5                 \ Move the text cursor to column 4
STA XC

LDA #167               \ Print recursive token 7 token ("{current system name}
JSR NLIN3              \ MARKET PRICES") and draw a horizontal line at pixel
\ row 19 to box in the title

LDA #3                 \ Move the text cursor to row 3
STA YC

JSR TT163              \ Print the column headers for the prices table

LDA #0                 \ We're going to loop through all the available market
STA QQ29               \ items, so we set up a counter in QQ29 to denote the
\ current item and start it at 0

.TT168

LDX #%10000000         \ Set bit 7 of QQ17 to switch to Sentence Case, with the
STX QQ17               \ next letter in capitals

JSR TT151              \ Call TT151 to print the item name, market price and
\ availability of the current item, and set QQ24 to the
\ item's price / 4, QQ25 to the quantity available and
\ QQ19+1 to byte #1 from the market prices table for
\ this item

INC YC                 \ Move the text cursor down one row

INC QQ29               \ Increment QQ29 to point to the next item

LDA QQ29               \ If QQ29 >= 17 then jump to TT168 as we have done the
CMP #17                \ last item
BCC TT168

RTS                    \ Return from the subroutine
}

Name: var                                             [View individually]
Type: Subroutine
Category: Market
Summary: Calculate QQ19+3 = economy * |economic_factor|

Set QQ19+3 = economy * |economic_factor|, given byte #1 of the market prices
table for an item. Also sets the availability of Alien Items to 0.

This routine forms part of the calculations for market item prices (TT151)
and availability (GVL).

Arguments:

QQ19+1               Byte #1 of the market prices table for this market item
(which contains the economic_factor in bits 0-5, and the
sign of the economic_factor in bit 7)

.var
{
LDA QQ19+1             \ Extract bits 0-5 from QQ19+1 into A, to get the
AND #31                \ economic_factor without its sign, in other words:
\
\   A = |economic_factor|

LDY QQ28               \ Set Y to the economy byte of the current system

STA QQ19+2             \ Store A in QQ19+2

CLC                    \ Clear the C flag so we can do additions below

LDA #0                 \ Set AVL+16 (availability of Alien Items) to 0,
STA AVL+16             \ setting A to 0 in the process

.TT153

\ We now do the multiplication by doing a series of
\ additions in a loop, building the result in A. Each
\ loop adds QQ19+2 (|economic_factor|) to A, and it
\ loops the number of times given by the economy byte;
\ in other words, because A starts at 0, this sets:
\
\   A = economy * |economic_factor|

DEY                    \ Decrement the economy in Y, exiting the loop when it
BMI TT154              \ becomes negative

JMP TT153              \ Loop back to TT153 to do another addition

.TT154

STA QQ19+3             \ Store the result in QQ19+3

RTS                    \ Return from the subroutine
}

Name: hyp1                                            [View individually]
Type: Subroutine
Category: Universe

(QQ9, QQ10), and set up the current system's state to those of the new system.

Returns:

(QQ0, QQ1)           The galactic coordinates of the new system

QQ2 to QQ2+6         The seeds of the new system

EV                   Set to 0

QQ28                 The new system's economy

tek                  The new system's tech level

gov                  The new system's government

Other entry points:

hyp1+3               Jump straight to the system at (QQ9, QQ10) without
first calculating which system is closest. We do this
if we already know that (QQ9, QQ10) points to a system

.hyp1
{
JSR TT111              \ Select the system closest to galactic coordinates
\ (QQ9, QQ10)

JSR jmp                \ Set the current system to the selected system

LDX #5                 \ We now want to copy the seeds for the selected system
\ in QQ15 into QQ2, where we store the seeds for the
\ current system, so set up a counter in X for copying
\ 6 bytes (for three 16-bit seeds)

.TT112

LDA QQ15,X             \ Copy the X-th byte in QQ15 to the X-th byte in QQ2,
STA QQ2,X

DEX                    \ Decrement the counter

BPL TT112              \ Loop back to TT112 if we still have more bytes to
\ copy

INX                    \ Set X = 0 (as we ended the above loop with X = &FF)

STX EV                 \ Set EV, the extra vessels spawning counter, to 0, as
\ we are entering a new system with no extra vessels
\ spawned

LDA QQ3                \ Set the current system's economy in QQ28 to the
STA QQ28               \ selected system's economy from QQ3

LDA QQ5                \ Set the current system's tech level in tek to the
STA tek                \ selected system's economy from QQ5

LDA QQ4                \ Set the current system's government in gov to the
STA gov                \ selected system's government from QQ4

RTS                    \ Return from the subroutine
}

Name: GVL                                             [View individually]
Type: Subroutine
Category: Universe
Summary: Calculate the availability of a market item

Calculate the availability for each market item and store it in AVL. This is
called on arrival in a new system.

Other entry points:

hyR                  Contains an RTS

.GVL
{
JSR DORND              \ Set A and X to random numbers

STA QQ26               \ Set QQ26 to the random byte that's used in the market
\ calculations

LDX #0                 \ We are now going to loop through the market item
STX XX4                \ availability table in AVL, so set a counter in XX4
\ (and X) for the market item number, starting with 0

.hy9

LDA QQ23+1,X           \ Fetch byte #1 from the market prices table (units and
STA QQ19+1             \ economic_factor) for item number X and store it in
\ QQ19+1

JSR var                \ Call var to set QQ19+3 = economy * |economic_factor|
\ (and set the availability of Alien Items to 0)

LDA QQ23+3,X           \ Fetch byte #3 from the market prices table (mask) and
AND QQ26               \ AND with the random number for this system visit
\ to give:
\
\   A = random AND mask

CLC                    \ Add byte #2 from the market prices table
ADC QQ23+2,X           \ (base_quantity) so we now have:
\
\   A = base_quantity + (random AND mask)

LDY QQ19+1             \ Fetch the byte #1 that we stored above and jump to
BMI TT157              \ TT157 if it is negative (i.e. if the economic_factor
\ is negative)

SEC                    \ Set A = A - QQ19+3
SBC QQ19+3             \
\       = base_quantity + (random AND mask)
\         - (economy * |economic_factor|)
\
\ which is the result we want, as the economic_factor
\ is positive

.TT157

CLC                    \ Set A = A + QQ19+3
\       = base_quantity + (random AND mask)
\         + (economy * |economic_factor|)
\
\ which is the result we want, as the economic_factor
\ is negative

.TT158

BPL TT159              \ If A < 0, then set A = 0, so we don't have negative
LDA #0                 \ availability

.TT159

LDY XX4                \ Fetch the counter (the market item number) into Y

AND #%00111111         \ Take bits 0-5 of A, i.e. A mod 64, and store this as
STA AVL,Y              \ this item's availability in the Y=th byte of AVL, so
\ each item has a maximum availability of 63t

INY                    \ Increment the counter into XX44, Y and A
TYA
STA XX4

ASL A                  \ Set X = counter * 4, so that X points to the next
ASL A                  \ item's entry in the four-byte market prices table,
TAX                    \ ready for the next loop

CMP #63                \ If A < 63, jump back up to hy9 to set the availability
BCC hy9                \ for the next market item

.^hyR

RTS                    \ Return from the subroutine
}

Name: GTHG                                            [View individually]
Type: Subroutine
Category: Universe
Summary: Spawn a Thargoid ship and a Thargon companion

.GTHG
{
JSR Ze                 \ Call Ze to initialise INWK

LDA #%11111111         \ Set the AI flag in byte #32 so that the ship has AI,
STA INWK+32            \ is extremely and aggressively hostile, and has E.C.M.

LDA #THG               \ Call NWSHP to add a new Thargoid ship to our local
JSR NWSHP              \ bubble of universe

LDA #TGL               \ Call NWSHP to add a new Thargon ship to our local
JMP NWSHP              \ bubble of universe, and return from the subroutine
\ using a tail call
}

Name: MJP                                             [View individually]
Type: Subroutine
Category: Flight
Summary: Process a mis-jump into witchspace

Process a mis-jump into witchspace (which happens very rarely). Witchspace has
a strange, almost dust-free aspect to it, and it is populated by hostile
Thargoids. Using our escape pod will be fatal, and our position on the
galactic chart is in-between systems. It is a scary place...

There is a 1% chance that this routine is called from TT18 instead of doing
a normal hyperspace, or we can manually trigger a mis-jump by holding down
CTRL after first enabling the "author display" configuration option ("X") when
paused.

Other entry points:

ptg                  Called when the user manually forces a mis-jump

{
.^ptg

LSR COK                \ Set bit 0 of the competition flags in COK, so that the
SEC                    \ copmpetition code will include the fact that we have
ROL COK                \ manually forced a mis-jump into witchspace

.^MJP

\LDA #1                 \ This instruction is commented out in the original
\ source - it is not required as a call to TT66-2 sets
\ A to 1 for us. This is presumably an example of the
\ authors saving a couple of bytes by calling TT66-2
\ instead of TT66, while leaving the original LDA
\ instruction in place

JSR TT66-2             \ Clear the top part of the screen, draw a white border,
\ and set the current view type in QQ11 to 1

JSR LL164              \ Call LL164 to show the hyperspace tunnel and make the
\ hyperspace sound for a second time (as we already
\ called LL164 in TT18)

JSR RES2               \ Reset a number of flight variables and workspaces, as
\ well as setting Y to &FF

STY MJ                 \ Set the mis-jump flag in MJ to &FF, to indicate that
\ we are now in witchspace

.MJP1

JSR GTHG               \ Call GTHG to spawn a Thargoid ship

LDA #3                 \ Fetch the number of Thargoid ships from MANY+THG, and
CMP MANY+THG           \ if it is less than 3, loop back to MJP1 to spawn
BCS MJP1               \ another one, until we have three Thargoids

STA NOSTM              \ Set NOSTM (the maximum number of stardust particles)
\ to 3, so there are fewer bits of stardust in
\ witchspace (normal space has a maximum of 18)

LDX #0                 \ Initialise the front space view
JSR LOOK1

LDA QQ1                \ Fetch the current system's galactic y-coordinate in
EOR #%00011111         \ QQ1 and flip bits 0-5, so we end up somewhere in the
STA QQ1                \ vicinity of our original destination, but above or
\ below it in the galactic chart

RTS                    \ Return from the subroutine
}

Name: TT18                                            [View individually]
Type: Subroutine
Category: Flight
Summary: Try to initiate a jump into hyperspace

Try to go through hyperspace. Called from TT102 in the main loop when the
hyperspace countdown has finished.

.TT18
{
LDA QQ14               \ Subtract the distance to the selected system (in QQ8)
SEC                    \ from the amount of fuel in our tank (in QQ14)
SBC QQ8
STA QQ14

LDA QQ11               \ If the current view is not a space view, jump to ee5
BNE ee5                \ to skip the following

JSR TT66               \ Clear the top part of the screen, draw a white border,
\ and set the current view type in QQ11 to 0 (space
\ view)

JSR LL164              \ Call LL164 to show the hyperspace tunnel and make the
\ hyperspace sound

.ee5

JSR CTRL               \ Scan the keyboard to see if CTRL is currently pressed,
\ returning a negative value in A if it is

AND PATG               \ If the game is configured to show the author's names
\ on the start-up screen, then PATG will contain &FF,
\ otherwise it will be 0

BMI ptg                \ By now, A will be negative if we are holding down CTRL
\ and author names are configured, which is what we have
\ to do in order to trigger a manual mis-jump, so jump
\ to ptg to do a mis-jump (ptg not only mis-jumps, but
\ updates the competition flags, so Acornsoft could tell
\ from the competition code whether this feature had
\ been used)

JSR DORND              \ Set A and X to random numbers

CMP #253               \ If A >= 253 (1% chance) then jump to MJP to trigger a
BCS MJP                \ mis-jump into witchspace

\JSR TT111              \ This instruction is commented out in the original
\ source. It finds the closest system to coordinates
\ (QQ9, QQ10), but we don't need to do this as the
\ crosshairs will already be on a system by this point

JSR hyp1+3             \ Jump straight to the system at (QQ9, QQ10) without
\ first calculating which system is closest

JSR GVL                \ Calculate the availability for each market item in the
\ new system

JSR RES2               \ Reset a number of flight variables and workspaces

JSR SOLAR              \ Halve our legal status, update the missile indicators,
\ and set up data blocks and slots for the planet and
\ sun

LDA QQ11               \ If the current view in QQ11 is not a space view (0) or
AND #%00111111         \ one of the charts (64 or 128), return from the
BNE hyR                \ subroutine (as hyR contains an RTS)

JSR TTX66              \ Otherwise clear the screen and draw a white border

LDA QQ11               \ If the current view is one of the charts, jump to
BNE TT114              \ TT114 (from which we jump to the correct routine to
\ display the chart)

INC QQ11               \ This is a space view, so increment QQ11 to 1

\ Fall through into TT110 to show the front space view
}

Name: TT110                                           [View individually]
Type: Subroutine
Category: Flight
Summary: Launch from a station or show the front space view

Launch the ship (if we are docked), or show the front space view (if we are

Called when red key f0 is pressed while docked (launch), after we arrive in a
new galaxy, or after a hyperspace if the current view is a space view.

.TT110
{
LDX QQ12               \ If we are not docked (QQ12 = 0) then jump to NLUNCH
BEQ NLUNCH

JSR LAUN               \ Show the space station launch tunnel

JSR RES2               \ Reset a number of flight variables and workspaces

JSR TT111              \ Select the system closest to galactic coordinates
\ (QQ9, QQ10)

INC INWK+8             \ Increment z_sign ready for the call to SOS, so the
\ planet appears at a z_sign of 1 in front of us when
\ we launch

JSR SOS1               \ Call SOS1 to set up the planet's data block and add it
\ to FRIN, where it will get put in the first slot as
\ it's the first one to be added to our local bubble of
\ universe following the call to RES2 above

LDA #128               \ For the space station, set z_sign to &80, so it's
STA INWK+8             \ behind us (&80 is negative)

INC INWK+7             \ And increment z_hi, so it's only just behind us

JSR NWSPS              \ Add a new space station to our local bubble of
\ universe

LDA #12                \ Set our launch speed in DELTA to 12
STA DELTA

JSR BAD                \ Call BAD to work out how much illegal contraband we
\ are carrying in our hold (A is up to 40 for a
\ standard hold crammed with contraband, up to 70 for
\ an extended cargo hold full of narcotics and slaves)

ORA FIST               \ OR the value in A with our legal status in FIST to
\ get a new value that is at least as high as both
\ values, to reflect the fact that launching with a
\ hold full of contraband can only make matters worse

STA FIST               \ Update our legal status with the new value

.NLUNCH

LDX #0                 \ Set QQ12 to 0 to indicate we are not docked
STX QQ12

JMP LOOK1              \ Jump to LOOK1 to switch to the front view (X = 0),
\ returning from the subroutine using a tail call
}

Name: TT114                                           [View individually]
Type: Subroutine
Category: Charts
Summary: Display either the Long-range or Short-range Chart

Display either the Long-range or Short-range Chart, depending on the current
view setting. Called from TT18 once we know the current view is one of the
charts.

Arguments:

A                    The current view, loaded from QQ11

.TT114
{
BMI TT115              \ If bit 7 of the current view is set (i.e. the view is

JMP TT22               \ Otherwise the current view is the Long-range Chart, so

.TT115

}

Name: LCASH                                           [View individually]
Type: Subroutine
Category: Maths (Arithmetic)
Summary: Subtract an amount of cash from the cash pot

Subtract (Y X) cash from the cash pot in CASH, but only if there is enough
cash in the pot. As CASH is a four-byte number, this calculates:

CASH(0 1 2 3) = CASH(0 1 2 3) - (0 0 Y X)

Returns:

C flag               If set, there was enough cash to do the subtraction

If clear, there was not enough cash to do the
subtraction

.LCASH
{
STX T1                 \ Subtract the least significant bytes:
LDA CASH+3             \
SEC                    \   CASH+3 = CASH+3 - X
SBC T1
STA CASH+3

STY T1                 \ Then the second most significant bytes:
LDA CASH+2             \
SBC T1                 \   CASH+2 = CASH+2 - Y
STA CASH+2

LDA CASH+1             \ Then the third most significant bytes (which are 0):
SBC #0                 \
STA CASH+1             \   CASH+1 = CASH+1 - 0

LDA CASH               \ And finally the most significant bytes (which are 0):
SBC #0                 \
STA CASH               \   CASH = CASH - 0

BCS TT113              \ If the C flag is set then the subtraction didn't
\ underflow, so the value in CASH is correct and we can
\ C flag set to indicate success (as TT113 contains an
\ RTS)

\ Otherwise we didn't have enough cash in CASH to
\ subtract (Y X) from it, so fall through into
\ MCASH to reverse the sum and restore the original
\ value in CASH, and returning with the C flag clear
}

Name: MCASH                                           [View individually]
Type: Subroutine
Category: Maths (Arithmetic)
Summary: Add an amount of cash to the cash pot

Add (Y X) cash to the cash pot in CASH. As CASH is a four-byte number, this
calculates:

CASH(0 1 2 3) = CASH(0 1 2 3) + (Y X)

Other entry points:

TT113                Contains an RTS

.MCASH
{
TXA                    \ Add the least significant bytes:
CLC                    \
ADC CASH+3             \   CASH+3 = CASH+3 + X
STA CASH+3

TYA                    \ Then the second most significant bytes:
STA CASH+2             \   CASH+2 = CASH+2 + Y

LDA CASH+1             \ Then the third most significant bytes (which are 0):
STA CASH+1             \   CASH+1 = CASH+1 + 0

LDA CASH               \ And finally the most significant bytes (which are 0):
STA CASH               \   CASH = CASH + 0

CLC                    \ Clear the C flag, so if the above was done following
\ a failed LCASH call, the C flag correctly indicates
\ failure

.^TT113

RTS                    \ Return from the subroutine
}

Name: GCASH                                           [View individually]
Type: Subroutine
Category: Maths (Arithmetic)
Summary: Calculate (Y X) = P * Q * 4

Calculate the following multiplication of unsigned 8-bit numbers:

(Y X) = P * Q * 4

.GCASH
{
JSR MULTU              \ Call MULTU to calculate (A P) = P * Q
}

Name: GC2                                             [View individually]
Type: Subroutine
Category: Maths (Arithmetic)
Summary: Calculate (Y X) = (A P) * 4

Calculate the following multiplication of unsigned 16-bit numbers:

(Y X) = (A P) * 4

.GC2
{
ASL P                  \ Set (A P) = (A P) * 4
ROL A
ASL P
ROL A

TAY                    \ Set (Y X) = (A P)
LDX P

RTS                    \ Return from the subroutine
}

Name: EQSHP                                           [View individually]
Type: Subroutine
Category: Equipment
Summary: Show the Equip Ship screen (red key f3)

Other entry points:

err                  Beep, pause and go to the docking bay (i.e. show the
Status Mode screen)

{
.bay

JMP BAY                \ Go to the docking bay (i.e. show the Status Mode
\ screen)

.^EQSHP

JSR DIALS              \ Call DIALS to update the dashboard

LDA #32                \ Clear the top part of the screen, draw a white border,
JSR TT66               \ and set the current view type in QQ11 to 32 (Equip
\ Ship screen)

LDA #12                \ Move the text cursor to column 12
STA XC

LDA #207               \ Print recursive token 47 ("EQUIP") followed by a space
JSR spc

LDA #185               \ Print recursive token 25 ("SHIP") and draw a
JSR NLIN3              \ horizontal line at pixel row 19 to box in the title

LDA #%10000000         \ Set bit 7 of QQ17 to switch to Sentence Case, with the
STA QQ17               \ next letter in capitals

INC YC                 \ Move the text cursor down one line

LDA tek                \ Fetch the tech level of the current system from tek
CLC                    \ and add 3 (the tech level is stored as 0-14, so A is
ADC #3                 \ now set to between 3 and 17)

CMP #12                \ If A >= 12 then set A = 12, so A is now set to between
BCC P%+4               \ 3 and 12
LDA #12

STA Q                  \ Set QQ25 = A (so QQ25 is in the range 3-12 and
STA QQ25               \ represents number of the most advanced item available
INC Q                  \ in this system, which we can pass to gnum below when
\
\ Set Q = A + 1 (so Q is in the range 4-13 and contains
\ QQ25 + 1, i.e. the highest item number on sale + 1)

LDA #70                \ Set A = 70 - QQ14, where QQ14 contains the current
SEC                    \ level in light years * 10, so this leaves the amount
SBC QQ14               \ of fuel we need to fill 'er up (in light years * 10)

ASL A                  \ The price of fuel is always 2 Cr per light year, so we
STA PRXS               \ double A and store it in PRXS, as the first price in
\ the price list (which is reserved for fuel), and
\ because the table contains prices as price * 10, it's
\ in the right format (so a full tank, or 7.0 light
\ years, would be 14.0 Cr, or a PRXS value of 140)

LDX #1                 \ We are now going to work our way through the equipment
\ price list at PRXS, printing out the equipment that is
\ available at this station, so set a counter in X,
\ starting at 1, to hold the number of the current item
\ plus 1 (so the item number in X loops through 1-13)

.EQL1

STX XX13               \ Store the current item number + 1 in XX13

JSR TT67               \ Print a newline

LDX XX13               \ Print the current item number + 1 to 3 digits, left-
CLC                    \ padding with spaces, and with no decimal point, so the
JSR pr2                \ items are numbered from 1

JSR TT162              \ Print a space

LDA XX13               \ Print recursive token 104 + XX13, which will be in the
CLC                    \ range 105 ("FUEL") to 116 ("GALACTIC HYPERSPACE ")
ADC #104               \ so this prints the current item's name
JSR TT27

LDA XX13               \ Call prx-3 to set (Y X) to the price of the item with
JSR prx-3              \ number XX13 - 1 (as XX13 contains the item number + 1)

SEC                    \ Set the C flag so we will print a decimal point when
\ we print the price

LDA #25                \ Move the text cursor to column 25
STA XC

LDA #6                 \ Print the number in (Y X) to 6 digits, left-padding
JSR TT11               \ with spaces and including a decimal point, which will
\ be the correct price for this item as (Y X) contains
\ the price * 10, so the trailing zero will go after the
\ decimal point (i.e. 5250 will be printed as 525.0)

LDX XX13               \ Increment the current item number in XX13
INX

CPX Q                  \ If X < Q, loop back up to print the next item on the
BCC EQL1               \ list of equipment available at this station

JSR CLYNS              \ Clear the bottom three text rows of the upper screen,
\ and move the text cursor to column 1 on row 21, i.e.
\ the start of the top row of the three bottom rows

LDA #127               \ Print recursive token 127 ("ITEM") followed by a
JSR prq                \ question mark

JSR gnum               \ Call gnum to get a number from the keyboard, which
\ will be the number of the item we want to purchase,
\ returning the number entered in A and R, and setting
\ the C flag if the number is bigger than the highest
\ item number in QQ25

BEQ bay                \ If no number was entered, jump up to bay to go to the
\ docking bay (i.e. show the Status Mode screen)

BCS bay                \ If the number entered was too big, jump up to bay to
\ go to the docking bay (i.e. show the Status Mode
\ screen)

SBC #0                 \ Set A to the number entered - 1 (because the C flag is
\ clear), which will be the actual item number we want

LDX #2                 \ Move the text cursor to column 2 on the next line
STX XC
INC YC

PHA                    \ While preserving the value in A, call eq to subtract
JSR eq                 \ the price of the item we want to buy (which is in A)
PLA                    \ from our cash pot, but only if we have enough cash in
\ the pot. If we don't have enough cash, exit to the
\ docking bay (i.e. show the Status Mode screen)

BNE et0                \ If A is not 0 (i.e. the item we've just bought is not

STA MCNT               \ We just bought fuel, so we zero the main loop counter

LDX #70                \ And set the current fuel level * 10 in QQ14 to 70, or
STX QQ14               \ 7.0 light years (a full tank)

.et0

CMP #1                 \ If A is not 1 (i.e. the item we've just bought is not

LDX NOMSL              \ Fetch the current number of missiles from NOMSL into X

INX                    \ Increment X to the new number of missiles

LDY #117               \ Set Y to recursive token 117 ("ALL")

CPX #5                 \ If buying this missile would give us 5 missiles, this
BCS pres               \ is more than the maximum of 4 missiles that we can
\ fit, so jump to pres to show the error "All Present",
\ beep and exit to the docking bay (i.e. show the Status
\ Mode screen)

STX NOMSL              \ Otherwise update the number of missiles in NOMSL

JSR msblob             \ And call msblob to update the dashboard's missile
\ indicators with our new purchase

.et1

LDY #107               \ Set Y to recursive token 107 ("LARGE CARGO{switch to
\ sentence case} BAY")

CMP #2                 \ If A is not 2 (i.e. the item we've just bought is not

LDX #37                \ If our current cargo capacity in CRGO is 37, then we
BEQ pres               \ to show the error "Large Cargo Bay Present", beep and
\ exit to the docking bay (i.e. show the Status Mode
\ screen)

STX CRGO               \ Otherwise we just scored ourselves a large cargo bay,
\ so update our current cargo capacity in CRGO to 37

.et2

CMP #3                 \ If A is not 3 (i.e. the item we've just bought is not

INY                    \ Increment Y to recursive token 108 ("E.C.M.SYSTEM")

LDX ECM                \ If we already have an E.C.M. fitted (i.e. ECM is
BNE pres               \ non-zero), jump to pres to show the error "E.C.M.
\ System Present", beep and exit to the docking bay
\ (i.e. show the Status Mode screen)

DEC ECM                \ Otherwise we just took delivery of a brand new E.C.M.
\ system, so set ECM to &FF (as ECM was 0 before the DEC
\ instruction)

.et3

CMP #4                 \ If A is not 4 (i.e. the item we've just bought is not

JSR qv                 \ Print a menu listing the four views, with a "View ?"
\ prompt, and ask for a view number, which is returned
\ in X (which now contains 0-3)

LDA #4                 \ This instruction doesn't appear to do anything, as we
\ either don't need it (if we already have this laser)
\ or we set A to 4 below (if we buy it)

LDY LASER,X            \ If there is no laser mounted in the chosen view (i.e.
BEQ ed4                \ LASER+X, which contains the laser power for view X, is

.ed7

LDY #187               \ Otherwise we already have a laser mounted in this
BNE pres               \ view, so jump to pres with Y set to token 27
\ (" LASER") to show the error "Laser Present", beep
\ and exit to the docking bay (i.e. show the Status
\ Mode screen)

.ed4

LDA #POW               \ We just bought a pulse laser for view X, so we need
STA LASER,X            \ to fit it by storing the laser power for a pulse laser
\ (given in POW) in LASER+X

LDA #4                 \ Set A to 4 as we just overwrote the original value,
\ and we still need it set correctly so we can continue
\ through the conditional statements for all the other
\ equipment

.et4

CMP #5                 \ If A is not 5 (i.e. the item we've just bought is not

JSR qv                 \ Print a menu listing the four views, with a "View ?"
\ prompt, and ask for a view number, which is returned
\ in X (which now contains 0-3)

STX T1                 \ Store the view in T1 so we can retrieve it below

LDA #5                 \ Set A to 5 as the call to qv will have overwritten
\ the original value, and we still need it set
\ correctly so we can continue through the conditional
\ statements for all the other equipment

LDY LASER,X            \ If there is no laser mounted in the chosen view (i.e.
BEQ ed5                \ LASER+X, which contains the laser power for mount X,

\BPL P%+4               \ This instruction is commented out in the original
\ source, though it would have no effect (it would
\ simply skip the BMI if A is positive, which is what
\ BMI does anyway)

BMI ed7                \ If there is a beam laser already mounted in the chosen
\ view (i.e. LASER+X has bit 7 set, which indicates a
\ beam laser rather than a pulse laser), skip back to
\ ed7 to print a "Laser Present" error, beep and exit
\ to the docking bay (i.e. show the Status Mode screen)

LDA #4                 \ If we get here then we already have a pulse laser in
JSR prx                \ the selected view, so we call prx to set (Y X) to the
\ price of equipment item number 4 (extra pulse laser)
\ so we can give a refund of the pulse laser

JSR MCASH              \ Add (Y X) cash to the cash pot in CASH, so we refund
\ the price of the pulse laser we are exchanging for a
\ new beam laser

.ed5

LDA #POW+128           \ We just bought a beam laser for view X, so we need
LDX T1                 \ to mount it by storing the laser power for a beam
STA LASER,X            \ laser (given in POW+128) in LASER+X, using the view
\ number we stored in T1 earlier, as the call to prx
\ will have overwritten the original value in X

.et5

LDY #111               \ Set Y to recursive token 107 ("FUEL SCOOPS")

CMP #6                 \ If A is not 6 (i.e. the item we've just bought is not

LDX BST                \ If we already have fuel scoops fitted (i.e. BST is
BEQ ed9                \ zero), jump to ed9, otherwise fall through into pres
\ to show the error "Fuel Scoops Present", beep and
\ exit to the docking bay (i.e. show the Status Mode
\ screen)

.pres

\ If we get here we need to show an error to say that
\ item number A is already present, where the item's
\ name is recursive token Y

STY K                  \ Store the item's name in K

JSR prx                \ Call prx to set (Y X) to the price of equipment item
\ number A

JSR MCASH              \ Add (Y X) cash to the cash pot in CASH, as the station
\ already took the money for this item in the JSR eq
\ instruction above, but we can't fit the item, so need
\ our money back

LDA K                  \ Print the recursive token in K (the item's name)
JSR spc                \ followed by a space

LDA #31                \ Print recursive token 145 ("PRESENT")
JSR TT27

.^err

JSR dn2                \ Call dn2 to make a short, high beep and delay for 1
\ second

JMP BAY                \ Jump to BAY to go to the docking bay (i.e. show the
\ Status Mode screen)

.ed9

DEC BST                \ We just bought a shiny new fuel scoop, so set BST to
\ &FF (as BST was 0 before the jump to ed9 above)

.et6

INY                    \ Increment Y to recursive token 112 ("E.C.M.SYSTEM")

CMP #7                 \ If A is not 7 (i.e. the item we've just bought is not

LDX ESCP               \ If we already have an escape pod fitted (i.e. ESCP is
BNE pres               \ non-zero), jump to pres to show the error "Escape Pod
\ Present", beep and exit to the docking bay (i.e. show
\ the Status Mode screen)

DEC ESCP               \ Otherwise we just bought an escape pod, so set ESCP
\ to &FF (as ESCP was 0 before the DEC instruction)

.et7

INY                    \ Increment Y to recursive token 113 ("ENERGY BOMB")

CMP #8                 \ If A is not 8 (i.e. the item we've just bought is not

LDX BOMB               \ If we already have an energy bomb fitted (i.e. BOMB
BNE pres               \ is non-zero), jump to pres to show the error "Energy
\ Bomb Present", beep and exit to the docking bay (i.e.
\ show the Status Mode screen)

LDX #&7F               \ Otherwise we just bought an energy bomb, so set BOMB
STX BOMB               \ to &7F

.et8

INY                    \ Increment Y to recursive token 114 ("ENERGY UNIT")

CMP #9                 \ If A is not 9 (i.e. the item we've just bought is not

LDX ENGY               \ If we already have an energy unit fitted (i.e. ENGY is
BNE pres               \ non-zero), jump to pres to show the error "Energy Unit
\ Present", beep and exit to the docking bay (i.e. show
\ the Status Mode screen)

INC ENGY               \ Otherwise we just picked up an energy unit, so set
\ ENGY to 1 (as ENGY was 0 before the INC instruction)

.etA

INY                    \ Increment Y to recursive token 115 ("DOCKING
\ COMPUTERS")

CMP #10                \ If A is not 10 (i.e. the item we've just bought is not

LDX DKCMP              \ If we already have a docking computer fitted (i.e.
BNE pres               \ DKCMP is non-zero), jump to pres to show the error
\ "Docking Computer Present", beep and exit to the
\ docking bay (i.e. show the Status Mode screen)

DEC DKCMP              \ Otherwise we just got hold of a docking computer, so
\ set DKCMP to &FF (as DKCMP was 0 before the DEC
\ instruction)

.etB

INY                    \ Increment Y to recursive token 116 ("GALACTIC
\ HYPERSPACE ")

CMP #11                \ If A is not 11 (i.e. the item we've just bought is not

LDX GHYP               \ If we already have a galactic hyperdrive fitted (i.e.
BNE pres               \ GHYP is non-zero), jump to pres to show the error
\ "Galactic Hyperspace Present", beep and exit to the
\ docking bay (i.e. show the Status Mode screen)

DEC GHYP               \ Otherwise we just splashed out on a galactic
\ hyperdrive, so set GHYP to &FF (as GHYP was 0 before
\ the DEC instruction)

.et9

JSR dn                 \ We are done buying equipment, so print the amount of
\ cash left in the cash pot, then make a short, high
\ beep to confirm the purchase, and delay for 1 second

JMP EQSHP              \ Jump back up to EQSHP to show the Equip Ship screen
\ again and see if we can't track down another bargain
}

Name: dn                                              [View individually]
Type: Subroutine
Category: Text
Summary: Print the amount of cash and beep

Print the amount of money in the cash pot, then make a short, high beep and
delay for 1 second.

.dn
{
JSR TT162              \ Print a space

LDA #119               \ Print recursive token 119 ("CASH:{cash right-aligned
JSR spc                \ to width 9} CR{crlf}") followed by a space

\ Fall through into dn2 to make a beep and delay for
\ 1 second before returning from the subroutine
}

Name: dn2                                             [View individually]
Type: Subroutine
Category: Text
Summary: Make a short, high beep and delay for 1 second

.dn2
{
JSR BEEP               \ Call the BEEP subroutine to make a short, high beep

LDY #50                \ Delay for 50 vertical syncs (50/50 = 1 second) and
JMP DELAY              \ return from the subroutine using a tail call
}

Name: eq                                              [View individually]
Type: Subroutine
Category: Equipment
Summary: Subtract the price of equipment from the cash pot

If we have enough cash, subtract the price of a specified piece of equipment
from our cash pot and return from the subroutine. If we don't have enough
cash, exit to the docking bay (i.e. show the Status Mode screen).

Arguments:

A                    The item number of the piece of equipment (0-11) as
shown in the table at PRXS

.eq
{
JSR prx                \ Call prx to set (Y X) to the price of equipment item
\ number A

JSR LCASH              \ Subtract (Y X) cash from the cash pot, but only if
\ we have enough cash

BCS c                  \ If the C flag is set then we did have enough cash for
\ subroutine (as c contains an RTS)

LDA #197               \ Otherwise we don't have enough cash to but this piece
JSR prq                \ of equipment, so print recursive token 37 ("CASH")
\ followed by a question mark

JMP err                \ Jump to err to beep, pause and go to the docking bay
\ (i.e. show the Status Mode screen)
}

Name: prx                                             [View individually]
Type: Subroutine
Category: Equipment
Summary: Return the price of a piece of equipment

This routine returns the price of equipment as listed in the table at PRXS.

Arguments:

A                    The item number of the piece of equipment (0-11) as
shown in the table at PRXS

Returns:

(Y X)                The item price in Cr * 10 (Y = high byte, X = low byte)

Other entry points:

prx-3                Return the price of the item with number A - 1

{
SEC                    \ Decrement A (for when this routine is called via
SBC #1                 \ prx-3)

.^prx

ASL A                  \ Set Y = A * 2, so it can act as an index into the
TAY                    \ PRXS table, which has two bytes per entry

LDX PRXS,Y             \ Fetch the low byte of the price into X

LDA PRXS+1,Y           \ Fetch the low byte of the price into A and transfer
TAY                    \ it to X, so the price is now in (Y X)

.^c

RTS                    \ Return from the subroutine
}

Name: qv                                              [View individually]
Type: Subroutine
Category: Equipment
Summary: Print a menu of the four space views, for buying lasers

Print a menu in the bottom-middle of the screen, at row 16, column 12, that
lists the four available space views, like this:

0 Front
1 Rear
2 Left
3 Right

Also print a "View ?" prompt and ask for a view number. The menu is shown
when we choose to buy a new laser in the Equip Ship screen.

Returns:

X                    The chosen view number (0-3)

.qv
{
LDY #16                \ Move the text cursor to row 16, and at the same time
STY YC                 \ set Y to a counter going from 16-20 in the loop below

.qv1

LDX #12                \ Move the text cursor to column 12
STX XC

TYA                    \ Transfer the counter value from Y to A

CLC                    \ Print ASCII character "0" - 16 + A, so as A goes from
ADC #'0'-16            \ 16 to 20, this prints "0" through "3" followed by a
JSR spc                \ space

LDA YC                 \ Print recursive text token 80 + YC, so as YC goes from
CLC                    \ 16 to 20, this prints "FRONT", "REAR", "LEFT" and
JSR TT27

INC YC                 \ Move the text cursor down a row)

LDY YC                 \ Update Y with the incremented counter in YC

CPY #20                \ If Y < 20 then loop back up to qv1 to print the next
BCC qv1                \ view in the menu

.qv3

JSR CLYNS              \ Clear the bottom three text rows of the upper screen,
\ and move the text cursor to column 1 on row 21, i.e.
\ the start of the top row of the three bottom rows

.qv2

LDA #175               \ Print recursive text token 15 ("VIEW ") followed by
JSR prq                \ a question mark

JSR TT217              \ Scan the keyboard until a key is pressed, and return
\ the key's ASCII code in A (and X)

SEC                    \ Subtract ASCII '0' from the key pressed, to leave the
SBC #'0'               \ numeric value of the key in A (if it was a number key)

CMP #4                 \ If the number entered in A >= 4, then it is not a
BCS qv3                \ valid view number, so jump back to qv3 to try again

TAX                    \ We have a valid view number, so transfer it to X

RTS                    \ Return from the subroutine
}

Save output/ELTD.bin

PRINT "ELITE D"
PRINT "Assembled at ", ~CODE_D%
PRINT "Ends at ", ~P%
PRINT "Code size is ", ~(P% - CODE_D%)