<> <> <> <<>> <> <> DIRECTORY BasicTime USING [Pulses, MicrosecondsToPulses], DeviceCleanup USING [Item, Reason, Await], DLionInputOutput USING [firstReservedPage, IOPage], <> <> <> <> <> 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 <= (SIZE[BandRecord] * MaxBands + SIZE[ImageCSB]));>> 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; <= SIZE[ControlMask]);>> controlDataLoc: LONG POINTER TO ControlData = LOOPHOLE[DLionInputOutput.IOPage + 62B]; <> ControlData: TYPE = WORD; <= SIZE[ControlData]);>> statusMaskLoc: LONG POINTER TO StatusMask = LOOPHOLE[DLionInputOutput.IOPage + 65B]; <> StatusMask: TYPE = WORD; <= SIZE[StatusMask]);>> statusLoc: LONG POINTER TO BYTE = LOOPHOLE[DLionInputOutput.IOPage + 66B]; <> <= 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 <> <> <<(controlDataLoc+1)^ _ LAST[WORD]; -- For the Pilot 6 version of Domino>> 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.