×   Main Menu ALL The 8BS News Manuals (New menu) Links Worth a Look Tools Disc and Basic Webring Site Map 8BS Guestbook Old Guest Book Me The Barnsley Rovers   
8-Bit Software

The BBC and Master Computer Public Domain Library

A085 Print Line Number on screen

Submitted by Steve Fewell

Routine:Print Line Number
Name: Print Line number (&2A-&2B) on the screen
Starting Address: &A085
Entry criteria: &2A and &2B (the IWA) contain an untokenised Line Number.

Description:

This routine uses bytes stored at &8021-&802A, which contain the five 16-bit values: 1, 10, 100, 1000 and 10000.
These values are used to print Line Numbers (which are a maximum of 5 decimal digits wide).
The tens conversion table (&8021-&802A) consists of the following:

High byte Location Value   Low Byte Location Value   Description
8021 &00 8026 &01 The high and low byte of the value &0001 (1 in decimal)
8022 &00 8027 &0A The high and low byte of the value &000A (10 in decimal)
8023 &00 8028 &64 The high and low byte of the value &0064 (100 in decimal)
8024 &03 8029 &E8 The high and low byte of the value &03E8 (1000 in decimal)
8025 &27 802A &10 The high and low byte of the value &2710 (10000 in decimal)

Firstly, this routine sets the number of bytes in the Print output field (location &14).
If this routine is entered at location &A085 (i.e. from LIST) then the Print output field will be set to 5-digits
wide - so that all Line Numbers are positioned to 5 characters wide & therefore line up, as the following example shows:

    1
    5
   10
   70
  110
 2000
 2010
11100


If this routine is entered at location &A081 (i.e. from TRACE line printout) then the Print output field will be set to 0
(no fixed width) - so that all Line Numbers are positioned to 0 characters wide (and will take up as many characters as
needed), the following is an example of this output width, using a selection of different Line Numbers:

1
5
10
70
110
2000
2010
11100


Locations &3F-&43 are used to store the units/tens values (digit counts) as follows:
   - Location &3F is the number of 1's units in the Line Number (i.e. the value of the digit in the unit position).
   - Location &40 is the number of 10's units in the Line Number.
   - Location &41 is the number of 100's units in the Line Number.
   - Location &42 is the number of 1000's units in the Line Number.
   - Location &43 is the number of 10000's units in the Line Number.

Set X to #&04 (as the number of values to process is 5). The largest value (10000) will be processed first, followed by
the second largest (1000), and then the next largest (100), and then 10 and finally 1.

[&A08B] Zero the digit count for the current search value. The search value is the value pointed to by the value in X.
I.e. when X is 4, the search value's digit count store is location &3F + #&04 = &43, the search value MSB
byte is located at location &8021 + #&04 = &8025, and the search value LSB byte is located at location &8026
+ #&04 = &802A.
E.g. So, when X is 3 we will search for the value 1000, and location &42 will be zeroed at the start of the search; or
when X is 1 we will search for the value 10, and location &40 will be zeroed at the start of the search.

Set the carry flag to begin a subtraction. Note: the carry flag is not reset during subtractions of the same Search Value,
as the carry is carried over between subtractions of the same Search Value (where X is unchanged).
[&A08E] Subtract the current Search Number low byte (&8026 + X) from the low byte of the Line Number in the IWA (&2A).
Store the result in Y.
Subtract the current Search Number high byte (&8021 + X) from the high byte of the Line Number in the IWA (&2B).
Store the result in A.
If the subtraction did not underflow (carry is set), then the search value was sucessfully subtracted; so store the new Line
Number value (after the subtraction -> Y = low byte, A = high byte) in the IWA (locatons &2A, &2B respecively),
increment the Digit Counter (&3F + X) and jump back to &A08E to try another subtraction of the Search value.

Otherwise [&A0A3], the Search Value could not be subtracted, so we need to move on to the next (lower) search value).
Decrement X (to move down to the next lower Search value).
If X is positive (>=0) then jump back to &A08B to check whether we can subject this Search value from the IWA value.

Otherwise, the search has been completed, and locations &3F-&43 should now contain the separate digits of the line
Number - ready to print.

Find the first non-zero digit Set X to 5 (possible number of bytes to output).
[&A0A8] decrement X (and if X is zero then jump to the output routine - &A0AF) and check whether the Digit Counter
value at location &3F + X is zero. if it is then jump back to &A0A8 to find the first non-zero digit.

Output the Line Number value to the screen Now X points to the first non-zero byte (or the first byte if the Line Number is zero), where X=4 points to the digit at
location &43 and X=0 points to the digit at location &3F.
Store X in location &37 (this is a pointer to the first digit required to be output).

Print any required leading spaces, as follows:
If the Output field width value (location &14) is not zero, then subtract &37 (X) from the &14 value, the result
is the number of spaces required to be output on the line before the first non-zero digit is output.
If the number of spaces required is not zero then set X to the number of spaces required and call routine &BDBF output
X number of spaces.

Set X to the first digit to output pointer (from location &37).
Print each digit of the line number to the screen (starting at location &3F + X and finishing at location &3F,
reducing X by 1 after each digit has been printed.
To print each digit, the decimal value is ORA-ed with #&30 to add the ASCII offset value (64).
Exit after all required digits have been output.


Disassembly for the Print Line Number on screen routine

A081   169 000 A9 00 LDA#&00
A083   128 002 80 02 BRA 2 --> &A087
A085   169 005 A9 05 LDA#&05
A087   133 020 85 14 STA &14
A089   162 004 A2 04 LDX#&04
A08B t? 116 063 74 3F STZ &3F,X
A08D 8 056 38 SEC
A08E * 165 042 A5 2A LDA &2A
A090 & 253 038 128 FD 26 80 SBC &8026,X
A093   168 A8 TAY
A094 + 165 043 A5 2B LDA &2B
A096 ! 253 033 128 FD 21 80 SBC &8021,X
A099   144 008 90 08 BCC 8 --> &A0A3
A09B + 133 043 85 2B STA &2B
A09D * 132 042 84 2A STY &2A
A09F ? 246 063 F6 3F INC &3F,X
A0A1   128 235 80 EB BRA -21 --> &A08E
A0A3   202 CA DEX
A0A4   016 229 10 E5 BPL -27 --> &A08B
A0A6   162 005 A2 05 LDX#&05
A0A8   202 CA DEX
A0A9   240 004 F0 04 BEQ 4 --> &A0AF
A0AB ? 181 063 B5 3F LDA &3F,X
A0AD   240 249 F0 F9 BEQ -7 --> &A0A8
A0AF 7 134 055 86 37 STX &37
A0B1   165 020 A5 14 LDA &14
A0B3   240 010 F0 0A BEQ 10 --> &A0BF
A0B5 7 229 055 E5 37 SBC &37
A0B7   240 006 F0 06 BEQ 6 --> &A0BF
A0B9   170 AA TAX
A0BA   032 191 189 20 BF BD JSR &BDBF Output X number of Spaces
A0BD 7 166 055 A6 37 LDX &37
A0BF ? 181 063 B5 3F LDA &3F,X
A0C1 0 009 048 09 30 ORA#&30
A0C3   032 148 189 20 94 BD JSR &BD94 Output character to the screen
A0C6   202 CA DEX
A0C7   016 246 10 F6 BPL -10 --> &A0BF
A0C9 ` 096 60 RTS

 


 Back to 8BS
Or