Page Last Altered:

**Submitted by Steve Fewell**

**Routine**:ASCNUM:ExtractNum

**Name**: ASCII TO NUM: Extract Integer/Floating-Point Number at PTRB

**Starting Address**: &A2E1

**Entry criteria**: The SWA
contains the ASCII number to extract

**Exit**: Depending of the size of the number, and whether it contains a
fractional part

or not, either the FWA or IWA
will contain the binary conversion

or the number. A=&40 if Integer, or &FF if Floating-point.

Carry is clear if the ASCII text could not be converted to a numeric value.

**Description**:

Clears bytes &31 to &35 (The FWA Mantissa & rounding bytes).

Clears byte &47 - the 'Decimal Point found' flag. (remains zero if number is Integer)

Clears byte &48 - the Exponent of the extracted number. (remains zero if number is Integer)

If Next Character at PTRB is "." then A31C [*if decimal point has already been found,
then A364 (Complete & tidy-up the number value) as the number is complete.
Otherwise, increment &47 (to set the decimal point found flag)
then goto A315 (to process the next character of the number).*]

If Next Character at PTRB >= ":" or <= "/" then A2DA [*Return 0.00 as no number found.*].

Subtract 48 (47 + 1 as Carry Clear), so A=0 for "0", 1 for "1" ..., 9 for "9".

Store digit found at LSB of FWA (&35, the FWA rounding byte).

Load next character from PTRB in A.

If character >= ":" [non-digit] then A324 [process main body of number], as this checks

for "E" before terminating number extraction at an invalid character.]

Subtract 48 (47 + 1 as Carry Clear), so A=0 for "0", 1 for "1" ..., 9 for "9".

If carry clear (underflow occurred, A <= "/" [non-digit]) then A316 [* if char not = "." then A324
(to process main body of number);
otherwise, If character is "." then A31C [if decimal point has already been
found, then A364 (Complete & tidy-up the number value) as the number is complete.
Otherwise, increment &47 (to set the decimal point found flag)
then goto A315 (to process the next character of the number).]
*]

Temporarily store A in &2E [FWA sign].

Multiplies the number in &35 by 10 and adds ?&2E to the result to form

a 2-digit binary number.

The multiply does this: ?&35=((?&35*4)+?&35)*2) + ?&2E

= ?&35=(?&35*5*2) plus ?&2E.

Get next character, and if it isn't "." then goto A324 [to process the main body of the

number]. Otherwise, set decimal found flag and get next character before going to A324 [main body]

or finish extraction (A364) if the next character was another ".".

** ASCNUM: A324: Process main body of number: **

This routine is first entered after the first two digits have been processed, (by A2E1) or after a "."

if the decimal point was encountered before that stage. This routine doesn't need to deal

with a "no number found" situation, as this has already been dealt with in A2E1.

This routine keeps the Exponent &48 in line with the binary value, and copes with

exponential values ("E"). It also copes with much bigger numbers than the 2-digit ones that

A2E1 processed.

This routines does the following:
If ASCII character is "E" then goto &A35D [to get the exponent value and convert the exponential

number to the completed binary value and exit with the result stored in the FWA]

If the character is not a valid digit (char >= ":" or char <= "/") then goto A364 to complete

the number and finish the extraction.

Subtract 48 (47 + 1 as Carry Clear), so A=0 for "0", 1 for "1" ..., 9 for "9".

X = ?&31 (FWA Mantissa byte 1). If this value is less than or equal to 24 then it is

ok to add the next digit to the end of the number [so goto &A33E]. Otherwise, the digit is not

added [number is too large] and the exponent is incremented (if no decimal point has been

found [integer value]). Then goto A315. A315 gets the next character, handles any decimal point

character found, or calls A324 again to handle all other characters.

** ASCNUM: A33E: Add digit to end of number (and multiply 'old' number by 10): **

If the number has a decimal point in it (?&47 not = 0) then decrement &48 (the exponent)

as we are adding a digit to the LSB of the value without moving the decimal point from its current position.

Multiply the current number by 10 (using &A279 [multiply FWA Mantissa by 10] routine).

&A279 returns with A unchanged, so we can add the next digit to &35 in order to

add the new digit to the end of the current number (now multiplied by 10 to cope with decimal-binary conversion).

If overflow occures, then we need to increment the rest of the bytes of the FWA Mantissa

(&34 and then &33 (if incrementing &34 overflowed), etc... to &31 if necessary).

lastly, we need to go back to A315 to get the next charater.

&A315 gets the next character, handles any decimal point character found, or calls &A324 again to

handle all other characters.

A2DA | 032 004 164 | 20 04 A4 | JSR &A404 | |

A2DD | 024 | 18 | CLC | |

A2DE | 169 255 | A9 FF | LDA#&FF | |

A2E0 | ` | 096 | 60 | RTS |

A2E1 | d1 | 100 049 | 64 31 | STZ &31 |

A2E3 | d2 | 100 050 | 64 32 | STZ &32 |

A2E5 | d3 | 100 051 | 64 33 | STZ &33 |

A2E7 | d4 | 100 052 | 64 34 | STZ &34 |

A2E9 | d5 | 100 053 | 64 35 | STZ &35 |

A2EB | dG | 100 071 | 64 47 | STZ &47 |

A2ED | dH | 100 072 | 64 48 | STZ &48 |

A2EF | . | 201 046 | C9 2E | CMP#&2E |

A2F1 | ) | 240 041 | F0 29 | BEQ 41 --> &A31C |

A2F3 | : | 201 058 | C9 3A | CMP#&3A |

A2F5 | 176 227 | B0 E3 | BCS -29 --> &A2DA | |

A2F7 | / | 233 047 | E9 2F | SBC#&2F |

A2F9 | 0 | 048 223 | 30 DF | BMI -33 --> &A2DA |

A2FB | 5 | 133 053 | 85 35 | STA &35 |

A2FD | 200 | C8 | INY | |

A2FE | 177 025 | B1 19 | LDA (&19),Y | |

A300 | : | 201 058 | C9 3A | CMP#&3A |

A302 | 176 032 | B0 20 | BCS 32 --> &A324 | |

A304 | / | 233 047 | E9 2F | SBC#&2F |

A306 | 144 014 | 90 0E | BCC 14 --> &A316 | |

A308 | . | 133 046 | 85 2E | STA &2E |

A30A | 5 | 165 053 | A5 35 | LDA &35 |

A30C | 010 | 0A | ASL A | |

A30D | 010 | 0A | ASL A | |

A30E | e5 | 101 053 | 65 35 | ADC &35 |

A310 | 010 | 0A | ASL A | |

A311 | e. | 101 046 | 65 2E | ADC &2E |

A313 | 5 | 133 053 | 85 35 | STA &35 |

A315 | 200 | C8 | INY | |

A316 | 177 025 | B1 19 | LDA (&19),Y | |

A318 | . | 201 046 | C9 2E | CMP#&2E |

A31A | 208 008 | D0 08 | BNE 8 --> &A324 | |

A31C | G | 165 071 | A5 47 | LDA &47 |

A31E | D | 208 068 | D0 44 | BNE 68 --> &A364 |

A320 | G | 230 071 | E6 47 | INC &47 |

A322 | 128 241 | 80 F1 | BRA -15 --> &A315 |

A324 | E | 201 069 | C9 45 | CMP#&45 |

A326 | 5 | 240 053 | F0 35 | BEQ 53 --> &A35D |

A328 | : | 201 058 | C9 3A | CMP#&3A |

A32A | 8 | 176 056 | B0 38 | BCS 56 --> &A364 |

A32C | / | 233 047 | E9 2F | SBC#&2F |

A32E | 4 | 144 052 | 90 34 | BCC 52 --> &A364 |

A330 | 1 | 166 049 | A6 31 | LDX &31 |

A332 | 224 024 | E0 18 | CPX#&18 | |

A334 | 144 008 | 90 08 | BCC 8 --> &A33E | |

A336 | G | 166 071 | A6 47 | LDX &47 |

A338 | 208 219 | D0 DB | BNE -37 --> &A315 | |

A33A | H | 230 072 | E6 48 | INC &48 |

A33C | 128 215 | 80 D7 | BRA -41 --> &A315 |

A33E | G | 166 071 | A6 47 | LDX &47 |

A340 | 240 002 | F0 02 | BEQ 2 --> &A344 | |

A342 | H | 198 072 | C6 48 | DEC &48 |

A344 | y | 032 121 162 | 20 79 A2 | JSR &A279 |

A347 | e5 | 101 053 | 65 35 | ADC &35 |

A349 | 5 | 133 053 | 85 35 | STA &35 |

A34B | 144 200 | 90 C8 | BCC -56 --> &A315 | |

A34D | 4 | 230 052 | E6 34 | INC &34 |

A34F | 208 196 | D0 C4 | BNE -60 --> &A315 | |

A351 | 3 | 230 051 | E6 33 | INC &33 |

A353 | 208 192 | D0 C0 | BNE -64 --> &A315 | |

A355 | 2 | 230 050 | E6 32 | INC &32 |

A357 | 208 188 | D0 BC | BNE -68 --> &A315 | |

A359 | 1 | 230 049 | E6 31 | INC &31 |

A35B | 128 184 | 80 B8 | BRA -72 --> &A315 |

A404 |