<> <> <> DIRECTORY Basics USING [BITAND, bitsPerWord, LongMult], CountedVM USING [Free, Handle, SimpleAllocate], DoradoInputOutput USING [ExternalInput, StopEventCounters], <> Imager USING [Context], ImagerBitmapContext USING [Brick, Create, SetBitmap, SetBrick], ImagerBrick USING [Brick, BrickFromDotScreen], ImagerDevice USING [FontTuner], ImagerSample USING [Clear, GetBase, GetBitsPerLine, GetBitsPerSample, GetRef, GetSize, MapFromVM, RasterSampleMap], Loader USING [MakeProcedureResident, MakeGlobalFrameResident], PlatemakerControl USING [PrinterParameters, PrinterParametersRec], PrincOps USING [bitsPerWord], PrincOpsUtils USING [LongZero], Process USING [CheckForAbort, MsecToTicks, Pause, priorityForeground, priorityNormal, SetPriority, Yield], RasterControllerDorado, RasterControllerFace, Rope USING [Cat, ROPE], StorageAccounting USING [CollectionInterval], SafeStorage USING [SetCollectionInterval], UserProfile USING [Boolean, CallWhenProfileChanges, Number, ProfileChanged, ProfileChangedProc], VM USING [AddressForPageNumber, Free, Interval, Pin, SimpleAllocate, Unpin, PagesForWords]; PlatemakerControlImpl: CEDAR PROGRAM IMPORTS Basics, CountedVM, DoradoInputOutput, -- FontTune, -- ImagerBitmapContext, ImagerBrick, ImagerSample, Loader, PrincOpsUtils, Process, RasterControllerFace, Rope, SafeStorage, StorageAccounting, UserProfile, VM EXPORTS PlatemakerControl ~ BEGIN OPEN RasterControllerDorado, RasterControllerFace; ROPE: TYPE ~ Rope.ROPE; MakePrinterSampleMap: PUBLIC PROC RETURNS [pixelMap: ImagerSample.RasterSampleMap] = BEGIN fBits: NAT _ currentParameters.fSize; sSize: NAT _ currentParameters.sSize; wordsPerLine: NAT ~ ((fBits+255)/256) * 16; -- Integral number of munches. words: LONG CARDINAL ~ Basics.LongMult[wordsPerLine, sSize]; pages: CARDINAL = VM.PagesForWords[words]; vm: CountedVM.Handle _ CountedVM.SimpleAllocate[words]; interval: VM.Interval ~ vm.interval; pixelMap _ ImagerSample.MapFromVM[ vm: vm, box: [min: [0, 0], max: [sSize, fBits]], bitsPerSample: 1, bitsPerLine: wordsPerLine*Basics.bitsPerWord]; 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; ImagerSample.Clear[pixelMap]; END; FreePrinterSampleMap: PUBLIC PROC [pixelMap: ImagerSample.RasterSampleMap] = BEGIN vm: CountedVM.Handle _ NARROW[ImagerSample.GetRef[pixelMap]]; interval: VM.Interval ~ vm.interval; VM.Unpin[interval]; TRUSTED {CountedVM.Free[vm]}; END; ContextFromSampleMap: PUBLIC PROC [sampleMap: ImagerSample.RasterSampleMap, fontTunerParms: Rope.ROPE _ NIL] RETURNS [context: Imager.Context] = BEGIN fontTuner: ImagerDevice.FontTuner _ NIL; <> context _ ImagerBitmapContext.Create[deviceSpaceSize: ImagerSample.GetSize[sampleMap], scanMode: [slow: down, fast: right], surfaceUnitsPerInch: [1200, 1200], pixelUnits: FALSE, fontCacheName: $PrinterBitmap, fontTuner: NIL]; ImagerBitmapContext.SetBitmap[context, sampleMap]; ImagerBitmapContext.SetBrick[context, brick]; ImagerSample.Clear[sampleMap]; END; brick: ImagerBitmapContext.Brick; PrintMap: PUBLIC PROC [sampleMap: ImagerSample.RasterSampleMap] RETURNS [succeeded: BOOLEAN _ TRUE] ~ TRUSTED { <> ENABLE UNWIND => NULL; oldGC: INT _ StorageAccounting.CollectionInterval; IF NOT CheckConfig[].rastAHere THEN ERROR; -- PrinterTrouble["RastA board not present."]; { ENABLE UNWIND => { ShutupMicrocode[]; []_ SafeStorage.SetCollectionInterval[oldGC]; Process.SetPriority[Process.priorityNormal]; succeeded _ FALSE; <> }; InitializeRCBChain: PROC [ bitmap: LONG POINTER, words: CARDINAL, lines: CARDINAL, fMargin: CARDINAL _ 0, sMargin: INTEGER _ 2700, sRepeat, fRepeat: INTEGER _ 0, sReverse, fReverse: BOOLEAN _ FALSE, fMosaic: BOOLEAN _ FALSE, sSkip: CARDINAL _ 0, bitsPerSample: [0..bitsPerWord] _ 1, invert: BOOL _ FALSE] ~ TRUSTED { InitializeRCB[rcb: tailRCB]; InitializeCCB[ccb: tailCCB, halftoneCtl: [invertMask: ~invert]]; InitializeRCB[ rcb: mainRCB, next: tailRCB, bitmap: bitmap, activeWordsPerLine: words, wordsPerLine: words*(sSkip+1), lines: lines, fMargin: fMargin, sRepeat: sRepeat, fRepeat: fRepeat, sReverse: sReverse, fReverse: fReverse, mosaic: fMosaic, bitsPerSample: bitsPerSample ]; InitializeCCB[ ccb: mainCCB, next: tailCCB, lines: lines, halftoneCtl: [invertMask: ~invert] ]; IF sMargin > 0 THEN { InitializeRCB[rcb: leadRCB, next: mainRCB, lines: sMargin]; InitializeCCB[ccb: leadCCB, next: mainCCB, lines: sMargin, halftoneCtl: [invertMask: ~invert]]; mrb.rcb[A] _ leadRCB; mrb.ccb _ leadCCB; } ELSE {mrb.rcb[A] _ mainRCB; mrb.ccb _ mainCCB}; }; <<>> i: VM.Interval _ VM.SimpleAllocate[1]; leadRCB: RCBPointer _ LOOPHOLE[VM.AddressForPageNumber[i.page]]; i2: VM.Interval _ VM.SimpleAllocate[1]; mainRCB: RCBPointer _ LOOPHOLE[VM.AddressForPageNumber[i2.page]]; i3: VM.Interval _ VM.SimpleAllocate[1]; tailRCB: RCBPointer _ LOOPHOLE[VM.AddressForPageNumber[i3.page]]; i4: VM.Interval _ VM.SimpleAllocate[1]; leadCCB: CCBPointer _ LOOPHOLE[VM.AddressForPageNumber[i4.page]]; i5: VM.Interval _ VM.SimpleAllocate[1]; mainCCB: CCBPointer _ LOOPHOLE[VM.AddressForPageNumber[i5.page]]; i6: VM.Interval _ VM.SimpleAllocate[1]; tailCCB: CCBPointer _ LOOPHOLE[VM.AddressForPageNumber[i6.page]]; ib: VM.Interval _ VM.SimpleAllocate[2 * hardwareScanlinePages]; zeros: LONG POINTER _ VM.AddressForPageNumber[ib.page]; repCnt: INTEGER _ currentParameters.sRepeat; copyCnt: INT _ 0; <<>> VM.Pin[ib]; PrincOpsUtils.LongZero[zeros, 2 * hardwareScanlineWords]; -- fill the scan line with zeros VM.Pin[i]; VM.Pin[i2]; VM.Pin[i3]; VM.Pin[i4]; VM.Pin[i5]; VM.Pin[i6]; InitializeRCBChain[bitmap: zeros, words: hardwareScanlineWords, lines: 2, sMargin: 0]; <<>> ResetMicrocode[]; SetUpForRosClock[]; SetUpForRealLineSync[]; [] _ StartMicrocode[mrb]; Process.Pause[Process.MsecToTicks[1000]]; -- wait for microcode to transfer data ShutupMicrocode[]; zeros _ NIL; InitializeRCBChain[ bitmap: ImagerSample.GetBase[sampleMap].word, words: ImagerSample.GetBitsPerLine[sampleMap]/PrincOps.bitsPerWord, lines: ImagerSample.GetSize[sampleMap].s/(currentParameters.sSkip+1), fMargin: currentParameters.fMargin, sMargin: currentParameters.sMargin, sRepeat: repCnt, fRepeat: currentParameters.fRepeat, sReverse: currentParameters.sReverse, fReverse: currentParameters.fReverse, sSkip: currentParameters.sSkip, fMosaic: currentParameters.fMosaic, bitsPerSample: ImagerSample.GetBitsPerSample[sampleMap] ]; [] _ SafeStorage.SetCollectionInterval[LAST[INT]/4]; Process.SetPriority[Process.priorityForeground]; FOR timer: INT _ 0, timer+1 DO IF GetPageSync[] THEN EXIT; Process.CheckForAbort[]; ENDLOOP; [] _ StartMicrocode[mrb]; Process.SetPriority[Process.priorityNormal]; [] _ SafeStorage.SetCollectionInterval[oldGC]; Process.CheckForAbort[]; FOR timer: INT _ 0, timer+1 DO IF NOT GetPageSync[] THEN EXIT; Process.CheckForAbort[]; Process.Yield[]; ENDLOOP; ShutupMicrocode[]; VM.Unpin[i]; VM.Unpin[i2]; VM.Unpin[i3]; VM.Unpin[i4]; VM.Unpin[i5]; VM.Unpin[i6]; VM.Unpin[ib]; VM.Free[i]; VM.Free[i2]; VM.Free[i3]; VM.Free[i4]; VM.Free[i5]; VM.Free[i6]; VM.Free[ib]; mrb.rcb[A] _ leadRCB _ mainRCB _ tailRCB _ NIL; mrb.ccb _ leadCCB _ mainCCB _ tailCCB _ NIL; }; }; ParseProfile: UserProfile.ProfileChangedProc = { <<[reason: UserProfile.ProfileChangeReason]>> ENABLE UNWIND => NULL; currentParameters _ GetParameters[]; }; currentParameters: PlatemakerControl.PrinterParameters _ NEW[PlatemakerControl.PrinterParametersRec]; UpdateParameters: PUBLIC PROC [] = BEGIN currentParameters _ GetParameters[]; END; SetSMargin: PUBLIC PROC [sMargin: CARDINAL] = BEGIN currentParameters.sMargin _ sMargin; END; SetFMargin: PUBLIC PROC [fMargin: CARDINAL] = BEGIN currentParameters.fMargin _ fMargin; END; MakeNewBrick: PROC [pixelsPerDot: REAL _ 9, degrees: REAL _ 45.0] = BEGIN localBrick: ImagerBrick.Brick _ ImagerBrick.BrickFromDotScreen[pixelsPerDot, degrees]; brick.maxSample _ localBrick.maxSample; brick.sampleMap _ localBrick.sampleMap; brick.phase _ localBrick.phase; END; GetParameters: PROC [] RETURNS [PlatemakerControl.PrinterParameters] ~ { prefix: ROPE _ "Platemaker."; pp: PlatemakerControl.PrinterParameters _ NEW[PlatemakerControl.PrinterParametersRec]; pp.fMargin _ UserProfile.Number[Rope.Cat[prefix, "fMargin"], 100]; pp.sMargin _ UserProfile.Number[Rope.Cat[prefix, "sMargin"], 1400]; pp.fSize _ UserProfile.Number[Rope.Cat[prefix, "fSize"], 12000]; pp.sSize _ UserProfile.Number[Rope.Cat[prefix, "sSize"], 13500]; pp.fDPI _ UserProfile.Number[Rope.Cat[prefix, "fDPI"], 1200]; pp.sDPI _ UserProfile.Number[Rope.Cat[prefix, "sDPI"], 1200]; pp.fRepeat _ UserProfile.Number[Rope.Cat[prefix, "fRepeat"], 0]; pp.sRepeat _ UserProfile.Number[Rope.Cat[prefix, "sRepeat"], 0]; pp.fReverse _ UserProfile.Boolean[key: Rope.Cat[prefix, "fReverse"], default: FALSE]; pp.sReverse _ UserProfile.Boolean[key: Rope.Cat[prefix, "sReverse"], default: FALSE]; pp.fMosaic _ UserProfile.Boolean[key: Rope.Cat[prefix, "fMosaic"], default: FALSE]; pp.sSkip _ UserProfile.Number[Rope.Cat[prefix, "sSkip"], 0]; pp.bpp _ UserProfile.Number[Rope.Cat[prefix, "bpp"], 1]; pp.background _ UserProfile.Number[Rope.Cat[prefix, "background"], 0]; RETURN [pp]; }; <> <<>> <> pageSyncMask: WORD = 100000B; <> GetPageSync: PROC RETURNS [pageSync: BOOL] ~ TRUSTED { printerStatus: WORD _ LOOPHOLE [DoradoInputOutput.ExternalInput[]]; RETURN [Basics.BITAND[printerStatus, pageSyncMask] # 0]; }; mrbInterval: VM.Interval ~ VM.SimpleAllocate[1]; mrb: MRBPointer _ LOOPHOLE[VM.AddressForPageNumber[mrbInterval.page]]; VM.Pin[mrbInterval]; InitializeMRB[mrb]; UserProfile.CallWhenProfileChanges[proc: ParseProfile]; UserProfile.ProfileChanged[reason: firstTime]; Loader.MakeProcedureResident[PrintMap]; Loader.MakeGlobalFrameResident[PrintMap]; TRUSTED {DoradoInputOutput.StopEventCounters[]}; END.