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 = { 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. dPlatemakerControlImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Tim Diebert: April 21, 1987 9:40:44 am PDT FontTune USING [CreateFontTuner], IF fontTunerParms # NIL THEN fontTuner _ FontTune.CreateFontTuner[fontTunerParms]; Sends the n SampleMaps to the printer hardware, in order. Printer parameters are based on the printer parameter passed in during the GetMaps call. Fails if the id doesn't match the one currently in control. FlushQueue[]; [reason: UserProfile.ProfileChangeReason] Stuff for the hardware. The genI/O port stuff; Stuff for controlling the printer engine: Κ A˜šœ™Icode™Kšœœ+˜BKšœ œ˜Kšœœ ˜Kšœœ]˜jKšœ˜Kšœ˜Kšœœœ˜Kšœœ˜-Kšœ œ˜*Kšœ œO˜`KšœœS˜[—K˜K˜KšΠlnœœ˜$Kšœ'Οcœš˜ΩKšœ˜šœ œ-˜:K˜Kšœœœ˜K˜š Οnœœœœ,˜ZKšœœ˜%Kšœœ˜%KšœœŸ˜KKšœœœ(˜