OS/8
software
support manual

 

digital equipment corporation


 CONTENTS
  INTRODUCTION
CHAPTER 1 OS/8 CONCEPTS AND TERMINOLOGY
1.1 Software Components of OS/8
1.2 Files
1.2.1 File Names and Extensions
1.2.2 File Structured Devices
1.2.3 File Types
1.2.4 File Directories and Additional Information Words
1.3 Core Control Block
1.3.1 Program Starting Address
1.3.2 Job Status Word
1.4 Device Names and Device Numbers
1.5 The DEVICE and FILENAME Pseudo-ops
CHAPTER 2 USER SERVICE ROUTINE
2.1 Calling the USR
2.1.1 Standard USR Call
2.1.2 Direct and Indirect Calling Sequence
2.2 Summary of USR Functions
2.2.1 FETCH Device Handler
2.2.2 LOOKUP Permanent File
2.2.3 ENTER Output (Tentative) File
2.2.4 The CLOSE Function
2.2.5 Call Command Decoder (DECODE)
2.2.6 CHAIN Function
2.2.7 Signal User Error
2.2.8 Lock USR in Core (USRIN)
2.2.9 Dismiss USR from Core (USROUT)
2.2.10 Ascertain Device Information (INQUIRE)
2.2.11 RESET System Tables
CHAPTER 3 THE COMMAND DECODER
3.1 Command Decoder Convention
3.2 Command Decoder Error Messages
3.3 Calling the Command Decoder
3.4 Command Decoder Tables
3.4.1 Output Files
3.4.2 Input Files
3.4.3 Command Decoder Option Table
3.4.4 Example
3.5 Special Mode of the Command Decoder
3.5.1 Calling the Command Decoder Special Mode
3.5.2 Operation of the Command Decoder in Special Mode
CHAPTER 4 USING DEVICE HANDLERS
4.1 Calling Device Handlers
4.2 Device Dependent Operations
4.2.1 Teletype (TTY)
4.2.2 High-Speed Paper Tape Reader (PTR)
4.2.3 High-Speed Paper Tape Punch (PTP)
4.2.4 Line Printer (LPT)
4.2.5 Cassettes
4.2.6 Card Reader (CDR)
4.2.7 File Structured Devices
4.2.8 TD8E DECtape
CHAPTER 5 RECONFIGURING THE OS/8 SYSTEM
5.1 Conditional Assembly of CONFIG
5.1.1 System Device Selection
5.1.2 Optional Device Parameters
5.1.3 Other Options
5.1.4 Example
5.2 Writing Device Handlers
5.2.1 Inserting Device Handlers Into CONFIG
5.3 Inserting Device Handlers Into OS/8
APPENDIX A OS/8 FILE STRUCTURES
A.1 FILE DIRECTORIES
A.1.1 Directory Entries
A.1.2 Number and Size of OS/8 Files
A.1.3 Sample Directory
A.2 File Formats
A.2.1 ASCII and Binary Files
A.2.2 Core Image (.SV Format) Files
A.2.3 Relocatable FORTRAN Library File
APPENDIX B DETAILED LAYOUT OF THE SYSTEM
B.1 LAYOUT OF THE SYSTEM DEVICE
B.2 Layout of the OS/8 Resident Program
B.3 System Device Tables
B.3.1 Permanent Device Name Table
B.3.2 User Device Name Table
B.3.3 Device Handler Residency Table
B.3.4 Device Handler Information Table
B.3.5 Device Control Word Table
B.3.6 Device Length Table
APPENDIX C SYSTEM ERROR CONDITIONS AND MESSAGES
C.1 SYSTEM HALTS
C.2 USR Errors
C.3 Keyboard Monitor Errors
C.4 Command Decoder Errors
APPENDIX D PROGRAMMING NOTES
D.1 The Default File Storage Device, DSK
D.2 Modification to Card Reader Handler
D.3 Suppression of Carriage Return/Line Feed in FORTRAN I/O
D.4 Accessing the System Date in a FORTRAN Program
D.5 Determining Core Size on PDP-8 Family Computers
D.6 Relocating Code
D.7 Using PRTC12-F to Convert OS/8 DECtapes to OS/12 LINCtapes
D.8 Notes on Loading Device Handlers
D.9 Available Locations in the USR Area
D.10 Accessing Additional Information Words in OS/8
D.11 SABR Programming Notes
APPENDIX E CHARACTER CODES AND CONVENTIONS
APPENDIX F OS/8 INPUT/OUTPUT ROUTINES

INTRODUCTION

The 8K Operating System (OS/8) is an extremely powerful program development system. OS/8 greatly expands the capabilities of any 8K PDP-8, 8/I, 8/L, 8/E, or PDP-12 computer having the necessary disk or DECtape storage. Use of OS/8 is described in detail in Chapter 9 of Introduction to Programming 1972.

This manual covers a wide range of advanced topics pertinent to the experienced user. In Chapter 1 the various basic system concepts are described and terms are defined. Chapter 2 explains the process by which user programs call upon the system for the performance of important operations; including loading device handlers, opening and closing files, and chaining to other programs. Chapter 3 covers the functions of the Command Decoder and the means by which the user program can employ its services. Chapter 4 explains the use and operation of the device handlers in detail. Chapter 5 covers the details of "custom tailoring" a system, including how to write a device handler for a non-standard device.

Technical information, intended to enhance the information in the Introduction to Programming handbook, as well as this manual, can be found in the Appendices. Appendix A details the OS/8 directory structure and gives a standard file formats. Appendix B describes the system data base and gives the layouts of the system areas. Appendix C gives a complete list of system error messages. Appendix D illustrates some useful advanced techniques and programming "tricks" for use with the OS/8 system. Appendix E is a complete list of the standard ASCII character codes meaningful to OS/8. Finally, Appendix F describes a set of generalized I/O routines for use under the OS/8 system.

OS/8 does not attempt to solve all problems. Since it runs with the interrupt disabled, any calls to the system must be made with the interrupt turned off. Nonetheless, OS/8 provides a powerful means to solve the most frequently encountered problem in developing software for PDP-8 family computers.


CHAPTER 1
OS/8 CONCEPTS AND TERMINOLOGY

Before examining the details of the OS/8 system the reader should first be familiar with the simpler techniques and terms used within the frameword of the OS/8 system. The material in this chapter, along with that contained in Chapter 9 of Introduction to Programming 1972, provides the tools needed to pursue the latter chapters.

1.1 SOFTWARE COMPONENTS OF OS/8

There are four main components of the OS/8 system:

  1. The Keyboard Monitor performs commands specified by the user at the console. The nine Keyboard Monitor commands (ASSIGN, DEASSIGN, GET, SAVE, ODT, RUN, R, START, and DATE) are explained in Chapter 9 of Introduction to Programming 1972.

    Users programs can exit to the Keyboard Monitor by executing a JMP to location 7600 in field 0.

    NOTE
    All JMP's to 7600 must be made with the DATA FIELD set to zero.

    This saves the contents of location 0 to 1777 in field 0 and loads the Keyboard Monitor which could be called by a JMP to location 7605 in field 0. In this latter case the contents of core are not saved, which conserves some time.

    Existing system programs, device handlers, and the Command Decoder test for the CTRL/C character in the Teletype input buffer and on finding this character abort the current operation and performs a JMP to 7600 in field 0. Thus, typing CTRL/C is the conventional method of calling the Keyboard Monitor from the console.

  2. Device handlers, which are subroutines for performing all device-oriented input/output operations, can be utilized by any program. These subroutines have standard calling sequences and "mask" from the user program the special characteristics of the I/O device. In this way, device independent I/O is achieved. A detailed description of device handlers is found in Chapter 4.
  3. The User Service Routine (USR) is to a program what the Keyboard Monitor is to the user. For example, programs can request the USR to fetch device handlers, perform file operations on any device, chain to another program, or call the Command Decoder. A full description of the USR functions is found in Chapter 2.
  4. The Command Decoder interprets a command line typed by the user to indicate input and output files and various options. The command line format is described in detail in Chapter 9 of Introduction to Programming 1972. The Command Decoder removes the burden of this repetitive operation from the user's program. A full description of the Command Decoder's function is found in Chapter 3.

1.2 FILES

Files are basic units of the OS/8 system, and a thorough understanding of file structure is required for its use. A file is any collection of data to be treated as a unit. The format of this data is unimportant; for example, OS/8 can manipulate several standard formats, including ASCII files, binary files, and core image files. The important consideration is that the data forms a single unit within the system.

1.2.1 File Names and Extension

An individual file is identified by its file name and extension. The file name consists of up to six alphanumeric characters, optionally followed by a two character extension. The extension is often used to clarify the format of the data within the file. For example, an ASCII file used as input to PAL8 migh be given a .PA extension, while a core image file has a .SV extension.

1.2.2 File Structured Devices

Devices that can be logically divided into a number of 256 word blocks and have the ability to read and write from any desired block are called file structured devices. Disks and DECtapes are file structured devices while a paper tape reader or Teletype is not.

The system device (SYS:) in any OS/8 system is always file structured, as is the default storage device, DSK:

All OS/8 file structured devices must be logically divided into these 256 word blocks. Hence, 256 words is considered the standard OS/8 block size. Some devices, like RK8, DECtape, and LINCtape, are phyically divided into blocks. These physical blocks should not be confused with the logical 256 word blocks. For example, DECtapes must be formatted with standard 129 word physical blocks. A logical OS/8 block consists of the first 128 words of two consecutive physical DECtape blocks. The 129th word of every DECtape block is not used by OS/8. Similarly, LINCtapes are formatted with 129 (or 128) words per block but never 256, as this format is unacceptable to OS/8.

A given OS/8 file consists of one or more sequential blocks of 256 words each (consecutively numbered). A minimum of one block per file is required, although a single file could occupy all of the blocks on a device.

1.2.3 File Types

Three different types of files exist in the OS/8 system:

  1. An "empty file" is a contiguous area of unused blocks. Empty files are created when permanent files are deleted.
  2. A "tentative file" is a file that is open to accept output and has not yet been closed. Only one tentative file can be open on any single device at one time.
  3. A "permanent file" is a file that has been given a fixed size and is no longer expandable. A tentative file becomes permanent when it is closed.

To further understand file types, consider what occurs when a file is created. Normally, the User Service Routine in creating a tentative file first locates the largest empty file available and creates a tentative file in that space. This ensures the maximum space into which the file can expand. The user program then writes data into the tentative file. At the end of the data, the program calls the USR to close the tentative file, making it a permanent file. The USR does so and allocates whatever space remains on the end of the tentative file to a new, smaller, empty file.

1.2.4 File Directories and Additional Information Words

To maintain records of the files on a device, OS/8 allocates blocks 1 through 6 of each file structured device as the file directory. Entries in this directory inform the system of the name, size, and location of each file, including all empty files and the tentative file, if one exists. For a detailed description of the entries in the file directory, see Appendix A.

Each entry in a directory can, optionally, have extra storage words called Additional Information Words. The number of Additional Information Words is determined at the time the directory is initially created (normally by using the /S or /Z features of PIP; see Chapter 9 of Introduction to Programming 1972).

Whenever Additional Information Words are used, the first one for each file entry is used to store the value of the System Date Word at the time the file was created. This value is set by executing a DATE command (see Chapter 9 of Introduction to Programming 1972). OS/8 automatically uses one extra word per entry for the date.

NOTE
The value of the system DATE word is contained in location 7666 in field 1; this word has the following format:

Figure 1-1

A date word of 0 implies that no DATE command has been executed since the system initialization.

The values of additional Information Words beyond the first are user-defined. See Appendix D for further information on Additional Information Words.

1.3 Core Control Block

Associated with each core image file (.SV file) is a block of data called the Core Control Block. The Core Control Block is a table of information containing the program's starting address, areas of core into which the program is loaded, and the program's Job Status Word. The Core Control Block is created at the time the program is loaded by the ABSLDR or LOADER program and is written onto the .SV file by the SAVE operation. More information on the Core Control Block can be found in the description of core image files in section A.2.2.

NOTE
Specifying arguments to the SAVE command as described in Chapter 9 of Introduction to Programming 1972, can alter the contents of that program's Core Control Block.

When a program is loaded the starting address and Job Status Word are loaded from the Core Control Block and saved in core. The Core Control Block itself is saved in the last 200 (octal) words of block 37 on the system device unless the program was loaded with the R (rather than GET or RUN) command.

1.3.1 Program Starting Address

The current starting address (used by the START command) is stored in two words at locations 7744 and 7745 in field 0. the format of these words is:

LOCATIONCONTENTSNOTES
774472N3 N is the field in which to start.
7745addr Starting address of the program.

1.3.2Job Status Word

The Job Status Word contains certain flags that affect OS/8 operations, such as whether to save core when loading the USR or Command Decoder. The Job Satus Word for the program currently in core is saved at location 7746 in field 0 and contains the following information:

Bit ConditionMeaning
Bit 0 = 1File does not load into locations 0 to 1777 in field 0.
Bit 1 = 1File does not load into locations 0 to 1777 in field 1.
Bit 2 = 1Program must be reloaded before it can be restarted.
Bit 3 = 1Program does not destroy the contents of the highest existing memory field, an optimization for Batch system.
Bits 4 thru 9Reserved for future use.
Bit 10 = 1Locations 0 to 1777 in field 0 need not be saved when calling the Command Decoder.
Bit 11 = 1Locations 0 to 1777 in field 1 need not be saved when calling the USR.

The Job Status Word can be updated from the user's program, thus providing the optimization of tape (disk) motion. More information on the Core Control Block can be found in the description of Core Image (.SV) files found in Appendix A.

NOTE
When bit 2 is 1, any attempt to perform a START (without an explicit address) results in a

   NO !!

error message being printed. As this bit is always zero in the Core Control Block, the user program is expected to internally set this bit (in location 7746) if a program is not restartable. This could be done as follows:

   CDF 0
   TAD 7746  /LOAD JOB STATUS WORD
   AND (6777
   TAD (1000
   DCA 7746  /JOB IS NOT RESTARTABLE

Bit 3 of the JSW (Job Status Word) is used as an optimization for the Batch operating system. If a program can never cause the highest existing memory field to be altered, this bit should be set. For example, EDIT, PIP, FORT, SABR can never use above 8K. Thus, they should have bit 3 on. Programs such as ABSLDR, LOADER, PAL8, and CREF can alter all core. They should perhaps not have bit 3 on. Note that the more core that exists the more unlikely it is that a program will destroy upper core. Thus, on 28K, only the largest FORTRAN programs can alter field 6. Thus, with large amounts of core, bit 3 should be set.

Bit 3 can be set with ABSLDR. Setting /P in the command line to ABSLDR will set bit 3. Refer to the OS/8 BATCH User's Manual for more information.

1.4 Device Names and Device Numbers

The OS/8 system can accommodate up to 15 separate devices. In Chapter 9 of Introduction to Programming 1972 the reader is introduced to the concept of device names. Briefly, each device on the system is recognized by either a permanent device name (such as PTR or DTA1) which is created when the system is built, or a user-defined device name determined by an ASSIGN command. The system ensures that the user-defined device name takes precedence. For example,

   .ASSIGN DSK DTA4

causes all future references to DTA4 to address the device DSK.

In calling the User Service Routine, a device can be alternatively recognized by a device number. Each device on the system has a unique predefined number in the range 1 to 17 (octal) assigned at the time the system is generated.

Thus, user programs have the choice of referring to a device by either name or number. Referencing a device by name is preferable as it maintains device independence for the program.

Accessing devices by number should be done only when the appropriate number has been obtained from a USR call 12. Except for SYS and DSK, the OS/8 peripherals do not have fixed numbers; they vary whenever BUILD is used to modify a system. Thus, it is suggested that reference by name be used.

To determine if a device name is recognized in the system, attempt to ASSIGN that device. For example, if one does not know if his LINCtape handlers are called LTA or DTA, he could perform:

   .DEASSIGN
   .AS LTA0

If the system responds with a dot, LTA0 does indeed exist. If the system responds with:

   LTA0 NOT AVAILABLE

no device named LTA0 is present.

1.5 The DEVICE and FILENAME Pseudo-ops

Several of the USR functions take device names or file names as arguments. To simplify the task of generating these arguments, the DEVICE and FILENAME pseudo-ops have been added to the PAL8 Assembler.

A device name consists of a two word block, containing four alphanumeric characters in 6-bit ASCII format. A block in this format can be created by the DEVICE pseudo-op as follows:

   DEVICE DTA1

generates the following two words:

   0424
   0161

Similarly, the FILENAME pseudo-op creates a four word block, the first three words of which contain the file name and the fourth word of which contains the file extension. For example:

   FILENAME PIP.SV

generates the following four words:

   2011
   2000
   0000
   2326

Note that positions for character 4 though 6 are filled with zeros.

The DEVICE and FILENAME pseudo-ops are used in examples in the following chapters.


CHAPTER 2
USER SERVICE ROUTINE

The User Service Routine, or USR, is a collection of subroutines which perform the operations of opening and closing files, loading device handlers, chaining programs together, and calling the Command Decoder. It provides these functions not only for the system itself, but for all programs running under the OS/8 system.

2.1 CALLING THE USR

Performing any USR function is as simple as giving a JMS followed by the proper arguments. Calls to the USR take a standardized calling sequence. This standard call should be studied before progressing to the operation of the various USR functions.

2.1.1 Standard USR Call

In the remainder of this chapter, the following calling sequence is referenced:

TAD VAL The contents of the AC is applicable in some cases only.
CDF N Where N is the value of the current program field multiplied by 10 (octal).
CIF 10
JMS I (USR
Where USR is either 7700 or 0200, see section 2.1.2.
FUNCTION This word contains an integer from 1 to 13 (octal) indicating which USR operation is to be performed.
ARG(1) The number and meaning of these argument words vary with the particular USR function to be performed.
error return When applicable, this is the return address for all errors.
normal return The operation was successful. The AC=0, data field is set to current field.

Alternatively, a program can opt to keep the USR permanently resident in core at locations 10000 to 11777 by using the USRIN function (see section 2.2.8). Once the USR has been brought into core, a USR call can be made by performing a JMS to location 10200. This is a more efficient way of calling the USR. When USR operations have been completed, the program restores locations 10000 to 11777 to their initial state by executing the USROUT function (see section 2.2.9).

2.2 Summary of USR Functions

Function
Code
NameOperation
1 FETCH Loads a device handler into core. Returns entry address of the handler.
2 LOOKUP Searches the file directory on any device to locate a specified permanent file.
3 ENTER Creates and opens for output a tentative file on a specified device.
4 CLOSE The currently open tentative file on the specified device is closed and becomes a permanent file. Also, any previous permanent file with the same name is deleted.
5 DECODE The Command Decoder is called. The function of the Command Decoder is described in Chapter 3.
6 CHAIN Loads a specified core image file from the system device and starts it.
7 ERROR Prints an error message of the form USER ERROR n AT LOCATION xxxxx.
10 USRIN The USR is loaded into core. Subsequent calls to the USR are by a JMS to 10200.
11 USROUT Dismisses the USR from core and restores the previous contents of locations 10000 to 11777.
12 INQUIRE Ascertains whether a given device exists and, if so, whether its handler is in core.
13 RESET Resets system tables to their initial cleared state.
14-17   Not currently used, these request numbers are reserved for future use.

An attempt to call the USR with a code greater than 13 (octal) will currently cause a Monitor Error 4 message to be printed and the program to be aborted.

NOTE
If the specified device is not file structured, the LOOKUP, ENTER, and CLOSE functions verify only that the device is acceptable for input in the case of LOOKUP. For example, ENTERing a file on the paper tape punch is a legal function.

2.2.1 FETCH Device Handler (Function Code = 1)

Device handlers must be loaded into core so as to be available to the USR and user program for I/O operations on that device. Before performing a LOOKUP, ENTER, or CLOSE function on any device, the handler for that device must be loaded by FETCH.

The FETCH function takes two distinct forms:

  1. Load a device handler corresponding to a given device name.
  2. Load a device handler corresponding to a given device number.

The following is an example of loading a handler by name:

   CLA            /AC MUST BE CLEAR
   CDF 0
   CIF 10
   JMS I (USR
   1              /FUNCTION CODE = 1
   DEVICE DTA3    /GENERATES TWO WORDS: ARG(1)
	          /AND ARG(2)
   6001           /ARG(3)
   JMP ERR        /ERROR RETURN
   .              /NORMAL RETURN
   .
   .

ARG(1) and ARG(2) contain the device name in standard format. If the normal return is taken, ARG(2) is changed to the device number corresponding to the device loaded. ARG(3) contains the following information:

Notice that in the example above, the handler for DTA3 is to be loaded into locations 6000 to 6177. If necessary, a two page handler could be loaded; the second page would be placed in locations 6200 to 6377. After a normal return, ARG(3) is changed to contain the entry point of the handler.

A different set of arguments is used to fetch a device handler by number. The following is an example of this form:

   TAD VAL         /AC IS NOT ZERO
   CDF 0
   CIF 10
   JMS I (USR
   1               /FUNCTION CODE = 1
   6001            /ARG(1)
   JMP ERR         /ERROR RETURN
   .               /NORMAL RETURN
   .
   .

On entry to the USR the AC contains the device number in bits 8 to 11 (bits 0 to 7 are ignored).

The format for ARG(1) is the same as that for ARG(3) in the previous example. Following a normal return ARG(1) is replaced with the entry point of the handler.

The conditions that can cause an error return to occur in both cases are as follows:

  1. There is no device corresponding to the given device name or device number, or
  2. An attempt was made to load a two page handler into one page. If this is an attempt to load the handler by name, the contents of ARG(2) have been changed already to the internal device number.

In addition, one of the following Monitor errors can be printed, followed by a return to the keyboard monitor:

Error MessageMeaning
MONITOR ERROR 4 AT xxxxxx Results if bits 8 to 11 of the AC are zero (and bits 0 to 7 are non-zero).
MONITOR ERROR 5 AT xxxxxx Results if a read error occurs while loading the device handler.

The FETCH function checks to see if the handler is in core, and if it is not, then the handler and all co-resident handlers are loaded. While the FETCH operation is essentially a simple one, the user should be aware of the following points:

  1. Device handlers are always loaded into field 0.
  2. The entry point that is returned may not be on the page desired. This would happen if the handler were already resident.
  3. Never attempt to load a handler into 7600 or into page 0. Never load a two page handler into 7400.

For more information on using device handler, see Chapter 4.

NOTE
Two or more device handlers are "co-resident" when they are both included in the same one or two core pages. For example, the paper tape reader and punch routines are co-resident as are the eight DECtape handler routines.

2.2.2 LOOKUP Permanent File (Function Code = 2)

This request locates a permanent file entry on a given device, if one exists. An example of a typical LOOKUP would be:

           TAD VAL           /LOAD DEVICE NUMBER
           CDF 0
           CIF 10
           JMS I (USR
           2                 /FUNCTION CODE = 2
           NAME              /ARG(1), POINTS TO FILE NAME
           0                 /ARG(2)
           JMP ERR           /ERROR RETURN
           .                 /NORMAL RETURN
   NAME,   FILENAME PROG.PA

This request looks up a permanent file entry with the name PROG.PA. The device number on which the lookup is to be perfomed is in AC bits 8 to 11. ARG(1) contains a pointer to the file name; note that the file name block must be in the same field as the call, and that it cannot be in locations 10000 to 11777. The device handler must have been previously loaded into core. If the normal return is taken, ARG(1) is changed to the starting block of the file and ARG(2) contains the file length in blocks as a negative number. If the device specified is a readable, non-file structured device (for example, the paper tape reader), then ARG(1) and ARG(2) are both set to zero.

If the error return is taken, ARG(1) and ARG(2) are unchanged. The following conditions cause an error return:

  1. The device specified is a write-only device.
  2. The file specified was not found.

In addition, specifying illegal arguments can cause one of the following monitor errors, followed by a return to the Keyboard Monitor:

Error MessageMeaning
MONITOR ERROR 2 AT xxxxx Results if an I/O error occurred while reading the device directory.
MONITOR ERROR 3 AT xxxxx Results if the device handler for the specified device is not in core.
MONITOR ERROR 4 AT xxxxx Results if bits 8 to 11 of the AC are zero.

The LOOKUP function is the standard method of opening a permanent file for input.

2.2.3 ENTER Output (Tentative) File (Function Code = 3)

The ENTER function is used to create a tentative file entry to be used for output. An example of a typical ENTER function is as follows:

           TAD VAL             /AC IS NOT ZERO
           CDF 0
           CIF 10
           JMS I (USR
           3                   /FUNCTION CODE = 3
           NAME                /ARG(1) POINTS TO FILE NAME
           0                   /ARG(2)
           JMP ERROR           /ERROR RETURN
           .                   /NORMAL RETURN
           .
           .
   NAME,   FILENAME PROG.LS

Bits 8 to 11 of the AC contain the device number of the selected device; the device handler for this device must be loaded into core before performing an ENTER function. If bits 0 to 7 of the AC are non-zero, this value is considered to be a declaration of the maximum length of the file. The ENTER function searches the file directory for the smallest empty file that contains at least the declared number of blocks. If bits 0 to 7 of the AC are zero, the ENTER function locates the largest available empty file.

On a normal return, the contents of ARG(1) are replaced with the starting block of the file. The 2's complement of the actual length of the created tentative file in blocks (which can be equal to or greater than the requested length) replaces ARG(2). if the file directory contains any Additional Information Words, the system DATE (location 17666) is written as the first Additional Information Word of the newly created tentative file at this time.

NOTE
If the selected device is not file structured but permits output operations (e.g., the high speed punch), the ENTER operation always succeeds. In this case, ARG(1) and ARG(2) are both zeroed on return.

If the error return is taken, ARG(1) and ARG(2) are unchanged. The following conditions cause an error return:

  1. The device specified by bits 8 to 11 of the AC is a read only device.
  2. No empty file exists which satisfies the requested length requirement.
  3. Another tentative file is already active on this device (only one output file can be active at any given time).
  4. The first word of the file name was 0 (an illegal file name).

In addition, one of the following monitor errors can occur, followed by a return to the Keyboard Monitor:

Error MessageMeaning
MONITOR ERROR 2 AT xxxxx Results if an I/O error occurred while reading or writing the device directory.
MONITOR ERROR 3 AT xxxxx Results if the device handler for the specified device is not in core.
MONITOR ERROR 4 AT xxxxx Results if AC bits 8 to 11 are zero.
MONITOR ERROR 5 AT xxxxx Read error on the system device while bringing in the overlay code for the ENTER function.
MONITOR ERROR 6 AT xxxxx Results if a directory overflow occurred (no room for tentative file entry in directory).

2.2.4 The CLOSE Function (Function Code = 4)

The CLOSE function has a dual purpose: first, it is used to close the current active tentative file, making it a permanent file. Second, when a tentative file becomes permanent it is necessary to remove any permanent file having the same name; this operation is also performed by the CLOSE function. An example of CLOSE usage follows:

           TAD VAL        /GET DEVICE NUMBER
           CDF 0
           CIF 10
           JMS I (USR
           4              /FUNCTION CODE = 4
           NAME           /ARG(1)
           15             /ARG(2)
           JMP ERR        /ERROR RETURN
           .              /NORMAL RETURN
           .
   NAME,   FILENAME PROG.LS

The device number is contained in AC bits 8 to 11 when calling the USR. ARG(1) is a pointer to the name of the file to be deleted and ARG(2) contains the number of blocks to be used for the new permanent file.

The normal sequence of operations on an output file is:

  1. FETCH the device handler for the output device.
  2. ENTER the tentative file on the output device, getting the starting block and the maximum number of blocks available for the file.
  3. Perform the actual output using the device handler, keeping track of how many blocks are written, and checking to ensure that the file does not exceed the available space.
  4. CLOSE the tentative file, making it permanent. The CLOSE operation would always use the same file name as the ENTER performed in step 2. The closing file length would have been computed in step 3.

After a normal return from CLOSE, the active tentative file is permanent and any permanent file having the specified file name already stored on the device is deleted. If the specified device is a non-file structured device that permits output (the paper tape punch, for example) the CLOSE function will always succeed.

NOTE
The user must be careful to specify the same file names to the ENTER and the CLOSE functions. Failure to do so can cause several permanent files with identical names to appear in the directory. If CLOSE is intended only to be used to delete some existing file, then the number of blocks, ARG(2) should be zero.

The following conditions cause the error return to be taken:

  1. The device specified by bits 8 to 11 of the AC is a read only device.
  2. There is neither an active tentative file to be made into a permanent file, nor a permanent file with the specified name to be deleted.

In addition, one of the following Monitor errors can occur:

Error MessageMeaning
MONITOR ERROR 1 AT xxxxx Results if the length specified by ARG(2) exceeded the allotted space.
MONITOR ERROR 2 AT xxxxx Results if an I/O error occurred while reading or writing the device directory.
MONITOR ERROR 3 AT xxxxx Results if the device handler for the specified device is not in core.
MONITOR ERROR 4 AT xxxxx Results if AC bits 8 to 11 are zero.

2.2.5 Call Command Decoder (DECODE) (Function Code = 5)

The DECODE function causes the USR to load and execute the Command Decoder. The Command Decoder accepts (from the Teletype) a list of input and output devices and files, along with various options. The Command Decoder performs a LOOKUP on all input files, sets up necessary tables in the top page of field 1, and returns to the user program. These operations are described in detail in Chapter 3, which should be read before attempting to use the DECODE function.

A typical call to the Command Decoder looks as follows:

           CDF 0
           CIF 10
           JMS I (USR
           5             /FUNCTION CODE = 5
           2001          /ARG(1), ASSUMED INPUT EXTENSION
           0             /ARG(2), ZERO TO PRESERVE ALL
	                 /TENTATIVE FILES
           .             /NORMAL RETURN
           .
           .

ARG(1) is the assumed input extension, in the above example it is ".PA". On return from the Command Decoder, information is stored in tables located in the top page of field 1. The DECODE function also resets all system tables as in the RESET function (see RESET function, section 2.2.11). If ARG(2) is 0 all currently active tentative files remain open; if ARG(2) is non-zero all tentative files are deleted and the normal return is to ARG(2) instead of ARG(2)+1.

The DECODE function has no error return (Command Decoder error messages are given in Chapter 3). However, the following Monitor error can occur:

Error MessageMeaning
MONITOR ERROR 5 AT xxxxx I/O error occurred while reading or writing on the system device.

2.2.6 CHAIN Function (Function Code = 6)

The CHAIN function permits a program to load and start another program with the restriction that the program chained to must be a core image (.SV) file located on the system device. A typical implementation of the CHAIN function looks as follows:

           CDF 0
           CIF 10
           JMS I (USR
           6           /FUNCTION CODE = 6
           BLOCK       /ARG(1), STARTING BLOCK NUMBER

There is no normal or error return from CHAIN. However, the following monitor error can occur:

Error MessageMeaning
MONITOR ERROR 5 AT xxxxx I/O error occurred while reading or writing on the system device.
CHAIN ERR An attempt was made to CHAIN to a file which was a core image (.SV) file. Control returns to the keyboard monitor.

The CHAIN function loads a core image file located on the system device beginning at the block number specified as ARG(1) (which is normally determined by performing a LOOKUP on the desired file name). Once loaded, the program is started at an address one greater than the starting address specified by the program's Core Control Block.

CHAIN automatically performs a USROUT function (see section 2.2.9) to dismiss the USR from core, and a RESET to clear all system tables (see section 2.2.11), but CHAIN does not delete tentative files.

The areas of core altered by the CHAIN function are determined by the contents of the Core Control Block of the core image file loaded by CHAIN. The Core Control Block for the file is set up by the ABSLDR or LOADER programs. It can be modified by performing a SAVE command with specific arguments. Every page of core in which at least one location was saved is loaded. If the page is one of the "odd numbered" pages (pages 1, 3, etc.; locations 0200 to 0377, 0600 to 0777, etc.), the previous page is always loaded. In addition, CHAIN always alters the contents of locations 07200 to 07577.

NOTE
CHAIN destroys a necessary part of the ODT resident breakpoint routine. Thus an ODT breakpoint should never be maintained across a CHAIN.

With the above exceptions, programs can pass data back and forth in core while chaining. For example, FORTRAN programs normally leave the COMMON area in field 1 unchanged. This COMMON area can then be accessed by the program activated by the CHAIN.

2.2.7 Signal User ERROR (Function Code = 7)

The USR can be called to print a user error message for a program. The following is a possible ERROR call:

           CDF 0
           CIF 10
           JMS I (USR
           7              /FUNCTION CODE = 7
           2              /ARG(1), ERROR NUMBER

The ERROR function causes a message of the form:

   USER ERROR n AT xxxxx

to be printed. Here n is the error number given as ARG(1); n must be between 0 and 11 (octal), and xxxxx is the address of ARG(1). If ARG(1) in the sample call above was at location 500 in field 0, the message:

   USER ERROR 2 AT 00500

would be printed. Following the message, the USR returns control to the Keyboard Monitor, preserving the user program intact.

The error number is arbitrary. Two numbers have currently assigned meanings:

Error MessageMeaning
USER ERROR 0 AT xxxxx During a RUN, GET, or R command, this error message indicates that an error occurred while loading the core image.
USER ERROR 1 AT xxxxx While executing a FORTRAN or SABR program, this error indicates that a call was made to a subroutine that was not loaded.

2.2.8 Lock USR in Core (USRIN) (Function Code = 10)

When making a number of calls to the USR it is advantageous for a program to avoid reloading the USR each time a USR call is made. The USR can be brought into core and kept there for subsequent use by the USRIN function. The calling sequence for the USRIN function looks as follows:

           CDF 0
           CIF 10
           JMS I (7700
           10           /FUNCTION CODE = 10
           .            /NORMAL RETURN
           .
           .

The USRIN function saves the contents of the locations 10000 to 11777 on the system scratch blocks, loads the USR into this area in core, and returns control to the user program.

NOTE
If bit 11 of the current Job Status Word is a one, the USRIN function will not save the contents of locations 10000 thru 11777.

2.2.9 Dismiss USR from Core (USROUT) (Function Code = 11)

When a program has loaded the USR into core with the USRIN function and no longer wants or needs the USR in core, the USROUT function is used to restore the original contents of locations 10000 to 11777. The calling sequence for the USROUT function is as follows:

           CDF 0
           CIF 10
           JMS I (200        /DO NOT JMS TO 17700!!
           11                /FUNCTION CODE = 11
           .                 /NORMAL RETURN 
           .
           .

The USROUT function and the USRIN function are complementary operations. Subsequent calls to the USR must be made by performing a JMS to location 7700 in field 1.

NOTE
If bit 11 of the current Job Status Word is a 1, the contents of core are not changed by the USROUT function. In this case USROUT is a redundant operation since core was not preserved by the USRIN function.

2.2.10 Ascertain Device Information (INQUIRE) (Function Code = 12)

On some occasions a user may wish to determine what internal device number corresponds to a given device name or whether the device handler for a specified device is in core, without actually performing a FETCH operation. INQUIRE performs these operations for the user. The function call for INQUIRE closely resembles the FETCH handler call.

INQUIRE, like FETCH, has two distinct forms:

  1. Obtain the device number corresponding to a given device name and determine if the handler for that device is in core (example shown below).
  2. Determine if the handler corresponding to a given device number is in core.

An example of the INQUIRE call is shown below:

           CLA            /AC MUST BE CLEAR
           CDF 0
           CIF 10
           JMS I (USR
           12             /FUNCTION CODE = 12
           DEVICE DTA3    /GENERATES TWO WORDS:
	                  /ARG(1) AND ARG(2)
           0              /ARG(3)
           JMP ERR        /ERROR RETURN
           .              /NORMAL RETURN
           .
           .

ARG(1) and ARG(2) contain the device name in standard format. When the normal return is taken and ARG(2) is changed to the device number corresponding to the given name, and ARG(3) contains either the entry point of the device handler if it is already in core, or zero if the corresponding device handler has not yet been loaded.

A slightly different set of arguments is used to inquire about a device by its device number:

           TAD VAL        /AC IS NON-ZERO
           CDF 0
           CIF 10
           JMS I (USR
           12             /FUNCTION CODE = 12
           0              /ARG(1)
           JMP ERR        /ERROR RETURN
           .              /NORMAL RETURN
           .
           .

On entry to INQUIRE, AC bits 8 to 11 contain the device number (bits 0 to 7 ignored).

NOTE
If AC bits 0 to 7 are non-zero, and bits 8 to 11 are zero (an illegal device number) a:

   MONITOR ERROR 4 AT xxxxx

message is printed and program execution is terminated.

On normal return ARG(1) is set to the entry point of the device handler if it is already in core, or zero if the corresponding device handler has not yet been loaded.

The error return in both cases is taken only if there is no device corresponding to the device name or number specified.

2.2.11 RESET System Tables (Function Code = 13)

There are certain occasions when it is desired to reset the system tables, effectively removing from core all device handlers except the system handler. An example of the RESET function is shown below:

           CDF 0
           CIF 10
           JMS I (USR
           13            /FUNCTION CODE = 13
           0             /0 PRESERVES TENTATIVE FILES
           .             /NORMAL RETURN
           .
           .

RESET zeros all entries except the one for the system device in the Device Handler Residency Table (see section B.3.3), removing all device handlers, other than that for the system device, from core. This should be done anytime a user program modifies any page in which a device handler was loaded.

RESET has the additional function of deleting all currently active tentative files (files that have been entered but not closed). This is accomplished by zeroing bits 9 through 11 of every entry in the Device Control Word Table (see section B.3.5).

If RESET is to be used in this last fashion, to delete all active tentative files, then ARG(1) must be non-zero and the normal return is to ARG(1) rather than to ARG(1)+1. For example, the following call would serve this purpose:

           CDF 0
           CDF 10
           JMS I (USR
           13             /FUNCTION CODE = 13
           CLA CMA        /NON-ZERO:

The normal return would execute the CLA CMA and all active tentative files on all devices would be deleted. The Keyboard Monitor currently does not reset the Monitor tables. If user programs which do not call the Command Decoder are used, it is wise to do a RESET operation before loading device handlers. The RESET will ensure that the proper handler will be loaded into core.


CHAPTER 3
THE COMMAND DECODER

OS/8 provides a powerful subroutine called the Command Decoder for use by all system programs. The Command Decoder is normally called when a program starts running. When called, the Command Decoder prints a * and then accepts a command line from the console Teletype that includes a list of I/O devices, file names, and various option specifications. The Command Decoder validates the command line for accuracy, performs a LOOKUP on all input files, and sets up various tables for the calling program.

The operations performed by the Command Decoder greatly simplify the initialization routines of all OS/8 programs. Also, since command lines all have a standard basic structure, the Command Decoder makes learning to use OS/8 much simpler.

3.1 COMMAND DECODE CONVENTIONS

Chapter 9 of Introduction to Programming 1972 describes the syntax for the command line in detail. A brief synopsis is given here only to clearify the later discussion in this chapter.

The command line has the following general form:

   *out files<input files/(options)

There can be 0 to 3 output files and 0 to 9 input files specified.

Output File FormatMeaning
EXPLE.EXOutput to a file named EXPLE.EX on device DSK (the default file storage device).
LPT:Output to the LPT. This format generally specifies a non-file structured device.
DTA2:EXPLE.EXOutput to a file name EXPLE.EX on device DTA2.
DTA2:EXPLE.EX[99]Output to a file name EXPLE.EX on device DTA2. A maximum output file size of 99 blocks is specified.
nullNo output specified.

An input file specification has one of the following forms:

Input File FormatMeaning
DTA2:INPUTInput from a file named INPUT.df on device DTA2. "df" is the assumed input file extension specified in the Command Decoder.
DTA2:INPUT.EXInput from a file named INPUT.EX ond evice DTA2. In this case .EX overrides the assumed input file extension.
INPUT.EXInput from a file named INPUT.EX. If there is no previously specified input device, input is from device DSK, the default file storage device; otherwise, the input device is the same as the last specified input device.
PTR:Input from device PTR; no file name is needed for non-file structured devices.
DTA2:Input from device DTA2 treated as a non-file structured device, as, for example, in the PIP command line:

   *TTY:/L<DTA2:

In both of the last two formats, no LOOKUP operation is performed since the device is assumed to be non-file structured.

nullRepeats input from the previous device specified (must not be first in input list, and must refer to a non-file structured device). For example:

   *<PTR:,,

(two null files) indicates that three paper tapes are to be loaded.

NOTE
Whenever a file extension is left off an input file specification, the Command Decoder first performs a LOOKUP for the given name appending a specified assumed extension. If the LOOKUP fails, a second LOOKUP is made for the file appending a null (zero) extension.

The Command Decoder verifies that the specified device names, file names, and extensions consist only of the characters A through Z and 0 through 9. If not, a syntax error is generated and the command line is considered to be valid.

There are two kinds of options that can be specified: first, alphanumeric option switches are denoted by a single alphanumeric character preceded by a slash (/) or a string of characters enclosed in parentheses; secondly, a numeric option can be specified as an octal number from 1 to 37777777 preceded by an equal size (=). These options are passed to the user program and are interpreted differently by each program.

Finally, the Command Decoder permits the command line to be terminated by either the RETURN or ALT MODE key. This information is also passed to the user program.

3.2 Command Decoder Error Messages

If an error in the command line is detected by the Command Decoder, one of the following error messages is printed. After the error message, the Command Decoder starts a new line, prints a *, and waits for another command line. The erroneous command is ignored.

Error MessageMeaning
ILLEGAL SYNTAXThe command line is formatted incorrectly.
TOO MANY FILESMore than three output files or nine input files were specified.
device DOES NOT EXISTThe specified device name does not correspond to any permanent device name or any user assigned device named.
name NOT FOUNDThe specified input file name was not found on the selected device.

3.3 Calling the Command Decoder

The Command Decoder is initiated by the DECODE function of the USR. DECODE causes the contents of locations 0 to 1777 of field 0 to be saved on the system scratch blocks, and Command Decoder to be brought into that area of core and started. When the command line has been entered and properly interpreted, the Command Decoder exits to the USR, which restores the original contents of 0 to 1777 and returns to the calling program.

NOTE
By setting bit 10 of the Job Status Word to a 1 the user can avoid this saving and restoring of core for programs that do not occupy locations 0 to 1777.

The DECODE call can reside in the area between 0 to 1777 in field 0 and still function correctly. A typical call would appear as follows:

           CDF 0      /SET DATA FIELD TO CURRENT FIELD
           CIF 10     /INSTRUCTION FIELD MUST BE 1
           JMS I (USR /USR=7700 IF USR IS NOT IN CORE
	              /OR USR=0200 IF USRIN WAS PERFORMED
           5          /DECODE FUNCTION = 5
           2001       /ARG(1),ASSUMED INPUT EXTENSION
           0          /ARG(2),ZERO TO PRESERVE
	              /ALL TENTATIVE FILES
           .          /NORMAL RETURN
           .
           .

ARG(1) is the assumed input extension. If an input file name is given with no specified extension, the Command Decoder first performs a LOOKUP for a file having the given name with the assumed extension. If the LOOKUP fails, the Command Decoder performs a second LOOKUP for a file having the given name and a null (zero) extension. In this example, the assumed input extension is ".PA".

DECODE performs an automatic RESET operation (see section 2.2.11) to remove from core all device handlers except those equivalent to the system device. As in the RESET function, if ARG(2) is zero all currently active tentative files are preserved. If ARG(2) is non-zero, all tentative files are deleted and DECODE returns to ARG(2) instead of ARG(2)+1.

As the Command Decoder normally handles all of its own errors, there is no error return from the DECODE operation.

3.4 Command Decoder Tables

The Command Decoder sets up various tables in the top page of field 1 that describe the command line typed to the user program.

3.4.1 Output Files

There is room for three entries in the output file table that begins at location 17600. Each entry is five words long and has the following format:

Figure 3-1

Bits 0 to 7 of word 1 in each entry contain the file length, if the file length was specified with the square bracket construction in the command line. Otherwise, those bits are zero.

The entry for the first output file is in locations 17600 to 17604, the second is in locations 17605 to 17611, and the third is in locations 17612 to 17616. If word 1 of any entry is zero, the corresponding output file was not specified. A zero in word 2 means that no file name was specified.

Also, if word 5 of any entry is zero no file extension was specified for the corresponding file. It is left to the user program to take the proper action in these cases.

These entries are in a format that is acceptable to the ENTER function.

3.4.2 Input Files

There is room for nine entries in the input file table that begins at location 17617. Each entry is two words long and has the following format:

Figure 3-2

Bits 0 to 7 of word 1 contain the file length as a negative number. Thus, 377 (octal) in these bits is a length of one block, 376 (octal) is a length of two blocks, etc. If bit 0 to 7 are zero, the specified file has a length greater than or equal to 256 blocks or a non-file structured device was specified.

NOTE
This restriction to 255 blocks of actual specified size can cause some problems if the program has no way of detecting end-of-file conditions. For example, PIP cannot copy in image mode any file on a file structured device that is greater than 255 blocks long, although it can handle in /A or /B modes (ASCII or Binary) files of unlimited size. In /A or /B modes PIP will detect the CTRL/Z marking the end-of-file.

If this is liable to be a problem, it is suggested that the user program employ the special mode of the Command Decoder described in section 3.5 and perform its own LOOKUP on the input files to obtain the exact file length.

The two word input tables begin in locations 17617, 17621, 17623, 17625, 17627, 17631, 17633, 17635, and 17637. If location 17617 is zero, no input files were indicated in the command line. If less than nine input files were specified, the unused entries in the input file list are zeroed (location 17641 is always set to zero to provide a terminator even when no files are specified).

3.4.3 Command Decoder Option Table

Five words are reserved beginning at location 17642 to store the various options specified in the command line. The format of these five words is as follows:

Figure 3-3

Each of these bits corresponds to one of the possible alphanumeric option switches. The corresponding bit is 1 if the switch was specified, 0 otherwise.

NOTE
If no = n option is specified, the Command Decoder zeros 17646 and bits 1 to 11 of 17642. Thus, typing =0 is meaningless since the user program cannot tell that any option was specified.

Bit 0 of location 17642 is 0 if the command line was terminated by a carriage return, 1 if it was terminated by an ALT MODE.

3.4.4 Example

To clarify some of the preceding, consider the interpretation of the following command line:

   *BIN[10],<PTR:,,DTA2:PARA,MAIN/L=14200$

If this command line is typed to PAL8, it would cause assembly of a program consisting of four separate parts: two paper tapes, one file named PARA.PA on DTA2, and one file named MAIN.PA also on DTA2. The binary output is placed on a file named BIN.BN on device DSK, for which only 10 blocks need be allocated. No listing is generated. In addition, automatic loading of the binary output is specified by the /L option, with the starting address given as 4200 in field 1. Finally, the line is terminated by the ALTMODE key (which echoes as $) causing a return to the Keyboard Monitor after the program is loaded.

In the case of this example, the Command Decoder returns to PAL8 with the following values in the system tables:

NOTE
The entries for PTR (where no input file name is specified) have a starting block number and file size of zero. This is always true of the input table for a non-file structured device, or a file structured device on which no file name is given.

Figure 3-4

3.5 Special Mode of the Command Decoder

Occasionally the user program does not want the Command Decoder to perform the LOOKUP on input files, leaving this option to the user program itself. Programs such as format conversion routines could use this special format. If the input files were not OS/8 format, a command decoder LOOKUP operation would fail. The capability to handle this case is provided in the OS/8 Command Decoder. This capability is generally referred to as the "special mode" of the Command Decoder.

3.5.1 Calling the Command Decoder in Special Mode

The special mode call to the Command Decoder is identical to the standard DECODE call except that the assumed input file extension, specified by ARG(1) is equal to 5200. The value 5200 corresponds to an assumed extension of ".*", which is illegal. Therefore, the special mode of the Command Decoder in no way conflicts with the normal mode.

3.5.2 Operation of the Command Decoder in Special Mode

In special mode the Command Decoder is loaded and inputs a command line as usual. The appearance of the command line is altered by the special mode in these respects:

  1. Only one output file can be specified.
  2. No more than five input files can be specified, rather than the nine acceptable in normal mode.
  3. The character asterisk (*) is legal in file names and extensions, both in input files and on output files. It is strongly suggested that this character be tested by the user program and treated either as a special option or as an illegal file name. The user program must be careful not to ENTER an output file with an asterisk in its name as such a file cannot be manipulated or deleted by the standard system programs.

The output and option table set up by the Command Decoder is not altered in special mode. Entries in the input table are changed to the following format:

Figure 3-5

The table entry for the first input file is in locations 17605 to 17611; the second in locations 17612 to 17616; the third in locations 17617 to 17623; the fourth in locations 17624 to 17630; and the fifth in locations 17631 to 17635. A zero in word 1 terminates the list of input files. If word 2 of an entry is zero, no input file name was specified.

The OS/8 batch generating system will not allow calls to the command decoder in special mode. Batch mode is not entered if a call in Special Mode is discovered.


CHAPTER 4
USING DEVICE HANDLERS

A device handler is a system subroutine that is used by all parts of the OS/8 system and by all standard system programs to perform I/O transfers. All device handlers are called in the same way and they all perform the same basic operation: reading or writing a specified number of 128 records beginning at a selected core address.

These subroutines effectively mask the unique characteristics of different I/O devices from the calling program; thus, programs that use device handlers properly are effectively "device independent". Changing devices involves merely changing the device handlers used for I/O.

OS/8 device handlers have another important feature. They are able to transfer a number of records as a single operation. On a device like DECtape this permits many blocks of data to be transferred without stopping the tape motion. On a disk, a single operation could transfer an entire track or more. This capability significantly increases the speed of operation of OS/8 programs, usch as PIP, that have large buffer areas.

NOTE
The word "record" is defined to mean 128 words of data; thus, an OS/8 block consists of two 128 word records.

4.1 CALLING DEVICE HANDLERS

Device handlers are loaded into a user selected area in field 0 by the FETCH function. FETCH returns in ARG(1) the entry point of the handler loaded. The handler is called by performing a JMS to the specified entry point address. It has the following format:

           CDF N        /WHERE N IS THE VALUE OF THE CURRENT
	                /PROGRAM INSTRUCTION FIELD TIMES 10 (OCTAL)
           CIF 0        /DEVICE HANDLER ALWAYS IN FIELD 0
           JMS I ENTRY
           ARG(1)       /FUNCTION CONTROL WORD
           ARG(2)       /BUFFER ADDRESS
           ARG(3)       /STARTING BLOCK NUMBER
           JMP ERR      /ERROR RETURN
           .            /NORMAL RETURN (I/O TRANSFER COMPLETE)
           .
           .
   ENTRY,  0            /ENTRY CONTAINS THE ENTRY POINT OF THE
	                /HANDLER, DETERMINED WHEN LOADED BY FETCH

As with calls to the USR, it is important that the Data Field is set to the current program field before the device handler is called. On exit from the device handler, the Data Field will remain set to the current program field.

ARG(1) is the function control word, and contains the following information:

BitsContents
0 0 for an input operation, 1 for an output operation.
1 to 5 The number of 128 word records to be transferred. If bits 1-5 are zero and the device is non-file oriented (i.e., TTY, LPT, etc.) the operation is a no-op. If the device is file oriented (SYS, DECtape, disk, etc.), a read/write of 40 (octal) pages is performed.
6 to 8 The memory field in which the transfer is to be performed.
9 to 11 Device dependent bits, can be left zero. Currently only bit 11 is used; on DECtape bit 11 determines the direction in which the tape is started. If bit 11 is 0 the tape starts in reverse. If bit 11 is 1 the tape starts forward. All other handlers ignore these bits at present.

NOTE
Starting forward saves time as long as the block number, ARG(3), is seven or more blocks greater than the number of the block at which the tape is currently positioned.

ARG(2) is the starting location of the transfer buffer.

ARG(3) is the number of the block on which the transfer is to begin. The user program initially determines this value by performing a LOOKUP or ENTER operation. After each transfer the user program should itself add to the current block number the actual number blocks transferred, equal to one-half the number of 128 word records specified, rounded up if the number of records was odd.

There are two kinds of error returns: fatal and non-fatal. When the error return occurs and the contents of the AC are negative the error is fatal. A fatal error can be caused by a parity error on input, a write lock error on output, or an attempt to write on a read-only device (or vice versa). The meaning can vary from device to device, but in all cases it is serious enough to indicate that the data transferred, if any, is invalid.

When the error return occurs and the contents of the AC are greater than or equal to zero, a non-fatal error has occurred. This error always indicates detection of the logical end-of-file. For example, when the paper tape reader handler detects the end of a paper tape it inserts a CTRL/Z code in the buffer and takes the error exit with the AC equal to zero. While all non-file structured input devices can detect the end-of-file condition, no file structued device can; and no device handler takes the non-fatal error return when doing output.

The following restrictions apply to the use of device handlers:

  1. If bits 1 to 5 of the function control word, ARG(1), are zero, a transfer of 40 (octal) pages or an entire memory field is indicated. Care must be used to ensure that the the handler is not overlaid in this call.
  2. The user program must never specify an input into locations 7600 to 7777, 17600 to 17777, or 27600-27777 or the page(s) in which the device handler itself resides. In general, 7600-7777 in every memory field are reserved for use by DEC software. Those areas should be used with caution.
  3. Note that the amount of data transferred is given as a number of 128 word records, exactly one half of an OS/8 block. Attempting to output an odd number of records can change the contents of the last 128 words of the last block written. For example, outputting 128 words to a block on the RK8 disk causes the last 128 words of the block to be filled with zeroes.
  4. The specified buffer address does not have to begin at the start of a page. The specified buffer cannot overlap fields, rather the address will "wrap round" memory. For example, a write of 2 pages starting at locations 07600 would cause locations 7600-7777 and 0-177 of field 0 to be written.

4.2 Device Dependent Operations

This section describes briefly the operation of certain standard OS/8 device handlers, including normal operation, any special initialization operations for block 0, terminating conditions, and response to control characters typed at the keyboard. Further information on device handlers can be found in Chapter 5.

4.2.1 Teletype (TTY)

  1. Normal Operation

    This handler inputs characters from the Teletype keyboard and packs them into the buffer or unpacks characters from the buffer and outputs them to the teleprinter.

    On input, characters are echoed as they are typed. Following a carriage return, a line feed character is inserted into the input buffer and printed on the Teletype.

  2. Initialization for Block 0

    None.

  3. Terminating Conditions

    On input, detection of a CTRL/Z causes a CTRL/Z (octal code 232) to be placed in the input buffer, the remaining words of the buffer filled with zeros, and a non-fatal error to be returned. On output, detection of a CTRL/Z character in the output buffer causes output to be terminated and the normal return to be taken. There are no fatal errors associated with the Teletype handler.

  4. Teletype Interaction

    CTRL/C forces a return to the Keyboard Monitor. CTRL/Z forces an end-of-file on input (see 3). CTRL/O terminates printing of the contents of the current buffer on output.

4.2.2 High-Speed Paper Tape Reader (PTR)

  1. Normal Operation

    This handler inputs characters from the high-speed paper tape reader and packs them into the buffer.

  2. Initialization for Block 0

    The handler prints an up-arrow (up arrow) on the teleprinter and waits for the user to load the paper tape reader. By typing any single character (except CTRL/C) the user initiates reading of the paper tape.

    NOTE
    On some Teletypes, up-arrow is replaced by the circumflex (^) character.
  3. Terminating Conditions

    Detection of an end-of-tape condition, indicated by the failure to get a character in a specified period of time, causes a CTRL/Z to be entered in the buffer, the remaining words of the buffer to be filled with zeros, and a non-fatal error to be returned. Attempting to output to the paper tape reader causes a fatal error to be returned.

  4. Teletype Interaction

    Typing CTRL/C forces a return to the Keyboard Monitor.

4.2.3 High-Speed Paper Tape Punch (PTP)

  1. Normal Operation

    This handler unpacks characters from the output buffer and punches them on the paper tape punch.

  2. Initialization for Block 0

    None.

  3. Terminating Conditions

    Attempting to input from the paper tape punch causes a fatal error to be returned. There are no non-fatal errors associated with this handler.

  4. Teletype Interaction

    Typing CTRL/C forces a return to the Keyboard Monitor, but only when actual punching has begun, or if ^C is typed before punching commences. If the punch is off line, ^C is only effective immediately before punching would begin.

4.2.4 Line Printer (LPT)

  1. Normal Operation

    This handler unpacks characters from the buffer and prints them on the line printer. The character horizontal tab (ASCII 211) causes sufficient spaces to be inserted to position the next character at a "tab stop" (every eighth column, by definition). The character vertical tab (ASCII 213) causes nine line feeds to output. The character Form Feed (ASCII 214) causes a skip to the top of the next page. Finally, the handler maintains a record of the current print column and starts a new line after 80 or 128 columns have been printed. This handler functions properly only on ASCII data.

  2. Initialization for Block 0

    Before printing begins, the line printer handler issues a form feed to space to the top of the next page.

  3. Terminating Conditions

    On detection of a CTRL/Z character in the buffer, the line printer handler issues a form feed and immediately takes the normal return. Attempting to input from the line printer forces a fatal error to be returned. Also if the line printer error flag is set a fatal error is returned. There are no non-fatal errors associated with the line printer handler.

  4. Teletype Interaction

    Typing CTRL/C forces a return to the Keyboard Monitor. The handler for the LS8E line printer utilizes the expanded character capability of the printer. If a 216 (CTRL/N) character appears anywhere in a line of text, the entire line is printed in the expanded character mode. The 216 must be used on a line-by-line basis.

4.2.5 Cassettes

  1. Normal Operation

    This handler performs character I/O between the cassettes and the buffer. It treats cassettes as a non-file structured device. Data appears on cassette in 192-byte records.

  2. Initialization for Block 0

    On input the cassette is rewound. On output the cassette is rewound and a file gap is written.

  3. Terminating Condition

    An end-of-file on input is a software error.

  4. Teletype Interaction

    Typing CTRL/C forces a return to the Keyboard Monitor.

    NOTE
    The handler neither reads nor writes standard files. It is merely a paper tape replacement. It writes raw data (organized into 192-byte records) onto the cassettes starting at the beginning; and then later reads it back.

The source is already in OS/8 BUILD format. The handler has only two entry points (for drives A and B of a controller). The decision as to which controller it uses is made at assembly time by changing the symbol code. The result is as follows:

CODEDEVICE NAMEHANDLERDEVICE CODE
0 TA8A A:CSA0
B:CSA1
70
1 TA8B A:CSA2
B:CSA3
71
2 TA8C A:CSA4
B:CSA5
72
3 TA8D A:CSA6
B:CSA7
73

The handler has the internal device code of 27 (see Table 9-33 on page 9-152 of Introduction to Programming 1972). The handler is two pages long.

4.2.6 Card Read (CDR)

  1. Normal Operation

    This handler reads characters from the card reader and packs them into the input buffer. Trailing spaces (blank columns) on a card are deleted from input. The handler can accept only alphanumeric format data on cards (the DEC029 standard card codes are used).

  2. Initialization for Block 0

    None.

  3. Terminating Conditions

    A card which contains an underline character in column 1 (an 0-8-5 punch) with the remaining columns blank is an end-of-file card. In addition, after reading each card the handler checks to see if a CTRL/Z was typed at the keyboard. After either an end-of-file card or a CTRL/Z being typed, a CTRL/Z is inserted in the buffer, the remaining words of the input buffer are filled with zeros, and a non-fatal error is returned. Attempting to output to the card reader causes a fatal error to be returned.

  4. Teletype Interaction

    Typing CTRL/C forces a return to the Keyboard Monitor. typing CTRL/Z forces an end-of-file to occur (see 3.).

4.2.7 File Structured Devices

  1. Normal Operation

    (DECtape, LINCtape, TD8E DECtape, DF32, RF08, and RK8)

    These handlers transfer data directly between the device and the buffer.

  2. Initialization for Block 0

    None.

  3. Terminating Conditions

    A fatal error is returned whenever the transfer causes one of the error flags in the device status register to be set. For example, a fatal error results if a parity error occurs on input, or a write lock error occurs on output.

    The device handlers generally try three times to perform the operation before giving up and returning a fatal error. There are no non-fatal errors associated with file structured devices.

  4. Teletype Interaction

    Typing CTRL/C forces a return to the Keyboard Monitor.

    NOTE
    The system device handler does NOT respond to a typed CTRL/C.

4.2.8 TD8E DECtape

TD8E DECtape is the new accumulator transfer DECtape. Since OS/8 is a noninterrupt driven system, TD8E DECtape has data transfer rates equivalent to those for TC08 DECtape; however, the interrupt should never be used with the TD8E. Device handlers for TD8E DECtape are supplied as a standard part of OS/8. Each pair of drives (0 and 1, 2 and 3, etc.) requires a two page device handler. Thus, to have all eight TD8E dries in the system at one time requires four separate handlers. Thus for TD8E, it is wise to restrict usage to those units that physically exist. Also, the tape drives are hardwired to select one of two possible unit numbers; thus, the first pair of drives installed must be called units 0 to 1. Any other numbers will cause a SELECT error. In this case, the computer hangs until the correct drive is selected.


CHAPTER 5
RECONFIGURING THE OS/8 SYSTEM

It is sometimes necessary to construct an OS/8 system from scratch, or to make a new peripheral device available to OS/8. Both of these tasks are a part of reconfiguring the OS/8 system. OS/8 BUILD, which is described in detail in Chapter 9 of Introduction to Programming 1972 allows the user to quickly and easily build a new system or to alter the device complement of an existing system. We suggest that BUILD be used to perform these functions.

CONFIG is the original OS/8 system configurator. CONFIG can be used to generate a limited range of systems. It is suggested that CONFIG be used when a system is to be built from scratch (paper tapes) on a system which does not have high-speed paper tape reader. When there are fewer paper tapes to read in, use BUILD to create the system. See Getting On-line with OS/8 in Chapter 9 of Introduction to Programming 1972.

5.1 CONDITIONAL ASSEMBLY OF CONFIG

The source file CONFIG.06 contains all of the device dependent code for OS/8. By using conditional assembly symbols, various system configurations can be crated. Conditional symbols are used in conjunction with the IFDEF, IFNDEF, IFZERO, and IFNZRO pseudo-ops in PAL8. With suitable definitions, these conditional expressions cause various portions of CONFIG to be assembled. Creating a suitable configuration requires defining the proper combination of symbols.

5.1.1 System Device Selection

The system device is selected by assigning any one of the system parameters a non-zero value. If more than one of these parameters have non-zero values, assembly errors will occur.

  1. RF08 Disk System

    Defining RF08=n, where n = 1,2,3 or 4 causes an n disk RF08 to be the system device. For example, RF08 = 2 causes a 512K RF/RS08 system to be generated.

  2. DF32 Disk System

    Defining DF32 = n, where n = 1,2,3, or 4 causes an n disk DF32 system to be generated. Thus, defining DF32 = 2 would generate a 64K DF/DS32 system to be generated.

    NOTE
    Since the OS/8 system requires 14K of disk space, a single DF32 as the system device is not suggested. DEC will not support OS/8 running on a single DF32 disk.
  3. RK8 Disk System

    Defining RK8=1 causes the RK8 disk to be the system device.

  4. PDP-12 LINCtape System

    Defining LINCSYS = n, where n= 1 or 2 causes LINCtape unit 0 to be the system device. If LINCSYS = 1, the default storage device (DSK) is set equivalent to SYS, which is LINCtape unit 0. If LINCSYS = 2, the default storage device is LINCtape unit 1. The user should also be sure to specify LINCTAPE = 1 in addition to LINCSYS =n. If this is not done, DECtape handlers rather than LINCtape handlers will be inserted in the system.

  5. 12K TD8E System

    Defining TD8ESYS = n, where n = 1 or 2 will cause a system to be generated which uses TD8E DECtape unit 0 as the system device. This system requires a minimum 12K of memory. The system handler resides in pages 07600 and 27600. The system generated in this case only recognizes DECtape units 0 to 1 (DTA0 & DTA1). If other TD8E units are to be used, they must be inserted using OS/8 BUILD. See Chapter 9 of Introduction to Programming 1972 for details. If TD8ESYS = 1, the default DSK is set equal to DECtape unit 0. if TD8ESYS = 2, DSK is made equivalent to unit 1.

  6. TD8E with 256 Read-Only-Memory (ROM)

    Defining ROM = 1 will generate a system which uses the MR8E ROM handler for a system device. This causes TD8E DECtape unit 0 to be the system device, as well as the default device DSK. Tape units 0 and 1 are the only ones available. BUILD can be used to insert handlers for drives other than 0 and 1.

  7. TC08 DECtape System

    If none of the above mentioned parameters are defined, TC08 DECtape is the default system device. One can also set DECTAPE = n, where n = 1 or 2 to cause DECtape unit 0 to be the system device. If DECtape = 1, unit 0 is the default storage device. If DECtape = 2, unit 1 is the default storage device.

5.1.2 Optional Device Parameters

The standard system, generated by defining one of the system device parameters, contains the following device handlers:

Permanent Device NameMeaning
SYS,DSKSelected system device. Default file storage device. DSK is the same device as SYS, unless LINCSYS = 2, DECTAPE = 2, or TD8ESYS = 2 are specified.
TTYTeletype - ASR33, 35, LA30, VT05.
PTRHigh speed paper tape reader.
PTPHigh speed paper tape punch.
CDRCard reader (punch card or mark-sense).
LPTLE8 line printer.
DTA0-DTA7Handlers for eight DECtape drives. LINCtapes are also referenced as DTA. If TD8E is used, DTA0 and DTA1 are the only names available.

These handlers can be replaced by other, similar handlers by defining one or more of the following optional device parameters:

  1. LINCtape

    PDP-12 users must replace the standard TC08 DECtape handlers with LINCtape handlers. This must be done by setting LINCTAPE = 1. Note that the names for the devices remain DTA0-DTA7. BUILD must be used to rename the LINCtapes LTA0-LTA7.

  2. LP08

    Some systems (PDP-12) may have the older Analex 645 line printer rather than the standard LE8 (LP08) line printer. Defining LP08=0 will cause a handler for the Analex printer to be assembled. Device LPT will then reference this printer.

    NOTE
    The FORTRAN runtime system can use only the LE8 printer, since device 3 on output references line printer. To allow FORTRAN to use the 645 printer, modifications must be made to the FORTRAN library routines. The alternative is doing output to the line printer via the device independent channel 4. In this case, the actual line priner handler in the system is used, whether it is LE8 or 645.
  3. Low speed paper tape

    All those users who do not have the high speed reader hardware must set NOHSPT = 1. This causes the standard reader/punch handler to be replaced with similar handlers for the low speed reader/punch. The TTY handler is not suitable for reading in non-ASCII code, as certain tape characters would appear to be control characters.

    This simulated reader/punch handler prints a (^) character before reading a tape. The user then places his paper tape into the low speed reader, and sets the Teletype reader switch to START.

    NOTE
    While the tape is being read, do not type any characters at the keyboard, as garbled input will be generated. At the end of the read, the tape handler will time out, causing an end of file to be generated

    This option must be used if high speed tape I/O is not available. Devices PTP and PTR will reference the Teletype reader/punch if NOHSPT = 1.

  4. Multiple RK8 handlers

    Users with RK8 disk packs have the option of using the disks as a non-system storage device. Thus, a configuration could use RF08 as the system device, and still be able to access the RK8 disk. Setting RK01 = n, where n = 1,2,3 or 4 will generate a handler for n non-system RK8 disk drives.

    The possible permanent device names are:

       RKA0, RKA1, RKA2, and RKA3
    

    To make room for these devices in the system, n DECtape drivers are deleted from the system. Thus,

       RK01 = 2
    

    will cause a system to be generated which contains handlers for two RK8 drives: RKA0 and RKA1. DTA6 and DTA7 will no longer be available for use.

  5. TD8E DECtape

    Users may have TD8E DECtape for use as non-system devices by setting TD8E = 1. This causes the standard DECtape drivers to be replaced by handlers for TD8E Units 0 and 1. DTA2 - DTA7 are no longer available for use. If more than two TD8E drives are present, BUILD can be used to insert handlers for them.

5.1.3 Other Options

DIRECT and LIST are two more options available when generating an OS/8 system with CONFIG. The parameter "DIRECT" determines whether or not the system directory is to be zeroed when the system is generated. Defining DIRECT = 1 causes the new system to be built without destroying a previous directory. This gives the user the capability of putting a new OS/8 Monitor onto a system device without losing files that were on the device previously.

When generating an assembly listing of CONFIG, the sections of code which do not get assembled are automatically XLISTed (not printed). Thus, only the assembled sections appear on the output listing. To list all parts of the file, including non-assembled code, set LIST = 1. The listing will then be all inclusive.

5.1.4 Example

As an example of reconfiguring an OS/8 system, suppose a machine has the following configuration:

  1. PDP-8E computer
  2. DECtape (TC08)
  3. RF08 disk with two RS08's (76K of storage)
  4. Type 645 line printer (LP12)
  5. High-speed reader/punch
  6. Card reader

The following steps would be taken to build a system tailored to the above configuration:

  1. Build the system in the standard way, as described in Chapter 9 of Introduction to Programming 1972.
  2. Use PIP to put the file CONFIG.06 on the disk.
  3. Execute the following commands:

       .R EDIT
       *PARA.PA<
    
       #A
       /PARAMETER FILE
       RF08=3          /3 PLATTER RF08 SYSTEM
       LP08=0          /OLD STYLE LINE PRINTER
       DIRECT=1        /PRESERVE SYSTEM DIRECTORY
    
       #E
    
       .R PAL8
       *PTP:<PARA,CONFIG
    
  4. The output from PAL8 is the new CONFIG tape to be used in rebuilding the system. At this point, the system should be rebuilt. Refer to Chapter 9 of Introduction to Programming 1972, the section entitled Building OS/8 from Paper Tapes. In the procedure for Creating OS/8 with CONFIG, substitute the newly created CONFIG tape for the standard tape supplied with OS/8.
  5. Finally, since the DIRECT parameter prevented the new size of the system device (changed from 256K to 768K for this example) from being automatically written in the directory, it must be updated by the following operation:

       .R PIP
       *SYS:<SYS:/S=1
       ARE YOU SURE?
       YES
    

5.2 Building a System on DECtape or LINCtape

To avoid the time involved in rebuilding the system from paper tape each time it is changed, the binary tapes of OS/8, the Command Decoder (CD), and CONFIG can be placed on DECtape (or LINCtape) and the system built by the following procedure:

  1. Put the system tape on unit 0 and the tape containing the binary files OS8.BN, CD.BN, and CONFIG.BN on unit 1 (where CONFIG.BN corresponds tothe system configuration).
  2. Bootstrap the DECtape (or LINCtape) system and execute the following commands:

       .R ABSLDR
       *DTA1:OS8,CONFIG/G
    
  3. The system should halt with 7777 in the AC (if not, an error has occurred, try again from step 2); press CONTINUE to proceed. If the system device is not being changed, the build is complete at this point, otherwise execute the following command:

       .R ABSLDR
       *DTA1:OS8,CONFIG,CD/G
    
  4. The new system is built and responds to the RETURN key by printing a dot when ready to accept input. Now, if necessary, transfer files to the new system device with PIP.

Of course the above procedure is not limited to DECtape or LINCtape. The files OS8.BN, CD.BN, and CONFIG.BN could just as easily be placed on a disk and loaded from there. The example is intended to illustrate a useful alternative technique for building a system.

5.2.1 Writing Device Handlers

A device handler is a page-independent one or two page long subroutine. The device handler must run properly in any single page or two contiguous pages in field 0 (except 0000 to 0177 or 7600 to 7777). All device handlers have the same calling sequence:

           CDF N          /N IS THE CURRENT FIELD TIMES 10 (OCTAL)
           CIF 0          /DEVICE HANDLER LOCATED IN FIELD 0
           JMS I ENTRY    /ENTRY IS DETERMINED BY USR "FETCH'
           FUNCTION       /FUNCTION IS BROKEN DOWN AS FOLLOWS:
	                  /BIT 0 = 0 FOR READ
	                  /BIT 0 = 1 FOR WRITE
	                  /BITS 1 TO 5 = NUMBER OF PGS TO TRANSFER
	                  /BITS 6 TO 8 = FIELD FOR TRANSFER
	                  /BITS 9 TO 11 = DEVICE DEPENDENT BITS
           BUFFER         /CORE ADDRESS OF TRANSFER BUFFER
           BLOCK          /BLOCK NUMBER TO START TRANSFER
           ERROR          /ERROR RETURN, AC>=0 MEANS END-OF-FILE
	                  /              AC<0 MEANS FATAL ERROR
           NORMAL         /NORMAL RETURN

The device handler reads or writes a number of 128-word records beginning at the selected block. In general, device handlers should conform to the following standards:

  1. On normal return from a device handler the AC is zero and the DATA FIELD is always restored to its original entry value.
  2. Although the starting block number has true significance only for file structured devices, handlers for non-file structured devices can check the block number and perform initialization if the block number is zero. For example, the line printer handler outputs a form feed before printing when the specified block number is zero.
  3. Handlers should be written to be as foolproof as possible. Examples of typical user errors are: calling handler with non-zero AC (always perform a CLA in the handler); trying to read on a write only device, or trying to write on a read only device (gives a fatal error return); specifying 0 pages to be transferred (accept as meaning no actual transfer is to take place); or attempting to access a nonexistent block (gives a fatal error return).
  4. Device handlers normally check to see if a CTRL/C (ASCII 203) has been typed by the user. If one has, the handler aborts I/O and JMP's to location 7600 in field 0.
  5. Device handlers should be able to detect standard error conditions like checksum or parity errors. Whenever possible, several attempts to perform the transfer should be made before aborting I/O and taking the error exit. In addition, when operator intervention is required, the handler would normally wait for the action rather than take a fatal error exit. For example, if the paper tape punch is not turned on, the PTP handler waits for the punch to be turned on.
  6. By convention, in any handler for a device (like DECtape) that can search either forward or backward for a block, Bit 11 of the function word (one of the device-dependent bits) controls the starting direction of the search. Bit 11 is a 1 if the starting direction is forward and a 0 if it is reverse. The other two device dependent bits are not assigned any significance at the present time.
  7. Remember that the user specifies a multiple of 128 words to transfer, whereas the transfer starts at the beginning of a 128 or 256 word block. This means that the handler must provide that capability of reading or writing the first half of a block. Writing the first half of the block causes the contents of the second half of the block to be altered. For example, writing 128 words to the RK8 disk (256 word blocks) causes the second half of the block to be filled with zeroes. This is usually done by the hardware controller.
  8. The entry point to a two page device handler must be in the first page.
  9. A number of handlers can be included in the one or two pages of code. Where more than one handler is included in a single handler subroutine, the handlers are called co-resident. Co-resident handlers are always brought into core together. For example, all eight DECtape handlers fit into one page; hence, the DECtape handlers are co-resident. One restriction on co-resident handlers is that if they are two pages long all entry points must be in the first page.
  10. The USR, while doing file operations, maintains in core the last directory block read in order to reduce the number of directory reads necessary. The proper functioning of this feature depends on the fact that every handler for a file-structured device on a single system has a unique entry point relative to the beginning of the handler. The relative entry points currently assigned for file structured handlers are:

    Device HandlersRelative Entry Points
    System Device Handler7
    DECtape, LINCtape, or TD8E DECtape 10 to 17
    RKA020
    RKA121
    RKA222
    RKA323
  11. If the device is block oriented (such as DECtape, LINCtape, or Disk), then the handler transfers data directly with no alteration. However, if the device is character oriented (such as a paper tape reader, Teletype, or line printer), the handler is required to pack characters into the buffer on input and unpack them on output. The standard OS/8 character packing format puts three 8-bit characters into two words as follows:

    Figure 5-1

    For example, the 3 characters 'ABC' would be packed into 2 words as follows:

       Word 1: 6301
       Word 2: 1702
    

    When packing characters on input, the character CTRL/Z (octal 232) is inserted at the logical end-of-file (for example, at the end of the tape in the paper tape reader handler). Following CTRL/Z, the remaining words of the input buffer should be zeroed.

The device handler, whether one or two pages long, must be completely page independent: it must be capable of executing in any page(s) in field 0, except page 0 and 7600 to 7777. Page independent code can have no address constants. Writing one page handlers is relatively easy, since the addressing structure of the PDP-8 is essentially page independent. Writing page relocateable code for two pages, however, is considerably more difficult, as the two pages must communicate. The usual technique utilized in writing two page handlers is to include some initialization code which includes a JMS . . This replaces that location by an address on the page the handler was loaded on. Using this, the handler can then determine where the relevant pieces of code are in core.

As an example, the following is the initialization procedure performed by the TD8E DECtape routine. This is by no means the only technique that is possible, but it is a workable solution.

           *200
		             /EXECUTED CODE
   JINIT,  JMP INIT          /START INITIALIZATION
           .
           .
           .
   INIT,   JMS .             /FIND OUT WHERE WE ARE.
   BASE,   TAD CRDQAD        /INIT GETS ADDRESS OF BASE
           SPA               /NEGATIVE TERMINATES LIST
           JMP NXINIT        /INITIALIZE SECOND PAGE
           TAD INIT          /NOW UPDATE THE LIST OF
           DCA CRDQAD        /ADDRESS DEPENDENT LOCATIONS
           ISZ .-1           /POINT TO NEXT ELEMENT
           ISZ BASE          /NEXT INPUT VALUE
           JMP BASE          /LOOP OVER INPUT TABLE
           .
           .
           .
   CRDQAD, R4LINE-BASE       /THESE ARE ALL POSITIVE DIFFERENCES,
   CINIT2, INIT2-BASE        /SINCE THE ROUTINES INDICATED ARE
   CSELCT, SELECT-BASE       /IN THE SECOND PAGE. AFTER
   CXUNIT, XUNIT-BASE        /INITIALIZATION, CRDQAD POINTS TO
   BUFF,   4000              /THE ACTUAL ADDRESS OF R4LINE, ETC.
           .                 /THE 4000 IN BUFF TERMINATES
           .                 /THE FIRST INITIALIZATION.
           .                 /MORE PAGE INDEPENDENT CODE
   NXINIT, JMS I CINIT2      /INITIALIZE SECOND PAGE
   BASE2,  DCA JINIT         /CLEAR OUT JINIT. NO MORE
           JMP JINIT         /RELOCATING IS NEEDED UNTIL THE
		             /HANDLER IS LOADED INTO CORE AGAIN.
           *400              /SECOND PAGE OF HANDLER
   INIT2,  0                 /ADDRESS OF BASE2 GOES HERE
   INIT3,  TAD CTRY3
           SNA               /A 0 TERMINATES THIS LIST
           JMP I INIT2
           TAD INIT2         /ADD VALUE OF BASE2 TO LIST
           DCA CTRY3         /PUT BACK INTO LIST
           ISZ .-1           /NEXT LOC. TABLE
           ISZ INIT3
           JMP INIT3
           .
           .
           .
   CTRY3,  TRY3-BASE2        /THIS LIST GETS VALUE OF BASE2
   CRWCOM, TRWCOM-BASE2      /ADDED IN TO POINT TO THE REAL
   XBUFF,  0                 /ROUTINE.

Writing 2-page independent code can be expensive in terms of core required. The routines should be set up in such a way as to minimize communication between the two pages. Some other points to keep in mind are:

  1. Relocation code is once-only code. It is done once when the handler is loaded and need never be done again until the handler is re-loaded from the system device. For this reason, the relocation code can be placed in a buffer area or setup in temporary scratch locations which are later used as temporary storage.
  2. A useful hint is that a JMP into the next page of code is not required. The code can just as easily fall through 377 into 400. This may save a few locations of relocation code.

5.3 Inserting Device Handlers into OS/8

After the handler has been written and thoroughly debugged as a stand-alone routine, it can be integrated into the OS/8 monitor, where it will become a resident device handler. To accomplish the integration, use OS/8 BUILD, described thoroughly in the BUILD section in Chapter 9 of Introduction to Programming 1972.


APPENDIX A
OS/8 FILE STRUCTURES

A.1 FILE DIRECTORIES

Blocks 1 through 6 on all file structured devices are reserved for the file directory of that device. Six blocks are always allocated, though all are not necessarily active at any given time. To minimize the number of directory reads and writes necessary, OS/8 fills one directory block completely before overflowing onto a second block. Thus the user with only a few files can perform directory LOOKUPs and ENTERs faster than one with many files.

The directory blocks are each structured according to the following format:

Figure A-1

Locations 0 through 4 of each directory block are called the segment header.

A.1.1 Directory Entries

There are three types of file directory entries. They are PERMANENT FILE ENTRY, EMPTY FILE ENTRY, and TENTATIVE FILE ENTRY. A permanent file entry appears as follows:

Figure A-2

NOTE
If word 3 is zero, the given file has a null extension.

An empty file entry appears as follows:

Figure A-3

A tentative file entry appears as a permanent file entry with a length of zero. It is always immediately followed by an empty file entry. When the tentative file is entered in a directory, location 3 in the segment header becomes a pointer to this entry. The CLOSE function inserts the length word of the tentative file entry, making it a permanent file, and adjusts the length of the following empty file entry (deleting that entry if the length becomes zero).

Whether or not there is a tentative file open on any device is determined by examination of bits 9 to 11 of the system Device Control Word Table (see section B.3.5) not the contents of location 3 in the segment header. Zeroing these bits in the Device Control Word Table makes the active tentative file on the device inactive. The next time that the system has to write the directory segment, the inactive tentative file entry is removed. The distinction between active and inactive tentative files is made so that OS/8 can avoid spending the time required to perform an extra read and write of the device directory.

A.1.2 Number and Size of OS/8 Files

All files on an OS/8 device must occupy a continuous group of blocks on the device. The length of any file is indicated in its directory entry, and the starting block of the file is deduced by adding together word 1 of the segment header and the lengths of all files whose entries precede it in the directory segment.

Each directory segment must have enough unused words at the end to accommodate a permanent file entry (N+5 words, where N is the number of Additional Information Words). Thus, if N is the number of Additional Information Words the maximum number of permanent file entries in any one segment is:

Figure A-4

NOTE
N is defined to be 1; i.e., the DATE word is always part of the overlay.

Directory fragmentation ( alternation of permanent file entries with empty file entries) reduces this maximum, and in the worst case the number of permanent file entries in any one segment is limited to:

Figure A-5

with N=1, MAX=40, and MIN=30. Since there are six segments in the directory, the maximum number of files possible (with N=1) would be 240.

Finally, OS/8 devices are limited to 4095 blocks, each 256 words long. Thus, the maximum size of any single OS/8 file structured device is 1,048,320 words. Blocks 0 through 6 of the device are unavailable for file storage; therefore, the largest possible file is 4088 blocks long, or 1,046,528 words.

A.1.3 Sample Directory

The initial directory written when the OS/8 system is built looks as follows:

Figure A-6

A.2 File Formats

There are three different standard file formats used by OS/8 and associated system programs:

  1. ASCII and Binary files.
  2. Core Image files (.SV format)
  3. Relocatable FORTRAN library files (LIB8.RL is the only current example of this format).

NOTE
Binary files can contain either absolute binary data (i.e., output from PAL8) or relocatable binary data (i.e., output from SABR).

A.2.1. ASCII and Binary Files

ASCII and Binary files are packed three characters into two words, as follows:

Figure A-7

The following conventions are used by OS/8 system programs:

  1. In ASCII files the character NULL (ASCII 000) is always ignored.
  2. In Binary files the binary data must be preceded by one or more frames of leader/trailer code (ASCII 200 code). The first character of binary data must be either 100 to 177 (octal) (an origin setting for absolute binary files), 240 to 257 (octal) (a COMMON declaration frame for relocatable binary files), or 300 (octal), which is an origin setting. The end of binary data is indicated by one or more frames of leader/trailer code.
  3. ASCII and Binary files are terminated by a CTRL/Z code (ASCII 232). In binary files, a CTRL/Z code occurring before the trailer code is treated as data rather than end-of-file.

Core Image (.SV Format) Files

A core image file consists of a header followed by the actual core image. The header block is called the Core Control Block. The Core Control Block consists of the first 128 words of the 256-word block reserved for that purpose. The second 128 words are unused. The Core Control Block is formatted as follows:

Figure A-8

The format of the Job Status Word is as follows:

Bit ConditionMeaning
Bit 0 = 1 File does not load into locations 0 to 1777 in field 0.
Bit 1 = 1 File does not load into locations 0 to 1777 in field 1.
Bit 2 = 1 Program must be reloaded before it can be restarted.
Bit 3 = 1 Program never uses above 8K. This is used when Batch processing is active.
Bit 10 = 1 Locations 0 to 1777 in field 0 need not be preserved when the Command Decoder is called.
Bit 11 = 1 Locations 0 to 1777 in field 1 need not be preserved when the USR is called.

The Core Segment Doublewords control the reading and writing of the associated areas of core. The format of each entry is as follows:

Figure A-9

The core origin must be a multiple of 400 (octal). The Core Segment Control Doublewords are sorted within the header block in order of decreasing field and increasing origin within the same field. There can be no more than 32 (decimal) Core Segment Control Doublewords in any Core Control Block.

The Code Control Block for the program at the time it is loaded into core is always saved in words 200 (octal) through 377 (octal) of block 37 (octal) (one of the system scratch blocks) on the system device. It is palced there by the GET and RUN operations or by the ABSLDR or LOADER programs. The Core Control Block is used when performing a SAVE without arguments.

NOTE
The R command differs from the RUN command in that the program's Core Control Block is not written onto the scratch area when using the R command. In order to SAVE a program that has been loaded by the R command all of the arguments of the SAVE command must be explicitly stated.

A.2.3 Relocatable FORTRAN Library File

A relocatable FORTRAN library consists of a library directory block followed by relocatable binary segments. The directory block has the following format:

Figure A-10

The Load Pointer is a number between 0 and 377 (octal) which points (relative to the beginning of the block) to an array of Loader Control Words. The Loader Control Words have the following information:

Figure A-11

There can be one or more Loader Control Words for each entry. The Loader Control Words for an entry are terminated by a word of zero. The following is a simple directory block.

Figure A-12

APPENDIX B
DETAILED LAYOUT OF THE SYSTEM

This appendix covers three topics: the reserved areas on the system device, the resident portion of OS/8, and the various system tables.

B.1 LAYOUT OF THE SYSTEM DEVICE

The first 70 octal blocks (14K words) on the system device are reserved by the OS/8 system. These blocks are used as follows:

Block(s) in OctalContents
0System Bootstrap Routine
1-6Device Directory
7-12Keyboard Monitor
13-15User Service Routine
16-25Device Handlers
26ENTER Processor for USR
27-50SYSTEM SCRATCH BLOCKS
51-53COMMAND DECODER
54-55SAVE and DATE Overlays
56Monitor Error Routine
57CHAIN Processor for USR
60-63SYSTEM ODT
64-65,67Reserved for System Expansion
6612K TD8E Resident Code

File storage begins with block 70 (octal).

The system scratch blocks are used for preserving the contents of core when the Keyboard Monitor, USR, Command Decord, or ODT are loaded. In addition, various system programs use the scratch area. Most importantly, the SAVE command expects the Core Control Block to be loaded in words 200 (octal) to 377 (octal) of block 37 (octal). The Core Control Block is stored at those locations by the GET or RUN command or by the ABSLDR or LOADER program.

A detailed breakdown of system scratch block usage follows:

Block(s) in OctalContents
27-32The contents of locations 10000 to 11777 are saved in this area when the USR is loaded.
33-36The contents of locations 0 to 1777 are saved in this area when the Command Decoder, Keyboard Monitor, or ODT is loaded.
37Words 200 (octal) to 377 (octal) of this block contain the Core Control Block for the last program loaded by the GET or RUN command, or the ABSLDR or LOADER program.
50Reserved for future expansion.

B.2 Layout of the OS/8 Resident Program

The top core pages in fields 0, 1, and 2 are used by the resident portion of OS/8 and are not accessible by the user. As a general rule, system and user programs should never destroy the contents of locations 7600 to 7777 of any field.

The resident portion of OS/8 is structured as follows:

Figure B-1
TOP PAGE OF FIELD 1
Figure B-2

Systems built around TD8E DECtape without the Read-Only-Memory option use 7600 in field 2 as an extension of the system device handler.

TOP PAGE OF FIELD 2.
Figure B-3

If a ROM (Read-Only-Memory) is being used with an 8K TD8E system, locations 7400-7777 of field 7 are inaccessible to the user. That core is used for system handler functions.

B.3 System Device Tables

Each device is described to the system by entries in five system tables. Each of these tables is fifteen words long, where the device number is the index into the table. The five tables are described below.

B.3.1 Permanent Device Name Table

Entries in this table specify the permanent name of each device. The entries are computed by encoding the actual four-character device name in a single word as follows:

  1. The device name is expressed as two words in the standard DEVICE format. For example, if the device name were "PTR" the two words would be:

        WORD 1: 2024
        WORD 2: 2200
    

    Note that when the device name is left justified; 0's are inserted to fill four characters.

  2. A single word is created by adding together these two words.
  3. If word 2 is non-zero, bit 0 of the resulting word is forced to be a one. For example, the table entry for "PTR" would be 4224.

An entry of zero means that there is no device for the corresponding device number.

NOTE
Conventionally, device names consist only of the characters A to Z and 0 to 9. The first character of the device name should be allphabetic. The coding used makes all one and two character device names unique; however, names of more than two characters are not unique. For example, "PTR" and "RTP" have the same encoding.

The Permanent Device Name Table is fifteen locations long; it resides in the USR. When the USR is in core the beginning of the table is in field 1 at a location the address of which is contained in location 10036.

B.3.2 User Device Name Table

Entries are made in this table whenever the user performs an ASSIGN and are restored to zero by a DEASSIGN. These entries have the same format as those in the Permanent Device Name Table.

The User Device Name Table resides in locations 17741 through 17757.

B.3.3 Device Handler Residency Table

When a device handler is loaded by the USR, the entry in this table for the device loaded (and entries for all devices whose handlers are co-resident, if any) is set to cotnain the entry point for the device handler. Entries other than those that contain an address above 7600 (thus referring to the system handler) are restored to 0 when a RESET, DECODE or CHAIN function is executed. When a program exits to the Keyboard Monitor this table is not cleared. The Keyboard Monitor Commands GET, RUN, R, SAVE, and START (with no explicit address) clear this table.

NOTE
Since the system device handler is always resident the first entry (SYS is always device number 1) in the Device Handler Residency Table is always 7607 (the entry point of the system device handler).

The Device Handler Residency Table resides in locations 17647 through 17665.

B.3.4 Device Handler Information Table

Each entry in this table contains all the informatin needed by the USR to load the corresponding handler. The format of these entries is as follows:

Bit ConditionMeaning
Bit 0 = 1If this is a two page device handler.
Bits 1 to 4Contain the relative block location of the device handler record on the system device. This is computed by subtracting 15 (octal) (one less than the first device handler block) from the actual block number.
Bits 5 to 11Contain the offset of the handler entry point from the beginning of the page. Note that the entry points to all handlers must be in the first page.

If an entry is 0 the corresponding device handler is not saved in any of the device handler storage blocks. This is always true of device number 1 (the system device) and for all device numbers that are not used in a given configuration. The Device Handler Information Table is 15 locations long and resides in the USR. When the USR is in core the beginning of the table is in field 1 at a location the address of which is contained in location 10037.

B.3.5 Device Control Word Table

Entries in this table specify special device characteristics, including the physical device type. The entry format is as follows:

Bit ConditionMeaning
Bit 0 = 1If the device is file-structured.
Bit 1 = 1If the device is read-only.
Bit 2 = 1If the device is write-only.
Bits 3 to 8Contain the physical device type code (described below).
Bits 9 to 11For file structured devices, these bits contain the directory block number of the currently active tentative file. If bits 9 to 11 are zero, there is no active tentative file on the device. For non-file structured devices, bits 9 to 11 are always zero. Bits 9 to 11 are reset to zero by the commands GET, RUN, R, SAVE, START (with no explicit address) and optionally by the USR functions RESET and DECODE.

The device type is a number between 0 and 77 (octal), of which 0 through 20 (octal) are currently assigned to existing devices, as follows:

Device CodeDevice
0Teletype
1High-speed paper tape reader
2High-speed paper tape punch
3Card Reader
4Line Printer
5RK8 Disk
6256K Disk (RF08)
7512K Disk (RF08 + RS08)
10768K Disk (RF08 + 2 RS08's)
111024K Disk (RF08 + 3 RS08's)
1232K Disk (DF32)
1364K Disk (DF32 + DS32)
1496K Disk (DF32 + 2 DS32's)
15128K Disk (DF32 + 3 DS32's)
16DECtape
17LINCtape (PDP-12 only)
20Magnetic Tape
21TD8E DECtape
22-77Unused currently

The Device Control Word Table resides in locations 17760 through 17776.

B.3.6 Device Length Table

There is a sixth table that is not normally considered part of the system tables. This is the Device Length Table and is used only by PIP to perform the /Z (zero directory) and /S (compress devices) options. This table is 64 locations long, one entry for each possible device type. In this table an entry of 0 means that the corresponding device is non-file structured; otherwise the entry contains the negative of the number of available 256-word blocks on the device.

For example, the entry for a 256K disk would be 6000 (octal) (minus 2000 (octal), or 1024 (decimal), 256-word blocks).

The Device Length Table resides in PIP. When PIP is brought into core the Device Length Table is in locations 13600 to 13677. When new device types are added to the system this table should be patched with ODT to reflect the device length of the new device.


APPENDIX C
SYSTEM ERROR CONDITIONS AND MESSAGES

This is a summary of all error messges that are result of system errors. These errors are also described in the relevant sections of this manual and in chapter 9 of Introduction to Programming 1972.

C.1 SYSTEM HALTS

Errors that occur as a result of a major I/O failure on the system device can cause a system halt to occur. These are as follows:

Value of PCMeaning
00601A read error occurred while attempting to load ODT. Return to the Keyboard Monitor by restarting at 07605.
07641An error occurred while reading a program into core during a CHAIN. Return to the Keyboard Monitor by restarting at 07605.
07605An error occurred while attempting to write the Keyboard Monitor area onto the system scratch blocks. Verify that the system device is not WRITE LOCKed and restart at location 07600 to try again.
07702A user program has performed a JMS to 7700 in field 0. This is a result of trying to call the USR without first performing a CIF 10. As location 07700 has been destroyed, the user must re-bootst