-- File: PDTTYLearSiegler.mesa -- Last Edited: 13-Nov-81 15:18:10 By: Fay -- Last Edited: 27-Oct-82 12:02:02 By: Loretta -- Last Edited: September 20, 1984 3:49:16 pm PDT By: Plass DIRECTORY Ascii USING [BS, ControlG, CR, LF, SP], Environment USING [Block], Process USING [GetPriority, Priority, priorityForeground, SetPriority], Stream USING [ Byte, defaultObject, DeleteProcedure, GetProcedure, Handle, Object, PutProcedure, PutByteProcedure, SendAttentionProcedure, SendNowProcedure, SetSSTProcedure, WaitAttentionProcedure], TTY, TTYConstants, TTYPort USING [ChannelHandle, ChannelQuiesced, Create, Delete, Get, Quiesce, Put, SetParameter, TransferStatus], TTYPortEnvironment USING [LineSpeed]; PDTTYLearSiegler: MONITOR IMPORTS Process, Stream, TTY, TTYPort EXPORTS TTY = BEGIN -- Types Byte: TYPE = Stream.Byte; CharObjectHandle: TYPE = LONG POINTER TO CharObject; CharObject: TYPE = RECORD [p: CharObjectHandle, c: CHARACTER]; ControlG: Byte = LOOPHOLE[Ascii.ControlG]; CR: Byte = LOOPHOLE[Ascii.CR]; LF: Byte = LOOPHOLE[Ascii.LF]; BS: Byte = LOOPHOLE[Ascii.BS]; SP: Byte = LOOPHOLE[Ascii.SP]; -- this might be expanded to multiple tty's by having several of thes buggers -- and refering to them (somehow) via handle, and having object monitors. myTTY: RECORD [ so: Stream.Object _ Stream.defaultObject, breakDetected: BOOLEAN _ NULL, breakCount: INTEGER _ NULL, channel: TTYPort.ChannelHandle _ NIL, -- also on/off flag mode: Byte _ TTYConstants.normal, modeVal: CARDINAL _ 0]; receiveDeath: CONDITION; controlStop: CHARACTER = 36C; CreateTTYInstance: PUBLIC ENTRY PROC [ name: LONG STRING, backingStream: Stream.Handle, tty: TTY.Handle] RETURNS [ttyImpl, backing: Stream.Handle] = { ENABLE UNWIND => NULL; IF myTTY.channel # NIL THEN RETURN WITH ERROR TTY.OutOfInstances; myTTY.channel _ TTYPort.Create[0]; myTTY.breakDetected _ FALSE; myTTY.breakCount _ 0; TTYPort.SetParameter[myTTY.channel, [dataSetReady[TRUE]]]; TTYPort.SetParameter[myTTY.channel, [clearToSend[TRUE]]]; TTYPort.SetParameter[myTTY.channel, [lineSpeed[bps9600]]]; myTTY.so.get _ GetBlock; myTTY.so.putByte _ PutByte; myTTY.so.put _ Put; myTTY.so.delete _ Delete; myTTY.so.waitAttention _ WaitAttention; myTTY.so.sendAttention _ SendAttention; myTTY.so.setSST _ SetSST; myTTY.so.sendNow _ SendNow; RETURN[@myTTY.so, NIL]}; Delete: ENTRY Stream.DeleteProcedure = { channel: TTYPort.ChannelHandle = myTTY.channel; IF channel=NIL THEN RETURN; TTYPort.Quiesce[channel]; WHILE myTTY.channel#NIL DO WAIT receiveDeath [] ENDLOOP; TTYPort.Delete[myTTY.channel]}; PutByte: ENTRY Stream.PutByteProcedure = { SELECT myTTY.mode FROM TTYConstants.normal => PutByteInternal[byte]; TTYConstants.removeChars => myTTY.modeVal _ myTTY.modeVal*256 + byte; ENDCASE}; Put: Stream.PutProcedure = { IF endRecord THEN RETURN; FOR i: CARDINAL IN [block.startIndex..block.stopIndexPlusOne) DO sH.putByte[sH, block.blockPointer[i]] ENDLOOP; }; lastChar: Byte _ 0; PutByteInternal: INTERNAL PROC [c: Byte] = { PutIt: PROCEDURE [c: Stream.Byte] = INLINE { [] _ TTYPort.Put[myTTY.channel, LOOPHOLE[c] ! TTYPort.ChannelQuiesced => CONTINUE]}; IF myTTY.channel = NIL THEN RETURN; IF lastChar=CR AND c=LF THEN NULL ELSE PutIt[c]; lastChar _ c; SELECT c FROM CR => PutIt[LF]; BS => {PutIt[SP]; PutIt[BS]}; ENDCASE}; WaitAttention: Stream.WaitAttentionProcedure = { RETURN[IF myTTY.breakDetected THEN TTYConstants.aborted ELSE TTYConstants.notAborted]}; SendAttention: Stream.SendAttentionProcedure = { SELECT byte FROM TTYConstants.aborted => { myTTY.breakCount _ myTTY.breakCount + 1; IF myTTY.breakCount > 0 THEN myTTY.breakDetected _ TRUE}; TTYConstants.notAborted => { IF myTTY.breakCount > 0 THEN myTTY.breakCount _ myTTY.breakCount - 1; IF myTTY.breakCount = 0 THEN myTTY.breakDetected _ FALSE}; ENDCASE}; SetSST: ENTRY Stream.SetSSTProcedure = { SELECT myTTY.mode FROM TTYConstants.removeChars => FOR i: CARDINAL IN [0..myTTY.modeVal) DO PutByteInternal[BS]; ENDLOOP; TTYConstants.blinkDisplay => PutByteInternal[ControlG]; ENDCASE; myTTY.mode _ sst; myTTY.modeVal _ 0}; SendNow: Stream.SendNowProcedure = {}; GetBlock: Stream.GetProcedure = { csmPriority: Process.Priority = Process.priorityForeground; NotifyNextOfKin: ENTRY PROC = INLINE {myTTY.channel _ NIL; NOTIFY receiveDeath}; oldPriority: Process.Priority = Process.GetPriority[]; ProcessChar: ENTRY PROC RETURNS [done: BOOLEAN _ FALSE] = INLINE { IF stat = breakDetected OR ch = controlStop THEN { myTTY.breakDetected _ TRUE; myTTY.breakCount _ myTTY.breakCount + 1; TTYPort.SetParameter[myTTY.channel, [breakDetectedClear[TRUE]] ! TTYPort.ChannelQuiesced => CONTINUE]} ELSE { block.blockPointer[block.startIndex] _ LOOPHOLE[ch]; bytesTransferred _ 1; why _ normal; sst _ TTYConstants.normal; RETURN[TRUE]}}; ch: CHARACTER; stat: TTYPort.TransferStatus; Process.SetPriority[csmPriority]; bytesTransferred _ 0; DO [ch, stat] _ TTYPort.Get[myTTY.channel ! TTYPort.ChannelQuiesced => EXIT]; IF stat=aborted OR stat=abortedByDelete THEN EXIT; IF ProcessChar[] THEN RETURN; ENDLOOP; Process.SetPriority[oldPriority]; NotifyNextOfKin[]}; -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- MAINLINE CODE -- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ END.... LOG July 28, 1980 9:25 AM Mary Artibee Created. August 15, 1980 1:18 PM Mary Artibee Many changes. Time: August 27, 1980 7:01 PM Mary Artibee Private errors on Create, BackingStream. Time: September 12, 1980 11:41 PM Yokota Added UserAbort and ResetUserAbort. Time: September 19, 1980 3:24 PM Yokota Line Speed is set to 9600bps. Time: October 2, 1980 1:32 PM Artibee Change tty init; remove Process. October 3, 1980 5:32 PM Yokota Added tty.breakDetected, tty.breakCount and controlStop. UserAbort, ResetUserAbort and Receive are modified to use them. October 7, 1980 4:38 PM Yokota Priority of Receive process is raised and Break detection is done using only tty.breakDetected. February 23, 1981 1:24 PM Gobbel Fixed bug in input stream processing; replaced calls to Storage with Heap ops. 26-Aug-81 18:54:16 Forrest Rolled into 8.0c 13-Nov-81 15:18:04 Fay Converted to new TTY interface for 8.0e. September 20, 1984 3:49:39 pm PDT Plass Made smarter about CR vs. CRLF, added NOP SendNow operation. "J77