QL· Technical Guide
QL· Technical Guide
Guide
ISBN 1 850160368
1
Contents continued
9.0 Interfacing to SuperBASIC 47
9.1 Memory Organisation within the SuperBASIC Area 47
9.2 The Name Table 48
9.3 Name List 49
9.4 Variable Values Area 49
9.5 Storage Formats 50
9.6 Code Restrictions 52
9.7 Linking in New Procedures and Functions 52
9.8 Parameter Passing 52
9.9 Getting the Values of Actual Parameters 53
9.10 The Arithmetic Stack Returned Values 54
9.11 The Channel Table 55
2
/
3
1.0 About this Guide
This guide describes the methods which may be used for machine code
programming on the QL. Its contents are also relevant to compiler
writers who must implement a run-time library for other languages. This
guide describes only those techniques which are specific to the QL. It does
not contain a general description of 68000 or 68008 assembly language
programming: this information can be obtained from a number of different
sources, details of which may be found in the bibliography. It is, therefore,
strongly recommended that a reference book describing 68000
assembly language be consulted before attempting to understand this
guide.
The guide also gives details of how various peripherals such as hard
disk interfaces, add-on memory and ROM cartridges may be added on to the
QL, with many details about how the firmware for such devices should be
written.
4
The commercial section of this guide sets out the various options
offered by Sinclair Research for the distribution of QL Software. Its aim is to
give you an idea of the way in which we work and the likely
channels through which a potential product would pass before it is
accepted for publication and offered for sale to our customers. The
section also gives information on the purchase and duplication of
Microdrive cartridges.
Finally, should you feel that anything essential is missing from this manual
we would be very grateful if you would write and tell us. The address to write
to is:
5
2.0 Introduction to Qdos
Qdos is the QL operating system. It is a single-user multi-tasking
operating system: that is, it provides the means for several independent
programs to run concurrently in the QL, but does not provide any
mechanisms to prevent those programs from interfering with each other.
Qdos can be thought of as a collection of several things:
The Qdos mechanisms for start-up are described in section 2.4. Once
start-up has been performed, Qdos does not "run" in the sense that traditional
operating systems run: its pieces of code and data structures simply exist for
programs to use. There is no Qdos "main program" that maintains continuous
control of the machine: the SuperBASIC interpreter, which takes the place of
the command interpreter found in traditional operating systems, is simply a
program which runs on the QL and uses Qdos's facilities, albeit with a number
of special provisions. It is possible, and indeed commonly done, to destroy the
SuperBASIC interpreter completely, and yet still use all the facilities of the
operating system.
Note that in this guide, hex numbers are preceded by a dollar sign ($)
as used in the Motorola assembly language format.
6
2.1 Memory Map
This section describes how Qdos maintains its RAM area. In the QL, the RAM
starts with the screen RAM at address $20000, and the area available to
Qdos starts at $28000. In an unexpanded QL, the RAM finishes at $3FFFF,
whilst in a QL with expansion memory, the RAM may go up as far as $BFFFF.
The Qdos initialisation routine determines the amount of RAM present and
adjusts the position of its pointers accordingly.
2.1.1 Principles-
There is no memory management hardware in the QL. This means that all
code must execute from fixed addresses in physical memory, and
that a piece of code may not be moved after it has been loaded into
memory. For this reason, memory is usually allocated in fixed size areas which
remain in a fixed location until deleted. The SuperBASIC area is an important
exception to this.
7
This block is normally located at address $28000, but is not fixed at this
address in principle. Applications programs should not rely on that
fixed address, but should get the address of the base of system
variables by calling the MT.INF trap (see section 13.0).
The user code needs to retain one pointer to the free space in the heap. This is
a long word and is a relative pointer to the free space in the heap. When the
heap has no free space, either because it does not exist, or because it is full,
this pointer is zero.
8
2.1.5 Free Memory Area-
The free memory area is used by Qdos as a buffer memory for the
Microdrives, or, if Qdos is suitably extended, for other filing system devices.
The area is structured as a collection of slave blocks, that is,
blocks which are associated with a physical block on a medium. When
memory is allocated in another area which would encroach on the free
memory area, Qdos must remove one or more slave blocks. Before such a
removal takes place, Qdos ensures that a true copy of the information is
present on the medium.
Whilst the common heap grows upwards into the free memory area, the areas
above it grow downwards into it. As there are three areas above it (the
resident procedure area, the transient program area and the SuperBASIC
area), special provisions are made so that all three can grow at the
appropriate times.
All references to the SuperBASIC area are made relative to the address
register A6, and the value of A6 on entry to the interpreter is adjusted by Qdos
to the current base of the SuperBASIC area (which is held in the system
variable SV_BASIC), offset by the length of the interpreter's job header
(currently $68 bytes).
The SuperBASIC interpreter divides its working area into several portions,
details of which may be found by looking at the BV definitions in section 18.3.
All of the pointers to these various portions are also relative to A6.
9
2.1.7 Transient Program Area-
The transient program area is the area of memory into which the user's
applications programs are loaded. Each job is allocated a block of
memory in the transient program area, which it keeps until it is deleted:
this area is used for the job's code, data and stack. Programs loaded in this
way are not normally re-entrant, but it is relatively straightforward
to use the mechanisms in the system to set up a single piece of code which
is shared by several different jobs with different data areas.
The area is normally used to load in machine code procedures and functions
written to extend the SuperBASIC language (see section 9.7), and occasionally
for loading in the code of device drivers when these are not located in ROM in
an add-on device.
2.2.1 Traps-
Traps are called using the 68008 TRAP #n instruction: on the QL, this has the
effect of a subroutine call to a defined location which has the side effect of
saving the status register and entering supervisor mode.
10
Of the sixteen trap numbers available on the 68008, numbers 0 to 4 inclusive are
defined for use by Qdos, the remainder being free for the user to redirect to his own
routines. Roughly speaking, the traps are utilised as follows:
Traps are called by setting up any required parameters in registers A0-A3 and
D1-D3, setting up the code for the required trap in DO (usually with a MOVEQ
instruction), then executing the TRAP instruction. Trap routines do not affect D4
to D7 or A4 to A6. There are, however, a few defined cases which are
exceptions to this.
When the TRAP operation is complete, control is returned to the program at the
location following the TRAP instruction, with an error key in all 32 bits of D0. This
key is set to zero if the operation has been completed successfully, and is set to a
negative number for any of the system-defined errors (see section 17.1 for a list of
the meanings of the possible error codes). The key may also be set to a positive
number, in which case that number is a pointer to an error string, relative to address
$8000. The string is in the usual Qdos form of a word giving the length of the string,
followed by the characters.
Note that all traps can return the error code ERR.BP (for bad parameter).
Note also that the condition codes may not be set according to the error code
on return from a trap, thus a program wishing to detect an error should
execute a TST.L DO instruction immediately after the TRAP instruction.
11
2.2.2 Vectored Routines-
In addition to the routines accessed by traps, there are several utility
routines which are available to the applications program: their
addresses are held in a vector table which is located in the ROM
starting at address $CO. A vectored routine can be accessed by the
following code:
MOVE.W VECTOR_ADDRESS,An
JSR (An)
MOVE.W VECTOR_ADDRESS,An
JSR $4000(An)
The entries in section 16.0 for vectored routines which require this
treatment are suitably marked.
MOVE.W VECTOR_ADDRESS,An
JSR $4000(An)
BRA.S BAD_MEDIUM_ERROR
BRA.S BAD_SECTOR_ERROR
12
BAD_MEDIUM_ERROR
* Code for processing a bad medium error starts here
"
“
“
BAD_SECTOR_ERROR
* Code for processing a bad sector error starts here
"
“
“
Obviously, a similar mechanism can be used with any number of error returns
(including zero or one).
A job should only use 64 bytes on the supervisor stack, and all of the space
used on this stack must be released before exiting supervisor mode. In
general, there should be nothing on the supervisor stack when a manager
trap is made.
Some system calls are only partially atomic, that is, when they have
completed their primary function, some other job may gain a share of CPU
time before control returns to the calling job. These partially atomic system
calls must not be made from a job in supervisor mode. All of the scheduler
calls (ie, TRAP #1 with DO=4, 5, 8, 9, $A, $8) fall into this category, as do all
the I/O calls (TRAP #3), unless immediate return (timeout<>0) is specified.
13
A piece of code in supervisor mode can be interrupted by the frame (50/60
Hz) or external interrupts, so care must be taken, when writing interrupt
servers, that the system's internal data structure is not modified, directly or
indirectly, by system calls. In practice, since interrupt servers tend only to be
moving data into or out of queues, this is not a serious limitation.
User traps 5 to 15 inclusive, together with the software error traps for "address
error", "illegal instruction", "divide by zero", "check array", "trap on overflow",
"privilege violation" and "trace" are redirectable by the user on a per-job basis:
see the entry for MT.TRAPV in section 13.0.
Traps and exception vectors which are not used by Qdos may be redirected
through a table which is set up by a particular job.
If a job has set up a table of trap vectors for itself, then that table will
automatically be used when that particular job is being executed. The
vector tables used by other jobs will not be affected. A job set up by, even if
not owned by, a job which has set up a table of trap vectors, will use the
same table as that job, until it is redefined.
If the job ID is a negative word, then the table will be set up for the calling
job.
14
The table is in the form of a long word address for each trap or
exception. They are in the following order:
15
2.4 Start-up
The first thing that Qdos does when the system is reset is to execute a
RAM test. This test determines the amount of contiguous RAM present, and if there is
any RAM failure, hangs up the machine.
Qdos then initialises the system variables, the system management tables, and the
SuperBASIC area.
The address $COOO is then checked by Qdos for the characteristic longword
$4AFB0001: if this is found, Qdos links in the SuperBASIC procedures contained in
the ROM, prints out the name of the ROM, and performs a JSR to its initialisation
point (details of the correct format of the ROM are found in section 8.0 on ROM
device drivers). It is perfectly in order for the code in this ROM to take over the
machine completely and never return to the system, for example if another
operating system were being booted.
Qdos then does the same for the other ROMs in the expansion slots.
If all of these ROMs return control to Qdos, the next action is to try to open a
device driver "BOOT": if this is found, its contents are loaded as a SuperBASIC
program and executed. If no device driver "BOOT" has been linked in, Qdos
attempts to find a file "MDV1_BOOT" and load and execute its contents as a
SuperBASIC program. If both of these attempts fail, Qdos starts up the
SuperBASIC interpreter with an empty program memory.
16
3.0 Machine Code Programming
on the QL
Four types of machine code are available to program the QL, each being
used to perform quite different operations: jobs, SuperBASIC procedures and
functions, tasks, and the operating system or extensions to it. Thus there are
several differences in both the form in which they are written, and the way in
which they are treated by Qdos.
3.1 Jobs
Most application programs written in machine code or compiled code will be
in the form of jobs. A job is an entity which has a share of machine resources:
it has a priority which allows it to claim time-slots of CPU activity, and it has a
fixed-size area of memory where data and code can be stored: code normally
starts at the bottom of the area, and data at the top. This area is located
somewhere in the transient program area.
Note that the command interpreter is itself a job but with the exceptional
characteristic that its data area is expandable.
A job also has the ability to own I/O channels or other jobs. There is no
protection between jobs under Qdos, so that channels are available for use by
all jobs. Ownership simply implies that when the owner of a channel or job is
deleted, the owned channel or job is deleted also (this process continues
recursively).
Jobs have three well-defined states: they are active, sharing CPU resources
with other jobs; suspended, for example, waiting for I/O or another job; or
inactive, occupying memory but not capable of using CPU resources.
The priority of a job can be zero, in which case it is suspended, and does not
consume CPU time. It can in fact be suspended for its entire lifetime and
never execute at all, which would be the case if it was simply used as a
means of obtaining some memory into which data could be loaded. A job at
any other priority level is active.
17
When a job is started, two parts of its area of memory have defined
meanings: the bottom of the code area, and the stack, which is at the top of
the data area. It is the programmer's responsibility to set up the
bottom of the code area, which should be in the following form for use
by Qdos utilities:
JMP.L JOB_START
DC.IN $4AFB
DC.IN JOB_NAME_LENGTH
DC.IN 'Nameofjob'
JOB_START
* Code begins execution here (assuming that the start address
defined when the job was created was zero)
On the first occasion that a job is activated, (A6) points to the base of the job
area, (A6,A4) points to the bottom of the data space, and (A6,A5) points to
the top of the job area. There may be some information on the stack, which
will be in the following form: (A7) points to the number of channels which
have been opened for the jobbefore it was activated; above this is a
sequence of longwords holding the channel IDs, and above these are a
command string which may have been passed to the job. It is the
programmer's responsibility when starting a job to set up this information: the
SuperBASIC EXEC, EXEC_W commands and any utilities produced by
Sinclair are compatible with this form.
Code area
Job name
$4AFB
(A6) JMP.L JOB_START
18
Note that the normal sequence in Qdos is as follows:
The system job table holds information about the jobs within the system. The
system variable SV_JBBAS points to the base of the job table, and SV_JBTOP
points to the top. The table is a series of longwords each of which points to a
job control block: the contents of this are described in section 18.5. The job is
identified to the system by its Job ID: this is a longword consisting of a word
giving its position in the job table (in the least significant word), and a word of
tag allocated by the operating system when the job is created (in the most
significant word).
A job terminates itself by calling MT.FRJOB with its own job ID (or -1,
which always refers to the current job).
19
3.2 SuperBASIC Procedures and Functions
The SuperBASIC command interpreter is job number zero. It behaves
like all other jobs in most respects, with the important exception that it
owns a special data area which is expandable, and may be moved
without the knowledge of the interpreter. This area is located
immediately below the transient program area.
On exit from the procedure, an error key is passed to the interpreter in DO.L:
this must be setto zero if there was no error. The procedure or function can
then be exited using an RTS statement.
Machine code procedures and functions are normally loaded into the
resident procedure area above the transient program area. This area can only
be expanded or deleted when the transient program area is
empty, which is normally immediately after the machine is booted.
20
Trap #4 is the one special trap which relates to SuperBASIC procedures and
functions. This trap is used to make the addresses passed to an I/O trap
relative to A6, which is necessary when working with the SuperBASIC
variables area. It only affects the following trap, and must therefore be called
before each trap whose addresses are to be modified.
3.3 Tasks
Tasks are special pieces of code invoked under interrupt, usually as part of the
physical layer of a device driver. They obey special rules according to the
precise conditions under which they are called: these rules are described in the
sections on device drivers (sections 6.0-8.0). The important restriction on tasks
is that they must not allocate or release machine resources: this should only be
done from within a job, or within the access layer of a device driver.
21
4.0 Memory Allocation
Memory is allocated differently in each area of the Qdos memory map.
• Memory in the free memory area is not allocated or deallocated by the user,
except by the slave block mechanisms defined in section 7.0 on directory
device drivers.
22
4.1 Heap Mechanism
The mechanisms for allocating and releasing heap space are common to
various routines. They are as follows:
A heap is an area of memory which contains a linked list of used heap items,
and a linked list of free heap items. Each heap item is an area of memory
(which is a multiple of 8 bytes long), together with a pair of longwords: the first is
the length of the heap item, while the second is a pointer (relative to itself) to the
next heap item in the list. The use of relative pointers ensures that heaps may
be moved.
Provided the user code can remember the length of a heap item, all of the
memory in it may be used by the code. On allocation of the heap item, the first
long word holds its length, and so, if desired, this may be retained by the user
code.
The user code requires to keep one pointer to the first free space item in the
heap. This is a long word, and is relative. When the heap has no free space,
either because it does not exist, or because it is full, this pointer is zero.
Releasing a heap item adds it to the list of free space items within the heap,
and consolidates it with adjacent free spaces where appropriate.
23
5.0 Input/Output on the QL
A QL program uses I/O by accessing the Qdos. The IOSS in turn accesses the
device driver for the appropriate device. The device driver is a piece of code
which can perform low-level I/O routines for a particular device: that device may
correspond to a piece of hardware, such as a serial port, or it may be some
notional device occupying a piece of memory, such as a pipe, which is a
communication channel between jobs.
QL I/O is performed through the IOSS using an I/O channel. The applications
program opens a channel by passing a device name to the IOSS, which
returns a channel/D. The IOSS and the built-in device drivers have the ability
to recognize qualifiers appended to the actual name of the device which can
direct the open operation in particular ways, such as identifying a file name, or
selecting some hardware option. The program then uses the channellD to
identify to the IOSS which channel it wishes to access when performing read
or write operations on it. It can also close the channel, passing the channel lD
to the IOSS. There may be several channels open which use the same device
driver, such as multiple screen windows, or Microdrive files. For this reason, all
the built-in drivers are re-entrant, as must be the user-defined drivers if they
are to have the same capability.
The QL ROM contains drivers for several devices such as screen windows,
serial ports, pipes, microdrives, and so on. The user can add his own device
drivers for pieces of add-on hardware, or simply for additional functions with
the existing hardware.
Note that a channel lD is not the same thing as a SuperBASIC channel number
(denoted by #expression): the latter is the index of an entry in the SuperBASIC
channel table which includes a channel lD. See sections 18.4 and 18.7 for
details of the channel table.
24
5.1 Serial I/O
All device drivers have, at the very least, the capability to perform serial I/O:
that is, the operations of reading bytes, writing bytes, and testing for pending
input. Serial I/O is completely byte-oriented - unlike many operating systems
there is no inbuilt record structure, which means that the user is free to
superpose his own record maintenance in whatever form he wishes. I/O which
is purely serial is completely redirectable: when different devices are being
used, the device name passed to the channel open trap is the only thing that
changes.
The IOSS supports one control character only, this being the newline
character, which is ASCII 10 ($OA). Whilst this has the disadvantage
that one cannot directly store files of graphics commands which can be
retrieved by a simple copy, it does have the advantage that files containing
arbitrary sequences of bytes cannot do irretrievable damage to the system by
being copied to a device for which they were not intended. The serial driver has
the option of supporting ASCII 13 as a newline, and ASCII 26 (CTRL -Z) as an
end of file marker.
All serial I/O calls support a time-out feature, which may be zero (return
immediately), indefinite (wait until the operation is complete), or finite (wait
until the operation is complete, or for a set time, whichever is the sooner).
This last feature makes it very easy to write code which, for example, puts
up a menu only if the user hesitates.
The fetch and send traps have several special meanings when used in
conjunction with screen or console channels: for a more detailed
description ofthese, see section 15.0 on I/O Traps.
Forthe fetch byte and fetch string traps, characters read from the
keyboard are not echoed in the associated window, and cursor
handling is left to the applications program.
25
5.2 File I/O
Qdos files appear to the applications program as arrays of bytes on a physical
device, with an associated file pointer which gives the "current position" in a
file. A file also has a header, which is normally 64 bytes long containing
information about the file such as its name, length, etc. Further details
concerning the format of the file header are given in section 7.0 on Directory
Device Drivers.
The open call to a file system device supports several modes: old (exclusive),
old (shared), or new (exclusive). New (overwrite) mode has a slot allocated in
the open keys, but is not currently supported for Microdrives. In addition, a
special open key indicates that it is desired to open the directory of the medium
for reading rather than a particular file; the directory cannot be explicitly written,
but is maintained by the device driver when open calls and deletions are made.
In addition to the serial I/O operations described above, Qdos supports the
following operations for file-system devices:
26
The FS.FLUSH and FS.CHECK command are subtly different:
FS.FLUSH ensures that all write operations are complete, whereas
FS.CHECK ensures that all write and read operations (including
prefetches) are complete.
There are two main coordinate systems used for screen I/O: these are the
graphics coordinate system and the pixel coordinate system (see the Concepts
manual for details). Note that in 256-pixel mode and for several commands in
512-pixel mode, the least significant bit of a dimension in the x-direction is
ignored, so that a given pixel address refers to the same location in both
modes. Some traps refer to character coordinates: these are based on the
pixel coordinate system but are scaled by the current character spacing for the
window.
27
Each window will have its own particular set of characteristics: a border width,
a border colour, a paper colour, a strip colour, an ink colour, a cursor position,
a cursor increment, a flag which says whether the cursor is suppressed, a pair
of font pointers, information about newline treatment, and graphics information.
Details of the window definition block are given in the section 15.0.
28
If the cursor is suppressed, the newline is held pending. It can be cleared
by any call to position the cursor, or activated by any of the following
events:
29
The user can temporarily suspend screen output to a console channel by
typing the freeze screen character (CTRL-F5). Output is resumed when any
character is typed, but the character is ignored for all other purposes. If a
non-indefinite time-out has been set for the suspended operation, it may
return non-complete if the screen is frozen past the time-out period.
The keyboard auto-repeats on all keys except the keyboard change queue
character, CTRL-Space (the SuperBASIC break) or CTRL-F5 (the freeze
screen character). However, auto-repeat will not occur unless the type-ahead
queue for the console channel to which input is currently directed is empty. The
delay before auto-repetition begins is held in the system variable SV_ARDEL,
and the interval between repetitions is held in SV_ARFRQ (both in multiples of
1/50th or 1/6Oth of a second). These can be altered by a program.
30
6.0 QDOS Device Drivers
A user-supplied Qdos device driver is a collection of routines which allow an
applications program to perform IOSS functions on a user- supplied device in
the same way as such functions are performed on the devices built into the
system. As these routines are linked into the system's lists in front of the
corresponding system routines, they may be used to replace the system
routines. At the very least, the device driver contains a set of routines for
opening a channel, closing a channel, and performing serial I/O on that
channel: these routines are called via the IOSS as part of the job that is
performing the I/O. The driver may also include one or more tasks, that is,
routines performed asynchronously with the calling job, usually under
interrupt.
Such tasks, which are known as the physical layer of the device driver,
normally communicate with the rest of the device driver, which is known as
the access layer, using asynchronous queues. These queues are usually
polled by the task at regular intervals, either on every occasion the scheduler
is entered, or on every 50/60 Hz polling interrupt.
Drivers for file system devices use a slightly different, and more general,
mechanism: this is described in section 7.0.
Both drivers and tasks are linked in to lists provided by the operating
system. The following traps are used to add and remove items from
those lists:
The QL provides several utility routines which are useful for various
actions commonly performed in device drivers, such as decoding a
device name, performing queue operations, etc.
31
6.1 Device Driver Memory Allocation
Device drivers allocate memory in two areas: the device driver definition block
and the channel definition block. The device driver definition block belongs to the
driver itself, and is allocated by the code which sets up the driver when it is
initialised and linked into the various lists. The channel definition block belongs to
each I/O channel, and is allocated by the driver itself when a channel is opened.
Various parts of the channel definition block are thereafter used by the lOSS for
its own purposes.
In theory, the access layer can allocate space on the heap at other times: in
practice this is not usually required. The whole system can be made re-entrant
to allow several channels to be open with the same device driver and the
same device driver definition block, but with different channel definition blocks.
Note that the system will certainly crash if the area of a channel definition
block is deallocated and used for something else before the channel is
closed, or if the area of a device driver definition block is deallocated and
used for something else before the device driver is removed from the
system's lists, for example if the device driver definition block is in a transient
program which is force-removed. This possibility can be obviated by
allocating the block in the common heap with a job number of zero, or by
allocating it in the resident procedure area.
Tasks must not allocate or release memory: this must be done for
them by the access layer, or by the device driver initialisation code.
The device driver definition block will normally have the following
structure, assuming that A3 has been made to point to it:
32
$00(A3) Link to next external interrupt routine
$04(A3) Address of external interrupt routine
$08(A3) Link to next poll interrupt routine
$0C(A3) Address of poll interrupt routine
$10(A3) Link to next scheduler loop routine
$14(A3) Address of scheduler loop routine
$18(A3) Link to access layer of next device driver
$1C(A3) Address of input/output routine
$20(A3) Address of channel open routine
$24(A3) Address of channel close routine
$28(A3) Any further workspace required for the device driver
The initialisation code should fill in the addresses of the open, close and I/O
routines, together with those of any of the routines for tasks that it will be
employing. It should also fill in any preset data required in the remainder of the
workspace.
Finally, the link routines described above should be called to include the
driver in the operating system's lists.
Note that the structure of the first 24 bytes of the device driver definition
block is not mandatory; however, it is desirable from the point of view of
consistency that it be kept the same. The comments in later sections
about the base of the device driver definition block being passed to the
driver are only valid if the above structure has been used.
When the operating system calls one of the tasks in the physical layer, it
passes the task a standard set of values in some of the registers. These
values are as follows:
33
6.3.1 External Interrupt Tasks-
An external interrupt task must check its own hardware to determine whether
the interrupt was for itself or for some other driver. It may also need to clear the
source of the interrupt at that point. If the interrupt was not for itself, it should
return.
Scheduler loop tasks are called at around 50/60Hz when the machine is
busy, and more frequently if the machine is idle.
All physical layer calls return with RTS. D0 to D7 and A0 to A6 inclusive may
be smashed.
For all access layer calls, the values of A3, A6 and A7 are the same as) for
the physical layer. The other registers have different meanings, as described
below in the sections for the individual types of call.
34
6.4.1 The Channel Open Routine-
When the channel open routine is called via the lOSS, the following
registers are set in addition to A3, A6 and A7 which are as described
above:
First, decode the name; the utility IO.NAME, which is described in section
16.0, will normally be used for this purpose. Return with ERR.NF in D0 if
the name was not recognised by this driver, or with ERR.BN if the name
was recognised, but some of the additional information was incorrect in
value or format.
Finally, allocate some space for the channel definition block. Any buffers or
working area required for each channel are normally allocated in the
common heap. Return with ERR.OM if there was not enough memory to do
this.
The function of the close routine is simply to release the memory taken up by
the channel definition block and to ensure that everything in the device driver
definition block is tidy.
35
Under some circumstances, it may not be possible to close the channel
immediately because there are bytes waiting to be transmitted by the physical
layer. In this case, the physical layer must contain a scheduler loop task, and
the close routine should set a flag for the physical layer to complete the
release of the memory on the next invocation of that task in which it is
possible to do so. When this happens, it is usually necessary to build in a
special mechanism to cope with the undesirable event of a program closing a
channel to a particular device, and then re-opening it immediately only to
receive an "in use" error because the closed channel has not yet been
cleared.
The close routine should return with zero in D0, as it is assumed that a close
routine cannot fail. Only registers D0 to D3 and A0 to A3 may be smashed.
The I/O routine should return ERR.NC (not complete) if it cannot complete
the operation immediately. If a string operation has been partially
completed, the values in D1 and A1 (number of bytes transferred and buffer
pointer) should be set appropriately so that the operation can continue on
the next try. D0 should be zero on return if the operation has been
completed correctly. Registers D2 to D7 may be smashed.
36
Since most of the code for handling serial 110 is common to all device drivers, the I/O
routine usually calls one of the utility routines IO.SERQ or IO.SERIO (which are
described in section 16.0). IO.SERQ assumes that the only function ofthe access layer
is to move bytes in and out of a pair of queues pointed to by fixed positions in the
channel definition block, while IO.SERIO assumes that the operations required of it can
all be made up out of three primitive routines for sending one byte, fetching one byte,
and checking for pending input, such routines being supplied by the writer of the device
driver.
Note that channels are assumed to be bidirectional; it is the responsibility of the I/O
routine to trap an operation in a direction that is not allowed.
Note also that output operations which appear to the user as complete have merely
completed the access layer call correctly: there being no general way in which the user
can ascertain whether the physical layer has in fact completed the operation.
37
7.0 Directory Device Drivers
Drivers for devices which have a directory and form part of the filing
system have a somewhat extended set of functions. For directory device
drivers, there are three blocks in which memory is allocated, rather than
two: these are the directory driver linkage block, the physical definition
block and the channel definition block.
There is one directory driver linkage block for each directory driver: it is an
extended form ofthe device driver definition block as found in a non-directory
device driver. The block contains information about how to use the driver,
together with the links in the operating system's lists.
For each I/O channel that is open, there is an open channel definition
block.
Each file is assumed to have a 64-byte header (the logical beginning of file is
set to byte 64, not byte zero). This header should be formatted as follows:
The current file types allowed are: 2, which is a relocatable object file;
1, which is an executable program; 255 is a directory; and 0 which is anything
else. In the
38
case of file type 1,the first longword of type-dependent information holds
the default size of the data space for the program.
The format of the directory driver linkage block is as follows (assuming that
A3 has been made to point to it):
$00(A3) link to next external interrupt routine
$04(A3) address of external interrupt routine
$08(A3) link to next 50/60 Hz interrupt routine
$0C(A3) address of 50/60 Hz interrupt routine
$10(A3) link to next scheduler loop routine
$14(A3) address of scheduler loop routine
$18(A3) link to access layer of next directory driver
$1C(A3) address of input/output routine
$20(A3) address of channel open routine
$24(A3) address of channel close routine
$28(A3) address of entry for forced slaving
$2C(A3) reserved
$30(A3) reserved
$34(A3) address of entry to format medium
$38(A3) length of physical definition block
$3C(A3) word-length of drive name characters of drive name
(e.g. MDV)
Note that a directory driver must have at least 40 bytes of RAM for the
linkage block.
39
7.2 Access Layer
The access layer of a directory driver contains five routines: the channel
open/file delete routine, the close routine, the I/O routine, the forced
slaving routine and the format routine.
For all directory device driver access layer calls (including open), A0 points
to the base of the channel definition block when each routine is called.
However, the format of the block is somewhat different:
40
7.2.1 The Channel Open/File Delete Routine-
The function of the open routine depends on the access mode. This may have
been passed to the lOSS in D3 if the open routine was called as a result of an
IO.OPEN trap, or it may be a negative number, which would be the case if the
routine has been entered as a result of an IO.DELET trap.
In order to understand the open routine, it is necessary first to understand the way
in which Qdos handles device names. When a device name is passed to the lOSS
as a result of an open or delete call, the lOSS looks for a match in its lists of device
drivers and directory device drivers. The matching mechanism for non-directory
device drivers is defined within the open routine for that driver. The matching
mechanism for directory device drivers is as follows. The first characters of the
name are checked against the drive name in the directory driver linkage block
(which is put there when the driver is initialised), and these are expected to be
followed by a drive number between 1 and 8, followed by an underscore, followed
usually by the filename. If a match is found, the file system looks to see if there is a
physical definition block for that drive already in existence. If there is not, a physical
definition block is created in the system's table of physical definition blocks (the
drive ID in the channel definition block is an index to this table). Note that the file
system has no knowledge of whether a drive is actually connected, and will set up
the definition block regardless.
The lOSS then checks to see if this is the second or subsequent open to a shared
file: if this is the case it generates the complete channel definition block itself,
setting FS_NBYTE to $40, and copies the remaining information from the channel
definition block for the first open. The directory driver's open routine is not called.
Otherwise, the lOSS calls the open routine, passing it the file name in the channel
definition block.
41
The channel and physical definition blocks are all set to zero except for the
following, which are filled in by the lOSS:
In the case of a device with removable media, the open routine should find
out the name of the medium and install it in FS_MNAME. It should also look
at the access mode to find out which operation is required. If the required
operation is delete, it should perform that operation and return, but if the
required operation is another sort of open, then it should fill in the
appropriate portions of the channel definition block, namely FS_FILNR,
FS_EBLOK, FS_EBYTE, FS_NBLOK and FS_NBYTE. FS_CBLOK is a
pointer to the slave block table which may be filled in as an indication to the
I/O routine that the block it is looking for may be slaved there. The I/O
routine must check this however, normally by searching the slave) table.
The lOSS will free the channel definition block on exit from the open routine
if the action was a delete or if the open routine returns an error key in D0.
42
The close routine for a directory device driver has two additional functions: it
must unlink the channel from the list of files open, and must decrement the
FS_FILES field in the physical definition block, which gives the number of
files open on the medium. Suitable code for performing these operations and
ending the close routine isas follows:
The close routine must also initiate the process of tidying up any slave blocks
remaining for that channel. It need not force the slave blocks to be made into
true copies itself, but it must be guaranteed that the copying will happen
without further intervention by the calling program.
43
7.3 Slaving
The area of memory between SV_FREE and SV_BASIC is used by the
filing system as temporary storage for file slave blocks and for the slave
block table. A slave block is a block of 512 bytes of data. The slave block table
is a table of 8 entries whose start point is held in the system variable
SV_BTBAS and whose top is held in the system variable SV_BITOP; the
system variable SV_BTPNT points to the most recently allocated slave block
table entry. The address of a slave block, relative to the base of system
variables, is equal to 512/8 times the offset of the corresponding entry in the
slave block table from the beginning of that table.
Currently, only the first byte of each slave block table entry is used by Qdos
itself: the remaining bytes are available for use by the driver. This byte is
divided into two four-bit nibbles. The most significant nibble contains the drive
identifier (0 ..15), and the least significant nibble is a code indicating the status
of the block. The byte is formatted as follows:
For Microdrives, the remaining space in each slave block table entry is laid
out as follows:
It is left to the device driver to decide what the slave blocks are used for but it
must be prepared to release a slave block if requested to do so by the memory
manager. This is done by calling the driver's forced slaving routine with the
following parameters:
44
Registers D0 to D3 and AO to A4 inclusive may be smashed. There may not be
an error return to this routine.
Typically the slave blocks are used to buffer data being written to a device,
the actual writing being carried out by an asynchronous task.
*
*form offset into slave block table, gives
*slave block no.*8; entries are 8 bytes wide in table
*
SUB.L SV_BTBAS(A6),D0
LSL.L #6,D0 multiply by 64 (8*64=512)
MOVE.L D0,A5
ADD.L A6,A5 add offset to system
variable base
* A5 now has base address of slave block
It should return the error code in D0, the number of good sectors in D1 and
the total number of sectors in D2. Registers D3 to D7 and A0 to A5 inclusive
may be smashed.
45
8.0 Built-in Device Drivers
The following devices are built in to the QL ROM:
Within device names, no distinction is made between upper and lower case
letters.
46
9.0 Interfacing to SuperBASIC
When writing SuperBASIC procedures or functions in machine code, there are
several things that an applications programmer may want to do: he may wish to
look at or modify the information held in SuperBASIC variables and arrays, he
may wish to access or modify the SuperBASIC list of I/O channels, and he may
wish to reserve and use space on the arithmetic stack. He will also, of course,
wish to access the list of parameters passed to the routine and return values
either to those parameters or in a function return. In order to do this, it is
necessary to understand the data structures used by the interpreter and
to emulate the interpreter's techniques for manipulating them.
The job header is located at the bottom of the SuperBASIC area, and looks just
like any other job header (see section 18.5). Immediately above this is the
SuperBASIC work area; this is an area of fixed storage used for the working
variables of the interpreter. Included in these working variables are pointers to
the other areas: the interpreter can not only shuffle these areas around, but may
ask Qdos to change the size of the whole SuperBASIC area.
47
The organisation of this area is shown in section 18.3. Throughout normal
operation of the interpreter, A6 points to the base of the SuperBASIC work
area, the whole of which may move between instructions, with a corresponding
change in A6. All the pointers are, of course, relative to A6, so that their values
need not be changed when the SuperBASIC area is moved.
The name table, the name list and the variable values area are required by the
applications programmer in order to access and/or modify SuperBASIC
variables and parameters. The channel table is required in order to access
SuperBASIC I/O channels, and the arithmetic stack (usually abbreviated to RI
stack) is a convenient area in which to reserve storage, and is also where
parameters are passed. The remaining areas are not described in this
document.
48
Byte 0 of the name table has an additional usage during parameter
passing: see section 9.8.
The Name pointer is a pointer to an entry in the name list (see the
following section). A name pointer of -1 indicates a nameless item
such as the value of an expression; any other negative pointer indicates a
pointer to another entry in the name table of which this entry is a copy.
The Value pointer is a pointer to an entry in the variable values area (see
section 9.4). A value pointer of -1 indicates that the value is undefined.
Since all these areas may move during execution, the pointers are offsets
from the base of each area. For the RI stack, the base is at the high
address; for the others it is at the bottom.
The entries for expressions and substrings are for use within the expression
evaluator: the applications programmer would not normally use them.
49
9.5 Storage Formats
The most significant four bits of the exponent are zero, whilst the remaining
twelve bits are an offset from -$800. The mantissa is two's complement and
fractional, with bit 31 of the mantissa representing -1, and bit 30 of the
mantissa representing +1/2. There are no implicit bits in the mantissa, so
either bit 31 or bit 30 will be set for a normalized number, except in the
special case of zero.
50
9.5.4 Array Storage
An array descriptor has a header which consists of a longword offset of the
array values from the base of the variable value area, followed by the number
of dimensions (word), followed by a pair of words for each dimension. The first
word is the maximum index, the second word is the index multiplier for this
dimension.
The storage of floating point and integer arrays is entirely regular. A floating
point array takes 6 bytes per element, an integer array 2 bytes per element.
51
9.6 Code Restrictions
There is a simple set of rules for writing procedures in machine code for
SuperBASIC.
1. As the SuperBASIC program area is liable to move at any time while the
execution is in user mode, all refererences to this area must be indexed by A6
or A7. A6 and A7 must never be saved, used in arithmetic or address
calculations, and must never be altered, except by pushing or popping the A7
stack. In extreme circumstances it is possible to enter supervisor mode (Trap
#0) to make the following action atomic. If this is done, A6 and User stack
pointer must not be saved or manipulated before entering supervisor mode,
and they must be restored before exiting.
2. Not more than 128 bytes must be used on the user stack.
3. D0 must be returned as an error code (long).
4. D1 to D7 and A0 to A5 inclusive may be treated as volatile.
52
parameter list. The interpreter then swaps the new name table entries with
the old name table entries corresponding to the actual parameters. In the
case of a procedure or function written in machine code, the code is then
called with A3 pointing to the name table entry for the first parameter in the
list, and A5 pointing to the last ((A5-A3)/8 is the number of parameters).
Byte 0 of the name table entry for a parameter has an additional meaning to
that associated with a normal name table entry. The bottom four bits have
the usual indication of type (0=null, 1=string etc.), but the top four bits are
used to indicate the separator that was present after the parameter in the
actual parameter list, together with information as to whether the actual
parameter was preceded by a hash (#).
53
in the least significant word of D3, and the values themselves in order on the
arithmetic stack with the first parameter at the top (lowest address) of the
stack. These routines smash the separator flags. They are as follows:
CA.GTINT gets 16-bit integers, CA.GTFP gets floating point numbers,
CA.GTSTR gets strings, and CA.GTLIN gets floating point numbers but
converts them to 32-bit long integers.
These routines may still be used when processing parameters of mixed type
or when wishing to inspect the separators. To begin with, the values of A3 and
A5 should be saved; then, for each parameter in succession, the separator
flags are inspected, and the appropriate routine is called with A3 pointing to
the parameter and A5 equal to A3+8, thus getting one parameter.
These routines smash D1, D2, D4, D6, A0 and A2. The error codes are
returned in D0 and the condition codes.
The vectored routines for getting parameters reserve their own space on the
arithmetic stack.
54
The arithmetic stack is automatically tidied up both after procedures, and
after errors in functions. To make a good return from a function, the
returned value should be at the top (lowest address) of the stack with
nothing below it (that is with both (A6,A1.L) and BV_RIP(A6) pointing to it)
when the routine is exited. The type of the returned value should be in D4 (1
=string, 2=floating point number, 3=integer). Since SuperBASIC has no long
integer type, long integers must be converted to floating point before
returning.
Note that strings must be aligned on the arithmetic stack so that the character
count is on a word boundary. All entries on the stack must be a multiple of two
bytes long, so that a string of odd length has one byte at the end which
contains no information.
If a channel entry is off the top of the channel table, or if the channel
ID is negative, there is no channel open to that # number.
55
10.0 Hardware-related Programming
10.1 Memory Map
The 68008 has one megabyte of address space. Although an unexpanded QL uses
only the bottom 256 kbytes of this, the allocation for the remainder is determined and
should be adhered to when designing add-on hardware. This is how it is made up:
$FFFFF ______________
Add-on ROM
$EOOOO _______________ (Up to 128 kbytes)
Add-on peripherals
(8 slots of up to
$C0000 ___________ 16 kbytes each)
Add-on RAM
$40000 ___________ (Up to 512 kbytes)
On-board user RAM
$28000 ___________ (96 kbytes)
Screen RAM
$20000 ___________ (32 kbytes)
On-board I/O
$10000 ___________ (Partially decoded)
Plug-in ROM cartridge
$0C000 ___________ (16 kbytes)
On-board ROM
$00000 ___________ (48 kbytes)
The registers in the on-board I/O area are partially decoded: the details of this
decode may vary according to different versions of the QL hardware - some
versions will recognise any address in the entire area.
56
However, the address map normally used is the same for all QLs:
The display control registers are in the ZX8301 "Master chip", and the others
are in the ZX8302 "Peripheral chip". The details of the QL hardware are
rather obscure, and it is strongly recommended that these registers should
not be used by applications programs, and should only be accessed via
Qdos traps or vectored routines.
In 512-pixel mode, two bits per pixel are used, and the GREEN and BLUE
signals are tied together, giving a choice of four colours: black, white, green
and red. On a monochrome screen, this will translate as a four level greyscale.
In 256-pixel mode, four bits per pixel are used: one bit each for Red, Green and
Blue, and one bit for flashing. The flash bit operates as a toggle: when set for the
first time, it freezes the background colour at the value set by R, G and B, and
starts flashing at the next bit in the line; when set for the second time, it stops
flashing. Flashing is always cleared at the beginning of a raster line.
57
Addressing for display memory starts at the bottom of dynamic RAM and
progresses in the order of the raster scan - from left to right and from top to
bottom of the picture. Each word in display memory is formatted as follows:
D7 D6 D5 D4 D3 D2 D1 D0 D7 D6 D5 D4 D3 D2 D1 D0
G7 G6 G5 G4 G3 G2 G1 G0 R7 R6 R5 R4 R3 R2 R1 R0 512-pixel
G3 F3 G2 F2 G1 F1 G0 F0 R3 B3 R2 B2 R1 B1 R0 B0 256-pixel
R, G, Band F in the above refer to Red, Green, Blue and Flash. The
numbering is such that a binary word appears written as it will appear on the
display: ie R0 is the value of Red for the rightmost pixel, that is the last pixel
to be shifted out onto the raster.
One of its bits is available through the Qdos MT.DMODE trap: bit 3,
which is 0 for 512-pixel mode and 1 for 256-pixel mode.
The other two bits of the display control register are not supported by Qdos,
these being bit 1 of the display control register, which can be used to blank
the display completely, and bit 7, which can be used to switch the base of
screen memory from $20000 to $28000. Future versions of Qdos may allow
the system variables to be initialised at $30000 to take advantage of this dual-
screen feature: the present version does not.
Bits 0,2,4,5 and 6 of the display control register should never be set to
anything other than zero, as they are reserved and may have unpredictable
results in future versions of the QL hardware.
58
When the keyboard is accessed via the console driver, the usual functions of
debounce and conversion to ASCII are performed, in addition to the
functions described in section 15.0. The other way of accessing the
keyboard is to use the MT.lPCOM trap to monitor the instantaneous state of
the keys directly: this is the only way of detecting multiple key presses
(necessary for joystick input), or of detecting the state of the SHIFT, CTRL
and ALT keys when no other key has been depressed. See the SuperBASIC
Keywords entry on the KEYROW function for an example of the use of this
technique.
The same trap, with different parameters, is used for sound generation.
10.7 Network
This should not be accessed other than by the built-in device driver.
59
10.8 Microdrives
Normally, these should not be accessed other than by the built-in device driver.
However, it is possible to write routines to access microdrive sectors directly in
order to perform such functions as fast medium-to-medium copying or recovery
of data from a damaged medium.
There are four vectored routines provided for this purpose: MD.READ,
MD.WRITE, MD.VERIN and MD.SECTR. Use of these routines requires a
detailed understanding of the microdrive hardware and format, and is
probably beyond the scope of most users.
However, to use these routines the following code example shows how a
microdrive is selected or de-selected. In later versions of the operating
system it will be a vectored entry.
sys_wser
move.b dO,-(sp) ;save operation
wait
subq.w #1,sv_timo(aO) ;decrement timeout
blt.s set.mode ;done?
move.w #(2OOOO*15-82)/36,dO ;time= 18*n+42 cycles
delay1
dbra dO,delay1 ;delay
bra.s wait ;repeat until
timeout expires
set_mode
clr.w sv_timo(aO) ;clear wait
and.b #pc.notmd,sv_tmode(aO) ;not RS232
move.b (sp)+,dO
or.b dO,sv_tmode(aO)
;either mdv or net
and.b #OFFh-pc.maskt,sv_pcint(aO)
;disable transmit
interrupt
exit
move.b sv_tmode(aO),pc_tctrel
;set pc
rts
sys_rser
bclr #pc..serb,sv_tmode(aO) ;set RS232 mode
or.b #pc.maskt,sv_pcint(aO) ;enable transmit
interrupt
bra.s exit
md_desel
moveq #pc.desel,d2 ;clock in deselect bit first
moveq #7,d1 ;deselect all
bra.s sedes
60
md_selec
;clock in select bit first
moveq #pc.selec,d2
subq.w #1,d1 ;and clock it through n
;times
sedes
\
clk_loop
move.b d2,(a3) ;clock high
moveq #(18*15-40)/4,d0 ;time=2*n+20 cycles
ror.l d0,d0
bclr #pc..sclk,d2 ;clock low
move.b d2,(a3) ;... clocks d2.0 into first
;drive
moveq #(18*15-40)/4,d0 ;time=2*n+ 20 cycles
ror.l d0,d0
moveq #pc.desel,d2 ;clock high - deselect bit
;next
dbra d1,clk_loop
rts
drive
bsr.s startup
bsr.s wind_dwn
rts
; errors:
startup
cmp.l #1,d3 ;Iegal microdrive?
blt.s ill_drve ;jump if not
cmp #8,d3 ;Iegal microdrive?
bgt.s ill_drve ;jump if not
move.l (sp)+,a3 ;a3=return address
moveq #mt.inf,d0 ;select MT.INF
trap #1 ;a0= 'to system
;variables
trap #0
;supervisor mode
move.l a3,-(sp)
;'return' (geddit?) the
moveq #10h,d0 ;return address
bsr sys_wser ;microdrive mode
;wait for RS232 to
;complete
61
or #0700h,sr ;shut out rest of world
move.l d3,d1 ;d1 is microdrive to be
;started
move.l #mdctrl,a3 ;a3= "control register
bsr md_selec ;start it up
moveq #0,d0 ;no problems
rts ;return
ill_drve
moveq #-4,d0 ;error=out of range
rts
; d1 d1 smashed
; d2 d2 smashed
; a0 a0 SV_BASE
; a3 a3 ^instruction after
call to here(!!)
wind_dwn
moveq #mt.inf,d0 ;select MT.INF
trap #1 ;a0= ^to system
;variables
move.l #mdctrl,a3 ;a3= ^control register
bsr.s md_desel ;wind it down
62
11.0 Adding Peripheral Cards
to the QL
Peripheral cards may be plugged into the expansion connector on the left-
hand side of the QL , or into one of the connectors in the QL expansion
module: a unit which allows several add-on cards to be connected to the QL
in parallel. The QL expansion module consists of a power supply and a card
cage containing a specially wired backplane. The backplane is connected to
the QL via a ribbon cable and buffer card.
There are two general categories of peripheral card for the QL : pure add-
on memory cards, and other peripheral cards.
It is intended that only one pure add-on RAM card be plugged into the machine
at anyone time. It is allocated the address area between $40000 and $BFFFF;
the add-on memory should be contiguous from $40000 upwards. This allows
for an add-on memory size of up to 512 kbytes.
There is also room for an add-on ROM card of up to 128 kbytes, which is
allocated the addresses $E0000 to $FFFFF.
Other peripheral cards contain electronics for the devices being added, a
small ROM containing the drivers for the devices being added together with a
code allowing the QL to detect that the card is present, and a 4-bit comparator
which is used to select the card as explained below.
Note that the convention adopted in this document for an active low signal is to
append the letter "L" to the end of the signal name, as in DTACKL, VPAL etc.
This takes the place of the overbar indication used in the data sheets from
most vendors.
63
The connector inside both the QL and the expansion module is a 64- way
male DIN-41612 indirect edge connector, as found on standard Eurocard
modules. The connector on each add-on card should be the inverse version
of this.
The VIN supply is in the region of +9V DC: the trough never falling below 7V.
Up to 500 mA may be drawn from this to power the card.
No add-on card should load any pin on the edge connector by more than two
LSTTL loads. All add-on card data bus output drivers should be a 74LS245
or equivalent, in terms of drive ability, and being tri-state.
All 68008 signals are available both on the expansion connector and in the
expansion module to allow expansion to include coprocessors or other
peripherals.
The following signals are outputs only: A0-A19, RDWL, ASL, DSL, BGL,
CLKCPU, E, RED, BLUE, GREEN, CSYNCL, VSYNCH, ROMOEH, FC0-2 ,
RESETCPUL.
64
The following lines are inputs only, and should only be driven from open
collector outputs: DTACKL, BRL, VPAL, IPL0L, IPL1L, BERRL, EXTINTL,
DBGL.
When using the QL expansion module, the data bus buffers in the module
are enabled whenever A18 or A19 is high, or if the Data Bus Grab Signal
(DBGL) is asserted by any add-on card on pin 25A of the edge connector.
If DBGL is to be used, it should be driven by an open collector buffer.
If there is a ROM containing device drivers for the peripheral card, it should
sit in the bottom addresses of the 16 kbyte block. The format of the lowest
part of this ROM is specified in the next section.
I'
65
11.4 Add-on Card ROMs
When the machine is booted, the operating system checks for plug-in
ROM drivers by looking forthe characteristic longword flag $4AFB0001 at
the base of each location in which a ROM might be present. The beginning
of a plug-in ROM should be in the following format:
The pointers are relative to the base of the ROM. If the list pointer is zero
then there will be no attempt to link routines into SuperBASIC.
The list of BASIC procedures and functions is in the form used by BP.lNIT (see
section 16.0).
At start-up the machine will link in the additional BASIC procedures from the
ROM, then call the initialisation routine (in user mode) which must not
modify A6, and finally must restore AO (the initial window ID), and A3, the
pointer to the ROM, on exit. Up to 128 bytes may be used on the user stack.
All code for device drivers must be position independent, since the
addresses of the ROM and the devices on the card will be dependent upon
the position at which it has been plugged into the QL expansion module.
This allows multiple copies of the same add-on card to be used
simultaneously.
66
12.0 Non-English QLs
There are three areas in which non-English QLs may differ from English
QLs: the video, the keyboard, and the character set for serial
communications.
12.1 Video
This is different for countries where the television system is NTSC, which
permits the use of fewer raster lines than PAL. In QLs for such countries, the
following options are the defaults:
67
12.2 Non-English-language Keyboards
The keyboard layout for most European countries will be different from the
English layout. This difference should be largely transparent to applications
software, since the "QL ASCII" codes contain all the characters necessary for
the European countries in question, and the codes generated are independent
of the keyboard layout and hence of the actual key depressions required to
generate them.
However, there are a few subtleties, the following being the most obvious:
2. The keyrow function (or MT.IPCOM trap) refers to the physical position of the
keys, not to their logical meaning. For example, a test on an English QL for the
letter "0" using keyrow will turn into a test for the letter "A" on a French QL which
has an AZERTY keyboard.
3. An instruction to "hit any key" will not be strictly accurate for a country which
employs non-spacing diacriticals, where the keypress of an accent character
does not generate a code until the character to be accented is pressed. The
length of the type-ahead buffer in the IPC will be apparently reduced in such
cases.
68
12.4 Special Alphabets
Languages with non-Roman alphabets, such as Hebrew, Greek, Thai, Arabic,
etc., require special treatment. No general scheme has been devised for making
software transportable to these countries, and the implementation means will be
specific to each country.
69
TRAP #1 D0=$A MT.ACTIV
Activate a job
Call parameters
Return parameters
D1.L job ID
D2.B priority (0 to 127) D1.L job ID
D3.W timeout (0 or -1) AO D2 preserved
A1 D3 preserved
A2 A0 base of job ctrl area
A3 A1 preserved
A2 preserved
Error returns:
A3 preserved if D3 =0
NJ job does not exist
NC job already active
This activates a job in the transient area. Execution commences at the start
address defined when the job was created.
If the timeout is zero then the execution of the current job continues, otherwise
the current job will be suspended until the job activated has
completed. The trap will then return with the error code from that job.
70
TRAP #1 D0=$16 MT.ALBAS
Allocate BASIC program area
Error returns:
OM out of memory
71
TRAP#1 D0=$18 MT.ALCHP
Allocate common heap area
Call parameters
Return parameters
D1.L nr. bytes required
D1.L nr. bytes allocated
D2.L owner job ID
D2 ???
D3 D3 ???
A0
A0 base address of area
A1
A1 ???
A2
A2 ???
A3 A3 ???
Error returns:
OM out of memory
NJ job does not exist
72
Trap #1 D0=$C MT.ALLOC
Allocate an area in a heap
Error returns:
Two trap entries are provided for user heap management where this is required
to be atomic. A6 is used as a base address for both this call and for
MT.LNKFR so that A0 (and A1) is an address relative to A6.
73
TRAP #1 D0=$E MT.ALRES
Allocate resident procedure area
Error returns:
OM out of memory
NC unable to allocate (TRNSP area not empty)
74
TRAP #1 D0=$12 MT.BAUD
Set the baud rate
Call parameters
Return parameters
D1.W baud rate
D1 ???
D2
D2 preserved
D3
D3 preserved
A0 A0 preserved
A1 A1 preserved
A2 A2 preserved
A3 A3 preserved
BP non recognised baud rate
OM out of memory
NJ no room in job table or D1 is not a job
75
This trap allocates space in the transient program area, and sets up a job
entry in the scheduler tables. This does not invoke the job and the only
initialisation is that two words of 0 are put on the stack. The program itself
would normally be loaded, by another job, into the space allocated, after this
system call. The stack pointer saved in the job control area points initially to
two zero words on the stack (at the highest addresses in the job's data area);
if channels are to be opened for the job, or a command string is to be passed
to the job, then this can be done before the job is activated.
This call is used to set or read the current display mode. It is treated as a
manager trap as it affects all the displayed windows. If a call is made to set the
screen mode, then all the windows on the screen are cleared and the character
sizes may be adjusted. Obviously, there are serious risks involved in calling this
trap to set the mode when there are jobs in the machine accessing the screen.
76
TRAP #1 D0=$6 MT.FREE
Find largest contiguous free space that may be allocated in
the transient program area
Error returns:
This inactivates a complete job tree and deletes all jobs in it. If D1 is a
negative word then the job is the current job.
77
Neither of the traps MT.FRJOB or MT.RJOB to remove jobs can remove job
0.
78
TRAP #1 D0=$11 MT.lPCOM
Send a command to the IPC
79
The complete command format is:
Most of the IPC commands are for use by the operating system and any
attempt by application programs to use these is liable to cause loss of data
or worse. There are three commands for the IPC which may be used by
applications programs:
80
TRAP #1 D0=$2 MTJINF
Information on a job
Error returns:
This trap may be used to check the status of a tree of jobs. On each call
02 should be the 10 of the job at the top of the tree; to scan a complete tree
the trap is made with 01 being the return value of the previous call. When
the tree has been completely scanned 01 is returned equal to zero.
81
Trap #1 D0=$0 MT.LNKFR
Link a free space (back) into a heap
A6 is used as a base address for this call and for MT.ALLOC so that A0 (and
A1) is an address relative to A6.
82
TRAP#1 D0=$1A MT.LXINT
D0=$1C MT.LPOLL
D0=$1E MT.LSCHD
D0=$20 MT.LlOD
D0=$22 MT.LDD
D1 D1 preserved
D2 D2 preserved
D3 D3 preserved
A0 address of link A0 preserved
A1 A1 ???
A2 A2 preserved
A3 A3 preserved
83
TRAP #1 D0=$B MT.PRIOR
Change job priority
Error returns:
This call is used to change the priority of a job. If D1 is a negative word it will
change the priority of the current job. Setting the priority to 0 will cause
inactivation. This call re-enters the scheduler and so a job setting its own priority
to zero will be immediately inactivated.
84
MT.RDD See the entry for MT.RXINT for details.
TRAP #1 D0=$19
MT.RECHP
Release common heap area
D1 D1 ???
D2 D2 ???
D3 D3 ???
A0 base of area to be freed A0 ???
A1 A1 ???
A2 A2 ???
A3 A3 ???
85
TRAP #1 D0=$9 MT.RELJB
Release a job
Error returns:
86
TRAP #1 D0=$F MT.RERES
Release resident procedure area
D1 D1 ???
D2 D2 ???
D3 D3 ???
A0 A0 ???
A1 A1 ???
A2 A2 ???
A3 A3 ???
Error returns:
87
TRAP#1 D0=$4 MT.RJOB
Remove job from transient program area
Error returns:
This trap removes a job (and its subsidiaries) from the transient program
area. Only inactive jobs may be removed.
88
TRAP #1 D0=$1B MT.RXINT
D0=$1D MT.RPOLL
D0=$1F MT.RSCHD
D0=$21 MT.RIOD
D0=$23 MT.RDD
D1 D1 preserved
D2 D2 preserved
D3 D3 preserved
A0 address of link A0 preserved
A1 ???
A1
A2 preserved
A2
A3 preserved
A3
89
TRAP #1 D0=$14 MT.SCLCK
Set the clock
90
TRAP #1 D0=$8 MT.SUSJB
Suspend a job
Error returns:
A job may be suspended for an indefinite period, or until a given time has
elapsed. The timeout period is up to ($7FFF times the frame time).
If the job ID is a negative word, then the current job is suspended. The flag
byte is cleared when the job is released. If there is no flag byte, then A 1
should be o. If the timeout period is specified as -1, then the suspension is
indefinite; no other negative value should be used. If the job is already
suspended, the suspension will be reset. All jobs are rescheduled.
91
TRAP #1 D0=$7 MT.TRAPV
Set the per-job pointer to trap vectors
92
14.0 I/O Management Traps
D1 preserved
D1
D2 preserved
D2 D3 preserved
D3 A0 ???
A0 channel lD A1
A1 ??
A2 ?
A3 A2 preserved
A3 preserved
Error returns:
93
TRAP #2 D0=$4 IO.DELET
Delete a file
Error returns:
94
TRAP #2 D0=$3 IO.FORMT
Format a sectored medium
Error returns:
OM out of memory
NF drive not found
IU drive in use
FF format failed
The medium name is in the form of a character count (word) followed by the
ASCII characters of the drive name, the drive number, underscore then up to
10 characters for the medium name. For example, MDV1_November.
95
TRAP #2 D0=$1 IO.OPEN
Open a channel
Error returns:
96
If the job ID is passed as a negative word (for example -1) then the channel
will be associated with the current job.
The file or device name should be a string of ASCII characters. This string is
preceded by a character count (word), the pointer should point to this word (on
a word boundary).
The error return "BN" indicates that the name of the device has been
recognised but that the additional information is incorrect, for example
CON_512y240.
The code is usually ignored for access to any non-shared device: in practice,
this is anything other than a file store. If the error code is non- zero then no
channel has been opened.
Note that New (overwrite) is not currently supported for Microdrive files.
97
15.0 I/O Traps
D1 D1 ???
D2 D2 preserved
D3.W timeout D3. L preserved
A0 channel lD A0 preserved
A1 A1 ???
A2 A2 preserved
A3 A3 preserved
Error returns:
NC not complete
NO channel not open
This trap is used to check whether all of the pending operations have
completed.
98
TRAP #3 D0=$41 FS.FLUSH
Flush buffers for this file
D1 D1 ???
D2 D2 preserved
D3.W timeout D3.L preserved
A0 channel ID A0 preserved
A1 A1 ???
A2 A2 preserved
A3 A3 preserved
Error returns:
NC not complete
NO channel not open
When a write operation to a file is complete, the data written may still be in the
slave blocks rather than on the file. For further details please see Section 5.2
on File I/O. This call may be used to check that a file is in a known state.
99
TRAP #3 D0=$47
FS.HEADR
Read file header
Call parameters
Return parameters
D1
D2.W buffer length D1.W length of header read
D3.W timeout D2 preserved
A0 channel lD D3.L preserved
A1 base of read buffer A0 preserved
A2 A1 top of read buffer
A3 A2 preserved
A3 preserved
Error returns:
NC not complete
NO channel not open
BO buffer overflow
The read header call is provided so that a job can allocate the space for a load
call as well as determining the characteristics of a file. The buffer provided
must be at least 14 bytes long. In the case of a trap to a pure serial device,
then the length of the header returned in D1 will be spurious.
The file pointer is such that position zero is the first byte after the header.
Thus block boundaries on standard directory driver files are at positions
512*n-64.
100
TRAP#3 D0=$46 FS.HEADS
Set file header
NC not complete
NO channel not open
This call sets the first 14 bytes of the header. The length of file will normally be
overwritten by the filing system. When a header is sent over a pure serial
device, then the 14 bytes of the header are preceded by a byte $FF.
101
TRAP #3 D0=$48 FS.LOAD
Load file into memory
D1 D1 ???
D2.L length of file D2 preserved
D3.W timeout D3. L preserved
A0 channellD A0 preserved
A1 base address for load A1 top address after load
A2 A2 preserved
A3 A3 preserved
Error returns:
Files may be loaded into memory in their entirety with the file load trap. If the
transient program area is used for this, a trap # 1 must have been invoked to
reserve the space before the file load trap is invoked.
D3 should be set to -1 before both this trap, and FS.SAVE, and the base
address in A1 must be even.
102
TRAP#3 D0=$45 FS.MDINF
Get information about medium
Error returns:
NC not complete
NO channel not open
The name of the medium, its capacity, and the available space may be
obtained for a file or directory that is open.
The medium name is 10 bytes long and left justified. Any remaining bytes
are filled with the space character ($20).
103
TRAP#3 D0=$42 FS.POSAB
Position file pointer absolute
Error returns:
NC not complete
NO channel not open
EF end of file
104
TRAP #3 DO=$43 FS.POSRE
Position file pointer relative
Error returns:
NC not complete
NO channel not open
EF end of file
If a file positioning trap returns an off file limits error, then the pointer is set to
the nearest limit, this being 0 or end of file. The relative file positioning may, of
course, be used to read the current file position.
105
TRAP#3 D0=$49 FS.SAVE
Save file from memory
D1 D1 ???
D2.L length of file D2 preserved
D3.W timeout D3.L preserved
A0 channel lO A0 preserved
A1 base address of fi Ie A1 top address of file
A2 A2 preserved
A3 A3 preserved
Error returns:
In common with FS.LOAD, D3 should be set to -1 before this trap, and the
base address in A1 must be even.
106
TRAP #3 D0=$4 IO.EDLIN
Edit a line of characters (console driver only)
Error returns:
NC not complete
NO channel not open
BO buffer overflow
This is similar to the fetch line trap, except that the pointer A 1 is always to the
end of the line, D1 contains the current cursor position in the msw and the
length of the line in the Isw and the line (from the current cursor position) is
written out to the console when the call is made. The line should not have a
terminating character when the trap is made, but the terminating character will
be included in the character count on return. Enter (ASCII 10), up cursor or
down cursor are all acceptable terminating characters.
107
TRAP#3 D0=$1 IO.FBYTE
Fetch a byte
Error returns:
NC not complete
NO channel not open
EF end of file
108
TRAP #3 DO=$2 or 3 IO.FLlNE
IO.FSTRG
Error returns:
NC not complete
NO channel not open
EF end of file
B0 buffer overflow (fetch line only)
The character count of a fetch a line trap includes the linefeed character
if found.
109
TRAP #3 D0=$0 IO.PEND
Check for pending input
D1 D1 ???
D2 D2.L preserved
D3. W timeout D3.L preserved
A0 channel lD A0 preserved
A1 A1 ???
A2 A2 preserved
A3 A3 preserved
Error returns:
This trap is used to check for pending input on a channel. It does not read
any data or modify the input channel in any way. This only works on the
console device if D3=0 and the keyboard queue is already connected to the
console.
110
TRAP #3 D0=$5 IO.SBYTE
Send a byte
Call parameters
Return parameters
D1.B byte to be sent
D2 D1 ???
D3.W timeout D2.L preserved
AO channellD D3.L preserved
A1 AO preserved
A2 A1 ???
A3 A2 preserved
A3 preserved
Error returns:
NC not complete
NO channel not open
DF drive full
OR off window/paper etc
111
TRAP#3 D0=$7 IO.SSTRG
Send a string of bytes
Call parameters
Return parameters
D1
D2.W nr of bytes to be sent D1.W nr. of bytes sent
D3.W timeout D2.W preserved
A0 channel ID D3.L preserved
A1 base of buffer A0 preserved
A2 A1 updated ptr to buffer
A3 A2 preserved
A3 preserved
Error returns:
NC not complete
NO channel not open
OF drive full
Please refer to section 5.3.5 for details of the special treatment afforded to
newlines on the console or screen device.
SD.ARC See the entry for SD.POINT for details.
112
TRAP #3 D0=$C SD.BORDR
Set the border width and colour
NC not complete
NO channel not open
This call redefines the border of a window. By default this is of no width. The
width of the border is doubled on the vertical edges. The border is inside the
window limits. All subsequent screen traps (except this one) use the reduced
window size for defining cursor position and window limits.
As a special case, the colour $80 defines a transparent border so that the
border contents are not altered by the trap.
If the call changes the width of the border, then the cursor is reset to the
home position (top left hand corner).
113
TRAP #3 D0=$20 to 24
SD.CLEAR
SD.CLRBT
SD.CLRLN
SD.CLRRT
SD.CLRTP
D1 D1 ???
D2 D2.L preserved
D3.W timeout D3.L preserved
A0 channellD A0 preserved
A1 A1 ???
A2 A2 preserved
Error returns:
NC not complete
NO channel not open
The clear window traps can clear all or part of a window. To clear a part of
a window the cursor is used as a reference. The clear operation consists of
overwriting all the pixels in the designated area with paper colour.
The division between the top of the window and the bottom of the window
is the cursor line. The cursor line is in neither the top nor the bottom ofthe
window.
114
The cursor line is the whole height of the current character fount (either 10 or
20 rows). The right hand end includes the character at the current cursor
position.
D1 D1 ???
D2 D2.L preserved
D3.W timeout D3.L preserved
A0 channel lD A0 preserved
A1 A1 ???
A2 A2 preserved
Error returns:
NC not complete
NO channel not open
The cursor is automatically enabled when a read line or edit line trap is
issued to a console window.
115
TRAP #3 D0=$F SO.CURS
Suppress the cursor
D1 D1 ???
D2 D2.L preserved
D3.W timeout D3.L preserved
A0 channellD A0 preserved
A1 A1 ???
A2 A2 preserved
Error returns:
NC not complete
NO channel not open
The calls to suppress or enable the cursor do not return an error if the cursor
is already suppressed or enabled (respectively), as they merely ensure that
the cursor is in the desired state.
116
TRAP #3 D0=$9 SD.EXTOP
Call an extended operation
D1 parameter D1 parameter
D2 parameter D2 preserved
D3.W timeout D3.L preserved
A0 channel lD A0 preserved
A1 parameter A1 parameter
A2 start address of routine A2 preserved
Error returns:
NC not complete
NO channel not open
and anything from the operation routine
117
TRAP #3 DO=$2E SO.FILL
Fill rectangular block in window
Error returns:
NC not complete
NO channel not open
OR block falls outside window
This trap fills a rectangular block of a window with the current ink colour,
taking into account the mode set by SD.SETMD.
The block definition is in the same form as the window definition. It is 4 words
long: width, height, X origin and Y origin. The origin is referred to the window
origin.
118
TRAP #3 D0=$35
SD.FLOOD
Turn area flood on and off
Return parameters
Call parameters
Error returns:
NC not complete
NO channel not open
119
TRAP #3 D0=$25 SD.FOUNT
Set or reset the fount
D1 D1 ???
D2 D2.L preserved
D3.W timeout D3.L preserved
A0 channel ID A0 preserved
A1 base of fount A1 ???
A2 base of second fount A2 preserved
Error returns:
NC not complete
NO channel not open
If the fount address is given as zero the default fount will be used.
The structure of the fount assumes that up to a certain value characters are
invalid (default $1 E), from the next value (default $1 F) a known number of
characters are valid (default $61). Thus the structure is as follows:
$00 lowest valid character (byte)
$01 number of valid characters-1 (byte)
$02 to $0A 9 bytes of pixels for the first valid character
$08 to $13 etc.
Each byte of pixels has the pixels in bit 6 to bit 2 (inclusive) of the byte. The
top row of any character is implicitly blank.
120
The default fount extends from $20 to $7F.
Error returns:
NC not complete
NO channel not open
121
The whole of a window, or the whole of the cursor line, or the right hand end of
the cursor line may be panned by any number of pixels to the right or to the
left. A positive distance implies that the pixels will move to the right. The space
left behind will be filled with paper colour.
The cursor line is the whole height of the current character fount
(either 10 or 20 rows). The right hand end includes the character at the current
cursor position.
Error returns:
NC not complete
NO channel not open
OR off window
The cursor position is the top left hand corner of the next character rectangle
referred to the top left hand corner of the window. This trap clears the pending
newline in the window.
122
TRAP #3 D0=$30 SD.POINT SD.POINT
D0=$31 SD.LlNE SD.ARC
D0=$32 SD.ARC SD.ELlPS
D0=$33 SD.ELlPS SD.GCUR
D0=$34 SD.SCALE SD.LINE
D0=$36 SD.GCUR SD.SCALE
Plot a point, line, arc, ellipse, set scale or graphics cursor position.
Expects parameters on the arithmetic stack pointed to by (A1)
D1 D1 ???
D2 D2.L preserved
D3.W timeout D3.L preserved
A0 channel lD A0 preserved
A1 arithmetic stack pointer A1 ???
A2 A2 preserved
Error returns:
NC not complete
NO channel not open
These four traps draw various lines and arcs in the window. Any point on
these lines which falls outside the window will not be plotted.
123
SD.ARC $00(A1) angle subtended by arc
$06(A1) y-coord of finish of line
$0C(A1) x-coord of finish of line
$12(A1) y-coord of start of line
$18(A1 ) x-coord of start of line
For all the graphics traps, the parameters on the A1 stack are floating point,
and coordinates are referred to an arbitrary origin (default is 0,0) with an
arbitrary scale (default is height of window = 100 units).
The calling program must allocate at least 240 bytes on the A1 stack.
124
TRAP #3 D0=$10 to 16 SD.POS
SD.NCOL
Cursor positioning by character intervals SD.NL
SD.NROW
D0=$10 SD.POS absolute position SD.PCOl
D0=$11 SD.TAB tabulate SD.PROW
D0=$12 SD.Nl newline SD.TAB
D0=$13 SD.PCOl previous column
D0=$14 SD.NCOl next column
D0=$15 SD.PROW previous row next
D0=$16 SD.NROW row
Error returns:
NC not complete
NO channel not open
OR position would be out of window
In the case of an error return, the cursor position is not changed. The cursor
position is the top left hand corner of the next character rectangle referred to
the top left hand corner of the window. These traps clear the pending
newline in the window.
125
TRAP #3 D0=$A or B SD.PXENQ
SD.CHENQ
Return the current window size and cursor position
D1 D1 preserved
D2 D2 preserved
D3.W timeout D3.L preserved
A0 channel 10 A0 preserved
A1 base of enquiry block A1 ???
A2 A2 preserved
Error returns:
NC not complete
NO channel not open
The window size (X,Y) and cursor position (X,Y) are put into a 4 word
enquiry block. The top left hand corner of the window is cursor position 0,0.
These traps activate the newline if pending in the window.
126
TRAP#3 D0=$26 SD.RECOL
Recolour a window
D1 D1 ???
D2 D2.L preserved
D3.W timeout D3.L preserved
A0 channel lD A0 preserved
A1 pointer to colour list A1 ???
A2 A2 preserved
Error returns:
NC not complete
NO channel not open
The colour list is 8 bytes long and should contain the new colours required for
each of the 8 colours in the window. Each of the new colours must be in the
range 0 to 7. For 4 colour mode, only bytes 0,2,4 and 6 need to be filled in.
127
TRAP #3 D0=$18 to 1A SD.SCROL
SO.SCRBT
Scroll part or all of a window SO.SCRTP
NC not complete
NO channel not open
Part or all of a window may be scrolled; for partial scrolling the cursor is used as
a reference. These traps cause pixels to be transferred from one row to
another. Vacated rows of pixels are filled with paper colour. A positive scroll
distance implies that the pixels in the window will be moved in a positive
direction, ie, downwards. The space left behind will be
filled with paper colour.
The division between the top of the window and the bottom of the window is
the cursor line. The cursor line is included in neither the top nor the bottom of
the window. The cursor is not moved.
128
TRAP #3 D0=$2A and 2B SD.SETFL
SD.SETUL
Set flash and underscore
Error returns:
NC not complete
NO channel not open
129
TRAP #3 D0=$2C SD.SETMD
Set the character writing or plotting mode
Error returns:
NC not complete
NO channel not open
130
TRAP #3 D0=$27 to 29 SO.SETPA
SO.SETIN
Set screen colours SO.SETST
DO=$27 SD.SETPA
DO=$28 SD.SETST set paper colour
DO=$29 SD.SETIN set strip colour
set ink colour
Error returns:
NC not complete
NO channel not open
The screen driver uses three colours. There is the background colour of a
window: referred to as paper colour; this is the colour which is used by the
scroll, pan and clear operations. There is the colour which is used by the
character generator to provide a highlighting background for individual
characters or words: referred to as strip colour. Finally, there is the colour used
for writing characters and drawing graphics: referred to as ink colour.
131
TRAP#3 D0=$20 SD.SETST
Set character size and spacing
Error returns:
NC not complete
NO channel not open
The character generator supports two widths and two heights of character. In 8
colour mode, only the double width characters may be used. In addition the
spacing between characters is entirely flexible, but for simplicity of use only two
additional spacings are supported directly: these are 8 pixel and 16 pixel, in
single and double width respectively.
Calls with D1=0 or 1 in 8 colour mode will operate as though a call had
been made with D1 equal to 2 or 3.
132
TRAP #3 D0=$0 SD.WDEF
Redefine a window
Error returns:
NC not complete
NO channel not open
OR window does not fit on page
This call redefines the shape or position of a window: the contents are not
moved or modified, but the cursor is repositioned at the top left hand corner of
the new window. The window block is 4 words long and is the width, height, X
origin and Y origin.
133
16.0 Vectored Routines
Vector$110 BP.INIT
word 0
word approximate number of functions (see below)
word 0
134
The pointers to the routines are relative to the address of the pointer
(e.g. DC.W ENTRY- *)
All registers except A 1, and D2 are preserved by BP.INIT and no more than
48 bytes are used on the user stack.
The type of the entity to be assigned (and hence its length) is determined by the
type in the name table entry.
On exit, D0 is an error code, and D1, D2, D3, A0, A 1 and A2 are smashed.
Since not only the stack but the whole SuperBASIC area may move during
the call, the arithmetic stack pointer should be saved in BV_RIP(A6),
whence it should be retrieved after the call has been completed.
135
CA.GTFP See the entry for CA.GTINT for details.
On entry, (A6,A3) points to the name table entry for the first parameter in
the list, and (A6,A5) points to the entry for the last.
These routines smash D1, D2, D4, D6, AO and A2. DO, and also the
condition codes, give the error code. The separator flags in the name table
entries are also smashed.
136
CN.BTOIL See the entry for CN.DTOF for details.
There are two date conversion routines: CN.DATE returns the date in the form
yyyy mmm dd hh:mm:ss, CN.DAY returns a three letter day of the week. The
result is put on the A 1 stack in string format. At least 22 bytes are required by
CN.DATE and at least 6 bytes by CN.DAY. CN.DAY See the entry for
CN.DATE for details.
137
Vector $100 CN.DTOF floating point CN.DTOF
$102 CN.DTOI integer CN.BTOlL
&$104 CN.BTOIB binary (byte) CN.BTOIW
&$106 CN.BTOIW binary (word) CN.DTOI
&$108 CN.BTOlL binary (long) CN.HTOIB
&$10A CN.HTOIB hex (byte) CN.HTOlL
&$10C CN.HTOIW hex (word) CN.HTOIW
&$10E CN.HTOlL hex (long)
D1 D1 ???
D2 D2 ???
D3 D3 ???
D7 0 or ptr to end buffer D7 preserved
A0 pointer to buffer A0 pointer to buffer
A1 pointer to stack A1 pointer to stack
A2 A2 ???
A3 A3 ???
Error returns:
The hex and binary conversions from ASCII to number, always put a
long word on the A1 stack. A1 is set to point to the least significant
byte or less significant word for the byte and word conversions.
138
If there is an error then A0 and A1 are both unchanged. Otherwise, on return,
A1 points to the return value (floating point, long word, word or byte) and AO
points to the next character in the buffer.
D0 ???
D1 D1 ???
D2 D2 ???
D3 D3 ???
A0 pointer to buffer A0 pointer to buffer
A1 pointer to stack A1 pointer to stack
A2 A2 ???
A3 A3 ???
139
CN.lTOBL See the entry for CN.FTOD for details.
CN.ITOBW See the entry for CN.FTOD for details.
CN.ITOD See the entry for CN.FTOD for details.
CN.ITOHB See the entry for CN.FTOD for details.
CN.lTOHL See the entry for CN.FTOD for details.
CN.ITOHW See the entry for CN.FTOD for details.
Call parameters
Return parameters
D1
D2 D1 ???
D3 D2 ???
A0 pointer to name D3 ???
A1 A0 preserved
A1 ???
A2
A2 ???
A3 pointer to parameters
A3 preserved
Error returns:
This routine parses a device name. Given a device name and a description
of the syntax of the name to be checked against and for the possible
parameters to be appended to it, the routine determines·) whether the name
is recognised, and extracts the parameters if it is. The device name is formed
using four components:
140
Name ASCII characters, normally letters. Case is ignored.
Separator Single ASCII character. Case is ignored.
Number Decimal number in the range 0 to 32767
Code One of a list of ASCII characters
On entry to the routine, AO must point to the device name (which is in the
usual Qdos string format), A3 must point to an area of memory which is
sufficient to hold the decoded parameter values, and A6 must point to the base
of system variables. The device description starts 6 bytes after the call, and is
in the following format:
For each numeric parameter value in the description, the utility will return
either the value given in the device name, or the default. For each list of codes
in the description the utility will return the position of the code in the list, or
zero.
Examples:
141
Device name Parameters
CON 448,180,0,0,128
CON_256 256,180,0,0,128
con_60 448,180,0,0,60
conaOx12 448,180,0,12,128
con_256x64a64x128_20 256,64,64,128,20
SER 1,0,0,0
SERE 1,1,0,0
ser2miZ 2,3,1,2
If the name is not matched, the routine returns immediately after the call with
ERR.NF in D0. If the name is matched but the additional information is
incorrect, it returns 2 bytes after the call with ERR.BN in D0. If a match is
found, it returns 4 bytes after the call with D0=0.
142
Vector $DC IO.QSET set up a queue IO.QSET
$DE IO.QTEST test status of queue IO.QEOF
$E0 IO.QIN put byte into queue IO.QIN
$E2 IO.QOUT extract byte from queue IO.QUOT
$E4 IO.QEOF put end of file marker into queue IO.QTEST
Error returns:
143
Vector $EB IO.SERQ direct queue handling IO.SERQ
$EA IO.SERIO general IO handling IO.SERIO
Error returns:
IO.SERQ should be called with standard 1055 values in DO, D1, D2,
D3,A0 and A1.
For serial I/O where the operations for byte input and output are not so
simple, the routine IO.SERIO may be called. The call instruction should be
followed by three long words, these being the entry addresses for
testing for pending input, (next byte in D1)
fetch byte, (byte in D1)
send byte. (byte in D1)
144
The use of absolute addresses for these may prove awkward; so the entry to
this routine is best included in the physical definition block for the driver:
at $28(A3) or similar or
invoked by or
For the calls to the three service routines D0 should be returned as the error
code, D1 to D3 and A1 to A3 inclusive are volatile.
Both of these calls treat actions 0,1,2,3,5 and 7, the header set and read
actions and load and save: for undefined actions they return ERR.BP.
145
Vector $124 MD.READ read a sector MD.READ
$126 MD.WRITE write a sector MD.SECTR
$128 MD.VERIN verify a sector MD.VERIN
$12A MD.SECTR read a sector header MD.WRITE
D1 file nr (read/verify)
D1
D2 block nr (read/verify)
D2
D7 sector nr (read headr)
D7
A0 ???
A0
A1 pointer to end of bufr
A1 pointer to start of bufr
A2 ???
A2
A3 $18020
A3 $18020
Error returns:
MD.WRITE none
MD.READ, MD.VERIN normal - failed
return+2 OK
MD.SECTR normal - bad medium
return+2 - bad sector header
return +4 - OK
The microdrive support routines are vectored to simplify the writing of file
recovery programs. On entry A3 must point to the microdrive control register,
and the interrupts must be disabled. All registers except A3 and A6 are treated
as volatile.
Before calling MD.WRITE the stack pointer must point to a word: the file
number and the block number of the sector to be written are in the high and
low byte respectively.
146
These vectors point to $4000 bytes before the actual entry point. The
following code may be used:
MOVE.W aa.aaaa,An
JSR $4000(An)
Error returns:
OM out of memory
147
This routine must be called from supervisor mode, with A6 pointing to the
base of system variables. It may not be called from a task which services an
interrupt.
The space requested must include room for the heap entry header. For
simple heap entries this is 16 bytes long, for IOSS channels this is 24 bytes
long.
The address of the heap area is the base of the area allocated, not the base
of the area which may be used (contrast with trap #1 D0= $18 and $19).
Error returns:
148
Vector $DA MM.LNKFR
Link a free space (back) into a heap
D1 D1 ???
D2 D2 ???
D3 D3 ???
A0 ???
A0 base of area to release
A1 ???
A1
A2 ???
A2 A3 ???
A3
149
Vector $11C RI.EXEC executes an operation RI.EXEC
$11E RI.EXECB executes a list of operations RI.EXECB
Error returns:
OV arithmetic overflow
All addresses passed to these routines must be relative to A6. The arithmetic
package is available for general use through two vectors: the first executes a
single operation; the second executes a list of operations.
The package operates on floating point numbers on a downward stack
pointed to by (A6,A1.L). lt operates on the top of the stack (TOS) which is
pointed to by (A6,A1.L), and the next on stack (NOS) at 6(A6,A1.L).
The interpreter takes two types of operation codes. The first is a true arithmetic
operation with an operation code between $02 and $30 inclusive, the second is
a negative code between $FFFF and $FF31 inclusive: this indicates a load or
store operation of a floating point number to or from the location given by the
calculation (A6.L +A4.L +opcode$FFFE). lf bit 0 of the opcode is clear the
operation is a load (A1 decremented by 6, creating a new TOS), if it is set the
operation is a store (A1 incremented by 6, NOS- ->TOS)
150
For RI.EXEC the operation code should be passed asa word. For
RI.EXECB the operation codes are in a table of bytes pointed to by A3. The
table isterminated by a zero byte.
151
Vector $E6 UT.CSTR
Compare two strings
UT.ERRO
UT.ERR
Return parameters
Call parameters
D0.1 preserved
D0.1 error code
D1 preserved
D1
D2 preserved
D2
D3 preserved
D3
A0 preserved
A0 channel ID (UT.ERR only)
A1 preserved
A1
A2 preserved
A2
A3 preserved
A3
152
These routines must be called from user mode.
These routines exist for writing simple messages to a channel. They are
basic error message handlers which write a standard or device driver
supplied error message to either the command channel 0, or else to a
defined channel.
UT.LINK
UT.UNLINK
Vector $02 UT.LINK link an item into a list
$04 UT.UNLNK unlink an item from a list
D1 D1 preserved
D2 D2 preserved
D3 D3 preserved
A0 base of item (un)linked A0 preserved
A1 pointer to previous item A1 updated
A2 A2 preserved
A3 A3 preserved
These routines are passed the base address of the item to be linked or
unlinked, and a pointer which points to either the pointer to the first item in
the list, or to an item in the list.
When an item is linked in, it will be linked in at the start of the list, or, if the
pointer was to an item in the list, after that item.
When an item is removed, the pointer may point to the pointer to the
first item in the list, or to any item in the list before the item to be
removed.
When starting a new list, the pointer to the first item in the list must be zero.
153
Each item in the list must have 4 bytes reserved at the start for the link pointer.
Error returns:
154
Vector $D0 UT.MTEXT
Send a message to a channel
D1 D1 ???
D2 D2 ???
D3 D3 ???
A0 channellD A0 preserved
A1 base of message A1 ???
A2 A2 preserved
A3 A3 preserved
Error returns:
The above routines (UT.MINT and UT.MTEXT) are provided to write parts
of more complex messages to a defined channel.
155
UT.WINDW
Vector $C4 UT.WINDW set up a window using a UT.CON
supplied name UT.SCR
set up console window
$C6 UT.CON
set up screen window
$C8 UT.SCR
D1 D1 ???
D2 D2 ???
D3 D3 ???
A0 ptr to name (WINDW only) A0 channel ID
A1 ptr to parameter block A1 ???
A2 A2 ???
A3 A3 ???
Error returns:
The above three routines, which must be called in user mode, set up console
or screen windows using a parameter list which follows the call statement. In
the first case, the window is opened using a name which has been supplied,
a block of parameters defining the border, and the paper, strip and ink
colours. The window is set up and cleared for use.
The second and third routines define the window using an additional block
of four words.
156
The parameter block is as follows:
157
18.0 Qdos Keys
The following sections contain keys for various features of Qdos. These
keys provide a definition for several of the data structures within Qdos.
The following keys indicate error messages already defined in the system.
A positive error code istaken as an address of a user-supplied error
message. See the Concepts manual for a fuller description ofthe way in
which these are used by the procedures built into SuperBASIC.
158
18.2 System Variables
The following list gives the offset of each system variable from the base
of the system variables (whose position can be found using the MT.lNF
trap), together with the length of the variable.
The following variables are the pointers which define the current state of the
Qdos memory map.
The following system variables are pointers to the list of tasks and drivers.
159
The following system variables are pointers to the resource management tables.
The slave block tables have 8 byte entries, whilst the others have 4 byte entries.
The following variables contain information about how to treat the keyboard, and
about other aspects of the IPC and serial port communications. SV_CAPS,
SV_ARDEL, SV_ARFRQ and SV_CSUB can safely be poked.
160
SV_MDRUN $EE byte which drive is running?
SV_MDCNT $EF byte microdrive run-up run-down counter
SV_MDDID $F0 8 bytes drive ID*4 of each microdrive
SV_MDSTA $F8 8 bytes status 0=no pending ops
SV_FSDEF $100 16*long pointers to file system physical definition
SV_FSLST $140 long pointer to list offile channel definitions
The following area, between $180 and $480 is reserved for the supervisor
stack. There is no explicit stack protection in the code, although the stack
should be of sufficient size for most normal purposes.
The first part of the area holds the pointers to the various areas of
memory used by the interpreter: it defines the partitioning of
SuperBASIC's own area of memory.
161
BV_RTP $3C long
BV_LNBAS $40 long line number table
BV_LNP $44 long
162
BV_DALNO $94 word current DATA line number
BV_DASTM $96 byte current DATA statement number
BV_DAITM $97 byte next DATA item to read
163
18.4 Offsets on BASIC Channel Definitions
The following section gives the format of an entry in the SuperBASIC
channel table, These entries can be monitored or modified by user-
164
JB_RELA6 $16 byte MSB set if next trap #2 or #3 has
addressing relative to A6
JB_WFLAG $17 byte set if there is a job waiting on
completion of this one
JB_WJOB $18 long job Id of waiting job
JB_TRAPV $1C long pointer to trap redirection vectors
JB_00 $20 save offset of D0
JB_01 $24 save offset of D1
JB_02 $28 save offset of D2
JB_03 $2C save offset of D3
JB_04 $30 save offset of D4
JB_05 $34 save offset of D5
JB_06 $38 save offset of D6
JB_07 $3C save offset of D7
JB A0 $40 save offset of A0
JB A1 $44 save offset of A1
JB A2 $48 save offset of A2
JB A3 $4C save offset of A3
JB A4 $50 save offset of A4
JB A5 $54 save offset of A5
JB A6 $58 save offset of A6
JB A7 $5C save offset of A7
JB_USP $5C save offset of USP
JB_SR $60 save offset of SR
JB_PC $62 save offset of PC
JB_ENO $68
165
18.6 Memory Block Table Definitions
The following keys define the format of the start of a slave block.
The most significant 4 bits of the status byte contain the pointer to the physical
device block SV_FSDEF, the least significant are the status
codes:
166
Channel definition header for all channels:
167
18.8 File System Definition Blocks
File system channel definition block format:
168
18.9 Screen Driver Data Block Definition
This is the format of the block handed to a screen driver operation.
SD_NLSTA $48 byte new line status (>0 implicit, <0 explicit)
SD_END $68
169
18.10 Queue Header Definitions
The following is the format of the header of a queue manipulated using
the system's built-in queue handling routines.
170
RI.SQRT $28 square root
RI.LN $2A natural log
RI.LOG10 $2C logarithm to base 10
RI.EXP $2E exponential
RI.POWFP $30 nos to power of tos
RI.MAXOP $30 highest valid opcode
RI.LOAD $00 load operation bit
RI.STORE $01 store operation bit
171
PC_TDATA $18022 transmit data
PC_TRAK1 $18022 Microdrive read track 1
PC_TRAK2 $18023 Microdrive read track 2
MC_STAT $18063 display control
172
Write masks:
173
MT.ALBAS $16 allocate BASIC area
MT.REBAS $17 release BASIC area
MT.ALCHP $18 allocate space in common heap
MT.RECHP $19 release space in common heap
MT.LXINT $1A link in external interrupt handler
MT.RXINT $1B remove external interrupt
MT.LPOLL $1C handler
link in polled task
MT.RPOLL $1D remove polled task
MT.LSCHD $1E link in scheduler task
MT.RSCHD $1F remove scheduler task
MT.LlOD $20 link in IO driver
MT.RIOD $21 remove IO driver
MT.LDD $22 link in directory driver
MT.RDD $23 remove directory driver
174
SD.WDEF $0D define window
SD.CURE $0E enable cursor
SD.CURS $0F suppress cursor
SD.POS $10 absolute position
SD.TAB $11 tab (horizontal position)
SD.NL $12 newline
SD.PCOL $13 previous column
SD.NCOL $14 next column
SD.PROW $15 previous row
SD.NROW $16 next row
SD.PIXP $17 set pixel position
SD.SCROL $18 scroll whole window
SD.SCRTP $19 scroll top of window
SD.SCRBT $1A scroll bottom of window
SD.PAN $18 pan window
SD.PANLN $1E pan cursor line
SD.PANRT $1F pan RHS of cursor line
SD.CLEAR $20 clear whole window
175
SD.LIN $39 lines in pixel coords
FS.CHECK $40 check all pending operations
FS.FLUSH $41 flush buffers
FS.POSAB $42 position file pointer (absolute)
FS.POSRE $43 position file pointer (relative)
FS.MDINF $45 information about medium
FS.HEADS $46 set file header
FS.HEADR $47 read file header
FS.LOAD $48 load file
FS.SAVE $49 save file
176
CN.ITOHL $FE long to ASCII hex
CN.ITOHW $FC word to ASCII hex
177
19.0 Doing Business with Sinclair
The purpose of this section is to encourage those thinking of developing
commercial software for the QL to consider offering it to Sinclair Research for
publishing, promotion and distribution. There are various options offered to
software houses, with varying degrees of Sinclair involvement and support.
The second option is for the software house to give Sinclair an exclusive
licence to distribute the product in Sinclair packaging, but to sell the product
to Sinclair as a fully packaged finished product to Sinclair specification. In this
way the software house remains responsible for production and packaging,
with Sinclair undertaking promotion, distribution and sale.
The third option is for the software house to retain responsibility for
production, packaging, promotion, distribution and sale of the product, but
allowing Sinclair to offer the product for sale in addition. This method
provides the software house with an opportunity to increase its sales, as the
product will be promoted in all Sinclair Mail Order literature. As orders are
received, they will be passed to the software house, and Sinclair will require
a percentage commission on orders generated in this way. Under this option,
Sinclair packaging is not used for the product and so it remains very much
the software house's 'own brand'.
178
Further details of the above options are given later on in this section, but
first, the procedure for offering software to Sinclair is dealt with, together
with Sinclair methods of review and appraisal.
The first of these areas is the product concept. Under this heading,
answers must be provided to such questions as:
If it exists:
How is it selling?
Methods of sale?
Volumes to date?
What machine does it run on?
Obviously, some of the questions listed above assume that the product does
not already exist for the QL or any other Sinclair computer. However, if it does
run on some other computers, the second area to be examined would be
concerned with how the product might be adapted to make use of the QL's
features.
179
Specifically:
Apart from considering the two areas described above, the product would need
to be reviewed by Sinclair. For such a review to take place, the software house
would need to send either:
1, The product itself, running on the QL, together with draft documentation,It
need not be finished and completely bug free, so long as it is sufficiently
complete to be able to be put out for review,
or
or
3. Anything that does not fall clearly into either of these two categories
(e.g., games, compilers, utilities, expert systems etc.), should be sent
to the Software Manager, at the same address.
180
19.3 How Products are reviewed and what
Sinclair are looking for
1. Games and entertainment software
3. Educational software
181
2. Software which provides adult home education in fields
previously uncatered for.
4. Business software
Business software will be reviewed internally unless it caters for a
specific vertical market in which case Sinclair may seek permission to
have the product reviewed in detail by an independent
consultant. When possible business packages are being considered,
both the company and the product will be examined very carefully.
Thus the following are particularly sought after:
4. A secure financial backing which will ensure that the company will
not disappear after Sinclair have launched the product, leaving no
support for it.
182
1. Distribution in Sinclair packaging
Under this option, the product would neither be sold in Sinclair packaging
nor would it carry the Sinclair name. It would instead be packaged in the
software house's own packaging under its own name. It would, however,
be promoted as a Sinclair endorsed product in the Sinclair catalogue.
Orders would be sent to a special PO box at Sinclair's despatching
warehouse and would then be forwarded direct to the software house for
fulfilment. Sinclair would, of course, expect to be paid a percentage
commission on orders generated in this way, which would normally be
equivalent to 15% of the retail selling price.
183
19.5 Promotion and Distribution
6) be offered to our local area offices and distributors all over the world,
for translation into foreign languages;
184
19.6 Summary
Many software houses writing software for personal computers today are
concerned about the possible dilution of effort that is entailed
when a product has to be packaged, promoted, marketed and sold as
well as developed. Sinclair Research are known for their ability to obtain
media coverage and for their marketing and distribution capabilities.
In the case of the QL, Sinclair believe that software houses can be offered
distribution opportunities without equal. The Qlub will enable direct contact to
be retained with customers on a far larger scale than previously possible with
other Sinclair computers. It is proposed to use the Qlub Newsletters as a
method of informing customers of every new product launched in advance of
the general public. Small discounts will be offered which will make the product
attractive tothe customer, but will not begin to approach the kind of discounts
Sinclair would need to give should the product be offered through a distributor
or a retailer.
185
20.0 Bibliography
1. MC68000 16/32-bit microprocessor programmer's reference manual.
186
21.0 Index
CA.GTFP 54,136,176
A1 stack see arithmetic stack CA.GTINT 54,136,176
access layer CA.GTLIN 54,136,176
of device driver 31,32,34,37 CA.GTSTR 54,136,176
of directory drive 38-45 CAPSLOCK 30
add-on change queue character 30
card ROM 66 channel 24
cards 63,66 close 24,30,35-36,42-3
hardware 56 console
peripherals 56 definition block 32,38,166-167
RAM 56,63 ID 17,24
ROM 10,56,63,66 number 55
allocation open 24,30,34-35,41-42
heap 8,23,147 table 47,55
memory 9-10,22,31 superBASIC 9,164
alphabets, special 69 character conversion 138,139
area flood 119 character set 68
arithmetic change queue 30
interpreter operation codes 170-171 freeze screen 30
stack 47,54-55,135 local 68
array storage 51 spacing 27
atomic actions 13 character size 125,130,175
auto-repeat 30 clock 59
real-time 57,59
baud 59,75,173 CN.BTOIB 138,176
blocks CN.BTOIL 138,176
physical 38 CN.BTOIW 138,176
slave 9,44,166 CN.DATE 59,137
BOOT CN.DAY 59,137
device driver 16 CN.DTOF 138,176
file 16 CN.DTOI 138,176
border 28,113 CN.FTOD 139,176
BP.INIT 52,69,134,176 CN.HTOIB 138,176
BP.LET 55,135,176 CN.HTOIL 138,176
buffer 47 CN.HTOIW 138,176
bus error 14 CN.ITOBB 139,176
business 178-185 CN.ITOBL 139,176
BV.CHRIX 22,54,135,176
187
CN.ITOBW 139,176 device 24
CN.ITOD 139,176 decoding 31,140
CN.ITOHB 139,176 name 24
CN.ITOHL 139,177 device driver(s) 22,24,31-37
CN.ITOHW 139,177 access layer 31,32,34-37
code BOOT 16
initialisation 31,33 built-in 46
position-independent 19 console 46
restrictions 52 definition block 32
colour 28,74 directory 38-45,60
border 28 initialisation 32-33
ink 28 memory allocation 32
paper 28 Microdrive 46
strip 28 network 59
command interpreter 17 non-directory 39,41
common heap 7,8 physical layer 21,31,33-34
allocation 8,23,147 pipe 46
release 149 screen 46
console 27 serial I/O 46
I/O 27-30,46 serial network link 46
console channels 27 user defined 21
special properties 29-30 user supplied 31
contracts 182-183 directory device driver(s) 38-45
coordinate system access layer 40
graphics 27 initialisation 38
pixel 27 linkage block 39
CPU interface 64-65 Microdrive 60
CTS 59 display
cursor 125 control 57-58
flashing 30 modes 27,76
increment 28 RAM 56
position 28 display control register 58
distribution 183-184
date 137 draw 123
definition block DTR 59
channel 31,38,166-167
device driver 31-33 error
directory device bus 14
linkage 38 keys 158
file system 166-167 messages 152,158
physical 38 exception processing 14-15
188
EXEC 18 hardware 56,171-173
EXEC_W 18 add-on 56
expansion 63-64 heap 23
extensions, operating system 17,21 allocation 8,23,147,149
external interrupt 14,34 common 7,8,9,147-149
expanding 23
file linking free space into 149
BOOT 16 mechanism 8,23
header 26,38 management 72-73
format 26 setting up 23
I/O 26 user 23
pointer 26
program 47 initialisation
shared 41 code 31,33
file delete 41-42 device driver 32,33
file system definition blocks 168 directory device driver 38
flag 28 Qdos 6-16,158-177
characteristics 66 system management
flashing 30,57,58 tables 16
floating point storage 50,51 system variables 16
format routine 41,45 Input/Output (I/O) 24-30,33
fount 120 36-37,42,43
frame interrupt 14 console 27-30,46
free memory 7,9,22-23 file 26
freeze screen character 30 queue 30
FS.CHECK 26-27,98,176 screen 27-30,46
FS.FLUSH 26-27,99,176 serial 24,31,46,59,144
FS.HEADR 100,176 Input/Output sub-system 8,24,43
FS.HEADS101.176 Integer storage 50,51
FS. LOAD 102,176 Intelligent Peripheral
FS.MDINF103,176 Controller
FS.POSAB 104,176 8049 (IPC) 58,79
FS.POSRE 105,176 link commands 171
FS.SAVE106,176 interfacing 47-55
functions 52 interrupt
linking 52 auto-vectored 13
superBASIC 21 external 13,24
frame 14
graphics 29,123 level 10,15
coordinate system 27 non-maskable 15
operations 29 polling 34
traps for 14-16
189
interrupt servers 14 enable cursor 115,175
I/O see Input/Output extended operation 117,174
IO.CLOSE 93,174 fetch a byte 108,174
IO.DELET 41,94,174 fetch a line of bytes 109,174
IO.EDLIN 29,107,174 fetch a string of
IO.FBYTE 108,174 bytes 108,174
IO.FLINE 29,109,174 fill block 118,175
IO.FORMT 95,174 flush buffers 99,176
IO.FSTRG 108,174 information about
I/O management traps 10-11,93-97 medium 103,176
close channel 93,174 keys 173-176
delete file 94,174 load file 102,176
format medium 95,174 newline 125,175
keys 174 next column 125,175
open channel 96,174 next row 125,175
IO.NAME 35,140,177 pan part or whole
IO.OPEN 35,41,96,174 window 121,175
IO.PEND 110,174 pixel based size/
IO.QEOF 143.177 position enquirer 104,126
IO.QIN 143.177 plot and draw various lines and
IO.QOUT 143.177 arcs 123,175
IO.QSET 143,177 position file pointer (absolute)
IO.QTEST 143,177 104,176
IO.SBYTE 25,111,174 position file pointer (relative)
IO.SERIO 37,144,177 105,176
IO.SERQ 37,144,177 previous column 125,175
IOSS see Input/Output previous row 125,175
sub-system read file header 100,176
IO.SSTRG112.174 recoloura window 127,175
I/O traps 11,21,98-133 save file 106,176
absolute position 104,125 scroll part or whole window
character based size/position 128,175
enquiry 126,174 send a byte 111,174
check all pending send a string of bytes 112,174
operations 98,176 set character size and spacing
check for pending input 110,174 132,175
clear part or whole set character size 130,175
window 114,174 set file header 101,176
define window 133,174 set fill mode vectors 119,175
define window border 113,174 set flash and under-score
edit a line 107,174 129,175
190
set fount addresses 120,175 allocate BASIC area 71,173
set pixel position 122,175 allocate resident procedure area
set screen colours 131,175 74,173
set write mode 130,175 allocate space in common heap
suppress cursor 116,175 72,173
tab (horizontal position) 125,175 create a job 75,173
find how much free space there is
IPC see Intelligent Peripheral 77,173
Controller force remove a job 77,173
job(s)10,17-21 get information on job 81,173
active 17-19 get system information 78,173
format keys 173-176
header 47,164-165 link external interrupt handler
ID 13,18-19 83,174
inactive 17 link in directory driver 83,174
start-up 17-19 link in I/O driver 83,174
suspended 17 link in polled task 83,174
table 19 link in schedulertask 83,174
tree 47,49 read clock 84,173
release a bit of a heap 82,173
keyboard release a job 86,173
auto-repeat 30 release BASIC area 85,174
control 58 release resident procedure area
non-English language 67 87,173
special functions 30 release space in common heap
type-ahead 30 85,174
KEYROW 40,59 remove directory driver 89,174
remove external interrupt handler
line number table 47 89,174
linked lists 23,90 remove I/O driver 89,174
linking remove job 88,173
functions 52 remove polled task 89,174
procedures 52 remove schedulertask 89,174
send IPC command 79,173
machine code set a job priority 84,173
procedures 20 set baud rate 75,173
programming 17-21 set clock 90,173
Manager traps 11,69-92 set display mode 76,173
activate a job 69,173 set pointer to trap redirection
adjust clock 69,173 vector 92,173
allocate a bit of a suspend a job 91,173
heap 73,173 Master chip 57
191
MD.READ 60,146,177 MT. RDD 31,85,89,174
MD.SECTR 12,60,146,177 MT.REBAS 14,85,174
MD.VERIN 60,146,177 MT.RECHP 8,22,85,174,
MD.WRITE 60,146,177 MT.RELJB 86.173
medium name 42 MT.RERES 22,87,173
memory MT.RIOD 31,89,174
allocation 8-10,22,31 MT.RJOB 88,173
block table 166 MT.RPOLL 31,89,174
device driver 31 MT.RSCH 031,89,174
free 7,9,22 MT.RXINT 31,89,174
map 7-10,56 MT.SCLCK 59,90,173
organisation in superBASIC 47-48 MT.SUSJ 691,173
Microdrive 46 MT.TRAPV 14,92,173
Microdrives 24,26,46,60
Microdrive support routines 146 name
MM.ALCHP 22,147,177 decode 31,35,39,140,177
MM.ALLOC 22,148,177 list 48,49
MM.LNKFR 22,149,177 pointer 49
MM.RECHP 22,149,177 table 48-49,53,134
MT.ACLCK 59,69,173 network 46,59
MT.ACTIV 70,173 newline 25,28
MT.ALBAS 22,71,174 non-English 67-68
MT.ALCHP 8,22,72,174 version codes
MT.ALLOC 8,73,173 NTSC 40
MT.ALRES 14,74,173
MT.BAUD 59,75,173 on-board
MT.CJOB 75,173 RAM 56
MT.DMODE 27,57,58,76,173 ROM 56
MT.FREE 77,173 operating system 6
MT.FRJOB77.173 extensions to 17,21
MT.INF 8,19,67,78,173 operations
MT.IPCOM 58,68,79,173 executing lists of 151
MT.JINF81,173 execution of 150
MT.LDD 31,39,83,174 ownership 178
MT.LIOD 31,83,174
MT.LNKFR82,173 PAL 67
MT.LPOLL 31,39,83,174 pan 28,121,175
MT.LSCHD 31,39,83,174 parameter passing 52-53
MT.LXINT 31,39,83,174 parameters, actual 53-54
MT. PRIOR 84,173 peripheral card addressing 65
MT.RCLCK 59,84,173 peripheral cards 63-65
192
peripheral chip 57 Rl stack see arithmetic stack
physical definition block 38 ROM 3,10,24 -34
physical layer device driver 21,31,33-34 add-on 10,56,63,65,66
pipe 24,46 format 46
pixel coordinate system 27 on-board 56
plot 123 plug-in 56
polling interrupt 34 RS232 see serial I/O
priority 17,84,86
procedures 52 save area 97
linking 52 scheduler loop 34
SuperBASIC 17,20-21 screen
program file 47 colour 131
programming 56-62 I/O 27-30,46
promotion 183-184 RAM 56
publication 178 screen character output operations
28
Qdos screen driver 46
initialisation 7 datablock169
keys 105- scrolling 128
routines 10-14 SD.ARC 29.123
queue(s) 143 SD.BORDR 28,113,174
asynchronous 31 SD.CHENQ 28,126,174
handling 144 SD.CLEAR 28,114,175
header 170 SD.CLRBT 28,114,175
I/O 30 SD.CLRLN 28,114,175
type-ahead 30 SD.CLRRT 28,114,175
SD.CLRTP 28,114,175
RAM 7,22-23 SD.CURE 28,115,175
add-on 56,63 SD.CURS 28,116,175
base 7 SD.ELIPS 29,123,175
display 6,56 SD.EXTOP 30,117,174
on-board 56 SD.FILL 28,118,175
screen 56 SD.FLOOD 29,119,175
test 16 SD.FOUNT29,120,175
real-time clock 57,59 SD.GCUR 29,123,175
recolouring 127 SD.LINE 29,123,175
resident procedure area 7,9,10,20,22 SD.NCOL 125,175
restrictions on code 52 SD.NL 125,175
return list 47 SD.NROW 125,175
RI.EXEC 105,150 SD.PAN 28,121,175
RI.EXECB105,150 SD.PANLN 28,121,175
193
SD.PANRT 28,121,175 start-up 6,16
SD.PCOL 125,175 job 17-19
SD.PIXP 122.175 system 16
SD.POINT 29,123,175 storage 50-51
SD.POS 125,175 array 51
SD.PROW 125,175 floating point 50,51
SD.PXENQ 28,126,174 integer 50,51
SD.RECOL 28,127,175 string 51
SD.SCALE 29,123,175 substring 51
SD.SCRBT 28,128,175 strings, comparison of 152
SD.SCROL 28,128,175 string storage 51
SD.SCRTP 28,128,175 substring storage 51
SD.SETFL 29,129,175 SuperBASIC 7,9,10
SD.SETIN 28,131,175 channel table 9
SD.SETMD 28,130,175 format 164
SD.SETPA 28,131,175 data area 20
SD.SETST 28,132,175 function 52
SD.SETSZ 29,132,175 initialisation 16
SD.SETUL 29,129,175 interfacing 47-55
SD.TAB 125,175 memory organisation 47-48
SD.WDEF 28,133,175 procedures and functions 20-21
serial I/O 24,31,36,46,84 program 9
device driver 46 traps 10-11
serial network link 46 variables 7-8,161-163
slave block 9,44,166 work area 7,9,47
table 44 supervisor
slaving 26,40,44-45 software mode 11,13,52
business 181 stack 13
commercial 178 suspended job 17
compilers, utilities 180 system
educational 180-181 job table 19
entertainment 180 management tables 7-8
games 180 initialisation 16
review of 180-181 start-up 16
sound control 58-59 variables 7-8,20,159-161
stack base 6,159
arithmetic 47,54—55 initialisation 16
supervisor 13
user 66 tables
channel 47,55
job 19
194
line number 47 UT.MINT 154,177
memory block 166 UT.MTEXT 155,177
name 47-49,53,78 UT.SCR 156,177
system management 7,8,16 UT.UNLNK 153,177
tasks 17,21,31 UT.WINDW 156,177
external interrupt 34
polling interrupt 34 value pointer 49
scheduler loop 34 variables
time-out 30,36,42 SuperBASIC 9,161-163
token list 47 system 7,8,16,19,93-94
transient program area variable values area 47,48
7,9,10,17,20,22,45 vectored routines 12-13,54,134-
trap(s) 10-11 157,176-177
#0 11,13 error handling 12
#1 11,13 video 67
#2 11 for monitor operation 67
#3 11,13 for TV operation 67
#4 11,21
errors in 11 windows 27-28
hardware interrupts 14-15 border 28,113
Input/Output 11,21,98-133 clearing 114
Input/Output control 11,93-97 colour 28,127
keys 173-176 overlap 27
manager 11,69-92 position 27
redirection 14 properties and operations 27-28
software error 14 setting up 156
SuperBASIC 11 size 27
user 14
type, name table 47,48 ZX8301 57
type-ahead queue 30 ZX8302 57
user
code 8,22
heap 22
traps 14
user stack 66
UT. CON 156,177
UT.CSTR 152.177
UT.ERR 152.177
UT.ERRO 152,177
UT.LINK 153,177
195