<> <> <> <> <<>> <> DIRECTORY DeviceCleanup USING [Await, Item, Reason], DLionInputOutput USING [IOPage], TTYPortFace; TTYPortHeadDLion: CEDAR PROGRAM IMPORTS DeviceCleanup, DLionInputOutput EXPORTS TTYPortFace ~ { <> <<>> 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): BOOLEAN _ FALSE, dataSetReady(0:15..15): BOOLEAN _ FALSE ]; <> <<>> ConvertParity: ARRAY TTYPortFace.Parity OF ChipParity ~ [none: none, odd: odd, even: even]; TTY: LONG POINTER TO CSB ~ LOOPHOLE[DLionInputOutput.IOPage + 121B]; <<>> <> <<>> state: ParameterRecord _ [onOff: off]; <> 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]; }; <> <<>> 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[]; }.