DIRECTORY
FontTune USING [CreateFontTuner],
Imager USING [Context],
ImagerBitmapContext USING [Brick, Create, SetBitmap, SetBrick],
ImagerDevice USING [FontTuner],
ImagerSample USING [Clear, GetSize, NewSampleMap, Put, RasterSampleMap, SampleMap],
Loader USING [MakeProcedureResident, MakeGlobalFrameResident],
LSEPFace,
Process USING [Pause, Priority, GetPriority, priorityFaultHandlers, SecondsToTicks, SetPriority],
PrincOps USING [bitsPerWord, wordsPerPage, PageCount],
RavenCodes,
RavenControl,
RavenDriver,
Rope USING [ROPE];
~
BEGIN
OPEN RavenDriver;
myPixelMap: ImagerSample.RasterSampleMap ← NIL;
secondPixelMap: ImagerSample.RasterSampleMap ← NIL;
GetPrinterSampleMap: PUBLIC PROC RETURNS [sampleMap: ImagerSample.RasterSampleMap] = {RETURN[myPixelMap]};
ContextFromSampleMap:
PUBLIC
PROC [sampleMap: ImagerSample.RasterSampleMap,
fontTunerParms: Rope.
ROPE ←
NIL]
RETURNS [context: Imager.Context] =
BEGIN
fontTuner: ImagerDevice.FontTuner ← NIL;
IF fontTunerParms # NIL THEN fontTuner ← FontTune.CreateFontTuner[fontTunerParms];
context ← ImagerBitmapContext.Create[deviceSpaceSize: ImagerSample.GetSize[sampleMap], scanMode: [slow: right, fast: up], surfaceUnitsPerInch: [300, 300], pixelUnits: FALSE, fontCacheName: $PrinterBitmap, fontTuner: NIL];
ImagerBitmapContext.SetBitmap[context, sampleMap];
ImagerBitmapContext.SetBrick[context, coarseBrick];
ImagerSample.Clear[sampleMap];
END;
lastPaperFeed: RavenControl.PaperTray ← top;
MakeSimpleBrick:
PROC [t:
ARRAY [0..4)
OF
PACKED
ARRAY [0..4)
OF [0..16)]
RETURNS [ImagerBitmapContext.Brick] ~ {
b: ImagerSample.SampleMap ~ ImagerSample.NewSampleMap[box: [max: [4, 4]], bitsPerSample: 8];
FOR s:
NAT
IN [0..4)
DO
FOR f:
NAT
IN [0..4)
DO
ImagerSample.Put[b, [s, f], t[s][f]];
ENDLOOP;
ENDLOOP;
RETURN [[maxSample: 15, sampleMap: b, phase: 0]]
};
coarseBrick: ImagerBitmapContext.Brick ← MakeSimpleBrick[[
[00, 01, 13, 14],
[08, 02, 03, 15],
[09, 10, 04, 05],
[07, 11, 12, 06]
]];
SetRegistration:
PUBLIC
PROCEDURE [registration: RavenRegistration] =
TRUSTED
BEGIN
DivideUp: PROCEDURE [divident, divisor: CARDINAL] RETURNS [quotient: CARDINAL] = TRUSTED INLINE BEGIN RETURN[quotient: (divident + divisor - 1) / divisor]; END;
sets up arguments for call which will set page offsets
LSEPFace.SetPageOffsets[
wordsFast: DivideUp[divident: registration.long * registrationTabSize,
divisor: PrincOps.bitsPerWord],
linesSlow: registration.short * registrationTabSize];
END; -- SetRegistration
printing: BOOL ← FALSE;
PrintingError: PUBLIC ERROR = CODE;
WakeUp:
PUBLIC
PROCEDURE[] =
BEGIN
RavenControl.SendEngineCommand[solicitStatus]; -- Jump start the Raven
END;
PrintFromSampleMap:
PUBLIC
PROC [sampleMap: ImagerSample.RasterSampleMap,
copies:
CARDINAL ← 1, paperFeed: RavenDriver.PaperFeed ← alternating]
RETURNS [endingStatus: PrinterStatus, type: StatusType] =
BEGIN
ENABLE ABORTED => printing ← FALSE;
eventContext: REF RavenControl.EventContext ← NEW[RavenControl.EventContext];
feedOkay, engineError, transferIsReady, transferWait: BOOL ← FALSE;
old: Process.Priority ← Process.GetPriority[];
engineStatus: RavenControl.EngineStatus;
paperTray: RavenControl.PaperTray ←
SELECT paperFeed
FROM
bottom => bottom,
top => top,
alternating => IF lastPaperFeed = top THEN bottom ELSE top,
ENDCASE => top;
RavenControl.SetToCurrentEventContext[eventContext];
printing ← TRUE;
lastPaperFeed ← paperTray;
DO
-- wait ok loop
IF engineStatus IN [imageFault1..imageFault3] THEN engineStatus ← okay; -- clear "sticky" status with new job start
reset counters to new starting page
SELECT RavenControl.GetEngineStatus[]
FROM
okay, tonerLow => EXIT;
okayFlushRequired,
IN [imageFault1..imageFault3] =>
BEGIN
"Flush" the printer with a blank sheet to complete previous unfinished imaging
RavenControl.Feed[paperTray, aligned];
DO
-- flush printing loop
SELECT RavenControl.WaitEngineEvent[eventContext]
FROM
pageDelivery, idle, feedError, softError, hardError, timeout => EXIT; -- wait for these
ENDCASE => LOOP; -- others are in-process
ENDLOOP; -- flush printing loop
LOOP; -- flushed one sheet, try again
END;
preRegistrationFault => {Process.Pause[Process.SecondsToTicks[1]]; LOOP}; -- Wait for someone to fix it
ENDCASE =>
BEGIN
-- wake up printer / query every second
RavenControl.SendEngineCommand[solicitStatus];
Process.Pause[Process.SecondsToTicks[1]];
LOOP;
END;
ENDLOOP; -- wait ok loop
RavenControl.PageTransferSet[sampleMap];
BEGIN
ENABLE
UNWIND => Process.SetPriority[old];
Process.SetPriority[Process.priorityFaultHandlers];
RavenControl.Feed[paperTray, aligned];
feedOkay ← FALSE;
transferIsReady ← TRUE;
DO
-- page printing loop
SELECT RavenControl.WaitEngineEvent[eventContext]
FROM
readyToFeed =>
{feedOkay ←
TRUE;
IF transferWait AND NOT transferIsReady THEN LOOP};
feeding => { -- pageFeed ← pageFeed + 1; --transferIsReady ← FALSE; LOOP};
transferReady =>
BEGIN
transferIsReady ← TRUE;
IF (NOT transferWait) OR (NOT feedOkay) THEN LOOP;
IF (NOT feedOkay) THEN LOOP;
END;
imaged => LOOP;
imagedOverrun => {-- pageTrash ← pageTrash + 1; -- transferWait ← TRUE; LOOP};
pageSyncMiss => EXIT;
pageDelivery => EXIT; -- Page is at otuput
idle, timeout => EXIT;
feedError => {engineError ← TRUE; EXIT};
softError => {engineError ← TRUE; EXIT};
hardError => {engineError ← TRUE; EXIT};
ENDCASE => ERROR;
ENDLOOP; -- page printing loop
IF engineError THEN {Process.SetPriority[old]; ERROR PrintingError};
END;
Process.SetPriority[old];
mySP:
REF StatusProc ←
NIL;
RegisterStatusProc: PUBLIC ENTRY PROC [sp: StatusProc] = {mySP ← NEW[StatusProc ← sp]};
UnRegisterStatusProc: PUBLIC ENTRY PROC [sp: StatusProc] = {mySP ← NIL};
activeLength: (0..PrincOps.wordsPerPage] ← ((11*300)+15)/16;
Init:
PROC [] =
BEGIN
Loader.MakeProcedureResident[PrintFromSampleMap];
Loader.MakeGlobalFrameResident[PrintFromSampleMap];
RavenControl.Initialize[16*3];
RavenControl.SetScanLineLength[activeLength];
myPixelMap ← RavenControl.GetPageMap[];
secondPixelMap ← MakePrinterPixelMap[];
RavenControl.SendEngineCommand[solicitStatus]; -- Jump start the Raven
END;
Init[];