-- PDDeviceDriverImpl.mesa
-- Jim Gasbarro  2-Apr-84 19:12:54

DIRECTORY
	ColorVersatecDriver,
	ColorVersatecUtils,
	DicentraDiskDriver,
	PDDeviceDriver;

PDDeviceDriverImpl: MONITOR 
	IMPORTS ColorVersatecDriver, ColorVersatecUtils, DicentraDiskDriver 
	EXPORTS PDDeviceDriver
	= BEGIN
	
OPEN PDDeviceDriver;

diskCmdOffset: CARDINAL = 32;
versatecCmdOffset: CARDINAL = 0;
bandOffset: LONG CARDINAL = 64;
cylindersPerPartition: CARDINAL = 200;
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;

StoreBand: PUBLIC PROC [sourcePtr: LONG POINTER TO WORD, destOffset: LONG CARDINAL, wordCount: LONG CARDINAL, color: Color ← Black] =
	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];
	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 fourColor THEN BEGIN
		ColorVersatecDriver.SetColorMode[inches: LongestColor[], mode: FirstPassOfColor, color: Black, cmdOffset: versatecCmdOffset];
		SkipWS[bands: passBands[Black]];
		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];
		SkipWS[bands: passBands[Black]];
		PrintColor[color: color, bands: nBands[color]];
		ColorVersatecDriver.SendEOT[];
		END; 
	RETURN[ok];
	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;
	
PrintColor: PROC [color: Color, bands: CARDINAL] =
	BEGIN
	c, h, s: CARDINAL; 
	x, cylOffset, sectorOffset: LONG CARDINAL;
	cylOffset ← LOOPHOLE[color] * cylindersPerPartition;
	FOR i: CARDINAL IN [0..bands) DO
		sectorOffset ← i * sectorsPerBand;
		c ← CARDINAL[sectorOffset / (sectorsPerTrack * tracksPerCylinder) + cylOffset];
		h ← CARDINAL[(x ← (sectorOffset MOD (sectorsPerTrack * tracksPerCylinder))) / sectorsPerTrack];
		s ← CARDINAL[x MOD sectorsPerTrack];
		[] ← DicentraDiskDriver.Read[cylinder: c, head: h, sector: s, sectorCount: sectorsPerBand, cmdOffset: diskCmdOffset, dataOffset: bandOffset];
		ColorVersatecDriver.PlotBuffer[wordCount: wordsPerBand, hyperOffset: bandOffset];
		ENDLOOP;
	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;
END.