RI_EXEC/QA_OP and RI_EXECB/QA_MOP - Vectors $11C and $11E
These vectors execute one (RI_EXEC/QA_OP) or a list (RI_EXECB/QA_MOP) of arithmetic operations.
Call Parameters | Return Parameters |
D0.W | Unused or operation | D0.L | Error code. |
D7.L | Should be set to 0 | D7.L | Preserved. |
A1.L | Pointer to maths stack. | A1.L | Updated. |
A3.L | Unused or pointer to list | A3.L | Preserved. |
A4.L | Pointer to variables area | A4.L | Preserved. |
Operations
The odd operation codes less than $30 and code $32 are for SMSQ. These are similar to the codes used in Minerva.
Opcode | Name | Function | Change in A1 |
$00 | - | End of ops | 0 |
$01 | qa_one | push 1 | -6 |
$02 | qa_nint | fp to nearest word integer | +4 |
$03 | qa_zero | push 0 | -6 |
$04 | qa_int | truncate fp to word integer | +4 |
$05 | qa_n | followed by a signed byte to push -128 to 127 | -6 |
$06 | qa_nlint | fp to nearest long word integer | +2 |
$07 | qa_k | followed by a byte pushes a value (see table below) | -6 |
$08 | qa_float | integer word to fp | -4 |
$09 | qa_flong | integer long word to fp | -2 |
$0A | qa_add | add TOS to NOS | +6 |
$0C | qa_sub | subtract TOS from NOS | +6 |
$0D | qa_halve | TOS/2 | 0 |
$0E | qa_mul | TOS*NOS | +6 |
$0F | qa_doubl | TOS*2 | 0 |
$10 | qa_div | NOS/TOS | +6 |
$11 | qa_recip | 1/TOS | 0 |
$12 | qa_abs | absolute value | 0 |
$13 | qa_roll | (TOS)B,C,A → (TOS)A,B,C (roll third to top) | 0 |
$14 | qa_neg | negate | 0 |
$15 | qa_over | NOS (A,B → B,A,B) | -6 |
$16 | qa_dup | duplicate | -6 |
$17 | qa_swap | TOS↔NOS | 0 |
$18 | qa_cos | cosine | 0 |
$1A | qa_sin | sine | 0 |
$1C | qa_tan | tangent | 0 |
$1E | qa_cot | cotangent | 0 |
$20 | qa_asin | arcsine | 0 |
$22 | qa_acos | arccosine | 0 |
$23 | qa_atan2 | arctangent(NOS/TOS) | +6 |
$24 | qa_atan | arctangent | 0 |
$26 | qa_acot | arccotangent | 0 |
$28 | qa_sqrt | square root | 0 |
$29 | qa_squar | TOS*TOS | 0 |
$2A | qa_log | natural logs | 0 |
$2C | qa_l10 | base 10 logs | 0 |
$2E | qa_exp | exponential | 0 |
$30 | qa_pwrf | NOS raised to the power TOS | +6 |
$32 | qa_pi | push pi | -6 |
$33 | - | fp number from stack to -$CE(A4,A6.L) | +6 |
$34 | - | fp number from -$CC(A4,A6.L) to stack | -6 |
$35 | - | fp number from stack to -$CC(A4,A6.L) | +6 |
and so on until . . |
$FC | - | fp number from -4(A4,A6.L) to stack | -6 |
$FD | - | fp number from stack to -4(A4,A6.L) | +6 |
$FE | - | fp number from -2(A4,A6.L) to stack | -6 |
$FF | - | fp number from stack to -2(A4,A6.L) | +6 |
qa_k Table
Byte | Name | Value |
$56 | qak_pi180 | pi/180 |
$69 | qak_loge | log10e |
$79 | qak_pi6 | pi/6 |
$88 | qak_ln2 | ln(2) |
$98 | qak_sqrt3 | sqrt(3) |
$A8 | qak_pi | pi |
$A7 | qak_pi2 | pi/2 |
This example shows how to use RI_EXECB/QA_MOP to calculate (x2 - 1)/(x + 1). The answer is, of course, x - 1 but this gives a check on the operation. It is assumed that A6 points to the data space and that the variables area contains x as a floating point number.
The op codes $FA and $FB push and pop the value at -6(A4,A6.L).
mt equ 30 ; Space for A1 stack.
va equ mt+6 ; 6 bytes for variables area.
ops dc.b $FA ; Push x x
dc.b qa_squar ; ($29) x*x x*x
dc.b qa_one ; ($01) push 1 1 : x*x
dc.b qa_sub ; ($0C) NOS - TOS x*x - 1
dc.b $FA ; Push x x : x*x - 1
dc.b qa_one ; ($01) push 1 1 : x : x*x - 1
dc.b qa_add ; ($0A) NOS + TOS x + 1 : x*x - 1
dc.b qa_div ; ($10) NOS/TOS (x*x - 1)/(x + 1)
dc.b $FB ; Pop answer
dc.b 0 ; Mark end
calc lea mt,a1 ; Bottom of stack (relative to A6).
lea va,a4 ; Bottom of variables area (relative to A6).
lea ops,a3 ; Pointer to operations.
movea.w RI_EXECB,a2 ; RI_EXECB vector address.
jsr (a2) ; Make the call
bne.s Error_handler ; Oops!