-- 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.