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 BOOL ← TRUE;
width: PUBLIC NAT ← 1024;
height: PUBLIC NAT ← 808;
wordsPerLine: PUBLIC NAT ← (width+Basics.bitsPerWord-1)/Basics.bitsPerWord;
DisplayFace Implementation
bitmapAddress: LONG POINTER ← NIL;
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 BOOL ← TRUE;
SetBackground:
PUBLIC
SAFE
PROC [background: Background] =
TRUSTED
{csb.invert ← (background = black)};
hasBorder: PUBLIC BOOL ← TRUE;
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 BOOL ← TRUE;
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: BOOL ← FALSE;
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