|Prev: 32D7||Up: Map||Next: 33A2|
Used by the routine at FP_CALC.
This subroutine is used to perform floating-point calculations. These can be considered to be of three types:
The operations to be performed are specified as a series of data-bytes, the literals, that follow an RST $28 instruction that calls this subroutine. The last literal in the list is always '+38' which leads to an end to the whole operation.
In the case of a single operation needing to be performed, the operation offset can be passed to the calculator in the B register, and operation '+3B', the single calculation operation, performed.
It is also possible to call this subroutine recursively, i.e. from within itself, and in such a case it is possible to use the system variable BREG as a counter that controls how many operations are performed before returning.
The first part of this subroutine is complicated but essentially it performs the two tasks of setting the registers to hold their required values, and to produce an offset, and possibly a parameter, from the literal that is currently being considered.
The offset is used to index into the calculator's table of addresses to find the required subroutine address.
The parameter is used when the multi-purpose subroutines are called.
Note: a floating-point number may in reality be a set of string parameters.
|CALCULATE||335B||CALL STK_PNTRS||Presume a unary operation and therefore set HL to point to the start of the 'last value' on the calculator stack and DE one past this floating-point number (STKEND).|
|GEN_ENT_1||335E||LD A,B||Either transfer a single operation offset to BREG temporarily, or, when using the subroutine recursively, pass the parameter to BREG to be used as a counter.|
|GEN_ENT_2||3362||EXX||The return address of the subroutine is stored in HL'. This saves the pointer to the first literal. Entering the calculator here is done whenever BREG is in use as a counter and is not to be disturbed.|
|RE_ENTRY||3365||LD ($5C65),DE||A loop is now entered to handle each literal in the list that follows the calling instruction; so first, always set STKEND.|
|3369||EXX||Go to the alternate register set and fetch the literal for this loop.|
|336B||INC HL||Make HL' point to the next literal.|
|SCAN_ENT||336C||PUSH HL||This pointer is saved briefly on the machine stack. SCAN_ENT is used by fp_calc_2 to find the subroutine that is required.|
|336D||AND A||Test the A register.|
|336E||JP P,FIRST_3D||Separate the simple literals from the multi-purpose literals. Jump with literals +00 to +3D.|
|3371||LD D,A||Save the literal in D.|
|3372||AND $60||Continue only with bits 5 and 6.|
|3374||RRCA||Four right shifts make them now bits 1 and 2.|
|3378||ADD A,$7C||The offsets required are +3E to +41, and L will now hold double the required offset.|
|337B||LD A,D||Now produce the parameter by taking bits 0, 1, 2, 3 and 4 of the literal; keep the parameter in A.|
|337E||JR ENT_TABLE||Jump forward to find the address of the required subroutine.|
|FIRST_3D||3380||CP $18||Jump forward if performing a unary operation.|
|3384||EXX||All of the subroutines that perform binary operations require that HL points to the first operand and DE points to the second operand (the 'last value') as they appear on the calculator stack.|
|DOUBLE_A||338C||RLCA||As each entry in the table of addresses takes up two bytes the offset produced is doubled.|
|ENT_TABLE||338E||LD DE,$32D7||The base address of the table.|
|3391||LD H,$00||The address of the required table entry is formed in HL, and the required subroutine address is loaded into the DE register pair.|
|3397||LD HL,$3365||The address of RE_ENTRY is put on the machine stack underneath the subroutine address.|
|339C||EXX||Return to the main set of registers.|
|339D||LD BC,($5C66)||The current value of BREG is transferred to the B register thereby returning the single operation offset (see compare).|
|delete||33A1||RET||An indirect jump to the required subroutine.|
|Prev: 32D7||Up: Map||Next: 33A2|