h58257
s 00429/00000/00000
d D 1.1 83/03/23 16:01:59 bog 1 0
c date and time created 83/03/23 16:01:59 by bog
e
u
4
U
t
T
I 1
C This set of subroutines implements a simple communications
C driver for the GSS-4010 Emulator.
C
C The driver is not interrupt driven.  Using this driver,
C GSS-4010 switches back and forth between listening to the host
C via the RS232 line and listening to the keyboard for user
C input.
C
C It is recommended that you use an interrupt-driven host
C communications driver rather than a polled one like this one
C because GSS-4010 will not perform as well as it would if a
C more sophisticated host-access mechanism were used.  The
C effective throughput cannot be better than about half that of
C the more sophisticated approach and may be much worse,
C depending on the host.
C
C There are five modules here.  The HSIO BlockData module lets
C GSS-4010 know what capabilities the driver has.  The other
C four modules implement the host-access mechanism.
C
C Note that this driver assumes that it is running on a system
C where baud rate, parity etc.  are set up external to GSS-4010,
C e.g.  a SPEED program or some such.  The driver does NO setup
C on the SIO.
C
      BlockData HSIO
C If the driver is not capable of changing the baud rates,
C  RBdCpL and TBdCpL will be zero.
C
C If the driver is not capable of splitting transmit and receive
C  rates, TBdCpL will be zero and only the RxBdCp set will be
C  used.
C
C Usual baud rates:
C	50
C	75
C	110
C	134.5 (encoded as 134)
C	150
C	200
C	300
C	600
C	1200
C	1800
C	2000
C	2400
C	4800
C	7200
C	9600
C	19200
C	external (coded as -1)
C
C Number of receive baud rates
      Integer*2 RBdCpL
C
C Array of receive rates
      Integer*2 RxBdCp(15)
C
C Number of transmit baud rates
      Integer*2 TBdCpL
C
C Array of transmit rates
      Integer*2 TxBdCp(15)
C
C
C If the driver is not capable of controlling parity,
C  ParCap will be 0; -1 if capable.
      Integer*2 ParCap
C
C
C If the driver is not capable of controlling the number of
C  data bits, DtBCpL will be zero.
C
C Number of data bit formats
      Integer*2 DtBCpL
C
C Array of valid data bits per character
      Integer*2 DtBtCp(4)
C
C
C If the driver is not capable of controlling the number
C  of stop bits, StBCpL will be zero.
C
C Number of stop bit formats
      Integer*2 StBCpL
C
C Array of valid stop bits per character
C  Usual value		coding
C	1		  1
C	1.5		  2
C	2		  3
      Integer*2 StBtCp(3)
C
C
C If the driver is not capable of sending a Break,
C  TxBkCp will be 0; -1 if capable.
      Integer*2 TxBkCp
C
C If the driver is not capable of controlling the time a Break
C  spaces, TBkTCp will be 0; -1 if capable.
      Integer*2 TBkTCp
C
C If the driver is not capable of controlling DSR/DTR receive
C  flagging, RHwFCp will be 0; -1 if capable.
      Integer*2 RHwFCp
C
C Receive string flagging capability:
C  0	Driver not capable of controlling string flagging
C  1	Driver capable of single-character string flagging
C  2	Driver capable of arbitrary string flagging
      Integer*2 RStFCp
C
C If the driver is not capable of controlling RTS/CTS transmit
C  flagging, THwFCp will be 0; -1 if capable.
      Integer*2 THwFCp
C
C Transmit string flagging capability:
C  0	Driver not capable of controlling string flagging
C  1	Driver capable of single-character string flagging
C  2	Driver capable of arbitrary string flagging
      Integer*2 TStFCp
C
C If the driver is not capable of having a receive flagging
C  mode different from the transmit flagging mode, SpFMCp will
C  be 0; -1 if capable.
      Integer*2 SpFMCp
C
C Whether currently open; 0 if not, -1 if so
      Integer*2 COpen
C
C Current receive baud rate index
      Integer*2 RBaudI
C
C Current receive baud rate
      Integer*2 CRBaud
C
C Current transmit baud rate index
      Integer*2 TBaudI
C
C Current transmit baud rate
      Integer*2 CTBaud
C
C Current parity setting
      Integer*2 CurPar
C
C Current data bits per character index
      Integer*2 DatBtI
C
C Current data bits per character
      Integer*2 CDatBt
C
C Current stop bits per character index
      Integer*2 StoBtI
C
C Current stop bits per character
      Integer*2 CStoBt
C
C Current break time in milliseconds
      Integer*2 CBkTim
C
C Current input flagging mode
      Integer*2 CIFMod
C
C Current output flagging mode
      Integer*2 COFMod
C
C Current input flagging stop string
      Integer*2 CInStL
      Integer*2 CInStS(40)
C
C Current input flagging go string
      Integer*2 CInGoL
      Integer*2 CInGoS(40)
C
C Current output flagging stop string
      Integer*2 COtStL
      Integer*2 COtStS(40)
C
C Current output flagging go string
      Integer*2 COtGoL
      Integer*2 COtGoS(40)
C
      Common /GHCmCp/ RBdCpL,RxBdCp,TBdCpL,TxBdCp
      Common /GHCmCp/ ParCap,DtBCpL,DtBtCp,StBCpL,StBtCp
      Common /GHCmCp/ TxBkCp,TBkTCp
      Common /GHCmCp/ RHwFCp,RStFCp,THwFCp,TStFCp,SpFMCp
C
      Common /GHStat/ COpen
      Common /GHStat/ RBaudI,CRBaud,TBaudI,CTBaud
      Common /GHStat/ CurPar
      Common /GHStat/ DatBtI,CDatBt,StoBtI,CStoBt
      Common /GHStat/ CBkTim
      Common /GHStat/ CIFMod,COFMod
      Common /GHStat/ CInStL,CInStS,CInGoL,CInGoS,
     x                COtStL,COtStS,COtGoL,COtGoS
C
C If the driver is not capable of changing the baud rates,
C  RBdCpL and TBdCpL will be zero and RxBdCp and TxBdCp need not
C  be set.
C
C If the driver is not capable of splitting transmit and
C  receive rates, TBdCpL will be zero and only the RxBdCp set
C  will be used.
C
C Usual baud rates:
C	50
C	75
C	110
C	134.5 (encoded as 134)
C	150
C	200
C	300
C	600
C	1200
C	1800
C	2000
C	2400
C	4800
C	7200
C	9600
C	19200
C	external (coded as -1)
C
C Number of receive baud rates
      Data RBdCpL/0/
C
C Array of receive rates
C      Data RxBdCp(15)
C
C Number of transmit baud rates
      Data TBdCpL/0/
C
C Array of transmit rates
C      Data TxBdCp(15)
C
C
C If the driver is not capable of controlling parity,
C  ParCap will be 0; -1 if capable.
      Data ParCap/0/
C
C
C If the driver is not capable of controlling the number of
C  data bits, DtBCpL will be zero.
C
C Number of data bit formats
      Data DtBCpL/0/
C
C Array of valid data bits per character
C      Data DtBtCp(4)
C
C
C If the driver is not capable of controlling the number of
C  stop bits, StBCpL will be zero.
C
C Number of stop bit formats
      Data StBCpL/0/
C
C Array of valid stop bits per character
C  Usual value		coding
C	1		  1
C	1.5		  2
C	2		  3
C      Data StBtCp(3)
C
C
C If the driver is not capable of sending a Break,
C  TxBkCp will be 0; -1 if capable.
      Data TxBkCp/0/
C
C If the driver is not capable of controlling the time a
C  Break spaces, TBkTCp will be 0; -1 if capable.
      Data TBkTCp/0/
C
C If the driver is not capable of controlling DSR/DTR
C  receive flagging, RHwFCp will be 0; -1 if capable.
      Data RHwFCp/0/
C
C Receive string flagging capability:
C  0	Driver not capable of controlling string flagging
C  1	Driver capable of single-character string flagging
C  2	Driver capable of arbitrary string flagging
      Data RStFCp/0/
C
C If the driver is not capable of controlling RTS/CTS
C  transmit flagging, THwFCp will be 0; -1 if capable.
      Data THwFCp/0/
C
C Transmit string flagging capability:
C  0	Driver not capable of controlling string flagging
C  1	Driver capable of single-character string flagging
C  2	Driver capable of arbitrary string flagging
      Data TStFCp/0/
C
C If the driver is not capable of having a receive flagging
C  mode different from the transmit flagging mode, SpFMCp will
C  be 0; -1 if capable.
      Data SpFMCp/0/
C
C Whether currently open; 0 if not, -1 if so
      Data COpen/0/
      End
      Subroutine HsInit
C Call HsInit
C   Open communications channel with parameters specified in
C   /GHStat/.
C
C   This very simple driver for a Z80-SIO port is not buffered
C   and uses subroutines to talk to the port hardware.  It
C   assumes that speed, parity, format, and so on have been set
C   up externally and that all the driver must do is talk to
C   the port data in and out.
C
C   The SIO data is at 02ch (44), control is 02dh (45).
C
      Integer*2 Error
      Integer*2 COpen
      Common /GHStat/COpen
C Turn on Open flag
      COpen = -1
C Stop the host
1     Call HsSend(19,Error)
      If (Error.Eq.-1) Goto 1
      End
      Subroutine HsStop
C Call HsStop
C   Shut down communications channel
C
C Turn off Open flag
      Integer*2 COpen
      Common /GHStat/COpen
      COpen = 0
      End
      Subroutine HsRecv(Ch,Error)
C Call HsRecv(Ch,Error)
C    Output    Ch:     ADE Integer*2 character in Ascii 0..127,
C                       with -1 meaning EMPTY
C              Error:  Integer*2 error returned; always 0
C
C The HsRecv subroutine is the most complicated in this driver.
C When communications are first established, a ^S is sent to the
C host to stop it from sending.  The receive routine then sends
C a ^Q to let the host send stuff.  It waits TimeGo iterations
C for something from the host.  After each character it gets
C from the host it waits another TimeGo iterations.  When either
C HsRecv's buffer gets more than 80% full or no characters are
C received in TimeGo iterations, it sends a ^S to stop the host.
C It then spins again for TimeSt iterations to get characters
C the host might send while the host processes the ^S.  When it
C finally times out, HsRecv switches into a buffer unload mode
C and returns to GSS-4010, one by one, the characters it
C received from the host and buffered up.
C
C Note that TimeGo and TimeSt are host AND baud-rate dependent;
C they may need to be tweaked to get this driver to work at all,
C much less satisfactorily.
C
      Integer*2 Ch,Error,LError,TimeGo,TimeSt,Timer
      Integer*2 Buffer(256),BufHed,BufTal,BufSto,I
      Integer*1 Inp
      Data TimeGo,TimeSt,BufHed,BufTal,BufSto/100,40,1,0,200/
C
C If there is a character in the buffer, return it
      If (BufHed.Gt.BufTal) Goto 10
      Ch = Buffer(BufHed)
C Remove parity bit
      If (Ch.Lt.0) Ch = Ch+256
      If (Ch.Gt.127) Ch = Ch-128
      BufHed = BufHed+1
      Error = 0
      Return
C
C First, start the host
10    Call HsSend(17,LError)
      If (LError.Eq.-1) Goto 10
C Reset buffer pointers
      BufHed = 1
      BufTal = 0
C Assume no character will be received
      Ch = -1
      Error = 0
C
C Wait TimeGo time for possible host character
9     Timer = TimeGo
11    Call Out(45,0)
      I = Inp(45)
      If (Mod(I,2).Eq.0) Goto 17
      BufTal = BufTal+1
      Buffer(BufTal) = Inp(44)
      If (BufTal.Ge.BufSto) Goto 12
      Goto 9
17    Timer = Timer-1
      If (Timer.Gt.0) Goto 11
C
C No character received; stop the host
12    Call HsSend(19,LError)
      If (LError.Eq.-1) Goto 12
      Timer = TimeSt
13    Call Out(45,16)
      I = Inp(45)
      If (Mod(I,2).Ne.0) Goto 19
      Timer = Timer-1
      If (Timer.Gt.0) Goto 13
      Return
C Get character into buffer
19    BufTal = BufTal+1
      Buffer(BufTal) = Inp(44)
      Goto 13
      End
      Subroutine HsSend(Ch,Error)
C Call HsSend(Ch,Error)
C    Input     Ch:     ADE Integer*2 character in Ascii 0..127;
C                       BREAK is -2
C    Output    Error:  Integer*2 busy flag:
C                       -1: port busy; Ch not sent
C                        0: Ch sent successfully
C
      Integer*2 Ch,Error
      Integer*2 I
      Integer*1 Inp
C Select Read Register 0
      Call Out(45,0)
C See if character can be sent; test Tx buffer empty bit
      I = Inp(45)
      If (Mod(I,8).Le.3) Goto 1
      Call Out(44,Ch)
      Error = 0
      Return
1     Error = -1
      End
E 1
