-- file: IntDiablo.Mesa
-- last edited by Brotz, February 9, 1982 4:43 PM

DIRECTORY
exD: FROM "ExceptionDefs" USING [DisplayException, DisplayExceptionLine,
hytypeNotConnected, pressSpaceWhenReady, pressToContinue],
Inline USING [BITAND, BITOR, LowHalf],
intCommon USING [keystream],
LaurelHardcopyDefs USING [AbortHardcopy, CheckForAbort, elevenInchesInMicas,
inch, LineSegmentTable, Mica, micasPerDiabloX, pwiIn, pwiOut, wAbsMaxStrobe,
wiAllReady, wiCarriage, wiCheck, wiDaisy, widthTable, wiNil, wiOnline, wiPaper,
wiReady, wiReset, wiRibbon, wMaxStrobe, yPerInch],
ovD: FROM "OverviewDefs" USING [CharMask];

IntDiablo: PROGRAM
IMPORTS exD, Inline, intC: intCommon, LaurelHardcopyDefs
EXPORTS LaurelHardcopyDefs = PUBLIC

BEGIN
OPEN LaurelHardcopyDefs;

currentX: CARDINAL;
currentY: CARDINAL;


NewDiabloPage: PROCEDURE [firstPage: BOOLEAN] =
BEGIN
IF firstPage AND ~FReset[] THEN
BEGIN
exD.DisplayException[exD.hytypeNotConnected];
exD.DisplayExceptionLine[exD.pressToContinue, 2];
DO CheckForAbort[]; ENDLOOP;
END
ELSE BEGIN
IF firstPage THEN {currentX ← 0; currentY ← yPerInch + yPerInch/2};
PositionX[0];
exD.DisplayExceptionLine[exD.pressSpaceWhenReady, 2];
intC.keystream.putback[intC.keystream, intC.keystream.get[intC.keystream]];
CheckForAbort[];
END;
END; -- of NewDiabloPage --


FinishDiabloPage: PROCEDURE =
-- Completes the current page part by pushing the paper out of the HyType printer.
BEGIN
PositionY[0];
currentY ← 0;
MoveDeltaY[yPerInch + yPerInch/2];
END; -- of FinishDiabloPage --


PrintDiabloString: PROCEDURE [string: STRING, fontNumber: CARDINAL, x, y: Mica,
segTable: POINTER TO LineSegmentTable] =
BEGIN
char: CHARACTER;
diabloX, nextCharWidth: CARDINAL;
oldCharWidth: CARDINAL ← 0;
CheckForAbort[ ! AbortHardcopy => {FinishDiabloPage[]; [] ← FReset[]}];
PositionY[y];
PositionX[x];
diabloX ← currentX;
FOR i: CARDINAL IN [0 .. string.length) DO
char ← string[i];
nextCharWidth ← widthTable[fontNumber][char] / micasPerDiabloX;
diabloX ← diabloX + (oldCharWidth + nextCharWidth) / 2;
oldCharWidth ← nextCharWidth;
MoveDeltaX[diabloX - currentX];
PrintChar[char];
ENDLOOP;
END; -- of PrintDiabloString --


FOnline: PROCEDURE RETURNS [BOOLEAN] =
BEGIN
-- I can find no documentation of it,
-- but I believe my interpretation of this bit to be correct:
RETURN[Inline.BITAND[pwiIn↑, wiOnline] = 0];
END; -- of FOnline --


MoveDeltaX: PROCEDURE [deltaX: INTEGER] =
BEGIN
tempDeltaX: INTEGER;
IF deltaX = 0 THEN RETURN;
IF deltaX IN (-wMaxStrobe .. wMaxStrobe) THEN
BEGIN
Strobe[wiCarriage, IF deltaX < 0 THEN wMaxStrobe - deltaX ELSE deltaX];
currentX ← currentX + deltaX;
END
ELSE BEGIN
tempDeltaX ← deltaX/2;
MoveDeltaX[tempDeltaX];
MoveDeltaX[deltaX - tempDeltaX];
END;
END; -- of MoveDeltaX --


PositionX: PROCEDURE [x: Mica] =
BEGIN
diabloX: CARDINAL ← x / micasPerDiabloX;
MoveDeltaX[diabloX - currentX];
END; -- of PositionX --


MoveDeltaY: PROCEDURE [deltaY: INTEGER] =
BEGIN
tempDeltaY: INTEGER;
IF deltaY = 0 THEN RETURN;
IF deltaY IN (-wMaxStrobe .. wMaxStrobe) THEN
BEGIN
Strobe[wiPaper, IF deltaY < 0 THEN wMaxStrobe - deltaY ELSE deltaY];
currentY ← currentY + deltaY;
END
ELSE
BEGIN
tempDeltaY ← deltaY/2;
MoveDeltaY[tempDeltaY];
MoveDeltaY[deltaY - tempDeltaY];
END;
END; -- of MoveDeltaY --


PositionY: PROCEDURE [y: Mica] =
BEGIN
diabloY: CARDINAL
← Inline.LowHalf[(LONG[elevenInchesInMicas - y] * LONG[yPerInch]) / LONG[inch]];
MoveDeltaY[diabloY - currentY];
END; -- of PositionY --


PrintChar: PROCEDURE [char: CHARACTER] =
BEGIN
char ← Inline.BITAND[char, ovD.CharMask];
IF char > 40C THEN Strobe[wiDaisy, char];
END; -- of PrintChar --


FReset: PROCEDURE RETURNS [f: BOOLEAN] =
BEGIN
tempX: CARDINAL ← currentX;
pwiOut↑ ← wiNil;
pwiOut↑ ← wiReset;
pwiOut↑ ← wiNil;
IF (f ← FWait[wiAllReady]) THEN
BEGIN
currentX ← 0;
PositionX[tempX];
END;
END; -- of FReset --


Strobe: PROCEDURE [wi: UNSPECIFIED, w: UNSPECIFIED] =
BEGIN
IF w >= wAbsMaxStrobe THEN ERROR AbortHardcopy;
-- *** Argument field overflow

IF Inline.BITAND[pwiIn↑, wiCheck] = 0 THEN ERROR AbortHardcopy;
-- *** Printer check

IF ~FWait[Inline.BITOR[wiReady, wi]] THEN [] ← FReset[];

w ← Inline.BITOR[w, wiRibbon];
pwiOut↑ ← w;
pwiOut↑ ← Inline.BITOR[w, wi];
pwiOut↑ ← w;
END; -- of Strobe --


FWait: PROCEDURE [wi: UNSPECIFIED] RETURNS [BOOLEAN] =
BEGIN
THROUGH [0 .. 140000B) DO
IF Inline.BITAND[pwiIn↑, wi] = 0 THEN RETURN[TRUE];
ENDLOOP;
RETURN [FALSE];
END; -- of FWait --


END. -- of IntDiablo --