-- SA800NeckD0.mesa (last edited by: Forrest on: September 18, 1980 3:24 PM)--

DIRECTORY
Mopcodes USING [zMISC],
SA800Face USING [Context, Operation, OperationPtr, Status];

SA800NeckD0: DEFINITIONS =
BEGIN

-- CONSTANTS

-- The following are canned status that may be returned to the client, usually at Initate time.
clearResult: Result = LOOPHOLE [-1];
notReady: SA800Face.Status = [
diskChange: FALSE, na1: FALSE, twoSided: FALSE, na3: FALSE, error: TRUE,
inProgress: FALSE, recalibrateError: FALSE, dataLost: FALSE, notReady: TRUE,
writeProtect: FALSE, deletedData: FALSE, recordNotFound: FALSE, crcError: FALSE,
track00: FALSE, index: FALSE, busy: FALSE];
diskChange: SA800Face.Status = [
diskChange: TRUE, na1: FALSE, twoSided: FALSE, na3: FALSE, error: TRUE,
inProgress: FALSE, recalibrateError: FALSE, dataLost: FALSE, notReady: FALSE,
writeProtect: FALSE, deletedData: FALSE, recordNotFound: FALSE, crcError: FALSE,
track00: FALSE, index: FALSE, busy: FALSE];
inProgress: SA800Face.Status = [
diskChange: FALSE, na1: FALSE, twoSided: FALSE, na3: FALSE, error: FALSE,
inProgress: TRUE, recalibrateError: FALSE, dataLost: FALSE, notReady: FALSE,
writeProtect: FALSE, deletedData: FALSE, recordNotFound: FALSE, crcError: FALSE,
track00: FALSE, index: FALSE, busy: TRUE];
writeProtect: SA800Face.Status = [
diskChange: FALSE, na1: FALSE, twoSided: FALSE, na3: FALSE, error: TRUE,
inProgress: FALSE, recalibrateError: FALSE, dataLost: FALSE, notReady: FALSE,
writeProtect: TRUE, deletedData: FALSE, recordNotFound: FALSE, crcError: FALSE,
track00: FALSE, index: FALSE, busy: FALSE];
infoMask: SA800Face.Status = [
diskChange: FALSE, na1: FALSE, twoSided: TRUE, na3: FALSE, error: FALSE,
inProgress: TRUE, recalibrateError: FALSE, dataLost: FALSE, notReady: FALSE,
writeProtect: TRUE, deletedData: FALSE, recordNotFound: FALSE, crcError: FALSE,
track00: TRUE, index: FALSE, busy: FALSE];
statusError: SA800Face.Status = [
diskChange: FALSE, na1: FALSE, twoSided: FALSE, na3: FALSE, error: TRUE,
inProgress: FALSE, recalibrateError: TRUE, dataLost: TRUE, notReady: TRUE,
writeProtect: FALSE, deletedData: FALSE, recordNotFound: TRUE, crcError: TRUE,
track00: FALSE, index: FALSE, busy: FALSE];

-- major function words for supported commands
ChipLoad: TYPE = MACHINE DEPENDENT RECORD [
addr: ChipAddr, --FDC addressing lines
displ: [0..17B], --displacement to next field of IOCB
data: [0..377B]]; --command data byte
ChipAddr: TYPE = MACHINE DEPENDENT RECORD [
notRd: BOOLEAN, --FDCwrite|FDCread’
notCs: BOOLEAN, --FDCdack|FDCcs’
a1: BOOLEAN, --A1
a0: BOOLEAN]; --A0
WakeLoad: TYPE = MACHINE DEPENDENT RECORD [
cmd: [0..17B], --command dispatch type
displ: [0..17B], --displacement to next IOCB field
wake: [0..377B]]; --WakeAllow funtion

command: ChipAddr = [notRd: TRUE, notCs: FALSE, a1: FALSE, a0: FALSE];
parameter: ChipAddr = [notRd: TRUE, notCs: FALSE, a1: FALSE, a0: TRUE];

parm0: CARDINAL = 12B; --offset to parameter #0
parm1: CARDINAL = 13B; --offset to parameter #1
parm2: CARDINAL = 14B; --offset to parameter #2
parm3: CARDINAL = 15B; --offset to parameter #3
parm4: CARDINAL = 16B; --offset to parameter #4

sel0: UNSPECIFIED = 100B; --select drive 0--

nop: ChipLoad = [addr: command, displ: 00B, data: 0B];
readData: ChipLoad = [addr: command, displ: parm0, data: sel0+27B];
writeData: ChipLoad = [addr: command, displ: parm0, data: sel0+13B];
writeDeletedData: ChipLoad = [addr: command, displ: parm0, data: sel0+17B];
readID: ChipLoad = [addr: command, displ: parm0, data: sel0+33B];
specify: ChipLoad = [addr: command, displ: parm0, data: 65B];
seekTrack: ChipLoad = [addr: command, displ: parm0, data: sel0+51B];
formatTrack: ChipLoad = [addr: command, displ: parm0, data: sel0+43B];

-- Specification of the wake allow after the command phase
nopWakeAllow: WakeLoad = [cmd: 0B, displ: 0B, wake: 5B];
seekWakeAllow: WakeLoad = [cmd: 6B, displ: 11B, wake: 1B];
readWakeAllow: WakeLoad = [cmd: 10B, displ: 11B, wake: 11B];
writeWakeAllow: WakeLoad = [cmd: 14B, displ: 11B, wake: 11B];
initWakeAllow: WakeLoad = [cmd: 0B, displ: 11B, wake: 5B];

CommandMatrix: TYPE = RECORD [
function: ChipLoad, wake: WakeLoad,
stuffer: PROCEDURE [iocb: IOCBlongPtr, operation: SA800Face.OperationPtr]];

SectorIndex: TYPE = [0..4);
SectorMatrix: TYPE = RECORD [
sectorsPerTrack: CARDINAL, --number of sectors per track given sector length
gap3: CARDINAL]; -- length of gap3 (formatting) given sector length

StateHandle: TYPE = LONG POINTER TO State;
State: TYPE = RECORD [
--Alignment: none.
--Location: global frame.
--Lifetime: life of device face.
user: SA800Face.Context, --portion of context available to client
head: HeadContext]; --not available to client

HeadContext: TYPE = RECORD [
status: SA800Face.Status, --most currently processed status
sectorIndex: SectorIndex]; --index into sector length table

-- definition of the CSB for the floppy disk
CSBPtr: TYPE = LONG POINTER TO CSB;
CSB: TYPE = MACHINE DEPENDENT RECORD [state: CSBState];
CSBState: TYPE = MACHINE DEPENDENT RECORD [
--Alignment: hexword.
--Location: assumed to be last 16K of first64K.
--Lifetime: forever.
next(0): IOCBlongPtr, -- assumption: MSW is always zero (first64K)
abortMicrocode(2): UNSPECIFIED,
notify(3): UNSPECIFIED, -- interrupt mask word used by firmware
tail(4): IOCBlongPtr]; -- (software) pointer to end of IOCB chain

-- definition of the IOCB for the floppy disk
-- The queue of IOCB’s the hardware knows about can be broken if there are operations
-- with runs of pages
IOCBlongPtr: TYPE = LONG POINTER TO IOCB;
IOCB: TYPE = MACHINE DEPENDENT RECORD [
--Alignment: quadword.
--Location: first64K of memory.
--Lifetime: Duration of the operation that it represents.
next(0B): IOCBlongPtr, --assumption: MSW is always zero (first64K)
softwareNext(2B): IOCBlongPtr, --actual unbroken queue of IOCB’s
address(4B): LONG POINTER, --pointer to client (quadword aligned) buffer
length(6B): CARDINAL, --length of client buffer in words
result(7B): Result, --result status collected from controller/device
wake(10B): WakeLoad, --word to be loaded in cmdWakeAllow register
function(11B): ChipLoad, --word to be loaded in cmd register
p0(12B): ChipLoad, --parameter number 0
p1(13B): ChipLoad, --parameter number 1
p2(14B): ChipLoad, --parameter number 2
p3(15B): ChipLoad, --parameter number 3
p4(16B): ChipLoad, --parameter number 4
unused(17B): UNSPECIFIED]; --not currenly assigned

Result: TYPE = MACHINE DEPENDENT RECORD [
standardResult: StandardResult, --Standard result from chip [0:5]
driveStatus: DriveStatus, --Drive status read from chip [5:7]
controllerStatus: ControllerStatus]; --Controller status at function end [12:4]

StandardResult: TYPE = MACHINE DEPENDENT RECORD [
deleted: BOOLEAN, --Deleted data found if TRUE
completion: Completion]; --4 bits of completion type and code

DriveStatus: TYPE = MACHINE DEPENDENT RECORD [
ready1: BOOLEAN, --Drive1 is ready
writeFault: BOOLEAN, --?
indexPulse: BOOLEAN, --coincident with operation complete
writeProtect: BOOLEAN, --physically protected
ready0: BOOLEAN, --Drive0 is ready
track00: BOOLEAN, --head currently position over track00
customerOption: BOOLEAN]; --?

ControllerStatus: TYPE = MACHINE DEPENDENT RECORD [
dmaWakeReq: BOOLEAN, --DMA wakeup required
oDataParity: BOOLEAN, --parity error on output data
oFault: BOOLEAN, --output fault
fdcIntF: BOOLEAN]; --FDC interrupt

Completion: TYPE = MACHINE DEPENDENT RECORD [
type: [0..3B], --completion type (only zero is good)
code: [0..3B]]; --completion code

-- PROCEDURES

OUTPUT: PUBLIC PROCEDURE [value, address: UNSPECIFIED] =
MACHINE CODE BEGIN Mopcodes.zMISC, 6; END;

END.....-- SA
800NeckD0
LOG

June 25, 1980 9:22 AM by AOF; Added log to file. Changes to make
recalibrate a subfuncion of Initiate.
June 27, 1980 4:13 PM by AOF; Added check for controller status and method of setting error in status when one or more fatal errors has occurred..
September 15, 1980 4:22 PM by Forrest; Add pending field to IOCB; add explict bit positions to some Machine Dependent RECORDS..