!TITLE Terminal Input Output
!<DDISABLETERMINALSTREAM
externalintegerfn  DDISABLE TERMINAL STREAM1(integername  CURSOR,
      integer  STREAM, REASON)
!
! This procedure is used to suspend (REASON=4) or abort (REASON=5) an
! input (STREAM=0) or output (STREAM=1) operation.  For interactive
! I/O streams, only the "abort" option is likely to be required, and the
! effect is to send a "control message" through the communications
! system.  For an output stream, as much unprinted data as possible is
! flushed from the system, for an input stream, similarly any data which
! has been typed is flushed from the system.  In each case the stream is
! re-initialised and further operations may not be carried out on the
! stream until it has been re-enabled using the DENABLE TERMINAL STREAM
! procedure.
!
! The DDISABLE TERMINAL STREAM procedure may be called at any time, but
! is typically invoked in response to an asynchronous "INT:" message
! generated by the user at the interactive terminal (see the procedure
! DCLEAR INT MESSAGE, described below, and the contingency handling
! procedures, described in Section A1.6).
!>
! RESULT = 0   OK
!          -1  NO NOMINATED BUFFER
INTEGER  J
      J = IN2(256 + 17)
      -> OUT UNLESS  J = 0
!
      COMMS CLOSEDOWN AND  -> OUT IF  STREAM = -1
!
      J = 45
      -> OUT IF  VAL(ADDR(CURSOR), 4, 1, D CALLERS PSR) = NO
!
      J = 8
      -> OUT UNLESS  0<=STREAM<=1; ! BAD PARAM
!
      J = DISABLE STREAM(CURSOR,STREAM,REASON)
      IF  J=0 START 
         IF  STREAM = 0 C 
         THEN  IOSTAT_INBUFLEN = -1  C 
         ELSE  IOSTAT_OUTBUFLEN = -1
      FINISH 
OUT:
      RESULT  = OUT(J, "")
END ; ! DDISABLE TERMINAL STREAM1
!
!-----------------------------------------------------------------------
!
INTEGERFN  CONNECT STREAM(INTEGER  STREAM, DEST)
INTEGERNAME  J
RECORD  (PARMF)P
      IF  STREAM = 0 C 
      THEN  J == UINF_INSTREAM C 
      ELSE  J == UINF_OUTSTREAM
!
      RESULT  = J UNLESS  J = 0; ! stream already connected
!
      P = 0
      P_DEST = X'00370001'
      P_P1 = STREAM; ! 0 or 1 to indicate input or output respectively
      P_P2 = DEST; ! SNO FOR CONTROL MESSAGES
      P_P3 = UINF_STREAM ID + STREAM
      DOUT11I(P)
      J = P_P1 IF  P_P2 = 0; ! save stream number
      RESULT  = P_P2
END ; ! CONNECT STREAM
!
!-----------------------------------------------------------------------
!
INTEGERFN  DISCONNECT STREAM(INTEGER  STRM)
INTEGERNAME  J
RECORD  (PARMF)P
      IF  STRM = 0 C 
      THEN  J == UINF_INSTREAM C 
      ELSE  J == UINF_OUTSTREAM
      RESULT  = 0 IF  J = 0; ! dont bother if already disconnected
!
      P=0
      P_DEST=X'00370005'
      P_P1 = J
      J = 0; ! only do it once !
      DOUTI(P)
      RESULT =P_P2
END ; ! DISCONNECT STREAM
!
!-----------------------------------------------------------------------
!
INTEGERFN  ENABLE STREAM(INTEGER  STREAM,SEG,OFFSET,LENGTH,CURSOR,MODE)
! WE TRUST OURSELVES TO HAVE SEG CONNECTED (IN COMMS MODE). OFFSET IS
! BYTE OFFSET (UP TO 16 BITS) INTO THE SEGMENT, AND OFFSET + LENGTH
! MUST ALSO BE WITHIN THE SEGMENT.
!
! Bits in MODE are to be set as follows:
!     R-most quartet:   0 = sequential
!                       1 = circular
!     next quartet:     0 = ISO
!                       1 = EBCDIC
!                       2 = binary
!                       3 = control (e.g. set-mode)
!
INTEGER  CELL,FLAG
INTEGERNAME  J
RECORD  (PARMF)P
      RESULT  = 1 IF  ENABLED(STREAM) = 1; ! already enabled
!
      IF  STREAM = 0 C 
      THEN  J == UINF_INSTREAM C 
      ELSE  J == UINF_OUTSTREAM
!
      RESULT  = 1 IF  J = 0; ! not even connected
!
      ENABLED(STREAM) = 1; ! I know it isn't yet, but an INT may
                           ! arrive to kill the process and the disconnect
                           ! won't work until the stream has been disabled
      CELL=SST(SEG)
      P_DEST=X'00370002'
      P_SRCE=0
      P_P1 = J
      P_P2=CBTA(CELL)_DA
      P_P3=CBTA(CELL)_TAGS
      P_P4=MODE
      P_P5=(CURSOR<<16) ! OFFSET
      P_P6=LENGTH
      DOUT11I(P)
      FLAG=P_P2
      UNLESS  FLAG=0 THEN  ENABLED(STREAM)=0; ! if it fails, clear the bit that says its enabled
      RESULT =FLAG
END ; ! ENABLE STREAM
!
!-----------------------------------------------------------------------
!
INTEGERFN  DISABLE STREAM(INTEGERNAME  CURSOR,INTEGER  STRM,REASON)
! NOTE: INPUT/AWAIT-UPDATE REQUESTS HAVE A SACT OF ZERO.
! DISABLE REQUESTS HAVE A SACT OF 1. WHEN A DISABLE HAS BEEN DONE,
! A REPLY TO AN INPUT/OUTPUT-PTR-UPDATE REQ MAY BE ON ITS WAY, AND WE
! THROW IT AWAY IF IT ARRIVES HERE BEFORE THE REPLY TO "DISABLE".
RECORD  (PARMF)P
INTEGER  FLAG
      CURSOR=0
      RESULT  = 0 IF  ENABLED(STRM) = 0; ! not enabled
      P=0
      P_DEST=X'00370004'
      IF  STRM=0 THEN  P_P1=UINF_INSTREAM ELSE  P_P1=UINF_OUTSTREAM
      P_P2=REASON; ! MODE 4 = SUSPEND, MODE 5 = ABORT
      DOUTI(P)
      FLAG=P_P2
      IF  FLAG=0 THEN  ENABLED(STRM)=0 AND  CURSOR=P_P5
      RESULT =FLAG
END ; ! DISABLE STREAM
!
!-----------------------------------------------------------------------
!
EXTERNALROUTINE  COMMS CLOSE DOWN
INTEGER  J, S
      CYCLE  S = 0, 1, 1; ! do streams 0 and 1
         J = DISABLESTREAM(J, S, 4); ! cursor irrelevant, suspend, zero res if not enabled
         WRSN("Disable ".ITOS(S)." flag=", J) UNLESS  J = 0
         J = DISCONNECTSTREAM(S)
         WRSN("Disconnect ".ITOS(S)." flag=", J) UNLESS  J = 0
      REPEAT 
END ; ! COMMS CLOSE DOWN
!
!-----------------------------------------------------------------------
!
!<DENABLETERMINALSTREAM
externalintegerfn  DENABLE TERMINAL STREAM(integer  STREAM, MODE,
      LEVEL, ADR, LEN, CURSOR)
!
! When a user logs in to EMAS 2900 from an interactive terminal, a
! process is created and two interactive streams, one for input and one
! for output, connect the process to the terminal.  (Note that this
! usage of the word "connect" is distinct from that pertaining to files
! and virtual memories in EMAS 2900.)  The process sends output to its
! terminal by writing the data into a file.  Similarly, input from the
! terminal is placed by the System in a file.  In each case, the file
! (or part of it) is used by the process and the communications system as
! a circular buffer.
!
! Procedure DENABLE TERMINAL STREAM is used to connect a file into the
! virtual memory and to specify the circular buffer within the file.
! ADR is the start of the buffer and LEN is its length (in bytes).
! STREAM should be set to 0 or 1, indicating input or output respectively
! LEVEL is not used and should be set to zero.
! MODE should be set to 1.
!
! After this procedure has been successfully executed, the specified
! circular buffer is available for interactive input or output.  After
! a stream has been disabled or aborted (see procedure DDISABLE TERMINAL
! STREAM), this procedure may be called again to re-specify a circular
! buffer, to allow input or output to be resumed.
!
! Each EMAS 2900 process may have at most one input and one output
! stream connected to the communications system.
!>
!     RESULT =  0   OK
!              -1   ILLEGAL ADDRESSES OR ALREADY NOMINATED
!              >0   CONNECT FAIL FLAG
! STREAM SHOULD BE SET 0 TO NOMINATE INPUT, OR 1 FOR OUTPUT
!
! OFFSET AND LENGTH MUST BE WITHIN THE FILE, WHICH
! SHOULD NOT EXCEED 32 KBYTES (WE WANT TO DESCRIBE IT IN 15 BITS IN THE FE).
INTEGER  J,OFFSET,SEG
      J = IN2(256 + 22)
      -> OUT UNLESS  J = 0
!
      SEG=ADR>>18
      OFFSET=ADR<<14>>14
!
      J = 8
      -> OUT UNLESS  0<=STREAM<=1  C 
         AND  0<LEN<=X'7FFF' AND  0<=OFFSET<X'7FFF' AND  0<=CURSOR<LEN
      IF  SEG>HISEG OR   C 
         OFFSET+LEN-1>(ST(SEG)_APFLIM&X'0003FF80') ! X'7F' THEN  C 
            -> OUT
IF  MODE=0 THEN  MODE=1; ! TEMPORARY (DEC 79) UNTIL SUBSYS SETS MODE PROPERLY !!!!!!!!!!!!!!!!
      J=ENABLE STREAM(STREAM,SEG,OFFSET,LEN,CURSOR,MODE)
      UNLESS  J = 0 START 
         WRSNT("Enable stream", STREAM, 5)
         WRSN(" flag", J)
         J = 4
         -> OUT
      FINISH 
! SET UP GLOBALS FOR SUBSEQUENT CHECKING OF TERMINAL REQUESTS
      IF  STREAM=0 START 
         INBUFA=ADR
         INBUFLEN=LEN
         IOSTAT_INBUFLEN=LEN
      FINISH  ELSE  START 
         OUTBUFA=ADR
         IOSTAT_OUTBUFLEN=LEN
         OUTBUFLEN=LEN
      FINISH 
OUT:
      RESULT  = OUT(J, "II")
END ; ! DENABLE TERMINAL STREAM
!
!-------------------end-of-included-text---------------------------------
!