TerminalHeadDLion.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Taft, February 27, 1983 3:27 pm
Doug Wyatt, April 25, 1985 11:00:56 am PST
DIRECTORY
Basics USING [BITOR, bitsPerWord, LongDiv, LowHalf],
DeviceCleanup USING [Await, Item, Reason],
DLionInputOutput USING [IOPage--, SetReservedMemoryUse--],
Process USING [GetPriority, MsecToTicks, Pause, Priority, priorityRealTime, SetPriority],
TerminalDefs USING [Background, Cursor, KeyBits, Position],
TerminalFace USING [FieldRate, MonitorType];
TerminalHeadDLion: MONITOR
IMPORTS Basics, DeviceCleanup, DLionInputOutput, Process
EXPORTS TerminalFace
= BEGIN OPEN TerminalDefs;
CSB: TYPE = MACHINE DEPENDENT RECORD [
wakeups: WORD, --vertical field wake up bits--
off: BOOL,
unused: [0..7],
invert, disconnect: BOOL,
line: CARDINAL [0..1024),
border: RECORD [oddPairs, evenPairs: [0..400B)],
cursor: Position, --cursor location--
map: Cursor --cursor bit map--
];
csb: LONG POINTER TO CSB = LOOPHOLE[DLionInputOutput.IOPage + 353B]; --FFEB--
hasBuffer: PUBLIC BOOLTRUE;
width: PUBLIC NAT ← 1024;
height: PUBLIC NAT ← 808;
wordsPerLine: PUBLIC NAT ← (width+Basics.bitsPerWord-1)/Basics.bitsPerWord;
DisplayFace Implementation
bitmapAddress: LONG POINTERNIL;
it should it be an ERROR to this if already connected
or to turn on/off a disconnected display
Connect: PUBLIC UNSAFE PROC [base: LONG POINTER] = {
DLionInputOutput.SetReservedMemoryUse[Display];
csb.off ← TRUE;
csb.disconnect ← FALSE;
bitmapAddress ← base;
};
Disconnect: PUBLIC SAFE PROC = TRUSTED {
csb.off ← TRUE;
csb.disconnect ← TRUE;
bitmapAddress ← NIL;
DLionInputOutput.SetReservedMemoryUse[notBusy];
};
TurnOn: PUBLIC UNSAFE PROC = {csb.off ← FALSE};
TurnOff: PUBLIC SAFE PROC = TRUSTED {csb.off ← TRUE};
pixelsPerInch: PUBLIC CARDINAL ← 75;
refreshRate: PUBLIC CARDINAL ← 39;
interlaced: PUBLIC BOOLTRUE;
SetBackground: PUBLIC SAFE PROC [background: Background] = TRUSTED
{csb.invert ← (background = black)};
hasBorder: PUBLIC BOOLTRUE;
SetBorderPattern: PUBLIC SAFE PROC [oddPairs, evenPairs: [0..377B]] = TRUSTED
{csb.border ← [oddPairs, evenPairs]};
monitorType: PUBLIC TerminalFace.MonitorType ← lf;
SetFieldRate: PUBLIC SAFE PROC [rate: TerminalFace.FieldRate]
RETURNS [ok: BOOL] = CHECKED
{RETURN [rate=normalLF]};
SetVerticalWaveforms: PUBLIC SAFE PROC [sync, visible, topBorder: CARDINAL]
RETURNS [ok: BOOL] = CHECKED
{RETURN [FALSE]};
SetCursorPattern: PUBLIC SAFE PROC [cursor: Cursor] = TRUSTED {csb.map ← cursor};
cursorPosition: PUBLIC LONG POINTER TO Position ← @csb.cursor;
globalStateSize: PUBLIC CARDINAL ← 0;
Initialize: PUBLIC PROC[globalState: LONG POINTER, wakeVF: WORD] = {
csb^ ← CSB[
wakeups: Basics.BITOR[wakeVF, csb.wakeups],
off: NULL,
unused: 0,
invert: FALSE,
disconnect: TRUE,
line: 0,
border: [210B, 42B],
cursor: [0,0],
map: ALL[0]
];
pSGCSB^ ← SoundGeneratorCSB[
busy: FALSE,
command: NULL,
period: 0
];
};
Keyboard
keyboard: PUBLIC LONG POINTER TO READONLY KeyBits ←
LOOPHOLE[DLionInputOutput.IOPage + 72B]; --FF3A
Mouse
mousePointer: LONG POINTER TO Position ~
LOOPHOLE[DLionInputOutput.IOPage + 70B]; --FF38
mousePosition: PUBLIC LONG POINTER TO READONLY Position ← mousePointer;
SetPositionRec: TYPE ~ MACHINE DEPENDENT RECORD [
point(0:0..31): Position,
busy(2:0..0): BOOL,
fill(2:1..15): [0..32767]
];
setPosition: LONG POINTER TO SetPositionRec ~
LOOPHOLE[DLionInputOutput.IOPage + 133B]; --FF5B
SetMousePosition: PUBLIC SAFE PROC [p: Position] = TRUSTED {
DO
mousePointer^ ← p;
IF NOT setPosition.busy THEN EXIT
ENDLOOP;
setPosition.point ← p; setPosition.busy ← TRUE;
};
Sound Generator
hasSoundGenerator: PUBLIC BOOLTRUE;
SoundGeneratorCSBOffset: CARDINAL = 136B; -- = 0101 1110 = 5EX
SoundGeneratorCSB: TYPE = MACHINE DEPENDENT RECORD [
busy (0:0..0): BOOL,
command (0:1..15): MACHINE DEPENDENT {start (0), stop (1)},
period (1:0..15): CARDINAL -- = 1843200/f, where f is frequency in Hz
];
pSGCSB: LONG POINTER TO SoundGeneratorCSB =
DLionInputOutput.IOPage + SoundGeneratorCSBOffset;
Beep wants to run at interrupt priority, so it can accurately time
the duration of the beep. Either interrupt priority should have an extra
state vector, or Beep's code (and local and global frame) must be pinned.
Beep: PUBLIC ENTRY SAFE PROC [frequency: CARDINAL, duration: CARDINAL] = TRUSTED {
priority: Process.Priority = Process.GetPriority[];
aborted: BOOLFALSE;
WHILE pSGCSB.busy DO ENDLOOP;
Process.SetPriority[MAX[Process.priorityRealTime, priority]];
The MAX in the next statement prevents the LowHalf from overflowing.
The period (in usec*1.8432) will be in the range [~29..63535].
pSGCSB.period ← Basics.LowHalf[Basics.LongDiv[1843200, MAX[frequency, 29]]];
pSGCSB.command ← start;
pSGCSB.busy ← TRUE;
WHILE pSGCSB.busy DO ENDLOOP;
Process.Pause[Process.MsecToTicks[duration] !
ABORTED => {aborted ← TRUE; CONTINUE}];
pSGCSB.command ← stop;
pSGCSB.busy ← TRUE;
WHILE pSGCSB.busy DO ENDLOOP;
Process.SetPriority[priority];
IF aborted THEN RETURN WITH ERROR ABORTED;
};
Display/Raven/Sound Generator cleanup Proc
InitializeCleanup: PUBLIC SAFE PROC = TRUSTED { OPEN DeviceCleanup;
csbState: CSB;
sgcsbState: SoundGeneratorCSB;
item: Item;
mousePos: Position;
DO
reason: Reason = Await[@item];
SELECT reason FROM
turnOff, kill => {
csbState ← csb^;
csb.off ← TRUE;
mousePos ← mousePosition^;
THROUGH [0..8000] DO --wait for field-- ENDLOOP;
THROUGH [0..30000] DO IF ~pSGCSB.busy THEN EXIT ENDLOOP;
stop sound generator
sgcsbState ← pSGCSB^;
pSGCSB.command ← stop;
pSGCSB.busy ← TRUE;
THROUGH [0..30000] DO IF ~pSGCSB.busy THEN EXIT ENDLOOP;
};
turnOn => {
setPosition.point ← mousePos; setPosition.busy ← TRUE;
mousePointer^ ← mousePos;
pSGCSB^ ← sgcsbState;
csb^ ← csbState;
};
ENDCASE;
ENDLOOP;
};
setPosition.fill ← 0;
END.
February 27, 1983 2:12 pm Taft DisplayFaceExtras