-- AltoScreenImpl.mesa
-- Last changed by Doug Wyatt, December 4, 1980 4:26 PM

DIRECTORY
AltoDevice USING [Bitmap],
Blt USING [Handle, New, SetX, SetY, Rect, Free],
Memory USING [long],
AltoDisplay USING [DCBHandle, LongDCB, DCBchainHead, DCBnil, LongDCBSeal,
MaxWordsPerLine, MaxScanLines],
AltoHardware USING [BankRegisters],
InlineDefs USING [LowHalf],
SegmentDefs USING [DataSegmentHandle, NewDataSegment, BitmapDS,
DefaultXMBase, DefaultBase0, DefaultBase1, DefaultBase2, DefaultBase3,
LongDataSegmentAddress],
SystemDefs USING [Even, PagesForWords];

AltoScreenImpl: PROGRAM
IMPORTS Blt,Memory,InlineDefs,SegmentDefs,SystemDefs
EXPORTS AltoDevice = {

Bitmap: TYPE = AltoDevice.Bitmap;

dcbsp: ARRAY [0..SIZE[AltoDisplay.LongDCB]] OF WORD;
dcb: AltoDisplay.DCBHandle←SystemDefs.Even[@dcbsp];
screenBitmap: Bitmap ← [NIL,0,0];
screenx,screeny: CARDINAL←0;

ScreenBitmap: PUBLIC PROCEDURE RETURNS[Bitmap] = {
IF screenBitmap.base=NIL THEN InitScreen[];
RETURN[screenBitmap];
};

InitScreen: PROCEDURE = {
OPEN SegmentDefs,AltoDisplay;
pnext: POINTER TO DCBHandle←DCBchainHead;
w,h,words,pages: CARDINAL;
seg: DataSegmentHandle;
UNTIL pnext↑=NIL DO
dcb: DCBHandle=pnext↑;
screeny←screeny+2*dcb.height;
pnext←@dcb.next
ENDLOOP;
w←MaxWordsPerLine; h←MaxScanLines-screeny;
words←w*h; pages←SystemDefs.PagesForWords[words];
seg ← NewDataSegment[
base: IF Memory.long THEN DefaultXMBase
ELSE (SELECT AltoHardware.BankRegisters[DWT].normal FROM
0 => DefaultBase0,
1 => DefaultBase1,
2 => DefaultBase2,
3 => DefaultBase3,
ENDCASE => ERROR),
pages: pages];
seg.type ← BitmapDS;
screenBitmap ← [base: LongDataSegmentAddress[seg], raster: w, height: h];
ClearBitmap[screenBitmap];
IF Memory.long THEN {
ldcb: POINTER TO LongDCB=LOOPHOLE[dcb];
ldcb↑←[next: DCBnil, resolution: high, background: white,
indenting: 0, width: w, height: h/2,
tag: long, bitmap: LongDCBSeal,
longBitmap: screenBitmap.base];
}
ELSE dcb↑←[next: DCBnil, resolution: high, background: white,
indenting: 0, width: w, height: h/2,
bitmap: InlineDefs.LowHalf[screenBitmap.base]];
pnext↑←dcb;
};

ClearBitmap: PROCEDURE[b: Bitmap] = {
blt: Blt.Handle←Blt.New[b.base,b.raster];
Blt.SetX[blt,0,16*b.raster];
Blt.SetY[blt,0,b.height];
blt.grays[0]←125252B; blt.grays[1]←52525B;
blt.grays[2]←125252B; blt.grays[3]←52525B;
Blt.Rect[blt]; Blt.Free[@blt];
};

ScreenOrigin: PUBLIC PROCEDURE RETURNS[x,y: CARDINAL] = {
RETURN[x: screenx, y: screeny]
};

}.