TTYPortHeadDLion.mesa
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Tim Diebert: November 16, 1985 4:30:06 pm PST
Bill Jackson (bj) July 31, 1986 1:56:13 am PDT
Reconstructed from the Pilot 6.0 heads.
DIRECTORY
DeviceCleanup USING [Await, Item, Reason],
DLionInputOutput USING [IOPage],
TTYPortFace;
TTYPortHeadDLion: CEDAR PROGRAM
IMPORTS DeviceCleanup, DLionInputOutput
EXPORTS TTYPortFace ~ {
Types
ChipParity: TYPE ~ MACHINE DEPENDENT {
none(0),
odd(1),
even(3)
};
CSB: TYPE ~ MACHINE DEPENDENT RECORD [
outData(0): UNSPECIFIED, -- Char or Parameter Record
outControl(1): OutControl,
inData(2): CHAR,
inControl(3): InCharStatus,
unused(4:0..7): [0..400B),
dataTerminalReady(4:8..8): BOOL,
unused1(4:9..12): [0..20B),
requestToSend(4:13..13): BOOLEAN,
rxRDY(4:14..14): BOOLEAN,
txRDY(4:15..15): BOOLEAN,
notifyMask(5): WORD
];
InCharStatus: TYPE ~ MACHINE DEPENDENT RECORD [
state(0:0..0):  MACHINE DEPENDENT {empty(0), charPresent(1)},
unused(0:1..7): [0..200B),
success(0:8..8): BOOLEAN,
breakDetected(0:9..9): BOOLEAN,
framingError(0:10..10): BOOLEAN,
dataLost(0:11..11): BOOLEAN,
parityError(0:12..12): BOOLEAN,
unused1(0:13..14): [0..4),
notReady(0:15..15): BOOLEAN
];
OutControl: TYPE ~ MACHINE DEPENDENT {
(0), -- outControl >= putChar means busy
putChar(100000B), -- setParameterCommand(100001B),
getStatus(100002B),
on(100003B),
off(100004B),
setDSR(100401B),
setCTS(101001B),
setCharLength(102001B),
setParity(104001B),
setStopBits(110001B),
setBaudRate(120001B),
setAllParameters(137401B),
(177777B)
};
ParameterRecord: TYPE ~ MACHINE DEPENDENT RECORD [
onOff(0:0..3): MACHINE DEPENDENT {on(0), off(1), (17B)}, -- (Head flag)
baudRate(0:4..7): TTYPortFace.LineSpeed ← bps1200,
stopBits(0:8..9): TTYPortFace.StopBits ← two,
parity(0:10..11): ChipParity ← none,
charLength(0:12..13): TTYPortFace.CharacterLength ← lengthIs8bits,
clearToSend(0:14..14): BOOLEANFALSE,
dataSetReady(0:15..15): BOOLEANFALSE
];
Constants
ConvertParity: ARRAY TTYPortFace.Parity OF ChipParity ~ [none: none, odd: odd, even: even];
TTY: LONG POINTER TO CSB ~ LOOPHOLE[DLionInputOutput.IOPage + 121B];
Global State
state: ParameterRecord ← [onOff: off];
Procs
GetCommand: PUBLIC PROC [CARDINAL] RETURNS [data: CHAR, stat: TTYPortFace.TransferStatus] ~ TRUSTED {
ttyInStatus: InCharStatus ~ TTY.inControl;
IF ttyInStatus.state = empty THEN RETURN[NULL, notReady];
data ← TTY.inData; TTY.inControl.state ← empty;
stat ← SELECT TRUE FROM
ttyInStatus.success => success,
ttyInStatus.breakDetected => breakDetected,
ttyInStatus.framingError => asynchFramingError,
ttyInStatus.dataLost => dataLost,
ttyInStatus.parityError => parityError,
ttyInStatus.notReady => notReady,
ENDCASE => success;
};
GetLineCount: PUBLIC PROC RETURNS [CARDINAL] ~ {
RETURN[1];
};
GetStatus: PUBLIC PROC [CARDINAL] RETURNS [status: TTYPortFace.DeviceStatus] ~ TRUSTED {
status ← [
readyToPut: (TTY.outControl < putChar),
readyToGet: (TTY.inControl.state = charPresent),
dataTerminalReady: TTY.dataTerminalReady,
requestToSend: TTY.requestToSend
];
};
InitializeCleanup: PROC ~ TRUSTED {
item: DeviceCleanup.Item;
mask: WORD;
DO
reason: DeviceCleanup.Reason = DeviceCleanup.Await[@item];
IF state.onOff=on THEN
SELECT reason FROM
turnOff, kill => {
WHILE TTY.outControl >= putChar DO NULL; ENDLOOP;
mask ← TTY.notifyMask;
TTY.notifyMask ← 0;
TTY.outControl ← off;
WHILE TTY.outControl >= putChar DO NULL; ENDLOOP;
};
turnOn => {
TTY.notifyMask ← mask;
TTY.outControl ← on;
WHILE TTY.outControl >= putChar DO NULL; ENDLOOP;
TTY.outData ← state;
TTY.outControl ← setAllParameters;
};
disconnect => NULL; -- turnOff was already called
ENDCASE;
ENDLOOP;
};
PutCommand: PUBLIC PROC [lineNumber: CARDINAL, data: CHAR] RETURNS [status: TTYPortFace.TransferStatus] ~ TRUSTED {
IF TTY.outControl >= putChar THEN RETURN[notReady];
TTY.outData ← data;
TTY.outControl ← putChar;
status ← success;
};
Off: PUBLIC PROC [CARDINAL] ~ TRUSTED {
WHILE TTY.outControl >= putChar DO
NULL;
ENDLOOP;
TTY.notifyMask ← 0;
TTY.outControl ← off;
state ← [onOff: off];
};
should check to see if the out is busy???
On: PUBLIC PROC [lineNumber: CARDINAL, mask: UNSPECIFIED] ~ TRUSTED {
state ← [onOff: on];
TTY.notifyMask ← mask;
TTY.inControl.state ← empty;
TTY.outControl ← on;
};
SetParameter: PUBLIC PROC [lineNumber: CARDINAL, parameter: TTYPortFace.Parameter] ~ TRUSTED {
control: OutControl;
WITH parameter SELECT FROM
characterLength => {control ← setCharLength; state.charLength ← characterLength};
clearToSend => {control ← setCTS; state.clearToSend ← clearToSend};
dataSetReady => {control ← setDSR; state.dataSetReady ← dataSetReady};
lineSpeed => {control ← setBaudRate; state.baudRate ← lineSpeed};
parity => {control ← setParity; state.parity ← ConvertParity[parity]};
stopBits => {control ← setStopBits; state.stopBits ← stopBits};
ENDCASE => RETURN;
WHILE (TTY.outControl >= putChar) DO
NULL;
ENDLOOP;
TTY.outData ← state;
TTY.outControl ← control;
};
InitializeCleanup[];
}.