![]() |
Routines |
Prev: 11405 | Up: Map |
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.
|
|||||||||
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 |