TerminalHeadDorado.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Taft, February 27, 1983 3:27 pm
Levin, August 8, 1983 3:08 pm
Birrell, August 18, 1983 1:54 pm
Russ Atkinson (RRA) February 19, 1985 2:08:51 pm PST
Doug Wyatt, May 21, 1985 6:46:09 pm PDT
DIRECTORY
Basics USING [bitsPerWord],
DoradoInputOutput USING [millisecondsPerTick, savedCursor, SetDisplayFieldRate],
DeviceCleanup USING [Await, Item, Reason],
PrincOpsUtils USING [BITOR, LowHalf],
ProcessorFace USING [GetClockPulses, microsecondsPerHundredPulses],
TerminalDefs USING [Background, Cursor, KeyBits, Position],
TerminalFace USING [FieldRate, MonitorType];
TerminalHeadDorado: CEDAR PROGRAM
IMPORTS DeviceCleanup, DoradoInputOutput, PrincOpsUtils, ProcessorFace
EXPORTS TerminalFace
~ BEGIN OPEN TerminalDefs;
Black and white display
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: 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
pDCBReal: LONG POINTER TO DCB;
pDCBBlank: LONG POINTER TO DCB;
pDCBNull: PDCB = LOOPHOLE[0];
cslRefreshRate: CARDINAL = 30;
lfRefreshRate: CARDINAL = 38; -- actually ??
cslWordsPerLine: CARDINAL = 38;
cslScanLines: CARDINAL = 808;
lfWordsPerLine: CARDINAL = 64;
lfScanLines: CARDINAL = 808;
displayState: {disconnected, off, on} ← disconnected;
bitmapBase: LONG POINTER ← NIL; -- undefined if displayState=disconnected
hasBuffer: PUBLIC BOOL ← FALSE;
pixelsPerInch: PUBLIC CARDINAL ← 72;
refreshRate: PUBLIC CARDINAL ← 0; -- frames (two fields) per second
interlaced: PUBLIC BOOL ← TRUE;
width: PUBLIC NAT ← 0;
height: PUBLIC NAT ← 0;
wordsPerLine: PUBLIC NAT ← 0;
Connect:
PUBLIC
UNSAFE
PROC [base:
LONG
POINTER] =
UNCHECKED {
displayState ← off;
bitmapBase ← base;
csbPtr.dcbChainHead ← PrincOpsUtils.LowHalf[pDCBBlank]; -- DCB's are in first64K
};
Disconnect:
PUBLIC
PROC =
TRUSTED {
displayState ← disconnected;
bitmapBase ← NIL;
csbPtr.dcbChainHead ← pDCBNull;
};
TurnOn:
PUBLIC
UNSAFE
PROC =
UNCHECKED {
IF displayState = disconnected THEN ERROR;
displayState ← on;
pDCBReal.longBitmap ← bitmapBase;
csbPtr.dcbChainHead ← PrincOpsUtils.LowHalf[pDCBReal]; -- DCB's are in first64K
};
TurnOff:
PUBLIC
PROC =
TRUSTED {
IF displayState = disconnected THEN ERROR;
displayState ← off;
csbPtr.dcbChainHead ← PrincOpsUtils.LowHalf[pDCBBlank]; -- DCB's are in first64K
};
SetBackground:
PUBLIC
PROC [background: Background] =
TRUSTED {
pDCBReal.background ← pDCBBlank.background ← background;
};
Border pattern
hasBorder: PUBLIC BOOL ← FALSE;
SetBorderPattern: PUBLIC PROC [oddPairs, evenPairs: [0..377B]] = { };
Monitor type, field rate, and waveforms
monitorType: PUBLIC TerminalFace.MonitorType ← lf; -- changed in Start
SetFieldRate:
PUBLIC
PROC [rate: TerminalFace.FieldRate]
RETURNS [ok:
BOOL] =
TRUSTED {
SELECT monitorType
FROM
alto => RETURN [rate=normalAlto];
lf => {
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];
};
ENDCASE;
};
SetVerticalWaveforms:
PUBLIC
PROC [sync, visible, topBorder:
CARDINAL]
RETURNS [ok:
BOOL] =
TRUSTED {
DoradoInputOutput.SetDisplayFieldRate[sync: sync, visible: visible, topBorder: topBorder];
RETURN [TRUE]
};
Cursor
cursorPosition: PUBLIC LONG POINTER TO Position ← LOOPHOLE[LONG[426B]];
pHardwareCursor: LONG POINTER TO Cursor = LOOPHOLE[LONG[431B]];
SetCursorPattern:
PUBLIC
PROC [cursor: Cursor] =
TRUSTED {
pHardwareCursor^ ← cursor;
DoradoInputOutput.savedCursor ← cursor;
};
Initialization
globalStateSize: PUBLIC CARDINAL ← SIZE[DCB]*2;
InitializeCleanup:
PUBLIC
PROC =
TRUSTED {
OPEN DeviceCleanup;
item: Item;
reason: Reason;
state: CSBState;
mouseCoord: Position;
cursorCoord: Position;
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 => {
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;
};
turnOn => {
mouse^ ← mouseCoord;
cursorPosition^ ← cursorCoord;
cursor pattern itself is restored by SetMP trap handler in ProcessorHeadDorado
csbPtr^ ← state;
};
ENDCASE;
ENDLOOP;
};
Initialize:
PUBLIC
UNSAFE
PROC [globalState:
LONG
POINTER, wakeVF:
WORD] =
TRUSTED {
dcb:
DCB = [
next: pDCBNull, resolution: high, background: white, indenting: 0, width: 0,
shortBitmap: longBitMapSeal, tag: long, height: 0, longBitmap: NIL];
csbPtr.wakeupMask ← PrincOpsUtils.BITOR[wakeVF, csbPtr.wakeupMask];
pDCBBlank ← LOOPHOLE[globalState];
pDCBReal ← LOOPHOLE[globalState + SIZE[DCB]];
pDCBBlank^ ← pDCBReal^ ← dcb;
pDCBReal.width ← width/Basics.bitsPerWord;
pDCBReal.height ← height/2;
};
Keyboard
keyboard: PUBLIC LONG POINTER TO READONLY KeyBits ← LOOPHOLE[LONG[177033B]];
Mouse
mouse: LONG POINTER TO Position = LOOPHOLE[LONG[424B]];
mousePosition: PUBLIC LONG POINTER TO READONLY Position ← mouse;
SetMousePosition: PUBLIC PROC [position: Position] = TRUSTED { mouse^ ← position };
Sound Generator
hasSoundGenerator: PUBLIC BOOL ← FALSE;
Beep: PUBLIC PROC [frequency, duration: CARDINAL] ~ { };
Constants for ProcessorFace condition variable time
cslMillisecondsPerTick: CARDINAL = 50;
lfMillisecondsPerTick: CARDINAL = 40; -- actually 39.7
torMillisecondsPerTick: CARDINAL = 40; -- what should this be?
Main Body
TRUSTED {
displayIsLF: BOOL =
(DoradoInputOutput.RWMufMan[[useDMD: FALSE, dMuxAddr: 3106B]].dMuxData # 0);
IF displayIsLF
THEN {
monitorType ← lf;
wordsPerLine ← lfWordsPerLine;
refreshRate ← lfRefreshRate;
DoradoInputOutput.millisecondsPerTick ← lfMillisecondsPerTick;
}
ELSE {
monitorType ← alto;
wordsPerLine ← cslWordsPerLine;
refreshRate ← cslRefreshRate;
DoradoInputOutput.millisecondsPerTick ← cslMillisecondsPerTick;
};
The following assumes an LF display.
As far as we know, no Dorado running Cedar has an alto display. -- DKW
monitorType ← lf;
refreshRate ← lfRefreshRate;
DoradoInputOutput.millisecondsPerTick ← lfMillisecondsPerTick;
wordsPerLine ← lfWordsPerLine;
width ← wordsPerLine*Basics.bitsPerWord;
height ← lfScanLines;
csbPtr.dcbChainHead ← pDCBNull; -- DCB's are in first64K
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