xref: /csrg-svn/sys/luna68k/stand/sio.c (revision 57100)
1*57100Sakito /*
2*57100Sakito  * Copyright (c) 1992 OMRON Corporation.
3*57100Sakito  * Copyright (c) 1992 The Regents of the University of California.
4*57100Sakito  * All rights reserved.
5*57100Sakito  *
6*57100Sakito  * This code is derived from software contributed to Berkeley by
7*57100Sakito  * OMRON Corporation.
8*57100Sakito  *
9*57100Sakito  * %sccs.include.redist.c%
10*57100Sakito  *
11*57100Sakito  *	@(#)sio.c	7.1 (Berkeley) 12/13/92
12*57100Sakito  */
13*57100Sakito 
14*57100Sakito /* sio.c   NOV-25-1991 */
15*57100Sakito 
16*57100Sakito #define NSIO 2
17*57100Sakito 
18*57100Sakito #include <sys/param.h>
19*57100Sakito #include <luna68k/stand/sioreg.h>
20*57100Sakito #include <luna68k/stand/rcvbuf.h>
21*57100Sakito #include <luna68k/stand/kbdreg.h>
22*57100Sakito 
23*57100Sakito struct rcvbuf	rcvbuf[NSIO];
24*57100Sakito 
25*57100Sakito int	sioconsole = -1;
26*57100Sakito struct	siodevice *sio_addr[2];
27*57100Sakito int	cur_unit;
28*57100Sakito 
29*57100Sakito 
30*57100Sakito #define	siounit(x)	( x & 0xffff )
31*57100Sakito #define isprint(c)      ((c >= 0x20) && (c < 0x7F) ? 1 : 0)
32*57100Sakito 
33*57100Sakito 
34*57100Sakito void
35*57100Sakito _siointr()
36*57100Sakito {
37*57100Sakito 	register int unit;
38*57100Sakito 
39*57100Sakito 	for (unit = 0; unit < NSIO; unit++)
40*57100Sakito 		siointr(unit);
41*57100Sakito }
42*57100Sakito 
43*57100Sakito siointr(unit)
44*57100Sakito 	register int unit;
45*57100Sakito {
46*57100Sakito 	register struct	siodevice *sio = sio_addr[unit];
47*57100Sakito 	register int rr0 = sioreg(REG(unit, RR0), 0);
48*57100Sakito 	register int rr1 = sioreg(REG(unit, RR1), 0);
49*57100Sakito 
50*57100Sakito 	if (rr0 & RR0_RXAVAIL) {
51*57100Sakito 		if (rr1 & RR1_FRAMING)
52*57100Sakito 			return;
53*57100Sakito 
54*57100Sakito 		if (rr1 & (RR1_PARITY | RR1_OVERRUN))
55*57100Sakito 		    sioreg(REG(unit, WR0), WR0_ERRRST); /* Channel-A Error Reset */
56*57100Sakito 
57*57100Sakito 		if (unit == 1) {
58*57100Sakito 			register int c = kbd_decode(sio_addr[unit]->sio_data);
59*57100Sakito 
60*57100Sakito 			if ((c & KC_TYPE) == 0) {
61*57100Sakito 				if (isprint(c))
62*57100Sakito 					PUSH_RBUF(unit, c);
63*57100Sakito 				else
64*57100Sakito 					PUSH_RBUF(unit, ' ');
65*57100Sakito 			}
66*57100Sakito 		} else {
67*57100Sakito 			PUSH_RBUF(unit, sio_addr[unit]->sio_data);
68*57100Sakito 		}
69*57100Sakito 	}
70*57100Sakito }
71*57100Sakito 
72*57100Sakito /*
73*57100Sakito  * Following are all routines needed for SIO to act as console
74*57100Sakito  */
75*57100Sakito #include <luna68k/luna68k/cons.h>
76*57100Sakito #include "romvec.h"
77*57100Sakito 
78*57100Sakito siocnprobe(cp)
79*57100Sakito 	struct consdev *cp;
80*57100Sakito {
81*57100Sakito 	sio_addr[0] = (struct siodevice *) 0x51000000;
82*57100Sakito 	sio_addr[1] = (struct siodevice *) 0x51000004;
83*57100Sakito 
84*57100Sakito 	/* make sure hardware exists */
85*57100Sakito 	if (badaddr((short *)sio_addr[0])) {
86*57100Sakito 		cp->cn_pri = CN_DEAD;
87*57100Sakito 		return;
88*57100Sakito 	}
89*57100Sakito 
90*57100Sakito 	/* locate the major number */
91*57100Sakito 
92*57100Sakito 	/* initialize required fields */
93*57100Sakito 	cp->cn_dev = cur_unit = 0;
94*57100Sakito 	cp->cn_tp  = 0;
95*57100Sakito 	cp->cn_pri = CN_NORMAL;
96*57100Sakito }
97*57100Sakito 
98*57100Sakito siocninit(cp)
99*57100Sakito 	struct consdev *cp;
100*57100Sakito {
101*57100Sakito 	int unit = siounit(cp->cn_dev);
102*57100Sakito 
103*57100Sakito 	sioinit();
104*57100Sakito 	sioconsole = unit;
105*57100Sakito }
106*57100Sakito 
107*57100Sakito siocngetc(dev)
108*57100Sakito 	dev_t dev;
109*57100Sakito {
110*57100Sakito 	register int c, unit = siounit(dev);
111*57100Sakito 
112*57100Sakito 	while (RBUF_EMPTY(unit)) {
113*57100Sakito 		DELAY(10);
114*57100Sakito 	}
115*57100Sakito 
116*57100Sakito 	POP_RBUF(unit, c);
117*57100Sakito 
118*57100Sakito 	return(c);
119*57100Sakito }
120*57100Sakito 
121*57100Sakito siocnputc(dev, c)
122*57100Sakito 	dev_t dev;
123*57100Sakito 	int c;
124*57100Sakito {
125*57100Sakito 	int unit = siounit(dev);
126*57100Sakito 	int s;
127*57100Sakito 
128*57100Sakito 	if (sioconsole == -1) {
129*57100Sakito 		(void) sioinit();
130*57100Sakito 		sioconsole = unit;
131*57100Sakito 	}
132*57100Sakito 
133*57100Sakito 	s = splsio();
134*57100Sakito 
135*57100Sakito 	/* wait for any pending transmission to finish */
136*57100Sakito 	while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0);
137*57100Sakito 
138*57100Sakito 	sio_addr[unit]->sio_data = (c & 0xFF);
139*57100Sakito 
140*57100Sakito 	/* wait for any pending transmission to finish */
141*57100Sakito 	while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0);
142*57100Sakito 
143*57100Sakito 	splx(s);
144*57100Sakito }
145*57100Sakito 
146*57100Sakito /* SIO misc routines */
147*57100Sakito 
148*57100Sakito sioinit()
149*57100Sakito {
150*57100Sakito 	int s;
151*57100Sakito 
152*57100Sakito 	RBUF_INIT(0);
153*57100Sakito 	RBUF_INIT(1);
154*57100Sakito 
155*57100Sakito 	s = splsio();
156*57100Sakito 
157*57100Sakito 	sioreg(REG(0, WR0), WR0_CHANRST);		/* Channel-A Reset */
158*57100Sakito 
159*57100Sakito 	sioreg(WR2A, WR2_VEC86  | WR2_INTR_1);		/* Set CPU BUS Interface Mode */
160*57100Sakito 	sioreg(WR2B, 0);				/* Set Interrupt Vector */
161*57100Sakito 
162*57100Sakito 	sioreg(REG(0, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
163*57100Sakito 	sioreg(REG(0, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY);	/* Tx/Rx */
164*57100Sakito 	sioreg(REG(0, WR3), WR3_RX8BIT | WR3_RXENBL);		/* Rx */
165*57100Sakito 	sioreg(REG(0, WR5), WR5_TX8BIT | WR5_TXENBL);		/* Tx */
166*57100Sakito 	sioreg(REG(0, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
167*57100Sakito 	sioreg(REG(0, WR1), WR1_RXALLS);		/* Interrupted All Char. */
168*57100Sakito 
169*57100Sakito 	sioreg(REG(1, WR0), WR0_CHANRST);		/* Channel-A Reset */
170*57100Sakito 
171*57100Sakito 	sioreg(REG(1, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
172*57100Sakito 	sioreg(REG(1, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY);	/* Tx/Rx */
173*57100Sakito 	sioreg(REG(1, WR3), WR3_RX8BIT | WR3_RXENBL);		/* Rx */
174*57100Sakito 	sioreg(REG(1, WR5), WR5_TX8BIT | WR5_TXENBL);		/* Tx */
175*57100Sakito 	sioreg(REG(1, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
176*57100Sakito 	sioreg(REG(1, WR1), WR1_RXALLS);		/* Interrupted All Char. */
177*57100Sakito 
178*57100Sakito 	splx(s);
179*57100Sakito }
180*57100Sakito 
181*57100Sakito int
182*57100Sakito sioreg(reg, val)
183*57100Sakito 	register int reg, val;
184*57100Sakito {
185*57100Sakito 	register int chan;
186*57100Sakito 
187*57100Sakito 	chan = CHANNEL(reg);
188*57100Sakito 
189*57100Sakito 	if (isStatusReg(reg)) {
190*57100Sakito 		if (REGNO(reg) != 0)
191*57100Sakito 		    sio_addr[chan]->sio_cmd = REGNO(reg);
192*57100Sakito 		return(sio_addr[chan]->sio_stat);
193*57100Sakito 	} else {
194*57100Sakito 		if (REGNO(reg) != 0)
195*57100Sakito 		    sio_addr[chan]->sio_cmd = REGNO(reg);
196*57100Sakito 		sio_addr[chan]->sio_cmd = val;
197*57100Sakito 		return(val);
198*57100Sakito 	}
199*57100Sakito }
200