|
|
1.1 root 1: /*
2: * io.386/vtkb_d.c
3: *
4: * Keyboard driver, virtual consoles, no loadable tables, German.
5: *
6: * Revised: Fri Jul 16 08:39:12 1993 CDT
7: */
8:
9: #include <sys/coherent.h>
10: #include <sys/reg.h>
11: #include <sys/con.h>
12: #include <sys/devices.h>
13: #include <sys/errno.h>
14: #include <sys/stat.h>
15: #include <sys/tty.h>
16: #include <signal.h>
17: #include <sys/sched.h>
18: #include <sys/silo.h>
19: #include <sys/kb.h>
20: #include <sys/vt.h>
21:
22: #define ISVEC 1 /* Keyboard interrupt vector */
23: #define DEBUG 0
24:
25: #define SPC 0376 /* Special encoding */
26: #define XXX 0377 /* Non-character */
27: #define KBDATA 0x60 /* Keyboard data */
28: #define KBCTRL 0x61 /* Keyboard control */
29: #define KBFLAG 0x80 /* Keyboard reset flag */
30: #define LEDCMD 0xED /* status indicator command */
31: #define KBACK 0xFA /* status indicator acknowledge */
32: #define EXTENDED0 0xE0 /* extended key seq initiator */
33: #define EXTENDED1 0xE1 /* extended key seq initiator */
34:
35: #define KEYUP 0x80 /* Key up change */
36: #define KEYSC 0x7F /* Key scan code mask */
37: #define LSHIFT 0x2A-1 /* Left shift key */
38: #define LSHIFTA 0x2B-1 /* Alternate left-shift key */
39: #define RSHIFT 0x36-1 /* Right shift key */
40: #define CTRLkb 0x1D-1 /* Control key */
41: /*-- #define CAPLOCK 0x1D-1 --*/ /* Control key */
42: #define ALTkb 0x38-1 /* Alt key or ALT GR */
43: #define CAPLOCK 0x3A-1 /* Caps lock key */
44: /*-- #define CTRL 0x3A-1 --*/ /* Caps lock key */
45: #define NUMLOCK 0x45-1 /* Numeric lock key */
46: #define DELETE 0x53-1 /* Del, as in CTRL-ALT-DEL */
47: #define BACKSP 0x0E-1 /* Back space */
48: #define SCRLOCK 0x46-1 /* Scroll lock */
49:
50: /* Shift flags */
51: #define SRS 0x01 /* Right shift key on */
52: #define SLS 0x02 /* Left shift key on */
53: #define CTS 0x04 /* Ctrl key on */
54: #define ALS 0x08 /* Alt key on */
55: #define CPLS 0x10 /* Caps lock on */
56: #define NMLS 0x20 /* Num lock on */
57: #define AKPS 0x40 /* Alternate keypad shift */
58: #define SHFT 0x80 /* Shift key flag */
59: #define AGS 0x100 /* Alt Graphics on */
60:
61: /* Function key information */
62: #define NFKEY 50 /* Number of settable functions */
63: #define NFCHAR 150 /* Number of characters settable */
64: #define NFBUF (NFKEY*2+NFCHAR+1) /* Size of buffer */
65:
66: #define ESCAPE_CHAR '\x1B'
67: #define ESCAPE_STRING "\x1B"
68: #define HEXFF_STRING "\xFF"
69: #define DELETE_STRING "\x7F"
70:
71: /*
72: * Functions.
73: */
74: int isrint();
75: int istime();
76: void isbatch();
77: int mmstart();
78: int isopen();
79: int isclose();
80: int isread();
81: int mmwrite();
82: int isioctl();
83: void mmwatch();
84: int isload();
85: int isuload();
86: int ispoll();
87: int nulldev();
88: int nonedev();
89:
90: /*
91: * Configuration table.
92: */
93: CON iscon ={
94: DFCHR|DFPOL, /* Flags */
95: KB_MAJOR, /* Major index */
96: isopen, /* Open */
97: isclose, /* Close */
98: nulldev, /* Block */
99: isread, /* Read */
100: mmwrite, /* Write */
101: isioctl, /* Ioctl */
102: nulldev, /* Powerfail */
103: mmwatch, /* Timeout */
104: isload, /* Load */
105: isuload, /* Unload */
106: ispoll /* Poll */
107: };
108:
109: /*
110: * Flag indicating turbo machine.
111: */
112: int isturbo = 0;
113:
114: /*
115: ==============================================================================
116: ==============================================================================
117: */
118: /* constants for vtdata[] */
119: #define VT_VGAPORT 0x3D4
120: #define VT_MONOPORT 0x3B4
121:
122: #define VT_MONOBASE (SEG_VIDEOa|DPL_1)
123: #define VT_VGABASE (SEG_VIDEOb|DPL_1)
124:
125: /*
126: Patchable table entrys,
127: we go indirect in order to produce a label which can be addressed
128: */
129: HWentry VTVGA = { 4, 0, VT_VGAPORT, { 0, VT_VGABASE }, { 25, 80 } };
130: HWentry VTMONO = { 4, 0, VT_MONOPORT, { 0, VT_MONOBASE }, { 25, 80 } };
131:
132: HWentry *vtHWtable[] = {
133: VTVGA, /* VGA followed by MONO is compatible to DOS */
134: VTMONO,
135: 0 /* MUST STAY AS LAST ELEMENT !!! */
136: };
137:
138: extern int mminit();
139: static VTDATA const_vtdata = {
140: mminit, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 23, 24, 0, 0, 0, 23, 0, 0, 1
141: };
142:
143: /* later this should be dynamic */
144: VTDATA *vtconsole, **vtdata;
145:
146: int vtcount, vtmax;
147: extern int vtactive;
148: int vt_verbose = { 0 };
149: int vt_opened = { 0 };
150:
151: /* Terminal structure. */
152: TTY **vttty;
153:
154: /*
155: ==============================================================================
156: ==============================================================================
157: */
158:
159: static silo_t in_silo;
160:
161: /*
162: * State variables.
163: */
164: int islock; /* Keyboard locked flag */
165: int isbusy; /* Raw input conversion busy */
166: static unsigned shift; /* Overall shift state */
167: static char scrollkb; /* Scroll lock state */
168: static char lshiftkb = LSHIFT; /* Left shift alternate state */
169: static char isfbuf[NFBUF]; /* Function key values */
170: static char *isfval[NFKEY]; /* Function key string pointers */
171: static int ledcmd; /* LED update command flag */
172: static int extended; /* extended key scan count */
173: static char extmode; /* use extended mode for this key */
174: static char ext0seen; /* 0xE0 prefix seen */
175: static char fk_loaded; /* true == funcion keys resident */
176: static int xlate =1; /* scan code translation flag */
177:
178: /*
179: * Tables for converting key code to ASCII.
180: * lmaptab specifies unshifted conversion,
181: * umaptab specifies shifted conversion,
182: * smaptab specifies the shift states which are active.
183: * An entry of XXX says the key is dead.
184: * An entry of SPC requires further processing.
185: *
186: * Key codes:
187: * ESC .. <- == 1 .. 14
188: * -> .. \n == 15 .. 28
189: * CTRL .. ` == 29 .. 41
190: * ^Shift .. PrtSc == 42 .. 55
191: * ALT .. CapsLock == 56 .. 58
192: * F1 .. F10 == 59 .. 68
193: * NumLock .. Del == 69 .. 83
194: * ISO, F11, F12 == 86 .. 88
195: */
196: unsigned char agmaptab[] ={ /* Alt Gr */
197: XXX, XXX,'\375','\374',XXX, XXX, XXX, /* 1 - 7 */
198: '{', '[', ']', '}', '\\', XXX, XXX, XXX, /* 8 - 15 */
199: '@', XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 16 - 23 */
200: XXX, XXX, XXX, '~', XXX, XXX, XXX, XXX, /* 24 - 31 */
201: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 32 - 39 */
202: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 40 - 47 */
203: XXX, XXX,'\346', XXX, XXX, XXX, XXX, XXX, /* 48 - 55 */
204: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 56 - 63 */
205: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 64 - 71 */
206: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 72 - 79 */
207: XXX, XXX, XXX, XXX, XXX, XXX, '|', XXX, /* 80 - 87 */
208: XXX /* 88 */
209: };
210:
211: static unsigned char lmaptab[] ={
212: ESCAPE_CHAR, '1', '2', '3', '4', '5', '6', /* 1 - 7 */
213: '7', '8', '9', '0','\341','\'', '\b', '\t', /* 8 - 15 */
214: 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* 16 - 23 */
215: 'o', 'p','\201', '+', '\r', XXX, 'a', 's', /* 24 - 31 */
216: 'd', 'f', 'g', 'h', 'j', 'k', 'l','\224', /* 32 - 39 */
217: '\204','^', XXX, '#', 'y', 'x', 'c', 'v', /* 40 - 47 */
218: 'b', 'n', 'm', ',', '.', SPC, XXX, SPC, /* 48 - 55 */
219: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
220: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
221: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
222: SPC, SPC, SPC, SPC, XXX, XXX, '<', XXX, /* 80 - 87 */
223: XXX /* 88 */
224: };
225:
226: static unsigned char umaptab[] ={
227: ESCAPE_CHAR, '!', '"','\025', '$', '%', '&', /* 1 - 7 */
228: '/', '(', ')', '=', '?', '`', '\b', SPC, /* 8 - 15 */
229: 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* 16 - 23 */
230: 'O', 'P','\232', '*', '\r', XXX, 'A', 'S', /* 24 - 31 */
231: 'D', 'F', 'G', 'H', 'J', 'K', 'L','\231', /* 32 - 39 */
232: '\216','\370',XXX,'\'', 'Y', 'X', 'C', 'V', /* 40 - 47 */
233: 'B', 'N', 'M', ';', ':', SPC, XXX, SPC, /* 48 - 55 */
234: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
235: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
236: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
237: SPC, SPC, SPC, SPC, XXX, XXX, '>', XXX, /* 80 - 87 */
238: XXX /* 88 */
239: };
240:
241: #define SS0 0 /* No shift */
242: #define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */
243: #define SES (SLS|SRS) /* Shift */
244: #define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */
245: #define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */
246:
247: static unsigned char smaptab[] ={
248: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */
249: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */
250: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */
251: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */
252: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */
253: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */
254: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */
255: SHFT, SS1, SHFT, SS1, SS1, SS1, SS1, SS1, /* 56 - 63 */
256: SS1, SS1, SS1, SS1, SS1, SHFT, KEY, KEY, /* 64 - 71 */
257: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */
258: KEY, KEY, KEY, KEY, SS0, SS0, SES, SS0, /* 80 - 87 */
259: SS0
260: };
261:
262: /*
263: * Load entry point.
264: * Do reset the keyboard because it gets terribly munged
265: * if you type during the boot.
266: */
267: isload()
268: {
269: register short i; /* was: int i */
270: register HWentry **hw;
271: register VTDATA *vp;
272:
273: /*
274: * Reset keyboard if NOT an XT turbo.
275: */
276: if ( ! isturbo ) {
277: outb(KBCTRL, 0x0C); /* Clock low */
278: for (i = 10582; --i >= 0; ); /* For 20ms */
279: outb(KBCTRL, 0xCC); /* Clock high */
280: for (i = 0; --i != 0; )
281: ;
282: i = inb(KBDATA);
283: outb(KBCTRL, 0xCC); /* Clear keyboard */
284: outb(KBCTRL, 0x4D); /* Enable keyboard */
285: }
286:
287: PRINTV("vtload:\n");
288: fk_loaded = 0;
289:
290: /* figure out what our current max is */
291: for( vtmax = 0, hw = vtHWtable; *hw; ++hw ) {
292: vtmax += (*hw)->count;
293: (*hw)->found = 0; /* assume non-exist */
294: }
295: PRINTV( "vtload: %d screens possible\n", vtmax );
296:
297: vtdata = (VTDATA **) kalloc( vtmax * sizeof( *vtdata ) );
298: if( vtdata == NULL ) {
299: printf( "vtload: unable to obtain vtdata[%d]\n", vtmax );
300: u.u_error = -1;
301: return;
302: }
303: PRINTV( "vtload: obtained vtdata[%d] @%x\n", vtmax, vtdata );
304:
305: vttty = (TTY **) kalloc( vtmax * sizeof( *vttty ) );
306: if( vttty == NULL ) {
307: printf( "vtload: unable to obtain vttty[%d]\n", vtmax );
308: u.u_error = -1;
309: return;
310: }
311: PRINTV( "vtload: obtained vttty[%d] @%x\n", vtmax, vttty );
312:
313: /* determine which video adaptors are present */
314: for( vtcount = 0, hw = vtHWtable; *hw; ++hw ) {
315: /* remember our logical start */
316: (*hw)->start = vtcount;
317: PRINTV( ", start %d\n", vtcount );
318:
319: /* allocate the necessary memory */
320: for ( i = 0; i < (*hw)->count; ++i ) {
321: vp = vtdata[vtcount] = kalloc( sizeof(VTDATA) );
322: PRINTV( " vtdata[%d] = @%x\n", vtcount, vp );
323: if( vp == NULL || !VTttyinit(vtcount) ) {
324: printf("not enough memory for VTDATA\n" );
325: break;
326: }
327:
328: /* fill in appropriately */
329: *vp = const_vtdata;
330: vp->vmm_port = (*hw)->port;
331: vp->vmm_vseg = (*hw)->vidmemory.seg;
332: vp->vmm_voff = (*hw)->vidmemory.off;
333:
334: vp->vt_ind = vtcount;
335: vtdatainit(vp);
336: if (i == 0 ) {
337: vp->vmm_visible = VNKB_TRUE;
338: vp->vmm_seg = vp->vmm_vseg;
339: vp->vmm_off = vp->vmm_voff;
340: updscreen(vtcount);
341: }
342: (*hw)->found++;
343: vtcount++;
344: }
345: }
346:
347: /*
348: * initialize vtconsole
349: */
350: vtconsole = vtdata[vtactive = 0];
351: vtconsole->vmm_invis = 0; /* vtconsole cursor visible */
352:
353: /*
354: * Seize keyboard interrupt.
355: */
356: #ifdef _I386
357: setivec(ISVEC, isrint);
358: #else
359: #if VT_MAJOR == KB_MAJOR
360: setivec(1, isrint);
361: #else
362:
363: /*
364: * Map table and vector to us
365: */
366: i = sphi();
367: PRINTV( "VTload: unload old vector\n" );
368: kcall( Kclrivec, 1 );
369: setivec(1, isrint);
370: spl( i );
371: #endif
372: #endif /* _I386 */
373:
374: /*
375: * Enable mmwatch() invocation every second.
376: */
377: drvl[VT_MAJOR].d_time = 1;
378:
379: /*
380: * Initialize video display.
381: */
382: for ( i = 0; i < vtcount; ++i )
383: mmstart( vttty[i] );
384: }
385:
386: /*
387: * Unload entry point.
388: */
389: isuload()
390: {
391: register int i;
392: register level = sphi();
393:
394: clrivec(ISVEC);
395: #ifndef _I386
396: #if VT_MAJOR != KB_MAJOR
397: kcall( Ksetivec, ISVEC, &Kisrint );
398: #endif
399: #endif
400: spl( level );
401:
402: /* Restore pointers to original state. */
403: vtconsole = vtdata[0];
404: vtconsole->vmm_invis = 0;
405: vtconsole->vmm_visible = VNKB_TRUE;
406:
407: if( vt_opened )
408: printf( "VTclose with %d open screens\n", vt_opened );
409:
410: #ifndef _I386
411: for( i = 0; i < vtcount; ++i ) {
412: PRINTV( "VTuload: free far %x:%x, tty %x\n",
413: vttty[i]->t_buffer->s_faddr, vttty[i] );
414: sfree( vttty[i]->t_buffer );
415: kfree( vttty[i] );
416: sfree( vtdata[i].vt_buffer );
417: }
418: #endif
419: }
420:
421: /*
422: * Default function key strings (terminated by -1 [\377])
423: */
424:
425: static char *deffuncs[] = {
426: /* Normal function keys */
427: ESCAPE_STRING "[M" HEXFF_STRING, /* F1 */
428: ESCAPE_STRING "[N" HEXFF_STRING, /* F2 */
429: ESCAPE_STRING "[O" HEXFF_STRING, /* F3 */
430: ESCAPE_STRING "[P" HEXFF_STRING, /* F4 */
431: ESCAPE_STRING "[Q" HEXFF_STRING, /* F5 */
432: ESCAPE_STRING "[R" HEXFF_STRING, /* F6 */
433: ESCAPE_STRING "[S" HEXFF_STRING, /* F7 */
434: ESCAPE_STRING "[T" HEXFF_STRING, /* F8 */
435: ESCAPE_STRING "[U" HEXFF_STRING, /* F9 */
436: ESCAPE_STRING "[V" HEXFF_STRING, /* F10 - historical value */
437: /* No F11 or F12 on these keyboards */
438:
439: /* Shifted function keys */
440: ESCAPE_STRING "[Y" HEXFF_STRING, /* sF1 */
441: ESCAPE_STRING "[Z" HEXFF_STRING, /* sF2 */
442: ESCAPE_STRING "[a" HEXFF_STRING, /* sF3 */
443: ESCAPE_STRING "[b" HEXFF_STRING, /* sF4 */
444: ESCAPE_STRING "[c" HEXFF_STRING, /* sF5 */
445: ESCAPE_STRING "[d" HEXFF_STRING, /* sF6 */
446: ESCAPE_STRING "[e" HEXFF_STRING, /* sF7 */
447: ESCAPE_STRING "[f" HEXFF_STRING, /* sF8 */
448: ESCAPE_STRING "[g" HEXFF_STRING, /* sF9 */
449: ESCAPE_STRING "[h" HEXFF_STRING, /* sF10 */
450:
451: /* Ctrl-ed function keys */
452: ESCAPE_STRING "[k" HEXFF_STRING, /* cF1 */
453: ESCAPE_STRING "[l" HEXFF_STRING, /* cF2 */
454: ESCAPE_STRING "[m" HEXFF_STRING, /* cF3 */
455: ESCAPE_STRING "[n" HEXFF_STRING, /* cF4 */
456: ESCAPE_STRING "[o" HEXFF_STRING, /* cF5 */
457: ESCAPE_STRING "[p" HEXFF_STRING, /* cF6 */
458: ESCAPE_STRING "[q" HEXFF_STRING, /* cF7 */
459: ESCAPE_STRING "[r" HEXFF_STRING, /* cF8 */
460: ESCAPE_STRING "[s" HEXFF_STRING, /* cF9 */
461: ESCAPE_STRING "[t" HEXFF_STRING, /* cF10 */
462:
463: /* Ctrl-shifted function keys */
464: ESCAPE_STRING "[w" HEXFF_STRING, /* csF1 */
465: ESCAPE_STRING "[x" HEXFF_STRING, /* csF2 */
466: ESCAPE_STRING "[y" HEXFF_STRING, /* csF3 */
467: ESCAPE_STRING "[z" HEXFF_STRING, /* csF4 */
468: ESCAPE_STRING "[@" HEXFF_STRING, /* csF5 */
469: ESCAPE_STRING "[[" HEXFF_STRING, /* csF6 */
470: ESCAPE_STRING "[\\" HEXFF_STRING, /* csF7 */
471: ESCAPE_STRING "[]" HEXFF_STRING, /* csF8 */
472: ESCAPE_STRING "[^" HEXFF_STRING, /* csF9 */
473: ESCAPE_STRING "[_" HEXFF_STRING, /* csF10 */
474:
475: /* Alt keys -- use original 83 key setting since these are
476: * not defined for virtual terms; actually, many will never
477: * be used since intercepted by virtual term code, but
478: * should be here in case someone defines like 1 virtual term
479: * so the keys return something semi-useful */
480: ESCAPE_STRING "[1y" HEXFF_STRING, /* aF1 */
481: ESCAPE_STRING "[2y" HEXFF_STRING, /* aF2 */
482: ESCAPE_STRING "[3y" HEXFF_STRING, /* aF3 */
483: ESCAPE_STRING "[4y" HEXFF_STRING, /* aF4 */
484: ESCAPE_STRING "[5y" HEXFF_STRING, /* aF5 */
485: ESCAPE_STRING "[6y" HEXFF_STRING, /* aF6 */
486: ESCAPE_STRING "[7y" HEXFF_STRING, /* aF7 */
487: ESCAPE_STRING "[8y" HEXFF_STRING, /* aF8 */
488: ESCAPE_STRING "[9y" HEXFF_STRING, /* aF9 */
489: ESCAPE_STRING "[0y" HEXFF_STRING /* aF10 */
490: };
491:
492: /*
493: * Open routine.
494: */
495: isopen(dev, mode)
496: dev_t dev;
497: unsigned int mode;
498: {
499: register int s;
500: register TTY *tp;
501: int index = vtindex(dev);
502:
503: PRINTV("isopen: %x\n", dev);
504: if (index < 0 || index >= vtcount) {
505: u.u_error = ENXIO;
506: return;
507: }
508:
509: tp = vttty[index];
510: if ((tp->t_flags&T_EXCL) != 0 && !super()) {
511: u.u_error = ENODEV;
512: return;
513: }
514: ttsetgrp(tp, dev, mode);
515:
516: s = sphi();
517: if (tp->t_open++ == 0) {
518: initkeys(); /* init function keys */
519: tp->t_flags = T_CARR; /* indicate "carrier" */
520: ttopen(tp);
521: }
522: spl(s);
523: #if 0
524: updleds(); /* update keyboard status LEDS */
525: #endif
526: }
527:
528: /* Init function keys */
529: initkeys()
530: { register int i;
531: register char *cp1, *cp2;
532:
533: for (i=0; i<NFKEY; i++)
534: isfval[i] = 0; /* clear function key buffer */
535: cp2 = isfbuf; /* pointer to key buffer */
536: for (i=0; i<NFKEY; i++)
537: { isfval[i] = cp2; /* save pointer to key string */
538: cp1 = deffuncs[i]; /* get init string pointer */
539: while ((*cp2++ = *cp1++) != -1) /* copy key data */
540: if (cp2 >= &isfbuf[NFBUF-3]) /* overflow? */
541: return;
542: }
543: }
544:
545: void isvtswitch(); /* deferred virtual terminal switch */
546:
547: /*
548: * Close a tty.
549: */
550: isclose(dev)
551: {
552: register int s;
553: int index = vtindex(dev);
554: register TTY *tp = vttty[index];
555:
556: if (--tp->t_open == 0)
557: ttclose(tp);
558:
559: }
560:
561: /*
562: * Read routine.
563: */
564: isread(dev, iop)
565: dev_t dev;
566: IO *iop;
567: {
568: int index = vtindex(dev);
569: register TTY *tp = vttty[index];
570:
571: ttread(tp, iop, 0);
572: if (tp->t_oq.cq_cc)
573: mmtime(tp);
574: }
575:
576: /*
577: * Ioctl routine.
578: */
579: /*
580: * special struct for the KDMAPDISP call
581: */
582:
583: #define KDMAPDISP (('K' << 8) | 2) /* map display into user space */
584: #define KDSKBMODE (('K' << 8) | 6) /* turn scan code xlate on/off */
585: #define KDMEMDISP (('K' << 8) | 7) /* dump byte of virt/phys mem */
586: #define KDENABIO (('K' << 8) | 60) /* enable IO */
587: #define KIOCSOUND (('K' << 8) | 63) /* start sound generation */
588: #define KDSETLED (('K' << 8) | 66) /* set leds */
589:
590: #define TIMER_CTL 0x43 /* Timer control */
591: #define TIMER_CNT 0x42 /* Timer counter */
592: #define SPEAKER_CTL 0x61 /* Speaker control */
593:
594: struct kd_memloc {
595: char *vaddr; /* virtual address to map to */
596: char *physaddr; /* physical address to map to */
597: long length; /* size in bytes to map */
598: long ioflg; /* enable I/O addresses if non-zero */
599: };
600:
601: static TIM tp;
602: int
603: kbstate(action)
604: int action;
605: {
606: int i;
607: if (action == 1) {
608: timeout(&tp,20,kbstate,2);
609: outb(KBCTRL, 0xCC); /* Clock high */
610: }
611: if (action == 2) {
612: i = inb(KBDATA);
613: outb(KBCTRL, 0xCC); /* Clear keyboard */
614: outb(KBCTRL, 0x4D); /* Enable keyboard */
615: }
616: }
617:
618:
619: static int X11led;
620:
621:
622: isioctl(dev, com, vec)
623: dev_t dev;
624: struct sgttyb *vec;
625: {
626: register int s;
627:
628: switch(com) {
629: #define KDDEBUG 0
630: #if KDDEBUG
631: case KDMEMDISP:
632: {
633: struct kd_memloc* mem;
634: unsigned char ub, pb;
635: mem = vec;
636: pxcopy( mem->physaddr, &pb, 1, SEG_386_KD );
637: ub = getubd( mem->vaddr );
638: printf( "User's byte %x(%x), Physical byte %x, Addresses %x %x\n",
639: mem->ioflg, ub, pb, mem->vaddr, mem->physaddr );
640: goto ioc_done;;
641: }
642: #endif
643: case KDMAPDISP:
644: {
645: struct kd_memloc* mem;
646: mem = vec;
647: #if KDDEBUG
648: printf( "mapPhysUser(%x, %x, %x) = %d\n",
649: mem->vaddr, mem->physaddr, mem->length,
650: #endif
651: mapPhysUser(mem->vaddr, mem->physaddr, mem->length)
652: #if KDDEBUG
653: )
654: #endif
655: ;
656: }
657: case KDENABIO:
658: {
659: int i;
660: for (i = 0 ; i < 64 ; i++ )
661: iomapAnd(0,i);
662: goto ioc_done;;
663: }
664: case KIOCSOUND:
665: {
666: if (vec) {
667: outb(TIMER_CTL, 0xB6);
668: outb(TIMER_CNT, (int)vec&0xFF);
669: outb(TIMER_CNT, (int)vec>>8);
670: outb(SPEAKER_CTL, inb(SPEAKER_CTL) | 03); /* Turn speaker on */
671: }
672: else
673: outb(SPEAKER_CTL, inb(SPEAKER_CTL) & ~03 ); /* speaker off */
674: goto ioc_done;;
675: }
676: case KDSKBMODE:
677: {
678: outb(KBCTRL, 0x0C); /* Clock low */
679: timeout(&tp,3,kbstate,1); /* wait about 20-30ms */
680: xlate = (int)vec;
681: goto ioc_done;;
682: }
683: case KDSETLED:
684: {
685: X11led = (int)vec;
686: updleds();
687: goto ioc_done;;
688: }
689:
690: case TIOCSETF:
691: case TIOCGETF:
692: isfunction(com, (char *)vec);
693: goto ioc_done;;
694: case TIOCSHIFT: /* switch left-SHIFT and "\" */
695: lshiftkb = LSHIFTA; /* alternate values */
696: lmaptab[41] = '\\';
697: lmaptab[42] = XXX;
698: umaptab[41] = '|';
699: umaptab[42] = XXX;
700: smaptab[41] = SS1;
701: smaptab[42] = SHFT;
702: goto ioc_done;;
703: case TIOCCSHIFT: /* normal (default) left-SHIFT and "\" */
704: lshiftkb = LSHIFT; /* normal values */
705: lmaptab[41] = XXX;
706: lmaptab[42] = '\\';
707: umaptab[41] = XXX;
708: umaptab[42] = '|';
709: smaptab[41] = SHFT;
710: smaptab[42] = SS1;
711: goto ioc_done;;
712: }
713: s = sphi();
714: ttioctl(vttty[vtindex(dev)], com, vec);
715: spl(s);
716:
717: ioc_done:
718: return;
719: }
720:
721: /*
722: * Set and receive the function keys.
723: */
724: isfunction(c, v)
725: int c;
726: char *v;
727: {
728: register char *cp;
729: register int i;
730:
731: if (c == TIOCGETF) {
732: for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++)
733: putubd(v++, *cp);
734: } else {
735: for (i=0; i<NFKEY; i++) /* zap current settings */
736: isfval[i] = 0;
737: cp = isfbuf; /* pointer to key buffer */
738: for (i=0; i<NFKEY; i++) {
739: isfval[i] = cp; /* save pointer to key string */
740: while ((*cp++ = getubd(v++)) != -1) /* copy key data */
741: if (cp >= &isfbuf[NFBUF-3]) /* overflow? */
742: return;
743: }
744: }
745: }
746:
747:
748: /*
749: * Poll routine.
750: */
751: ispoll( dev, ev, msec )
752: dev_t dev;
753: int ev;
754: int msec;
755: {
756: register TTY *tp = vttty[vtindex(dev)];
757:
758: return ttpoll(tp, ev, msec);
759: }
760:
761: /*
762: * Receive interrupt.
763: */
764: isrint()
765: {
766: register int c;
767: register int s;
768: register int r;
769: int savests;
770: int update_leds = 0;
771:
772: /*
773: * Schedule raw input handler if not already active.
774: */
775: if ( isbusy == 0 ) {
776: isbusy = 1;
777: defer(isbatch, vttty[vtactive]);
778: }
779:
780: /*
781: * Pull character from the data
782: * port. Pulse the KBFLAG in the control
783: * port to reset the data buffer.
784: */
785: r = inb(KBDATA) & 0xFF;
786: c = inb(KBCTRL);
787: outb(KBCTRL, c|KBFLAG);
788: outb(KBCTRL, c);
789: if (!xlate) {
790: if (ledcmd) {
791: ledcmd = 0;
792: if (r == KBACK) { /* output to status LEDS */
793: outb(KBDATA, X11led);
794: return;
795: }
796: }
797: isin(r);
798: return;
799: }
800:
801: #if KBDEBUG
802: printf("kbd: %d\n", r); /* print scan code/direction */
803: #endif
804: if (ledcmd) {
805: ledcmd = 0;
806: if (r == KBACK) { /* output to status LEDS */
807: c = scrollkb & 1;
808: if (shift & NMLS)
809: c |= 2;
810: if (shift & CPLS)
811: c |= 4;
812: outb(KBDATA, c);
813: }
814: return;
815: }
816: if (extended > 0) { /* if multi-character seq, */
817: --extended; /* ... ignore this char */
818: return;
819: }
820: switch (r) {
821: case EXTENDED0: /* 0xE0 prefix found */
822: ext0seen = 1;
823: return;
824: case EXTENDED1: /* ignore extended sequences */
825: extended = 5;
826: return;
827: case 0xFF: /* Overrun */
828: return;
829: }
830:
831: if (ext0seen) {
832: ext0seen = 0;
833: extmode = 1;
834: } else
835: extmode = 0;
836:
837: c = (r & KEYSC) - 1;
838: /*
839: * Check for reset.
840: */
841: if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS))
842: boot();
843:
844: /*
845: * Track "shift" keys.
846: */
847: s = smaptab[c];
848: if (s&SHFT) {
849: if (r&KEYUP) { /* "shift" released */
850: if (c == RSHIFT)
851: shift &= ~SRS;
852: else if (c == lshiftkb)
853: shift &= ~SLS;
854: else if (c == CTRLkb)
855: shift &= ~CTS;
856: else if (c == ALTkb)
857: shift &= extmode ? ~AGS : ~ALS;
858: } else { /* "shift" pressed */
859: if (c == lshiftkb)
860: shift |= SLS;
861: else if (c == RSHIFT)
862: shift |= SRS;
863: else if (c == CTRLkb)
864: shift |= CTS;
865: else if (c == ALTkb)
866: shift |= extmode ? AGS : ALS;
867: else if (c == CAPLOCK) {
868: shift ^= CPLS; /* toggle cap lock */
869: updleds();
870: } else if (c == NUMLOCK) {
871: shift ^= NMLS; /* toggle num lock */
872: updleds();
873: }
874: }
875: return;
876: }
877:
878: /*
879: * No other key up codes of interest.
880: */
881: if (r&KEYUP)
882: return;
883:
884: /*
885: * Map character, based on the
886: * current state of the shift, control, alt graphics,
887: * meta (ALT) and lock flags.
888: */
889: if (shift & AGS) /* Alt Graphics ? */
890: c = agmaptab[c];
891: else if (shift & CTS) {
892: if (s == CTS) /* Map Ctrl (BS | NL) */
893: c = (c == BACKSP) ? 0x7F : 0x0A;
894: else if (s==SS1 || s==LET) {
895: if((c = umaptab[c]) != SPC) /* Normal Ctrl map */
896: c &= 0x1F; /* Clear bits 5-6 */
897: } else { if (s==KEY || s==SS0)
898: vtnumeric(r);
899: return; /* Ignore this char */
900: }
901: } else if (s &= shift) {
902: if (shift & SES) { /* if shift on */
903: if (s & (CPLS|NMLS)) /* if caps/num lock */
904: c = lmaptab[c]; /* use unshifted */
905: else
906: c = umaptab[c]; /* use shifted */
907: } else { /* if shift not on */
908: if (s & (CPLS|NMLS)) /* if caps/num lock */
909: c = umaptab[c]; /* use shifted */
910: else
911: c = lmaptab[c]; /* use unshifted */
912: }
913: } else
914: c = lmaptab[c]; /* use unshifted */
915:
916: /*
917: * Act on character.
918: */
919: if (c == XXX)
920: return; /* char to ignore */
921:
922: if (c != SPC) { /* not special char? */
923: if (shift & ALS) /* ALT (meta bit)? */
924: c |= 0x80; /* set meta */
925: isin(c); /* send the char */
926: } else
927: update_leds += isspecial(r); /* special chars */
928: if (update_leds) {
929: savests = sphi();
930: outb(KBDATA, LEDCMD);
931: ledcmd = 1;
932: spl(savests);
933: }
934: }
935:
936: /*
937: * Process numeric keypad for virtual terminals.
938: */
939: vtnumeric(c)
940: int c;
941: {
942: switch (c) {
943: case 71: /* ctrl-7 */
944: defer(isvtswitch, vt7);
945: break;
946: case 72: /* ctrl-8 */
947: defer(isvtswitch, vt8);
948: break;
949: case 73: /* ctrl-9 */
950: defer(isvtswitch, vt9);
951: break;
952: case 74: /* ctrl - */
953: defer(isvtswitch, vtp);
954: break;
955: case 75: /* ctrl-4 */
956: defer(isvtswitch, vt4);
957: break;
958: case 76: /* ctrl-5 */
959: defer(isvtswitch, vt5);
960: break;
961: case 77: /* ctrl-6 */
962: defer(isvtswitch, vt6);
963: break;
964: case 78: /* ctrl + */
965: defer(isvtswitch, vtn);
966: break;
967: case 79: /* ctrl-1 */
968: defer(isvtswitch, vt1);
969: break;
970: case 80: /* ctrl-2 */
971: defer(isvtswitch, vt2);
972: break;
973: case 81: /* ctrl-3 */
974: defer(isvtswitch, vt3);
975: break;
976: case 82: /* ctrl 0 (vt0) */
977: defer(isvtswitch, vt0);
978: break;
979: case 83: /* ctrl del (toggle) */
980: c = vtt;
981: defer(isvtswitch, vtt);
982: break;
983: }
984: }
985:
986: /*
987: * Handle special input sequences.
988: * The character passed is the key number.
989: *
990: * The keypad is translated by the following table,
991: * the first entry is the normal sequence, the second the shifted,
992: * and the third the alternate keypad sequence.
993: */
994: static char *keypad[][3] = {
995: { ESCAPE_STRING "[H", "7", ESCAPE_STRING "?w" }, /* 71 */
996: { ESCAPE_STRING "[A", "8", ESCAPE_STRING "?x" }, /* 72 */
997: { ESCAPE_STRING "[I", "9", ESCAPE_STRING "?y" }, /* 73 */
998: { ESCAPE_STRING "[D", "4", ESCAPE_STRING "?t" }, /* 75 */
999: { ESCAPE_STRING "7", "5", ESCAPE_STRING "?u" }, /* 76 */
1000: { ESCAPE_STRING "[C", "6", ESCAPE_STRING "?v" }, /* 77 */
1001: { ESCAPE_STRING "[F", "1", ESCAPE_STRING "?q" }, /* 79 */
1002: { ESCAPE_STRING "[B", "2", ESCAPE_STRING "?r" }, /* 80 */
1003: { ESCAPE_STRING "[G", "3", ESCAPE_STRING "?s" }, /* 81 */
1004: { ESCAPE_STRING "[L", "0", ESCAPE_STRING "?p" }, /* 82 */
1005: { DELETE_STRING , ".", ESCAPE_STRING "?n" } /* 83 */
1006: };
1007:
1008: isspecial(c)
1009: int c;
1010: {
1011: register char *cp;
1012: register int s;
1013: int update_leds = 0;
1014:
1015: cp = 0;
1016:
1017: switch (c) {
1018: case 15: /* cursor back tab */
1019: cp = "\033[Z";
1020: break;
1021: case 53:
1022: if (extmode)
1023: cp = "/";
1024: else if (shift & SES)
1025: cp = "_";
1026: else
1027: cp = "-";
1028: break;
1029: case 55: /* ignore PrtScr */
1030: if (!extmode)
1031: cp = "*";
1032: break;
1033: case 59: case 60: case 61: case 62: case 63: /* Function keys */
1034: case 64: case 65: case 66:
1035: /* offset to function string */
1036: /* Magic numbers 21 and 61 to mach vtnkb constants */
1037: if ( shift & ALS ) {
1038: switch(c) {
1039: case 59: /* Alt-F1 */
1040: defer(isvtswitch, vt0);
1041: break;
1042: case 60: /* Alt-F2 */
1043: defer(isvtswitch, vt1);
1044: break;
1045: case 61: /* Alt-F3 */
1046: defer(isvtswitch, vt2);
1047: break;
1048: case 62: /* Alt-F4 */
1049: defer(isvtswitch, vt3);
1050: break;
1051: case 63: /* Alt-F5 */
1052: defer(isvtswitch, vt4);
1053: break;
1054: case 64: /* Alt-F6 */
1055: defer(isvtswitch, vt5);
1056: break;
1057: case 65: /* Alt-F7 */
1058: defer(isvtswitch, vt6);
1059: break;
1060: case 66: /* Alt-F8 */
1061: defer(isvtswitch, vt7);
1062: break;
1063: default:
1064: break;
1065: }
1066: }
1067: else { if((shift & (SES)) && (shift & CTS)) /* ctrl-shft-Fx */
1068: cp = isfval[c-29];
1069: else { if(shift & CTS) /* ctrl-Fx */
1070: cp = isfval[c-39];
1071: else { if(shift & (SES)) /* shift-Fx */
1072: cp = isfval[c-49];
1073: else cp = isfval[c-59]; /* Plain Fx */
1074: }}}
1075: break;
1076: case 67: case 68:
1077: /* offset to function string */
1078: if ( shift & ALS ) {
1079: switch(c) {
1080: case 67: /* Alt-F9 */
1081: defer(isvtswitch, vt8);
1082: break;
1083: case 68: /* Alt-F10 */
1084: defer(isvtswitch, vt9);
1085: break;
1086: default:
1087: break;
1088: }
1089: }
1090: else { if ((shift & (SES)) && (shift & CTS)) /* cs-Fx */
1091: cp = isfval[c-29];
1092: else { if (shift & CTS) /* c-Fx */
1093: cp = isfval[c-39];
1094: else { if (shift & (SES)) /* s-Fx */
1095: cp = isfval[c-49];
1096: else cp = isfval[c-59]; /* Fx */
1097: }}}
1098: break;
1099: case 70: /* Scroll Lock -- stop/start output */
1100: {
1101: static char cbuf[2];
1102:
1103: cp = &cbuf[0]; /* working buffer */
1104: if (! _IS_RAWIN_MODE (vttty [vtactive])) {
1105: ++update_leds;
1106:
1107: if (vttty[vtactive]->t_flags&T_STOP){/* output stopped? */
1108: cbuf[0] = vttty[vtactive]->t_tchars.t_startc;
1109: scrollkb = 0;
1110: } else {
1111: cbuf[0] = vttty[vtactive]->t_tchars.t_stopc;
1112: scrollkb = 1;
1113: }
1114: }
1115: break;
1116: }
1117:
1118: case 79: /* 1/End */
1119: case 80: /* 2/DOWN */
1120: case 81: /* 3/PgDn */
1121: case 82: /* 0/Ins */
1122: case 83: /* ./Del */
1123: --c; /* adjust code */
1124: case 75: /* 4/LEFT */
1125: case 76: /* 5 */
1126: case 77: /* 6/RIGHT */
1127: --c; /* adjust code */
1128: case 71: /* 7/Home/Clear */
1129: case 72: /* 8/UP */
1130: case 73: /* 9/PgUp */
1131: s = 0; /* start off with normal keypad */
1132: if (shift & NMLS) /* num lock? */
1133: s = 1; /* set shift pad */
1134: if (shift & SES) /* shift? */
1135: s ^= 1; /* toggle shift pad */
1136: if (shift & AKPS) /* alternate pad? */
1137: s = 2; /* set alternate pad */
1138: if (extmode) /* not from keypad? */
1139: s = 0; /* force normal sequence */
1140: cp = keypad[c-71][s]; /* get keypad value */
1141: break;
1142: }
1143: if (cp) /* send string */
1144: while ((*cp != 0) && (*cp != -1))
1145: isin( *cp++ & 0377 );
1146: return update_leds;
1147: }
1148:
1149: /**
1150: *
1151: * void
1152: * ismmfunc( c ) -- process keyboard related output escape sequences
1153: * char c;
1154: */
1155: void
1156: ismmfunc(c)
1157: register int c;
1158: {
1159: switch (c) {
1160: case 't': /* Enter numlock */
1161: shift |= NMLS;
1162: updleds(); /* update LED status */
1163: break;
1164: case 'u': /* Leave numlock */
1165: shift &= ~NMLS;
1166: updleds(); /* update LED status */
1167: break;
1168: case '=': /* Enter alternate keypad */
1169: shift |= AKPS;
1170: break;
1171: case '>': /* Exit alternate keypad */
1172: shift &= ~AKPS;
1173: break;
1174: case 'c': /* Reset terminal */
1175: islock = 0;
1176: shift = 0;
1177: initkeys();
1178: updleds(); /* update LED status */
1179: break;
1180: }
1181: }
1182:
1183: /**
1184: *
1185: * void
1186: * isin( c ) -- append character to raw input silo
1187: * char c;
1188: */
1189: static
1190: isin( c )
1191: register int c;
1192: {
1193: int cache_it = 1;
1194: TTY * tp = vttty[vtactive];
1195:
1196: /*
1197: * If using software incoming flow control, process and
1198: * discard t_stopc and t_startc.
1199: */
1200: if (_IS_IXON_MODE (tp)) {
1201: #if _I386
1202: if (_IS_START_CHAR (tp, c) ||
1203: (_IS_IXANY_MODE (tp) && (tp->t_flags & T_STOP) != 0)) {
1204: tp->t_flags &= ~(T_STOP | T_XSTOP);
1205: ttstart(tp);
1206: cache_it = 0;
1207: } else if (_IS_STOP_CHAR (tp, c)) {
1208: if ((tp->t_flags & T_STOP) == 0)
1209: tp->t_flags |= (T_STOP | T_XSTOP);
1210: cache_it = 0;
1211: }
1212: #else
1213: if (_IS_STOP_CHAR (tp, c)) {
1214: if ((tp->t_flags & T_STOP) == 0)
1215: tp->t_flags |= T_STOP;
1216: cache_it = 0;
1217: }
1218: if (_IS_START_CHAR (tp, c)) {
1219: tp->t_flags &= ~ T_STOP;
1220: ttstart (tp);
1221: cache_it = 0;
1222: }
1223: #endif
1224: }
1225: /*
1226: * If the tty is not open the character is
1227: * just tossed away.
1228: */
1229: if (vttty[vtactive]->t_open == 0)
1230: return;
1231:
1232:
1233: /*
1234: * Cache received character.
1235: */
1236: if (cache_it) {
1237: in_silo.si_buf[ in_silo.si_ix ] = c;
1238:
1239: if ( ++in_silo.si_ix >= sizeof(in_silo.si_buf) )
1240: in_silo.si_ix = 0;
1241: }
1242: }
1243:
1244: /**
1245: *
1246: * void
1247: * isbatch() -- raw input conversion routine
1248: *
1249: * Action: Enable the video display.
1250: * Canonize the raw input silo.
1251: *
1252: * Notes: isbatch() was scheduled as a deferred process by isrint().
1253: */
1254: static void
1255: isbatch( tp )
1256: register TTY * tp;
1257: {
1258: register int c;
1259: static int lastc;
1260: VTDATA *vp = tp->t_ddp;
1261:
1262: /*
1263: * Ensure video display is enabled.
1264: */
1265: if (vp->vmm_visible)
1266: mm_von(vp);
1267:
1268: isbusy = 0;
1269:
1270: /*
1271: * Process all cached characters.
1272: */
1273: while ( in_silo.si_ix != in_silo.si_ox ) {
1274:
1275: /*
1276: * Get next cached char.
1277: */
1278: c = in_silo.si_buf[ in_silo.si_ox ];
1279:
1280: if ( in_silo.si_ox >= sizeof(in_silo.si_buf) - 1 )
1281: in_silo.si_ox = 0;
1282: else
1283: in_silo.si_ox++;
1284:
1285: if (islock == 0 || _IS_INTERRUPT_CHAR (tp, c) ||
1286: _IS_QUIT_CHAR (tp, c)) {
1287: ttin (tp, c);
1288: } else if (c == 'b' && lastc == ESCAPE_CHAR) {
1289: islock = 0;
1290: ttin (tp, lastc);
1291: ttin (tp, c);
1292: } else if (c == 'c' && lastc == ESCAPE_CHAR) {
1293: ttin (tp, lastc);
1294: ttin (tp, c);
1295: } else
1296: putchar ('\a');
1297:
1298: lastc = c;
1299: }
1300: }
1301:
1302: /*
1303: * update the keyboard status LEDS
1304: */
1305:
1306: updleds()
1307: {
1308: int s;
1309:
1310: s = sphi ();
1311: outb (KBDATA, LEDCMD);
1312: ledcmd = 1;
1313: spl (s);
1314: }
1315:
1316: /*
1317: * unlock the scroll in case an interrupt character is received
1318: */
1319: kbunscroll()
1320: {
1321: scrollkb = 0;
1322: updleds();
1323: }
1324: int
1325: VTttyinit(i)
1326: int i;
1327: {
1328: TTY *tp;
1329:
1330: /*
1331: * get pointer to TTY structure from kernal memory space
1332: */
1333: if( (tp = vttty[i] = (TTY *)kalloc(sizeof (TTY))) == NULL )
1334: return(0);
1335: PRINTV( " vttty[%d]: @%x, ", i, tp );
1336:
1337: #if FAR_TTY
1338: /*
1339: * get pointers to the buffers pointed to by the TTY structure
1340: * from user memory space
1341: */
1342: tp->t_buffer = salloc( (fsize_t)NCIB+2*SI_BUFSIZ, SFSYST|SFNSWP );
1343: tp->t_ib = 0;
1344: tp->t_rawin.si_buf = NCIB;
1345: tp->t_rawout.si_buf = NCIB+SI_BUFSIZ;
1346: #endif
1347: tp->t_param = NULL;
1348: tp->t_start = &mmstart;
1349:
1350: #ifndef _I386
1351: #if VT_MAJOR == KB_MAJOR
1352: tp->t_cs_sel = 0;
1353: #else
1354: tp->t_cs_sel = cs_sel();
1355: #endif
1356: #endif
1357: tp->t_ddp = vtdata[i];
1358: PRINTV( "data @%lx\n", tp->t_ddp );
1359: return(1);
1360: }
1361:
1362: vtdatainit(vp)
1363: VTDATA *vp;
1364: {
1365: #ifndef _I386
1366: VT_FARSEG vt_farseg;
1367: #endif
1368: /*
1369: * vtdata init - vmm part
1370: */
1371: vp->vmm_invis = -1; /* cursor invisible */
1372:
1373: #ifdef _I386
1374: vp->vt_buffer = kalloc( TEXTBLOCK );
1375: vp->vmm_seg = vp->vmm_mseg = ds_sel();
1376: vp->vmm_off = vp->vmm_moff = vp->vt_buffer;
1377: #else
1378: vp->vt_buffer = salloc ( (fsize_t)TEXTBLOCK, SFSYST|SFNSWP|SFHIGH );
1379: vp->vmm_seg = vp->vmm_mseg = FP_SEG( vp->vt_buffer->vt_faddr );
1380: vp->vmm_off = vp->vmm_moff = FP_OFF( vp->vt_buffer->vt_faddr );
1381: #endif
1382: PRINTV( "vt@%x init index %d,%d), seg %x, off %x\n",
1383: vp, vp->vt_ind, vp->vmm_mseg, vp->vmm_moff );
1384: /*
1385: * vtdata init - vnkb part
1386: */
1387: /* Make the first memory block active, if present */
1388: vp->vnkb_lastc = 0;
1389: vp->vnkb_fnkeys = 0;
1390: vp->vnkb_funkeyp = 0;
1391: vp->vnkb_fk_loaded = 0; /* no Fn keys yet */
1392: }
1393:
1394: /*
1395: * Given device number, return index for vtdata[], vttty[], etc.
1396: *
1397: * Major number must be VT_MAJOR for CPU to get here.
1398: *
1399: * Minor Number Index Value
1400: * ----- ------ ----- -----
1401: * 0000 0000 vtactive ... device (2,0) is the active screen
1402: * 0000 0001 0
1403: * 0000 0010 1
1404: * 0000 0011 2
1405: * ....
1406: * 0000 1111 14
1407: *
1408: * 0100 xxxx xxxx ... color devices only
1409: * 0101 xxxx xxxx - (# of color devices found) ... monochrome only
1410: *
1411: * Return value is in range 0 to vtcount-1 for valid minor numbers,
1412: * -1 for invalid minor numbers.
1413: */
1414: int
1415: vtindex( dev )
1416: dev_t dev;
1417: {
1418: register int ret = -1;
1419:
1420: if ( dev & VT_PHYSICAL ) {
1421: int hw = ( dev >> 4 ) & 3;
1422: int hw_index = dev & 0x0F;
1423:
1424: if( hw_index < vtHWtable[hw]->found )
1425: ret = vtHWtable[hw]->start + hw_index;
1426: } else {
1427: int lg_index = dev & 0x0F;
1428:
1429: if (lg_index == 0)
1430: ret = vtactive;
1431: if (lg_index > 0 && lg_index <= vtcount )
1432: ret = lg_index-1;
1433: }
1434: if (ret >= 0)
1435: ret %= vtcount;
1436: else
1437: PRINTV( "vtindex: (%x) %d. invalid !\n", dev, ret );
1438: return ret;
1439: }
1440:
1441: /*
1442: *
1443: * void
1444: * isvtswitch() -- deferred virtual terminal switch
1445: *
1446: * Action: - save current shift key status
1447: * - determine new active virtual terminal
1448: * - deactivate shift key status of the current virtual terminal
1449: * - deactivate current virtual terminal
1450: * - activate shift key status of the new virtual terminal with
1451: * the previously saved shift key status
1452: * - activate new virtual terminal
1453: *
1454: * Notes: isvtswitch() was scheduled as a deferred process by
1455: * process_key() which is a function called by isrint().
1456: */
1457: void
1458: isvtswitch(key_val)
1459: {
1460: register int new_index, i;
1461: unsigned lockshift, nolockshift;
1462: VTDATA *vp = vtdata[vtactive];
1463: VTDATA *vp_old, *vp_new;
1464: static int vtprevious;
1465:
1466: lockshift = shift & (CPLS | NMLS);
1467: nolockshift = shift & ~(CPLS | NMLS);
1468: PRINTV( "F%d: %d", key_val, vtactive );
1469:
1470: switch (key_val) {
1471: case VTKEY_HOME:
1472: new_index = 0;
1473: break;
1474: case VTKEY_NEXT:
1475: new_index = vtactive;
1476: for( i = 0; i < vtcount; ++i ) {
1477: new_index = ++new_index % vtcount;
1478: if( vttty[new_index]->t_open )
1479: break;
1480: }
1481: break;
1482: case VTKEY_PREV:
1483: new_index = vtactive;
1484: for( i = 0; i < vtcount; ++i ) {
1485: new_index = (--new_index+vtcount) % vtcount;
1486: if( vttty[new_index]->t_open )
1487: break;
1488: }
1489: break;
1490: case VTKEY_TOGL:
1491: new_index = vtprevious;
1492: break;
1493: default:
1494: new_index = vtindex(vtkey_to_dev(key_val));
1495: if( new_index < 0) {
1496: putchar( '\007' );
1497: return;
1498: }
1499: }
1500:
1501: T_CON(8, printf("%d->%d ", vtactive, new_index));
1502: if( new_index == vtactive )
1503: return;
1504:
1505: /* Save which locking shift states are in effect. */
1506:
1507: vp_old = vtdata[vtactive];
1508: vp_new = vtdata[new_index];
1509:
1510: vp_old->vnkb_shift = lockshift;
1511: vtdeactivate(vp_new, vp_old); /* deactivate old virtual terminal */
1512:
1513: /* Restore shift lock state, append current momentary shift state. */
1514: shift = vp_new->vnkb_shift | nolockshift;
1515:
1516: vtactivate(vp_new); /* activate new virtual terminal */
1517: updterminal(new_index);
1518: vtprevious = vtactive;
1519: vtactive = new_index; /* update vtactive */
1520: }
1521:
1522: vtdeactivate(vp_new, vp_old)
1523: register VTDATA *vp_new, *vp_old;
1524: {
1525: register i;
1526: VTDATA *vpi;
1527:
1528: /* store old screen contents in memory segment */
1529: ffcopy (vp_old->vmm_voff, vp_old->vmm_vseg,
1530: vp_old->vmm_moff, vp_old->vmm_mseg, TEXTBLOCK);
1531:
1532: /*
1533: * if changing to another screen on same video board
1534: * for all screens on same board as new screen
1535: * deactivate, but don't update
1536: * else - changing to a screen on different board
1537: * for all screens NOT on same board as new screen
1538: * deactivate, but don't update
1539: */
1540: if ( vp_old->vmm_port == vp_new->vmm_port ) {
1541: T_CON(8, printf("deactivate on %x ", vp_new->vmm_port));
1542: for (i = 0; i < vtcount; ++i) {
1543: vpi = vtdata[i];
1544: if ( vpi->vmm_port == vp_new->vmm_port ) {
1545: /* deactivate, but don't update */
1546: vpi->vmm_invis = ~0;
1547: vpi->vmm_visible = VNKB_FALSE;
1548: vpi->vmm_seg = vpi->vmm_mseg;
1549: vpi->vmm_off = vpi->vmm_moff;
1550: if( vpi->vmm_seg == 0 )
1551: printf( "[1]vpi->vmm_seg = 0\n" );
1552: PRINTV( "vt.back %d. seg %x off %x\n", i,
1553: vpi->vmm_seg, vpi->vmm_off );
1554: }
1555: }
1556: } else {
1557: T_CON(8, printf("deactivate %x->%x ",
1558: vp_old->vmm_port, vp_new->vmm_port));
1559: for (i = 0; i < vtcount; ++i) {
1560: vpi = vtdata[i];
1561: if ( (vpi->vmm_port != vp_new->vmm_port)
1562: && (vpi->vmm_invis == 0) ) {
1563: /* update, but don't deactivate */
1564: vpi->vmm_invis = ~0;
1565: updscreen(i);
1566: }
1567: }
1568: }
1569: }
1570:
1571: vtactivate(vp)
1572: VTDATA *vp;
1573: {
1574: register VTDATA *vpi;
1575: register i;
1576:
1577: /*
1578: * copy from screen contents from heap segment to video memory
1579: * only if necessary
1580: */
1581: if (vp->vmm_visible == VNKB_FALSE)
1582: ffcopy (vp->vmm_moff, vp->vmm_mseg,
1583: vp->vmm_voff, vp->vmm_vseg, TEXTBLOCK);
1584:
1585: for (i = 0; i < vtcount; ++i) {
1586: vpi = vtdata[i];
1587: if (vpi->vmm_port == vp->vmm_port) {
1588: vpi->vmm_invis = -1;
1589: vpi->vmm_visible = VNKB_FALSE;
1590: vpi->vmm_seg = vpi->vmm_mseg;
1591: vpi->vmm_off = vpi->vmm_moff;
1592: if (vpi->vmm_seg == 0)
1593: printf ("[2]vpi->vmm_seg = 0\n");
1594: PRINTV ("vt.back seg %x off %x\n",
1595: vpi->vmm_seg, vpi->vmm_off);
1596: }
1597: }
1598: /*
1599: * Set new active terminal
1600: */
1601: vp->vmm_invis = 0;
1602: vp->vmm_visible = VNKB_TRUE;
1603: vp->vmm_seg = vp->vmm_vseg;
1604: vp->vmm_off = vp->vmm_voff;
1605: if (vp->vmm_seg == 0)
1606: printf ("vp->vmm_seg = 0\n");
1607: }
1608:
1609: /*
1610: * update the terminal to match vtactive
1611: */
1612: updterminal(index)
1613: int index;
1614: {
1615: updscreen(index);
1616: updleds();
1617: }
1618:
1619: /*
1620: * Given a function key number (e.g. vt0),
1621: * return the corresponding minor device number.
1622: *
1623: * Assume valid key number (VTKEY(fnum) is true) by the time we get here.
1624: */
1625: int
1626: vtkey_to_dev(fnum)
1627: int fnum;
1628: {
1629: if (fnum >=vt0 && fnum <= vt15)
1630: return fnum-vt0+1;
1631: if (fnum >=color0 && fnum <= color15)
1632: return (fnum-color0)|(VT_PHYSICAL|VT_HW_COLOR);
1633: if (fnum >=mono0 && fnum <= mono15)
1634: return (fnum-mono0)|(VT_PHYSICAL|VT_HW_MONO);
1635: printf("vtkey_to_dev(%d)! ", fnum);
1636: return 0;
1637: }
1638: /* End of vtkb_d.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.