<> <> <> <<>> <> <> DIRECTORY BasicTime USING [Pulses, MicrosecondsToPulses], DeviceCleanup USING [Item, Reason, Await], DLionInputOutput USING [ firstReservedPage, IOPage, ioPageRealAddrLow, lsepControlDataOffset, lsepControlDataMax, lsepControlMaskOffset, lsepControlMaskMax, lsepImageCSBOffset, lsepImageCSBMax, lsepStatusMaskOffset, lsepStatusMaskMax, lsepStatusOffset, lsepStatusMax], Loader USING [MakeProcedureResident, MakeGlobalFrameResident], LSEPFace, PrincOps USING [PageCount, PageNumber, wordsPerPage], PrincOpsUtils USING [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 + DLionInputOutput.lsepImageCSBOffset]; 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 compileCheckLSEPSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepImageCSBMax >= (SIZE[BandRecord] * MaxBands + SIZE[ImageCSB])); firstBandRecord: Index = LOOPHOLE[(DLionInputOutput.ioPageRealAddrLow + DLionInputOutput.lsepImageCSBOffset + NAT[SIZE[ImageCSB]]), BandRecordBase RELATIVE ORDERED POINTER TO BandRecord]; bandRecordLimit: Index = firstBandRecord + MaxBands * SIZE[BandRecord]; bandRecordBase: BandRecordBase = LOOPHOLE[imageLoc + SIZE[ImageCSB] - LOOPHOLE[firstBandRecord, CARDINAL]]; controlMaskLoc: LONG POINTER TO ControlMask = LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepControlMaskOffset]; ControlMask: TYPE = WORD; compileCheckControlMaskSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepControlMaskMax >= SIZE[ControlMask]); controlDataLoc: LONG POINTER TO ControlData = LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepControlDataOffset]; ControlData: TYPE = WORD; compileCheckControlDataSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepControlDataMax >= SIZE[ControlData]); statusMaskLoc: LONG POINTER TO StatusMask = LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepStatusMaskOffset]; StatusMask: TYPE = WORD; compileCheckStatusMaskSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepStatusMaskMax >= SIZE[StatusMask]); statusLoc: LONG POINTER TO BYTE = LOOPHOLE[DLionInputOutput.IOPage + DLionInputOutput.lsepStatusOffset]; compileCheckStatusSize: BOOLEAN [TRUE..TRUE] = (DLionInputOutput.lsepStatusMax >= SIZE[BYTE]); 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 UNTIL controlDataLoc^ = 0 DO ENDLOOP; controlDataLoc^ _ command + 80H; -- send off a command byte END; GetStatus: PUBLIC PROC RETURNS [status: BYTE] = BEGIN status _ statusLoc^; -- pick up previously recieved status byte statusLoc^ _ 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.