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