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