Routines 
Prev: 2C8D  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 floatingpoint 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  2C9B  CP $C4  Is the character a 'BIN'?  
2C9D  JR NZ,NOT_BIN  Jump if it is not 'BIN'.  
2C9F  LD DE,$0000  Initialise result to zero in DE.  
BIN_DIGIT  2CA2  RST $20  Get the next character.  
2CA3  SUB "1"  Subtract the character code for '1'.  
2CA5  ADC A,$00  0 now gives 0 with carry set; 1 gives 0 with carry reset.  
2CA7  JR NZ,BIN_END  Any other character causes a jump to BIN_END and will be checked for syntax during or after scanning.  
2CA9  EX DE,HL  Result so far to HL now.  
2CAA  CCF  Complement the carry flag.  
2CAB  ADC HL,HL  Shift the result left, with the carry going to bit 0.  
2CAD  JP C,REPORT_6  Report overflow if more than 65535.  
2CB0  EX DE,HL  Return the result so far to DE.  
2CB1  JR BIN_DIGIT  Jump back for next 0 or 1.  
BIN_END  2CB3  LD B,D  Copy result to BC for stacking.  
2CB4  LD C,E  
2CB5  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  2CB8  CP "."  Is the first character a '.'?  
2CBA  JR Z,DECIMAL  If so, jump forward.  
2CBC  CALL INT_TO_FP  Otherwise, form a 'last value' of the integer.  
2CBF  CP "."  Is the next character a '.'?  
2CC1  JR NZ,E_FORMAT  Jump forward to see if it is an 'E'.  
2CC3  RST $20  Get the next character.  
2CC4  CALL NUMERIC  Is it a digit?  
2CC7  JR C,E_FORMAT  Jump if not (e.g. 1.E4 is allowed).  
2CC9  JR DEC_STO_1  Jump forward to deal with the digits after the decimal point.  
DECIMAL  2CCB  RST $20  If the number started with a decimal, see if the next character is a digit.  
2CCC  CALL NUMERIC  
DEC_RPT_C  2CCF  JP C,REPORT_C  Report the error if it is not.  
2CD2  RST $28  Use the calculator to stack zero as the integer part of such numbers.  
2CD3  DEFB $A0  stk_zero  
2CD4  DEFB $38  end_calc  
DEC_STO_1  2CD5  RST $28  Use the calculator to copy the number 1 to mem0.  
2CD6  DEFB $A1  stk_one  
2CD7  DEFB $C0  st_mem_0  
2CD8  DEFB $02  delete  
2CD9  DEFB $38  end_calc  
For each passage of the following loop, the number (N) saved in the memory area mem0 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  2CDA  RST $18  Get the present character.  
2CDB  CALL STK_DIGIT  If it is a digit (D) then stack it.  
2CDE  JR C,E_FORMAT  If not jump forward.  
2CE0  RST $28  Now use the calculator.  
2CE1  DEFB $E0  get_mem_0: V, D, N  
2CE2  DEFB $A4  stk_ten: V, D, N, 10  
2CE3  DEFB $05  division: V, D, N/10  
2CE4  DEFB $C0  st_mem_0: V, D, N/10 (N/10 is copied to mem0)  
2CE5  DEFB $04  multiply: V, D*N/10  
2CE6  DEFB $0F  addition: V+D*N/10  
2CE7  DEFB $38  end_calc  
2CE8  RST $20  Get the next character.  
2CE9  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  2CEB  CP "E"  Is the present character an 'E'?  
2CED  JR Z,SIGN_FLAG  Jump forward if it is.  
2CEF  CP "e"  Is it an 'e'?  
2CF1  RET NZ  Finished unless it is so.  
SIGN_FLAG  2CF2  LD B,$FF  Use B as a sign flag, +FF for '+'.  
2CF4  RST $20  Get the next character.  
2CF5  CP "+"  Is it a '+'?  
2CF7  JR Z,SIGN_DONE  Jump forward.  
2CF9  CP ""  Is it a ''?  
2CFB  JR NZ,ST_E_PART  Jump if neither '+' nor ''.  
2CFD  INC B  Change the sign of the flag.  
SIGN_DONE  2CFE  RST $20  Point to the first digit.  
ST_E_PART  2CFF  CALL NUMERIC  Is it indeed a digit?  
2D02  JR C,DEC_RPT_C  Report the error if not.  
2D04  PUSH BC  Save the flag in B briefly.  
2D05  CALL INT_TO_FP  Stack ABS m, where m is the exponent.  
2D08  CALL FP_TO_A  Transfer ABS m to A.  
2D0B  POP BC  Restore the sign flag to B.  
2D0C  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).  
2D0F  AND A  
2D10  JP M,REPORT_6  
2D13  INC B  Test the sign flag in B; '+' (i.e. +FF) will now set the zero flag.  
2D14  JR Z,E_FP_JUMP  Jump if sign of m is '+'.  
2D16  NEG  Negate m if sign is ''.  
E_FP_JUMP  2D18  JP e_to_fp  Jump to assign to the 'last value' the result of x*10↑m. 
Prev: 2C8D  Up: Map 