-- doubleVersatec.mesa - April 1980
-- Low level output to Versatec
-- NON-microcode, double spacing version
-- To make a microcode version bind versatec.config
-- Updated: February 6, 1981 4:55 PM

DIRECTORY
InlineDefs: FROM "InlineDefs" USING [BITSHIFT, BITAND, LongCOPY],
MiscDefs: FROM "MiscDefs" USING [CallDebugger],
VersatecDefs: FROM "VersatecDefs";

Versatec: PROGRAM
IMPORTS InlineDefs, MiscDefs
EXPORTS VersatecDefs =
BEGIN OPEN InlineDefs, MiscDefs;

StartVersatecPlot: PUBLIC PROCEDURE[fileName: STRING, width,height: CARDINAL] =
BEGIN
PlotterCommand[Vreset];
END;

EndVersatecPlot: PUBLIC PROCEDURE =
BEGIN
PlotterCommand[Vformfeed];
END;

WriteVersatecLine: PUBLIC PROCEDURE [line: LONG POINTER, nBytes: CARDINAL] =
--*** THIS IS THE DOUBLE SPACING VERSION ***
BEGIN OPEN InlineDefs;
i, end: POINTER TO UNSPECIFIED;
nWords: CARDINAL ← MIN[nBytes/2,217];
bank0line: ARRAY [0..217) OF CARDINAL;

LongCOPY[line, nWords, @bank0line[0]];

PlotterCommand[Vclear];
WaitPlotterReady[];


end ← @bank0line[nWords-1]+1;
FOR i ← @bank0line[0], i+1 UNTIL i=end
DO
Plotter↑ ← (Plotter↑ ← VClockLow-Expand[BITAND[BITSHIFT[i↑,-12],17B]]) - 10000B;
Plotter↑ ← (Plotter↑ ← VClockLow-Expand[BITAND[BITSHIFT[i↑,-8],17B]]) - 10000B;
Plotter↑ ← (Plotter↑ ← VClockLow-Expand[BITAND[BITSHIFT[i↑,-4],17B]]) - 10000B;
Plotter↑ ← (Plotter↑ ← VClockLow-Expand[BITAND[i↑,17B]]) - 10000B;
ENDLOOP;

Plotter↑ ← (Plotter↑ ← VClockLow) - 10000B;
Plotter↑ ← VClockLow;

PlotterCommand[Vrlter];
WaitPlotterReady[];

--and a blank line:

PlotterCommand[Vclear];
WaitPlotterReady[];
Plotter↑ ← (Plotter↑ ← VClockLow) - 10000B;
Plotter↑ ← VClockLow;
PlotterCommand[Vrlter];
WaitPlotterReady[];

END;

-- Private stuff

VClockLow: CARDINAL ← 14377B;
VClockHigh: CARDINAL ← 4377B;

Plotter: POINTER TO CARDINAL = LOOPHOLE[177016B];
PlotterStatus: POINTER TO CARDINAL = LOOPHOLE[177030B];

PlotterCommands: TYPE = {Vclear, Vreset, Vrlter, Vformfeed};

Expand: ARRAY [0..17B] OF CARDINAL ←
[0,1,4,5,20B,21B,24B,25B,100B,101B,104B,105B,120B,121B,124B,125B];

HighByte: PROCEDURE [x: CARDINAL] RETURNS [CARDINAL] = INLINE
BEGIN OPEN InlineDefs;
RETURN [BITSHIFT[x, -8]];
END;

WaitPlotterReady: PROCEDURE = INLINE
BEGIN OPEN InlineDefs;
UNTIL BITAND[10000B, PlotterStatus↑] = 0 DO NULL; ENDLOOP;
END;

PlotterCommand: PROCEDURE [command: PlotterCommands] =
BEGIN OPEN InlineDefs;
UNTIL BITAND[40000B, PlotterStatus↑] = 0
DO CallDebugger["Turn on plotter and Proceed"]; ENDLOOP;
IF command = Vreset THEN Plotter↑ ← VClockLow ELSE WaitPlotterReady[];

Plotter↑ ← VClockLow;

IF command # Vreset THEN WaitPlotterReady[];

Plotter↑ ← VClockLow +
(SELECT command FROM
Vclear => 40000B,
Vreset => 1000B,
Vrlter => 20000B,
Vformfeed => 100000B,
ENDCASE => 0);
Plotter↑ ← VClockLow;
END;

-- *** START CODE ***

END.