-- ColorVersatecInterpOutputImpl.mesa
-- Michael Plass, 12-Apr-84 12:56:07
DIRECTORY Environment, PDFileFormat, PDInterpBasic, PDInterpOutput, PDInterpBitmap, PDDeviceDriver, OthelloDefs, PDInterpSysCalls, Process, ProcessorFace;

ColorVersatecInterpOutputImpl: PROGRAM
	IMPORTS PDInterpBitmap, PDDeviceDriver, PDInterpSysCalls, OthelloDefs -- , Process, ProcessorFace
	EXPORTS PDInterpOutput
= BEGIN

bitsPerWord: NAT = Environment.bitsPerWord;
currentHerald: PDFileFormat.Herald;
currentStartImage: PDFileFormat.StartImage;
currentBandNumber: NAT ← 0;
bandWords: INT ← 0;
band: PDInterpBitmap.BitmapDesc ← [sOrigin: 0, fOrigin: 0, sMin: 0, fMin: 0, sSize: 0, fSize: 0, pointer: NIL, rast: 0, lines: 0];
bandWordsAllocated: INT ← 0;

CurrentBandDesc: PROC RETURNS [PDInterpBitmap.BitmapDesc] = {
	band.sOrigin ← currentHerald.bandSSize*(currentBandNumber+currentStartImage.passBands);
	PDInterpBitmap.Clear[band];
	RETURN [band]
	};
	
StartImage: PUBLIC PROC [herald: PDFileFormat.Herald, startImage: PDFileFormat.StartImage]
	RETURNS [PDInterpBitmap.BitmapDesc] = {
	rast: NAT = (--startImage.fSizePage-- 8000 +bitsPerWord-1)/bitsPerWord;
	lines: INT = herald.bandSSize;
	words: INT = rast*lines;
	color: PDDeviceDriver.Color ← SELECT startImage.toner FROM
		black => Black,
		cyan => Cyan,
		magenta => Magenta,
		yellow => Yellow,
		ENDCASE => ERROR;
	currentHerald ← herald;
	currentStartImage ← startImage;
	currentBandNumber ← 0;
	IF words > bandWordsAllocated THEN {
		IF band.pointer # NIL THEN PDInterpSysCalls.FreeSpace[band.pointer];
		band.pointer ← PDInterpSysCalls.AllocateSpace[words];
		bandWordsAllocated ← words;
		};
	band.sOrigin ← 0;
	band.fOrigin ← 0; -- startImage.fMinPage;
	band.sMin ← 0;
	band.fMin ← 0;
	band.sSize ← herald.bandSSize;
	band.fSize ← rast*bitsPerWord;
	band.rast ← rast;
	band.lines ← herald.bandSSize;
	bandWords ← words;
	IF currentStartImage.feed THEN {
		passBands ← ALL[LAST[NAT]];
		nBands ← ALL[0];
		};
	passBands[color] ← currentStartImage.passBands;
	nBands[color] ← currentStartImage.nBands;
	RETURN [CurrentBandDesc[]]
	};
	
EndBand: PUBLIC PROC RETURNS [PDInterpBitmap.BitmapDesc] = {
	PDDeviceDriver.StoreBand[
		sourcePtr: band.pointer,
		destOffset: bandWords*currentBandNumber,
		wordCount: bandWords,
		color: SELECT currentStartImage.toner FROM
			black => Black,
			cyan => Cyan,
			magenta => Magenta,
			yellow => Yellow,
			ENDCASE => ERROR
		];
	currentBandNumber ← currentBandNumber + 1;
	RETURN [CurrentBandDesc[]]
	};
	
passBands: ARRAY PDDeviceDriver.Color OF NAT;
nBands: ARRAY PDDeviceDriver.Color OF NAT;
	
EndImage: PUBLIC PROC = {
	successCode: PDDeviceDriver.SuccessCode;
	scanLineLength: CARDINAL ← band.fSize;
	IF currentStartImage.strip THEN {
	  minPass: NAT ← LAST[NAT];
	  FOR c: PDDeviceDriver.Color IN PDDeviceDriver.Color DO
	  	minPass ← MIN[passBands[c], minPass];
		ENDLOOP;
	  FOR c: PDDeviceDriver.Color IN PDDeviceDriver.Color DO
	  	passBands[c] ← passBands[c] - minPass;
		ENDLOOP;
	  FOR copyNum: CARDINAL IN [0..currentHerald.copies) DO
		DO 
			s: PDDeviceDriver.PrinterStatus;
			successCode ← PDDeviceDriver.PrintPage[
				passBands: passBands,
				nBands: nBands,
				fourColor: currentStartImage.toner#black
				];
			SELECT successCode FROM
				warning => EXIT;
				error => {
					WHILE (s←PDDeviceDriver.GetStatus[])#standBy DO
						PDDeviceDriver.DisplayBadStatusInMP[s];
						SELECT s FROM
							registrationJam => OthelloDefs.WriteLine[" - Registration jam"];
							fuserJam => OthelloDefs.WriteLine[" - Fuser jam"];
							warming => OthelloDefs.WriteLine[" - Warming up"];
							feederFault => OthelloDefs.WriteLine[" - Out of paper"];
							interlockOpen => OthelloDefs.WriteLine[" - Door open"];
							fuserCold => OthelloDefs.WriteLine[" - Fuser cold"];
							parityError => OthelloDefs.WriteLine[" - Parity Error"];
							offLine => OthelloDefs.WriteLine[" - Offline"];
							ENDCASE => OthelloDefs.WriteLine[" - Can't feed page"];
						ENDLOOP
					};
				ENDCASE => EXIT; -- ok
			ENDLOOP;
		ENDLOOP;
	  };
	};
	
END.