-- SA800Face.mesa: (last edited by: Forrest, September 18, 1980 11:55 AM)

DIRECTORY PilotDisk USING [Handle];
SA800Face: DEFINITIONS =
BEGIN
-- Processor independent access to a floppy disk drive of the SA800 family. To date this includes the SA800/801 and the SA850/851. Each controller may have one or more drives, each drive may have one or more recording surfaces (read/write heads and recording surfaces are synonymous). Currently the SA800/801 is known to be single sided while the SA850/851 may be single or double sided.
-- EXPORTED VARIABLES
initialAllocationLength: READONLY CARDINAL; --Length in words of a block of resident memory allocated for internal use by the device face implementation. Alignment: Quadword. Lifetime: Permanent.
operationBlockLength: READONLY CARDINAL; --Length in words of the Operation block that must be allocated from resident memory to create any of the asynchronous functions defined by Initiate and Format. Alignment: Quadword. Lifetime: Duration of the operation.
nullDeviceHandle: READONLY DeviceHandle; --Null device handle used in device enumeration.

-- TYPES AND PROCS
DeviceHandle: TYPE = PilotDisk.Handle;
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: {IBM, Troy}, --Client’s selection of the format type; either an IBM compatible format (which includes STAR), or the Xerox 850 (Troy) format.
density: {single, double}, --Selection of either FM (single density) or MFM (double density) recording. This is an available selection when formatting a new disketted. When accessng a previously recorded diskette, the client must provide the correct setting. (Note that track00 on IBM format diskettes and all tracks of Troy format diskettes will be single density.)
sectorLength: CARDINAL]; --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.
SetContext: PROC [device: DeviceHandle, context: Context] RETURNS [ok: BOOLEAN];
--Sets context as defined above and returns a BOOLEAN indicating whether the setting where accepted.
GetContext: PROC [device: DeviceHandle] RETURNS [context: Context];
--Returns the current settings of the context.
Attributes: TYPE = RECORD [
deviceType: {SA800, SA850}, --Indicates what type of drive is connected to the controller.
numberOfCylinders: [0..256), --Number of cylinders available for recording on the drive connected to the controller.
numberOfHeads: [0..256), --Number of read/write heads available for recording on the drive connected to the controller.
trackLength: CARDINAL]; --Length in words of the buffer that the client must supply in order to format the diskette.
GetDeviceAttributes: PROC [device: DeviceHandle] RETURNS [attributes: Attributes];
--Returns attributes as defined above.
-- An operation is required for all IO.
-- If function IN [nop..recalibrate], only the device and function fields are of use. All other fields are considered to be UNDEFINED and may be modified by implementations as they see fit.
-- if function IN [readSector..readID]) the count is taken to be the number of sectors in the IO operation. if function=formatTrack, diskAddress.sector is ignored and count is taken to be a track count.

OperationPtr: TYPE = LONG POINTER TO Operation;
Operation: TYPE = MACHINE DEPENDENT RECORD [
device (0): DeviceHandle,
function (1: 0..2): Function,-- ignored if submitted by FormatTrack
unused (1: 3..14): UNSPECIFIED [0..4096) ← 0,-- always ignored
incrementDataPointer (1: 15..15): BOOLEAN,-- ignored if nop, recal, recovery
address (2): DiskAddress,-- ignored if nop, recal, recovery. Sector is ignored in FormatTrack operations.
buffer (4): Buffer,-- ignored if nop, recal, recovery
count (7): CARDINAL];-- ignored if nop, recal, recovery. Number of tracks to format if FormatTrack; number of sectors to transfer otherwise.
Function: TYPE = {
nop,--Does not transfer any data but does create an asychronous operation and returns a valid endng status.
recalibrate,--Request the read/write heads step out until track00 is sensed.
recovery,--Performs extended error recovery procedure
readSector,--Reads one sector from the diskette at the specified disk address.
writeSector,--Writes one sector with a data addres mark at the specified disk address.
writeDeletedSector,--Writes one sector with a deleted data addres mark at the specified disk address.
readID,--Reads to first encountered record ID from the specified disk address (the value of sector in the disk address is ignored).
formatTrack};--format the track specified by DiskAddress
Buffer: TYPE = RECORD [
address:
LONG POINTER,--quadword aligned.
length: CARDINAL];--Length in words.
DiskAddress: TYPE = MACHINE DEPENDENT RECORD [
cylinder:
CARDINAL,--must be IN [0..numberOfCylinders]
head: [0..256),--must be IN [0..numberOfHeads]
sector: [0..256)];--must be IN [1..{value depends on sectorLength}]
Status: TYPE = MACHINE DEPENDENT RECORD [
diskChange: BOOLEAN,-- Disk drive has apparently gone to a not ready (door open) state since the last operation was performed. Only DiskChangeClear will reset this status.
na1: BOOLEAN,
twoSided: BOOLEAN,--The diskette currently installed is two-sided.
na3: BOOLEAN,
error: BOOLEAN,--This status record indicates an error
inProgress: BOOLEAN,--The operation is not yet complete
recalibrateError: BOOLEAN,--recalibrate subfunction failed to sense track00.
dataLost: BOOLEAN,--The buffer supplied by the client was not as large as the data transfer requested.
notReady: BOOLEAN,--The drive is not ready.
writeProtect: BOOLEAN,--Logical OR of the context setting of protect and the physical signal being returned from the drive.
deletedData: BOOLEAN,--The sector contained a deleted data address mark.
recordNotFound: BOOLEAN, --The record defined by the disk address could not be found.
crcError: BOOLEAN,--A CRC error was encountered on either the record ID or data field.
track00: BOOLEAN,--Read/Write heads are currently positioned over track00, the outermost track.
index: BOOLEAN,--An index pulse signal was detected concurrent with the posting of this status.
busy: BOOLEAN];--The drive is not idle.
Initiate: PUBLIC PROC [operationPtr: OperationPtr]
RETURNS [status: Status, maxSecondsThisOperation: CARDINAL];
--Used to create asynchronous operations from the Function set. The status reflects any errors preventing the operatin from being preformed. MaxSecondsPerOperation can be used by drivers for timeouts. It reflects the seconds the operation will take AFTER pervious operations have been completed.
Poll: PUBLIC PROC [operationPtr: OperationPtr] RETURNS [status: Status];
--Checks status of an asynchronous operation.
DiskChangeClear: PUBLIC PROC [device: DeviceHandle];
--Clears the disk change status.
Reset: PUBLIC PROC [device: DeviceHandle];
--Stops all processing being done by the Head, causing it to "forget" all known operations, and sets the hardware to a startup state.
Initialize: PUBLIC PROC [notify: WORD, initialAllocation: LONG POINTER];
--Provides information to the device face implementation that will be used internally. (Must be called before any other procedures.)
GetNextDevice: PUBLIC PROC [previous: DeviceHandle]
RETURNS [next: SA800Face.DeviceHandle];
--Enumerates all devices and controllers for the SA800Face.
InitializeCleanup: PUBLIC PROC [device: DeviceHandle];
--Initializes procedures used during device startup and shutdown.
END...
LOG
Edited: June 17, 1980 9:53 AM by AOF: Added log to file.
Edited: June 18, 1980 9:11 AM by AOF: Added additional enumerated element (recovery) to functions allowed in Initiate.
Edited: June 24, 1980 10:32 AM by AOF: Made recalibrate a subfunction of Initiate.
Edited: June 27, 1980 10:34 AM by AOF: Changed defintion of Reset.
Edited: July 29, 1980 9:41 AM by AOF: Changed ref to OISDisk to PilotDisk.
Edited: August 23, 1980 10:33 AM by AOF: Add multiple sector per operation.
Edited: September 15, 1980 3:16 PM by Forrest: Add don’t increment field; delete SA800HeadD0: PROGRAM.