<> <> <> <> DIRECTORY BansheeControl USING [--BandBLTTransferCreatePage, BandBLTTransferReady, --Display, EngineEvent, EngineStatus, EventContext, GetEnginePaper, GetEngineStatus, Initialize, PageTransferSet, SendEngineCommand, SetToCurrentEventContext, TransferRelease, unlimitedAvailable, WaitEngineStatus, WaitEngineEvent], BansheeEngine USING [DisplayDigit, JobHandle], BansheeSequence USING [--GetBandlist, --pageCount, Set], BansheeStatus USING [Type], PrincOps USING [PageCount], LSEPFace USING [AdvanceBand], PaperTypes USING [Paper], PrintingState USING [Type], Process USING [Detach, Pause, priorityForeground, priorityRealTime, SecondsToTicks, SetPriority], Loader USING [MakeGlobalFrameResident, MakeProcedureResident]; BansheeEngineImpl: CEDAR MONITOR IMPORTS BansheeControl, BansheeSequence, Loader, LSEPFace, Process EXPORTS BansheeEngine = BEGIN PrintingStateKind: TYPE = {current, next}; newPrintingState: ARRAY PrintingStateKind OF CONDITION; debugForceTransferWait: BOOLEAN _ FALSE; -- are we always going to wait for transfer to be ready before feeding jobInternal: BansheeEngine.JobHandle; printingState: ARRAY PrintingStateKind OF PrintingState.Type; pageDelivered, pageFeed, pageTransfer, pageTrash: CARDINAL; stickyEngineStatus: BansheeControl.EngineStatus _ okay; Beep: PUBLIC PROCEDURE = BEGIN BansheeControl.SendEngineCommand[chime]; END; Display: PUBLIC PROCEDURE [digitLS, digitMS: BansheeEngine.DisplayDigit] = BEGIN BansheeControl.Display[LOOPHOLE[digitLS], LOOPHOLE[digitMS]]; END; GetPageBalance: PUBLIC PROCEDURE RETURNS [balance: CARDINAL] = BEGIN RETURN[balance: SELECT GetPrintingStateEntry[kind: current] FROM completed => 0, ENDCASE => BansheeSequence.pageCount + pageTrash - pageDelivered]; END; -- GetPageBalance GetPaperSize: PUBLIC PROCEDURE RETURNS [paperSize: PaperTypes.Paper] = BEGIN RETURN[SELECT BansheeControl.GetEnginePaper[] FROM paperLetter => [knownSize: letter], paperLegal => [knownSize: legal], paperA4 => [knownSize: a4], paper215X330 => [knownSize: legal], paperEnvelope10 => [knownSize: other, otherSize: [114, 254]], -- 4.5x10" paperEnvelopeRX => [knownSize: other, otherSize: [114, 254]], ENDCASE => ERROR]; END; -- GetPaperSize GetPrintingState: PUBLIC PROCEDURE RETURNS [state: PrintingState.Type] = BEGIN RETURN[state: GetPrintingStateEntry[kind: current]]; END; -- GetPrintingState GetStatus: PUBLIC PROCEDURE RETURNS [status: BansheeStatus.Type] = BEGIN IF stickyEngineStatus NOT IN [imageFault1..sequenceFault] THEN stickyEngineStatus _ BansheeControl.GetEngineStatus[]; -- "sticky" stauses status _ SELECT stickyEngineStatus FROM okay => okay, okayFlushRequired => okay, diagnosticOkay => repairMode, noPaper => noPaper, preregistrationJam => preRegistrationJam, fuserJam => fuserJam, noExit => exitJam, outputTrayFull => outputTrayFull, feedTrayNotEngaged => paperCassetteRemoved, clamShellOpen => clamshellOpen, copyModeOn => copyMode, noToner => noToner, callForService => callForService, diagnosticNotReady => repairMode, offline => offLine, communicationFault => communicationFault, imageFault1 => imageFault1, imageFault2 => imageFault2, imageFault3 => imageFault2, sequenceFault => sequenceFault, ENDCASE => ERROR; END; -- GetStatus Initialize: PUBLIC PROCEDURE [bufferSize: PrincOps.PageCount, enableUnlimited: BOOLEAN] = TRUSTED BEGIN <> Loader.MakeProcedureResident[LSEPFace.AdvanceBand]; Loader.MakeGlobalFrameResident[LSEPFace.AdvanceBand]; <> Loader.MakeGlobalFrameResident[BansheeControl.SendEngineCommand]; Loader.MakeProcedureResident[BansheeControl.SendEngineCommand]; <> BansheeControl.Initialize[bufferSize: bufferSize, enableUnlimited: TRUE]; <> Process.Detach[FORK Print]; -- priority = 2 (sometimes 5) END; -- Initialize SetJob: PUBLIC PROCEDURE [job: BansheeEngine.JobHandle] = BEGIN jobInternal _ job; END; -- SetJob SetPrintingState: PUBLIC PROCEDURE [state: PrintingState.Type] = BEGIN <> SetPrintingStateEntry[kind: next, state: state]; END; -- SetPrintingState WaitPrintingState: PUBLIC PROCEDURE [targetState: PrintingState.Type, targetEqual: BOOLEAN] RETURNS [state: PrintingState.Type] = BEGIN <> RETURN[state: WaitPrintingStateEntry[kind: current, targetState: targetState, targetEqual: targetEqual]]; END; -- WaitPrintingState WaitStatus: PUBLIC PROCEDURE RETURNS [status: BansheeStatus.Type] = BEGIN [] _ BansheeControl.WaitEngineStatus[]; RETURN[GetStatus[]]; END; -- WaitStatus GetPrintingStateEntry: ENTRY PROCEDURE [kind: PrintingStateKind] RETURNS [state: PrintingState.Type] = BEGIN RETURN[state: printingState[kind]]; END; SetPrintingStateEntry: ENTRY PROCEDURE [kind: PrintingStateKind, state: PrintingState.Type] = BEGIN printingState[kind] _ state; BROADCAST newPrintingState[kind]; END; WaitPrintingStateEntry: ENTRY PROCEDURE [kind: PrintingStateKind, targetState: PrintingState.Type, targetEqual: BOOLEAN] RETURNS [state: PrintingState.Type] = BEGIN <> UNTIL targetEqual = (printingState[kind] = targetState) DO WAIT newPrintingState[kind]; ENDLOOP; RETURN[state: printingState[kind]]; END; -- WaitPrintingStateEntry Print: PROCEDURE = BEGIN <> diagnosticPrint: BOOLEAN _ FALSE; -- wait for pageDelivery before feeding forceTransferWait: BOOLEAN; -- Always wait for transfer if page sync miss. transferWait: BOOLEAN; -- Should we wait for transfer to be ready before feed feedOkay: BOOLEAN; -- Will engine accept feed command unlimitedPage: BOOLEAN _ FALSE; -- print this page in unlimited mode printEvent --, transferEvent-- : BansheeControl.EngineEvent; engineError, transferIsReady: BOOLEAN; beeperActive: BOOLEAN _ FALSE; eventContextHandleTransfer: REF BansheeControl.EventContext _ NEW[BansheeControl.EventContext]; eventContextPrint: REF BansheeControl.EventContext _ NEW[BansheeControl.EventContext]; DisplayFault: PROCEDURE = TRUSTED BEGIN Beeper: PROCEDURE = TRUSTED BEGIN THROUGH [1..5] DO BansheeControl.SendEngineCommand[chime]; Process.Pause[Process.SecondsToTicks[2]]; ENDLOOP; beeperActive _ FALSE; END; -- Beeper SELECT BansheeControl.GetEngineStatus[] FROM imageFault1, imageFault2, imageFault3, sequenceFault => BEGIN BansheeControl.SendEngineCommand[SELECT BansheeControl.GetEngineStatus[] FROM imageFault1 => displayP1, imageFault2 => displayP2, imageFault3 => displayP3, ENDCASE => displayP5]; IF NOT beeperActive THEN BEGIN beeperActive _ TRUE; Process.Detach[FORK Beeper]; -- beep, then go away END; END; ENDCASE => Display[blank, blank]; END; -- DisplayFault <> <> <> <> <> <> <> <