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 |
Or