xref: /csrg-svn/sys/luna68k/stand/sio.c (revision 63199)
157100Sakito /*
257100Sakito  * Copyright (c) 1992 OMRON Corporation.
3*63199Sbostic  * Copyright (c) 1992, 1993
4*63199Sbostic  *	The Regents of the University of California.  All rights reserved.
557100Sakito  *
657100Sakito  * This code is derived from software contributed to Berkeley by
757100Sakito  * OMRON Corporation.
857100Sakito  *
957100Sakito  * %sccs.include.redist.c%
1057100Sakito  *
11*63199Sbostic  *	@(#)sio.c	8.1 (Berkeley) 06/10/93
1257100Sakito  */
1357100Sakito 
1457100Sakito /* sio.c   NOV-25-1991 */
1557100Sakito 
1657100Sakito #define NSIO 2
1757100Sakito 
1857100Sakito #include <sys/param.h>
1957100Sakito #include <luna68k/stand/sioreg.h>
2057100Sakito #include <luna68k/stand/rcvbuf.h>
2157100Sakito #include <luna68k/stand/kbdreg.h>
2257100Sakito 
2357100Sakito struct rcvbuf	rcvbuf[NSIO];
2457100Sakito 
2557100Sakito int	sioconsole = -1;
2657100Sakito struct	siodevice *sio_addr[2];
2757100Sakito int	cur_unit;
2857100Sakito 
2957100Sakito 
3057100Sakito #define	siounit(x)	( x & 0xffff )
3157100Sakito #define isprint(c)      ((c >= 0x20) && (c < 0x7F) ? 1 : 0)
3257100Sakito 
3357100Sakito 
3457100Sakito void
_siointr()3557100Sakito _siointr()
3657100Sakito {
3757100Sakito 	register int unit;
3857100Sakito 
3957100Sakito 	for (unit = 0; unit < NSIO; unit++)
4057100Sakito 		siointr(unit);
4157100Sakito }
4257100Sakito 
siointr(unit)4357100Sakito siointr(unit)
4457100Sakito 	register int unit;
4557100Sakito {
4657100Sakito 	register struct	siodevice *sio = sio_addr[unit];
4757100Sakito 	register int rr0 = sioreg(REG(unit, RR0), 0);
4857100Sakito 	register int rr1 = sioreg(REG(unit, RR1), 0);
4957100Sakito 
5057100Sakito 	if (rr0 & RR0_RXAVAIL) {
5157100Sakito 		if (rr1 & RR1_FRAMING)
5257100Sakito 			return;
5357100Sakito 
5457100Sakito 		if (rr1 & (RR1_PARITY | RR1_OVERRUN))
5557100Sakito 		    sioreg(REG(unit, WR0), WR0_ERRRST); /* Channel-A Error Reset */
5657100Sakito 
5757100Sakito 		if (unit == 1) {
5857100Sakito 			register int c = kbd_decode(sio_addr[unit]->sio_data);
5957100Sakito 
6057620Sakito 			if ((c & KC_TYPE) == KC_CODE)
6157620Sakito 				PUSH_RBUF(unit, c);
6257100Sakito 		} else {
6357100Sakito 			PUSH_RBUF(unit, sio_addr[unit]->sio_data);
6457100Sakito 		}
6557100Sakito 	}
6657100Sakito }
6757100Sakito 
6857100Sakito /*
6957100Sakito  * Following are all routines needed for SIO to act as console
7057100Sakito  */
7157100Sakito #include <luna68k/luna68k/cons.h>
7257100Sakito #include "romvec.h"
7357100Sakito 
7457100Sakito siocnprobe(cp)
7557100Sakito 	struct consdev *cp;
7657100Sakito {
7757100Sakito 	sio_addr[0] = (struct siodevice *) 0x51000000;
7857100Sakito 	sio_addr[1] = (struct siodevice *) 0x51000004;
7957100Sakito 
8057100Sakito 	/* make sure hardware exists */
8157100Sakito 	if (badaddr((short *)sio_addr[0])) {
8257100Sakito 		cp->cn_pri = CN_DEAD;
8357100Sakito 		return;
8457100Sakito 	}
8557100Sakito 
8657100Sakito 	/* locate the major number */
8757100Sakito 
8857100Sakito 	/* initialize required fields */
8957100Sakito 	cp->cn_dev = cur_unit = 0;
9057100Sakito 	cp->cn_tp  = 0;
9157100Sakito 	cp->cn_pri = CN_NORMAL;
9257100Sakito }
9357100Sakito 
9457100Sakito siocninit(cp)
9557100Sakito 	struct consdev *cp;
9657100Sakito {
9757100Sakito 	int unit = siounit(cp->cn_dev);
9857100Sakito 
9957100Sakito 	sioinit();
10057100Sakito 	sioconsole = unit;
10157100Sakito }
10257100Sakito 
siocngetc(dev)10357100Sakito siocngetc(dev)
10457100Sakito 	dev_t dev;
10557100Sakito {
10657100Sakito 	register int c, unit = siounit(dev);
10757100Sakito 
10857100Sakito 	while (RBUF_EMPTY(unit)) {
10957100Sakito 		DELAY(10);
11057100Sakito 	}
11157100Sakito 
11257100Sakito 	POP_RBUF(unit, c);
11357100Sakito 
11457100Sakito 	return(c);
11557100Sakito }
11657100Sakito 
siocnputc(dev,c)11757100Sakito siocnputc(dev, c)
11857100Sakito 	dev_t dev;
11957100Sakito 	int c;
12057100Sakito {
12157100Sakito 	int unit = siounit(dev);
12257100Sakito 	int s;
12357100Sakito 
12457100Sakito 	if (sioconsole == -1) {
12557100Sakito 		(void) sioinit();
12657100Sakito 		sioconsole = unit;
12757100Sakito 	}
12857100Sakito 
12957100Sakito 	s = splsio();
13057100Sakito 
13157100Sakito 	/* wait for any pending transmission to finish */
13257100Sakito 	while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0);
13357100Sakito 
13457100Sakito 	sio_addr[unit]->sio_data = (c & 0xFF);
13557100Sakito 
13657100Sakito 	/* wait for any pending transmission to finish */
13757100Sakito 	while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0);
13857100Sakito 
13957100Sakito 	splx(s);
14057100Sakito }
14157100Sakito 
14257100Sakito /* SIO misc routines */
14357100Sakito 
sioinit()14457100Sakito sioinit()
14557100Sakito {
14657100Sakito 	int s;
14757100Sakito 
14857100Sakito 	RBUF_INIT(0);
14957100Sakito 	RBUF_INIT(1);
15057100Sakito 
15157100Sakito 	s = splsio();
15257100Sakito 
15357100Sakito 	sioreg(REG(0, WR0), WR0_CHANRST);		/* Channel-A Reset */
15457100Sakito 
15557100Sakito 	sioreg(WR2A, WR2_VEC86  | WR2_INTR_1);		/* Set CPU BUS Interface Mode */
15657100Sakito 	sioreg(WR2B, 0);				/* Set Interrupt Vector */
15757100Sakito 
15857100Sakito 	sioreg(REG(0, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
15957100Sakito 	sioreg(REG(0, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY);	/* Tx/Rx */
16057100Sakito 	sioreg(REG(0, WR3), WR3_RX8BIT | WR3_RXENBL);		/* Rx */
16157100Sakito 	sioreg(REG(0, WR5), WR5_TX8BIT | WR5_TXENBL);		/* Tx */
16257100Sakito 	sioreg(REG(0, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
16357100Sakito 	sioreg(REG(0, WR1), WR1_RXALLS);		/* Interrupted All Char. */
16457100Sakito 
16557100Sakito 	sioreg(REG(1, WR0), WR0_CHANRST);		/* Channel-A Reset */
16657100Sakito 
16757100Sakito 	sioreg(REG(1, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
16857100Sakito 	sioreg(REG(1, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY);	/* Tx/Rx */
16957100Sakito 	sioreg(REG(1, WR3), WR3_RX8BIT | WR3_RXENBL);		/* Rx */
17057100Sakito 	sioreg(REG(1, WR5), WR5_TX8BIT | WR5_TXENBL);		/* Tx */
17157100Sakito 	sioreg(REG(1, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
17257100Sakito 	sioreg(REG(1, WR1), WR1_RXALLS);		/* Interrupted All Char. */
17357100Sakito 
17457100Sakito 	splx(s);
17557100Sakito }
17657100Sakito 
17757100Sakito int
sioreg(reg,val)17857100Sakito sioreg(reg, val)
17957100Sakito 	register int reg, val;
18057100Sakito {
18157100Sakito 	register int chan;
18257100Sakito 
18357100Sakito 	chan = CHANNEL(reg);
18457100Sakito 
18557100Sakito 	if (isStatusReg(reg)) {
18657100Sakito 		if (REGNO(reg) != 0)
18757100Sakito 		    sio_addr[chan]->sio_cmd = REGNO(reg);
18857100Sakito 		return(sio_addr[chan]->sio_stat);
18957100Sakito 	} else {
19057100Sakito 		if (REGNO(reg) != 0)
19157100Sakito 		    sio_addr[chan]->sio_cmd = REGNO(reg);
19257100Sakito 		sio_addr[chan]->sio_cmd = val;
19357100Sakito 		return(val);
19457100Sakito 	}
19557100Sakito }
196