Sequential Character File Manager
Contents
Sequential Character File Manager
The Sequential Character File Manager (SCFMAN) supports devices that operate on a character-by-character basis. These include terminals, printers, and modems.
SCF is a re-entrant subroutine package. The I/O manager calls the SCF manager for I/O system handling of sequential, character-oriented devices. The SCF manager includes the extensive I/O editing functions typical of line-oriented operations, such as:
- backspace
- line delete
- line repeat
- auto line feed
- screen pause
- return delay padding
The SCF-type device driver modules are VTIO, PRINTER, and RS-232. They run the video display, printer, and serial ports respectively. See the NitrOS-9 Commands manual for additional Color Computer I/O devices.
SCF Line Editing Functions
The SCF manager supports two sets of read and write functions. I$Read and I$Write pass data with no modification. I$ReadLn and I$WritLn provide full line editing of device functions.
Read and Write
The Read and Write system calls to SCF-type devices correspond to the BASIC09 GET and PUT statements. While they perform little modification to the data they pass, they do filter out keyboard interrupt, keyboard terminate, and pause characters. (Editing is disabled if the corresponding character in the path descriptor contains a zero.
Carriage returns are not followed by line feeds or nulls automatically, and the high order bits are passed as sent/received.
Read Line and Write Line
The Read Line and Write Line system calls to SCF-type devices correspond to the BASIC09 INPUT, PRINT, READ, and WRITE statements. They provide full line editing of all functions enabled for a particular device.
The system initializes I$ReadLn and I$WritLn functions when you first use a particular device. (NitrOS-9 copies the option table from the device descriptor table associated with the specific device.
Later, you can alter the calls—either from assembly-language programs (using the Get Status system call), or from the keyboard (using the TMODE command). All bytes transferred by I$ReadLn and I$WritLn have the high order bit cleared.
SCF Definitions of the Path Descriptor
The PD.FST and PD.OPT sections of the path descriptor are reserved for an used by the SCF file manager.
The following table describes the SCF manager’s use of PD.FST and PD.OPT. For your convenience, the table also includes the other sections of the path descriptor.
The PD.OPT section contains the values that determine the line editing functions. It contains many device operating parameters that can be read or written by the Set Status or Get Status system call. Any values not set by this table default to zero.
Note: You can disable most of the editing functions by setting the corresponding control character in the path descriptor to zero. You can use the Set Status system call or the TMODE command to do this. Or, you can go a step further by setting the corresponding control character value in the device descriptor module to zero.
To determine the default settings for a specific device, you can inspect the device descriptor.
Name | Relative Address | Size (Bytes) | Use |
Universal Section (Same for all file managers) | |||
PD.PD | $00 | 1 | Path number |
PD.MOD | $01 | 1 | Access mode: 1 = read 2 = write 3 = update |
PD.CNT | $02 | 1 | Number of open images (paths using this path descriptor) |
PD.DEV | $03 | 2 | Address of the associated device table entry |
PD.CPR | $05 | 1 | Current process ID |
PD.RGS | $06 | 2 | Address of the caller’s 6809 register stack |
PD.BUF | $08 | 2 | Address of the 256-byte data buffer (if used) |
SCF Path Descriptor Definitions (PD.FST Section) | |||
PD.DV2 | $0A | 2 | Device table address of the second (echo) device |
PD.RAW | $0C | 1 | Edit flag: 0 = raw mode 1 = edit mode |
PD.MAX | $0D | 2 | Read Line maximum character count |
PD.MIN | $0F | 1 | Devices are mine if cleared |
PD.STS | $10 | 2 | Status routine module address |
PD.STM | $12 | 2 | Reserved for status routine |
SCF Option Section Definition (PD.OPT Section)(Copied from the device descriptor) | |||
PD.DTP | $20 | 1 | Device class: 0 = SCF 1 = RBF 2 = PIPE 3 = SBF |
PD.UPC | $21 | 1 | Case: 0 = uppercase and lowercase 1 = uppercase only |
PD.BSO | $22 | 1 | Backspace: 0 = backspace 1 = backspace, space, and backspace |
PD.DLO | $23 | 1 | Delete: 0 = backspace over line 1 = carriage return, line feed |
PD.EKO | $24 | 1 | Echo: 0 = no echo 1 = echo |
PD.ALF | $25 | 1 | Auto line feed: 0 = no auto line feed 1 = auto line feed |
PD.NUL | $26 | 1 | End-of-line null count: N = number of nulls ($00) sent after each carriage return or carriage return and line feed (n = $00-$FF) |
PD.PAU | $27 | 1 | End of page pause: 0 = no pause 1 = pause |
PD.PAG | $28 | 1 | Number of lines per page |
PD.BSP | $29 | 1 | Backspace character |
PD.DEL | $2A | 1 | Delete-line character |
PD.EOR | $2B | 1 | End-of-record character (End-of-line character) Read only. Normally set to $0D0 = Terminate read-line only at the end of the file |
PD.EOF | $2C | 1 | End-of-file character (read only) |
PD.RPR | $2D | 1 | Reprint-line character |
PD.DUP | $2E | 1 | Duplicate-last-line character |
PD.PSC | $2F | 1 | Pause character |
PD.INT | $30 | 1 | Keyboard-interrupt character |
PD.QUT | $31 | 1 | Keyboard-terminate character |
PD.BSE | $32 | 1 | Backspace-echo character |
PD.OVF | $33 | 1 | Line-overflow character (bell CTRL-G) |
PD.PAR | $34 | 1 | Device initialization value (parity) $00 = no parity |
PD.BAU | $35 | 1 | Software settable baud rate $00 = 110 baud |
PD.D2P | $36 | 2 | Offset to second device name string |
PD.XON | $38 | 1 | ACIA XON character |
PD.XOFF | $39 | 1 | ACIA XOFF character |
PD.ERR | $3A | 1 | Most recent I/O error status |
PD.TBL | $3B | 2 | Copy of device table address |
PD.PLP | $3D | 2 | Path descriptor list pointer |
PD.PST | $3F | 1 | Current path status |
PD.EOF specifies the end-of-file character. If this is the first and only character that is input to the SCF device, SCF returns an end-of-file error on Read or ReadLn.
PD.PSC specifies the pause character, which suspends output to the device before the next end-of-record character. The pause character also deletes any type-ahead input for ReadLn.
PD.INT specifies the keyboard-interrupt character. When the character is received, the system sends a keyboard-terminate signal to the last user of a path. The character also terminates the current I/O request (if any) with an error identical to the keyboard interrupt signal code.
PD.QUT specifies the keyboard-terminate character. When this character is received, the system sends a keyboard-terminate signal to the last user of a path. The system also cancels the current I/O request (if any) by sending an error code identical to the keyboard interrupt signal code.
PD.PAR specifies the parity information for external serial devices.
PD.BAU specifies baud rate, word length, and stop bit information for serial devices.
PD.XON contains either the character used to enable transmission of characters or a null character that disables the use of XON.
PD.XOFF contains either the character used to disable transmission of characters or a null character that disables the use of XOFF.
SCF-Type Device Descriptor Modules
The following chart shows how the initialization table in the device descriptors is used for SCF-type devices. The values are those the I/O manager copies from the device descriptor to the path descriptor.
An SCF editing function is turned off if its corresponding value is set to zero. For example, if IT.EOF is set to zero, there is no end-of-file character.
Name | Relative Address | Size (Bytes) | Use |
(header) | $00-$11 | Standard device descriptor module header | |
IT.DVC | $12 | 1 | Device class: 0 = SCF 1 = RBF 2 = PIPE 3 = SBF |
IT.UPC | $13 | 1 | Case: 0 = upper- and lowercase 1 = uppercase only |
IT.BSO | $14 | 1 | Backspace: 0 = backspace 1 = backspace, space, and backspace |
IT.DLO | $15 | 1 | Delete: 0 = backspace over line 1 = carriage return |
IT.EKO | $16 | 1 | Echo: 0 = echo off 1 = echo on |
IT.ALF | $17 | 1 | Auto line feed: 0 = auto line feed disabled 1 = auto line feed enabled |
IT.NUL | $18 | 1 | End-of-line null count |
IT.PAU | $19 | 1 | Pause: 0 = end-of-page pause disabled 1 = end-of-page pause enabled |
IT.PAG | $1A | 1 | Number of lines per page |
IT.BSP | $1B | 1 | Backspace character |
IT.DEL | $1C | 1 | Delete-line character |
IT.EOR | $1D | 1 | End-of-record character |
IT.EOF | $1E | 1 | End-of-file character |
IT.RPR | $1F | 1 | Reprint-line character |
IT.DUP | $20 | 1 | Duplicate-last-line character |
IT.PSC | $21 | 1 | Pause character |
IT.INT | $22 | 1 | Interrupt character |
IT.QUT | $23 | 1 | Quit character |
IT.BSE | $24 | 1 | Backspace echo character |
IT.OVF | $25 | 1 | Line-overflow character (bell) |
IT.PAR | $26 | 1 | Initialization value—used to initialize a device control register when a path is opened to it (parity) $00 = no parity |
IT.BAU | $27 | 1 | Baud rate $00 = 110 baud |
IT.D2P | $28 | 2 | Attached device name string offset |
IT.XON | $2A | 1 | X-ON character |
IT.XOFF | $2B | 1 | X-OFF character |
IT.COL | $2C | 1 | Number of columns for display |
IT.ROW | $2D | 1 | Number of rows for display |
IT.WND | $2E | 1 | Window number |
IT.VAL | $2F | 1 | Data in rest of descriptor is valid |
IT.STY | $30 | 1 | Window type |
IT.CPX | $31 | 1 | X cursor position |
IT.CPY | $32 | 1 | Y cursor position |
IT.FGC | $33 | 1 | Foreground color |
IT.BGC | $34 | 1 | Background color |
IT.BDC | $35 | 1 | Border color |
SCF-Type Device Driver Modules
An SCF-type device driver module contains a package of subroutines that perform raw (unformatted) data I/O transfers to or from a specific hardware controller. Such a module is usually re-entrant so that one copy of the module can simultaneously run several devices that use identical I/O controllers. The I/O manager allocates a permanent memory area for each controller sharing the driver.
The size of the memory area is defined in the device driver module header. The I/O manager and SCF use some of the memory area. The device driver can use the rest in any way (typically as variables and buffers). Typically, the driver uses the area as follows:
Name | Relative Address | Size (Bytes) | Use |
V.PAGE | $00 | 1 | Port extended 24-bit address |
V.PORT | $01 | 2 | Device base address (defined by the I/O manager) |
V.LPRC | $03 | 1 | ID of the last active process |
V.BUSY | $04 | 1 | ID of the active process (defined by RBF): 0 = no active process |
V.WAKE | $05 | 1 | ID of the process to reawaken after the device completes I/O (defined by the device driver): 0 = no waiting process |
V.USER | $06 | 0 | Beginning of file manager specific storage |
V.TYPE | $06 | 1 | Device type or parity |
V.LINE | $07 | 1 | Lines left until the end of the page |
V.PAUS | $08 | 1 | Pause request: 0 = no pause requested |
V.DEV2 | $09 | 2 | Attached device memory area |
V.INTR | $0B | 1 | Interrupt character |
V.QUIT | $0C | 1 | Quit character |
V.PCHR | $0D | 1 | Pause character |
V.ERR | $0E | 1 | Error accumulator |
V.XON | $0F | 1 | XON character |
V.XOFF | $10 | 1 | XOFF character |
V.KANJI | $11 | 1 | Reserved |
V.KBUF | $12 | 2 | Reserved |
V.MODADR | $14 | 2 | Reserved |
V.PDLHD | $16 | 2 | Path descriptor list header |
V.RSV | $18 | 5 | Reserved |
V.SCF | $1D | 0 | End of SCF memory requirements |
FREE | $1D | 0 | Free for the device driver to use |
V.LPRC contains the process ID of the last process to use the device. The IRQ service routing sends this process the proper signal if it receives a quit character or an interrupt character. V.LPRC is defined by SCF.
V.BUSY contains the process ID of the process that is using the device. (If the device is not being used, V.BUSY contains a zero.) The process ID is used by SCF to prevent more than one process from using the device at the same time. V.BUSY is defined by SCF.
SCF Device Driver Subroutines
Like all device drivers, SCF device drivers use a standard executable memory module format.
The execution offset address in the module header points to a branch table that has six 3-byte entries. Each entry is typically an LBRA to the corresponding subroutine. The branch table is defined as follows:
ENTRY LBRA INIT Initialize driver LBRA READ Read character LBRA WRITE Write character LBRA GETSTA Get status LBRA SETSTA Set status LBRA TERM Terminate device
If no error occurs, each subroutine exits with the C bit in the Condition Code register cleared. If an error occurs, each subroutine sets the C bit and returns an appropriate error code in Register B.
The rest of this chapter describes these subroutines and their entry and exit conditions.
Init
Initializes device control registers and enables interrupts if necessary.
Entry Conditions
Y address of the device descriptor
U address of the device memory area
Exit Conditions
CC carry set on error
B error code (if any)
Additional Information
- Prior to being called, the device memory area is cleared (set to zero), except for V.PAGE and V.PORT. (V.PAGE and V.PORT contain the device address.) There is no need to initialize the part of the memory area used by the I/O manager and SCF.
- Follow these steps to use Init:
- Initialize the device memory area.
- Place the IRQ service routine on the IRQ polling list, use the Set IRQ system call (F$IRQ).
- Initialize the device control registers.
Read
Reads the next character from the input buffer.
Entry Conditions
Y address of the path descriptor
U address of the device memory area
Exit Conditions
A character read
CC carry set on error
B error code (if any)
Additional Information
- This is a step by step description of a Read operation:
- Read gets the next character from the input buffer.
- If no data is ready, Read copies its process ID from V.BUSY into V.WAKE. It then uses the Sleep system call to put itself to sleep.
- Later, when Read receives data, the IRQ service routine leaves the data in a buffer. Then, the routine checks V.WAKE to see if any process is waiting for the device to complete I/O. If so, the IRQ service routine sends a wakeup signal to the waiting process.
- Data buffers are not automatically allocated. If a buffer is used, it defines it in the device memory area.
Write
Sends a character (places a data byte in an output buffer) and enables the device output interrupts.
Entry Conditions
A character to write
Y address of the path descriptor
U address of the device memory area
Exit Conditions
CC carry set on error
B error code (if any)
Additional Information
- If the data buffer is full, Write copies its process ID from V.BUSY into V.WAKE. Write then puts itself to sleep.
- Later, when the IRQ service routine transmits a character and makes room for more data, it checks V.WAKE to see if there is a process waiting for the device to complete I/O. If there is, the routine sends a wakeup signal to that process.
- Write must ensure that the IRQ service routine that starts it begins to place data in the buffer. After an interrupt is generated, the IRQ service routine continues to transmit data until the data buffer is empty. Then, it disables the device’s ready-to-transmit interrupts.
- Data buffers are not allocated automatically. If a buffer is used, define it in the device memory area.
GetSta and SetSta
Gets/sets device operating parameters (status) as specified for the Get Status and Set Status system calls. GetSta and SetSta are wildcard calls.
Entry Conditions
A depends on the function code
Y address of the path descriptor
U address of the device memory area
Other registers depend on the function code.
Exit Conditions
CC carry set on error
B error code (if any)
Other registers depend on the function code
Additional Information
- Any codes not defined by the I/O manager or SCF are passed to the device driver.
- You might need to examine or change the register stack that contains the values of the 6809 registers at the time of the call. The address of the register stack can be found in PD.RGS, which is located in the path descriptor.
- You can use the following offsets to access any value in the register packet:
Reg. | Relative Address | Size | 6809 Register |
R$CC | $00 | 1 | Condition code register |
R$D | $01 | 2 | Register D |
R$A | $01 | 1 | Register A |
R$B | $02 | 1 | Register B |
R$DP | $03 | 1 | Register DP |
R$X | $04 | 2 | Register X |
R$Y | $06 | 2 | Register Y |
R$U | $08 | 2 | Register U |
R$PC | $0A | 2 | Program counter |
The function code is retrieved from R$B on the user stack. |
Term
Terminates a device. Term is called when a device is no longer in use (when the link count of the device descriptor module becomes zero).
Entry Conditions
U pointer to the device memory area
Exit Conditions
CC carry set on error
B error code (if any)
Additional Information
- To use Term:
- Wait until the IRQ service routine empties the output buffer.
- Disable the device interrupts.
- Remove the device from the IRQ polling list.
- When Term closes the last path to a device, NitrOS-9 returns to the memory pool the memory that the device used. If the device has been attached to the system using the I$Attach system call, NitrOS-9 does not return the static storage for the driver until an I$Detach call is made to the device. Modules contained in the Boot file are never terminated, even if their link counts reach zero.
IRQ Service Routine
Receives device interrupts. When I/O is complete, the routine sends a wakeup signal to the process identified by the process ID in V.WAKE. The routine also clears V.WAKE as a flag to indicate to the main program that the IRQ has occurred.
Additional Information
- The IRQ Service Routine is not included in the device driver branch tables, and is not called directly by SCF. However, it is a key routine in device drivers.
- When the IRQ Service routine finishes servicing an interrupt, the routine must clear the carry and exit with an RTS instructions.
- Here is a typical sequence of events that the IRQ Service Routing performs:
- Service the device interrupts (receive data from the device or send data to it). Ensure this routine puts its data into and gets its data from buffers that are defined in the device memory area.
- Wake up any process that is waiting for I/O to complete. To do this, the routine checks to see if there is a process ID in V.WAKE (a value other than zero); if so, it sends a wakeup signal to that process.
- If the device is ready to send more data, and the output buffer is empty, disable the device’s ready-to-transmit interrupts.
- If a pause character is received, set V.PAUS in the attached device storage area to a value other than zero. The address of the attached device memory area is in V.DEV2.
- If a keyboard terminate or interrupt character is received, signal the process in V.LPRC (last known process) if any.