Prev: 11405 Up: Map Next: 11547
11419: THE 'DECIMAL TO FLOATING POINT' SUBROUTINE
Used by the routine at S_DECIMAL.
As part of syntax checking decimal numbers that occur in a BASIC line are converted to their floating-point forms. This subroutine reads the decimal number digit by digit and gives its result as a 'last value' on the calculator stack. But first it deals with the alternative notation BIN, which introduces a sequence of 0's and 1's giving the binary representation of the required number.
Input
A Code of the first character in the number
DEC_TO_FP 11419 CP 196 Is the character a 'BIN'?
11421 JR NZ,NOT_BIN Jump if it is not 'BIN'.
11423 LD DE,0 Initialise result to zero in DE.
BIN_DIGIT 11426 RST 32 Get the next character.
11427 SUB "1" Subtract the character code for '1'.
11429 ADC A,0 0 now gives 0 with carry set; 1 gives 0 with carry reset.
11431 JR NZ,BIN_END Any other character causes a jump to BIN_END and will be checked for syntax during or after scanning.
11433 EX DE,HL Result so far to HL now.
11434 CCF Complement the carry flag.
11435 ADC HL,HL Shift the result left, with the carry going to bit 0.
11437 JP C,REPORT_6 Report overflow if more than 65535.
11440 EX DE,HL Return the result so far to DE.
11441 JR BIN_DIGIT Jump back for next 0 or 1.
BIN_END 11443 LD B,D Copy result to BC for stacking.
11444 LD C,E
11445 JP STACK_BC Jump forward to stack the result.
For other numbers, first any integer part is converted; if the next character is a decimal, then the decimal fraction is considered.
NOT_BIN 11448 CP "." Is the first character a '.'?
11450 JR Z,DECIMAL If so, jump forward.
11452 CALL INT_TO_FP Otherwise, form a 'last value' of the integer.
11455 CP "." Is the next character a '.'?
11457 JR NZ,E_FORMAT Jump forward to see if it is an 'E'.
11459 RST 32 Get the next character.
11460 CALL NUMERIC Is it a digit?
11463 JR C,E_FORMAT Jump if not (e.g. 1.E4 is allowed).
11465 JR DEC_STO_1 Jump forward to deal with the digits after the decimal point.
DECIMAL 11467 RST 32 If the number started with a decimal, see if the next character is a digit.
11468 CALL NUMERIC
DEC_RPT_C 11471 JP C,REPORT_C Report the error if it is not.
11474 RST 40 Use the calculator to stack zero as the integer part of such numbers.
11475 DEFB 160 stk_zero
11476 DEFB 56 end_calc
DEC_STO_1 11477 RST 40 Use the calculator to copy the number 1 to mem-0.
11478 DEFB 161 stk_one
11479 DEFB 192 st_mem_0
11480 DEFB 2 delete
11481 DEFB 56 end_calc
For each passage of the following loop, the number (N) saved in the memory area mem-0 is fetched, divided by 10 and restored, i.e. N goes from 1 to .1 to .01 to .001 etc. The present digit (D) is multiplied by N/10 and added to the 'last value' (V), giving V+D*N/10.
NXT_DGT_1 11482 RST 24 Get the present character.
11483 CALL STK_DIGIT If it is a digit (D) then stack it.
11486 JR C,E_FORMAT If not jump forward.
11488 RST 40 Now use the calculator.
11489 DEFB 224 get_mem_0: V, D, N
11490 DEFB 164 stk_ten: V, D, N, 10
11491 DEFB 5 division: V, D, N/10
11492 DEFB 192 st_mem_0: V, D, N/10 (N/10 is copied to mem-0)
11493 DEFB 4 multiply: V, D*N/10
11494 DEFB 15 addition: V+D*N/10
11495 DEFB 56 end_calc
11496 RST 32 Get the next character.
11497 JR NXT_DGT_1 Jump back (one more byte than needed) to consider it.
Next consider any 'E notation', i.e. the form xEm or xem where m is a positive or negative integer.
E_FORMAT 11499 CP "E" Is the present character an 'E'?
11501 JR Z,SIGN_FLAG Jump forward if it is.
11503 CP "e" Is it an 'e'?
11505 RET NZ Finished unless it is so.
SIGN_FLAG 11506 LD B,255 Use B as a sign flag, 255 for '+'.
11508 RST 32 Get the next character.
11509 CP "+" Is it a '+'?
11511 JR Z,SIGN_DONE Jump forward.
11513 CP "-" Is it a '-'?
11515 JR NZ,ST_E_PART Jump if neither '+' nor '-'.
11517 INC B Change the sign of the flag.
SIGN_DONE 11518 RST 32 Point to the first digit.
ST_E_PART 11519 CALL NUMERIC Is it indeed a digit?
11522 JR C,DEC_RPT_C Report the error if not.
11524 PUSH BC Save the flag in B briefly.
11525 CALL INT_TO_FP Stack ABS m, where m is the exponent.
11528 CALL FP_TO_A Transfer ABS m to A.
11531 POP BC Restore the sign flag to B.
11532 JP C,REPORT_6 Report the overflow now if ABS m is greater than 255 or indeed greater than 127 (other values greater than about 39 will be detected later).
11535 AND A
11536 JP M,REPORT_6
11539 INC B Test the sign flag in B; '+' (i.e. 255) will now set the zero flag.
11540 JR Z,E_FP_JUMP Jump if sign of m is '+'.
11542 NEG Negate m if sign is '-'.
E_FP_JUMP 11544 JP e_to_fp Jump to assign to the 'last value' the result of x*10↑m.
Prev: 11405 Up: Map Next: 11547