TapeOps:
CEDAR
DEFINITIONS =
BEGIN
ROPE: TYPE ~ Rope.ROPE;
maxBufferLength: INT ~ 16384;
Density: TYPE ~ {NRZI800, PE1600};
DriveNumber: TYPE ~ [0..7];
RetryCount: TYPE ~ [0 .. 256);
ErrorCode:
TYPE ~
{
DataError, -- Error in reading or writing the data on the tape.
NameLookUpError, -- Server name specified could not be found.
ServerControlStreamAbort, -- The BSP connection with the Tape Server was broken.
ServerProtocolError, -- The Server made a protocol error that could not be recovered from. See Implimentor if this error is encountered.
TapeOperationError, -- The Tape Server could not complete the operation because the tape drive status was not as expected.
TapeUserError -- This error is raised when an operation could not be performed because of an inapropriate user operation like Tape Not Mounted, Write Protect Ring Out on a Write, Drive Number In use or SetDensity attempted while tape was not at BOT.
};
The only errors that cause the tape connection not to established or to be broken are NameLookUpError, ServerControlStreamAbort and ServerProtocolError.
TapeOpsError: ERROR [ec: ROPE, code: ErrorCode];
TapeHandle: TYPE ~ REF TapeHandleRec;
-- Status from tape server
TapeStatusIndex:
TYPE =
MACHINE
DEPENDENT
{
RDY(0), --100000 ReaDY. Unit loaded, Tape not in motion
ONL(1), -- 40000 ON Line. Unit loaded, Tape may be in motion
RWD(2), -- 20000 ReWinDing. Unit is rewinding
FPT(3), -- 10000 File ProTect. Write Ring removed.
BOT(4), -- 4000 Beginning Of Tape. Tape is at load point
EOT(5), -- 2000 End Of Tape. EOT marker was crossed in a forward direction
FMK(6), -- 1000 End Of File. Last record (R/W) was an EOF mark (Tape Mark)
NRZI(7), -- 400 NRZI Status is present in the drive. 800: BOOL,s per inch mode.
errHE(8), -- 200 Hard Error. A non recoverable error occured during R/W operation
errSE(9), -- 100 Soft Error. A correctable error occured during R/W operation.
errDL(10), -- 40 Data Late. Write or Read buffer went empty or overflowed
errRDP(11), -- 20 Read Data Parity. A read parity error occured.
errICL(12), -- 10 InCorrect Length on write
errHDW(13), -- 4 HarDWare ERRor. THe controller microcode detected an error.
errWFP(14), -- 2 Write on File Protected reel. (FPT & Write-Op)
errCMD(15) -- 1 ComManD ERror. Unkown command type.
};
FBool: TYPE = BOOL ← FALSE;
TapeStatus: TYPE = PACKED ARRAY TapeStatusIndex OF FBool;
-- Procs
OpenDrive:
PROC [serverName:
ROPE, driveNumber:
NAT ← 0, density: Density ← PE1600,
justOpen:
BOOL ←
FALSE]
RETURNS [tapeHandle: TapeHandle];
Opens a connection with the MagTapeServer specified by the serverName and driveNumber parameters, if justOpen is FALSE a Rewind operation is performed and the density is established for subsequent operations.
Raises TapeOpsError with TapeUserError, or TapeOperationError. If the error is raised no TapeHandle is created.
CloseDrive:
PROC [tapeHandle: TapeHandle];
CloseDrive releases the tape drive back to the server, and closes the BSP connection. The tape is left in position.
GetStatus:
PROC [tapeHandle: TapeHandle]
RETURNS [status: TapeStatus];
Returns the current status of the Tape Drive in use. If all bits are off it is an indication that the tape is mounted but not ReaDY. If both the BOT and EOT markers are on at the same time, it is an indication that the tape is not loaded.
Raises TapeOpsError with code ServerProtocolError
SetRetry:
PROC [tapeHandle: TapeHandle, retryCount: RetryCount ← 4];
Sets the number of times that a Data operation is to be retried by the server.
SetDensity:
PROC [tapeHandle: TapeHandle, density: Density];
Sets the tape density {800 or 1600 bpi} at which operations are to be performed. This command can only be issued at BOT since there is extra data written at the front of a 1600 bpi tape to indicated its density.
Rewind:
PROC
[tapeHandle: TapeHandle, waitForCompletion: BOOL ← FALSE] RETURNS [status: TapeStatus];
Rewind the tape. If waitForCompletion is true the procedure will not return until the operation was completed or the op timed out.
Unload:
PROC [tapeHandle: TapeHandle]
RETURNS [status: TapeStatus];
Unloads the tape from the transport. It does not close the server connection.
ReadRecord:
PROC [tapeHandle: TapeHandle, buffer:
REF
TEXT ←
NIL]
RETURNS [tapeMark: BOOL, record: REF TEXT, status: TapeStatus];
Reads the tape into the buffer supplied, if it is alrge enough to hold the record, and returns this buffer or a NEW one, if buffer was too small, and tapeMark if an end of file mark was encountered on the tape.
WriteRecord:
PROC
[tapeHandle: TapeHandle, writeData: REF READONLY TEXT] RETURNS [status: TapeStatus];
Writes the data in writeData on the tape. The length of the data is writeData.Length.
WriteFileMark:
PROC [tapeHandle: TapeHandle]
RETURNS [status: TapeStatus];
Writes a file mark onto the tape.
ForwardSpaceFile:
PROC [tapeHandle: TapeHandle]
RETURNS [status: TapeStatus];
Moves the tape in a forward direction until a tapemark has been read. If there is no tapemark on the tape, the tape will run-away until the EOT marker is encountered.
ForwardSpaceRecord:
PROC [tapeHandle: TapeHandle]
RETURNS [status: TapeStatus];
Moves the tape forward 1 record. The data is NOT read.
BackSpaceFile:
PROC [tapeHandle: TapeHandle]
RETURNS [status: TapeStatus];
Moves the tape in a backward direction until 1 tapemark has been read. If there is no tapemark on the tape, the tape will proceed until the BOT marker is encountered.
BackSpaceRecord:
PROC [tapeHandle: TapeHandle]
RETURNS [status: TapeStatus];
Moves the tape backward 1 record. The data is NOT read.
-- Internal Data Structures. For wizards only.
TapeHandleRec:
TYPE ~
RECORD
[
serverName: ROPE ← NIL,
commPortAddress: PupTypes.PupAddress,
commStream: IO.STREAM,
versionString: ROPE ← NIL,
driveNumber: NAT ← 0,
density: Density ← PE1600,
densityIsSet: BOOL ← FALSE,
status: TapeStatus ← ALL[FALSE],
open: BOOL ← FALSE,
buffer: REF TEXT ← NIL
];
END.