Trap #1 Codes
D0Description
$00MT_INF / SMS_INFOGet system information
$01MT_CJOB / SMS_CRJBCreate but do not activate a new job
$02MT_INF / SMS_INJBGet information for an existing job
$03Not implemented
$04MT_RJOB / SMS_RMJBRemove an existing (inactive) job
$05MT_FRJOB / SMS_FRJBForce remove an existing job
$06MT_FREE / SMS_FRTPFind the maximum amount of free memory
$07MT_TRAPV / SMS_EXVSet the TRAP Vector table in RAM
$08MT_SUSJB / SMS_SSJBSuspend an existing job
$09MT_RELJB / SMS_USJBRelease an existing job from suspension
$0aMT_ACTIV / SMS_ACJBActivate a newly created job
$0bMT_PRIOR / SMS_SPJBSet a job's priority
$0cMT_ALLOC / SMS_ALHPAllocate user heap space
$0dMT_LNKFR / SMS_REHPFree allocated user heap space
$0eMT_ALRES / SMS_ARPAAllocate resident procedure space
$0fMT_RERESRelease allocated resident procedure space



MT_INF / SMS_INFO - Get system information.
TRAP #1
D0 = $00
Call ParametersReturn Parameters
D1 Unused D1.L Current job id
D2 Unused D2.L QDOS/SMSQ version in ASCII (x.yy)
D3 Unused D3.L Preserved
A0 Unused A0.L Pointer to base of system variables
A1 Unused A1.L Preserved
A2 Unused A2.L Preserved
A3 Unused A3.L Preserved
This trap call does not return any errors.
Notes :

All registers not shown above are not used on entry and are preserved on exit.

Example

The following shows the use of this call to get the location of the SuperBasic PROGD$ device :

        moveq   #mt_inf,d0        ; Trap code
        trap    #1                ; Fetch system information
        move.l  sv_progd(A0),A0   ; A0 now holds the start address of where PROGD$ is stored, or zero
        :                         ; And from there, the device name can be extracted.
        :	

Back to top

MT_CJOB / SMS_CRJB - Create but do not activate a new job
TRAP #1
D0 = $01
Call ParametersReturn Parameters
D1.L ID of the job which will own the job being created D1.L Job id of the created job
D2.L Size, in bytes, of the size of the new job's code space D2.L Preserved
D3.L Size, in bytes, of the new job's data space D3.L Preserved
D7 Unused D7.L Corrupted - set to same value as D1.L
A0 Unused A0.L Base address of the new job. Points to JB_END within the job header
A1.L Start address of the jobs code, or zero A1.L Preserved
A2 Unused A2.L Preserved
A3 Unused A3.L Preserved
Errors returned in D0.L :

ERR_NJ - No room in the QDOS job table, or D1 was not a valid job id on entry
ERR_OM - Not enough memory to create the job.
Notes :

All registers not shown above are not used on entry and are preserved on exit.
D7 is not documented as being corrupted in any docs that I have, personal experience shows otherwise.
If A0.L is zero on entry, then a blank job area will be created ready for you to load some code into, similar to how EXEC works.
If you already have some code in memory, and that code is re-entrant, then set A0.L to the start address of the code, and a new job will be created for you, re-using another job's code.

Example

The following shows the use of this call to create a new job :

        moveq   #mt_cjob,d0       ; Trap code
        moveq   #-1,d1            ; Current job will be the owner
        move.l  #2048,d2          ; Code size is 2048 bytes
        move.l  #1024,d3          ; Data space and stack takes 1024 bytes
        suba.l  a1,a1             ; Indicate I will load code later
        trap    #1                ; Fetch system information
        tst.l   d0                ; Check for errors
        bne.s   <Error handler>   ; Oops, an error occurred
        <Load job's code from a file etc to the address in A0.L>
        :
        :

Back to top

MT_INF / SMS_INJB - Get information for an existing job
TRAP #1
D0 = $02
Call ParametersReturn Parameters
D1.L Id of job to get information for D1.L Id of next job in tree
D2.L Id of job at top of the tree D2.L Parent job's id for the job we enquired upon
D3 Unused D3.L Lowest byte = job's priority
Highest 3 bytes = $FF if job suspended, else zero
A0 Unused A0.L Base address (JB_END) of the job
A1 Unused A1.L Corrupted
A2 Unused A2.L Preserved
A3 Unused A3.L Preserved
Errors returned in D0.L :

ERR_NJ - Invalid job
Notes :

All registers not shown above are not used on entry and are preserved on exit.

This call can be used to scan the entire job tree, by calling it in a loop with D1.L = D2.L = zero, then on each subsequent call, setting D1.L to the value just returned in D1.L. Eventually, D1.L will be returned as zero which indicates end of the tree. If D1.L = D2.L <> zero, then only that sub-tree will be scanned, not the entire tree.

Example

The following shows the use of this call to scan the entire job tree :

        moveq   #0,d1             ; Zero = SuperBasic
        move.l  d1,d2             ; Job at top of tree also = SuperBasic
loop    moveq   #mt_jinf,d0       ; Trap code
        trap    #1                ; Fetch job information, sets D1.L = next job in tree
        tst.l   d0                ; Check for errors
        bne.s   <Error handler>   ; Oops, an error occurred
        tsl.l   d1                ; Are we done yet ?
        beq.s   done              ; Yes, no more jobs
        :
        <Do stuff here with info returned, but preserve D1.L and D2.L>
        :
        bra.s   loop              ; Using D1 and D2's values from the trap, go and do next job
done    <Do stuff here when finished>
        :
        :

Back to top

This trap code is not implemented.
TRAP #1
D0 = $03
Call ParametersReturn Parameters
Errors returned in D0.L :

None, your system will have crashed !

Back to top

MT_RJOB / SMS_RMJB - Remove an existing (inactive) job
TRAP #1
D0 = $04
Call ParametersReturn Parameters
D1.L Id of job to be removed, or -1 for the current job. D1.L Corrupted
D2 Unused D2.L Corrupted
D3.L Error code to return D3.L Corrupted
A0 Unused A0.L Corrupted
A1 Unused A1.L Corrupted
A2 Unused A2.L Corrupted
A3 Unused A3.L Corrupted
Errors returned in D0.L :

ERR_NC - Not complete (Job is active)
ERR_NJ - Invalid job id
Notes :

All registers not mentioned above are unused on entry and preserved on exit.
Job 0 (SuperBasic) cannot be removed.
This trap is not atomic as it can exit via the scheduler - if the current job is being removed.
If the job being removed is active, then ERR_BC (not complete) is returned.
If the job has child jobs, they are removed whether or not they are active - (probably) using MT_FRJOB below.
The error code in D3.L is passed to any job which is waiting for this job to complete.
Any resources - channels, memory etc - owned by the job being removed, or its children, are released.

Example

The following shows the use of this call to remove the current job :

        moveq   #mt_rjob,d0       ; Trap code
        moveq   #-1,d1            ; Indicate the current job
        moveq   #0,d3             ; Don't pass any error codes
        trap    #1                ; Kill this job 
        :
        :

I have a small problem with this, assuming that the current job is removing itself, then it must be active, otherwise, how would it remove itself? This implies that the current job cannot use this call to remove itself. I feel a small delve into the source of QDOS coming on.


Back to top

MT_FRJOB / SMS_FRJB - Force remove an existing job
TRAP #1
D0 = $05
Call ParametersReturn Parameters
D1.L Id of job to be removed, or -1 for the current job. D1.L Corrupted
D2 Unused D2.L Corrupted
D3.L Error code to return D3.L Corrupted
A0 Unused A0.L Corrupted
A1 Unused A1.L Corrupted
A2 Unused A2.L Corrupted
A3 Unused A3.L Corrupted
Errors returned in D0.L :

ERR_NC - Not complete (Job is active)
ERR_NJ - Invalid job id
Notes :

All registers not mentioned above are unused on entry and preserved on exit.
Job 0 (SuperBasic) cannot be removed.
This trap is not atomic as it can exit via the scheduler - if the current job is being removed.
If the job being removed is active, it is inactivated and removed.
If the job has child jobs, they are removed whether or not they are active.
The error code in D3.L is passed to any job which is waiting for this job to complete.
Any resources - channels, memory etc - owned by the job being removed, or its children, are released.

Example

The following shows the use of this call to force remove the current job :

        moveq   #mt_frjob,d0      ; Trap code
        moveq   #-1,d1            ; Indicate the current job
        moveq   #0,d3             ; Don't pass any error codes
        trap    #1                ; Kill this job 
        :
        :

Back to top

MT_FREE / SMS_FRTP - Find the maximum amount of free memory
TRAP #1
D0 = $06
Call ParametersReturn Parameters
D1 Unused D1.L Maximum free space in bytes
D2 Unused D2.L Corrupted
D3 Unused D3.L Corrupted
A0 Unused A0.L Corrupted
A1 Unused A1.L Corrupted
A2 Unused A2.L Corrupted
A3 Unused A3.L Corrupted
Errors returned in D0.L :

None.
Notes :

This trap returns the number of bytes in the biggest free area of Transient Program area or
the number of bytes between SV_BASIC and SV_FREE minus 512 - whichever is the biggest.
Of course, by the time you have the figure, you might still fail to allocate it all if another job has got there first and allocated some space for itself.

Example

The following shows the use of this call :

        moveq   #mt_free,d0       ; Trap code
        trap    #1                ; Kill this job 
        <do stuff here with the number of bytes in D1.L>
        :
        :

Back to top

MT_TRAPV / SMS_EXV - Set the TRAP Vector table in RAM
TRAP #1
D0 = $07
Call ParametersReturn Parameters
D1.L Id of the job for which the TRAP table is to be redirected D1.L Preserved
D2 Unused D2.L Preserved
D3 Unused D3.L Preserved
A0 Unused A0.L Base of job whose id was passed in D1.L
A1 Ponter to new TRAP table. A1.L Corrupted
A2 Unused A2.L Preserved
A3 Unused A3.L Preserved
Errors returned in D0.L :

Err_NJ - Invalid job id.
Notes :

This trap allows a job to redirect the TRAP #5 to TRAP #15 calls and exception handlers, but not all of them, which are normally unused by QDOS/SMS. Different jobs can have different tables, but a job is given the same table as its parent when first created. See the example code for full details of the format of the table etc.

Example

This example code, shows the use of this trap to create an exception handler for an original QL only. Later processors have different stack frames for the Address exception.


Back to top

MT_SUSJB / SMS_SSJB - Suspend an existing job
TRAP #1
D0 = $08
Call ParametersReturn Parameters
D1.L Id of the job to be suspended, or -1 for the current job D1.L Preserved
D2 Unused D2.L Preserved
D3.W Timout period in frame counts, or -1 for indefinite suspension D3.L Preserved
A0 Unused A0.L Base address of job's header
A1.L Address of the flag byte (see below) or zero A1.L Documented as Preserved but isn't
A2 Unused A2.L Preserved
A3 Unused A3.L Preserved
Errors returned in D0.L :

ERR_NJ - Invalid job
Notes :

A1.L is documented as being preserved, but personal experience has shown that it is not always preserved.
The value in D3.W is stored in the job's header at JB_STAT.
The value in A1.L is stored in the header at JB_HOLD.
A frame period is 1/50th in UK/Europe but 1/60th in the USA.
The flag byte will be cleared when the job is released again.
If the job being suspended is already suspended, then the current suspend period is changed to the new one, and the job is re-suspended for the requested period.
This trap always exits via the job scheduler, so it is not atomic.

Example

The following shows the use of this call :

        moveq   #mt_susjb,d0      ; Trap code
        moveq   #-1,d1            ; Suspend myself
        moveq   #50,d3            ; Suspend for one European second or 50/60th American seconds
        suba.l  a0,a0             ; No flag byte required
        trap    #1                ; Suspend the job
        <Do stuff here whan the suspension is over>
        :
        :

Back to top

MT_RELJB / SMS_USJB - Release an existing job from suspension
TRAP #1
D0 = $09
Call ParametersReturn Parameters
D1.L Id of the job to be released D1.L Preserved
D2 Unused D2.L Preserved
D3 Unused D3.L Preserved
A0 Unused A0.L Base address of job's header
A1.L Unused A1.L Preserved
A2 Unused A2.L Preserved
A3 Unused A3.L Preserved
Errors returned in D0.L :

ERR_NJ - Invalid job
Notes :

The flag byte (at JB_HOLD in the job header) will be cleared when the job is released.
This trap always exits via the job scheduler, so it is not atomic.

Example

The following shows the use of this call :

        moveq   #mt_reljb,d0      ; Trap code
        moveq   #<job_id>,d1      ; <job_id> is a known job id
        trap    #1                ; Suspend the job
        :
        :

Back to top

MT_ACTIV / SMS_ACJB - Activate a newly created job
TRAP #1
D0 = $0a
Call ParametersReturn Parameters
D1.L Id of the job to be activated D1.L Preserved
D2.B Priority 0 to 127 but see below D2.L Preserved/Corrupted
D3.W Timeout 0 or -1 D3.L Preserved
A0 Unused A0.L Base address of job's header
A1 Unused A1.L Preserved
A2 Unused A2.L Preserved
A3 Unused A3.L Preserved/Corrupted
Errors returned in D0.L :

ERR_NC - Not complete (Job is already active)
ERR_NJ - Invalid job
Notes :

If the timeout in D3.W is zero, then this equates to EXEC and the job doing the activation will continue to run. Otherwise, it will wait for the job being activated to remove itself using MT_FRJOB before continuing.
Also note that A3.L is corrupted if the timeout was not zero on entry.
The priority passed in D2.B is documented as being in the range 0 to 127, however, it appears that values from 0 to 255 can be used.
Dickens states that D2 is preserved and Pennell says corrupted. Best to assume the worst and consider it corrupted.
This trap is not atomic and always exits via the scheduler.

Example

The following shows the use of this call :

        moveq   #mt_activ,d0      ; Trap code
        moveq   #<job_id>,d1      ; <job_id> is a known job id
        moveq   #32,d2            ; Standard default priority is 32
        moveq   #0,d3             ; Continue executing this job, after activating the other one
        trap    #1                ; Suspend the job
        :
        :

Back to top

MT_PRIOR / SMS_SPJB - Set a job's priority
TRAP #1
D0 = $0b
Call ParametersReturn Parameters
D1.L Id of the job D1.L Preserved
D2.B Priority 0 to 127 but see below D2.L Preserved
D3 Unused D3.L Preserved
A0 Unused A0.L Base address of job's header
A1 Unused A1.L Preserved
A2 Unused A2.L Preserved
A3 Unused A3.L Preserved
Errors returned in D0.L :

ERR_NJ - Invalid job
Notes :

The priority passed in D2.B is documented as being in the range 0 to 127, however, it appears that values from 0 to 255 can be used.
This trap is not atomic and always exits via the scheduler.

Example

The following shows the use of this call :

        moveq   #mt_prior,d0      ; Trap code
        moveq   #-1,d1            ; Change my own priority
        moveq   #1,d2             ; Set priority very low
        trap    #1                ; Change the priority
        :
        :

Back to top

MT_ALLOC / SMS_ALHP - Allocate user heap space
TRAP #1
D0 = $0c
Call ParametersReturn Parameters
D1.L Number of bytes required in user heap D1.L Number of bytes allocated
D2 Unused D2.L Corrupted
D3 Unused D3.L Corrupted
A0 Pointer to pointer to free space (relative A6) A0.L Address of area allocated (relative A6)
A1 Unused A1.L Corrupted
A2 Unused A2.L Corrupted
A3 Unused A3.L Corrupted
Errors returned in D0.L :

ERR_OM - Out of memory (in user heap).
Notes :

A user heap is an area of memory, maybe in the common heap, set aside for use by a single job. The job can allocate areas of this user heap for its own needs, and deallocate them as required. This stops, or reduces fragmentation of the common heap which is used by every task in the system. Look here for more information on heaps.

Example

This example show the use of this, and other, heap manipulation traps :


Back to top

MT_LNKFR / SMS_REHP - Free allocated user heap space
TRAP #1
D0 = $0d
Call ParametersReturn Parameters
D1.L Size of area to be linked (back) in to the user heap D1.L Corrupted
D2 Unused D2.L Corrupted
D3 Unused D3.L Corrupted
A0.L Address of the area of heap/memory to link (back) in to the user heap (Relative A6) A0.L Corrupted
A1.L Pointer to pointer to free space (Relative A6) or zero. A1.L Corrupted
A2 Unused A2.L Corrupted
Errors returned in D0.L : None
Notes :

This trap is used to create a user heap by setting the memory location (long word) that (A1,A6) points to to zero. Then a chunk of memory, probably previously allocated from the common heap is passed in (A0,A6) and you now have a user heap to play with. If the pointer to the free space is not zero, then you are assumed to be 'freeing' a previously allocated chunk of user heap. See the example file for more details.

Example

This example show the use of this, and other, heap manipulation traps :


Back to top

MT_ALRES / SMS_ARPA - Allocate resident procedure space
TRAP #1
D0 = $0e
Call ParametersReturn Parameters
D1.L Number of bytes required D1.L Corrupted
D2 Unused D2.L Corrupted
D3 Unused D3.L Corrupted
A0 Unused A0.L Base address of allocated memory
A1 Unused A1.L Corrupted
A2 Unused A2.L Corrupted
A3 Unused A3.L Corrupted
Errors returned in D0.L :

ERR_NC - Not complete (usually means some jobs are executing)
ERR_OM - Out of memory
Notes :

This trap is how the SuperBasic function RESPR works. It allocates space in the resident procedures area, but only if there are no jobs running.

Example

The following shows the use of this call :

        moveq   #mt_alres,d0      ; Trap code
        move.l  #1024,d1          ; 1 Kbyte required in Resident procedure space
        trap    #1                ; Allocate the space
        tst.l   D0                ; Did it work ?
        bne.s   <error handler>   ; No, handle errors
        <Use space allocated from (A0) onwards>
        :
        :

Back to top

MT_RERES (QDOS only) - Release allocated resident procedure space
TRAP #1
D0 = $0f
Call ParametersReturn Parameters
D1 Unused D1.L Corrupted
D2 Unused D2.L Corrupted
D3 Unused D3.L Corrupted
A0 Unused A0.L Corrupted
A1 Unused A1.L Corrupted
A2 Unused A2.L Corrupted
A3 Unused A3.L Corrupted
Errors returned in D0.L :

ERR_NC - Not complete (Usually means that some jobs are running)
Notes :

This trap has no equivalent under SMS, probably due to the serious danger of crashing the system.
The RESPR area is completely removed by this trap - if there are no jobs running - but, as some device drivers allocate RESPR memory, this can cause subsequent system crashes.
In addition, some versions of QDOS actually allocate more space, rather than releasing all of it.
Best avoided !

Back to top