DIRECTORY
Basics USING [bitsPerWord, DoubleShiftRight, LongMult],
CountedVM USING [Handle, SimpleAllocate],
FontTune USING [CreateFontTuner],
Imager USING [Context, metersPerInch, RotateT, ScaleT, SetPriorityImportant, TranslateT],
ImagerFastShow USING [Create],
ImagerPixelMap USING [DeviceRectangle, PixelMap, PixelMapRep, Clear],
ImagerRaster USING [FontTuner],
Loader USING [MakeProcedureResident, MakeGlobalFrameResident],
LSEPFace,
Process USING [Detach, Pause, MsecToTicks, Priority, GetPriority, priorityBackground, priorityFaultHandlers, priorityRealTime, SetPriority],
PrincOps USING [bitsPerWord, wordsPerPage, BBTableSpace, BBptr, PageCount],
PrincOpsUtils USING [AllocateNakedCondition, BITBLT, AlignedBBTable, GetClockPulses --, LongCopy --],
RavenCodes,
RavenDriver,
Rope USING [ROPE],
VM USING [Allocate, Interval, PageCount, PagesForWords, Pin ],
VMSideDoor USING [AssignSpecialRealMemory];
~
BEGIN
OPEN RavenDriver;
myPixelMap: ImagerPixelMap.PixelMap ← [0, 0, 0, 0, 0, 0, NIL];
secondPixelMap: ImagerPixelMap.PixelMap ← [0, 0, 0, 0, 0, 0, NIL];
GetPrinterPixelMap: PUBLIC PROC RETURNS [pixelMap: ImagerPixelMap.PixelMap] = {RETURN[myPixelMap]};
MakePrinterPixelMap:
PROC RETURNS [pixelMap: ImagerPixelMap.PixelMap] =
BEGIN
bounds: ImagerPixelMap.DeviceRectangle ← [0, 0, (8*300+300/2), (11*300)];
numBands: NAT = ((8*300+300/2)+15)/16;
numLines: CARDINAL = numBands * sizeEachBand;
wordsPerLine: NAT ~ activeLength;
words: LONG CARDINAL ~ Basics.LongMult[wordsPerLine, numLines];
pages: CARDINAL = VM.PagesForWords[words];
vm: CountedVM.Handle ← CountedVM.SimpleAllocate[words];
interval: VM.Interval ~ vm.interval;
refRep:
REF ImagerPixelMap.PixelMapRep ←
NEW[ImagerPixelMap.PixelMapRep ← [
ref: vm, pointer: vm.pointer, words: vm.words,
lgBitsPerPixel: 0, rast: wordsPerLine, lines: numLines]];
FOR i:
INT ← 0, i+400
UNTIL i >= interval.count
DO
-- only pin about 100K each time
VM.Pin[[page: interval.page+i, count: MIN[interval.count-i, 400]]];
Process.Pause[Process.MsecToTicks[500]]; -- wait a half second for Laundry process
ENDLOOP;
pixelMap.refRep ← refRep;
pixelMap.sMin ← 0;
pixelMap.fMin ← 0;
[pixelMap.sOrigin, pixelMap.fOrigin, pixelMap.sSize, pixelMap.fSize] ← bounds;
ImagerPixelMap.Clear[pixelMap];
END;
ContextFromPixelMap:
PUBLIC
PROC [pixelMap: ImagerPixelMap.PixelMap,
fontTunerParms: Rope.
ROPE ←
NIL]
RETURNS [context: Imager.Context] =
BEGIN
fontTuner: ImagerRaster.FontTuner ← NIL;
IF fontTunerParms # NIL THEN fontTuner ← FontTune.CreateFontTuner[fontTunerParms];
context ← ImagerFastShow.Create[pm: pixelMap, pixelsPerInch: RavenCodes.resolution[fast], pixelUnits: TRUE, fontTuner: fontTuner];
Imager.SetPriorityImportant[context, TRUE];
Imager.RotateT[context, -90.0];
Imager.TranslateT[context, [-(8*300+300/2), 0]];
Imager.ScaleT[context, RavenCodes.resolution[fast]/Imager.metersPerInch];
END;
lastPaperFeed: RavenCodes.PrinterCommand ← feed;
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
lastBand: BOOL;
pageBufferIndex: CARDINAL; -- index to current band in page buffer
pageBufferIndexLast: CARDINAL; -- last meaningful band in page buffer
pageBufferBandBuffer: LONG POINTER; -- band buffer virtual address
bandBufferSize: PrincOps.PageCount = 16; -- From BandBLT
ScanLine: TYPE = [0..bandBufferSize); -- scan line index into a band
bandLast, band, firstBand: LSEPFace.Index;
bbTableSpace: PrincOps.BBTableSpace;
bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace];
dstBpl: INTEGER ~ PrincOps.wordsPerPage*Basics.bitsPerWord;
BandCopyInternal:
PROCEDURE [pixelMap: ImagerPixelMap.PixelMap, pm:
REF ImagerPixelMap.PixelMapRep] =
INLINE
BEGIN
copy from page buffer to imaging band, by scan line scan lines in the buffer are each wordsPerScanLine words scan lines in the imaging band are each 256 words, offset ahead by 256 words-wordsPerScanLine
bandOffset: CARD ← LONG[pageBufferIndex] * LONG[pm.rast] *
LONG[LAST[ScanLine]];
sourceAddr: LONG POINTER ← pm.pointer + Basics.LongMult[pageBufferIndex, pm.rast*sizeEachBand];
bb^ ← [
dst: [word: pageBufferBandBuffer, bit: 0],
dstBpl: dstBpl,
src: [word: sourceAddr, bit: 0],
srcDesc: [srcBpl[pm.rast*Basics.bitsPerWord]],
height: sizeEachBand,
width: pixelMap.fSize,
flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: FALSE, srcFunc: null, dstFunc: null]
];
PrincOpsUtils.BITBLT[bb];
FOR scanIndex: ScanLine IN [FIRST[ScanLine]..LAST[ScanLine]] DO
PrincOpsUtils.LongCopy[
from: PageBufferAddress[base, pageBufferIndex, scanIndex],
from: LOOPHOLE[pm.pointer + bandOffset + (scanIndex * LONG[pm.rast])],
nwords: activeLength,
to: LOOPHOLE[LOOPHOLE[pageBufferBandBuffer, LONG CARDINAL] + scanIndex * 256]];
ENDLOOP;
IF (pageBufferIndex ← pageBufferIndex + 1) > pageBufferIndexLast
THEN
{lastBand ← TRUE; bandLast ← band};
mark current band ready for imaging and get address and index of next
[nextBand: band, nextBandAddress: pageBufferBandBuffer] ← LSEPFace.AdvanceBand[currentBand: band];
END; -- BandCopyInternal
dataOnPulses: ARRAY [0 .. 256) OF CARD ← ALL[0];
PrintFromPixelMap:
PUBLIC
PROC [pixelMap: ImagerPixelMap.PixelMap,
copies:
CARDINAL ← 1, paperFeed: RavenDriver.PaperFeed ← alternating]
RETURNS [endingStatus: PrinterStatus, type: StatusType] =
BEGIN
RETURN [ropeStatus[noStatus], normal];
EXITS OutErr => {RETURN [ropeStatus[currStatus], error]};
END;
currStatus: RavenCodes.PrinterStatus ← noStatus;
mySP: REF StatusProc ← NIL;
printing: BOOL ← FALSE;
newStatus: CONDITION;
SetScanLineLength:
PUBLIC
SAFE
PROCEDURE [scanLineLength: (0..PrincOps.wordsPerPage]] =
TRUSTED
BEGIN
END;
MonitorRavenStatus:
PROC [] =
BEGIN
END;
Message: TYPE = {traysUnlatched, preRegistrationFault, postRegistrationJam, preExitJam, postExitJam, doorOpen, outputTrayFull, tonerLow, aboutToDozeOff, fuserUnderTemperature, imageFault, commandStatusFault, offLine, ok};
RegisterStatusProc: PUBLIC ENTRY PROC [sp: StatusProc] = {mySP ← NEW[StatusProc ← sp]};
UnRegisterStatusProc: PUBLIC ENTRY PROC [sp: StatusProc] = {mySP ← NIL};
WakeUp:
PUBLIC
PROCEDURE[] =
BEGIN
LSEPFace.PutCommand[LOOPHOLE[RavenCodes.PrinterCommand[solicitStatus]]]; -- Jump start the Raven
END;
bandBufferCount: LSEPFace.BandBufferCount ← 3;
wordsPerBand: CARDINAL = sizeEachBand * PrincOps.wordsPerPage;
sizeEachBand: CARDINAL = 16;
pagesNeedForBands: VM.PageCount = LSEPFace.MaxBands * sizeEachBand + 20;
vm: VM.Interval;
activeLength: (0..PrincOps.wordsPerPage] ← ((11*300)+15)/16;
statusCondition: LONG POINTER TO CONDITION ← NIL; statusMask: WORD ← 0;
dataCondition: LONG POINTER TO CONDITION ← NIL; dataMask: WORD ← 0;
Init:
PROC [] =
BEGIN
vm ← VM.Allocate[pagesNeedForBands];
VMSideDoor.AssignSpecialRealMemory[vm]; -- Move to low core and Pin
LSEPFace.AllocateBands[vm.page, bandBufferCount, sizeEachBand, 1];
SetScanLineLength[activeLength];
myPixelMap ← MakePrinterPixelMap[];
secondPixelMap ← MakePrinterPixelMap[];
Loader.MakeProcedureResident[PrintFromPixelMap];
Loader.MakeGlobalFrameResident[PrintFromPixelMap];
[statusCondition, statusMask] ← PrincOpsUtils.AllocateNakedCondition[];
[dataCondition, dataMask] ← PrincOpsUtils.AllocateNakedCondition[];
Process.SetTimeout[dataCondition, Process.SecondsToTicks[20]];
LSEPFace.SetInterruptMasks[0, statusMask, dataMask];
LSEPFace.PutCommand[LOOPHOLE[RavenCodes.PrinterCommand[solicitStatus]]]; -- Jump start the Raven
Process.Detach[FORK MonitorRavenStatus[]]; -- Up to realTime
END;
ropeStatus: ARRAY RavenCodes.PrinterStatus OF PrinterStatus ← ALL[NIL];
ropeStatus[noStatus] ← "No status";
ropeStatus[key0] ← "key0";
ropeStatus[key1] ← "key1";
ropeStatus[key2] ← "key2";
ropeStatus[key3] ← "key3";
ropeStatus[key4] ← "key4";
ropeStatus[key5] ← "key5";
ropeStatus[key6] ← "key6";
ropeStatus[key7] ← "key7";
ropeStatus[key8] ← "key8";
ropeStatus[key9] ← "key9";
ropeStatus[keyClear] ← "keyClear";
ropeStatus[keyTest] ← "keyTest";
ropeStatus[keyOnLine] ← "keyOnLine";
ropeStatus[keyOffLine] ← "keyOffLine";
ropeStatus[warming] ← "Warming";
ropeStatus[standBy] ← "Ready";
ropeStatus[feederFault] ← "Feeder Fault";
ropeStatus[registrationJam] ← "Registration Jam";
ropeStatus[fuserJam] ← "Fuser Jam";
ropeStatus[noExit] ← "No Exit";
ropeStatus[interlockOpen] ← "Interlock Open";
ropeStatus[fuserCold] ← "Fuser Cold";
ropeStatus[feeding] ← "Feeding";
ropeStatus[readyToFeed] ← "Ready To Feed";
ropeStatus[displayAcknowledge] ← "displayAcknowledge";
ropeStatus[parityError] ← "parityError";
ropeStatus[unrecognizedCommand] ← "illegalCharacter";
ropeStatus[illegalSequence] ← "illegalSequence";
ropeStatus[feedTraysNotEngaged] ← "Paper Tray Open or Out of Paper";
ropeStatus[pageSync] ← "pageSync";
ropeStatus[pageAtOutputTray] ← "pageAtOutputTray";
ropeStatus[tonerLow] ← "Toner Low";
ropeStatus[goingOffLine] ← "goingOffLine";
ropeStatus[offLine] ← "offLine";
ropeStatus[outputTrayFull] ← "outputTrayFull";
ropeStatus[aboutToDozeOff] ← "Low Power Mode";
ropeStatus[statusError] ← "statusError";
ropeStatus[statusOverRun] ← "statusOverRun";
Init[];