* Written to handle single dz - `carrier'|`ring' support non-existent
* Re-written to handle multiple dz's and `carrier'|`ring'.
* General tidy up, new comments etc. Removal of ifdefs
* for CARRIER and RING. If you don't want them, tough.
* Define this if you want parity and framing errors
* to be logged (via printf). It can be very wordy.
* Define this to translate framing errors (breaks)
* to CINTR for terminals which lack a DEL key.
* Can be nasty if you get lots of line errors.
* Define to debug info for dialup lines.
* costs approximately 128 bytes
#define NDZ 2 /* number of DZ-11s */
#define NLINES 8*NDZ /* total number of lines */
#define TSCANRATE 2 /* dzscan called every 2 tics */
/* Must be >= 2 always */
#define RESPONDTIME (25*HZ) /* Carrier must be raised inside this */
#define CARRIERTIME (1*HZ) /* Carrier must drop for this before hangup */
#define FLUSHTIME 5 /* time required to allow hardware buffered
* characters to flush before setting speed */
#define SSPEED 12 /* standard speed 4800 bd */
struct dz
/* one for each dz-11 */
int *dzaddr
; /* dz device address */
char sopen
; /* bit set for single open lines */
char carrier
; /* bits set for carrier controlled lines */
char ring
; /* bits set for lines with dial in modems */
char active
; /* bits set for active dialup lines */
char openl
; /* bits set for open lines */
unsigned pyerrors
; /* count of of parity errors on input */
unsigned overrors
; /* count of of overrun errors on input */
/* dzaddr sopen carr ring */
{ 0160040, 0002, 0077, 0074 },
{ 0160050, 0000, 0000, 0000 }
int dzscanning
; /* set when scanning for input and modem change */
int dzrbuf
; /* no bit, byte, or tst ops */
int dzlpr
; /* no bit or byte ops */
char dztbuf
; /* no bit ops */
char dzbrk
; /* no bit ops */
#define TRDY 0100000 /* dzcsr */
#define RCVR_ON 010000 /* dzlpr */
#define IBM2741 RCVR_ON|S134_5|ODD_PAR|C6BIT /* if you must */
#define RERROR 070000 /* dzrbuf */
* table to map UNIX standard speeds to DZ11 speeds
* illegal speeds are ignored.
,0200 /* 6 - 200 -- ## ILLEGAL ## */
, 031 /* 14 - ext A - maps to 2000 */
, 037 /* 15 - ext B - maps to 19200 */
char dzdelays
[NLINES
]; /* Count of clock ticks for per-line
* delays. Count of <= 0 means no delay.
* Reduces requirement of timeouts.
int dzringt
[NLINES
]; /* Delay counts for modem control */
extern dzstart(), dzscan();
if(dev
.d_minor
>= NLINES
)
dzp
= &dz
[dev
.d_minor
>>3];
t_bit
= (1<<(dev
.d_minor
&07));
if((dzp
->sopen
&t_bit
) && (dzp
->openl
&t_bit
))
if(u
.u_procp
->p_ttyp
== 0)
if((tp
->t_state
&ISOPEN
) == 0)
tp
->t_speeds
= SSPEED
|(SSPEED
<<8);
tp
->t_flags
= ODDP
|EVENP
|XTABS
|RAW
;
dzp
->dzaddr
->dzcsr
=| (TIE
|RIE
|SAE
|MSE
); /* reciever interrupt every 16 chars */
dzscan(); /* start scanning */
if(!(dzp
->ring
&t_bit
) && !(dzp
->carrier
&t_bit
))
dzp
->dzaddr
->dzdtr
=| t_bit
; /* turn on DTR for non-dialup lines */
printf("%d wo%d\n", time
.loint
, dev
.d_minor
);
while(!(dzp
->dzaddr
->dzcarr
&t_bit
))
sleep(&tp
->t_rawq
, TTIPRI
);
printf("%d op%d\n", time
.loint
, dev
.d_minor
);
tp
->t_state
= (ISOPEN
|CARR_ON
|SSTART
);
* 1. modem status changes
* 2. process timeouts as dictated by dzdelays
* 3. input by calling dzrint
extern dzstart(), dzrint(), dzscan();
# define openring (dzp->openl & dzp->ring)
# define opencarrier (dzp->openl & dzp->carrier)
* scan open dialup/carrier lines.
for(dzp
= dz
; dzp
< &dz
[NDZ
]; dzp
++)
if((scanl
= openring
) | (scanc
= opencarrier
))
for(t_bit
= 1; t_bit
&0377; t_bit
=<< 1, tp
++, p
++)
/* this is an open `dialup' line */
if(!(dzaddr
->dzcarr
&t_bit
))
else if((*p
=- TSCANRATE
) <= 0)
printf("%d hu%d\n", time
.loint
, tp
->t_dev
.d_minor
);
dzaddr
->dzdtr
=& ~t_bit
; /* hang up the phone */
dzaddr
->dztcr
=& ~t_bit
; /* disable transmit */
if(!(tp
->t_state
&TIMEOUT
) && (tp
->t_outq
.c_cc
))
if(!(dzaddr
->dzdtr
&t_bit
) && (dzaddr
->dzring
&t_bit
))
dzaddr
->dzdtr
=| t_bit
; /* answer the phone */
printf("%d ap%d\n", time
.loint
, tp
->t_dev
.d_minor
);
else if((scanc
&t_bit
) && (dzaddr
->dzcarr
&t_bit
))
{ /* carrier only line */
else if((!(tp
->t_state
&TIMEOUT
)) && (tp
->t_outq
.c_cc
))
tp
=+ 8; p
=+ 8; /* in the case where no dialup/carrier lines on current dz */
* process timeouts for each line
for(i
= 0; i
< NLINES
; i
++)
if((dzdelays
[i
] > 0) && (--dzdelays
[i
] <= 0))
dz11
[i
].t_state
=& ~TIMEOUT
;
* restart scanning if necessary
dzscanning
= timeout(&dzscan
, 0, TSCANRATE
);
dzp
= &dz
[dev
.d_minor
>>3];
t_bit
= 1<<(dev
.d_minor
&07);
dzp
->dzaddr
->dzdtr
=& ~t_bit
; /* hang up the phone */
dzp
->dzaddr
->dzdtr
=& ~t_bit
; /* turn off dtr for non-dialup lines */
if((dzp
->openl
=& ~t_bit
) == 0)
dzp
->dzaddr
->dzcsr
= 0; /* disable receive on final close */
ttread(&dz11
[dev
.d_minor
]);
ttwrite(&dz11
[dev
.d_minor
]);
if((av
== 0) && (dzspeedmap
[u
.u_arg
[0]&017] < 0))
u
.u_error
= ENXIO
; /* illegal speed */
* set parameters from open or stty into DZ hardware registers
lpr
= dzspeedmap
[tp
->t_speeds
&017]<<8;
if(lpr
== (RCVR_ON
|S134_5
))
if(lpr
== (RCVR_ON
|S110
))
if((x
= tp
->t_flags
)&EVENP
)
/* delay only if it is permissible */
timeout(&wakeup
, tp
, FLUSHTIME
); /* wakeup in 5 tics */
sleep(tp
, TTOPRI
); /* delay while controller flushes */
delay(FLUSHTIME
); /* hang 5 */
dz
[tp
->t_dev
.d_minor
>>3].dzaddr
->dzlpr
= lpr
|(tp
->t_dev
.d_minor
&07);
* start (restart) transmission on a DZ11 line
t_bit
= 1<<(tp
->t_dev
.d_minor
&07);
dzp
= &dz
[tp
->t_dev
.d_minor
>>3];
if((!(dzp
->carrier
&t_bit
)) || (dzp
->dzaddr
->dzcarr
&t_bit
))
dzp
->dzaddr
->dztcr
=| t_bit
;
* DZ11 transmitter interrupt.
* Scan every line on each dz.
* Commencing with the device that caused
register struct dzr_read
*dzaddr
;
dzaddr
= (dzp
= &dz
[n
])->dzaddr
;
while((c
= dzaddr
->dzcsr
) < 0) /* xmit line ready */
t_bit
= 1<<(lino
= (c
>>8)&07);
if((!(dzp
->carrier
&t_bit
) || (dzaddr
->dzcarr
&t_bit
)) && (c
= getc(&tp
->t_outq
)) >= 0)
if(c
<= 0177 || tp
->t_flags
== RAW
)
dzdelays
[tp
-dz11
] = ((c
&0177)+(TSCANRATE
-1))/TSCANRATE
+1; /* set up timeout */
if(tp
->t_outq
.c_cc
<= ((tp
->t_speeds
&017) > B1200
?TTHSLOWAT
:TTLOWAT
) && (tp
->t_state
&ASLEEP
))
if(tp
->t_outq
.c_cc
<= TTLOWAT
&& (tp
->t_state
&ASLEEP
))
* DZ11 receiver interrupt
* Scan each dz commencing with the
* particular device that caused this call.
* Storing each charater as it comes.
register struct dzr_read
*dzaddr
;
while((c
= dzp
->dzaddr
->dzrbuf
) < 0) /* char present in silo */
tp
= &dzbase
[lino
= ((c
>>8)&07)];
printf("over run on dz %d/%d\n", n
, lino
);
c
= 0; /* null ( for getty ) */
c
= CINTR
; /* del for NCRs. */
continue; /* ignore framing errors if not raw */
printf("parity on dz %d/%d\n", n
, lino
);
continue; /* throw away bad chars */
if((!(dzp
->carrier
&t_bit
)) || (dzp
->dzaddr
->dzcarr
&t_bit
))