Submitted by Steve Fewell
Routine:tokeniseLineNumber
Name: Tokenise Line Number
Starting Address: &8D04
Entry criteria: A contains the first digit of the line number.
Pointer (&37, &38) points to the address in the program of the first digit of the Program Line Number.
Exit: The line number in the Program Line is tokenised.
Carry flag is set if error occurred (Line number too large).
Description:
Store the 4 lowest bits (bits 0, 1, 2 & 3) of the first digit (in A) in location &3D.
Set X to zero (the upper digit of the 2-byte binary line number)
Set Y to 1 (so the next character read will be the character after the first digit of the line number).
[&8D0C] Read next character from the (&37, &38) pointer.
If the next character is not a digit then go to &8D42 to store the line number token and exit.
Store the 4 lowest bits (bits 0, 1, 2 & 3) of the new digit on the stack.
Store X in location &3E.
Multiply the Line Number (in locations &3D (LSB) abd &3E (MSB) by 10, by:
*1) Storing the value of location &3D and &3E.
*2) Multiplying the Line Number value (in locations &3D-&3E) by 4
*3) Adding the stored &3D and &3E value to the result from step *2).
*4) Multiplying the Line Number value (in locations &3D-&3E [note: actually A at this stage] by 2.
If the Line Number MSB (&3E) becomes negative (or overflows) at any time during this multiply operation, the routine
will be exited with Carry set (as the line number is too large).
Next, retrieve the encoded next digit value from the Stack and add this digit to the Line Number (&3D-&3E).
This adds the digit to the binary line number.
If X (working copy of &3E) is negative then jump to &8D3F (exit with carry flag set), as the line number is too large.
Otherwise, jump back to &8D0C to process any further digits.
&8D42 Store Line Number Token & exit:
Examples:
Example1: Line Number = 10
[&8D04] A=&31. AND #&0F with A (1st digit), result=&01 (store in &3D).
[&8D14] A=&30. AND #&0F with A (2nd digit), result=&00. &3E & X = &00.
[&8D1E] Now: A=&02 and &3E=&00.
[&8D23] Now: A=&04 and &3E=&00.
[&8D27] Now: &3D and A = &05
[&8D2E] Now: A=&00, after addition, A=&00. &3D=&0A, A=&00.
[&8D39] Now: X=&00, A=&00 and &3D=&0A.
This 2-byte value is tokenised as follows:
(X = &00, &3D = &0A)
3rd byte of tokenised value = &40 (X (&00) OR &40).
2nd byte of tokenised value = &4A (A (&0A) OR &40).
1st byte of tokenised value = &54 (&00 EOR &54).
Example2: Line Number = 12345
[&8D04] A=&31. AND #&0F with A (1st digit), result=&01 (store in &3D).
[&8D14] A=&32. AND #&0F with A (2nd digit), result=&02. &3E & X = &00.
[&8D1E] Now: A=&02 and &3E=&00.
[&8D27] Now: A = &04, &3E = &00 and &3D = &05.
[&8D2E] Now: A=&00, after addition, A=&00. &3D=&0A, A=&00.
[&8D39] Now: X=&00, A=&0C and &3D=&0C.
[&8D14] A=&33. AND #&0F with A (3rd digit), result=&03. &3E & X = &00.
[&8D1E] Now: A=&0C (= &18 after addition) and &3E=&00.
[&8D27] Now: A = &30, &3E = &00 and &3D = &3C.
[&8D2E] Now: A=&00, after addition, A=&00. &3D=&78, A=&00.
[&8D39] Now: X=&00, &3D=&7B.
[&8D14] A=&34. AND #&0F with A (4th digit), result=&04. &3E & X = &00.
[&8D1E] Now: A=&7B (= &F6 after addition) and &3E=&00.
[&8D27] Now: A = &EC, &3E = &01 and &3D = &67.
[&8D2E] Now: A=&00, after addition, A=&02. &3D=&CE, A=&04.
[&8D39] Now: X=&04 and &3D=&D2.
[&8D14] A=&35. AND #&0F with A (5th digit), result=&05. &3E & X = &04.
[&8D1E] Now: A=&D2 (= &A4 after addition) and &3E=&09.
[&8D27] Now: A = &48, &3E = &13 and &3D = &1A.
[&8D2E] Now: A=&04, after addition, A=&18. &3D=&34, A=&30.
[&8D39] Now: X=&30 and &3D=&39.
This 2-byte value is tokenised as follows:
(X = &30, &3D = &39)
3rd byte of tokenised value = &70 (X (&40) OR &30).
2nd byte of tokenised value = &79 (A (&40) OR &39).
1st byte of tokenised value = &54 (&00 EOR &54).
Example3: Line Number = 333
[&8D04] A=&33. AND #&0F with A (1st digit), result=&03 (store in &3D).
[&8D14] A=&33. AND #&0F with A (2nd digit), result=&03. &3E & X = &00.
[&8D1E] Now: A=&06 and &3E=&00.
[&8D27] Now: A = &0C, &3E = &00 and &3D = &0F.
[&8D2E] Now: A=&00, after addition, A=&00. &3D=&1E, A=&00.
[&8D39] Now: X=&00 and &3D=&21.
[&8D14] A=&33. AND #&0F with A (3rd digit), result=&03. &3E & X = &00.
[&8D1E] Now: A=&42 and &3E=&00.
[&8D27] Now: A = &84, &3E = &00 and &3D = &A5.
[&8D2E] Now: A=&00, after addition, A=&00. &3D=&4A, A=&01.
[&8D39] Now: X=&01 and &3D=&4D.
This 2-byte value is tokenised as follows:
(X = &01, &3D = &4D)
3rd byte of tokenised value = &41 (X (&01) OR &40).
2nd byte of tokenised value = &4D (A (&0D) OR &40).
1st byte of tokenised value = &44 (&10 EOR &54) [(A (&01) AND &C0 => &00) ORA &3D (top 2 bits) = &40;
divide by 4 = &10 EOR &54 ==> &44].
8D04 | ) | 041 015 | 29 0F | AND#&0F |
8D06 | = | 133 061 | 85 3D | STA &3D |
8D08 | 162 000 | A2 00 | LDX#&00 | |
8D0A | 160 000 | A0 00 | LDY#&00 | |
8D0C | 200 | C8 | INY | |
8D0D | 7 | 177 055 | B1 37 | LDA (&37),Y |
8D0F | 032 148 141 | 20 94 8D | JSR &8D94 Check for numeric digit | |
8D12 | . | 144 046 | 90 2E | BCC 46 --> &8D42 (no more numeric digits present) |
8D14 | ) | 041 015 | 29 0F | AND#&0F |
8D16 | H | 072 | 48 | PHA |
8D17 | > | 134 062 | 86 3E | STX &3E |
8D19 | = | 165 061 | A5 3D | LDA &3D |
8D1B | 010 | 0A | ASL A | |
8D1C | &> | 038 062 | 26 3E | ROL &3E |
8D1E | 0 | 048 031 | 30 1F | BMI 31 --> &8D3F |
8D20 | 010 | 0A | ASL A | |
8D21 | &> | 038 062 | 26 3E | ROL &3E |
8D23 | 0 | 048 026 | 30 1A | BMI 26 --> &8D3F |
8D25 | e= | 101 061 | 65 3D | ADC &3D |
8D27 | = | 133 061 | 85 3D | STA &3D |
8D29 | 138 | 8A | TXA | |
8D2A | e> | 101 062 | 65 3E | ADC &3E |
8D2C | = | 006 061 | 06 3D | ASL &3D |
8D2E | * | 042 | 2A | ROL A |
8D2F | 0 | 048 014 | 30 0E | BMI 14 --> &8D3F |
8D31 | 176 012 | B0 0C | BCS 12 --> &8D3F | |
8D33 | 170 | AA | TAX | |
8D34 | h | 104 | 68 | PLA |
8D35 | e= | 101 061 | 65 3D | ADC &3D |
8D37 | = | 133 061 | 85 3D | STA &3D |
8D39 | 144 209 | 90 D1 | BCC -47 --> &8D0C | |
8D3B | 232 | E8 | INX | |
8D3C | 016 206 | 10 CE | BPL -50 --> &8D0C | |
8D3E | H | 072 | 48 | PHA |
8D3F | h | 104 | 68 | PLA |
8D40 | 8 | 056 | 38 | SEC |
8D41 | ` | 096 | 60 | RTS |
8D42 | 136 | 88 | DEY | |
8D43 | 169 141 | A9 8D | LDA#&8D | |
8D45 | 032 235 140 | 20 EB 8C | JSR &8CEB Replace untokenised value with token | |
8D48 | 7 | 165 055 | A5 37 | LDA &37 |
8D4A | 9 | 133 057 | 85 39 | STA &39 |
8D4C | 8 | 165 056 | A5 38 | LDA &38 |
8D4E | : | 133 058 | 85 3A | STA &3A |
8D50 | 032 162 141 | 20 A2 8D | JSR &8DA2 Increment Pointer (&37, &38) | |
8D53 | 032 162 141 | 20 A2 8D | JSR &8DA2 Increment Pointer (&37, &38) | |
8D56 | 032 162 141 | 20 A2 8D | JSR &8DA2 Increment Pointer (&37, &38) | |
8D59 | 9 | 177 057 | B1 39 | LDA (&39),Y |
8D5B | 7 | 145 055 | 91 37 | STA (&37),Y |
8D5D | 136 | 88 | DEY | |
8D5E | 208 249 | D0 F9 | BNE -7 --> &8D59 | |
8D60 | 160 003 | A0 03 | LDY#&03 | |
8D62 | 138 | 8A | TXA | |
8D63 | @ | 009 064 | 09 40 | ORA#&40 |
8D65 | 9 | 145 057 | 91 39 | STA (&39),Y |
8D67 | 136 | 88 | DEY | |
8D68 | = | 165 061 | A5 3D | LDA &3D |
8D6A | )? | 041 063 | 29 3F | AND#&3F |
8D6C | @ | 009 064 | 09 40 | ORA#&40 |
8D6E | 9 | 145 057 | 91 39 | STA (&39),Y |
8D70 | 136 | 88 | DEY | |
8D71 | ? | 169 063 | A9 3F | LDA#&3F |
8D73 | = | 020 061 | 14 3D | TRB &3D |
8D75 | 138 | 8A | TXA | |
8D76 | ) | 041 192 | 29 C0 | AND#&C0 |
8D78 | J | 074 | 4A | LSR A |
8D79 | J | 074 | 4A | LSR A |
8D7A | = | 005 061 | 05 3D | ORA &3D |
8D7C | J | 074 | 4A | LSR A |
8D7D | J | 074 | 4A | LSR A |
8D7E | IT | 073 084 | 49 54 | EOR#&54 |
8D80 | 9 | 145 057 | 91 39 | STA (&39),Y |
8D82 | 024 | 18 | CLC | |
8D83 | ` | 096 | 60 | RTS |