Prev: 13015 Up: Map Next: 13218
13147: THE 'CALCULATE' SUBROUTINE
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:
  • Binary operations, e.g. addition, where two numbers in floating-point form are added together to give one 'last value'.
  • Unary operations, e.g. sin, where the 'last value' is changed to give the appropriate function result as a new 'last value'.
  • Manipulatory operations, e.g. st_mem, where the 'last value' is copied to the first five bytes of the calculator's memory area.
The operations to be performed are specified as a series of data-bytes, the literals, that follow an RST 40 instruction that calls this subroutine. The last literal in the list is always '56' 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 '59', 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.
Input
B Operation offset or counter
CALCULATE 13147 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).
This entry point is used by the routine at series.
GEN_ENT_1 13150 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.
13151 LD (23655),A
This entry point is used by the routine at series.
GEN_ENT_2 13154 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.
13155 EX (SP),HL
13156 EXX
RE_ENTRY 13157 LD (23653),DE A loop is now entered to handle each literal in the list that follows the calling instruction; so first, always set STKEND.
13161 EXX Go to the alternate register set and fetch the literal for this loop.
13162 LD A,(HL)
13163 INC HL Make HL' point to the next literal.
This entry point is used by the routine at fp_calc_2.
SCAN_ENT 13164 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.
13165 AND A Test the A register.
13166 JP P,FIRST_3D Separate the simple literals from the multi-purpose literals. Jump with literals 0 to 61.
13169 LD D,A Save the literal in D.
13170 AND 96 Continue only with bits 5 and 6.
13172 RRCA Four right shifts make them now bits 1 and 2.
13173 RRCA
13174 RRCA
13175 RRCA
13176 ADD A,124 The offsets required are 62 to 65, and L will now hold double the required offset.
13178 LD L,A
13179 LD A,D Now produce the parameter by taking bits 0, 1, 2, 3 and 4 of the literal; keep the parameter in A.
13180 AND 31
13182 JR ENT_TABLE Jump forward to find the address of the required subroutine.
FIRST_3D 13184 CP 24 Jump forward if performing a unary operation.
13186 JR NC,DOUBLE_A
13188 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.
13189 LD BC,65531
13192 LD D,H
13193 LD E,L
13194 ADD HL,BC
13195 EXX
DOUBLE_A 13196 RLCA As each entry in the table of addresses takes up two bytes the offset produced is doubled.
13197 LD L,A
ENT_TABLE 13198 LD DE,13015 The base address of the table.
13201 LD H,0 The address of the required table entry is formed in HL, and the required subroutine address is loaded into the DE register pair.
13203 ADD HL,DE
13204 LD E,(HL)
13205 INC HL
13206 LD D,(HL)
13207 LD HL,13157 The address of RE_ENTRY is put on the machine stack underneath the subroutine address.
13210 EX (SP),HL
13211 PUSH DE
13212 EXX Return to the main set of registers.
13213 LD BC,(23654) The current value of BREG is transferred to the B register thereby returning the single operation offset (see compare).
The address of this entry point is found in the table of addresses. It is called via the calculator literal 2 by the routines at BEEP, IF_CMD, FOR, NEXT, CIRCLE, DRAW, CD_PRMS1, S_RND, LET, DEC_TO_FP, e_to_fp, FP_TO_BC, PRINT_FP, series, n_mod_m, exp, ln, get_argt and to_power.
delete 13217 RET An indirect jump to the required subroutine.
The delete subroutine contains only the single 'RET' instruction above. The literal '2' results in this subroutine being considered as a binary operation that is to be entered with a first number addressed by the HL register pair and a second number addressed by the DE register pair, and the result produced again addressed by the HL register pair.
The single 'RET' instruction thereby leads to the first number being considered as the resulting 'last value' and the second number considered as being deleted. Of course the number has not been deleted from the memory but remains inactive and will probably soon be overwritten.
Prev: 13015 Up: Map Next: 13218