EXOS 2.1 Kernel Specification

4. Applications Program Interface.

The first 256 bytes of the page zero segment, wich always resides in Z80­page 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 Z80­page 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.

4.1 EXOS System Calls - General

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 non­zero 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 Z80­page 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.

00 - System reset
01 - Open channel
02 - Create channel
03 - Close channel
04 - Destroy channel
05 - Read character
06 - Read block
07 - Write character
08 - Write block
09 - Channel read status
10 - Set and read channel status
11 - Perform special function on channel

16 - Read/Write/Toggle EXOS variable
17 - Capture channel
18 - Re­direct channel
19 - Set default device name

20 - Return system status
21 - Link device
22 - Read EXOS boundary
23 - Set user boundary
24 - Allocate segment
25 - Free segment
26 - Scan system extensions

27 - Allocate channel buffer (device only function)
28 - Explain error code
29 - Load module
30 - Load relocatable module

31 - Set time
32 - Read time
33 - Set date
34 - Read date

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 re­entrant, 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.

4.2 Hardware and Software Interrupts

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.

4.2.1 User Hardware Interrupt Routine

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 Z80­page 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.

4.2.2 Software interrupts

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 non­zero 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 Z80­page) 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 re­start 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 

4.3 The STOP key

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 non­terminating 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.

Next chapter: Segment Allocation

David Bouman. (dsbouma@cs.vu.nl)