Prev: 32D7 Up: Map Next: 33A2
335B: 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 $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.
Input
B Operation offset or counter
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).
This entry point is used by the routine at series.
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.
335F LD ($5C67),A
This entry point is used by the routine at series.
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.
3363 EX (SP),HL
3364 EXX
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.
336A LD A,(HL)
336B INC HL Make HL' point to the next literal.
This entry point is used by the routine at fp_calc_2.
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.
3375 RRCA
3376 RRCA
3377 RRCA
3378 ADD A,$7C The offsets required are +3E to +41, and L will now hold double the required offset.
337A LD L,A
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.
337C AND $1F
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.
3382 JR NC,DOUBLE_A
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.
3385 LD BC,$FFFB
3388 LD D,H
3389 LD E,L
338A ADD HL,BC
338B EXX
DOUBLE_A 338C RLCA As each entry in the table of addresses takes up two bytes the offset produced is doubled.
338D LD L,A
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.
3393 ADD HL,DE
3394 LD E,(HL)
3395 INC HL
3396 LD D,(HL)
3397 LD HL,$3365 The address of RE_ENTRY is put on the machine stack underneath the subroutine address.
339A EX (SP),HL
339B PUSH DE
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).
The address of this entry point is found in the table of addresses. It is called via the calculator literal +02 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 33A1 RET An indirect jump to the required subroutine.
The delete subroutine contains only the single 'RET' instruction above. The literal '+02' 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: 32D7 Up: Map Next: 33A2