DIRECTORY BasicTime USING [Pulses, MicrosecondsToPulses], DeviceCleanup USING [Item, Reason, Await], DLionInputOutput USING [firstReservedPage, IOPage, ioPageRealAddrLow], Loader USING [MakeProcedureResident, MakeGlobalFrameResident], LSEPFace, PrincOps USING [PageCount, PageNumber, wordsPerPage], PrincOpsUtils USING [BITAND, GetClockPulses], VM USING [AddressForPageNumber]; LSEPHeadDLion: PROGRAM IMPORTS BasicTime, DeviceCleanup, DLionInputOutput, Loader, PrincOpsUtils, VM EXPORTS LSEPFace = BEGIN OPEN LSEPFace; Index: PUBLIC TYPE = BandRecordBase RELATIVE ORDERED POINTER TO BandRecord; BandRecordBase: TYPE = LONG BASE POINTER TO RECORD [UNSPECIFIED]; Band: TYPE = BandBufferBase RELATIVE POINTER; -- real AND virtual relative pointer BandBufferBase: TYPE = LONG BASE POINTER TO RECORD [UNSPECIFIED]; BandRecord: TYPE = MACHINE DEPENDENT RECORD [ band(0): Band, next(1): Index, status(2): INTEGER]; imageLoc: LONG POINTER TO ImageCSB = LOOPHOLE[DLionInputOutput.IOPage + 20B]; ImageCSB: TYPE = MACHINE DEPENDENT RECORD [ run(0): Index, overrun(1): WORD, --zero=> ok, nonzero => overrun mask(2): CARDINAL, --band empty wakeup mask bandSize(3): CARDINAL, --number of lines (pages) in band lastStartedBand(4): Index, --for deviceCleanup to stop printer lineSize(5): CARDINAL, --constant = 256 tab(6): CARDINAL, --words of pixels to skip before starting scan scans(7): CARDINAL]; --number of blank lines after page sync firstBandRecord: Index = LOOPHOLE[40000B + 20B + 10B]; bandRecordLimit: Index = firstBandRecord + MaxBands * SIZE[BandRecord]; bandRecordBase: BandRecordBase = LOOPHOLE[imageLoc + SIZE[ImageCSB] - LOOPHOLE[firstBandRecord, CARDINAL]]; controlMaskLoc: LONG POINTER TO ControlMask = LOOPHOLE[DLionInputOutput.IOPage + 61B]; ControlMask: TYPE = WORD; controlDataLoc: LONG POINTER TO ControlData = LOOPHOLE[DLionInputOutput.IOPage + 62B]; ControlData: TYPE = WORD; statusMaskLoc: LONG POINTER TO StatusMask = LOOPHOLE[DLionInputOutput.IOPage + 65B]; StatusMask: TYPE = WORD; statusLoc: LONG POINTER TO BYTE = LOOPHOLE[DLionInputOutput.IOPage + 66B]; pagesCurrentlyInBands: PrincOps.PageCount _ 0; bandBufferBase: BandBufferBase; bandBufferBasePage: PrincOps.PageNumber; nullIndex: Index = LOOPHOLE[0]; IthIndex: PROC [i: CARDINAL [0..MaxBands)] RETURNS [Index] = INLINE BEGIN RETURN[firstBandRecord + (i * SIZE[BandRecord])]; END; AllocateBands: PUBLIC PROC [bandVirtualPageNumber: PrincOps.PageNumber, nBands: BandBufferCount, sizeEachBand: PrincOps.PageCount, slop: PrincOps.PageCount] = BEGIN bandBufferBase _ VM.AddressForPageNumber[bandVirtualPageNumber - DLionInputOutput.firstReservedPage]; bandBufferBasePage _ bandVirtualPageNumber; pagesCurrentlyInBands _ sizeEachBand * nBands + slop; FOR i: PrincOps.PageCount IN [0..pagesCurrentlyInBands) DO -- Clear Memory LOOPHOLE[VM.AddressForPageNumber[bandVirtualPageNumber + i], LONG POINTER TO ARRAY [0..PrincOps.wordsPerPage) OF WORD]^ _ ALL[0]; ENDLOOP; FOR i: CARDINAL IN [0..nBands) DO bandRecordBase[IthIndex[i]] _ [ band: LOOPHOLE[(DLionInputOutput.firstReservedPage + i * CARDINAL[sizeEachBand]) * PrincOps.wordsPerPage], next: IthIndex[(i + 1) MOD nBands], status: 0]; ENDLOOP; imageLoc.bandSize _ CARDINAL[sizeEachBand]; imageLoc.lastStartedBand _ nullIndex; imageLoc.lineSize _ PrincOps.wordsPerPage; END; DeallocateBands: PUBLIC PROC = BEGIN imageLoc.lastStartedBand _ nullIndex; pagesCurrentlyInBands _ 0; END; SetInterruptMasks: PUBLIC PROC [control, status, data: WORD] = BEGIN controlMaskLoc^ _ control; statusMaskLoc^ _ status; imageLoc.mask _ data; END; InitializeCleanUp: PUBLIC PROC = BEGIN item: DeviceCleanup.Item; saveCSB: ImageCSB; maxWaitTime: LONG CARDINAL = LONG[27500] * (2 * MaxBands); waitTime: BasicTime.Pulses = BasicTime.MicrosecondsToPulses[maxWaitTime]; DO reason: DeviceCleanup.Reason = DeviceCleanup.Await[@item]; SELECT reason FROM turnOff => BEGIN then: BasicTime.Pulses = PrincOpsUtils.GetClockPulses[]; IF imageLoc.lastStartedBand # nullIndex THEN WHILE (PrincOpsUtils.GetClockPulses[] - then) < waitTime AND bandRecordBase[imageLoc.lastStartedBand].status # 0 DO ENDLOOP; saveCSB _ imageLoc^; END; turnOn => BEGIN -- restore csb; client will have to redo page. saveCSB.lastStartedBand _ nullIndex; imageLoc^ _ saveCSB; END; disconnect => {}; ENDCASE; ENDLOOP; END; SetScanLineLength: PUBLIC PROC [activeWordsEachScanLine: (0..PrincOps.wordsPerPage]] = BEGIN offset: [0..PrincOps.wordsPerPage) = PrincOps.wordsPerPage - activeWordsEachScanLine; FOR i: Index _ firstBandRecord, i + SIZE[BandRecord] WHILE i < bandRecordLimit DO pageOffset: TYPE = MACHINE DEPENDENT RECORD [page(0:0..7): [0..377B), offset(0:8..15): [0..377B)]; LOOPHOLE[bandRecordBase[i].band, pageOffset].offset _ offset; ENDLOOP; END; SetPageOffsets: PUBLIC PROC [wordsFast: CARDINAL, linesSlow: CARDINAL] = BEGIN imageLoc.tab _ wordsFast; imageLoc.scans _ linesSlow; END; ResetBands: PUBLIC PROC RETURNS [Index, LONG POINTER] = BEGIN imageLoc.lastStartedBand _ nullIndex; FOR i: Index _ firstBandRecord, i + SIZE[BandRecord] WHILE i < bandRecordLimit DO bandRecordBase[i].status _ 0; ENDLOOP; RETURN[firstBandRecord, @bandBufferBase[bandRecordBase[firstBandRecord].band]]; END; ZeroBands: PUBLIC PROC = BEGIN FOR i: PrincOps.PageCount IN [0..pagesCurrentlyInBands) DO LOOPHOLE[VM.AddressForPageNumber[bandBufferBasePage + i], LONG POINTER TO ARRAY [0..PrincOps.wordsPerPage) OF WORD]^ _ ALL[0]; ENDLOOP; END; StartImage: PUBLIC PROC [band: Index] = BEGIN imageLoc.overrun _ 0; imageLoc.run _ band; END; BandOverrun: PUBLIC PROC RETURNS [BOOLEAN] = BEGIN RETURN[imageLoc.overrun # 0]; END; AdvanceBand: PUBLIC PROC [currentBand: Index] RETURNS [Index, LONG POINTER] = BEGIN b: LONG POINTER TO BandRecord = @bandRecordBase[currentBand]; b.status _ LAST[INTEGER]; imageLoc.lastStartedBand _ currentBand; RETURN[b.next, @bandBufferBase[bandRecordBase[b.next].band]]; END; BandFull: PUBLIC PROC [band: Index] RETURNS [BOOLEAN] = BEGIN RETURN[bandRecordBase[band].status # 0]; END; LastBand: PUBLIC PROC [band: Index] = BEGIN bandRecordBase[band].status _ -1; imageLoc.lastStartedBand _ band; END; PutCommand: PUBLIC PROC [command: BYTE] = BEGIN controlLocal: LONG POINTER TO CCSB = LOOPHOLE[DLionInputOutput.IOPage + 60B]; CCSB: TYPE = MACHINE DEPENDENT RECORD [unused(0): WORD, mask(1): WORD, data(2): WORD, status(3): WORD]; UNTIL controlLocal.status = 0 DO --GORP??-- ENDLOOP; controlLocal.data _ command + 80H; controlLocal.status _ LAST[WORD] END; GetStatus: PUBLIC PROC RETURNS [status: BYTE] = BEGIN statusLocal: LONG POINTER TO SCSB = LOOPHOLE[DLionInputOutput.IOPage + 64B]; -- FF34'x SCSB: TYPE = MACHINE DEPENDENT RECORD [overrun(0): WORD, mask(1): WORD, data(2): WORD, status(3): CARDINAL]; -- actually PrinterStatus IF statusLocal.overrun # 0 THEN {statusLocal.status _ 0; statusLocal.overrun _ 0; status _ 177B} ELSE IF statusLocal.status # 0 THEN {status _ LOOPHOLE[PrincOpsUtils.BITAND[statusLocal.data, 177B]]; statusLocal.status _ 0} ELSE status _ 0; END; Loader.MakeProcedureResident[AllocateBands]; Loader.MakeGlobalFrameResident[AllocateBands]; Loader.MakeProcedureResident[DeallocateBands]; Loader.MakeGlobalFrameResident[DeallocateBands]; Loader.MakeProcedureResident[SetInterruptMasks]; Loader.MakeGlobalFrameResident[SetInterruptMasks]; Loader.MakeProcedureResident[InitializeCleanUp]; Loader.MakeGlobalFrameResident[InitializeCleanUp]; Loader.MakeProcedureResident[SetScanLineLength]; Loader.MakeGlobalFrameResident[SetScanLineLength]; Loader.MakeProcedureResident[SetPageOffsets]; Loader.MakeGlobalFrameResident[SetPageOffsets]; Loader.MakeProcedureResident[ResetBands]; Loader.MakeGlobalFrameResident[ResetBands]; Loader.MakeProcedureResident[ZeroBands]; Loader.MakeGlobalFrameResident[ZeroBands]; Loader.MakeProcedureResident[StartImage]; Loader.MakeGlobalFrameResident[StartImage]; Loader.MakeProcedureResident[BandOverrun]; Loader.MakeGlobalFrameResident[BandOverrun]; Loader.MakeProcedureResident[AdvanceBand]; Loader.MakeGlobalFrameResident[AdvanceBand]; Loader.MakeProcedureResident[BandFull]; Loader.MakeGlobalFrameResident[BandFull]; Loader.MakeProcedureResident[LastBand]; Loader.MakeGlobalFrameResident[LastBand]; Loader.MakeProcedureResident[PutCommand]; Loader.MakeGlobalFrameResident[PutCommand]; Loader.MakeProcedureResident[GetStatus]; Loader.MakeGlobalFrameResident[GetStatus]; END...... Log: XXP /July 23, 1981 11:07 AM/Modified "PutCommand". XXP /August 12, 1981 8:53 PM/Implemented "DozeOff" and "WakeUp" PROCEDUREs. XXP /August 18, 1981 11:35 AM/Cleaned-up DIRECTORY. XXP /September 26, 1981 6:31 PM/ 1. Modified "AllocateBands" as follows: (a) call to "SpecialSpace.CreateForCode"; (b) call to "DLionInputOutput.DonateReservedMemory". 2. Modified "DeallocateBands" as follows: (a) call to "Space.Delete". Those changes were made to allow hiding the fact that SOME space MUST be reserved ("bandBufferPadding" pages) beyond the actually used BandBuffer area I also took this opportunity to move DLionInputOutput.DonateReservedMemory into AllocateBands, where it seems to belong. Question: is InitializeCleanUp now doing ALL it is supposed to do? FXH ? merged Claude's changes into Pilot version, except for the head creating/destroying the space and calling DonateReservedMemory. 14-Nov-81 15:06:15 JXP fold in changes made by JGS for bootstrap 15-Feb-82 9:03:01 FXH add lost edit for resolution pair 2-Mar-82 13:40:35 CRF and FXH Add special BitBlt-independent implementations of BYTBLTR and BLTLR so that they may be used with JLSEPMesa.db. 16-Mar-82 13:22:22 FXH Change Display to allow for display of 'F. 25-Mar-82 10:53:05 CRF Add special BitBlt-independent implementation of BYTBLT so that it may be used with RavenMesa.db (which used to be called JLSEPMesa.db). 26-Mar-82 15:12:52 CRF Deleted BYTBLT, BYTBLTR, and BLTLR implementations (they were merged into the ProcessorHeadDLion implementations). 28-Jul-82 10:17:04 AEF New IOPage layout. 9-Apr-83 14:47:56 AEF Don't use Utilities. 11-Apr-83 11:29:09 AEF Change use of PageMap. Time: 26-Sep-84 10:17:42 By: DXG Action: Added copyright notice and rebuild for 11.1 release. 7-Jun-85 11:50:38: NXS Created device independant version, changed name from RavenHeadDLion to LSEPHeadDLion for 12.0, fix PutCommand to allow send of 0. <LSEPHeadDLion.mesa Copyright Σ 1981, 1982, 1983, 1985, 1987 by Xerox Corporation. All rights reserved. Tim Diebert: January 27, 1987 1:13:31 pm PST To do: bury ImageCSB.lineSize into the microcode. Re-arrrange ImageCSB to make fields the microcode cares about contiguous. DLionInputOutput USING [ firstReservedPage, IOPage, ioPageRealAddrLow, lsepControlDataOffset, lsepControlDataMax, lsepControlMaskOffset, lsepControlMaskMax, lsepImageCSBOffset, lsepImageCSBMax, lsepStatusMaskOffset, lsepStatusMaskMax, lsepStatusOffset, lsepStatusMax, SetReservedMemoryUse], There is a game going on that the relative pointers "work" in relation BOTH to Physical 10000x and some virtual Base addresses. LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepImageCSBOffset]; compileCheckLSEPSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepImageCSBMax >= (SIZE[BandRecord] * MaxBands + SIZE[ImageCSB])); firstBandRecord: Index = LOOPHOLE[DLionInputOutput.ioPageRealAddrLow + 20B + SIZE[ImageCSB], BandRecordBase RELATIVE ORDERED POINTER TO BandRecord]; LOOPHOLE[DLionInputOutput.ioPageRealAddrLow + DLionInputOutput.lsepImageCSBOffset + SIZE[ImageCSB]]; LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepControlMaskOffset]; compileCheckControlMaskSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepControlMaskMax >= SIZE[ControlMask]); LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepControlDataOffset]; compileCheckControlDataSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepControlDataMax >= SIZE[ControlData]); LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepStatusMaskOffset]; compileCheckStatusMaskSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepStatusMaskMax >= SIZE[StatusMask]); LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepStatusOffset]; compileCheckStatusSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepStatusMax >= SIZE[BYTE]); DLionInputOutput.SetReservedMemoryUse[Raven, pagesCurrentlyInBands]; PageMap.SetMapFlags[ virtual: bandVirtualPageNumber + i, real: DLionInputOutput.firstReservedPage + i, flags: PageMap.flagsClean]; IF bandVirtualPageNumber + i # DLionInputOutput.firstReservedPage + i THEN ERROR; FOR i: PrincOps.PageCount IN [0..pagesCurrentlyInBands) DO PageMap.SetMapFlags[ virtual: bandBufferBasePage + i, real: 0, flags: PageMap.flagsVacant] ENDLOOP; DLionInputOutput.SetReservedMemoryUse[notBusy]; FOR i: LONG CARDINAL IN [0..pagesCurrentlyInBands) DO PageMap.SetMapFlags[ virtual: bandBufferBasePage + i, real: 0, flags: PageMap.flagsVacant]; ENDLOOP; UNTIL controlDataLoc^ = 0 DO ENDLOOP; controlDataLoc^ _ command + 80H; -- send off a command byte (controlDataLoc+1)^ _ LAST[WORD]; -- For the Pilot 6 version of Domino status _ statusLoc^; -- pick up previously recieved status byte statusLoc^ _ 0; Old Pilot 6 head stuff...... due to the possibility of BandBLT writing beyond that BandBuffer area. Κ Ώ˜codešœ™KšœU™UK™,K™Kšœ1™1KšœI™I—K˜šΟk ˜ Kšœ œ ˜/Kšœœ˜*Kšœœ0˜Fšœœ™K™DK™>K™MK™7—Kšœœ2˜>K˜ Kšœ œ'˜5Kšœœœ˜-Kšœœ˜ —K˜šΟn œ˜KšœD˜MKšœ ˜Kšœœ ˜—˜Kšœ™Kš œœœœœœœ ˜KKšœœœœœœœ œ˜AKšœœœœΟc$˜RKšœœœœœœœ œ˜Aš œ œœ œœ˜-Kšœ˜Kšœ˜Kšœ œ˜——˜š œ œœœ  œ ˜MKšœ@™H——˜š œ œœ œœ˜+K˜Kšœ œŸ˜2Kšœ œŸ˜,Kšœ œŸ!˜9KšœŸ#˜?Kšœ œŸ˜(KšœœŸ.˜AKšœ œŸ'˜=——˜Kš œœœœ*œœ ™‚—˜Kšœ œ˜6š œ œ,œœœœœ ™”KšœLœ ™d—Kšœ6œ ˜G˜ Kšœ œ œœ˜J——˜šœœœœ˜-Kšœ ˜(KšœC™K——˜Kšœ œœ˜—˜Kš œœœœ,œ™o—˜šœœœœ˜-Kšœ ˜(KšœC™K——˜Kšœ œœ˜—˜Kš œœœœ,œ™o—˜šœœœœ ˜+Kšœ ˜(KšœB™J——˜Kšœ œœ˜—˜Kš œœœœ+œ™l—˜š œ œœœœ˜!Kšœ ˜(Kšœ>™F——˜Kš œœœœ'œœ™^—K˜˜Kšœ.˜.K˜Kšœ(˜(Kšœœ˜—˜š žœœœœ ˜CKšœœœœ˜<——˜šž œœœ„˜€KšœœR˜eK˜+K˜5K™DšœœœŸ˜J™K™#K™I—Kšœœ2 œœœœœœ˜KšœDœœ™QKšœ˜—šœœœ ˜!˜šœ œ+œ˜PKšœ1œ ˜=—K˜ —Kšœ˜—Kšœœ˜+K˜%K˜*Kšœ˜——˜šžœœœ˜$K˜%šœœ™:™K™E—Kšœ™—K˜K™/Kšœ˜——˜š žœœœœ˜DK˜K˜K˜Kšœ˜——˜šžœœœ˜&K˜K˜Kšœ œœœ˜:K˜IK˜š˜K˜:šœ˜šœ ˜Kšœ8˜8šœ&˜,šœ3˜8Kšœ5œœ˜C——K˜Kšœ˜—šœ œŸ.˜?K˜$K˜Kšœ˜—˜š œœœœ™5™K™)K™—Kšœ™——Kšœ˜—Kšœ˜—Kšœ˜——˜šžœœœ8˜\K˜Ušœ!œ œ˜QKš œ œœ œœ7˜bKšœ5˜=Kšœ˜—Kšœ˜——˜š žœœœ œ œ˜HKšœ7œ˜@——˜š ž œœœœ œœ˜=K˜%šœ!œ œ˜NKšœœ˜)—KšœI˜OKšœ˜——˜šž œœœ˜šœœ˜:Kšœœ/ œœœœœœ˜~Kšœ˜—Kšœ˜——˜šž œœœ˜'Kšœ,œ˜5——˜š ž œœœœœ˜,Kšœœœ˜(——˜š ž œœœœ œœ˜SKšœœœœ+˜=Kšœ œœ˜K˜'Kšœ7˜=Kšœ˜——˜š žœœœœœ˜7Kšœœ#œ˜3——˜šžœœœ˜%KšœDœ˜M——˜š ž œœœ œ˜/Kšœœœ™%Kšœ!Ÿ™;KšœœœŸ$™GKš œœœœœœ ˜MKšœœœ œœ œ œ œ œ˜gKšœœŸ œœ˜4Kšœ"˜"Kšœœœ˜ Kšœ˜——˜š ž œœœœ œ˜5KšœŸ*™@K™K™Kš œ œœœœœ!Ÿ ˜VKšœœœ œœœ œ œ œŸ˜†šœ˜KšœA˜Ešœœ˜Kšœ œœ2˜^Kšœ ˜——Kšœ˜—K˜Kšœ,˜,Kšœ.˜.Kšœ.˜.Kšœ0˜0Kšœ0˜0Kšœ2˜2Kšœ0˜0Kšœ2˜2Kšœ0˜0Kšœ2˜2Kšœ-˜-Kšœ/˜/Kšœ)˜)Kšœ+˜+Kšœ(˜(Kšœ*˜*Kšœ)˜)Kšœ+˜+Kšœ*˜*Kšœ,˜,Kšœ*˜*Kšœ,˜,Kšœ'˜'Kšœ)˜)Kšœ'˜'Kšœ)˜)Kšœ)˜)Kšœ+˜+Kšœ(˜(Kšœ*˜*K˜K˜—Kšœ˜ K˜Kšœœ˜3Kšœœ/˜LKšœœ  œ˜4šœœ˜!˜'K˜)K˜4—˜)K˜—Kšœ6œ˜EK˜PKšœF™FK˜^K˜Kšœ)œ˜B—Kšœ†˜‰K˜šœ!œ˜'Kšœœ˜-—šœ!œ˜(K˜!šœ œœ˜/Kšœ2œœ ˜PK˜——šœ!œ˜(K˜*—šœ!˜$Kšœ1œ˜NK˜9—šœ!˜$KšœœœœP˜r—šœ!œ˜)K˜šœ œ˜(K˜——šœ!œ˜)K˜—šœžœœžœ6˜bKšœœƒ˜™—K˜—…—(Ζ@Α