-- XDisplay.mesa -- Mesa 6 version (won't work on Alto) -- Last changed by Doug Wyatt, May 31, 1980 10:16 PM DIRECTORY XDisplayDefs USING [BankIndex, BBAPtr, BBArray, BBDest, BBPtr, BMPtr, BitBlt, DcbArray, dcbChain, dcbNIL, DcbPtr, FirstDcb, LPBank, LPPtr, NextDcb, pBitBlt], AltoHardware USING [BankRegisters, Task], BitBltDefs USING [BITBLT], ImageDefs USING [AddCleanupProcedure, AllReasons, CleanupItem, CleanupProcedure], SegmentDefs, SystemDefs USING [PagesForWords]; XDisplay: PROGRAM IMPORTS XDisplayDefs,BitBltDefs,ImageDefs,SegmentDefs,SystemDefs EXPORTS XDisplayDefs SHARES XDisplayDefs = BEGIN OPEN XDisplayDefs; XDisplayError: PUBLIC SIGNAL = CODE; dBank: PUBLIC BankIndex_0; -- AltoIIXM bank registers Task: TYPE = AltoHardware.Task; -- The display word task (DWT) is the one that reads words -- out of the bitmap; its bank register supplies the high order -- bits of the long pointer used to address those words. SelectDBank: PROCEDURE[config: SegmentDefs.MemoryConfig] RETURNS[BankIndex] = BEGIN -- b: BankIndex; -- FOR b IN (0..LAST[BankIndex]] -- DO -- IF InlineDefs.BITAND[config.banks,bankMasks[b]]#0 THEN RETURN[b]; -- ENDLOOP; RETURN[0]; END; EnableDBank: PROCEDURE[BOOLEAN] _ NoopEnableDBank; NoopEnableDBank: PROCEDURE[BOOLEAN] = BEGIN END; AltoEnableDBank: PROCEDURE[on: BOOLEAN] = BEGIN AltoHardware.BankRegisters[DWT].normal_IF on THEN dBank ELSE 0 END; AllocDSegment: PUBLIC PROCEDURE[pages: CARDINAL] RETURNS[LONG POINTER] = BEGIN OPEN SegmentDefs; RETURN[LongSegmentAddress[NewDataSegment[ base: DefaultXMBase, pages: pages]]]; END; FreeDSegment: PUBLIC PROCEDURE[lp: LONG POINTER] = BEGIN OPEN SegmentDefs; DeleteDataSegment[LongVMtoDataSegment[lp]]; END; -- Bitmaps BMSize: PUBLIC PROCEDURE[bm: BMPtr, width,height: CARDINAL] = BEGIN w: CARDINAL_(width+15)/16; -- words required for width bm^_[base: NIL, raster: w, lines: height]; END; BMDisplaySize: PUBLIC PROCEDURE[bm: BMPtr, width,height: CARDINAL] = BEGIN dw: CARDINAL_(width+31)/32; -- double words required for width dl: CARDINAL_(height+1)/2; -- double scanlines required for height bm^_[base: NIL, raster: 2*dw, lines: 2*dl]; END; AllocBitmap: PUBLIC PROCEDURE[bm: BMPtr] = BEGIN pages: CARDINAL_SystemDefs.PagesForWords[bm.raster*bm.lines]; IF pages>0 THEN BEGIN bm.base_AllocDSegment[pages]; ClearBitmap[bm] END ELSE bm.base_NIL; END; FreeBitmap: PUBLIC PROCEDURE[bm: BMPtr] = BEGIN IF bm.base#NIL THEN BEGIN FreeDSegment[bm.base]; bm.base_NIL END; END; ClearBitmap: PUBLIC PROCEDURE[bm: BMPtr] = BEGIN bba: BBArray; bbt: BBPtr_BBInit[@bba]; IF bm.base=NIL THEN RETURN; BBDest[bbt,bm]; bbt.dw_bm.raster*16; bbt.dh_bm.lines; BitBlt[bbt]; END; -- Display Control Blocks Even: PROCEDURE[p: POINTER] RETURNS[POINTER] = INLINE BEGIN RETURN[p+(LOOPHOLE[p,CARDINAL] MOD 2)] END; dcbSeal: POINTER = LOOPHOLE[177423B]; -- The D-machines will regard dcb.lbitmap as the bitmap pointer only if -- dcb.tag=long AND dcb.bitmap=dcbSeal DcbInit: PUBLIC PROCEDURE[dcba: POINTER TO DcbArray] RETURNS[DcbPtr] = BEGIN dcb: DcbPtr_Even[dcba]; dcb^_[]; -- use default initialization in XDisplayDefs RETURN[dcb]; END; EnumerateDcbs: PUBLIC PROCEDURE [Proc: PROCEDURE[DcbPtr] RETURNS[BOOLEAN]] RETURNS[DcbPtr] = BEGIN dcb: DcbPtr; FOR dcb_FirstDcb[],NextDcb[dcb] UNTIL dcb=dcbNIL DO IF Proc[dcb] THEN EXIT ENDLOOP; RETURN[dcb]; END; LinesAbove: PUBLIC PROCEDURE[dcb: DcbPtr] RETURNS[CARDINAL] = BEGIN lines: CARDINAL_0; CountLines: PROCEDURE[tdcb: DcbPtr] RETURNS[BOOLEAN] = BEGIN IF tdcb=dcb THEN RETURN[TRUE] ELSE BEGIN lines_lines+2*tdcb.height; RETURN[FALSE] END; END; []_EnumerateDcbs[CountLines]; RETURN[lines]; END; InsertDcb: PUBLIC PROCEDURE[dcb,otherdcb: DcbPtr] = BEGIN Ins: PROCEDURE[tdcb: DcbPtr] RETURNS[BOOLEAN] = BEGIN found: BOOLEAN_(tdcb.next=otherdcb); IF found THEN tdcb.next_dcb; RETURN[found]; END; dcb.next_otherdcb; IF otherdcb=dcbChain^ THEN dcbChain^_dcb ELSE []_EnumerateDcbs[Ins]; END; RemoveDcb: PUBLIC PROCEDURE[dcb: DcbPtr] = BEGIN Rem: PROCEDURE[tdcb: DcbPtr] RETURNS[BOOLEAN] = BEGIN found: BOOLEAN_(tdcb.next=dcb); IF found THEN tdcb.next_dcb.next; RETURN[found]; END; IF dcb=dcbChain^ THEN dcbChain^_dcb.next ELSE []_EnumerateDcbs[Rem]; dcb.next_dcbNIL; END; Displayed: PUBLIC PROCEDURE[dcb: DcbPtr] RETURNS[BOOLEAN] = BEGIN Match: PROCEDURE[tdcb: DcbPtr] RETURNS[BOOLEAN] = BEGIN RETURN[tdcb=dcb] END; RETURN[EnumerateDcbs[Match]=dcb]; END; DcbBitmapProc: PROCEDURE[DcbPtr,BMPtr] _ ShortDcbBitmap; pDcbBitmap: PUBLIC POINTER TO PROCEDURE[DcbPtr,BMPtr] _ @DcbBitmapProc; ShortDcbBitmap: PROCEDURE[dcb: DcbPtr, bm: BMPtr] = BEGIN IF bm.base#NIL AND LPBank[bm.base]#dBank THEN BEGIN SIGNAL XDisplayError; RETURN END; -- Bitmap not in dBank dcb.width_0; dcb.tag_short; dcb.bitmap_LPPtr[bm.base]; dcb.height_bm.lines/2; dcb.width_(bm.raster/2)*2; END; LongDcbBitmap: PROCEDURE[dcb: DcbPtr, bm: BMPtr] = BEGIN dcb.width_0; dcb.tag_long; dcb.bitmap_dcbSeal; dcb.lbitmap_bm.base; dcb.height_bm.lines/2; dcb.width_(bm.raster/2)*2; END; -- BitBlt BBInit: PUBLIC PROCEDURE[bba: BBAPtr] RETURNS[BBPtr] = BEGIN bb: BBPtr_Even[bba]; bb^_[]; -- use default initialization in XDisplayDefs RETURN[bb]; END; BitBltProc: PROCEDURE[BBPtr,BankIndex] _ AltoBitBlt; pBitBlt: PUBLIC POINTER TO PROCEDURE[BBPtr,BankIndex] _ @BitBltProc; AltoBitBlt: PROCEDURE[bbt: BBPtr, altbank: BankIndex] = BEGIN ERROR XDisplayError; -- AltoBitBlt not implemented END; D0BitBlt: PROCEDURE[bbt: BBPtr, altbank: BankIndex] = BEGIN bbt.ptrs_D0; BitBltDefs.BITBLT[LOOPHOLE[bbt]]; bbt.ptrs_Alto; END; Reconfigure: PROCEDURE = BEGIN bankreg,dmachine: BOOLEAN; config: SegmentDefs.MemoryConfig_SegmentDefs.GetMemoryConfig[]; bankreg_config.AltoType=AltoIIXM; -- only AltoIIXM has bank registers dmachine_config.AltoType=D0 OR config.AltoType=Dorado; EnableDBank_IF bankreg THEN AltoEnableDBank ELSE NoopEnableDBank; BitBltProc_IF dmachine THEN D0BitBlt ELSE AltoBitBlt; DcbBitmapProc_IF dmachine THEN LongDcbBitmap ELSE ShortDcbBitmap; dBank_SelectDBank[config]; EnableDBank[TRUE]; END; XDisplayCleanupItem: ImageDefs.CleanupItem _ [link:, proc: XDisplayCleanupProc, mask: ImageDefs.AllReasons]; XDisplayCleanupProc: ImageDefs.CleanupProcedure = BEGIN SELECT why FROM Finish,Abort => BEGIN dcbChain^ _ dcbNIL; EnableDBank[FALSE] END; Save,Checkpoint => EnableDBank[FALSE]; InLd => EnableDBank[TRUE]; Restore,Continue => Reconfigure; ENDCASE; END; XDisplayCleanupProc[Restore]; ImageDefs.AddCleanupProcedure[@XDisplayCleanupItem]; END.