make kernel includes standard
[unix-history] / usr / src / sys / pmax / dev / dc.c
CommitLineData
12d43ee5
KM
1/*
2 * Copyright (c) 1992 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Ralph Campbell.
84722262
RC
7 * @(#)dz.c 7.9 (Berkeley) 6/28/90
8 */
9
10/*
11 * devDC7085.c --
12d43ee5
KM
12 *
13 * %sccs.include.redist.c%
14 *
38a01dbe 15 * @(#)dc.c 7.9 (Berkeley) %G%
12d43ee5
KM
16 *
17 * devDC7085.c --
18 *
19 * This file contains machine-dependent routines that handle the
20 * output queue for the serial lines.
21 *
22 * Copyright (C) 1989 Digital Equipment Corporation.
23 * Permission to use, copy, modify, and distribute this software and
24 * its documentation for any purpose and without fee is hereby granted,
25 * provided that the above copyright notice appears in all copies.
26 * Digital Equipment Corporation makes no representations about the
27 * suitability of this software for any purpose. It is provided "as is"
28 * without express or implied warranty.
29 *
30 * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devDC7085.c,
31 * v 1.4 89/08/29 11:55:30 nelson Exp $ SPRITE (DECWRL)";
32 */
33
34#include "dc.h"
35#if NDC > 0
36/*
37 * DC7085 (DZ-11 look alike) Driver
38 */
38a01dbe
KB
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/ioctl.h>
42#include <sys/tty.h>
43#include <sys/proc.h>
44#include <sys/map.h>
45#include <sys/buf.h>
46#include <sys/conf.h>
47#include <sys/file.h>
48#include <sys/uio.h>
49#include <sys/kernel.h>
50#include <sys/syslog.h>
12d43ee5 51
38a01dbe 52#include <machine/dc7085cons.h>
12d43ee5 53
38a01dbe
KB
54#include <mips/dev/device.h>
55#include <mips/dev/pdma.h>
12d43ee5
KM
56
57/*
58 * Driver information for auto-configuration stuff.
59 */
60int dcprobe();
84722262 61void dcintr();
12d43ee5 62struct driver dcdriver = {
84722262 63 "dc", dcprobe, 0, 0, dcintr,
12d43ee5
KM
64};
65
66#define NDCLINE (NDC*4)
67
c74d1258
RC
68extern void dcstart __P((struct tty *));
69extern void dcxint __P((struct tty *));
2c940704 70extern void ttrstrt __P((void *));
12d43ee5
KM
71
72struct tty dc_tty[NDCLINE];
73int dc_cnt = NDCLINE;
60160479
RC
74void (*dcDivertXInput)(); /* X windows keyboard input routine */
75void (*dcMouseEvent)(); /* X windows mouse motion event routine */
76void (*dcMouseButtons)(); /* X windows mouse buttons event routine */
12d43ee5
KM
77#ifdef DEBUG
78int debugChar;
79#endif
80
57373dbf 81static void dcscan __P((void *));
c74d1258
RC
82static int dcMapChar __P((int));
83static void dcKBDReset __P((void));
84static void MouseInit __P((void));
85
12d43ee5
KM
86/*
87 * Software copy of brk register since it isn't readable
88 */
89int dc_brk[NDC];
90char dcsoftCAR[NDC]; /* mask of dc's with carrier on (DSR) */
91
92/*
93 * The DC7085 doesn't interrupt on carrier transitions, so
94 * we have to use a timer to watch it.
95 */
96int dc_timer; /* true if timer started */
97
98/*
99 * Pdma structures for fast output code
100 */
101struct pdma dcpdma[NDCLINE];
102
103struct speedtab dcspeedtab[] = {
104 0, 0,
105 50, LPR_B50,
106 75, LPR_B75,
107 110, LPR_B110,
108 134, LPR_B134,
109 150, LPR_B150,
110 300, LPR_B300,
111 600, LPR_B600,
112 1200, LPR_B1200,
113 1800, LPR_B1800,
114 2400, LPR_B2400,
115 4800, LPR_B4800,
116 9600, LPR_B9600,
84722262
RC
117#ifdef DS5000
118 19200, LPR_B19200,
119#endif
12d43ee5
KM
120 -1, -1
121};
122
123#ifndef PORTSELECTOR
124#define ISPEED TTYDEF_SPEED
125#define LFLAG TTYDEF_LFLAG
126#else
127#define ISPEED B4800
128#define LFLAG (TTYDEF_LFLAG & ~ECHO)
129#endif
130
131/*
132 * Ascii values of command keys.
133 */
134#define KBD_TAB '\t'
135#define KBD_DEL 127
136#define KBD_RET '\r'
137
138/*
139 * Define "hardware-independent" codes for the control, shift, meta and
140 * function keys. Codes start after the last 7-bit ASCII code (127)
141 * and are assigned in an arbitrary order.
142 */
143#define KBD_NOKEY 128
144
145#define KBD_F1 201
146#define KBD_F2 202
147#define KBD_F3 203
148#define KBD_F4 204
149#define KBD_F5 205
150#define KBD_F6 206
151#define KBD_F7 207
152#define KBD_F8 208
153#define KBD_F9 209
154#define KBD_F10 210
155#define KBD_F11 211
156#define KBD_F12 212
157#define KBD_F13 213
158#define KBD_F14 214
159#define KBD_HELP 215
160#define KBD_DO 216
161#define KBD_F17 217
162#define KBD_F18 218
163#define KBD_F19 219
164#define KBD_F20 220
165
166#define KBD_FIND 221
167#define KBD_INSERT 222
168#define KBD_REMOVE 223
169#define KBD_SELECT 224
170#define KBD_PREVIOUS 225
171#define KBD_NEXT 226
172
173#define KBD_KP_ENTER 227
174#define KBD_KP_F1 228
175#define KBD_KP_F2 229
176#define KBD_KP_F3 230
177#define KBD_KP_F4 231
178#define KBD_LEFT 232
179#define KBD_RIGHT 233
180#define KBD_DOWN 234
181#define KBD_UP 235
182
183#define KBD_CONTROL 236
184#define KBD_SHIFT 237
185#define KBD_CAPSLOCK 238
186#define KBD_ALTERNATE 239
187
188/*
189 * Keyboard to Ascii, unshifted.
190 */
191static unsigned char unshiftedAscii[] = {
192/* 0 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
193/* 4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
194/* 8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
195/* c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
196/* 10 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
197/* 14 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
198/* 18 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
199/* 1c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
200/* 20 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
201/* 24 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
202/* 28 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
203/* 2c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
204/* 30 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
205/* 34 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
206/* 38 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
207/* 3c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
208/* 40 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
209/* 44 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
210/* 48 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
211/* 4c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
212/* 50 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
213/* 54 */ KBD_NOKEY, KBD_NOKEY, KBD_F1, KBD_F2,
214/* 58 */ KBD_F3, KBD_F4, KBD_F5, KBD_NOKEY,
215/* 5c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
216/* 60 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
217/* 64 */ KBD_F6, KBD_F7, KBD_F8, KBD_F9,
218/* 68 */ KBD_F10, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
219/* 6c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
220/* 70 */ KBD_NOKEY, '\033', KBD_F12, KBD_F13,
221/* 74 */ KBD_F14, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
222/* 78 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
223/* 7c */ KBD_HELP, KBD_DO, KBD_NOKEY, KBD_NOKEY,
224/* 80 */ KBD_F17, KBD_F18, KBD_F19, KBD_F20,
225/* 84 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
226/* 88 */ KBD_NOKEY, KBD_NOKEY, KBD_FIND, KBD_INSERT,
227/* 8c */ KBD_REMOVE, KBD_SELECT, KBD_PREVIOUS, KBD_NEXT,
228/* 90 */ KBD_NOKEY, KBD_NOKEY, '0', KBD_NOKEY,
229/* 94 */ '.', KBD_KP_ENTER, '1', '2',
230/* 98 */ '3', '4', '5', '6',
231/* 9c */ ',', '7', '8', '9',
232/* a0 */ '-', KBD_KP_F1, KBD_KP_F2, KBD_KP_F3,
233/* a4 */ KBD_KP_F4, KBD_NOKEY, KBD_NOKEY, KBD_LEFT,
234/* a8 */ KBD_RIGHT, KBD_DOWN, KBD_UP, KBD_NOKEY,
235/* ac */ KBD_NOKEY, KBD_NOKEY, KBD_SHIFT, KBD_CONTROL,
236/* b0 */ KBD_CAPSLOCK, KBD_ALTERNATE, KBD_NOKEY, KBD_NOKEY,
237/* b4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
238/* b8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
239/* bc */ KBD_DEL, KBD_RET, KBD_TAB, '`',
240/* c0 */ '1', 'q', 'a', 'z',
241/* c4 */ KBD_NOKEY, '2', 'w', 's',
242/* c8 */ 'x', '<', KBD_NOKEY, '3',
243/* cc */ 'e', 'd', 'c', KBD_NOKEY,
244/* d0 */ '4', 'r', 'f', 'v',
245/* d4 */ ' ', KBD_NOKEY, '5', 't',
246/* d8 */ 'g', 'b', KBD_NOKEY, '6',
247/* dc */ 'y', 'h', 'n', KBD_NOKEY,
248/* e0 */ '7', 'u', 'j', 'm',
249/* e4 */ KBD_NOKEY, '8', 'i', 'k',
250/* e8 */ ',', KBD_NOKEY, '9', 'o',
251/* ec */ 'l', '.', KBD_NOKEY, '0',
252/* f0 */ 'p', KBD_NOKEY, ';', '/',
253/* f4 */ KBD_NOKEY, '=', ']', '\\',
254/* f8 */ KBD_NOKEY, '-', '[', '\'',
255/* fc */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
256};
257
258/*
259 * Keyboard to Ascii, shifted.
260 */
261static unsigned char shiftedAscii[] = {
262/* 0 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
263/* 4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
264/* 8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
265/* c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
266/* 10 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
267/* 14 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
268/* 18 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
269/* 1c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
270/* 20 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
271/* 24 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
272/* 28 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
273/* 2c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
274/* 30 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
275/* 34 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
276/* 38 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
277/* 3c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
278/* 40 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
279/* 44 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
280/* 48 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
281/* 4c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
282/* 50 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
283/* 54 */ KBD_NOKEY, KBD_NOKEY, KBD_F1, KBD_F2,
284/* 58 */ KBD_F3, KBD_F4, KBD_F5, KBD_NOKEY,
285/* 5c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
286/* 60 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
287/* 64 */ KBD_F6, KBD_F7, KBD_F8, KBD_F9,
288/* 68 */ KBD_F10, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
289/* 6c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
290/* 70 */ KBD_NOKEY, KBD_F11, KBD_F12, KBD_F13,
291/* 74 */ KBD_F14, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
292/* 78 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
293/* 7c */ KBD_HELP, KBD_DO, KBD_NOKEY, KBD_NOKEY,
294/* 80 */ KBD_F17, KBD_F18, KBD_F19, KBD_F20,
295/* 84 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
296/* 88 */ KBD_NOKEY, KBD_NOKEY, KBD_FIND, KBD_INSERT,
297/* 8c */ KBD_REMOVE, KBD_SELECT, KBD_PREVIOUS, KBD_NEXT,
298/* 90 */ KBD_NOKEY, KBD_NOKEY, '0', KBD_NOKEY,
299/* 94 */ '.', KBD_KP_ENTER, '1', '2',
300/* 98 */ '3', '4', '5', '6',
301/* 9c */ ',', '7', '8', '9',
302/* a0 */ '-', KBD_KP_F1, KBD_KP_F2, KBD_KP_F3,
303/* a4 */ KBD_KP_F4, KBD_NOKEY, KBD_NOKEY, KBD_LEFT,
304/* a8 */ KBD_RIGHT, KBD_DOWN, KBD_UP, KBD_NOKEY,
305/* ac */ KBD_NOKEY, KBD_NOKEY, KBD_SHIFT, KBD_CONTROL,
306/* b0 */ KBD_CAPSLOCK, KBD_ALTERNATE, KBD_NOKEY, KBD_NOKEY,
307/* b4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
308/* b8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
309/* bc */ KBD_DEL, KBD_RET, KBD_TAB, '~',
310/* c0 */ '!', 'q', 'a', 'z',
311/* c4 */ KBD_NOKEY, '@', 'w', 's',
312/* c8 */ 'x', '>', KBD_NOKEY, '#',
313/* cc */ 'e', 'd', 'c', KBD_NOKEY,
314/* d0 */ '$', 'r', 'f', 'v',
315/* d4 */ ' ', KBD_NOKEY, '%', 't',
316/* d8 */ 'g', 'b', KBD_NOKEY, '^',
317/* dc */ 'y', 'h', 'n', KBD_NOKEY,
318/* e0 */ '&', 'u', 'j', 'm',
319/* e4 */ KBD_NOKEY, '*', 'i', 'k',
320/* e8 */ '<', KBD_NOKEY, '(', 'o',
321/* ec */ 'l', '>', KBD_NOKEY, ')',
322/* f0 */ 'p', KBD_NOKEY, ':', '?',
323/* f4 */ KBD_NOKEY, '+', '}', '|',
324/* f8 */ KBD_NOKEY, '_', '{', '"',
325/* fc */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY,
326};
327
328/*
329 * Keyboard initialization string.
330 */
331static u_char kbdInitString[] = {
332 LK_LED_ENABLE, LED_ALL, /* show we are resetting keyboard */
333 LK_DEFAULTS,
334 LK_CMD_MODE(LK_AUTODOWN, 1),
335 LK_CMD_MODE(LK_AUTODOWN, 2),
336 LK_CMD_MODE(LK_AUTODOWN, 3),
337 LK_CMD_MODE(LK_DOWN, 4), /* could also be LK_AUTODOWN */
338 LK_CMD_MODE(LK_UPDOWN, 5),
339 LK_CMD_MODE(LK_UPDOWN, 6),
340 LK_CMD_MODE(LK_AUTODOWN, 7),
341 LK_CMD_MODE(LK_AUTODOWN, 8),
342 LK_CMD_MODE(LK_AUTODOWN, 9),
343 LK_CMD_MODE(LK_AUTODOWN, 10),
344 LK_CMD_MODE(LK_AUTODOWN, 11),
345 LK_CMD_MODE(LK_AUTODOWN, 12),
346 LK_CMD_MODE(LK_DOWN, 13),
347 LK_CMD_MODE(LK_AUTODOWN, 14),
348 LK_AR_ENABLE, /* we want autorepeat by default */
349 LK_CL_ENABLE, 0x83, /* keyclick, volume */
350 LK_KBD_ENABLE, /* the keyboard itself */
351 LK_BELL_ENABLE, 0x83, /* keyboard bell, volume */
352 LK_LED_DISABLE, LED_ALL, /* clear keyboard leds */
353};
354
355/*
356 * Test to see if device is present.
357 * Return true if found and initialized ok.
358 */
359dcprobe(cp)
360 register struct pmax_ctlr *cp;
361{
362 register dcregs *dcaddr;
363 register struct pdma *pdp;
364 register struct tty *tp;
365 register int cntr;
12d43ee5
KM
366
367 if (cp->pmax_unit >= NDC)
368 return (0);
369 if (badaddr(cp->pmax_addr, 2))
370 return (0);
371
372 /* reset chip */
373 dcaddr = (dcregs *)cp->pmax_addr;
374 dcaddr->dc_csr = CSR_CLR;
375 MachEmptyWriteBuffer();
376 while (dcaddr->dc_csr & CSR_CLR)
377 ;
378 dcaddr->dc_csr = CSR_MSE | CSR_TIE | CSR_RIE;
379
380 /* init pseudo DMA structures */
381 pdp = &dcpdma[cp->pmax_unit * 4];
382 tp = &dc_tty[cp->pmax_unit * 4];
383 for (cntr = 0; cntr < 4; cntr++) {
384 pdp->p_addr = dcaddr;
385 pdp->p_arg = (int)tp;
386 pdp->p_fcn = dcxint;
387 tp->t_addr = (caddr_t)pdp;
388 pdp++, tp++;
389 }
390 dcsoftCAR[cp->pmax_unit] = cp->pmax_flags | 0xB;
391
392 if (dc_timer == 0) {
393 dc_timer = 1;
57373dbf 394 timeout(dcscan, (void *)0, hz);
12d43ee5 395 }
84722262
RC
396 printf("dc%d at nexus0 csr 0x%x priority %d\n",
397 cp->pmax_unit, cp->pmax_addr, cp->pmax_pri);
12d43ee5
KM
398 if (cp->pmax_unit == 0) {
399 int s;
400
401 s = spltty();
402 dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_8_BIT_CHAR |
403 KBD_PORT;
404 dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |
405 LPR_PARENB | LPR_8_BIT_CHAR | MOUSE_PORT;
406 MachEmptyWriteBuffer();
407 dcKBDReset();
408 MouseInit();
409 splx(s);
410 }
411 return (1);
412}
413
c74d1258 414dcopen(dev, flag, mode, p)
12d43ee5 415 dev_t dev;
c74d1258
RC
416 int flag, mode;
417 struct proc *p;
12d43ee5
KM
418{
419 register struct tty *tp;
420 register int unit;
421 int s, error = 0;
422 extern int dcparam();
423
424 unit = minor(dev);
425 if (unit >= dc_cnt || dcpdma[unit].p_addr == 0)
426 return (ENXIO);
427 tp = &dc_tty[unit];
428 tp->t_addr = (caddr_t)&dcpdma[unit];
429 tp->t_oproc = dcstart;
430 tp->t_param = dcparam;
431 tp->t_dev = dev;
432 if ((tp->t_state & TS_ISOPEN) == 0) {
433 tp->t_state |= TS_WOPEN;
434 ttychars(tp);
435#ifndef PORTSELECTOR
436 if (tp->t_ispeed == 0) {
437#endif
438 tp->t_iflag = TTYDEF_IFLAG;
439 tp->t_oflag = TTYDEF_OFLAG;
440 tp->t_cflag = TTYDEF_CFLAG;
441 tp->t_lflag = LFLAG;
442 tp->t_ispeed = tp->t_ospeed = ISPEED;
443#ifdef PORTSELECTOR
444 tp->t_cflag |= HUPCL;
445#else
446 }
447#endif
448 (void) dcparam(tp, &tp->t_termios);
449 ttsetwater(tp);
450 } else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0)
451 return (EBUSY);
452 (void) dcmctl(dev, DML_DTR, DMSET);
453 s = spltty();
454 while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&
455 !(tp->t_state & TS_CARR_ON)) {
456 tp->t_state |= TS_WOPEN;
457 if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
458 ttopen, 0))
459 break;
460 }
461 splx(s);
462 if (error)
463 return (error);
464 return ((*linesw[tp->t_line].l_open)(dev, tp));
465}
466
467/*ARGSUSED*/
c74d1258 468dcclose(dev, flag, mode, p)
12d43ee5 469 dev_t dev;
c74d1258
RC
470 int flag, mode;
471 struct proc *p;
12d43ee5
KM
472{
473 register struct tty *tp;
474 register int unit, bit;
475
476 unit = minor(dev);
477 tp = &dc_tty[unit];
478 bit = 1 << ((unit & 03) + 8);
479 if (dc_brk[unit >> 2] & bit) {
480 dc_brk[unit >> 2] &= ~bit;
481 ttyoutput(0, tp);
482 }
c74d1258 483 (*linesw[tp->t_line].l_close)(tp, flag);
12d43ee5
KM
484 if ((tp->t_cflag & HUPCL) || (tp->t_state & TS_WOPEN) ||
485 !(tp->t_state & TS_ISOPEN))
486 (void) dcmctl(dev, 0, DMSET);
487 return (ttyclose(tp));
488}
489
490dcread(dev, uio, flag)
491 dev_t dev;
492 struct uio *uio;
493{
494 register struct tty *tp;
495
496 tp = &dc_tty[minor(dev)];
497 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
498}
499
500dcwrite(dev, uio, flag)
501 dev_t dev;
502 struct uio *uio;
503{
504 register struct tty *tp;
505
506 tp = &dc_tty[minor(dev)];
507 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
508}
509
12d43ee5 510/*ARGSUSED*/
c74d1258 511dcioctl(dev, cmd, data, flag, p)
12d43ee5
KM
512 dev_t dev;
513 caddr_t data;
c74d1258
RC
514 int flag;
515 struct proc *p;
12d43ee5
KM
516{
517 register struct tty *tp;
518 register int unit = minor(dev);
519 register int dc = unit >> 2;
520 int error;
521
522 tp = &dc_tty[unit];
c74d1258 523 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
12d43ee5
KM
524 if (error >= 0)
525 return (error);
526 error = ttioctl(tp, cmd, data, flag);
527 if (error >= 0)
528 return (error);
529
530 switch (cmd) {
531
532 case TIOCSBRK:
533 dc_brk[dc] |= 1 << ((unit & 03) + 8);
534 ttyoutput(0, tp);
535 break;
536
537 case TIOCCBRK:
538 dc_brk[dc] &= ~(1 << ((unit & 03) + 8));
539 ttyoutput(0, tp);
540 break;
541
542 case TIOCSDTR:
543 (void) dcmctl(dev, DML_DTR|DML_RTS, DMBIS);
544 break;
545
546 case TIOCCDTR:
547 (void) dcmctl(dev, DML_DTR|DML_RTS, DMBIC);
548 break;
549
550 case TIOCMSET:
551 (void) dcmctl(dev, *(int *)data, DMSET);
552 break;
553
554 case TIOCMBIS:
555 (void) dcmctl(dev, *(int *)data, DMBIS);
556 break;
557
558 case TIOCMBIC:
559 (void) dcmctl(dev, *(int *)data, DMBIC);
560 break;
561
562 case TIOCMGET:
563 *(int *)data = dcmctl(dev, 0, DMGET);
564 break;
565
566 default:
567 return (ENOTTY);
568 }
569 return (0);
570}
571
572dcparam(tp, t)
573 register struct tty *tp;
574 register struct termios *t;
575{
576 register dcregs *dcaddr;
577 register int lpr;
578 register int cflag = t->c_cflag;
579 int unit = minor(tp->t_dev);
580 int ospeed = ttspeedtab(t->c_ospeed, dcspeedtab);
581
582 /* check requested parameters */
583 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
584 (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6)
585 return (EINVAL);
586 /* and copy to tty */
587 tp->t_ispeed = t->c_ispeed;
588 tp->t_ospeed = t->c_ospeed;
589 tp->t_cflag = cflag;
590
591 dcaddr = dcpdma[unit].p_addr;
592 if (tp == dc_tty + KBD_PORT) {
593 /* handle the keyboard specially */
594 dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_8_BIT_CHAR |
595 KBD_PORT;
596 MachEmptyWriteBuffer();
597 return (0);
598 }
599 if (tp == dc_tty + MOUSE_PORT) {
600 /* handle the mouse specially */
601 dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |
602 LPR_PARENB | LPR_8_BIT_CHAR | MOUSE_PORT;
603 MachEmptyWriteBuffer();
604 return (0);
605 }
606 if (ospeed == 0) {
607 (void) dcmctl(unit, 0, DMSET); /* hang up line */
608 return (0);
609 }
610 lpr = LPR_RXENAB | ospeed | (unit & 03);
611 if ((cflag & CSIZE) == CS7)
612 lpr |= LPR_7_BIT_CHAR;
613 else
614 lpr |= LPR_8_BIT_CHAR;
615 if (cflag & PARENB)
616 lpr |= LPR_PARENB;
617 if (cflag & PARODD)
618 lpr |= LPR_OPAR;
619 if (cflag & CSTOPB)
620 lpr |= LPR_2_STOP;
621 dcaddr->dc_lpr = lpr;
622 MachEmptyWriteBuffer();
623 return (0);
624}
625
84722262
RC
626/*
627 * Check for interrupts from all devices.
628 */
629void
630dcintr(unit)
631 register int unit;
632{
633 register dcregs *dcaddr;
634 register unsigned csr;
635
636 unit <<= 2;
637 dcaddr = dcpdma[unit].p_addr;
638 while ((csr = dcaddr->dc_csr) & (CSR_RDONE | CSR_TRDY)) {
639 if (csr & CSR_RDONE)
640 dcrint(unit);
641 if (csr & CSR_TRDY)
642 dcxint(&dc_tty[unit + ((csr >> 8) & 03)]);
643 }
644}
645
646dcrint(unit)
647 register int unit;
648{
649 register dcregs *dcaddr;
650 register struct tty *tp;
651 register int c, cc;
652 register struct tty *tp0;
653 int overrun = 0;
654
655 dcaddr = dcpdma[unit].p_addr;
656 tp0 = &dc_tty[unit];
657 while ((c = dcaddr->dc_rbuf) < 0) { /* char present */
658 cc = c & 0xff;
659 tp = tp0 + ((c >> 8) & 03);
660 if ((c & RBUF_OERR) && overrun == 0) {
661 log(LOG_WARNING, "dc%d,%d: silo overflow\n", unit >> 2,
662 (c >> 8) & 03);
663 overrun = 1;
664 }
665 /* the keyboard requires special translation */
666 if (tp == &dc_tty[KBD_PORT]) {
667#ifdef KADB
668 if (cc == LK_DO) {
669 spl0();
670 kdbpanic();
671 return;
672 }
673#endif
674#ifdef DEBUG
675 debugChar = cc;
676#endif
677 if (dcDivertXInput) {
60160479 678 (*dcDivertXInput)(cc);
84722262
RC
679 return;
680 }
681 if ((cc = dcMapChar(cc)) < 0)
682 return;
60160479
RC
683 } else if (tp == &dc_tty[MOUSE_PORT] && dcMouseButtons) {
684 register MouseReport *mrp;
84722262
RC
685 static MouseReport currentRep;
686
60160479
RC
687 mrp = &currentRep;
688 mrp->byteCount++;
84722262
RC
689 if (cc & MOUSE_START_FRAME) {
690 /*
691 * The first mouse report byte (button state).
692 */
60160479
RC
693 mrp->state = cc;
694 if (mrp->byteCount > 1)
695 mrp->byteCount = 1;
696 } else if (mrp->byteCount == 2) {
84722262
RC
697 /*
698 * The second mouse report byte (delta x).
699 */
60160479
RC
700 mrp->dx = cc;
701 } else if (mrp->byteCount == 3) {
84722262
RC
702 /*
703 * The final mouse report byte (delta y).
704 */
60160479
RC
705 mrp->dy = cc;
706 mrp->byteCount = 0;
707 if (mrp->dx != 0 || mrp->dy != 0) {
84722262
RC
708 /*
709 * If the mouse moved,
710 * post a motion event.
711 */
60160479 712 (*dcMouseEvent)(mrp);
84722262 713 }
60160479 714 (*dcMouseButtons)(mrp);
84722262
RC
715 }
716 return;
717 }
718 if (!(tp->t_state & TS_ISOPEN)) {
719 wakeup((caddr_t)&tp->t_rawq);
720#ifdef PORTSELECTOR
721 if (!(tp->t_state & TS_WOPEN))
722#endif
723 return;
724 }
725 if (c & RBUF_FERR)
726 cc |= TTY_FE;
727 if (c & RBUF_PERR)
728 cc |= TTY_PE;
729 (*linesw[tp->t_line].l_rint)(cc, tp);
730 }
731 DELAY(10);
732}
733
024ed1ef 734void
12d43ee5
KM
735dcxint(tp)
736 register struct tty *tp;
737{
738 register struct pdma *dp;
739 register dcregs *dcaddr;
740
741 dp = (struct pdma *)tp->t_addr;
742 if (dp->p_mem < dp->p_end) {
743 dcaddr = dp->p_addr;
744 dcaddr->dc_tdr = dc_brk[(tp - dc_tty) >> 2] | *dp->p_mem++;
745 MachEmptyWriteBuffer();
746 DELAY(10);
747 return;
748 }
749 tp->t_state &= ~TS_BUSY;
750 if (tp->t_state & TS_FLUSH)
751 tp->t_state &= ~TS_FLUSH;
752 else {
753 ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
754 dp->p_end = dp->p_mem = tp->t_outq.c_cf;
755 }
756 if (tp->t_line)
757 (*linesw[tp->t_line].l_start)(tp);
758 else
759 dcstart(tp);
760 if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) {
761 dp->p_addr->dc_tcr &= ~(1 << (minor(tp->t_dev) & 03));
762 MachEmptyWriteBuffer();
763 DELAY(10);
764 }
765}
766
024ed1ef 767void
12d43ee5
KM
768dcstart(tp)
769 register struct tty *tp;
770{
771 register struct pdma *dp;
772 register dcregs *dcaddr;
773 register int cc;
774 int s;
775
776 dp = (struct pdma *)tp->t_addr;
777 dcaddr = dp->p_addr;
778 s = spltty();
779 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
780 goto out;
781 if (tp->t_outq.c_cc <= tp->t_lowat) {
782 if (tp->t_state & TS_ASLEEP) {
783 tp->t_state &= ~TS_ASLEEP;
784 wakeup((caddr_t)&tp->t_outq);
785 }
86e31fc2 786 selwakeup(&tp->t_wsel);
12d43ee5
KM
787 }
788 if (tp->t_outq.c_cc == 0)
789 goto out;
790 /* handle console specially */
791 if (tp == dc_tty) {
792 while (tp->t_outq.c_cc > 0) {
793 cc = getc(&tp->t_outq) & 0x7f;
60160479 794 cnputc(cc);
12d43ee5
KM
795 }
796 /*
797 * After we flush the output queue we may need to wake
798 * up the process that made the output.
799 */
800 if (tp->t_outq.c_cc <= tp->t_lowat) {
801 if (tp->t_state & TS_ASLEEP) {
802 tp->t_state &= ~TS_ASLEEP;
803 wakeup((caddr_t)&tp->t_outq);
804 }
86e31fc2 805 selwakeup(&tp->t_wsel);
12d43ee5
KM
806 }
807 goto out;
808 }
809 if (tp->t_flags & (RAW|LITOUT))
810 cc = ndqb(&tp->t_outq, 0);
811 else {
812 cc = ndqb(&tp->t_outq, 0200);
813 if (cc == 0) {
814 cc = getc(&tp->t_outq);
57373dbf 815 timeout(ttrstrt, (void *)tp, (cc & 0x7f) + 6);
12d43ee5
KM
816 tp->t_state |= TS_TIMEOUT;
817 goto out;
818 }
819 }
820 tp->t_state |= TS_BUSY;
821 dp->p_end = dp->p_mem = tp->t_outq.c_cf;
822 dp->p_end += cc;
823 dcaddr->dc_tcr |= 1 << (minor(tp->t_dev) & 03);
824 MachEmptyWriteBuffer();
825out:
826 splx(s);
827}
828
829/*
830 * Stop output on a line.
831 */
832/*ARGSUSED*/
833dcstop(tp, flag)
834 register struct tty *tp;
835{
836 register struct pdma *dp;
837 register int s;
838
839 dp = (struct pdma *)tp->t_addr;
840 s = spltty();
841 if (tp->t_state & TS_BUSY) {
842 dp->p_end = dp->p_mem;
843 if (!(tp->t_state & TS_TTSTOP))
844 tp->t_state |= TS_FLUSH;
845 }
846 splx(s);
847}
848
849dcmctl(dev, bits, how)
850 dev_t dev;
851 int bits, how;
852{
853 register dcregs *dcaddr;
854 register int unit, mbits;
855 int b, s;
84722262
RC
856#ifdef DS5000
857 register int msr;
858#endif
12d43ee5
KM
859
860 unit = minor(dev);
861 b = 1 << (unit & 03);
862 dcaddr = dcpdma[unit].p_addr;
863 s = spltty();
864 /* only channel 2 has modem control (what about line 3?) */
84722262
RC
865 switch (unit & 03) {
866 case 2:
12d43ee5
KM
867 mbits = 0;
868 if (dcaddr->dc_tcr & TCR_DTR2)
869 mbits |= DML_DTR;
84722262 870#ifdef DS3100
12d43ee5
KM
871 if (dcaddr->dc_msr & MSR_DSR2)
872 mbits |= DML_DSR | DML_CAR;
84722262
RC
873#endif
874#ifdef DS5000
875 msr = dcaddr->dc_msr;
876 if (msr & MSR_CD2)
877 mbits |= DML_CAR;
878 if (msr & MSR_DSR2)
879 mbits |= DML_DSR;
880#endif
881 break;
882
883#ifdef DS5000
884 case 3:
885 mbits = 0;
886 if (dcaddr->dc_tcr & TCR_DTR3)
887 mbits |= DML_DTR;
888 msr = dcaddr->dc_msr;
889 if (msr & MSR_CD3)
890 mbits |= DML_CAR;
891 if (msr & MSR_DSR3)
892 mbits |= DML_DSR;
893 break;
894#endif
895
896 default:
12d43ee5 897 mbits = DML_DTR | DML_DSR | DML_CAR;
84722262 898 }
12d43ee5
KM
899 switch (how) {
900 case DMSET:
901 mbits = bits;
902 break;
903
904 case DMBIS:
905 mbits |= bits;
906 break;
907
908 case DMBIC:
909 mbits &= ~bits;
910 break;
911
912 case DMGET:
913 (void) splx(s);
914 return (mbits);
915 }
84722262
RC
916 switch (unit & 03) {
917 case 2:
12d43ee5
KM
918 if (mbits & DML_DTR)
919 dcaddr->dc_tcr |= TCR_DTR2;
920 else
921 dcaddr->dc_tcr &= ~TCR_DTR2;
84722262
RC
922 break;
923
924#ifdef DS5000
925 case 3:
926 if (mbits & DML_DTR)
927 dcaddr->dc_tcr |= TCR_DTR3;
928 else
929 dcaddr->dc_tcr &= ~TCR_DTR3;
930#endif
12d43ee5
KM
931 }
932 if ((mbits & DML_DTR) && (dcsoftCAR[unit >> 2] & b))
933 dc_tty[unit].t_state |= TS_CARR_ON;
934 (void) splx(s);
935 return (mbits);
936}
937
938/*
939 * This is called by timeout() periodically.
940 * Check to see if modem status bits have changed.
941 */
57373dbf 942/* ARGSUSED */
c74d1258 943static void
57373dbf
RC
944dcscan(arg)
945 void *arg;
12d43ee5
KM
946{
947 register dcregs *dcaddr;
948 register struct tty *tp;
949 register int i, bit, car;
950 int s;
951
952 s = spltty();
953 /* only channel 2 has modem control (what about line 3?) */
954 dcaddr = dcpdma[i = 2].p_addr;
955 tp = &dc_tty[i];
956 bit = TCR_DTR2;
957 if (dcsoftCAR[i >> 2] & bit)
958 car = 1;
959 else
960 car = dcaddr->dc_msr & MSR_DSR2;
961 if (car) {
962 /* carrier present */
963 if (!(tp->t_state & TS_CARR_ON))
964 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
965 } else if ((tp->t_state & TS_CARR_ON) &&
966 (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
967 dcaddr->dc_tcr &= ~bit;
968 splx(s);
57373dbf 969 timeout(dcscan, (void *)0, hz);
12d43ee5
KM
970}
971
972/*
973 * ----------------------------------------------------------------------------
974 *
975 * dcKBDPutc --
976 *
977 * Put a character out to the keyboard.
978 *
979 * Results:
980 * None.
981 *
982 * Side effects:
983 * A character is written to the keyboard.
984 *
985 * ----------------------------------------------------------------------------
986 */
987void
988dcKBDPutc(c)
989 register int c;
990{
991 register dcregs *dcaddr;
992 register u_short tcr;
993 register int timeout;
994 int s, line;
995
996 s = spltty();
997
998 dcaddr = dcpdma[KBD_PORT].p_addr;
999 tcr = dcaddr->dc_tcr;
1000 dcaddr->dc_tcr = tcr | (1 << KBD_PORT);
1001 MachEmptyWriteBuffer();
1002 DELAY(10);
1003 while (1) {
1004 /*
1005 * Wait for transmitter to be not busy.
1006 */
1007 timeout = 1000000;
1008 while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
1009 timeout--;
1010 if (timeout == 0) {
1011 printf("dcKBDPutc: timeout waiting for CSR_TRDY\n");
1012 break;
1013 }
1014 line = (dcaddr->dc_csr >> 8) & 3;
1015 /*
1016 * Check to be sure its the right port.
1017 */
1018 if (line != KBD_PORT) {
1019 tcr |= 1 << line;
1020 dcaddr->dc_tcr &= ~(1 << line);
1021 MachEmptyWriteBuffer();
1022 DELAY(10);
1023 continue;
1024 }
1025 /*
1026 * Start sending the character.
1027 */
1028 dcaddr->dc_tdr = dc_brk[0] | (c & 0xff);
1029 MachEmptyWriteBuffer();
1030 DELAY(10);
1031 /*
1032 * Wait for character to be sent.
1033 */
1034 while (1) {
1035 /*
1036 * cc -O bug: this code produces and infinite loop!
1037 * while (!(dcaddr->dc_csr & CSR_TRDY))
1038 * ;
1039 */
1040 timeout = 1000000;
1041 while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
1042 timeout--;
1043 line = (dcaddr->dc_csr >> 8) & 3;
1044 if (line != KBD_PORT) {
1045 tcr |= 1 << line;
1046 dcaddr->dc_tcr &= ~(1 << line);
1047 MachEmptyWriteBuffer();
1048 DELAY(10);
1049 continue;
1050 }
1051 dcaddr->dc_tcr &= ~(1 << KBD_PORT);
1052 MachEmptyWriteBuffer();
1053 DELAY(10);
1054 break;
1055 }
1056 break;
1057 }
1058 /*
1059 * Enable interrupts for other lines which became ready.
1060 */
1061 if (tcr & 0xF) {
1062 dcaddr->dc_tcr = tcr;
1063 MachEmptyWriteBuffer();
1064 DELAY(10);
1065 }
1066
1067 splx(s);
1068}
1069
1070#ifdef DEBUG
1071/*
1072 * ----------------------------------------------------------------------------
1073 *
84722262 1074 * dcDebugGetc --
12d43ee5 1075 *
84722262 1076 * Read a character from the keyboard if one is ready (i.e., don't wait).
12d43ee5
KM
1077 *
1078 * Results:
1079 * A character read from the mouse, -1 if none were ready.
1080 *
1081 * Side effects:
1082 * None.
1083 *
1084 * ----------------------------------------------------------------------------
1085 */
1086int
84722262 1087dcDebugGetc()
12d43ee5
KM
1088{
1089 register dcregs *dcaddr;
1090 register int c;
c74d1258 1091 int s;
12d43ee5
KM
1092
1093 dcaddr = dcpdma[KBD_PORT].p_addr;
1094 if (!dcaddr)
1095 return (0);
c74d1258
RC
1096
1097 s = spltty();
12d43ee5
KM
1098 if (c = debugChar)
1099 debugChar = 0;
1100 else {
1101 while (dcaddr->dc_csr & CSR_RDONE) {
1102 c = dcaddr->dc_rbuf;
1103 DELAY(10);
1104 if (((c >> 8) & 03) == KBD_PORT)
1105 break;
1106 c = 0;
1107 }
1108 }
c74d1258
RC
1109 splx(s);
1110
12d43ee5
KM
1111 return (c & 0xff);
1112}
1113#endif
1114
84722262
RC
1115/*
1116 * ----------------------------------------------------------------------------
1117 *
1118 * dcKBDGetc --
1119 *
1120 * Read a character from the keyboard.
1121 *
1122 * Results:
1123 * A character read from the keyboard.
1124 *
1125 * Side effects:
1126 * None.
1127 *
1128 * ----------------------------------------------------------------------------
1129 */
1130int
1131dcKBDGetc()
1132{
1133 register dcregs *dcaddr;
1134 register int c;
1135 int s;
1136
1137 dcaddr = dcpdma[KBD_PORT].p_addr;
1138 if (!dcaddr)
1139 return (-1);
1140 s = spltty();
1141 for (;;) {
1142 if (!(dcaddr->dc_csr & CSR_RDONE))
1143 continue;
1144 c = dcaddr->dc_rbuf;
1145 DELAY(10);
1146 if (((c >> 8) & 03) != KBD_PORT)
1147 continue;
1148 if ((c = dcMapChar(c & 0xff)) >= 0)
1149 break;
1150 }
1151 splx(s);
1152 return (c);
1153}
1154
1155/*
1156 * ----------------------------------------------------------------------------
1157 *
1158 * dcMapChar --
1159 *
1160 * Map characters from the keyboard to ASCII. Return -1 if there is
1161 * no valid mapping.
1162 *
1163 * Results:
1164 * None.
1165 *
1166 * Side effects:
1167 * Remember state of shift and control keys.
1168 *
1169 * ----------------------------------------------------------------------------
1170 */
1171static int
1172dcMapChar(cc)
1173 int cc;
1174{
1175 static u_char shiftDown;
1176 static u_char ctrlDown;
1177 static u_char lastChar;
1178
1179 switch (cc) {
1180 case KEY_REPEAT:
1181 cc = lastChar;
1182 goto done;
1183
1184 case KEY_UP:
1185 shiftDown = 0;
1186 ctrlDown = 0;
1187 return (-1);
1188
1189 case KEY_SHIFT:
1190 if (ctrlDown)
1191 shiftDown = 0;
1192 else
1193 shiftDown = 1;
1194 return (-1);
1195
1196 case KEY_CONTROL:
1197 if (shiftDown)
1198 ctrlDown = 0;
1199 else
1200 ctrlDown = 1;
1201 return (-1);
1202
1203 case LK_POWER_ERROR:
1204 case LK_KDOWN_ERROR:
1205 case LK_INPUT_ERROR:
1206 case LK_OUTPUT_ERROR:
1207 log(LOG_WARNING,
1208 "dc0,0: keyboard error, code=%x\n", cc);
1209 return (-1);
1210 }
1211 if (shiftDown)
1212 cc = shiftedAscii[cc];
1213 else
1214 cc = unshiftedAscii[cc];
1215 if (cc >= KBD_NOKEY) {
1216 /*
1217 * A function key was typed - ignore it.
1218 */
1219 return (-1);
1220 }
1221 if (cc >= 'a' && cc <= 'z') {
1222 if (ctrlDown)
1223 cc = cc - 'a' + '\1'; /* ^A */
1224 else if (shiftDown)
1225 cc = cc - 'a' + 'A';
1226 } else if (ctrlDown) {
1227 if (cc >= '[' && cc <= '_')
1228 cc = cc - '@';
1229 else if (cc == ' ' || cc == '@')
1230 cc = '\0';
1231 }
1232 lastChar = cc;
1233done:
1234 return (cc);
1235}
1236
12d43ee5
KM
1237/*
1238 * ----------------------------------------------------------------------------
1239 *
1240 * dcKBDReset --
1241 *
1242 * Reset the keyboard to default characteristics.
1243 *
1244 * Results:
1245 * None.
1246 *
1247 * Side effects:
1248 * None.
1249 *
1250 * ----------------------------------------------------------------------------
1251 */
1252void
1253dcKBDReset()
1254{
1255 register int i;
1256 static int inKBDReset;
1257
1258 if (inKBDReset)
1259 return;
1260 inKBDReset = 1;
1261 for (i = 0; i < sizeof(kbdInitString); i++)
1262 dcKBDPutc((int)kbdInitString[i]);
1263 inKBDReset = 0;
1264}
1265
1266/*
1267 * ----------------------------------------------------------------------------
1268 *
1269 * MousePutc --
1270 *
1271 * Write a character to the mouse.
1272 * This is only called at initialization time.
1273 *
1274 * Results:
1275 * None.
1276 *
1277 * Side effects:
1278 * A character is written to the mouse.
1279 *
1280 * ----------------------------------------------------------------------------
1281 */
1282static void
1283MousePutc(c)
1284 int c;
1285{
1286 register dcregs *dcaddr;
1287 register u_short tcr;
1288 register int timeout;
1289 int line;
1290
1291 dcaddr = dcpdma[MOUSE_PORT].p_addr;
1292 tcr = dcaddr->dc_tcr;
1293 dcaddr->dc_tcr = tcr | (1 << MOUSE_PORT);
1294 MachEmptyWriteBuffer();
1295 DELAY(10);
1296 while (1) {
1297 /*
1298 * Wait for transmitter to be not busy.
1299 */
1300 timeout = 1000000;
1301 while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
1302 timeout--;
1303 if (timeout == 0) {
1304 printf("MousePutc: timeout waiting for CSR_TRDY\n");
1305 break;
1306 }
1307 line = (dcaddr->dc_csr >> 8) & 3;
1308 /*
1309 * Check to be sure its the right port.
1310 */
1311 if (line != MOUSE_PORT) {
1312 tcr |= 1 << line;
1313 dcaddr->dc_tcr &= ~(1 << line);
1314 MachEmptyWriteBuffer();
1315 DELAY(10);
1316 continue;
1317 }
1318 /*
1319 * Start sending the character.
1320 */
1321 dcaddr->dc_tdr = dc_brk[0] | (c & 0xff);
1322 MachEmptyWriteBuffer();
1323 DELAY(10);
1324 /*
1325 * Wait for character to be sent.
1326 */
1327 while (1) {
1328 /*
1329 * cc -O bug: this code produces and infinite loop!
1330 * while (!(dcaddr->dc_csr & CSR_TRDY))
1331 * ;
1332 */
1333 timeout = 1000000;
1334 while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
1335 timeout--;
1336 line = (dcaddr->dc_csr >> 8) & 3;
1337 if (line != MOUSE_PORT) {
1338 tcr |= 1 << line;
1339 dcaddr->dc_tcr &= ~(1 << line);
1340 MachEmptyWriteBuffer();
1341 DELAY(10);
1342 continue;
1343 }
1344 dcaddr->dc_tcr &= ~(1 << MOUSE_PORT);
1345 MachEmptyWriteBuffer();
1346 DELAY(10);
1347 break;
1348 }
1349 break;
1350 }
1351 /*
1352 * Enable interrupts for other lines which became ready.
1353 */
1354 if (tcr & 0xF) {
1355 dcaddr->dc_tcr = tcr;
1356 MachEmptyWriteBuffer();
1357 DELAY(10);
1358 }
1359}
1360
1361/*
1362 * ----------------------------------------------------------------------------
1363 *
1364 * MouseGetc --
1365 *
1366 * Read a character from the mouse.
1367 * This is only called at initialization time.
1368 *
1369 * Results:
1370 * A character read from the mouse, -1 if we timed out waiting.
1371 *
1372 * Side effects:
1373 * None.
1374 *
1375 * ----------------------------------------------------------------------------
1376 */
1377static int
1378MouseGetc()
1379{
1380 register dcregs *dcaddr;
1381 register int timeout;
1382 register int c;
1383
1384 dcaddr = dcpdma[MOUSE_PORT].p_addr;
1385 for (timeout = 1000000; timeout > 0; timeout--) {
1386 if (!(dcaddr->dc_csr & CSR_RDONE))
1387 continue;
1388 c = dcaddr->dc_rbuf;
1389 DELAY(10);
1390 if (((c >> 8) & 03) != MOUSE_PORT)
1391 continue;
1392 return (c & 0xff);
1393 }
1394
1395 return (-1);
1396}
1397
1398/*
1399 * ----------------------------------------------------------------------------
1400 *
1401 * MouseInit --
1402 *
1403 * Initialize the mouse.
1404 *
1405 * Results:
1406 * None.
1407 *
1408 * Side effects:
1409 * None.
1410 *
1411 * ----------------------------------------------------------------------------
1412 */
1413static void
1414MouseInit()
1415{
1416 int id_byte1, id_byte2, id_byte3, id_byte4;
1417
1418 /*
1419 * Initialize the mouse.
1420 */
1421 MousePutc(MOUSE_SELF_TEST);
1422 id_byte1 = MouseGetc();
1423 if (id_byte1 < 0) {
1424 printf("MouseInit: Timeout on 1st byte of self-test report\n");
1425 return;
1426 }
1427 id_byte2 = MouseGetc();
1428 if (id_byte2 < 0) {
1429 printf("MouseInit: Timeout on 2nd byte of self-test report\n");
1430 return;
1431 }
1432 id_byte3 = MouseGetc();
1433 if (id_byte3 < 0) {
1434 printf("MouseInit: Timeout on 3rd byte of self-test report\n");
1435 return;
1436 }
1437 id_byte4 = MouseGetc();
1438 if (id_byte4 < 0) {
1439 printf("MouseInit: Timeout on 4th byte of self-test report\n");
1440 return;
1441 }
1442 if ((id_byte2 & 0x0f) != 0x2)
1443 printf("MouseInit: We don't have a mouse!!!\n");
1444 /*
1445 * For some reason, the mouse doesn't see this command if it comes
1446 * too soon after a self test.
1447 */
1448 DELAY(100);
1449 MousePutc(MOUSE_INCREMENTAL);
1450}
1451#endif /* NDC */