| Routines

353B: THE 'COMPARISON' OPERATIONS (offsets +09 to +0E, +11 to +16)

The address of this routine is found in the table of addresses. It is called indirectly via fp_calc_2. This subroutine is used to perform the twelve possible comparison operations (offsets +09 to +0E and +11 to +16: '<=', '>=', '<>', '>', '<' and '=' for numbers and strings respectively). The single operation offset is present in the B register at the start of the subroutine.
Input
B | Operation offset (+09 to +0E, +11 to +16)
DE | Address of the first byte of the second argument
HL | Address of the first byte of the first argument
compare | 353B | LD A,B | The single offset goes to the A register.
| 353C | SUB $08 | The range is now +01 to +06 and +09 to +0E.
| 353E | BIT 2,A | This range is changed to +00, +01, +02, +04, +05, +06, +08, +09, +0A, +0C, +0D, +0E.
| 3540 | JR NZ,EX_OR_NOT
| 3542 | DEC A
EX_OR_NOT | 3543 | RRCA | Then reduced to +00 to +07 with carry set for 'greater than or equal to' and 'less than'; the operations with carry set are then treated as their complementary operation once their values have been exchanged.
| 3544 | JR NC,NU_OR_STR
| 3546 | PUSH AF
| 3547 | PUSH HL
| 3548 | CALL exchange
| 354B | POP DE
| 354C | EX DE,HL
| 354D | POP AF
NU_OR_STR | 354E | BIT 2,A | The numerical comparisons are now separated from the string comparisons by testing bit 2.
| 3550 | JR NZ,STRINGS
| 3552 | RRCA | The numerical operations now have the range +00 to +01 with carry set for 'equal' and 'not equal'.
| 3553 | PUSH AF | Save the offset.
| 3554 | CALL subtract | The numbers are subtracted for the final tests.
| 3557 | JR END_TESTS
STRINGS | 3559 | RRCA | The string comparisons now have the range +02 to +03 with carry set for 'equal' and 'not equal'.
| 355A | PUSH AF | Save the offset.
| 355B | CALL STK_FETCH | The lengths and starting addresses of the strings are fetched from the calculator stack.
| 355E | PUSH DE
| 355F | PUSH BC
| 3560 | CALL STK_FETCH
| 3563 | POP HL | The length of the second string.
BYTE_COMP | 3564 | LD A,H |
| 3565 | OR L |
| 3566 | EX (SP),HL |
| 3567 | LD A,B |
| 3568 | JR NZ,SEC_PLUS | Jump unless the second string is null.
| 356A | OR C |
SECND_LOW | 356B | POP BC | Here the second string is either null or less than the first.
| 356C | JR Z,BOTH_NULL |
| 356E | POP AF |
| 356F | CCF | The carry is complemented to give the correct test results.
| 3570 | JR STR_TEST
BOTH_NULL | 3572 | POP AF | Here the carry is used as it stands.
| 3573 | JR STR_TEST
SEC_PLUS | 3575 | OR C |
| 3576 | JR Z,FRST_LESS | The first string is now null, the second not.
| 3578 | LD A,(DE) | Neither string is null, so their next bytes are compared.
| 3579 | SUB (HL)
| 357A | JR C,FRST_LESS | Jump if the first byte is less.
| 357C | JR NZ,SECND_LOW | Jump if the second byte is less.
| 357E | DEC BC | The bytes are equal; so the lengths are decremented and a jump is made to BYTE_COMP to compare the next bytes of the reduced strings.
| 357F | INC DE
| 3580 | INC HL
| 3581 | EX (SP),HL
| 3582 | DEC HL
| 3583 | JR BYTE_COMP
FRST_LESS | 3585 | POP BC |
| 3586 | POP AF |
| 3587 | AND A | The carry is cleared here for the correct test results.
STR_TEST | 3588 | PUSH AF | For the string tests, a zero is put on to the calculator stack.
| 3589 | RST $28
| 358A | DEFB $A0 | stk_zero
| 358B | DEFB $38 | end_calc
END_TESTS | 358C | POP AF | These three tests, called as needed, give the correct results for all twelve comparisons. The initial carry is set for 'not equal' and 'equal', and the final carry is set for 'greater than', 'less than' and 'equal'.
| 358D | PUSH AF
| 358E | CALL C,f_not
| 3591 | POP AF
| 3592 | PUSH AF
| 3593 | CALL NC,greater_0
| 3596 | POP AF
| 3597 | RRCA
| 3598 | CALL NC,f_not
| 359B | RET | Finished.