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