qdosmsq:vectors:op

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. |

ERR_OV | Overflow. |

- All registers not shown above are not used on entry and are preserved on exit.
- D7 MUST be zero for qa_exp.
- The detailed list of operations is given below. Unless otherwise stated, all operations are on floating point numbers on the maths stack.
- The operations $00 to $32 are all performed on numbers on the stack. Operations $33 to $FF transfer 6 bytes (the length of a floating point number) between the maths stack and the variables area.
- D0.W contains the single operation code for RI_EXEC/QA_OP and is unused for RI_EXECB/QA_MOP. Bits 8 to 15 of D0.W are not used and can take any value for operations $33 to $FF, but
**must**be zero for the other operations. - Operations qa_n ($05) and qa_k ($07) cannot be used as a single operation.
- (A1,A6.L) points to the maths stack.
- For RI_EXECB/QA_MOP A3 points to a list of operations, each one byte long. The list is ended by a zero byte.
- (A4,A6.L) points to the bottom of an area which can contain variables.

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 |

Byte | Name | Value |
---|---|---|

$56 | qak_pi180 | pi/180 |

$69 | qak_loge | log_{10}e |

$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 (x^{2} - 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!

qdosmsq/vectors/op.txt · Last modified: 2010/04/26 14:30 by george.gwilt