digital equipment corporation
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.
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:
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.
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.
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.
Three different types of files exist in the OS/8 system:
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: |
|
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.
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:
| LOCATION | CONTENTS | NOTES |
|---|---|---|
| 7744 | 72N3 | N is the field in which to start. |
| 7745 | addr | Starting address of the program. |
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 Condition | Meaning |
|---|---|
| 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 does not destroy the contents of the highest existing memory field, an optimization for Batch system. |
| Bits 4 thru 9 | Reserved for future use. |
| Bit 10 = 1 | Locations 0 to 1777 in field 0 need not be saved when calling the Command Decoder. |
| Bit 11 = 1 | Locations 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.
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.
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.
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
| 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).
| Function Code | Name | Operation |
|---|---|---|
| 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:
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:
In addition, one of the following Monitor errors can be printed, followed by a return to the keyboard monitor:
| Error Message | Meaning |
|---|---|
| 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:
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:
In addition, specifying illegal arguments can cause one of the following monitor errors, followed by a return to the Keyboard Monitor:
| Error Message | Meaning |
|---|---|
| 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:
In addition, one of the following monitor errors can occur, followed by a return to the Keyboard Monitor:
| Error Message | Meaning |
|---|---|
| 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:
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:
In addition, one of the following Monitor errors can occur:
| Error Message | Meaning |
|---|---|
| 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 Message | Meaning |
|---|---|
| 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 Message | Meaning |
|---|---|
| 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 Message | Meaning |
|---|---|
| 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:
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.
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 Format | Meaning |
|---|---|
| EXPLE.EX | Output 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.EX | Output 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. |
| null | No output specified. |
An input file specification has one of the following forms:
| Input File Format | Meaning |
|---|---|
| DTA2:INPUT | Input from a file named INPUT.df on device DTA2. "df" is the assumed input file extension specified in the Command Decoder. |
| DTA2:INPUT.EX | Input from a file named INPUT.EX ond evice DTA2. In this case .EX overrides the assumed input file extension. |
| INPUT.EX | Input 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. |
| null | Repeats 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 Message | Meaning |
|---|---|
| ILLEGAL SYNTAX | The command line is formatted incorrectly. |
| TOO MANY FILES | More than three output files or nine input files were specified. |
| device DOES NOT EXIST | The specified device name does not correspond to any permanent device name or any user assigned device named. |
| name NOT FOUND | The 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.
The Command Decoder sets up various tables in the top page of field 1 that describe the command line typed to the user program.
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:
|
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.
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:
|
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:
|
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. |
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. |
|
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:
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:
|
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.
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. |
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:
| Bits | Contents |
|---|---|
| 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:
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.
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.
None.
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.
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)
This handler inputs characters from the high-speed paper tape reader and packs them into the buffer.
The handler prints an 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. |
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.
Typing CTRL/C forces a return to the Keyboard Monitor.
4.2.3 High-Speed Paper Tape Punch (PTP)
This handler unpacks characters from the output buffer and punches them on the paper tape punch.
None.
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.
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.
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.
Before printing begins, the line printer handler issues a form feed to space to the top of the next page.
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.
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.
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.
On input the cassette is rewound. On output the cassette is rewound and a file gap is written.
An end-of-file on input is a software error.
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:
| CODE | DEVICE NAME | HANDLER | DEVICE 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.
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).
None.
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.
Typing CTRL/C forces a return to the Keyboard Monitor. typing CTRL/Z forces an end-of-file to occur (see 3.).
(DECtape, LINCtape, TD8E DECtape, DF32, RF08, and RK8)
These handlers transfer data directly between the device and the buffer.
None.
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.
Typing CTRL/C forces a return to the Keyboard Monitor.
| NOTE |
|---|
| The system device handler does NOT respond to a typed CTRL/C. |
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.
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.
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.
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.
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. |
Defining RK8=1 causes the RK8 disk to be the system device.
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.
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.
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.
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 Name | Meaning |
|---|---|
| SYS,DSK | Selected system device. Default file storage device. DSK is the same device as SYS, unless LINCSYS = 2, DECTAPE = 2, or TD8ESYS = 2 are specified. |
| TTY | Teletype - ASR33, 35, LA30, VT05. |
| PTR | High speed paper tape reader. |
| PTP | High speed paper tape punch. |
| CDR | Card reader (punch card or mark-sense). |
| LPT | LE8 line printer. |
| DTA0-DTA7 | Handlers 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:
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.
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. |
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. |
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.
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.
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.
As an example of reconfiguring an OS/8 system, suppose a machine has the following configuration:
The following steps would be taken to build a system tailored to the above configuration:
.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
.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:
.R ABSLDR *DTA1:OS8,CONFIG/G
.R ABSLDR *DTA1:OS8,CONFIG,CD/G
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.
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:
| Device Handlers | Relative Entry Points |
|---|---|
| System Device Handler | 7 |
| DECtape, LINCtape, or TD8E DECtape | 10 to 17 |
| RKA0 | 20 |
| RKA1 | 21 |
| RKA2 | 22 |
| RKA3 | 23 |
|
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:
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.
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:
|
Locations 0 through 4 of each directory block are called the segment header.
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:
|
| NOTE |
|---|
| If word 3 is zero, the given file has a null extension. |
An empty file entry appears as follows:
|
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:
|
| 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:
|
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.
The initial directory written when the OS/8 system is built looks as follows:
|
There are three different standard file formats used by OS/8 and associated system programs:
| NOTE |
|---|
| Binary files can contain either absolute binary data (i.e., output from PAL8) or relocatable binary data (i.e., output from SABR). |
ASCII and Binary files are packed three characters into two words, as follows:
|
The following conventions are used by OS/8 system programs:
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:
|
The format of the Job Status Word is as follows:
| Bit Condition | Meaning |
|---|---|
| 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:
|
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:
|
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:
|
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.
|
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 Octal | Contents |
|---|---|
| 0 | System Bootstrap Routine |
| 1-6 | Device Directory |
| 7-12 | Keyboard Monitor |
| 13-15 | User Service Routine |
| 16-25 | Device Handlers |
| 26 | ENTER Processor for USR |
| 27-50 | SYSTEM SCRATCH BLOCKS |
| 51-53 | COMMAND DECODER |
| 54-55 | SAVE and DATE Overlays |
| 56 | Monitor Error Routine |
| 57 | CHAIN Processor for USR |
| 60-63 | SYSTEM ODT |
| 64-65,67 | Reserved for System Expansion |
| 66 | 12K 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 Octal | Contents |
|---|---|
| 27-32 | The contents of locations 10000 to 11777 are saved in this area when the USR is loaded. |
| 33-36 | The contents of locations 0 to 1777 are saved in this area when the Command Decoder, Keyboard Monitor, or ODT is loaded. |
| 37 | Words 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. |
| 50 | Reserved 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:
|
| TOP PAGE OF FIELD 1 |
|
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. |
|
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.
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:
WORD 1: 2024
WORD 2: 2200
Note that when the device name is left justified; 0's are inserted to fill four characters.
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.
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 Condition | Meaning |
|---|---|
| Bit 0 = 1 | If this is a two page device handler. |
| Bits 1 to 4 | Contain 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 11 | Contain 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 Condition | Meaning |
|---|---|
| Bit 0 = 1 | If the device is file-structured. |
| Bit 1 = 1 | If the device is read-only. |
| Bit 2 = 1 | If the device is write-only. |
| Bits 3 to 8 | Contain the physical device type code (described below). |
| Bits 9 to 11 | For 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 Code | Device |
|---|---|
| 0 | Teletype |
| 1 | High-speed paper tape reader |
| 2 | High-speed paper tape punch |
| 3 | Card Reader |
| 4 | Line Printer |
| 5 | RK8 Disk |
| 6 | 256K Disk (RF08) |
| 7 | 512K Disk (RF08 + RS08) |
| 10 | 768K Disk (RF08 + 2 RS08's) |
| 11 | 1024K Disk (RF08 + 3 RS08's) |
| 12 | 32K Disk (DF32) |
| 13 | 64K Disk (DF32 + DS32) |
| 14 | 96K Disk (DF32 + 2 DS32's) |
| 15 | 128K Disk (DF32 + 3 DS32's) |
| 16 | DECtape |
| 17 | LINCtape (PDP-12 only) |
| 20 | Magnetic Tape |
| 21 | TD8E DECtape |
| 22-77 | Unused currently |
The Device Control Word Table resides in locations 17760 through 17776.
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.
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.
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 PC | Meaning |
|---|---|
| 00601 | A read error occurred while attempting to load ODT. Return to the Keyboard Monitor by restarting at 07605. |
| 07641 | An error occurred while reading a program into core during a CHAIN. Return to the Keyboard Monitor by restarting at 07605. |
| 07605 | An 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. |
| 07702 | A 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 |