OS-9 KERNEL
(OS9P1, OS9P2)
nput/Output Manager
(IOMAN)
Manager
(SCF)
Ram
Ram Disk
Driver
CC3Disk
Disk
Driver
CC3Hdisk
Disk
Driver
ACIAPak
Driver
ModPak
Driver
Term-Vdg
Desc
Grflnt
CC310
Interface
Term-Win
Desc
The VDG Interface performs both interface and low level routines
for VDG Color Computer 2 compatible modes and has limited
support for high res screen allocation.
The Grflnt Interface provides the standard code interpretations
and interface functions.
The Windint Interface, available in the Multi-view package, con
tains all the functionality of Grfint, along with additional sup
port features. If you use WindInt, do not include Grflnt.
Both WindInt and Grflnt use the low-level driver Grfdrv to per
form drawing on the bit-map screens.
Term-VDG uses CC310NdgInt while Term-win and all win
dow descriptors use CC310/(WindInt/Grflnt)/GrfDrv modules.
The I/O system provides system-wide, hardware-independent I/O
services for user programs and OS-9 itself. All I/O system calls
are received by the kernel and passed to the I/O manager for
processing.
The I/O manager performs some processing, such as the alloca
tion of data structures for the I/O path. Then, it calls the file
managers and device drivers to do most of the work. Additional
file manager, device driver, and device descriptor modules can be
loaded into memory from files and used while the system is
running.
The I/O manager provides the first level of service of I/O system
calls. It routes data on I/O process paths to and from the appro
priate file managers and device drivers.
The I/O Manager also maintains two important internal OS-9
data structures-the device table and the path table. Never mod
ify the I/O manager.
When a path is opened, the I/O manager tries to link to a mem
ory module that has the device name given or implied in the
pathlist. This module is the device descriptor. It contains the
names of the device driver and file manager for the device. The
I/O manager saves the names so later system calls can be routed
to these modules.
Create and Open handle file creating and opening for devices.
Typically, the process involves allocating any required buffers,
initializing path descriptor variables, and establishing the path
name. If the file manager controls multi-file devices (RBF),
directory searching is performed to find or create the specified
file.
Makdir creates a directory file on multi-file devices. Makdir is
neither preceded by a Create nor followed by a Close. File man
agers that are incapable of supporting directories need to return
carry set with an appropriate error code in Register B.
On multi-file devices, ChgDir searches for a directory file. If
ChgDir finds the directory, it saves the address of the directory
(up to four bytes) in the caller's process descriptor. The descrip
tor is located at P$DIO + 2 (for a data directory) or P$DIO + 8
(for an execution directory).
In the case of the RBF manager, the address of the directory's
file descriptor is saved. Open/Create begins searching in the cur
rent directory when the caller's pathlist does not begin with a
backslash M. File managers that do not support directories
should return the carry set and an appropriate error code in
Register B.
Multi-file device managers handle file delete requests by initiat
ing a directory search that is similar to Open. Once a device
manager finds the file, it removes the file from the directory.
Any media in use by the file are returned to unused status. In
the case of the RBF manager, space is returned for system use
and is marked as available in the free cluster bit map on the
disk. File managers that do not support multi- file devices
return an error.
File managers that support random access devices use Seek to
position file pointers of an already open path to the byte speci
fied. Typically, the positioning is a logical movement. No error is
produced at the time of the seek if the position is beyond the
current "end of file".
Normally, file managers that do not support random access
ignore Seek, However, an SCF-type manager can use Seek to
perform cursor positioning.
Read returns the number of bytes requested to the user's data
buffer. Make sure Read returns an EOF error if there is no data
available. Read must be capable of copying pure binary data, and
generally performs no editing on the data. Generally, the file
manager calls the device driver to actually read the data into
the buffer. Then, the file manager copies the data from the buffer
into the user's data area to keep file managers device
independent.
The Write request, like Read, must be capable of recording pure
binary data without alteration. The routines for Read and Write
are almost identical with the exception that Write uses the
device driver's output routine instead of the input routine. The
RBF manager and similar random access devices that use fixed
length records (sectors) must often preread a sector before writ
ing it, unless they are writing the entire sector. In OS-9, writing
past the end of file on a device expands the file with new data.
ReadLn differs from Read in two respects. First, ReadLn termi
nates when the first end-of-line (carriage return) is encountered.
ReadLn performs any input editing that is appropriate for the
device. In the case of SCF, editing involves handling functions
such as backspace, line deletion, and the removal of the high
order bit from characters.
WriteLn is the counterpart of ReadLn. It calls the device driver
to transfer data up to and including the first (if any) carriage
return encountered. Appropriate output editing can also be per
formed. For example, SCF outputs a line feed, a carriage return
character, and nulls (if appropriate for the device). It also pauses
at the end of a screen page.
The GetStat (get status) and PutStat (put status) system calls
are wildcard calls designed to provide a method of accessing fea
tures of a device (or file manager) that are not generally device
independent. The file manager can perform specific functions
such as setting the size of a file to a given value. Pass unknown
status calls to the driver to provide further means of device inde
pendence. For example, a PutStat call to format a disk track
might behave differently on different types of disk controllers.
Close is responsible for ensuring that any output to a device is
completed. (If necessary, Close writes out the last buffer.) It
releases any buffer space allocated in an Open or Create. Close
does not execute the device driver's terminate routine, but can
do specific end-of-file processing if you want it to, such as writ
ing end-of-file records on disks, or form feeds on printers.
Strictly speaking, device drivers must conform to the general for
mat presented in this manual. The I/O Manager is slightly dif
ferent because it only uses the Init and Terminate entry points.
Other entry points need only be compatible with the file man
ager for which the driver is written. For example, the Read entry
point of an SCF driver is expected to return one byte from the
device. The Read entry point of an RBF driver, on the other
hand, expects Read to return an entire sector.
The following code is part of an SCF file manager. The code
shows how a file manager might call a driver.
The device driver modules are subroutine packages that perform
basic, low-level I/O transfers to or from a specific type of I/O
device hardware controller. These modules are re-entrant. So,
one copy of the module can concurrently run several devices that
use identical I/O controllers.
Device driver modules use a standard module header, in which
the module type is specified as code $Ex (device driver). The exe
cution offset address in the module header points to a branch
table that has a minimum of six 3-byte entries.
Each entry is typically an LBRA to the corresponding subrou
tine. The file managers call specific routines in the device driver
through this table, passing a pointer to a path descriptor and
passing the hardware control register address in the 6809 regis
ters. The branch table looks like this:
Device drivers often must wait for hardware to complete a task
or for a user to enter data. Such a wait situation occurs if an
SCF device driver receives a Read but there is no data is avail
able, or if it receives a Write and no buffer space is available.
OS-9 drivers that encounter this situation should suspend the
current process (via F$Sleep). In this way the driver allows other
processes to continue using CPU time.
The most efficient way for a driver to awaken itself and resume
processing data is by using interrupt requests (IRAs). It is possi
ble for the driver to sleep for a number of system clock ticks and
then check the device or buffer for a ready signal. The drawbacks
to this technique are:
It might require a large number of ticks (perhaps 20) for
the device to become ready. Such a case leaves you with
a dilemma. If you make the program sleep for two ticks,
the system wastes CPU time while checking for device
ready. If the driver sleeps 20 ticks, it does not have a
good response time.
An interrupt system allows the hardware to report to the CPU
and the device drivers when the device is finished with an opera
tion. Using interrupts to its advantage, a device driver can set
up interrupt handling to occur when a character is sent or
received or when a disk operation is complete. There is a built-in
polling facility for pausing and awakening processes. Here is a
technique for handling interrupts in a device driver:
3. When the driver program wakes up, have it check to see
Usually, the driver performs this check by reading the
V.Wake storage byte. The V.Busy byte is maintained by the
file manager to be used as the process ID of the process
using the driver. When V.Busy is copied into V.Wake, then
V.Wake becomes a flag byte and an information byte. A non
zero Wake byte indicates that there is a process awaiting an
interrupt. The value in the Wake byte indicates the process
to be awakened by sending a wakeup signal as shown in the
following code:
The Suspend State allows the elimination of the F$Send system
call during interrupt handling. Because the process is already in
the active queue, it need not be moved from one queue to
another. The device driver IRQSERVC routine can now wake up
the suspended main driver by clearing the process status byte
suspend bit in the process state. Following are sample routines
for the Sleep and IRQSERVC calls:
Note that D.Proc is a pointer to the process descriptor of the cur
rent process. Process descriptors are always allocated on 256
byte page boundaries. Thus, having the high order byte of the
address is adequate to locate the descriptor. D.Proc is put in
V.Wake as a dual value. In one instance, it is a flag byte indi
cating that a process is indeed suspended. In the other instance,
it is a pointer to the process descriptor which enables the
IRQSERVC routine to clear the suspend bit. It is necessary to
have the interrupts masked from the time the device is enabled
until the suspend bit has been set. Making the interrupts
ensure that the IRQSERVC routine does not think it has cleared
the suspend bit before it is even set. If this happens, when the
bit is set the process might go into permanent suspension. The
IRQSERVC routine sample follows:
The rest of the device descriptor header consists of the informa
tion in the following chart:
tialization table into the option section (PD.OPT) of the path
descriptor. (See "Path Descriptors" in this chapter.)
The values in this table can be used to define the operating
parameters that are alterable by the Get Status and Set Status
system calls (I$GetStt and I$SetStt). For example, parameters
that are used when initializing terminals define which control
characters are to be used for functions such as backspace and
delete.
The initialization table can be a maximum of 32 bytes long. If
the table is fewer than 32 bytes long, OS-9 sets the remaining
values in the path descriptor to 0.
You might wish to add devices to your system. If a similar device
driver already exists, all you need to do is add the new hardware
and load another device descriptor. Device descriptors can be in
the boot module or they can be loaded into RAM from mass-stor
age files while the system is running.
Relative
Address
$00
$01
$02
$03
$04
$OA
$OB
$OD
$OE
$10
$11
$12,$12 + n
PROPT is a 32-byte option area used for file or device operat
ing parameters that are dynamically alterable. When the path is
opened, the 1/O manager initializes these variables by copying
the initialization table that is in the device descriptor module.
User programs can change the values later, using the Get Status
and Set Status system calls.
PD.FST and PD.OPT are defined for the file manager in the
assembly-language equate file (SCFDefs for the SCF manager or
RBFDefs for the RBF manager).