TerminalHeadD0.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Taft, February 27, 1983 3:27 pm
Birrell, November 3, 1983 2:23 pm
Russ Atkinson (RRA) February 19, 1985 3:20:46 pm PST
Doug Wyatt, April 25, 1985 2:54:30 pm PST
DIRECTORY
Basics USING [BITOR, bitsPerWord],
D0InputOutput USING [ControllerNumber, ControllerType, GetNextController, Input, millisecondsPerTick, null, nullControllerNumber, uibScb, utvfc],
DeviceCleanup USING [Await, Item, Reason],
PrincOpsUtils USING [LowHalf],
ProcessorFace USING [GetClockPulses, microsecondsPerHundredPulses],
TerminalDefs USING [Background, Cursor, KeyBits, Position],
TerminalFace USING [FieldRate, MonitorType];
TerminalHeadD0: PROGRAM
IMPORTS Basics, D0InputOutput, DeviceCleanup, PrincOpsUtils, ProcessorFace
EXPORTS TerminalFace
= BEGIN OPEN TerminalFace, TerminalDefs;
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
];
UTVFCControlRegister: TYPE = MACHINE DEPENDENT RECORD [
not currently used
controlNibbles: [0..377B] ← 0,
IncNC: [0..1] ← 0,
PPBckGnd: [0..3] ← 0,
PPBlank, PPVS, PreOField, AllowWU, ClrNC: [0..1] ← 0
];
UTVFCInputRegister: TYPE = MACHINE DEPENDENT RECORD [
controllerIDa: [0..377B] ← 2,
bitClockRate: [0..37B],
controllerIDb: [0..3] ← 2,
test: [0..1]
];
cslBitClockRate: [0..37B] = 5B;
lfBitClockRate: [0..37B] = 3B;
displayState: {disconnected, off, on} ← disconnected;
bitmapBase: LONG POINTERNIL; -- undefined if displayState=disconnected
controllerType: D0InputOutput.ControllerType;
controller: D0InputOutput.ControllerNumber;
pDCBReal: LONG POINTER TO DCB;
pDCBBlank: LONG POINTER TO DCB;
pDCBNull: PDCB = LOOPHOLE[0];
hasBuffer: PUBLIC BOOLFALSE;
See Start for initialization:
cslWordsPerLine: CARDINAL = 38;
lfWordsPerLine: CARDINAL = 64;
torWordsPerLine: CARDINAL = 40;
wordsPerLine: PUBLIC NAT ← lfWordsPerLine; -- see initialization below
width: PUBLIC NAT ← lfWordsPerLine*Basics.bitsPerWord;
See Start for initialization:
height: PUBLIC NAT ← 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 BOOLTRUE;
Connect: PUBLIC UNSAFE PROC [base: LONG POINTER] = UNCHECKED {
displayState ← off;
bitmapBase ← base;
csbPtr.dcbChainHead ← PrincOpsUtils.LowHalf[pDCBBlank]; -- DCB's are in first64K
};
Disconnect: PUBLIC SAFE 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 SAFE PROC = TRUSTED {
IF displayState = disconnected THEN ERROR;
displayState ← off;
csbPtr.dcbChainHead ← PrincOpsUtils.LowHalf[pDCBBlank]; -- DCB's are in first64K
};
SetBackground: PUBLIC SAFE PROC [background: Background] = TRUSTED {
pDCBReal.background ← pDCBBlank.background ← background;
};
Border pattern
hasBorder: PUBLIC BOOLFALSE;
SetBorderPattern: PUBLIC SAFE PROC [oddPairs, evenPairs: [0..377B]] = CHECKED{};
Cursor
cursorPosition: PUBLIC LONG POINTER TO Position ← LOOPHOLE[LONG[426B]];
pHardwareCursor: LONG POINTER TO Cursor ~ LOOPHOLE[LONG[431B]];
SHOULD BE IN IO PAGE
SetCursorPattern: PUBLIC SAFE PROC [cursor: Cursor] = TRUSTED {
pHardwareCursor^ ← cursor;
};
Initialization
globalStateSize: PUBLIC CARDINALSIZE[DCB]*2;
InitializeCleanup: PUBLIC SAFE PROC = TRUSTED {
OPEN DeviceCleanup;
item: Item;
reason: Reason;
state: CSBState;
mouseCoord: Position;
cursorCoord: Position;
cursor: Cursor;
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^;
cursor ← pHardwareCursor^;
csbPtr.dcbChainHead ← pDCBNull;
timeDone ← ProcessorFace.GetClockPulses[];
WHILE ProcessorFace.GetClockPulses[] - timeDone < maxPulsesPerRefresh DO
ENDLOOP;
};
turnOn => {
mouse^ ← mouseCoord;
cursorPosition^ ← cursorCoord;
pHardwareCursor^ ← cursor;
csbPtr^ ← state;
};
ENDCASE;
ENDLOOP;
};
Initialize: PUBLIC PROC [globalState: LONG POINTER, wakeVF: WORD] = {
dcb: DCB = [next: pDCBNull, resolution: high, background: white, indenting: 0, width: 0, shortBitmap: NIL, tag: long, height: 0, longBitmap: NIL];
csbPtr.wakeupMask ← Basics.BITOR[wakeVF, csbPtr.wakeupMask];
pDCBBlank ← globalState;
pDCBReal ← globalState + SIZE[DCB];
pDCBBlank^ ← pDCBReal^ ← dcb;
pDCBReal.width ← wordsPerLine;
pDCBReal.height ← height/2;
};
monitorType: PUBLIC MonitorType ← lf; -- changed in Init
SetFieldRate: PUBLIC SAFE PROC [rate: FieldRate] RETURNS [ok: BOOL] = CHECKED {
RETURN [
SELECT monitorType FROM
alto => rate=normalAlto,
lf => rate=normalLF,
ENDCASE => FALSE];
};
SetVerticalWaveforms: PUBLIC SAFE PROC [sync, visible, topBorder: CARDINAL] RETURNS [ok: BOOL] = CHECKED {RETURN [FALSE]};
KeyboardFace
keyboard: PUBLIC LONG POINTER TO READONLY KeyBits ← LOOPHOLE[LONG[177033B]];
MouseFace
mouse: LONG POINTER TO Position ~ LOOPHOLE[LONG[424B]];
mousePosition: PUBLIC LONG POINTER TO READONLY Position ← mouse;
SetMousePosition: PUBLIC SAFE PROC [position: Position] = TRUSTED {
mouse^ ← position;
};
Sound Generator
hasSoundGenerator: PUBLIC BOOLFALSE;
Beep: PUBLIC SAFE PROC [frequency, duration: CARDINAL] ~ CHECKED { };
Initialization
Init: PROC = {
OPEN D0InputOutput;
cslMillisecondsPerTick: CARDINAL = 50;
lfMillisecondsPerTick: CARDINAL = 40; -- actually 39.7
torMillisecondsPerTick: CARDINAL = 40; -- what should this be?
D0InputOutput.millisecondsPerTick ← lfMillisecondsPerTick;
IF (controller ← GetNextController[utvfc, nullControllerNumber]) ~= nullControllerNumber THEN {
inputReg: UTVFCInputRegister = LOOPHOLE[Input[[controller: controller, register: 0]]];
controllerType ← utvfc;
IF inputReg.bitClockRate = cslBitClockRate THEN {
monitorType ← alto;
wordsPerLine ← cslWordsPerLine;
width ← cslWordsPerLine*Basics.bitsPerWord;
refreshRate ← cslRefreshRate;
D0InputOutput.millisecondsPerTick ← cslMillisecondsPerTick;
};
}
ELSE
IF (controller ← GetNextController[uibScb, nullControllerNumber]) ~= nullControllerNumber THEN {
monitorType ← lf;
controllerType ← uibScb;
wordsPerLine ← torWordsPerLine;
width ← torWordsPerLine*Basics.bitsPerWord;
height ← torHeight;
D0InputOutput.millisecondsPerTick ← torMillisecondsPerTick;
}
ELSE controllerType ← null;
csbPtr.dcbChainHead ← pDCBNull; -- DCB's are in first64K
};
Init[];
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 24, 1981 3:06 PM Jose Correct width for Tor.
February 27, 1983 2:12 pm Taft DisplayFaceExtras
November 3, 1983 10:28 am Birrell conversion to 5.0