(edited 19-Sep-91) (Old SSM Chapter 10) (Programming for Specific Devices\PSD_CHAP)

This chapter provides information on device handlers that have special device-dependent characteristics. Read this chapter if you need to program specifically for one of the following devices: (UNNUMBERED) DL (RL01/RL02 disk handler) DM (RK06/RK07 disk handler) DU (MSCP disk handler) DW (CTI Bus-based disk handler) DX and DY (RX01/RX02 diskette handlers) DZ (Diskette handler) LD (Logical disk handler) MM, MS, and MT (Magtape handlers) MU (TMSCP magtape handler) NL (Null handler) NC, NQ, and NU (Ethernet handlers) UB (UNIBUS mapping register handler) VM (Virtual Memory handler) XC and XL (Communications Port handlers)

Much of the information in this chapter is based on other information in the RT--11 documentation set. You should be familiar with pertinent information found elsewhere rather than relying only on the information in this chapter. For example, much of the description of special functions as they apply to particular device handlers in this chapter assumes you know and understand the description of special functions (the .SPFUN request) in the (sml_book).

You should look at the on-line index utility, INDEX, or in the printed (mas_book) for other information in the RT--11 documentation set that pertains to a particular device handler or to various RT--11 features as they apply to that device handler.

Device handler operations are often controlled by various special functions. In this manual, you will be presented with both a code number and name for a special function. You can use the code in the particular special function call (.SPFUN) as documented. You can use the name (rather than the code) if you include in your program a macro call for the appropriate macro in the file, SYSTEM.MLB.

The following macros in SYSTEM.MLB define the names for the indicated type of special functions: (2\8) (Name\Device type) (.SFDDF\Disk device handlers) (.SFMDF\Magtape device handlers) (.SFNDF\Ethernet device handers) (.SFXDF\VTCOM device handlers) (.SFODF\'Other' device handlers, such as PI)

You could, for example, include the following code in your program or handler to define the names of all the disk type special functions in this manual. Then you could use the special function name, rather than the more cryptic function code. (Be sure that the volume that contains SYSTEM.MLB is also assigned the logical name SRC.) .LIBRARY "SRC:SYSTEM.MLB" .MCALL .SFDDF .SFDDF (DL (RL01/RL02 Disk Handler)\psd_dl_sec)

This section provides specific programming information for RL01 and RL02 disks. (Support for Special Functions)

The RL01/RL02 disk handler supports the following special functions. The device-specific parameter arguments are the same as for DM; see (psd_dm_sec) for information.

(3\6\8) (Code\Name\Action) (377\SF.ARD\Read operation without doing bad-block replacement; returns definitive error data.) (376\SF.AWR\Write operation without doing bad-block replacement; returns definitive error data.) (374\SF.BBR\Re-read the bad-block replacement table in the handler (the program changed it).) (373\SF.SIZ\Determine the size, in 256(10)-word blocks, of a particular volume.) (Support for Bad-Block Replacement)

Bad-block replacement for the RL01 and RL02 is similar to the bad-block support for the RK06/RK07 (DM). However, the RL01 and RL02 generate neither the bad sector error (BSE) nor the header validity error (HVRC). Therefore, the handler must check the bad-block replacement table for each I/O transfer. Since the table is always in memory as part of the DL handler, the I/O delay is not significant.

The last track of the RL01 and RL02 disks contains a table of the bad sectors that were discovered during manufacture of the disk. The 10(10) blocks preceding this table (the last 10(10) blocks in the second-to-last track) are set aside for bad-block replacements. The maximum number of bad blocks (10(10)) is defined in the handler.

As with the RK06 and RK07, you determine at initialization time whether to cover bad blocks with .BAD files or create a replacement table for them and substitute good blocks during I/O transfers. The advantage of using bad-block replacement is that it makes a disk with some bad blocks appear to have none. On the other hand, covering bad blocks with .BAD files fragments the disk. Because RT--11 files must be stored in contiguous blocks, this fragmentation limits the size of the largest file that can be stored.

The monitor file cannot reside on a block that contains a replaced block if you are using bad-block replacement. If this condition occurs, a boot error results when you bootstrap the system. In this case, move the monitor so that it does not reside on a block with an error.

If you specify the /REPLACE option during initialization of an RL01 or RL02 disk, DUP scans the disk for bad blocks. It merges the scan information with the manufacturing bad sector table, allocates a replacement for each bad block, and writes a table of the bad blocks and their replacements in the first 20 words of block 1 of the disk. Block 1 is a table of two-word entries. The first word is the block number of a bad block; the second word is its allocated replacement. The last entry in the table is 0. The entries in the table are in order by ascending bad block number. A sample table is shown in (PSDBBT_FIG).

(Bad-Block Replacement Table\PSDBBT_FIG) (POSTSCRIPT\S559C2PSDBBT_FIG.EPS\11)

The handler contains space to hold a resident copy of the bad block table for each unit. The amount of space allocated is defined by the SYSGEN conditional DL$UN, which represents the number of RL01/RL02 units to be supported. The value defaults to 2 if it is not defined. The handler reads the disk copy of the table into its resident area under the following three conditions: (UNNUMBERED) If a request is passed to the handler and the table for that unit has not been read since the handler was loaded into memory. If a request is passed to the handler and the handler detects Volume Check drive status. This status indicates that the drive spun down and spun up again, which means that the disk was probably changed. If an SF.BBR request is passed to the handler. This special function is used by DUP when it initializes the disk table to ensure that the handler has a valid resident copy. (DM (RK06/RK07 Disk Handler)\psd_dm_sec)

This section provides specific programming information for RK06 and RK07 disks. (Support for Special Functions)

The RK06/RK07 disk handler supports the following special functions:

(3\6\8) (Code\Name\Action) (377 \SF.ARD\Read operation without doing bad-block replacement; returns definitive error data.) (376 \SF.AWR\Write operation without doing bad-block replacement; returns definitive error data.) (374 \SF.BBR\Reread the bad-block replacement table in the handler (the program changed it).

SF.BBR uses no parameters.) (373 \SF.SIZ\Determine the size, in 256(10)-word blocks, of a particular volume.)

The special function (.SPFUN) request has the following general form, with the (area) and (chan) parameters and the optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book), and the other parameter arguments as described below: Macro Call: .SPFUN area,chan,func,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((func)\is the code for the function to be performed or the name of the function if the program has been assembled with the distributed module SYSTEM.MLB.) ((buf)\For SF.ARD and SF.AWR, the buffer size must be one word larger than required for the data. The first word of the buffer contains any returned error information. The remaining words in the buffer contain the data transferred. The error codes and information are as follows:
(3\8\8) (Code\Name\Meaning) (100000\ES.SUC\The I/O operation is successful.) (100001\ES.ECC\An ECC error is corrected.) (100002\ES.RTY\An error was recovered on a retry.) (100004\ES.UFF\An error was recovered through an offset retry.) (100010\ES.RCL\An error was recovered after recalibration.) (100200\ES.BBR\A bad block is detected (BSE error).) (1774xx\ES.ERR\An error was not recovered.)

For SF.BBR, (buf) should be 0.

For SF.SIZ, (buf) is a 1-word buffer where the .SPFUN request returns the size of the volume in 256(10)-word blocks.) ((wcnt)\For SF.BBR, (wcnt) should be 0.

For SF.SIZ, (wcnt) should be 1.) ((blk)\For SF.BBR, (blk) should be 0.

For SF.SIZ, (blk) should be 0.) (Support for Bad-Block Replacement)

The last cylinder of the RK06 and RK07 disks is used for bad-block replacement and error information. RT--11 supports a maximum of 32(10) replaceable bad blocks on these disks. The bad-block information is stored in block 1 on track 0, cylinder 0, of the disk. The replacement blocks are stored on tracks 0 and 1 of the last cylinder. A bad-block replacement table is created in block 1 of the disk by the DUP utility program when the disk is initialized. When a bad block is encountered and the table is not present in the handler from the same volume, the DM handler reads a replacement table from block 1 of the disk and stores it in the handler.

When a bad sector error (BSE) or header validity error (HVRC) is detected during a read or write, the DM handler replaces the bad block with a corresponding good block from the replacement tracks. The bad-block replacement feature of RT--11 requires blocks 0 through 5 and tracks 0 and 1 of the last cylinder to be good. This procedure causes an I/O delay since the read/write heads must move from their present position on the disk to the replacement area, and back again.

If this I/O delay cannot be tolerated, the disk can be initialized without bad-block replacement. In this case, bad blocks are covered by .BAD files. Neither the bad blocks nor the replacement tracks will be accessed.

You determine at volume initialization time whether to cover bad blocks with .BAD files or to create a replacement table for them and substitute good blocks during I/O transfers. The advantage of using bad-block replacement is that it makes a disk with some bad blocks appear to have none. On the other hand, covering bad blocks with .BAD files fragments the disk. Because RT--11 files must be stored in contiguous blocks, this fragmentation limits the size of the largest file that can be stored.

Only BSE and HVRC errors trigger the DM handler's bad block replacement mechanism. If a bad block develops that is not a BSE or HVRC error, the disk must be reformatted to have this new block included in the replacement mechanism. Reformatting should detect the new bad block. Mark it so that it generates a BSE or HVRC error and add the block number to the bad-block information on the disk. The disk should then be initialized to add the bad block to the replacement table.

The monitor file cannot reside on a block that contains a BSE error if you are using bad-block replacement. If this condition occurs, a boot error results when you bootstrap the system. In this case, move the monitor so that it does not reside on a block with a BSE error. Further, the monitor file (and any handler files) must reside in physically contiguous blocks -- none of the blocks can be in the replacement table. (DU (MSCP Disk Handler)\psd_du_sec)

This section provides specific programming information for MSCP disk devices.

The DU handler for RT--11 supports any disk system using the Mass Storage Communications Protocol (MSCP) interface. All disks using MSCP appear the same to the host computer. Thus, a single RT--11 DU handler can access any kind of MSCP disk. (Support for Special Functions\DUSPFUN_SEC)

The DU handler supports the following special functions:

(4\6\8\10) (Code\Name\Section\Action) (377 \SF.ARD\(psd_du_nfs_sf16_sec\value)\ Read operation without doing bad-block replacement; returns definitive error data.) (376 \SF.AWR\(psd_du_nfs_sf16_sec\value)\ Write operation without doing bad-block replacement; returns definitive error data.) (373 \SF.SIZ\(psd_du_sfsiz_sec\value)\ Determine the size, in 256(10)-word blocks, of a particular volume.) (\SF.S16\\(blk) argument for SF.SIZ to indicate 16-bit starting block.) (\SF.S32\\(blk) argument for SF.SIZ to indicate 32-bit starting block.) (372\SF.TAB\(psd_du_trans_sec\value)\ Returns the MSCP translation table.) (371\SF.OBY\\Obsolete; replaced by SF.BYP (360).) (367\SF.R32\(psd_du_nfs_sf32_sec\value)\ Read with 32-bit block number.) (366\SF.W32\(psd_du_nfs_sf32_sec\value)\ Write with 32-bit block number.) (360\SF.BYP\(psd_du_bypass_sec\value)\ Provides direct MSCP access.) (Determining Volume Size (SF.SIZ), Code 373\psd_du_sfsiz_sec)

Special function SF.SIZ returns the volume size in the word pointed to by the (buf) parameter argument. For DU, this special function is enhanced over that provided in the DL, DM, DY, and LD handlers. SF.SIZ for DU can return a 32-bit value for the device volume size and is, therefore, appropriate for use with device volumes that contain more than 65K blocks.

The volume size returned by the enhanced SF.SIZ is determined by any partition mapping. If a partition is mapped to the unit to which the channel is opened, the returned volume size is calculated from the base of the mapped partition to the usable end of the volume. If, for example, you have mapped unit DU1 to partition 1, an SF.SIZ for DU1 returns a volume size from the base of partition 1 to the usable end of the volume. If you reference the first partition on the volume, SF.SIZ returns the usable size of the entire volume.

The following description of parameters lists any differences between those for returning a 16-bit volume size and those for the 32-bit volume size. Macro Call: .SPFUN area,chan,#SF.SIZ,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\8) ((area)\is the address of a 6-word EMT argument block) ((chan)\is the channel opened on the unit for which you want the volume size) ((SF.SIZ)\is code 373 or the name SF.SIZ if the program has been assembled with the distributed module SYSTEM.MLB) ((buf)\For 16-bit value, is the address of a 1-word buffer in which volume size is returned

For 32-bit value, is the address of a 4-word buffer that on return contains a 32-bit value for the volume size followed by a 32-bit value for the MSCP logical block number from which the volume size was calculated.

(postscript\s559c2_sfsiz_fig.eps\7)

The low-order base bits contain the value 0 and the high-order base bits contain a value indicating the partition to which this unit is currently mapped. If the unit does not exist, SF.SIZ returns a hard error and the contents of (buf) are undefined) ((wcnt)\For 16-bit volume size, is 1. For 32-bit volume size, is 4) ((blk)\For 16-bit volume size, is 0, indicating subcode SF.S16. For 32-bit volume size, is 1, indicating subcode SF.S32) (Obtaining the DU Device Status (STATU$)\psd_du_statu_sec)

DU has a status word containing information about the last operation performed by the handler. The status word is called STATU$ and is located at an offset from the base of DU. See (psd_du_statu_tab). The offset is stored in the handler as an entry in the table set up by the .DRTAB macro. The first word of the 2-word table entry is the RAD50 characters (UMS), followed by the value of STATU$. Using .DRTAB is described in the (sml_book). The low 5 bits of STATU$ contain the status information. All other bits are reserved.

(STATU$ Status Information\psd_du_statu_tab) (2\8) (OctalValue\Meaning) (00\Success) (01\Invalid command) (02\Command aborted) (03\Unit off line) (04\Unit available) (05\Medium format error) (06\Write-protected medium) (07\Compare error) (10\Data error) (11\Host buffer access error) (12\Controller error) (13\Drive error)

Use DBG--11, ODT/VDT, Console ODT, or the E keyboard command to examine the contents of STATU$. You will need to perform customization patch 2.7.32 located in the (ins_book) to use the E command. Use the SHOW MEMORY command display to find the base of the DU handler and add the offset to that base.

You can obtain the information returned in STATU$ from within a program by calling the sytem subroutine, IGTDUS, as described in the (SSL_BOOK). (Support for Bad-Block Replacement\psd_du_bbr_sec)

All MSCP (DU) hard-disk systems support bad-block replacement (BBR), performed either by the disk controller or as a feature of the DU handler. For those MSCP hard disks for which BBR is provided by the controller, no support is required by the DU handler; bad-block replacement is transparent to RT--11.

In MSCP systems that use an RQDX1, RQDX2, or RQDX3 controller, BBR is performed by the controller. In those systems, BBR is done automatically by the hardware and does not require bad-block support in the DU handler.

In MSCP systems that use a KDA50, UDA50, KLESI--QA, or KLESI--UA controller, BBR can be performed by the DU handler.

(psd_du_bbr_tab) lists the MSCP controllers and drives supported by RT--11 and indicates whether bad-block replacement (BBR) is performed by the controller or the DU handler. (There is no BBR support for RX50 devices or write-only media.)

(MSCP Bad-Block Replacement (BBR)\psd_du_bbr_tab) (3\12\14) (MSCPController\Bad BlockReplaced by:\MSCP Drive) (RQDX1\controller\Supported RD-type drives) (RQDX2\controller\Supported RD-type drives) (RQDX3\controller\Supported RD-type drives) (KLESI--QA\handler\Supported RC-type drives) (KLESI--UA\handler\Supported RC-type drives) (UDA50\handler\Supported RA-type drives) (KDA50\handler\Supported RA-type drives)

The distributed DU for mapped monitors (DUX.SYS) supports handler BBR. If you are going to use an unmapped monitor with MSCP disks that require handler BBR, you should perform a system generation for that monitor and request support for DU handler bad-block replacement. Once you have generated such support, you can change monitors and continue DU handler bad-block replacement.

The following is general information on BBR as performed by DU: (unnumbered) Bad-block replacement is a technique in which substitute blocks are provided for blocks that have caused a read or write error. The replacement blocks appear to occupy the disk positions of the original blocks, and the disk appears to contain only good blocks. You can force bad-block replacement on a device by performing a read and verify operation on all blocks. You perform such a read/verify operation by issuing a FORMAT/VERIFY:ONLY command for the device. Whether bad-block replacement is performed by the controller or the handler, it has the effect of making a disk appear to be error free. In certain cases, however, an I/O operation, a verification procedure, or a bad-block search may report the presence of bad blocks on a disk with replaced blocks. In such cases, any block identified as a bad block should be considered to be a good block with bad data. This means that the controller or handler provided a replacement block for a defective block but was unable to recover the data it contained. You can force MSCP class devices to clear bad blocks that contain soft errors by coupling the DUP /H option with the /B or /K option. The /H option is not available as a KMON command. You should use only the DUP /H/B or /H/K command options with blank media or a volume you have just backed up. If the DU handler is unable to replace a block on a device, DU displays the following error message: ?DU-E-Replace command failure or inconsistent RCT. ?DU-E-Software write protecting volume.

If you receive that message, you should immediately back up that volume. Then check any file you had open for lost data. You cannot write to that volume again without first taking it off line and then placing it on line. (Non-File-Structured Read and Write Operations\psd_du_nfs_sec)

DU supports three methods for performing non-file-structured read and write operations. (JREAD and JWRITE\psd_du_nfs_jrjw_sec)

You can perform absolute (non-file-structured access) reads and writes to any MSCP device, using the JREAD and JWRITE system subroutines. JREAD and JWRITE use a 32-bit starting block number, which lets you read and write to any block on any DU device. See the (ssl_book) for details on JREAD and JWRITE. (Special Functions SF.ARD and SF.AWR\psd_du_nfs_sf16_sec)

DU supports special functions SF.AWR (code 376) and SF.ARD (code 377). SF.AWR and SF.ARD are appropriate for devices that contain no more than 65K blocks. If the DU device contains more than 65K blocks, see (psd_du_nfs_sf32_sec). For DU, SF.AWR performs a write to the specified sector, and SF.ARD performs a read from the specified sector. Those writes and reads are not absolute; bad-block replacement and block vectoring remain in force.

Special functions SF.AWR and SF.ARD are especially useful because they return status information in the first word of the return buffer. Status information includes any occurrence of a bad-block error, forced error, or drive error. No discrimination for such errors is returned by a .WRITE or .READ request.

DU support for SF.AWR and SF.ARD is the same as DM with the following exceptions: (unnumbered) DU supports an additional error code:

(3\8\8) (Code\Name\Meaning) (140000\ES.FRC\A forced error occurred.

If the device is a disk drive that supports BBR, the device controller or DU handler discovered bad data on a good (replaced) block. (Bad-block replacement was performed but no data was recovered.)

If the device does not support BBR, this is an unexpected condition. ) For DU, bad-block replacement and block vectoring remain in force. (Special Functions SF.R32 and SF.W32\psd_du_nfs_sf32_sec)

DU supports two special functions that perform non-file-structured block reads (SF.R32, code 367) and writes (SF.W32, code 366) on devices that contain more than 65K blocks. Because these special functions perform non-file-structured operations, they should generally not be used to perform operations on any device partition that contains a file structure.

Special functions SF.W32 and SF.R32 perform the same operations as the JWRITE and JREAD functions; JWRITE and JREAD use special functions SF.W32 and SF.R32. JWRITE and JREAD are described in the (ssl_book). (Caution) SF.W32 can write data to the reserved blocks on your DU device, which can render your DU device useless, because those blocks contain the replacement control table (RCT). You should, therefore, always issue a special function SF.SIZ (373) to a DU device to determine the volume size, because SF.SIZ returns the size at the boundary between the usable logical blocks and the RCT. Writing data only up to the volume size returned by SF.SIZ ensures you will not write data into the RCT.

The format for these special functions is: Macro Call: .SPFUN area,chan,func,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\6) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number for I/O in the range 0 to 376(8).) ((func)\is the symbol or numeric code value for the function to be performed:
(3\6\8) (Code\Name\Meaning) (366\SF.W32\32-bit non-file-structured block write) (367\SF.R32\32-bit non-file-structured block read) ) ((buf)\is the buffer address.) ((wcnt)\is the number of words to transfer. Valid values are 0 through 077777(8).) ((blk)\is the address of a 4-word argument block:
(2\6) (blk+0\is a 2-word (32-bit) starting block number for this request. The first word contains the low-order bits. The second word contains the high-order bits.

The correspondence between the starting block number and a particular block on a device is determined by any partitioning and unit mapping of the device:

If the device has not been partitioned, starting block 0 specifies physical (and logical) block 0 --- the start of the device. Any starting block number is offset from physical block 0.

If the device has been partitioned, logical block 0 of partition 0 continues to contain physical block 0. However, the starting block 0 of this request, because of device partitioning, corresponds to logical block 0 of the unit opened on this channel. Any starting block number is offset from logical block 0 of the partition mapped to the unit. For example, if the channel is opened for a non-file-structured operation to unit DU1 and DU1 is mapped to partition 1 (block 200000(8), starting block 0 corresponds to physical block 200000(8) of this device).

If, for example, your device contains an RT--11 file structure in partition 0, which is mapped to DU0, you could ensure the integrity of that file structure by always performing non-file-structured operations above partition 0 on the device.) (blk+4\on return, contains the number of words actually transferred) (blk+6\is reserved) ) (DU Translation Table (SF.TAB), Code 372\psd_du_trans_sec)

The DU translation table defines the correspondence between RT---11 unit numbers and MSCP unit numbers, ports, and partitions. The format of the table is given in (PSDDTT_FIG).

Special function SF.TAB (code 372) interacts with the translation table from an address contained in the (buf) argument of the SF.TAB call. You can read the contents of the translation table to the buffer or write the contents of the buffer to the table. Whether the SF.TAB request is a read or write operation is determined by the (wcnt) parameter argument. This procedure is explained in this section.

For RT--11 V5.4, changes were made in the structure of the DU handler translation table. The names of the offsets in the table and the size of the table was changed. All programs you write to access the information contained in the table should use the following offsets. All programs you have written should be changed to use the following offset names.

Beginning with RT--11 V5.5, you can build a DU handler that supports more than eight units. That affects the size of the translation table.

(DU Handler Translation Table\PSDDTT_FIG) (POSTSCRIPT\S559c2PSDDTT_FIG.EPS\9)

Whenever an I/O request is passed to the DU handler, DU uses the RT--11 unit number as an index into this table, extracts the MSCP unit number, port, and partition that have been assigned to that RT--11 unit, and uses the information to access the proper disk. (Size of the Translation Table)

The size of the DU translation table in the DU handler is related to the number of device units supported by DU. The DU handler can support up to 64(10) units. Therefore, the translation table can contain up to 64 table entries. (Structure of the Translation Table)

The DU unit translation table consists of a table header followed by table entries. Previously, the DU unit translation table had no header. Now, the DU unit translation table has a header starting at offset DU.ID, which is a word containing the Radix-50 value for the characters DU.

DU.ID is followed by DU.NUM. The low byte of DU.NUM contains the number of entries in the table. The high byte of DU.NUM is reserved.

The structure of the rest of the table remains as before. However, the offset names you should use to specify elements of the table have changed. The following is the structure of the table with the changed offset names:

(MSCP (DU) Translation Table Header\PSD_MSCP_TRANS_TAB) (3\6\6) (Offset\Name\Meaning) (0\DU.ID\Radix-50 value for characters DU) (2\DU.NUM\Byte containing number of entries in table) (3\\Reserved) (4\DU.ENT\The offset of the first table entry)

Each table entry consists of 4 bytes. Digital recommends you use the symbol DU.ESZ to represent the 4-byte size of each entry.

(MSCP (DU) Translation Table Entry) (3\6\6) (Offset\Name\Meaning) (0\DU.UNI\Physical MSCP unit number.

The symbol DU$Uxx=nnnnnn is the initial value for the translation table when the handler is assembled. In the symbol, (xx) is the octal RT--11 DU unit number (0-7 or 0-77) and (nnnnnn) is the MSCP unit number. The SET Dxx UNIT=nnnnnn command can subsequently change the value.) (2\DU.PAR\Byte containing partition number.

The symbol DU$Axx=nnn is the initial value for the translation table when the handler is assembled. In the symbol, (xx) is the octal RT--11 DU unit number (0-7 or 0-77) and (nnn) is the partition number. The SET DU PART=nnn command can subsequently change the value.) (3\DU.POR\Byte containing MSCP port (controller) number.

The symbol DU$Oxx=nnn is the initial value for the translation table when the handler is assembled. In the symbol, (xx) is the octal RT--11 DU unit number (0-7 or 0-77) and (nnn) is the MSCP port number. The SET DU PORT=nnn command can subsequently change the value.) (Accessing the Translation Table)

Before Version 5.5, the translation table access special function code SF.TAB (372) supported only eight units. The (wcnt) parameter for SF.TAB accepted two arguments, SF.TRD (1) to indicate a read of the table and SF.TWR (--1) to indicate a write to the table. The size of the table was fixed at eight entries. If the DU handler on your system continues to support only eight DU devices, you continue to read and write to the translation table as before.

However, if the DU handler on your system supports more than eight units, the SF.TAB special function accepts other values for the (wcnt) parameter to support the extended device units. For DU handlers that implement the extended device-unit feature, you indicate both a read or write operation and the size of the table you are reading and writing by specifying a positive or negative numeric argument for the (wcnt) parameter. A positive numeric argument indicates a read operation of the specified number of words from the DU translation table to the buffer. A negative number indicates a write operation of the specified number of words from the buffer to the DU translation table.

You can use the following procedure to read the translation table from a DU handler that supports extended device units into a buffer and write the translation table from a buffer to DU. The procedure assumes you want to verify or do not currently know the number of entries in the table. (numbered) A translation table entry is created for each supported unit. You can determine the number of entries by doing a read SF.TAB to return the table entry DU.NUM. DU.NUM is the low byte of the second word in the table and contains the octal number of table entries. Therefore, for the (wcnt) parameter, supply the argument +2, and for the (buf) parameter, point to a 2-word buffer. The translation table header and each entry continue to contain two words. Therefore, you can then read the entire DU handler extended device-unit translation table by supplying the value HEADER+(2*DU.NUM) for the (wcnt) parameter. For example, if DU.NUM indicated 16 entries, the value to specify for (wcnt) to read the entire table would be +(2+(2*16)). The (buf) parameter would point to a buffer of the same size. You could write the contents of the buffer to the DU handler by specifying the value -(2+(2*16)) for the (wcnt) parameter.

You can avoid the calculation process by specifying a buffer of 130(10) words, which can hold the largest translation table. (Special Function Bypass (SF.BYP), Code 360\psd_du_bypass_sec)

Special function SF.BYP bypassess all unit number translations and allows direct access to the MSCP port. For DU, SF.BYP (direct MSCP assess) serves the same purpose as the MU handler's SF.BYP (direct TMSCP access).

The request syntax and parameter argument definitions for SF.BYP are as follows: Macro Call: .SPFUN area,chan,#SF.BYP,buf,wcnt,blk

(2\6) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((SF.BYP)\is code 360 or the name SF.BYP if the program has been assembled with the distributed module SYSTEM.MLB.) ((buf)\is the address of the 52(10)-word TMSCP area.) ((wcnt)\when nonzero, is the virtual address of a data buffer to send to the handler. That virtual address is translated to a physical address and placed in the buffer of the TMSCP area.

when zero, the buffer address in the TMSCP area is not altered) ((blk)\indicates whether the handler should perform retries:

(2\4) (1 = \specifies retries) (0 = \specifies no retries) )

The buffer address in special function SF.BYP must point to a 52-word area in the user's job. The first 26 words are used to hold: (UNNUMBERED) A response packet length in bytes A virtual circuit identifier An end packet when the command is complete

The second 26 words are set up by the caller and contain: (UNNUMBERED) A length word (length of command) A virtual circuit identifier (must have octal 1 (001) in high byte) A valid MSCP command (48-byte command buffer)

Except for port initialization, the user program must do all command packet sequencing, error handling, and reinitialization when the bypass operations are complete. The format of the control block is shown below: (#)

(2\6) (Word\Contents) (#0\Response Packet Length) (#1\Virtual Circuit ID (from UDA or QDA controller)) (#2\MSCP Response Buffer (24 words)) (26\Command Packet Length (48 bytes)) (27\Virtual Circuit ID (from host)) (28\MSCP Command (24 words)) (51\Last Word of MSCP Command Packet) (Addressing an MSCP Disk\psd_du_addr_sec)

You identify an MSCP disk to the DU handler by specifying: (unNUMBERED) The MSCP unit number, in the range 0 through 253 The controller port number, in the range 0 through 3 The disk partition number, in the range 0 through 255

As DU is distributed, you address a disk -- DU0 through DU7, as desired -- and the DU handler references the disks that have been assigned to those RT--11 unit numbers. You can perform a system generation and request extended device-unit support for DU, which lets you address up to 64(10) disks. See the (syg_book) for information.

The default port number is 0, the default partition number is 0, and the default unit numbers correspond to the RT--11 unit numbers. Thus, if no modifications or SET commands are made to the DU handler, an MSCP disk will be referenced exactly like any other RT--11 disk; DU0 will refer to disk unit 0, DU1 will refer to disk unit 1, and so on. However, the names DU0 through DU7 can be reassigned to the MSCP disks of your choice by specifying MSCP unit, port, and partition numbers. Each of these parameters is described below. (MSCP Unit Numbers\psd_du_unit_sec)

Traditionally, there has always been a one-to-one correspondence between a physical disk drive unit number and an RT--11 disk unit number. This one-to-one correspondence does not necessarily apply to disks using the MSCP interface. Neither is an MSCP disk controller limited to eight units, nor are the unit identifying numbers limited to the range 0 through 7. The MSCP unit number of a disk is defined by the unit number plug of the disk drive. Although MSCP disks on most RT--11 systems may never have a unit number plug greater than 7, MSCP unit numbers can be in the range 0 through 253. The DU handler supports a 16-bit MSCP unit number, if required by the system configuration.

The relationship between an RT--11 unit number and an MSCP disk unit number is defined within the DU handler. Typically, any necessary assignments are made at system installation time by using a SET command in the following form: (SET DUn UNIT=x)

For example, you might issue the SET command (SET DU7 UNIT=21)

Any references to DU7 would then go to MSCP unit number 21. (Controller Port Numbers\psd_du_port_sec)

The controller port number provides a way of logically identifying the vector/CSR pair of a particular MSCP controller when your system has more than one.

You can access a second MSCP controller through the DU handler in one of two ways. One way is to create a second copy of the handler, as described in (psd_du_second_sec). You can then use the original DU handler to access disks connected through the first controller port, and the new copy of the handler to access disks connected through the second controller port. Although this procedure requires two copies of the handler, it allows totally independent operation of the two ports, giving maximum I/O throughput.

The second way is to configure the DU handler for multiple ports by defining the conditional assembly parameter DU$PORTS=n. If memory space is at a premium, this may be your best choice. However, the ports will not operate independently and I/O throughput may be slower. If a request is pending for a disk interfaced through port 0, any requests for a disk interfaced through port 1 must wait for the port 0 I/O to complete. The DU handler supports up to four ports, numbered 0 through 3. CSR and vector values for each port can be assigned with SET commands in the following form: (SET DU VECTOR=nnnnnn) (SET DU VECx=nnnnnn) (SET DU CSR=mmmmmm) (SET DU CSRx=mmmmmm)

The value for (x) can be 2, 3, or 4.

If you configure the DU handler for multiple ports, you must specify the port number when you assign an RT--11 unit number to a disk interfaced through a port other than 0. You can do this with a SET command in the following form: (SET DUn PORT=x)

For example, you might issue the SET command: (SET DU7 PORT=1)

This command might be combined with an MSCP unit number assignment: (SET DU7 UNIT=21,PORT=1)

You can perform a system generation and request support for multiport booting, as described in (psd_du_multiboot_sec). (Disk Partition Numbers\psd_du_part_sec)

Disk partition numbers allow RT--11 to use disks having more than 65,535 blocks. The disk partition number can be thought of as a high-order block number, as shown in (PSDMBN_FIG).

(MSCP Disk Block Number\PSDMBN_FIG) (POSTSCRIPT\S559c2PSDMBN_FIG.EPS\7)

If a disk has more than 65,535 blocks, the DU handler divides the disk into logical partitions of 65,535(1\Although RT--11 block numbers can be 0 through 177777(8), or a total of 65,536(10) blocks (200000(8) , or 000000 in 16 bits since the 17th bit is lost), the size of a partition is defined as 65,535(10) blocks (177777(8)), with RT--11 block numbers 0 through 177776. This avoids the problem of 16-bit overflow when dealing with the partition size. Because the partition number is added onto the left of the RT--11 block number to give the MSCP block number, one block between each partition is unused. Refer to the list below for the block numbers of the first three partitions:

(#) (Partition########Block Numbers\BOLD)

#####0######000000--177776, block 177777 unused

#####1######200000--377776, block 377777 unused

#####2######400000--577776, block 577777 unused ) blocks each. The DU handler supports up to 256(10) disk partitions. Therefore, the largest disk DU can access has 256*65,535 blocks. To an RT--11 user, such a disk would appear to be 256 separate 65,535-block disks, each disk having its own directory.

Because the DU handler stores the partition numbers as bytes, DU supports an MSCP block number of no more than 24 bits, even though full MSCP supports block numbers of up to 32 bits. However, the partition number entries in the DU handler's translation table could be expanded to word entries if desired and 32-bit block numbers supported with no particular difficulty. Refer to (DUSPFUN_SEC) for details of the format of the DU handler's translation table.

Partition numbers are assigned with a SET command in the following form: (SET DUn PART=x)

For example, you might issue the SET command (SET DU3 PART=1)

This command could be combined with unit and port assignments as well: (SET DU3 UNIT=2, PORT=0, PART=1)

The mnemonic DU3 will then refer to the MSCP disk with unit plug 2 interfaced through port 0, beginning at block 65,536 of the disk (partition 1).

An example using several disks may help to clarify these concepts. Consider the example of a system with two UNIBUS Disk Adaptor (UDA) controllers interfaced to six disks, shown in (PSD2DH_FIG).

(Two-Port DU Handler\PSD2DH_FIG) (POSTSCRIPT\S559c2PSD2DH_FIG.EPS\15)

The user of the system illustrated issues the following SET commands: (SET DU0 UNIT=0,PORT=0,PART=0) (SET DU1 UNIT=1,PORT=0,PART=0) (SET DU2 UNIT=2,PORT=0,PART=0) (SET DU3 UNIT=2,PORT=0,PART=1) (SET DU4 UNIT=3,PORT=0,PART=0) (SET DU5 UNIT=3,PORT=0,PART=1) (SET DU6 UNIT=20,PORT=1,PART=0) (SET DU7 UNIT=21,PORT=1,PART=0)

These commands assign DU0 to the first (removable) disk of the RC25 with MSCP unit number 0, and DU1 to the fixed disk of the RC25, identified as MSCP unit number 1. The disk unit with MSCP unit number 2 is an RA80, which has more than 65,535 blocks. Therefore, the next commands assign DU2 and DU3 to partition 0 and partition 1 of this disk, respectively. DU4 and DU5 are assigned in similar fashion to partitions 0 and 1 of the RA80 with MSCP unit number 3. Another RC25, interfaced to the second port of the UDA controller, is identified by MSCP units 20 and 21. The last two SET commands assign DU6 and DU7 to the two disks of this RC25 disk system. See (PSD_MSCP_TRANS_TAB) for information on setting up the default settings. (Creating a Second DU Handler\psd_du_second_sec)

You can create a second DU handler under all monitors. The procedure is different for unmapped or mapped monitors. (Under Unmapped Monitors)

You cannot run multiple DU handlers through the same MSCP controller; each handler must have a separate controller. Copy the handler to another file name and then modify the new file. Use the handler SET commands to change the vector and CSR of the copy to the values for the second port. For example, you could copy DU.SYS to DA.SYS and use the following SET commands to change the CSR and vector of the DA file: (SET DA VEC=nnnnnn) (SET DA CSR=mmmmmm)

The variables (nnnnnn) and (mmmmmm) are the vector and CSR addresses of the second port. (Under Mapped Monitors)

You cannot run multiple DU handlers through the same MSCP controller; each handler must have a separate controller. You can use the following procedure to create a second DU handler that can be used together with the distributed DU handler under all mapped monitors: (numbered) If you intend to perform a system generation to build a DU handler with support for extended device units or for any other reason, you must do that before creating a second DU handler. You must also preserve the system generation work files. The second DU handler must be assigned a name that does not conflict with any distributed handler. If the second DU handler will be assembled for extended device-unit support, the first letter of the second DU handler cannot be D or L. For the purpose of this procedure, the second DU handler is named BU. Therefore, copy the DU source file to BU: (.)(COPY DU.MAC BU.MAC (RET)) Unprotect BU.MAC and open it with the editor. Perform a search operation for the symbol DU$NAM and on the other side of the equal sign, change the string (<)^RDU > to (<)^RBU >, so that the entire line of code resembles the following: .IIF NDF DU$NAM, DU$NAM = <^RBU > Exit from the editor. If you used the system generation procedure to build the DU handler, use the following procedure to assemble and link BU.MAC. If you did not build the DU handler and are using the distributed DU, proceed to step 7. (alphabetic) Copy the device-build (.DEV) command file that was created during the system generation to a file named BU.DEV. Open the file BU.DEV on the editor. Perform a search operation for the string (+DU). The search places the cursor near the end of the first of three command lines that pertain to DU. The three command lines begin with MACRO, LINK, and SETOVR.

By placing an exclamation mark (!) character at the beginning of each line, comment out all command lines except the initial commands that assign device logical names and the three command lines that apply to DU. On the command lines that assemble and link DU, change all references from DU to BU, by replacing the (D) with (B). Exit from the editor. Issue the following command to run BU.DEV as a command file: (.)($@BU.DEV (RET))

BU.DEV builds the file BUX.SYG. When BU.DEV has completed, copy the file BUX.SYG to BUX.SYS. Determine the current CSR and vector addresses for DU, using the following command: (.)(SHOW DEV:DU (RET))

The MSCP port characteristics, such as CSR and vector addresses, for DU and BU cannot overlap. Specify addresses for BU that do not conflict with DU by using appropriate SET commands. If you did not build DU by using the system generation process, issue the following commands to assemble and link BU. In the commands, (ddn) represents that device on which the distributed system conditional file (such as XM.MAC), the created file, BU.MAC, and the system library SYSTEM.MLB reside: (.)(ASSIGN ddn: SRC (RET)) (.)(MACRO/OBJ:BUX ddn:(XM+BU) (RET)) (.)(LINK/NOBITMAP/EXE:BUX.SYS/BOUNDARY:512. DK:BUX (RET)) (Boundary?)( SETOVR (RET)) Determine the current CSR and vector addresses for DU, using the following command: (.)(SHOW DEV:DU (RET))

Specify addresses for BU that do not conflict with DU by using appropriate SET commands. (Multiport Booting\psd_du_multiboot_sec)

During system generation, you can select an option for the DU handler that will let you boot RT--11 from any DU port. If you do not specify DU multiport booting during SYSGEN, you can boot RT--11 from DU port 0 only. Use the following procedure to enable multiport DU booting: (numbered) Use the SET DUn commands to map the particular DU device to the MSCP unit, port, and partition numbers. For example: (.)(SET DU3 UNIT=0, PORT=1 (RET)) (.)(SET DU4 UNIT=1, PORT=1 (RET)) (.)(SET DU5 UNIT=2, PORT=1 (RET))

For the SET commands to take effect, you must UNLOAD and then LOAD the handler if it is a data device or reboot it if it is a system device. Copy the resulting DU handler to the port on the DU devices you want to be able to boot. For example: (.)(COPY DUX.SYS DU3: (RET)) To hard-boot the DU unit on a new port, use the COPY/BOOT command to copy the bootstrap to the volume on the desired port. The DU unit on that port will also support the soft-boot BOOT DUn: command. (DW (CTI Bus-based Disk Handler)\psd_dw_sec)

This section provides specific programming information for the hard disks on CTI Bus-based computers. (Support for Special Functions)

The DW handler supports the following special functions:

(3\6\8) (Code\Name\Action) (377\SF.ARD\Read) (376\SF.AWR\Write) (373\SF.SIZ\Return device size)

The special function (.SPFUN) request has the following general form, with the (area) and (chan) parameters and the optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book) and the other parameter arguments as described below: Macro Call: .SPFUN area,chan,func,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((func)\is the special function code or the name if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\For SF.ARD and SF.AWR, is the address of a 256(10)-word buffer.

For SF.SIZ, is the address of a one-word buffer in which the size of the volume is returned.) ((wcnt)\For SF.ARD and SF.AWR, is the track to read or write.) ((blk)\For SF.ARD and SF.AWR, is the logical block (rather than physical block) to be read or written. Because the physical block number for DW is one less than the logical block number, address physical block 0 as logical block --1.

For SF.SIZ, should be set to 0.) (DX and DY (Diskette Handlers)\psd_dxdy_sec)

This section provides specific programming information for RX01 and RX02 diskettes.

As distributed, DX and DY support one controller that supports two drives. Each DX and DY handler can support two controllers (and therefore four drives). For example, if the RX01 handler is created through system generation to support two controllers, it will support four devices: DX0, DX1, DX2, and DX3. DX0 and DX1 are drives 0 and 1 of the standard diskette at CSR 177170 and vector 264. DX2 and DX3 are drives 0 and 1 of the other controller (standard alternate address CSR 177150 and vector 270). Note that only one I/O process can be active at one time, even though there are two controllers. Overlapped I/O to the handler is not permitted.

Data is stored on DX and DY diskettes in sectors. Double-density diskette sectors are 128 words long. RT--11 normally reads and writes them in groups of two sectors. Single-density diskette sectors are 64 words long. RT--11 reads and writes them in groups of four sectors. However, special function requests for absolute reads and writes can access sectors individually. (Support for Special Functions)

The DX and DY handlers support the following special functions:

(3\6\8) (Code\Name\Action) (377\SF.ARD\Read absolute sector) (376\SF.AWR\Write absolute sector) (375\SF.WDD\Write absolute sector with deleted data mark) (373\SF.SIZ\Return device size, in 256(10)-word blocks (DY only))

A request to write absolute blocks should not write anything in track 0 if you want to use DUP or the COPY/DEVICE command to back up the volume. DUP does not copy data in track 0. Also, be sure you specify a valid buffer address and word count. The monitor checks that the (buf) parameter argument is in the job area, but it does not check the validity of ((buf+(2*wcnt)-1).)

The special function (.SPFUN) request has the following general form, with the (area) and (chan) parameters and the optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book) and the other parameter arguments as described below: Macro Call: .SPFUN area,chan,func,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((func)\is the code for the function to be performed, or the name of the function if the program has been assembled with the distributed module SYSTEM.MLB.) ((buf)\For SF.ARD, SF.AWR, and SF.WDD, is the location of a 129-word buffer (for double-density diskettes) or a 65-word buffer (for single-density diskettes). The first word of the buffer, the flag word, is normally set to 0.

The flag word set to 1 indicates a read on a physical sector containing a deleted data mark. The data area of the buffer extends from the second word to the end of the buffer.

(buf) for SF.SIZ is the location of a one-word buffer in which 494 is returned by single-density diskettes and 988 is returned by double-density diskettes.) ((wcnt)\For SF.ARD, SF.AWR, and SF.WDD, is the absolute track number, 0 through 76, to be read or written.

(wcnt) for SF.SIZ is reserved and should be set to 1) ((blk)\For SF.ARD, SF.AWR, and SF.WDD, is the absolute sector number, 1 through 26, to be read or written.

(blk) for SF.SIZ is reserved and should be set to 0.)

The diskette should be opened with a non-file-structured .LOOKUP. The following example performs a synchronous sector read from track 0, sector 7, into a 65-word area called BUFF. .SPFUN #RDLIST,#SF.ARD,#BUFF,#0,#7,#0 (DZ (Diskette Handler)\psd_dz_sec)

This section provides specific programming information for diskettes on CTI Bus-based computers. (Support for Special Functions)

The DZ handler supports the following special functions:

(3\6\8) (Code\Name\Action) (377\SF.ARD\Read absolute sector) (376\SF.AWR\Write absolute sector)

The special function (.SPFUN) request has the following general form, with the (area) and (chan) parameters and the optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book) and the other parameter arguments as described below: Macro Call: .SPFUN area,chan,func,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((func)\is the code for the function or the name of the function if the program is assembled with the distributed file SYSTEM.MLB.) ((wcnt)\is the track to be written.) ((blk)\is the sector.) ((buf)\is the address of a 256(10)-word buffer.)

The .SPFUN requests do not interleave sectors. RX50 diskettes have 80 tracks, and the .SPFUN requests wrap to track 0 after track 79. (LD (Logical Disk Handler)\psd_ld_sec)

This section provides specific programming information for logical disks.

The Logical Disk handler implements logical disk support. The LD handler accepts I/O requests just like any other disk handler. By means of embedded translation tables, the LD handler determines which physical disk and which starting block offset should be used for each LD I/O request. When the proper physical disk and block number are determined, the LD handler updates the block number and unit number in the I/O queue element so that they correspond to the values for the assigned physical disk. The LD handler then places the queue element on the I/O queue for the physical disk so that the actual I/O can take place.

In addition to operating as outlined above, the LD handler can also be run as a program. When run, the LD handler accepts CSI command lines and switches to initialize, assign, verify, write-enable, or write-lock logical disk units. (Support for Special Functions)

The logical disk handler supports the following special functions:

(3\6\8) (Code\Name\Action) (372\SF.TAB\Access the translation tables) (373\SF.SIZ\Return unit size. The parameter arguments for SF.SIZ for LD are the same as for DM. See (psd_dm_sec) for information) (LD Translation Tables (SF.TAB), Code 372\psd_ld_sftab_sec)

Special function SF.TAB (code 372) interacts with the translation tables from an address contained in the (buf) parameter argument of the SF.TAB call. You can read the contents of the translation tables to the buffer or write the contents of the buffer to the tables. Whether the SF.TAB request is a read or write operation is determined by the (wcnt) parameter argument. This procedure is explained in this section.

For RT--11 V5.4, changes were made to the structure of the LD translation tables. All programs you write to access the information contained in those tables should reflect the changes. All programs you have written to access LD translation tables should be changed to reflect the changes.

The tables start at a header; previously they started at a label. Following the 2-word header are four LD translation tables. That is unchanged. However, the names of offsets you use to reference the tables have changed. Some table contents have also changed.

Further, you can now build support for up to 64 logical disk units, which affects how you use the tables. (Size of the Translation Tables)

The size of the LD translation tables in the LD handler is related to the number of logical disk units supported by LD. Beginning with Version 5.5, you can use the system generation procedure (SYSGEN) to build an LD handler that supports extended device units. By default, SYSGEN builds support for 16(10) logical disk units when you request extended device-unit support. You can request up to 64(10) units. Of those 64 units, 32 can be mounted and 32 are reserved to Digital. (Structure of the Translation Tables)

The LD translation tables consist of a 2-word header followed by four LD translation tables. The LD translation tables start at header LD.ID. Header LD.ID is a 1-word table identifier and contains the Radix-50 value for the characters LD. Header LD.ID is followed by LD.NUM, a 1-byte count of the number of entries in the table. As LD is distributed, the value in LD.NUM is 10(8), indicating eight table entries. If LD is built for extended device-unit support, the value in LD.NUM can contain a value up to 100(8), indicating support for up to 64 logical disk units. LD.NUM is the low-order byte of the word LD.ID+2. The high-order byte of LD.ID+2 is reserved.

The four LD translation table offset names, location, and contents are: (LD.FLG (LD.ID+4))

The table beginning at offset LD.FLG is the table previously at the label HANDLR. LD.FLG contains one word for each LD unit number. The count of LD unit numbers is stored in LD.NUM. The bits in each word of LD.FLG have the following meaning:

(3\4\8) (Bits\Name\Meaning) (0--5\LD.NDX\An index to the handler tables in RMON for the physical device corresponding to the LD unit number.) (6\LD.UNX\A flag that signals the index entry (bits 0--5) may be inaccurate and should be updated. LD sets LD.UNX for all units if, upon entry, the LDREL$ bit in RMON fixed offset CONFG2 is set.) (7\LD.UOF\A flag that signals the entry in the LD.OFS table for that LD unit may be inaccurate. LD.UOF is set whenever a volume is squeezed. LD checks LD.UOF each time it uses an LD unit; if set, LD verifies that unit's LD.OFS table entry before proceeding.) (8--13\LD.UNT\Contain the unit number of the physical disk assigned to the logical disk unit.) (14\LD.RDO\Is the write-lock bit. If LD.RDO set, the LD unit is read only.) (15\LD.ACT\Is the allocation bit. If LD.ACT set, the LD unit is assigned. If LD.ACT clear, the LD unit is not assigned.) (LD.OFS (LD.FLG+(<)2*Contents of LD.NUM>))

The second translation table starts at the offset LD.OFS and contains one word for each LD unit number. The count of LD unit numbers is stored in LD.NUM. Each word in LD.OFS contains the offset in blocks from the beginning of the assigned physical disk to the start of the area on that physical disk assigned to that LD unit number. (LD.SIZ (LD.FLG+(<)4*Contents of LD.NUM>))

The third translation table starts at offset LD.SIZ and contains one word for each LD unit number. The count of LD unit numbers is stored in LD.NUM. Each word in LD.SIZ contains the size in blocks of the area on the physical disk assigned to that logical disk unit. (LD.NAM (LD.FLG+(<)6*Contents of LD.NUM>))

The fourth translation table starts at the label LD.NAM and contains four words for each LD unit number. The count of LD unit numbers is stored in LD.NUM.

The first word of each 4-word entry contains the Radix-50 2-character name of the physical disk that is assigned to that logical disk unit. That Radix-50 word must be the physical (not logical) device name without any unit number. DL is a valid physical device name; DK and DL1 are not valid.

The second, third, and fourth words of each entry contain the Radix-50 file name and file type assigned as the logical disk. (Accessing the Translation Tables)

Before Version 5.5, the translation table access special function code SF.TAB (372) supported only eight units. The (wcnt) parameter for SF.TAB accepted two arguments, +1 to indicate a read of the table and -1 to indicate a write to the table. The size of each LD translation table was fixed at eight entries. Beginning with Version 5.5, if the LD handler on your system continues to support only eight logical disk units, you continue to read and write to the translation tables as before.

However, if the LD handler on your system supports more than eight units, the SF.TAB special function provides additional values for the (wcnt) parameter to support the extended device units. For LD handlers that implement the extended device-unit feature, you indicate both a read or write operation and the size of the table you are reading and writing by specifying a positive or negative numeric argument for the (wcnt) parameter. A positive numeric argument indicates a read operation of the specified number of words from the LD translation tables to the buffer. A negative number indicates a write operation of the specified number of words from the buffer to the translation tables. For example, a (wcnt) parameter argument of +16 reads 16 words, and an argument of --16 writes 16 words.

You can use the following procedure to read the translation tables from an LD handler that supports extended device units into a buffer and write the translation table from a buffer to LD. The procedure assumes you do not currently know (or want to verify) the number of entries in the table. (numbered) Entries are reserved in each translation table for the total number of logical disk units supported by the handler. The offset at which each table starts is determined by the number of supported units. Therefore, to determine the starting offset for each table within the four translation tables, you first determine how many logical disk units are supported by the handler. You can determine the number of entries by doing a read SF.TAB to return the table entry LD.NUM. LD.NUM is the low byte of the second word in the table and contains the number of table entries. Therefore, for the (wcnt) parameter, supply the argument +2, and for the (buf) parameter, point to a 2-word buffer. Once you have determined the number of supported logical disk units, you can use that value to perform read/write operations for the tables. You can read the LD translation tables into memory by performing a single SF.TAB read operation. The number of words in the LD translation tables is two for the header (LD.ID plus LD.NUM), the value in LD.NUM for each of the first three tables and four times the value in LD.NUM for the fourth table:

2+7*(LD.NUM)

For example, if LD.NUM indicated 100(8) entries, the value to specify for (wcnt) to read the entire table would be +450(10). The (buf) parameter would point to a buffer of the same size.

You could write the contents of the buffer to the LD handler by specifying the value --450(10) for the (wcnt) parameter. (Other Bits Used by the LD Handler)

The LD handler uses bit 4 (LDREL$) in CONFG2, monitor fixed offset 370. This bit is set whenever a handler is unloaded or released. The LD handler checks this bit to see if a handler assigned to an LD unit has been removed from memory since it was last used. If the bit is set, the LD handler sets bit 7 in all the entries in the HANDLR table, then clears the LDREL$ bit. When the LD handler begins to process an I/O request, the LD handler checks bit 7 for the requested LD unit. If bit 7 is set, the LD handler verifies that the handler for the disk assigned to that LD unit number is in memory, then clears the bit. The LD handler checks and clears bit 7 for a unit only when an I/O request is sent to that unit. Checking only when absolutely necessary ensures that the LD handler will not waste time verifying units that may never be used by a particular user program. (MM, MS, and MT (Magtape Handlers)\psd_mmmsmt_sec)

This section provides specific programming information for reel-type magnetic tape devices.

Magnetic tape (magtape) has a sequential (not random-access) file structure. There is no directory at the beginning of each tape. RT--11 magtape handlers support a file structure that is compatible with ANSI tape labels and format, giving you full access to the tape controller without concern for the specifics of the device. See (VFF_BOOK) for more information on the format of magtapes and tape labels. Support for RT--11 magtape file structure is compatible only among systems that support DEC and ANSI standards for tape labels and file formats. DOS-formatted tapes cannot be read or written.

See the (sug_book) for SET command conditions for each of the magtape handlers. Those conditions can set the number of tracks, the density, the parity of the tape drive, and the CSR and vector addresses.

See also the (mas_book) under (Magtape) and the individual magtape handlers for more information. (File Structure Module (FSM))

The File Structure Module (FSM) creates the file structure on magtapes written by the distributed magtape handlers. The FSM is a discrete module (FSM.MAC) that is assembled with the magtape hardware handlers when handlers are built; it is included in the distributed magtape handlers. The FSM uses a protocol that is understood by RT--11 utilities and described in the (VFF_BOOK).

When you issue a call for a file-oriented operation, the monitor (and perhaps the USR) builds a queue element and passes it to the FSM. The FSM processes the operation by manipulating the magtape drive.

Through the system generation procedure, you can build each of the magtape handlers without the FSM; a hardware-only version of each handler. A hardware magtape handler is smaller and requires less memory, but does not contain any routines that define a file structure. It does contain routines that manipulate the magtape drive. See (maghard_sec).

Further, unless you write your own file structure module that duplicates the functionality of the FSM, RT--11 utilities do not understand whatever protocol you use to manage the magtape.

Therefore, Digital recommends that you use the distributed magtape handlers (unless special circumstances indicate that a handler without the FSM is appropriate), since only the handlers that contain the FSM can communicate with the RT--11 system utility programs.

This section uses some magtape-specific abbreviations:

(2\6) ((BOT\bold)\beginning-of-tape) ((EOF\bold)\end-of-file) ((EOT\bold)\physical end-of-tape) ((LEOT\bold)\logical end-of-tape

LEOT consists of an EOF1 label (which includes one tape mark) followed by two tape marks.) (Compatibility of Magtape Operations with the FSM)

As briefly explained above, the distributed magtape handlers contain the basic magtape hardware handler, which is assembled with a file structure module (FSM). As shown in the following tables, some magtape operations are intercepted by the FSM and some operations bypass the FSM and are processed directly by the basic magtape hardware handler.

Although the distributed magtape handlers can process all the magtape operations described in this section, performing hardware-oriented operations that are incompatible with the FSM disrupts the magtape's file structure and can make the magtape unsuitable for further file-oriented operations. In other words, to preserve the file-oriented nature of a magtape volume, perform only file-oriented operations on that volume or other operations that are compatible with the FSM.

The operations you can perform on a magtape can be divided into three classes: (unnumbered) Operations that use the FSM. These are file-structured operations that require the distributed handlers. Operations that bypass the FSM but are compatible with the FSM. These are non-file-structured operations that the FSM understands. Operations that bypass the FSM and produce a magtape that is incompatible with the FSM. You can perform these operations with the distributed handlers but the resulting magtape is not compatible with the FSM or any RT--11 utilities.

The following tables list magtape operations and their compatibility with the FSM. The tables list where more information can be found for each operation.

(Magtape Operations That Use the FSM\fsmfunc_tab) (3\16\8) (Operation\Section\Description) (FSM Search bySequenceNumber\(fsmfunc_seq_sec\value) \Search for a file on a magtape based on file's sequence number.) (FSM Search byFile Name\(fsmfunc_fil_sec\value) \Search for a file on a magtape based on the file name.) (.ENTER\( mag_enter_sec\value) \Open a file.) (.LOOKUP\ (mag_lookup_sec\value)\Find a file.) (.READx\(mag_read_sec\value)\Read from a file.) (.WRITx\( mag_write_sec\value)\Write to a file.) (.CLOSE \(mag_close_sec\value)\Close a file.) (.PURGE\(mag_purge_sec\value)\Delete entry and close channel.)
(Magtape Operations That Are Compatible with the FSM\OKfsmfunc_tab) (4\14\6\6) (Operation\Code\Section\Description) (NFS .LOOKUP\N/A\(mag_nfslookup_sec\value)\Open a channel to a device (non-file-structured .LOOKUP operation). Required before any special function.) (SF.USR\354\ (mag_sfusr_sec\value)\After NFS .LOOKUP, can be used in the following ways:

Perform asynchronous directory operations that do not require the USR.

Emulate a file-structured .LOOKUP or .ENTER to gain access to a file for further special function operations. ) (SF.MRD\370\(mag_sfmrd_sec\value)\After initial NFS .LOOKUP and SF.USR, perform read operations of variable length blocks.) (SF.MWR\371\(mag_sfmwr_sec\value)\After initial NFS .LOOKUP and SF.USR, perform write operations of variable length blocks.) (SF.MST\367\(mag_sfmst_sec\value) \After initial NFS .LOOKUP, stream TS05 (MS only).) (.CLOSE\N/A\(mag_nfsclose_sec\value)\Close channel and make device available.)

(Magtape Operations That Are Not Compatible with the FSM\NOOKFSMFUNC_TAB) (4\14\6\6) (Operation\Code\Section\Description) (SF.MOR\372\(mag_sfmor_sec\value)\Rewind and place drive off line.) (SF.MRE\373\( mag_sfmre_sec\value) \Rewind.) (SF.MWE\374\(mag_sfmwe_sec\value)\Write with extended gap.) (SF.MBS\375\(mag_sfmbs_sec\value)\ Backspace.) (SF.MFS\376\(mag_sfmfs_sec\value)\ Forward space.) (SF.MTM\377\(mag_sfmtm_sec\value)\ Write tapemark.) (NFS .READx\N/A\ \Obsolete. Non-file-structured read operation (use SF.MRD).) (NFS .WRITx\N/A\ \Obsolete. Non-file-structured write operation (use SF.MWR).) (Spacing Error Recovery)

Any errors detected during spacing operations abort the recovery attempt, and generate a hard (position) error.

Magtape handlers both with or without the FSM perform the following operations if a read parity error is detected. (NUMBERED) Backspaces over the block and rereads. When unsuccessful, the procedure is repeated until five read commands have failed. Backspaces five blocks, spaces forward four blocks, then reads the record. Repeats steps 1 and 2 eight times or until the block is read successfully.

The handler performs the following operations upon detection of a read after write (RAW) parity error. (NUMBERED) Backspaces over one block. Erases 3 inches of tape and rewrites the block. In no case is an attempt made to rewrite the block over the bad spot, since, even if the attempt succeeds, the block could be unreliable and cause problems later. Repeats steps 1 and 2 if the read after write still fails. When 25 feet of erased tape have been written, a hard error is given. (File Structure Magtape Handler)

The file structure magtape handlers combine the hardware handler, described in (HWMTHAND_SEC), with a file structure module. The file structure module, which is designed to operate with any magtape handler, permits the handler to accept file structure requests. The file structure magtape handler is a superset of the hardware handler. You can issue hardware commands to the file structure handler. The file structure magtape handlers are named MM.SYS, MS.SYS, and MT.SYS. The distributed versions of these handlers support tape drives 0 and 1. You can add support for more drives at system generation time.

A tape containing two files has the following format:

VOL1 HDR1 * data * EOF1 * HDR1 * data * EOF1 * * *

(VOL1\bold), (HDR1\bold), and (EOF1\bold) are ANSI tape labels. The asterisk (*) represents a tape mark. See (VFF_BOOK) for more information on magtape formats. (Magtape Operations That Use the FSM\FSMFUNC_SEC)

The following magtape operations, listed in (FSMFUNC_TAB), use the FSM. The distributed magtape handlers support these operations. (FSM Searching by Sequence Number\fsmfunc_seq_sec)

The FSM can search for files on tape based on their sequence number. It uses the relationship between the current tape position and the desired new position to find the desired file according to the following algorithm: (NUMBERED) When the file sequence number for the desired file is greater than the number of the current position, the handler moves the tape forward.

For example, if the tape is currently positioned at file sequence number 1, and the desired file is number 2, the tape moves forward from its position at the tape mark after file number 1 to the tape mark at the start of file number 2. When the file sequence number for the desired file is less than the number of the current position, the handler optimizes its seek time by moving the tape backward or forward, depending on the location of the file. In practice, the handler almost always rewinds the tape and then searches forward.

For example, assume the number of the current position is 2 and the desired file has sequence number 1. The tape leaves its position at the tape mark for file 2 and rewinds to the beginning of the volume. It then moves forward to the tape mark at the start of file 1. As another example, assume the current position is 9 and the desired file has sequence number 6. The tape rewinds to the beginning of the volume and the search proceeds in the forward direction.

If you release the handler through the UNLOAD command or the .RELEASE programmed request, the file position is lost. In this situation the tape moves backward until the handler locates BOT or a label from which it can determine the tape's position. (FSM Searching by File Name\fsmfunc_fil_sec)

The FSM can search for files on tape based on their file names. The routine to match file names uses an algorithm that enables the handler to recognize file names and file types used by other Digital operating systems. The FSM uses the file identifier field, translating the contents to a recognizable file name. This file name is matched to a file name stored in Radix-50 format. The format is as follows: filnam.typ

(2\10) ((filnam)\is a valid RT--11 file name left-justified in a six-character field. Unused character positions are not padded.) ((typ)\is a file type left-justified in a 3-character field.)

The algorithm the handler uses is backward compatible across all versions of the operating system. RT--11 tapes can be detected by the presence of (RT11) in character positions 64 through 67 of the HDR1 label. The algorithm is as follows: (NUMBERED) Clear the character count (CC). Check the next character in the file name. If it is a dot, do the following: (ALPHABETIC) Mark a dot found. When CC (<) 6, insert spaces and increment the CC until it equals 6. When CC (>) 6, delete characters and decrement the CC until it equals 6. If CC = 6 and if (RT11) is found in character positions 64 through 67 of the system code field, insert a dot in the translated name, mark the dot found, and increment CC. Move the character into the translated file name and point to the next character. Increment the CC. When CC (<) 10(10) go back to step 2. Check the dot-found indicator. If no dot was found, back up four characters and insert .DAT for the file type. Perform a character-by-character comparison between the desired file name and the file name that was just translated from the file identifier field in the HDR1 label. When they match exactly, consider the file found. (.ENTER Programmed Request\mag_enter_sec)

The .ENTER programmed request opens a file on a magtape by writing a HDR1 label and tape mark on the tape and leaving the tape positioned after the tape mark. The request initializes some internal tables and makes entries for the last block written and current block number. (The last block or file on tape is always the most recent one written.) The information for the internal tables and entries for the last written block is correct unless an .SPFUN request is performed on that channel. Normally, files opened with an .ENTER request do not have special functions performed on them, except when a nonstandard block size is to be written (one that is not 256 words long). To write a nonstandard block, open the file with an .ENTER request; then issue an .SPFUN write request. Close the file with a .CLOSE request after the operation is complete. If a file search is to be performed, open the tape non-file-structured with a .LOOKUP request. (MAGTAPEENTER_TAB) shows the sequence number values for .ENTER requests.

The .ENTER programmed request has the following format, with the (area, chan,) and (dblk) parameters as described in the (sml_book). The (seqnum) parameter is described below. Macro Call: .ENTER area,chan,dblk,,seqnum

(Sequence Number Values for .ENTER Requests\MAGTAPEENTER_TAB) (#) (4\8\8\30) (SeqnumArgument\File Name\Action Taken\Tape Position) ((>)0 \not null \Position at file sequence number and perform a .ENTER.\Found: ready to write. Not found: at LEOT; LEOT is an EOF1 label followed by two tape marks. LEOT is different from the physical end-of-tape.) (#0 \not null \Rewind tape and search tape for file name. If found then give error. If not found then enter the file. \Found: before file. Not found: ready to write.) (--1 \not null \Position tape at LEOT and enter file. \ Ready to write.) (--2 \not null \Rewind tape and search tape for file name. Enter file at found file or LEOT, whichever comes first. \Ready to write.) (#0 \null \Perform a non-file-structured .LOOKUP. \Tape is rewound.)

The .ENTER request returns the errors shown in (ENTERERR_TAB).

(.ENTER Errors\ENTERERR_TAB) (2\6) (Byte 52 Code \Meaning) (0 \Channel in use.) (1 \Device full. EOT was detected while writing HDR1. Tape is positioned after the first tape mark following the last EOF1 label on the tape. No such job exists (system job support only).) (2 \Device already in use. Magtape already has a file open on that unit.) (3 \File exists, cannot be deleted.) (4 \File sequence number not found. Tape is positioned the same as for device full.) (5 \Invalid argument error. A (seqnum) argument in the range --3 through --32767 was detected. A null file name was passed to .ENTER.)

The .ENTER request issues a directory hard error if errors occur while entering the file. (File-Structured .LOOKUP Programmed Request\mag_lookup_sec)

A file-structured .LOOKUP request finds a file by searching for a specific HDR1 label. Upon finding and reading the HDR1 label, the tape is positioned before the first data block of the file.

The .LOOKUP request has the following format, with the (area, chan,) and (dblk) parameters as described in the (sml_book). The (seqnum) parameter argument values are shown in (LOOKUPVAL_TAB): Macro Call: .LOOKUP area,chan,dblk,seqnum

(Sequence Number Values for File-Structured .LOOKUP Requests \LOOKUPVAL_TAB) (#) (4\8\8\30) (SeqnumArgument \File Name \Action Taken \Tape Position) ((>)0 \null \Perform a file-structured .LOOKUP on the file sequence number. \Found: ready to read first data block. Not found: at LEOT.) (#0 \not null \Rewind to the beginning of tape, then use file name to perform a file-structured .LOOKUP. \Found: ready to read first data block. Not found: at LEOT.) (--1 \not null \Do not rewind; perform a file-structured .LOOKUP for a file name. \Found: ready to read first data block from the current position. Not found: at LEOT.) ((>)0 \not null \Position at file sequence number and perform a file-structured .LOOKUP. If file name does not match file name given, return error. \Found: ready to read first data block. Not found: at the beginning of the file specified by the sequence number.)

The file-structured .LOOKUP returns the errors shown in (LOOKUPERR_TAB).

(.LOOKUP Errors\LOOKUPERR_TAB) (2\6) (Byte 52 Code \Meaning) (0 \Channel in use.) (1 \File not found. Tape is positioned after the first tape mark following the last EOF1 on the tape.) (2 \Device in use. Magtape already has a file open.) (5 \Invalid argument error. A (seqnum) argument in the range --2 through --32767 was detected. A .LOOKUP request must have a positive sequence number.) (6 \ Invalid unit number.)

The .LOOKUP request issues a directory hard error if errors occur while entering the file. (.READx Programmed Requests\mag_read_sec)

In this section, the term .READx refers to the .READ, .READC, and .READW group of programmed requests. Further, .READx requests are described for files that have been opened with the .ENTER and file-structured .LOOKUP requests.

The .READx requests read data from magtape in blocks of 512 bytes each. If a request is issued for fewer than 512 bytes, the handler reads the correct number of bytes. If the request is for more than 512 bytes, the handler performs the request with multiple 512-byte transfers (the last request may be for fewer than 512 bytes).

The .READx requests are valid in a file opened with a .LOOKUP request. They are also valid in a file opened with an .ENTER request, provided the block number requested does not exceed the last block written. (Exceeding the last block written returns code 0.)

If a tape mark is read, the routine repositions the tape so that another request causes the tape mark to be read again. When a .CLOSE is issued to a file opened by an .ENTER request, the tape position is left unchanged. Because magtape is sequentially accessed, a reposition in a file (a backup) without subsequently positioning to the end of the file (before a .CLOSE) causes data loss.

The guidelines for block numbers are as follows: (NUMBERED) When a .LOOKUP is used (to search the file) with this request, the handler tries to position the tape at the indicated block number. When it cannot, a 0 (EOF code) is issued, and the tape is positioned after the last block on the file. On an entered file, .READx checks to determine if the block requested is past the last block in the file. If it is, the tape is not moved and the 0 error code is issued.

The .READx request has the following format, with the (area, chan, buf, wcnt, blk) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .READx area,chan,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(READXERR_TAB) shows the errors the .READx requests return.

(.READx Errors\READXERR_TAB) (2\6) (Byte 52 Code \Meaning) (0 \Attempt to read past a tape mark; also generated by block that is too large.) (1 \Hard error occurred on channel.) (2 \Channel not open.) (.WRITx Programmed Requests\mag_write_sec)

In this section, the term .WRITx refers to the .WRITE, .WRITC, and .WRITW group of programmed requests. Further, .WRITx requests are described for files that have been opened with the .ENTER and file-structured .LOOKUP requests.

The .WRITx requests write data to magtape in blocks of 512 bytes. If a request is issued for fewer than 512 bytes, the handler forces the writing of 512 bytes from the buffer address. If a request is issued for more than 512 bytes, the handler performs multiple 512-byte transfers.

The .WRITx requests are valid in a file opened with an .ENTER. Once a file is opened, .WRITx determines if the requested block is past the last block in the file. If it is, the tape is not moved and the 0 error code is issued.

The .WRITx request has the following format, with the (area, chan, buf, wcnt, blk) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .WRITx area,chan,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(WRITXERR_TAB) shows the errors the .WRITx requests return.

(.WRITx Errors\WRITXERR_TAB) (2\6) (Byte 52 Code \Meaning) (0 \End-of-tape. The data for the last write was not written, but the previous block is valid. Also issued if the block number is too large.) (1 \Hard error occurred on channel.) (2 \Channel not open.)

After a write operation, the rest of the tape is undefined (see (LASTMTIO_FIG)).

(Operations Performed After the Last Block Written on Magtape\LASTMTIO_FIG) (postscript\MLO-007358B\24)

In example 1 in (LASTMTIO_FIG), blocks A, B, and C are written on the tape with the head positioned in the gap immediately following block C. Any forward operation of the tape drive except by write commands (that is, write, erase gap and write, or write tape mark) yields undefined results due to hardware restrictions.

In example 2 in (LASTMTIO_FIG), the head is shown positioned at BOT after a rewind operation so that successive read operations can read blocks A, B, and C. The head is left positioned as shown in example 3. Note that this is the same condition as shown in example 1, and all restrictions indicated in example 1 are applicable. (.CLOSZ, .DELETE, .GFxxx, .RENAME, and .SFxxx Programmed Requests)

These requests are invalid operations on magtape, and any attempt to execute them returns an invalid operation code (code 2) in byte 52. (.CLOSE Programmed Request\mag_close_sec)

The action of the .CLOSE request depends on how the file was opened. (UNNUMBERED) When a file is opened with an .ENTER request, the file is closed by writing a tape mark, an EOF1 label, and three more tape marks. In this operation, the tape is left positioned just before the second tape mark at LEOT. Note that the rest of the tape is no longer readable. When a file is opened with a file-structured .LOOKUP, the tape is positioned after the tape mark following the EOF1 label for that file.

The .CLOSE request has the following format, with the (chan) parameter as described in the (sml_book): Macro Call: .CLOSE chan

This request issues a directory hard error if a malfunction is detected. The error can be recovered with the .SERR request. (.PURGE Programmed Request\mag_purge_sec)

The action performed by a .PURGE request is determined by the following: (unnumbered) If the magtape channel has been opened by a .ENTER request, a .PURGE request deletes the current entry by a series of BACKUP and WRITE-TAPE-MARK operations, leaving the magtape positioned just before the second tape mark at LEOT. If the magtape channel has been opened with a file-structured or non-file-structured .LOOKUP, the .PURGE request frees the unit table entry for the handler, closes the channel, and makes the handler available for other operations.

The .PURGE request has the following format, with the (chan) parameter as described in the (sml_book): Macro Call: .PURGE chan (Magtape Operations That Are Compatible with the FSM\OKFSMFUNC_SEC)

The following magtape operations (as listed in (OKFSMFUNC_TAB)), bypass the FSM but are compatible with the FSM. The distributed magtape handlers support these operations and a magtape that is manipulated by these functions is supported by RT--11 utilities. (Non-File-Structured .LOOKUP Programmed Request\mag_nfslookup_sec)

You must issue a non-file-structured .LOOKUP request to open a channel to the device before starting any I/O operations. The non-file-structured .LOOKUP request causes the handler's hardware level to mark the drive busy so that no other channel can be opened to that drive until a .CLOSE is issued.

The .LOOKUP request has the following format, with the (area, chan,) and (dblk) parameters as described in the (sml_book). The values for the (seqnum) parameter argument are described in (nonfillookupval_tab): Macro Call: .LOOKUP area,chan,dblk,seqnum

(Sequence Number Values for Non-File-Structured .LOOKUP Requests\nonfilLOOKUPVAL_TAB) (#) (4\8\8\30) (Seqnum Argument \File Name \Action Taken \Tape Position) (#0 \null \Perform a non-file-structured .LOOKUP. \Rewound.) (--1 \null \Perform a non-file-structured .LOOKUP. \Not moved.)

(NFSLOOKERR_TAB) shows the errors that can be returned by the non-file-structured .LOOKUP request.

(Non-File-Structured .LOOKUP Errors\NFSLOOKERR_TAB) (2\6) (Byte 52 Code\Meaning) (0\Channel in use; channel already open.) (1\File not found; no such job.) (2\Device in use. The drive being accessed is already attached to another channel.) (5\Argument is invalid; for example, magtape file sequence number.) (6\Invalid unit number.) (Asynchronous Directory Operations (SF.USR), Code 354\mag_sfusr_sec)

SF.USR must be preceded by a non-file-structured .LOOKUP and can be used to perform two operations: (unnumbered) SF.USR can perform asynchronous directory operations without the USR, which makes it useful for long tape searches. It is particularly useful in multi-job environments, because the search operation locks the USR during directly issued .ENTER and .LOOKUP requests. SF.USR allows an emulation of the .ENTER and file-structured .LOOKUP requests to be issued after a non-file-structured .LOOKUP assigns a channel to the magtape handler.

The special function SF.USR has the following format, with the (area) and (chan) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.USR,buf,,blk

(2\10) ((SF.USR)\is the code 354 or the name SF.USR if the program has been assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a 7-word block with the following format: (#)
(2\6) (Word \Meaning) (0--2 \Radix--50 representation of the file name.) (#3 \One of the following codes: 3 for .LOOKUP 4 for .ENTER) (#4 \Sequence number value. See the corresponding sections for .LOOKUP or .ENTER for complete information on the interpretation of this value.) (5,6 \Reserved.) ) ((blk)\is the address of a 4-word error and status block used for returning .LOOKUP and .ENTER errors that are normally reported in byte 52. See (mag_except_sec). Only the first word of (blk) is used by this request. The other three words are reserved for future use and must be zero. If the value of (blk) is 0, no error information is returned. (ASYNCDIR_FIG) shows a programming example.)
(Asynchronous Directory Operation Example\ASYNCDIR_FIG) (\MULTIPAGE) .TITLE Asynchronous Directory Operation Example .ENABLE LC ; Print lower case .NLIST BEX ; Don't list text storage .MCALL .LOOKUP, .SPFUN, .CLOSE, .PRINT, .EXIT ; Definitions SF.USR = -20. ; Asynchronous request LOOKUP = 3 ; Lookup code for async request ENTER = 4 ; Enter code for async request CHAN = 0 ; Use channel 0 FNF = 1 ; 1 = File not found error FSN = 0 ; Use 0 as file sequence number ;Example assumes that magtape handler is loaded. START: .LOOKUP #AREA,#CHAN,#NFSBLK,#0 ; Open a channel ; for the next request BCS LOOKER ; Branch if error occurred .SPFUN #AREA,#CHAN,#SF.USR,#COMBLK,#ERRBLK ; Do a lookup BCC FILFND ; Branch if file found CMP #FNF,ERRBLK ; File not found error? BEQ NOTFND ; Branch if yes MOV #ASYERR,R0 ; No, some other error BR CLOSE LOOKER: MOV #LOOERR,R0 ; NFS Lookup error BR CLOSE FILFND: MOV #OK,R0 ; Report success BR CLOSE NOTFND: MOV #FNFERR,R0 ; Report file not found CLOSE: .PRINT ; Print error pointed to ; by R0 .CLOSE #CHAN ; Clean up... .EXIT ; and return to monitor ;Data area AREA: .BLKW 5 ; EMT argument block NFSBLK: .RAD50 /MT / ; Use this to open .WORD 0 ; magtape in non-file- .WORD 0 ; structured mode .WORD 0 COMBLK: .RAD50 /FILNAMTYP/ ; This is the file name ; we're looking for .WORD LOOKUP ; This is the asynch op ; code for lookup .WORD FSN ; This is file sequence ; number for the lookup .WORD 0,0 ; Reserved (must be 0) ERRBLK: .WORD 1 ; Set first word non-0 .WORD 0,0,0 ; so errors return here ;Messages LOOERR: .ASCIZ /Non-file-structured lookup failed/ OK: .ASCIZ /File found, lookup successful/ FNFERR: .ASCIZ /File not found/ ASYERR: .ASCIZ /Error in asynchronous request/ .EVEN .END START (Read Physical Blocks (SF.MRD), Code 370\mag_sfmrd_sec)

After an NFS .LOOKUP request (and optionally after an SF.USR), the SF.MRD request reads blocks of any size.

The special function SF.MRD has the following format, with the (area, chan, buf, wcnt,) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.MRD,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((SF.MRD)\is the code 370 or the name SF.MRD if the program is assembled with the distributed file SYSTEM.MLB.) ((blk)\is the address of a 4-word error and status block used for returning the exception conditions. See (mag_except_sec).)

This request returns the errors shown in (SPF370ERR_TAB). Additional qualifying information for these errors is returned in the first two words of the (blk) parameter argument status block. See (mag_except_sec).

(SF.MRD (Code 370) Errors\SPF370ERR_TAB) (3\10\8) (Byte 52 Code\First Word Code\ Qualifying Information) (EOF (Value = 0)\1 \Tape before EOF only (tape mark detected).) (\2 \Tape before EOT only (no tape mark detected).) (\3 \Tape before EOF and EOT (tape mark detected).) (Hard error (Value = 1)\0\No additional information (consult documentation for your particular tape drive for all possible error conditions).) (\1 \Tape drive not available.) (\2 \The controller lost the tape position.) (\3 \Nonexistent memory accessed.) (\4 \Tape is write locked.) (\5 \The last block read had more information.

The MM handler returns (in the second status word) the number of words not read.) (\6 \A short block was read. The second status word contains the difference between the number of words requested and the number read.) (Write Physical Blocks (SF.MWR), Code 371\mag_sfmwr_sec)

After an NFS .LOOKUP request and optionally after an SF.USR, the SF.MWR request writes blocks of any size.

The special function SF.MWR has the following format, with the (area, chan, buf, wcnt) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.MWR,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((SF.MWR)\is the code 371 or the name SF.MWR if the program is assembled with the distributed file SYSTEM.MLB.) ((blk)\is the address of a 4-word error and status block used for returning the exception conditions. See (mag_except_sec).)

This request returns the errors shown in (SPF371ERR_TAB).

(SF.MWR (Code 371) Errors\SPF371ERR_TAB) (3\10\8) (Byte 52 Code\First Word Code\Qualifying Information) (EOF (Value = 0)\1\Tape before EOF only (tape mark detected).) (\2 \Tape before EOT only (no tape mark detected).) (\3 \Tape before EOF and EOT (tape mark detected).) (Hard error (Value = 1)\0\No additional information (consult documentation for your particular tape drive for all possible error conditions.)) (\1\Tape drive not available.) (\2\The controller lost the tape position.) (\3\Nonexistent memory accessed.) (\4\Tape is write locked.) The TJU16 tape drive can return a hard error if a write request with a word count less than 7 is attempted. (Exception (Error and Status) Reporting\mag_except_sec)

Special function requests report end-of-file and hard error conditions through byte 52 in the system communication area. You can also receive additional information about those two error conditions. You can specify an address in the special function's (blk) parameter that points to a 4-word error and status block which returns that information.

Specify #0 for (blk) if you do not want exception reporting.

Although all four words in the error and status block must be initialized to 0 before the first special function is called, only words 1 and 2 of the status block return information. Words 3 and 4 are reserved and not written and therefore need only be initialized once (remain as set to 0).

The meaning of the error and status block contents is tied to the contents of byte 52 in the system communications area. The program should therefore check the state of the carry bit and byte 52 before attaching importance to the contents of the error and status block. (End-of-File Condition Exception Reporting)

Besides an actual EOF, the magtape handler's hardware level returns an end-of-file condition when the handler encounters an EOT, tape mark, or BOT. An end-of-file condition produces the following: (unnumbered) Sets the carry bit and byte 52 is zero. The first word of the error and status block is shown in (EOFQUALINFO_TAB). The second word contains the number of blocks not spaced when a tape mark is detected during a spacing operation.

(End-of-File Qualifying Information\EOFQUALINFO_TAB) (2\6) (FirstWord\Meaning) (1 \Tape before EOF only (tape mark detected).) (2 \Tape before EOT only (no tape mark detected).) (3 \Tape before EOT and EOF (tape mark detected).) (4 \Tape before BOT (no tape mark detected).) (Hard Error Condition Exception Reporting)

A hard error condition: (unnumbered) Sets the carry bit and byte 52 is 1. Returns in the first word the qualifying information shown in (HERRQUAL_TAB).

(Hard Error Qualifying Information\HERRQUAL_TAB) (2\6) (FirstWord\Meaning) (0 \No additional information (includes parity error and all others not listed below. Consult documentation for your particular tape drive for all possible error conditions.)) (1 \Tape drive not available.) (2 \The controller lost the tape position. When this error occurs, rewind or backspace the tape to a known position.) (3 \Nonexistent memory was accessed.) (4 \Tape is write locked.) (5 \The last block read had more information. The MM handler returns (in the second status word) the number of words not read.) (6 \A short block was read. The second status word contains the difference between the number of words requested and the number of words read.) (.CLOSE Programmed Request\mag_nfsclose_sec)

The magtape handler at the hardware level accepts the .CLOSE request and causes the handler to mark the drive as available; the channel becomes free.

The .CLOSE request has the following format, with the (chan) parameter as described in the (sml_book): Macro Call: .CLOSE chan (Enabling 100ips Streaming on a TS05/TSU05/TSV05 (SF.MST), Code 367\mag_sfmst_sec)

The SF.MST special function places the TS05 drive in 100ips streaming mode.

The special function SF.MST has the following format, with the (area) and (chan) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.MST,buf,,blk

(2\10) ((SF.MST)\is the code 367 or the name SF.MST if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is a word which enables or disables streaming.

If (buf) contains a 1, streaming is enabled.

If (buf) contains a 0, streaming is disabled. ) ((blk)\is a pointer to a 4-word error block. (See (mag_except_sec).))

Streaming is automatically turned off when a .CLOSE is issued on a channel open on magtape, when an abort occurs, or if there is a magtape I/O error.

This special function is valid only for a TS05 using the MS handler. An SF.MST call is ignored if it is used with any other magtape handler or if it is used with the MS handler running a TS11 magtape.

If you want to run a TS05 in streaming mode, you must also use double-buffered I/O so that there is always a request pending in the magtape I/O queue. If there is not, there will be too much delay between I/O requests and the streaming will not work properly. (Magtape Operations That Are Not Compatible with the FSM\NOOKFSMFUNC_SEC)

The magtape operations listed in (NOOKFSMFUNC_TAB) and described below bypass the FSM and are incompatible with the file structure produced by the FSM. The operations are direct hardware calls to the magtape handler. The distributed magtape handlers accept these operations, but a magtape that is manipulated by these functions is no longer ANSI-compatible or supported by RT--11 utilities.

When any of the following operations is called, the stored file sequence number and block number information are erased and are not reinitialized until a .CLOSE and another file-opening command have been performed. Note that the .CLOSE moves and, in the case of the file opened with .ENTER, writes the tape regardless of any commands that have been issued since the file was opened. When the file is closed, the magtape handler cannot write the size of the file because the file size is lost to the handler. It writes a zero in its place. The file sequence number field will be correct.

You initiate operations and use these special functions in the same manner as those that are compatible with the FSM: (numbered) Open a channel to the device by issuing a non-file-structured .LOOKUP. You can optionally open a file on the magtape volume by issuing an SF.USR. Issue the special functions to read, write, or position the magtape. Close the channel.

If you are going to be using the operations in this section consistently, you should investigate performing a system generation and building a magtape handler that does not contain the FSM; a hardware-level-only handler. Such a handler is appropriate for the operations in this section and has a much smaller memory image. See (maghard_sec) and the (syg_booK) for information. (Rewinding and Going Off Line (SF.MOR), Code 372\mag_sfmor_sec)

This request is the same as rewind, except that it takes the tape drive off line and then rewinds to BOT. The handler is free to accept commands after the rewind is initiated.

The special function SF.MOR has the following format, with the (area, chan,) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.MOR,,,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((SF.MOR)\is the code 372 or the name SF.MOR if the program is assembled with the distributed file SYSTEM.MLB.) ((blk)\is the address of a 4-word error and status block used for returning the exception conditions. See (mag_except_sec).)

This request returns the same error code and qualifying information as the rewind request. (Rewinding (SF.MRE), Code 373\mag_sfmre_sec)

The SF.MRE request rewinds the tape to BOT. The MT and MM handlers cannot accept other requests until the rewind operation is complete; the MS handler can.

The special function SF.MRE has the following format, with the (area, chan,) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.MRE,,,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((SF.MRE)\is the code 373 or the name SF.MRE if the program is assembled with the distributed file SYSTEM.MLB.) ((blk)\is the address of a 4-word error and status block used for returning the exception conditions. See (mag_except_sec).)

This request returns the error shown in (SPF373ERR_TAB).

(SF.MRE (Code 373) Errors\SPF373ERR_TAB) (3\10\8) (Byte 52 Code\First Word Code\Qualifying Information) (Hard error (Value = 1)\0\No additional information (consult documentation for your particular tape drive for all possible error conditions).) (\1\Tape drive not available.) (Writing with Extended Gap (SF.MWE), Code 374\mag_sfmwe_sec)

This request permits you to write on tapes that have bad spots. The call syntax is identical to the SF.MWR request except for its function code, which is 374. The errors are explained in (sfmweerr_tab).

(SF.MWE (code 374) Errors\SFMWEERR_TAB) (2\6) (Byte 52 Code\Meaning) (0\The EOT marker has been detected.) (1\Hard error occurred on channel.) (2\Channel not open.)

Additional qualifying information for these errors is returned in the first two words of the status block. See (mag_except_sec). (Spacing Backward (SF.MBS), Code 375\mag_sfmbs_sec)

The SF.MBS request spaces the magtape backward block-by-block or until a tape mark is detected.

You should note that because magtape is sequentially accessed, an SF.MBS operation in a file without a subsequent positioning to the end of the file (before a .CLOSE) causes data loss.

The special function SF.MBS has the following format, with the (area, chan, wcnt) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.MBS,,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((SF.MBS)\is the code 375 or the name SF.MBS if the program is assembled with the distributed file SYSTEM.MLB.) ((wcnt)\is the number of blocks to space past (must not exceed 65534(10)).) ((blk)\is the address of a 4-word error and status block used for returning the exception conditions. See (mag_except_sec).)

This request returns the errors shown in (SPF375ERR_TAB).

(SF.MBS (Code 375) Errors\SPF375ERR_TAB) (3\10\8) (Byte 52 Code\First Word Code\Qualifying Information) (EOF (Value = 0)\1\Tape before EOF only (tape mark detected).) (\2\Tape before EOT only (no tape mark detected).) (\3\Tape before EOF and EOT (tape mark detected).) (\4\Tape before BOT (no tape mark detected). The second word in the status block contains the number of blocks requested to be spaced (wcnt), minus the number of blocks spaced if a tape mark or BOT is detected. Otherwise, its value is not defined.) (Hard error (Value = 1)\0\No additional information (consult documentation for your particular tape drive for all possible error conditions).) (\1\Tape drive not available.) (\2\The controller lost the tape position.) (Spacing Forward (SF.MFS), Code 376\mag_sfmfs_sec)

The SF.MFS request spaces the magtape forward block-by-block or until a tape mark is detected. When a tape mark is detected, the handler reports it along with the number of blocks not skipped. These commands can be used to issue a space-to-tape-mark command by passing a number greater than the maximum number of blocks on a tape. The tape is left positioned after the tape mark or the last block passed. The two spacing requests have the following forms.

The special function SF.MFS has the following format, with the (area, chan) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.MFS,,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((SF.MFS)\is the code 376 or the name SF.MFS if the program is assembled with the distributed file SYSTEM.MLB.) ((wcnt)\is the number of blocks to space past (must not exceed 65534(10)).) ((blk)\is the address of a 4-word error and status block used for returning the exception conditions. See (mag_except_sec).)

This request returns the errors shown in (SPF376ERR_TAB).

(SF.MFS (Code 376) Errors\SPF376ERR_TAB) (3\10\8) (Byte 52 Code\First Word Code\Qualifying Information) (EOF (Value = 0)\1\Tape at EOF only (tape mark detected).) (\2\Tape at EOT only (no tape mark detected).) (\3\Tape at EOF and EOT (tape mark detected). The second word in the status block contains the number of blocks requested to be spaced ((wcnt)), minus the number of blocks spaced if a tape mark or BOT is detected. (A tape mark is counted as a block.) Otherwise, its value is not defined. The tape will be positioned after the tape mark on forward spacing and before the tape mark on backward spacing.) (Hard error (Value = 1)\0\No additional information (consult documentation for your particular tape drive for all possible error conditions).) (\1\Tape drive not available.) (\2\The controller lost the tape position.) Due to hardware restrictions, Digital recommends that no forward space commands be issued if the reel is positioned past the EOT marker. (Writing a Tape Mark (SF.MTM), Code 377\mag_sfmtm_sec)

The SF.MTM request writes a tape mark.

The special function SF.MTM has the following format, with the (area, chan) and optional (crtn, BMODE=str), and (CMODE=str) parameters as described in the (sml_book): Macro Call: .SPFUN area,chan,#SF.MTM,,,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((SF.MTM)\is the code 377 or the name SF.MTM if the program is assembled with the distributed file SYSTEM.MLB.) ((blk)\is the address of a 4-word error and status block used for returning the exception conditions. See (mag_except_sec).)

This request returns the errors shown in (SPF377ERR_TAB). Additional qualifying information for these errors is returned in the first two words of the (blk) argument status block. See (mag_except_sec).

(SF.MTM (Code 377) Errors\SPF377ERR_TAB) (3\10\8) (Byte 52 Code\First Word Code\Qualifying Information) (EOF (Value = 0)\1\Tape before EOF only (tape mark detected).) (Hard error (Value = 1)\0\No additional information (consult documentation for your particular tape drive for all possible error conditions).) (\1\Tape drive not available.) (\2\The controller lost the tape position.) (\4\Tape is write locked.) (Hardware Magtape Handler\maghard_SEC)

The hardware magtape handlers are identical to the distributed handlers except they are not built with the FSM. Therefore, the hardware magtape handlers accept only hardware requests. These are applicable in I/O operations where no file structure exists. Any file structure request you make to the hardware handler results in a monitor directory I/O error. The hardware handler is a subset of the file structure magtape handler. It can perform I/O operations on physical blocks, position the tape, and recover from errors.

Any file-structured request causes the hardware handler to issue a hard error. The hardware handler accepts only the non-file-structured .LOOKUP, .CLOSE, or special function requests.

If you do not need the file structure support, use the hardware handlers. You must perform a SYSGEN (see the (syg_book)) to get the hardware magtape handlers, then you must rename them in order to use them. Use a series of monitor commands similar to the following, which replace the file structure MS handler with the hardware MS handler. (numbered) Remove the distributed handler: (.)(REMOVE MS (RET)) Save the distributed handler: (.)(RENAME/SYS MS[X].SYS MS[X]FS.SYS (RET)) Replace the distributed handler with the hardware handler you built during SYSGEN: (.)(RENAME/SYS MS[X]HD.SYG MS[X].SYS (RET)) Install the hardware handler: (.)(INSTALL MS (RET)) (Transporting Tapes to RT--11)

RT--11 can read files written on other computer systems that support the ANSI standard labels. The following sections give a few examples of how to write ANSI tapes on some common Digital PDP-11 operating systems. Keep in mind that there are other factors involved in addition to the label and format compatibility, including density, parity, and number of tracks. Consult the appropriate system documentation for complete information on using magtapes under the different operating systems. (See the (VFF_BOOK) and the (SUM_BOOK) for information on transporting tapes from RT--11 to other systems.) (From RSTS/E)

RSTS/E supports two types of magtape format, DOS-11 and ANSI. In the following examples, (dd) represents the magtape handler name. To ensure that an ANSI file structure is written, issue the following commands: (ASSIGN ddn: .ANSI) Allocates the device to the job and ensures that an ANSI file structure is used. (RUN $PIP) (ddn:xxxxxx/ZE) PIP initializes the tape; (xxxxxx) is the volume ID. (Really zero ddn:? )(YES) PIP prompts before initializing the tape. (PIP ddn:=TEST1.MAC,TEST2.MAC) PIP copies files to the tape. (DEASSIGN ddn: ) Deallocates the device. (From RSX-11M)

RSX-11M needs the following commands to access a magtape: (ALL ddn:) Allocates a drive. (INI ddn:RT11) Initializes the tape and gives the name (RT11) as the volume identification. (MOU ddn:RT11) Mounts the tape volume. (PIP ddn:=[13,14]TEST1.MAC,TEST2.MAC) Copies files to the tape. (DMO ddn:RT11) Dismounts the tape volume. DEA ddn: Deassigns the drive. (From RSX-11D and IAS)

Use the following commands to write an ANSI tape on RSX-11D or IAS: (INI ddn:RT11) Initializes the tape and gives the name (RT11) as the volume identification. (MOU ddn:RT11) Mounts the tape volume.

For RSX-11D, use PIP to write files to the tape; for IAS, use the COPY command. (DMO ddn:RT11) Dismounts the tape volume.

The contents of files written under the RSX-11D, RSX-11M, and IAS systems do not necessarily correspond to those types of data files under RT--11. For example, under RT--11, text files consist of stream ASCII data (carriage return and line feed characters are embedded in the text); the other operating systems use a different type of character storage. Be sure to pay attention to the contents of the files you need to transfer.

When you write files to be read under RT--11, the only valid block size the utility programs use is 512 characters per block. However, the DIR program will list the directory of any ANSI compatible tape. (From VMS)

Creating a magtape on a VAX processor running the VMS operating system for subsequent transfer to a PDP--11 running RT--11 is described in the (VFF_book). Look there for the procedure. (Seven-Track Magnetic Tape)

Seven-track tapes contain six data tracks and one parity track, so a maximum of six data bits can be contained in one tape character. With seven-track tapes, the MT handler operates in either six-bit mode or core dump mode.

Six-bit mode is not compatible with the data normally created by PDP-11 systems; it is provided for transferring data to or from other systems. In addition, file structure operations cannot be performed in this mode. With the density set at 200 or 556 bpi, the magtape always operates in six-bit mode. When reading in six-bit mode, the handler places each six-bit tape character right-justified in a PDP-11 byte; the high-order two bits of the byte are set to 0. When writing in six-bit mode, the handler writes the low-order six bits of a PDP-11 byte as the six data bits of a tape character; the high-order two bits of the PDP-11 byte are not transferred or affected.

Core dump mode is compatible with PDP-11 systems. At 800 bpi, seven-track tape transfers can occur in either six-bit mode (SET MT: DENSE=807) or core dump mode (the default). (7TRACK_FIG) illustrates the differences between six-bit mode and core dump mode.

(Seven-Track Tape\7TRACK_FIG) (POSTSCRIPT\MLO-007359B\26.5)

In core dump mode, each PDP-11 byte is split into two tape characters. In writing to the tape, the handler writes the low-order four bits of a PDP-11 byte as the low-order four bits of the first tape character and the high-order four bits of the PDP-11 byte as the low-order four bits of the next tape character. The high-order two bits of each tape character are set to 0.

In reading from the tape, the reverse process occurs. The low-order four bits of the first tape character become the low-order four bits of the PDP-11 byte; the low-order four bits of the next tape character become the high-order four bits of the PDP-11 byte.

The high-order two bits of each tape character are not involved in the transfer, although they are included in the parity calculation. Thus, in core dump mode, the actual number of tape characters read or written is twice the number of PDP-11 bytes requested to be transferred; this conversion is performed by the magtape controller. (MU (TMSCP Magtape Handler)\psd_mu_sec)

This section provides specific programming information for TMSCP magtapes.

The MU handler supports magtape systems that use the tape mass storage communication protocol (TMSCP). The MU handler contains the same basic structure and provides the same support for programmed requests and special functions as described in (psd_mmmsmt_sec) except as explicitly stated in this section. Therefore, this section describes only how the MU handler is different from the MM, MS, and MT handlers. (Support for Special Functions)

The following special functions are either not supported by the reel-type magtape handlers or are supported in a different manner.

The SF.MTB and SF.BYP special functions are not affected by the presence (or absence) of the File Stucture Module (FSM), as they are not concerned with operations on magtape volumes. Rather, they are conerned with data structures within the handler itself or the handler's controller.

(3\6\8) (Code\Name\Function) (352\SF.MTB\Magtape data table access) (\SF.TRD\(wcnt) argument for a read from the table; specified with a +1) (\SF.TWR\(wcnt) argument for a write to the table; specified with a --1) (360\SF.BYP\Direct TMSCP access; special function bypass) (374\SF.MWE\Not Supported; writes with extended file gap executes as a write (SF.MWR) operation) (TMSCP Translation Tables (SF.MTB), Code 352)

Whenever an I/O request is passed to the MU handler, MU uses the RT--11 unit number as an index into the translation tables. MU then extracts the TMSCP unit number and port that have been assigned to that RT--11 unit, and uses the information to access the proper magtape drive.

You can read or write (modify) the memory-resident contents of the translation tables by using SF.MTB. (Size of the Translation Tables)

The size of the translation tables is determined by the number of device units supported by DU. The distributed MU supports one unit; you can build an MU that supports up to four units. You can determine the number of supported units for a particular handler by reading the MU.NUM field, as explained further. (Structure of the Translation Tables)

As shown in Tables (psd_mag_head_tab\value) and (psd_mag_ent_tab\value), the MU unit translation tables consist of a table header followed by table entries. The header starts at offset MU.ID, which is a word containing the Radix-50 value for the characters MU.

The MU.ID offset is followed by MU.NUM. The low byte of MU.NUM contains the number of entries in the table (and therefore the number of supported units). The high byte of MU.NUM is reserved.

The next offset is MU.ENT, which contains a pointer to the first table entry.

(TMSCP (MU) Translation Table Header\psd_mag_head_tab) (3\6\8) (Offset\Name\Meaning) (0\MU.ID\Radix-50 value for characters MU) (2\MU.NUM\Byte containing number of entries in table) (3\\Reserved) (4\MU.ENT\The offset of the first table entry)

Each table entry is 4 bytes, and Digital recommends you use the symbol MU.ESZ to represent the 4-byte size of each entry.

(TMSCP (MU) Translation Table Entry\psd_mag_ent_tab) (3\6\8) (Offset\Name\Meaning) (0\MU.UNI\Physical TMSCP unit number.

The symbol MU$Ux=nnnnnn is the initial value for the translation table when the handler is assembled. In the symbol, (x) is the octal RT--11 MU unit number (0--3) and (nnnnnn) is the TMSCP unit number. The SET MUx UNIT=nnnnnn command can subsequently change the value.) (2\MU.JOB\Byte containing the number of the job connected to this TMSCP unit.) (3\MU.POR\Byte containing the TMSCP port (controller) number.

The symbol MU$Ox=nnn is the initial value for the translation table when the handler is assembled. In the symbol, (x) is the octal RT--11 MU unit number (0--3) and (nnn) is the TMSCP port number. The SET MU PORT=nnn command can subsequently change the value.) (4\MU.ESZ\Size of an entry (4 bytes)) (Accessing the Translation Tables)

Special function SF.MTB can read or write the TMSCP translation tables. Whether a read or write operation is performed is determined by the (wcnt) argument. Specify +1 (SF.TRD) for (wcnt) to read the tables; --1 (SF.TWR) to write the tables.

The translation tables are read from or written to a buffer, which is pointed to by the (buf) parameter. (Special Function Bypass (SF.BYP), Code 360)

Special function SF.BYP bypasses all unit number translation and allows direct access to the TMSCP port. For MU, SF.BYP (direct TMSCP access) serves the same purpose as the DU handler's SF.BYP (direct MSCP access).

The request syntax and parameter argument definitions for SF.BYP are as follows: Macro Call: .SPFUN area,chan,#SF.BYP,buf,wcnt,blk

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((SF.BYP)\is code 360 or the name SF.BYP if the program has been assembled with the distributed module SYSTEM.MLB.) ((buf)\is the address of the 52(10)-word TMSCP area.) ((wcnt)\when nonzero, is the virtual address of a data buffer to send to the handler. That virtual address is translated to a physical address and placed in the buffer of the TMSCP area.

when zero, the buffer address in the TMSCP area is not altered.) ((blk)\indicates whether the handler should perform retries:

(2\4) (1 = \specifies retries) (0 = \specifies no retries) )

The buffer address in special function SF.BYP must point to a 52-word area in the user's job. The first 26 words are used to hold: (UNNUMBERED) A response packet length in bytes A virtual circuit identifier An end packet when the command is complete

The second 26 words are set up by the caller and contain: (UNNUMBERED) A length word (length of command) A virtual circuit identifier (must have octal 1 (001) in high byte) A valid TMSCP command (48(10)-byte command buffer)

Except for port initialization, the user program must do all command packet sequencing, error handling, and reinitialization when the bypass operations are complete. (Unit Support, CSR and Vectors)

The distributed MU handler supports one unit. Using the system generation procedure, you can build an MU handler that supports up to four units. Each unit requires a separate controller and you can only boot RT--11 from unit MU0, which must be installed at CSR address 774500 and vector address 260. The addresses for MU1 through MU3 float; they depend on what other devices are on the bus. The default CSR and vector addresses are as follows:

(2\8) (CSR\Vector) (774500\260) (774504\340) (774510\344) (774514\350) (NL (Null Handler)\psd_nl_sec)

The null handler accepts all read and write requests. On output operations, this handler acts as a data sink. When a program calls NL, the handler returns immediately to the monitor indicating that the output is complete. The handler returns no errors and causes no interrupts. On input operations, NL returns an immediate EOF indication for all requests; no data is transferred. Hence, the contents of the input buffer are unchanged. (NC, NQ, NU (Ethernet Handlers)\psd_ncnqnu_sec)

RT--11 includes three Ethernet handlers that provide support for Ethernet class controllers. The NC Ethernet handler supports the DECNA controller for CTI Bus-based processors. The NQ Ethernet handler supports the DELQA and DEQNA Ethernet controllers for Q-bus processors. The NU Ethernet handler supports the DELUA and DEUNA controllers for UNIBUS processors.

Each handler supports only one controller and a maximum of eight units. These unit numbers are used as a logical connection between a user program and an address/protocol pair to be recognized by the Ethernet hardware. (Restrictions)

Observe the following Ethernet handler restrictions: (UNNUMBERED) The handlers run only under mapped monitors. The handlers cannot be fetched and must be loaded. Programs that call the Ethernet handlers must be written to perform with the following elements in the order indicated: (NUMBERED) Use the .LOOKUP programmed request to open a channel to the device unit. Allocate the unit using .SPFUN 200. Perform the Ethernet operation or operations. Deallocate the unit using .SPFUN 200. Use the .CLOSE programmed request to close the channel to the specified device unit. (Support for Special Functions)

The Ethernet handlers support the following special functions. The special function names are from the .NALDF macro in the distributed file SYSTEM.MLB.

(4\6\8\12) (Code\Name\Section\Function) (200\SF.NAL\(psd_sfnal_sec\value)\Allocate/Deallocate unit) (201\SF.PRO\ \Reserved) (202\SF.NPR\(psd_sfnpr_sec\value)\Enable/Disable protocol type) (203\SF.NMU\(psd_sfnmu_sec\value)\Enable/Disable multicast address) (204\SF.NWR\(psd_sfnwr_sec\value)\Transmit Ethernet frame) (205\SF.NRD\(psd_sfnrd_sec\value)\Receive Ethernet frame)

Successful completion of a .SPFUN request clears the carry bit. Completion with error sets the carry bit, and the status word in the buffer contains an error code. (Allocate/Deallocate Unit (SF.NAL), Code 200\psd_sfnal_sec)

The allocate unit special function allocates a unit of the Ethernet handler for a job's exclusive use.

The deallocate unit special function deallocates the unit so it can be used by another job. (Allocate Unit)

The following is the form of the special function allocate unit: Macro Call: .SPFUN area,chan,#SF.NAL,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((SF.NAL)\is code 200 or the name SF.NAL if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a 4-word buffer containing the status word and space for the station's physical address. The buffer contents are returned by the allocate unit special function.)
(POSTSCRIPT\S559c2PSDNQNUBAU_FIG.EPS\7)
(2\10) (\The high byte of the status word contains a 0. Allocate unit returns one of the following octal status codes in the low byte of the status word: (#)
(2\6) (Code\Meaning) (#0\Success) (#2\Controller error while attempting to initialize the network interface (controller).) (#3\No resources (unit in use).) (11\Reserved.) ) ((wcnt)\is #0.) ((blk)\is #1.) (Deallocate Unit)

The following is the form of the special function deallocate unit: Macro Call: .SPFUN area,chan,#SF.NAL,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((SF.NAL)\is code 200 or the name SF.NAL if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a 1-word buffer containing the status word.)
(POSTSCRIPT\S559c2PSDNQNUBDU_FIG.EPS\2)
(2\10) (\The high byte of the status word contains a 0. Deallocate unit returns one of the following octal status codes in the low byte of the status word: (#)
(2\6) (Code\Meaning) (#0\Success.) (#1\Unknown unit. The specified unit was not opened by the job issuing the request.) (#2\Controller error while attempting to initialize the network interface (controller).) (11\Unit still active.) ) ((wcnt)\is #0.) ((blk)\is #0.) (Enable/Disable Protocol Type (SF.NPR), Code 202\psd_sfnpr_sec)

The enable protocol type special function adds a protocol type to the list of those to be recognized by the unit. Only one protocol type can be specified for each unit. At least one protocol type must be enabled to receive Ethernet frames.

The disable protocol type special function removes the protocol type from the list of those recognized by the unit. (Enable Protocol Type)

The following is the form of the special function enable protocol type: Macro Call: .SPFUN area,chan,#SF.NPR,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((func)\is code 202 or the name SF.NPR if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a 2-word buffer that contains the status word followed by the protocol type word.)
(POSTSCRIPT\S559c2PSDNQNUdPT_FIG.EPS\4)
(2\10) (\The high byte of the status word contains a 0. Enable protocol type returns one of the following octal status codes in the low byte of the status word: (#)
(2\6) (Code\Meaning) (#0\Success.) (#1\Unknown unit. The specified unit was not opened by the job issuing the request.) (#2\Controller error while attempting to initialize the network interface (controller).) (#3\No resources (unit's protocol table is full).) (#6\Reserved.) (10\Protocol type in use.)

The protocol type is specified by the user.) ((wcnt)\is #0.) ((blk)\is #1.) (Disable Protocol Type)

The following is the form of the special function disable protocol type: Macro Call: .SPFUN area,chan,#SF.NPR,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((SF.NPR)\is code 202 or the name SF.NPR if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a 2-word buffer that contains the status word, followed by the protocol type word.)
(POSTSCRIPT\S559c2PSDNQNUDPT_FIG.EPS\4)
(2\10) (\The high byte of the status word contains a 0. Disable protocol returns one of the following octal status codes in the low byte of the status word:
(2\6) (Code\Meaning) (0\Success.) (1\Unknown unit. The specified unit was not opened by the job issuing the request.) (2\Controller error while attempting to initialize the network interface (controller).) ) ((wcnt)\is #0.) ((blk)\is #0.) (Enable/Disable Multicast Address (SF.NMU), Code 203\psd_sfnmu_sec)

The enable multicast address special function adds a multicast address to the list of those to be recognized by that unit. You need not specify the unit's physical or broadcast address. RT--11 supports only one multicast address per handler unit.

The disable multicast address special function removes a multicast address from the list of those to be recognized by the unit. (Enable Multicast Address)

The following is the form of the special function enable multicast address: Macro Call: .SPFUN area,chan,#SF.NMU,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((func)\is code 203 or the name SF.NMU if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a 4-word buffer that contains the status word, followed by the 3-word multicast address. The low-order bit of the first address word should be a 1.)
(POSTSCRIPT\S559c2PSDNQNUEMA_FIG.EPS\7)
(2\10) (\The high byte of the status word contains a 0. Enable multicast address returns one of the following octal status codes in the low byte of the status word:
(2\6) (Code\Meaning) (0\Success.) (1\Unknown unit. The specified unit was not opened by the job issuing the request.) (2\Controller error while attempting to initialize the network interface (controller).) (3\No resources (unit's address table is full, or hardware address table is full).) ) ((wcnt)\is #0.) ((blk)\is #1.) (Disable Multicast Address)

The following is the form of the special function disable multicast address: Macro Call: .SPFUN area,chan,#SF.NMU,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((func)\is code 203 or the name SF.NMU if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a 4-word buffer that contains the status word, followed by the 3-word multicast address. The low-order bit at the first address word should be a 1.)
(POSTSCRIPT\S559c2PSDNQNUDMA_FIG.EPS\7)
(2\10) (\The high byte of the status word contains a 0. Disable multicast address returns one of the following octal status codes in the low byte of the status word:
(2\6) (Code\Meaning) (0\Success.) (1\Unknown unit. The specified unit was not opened by the job issuing the request.) (2\Controller error while attempting to initialize the network interface (controller).) ) ((wcnt)\is #0.) ((blk)\is #0.) (Transmit Ethernet Frame (SF.NWR), Code 204\psd_sfnwr_sec)

The special function transmit Ethernet frame transmits the Ethernet frame pointed to in the (buf) parameter argument. If the source address field of the frame is nonzero, it is kept and used. If the source field of the frame is zero, the unit's physical address is inserted in the source field before transmission.

The following is the form of the special function transmit Ethernet frame: Macro Call: .SPFUN area,chan,#SF.NWR,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((func)\is code 204 or the name SF.NWR if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a variable-size buffer containing a word for returning status, a reserved word, and up to 757(10) words comprising the Ethernet frame to be transmitted.)
(POSTSCRIPT\S559c2PSDNQNUTEF_FIG.EPS\23)
(2\10) (\Transmit Ethernet frame returns one of the following octal status codes in the low byte of the status word: (#)
(2\6) (Code\Meaning) (#0\Success.) (#1\Unknown unit. The specified unit was not opened by the job issuing the request.) (#2\Controller error while attempting to initialize the network interface (controller).) (13\Transmit failed. When status code 13 is returned in the low byte of the status word, transmit Ethernet frame returns one of the following octal status subcodes in the high byte of the status word: 1 = Invalid frame length. 2 = Excessive collisions. 3 = Carrier check failed.) ) ((wcnt)\is determined by the variable size of the user buffer (including the status and reserved words). The packet size (including the status and reserved words) can vary between 32(10) and 759(10) words.) ((blk)\is #0.) (Receive Ethernet Frame (SF.NRD), Code 205\psd_sfnrd_sec)

The receive Ethernet frame special function returns the next Ethernet packet with the desired unit address and protocol type to the buffer. The function does not return Ethernet frames that are received with errors.

The following is the form of the special function receive Ethernet frame: Macro Call: .SPFUN area,chan,#SF.NRD,buf,wcnt,blk[,crtn][,BMODE=str][,CMODE=str]

(2\10) ((area)\is the address of a 6-word EMT argument block.) ((chan)\is a channel number in the range 0 to 376(8).) ((func)\is code 205 or the name SF.NRD if the program is assembled with the distributed file SYSTEM.MLB.) ((buf)\is the address of a variable-size buffer containing a word for returned status, a word for returned fram size, and up to 757(10) words to receive the Ethernet frame. The buffer contents are returned by the receive Ethernet frame special function.)
(POSTSCRIPT\S559c2PSDNQNUREF_FIG.EPS\16)
(2\10) (\The high byte of the status word contains a 0. The receive Ethernet frame special function returns one of the following octal status codes in the low byte of the status word:
(2\6) (Code\Meaning) (0\Success.) (1\Unknown unit. The specified unit was not opened by the job issuing the request.) (2\Controller error while attempting to initialize the network interface (controller).) ) ((wcnt)\is the size of the user buffer including the status and frame size words. The maximum value allowed for the argument is 759(10); the minimum is 32(10). ) ((blk)\is #0.) (Example of Allocating an Ethernet Unit)

The following example allocates a unit of the Ethernet handlers. CONFG2 = 370 ;Config word 2 ; (RMON fixed offset) PROS$ = 020000 ;RT is running on a PRO-3xx BUS$ = 000100 ;Q-bus/UNIBUS processor . . . .GVAL #AREA,#CONFG2 ;Get contents of Config word 2 MOV #(<)^RNC >,DBLK ;Assume PRO BIT #PROS$,R0 ;Correct assumption? BNE 10$ ;yes... MOV #(<)^RNQ >,DBLK ;No, so assume Q-bus BIT #BUS$,R0 ;Correct assumption? BNE 10$ ;yes... MOV #(<)^RNU >,R0 ;Nope, must be ; UNIBUS after all 10$: .GTJB #AREA,#JOBDAT ;Get info on this job MOV JOBDAT,R0 ;R0 = job number (*2) ASR R0 ;Convert to job number 0-7 ADD #(<)^R 0>,R0 ;Make it final RAD50 digit ADD R0,DBLK ; and add it to ; the device name .LOOKUP #AREA,#0,#DBLK ;Open a channel to Ethernet . . ;.LOOKUP error processing . .SPFUN #AREA,#0,#200,#BUFFER,#0,#1 ;Allocate the unit to this job . . ;.SPFUN error processing . AREA: .BLKW 3 JOBDAT: .BLKW 12. DBLK: .WORD 0,0,0,0 BUFFER: .BLKW 4 . . . ;END OF EXAMPLE (PI (CTI Bus-Based Processor Interface System Support Handler)\psd_pi_sec)

This section contains specific information about the PI system support handler and using RT--11 with CTI Bus-based processors. PI is called a (system support handler) because RT--11 requires PI to provide certain necessary connections with the computer hardware. At bootstrap time, the monitor loads PI before binding with the system device handler file on the system volume. (Support for Special Functions)

The PI handler supports the following special functions which are used only with the GIDIS graphics package, as described in the (SSL_BOOK):

(3\6\8) (Code\Name\Action) (371\SF.PWR\Send command packet to GIDIS.) (370\SF.PRD\Get status from GIDIS.) (PI Keyboard Support)

PI supports the keyboard in normal mode or function key mode. (Normal Mode)

PI supports the following keys in normal mode: (unnumbered) All keys on the main keypad. All keys on the numeric keypad. Cursor control (arrow) keys on the editing keypad. The following special function keypad keys: HOLD SCREEN (F1), PRINT SCREEN (F2), SETUP (F3), ESCAPE (F11), BACK SPACE (F12), and LINE FEED (F13).

PRINT SCREEN (F2) prints a copy of the text from your terminal screen directly on your printer. PRINT SCREEN cannot be used to print graphics. You must be running the transparent spooling package (SPOOL) under a mapped monitor to use PRINT SCREEN.

SETUP (F3) clears a locked keyboard and turns off the WAIT light when pressed. Note that the SETUP key has nothing to do with the setup utility.

The following keys do not function in normal mode: (Unnumbered) Special function keys F4 through F10, F14, HELP (F15), DO (F16), and F17 through F20. Editing keypad keys FIND, INSERT HERE, REMOVE, SELECT, PREV SCREEN, and NEXT SCREEN. Editing functions under RT--11 use the numeric keypad (see the (ked_book).) (Function Key Mode (DECFKM))

Programs written for the PI handler can place the terminal in function key mode. In function key mode, each special function key sends an assigned control sequence to the processor. The control sequence is not assigned a specific function, but software can be programmed to recognize the control sequence.

A program places the terminal in function key mode by sending the 7-bit escape sequence: (ESC)[?39h (transmitted as octal 033 133 077 063 071 150)

A program returns the terminal to normal key mode by sending the 7-bit escape sequence (note the lower-case l (?39l)): (ESC)[?39l (transmitted as octal 033 133 077 063 071 154)

The following table lists control sequences for the special function keys:

(4\10\12\10) (Key\ControlSequence\Key\ControlSequence) (F1\(ESC)[11~\DO (F16)\(ESC)[29~) (F2\(ESC)[12~\F17\(ESC)[31~) (F3\(ESC)[13~\F18\(ESC)[32~) (F4\(ESC)[14~\F19\(ESC)[33~) (F5\(ESC)[15~\F20\(ESC)[34~) (F6\(ESC)[17~\COMPOSECHARACTER\(ESC)[10~) (F7\(ESC)[18~\FIND\(ESC)[1~) (F8\(ESC)[19~\INSERTHERE\(ESC)[2~) (F9\(ESC)[20~\REMOVE\(ESC)[3~) (F10\(ESC)[21~\SELECT\(ESC)[4~) (F11\(ESC)[23~\PREVSCREEN\(ESC)[5~) (F12\(ESC)[24~\NEXTSCREEN\(ESC)[6~) (F13\(ESC)[25~\\) (F14\(ESC)[26~\\) (HELP (F15)\(ESC)[28~\\) (Video Terminal Support)

PI supports the CTI Bus-based processor's video terminal in the following manner: (Advanced Video Option Emulation)

The PI handler supports a limited emulation of the VT100 implementation of the advanced video option, and uses the same escape sequences as the VT100 terminal. The limited emulation supports all VT100 character renditions (attributes) except BLINK; BLINK displays as BOLD. BOLD is not supported in 132-column mode, and 132-column mode is supported only by the mapped monitors. (Text Cursor Mode (DECTCEM))

Text cursor mode lets a program control whether the cursor is displayed on the video screen. Enabling text cursor mode displays the cursor and is the default. Text cursor mode is necessary when working with text because the cursor shows where the next character will be displayed.

A program places the terminal in text cursor mode by sending the 7-bit escape sequence:

(ESC)[?25h (transmitted as octal 033 133 077 062 065 150)

A program takes the terminal out of text cursor mode by sending the 7-bit escape sequence (note the lower-case l (?25l)):

(ESC)[?25l (transmitted as octal 033 133 077 062 065 154)

The cursor display can also be controlled using the SETUP CURSOR and SETUP NOCURSOR commands described in the (sug_book). (Device Attributes (DA))

A program uses the device attributes request/reply exchange to ask the terminal, "what are you?". The response sent by the terminal to the program can identify the terminal as a specific VT100 terminal (the default) or as a nonspecific member of the VT100 series of terminals. The SETUP modes VT100 and GENERIC100 (see the (sug_book)) determine which of the two responses the terminal sends the program. Digital recommends that all programs recognize both the VT100 and the GENERIC100 device attributes reply.

A program can request information on two levels. The primary level DA requests basic compatibility information. The secondary level DA requests the specific version and edit level of the PI handler.

The terminal reply to primary and secondary DA requests gives this information, and also tells the program which monitor the system is running. The following is a complete DA interchange:

A program requests primary DA by sending the 7-bit escape sequence:

(ESC)[c (transmitted as octal 033 133 143) (unnumbered) If the terminal is SETUP VT100, it responds by sending the 7-bit escape sequence: (unnumbered\--) When running under an unmapped monitor:

(ESC)[?1;1c (transmitted as octal 033 133 077 061 073 061 143) When running under a mapped monitor:

(ESC)[?1;3c (transmitted as octal 033 133 077 061 073 063 143) If the terminal is SETUP GENERIC100 without 132-column capability (running under an unmapped monitor), it responds by sending the 7-bit escape sequence:

(ESC)[?61c (transmitted as octal 033 133 077 066 061 143) If the terminal is SETUP GENERIC100 with 132-column capability (running under a mapped monitor), it responds by sending the 7-bit escape sequence:

(ESC)[?61;1c (transmitted as octal 033 133 077 066 061 073 061 143)

A program requests the secondary DA by sending the 7-bit escape sequence:

(ESC)[>c (transmitted as octal 033 133 076 143) (unnumbered) If the terminal is operating under an unmapped monitor, it responds by sending the 7-bit escape sequence:

(ESC)[>7;VVnnc (transmitted as octal 033 133 076 067 073 V V n n 143)

where (VV) is the version number, and (nn) is the edit level of the PI handler. If the terminal is operating under a mapped monitor, it responds by sending the 7-bit escape sequence:

(ESC)[>8;Vnnc (transmitted as octal 033 133 076 070 073 V V n n 143)

where (VV) is the version number, and (nn) is the edit level of the PI handler. (UB (UNIBUS Mapping Register (UMR) System Support Handler)\psd_ub_sec)

This section describes the UB handler that provides support for the UNIBUS mapping registers on UNIBUS processors. The UB handler provides DMA (direct memory access) support for 22-bit memory addressing during I/O operations.

UB is called a (system support handler) because RT--11 requires UB to provide certain necessary connections with the computer hardware. At bootstrap time, the monitor loads UB before binding with the system device handler file on the system volume. Therefore, UB cannot be installed with the INSTALL command. Instead, UB is automatically installed and loaded in memory on UNIBUS processors with the following configuration: (unnumbered) The processor is running a mapped monitor. The processor contains more than 256K-bytes of memory. The processor contains UNIBUS Mapping Registers at addresses 170200 through 170400 to support 40(8) 2-word UMRs. At least one device handler on the system uses DMA in performing I/O operations. All distributed RT--11 handlers that can perform DMA are so marked.

(psd_ub_user_dma_sec) describes how to provide UMR support in a user-written DMA handler. All installed user-written (not distributed) device handlers are compatible with RT--11 support for UB. All installed device handlers must be marked as compatible with UB, whether or not they perform DMA operations.

(psd_ub_user_nondma_sec) describes how to make a non-DMA user-written device handler compatible with RT--11 UB support.

UNIBUS Mapping Registers function in a manner that is similar to the Memory Management Unit (MMU) registers that provide 22-bit address translation for the CPU. The UMRs provide address translation (mapping) from the 18-bit UNIBUS to the 22-bit memory bus. (UMR Support with Distributed Handlers\psd_ub_dis_sec)

On supported UNIBUS system configurations, UB is automatically installed and loaded when the processor is booted. At that point, DMA I/O operations are handled transparently by the processor UMR hardware and the RT--11 operating system. Programs that use distributed RT--11 device handlers require no modification to support DMA access to a peripheral device.

The aspects of UMR support that apply to distributed handlers are: (unnumbered) Permanent UMR allocation.

Because of internal buffers, some RT--11 device handlers, such as DL, DM, DU, NU, and the various magtape handlers, require a preallocation of one or more permanent UMRs. RT--11 preallocates those permanent UMRs when the device handlers are installed at system boot. RT--11 reserves those permanent UMRs for those handlers when they are loaded. See (psd_disumr_tab). You can regain any preallocated permanent UMRs for handlers that install but you are not using, by renaming the device handler. Such a renamed handler does not install at the next system boot.

Contiguous permanent UMRs are allocated from the list of reserved permanent UMRs when handlers are loaded and returned to reserved status when handlers are unloaded. After numerous load/unload operations, the list of reserved permanent UMRs can become fragmented. A symptom of this condition is the inability to load a device handler that requires multiple permanent UMRs even when sufficient reserved permanent UMRs exist. Two courses of action are available if that condition occurs. You can reboot your system, or you can issue the SHOW UMR command and unload the device handlers that are displayed as occupying slots between the available reserved permanent UMRs. The system device handler resides at the top of the list. You should consolidate the list from the base upward. Temporary UMR allocation.

Many distributed device handlers require one or more UMRs on a temporary basis to process I/O requests. RT--11 allocates temporary UMRs as the need occurs. Each processor contains 31(10) accessible UMRs, and the allocation of UMRs can be displayed by the command SHOW UMR. Serialization of I/O request satisfaction.

When UB is loaded in memory, RT--11 no longer always satisfies I/O requests in serial order.

Of the distributed RT--11 device handlers, only DU and the magtape handlers (MM, MS, MT, and MU) require that I/O requests are satisfied in serial order. The guarantee of I/O request serialization is internal to those handlers and requires no user intervention.

However, RT--11 does not guarantee that I/O requests for other device handlers are satisfied in serial order. Rather, I/O requests are satisfied in the quickest manner possible, which might or might not be serial. For example, an I/O request that requires four UMRs might be queued for a time waiting for UMR allocation, while a subsequent I/O request requiring fewer UMRs is satisfied. However, if required, you can force serialized I/O request processing, using the SET UB SERIAL=n command, described in the (sug_book).

You can control other aspects of UMR support by specifying conditions for the SET UB command. Other than those conditions, UMR support is totally transparent when using the distributed RT--11 device handlers.

(Distributed Handler Support for UMRs\psd_disumr_tab) (3\8\6) (DeviceHandler\DMA=\PERMUMR=) (DL\YES\1) (DM\YES\1) (DU\YES\2) (DW\NO\) (DY\YES\1) (MM\YES\If support for FSM included, requires 1 if no support for FSM, requires 0) (MS\YES\If support for FSM included, requires 1 if no support for FSM, still requires 1) (MT\YES\If support for FSM included, requires 1 if no support for FSM, requires 0) (MU\YES\If support for FSM included, requires 3 if no support for FSM, requires 2) (NU\YES\3) (RK\YES\0) (VM\NO\) (Including Required UB Support in User-Written Non-DMA Handlers\psd_ub_user_nondma_sec)

All installed device handlers, including those that perform no DMA operations, must be modified for compatibility with UB. Otherwise, the RT--11 monitor bootstrap does not load UB and the system then operates with only the low 256K words of memory accessible to DMA operations.

You must explicitly specify whether each user-written device handler supports DMA, using the .DRDEF macro's (DMA=str) parameter. If a device handler does not perform DMA operations and, therefore, does not require UMR allocation, specify (DMA=NO). (Including UMR Support in User-Written DMA Handlers\psd_ub_user_dma_sec)

UMR support is appropriate for a device handler that performs I/O operations and is capable of DMA. Including UMR support in such a device handler lets the handler access computer memory beyond the 18-bit 256K-byte boundary during I/O operations.

The following paragraphs describe elements of the new UMR support that must be considered before you include UMR support in a device handler. Each element is either described when listed or you are pointed to the appropriate section of this manual where you will find the element description.

Including UMR support in any device handler requires that you understand the following items: (UNNUMBERED) The handler should not perform DMA operations from within its own install code. If a handler must be written to perform DMA from within its install code, you must turn off UB (SET UB NOINSTAL), reboot the system, and then install the handler. The handler must use the .DRDEF macro and include one or more of the parameters, (DMA=str, PERMUMR=n), and (SERIAL=str), as described in the (sml_book). If the handler uses the .QELDF macro to define queue elements, you should read about the offset, Q.MEM, as described in (SML_BOOK). RMON automatically allocates temporary UMRs for all .READx and .WRITx requests to handlers that are marked as DMA=YES. RMON also automatically releases all such temporary UMRs. Both operations are completely transparent to the handler. If the handler previously used queue element offsets Q.PAR and Q.BUFF to calculate non-DMA I/O virtual addresses, it must now use the new offset Q.MEM in conjunction with Q.BUFF. Q.MEM is described in (quel_off_sec). The handler now uses Q.PAR to calculate only DMA I/O virtual addresses. If the handler previously used extended memory subroutines $GETBYT, $PUTBYT, $PUTWRD, or $MPPHY, read the paragraphs (Changes to extended memory subroutines for UMR support), in (RLN_BOOK). You should examine the new RMON fixed offsets, $QHOOK, $H2UB, and the bits defined for UB in $CNFG3. They are described in (sim_book). You should decide if I/O requests for the handler or the job must be satisfied in serial order. Once UB is loaded in memory, I/O requests are not guaranteed to be satisfied in serial order by default.

If the handler requires serialized I/O request satisfaction, you must specify the .DRBEG macro (SERIAL=YES) parameter argument when you build the handler. See the .DRDEF macro information in the (sml_book).

If the job requires serialized I/O request satisfaction, see the SET UB SERIAL=n command described in the (sug_book). The device handler must use permanent or temporary UMRs for each special function that performs a DMA I/O operation.

The handler uses permanent UMRs for processing special functions that result in a DMA I/O operation to the handler internal buffer.

If the handler contains internal buffers that store command packets and responses, the handler has to use the ALLUMR routine to explicitly obtain at least one permanent UMR. The handler must explicitly release all permanent UMRs when it unloads, using the RLSUMR routine. Obtaining and releasing permanent UMRs is described in Sections (psd_ub_getumr_sec\value) and (psd_ub_rlsumr_sec\value).

The handler allocates at least one temporary UMR for each special function that performs a DMA I/O operation to the user buffer. The temporary UMRs are allocated either implicitly or explicitly.

Special functions (.SPFUNs) used by the handler are categorized as standard or nonstandard. A standard special function uses the .SPFUN (buf) parameter as the read/write buffer address and the (wcnt) parameter as the operation word count. Temporary UMRs for standard special functions are allocated implicitly. Defining standard special functions is described in (psd_ub_implicit_sec).

A nonstandard special function does not use (buf) as the read/write buffer address or (wcnt) as the operation word count. The handler must explicitly obtain temporary UMRs for nonstandard special functions, requiring additional processing by UB. Processing nonstandard special functions is described in (psd_ub_getumr_sec). (Defining Special Functions for Implicit UMR Allocation\psd_ub_implicit_sec)

The device handler should implicitly allocate UMRs for special functions that do the following: (UNNUMBERED) Perform DMA operations. Use the (buf) and (wcnt) paramaters in the documented manner; are standard special functions.

The handler supports implicit UMR allocation for standard special functions by using the .DRBEG (SPFUN=spsym) parameter and a list of those functions. The (spsym) argument is the label of the list of those functions. The list is structured in the same manner as that used for the .DRSPF (extension table) method. However, unlike the .DRSPF macro, no pointer to the list resides in block 0 of the handler and the concept of special function (type) has no meaning and is not included.

The list of standard special functions must continuously reside in the low-memory portion of the handler whenever the handler is loaded. For all special functions in the list, RMON performs the UMR allocation and the address translation.

Defining special functions for implicit UMR allocation is illustrated in the example program in this section. (Explicitly Allocating Permanent UMRs (ALLUMR)\psd_ub_allumr_sec)

If the device handler contains internal buffers that store command packets and responses, you must allocate at least one permanent UMR to the device handler.

RT--11 allows up to 22(10) UMRs to be permanently allocated to handlers and one UMR is permanently allocated to the I/O page. When the system is booted, RT--11 allocates the one UMR to the system's I/O page and then reserves permanent UMRs for requesting device handlers as each handler is installed. Therefore, unless the 23(10) limit is reached, RT--11 reserves sufficient permanent UMRs to support all installed device handlers that request permanent UMR allocation. However, reserved permanent UMRs are not allocated to a device handler until it is loaded. Unallocated reserved permanent UMRs are available for explicit allocation, using the ALLUMR routine. You can determine the current UMR allocation on your system by issuing the SHOW UMR command.

The ALLUMR routine, which resides in UB, is called to permanently allocate UMRs. If the handler requires UMRs for a single, contiguous chunk of memory, you need call ALLUMR only once. If the handler requires UMRs for noncontiguous chunks of memory, repeatedly call ALLUMR to allocate UMRs for each chunk.

You reference the UB entry vector through the $H2UB fixed offset (460) in RMON. The ALLUMR routine is offset 1 word ($H2UB+2) from the address pointed to by $H2UB.

Use the following procedure to allocate permanent UMRs: (NUMBERED) Calculate the number of permanent UMRs you need for each contiguous chunk of memory. One permanent UMR is required for each 4096 words of contiguous internal buffer space. Specify the total number of permanent UMRs the handler requires in the (PERUMR=n) parameter of the .DRDEF macro in your handler source code. The RT--11 monitor bootstrap (BSTRAP) uses that information to reserve the number of UMRs you permanently allocate to the handler. Before calling ALLUMR to allocate permanent UMRs for an internal buffer space, set up the following registers:

(2\8) (Register\Contents) (R0\Number of permanent UMRs to be allocated for this contiguous chunk of internal buffer space.

If you request more than one permanent UMR, the address of the first is defined by R1 and R2, and each subsequent UMR is offset by a value of 20000(8).) (R1\Bits 0--15 of the 22-bit physical memory base address (word aligned) of the internal buffer.) (R2\Bits 16--21 of the 22-bit physical memory base address of the internal buffer.) (R4\The address of a 1-word location in low memory that contains two RAD50 identifying characters. The SHOW UMR command displays these characters to identify this permanent UMR allocation. (In distributed handlers, is the device handler name.) The monitor must have continuous access to the specified memory location.

If ALLUMR is called more than once for this handler, R4 in subsequent calls must contain a different address in low memory for each call. The 1-word location contents can be, but do not need to be, the same two RAD50 characters.)

The contents of R3 and R5 are not defined or preserved across the call. Within the device handler FETCH/LOAD code, call the ALLUMR routine. On return from ALLUMR:

If the carry bit is clear: (UNNUMBERED) R1 contains bits 0--15 of the 18-bit UNIBUS virtual address of the internal buffer. R2 contains bits 16 and 17 of the 18-bit UNIBUS virtual address of the internal buffer. The handler uses the address returned by ALLUMR (or some offset from that address) to program the device for DMA I/O to/from the handler internal buffer.

If the carry bit is set, insufficient UMRs are available for allocation and the handler must fail its load code.

Once you have successfully called and returned from ALLUMR, your handler code should confirm that the FETCH/LOAD succeeded. If the fetch/load operation fails after successfully returning from ALLUMR, you must call RLSUMR to free the allocated UMRs. (Explicitly Obtaining Temporary UMRs (GETUMR)\psd_ub_getumr_sec)

Device handlers that support nonstandard .SPFUN I/O DMA operations to or from a user buffer must call GETUMR to explicitly obtain temporary UMRs to service those requests. The temporary UMRs are automatically released after the request is serviced. The handler uses the GETUMR routine, described in this section, to obtain the UMRs. Be sure to call GETUMR before removing the queue element from the handler's current queue element (xxCQE) list.

The handler supports explicit UMR allocation for nonstandard special functions by using the .DRBEG (NSPFUN=nspsym) parameter and a list of those functions. The (nspsym) argument is a unique symbol name that is the same as the label at the list of those functions. The list is structured in the same manner as that used for the .DRSPF (extension table) method. However, unlike the .DRSPF macro, no pointer to the list resides in block 0 of the handler and the concept of special function (type) has no meaning and is not included.

The list of nonstandard special functions must continuously reside in the low-memory portion of the handler whenever the handler is loaded. Also, the handler must call GETUMR (with a word count of zero) even when a listed nonstandard special function performs no I/O and no UMRs are needed.

Defining special functions for explicit UMR allocation is illustrated in the example program in this section.

The handler calls the GETUMR routine, which resides in UB, to obtain temporary UMRs. You reference the UB entry vector through the $H2UB fixed offset (460) in RMON. The GETUMR routine is located at the address pointed to by $H2UB (offset 0).

Use the following procedure to explicitly obtain temporary UMRs: (NUMBERED) Before calling GETUMR, set up the following registers:

(2\8) (Register\Contents) (R0\Number of words to be transferred; the word count. If no DMA I/O is to be performed by this request, R0=0.) (R1\Contents determined by R3:
(2\6) (R3 = 0\R1 contains the Q.PAR value that is calculated by the handler. RMON cannot calculate the Q.PAR value because the special function's (buf) parameter contains a nonstandard argument.) (R3 = 1\R1 contains bits 0-15 of the 22-bit physical memory base address (word aligned).) ) (R2\Contents determined by R3:
(2\6) (R3 = 0\R2 is unused.) (R3 = 1\R2 contains bits 16-21 of the 22-bit physical memory base address.) ) (R3\Contents indicate the type of address being specified:
(2\6) (R3 = 0\Address is PAR value, specified in R1. R2 is not used.) (R3 = 1\Address is 22-bit physical address, specified in R1 and R2.) ) (R4\Queue element offset Q.BLKN.)

The contents of all unused registers are not defined or preserved across the call. Within the device handler code that processes nonstandard special functions, call the GETUMR routine. On return from GETUMR: (UNNUMBERED) If the carry bit is clear, the contents on return for R1 and R2 are defined by the contents of R3 when GETUMR was called. If GETUMR is called with R3 = 0, on return, R1 contains the new Q.PAR equivalent value and R2 is not defined. If GETUMR is called with R3 = 1, on return, R1 contains bits 0--15 and R2 contains bits 16 and 17 of the 18-bit UNIBUS virtual address. If the carry bit is set, UB is unable to immediately allocate the requested UMRs for the queue element and the handler should simply return to the monitor. (Explicitly Releasing Permanent UMRs (RLSUMR)\psd_ub_rlsumr_sec)

All permanent UMRs that are allocated by a handler must be explicitly released by the handler when the handler is unloaded. A corresponding RLSUMR routine must be called for each ALLUMR routine that was called.

The RLSUMR routine, which resides in UB, releases permanent UMRs. You reference the UB entry vector through the $H2UB fixed offset (460) in RMON. The RLSUMR routine is offset 2 words ($H2UB+4) from the address pointed to by $H2UB.

Use the following procedure to explicitly release permanent UMRs: (NUMBERED) Before calling RLSUMR, set up the following register:

(2\10) (Register\Contents) (R1\The address of the 2-character RAD50 device handler name specified in R4 of the corresponding ALLUMR routine. (The contents of RLSUMR R1 match the contents of corresponding ALLUMR R4.))

The contents of R0 and R2--R5 are not defined or preserved across the call. Within the device handler RELEASE/UNLOAD code, call the RLSUMR routine.

On return from RLSUMR, all UMRs that were permanently allocated to the handler by the corresponding ALLUMR routine are released. (Example (Skeletal) Handler\psd_ub_examp_sec)

The following example skeletal handler illustrates the macros and routines required to support UMRs. (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SBTTL CONDITIONAL ASSEMBLY SUMMARY ;+ ;COND ; ; MMG$T = 1 Std conditional (XM only) ; TIM$T Std conditional (no code effects) ; ERL$G Std conditional (no code effects) ;- .MACRO ... .ENDM .MCALL .DRDEF .ASSUME .ADDR .DRSPF .LIBRARY "SRC:SYSTEM" .MCALL .SYCDF .FIXDF .HANDF .UBVDF .P1XDF .SYCDF .FIXDF .HANDF .UBVDF .P1XDF ; UB Definitions ; XB internal DMA buffer equates BUFSIZ =: 20000 ; Size of XB internal DMA buffer NOUMRS =: ; Number of permanent UMRs required ; Special function definitions ; All special functions are DMA except for FN$SIZ and FN$MPM. ; FN$WRT AND FN$RED go in UBTAB. FN$REP uses a permanent UMR. ; FM$NSP is nonstandard so it goes in UBNTAB. FN$MPM =: 370 ; Illustrate use of $MPMEM (not DMA) FN$NSP =: 371 ; Nonstandard SPFUN (DMA to ; user buffer) FN$SIZ =: 373 ; Get device size (not DMA) FN$REP =: 374 ; Force reread of replacement table FN$WRT =: 376 ; Absolute write (no bad block) FN$RED =: 377 ; Absolute read (replacement) .DRSPF ; Illustrate use of $MPMEM .DRSPF ; Nonstandard SPFUN (DMA to ; user buffer) .DRSPF ; Get device size .DRSPF ; Force reread of replacement table .DRSPF ; Absolute write (no bad block) .DRSPF ; Absolute read (replacement) ; DRDEF'S serial argument must be set equal to yes since XB calls ; GETUMR and depends on receiving queue elements from RMON in serial order. ; Calls to GETUMR can interfere with the serial ordering of queue elements ; unless "SERIAL = YES" is specified here. .DRDEF XB,0,SPFUN$,0,0,0,DMA=YES,PERMUMR=NOUMRS,SERIAL=YES .DRPTR FETCH=FETCH,LOAD=FETCH,RELEASE=RELEAS,UNLOAD=RELEAS .DREST CLASS=DVC.NL ; Start of handler .DRBEG XB,SPFUN=UBTAB,NSPFUN=UBNTAB XBBASE=XBSTRT+6 BR BEGIN ; Branch around data area ; Data area $ENTPT: .WORD 0 ; Pointer to $ENTRY table $PNMPT: .WORD 0 ; Pointer to $PNAME table H2UB: .WORD 0 ; Pointer to UBVECT XBSLOT: .WORD 0 ; XB'S offset in device tables XBENT: .WORD 0 ; XB'S $ENTRY table entry pointer XBPNA: .WORD 0 ; XB'S $PNAME table entry pointer ;+ ; Definition of the handler internal buffer and the words that are ; used to program DMA devices that transfer data to and from it. ;- XBDBUF: .WORD BUFSIZE ; XB DMA buffer - it is ; mapped by permanent UMRs BUFADH: .WORD 0 ; Bits 0-15 of UNIBUS virtual ; Pointer to XBDBUF BUFADL: .WORD 0 ; Bits 16-18 of UNIBUS virtual ; Pointer to XBDBUF ; Table of standard DMA SPFUNs that do DMA transfers to areas of ; memory not mapped by XB's permanent UMRS. UB will intercept these requests ; and assign temporary UMRs to them in the same manner as for .READx and ; .WRITx requests. UBTAB: .DRSPF -, ; Absolute write, no bad block .DRSPF -, ; Absolute read (replacement) .WORD 0 ; Table terminator ; Table of nonstandard DMA SPFUNs that do DMA transfers to areas of ; memory not mapped by XB's permanent UMRs. XB MUST explicitly allocate ; UMRs for the nonstandard SPFUNs listed here by calling UB's GETUMR ; routine. If no DMA transfer will take place (because of error, for ; example) XB should call GETUMR with a word count of 0. IF XB processes ; a nonstandard DMA SPFUN listed in UBNTAB without calling GETUMR, ; the job's I/O stream will hang. UBNTAB: .DRSPF -, ; DMA to user buffer .WORD 0 ; Table terminator BEGIN: MOV XBCQE,R4 ; Point to current queue element MOVB Q$FUNC(R4),R2 ; Get function code / unit number CMPB R2,#FN$MPM ; Dispatch to function routine BEQ FNMPM CMPB R2,#FN$NSP BEQ FNNSP CMPB R2,#FN$SIZ BEQ FNSIZ CMPB R2,#FN$REP BEQ FNREP CMPB R2,#FN$WRT BEQ FNWRT CMPB R2,#FN$RED BEQ FNRED TST R2 ; Normal request? BNE XBEXIT ; No, unknown SPFUN BR XBRDWR ; Yes, process read,write ... ; Routines to perform SPFUN operations ; at entry, R4 -> queue element FNNSP: MOV #4000,R0 ; R0 = word count MOV Q$PAR(R4),R1 ; Get address from QEL MOV @#$SYPTR,R3 ; Get start of RMON MOV $H2UB(R3),R5 ; R5 = UB entry vector CLR R3 ; Address type is PAR value CALL UB.GET(R5) ; Try to get UMRS ; (Note that at time of call, the ; Queue element must be on xxCQE) BCS RETURN ; Unable to get UMRs-do simple RETURN ... ; Got UMRs, initiate transfer BR XBEXIT ; DRFIN because this is an example ; Handler and there are really no ; Interrupts associated with it. ; If there were, the DRFIN would be ; Issued at interrupt time when ; The DMA transfer is finished. ; This is true for the other SPFUN ; Routines below, as well. FNMPM: ; This routine illustrates how to call $MPMEM. $MPMEM is used ; to map KT-11 virtual addresses (as described by Q.MEM and Q.BUFF ; offsets in the queue element) to 18 or 22-bit physical addresses. ; $MPMEM must be used for this purpose instead of $MPPHY when the ; handler has DMA = YES. (When DMA = NO, the handler may use ; either $MPMEM or $MPPHY.) ; ; At entry: R4 -> Q.BLKN offset in queue element MOV @#$SYPTR,R3 ; Get start of RMON MOV P1$EXT(R3),R3 ; R3 -> $P1EXT MOV R4,R5 ; Make R5 -> 5TH word (Q.BUFF) of CMP (R5)+,(R5)+ ; Queue element CALL $MPMEM(R3) ; Map KT-11 virtual to physical MOV (SP)+,R2 ; R2 = low 16 bits physical address MOV (SP)+,R3 ; R3 = HIGH 2 (OR 6) bits physical ; address ... ; Fall through to DRFIN FNSIZ: FNREP: FNWRT: FNRED: XBRDWR: XBEXIT: .DRFIN XB ; Return to monitor, done with ; queue element RETURN: RETURN ; Return to monitor, not done with ; queue element XBINT: ; Dummy ISR for XB ... .DREND XB .SBTTL FETCH/LOAD CODE ;+ ; FETCH ; ; ENTRY: R0 = Starting address of this handler service routine. ; R1 = Address of GETVEC routine. ; R2 = Value $SLOT*2. (length of the $PNAME table in bytes.) ; R3 = Type of entry. ; R4 = Address of SY read routine. ; R5 -> $ENTRY slot for this handler. ; ;- FETCH: MOV R5,R1 ; Save PTR to XB'S $ENTRY slot MOV @R1,R0 ; Get address of XBLQE MOV @#$SYPTR,R4 ; Get start of RMON MOV $H2UB(R4),R3 ; R3 = UBVECT pointer MOV R3,(R0) ; H2UB = address of UBVECT MOV $PNPTR(R4),R3 ; R3 = RMON offset to PNAME table ADD R4,R3 ; R3 -> PNAME table address MOV R3,<$PNMPT-XBBASE>(R0) ; $PNMPT -> PNAME table address ADD R2,R3 ; R3 -> $ENTRY table MOV R3,<$ENTPT-XBBASE>(R0) ; $ENTPT -> $ENTRY table MOV R5,(R0) ; XBENT -> XB'S $ENTRY table entry SUB R2,R5 ; R5 -> XB'S $PNAME table entry MOV R5,(R0) ; XBPNA -> XB'S $PNAME table entry ;+ ; Allocate permanent UMRs to point into XB's internal DMA buffers, ; XBDBUF and XBFILL, and get the UNIBUS virtual address. ;- MOV #,R1 ; R1 = LOW 16 bits of DMABUF address ADD R0,R1 ; CLR R2 ; R2 = HIGH 6 Bits of DMABUF address MOV (R0),R4 ; R4 -> PNAME entry for XB MOV (R0),R5 ; Get UB entry address MOV R0,-(SP) ; Save XB starting address MOV #NOUMRS,R0 ; R0 = number of UMRS required CALL UB.ALL(R5) ; Call ALLUMR MOV (SP)+,R0 ; Restore XB starting address BCS 30$ ; Couldn't get UMR, fail the load MOV R1,(R0) ; Store UNIBUS virtual address low MOV R2,(R0) ; Store UNIBUS virtual address high CLC ; Load succeeded 30$: RETURN ;+ ; RELEAS ; ; Routine to unload XB ; ; Entry: same as for load. ; ;- .ENABL LSB RELEAS:: MOV R5,R1 ; R1 = $ENTRY slot for DM SUB R2,R1 ; R2 -> $PNAME SLOT for DM MOV @#$SYPTR,R4 ; Get start of RMON MOV $H2UB(R4),R5 ; R5 = UB entry vector CALL UB.RLS(R5) ; Release UMRs RETURN ; And exit .END (VM (Virtual Memory Handler)\psd_vm_sec)

This section contains specific programming information for the VM device. The (int_book) contains complete information on using the VM device. You should read the VM chapter in the (int_book) first.

The VM handler installation code determines the size of memory when the handler is installed. After determining the size of memory, the handler installation code reserves all extended memory above the handler's base address. The handler does not need to perform this operation each time it is loaded, thereby speeding the handler load process.

If you do not want to use VM and do not want VM to reserve memory for its own use, you have several options. You can remove the VM handler from your system disk so that it will not be installed when you bootstrap your system. You can set the base address above the high limit of available memory, which will prevent handler installation. Or, you can put a command in your startup command file to remove the VM handler from your system after the bootstrap has installed it. Otherwise, the VM handler installation code will always reserve extended memory for its own use, thereby making it unavailable to your program.

The base address ((n)) used in the SET VM BASE=n command is the desired base address in octal, divided by 100(8). For example, the value 1600 sets the base address at the 28K-word address boundary, or 10000 sets the base address at the 128K-word address boundary; any other value between 1600 and the physical memory high limit is also acceptable. Lowering the value at which you set the VM base increases the region size. The table below gives a list of some K-word memory sizes and corresponding values for n. (#)

(2\8) (K-words\##N) (##28\##1600) (##32\##2000) (##64\##4000) (##96\##6000) (#128\#10000) (#256\#20000) (#512\#40000) (1024\100000)

(PSDVM22_FIG) shows a 22-bit system with a VM base address of 10000 (128K words).

(VM Handler in a 22-Bit System\PSDVM22_FIG) (POSTSCRIPT\S559c2PSDVM22_FIG.EPS\18)

If you are using a mapped monitor and your hardware does not have 22-bit addressing, the default VM handler will not install; you will have to change the base address to a lower value before using VM with your mapped system. You can still use extended memory for both an extended memory program and a VM volume, but the space available for one will be reduced by the space occupied by the other. Refer to (PSDVM18_FIG), showing an 18-bit system with the VM base address set to 3600 (60K words).

(VM Handler in an 18-Bit System\PSDVM18_FIG) (POSTSCRIPT\S559c2PSDVM18_FIG.EPS\12) (XC and XL (Communication Port (VTCOM) Handlers)\psd_xcxl_sec)

XC and XL are non-file-structured communications handlers. They support the virtual terminal communication package, VTCOM. However, their design does not preclude their use in other communication programs. The XC handler supports the CTI Bus-based computer communication port. The XL handler supports a variety of ports. See the RT--11 Software Product Description (SPD), included with your documentation set, for a list of supported ports.

XC or XL (depending on your system) is required when you use VTCOM.

XC and XL support the VTCOM utility, using .READx, .WRITx, and .SPFUN programmed requests. (.READx and .WRITx Support)

The XC and XL handlers support the .READ, .READC, .READW, .WRITE, .WRITC, and .WRITW requests. You use the .READx and .WRITx requests with XC and XL handlers as described in the (sml_book). Note, however, the following additional information: (unnumbered) You should specify the value 0 in the (blk) argument for the first request to XC or XL. All subsequent calls should specify a nonzero value for the (blk) argument. NULL characters are ignored by XC and XL during both .READs from and .WRITEs to the handlers. XC and XL pass only 7-bit data. The eighth (high-order) bit is stripped from each byte. (Special Functions (.SPFUN) Support)

In general, the XC and XL handlers support the .SPFUN request as described in the (sml_book). Note, however, the following general information: (unnumbered) You should specify the value 0 in the (blk) argument for the first request to XC or XL. All subsequent calls should specify a nonzero value for the (blk) argument. NULL characters are ignored by the XC and XL handlers; NULL characters are not stored or sent. However, SF.SRD (code 203) uses a NULL character to signal the end of available data (see SF.SRD in (xcxlspun_tab)). XC and XL pass only 7-bit data. The eighth (high-order) bit is stripped from each byte.

The XC and XL handlers support the following special function codes. Specific information about using each special function is included in the description for that request.

(XC/XL Special Function Codes\XCXLSPUN_TAB) (3\4\6) (Code\Name\Description) (201\SF.CLR\Resets the internal flag, indicating a received XOFF. Then sends an XON to the host.

Example: (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SPFUN #area,#chan,#SF.CLR,#buf,#wcnt,#blk[,#crtn][,BMODE=str][,CMODE=str] ) (202\SF.BRK\Sets or resets the state of the BREAK bit in the serial interface. Transition of the BREAK bit from 0 to 1 to 0 can get the attention of certain communications devices, such as terminal concentrators.

The (wcnt) argument is a flag that indicates whether the BREAK bit should be set or reset. Specify a value of 1 for the (wcnt) argument to set the BREAK bit; specify 0 to reset it. Digital recommends you use some time delay between turning the bit on and turning it off; do that by sending one or two characters.

Examples:

To turn on (set) the BREAK bit: (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SPFUN #area,#chan,#SF.BRK,#buf,#1,#blk[,#crtn][,BMODE=str][,CMODE=str]

To turn off (reset) the BREAK bit: (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SPFUN #area,#chan,#SF.BRK,#buf,#0,#blk[,#crtn][BMODE=str][,CMODE=str] ) (203\SF.SRD\Performs a special read from the handler. The (wcnt) argument specifies the number of bytes to be read. The read is completed when one of the following conditions is met: (unnumbered) The number of bytes specified in the (wcnt) argument have been transferred. The available characters have been transferred, when the number of available characters was less than the value specified in the (wcnt) argument. One character has been transferred, when no characters were available when the request was issued.

The byte following the last transferred character contains a NULL. You must allow for that NULL byte in your buffer.

Example:

The following example reads no more than six (but at least one) characters from XC or XL and places them in the buffer RCVBUF. RCVBUF must be at least seven bytes in length to receive the six characters and the NULL byte. (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SPFUN #area,#chan,#SF.SRD,#RCVBUF,#6,#blk[,#crtn][,BMODE=str][,CMODE=str] ) (204\SF.STS\Returns the driver status in the first word of the specified buffer. SF.STS always returns one word.

The high byte of the returned word contains the driver support level. The driver support level number will be updated as support is changed in the XC and XL handlers. Programs should verify operation with an established driver support level. The current (V5.6) driver support level is 18(10).

The low byte contains the status of two internal flags and a modem control signal. The significant bits of the low byte are:

(2\3) (Bit\Meaning) (0\Set if an XOFF has been sent to the host.) (1\Set if an XOFF has been received from the host.) (2\Set if the CLEAR TO SEND line is set.) (3\Set if Carrier Detect is high (on); clear if Carrier Detect is low (off).) (4\Set if Ring Indicator is high (on); clear if Ring Indicator is low (off).) (5-7\Reserved.)

Example:

The following example returns the driver support level in the high byte and the status of internal flags in the low byte of the 1-word buffer STATUS. (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SPFUN #area,#chan,#SF.STS,#STATUS,#1,#blk[,#crtn][,BMODE=str][,CMODE=str] ) (205\SF.OFF\Sets a flag that disables interrupts when the program exits. Digital recommends you issue .SPFUN SF.OFF before your program exits.

Example: (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SPFUN #area,#chan,#SF.OFF,#buf,#wcnt,#blk[,#crtn][,BMODE=str][,CMODE=str] ) (206\SF.DTR\Sets or resets the state of the DTR modem control signal. Setting (asserting) DTR can cause modems to answer an incoming call. Resetting (deasserting) DTR can cause modems to terminate a current call. DTR can also get the attention of certain communications devices, such as the Mini-Exchange. Specify a value of 1 for the (wcnt) argument to set the DTR control signal; specify 0 to reset the DTR control signal.

Not all interfaces support the DTR control signal. On interfaces that do not support DTR, the setting or resetting of DTR has no effect.

Example:

The following example sets the DTR control signal: (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SPFUN #area,#chan,#SF.DTR,#buf,#1,#blk[,#crtn][,BMODE=str][,CMODE=str]

The following example resets the DTR control signal: (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .SPFUN #area,#chan,#SF.DTR,#buf,#0,#blk[,#crtn][,BMODE=str][,CMODE=str] ) (EOF (End-of-File) Detection)

A CTRL/Z within data being read is treated as end-of-file (EOF) by the .READ request. At least two .READ requests are necessary to return the EOF error (carry bit set and byte 52 containing error code 0). The first .READ request transfers into your buffer all data up to (but not including) the CTRL/Z. The rest of the buffer is padded with nulls. A second .READ request is required to get the EOF error. Subsequent .READ requests can return additional characters. (The following gives you a 10 point code-example font) defcodexamplefonttenpointmono (End of chapter.)