-- DiskDefs.Mesa Edited by Sandman on June 30, 1980 5:11 PM
-- Copyright Xerox Corporation 1979, 1980
DIRECTORY
AltoDefs USING [BYTE, PageNumber],
AltoFileDefs USING [DISK, FP, SN, vDA, vDC];
DiskDefs: DEFINITIONS =
BEGIN OPEN AltoFileDefs, AltoDefs;
-- standard disk
nDisks: CARDINAL = 1;
nHeads: CARDINAL = 2;
nTracks: CARDINAL = 203;
nSectors: CARDINAL = 12;
StandardDisk: DISK = [nDisks, nTracks, nHeads, nSectors];
sysDisk: DISK;
NextDiskCommand: POINTER TO CBptr = LOOPHOLE[521B];
DiskStatus: POINTER TO DS = LOOPHOLE[522B];
LastDiskAddress: POINTER TO DA = LOOPHOLE[523B];
SectorInterrupts: POINTER TO CARDINAL = LOOPHOLE[524B];
-- physical disk address
DA: TYPE = MACHINE DEPENDENT RECORD [
sector: [0..17B], track: [0..777B], head, disk: [0..1], restore: [0..1]];
-- DAs with special meaning
InvalidDA: DA = DA[17B, 777B, 1, 1, 1];
-- disk header
DH: TYPE = MACHINE DEPENDENT RECORD [packID: CARDINAL, diskAddress: DA];
-- file identifier
FID: TYPE = MACHINE DEPENDENT RECORD [version: CARDINAL, serial: SN];
FreePageFID: FID = FID[177777B, SN[[1, 1, 1], 17777B, 177777B]];
-- disk label
DL: TYPE = MACHINE DEPENDENT RECORD [
next, prev: DA,
blank: UNSPECIFIED,
bytes: CARDINAL,
page: CARDINAL,
fileID: FID];
-- disk final status
DFS: TYPE = {CommandComplete, HardwareError, CheckError, IllegalSector};
-- disk status word
DS: TYPE = MACHINE DEPENDENT RECORD [
sector: [0..17B],
done: [0..17B],
seekFailed: [0..1],
seekInProgress: [0..1],
notReady: [0..1],
dataLate: [0..1],
noTransfer: [0..1],
checksumError: [0..1],
finalStatus: DFS];
-- useful status configurations
DSfree: CARDINAL = 1;
DSfake: CARDINAL = 3;
DSdone: CARDINAL = 17B;
DSmaskStatus: DS = DS[0, DSdone, 1, 0, 1, 1, 0, 1, LAST[DFS]];
DSgoodStatus: DS = DS[0, DSdone, 0, 0, 0, 0, 0, 0, CommandComplete];
DSfakeStatus: DS = DS[0, DSfake, 0, 0, 0, 0, 0, 0, CommandComplete];
DSfreeStatus: DS = DS[0, DSfree, 0, 0, 0, 0, 0, 0, CommandComplete];
-- disk subcommands
DSC: TYPE = {DiskRead, DiskCheck, DiskWrite};
-- hardware disk command
DC: TYPE = MACHINE DEPENDENT RECORD [
seal: BYTE, header, label, data: DSC, seek, exchange: [0..1]];
CBptr: TYPE = POINTER TO CB;
CBNil: CBptr = LOOPHOLE[0];
-- disk command block (label, page, and zone added)
CB: TYPE = MACHINE DEPENDENT RECORD [
nextCB: POINTER TO CB,
status: DS,
command: DC,
headerAddress: POINTER TO DH,
labelAddress: POINTER TO DL,
dataAddress: POINTER,
normalWakeups: WORD,
errorWakeups: WORD,
header: DH,
label: DL,
page: CARDINAL,
zone: POINTER TO CBZ];
nCB: CARDINAL = 3; -- minimun for full disk speed
lCBZ: CARDINAL = SIZE[CBZ] + nCB*(SIZE[CB] + SIZE[CBptr]);
-- Note: if there are n CBs, there are n+1 entries in the
-- cbQueue (an extra one contains a NIL to mark the end).
-- The extra one is represented by queueVec: ARRAY [0..1)
-- and thus is included in SIZE[CBZ].
CBZptr: TYPE = POINTER TO CBZ;
CBZ: TYPE = MACHINE DEPENDENT RECORD [
checkError: BOOLEAN,
errorCount: [0..77777B],
info: POINTER,
cleanup: PROCEDURE [CBptr],
errorDA: vDA,
currentPage: CARDINAL,
currentBytes: CARDINAL,
normalWakeups: WORD,
errorWakeups: WORD,
cbQueue: DESCRIPTOR FOR ARRAY OF CBptr,
qHead, qTail: CARDINAL,
queueVec: ARRAY [0..1) OF CBptr];
-- the queue vector starts at queueVec.
-- after the queue vector there follows
-- ARRAY OF CB, the CBs for the zone.
-- Procedures in DiskIO
RealDA: PROCEDURE [v: vDA] RETURNS [DA];
VirtualDA: PROCEDURE [da: DA] RETURNS [vDA];
ResetWaitCell: PROCEDURE;
SetWaitCell: PROCEDURE [POINTER TO WORD] RETURNS [POINTER TO WORD];
DDC: TYPE = RECORD [
cb: CBptr,
ca: POINTER,
da: vDA,
page: PageNumber,
fp: POINTER TO FP,
restore: BOOLEAN,
action: vDC];
DoDiskCommand: PROCEDURE [arg: POINTER TO DDC];
RetryCount: CARDINAL = 8;
RetryableDiskError: SIGNAL [cb: CBptr];
UnrecoverableDiskError: SIGNAL [cb: CBptr];
CBinit: TYPE = {clear, dontClear};
InitializeCBstorage: PROCEDURE [
zone: CBZptr, nCBs: CARDINAL, page: PageNumber, init: CBinit];
GetCB: PROCEDURE [zone: CBZptr, init: CBinit] RETURNS [cb: CBptr];
CleanupCBqueue: PROCEDURE [zone: CBZptr];
DiskCheckError: SIGNAL [page: PageNumber];
DiskRequestOption: TYPE = {swap, update, extend};
DiskRequest: TYPE = RECORD [
ca: POINTER,
da: POINTER TO vDA,
firstPage: PageNumber,
lastPage: PageNumber,
fp: POINTER TO FP,
fixedCA: BOOLEAN,
action, lastAction: vDC,
signalCheckError: BOOLEAN,
option:
SELECT OVERLAID DiskRequestOption FROM
swap => [desc: POINTER TO DiskPageDesc],
update => [cleanup: PROCEDURE [CBptr]],
extend => [lastBytes: CARDINAL],
ENDCASE];
DiskPageDesc: TYPE = RECORD [
prev, this, next: vDA, page: PageNumber, bytes: CARDINAL];
SwapPages: PROCEDURE [arg: POINTER TO swap DiskRequest]
RETURNS [page: PageNumber, byte: CARDINAL];
END.