The first 256 bytes of the page zero segment, wich always resides in Z80page 0, are laid out as follows.
+----+----+----+----+----+----+----+----+ 00h | Reserved for CP/M emulation | +----+----+----+----+----+----+----+----+ 08h | | : : Free : 28h | | +----+----+----+----+----+----+----+----+ 30h | EXOS system call entry vector | +----+----+----+----+----+----+----+----+ 38h | Interrupt vector | Soft ISR ad. | | +----+----+----+----+----+----+----+ + 40h | | : : Reserved for EXOS code & data : 50h | | + +----+----+----+----+ 58h | | | +----+----+----+----+ + 60h | | : : Reserved for CP/M emulation : : : (Default FCB) : 78h | | +----+----+----+----+----+----+----+----+ 80h | | : : Reserved for CP/M emulation : : : (Default buffer area) : F8h | | +----+----+----+----+----+----+----+----+
The areas which are listed as reserved for CP/M emulation can be used by any programs which do not require CP/M compatibility, but are never used by EXOS. The system entry points are described below.
An applications program is started up by being entered at its entry point address with a certain action code and possibly a command string (see section 9.2). To take control of the system, the user must do an EXOS reset call with the reset flags set correctly depending on the action code (see section 9.3 and 11.2). Having done this call, the user must set up his own stack and then enable interrupts. It then has full control of the system.
The segment with the applications program code in it, for example the cartridge ROM, will allways be entered in Z80page 3 by EXOS and generally it is convenient to leave it permenantly in page 3, although it can be moved if desired. When an EXOS call is made, or an interrupt occurs, then contents of pages 1,2 and 3 will be changed, possibly many times, but will always be restored to their original segments before returning to the user. Thus whatever paging the user sets up will be preserved by all EXOS calls and interrupts.
An EXOS call is made by executing a RST 30h
instruction. The area from 30h
to 5Bh
contains
code to handle the transfer of control to the main EXOS ROM and also to
handle the return to the user. This entire area should not be modified by
the applications programs at all, exept for the software interrupt
address at 3Dh
and 3Eh
(described in
section 4.2.2).
The different EXOS calls are defined by a one byte function code which
immediately follows the RST 30h
instruction. Parameters to
the EXOS calls are passed in registers A, BC and
DE, and these registers are also used to return results.
Register A always returns a status value which is zero if the
call was successful and nonzero if an error or unusual condition
occurred. There is a function call wich will provide a simple text string
explanation for these status codes.
Registers AF, BC and DE will not be preserved by any EXOS calls except in certain specific cases which are noted in the detailed descriptions of the calls in chapter 11. The contents of all other registers, (HL, IX, IY and the alternate register set including AF' ), and of the four Z80page registers, will be preserved by all EXOS calls, except in a few specific cases which are also noted in the detailed functional descriptions (chapter 11).
EXOS always switches to an internal system stack in the system segment whenever it is entered, and therefore uses very little space on the user's stack. However, at least 8 bytes should always be available beyond the top of the stack. Even if no EXOS calls are made, this space is required for interrupt servicing. The program stack should also be managed correctly such that there is never any wanted information above the stack pointer, it can be anywhere in Z80 memory, provided it is in RAM of course.
The system calls will be explained in more detail later but here is a list of them all with their function codes.
Function calls 1 to 11 are device calls. They each take a channel number in register A and the call will be passed on by EXOS to the appropriate device driver for that channel. Almost all of the other functions are handled entirely within the EXOS kernel. The exceptions are: Scan system extensions (code 26) which is an explicit request to pass a command string around all ROM and RAM extensions, and load module (29), explain error code (28) and read/write/toggle EXOS variable (16) which will offer their parameters to any extensions if they are not recognised.
When a device or system extension has control as a result of one of these calls being made, it is able to make its own EXOS calls. In this way EXOS is reentrant, although there are some limitations on this. Device drivers are not allowed to open or close channels when they have control (because of buffer moving problems - see sections 7.3 and 7.4). The allocate channel buffer call (code 27) can only be made by a device during an open channel call, the user should never make this call.
The EXOS calls which can result in nested EXOS calls being made carry out stack checking to ensure that the internal system stack does not overflow. This effectively limits the depth of nesting allowed although there is an absolute limit of 127 levels beyond which the system will not work. It is difficult to imagine this depth of nesting being required.
EXOS uses hardware interrupts to keep its clock/calendar up to date. Each device driver can also have an interrupt routine which EXOS will call whenever a specified type of interrupt occurs. Details of this are given with the explanation of device descriptors.
The user can specify the address of an interrupt service routine simply
by storing the address in the variable USER_ISR
in the
system segment. By default this variable is 0000h
which
means no user interrupt routine. The address must be in the page zero
segment.
The user's routine will be called on every Z80 interrupt with register D having a single bit set to indicate the source of the interrupt:
b1 -
Sound interrupt
b3 -
1Hz interrupt
b5 -
Video interrupt
b7 -
External (network) interrupt
The contents of Z80page 1 will be undefined and can be changed. Pages 2 and 3 must be preserved, and page 2 will always be the system segment containing the stack. Page 0 will contain the page zero segment and must of course be preserved. All of the Z80 registers, including the index registers and the alternate register set can be corrupted by the user's routine since EXOS will already have saved them. The user's interrupt routine should not attempt to reset the interrupt hardware in the Dave chip as EXOS will do this when the user returns.
The user's routine is called before any device interrupt routines, so the user can respond quickly to interrupts. Note that the interrupt routine address is zeroed by any system reset, either from an EXOS reset call or from a warm reset and will thus have to be set up again.
Software interrupts provide a way for the user to be alerted to various
events occuring within EXOS. A software interrupt is triggered by a
device driver's interrupt routine detecting some special occurence, such
as the network driver having received a block of data from the network.
When this occurs the device stores a software interrupt code in
the variable FLAG_SOFT_IRQ
which is in the system segment.
This code indicates what the reason for the software interrupt was.
Nothing else occurs until EXOS is about to return to the user, which may
be directly from the interrupt routine or may be very much later if the
interrupt occured while a device driver was executing. At this time a
software interrupt will be carried out if the user has defined a
nonzero software interrupt address. This address is
defined simply by storing the address at 3Dh
and
3Eh
in page 0, which is in fact the operand of a jump
instruction.
The software interrupt is carried out by EXOS jumping to the software
interrupt address (which can be in any Z80page) instead of executing
the normal RET
instruction which would return to the user.
The environment will be exactly as it would be if the return had been
made, with the correct paging and stack pointer. The return address will
still be on the stack so the software interrupt routine may return to the
main program. If it does return then - all - registers
must be preserved, as it could be interrupting any point in the user's
program.
It is not necessary for the software interrupt routine to return if it doesn't want to, it can cause some sort of warm restart of the user's program.
The software interrupt routine can find out the software interrupt code
by reading an EXOS variable CODE_SOFT_IRQ
. This is in fact a
copy of the code set up by the device since the code itself is reset to
zero before jumping to the routine to prevent multiple responses to the
software interrupt. If more than one software interrupt occurs before the
software interrupt routine can be called then only the most recent one
will be acknowledged.
All sources of software interrupts from built in devices can be enabled or disabled by setting appropriate EXOS variables, or making special function calls. The codes from built in devices are :
10h .. 1Fh - ?FKEY Keyboard function key pressed 20h - ?STOP Keyboard STOP key pressed 21h - ?KEY Keyboard any key pressed 30h - ?NET Network data received 40h - ?TIME Timer EXOS variable reached 0
The stop key is one of the possible sources of software interrupts in EXOS. However it is rather a special case. The Reason for this is that pressing the STOP key should always cause an immediate, or almost immediate response. However, the system is frequently waiting in a device driver for something to happen (such as the editor waiting for a key to be pressed), or is just doing something which will take a long time (such as the VIDEO driver doing a fill). In these cases if the STOP key only caused a software interrupt there would be no immediate response.
The solution to this is that whenever any device is doing something which
is potentially a slow, or nonterminating process, it checks the
value of FLAG_SOFT_IRQ
periodically. If it contains
?STOP
then the STOP key has been pressed. The device then
immediately, or at least soon, returns back to EXOS with a status code
.STOP
. Eventually this code will find its way back to the
user and the software interrupt will occur.
In fact in some cases the situation is worse than this because it is necessary to interrupt a process which runs with normal EXOS interrupts disabled, so the keyboard is not being scanned. An example of this is the cassette driver writing or reading from tape. However in these cases the device itself contains code to look at the STOP key and will cause both the software interrupt, and the error return itself.