Add original unix v6
This commit is contained in:
+300
@@ -0,0 +1,300 @@
|
||||
#
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH-11 driver
|
||||
* This driver calls on the DHDM driver.
|
||||
* If the DH has no DM11-BB, then the latter will
|
||||
* be fake. To insure loading of the correct DM code,
|
||||
* lib2 should have dhdm.o, dh.o and dhfdm.o in that order.
|
||||
*/
|
||||
|
||||
#include "../param.h"
|
||||
#include "../conf.h"
|
||||
#include "../user.h"
|
||||
#include "../tty.h"
|
||||
#include "../proc.h"
|
||||
|
||||
#define DHADDR 0160020
|
||||
#define NDH11 16 /* number of lines */
|
||||
#define DHNCH 8 /* max number of DMA chars */
|
||||
|
||||
struct tty dh11[NDH11];
|
||||
/*
|
||||
* Place from which to do DMA on output
|
||||
*/
|
||||
char dh_clist[NDH11][DHNCH];
|
||||
|
||||
/*
|
||||
* Used to communicate the number of lines to the DM
|
||||
*/
|
||||
int ndh11 NDH11;
|
||||
|
||||
/*
|
||||
* Hardware control bits
|
||||
*/
|
||||
#define BITS6 01
|
||||
#define BITS7 02
|
||||
#define BITS8 03
|
||||
#define TWOSB 04
|
||||
#define PENABLE 020
|
||||
/* DEC manuals incorrectly say this bit causes generation of even parity. */
|
||||
#define OPAR 040
|
||||
#define HDUPLX 040000
|
||||
|
||||
#define IENABLE 030100
|
||||
#define PERROR 010000
|
||||
#define FRERROR 020000
|
||||
#define XINT 0100000
|
||||
#define SSPEED 7 /* standard speed: 300 baud */
|
||||
|
||||
/*
|
||||
* Software copy of last dhbar
|
||||
*/
|
||||
int dhsar;
|
||||
|
||||
struct dhregs {
|
||||
int dhcsr;
|
||||
int dhnxch;
|
||||
int dhlpr;
|
||||
int dhcar;
|
||||
int dhbcr;
|
||||
int dhbar;
|
||||
int dhbreak;
|
||||
int dhsilo;
|
||||
};
|
||||
|
||||
/*
|
||||
* Open a DH11 line.
|
||||
*/
|
||||
dhopen(dev, flag)
|
||||
{
|
||||
register struct tty *tp;
|
||||
extern dhstart();
|
||||
|
||||
if (dev.d_minor >= NDH11) {
|
||||
u.u_error = ENXIO;
|
||||
return;
|
||||
}
|
||||
tp = &dh11[dev.d_minor];
|
||||
tp->t_addr = dhstart;
|
||||
tp->t_dev = dev;
|
||||
DHADDR->dhcsr =| IENABLE;
|
||||
tp->t_state =| WOPEN|SSTART;
|
||||
if ((tp->t_state&ISOPEN) == 0) {
|
||||
tp->t_erase = CERASE;
|
||||
tp->t_kill = CKILL;
|
||||
tp->t_speeds = SSPEED | (SSPEED<<8);
|
||||
tp->t_flags = ODDP|EVENP|ECHO;
|
||||
dhparam(tp);
|
||||
}
|
||||
dmopen(dev);
|
||||
tp->t_state =& ~WOPEN;
|
||||
tp->t_state =| ISOPEN;
|
||||
if (u.u_procp->p_ttyp == 0)
|
||||
u.u_procp->p_ttyp = tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a DH11 line.
|
||||
*/
|
||||
dhclose(dev)
|
||||
{
|
||||
register struct tty *tp;
|
||||
|
||||
tp = &dh11[dev.d_minor];
|
||||
dmclose(dev);
|
||||
tp->t_state =& (CARR_ON|SSTART);
|
||||
wflushtty(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from a DH11 line.
|
||||
*/
|
||||
dhread(dev)
|
||||
{
|
||||
ttread(&dh11[dev.d_minor]);
|
||||
}
|
||||
|
||||
/*
|
||||
* write on a DH11 line
|
||||
*/
|
||||
dhwrite(dev)
|
||||
{
|
||||
ttwrite(&dh11[dev.d_minor]);
|
||||
}
|
||||
|
||||
/*
|
||||
* DH11 receiver interrupt.
|
||||
*/
|
||||
dhrint()
|
||||
{
|
||||
register struct tty *tp;
|
||||
register int c;
|
||||
|
||||
while ((c = DHADDR->dhnxch) < 0) { /* char. present */
|
||||
tp = &dh11[(c>>8)&017];
|
||||
if (tp >= &dh11[NDH11])
|
||||
continue;
|
||||
if((tp->t_state&ISOPEN)==0 || (c&PERROR)) {
|
||||
wakeup(tp);
|
||||
continue;
|
||||
}
|
||||
if (c&FRERROR) /* break */
|
||||
if (tp->t_flags&RAW)
|
||||
c = 0; /* null (for getty) */
|
||||
else
|
||||
c = 0177; /* DEL (intr) */
|
||||
ttyinput(c, tp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* stty/gtty for DH11
|
||||
*/
|
||||
dhsgtty(dev, av)
|
||||
int *av;
|
||||
{
|
||||
register struct tty *tp;
|
||||
register r;
|
||||
|
||||
tp = &dh11[dev.d_minor];
|
||||
if (ttystty(tp, av))
|
||||
return;
|
||||
dhparam(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set parameters from open or stty into the DH hardware
|
||||
* registers.
|
||||
*/
|
||||
dhparam(atp)
|
||||
struct tty *atp;
|
||||
{
|
||||
register struct tty *tp;
|
||||
register int lpr;
|
||||
|
||||
tp = atp;
|
||||
spl5();
|
||||
DHADDR->dhcsr.lobyte = tp->t_dev.d_minor | IENABLE;
|
||||
/*
|
||||
* Hang up line?
|
||||
*/
|
||||
if (tp->t_speeds.lobyte==0) {
|
||||
tp->t_flags =| HUPCL;
|
||||
dmclose(tp->t_dev);
|
||||
return;
|
||||
}
|
||||
lpr = (tp->t_speeds.hibyte<<10) | (tp->t_speeds.lobyte<<6);
|
||||
if (tp->t_speeds.lobyte == 4) /* 134.5 baud */
|
||||
lpr =| BITS6|PENABLE|HDUPLX; else
|
||||
if (tp->t_flags&EVENP)
|
||||
if (tp->t_flags&ODDP)
|
||||
lpr =| BITS8; else
|
||||
lpr =| BITS7|PENABLE; else
|
||||
lpr =| BITS7|OPAR|PENABLE;
|
||||
if (tp->t_speeds.lobyte == 3) /* 110 baud */
|
||||
lpr =| TWOSB;
|
||||
DHADDR->dhlpr = lpr;
|
||||
spl0();
|
||||
}
|
||||
|
||||
/*
|
||||
* DH11 transmitter interrupt.
|
||||
* Restart each line which used to be active but has
|
||||
* terminated transmission since the last interrupt.
|
||||
*/
|
||||
dhxint()
|
||||
{
|
||||
register struct tty *tp;
|
||||
register ttybit, bar;
|
||||
|
||||
bar = dhsar & ~DHADDR->dhbar;
|
||||
DHADDR->dhcsr =& ~XINT;
|
||||
ttybit = 1;
|
||||
for (tp = dh11; bar; tp++) {
|
||||
if(bar&ttybit) {
|
||||
dhsar =& ~ttybit;
|
||||
bar =& ~ttybit;
|
||||
tp->t_state =& ~BUSY;
|
||||
dhstart(tp);
|
||||
}
|
||||
ttybit =<< 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Start (restart) transmission on the given DH11 line.
|
||||
*/
|
||||
dhstart(atp)
|
||||
struct tty *atp;
|
||||
{
|
||||
extern ttrstrt();
|
||||
register c, nch;
|
||||
register struct tty *tp;
|
||||
int sps;
|
||||
char *cp;
|
||||
|
||||
sps = PS->integ;
|
||||
spl5();
|
||||
tp = atp;
|
||||
/*
|
||||
* If it's currently active, or delaying,
|
||||
* no need to do anything.
|
||||
*/
|
||||
if (tp->t_state&(TIMEOUT|BUSY))
|
||||
goto out;
|
||||
/*
|
||||
* t_char is a delay indicator which may have been
|
||||
* left over from the last start.
|
||||
* Arrange for the delay.
|
||||
*/
|
||||
if (c = tp->t_char) {
|
||||
tp->t_char = 0;
|
||||
timeout(ttrstrt, tp, (c&0177)+6);
|
||||
tp->t_state =| TIMEOUT;
|
||||
goto out;
|
||||
}
|
||||
cp = dh_clist[tp->t_dev.d_minor];
|
||||
nch = 0;
|
||||
/*
|
||||
* Copy DHNCH characters, or up to a delay indicator,
|
||||
* to the DMA area.
|
||||
*/
|
||||
while (nch > -DHNCH && (c = getc(&tp->t_outq))>=0) {
|
||||
if (c >= 0200) {
|
||||
tp->t_char = c;
|
||||
break;
|
||||
}
|
||||
*cp++ = c;
|
||||
nch--;
|
||||
}
|
||||
/*
|
||||
* If the writer was sleeping on output overflow,
|
||||
* wake him when low tide is reached.
|
||||
*/
|
||||
if (tp->t_outq.c_cc<=TTLOWAT && tp->t_state&ASLEEP) {
|
||||
tp->t_state =& ~ASLEEP;
|
||||
wakeup(&tp->t_outq);
|
||||
}
|
||||
/*
|
||||
* If any characters were set up, start transmission;
|
||||
* otherwise, check for possible delay.
|
||||
*/
|
||||
if (nch) {
|
||||
DHADDR->dhcsr.lobyte = tp->t_dev.d_minor | IENABLE;
|
||||
DHADDR->dhcar = cp+nch;
|
||||
DHADDR->dhbcr = nch;
|
||||
c = 1<<tp->t_dev.d_minor;
|
||||
DHADDR->dhbar =| c;
|
||||
dhsar =| c;
|
||||
tp->t_state =| BUSY;
|
||||
} else if (c = tp->t_char) {
|
||||
tp->t_char = 0;
|
||||
timeout(ttrstrt, tp, (c&0177)+6);
|
||||
tp->t_state =| TIMEOUT;
|
||||
}
|
||||
out:
|
||||
PS->integ = sps;
|
||||
}
|
||||
Reference in New Issue
Block a user