QDOS Internals

Anything you never knew you wanted to know about the Sinclair QL.

User Tools

Site Tools


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 ParametersReturn Parameters
D0.WUnused or operationD0.LError code.
D7.LShould be set to 0D7.LPreserved.
A1.LPointer to maths stack. A1.LUpdated.
A3.LUnused or pointer to list A3.LPreserved.
A4.LPointer to variables areaA4.LPreserved.




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

OpcodeNameFunctionChange in A1
$00 - End of ops 0
$01qa_onepush 1-6
$02qa_nintfp to nearest word integer+4
$03qa_zeropush 0-6
$04qa_inttruncate fp to word integer+4
$05qa_nfollowed by a signed byte to push -128 to 127-6
$06qa_nlintfp to nearest long word integer+2
$07qa_kfollowed by a byte pushes a value (see table below)-6
$08qa_floatinteger word to fp-4
$09qa_flonginteger long word to fp-2
$0Aqa_addadd TOS to NOS+6
$0Cqa_subsubtract TOS from NOS+6
$12qa_absabsolute value0
$13qa_roll(TOS)B,C,A → (TOS)A,B,C (roll third to top)0
$15qa_overNOS (A,B → B,A,B)-6
$28qa_sqrtsquare root0
$2Aqa_lognatural logs0
$2Cqa_l10base 10 logs0
$30qa_pwrfNOS raised to the power TOS+6
$32qa_pipush 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



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!
qdosmsq/vectors/op.txt · Last modified: 2010/04/26 14:30 by george.gwilt