1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)kbms_if.c 7.1 (Berkeley) 06/04/92 11 */ 12 13 /* Keyboard Mouse Gate-array control routine */ 14 15 #include "../include/fix_machine_type.h" 16 #include "../include/adrsmap.h" 17 18 #include "ms.h" 19 #include "bm.h" 20 21 #include "param.h" 22 #include "../sio/scc.h" 23 24 #if defined(news1200) || defined(news3200) 25 #include "time.h" 26 #include "../iop/mouse.h" 27 #endif 28 29 typedef struct kbm_sw { 30 u_char *stat_port; /* Status port */ 31 u_char *data_port; /* Data port */ 32 u_char *intr_port; /* Interrupt port */ 33 u_char *reset_port; /* Reset port */ 34 u_char *init1_port; /* Initialize port 1 */ 35 u_char *init2_port; /* Initialize port 2 */ 36 u_char *buzz_port; /* Buzzer port */ 37 u_char *buzzf_port; /* Buzzer frequency port */ 38 u_char intr_en; /* Data for Interrupt Enable */ 39 u_char intr_in; /* Interrupt Occur flag */ 40 u_char data_rdy; /* Data Ready flag */ 41 u_char init1; /* Speed */ 42 u_char init2; /* Clock */ 43 u_char buzzf; /* Buzzer frequency */ 44 } Kbm_sw; 45 46 #define OFF 0x80 47 struct kbm_sw Kbm_port[] = { 48 { 49 #ifdef news3400 50 (u_char *) MOUSE_STAT, 51 #else 52 (u_char *) KEYB_STAT, 53 #endif 54 (u_char *) MOUSE_DATA, 55 (u_char *) MOUSE_INTE, 56 (u_char *) MOUSE_RESET, 57 (u_char *) MOUSE_INIT1, 58 (u_char *) MOUSE_INIT2, 59 (u_char *) KEYB_BUZZ, 60 (u_char *) KEYB_BUZZF, 61 RX_MSINTE, 62 RX_MSINT, 63 RX_MSRDY, 64 #ifdef news3400 65 0x80, /* 1200 bps */ 66 0, 67 0 68 #else 69 1, 70 0xe0, 71 0x0a 72 #endif 73 }, 74 { 75 (u_char *) KEYB_STAT, 76 (u_char *) KEYB_DATA, 77 (u_char *) KEYB_INTE, 78 (u_char *) KEYB_RESET, 79 (u_char *) KEYB_INIT1, 80 (u_char *) KEYB_INIT2, 81 (u_char *) KEYB_BUZZ, 82 (u_char *) KEYB_BUZZF, 83 RX_KBINTE, 84 RX_KBINT, 85 RX_KBRDY, 86 #ifdef news3400 87 0xf0, /* 9600 bps */ 88 0, 89 0 90 #else 91 0, 92 0xc0, 93 0x0a 94 #endif 95 } 96 }; 97 98 kbm_open(chan) 99 int chan; 100 { 101 register Kbm_sw *kbm = &Kbm_port[chan]; 102 103 #ifdef news3400 104 /* 105 * Reset KB I/F. 106 * Disable KB interrupt. 107 * Clear KB overrun flag. 108 */ 109 *(volatile u_char *)kbm->reset_port = (u_char)0x01; 110 *(volatile u_char *)kbm->init1_port = kbm->init1; 111 if (chan == SCC_MOUSE) 112 *(volatile u_char *)kbm->intr_port |= kbm->intr_en; 113 #else 114 *kbm->reset_port = (u_char)0; 115 *kbm->intr_port = (u_char)1; 116 #endif 117 #ifdef news1200 118 *kbm->init1_port = kbm->init1; 119 *kbm->init2_port = kbm->init2; 120 *kbm->buzzf_port = kbm->buzzf; 121 #endif 122 kbd_flush(); 123 } 124 125 kbm_close(chan) 126 int chan; 127 { 128 register Kbm_sw *kbm = &Kbm_port[chan]; 129 130 #ifdef news3400 131 *(volatile u_char *)kbm->reset_port = (u_char)0x01; 132 #else 133 *kbm->reset_port = (u_char)0; 134 *kbm->intr_port = (u_char)0; 135 #endif 136 } 137 138 kbm_rint(chan) 139 int chan; 140 { 141 #ifdef news3400 142 volatile u_char *port = (volatile u_char *)Kbm_port[chan].data_port; 143 volatile u_char *stat = (volatile u_char *)Kbm_port[chan].stat_port; 144 volatile u_char *inte = (volatile u_char *)Kbm_port[chan].intr_port; 145 #else 146 register u_char *port = Kbm_port[chan].data_port; 147 register u_char *stat = Kbm_port[chan].stat_port; 148 register u_char *inte = Kbm_port[chan].intr_port; 149 #endif 150 int rdy = Kbm_port[chan].data_rdy; 151 u_char code; 152 153 #ifdef news3400 154 *inte &= ~Kbm_port[chan].intr_en; 155 #endif 156 157 while (*stat & rdy) { 158 code = *port; 159 switch (chan) { 160 case SCC_MOUSE: { 161 #if NMS > 0 162 extern int _ms_helper(); 163 164 if (xputc(code, SCC_MOUSE) < 0) 165 printf("mouse queue overflow\n"); 166 /* KU:XXX softcall? */ 167 timeout(_ms_helper, (caddr_t)0, 0); 168 #endif 169 break; 170 } 171 case SCC_KEYBOARD: { 172 #if NBM > 0 173 extern int kb_softint(); 174 175 if (xputc(code, SCC_KEYBOARD) < 0) 176 printf("keyboard queue overflow\n"); 177 /* KU:XXX softcall? */ 178 timeout(kb_softint, (caddr_t)0, 0); 179 #endif 180 break; 181 } 182 default: 183 printf("kb or ms stray intr\n"); 184 break; 185 } 186 } 187 188 #ifdef news3400 189 *inte |= Kbm_port[chan].intr_en; 190 #else 191 *inte = 1; 192 #endif 193 } 194 195 196 kbm_write(chan, buf, count) 197 int chan; 198 char *buf; 199 register int count; 200 { 201 register u_char *port = Kbm_port[chan].buzz_port; 202 int c_save = count; 203 204 #ifdef news1200 205 *port = count; 206 #endif 207 208 #ifdef news1700 209 if (buf == NULL) 210 while (--count >= 0) 211 *port = 0xff; 212 else 213 while (--count >= 0) 214 *port = *buf++; 215 #endif 216 217 #ifdef news3400 218 *port = count / 3; 219 #endif 220 221 return (c_save); 222 } 223 224 int 225 kbm_getc(chan) 226 int chan; 227 { 228 #ifdef news3400 229 volatile u_char *port = (volatile u_char *)Kbm_port[chan].data_port; 230 volatile u_char *stat = (volatile u_char *)Kbm_port[chan].stat_port; 231 #else 232 register u_char *port = Kbm_port[chan].data_port; 233 register u_char *stat = Kbm_port[chan].stat_port; 234 #endif 235 int rdy = Kbm_port[chan].data_rdy; 236 237 if (*stat & rdy) 238 return (*port & 0xff); 239 else 240 return (-1); 241 } 242