FloppyChannel.mesa
Copyright Ó 1981, 1982, 1985, 1987 by Xerox Corporation. All rights reserved.
Tim Diebert: May 7, 1987 9:27:03 am PDT
DIRECTORY
Device USING [Type];
FloppyChannel: DEFINITIONS = BEGIN
Basic serial read/write access to a floppy disk drive.
TYPES
Handle: TYPE [2];
nullHandle: READONLY Handle;
Density: TYPE = {single, double};
Drive: TYPE = CARDINAL;
Format: TYPE = {IBM, Troy};
HeadCount: TYPE = [0..256);
SectorCount: TYPE = [0..256);
Attributes: TYPE = RECORD [
deviceType: Device.Type,
Indicates what type of drive is connected to the controller.
numberOfCylinders: CARDINAL,
Number of cylinders available for recording on the drive connected to the controller.
numberOfHeads: HeadCount,
Number of read/write heads available for recording on the drive connected to the
controller.
maxSectorsPerTrack: SectorCount,
Maximum number of sectors per track (based on context setting)
formatLength: CARDINAL,
Length in words of the buffer that the client must supply in order to format a track.
ready: BOOLEAN,
Whether drive is ready (contains a diskette)
diskChange: BOOLEAN,
Whether drive has gone from ready to not-ready
(door open), or from not-ready to ready, one or more times since the last
operation was performed.
twoSided: BOOLEAN];
(If ready=TRUE) Whether diskette currently installed has data on both sides
Context: TYPE = RECORD [
protect: BOOLEAN,
Software write protect available to the client. The actual write protect status
is a logical OR of this variable and the physical signal being returned from the
drive.
format: Format,
Client's selection of the format type; either an IBM compatible format (which
includes STAR), or the Xerox 850 (Troy) format.
density: Density,
Selection of either FM (single density) or MFM (double density) recording. This
is an available selection when formatting a new diskette. When accessng a
previously recorded diskette, the client must provide the correct setting.
sectorLength: CARDINAL [0..1024)];
Length in words of the sectors on the current track. The value must come from
a valid set defined as {64, 128, 256, 512} for IBM format and {1022} for Troy
format.
DiskAddress: TYPE = MACHINE DEPENDENT RECORD [
cylinder (0): CARDINAL,
must be IN [0..numberOfCylinders)
head (1: 0..7): HeadCount,
must be IN [0..numberOfHeads)
sector (1: 8..15): SectorCount];
must be IN [1..{value depends on sectorLength}]
Status: TYPE = MACHINE DEPENDENT {
goodCompletion,
operation has completed normally
diskChange,
The disk drive has apparently gone from ready to not-ready
(door open), or from not-ready to ready, one or more times since the last
operation was performed.
notReady,
drive is not ready
cylinderError,
can't locate specified cylinder
deletedData,
The sector contained a deleted data address mark.
recordNotFound,
can't find record for specified disk address
headerError,
bad checksum in header
dataError,
bad checksum in data
dataLost,
sector contained more data than expected (from context)
writeFault,
disk is write-protected (hardware or from context)
otherError (LAST[CARDINAL])}; --reserve 16 bits for expansion
unexpected software or hardware problem
ERRORS
Error: ERROR [type: ErrorType];
ErrorType: TYPE = {invalidDrive, invalidHandle};
PROCEDURES
The following procedures are used to gain access to a drive.
GetNextDrive: PROCEDURE [lastDrive: Drive] RETURNS [nextDrive: Drive];
nullDrive: Drive = LAST[CARDINAL];
Stateless enumerator of the drives on a system element. Begins with lastDrive
equal to nullDrive and ends when nextDrive is returnsed as nullDrive.
GetHandle: PROCEDURE [drive: Drive] RETURNS [handle: Handle];
Gets a Handle for a drive. A handle is only valid for as long as the drive
does not change state (i.e., go from ready to not-ready).
InterpretHandle: PROCEDURE [handle: Handle] RETURNS [drive: Drive];
Given a handle, returns the identity of the drive referred to by that drive.
The following six drive-access procedures include seek, error retry, and wait for
completion or error. Operations in a single call may not cross over from an IBM-format
track 0 to the rest of the diskette; no check is made for this.
ReadSectors: PROCEDURE [handle: Handle, address: DiskAddress, buffer: LONG POINTER,
count: CARDINAL ← 1, incrementDataPtr: BOOLEANTRUE]
RETURNS
[status: Status, countDone: CARDINAL];
Reads the specified number of sectors from the diskette beginning at the specified
disk address.
WriteSectors: PROCEDURE [handle: Handle, address: DiskAddress, buffer: LONG POINTER, count: CARDINAL ← 1, incrementDataPtr: BOOLEANTRUE]
RETURNS
[status: Status, countDone: CARDINAL];
Writes the specified number of sectors with data address marks to the diskette
beginning at the specified disk address.
WriteDeletedSectors: PROCEDURE [handle: Handle, address: DiskAddress,
buffer: LONG POINTER, count: CARDINAL ← 1, incrementDataPtr: BOOLEANTRUE]
RETURNS
[status: Status, countDone: CARDINAL];
Writes the specified number of sectors with deleted data address marks to the
diskette beginning at the specified disk address.
ReadID: PROCEDURE [handle: Handle, address: DiskAddress, buffer: LONG POINTER]
RETURNS
[status: Status];
Reads to first encountered record ID from the specified disk address. The value
of sector in the disk address is ignored.
Nop: PROCEDURE [handle: Handle] RETURNS [status: Status];
Does a regular drive-access operation without data transfer and returns a valid status.
GetContext: PROCEDURE [handle: Handle] RETURNS [context: Context];
Returns the current settings of the context.
GetDeviceAttributes: PROCEDURE [handle: Handle] RETURNS [attributes: Attributes];
Returns attributes as defined above.
SetContext: PROCEDURE [handle: Handle, context: Context] RETURNS [ok: BOOLEAN];
Sets context as defined above and returns a BOOLEAN indicating whether the settings were accepted.
FormatTracks: PROCEDURE [handle: FloppyChannel.Handle, start: FloppyChannel.DiskAddress,
trackCount: CARDINAL]
RETURNS
[status: FloppyChannel.Status, countDone: CARDINAL];
Formats the specified tracks.
END...