-- File: PressBandsOps.mesa: Routines for getting for a file at a printing server.
-- GetBits is called by Press.mesa
-- Last Edited: April 16, 1982 2:34 PM By: GWilliams & Pier
-- Normalizing Press Bands world.
DIRECTORY
AltoDefs USING [BytesPerWord, PageSize],
IODefs USING[WriteLine],
InlineDefs USING [BITOR, BITSHIFT--, COPY--],--COPY[from, nwords, to]
MiscDefs USING[CallDebugger--, Zero--],
PressBandsDefs,--only export to it
PressNetDefs USING [ddMgr, debuggerIfTfsError, EndReason, errorTfs, InitTrident],
SegmentDefs USING[DataSegmentHandle, DefaultBase, DeleteDataSegment, NewDataSegment, SegmentAddress],
TridentDefs USING [BadErrorRtn, dcReadLD, dcReadD, ddMgrPtr, DefaultTfsCleanupRtn, DefaultTfsErrorRtn, eofDA, fillInDA, FP, PAGE, TfsActOnPages, TfsCloseDisk, tfsdskPtr, TfsInit, TfsOpenFile, TFSwordsPerPage];
PressBandsOps: PROGRAM
IMPORTS IODefs, InlineDefs, MiscDefs, PressNetDefs, SegmentDefs, TridentDefs
EXPORTS PressBandsDefs =
BEGIN OPEN AltoDefs, IODefs, InlineDefs, MiscDefs, PressNetDefs, SegmentDefs, TridentDefs;

--Tfs stuff
disk: tfsdskPtr ← NIL;--this is a separate copy of the disk object.
bufferWordLen: CARDINAL = TFSwordsPerPage;
bufferByteLen: CARDINAL = BytesPerWord*bufferWordLen;
pagesLength: CARDINAL = 4;
firstVda: CARDINAL ← 0;--allways holds page 1 of the file
fp: FP;--fp gets filled in by TfsOpenFile
filePtr: POINTER TO FP ← @fp;
tfsSeg: DataSegmentHandle ← NIL;
tfsBuff: POINTER TO ARRAY[0..TFSwordsPerPage) OF CARDINAL;
pages: ARRAY[0..pagesLength] OF PAGE;
chars: POINTER TO ARRAY [0..30) OF CHARACTER;--just for looking around in the tfsBuff
dAsLength: CARDINAL;
dAsBase: POINTER;--this is modified after ea call on TfsActOnPages.
pageNum: CARDINAL;--for writing into the bands buffer

--Debugging Switches


ReadTfsPage: PUBLIC PROC[]=
-- Reads the next page of the bands file into the Bands trident buffer

{
endReason: EndReason ← illegalReason;
loopCtr: CARDINAL;--this detects infinite loops in GetBits
maxTries: CARDINAL = 3;
nmChars: CARDINAL ← BytesPerWord*TFSwordsPerPage;

dAs: DESCRIPTOR FOR ARRAY OF PAGE ← DESCRIPTOR[dAsBase, dAsLength];
BEGIN
IF (dAs[pageNum] ← dAs[pageNum+1]) = eofDA
THEN{endReason ← hitEOF; GOTO done;};--by now the vda of the next page to write is in

IF (dAs[pageNum] = fillInDA)
THEN--the vda is not valid
IF debuggerIfTfsError
THEN CallDebugger["disk address is fillInDA"L]
ELSE{endReason ← dANotFilled; GOTO done};

dAs[pageNum+1] ← fillInDA;--reset the to-be-pagenum+1 vda
dAsLength ← dAsLength + 1;--extend range of descriptor from new base
dAsBase ← dAsBase - 1;--must reset base because the low-level disk routines write pageNum onto
pageNum ← pageNum + 1;-- the disk label; and the vda is accessed from dAs using pageNum!
dAs ← DESCRIPTOR[dAsBase, dAsLength];
--TypeOutStatus[dAs, pageNum, charsInPage, TRUE];----the TRUE means "before ActOnPages"
[]← TfsActOnPages[disk, NIL, dAs, filePtr↑, pageNum, pageNum, dcReadD, @nmChars, dcReadD, tfsBuff, DefaultTfsCleanupRtn, DefaultTfsErrorRtn, TRUE, 0!
BadErrorRtn => {endReason ← tridentError; GOTO done;};];
--TypeOutStatus[dAs, pageNum, charsInPage, FALSE];----the FALSE means "after ActOnPages"

loopCtr ← 0;
UNTIL dAs[pageNum+1] # fillInDA
DO--the Default TfsCleanupRtn didn’t fill in the next DA, try again, but don’t write data this time
IF (loopCtr ← loopCtr + 1) > maxTries
THEN
IF debuggerIfTfsError
THENCallDebugger["disk address is fillInDA after some retries"L]
ELSE{endReason ← dANotFilled; GOTO done};
IF dAs[pageNum+1] = eofDA THEN EXIT;
[]←TfsActOnPages[disk, NIL, dAs, filePtr↑, pageNum, pageNum, dcReadLD, @nmChars, dcReadLD, tfsBuff, DefaultTfsCleanupRtn, DefaultTfsErrorRtn, TRUE, 0!
BadErrorRtn => {endReason ← dANotFilled; GOTO done;};];
ENDLOOP;
EXITS
done=>
SELECT endReason FROM
illegalReason =>WriteLine["illegal End."L];
tridentError, hitEOF, dANotFilled =>errorTfs[endReason];
ENDCASE;
END;
};--ReadTfsPage


InitTfsBandsBuffer: PUBLIC PROC[] RETURNS[POINTER]=
{
IF tfsSeg # NIL THEN DeleteDataSegment[tfsSeg];
tfsSeg ← NewDataSegment[DefaultBase, (TFSwordsPerPage + PageSize-1)/PageSize];
tfsBuff ← SegmentAddress[tfsSeg];
chars ← LOOPHOLE [tfsBuff];--for snooping around during debugging
pages ← [fillInDA, fillInDA, fillInDA, fillInDA, fillInDA];
dAsLength ← pagesLength;--this varies with the bits file writing
--in next line, we are assuming that Press.bits is contiguous!!!!
pages[1] ← firstVda;--this will be accessed as dAs[pageNum+1] to set up dAs[pageNum]
dAsBase ← @pages[0];
pageNum ← 0;--this gets incremented before using
RETURN [tfsBuff];
};
--InitTfsBandsBuffer

ReleaseTfsBandsBuffer
: PUBLIC PROC[]=
{
DeleteDataSegment[tfsSeg];
tfsSeg ← NIL;
}
;--ReleaseTfsBandsBuffer

CloseBandsFile
: PUBLIC PROC[]=
{
IF disk # NIL THEN
{disk ← TfsCloseDisk[disk, TRUE]};--the TRUE is for don’tDelete ddMgr, that’s done by caller
};
--CloseBandsFile

OpenPressBands: PUBLIC PROC[]=
--If it can’t find the file, it makes sure there is no disk object for it. Doesn’t touch the global ddMgr
BEGIN
fileSys: CARDINAL ← 1;--TP0:sys 1

--N.B. that ddMgr is assumed to have been inited by caller!! (In our case, by PressNetListener)
disk ← InitTrident[ddMgr, disk];--loads disk object
IF disk = NIL THEN ERROR errorTfs[noTrident];

[, firstVda,] ← TfsOpenFile[disk, "BANDS.", read, filePtr];--must fool Open with read. Only other option is create.
IF firstVda=0 AND disk.tfskd.model = 80 THEN --"not found" if not on 1st file system.
GOTO errorXit;

WHILE firstVda = 0 AND fileSys < 23 --check all filesystems on a T300
DO--drives 0-7 and 3 filesystems/drive
IF disk # NIL THEN
disk←LOOPHOLE[TfsCloseDisk[disk, TRUE]];--keep ddMgr, and make disk NIL
disk ← TfsInit[TRUE, BITOR[BITSHIFT[(fileSys MOD 3), 8], (fileSys/3)], ddMgr,];
fileSys ← fileSys + 1;
IF disk = NIL THEN LOOP;
[, firstVda, ] ← TfsOpenFile[disk, "Press.bits.", read, filePtr];
ENDLOOP;

IF firstVda = 0 THEN --get here only when not found on T300
GOTO errorXit;
EXITS
errorXit =>
{IF disk # NIL THEN disk ← TfsCloseDisk[disk, TRUE];--keep the ddMgr around
ERROR errorTfs[cantFindFile]};
END;
--OpenPressBands


END.
-- PressNetListener.mesa
-- Last Edited: March 4, 1982 2:38 PM By: GWilliams
-- Created new module for Cedar bands hacking on the Alto.
-- Last Edited: March 19, 1982 4:06 PM By: GWilliams
-- Cleaned up the error exits some (vis-a-vis closing disk object and not the ddMgr).