\t Things

\j \pn Things are general-purpose resources which may be used by any code
in the system, either from device drivers or directly from programs.  In
principle a Thing may be shareable by a finite or "infinite" number of "users",
or restricted to one user at a time.  A run-time system will be infinitely
shareable, a two-port serial chip may have two users, and so on.
The operating system provides suitable facilities for adding, removing and
using Things.

Things are kept in a linked list, each one being identified by a name which
must be unique.  A new thing is added by setting up a suitable linkage block
and then calling the operating system routine to link it into the list: the
new thing will be rejected if its name is not unique.  The linkage block
must be in the common heap so that it may be
discarded correctly when the Thing is removed.  Each Thing has a version ID
which will be returned to any Job which uses the Thing: this may be the familiar
ASCII number, e.g. "1.03", or a bit map of implemented facilities, e.g.
%10000101.  Thing names are set to lowercase when linked in: names passed
are compared in a case independent manner.

A piece of code that wishes to use a Thing supplies the system routine
with the name of the Thing, and any additional parameters the Thing itself
may require: this is very similar to the IOSS open call, except that the
result returned is an address, not an "ID".  The meaning of this address
depends on what the Thing is.  If the call to use a Thing is successful,
then a new entry is made in the Thing's "usage list", marking the Thing as
used by the given Job.

A piece of code may "free" a given Thing either by an explicit call to do
so, or, if it is a Job, by being removed.  As the code may "own" more than
one instance of a thing (e.g. two serial ports), parameters may be
passed to the Thing's FREE code to signal which instance is to be
discarded.  If the owner is a Job which is being removed, a special
"Forced FREE" routine is called.  If a Thing is freed on behalf of another
job, then that Job will be removed.

If a Thing is not in use it may be removed from the list by the
system routine provided, and its linkage block discarded.  An attempt
to remove a Thing that is in use will cause an error, in which case its
linkage block must not be discarded.   A Thing may supply a "remove" routine
to tidy itself up before removal - for instance, a parallel I/O port
would be set to all inputs.

A routine is provided to "force remove" a Thing.  If the Thing is in use,
then all Jobs using it will also be removed (with the exception of the
Job that is doing the forced remove, unless that Job
is owned by a Job that is itself using the Thing).  In this case the linkage
block is automatically returned to the common heap.

\f Thing linkage format

\j Items from TH_THING onwards (inclusive) must
be filled in by the initialsation code before a new thing is added with
the SMS.LTHG routine.

\f
SV_THING  $B8   long     points to first linkage block

TH_NXTTH  $00   long     points to NeXT THing linkage block
TH_USAGE  $04   long     USAGE list
TH_FRFRE  $08   long     code called when Force Remove FREes a thing
TH_FRZAP  $0C   long     code called when thing owner is removed
*
TH_THING  $10   long     points to THING itself
TH_USE    $14   long     code to invoke to USE the thing, or 0
TH_FREE   $18   long     code to invoke to FREE the thing, or 0
TH_FFREE  $1c   long     code to Force FREE a thing, or 0
TH_REMOV  $20   long     code to tidy up before REMOVing a thing, or 0
TH_NSHAR  $24   byte     byte set if Thing Not SHAReable
TH_VERID  $26   long     version ID, e.g. "1.03"  or %1011101
TH_NAME   $2a   w+bytes  NAME of thing


\f Thing header format

\j All offsets are relative to the address of the flag.

\f
THH_FLAG  $00   4 bytes  flag signalling standard header: value "THG%"
THH_TYPE  $04   long     type of Thing: -1=the THING code itself
                                         0=utility code (free format)
                                         1=executable code
                                         2=shared data (free format)
                                         3=extension code (user mode)
                                         4=extension code (supervisor mode)
                         bit 24 is set if the set if the Thing has a list
                            Things within it.

List of Things Header

THH_NEXT  $08   long     offset of next Thing in list (0 for last)
THH_EXID  $0c   long     extra ID

Executable Thing Header

THH_HDRS  $08   long     offset to start of header
THH_HDRL  $0c   long     size of header
THH_DATA  $10   long     dataspace
THH_STRT  $14   long     absolute pointer to start of code or
                           0 to start at (copy of) header

Extension Thing Header

THH_PDEF  $10   long     offset to parameter definitions (or 0)
THH_PDES  $14   long     offset to parameter descriptions
THH_CODE  $18            entry point for extension code - should exit with RTS


\j \pn A typical header might be

\f Different sorts of Thing

\j \pn Things may take many forms, but it may be useful to mention a few
"tricks" relating to specific ones here.  In particular, the programmer who
wishes to make use of Things \pi must \pn cater for the eventuality that his
Thing will be removed, probably forcibly.

Things in ROM will often link themselves in at boot: it may be desirable
to have a SuperBASIC procedure to re-link them if removed, but otherwise
no special problems present themselves.

Thing loaded into the resident procedure area act in a very similar way
to ROM Things, except that if removed there is wasted RAM where the Thing is
loaded.

Things loaded into the Transient Program area as active or inactive Jobs
can have the space used reclaimed when they are removed.  There are two ways
in which such a Thing can be removed, one is by a Thing call (RTHG or ZTHG)
and the other is via a remove Job call (FRJB).  The Thing remove code
must ensure that if the Job is removed, the Thing goes away, and vice versa.
This may be accomplished by ensuring that the Job owns the Thing linkage
block, and that the Thing remove code (a) sets the Job's PC to some code
which will cause it to remove itself, (b) sets the Job's priority to 127, and
(c) releases it from any current suspension.  Note that as the Thing remove
code is called from supervisor mode, it must not itself remove the Job.

Things loaded into common heap are the easiest to deal with.  The easiest case 
is where the Thing can be loaded into a suitably extended Thing linkage block,
in which case no special code is required.  If this is not possible, the
Thing remove code must release the heap entry containing the Thing.  While
it is conceivable that the heap containing the Thing will be released by some
outside agency without calling a Thing remove routine, any such action may be
regarded as so incredibly hostile that no precautions need be taken against it.
This contrasts with the "unexpected" removal of a Job, which may be regarded
as a fairly normal occurrence.

Hardware Things will frequently have some code or workspace in
one or other of the above areas of RAM.  The same comments thus apply, with
the extra requirement that the hardware be placed in a "safe" state when
the Thing controlling it is removed.  Ideally this safe state will be the same
as that obtained by resetting the computer.

\f
|                                                                      |
|  Trap #1   D0=$26     SMS.LTHG      Link in new Thing                |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1                                 D1    preserved                  |
|  D2                                 D2    preserved                  |
|  D3                                 D3    preserved                  |
|                                     D4+   all preserved              |
|                                                                      |
|  A0                                 A0    preserved                  |
|  A1    address of Thing linkage     A1    preserved                  |
|  A2                                 A2    preserved                  |
|                                     A3+   all preserved              |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        FEX    Thing of this name already exists                      |
|                                                                      |
\j
The linkage block should have TH_THING, TH_USE, TH_FREE, TH_FFREE, 
TH_REMOV, TH_VERID TH_SHARE and
TH_NAME filled in before this call is made: it must be allocated in the
common heap so that SMS.ZTHG, or SMS.RTHG called from another program,
can de-allocate the linkage block correctly.  The name in the linkage
block is set to lower case, to speed searching.

\f
|                                                                      |
|  Trap #1   D0=$27     SMS.RTHG      Remove Thing from list           |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1                                 D1    preserved                  |
|  D2                                 D2    preserved                  |
|  D3                                 D3    preserved                  |
|                                     D4+   all preserved              |
|                                                                      |
|  A0    name of Thing to remove      A0    preserved                  |
|  A1                                 A1    preserved                  |
|  A2                                 A2    preserved                  |
|                                     A3+   all preserved              |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        FDIU   Thing is in use                                        |
|                                                                      |
\j
This routine removes a Thing from the system, if it is not in use. It
will be of use where a different version of someThing is required.  The Thing
linkage block will have been returned to the common heap
if this call succeeds.

\f
|                                                                      |
|  Trap #1   D0=$28     SMS.UTHG      Use Thing                        |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1   Job ID                        D1    Job ID                     |
|  D2   parameter                     D2    returned result            |
|  D3   timeout                       D3    version                    |
|                                     D4+   all preserved              |
|                                                                      |
|  A0   name of Thing to use          A0    preserved                  |
|  A1                                 A1    pointer to Thing           |
|  A2   parameter                     A2    pointer to Thing linkage   |            |
|                                     A3+   all preserved              |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        ITNF   Thing was not found                                    |
|        NIMP   Extension not found                                    |
|               any returns from Thing's USE code                      |
|                                                                      |
\j
Request the use of a Thing for a given Job.  Various extra parameters
may be required for the Thing's USE code to determine whether the
request can be granted - it is up to the provider of the Thing to document
what these parameters are.  Similarly, extra results may be returned.
For an Extension Thing, D2 should be 0 or the required Extension ID.

\f
|                                                                      |
|  Trap #1   D0=$29     SMS.FTHG      Free Thing                       |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1   user Job ID                   D1    preserved                  |
|  D2   parameter                     D2    returned result            |
|  D3   parameter                     D3    preserved                  |
|                                     D4+   all preserved              |
|                                                                      |
|  A0   name of Thing to free         A0    preserved                  |
|  A1   parameter                     A1    preserved                  |
|  A2   parameter                     A2    returned result            |
|                                     A3+   all preserved              |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        ITNF   Thing was not found                                    |
|               any returns from Thing's FREE code                     |
|                                                                      |
\j
This routine will usually be called when a Job no longer requires the
use of a Thing.  If a Thing is freed on behalf of a Job other than the
calling Job, then the user Job is removed, as it would probably otherwise
continue trying to use the Thing.
As with the call to use a Thing, additional parameters may be
required or returned by the Thing itself.

\f
|                                                                      |
|  Trap #1   D0=$2A     SMS.ZTHG      Zap Thing                        |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1                                 D1    preserved                  |
|  D2                                 D2    preserved                  |
|  D3                                 D3    preserved                  |
|                                     D4+   all preserved              |
|                                                                      |
|  A0   name of Thing to zap          A0    preserved                  |
|  A1                                 A1    preserved                  |
|  A2                                 A2    preserved                  |
|                                     A3+   all preserved              |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        ITNF   Thing was not found                                    |
|                                                                      |
\j
This routine removes a Thing and all Jobs using it.
The call may not return, if the Job that called it was removed as
a result of the zap.  Because of this, it may not be called from
supervisor mode under QDOS.  The Thing linkage block is returned to the
common heap by this call.

\f
|                                                                      |
|  Trap #1   D0=$2B     SMS.NTHG      Next Thing                       |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1                                 D1    preserved                  |
|  D2                                 D2    preserved                  |
|  D3                                 D3    preserved                  |
|                                     D4+   all preserved              |
|                                                                      |
|  A0   thing name or 0               A0    preserved                  |
|  A1                                 A1    next thing linkage or 0    |
|  A2                                 A2    preserved                  |
|                                     A3+   all preserved              |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        ITNF   Thing was not found                                    |
|                                                                      |
\j This routine allows code to scan the Thing list to
find out what Things are available.  On each call the address of the
next thing linkage block in the list is returned, with 0 being returned
when the end of the list is reached.  If a zero pointer to a thing
name is passed then the first block in the list will be
returned.  The following code will thus scan the entire Thing list:

\f \mn
        SUB.L   A0,A0           ; start of list
SLOOP
        MOVEQ   #SMS.NXTH,D0    ; find next Thing
        TRAP    #DO.SMS2
        MOVE.L  A1,D0           ; was there another Thing?
        BEQ.S   SDONE           ; no
        BSR     \mi PROC  \mn   ; yes, process it
        LEA     TH_NAME(A1),A0  ; point to this Thing's name
        BRA.S   SLOOP           ; and find the next Thing
SDONE

\f \pn
|                                                                      |
|  Trap #1   D0=$2C     SMS.NTHU      Next Thing User                  |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1                                 D1    preserved                  |
|  D2                                 D2    owner of usage block       |
|  D3                                 D3    preserved                  |
|                                     D4+   all preserved              |
|                                                                      |
|  A0   thing name                    A0    preserved                  |
|  A1   thing usage block or 0        A1    next usage block or 0      |
|  A2                                 A2    preserved                  |
|                                     A3+   all preserved              |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        ITNF   Thing was not found                                    |
|        IJOB   usage block was not found                              |
|                                                                      |
\j
This routine allows code to scan the usage list of a given Thing to find
out which Jobs are using it. It returns in D2 the ID of the owner of the usage
block passed, unless A1 was zero, in which case D1 is undefined. All
blocks have been scanned when the returned usage block pointer is 0.
Note that the format of the usage block may change, so the returned address 
should only be used as a parameter for this routine.  Note also that
a Job may cease using the Thing between calls to this routine.
The usage list of a Thing may be scanned thus:

\f \mn
        LEA     \mi NAME\mn ,A0 ; point to Thing name
        SUB.L   A1,A1           ; start with first usage block
SLOOP
        MOVEQ   #SMS.NTHU,D0    ; find next user
        TRAP    #DO.SMS2
        MOVE.L  A1,D0           ; was there another?
        BEQ.S   SDONE           ; no
        BSR     \mi PROC  \mn   ; process this user
        BRA.S   SLOOP           ; and see if there's another
SDONE

\f \pn Thing-supplied code

\j \pn More complex Things may need to provide code to be invoked when
the Thing is used, freed and removed.  The addresses of any such routines
must be filled in in the Thing linkage block before the SMS.LTHG routine
is called to add the Thing into the list. If a routine address is zero then
the internal routines will be used - these cater for the most frequent case
of an infinitely-shareable thing.  All the following routines will be called
in Supervisor mode, and should end with an RTS instruction.  Note that as
a result of this, they must not call any of the non-atomic TRAPs.

\f
|                                                                      |
|  Thing use routine                  TH_USE                           |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1    Job ID                       D1    ???                        |
|  D2    additional parameter         D2    additional result          |
|  D3    additional parameter         D3    ???                        |
|                                     D4+   ???                        |
|                                                                      |
|  A0                                 A0    usage block                |
|  A1    Thing linkage block          A1    ???                        |
|  A2    additional parameter         A2    additional result          |
|                                     A3-A5 ???                        |
|  A6    system variables             A6    ???                        |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        D0 and the status register must be set                        |
|                                                                      |
\j
This routine will be called from within the SMS.UTHG routine to generate
a non-standard usage block.  If the Thing cannot be used, or the parameters
supplied are incorrect, then an error may be returned instead.  The usage
block pointed to by A0 should be a standard heap entry as allocated
by the MEM.ACHP vector (A0 points to the header, not the "usable memory),
of which the first $18 bytes (heap header + 8) are reserved for the use
of the operating system.  Additional parameters passed by the calling
code in D2/D3/A2 are unchanged, and results may be returned to the
calling code in D2 and A2.

\f
|                                                                      |
|  Thing free routine                 TH_FREE                          |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|  D1    Job ID                       D1    ???                        |
|  D2    additional parameter         D2    additional result          |
|  D3    additional parameter         D3    ???                        |
|                                     D4+   ???                        |
|                                                                      |
|  A0    usage block                  A0    usage block to unlink      |
|  A1    Thing linkage block          A1    ???                        |
|  A2    additional parameter         A2    additional result          |
|                                     A3-A5 ???                        |
|  A6    system variables             A6    ???                        |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        It is assumed that this routine always succeeds               |
|                                                                      |
\j
This routine will be called from within the SMS.FTHG routine to remove
a non-standard usage block.  A0 points to the first usage block in
the Thing's usage list that is owned by the Job specified - depending on
the passed parameters this may or may not be the usage block to
be removed.  When the correct usage block has been found, any internal
tidying up should be performed, and the block should be returned to the
heap.
Its address should then be returned so that it may be
unlinked from the usage list.

\f
|                                                                      |
|  Thing forced free routine          TH_FFREE                         |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|                                     D1+   ???                        |
|                                                                      |
|  A0    usage block                  A0    preserved                  |
|  A1    Thing linkage block          A1    ???                        |
|                                     A2-A5 ???                        |
|  A6    system variables             A6    ???                        |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        It is assumed that this routine always succeeds               |
|                                                                      |
\j
This routine will be called from within the operating system when the
Job that owns the usage block pointed to is force removed.  One call
will be made for each usage block in the Thing's usage list.  As with the
standard free routine, the usage block should be returned to the heap
by this routine.

\f
|                                                                      |
|  Thing remove routine               TH_REMOV                         |
|                                                                      |
|  Call parameters                    Return parameters                | 
|                                                                      | 
|                                     D1+   ???                        |
|                                                                      |
|  A0                                 A0    ???                        |
|  A1    Thing linkage block          A1    ???                        |
|                                     A2-A5 ???                        |
|  A6    system variables             A6    ???                        |
|                                                                      |
|  Completion codes                                                    |
|                                                                      |
|        It is assumed that this routine always succeeds               |
|                                                                      |
\j
This routine is called from the SMS.RTHG and SMS.ZTHG routines when
a Thing is to be removed entirely.  It should ensure that everything
associated with the Thing is in a "safe" state: this would include
setting hardware to a suitable state, freeing any extra heap entries and so
on.  It must also return the Thing linkage block to the heap.
