-- PDDeviceDriverImpl.mesa
-- Copyright (C) 1984, Xerox Corporation. All rights reserved.
-- Jim Gasbarro 2-Apr-84 19:12:54
-- Michael Plass, September 27, 1984 8:34:22 am PDT
-- Jim Gasbarro 10-Dec-84 14:02:07
DIRECTORY
ColorVersatecDriver,
ColorVersatecUtils,
DicentraDiskDriver,
PDDeviceDriver,
PDQueue,
Process;
PDDeviceDriverImpl: MONITOR
IMPORTS ColorVersatecDriver, ColorVersatecUtils, DicentraDiskDriver, PDQueue, Process
EXPORTS PDDeviceDriver
= BEGIN
OPEN PDDeviceDriver;
diskCmdOffset: CARDINAL = 32;
versatecCmdOffset: CARDINAL = 0;
bandOffset: LONG CARDINAL = 64;
cylindersPerPartition: CARDINAL = 200;
queueStateCylinder: CARDINAL = (ORD[Color.LAST] + 1) * cylindersPerPartition;
bpi: CARDINAL = ColorVersatecDriver.bpi;
wordsPerScan: CARDINAL = ColorVersatecDriver.wordsPerScan;
scansPerBand: CARDINAL = ColorVersatecDriver.scansPerBand;
wordsPerBand: LONG CARDINAL = ColorVersatecDriver.wordsPerBand;
sectorsPerBand: CARDINAL = ColorVersatecDriver.sectorsPerBand;
tracksPerCylinder: CARDINAL = DicentraDiskDriver.tracksPerCylinder;
sectorsPerTrack: CARDINAL = DicentraDiskDriver.sectorsPerTrack;
cylindersPerSpindle: CARDINAL = DicentraDiskDriver.cylindersPerSpindle;
wordsPerSector: LONG CARDINAL = DicentraDiskDriver.wordsPerSector;
separatorBandOffset: LONG CARDINAL ← 0;
separatorBandColor: Color ← Black;
StoreBand: PUBLIC ENTRY PROC [sourcePtr: LONG POINTER TO WORD, destOffset: LONG CARDINAL, wordCount: LONG CARDINAL, color: Color ← Black, isSeparatorBand: BOOLEAN ← FALSE] =
BEGIN
c, h, s: CARDINAL;
x, cylOffset, sectorOffset: LONG CARDINAL;
ColorVersatecUtils.HyperStore[sourcePtr: sourcePtr, destOffset: bandOffset, wordCount: wordCount];
cylOffset ← LOOPHOLE[color] * cylindersPerPartition;
sectorOffset ← (destOffset / wordsPerSector);
c ← CARDINAL[sectorOffset / (sectorsPerTrack * tracksPerCylinder) + cylOffset];
h ← CARDINAL[(x ← (sectorOffset MOD (sectorsPerTrack * tracksPerCylinder))) / sectorsPerTrack];
s ← CARDINAL[x MOD sectorsPerTrack];
[] ← DicentraDiskDriver.Write[cylinder: c, head: h, sector: s, sectorCount: CARDINAL[wordCount / wordsPerSector], cmdOffset: diskCmdOffset, dataOffset: bandOffset];
IF isSeparatorBand AND color=Black THEN {separatorBandOffset ← destOffset; separatorBandColor ← color};
END;
PrintPage: PUBLIC PROC [passBands: ARRAY Color OF NAT, nBands: ARRAY Color OF NAT, fourColor: BOOLEAN ← FALSE, color: Color ← Black] RETURNS [SuccessCode] =
BEGIN
LongestColor: PROC [] RETURNS [CARDINAL] =
BEGIN
inches: CARDINAL ← 0;
FOR c: Color IN Color DO
inches ← MAX[inches, ((passBands[c] + nBands[c]) * scansPerBand) / bpi];
ENDLOOP;
RETURN[inches];
END;
IF NOT ColorVersatecDriver.VersatecIsOK[] THEN
BEGIN
PDQueue.LogMessage["Versatec is Offline or out of paper. Waiting..."];
WHILE NOT ColorVersatecDriver.VersatecIsOK[] DO
Process.Pause[Process.SecondsToTicks[2]];
ENDLOOP;
PDQueue.LogMessage["Versatec is Online"];
END;
IF fourColor THEN BEGIN
ColorVersatecDriver.SetColorMode[inches: LongestColor[], mode: FirstPassOfColor, color: Black, cmdOffset: versatecCmdOffset];
PrintLeadingTitleBlock[];
SkipWS[bands: passBands[Black]-1];
PrintColor[color: Black, bands: nBands[Black]];
ColorVersatecDriver.Rewind[cmdOffset: versatecCmdOffset];
ColorVersatecDriver.SetColorMode[inches: 0, mode: IntermediatePassOfColor, color: Cyan, cmdOffset: versatecCmdOffset];
SkipWS[bands: passBands[Cyan]];
PrintColor[color: Cyan, bands: nBands[Cyan]];
ColorVersatecDriver.Rewind[cmdOffset: versatecCmdOffset];
ColorVersatecDriver.SetColorMode[inches: 0, mode: IntermediatePassOfColor, color: Magenta, cmdOffset: versatecCmdOffset];
SkipWS[bands: passBands[Magenta]];
PrintColor[color: Magenta, bands: nBands[Magenta]];
ColorVersatecDriver.Rewind[cmdOffset: versatecCmdOffset];
ColorVersatecDriver.SetColorMode[inches: 0, mode: IntermediatePassOfColor, color: Yellow, cmdOffset: versatecCmdOffset];
SkipWS[bands: passBands[Yellow]];
PrintColor[color: Yellow, bands: nBands[Yellow]];
ColorVersatecDriver.SendEOT[];
END
ELSE BEGIN
ColorVersatecDriver.SetColorMode[inches: 0, mode: SinglePassOfColor, color: color, cmdOffset: versatecCmdOffset];
PrintLeadingTitleBlock[];
SkipWS[bands: passBands[color]-1];
PrintColor[color: color, bands: nBands[color]];
ColorVersatecDriver.SendEOT[];
END;
RETURN[ok];
END;
PrintLeadingTitleBlock: PROC =
BEGIN
cylOffset: LONG CARDINAL ← LOOPHOLE[separatorBandColor] * cylindersPerPartition;
sectorOffset: LONG CARDINAL ← separatorBandOffset/wordsPerSector;
PrintColorBand[cylOffset, sectorOffset];
END;
SkipWS: PROC[bands: CARDINAL] =
BEGIN
buffer: ARRAY [0..wordsPerScan) OF CARDINAL;
p: POINTER ← @buffer;
FOR i: CARDINAL IN [0..wordsPerScan) DO
buffer[i] ← 0;
ENDLOOP;
FOR i: LONG CARDINAL IN [0..scansPerBand) DO
ColorVersatecUtils.HyperStore[sourcePtr: p, destOffset: bandOffset + (i * LENGTH[buffer]), wordCount: LENGTH[buffer]];
ENDLOOP;
FOR i: CARDINAL IN [0..bands) DO
ColorVersatecDriver.PlotBuffer[wordCount: wordsPerBand, hyperOffset: bandOffset];
ENDLOOP;
END;
PrintColorBand: ENTRY PROC [cylOffset: LONG CARDINAL, sectorOffset: LONG CARDINAL] =
BEGIN
c: CARDINAL ← CARDINAL[sectorOffset / (sectorsPerTrack * tracksPerCylinder) + cylOffset];
x: LONG CARDINAL ← (sectorOffset MOD (sectorsPerTrack * tracksPerCylinder));
h: CARDINAL ← CARDINAL[x / sectorsPerTrack];
s: CARDINAL ← CARDINAL[x MOD sectorsPerTrack];
[] ← DicentraDiskDriver.Read[cylinder: c, head: h, sector: s, sectorCount: sectorsPerBand, cmdOffset: diskCmdOffset, dataOffset: bandOffset];
ColorVersatecDriver.PlotBuffer[wordCount: wordsPerBand, hyperOffset: bandOffset];
END;
PrintColor: PROC [color: Color, bands: CARDINAL] =
BEGIN
cylOffset, sectorOffset: LONG CARDINAL;
cylOffset ← LOOPHOLE[color] * cylindersPerPartition;
FOR i: CARDINAL IN [0..bands) DO
sectorOffset ← i * sectorsPerBand;
PrintColorBand[cylOffset, sectorOffset];
ENDLOOP;
END;
ReadQueueState: ENTRY PROC [address: LONG POINTER, nwords: CARDINAL] =
BEGIN
[] ← DicentraDiskDriver.Read[cylinder: queueStateCylinder, head: 0, sector: 0, sectorCount: CARDINAL[(nwords+wordsPerSector-1)/wordsPerSector], cmdOffset: diskCmdOffset, dataOffset: bandOffset];
ColorVersatecUtils.HyperRead[destPtr: address, sourceOffset: bandOffset, wordCount: nwords]
END;
WriteQueueState: ENTRY PROC [address: LONG POINTER, nwords: CARDINAL] =
BEGIN
ColorVersatecUtils.HyperStore[sourcePtr: address, destOffset: bandOffset, wordCount: nwords];
[] ← DicentraDiskDriver.Write[cylinder: queueStateCylinder, head: 0, sector: 0, sectorCount: CARDINAL[(nwords+wordsPerSector-1)/wordsPerSector], cmdOffset: diskCmdOffset, dataOffset: bandOffset];
END;
DisplayBadStatusInMP: PUBLIC PROC [s: PrinterStatus] =
BEGIN
END;
GetStatus: PUBLIC PROC RETURNS [PrinterStatus] =
BEGIN
RETURN[noStatus];
END;
Display: PUBLIC PROC [c0, c1: CHAR] =
BEGIN
END;
maxStateWords: CARDINAL ← 16*1024;
PDQueue.RegisterDisk[read: ReadQueueState, write: WriteQueueState, maxWords: maxStateWords];
END.