-- UserTerminalHeadDorado.mesa
-- Last Edited by: Taft, February 27, 1983 3:27 pm
DIRECTORY
BitBlt USING [BBTable],
DoradoInputOutput USING [RWMufMan, savedCursor, SetDisplayFieldRate],
DeviceCleanup USING [Await, Item, Reason],
DisplayFace USING [Background, CursorPtr, GlobalStatePtr, Point],
DisplayFaceExtras USING [FieldRate, MonitorType],
Environment USING [bitsPerWord, first64K, PageCount, PageNumber, wordsPerPage],
HeadStartChain USING [Start],
Inline USING [BITOR, LongMult, LowHalf],
KeyboardFace USING [],
KeyStations USING [KeyBits],
MouseFace USING [Buttons, Point],
ProcessorFace USING [GetClockPulses, microsecondsPerHundredPulses],
RuntimeInternal USING [WorryCallDebugger],
SoundGenerator USING [];
UserTerminalHeadDorado: PROGRAM
IMPORTS
DeviceCleanup, DoradoInputOutput, RemainingHeads: HeadStartChain, Inline,
ProcessorFace, RuntimeInternal
EXPORTS
DisplayFace, DisplayFaceExtras, HeadStartChain, KeyboardFace, MouseFace, ProcessorFace,
SoundGenerator =
BEGIN
ErrorHalt: PROCEDURE = {
RuntimeInternal.WorryCallDebugger["Error in UserTerminalHeadDorado"L]};
--
-- DisplayFace
CSBPtr: TYPE = LONG POINTER TO CSBState;
CSBState: TYPE = MACHINE DEPENDENT RECORD [
dcbChainHead: PDCB, wakeupMask: WORD];
csbPtr: CSBPtr = LOOPHOLE[LONG[420B]]; -- SHOULD MOVE TO IO PAGE
PDCB: TYPE = POINTER TO DCB;
DCB: TYPE = MACHINE DEPENDENT RECORD [ -- address must be even
next: PDCB,
resolution: {high, low},
background: DisplayFace.Background,
indenting: [0..77B], -- in units of 16 bits
width: [0..377B], -- in units of 16 bits; must be even
shortBitmap: POINTER, -- must be even
tag: {short, long},
height: [0..77777B], -- in double scan lines
longBitmap: LONG POINTER]; -- must be even
longBitMapSeal: POINTER = LOOPHOLE[177423B]; -- required value of DCB.shortBitmap
displayState: {disconnected, off, on} ← disconnected;
bitmapBase: LONG POINTER; -- undefined if displayState=disconnected
pDCBReal: LONG POINTER TO DCB;
pDCBBlank: LONG POINTER TO DCB;
pDCBNull: PDCB = LOOPHOLE[0];
hasBuffer: PUBLIC BOOLEAN ← FALSE;
pagesForBitmap: PUBLIC Environment.PageCount; -- see initialization below
Connect: PUBLIC PROCEDURE [bitmap: Environment.PageNumber] =
BEGIN
displayState ← off;
bitmapBase ← LOOPHOLE[Inline.LongMult[bitmap, Environment.wordsPerPage]];
-- LongPointerFromPage
csbPtr.dcbChainHead ← Inline.LowHalf[pDCBBlank]; -- DCB's are in first64K
END;
Disconnect: PUBLIC PROCEDURE = {
displayState ← disconnected; csbPtr.dcbChainHead ← pDCBNull};
TurnOn: PUBLIC PROCEDURE =
BEGIN
IF displayState = disconnected THEN ErrorHalt[];
displayState ← on;
pDCBReal.longBitmap ← bitmapBase;
csbPtr.dcbChainHead ← Inline.LowHalf[pDCBReal] -- DCB's are in first64K
END;
TurnOff: PUBLIC PROCEDURE =
BEGIN
IF displayState = disconnected THEN ErrorHalt[];
displayState ← off;
csbPtr.dcbChainHead ← Inline.LowHalf[pDCBBlank]; -- DCB's are in first64K
END;
GetBitBltTable: PUBLIC PROCEDURE RETURNS [BitBlt.BBTable] =
BEGIN
IF displayState = disconnected THEN ErrorHalt[];
RETURN[
[
dst: [word: bitmapBase, bit: 0], dstBpl: bitmapWidth,
src: [word: bitmapBase, bit: 0], srcDesc: [srcBpl[bitmapWidth]],
width: width, height: height, flags: []]];
END;
SetBackground: PUBLIC PROCEDURE [background: DisplayFace.Background] = {
pDCBReal.background ← pDCBBlank.background ← background};
-- See Start for initialization:
width: PUBLIC CARDINAL [0..32767] ← lfWordsPerLine*Environment.bitsPerWord;
cslWordsPerLine: CARDINAL = 38;
lfWordsPerLine: CARDINAL = 64;
torWordsPerLine: CARDINAL = 40;
-- Size of bitmap, possibly large than screen image (initialized in Start):
bitmapWidth: CARDINAL ← lfWordsPerLine*Environment.bitsPerWord;
-- See Start for initialization:
height: PUBLIC CARDINAL [0..32767] ← 808; -- LF and CSL
torHeight: CARDINAL = 800;
pixelsPerInch: PUBLIC CARDINAL ← 72;
-- See Start for initialization:
refreshRate: PUBLIC CARDINAL ← lfRefreshRate; -- frames (two fields) per second
cslRefreshRate: CARDINAL = 30;
lfRefreshRate: CARDINAL = 38; -- actually ??
interlaced: PUBLIC BOOLEAN ← TRUE;
-- Scan line wakeups
-- SetScanLineWakeup not implemented.
-- GetScanLine not implemented.
-- Boarder pattern
hasBorder: PUBLIC BOOLEAN ← FALSE;
SetBorderPattern: PUBLIC PROCEDURE [oddPairs, evenPairs: [0..377B]] = {};
-- Cursor
pHardwareCursor: DisplayFace.CursorPtr = LOOPHOLE[LONG[431B]];
SetCursorPattern: PUBLIC PROCEDURE [cursorPtr: DisplayFace.CursorPtr] =
BEGIN pHardwareCursor↑ ← cursorPtr↑; DoradoInputOutput.savedCursor ← cursorPtr↑; END;
cursorPosition: PUBLIC LONG POINTER TO DisplayFace.Point ← LOOPHOLE[LONG[426B]];
-- Initialization
globalStateSize: PUBLIC CARDINAL ← SIZE[DCB]*2;
InitializeCleanup: PUBLIC PROCEDURE =
BEGIN OPEN DeviceCleanup;
item: Item;
reason: Reason;
state: CSBState;
mouseCoord: MouseFace.Point;
cursorCoord: DisplayFace.Point;
timeDone: LONG CARDINAL;
maxPulsesPerRefresh: LONG CARDINAL =
2* --for safety--
(LONG[100]* --pulsesPerHundredPulses-- 1000000 --microsecondsPerSecond--
)/(LONG[refreshRate] --framesPerSecond--
*ProcessorFace.microsecondsPerHundredPulses);
DO
reason ← Await[@item];
SELECT reason FROM
turnOff =>
BEGIN
state ← csbPtr↑;
mouseCoord ← mouse↑;
cursorCoord ← cursorPosition↑;
-- copy of cursor pattern itself is saved by SetCursorPattern
csbPtr.dcbChainHead ← pDCBNull;
timeDone ← ProcessorFace.GetClockPulses[];
WHILE ProcessorFace.GetClockPulses[] - timeDone < maxPulsesPerRefresh DO
ENDLOOP;
END;
turnOn =>
BEGIN
mouse↑ ← mouseCoord;
cursorPosition↑ ← cursorCoord;
-- cursor pattern itself is restored by SetMP trap handler in ProcessorHeadDorado
csbPtr↑ ← state;
END;
ENDCASE;
ENDLOOP;
END;
Initialize: PUBLIC PROCEDURE [
globalState: DisplayFace.GlobalStatePtr, wakeVF: WORD] =
BEGIN
dcb: DCB = [
next: pDCBNull, resolution: high, background: white, indenting: 0, width: 0,
shortBitmap: longBitMapSeal, tag: long, height: 0, longBitmap: NIL];
csbPtr.wakeupMask ← Inline.BITOR[wakeVF, csbPtr.wakeupMask];
pDCBBlank ← LOOPHOLE[@Environment.first64K[globalState]];
pDCBReal ← LOOPHOLE[@Environment.first64K[globalState] + SIZE[DCB]];
pDCBBlank↑ ← pDCBReal↑ ← dcb;
pDCBReal.width ← width/Environment.bitsPerWord;
pDCBReal.height ← height/2;
END;
-- DisplayFaceExtras.
monitorType: PUBLIC DisplayFaceExtras.MonitorType ← lf; -- changed in Start
SetFieldRate: PUBLIC PROCEDURE [rate: DisplayFaceExtras.FieldRate]
RETURNS [ok: BOOLEAN] =
BEGIN
SELECT monitorType FROM
alto =>
RETURN [rate=normalAlto];
lf =>
BEGIN
SELECT rate FROM
normalLF =>
DoradoInputOutput.SetDisplayFieldRate[sync: 18, visible: 430, topBorder: 14];
lfBall60hz =>
DoradoInputOutput.SetDisplayFieldRate[sync: 18, visible: 560, topBorder: 14];
lfPhillips60hz =>
DoradoInputOutput.SetDisplayFieldRate[sync: 58, visible: 520, topBorder: 25];
ENDCASE =>
RETURN [FALSE];
RETURN [TRUE];
END;
ENDCASE;
END;
SetVerticalWaveforms: PUBLIC PROCEDURE [sync, visible, topBorder: CARDINAL]
RETURNS [ok: BOOLEAN] =
BEGIN
DoradoInputOutput.SetDisplayFieldRate[
sync: sync, visible: visible, topBorder: topBorder];
RETURN [TRUE];
END;
--
-- HeadStartChain
Start: PUBLIC PROCEDURE =
BEGIN
displayIsLF: BOOLEAN =
(DoradoInputOutput.RWMufMan[[useDMD: FALSE, dMuxAddr: 3106B]].dMuxData # 0);
IF ~displayIsLF THEN
BEGIN
monitorType ← alto;
bitmapWidth ← width ← cslWordsPerLine*Environment.bitsPerWord;
refreshRate ← cslRefreshRate;
millisecondsPerTick ← cslMillisecondsPerTick;
END;
pagesForBitmap ←
((bitmapWidth/Environment.bitsPerWord)*height + Environment.wordsPerPage -
1)/Environment.wordsPerPage;
csbPtr.dcbChainHead ← pDCBNull; -- DCB's are in first64K
RemainingHeads.Start[];
END;
--
-- KeyboardFace
keyboard: PUBLIC LONG POINTER TO READONLY KeyStations.KeyBits ← LOOPHOLE[LONG[
177033B]];
--
-- MouseFace
position: PUBLIC LONG POINTER TO READONLY MouseFace.Point ← mouse;
SetPosition: PUBLIC PROCEDURE [newMousePosition: MouseFace.Point] =
BEGIN mouse↑ ← newMousePosition END;
buttons: PUBLIC LONG POINTER TO READONLY MouseFace.Buttons ← LOOPHOLE[keyboard];
mouse: LONG POINTER TO MouseFace.Point = LOOPHOLE[LONG[424B]];
--
-- ProcessorFace
-- See main body for initialization:
millisecondsPerTick: PUBLIC CARDINAL ← lfMillisecondsPerTick;
cslMillisecondsPerTick: CARDINAL = 50;
lfMillisecondsPerTick: CARDINAL = 40; -- actually 39.7
torMillisecondsPerTick: CARDINAL = 40; -- what should this be?
--
-- SoundGenerator (dummy implementation)
Beep: PUBLIC PROCEDURE [frequency: CARDINAL, duration: CARDINAL] = {};
END.
February 6, 1980 3:55 PM Gobbel Create file from UserTerminalImpl
February 8, 1980 12:29 PM McJones Start chaining
February 25, 1980 1:46 PM McJones Automatic determination of LF/CSL/Tor display
March 7, 1980 5:56 PM McJones Wait for two frames in turnOff arm of cleanup procedure
June 26, 1980 11:04 AM McJones OISProcessorFace=>ProcessorFace; allow Disconnect in disconnected state; add cursorPosition, mousePosition
July 29, 1980 9:54 AM McJones Add keyboard, hasBorder; split off MouseFace
July 30, 1980 6:21 PM McJones Add pagesForBitmap, GetBitBltTables; buffered=>hasBuffer
January 28, 1981 9:27 AM McJones Dummy SoundGenerator
March 21, 1981 4:51 PM Taft Convert for Dorado
9-Jun-81 18:04:35 Taft LF display
February 27, 1983 2:12 pm Taft DisplayFaceExtras