|
|
1.1 root 1: /*
2: * Keyboard/display driver for French keyboard.
3: * Coherent, IBM PC/XT/AT (286 and 386).
4: */
5: #include <sys/coherent.h>
6: #ifdef _I386
7: #include <sys/reg.h>
8: #else
9: #include <sys/i8086.h>
10: #endif
11: #include <sys/con.h>
12: #include <sys/devices.h>
13: #include <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 20 /* 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: * Functions.
68: */
69: int isrint();
70: int istime();
71: void isbatch();
72: int mmstart();
73: int isopen();
74: int isclose();
75: int isread();
76: int mmwrite();
77: int isioctl();
78: void mmwatch();
79: int isload();
80: int isuload();
81: int ispoll();
82: int nulldev();
83: int nonedev();
84:
85: /*
86: * Configuration table.
87: */
88: CON iscon ={
89: DFCHR|DFPOL, /* Flags */
90: KB_MAJOR, /* Major index */
91: isopen, /* Open */
92: isclose, /* Close */
93: nulldev, /* Block */
94: isread, /* Read */
95: mmwrite, /* Write */
96: isioctl, /* Ioctl */
97: nulldev, /* Powerfail */
98: mmwatch, /* Timeout */
99: isload, /* Load */
100: isuload, /* Unload */
101: ispoll /* Poll */
102: };
103:
104: /*
105: * Flag indicating turbo machine.
106: */
107: int isturbo = 0;
108:
109: /*
110: ==============================================================================
111: ==============================================================================
112: */
113: /* constants for vtdata[] */
114: #define VT_VGAPORT 0x3D4
115: #define VT_MONOPORT 0x3B4
116:
117: #ifdef _I386
118: #define VT_MONOBASE SEG_VIDEOa
119: #define VT_VGABASE SEG_VIDEOb
120: #else
121: #define VT_MONOBASE 0xB000
122: #define VT_VGABASE 0xB800
123: #endif
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:
177: /*
178: * Tables for converting key code to ASCII.
179: * lmaptab specifies unshifted conversion,
180: * umaptab specifies shifted conversion,
181: * smaptab specifies the shift states which are active.
182: * An entry of XXX says the key is dead.
183: * An entry of SPC requires further processing.
184: *
185: * Key codes:
186: * ESC .. <- == 1 .. 14
187: * -> .. \n == 15 .. 28
188: * CTRL .. ` == 29 .. 41
189: * ^Shift .. PrtSc == 42 .. 55
190: * ALT .. CapsLock == 56 .. 58
191: * F1 .. F10 == 59 .. 68
192: * NumLock .. Del == 69 .. 83
193: * ISO, F11, F12 == 86 .. 88
194: */
195: unsigned char agmaptab[] ={ /* Alt Gr */
196: XXX, XXX, '~', '#', '{', '[', '|', /* 1 - 7 */
197: '`', '\\', '^', '@', ']', '}', XXX, XXX, /* 8 - 15 */
198: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 16 - 23 */
199: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 24 - 31 */
200: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 32 - 39 */
201: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 40 - 47 */
202: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 48 - 55 */
203: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 56 - 63 */
204: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 64 - 71 */
205: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 72 - 79 */
206: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 80 - 87 */
207: XXX /* 88 */
208: };
209:
210: static unsigned char lmaptab[] ={
211: '\33', '&','\202', '"', '\'', '(', '-', /* 1 - 7 */
212: '\212','_','\207','\205',')', '=', '\b', '\t', /* 8 - 15 */
213: 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', /* 16 - 23 */
214: 'o', 'p','\260', '$', '\r', XXX, 'q', 's', /* 24 - 31 */
215: 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', /* 32 - 39 */
216: '\227','\375',XXX,'*', 'w', 'x', 'c', 'v', /* 40 - 47 */
217: 'b', 'n', ',', ';', ':', SPC, XXX, SPC, /* 48 - 55 */
218: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
219: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
220: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
221: SPC, SPC, SPC, SPC, XXX, XXX, '<', XXX, /* 80 - 87 */
222: XXX /* 88 */
223: };
224:
225: static unsigned char umaptab[] ={
226: '\33', '1', '2', '3', '4', '5', '6', /* 1 - 7 */
227: '7', '8', '9', '0','\370', '+', '\b', SPC, /* 8 - 15 */
228: 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16 - 23 */
229: 'O', 'P','\261','\234','\r', XXX, 'Q', 'S', /* 24 - 31 */
230: 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', /* 32 - 39 */
231: '%','\300',XXX,'\346', 'W', 'X', 'C', 'V', /* 40 - 47 */
232: 'B', 'N', '?', '.', '/', SPC, XXX, SPC, /* 48 - 55 */
233: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
234: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
235: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
236: SPC, SPC, SPC, SPC, XXX, XXX, '>', XXX, /* 80 - 87 */
237: XXX /* 88 */
238: };
239:
240: #define SS0 0 /* No shift */
241: #define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */
242: #define SES (SLS|SRS) /* Shift */
243: #define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */
244: #define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */
245:
246: static unsigned char smaptab[] ={
247: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */
248: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */
249: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */
250: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */
251: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */
252: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */
253: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */
254: SHFT, SS1, SHFT, SS0, SS0, SS0, SS0, SS0, /* 56 - 63 */
255: SS0, SS0, SS0, SS0, SS0, SHFT, KEY, KEY, /* 64 - 71 */
256: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */
257: KEY, KEY, KEY, KEY, SS0, SS0, SES, SS0, /* 80 - 87 */
258: SS0
259: };
260:
261: /*
262: * Load entry point.
263: * Do reset the keyboard because it gets terribly munged
264: * if you type during the boot.
265: */
266: isload()
267: {
268: register short i; /* was: int i */
269: register HWentry **hw;
270: register VTDATA *vp;
271:
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: static char *deffuncs[] = {
425: "\33[1x\377", /* F1 */
426: "\33[2x\377", /* F2 */
427: "\33[3x\377", /* F3 */
428: "\33[4x\377", /* F4 */
429: "\33[5x\377", /* F5 */
430: "\33[6x\377", /* F6 */
431: "\33[7x\377", /* F7 */
432: "\33[8x\377", /* F8 */
433: "\33[9x\377", /* F9 */
434: "\33[0x\377", /* F10 - historical value */
435: "\33[1y\377", /* F11 */
436: "\33[2y\377", /* F12 */
437: "\33[3y\377", /* F13 */
438: "\33[4y\377", /* F14 */
439: "\33[5y\377", /* F15 */
440: "\33[6y\377", /* F16 */
441: "\33[7y\377", /* F17 */
442: "\33[8y\377", /* F18 */
443: "\33[9y\377", /* F19 */
444: "\33[0y\377" /* F20 */
445: };
446:
447: /*
448: * Open routine.
449: */
450: isopen(dev, mode)
451: dev_t dev;
452: unsigned int mode;
453: {
454: register int s;
455: register TTY *tp;
456: int index = vtindex(dev);
457:
458: PRINTV("isopen: %x\n", dev);
459: if (index < 0 || index >= vtcount) {
460: u.u_error = ENXIO;
461: return;
462: }
463:
464: tp = vttty[index];
465: if ((tp->t_flags&T_EXCL) != 0 && !super()) {
466: u.u_error = ENODEV;
467: return;
468: }
469: ttsetgrp(tp, dev, mode);
470:
471: s = sphi();
472: if (tp->t_open++ == 0) {
473: initkeys(); /* init function keys */
474: tp->t_flags = T_CARR; /* indicate "carrier" */
475: ttopen(tp);
476: }
477: spl(s);
478: #if 0
479: updleds(); /* update keyboard status LEDS */
480: #endif
481: }
482:
483: /* Init function keys */
484: initkeys()
485: { register int i;
486: register char *cp1, *cp2;
487:
488: for (i=0; i<NFKEY; i++)
489: isfval[i] = 0; /* clear function key buffer */
490: cp2 = isfbuf; /* pointer to key buffer */
491: for (i=0; i<NFKEY; i++)
492: { isfval[i] = cp2; /* save pointer to key string */
493: cp1 = deffuncs[i]; /* get init string pointer */
494: while ((*cp2++ = *cp1++) != -1) /* copy key data */
495: if (cp2 >= &isfbuf[NFBUF-3]) /* overflow? */
496: return;
497: }
498: }
499:
500: void isvtswitch(); /* deferred virtual terminal switch */
501:
502: /*
503: * Close a tty.
504: */
505: isclose(dev)
506: {
507: register int s;
508: int index = vtindex(dev);
509: register TTY *tp = vttty[index];
510:
511: if (--tp->t_open == 0)
512: ttclose(tp);
513:
514: }
515:
516: /*
517: * Read routine.
518: */
519: isread(dev, iop)
520: dev_t dev;
521: IO *iop;
522: {
523: int index = vtindex(dev);
524: register TTY *tp = vttty[index];
525:
526: ttread(tp, iop, 0);
527: if (tp->t_oq.cq_cc)
528: mmtime(tp);
529: }
530:
531: /*
532: * Ioctl routine.
533: */
534: isioctl(dev, com, vec)
535: dev_t dev;
536: struct sgttyb *vec;
537: {
538: register int s;
539:
540: switch(com) {
541: case TIOCSETF:
542: case TIOCGETF:
543: isfunction(com, (char *)vec);
544: goto ioc_done;;
545: case TIOCSHIFT: /* switch left-SHIFT and "\" */
546: lshiftkb = LSHIFTA; /* alternate values */
547: lmaptab[41] = '\\';
548: lmaptab[42] = XXX;
549: umaptab[41] = '|';
550: umaptab[42] = XXX;
551: smaptab[41] = SS1;
552: smaptab[42] = SHFT;
553: goto ioc_done;;
554: case TIOCCSHIFT: /* normal (default) left-SHIFT and "\" */
555: lshiftkb = LSHIFT; /* normal values */
556: lmaptab[41] = XXX;
557: lmaptab[42] = '\\';
558: umaptab[41] = XXX;
559: umaptab[42] = '|';
560: smaptab[41] = SHFT;
561: smaptab[42] = SS1;
562: goto ioc_done;;
563: }
564: s = sphi();
565: ttioctl(vttty[vtindex(dev)], com, vec);
566: spl(s);
567:
568: ioc_done:
569: return;
570: }
571:
572: /*
573: * Set and receive the function keys.
574: */
575: isfunction(c, v)
576: int c;
577: char *v;
578: {
579: register char *cp;
580: register int i;
581:
582: if (c == TIOCGETF) {
583: for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++)
584: putubd(v++, *cp);
585: } else {
586: for (i=0; i<NFKEY; i++) /* zap current settings */
587: isfval[i] = 0;
588: cp = isfbuf; /* pointer to key buffer */
589: for (i=0; i<NFKEY; i++) {
590: isfval[i] = cp; /* save pointer to key string */
591: while ((*cp++ = getubd(v++)) != -1) /* copy key data */
592: if (cp >= &isfbuf[NFBUF-3]) /* overflow? */
593: return;
594: }
595: }
596: }
597:
598:
599: /*
600: * Poll routine.
601: */
602: ispoll( dev, ev, msec )
603: dev_t dev;
604: int ev;
605: int msec;
606: {
607: register TTY *tp = vttty[vtindex(dev)];
608:
609: return ttpoll(tp, ev, msec);
610: }
611:
612: /*
613: * Receive interrupt.
614: */
615: isrint()
616: {
617: register int c;
618: register int s;
619: register int r;
620: int savests;
621: int update_leds = 0;
622:
623: /*
624: * Schedule raw input handler if not already active.
625: */
626: if ( isbusy == 0 ) {
627: isbusy = 1;
628: defer(isbatch, vttty[vtactive]);
629: }
630:
631: /*
632: * Pull character from the data
633: * port. Pulse the KBFLAG in the control
634: * port to reset the data buffer.
635: */
636: r = inb(KBDATA) & 0xFF;
637: c = inb(KBCTRL);
638: outb(KBCTRL, c|KBFLAG);
639: outb(KBCTRL, c);
640: #if KBDEBUG
641: printf("kbd: %d\n", r); /* print scan code/direction */
642: #endif
643: if (ledcmd) {
644: ledcmd = 0;
645: if (r == KBACK) { /* output to status LEDS */
646: c = scrollkb & 1;
647: if (shift & NMLS)
648: c |= 2;
649: if (shift & CPLS)
650: c |= 4;
651: outb(KBDATA, c);
652: }
653: return;
654: }
655: if (extended > 0) { /* if multi-character seq, */
656: --extended; /* ... ignore this char */
657: return;
658: }
659: switch (r) {
660: case EXTENDED0: /* 0xE0 prefix found */
661: ext0seen = 1;
662: return;
663: case EXTENDED1: /* ignore extended sequences */
664: extended = 5;
665: return;
666: case 0xFF: /* Overrun */
667: return;
668: }
669:
670: if (ext0seen) {
671: ext0seen = 0;
672: extmode = 1;
673: } else
674: extmode = 0;
675:
676: c = (r & KEYSC) - 1;
677: /*
678: * Check for reset.
679: */
680: if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS))
681: boot();
682:
683: /*
684: * Track "shift" keys.
685: */
686: s = smaptab[c];
687: if (s&SHFT) {
688: if (r&KEYUP) { /* "shift" released */
689: if (c == RSHIFT)
690: shift &= ~SRS;
691: else if (c == lshiftkb)
692: shift &= ~SLS;
693: else if (c == CTRLkb)
694: shift &= ~CTS;
695: else if (c == ALTkb)
696: shift &= extmode ? ~AGS : ~ALS;
697: } else { /* "shift" pressed */
698: if (c == lshiftkb)
699: shift |= SLS;
700: else if (c == RSHIFT)
701: shift |= SRS;
702: else if (c == CTRLkb)
703: shift |= CTS;
704: else if (c == ALTkb)
705: shift |= extmode ? AGS : ALS;
706: else if (c == CAPLOCK) {
707: shift ^= CPLS; /* toggle cap lock */
708: updleds();
709: } else if (c == NUMLOCK) {
710: shift ^= NMLS; /* toggle num lock */
711: updleds();
712: }
713: }
714: return;
715: }
716:
717: /*
718: * No other key up codes of interest.
719: */
720: if (r&KEYUP)
721: return;
722:
723: /*
724: * Map character, based on the
725: * current state of the shift, control, alt graphics,
726: * meta (ALT) and lock flags.
727: */
728: if (shift & AGS) /* Alt Graphics ? */
729: c = agmaptab[c];
730: else if (shift & CTS) {
731: if (s == CTS) /* Map Ctrl (BS | NL) */
732: c = (c == BACKSP) ? 0x7F : 0x0A;
733: else if (s==SS1 || s==LET) /* Normal Ctrl map */
734: c = umaptab[c]&0x1F; /* Clear bits 5-6 */
735: else { if (s==KEY || s==SS0)
736: vtnumeric(r);
737: return; /* Ignore this char */
738: }
739: } else if (s &= shift) {
740: if (shift & SES) { /* if shift on */
741: if (s & (CPLS|NMLS)) /* if caps/num lock */
742: c = lmaptab[c]; /* use unshifted */
743: else
744: c = umaptab[c]; /* use shifted */
745: } else { /* if shift not on */
746: if (s & (CPLS|NMLS)) /* if caps/num lock */
747: c = umaptab[c]; /* use shifted */
748: else
749: c = lmaptab[c]; /* use unshifted */
750: }
751: } else
752: c = lmaptab[c]; /* use unshifted */
753:
754: /*
755: * Act on character.
756: */
757: if (c == XXX)
758: return; /* char to ignore */
759:
760: if (c != SPC) { /* not special char? */
761: if (shift & ALS) /* ALT (meta bit)? */
762: c |= 0x80; /* set meta */
763: isin(c); /* send the char */
764: } else
765: update_leds += isspecial(r); /* special chars */
766: if (update_leds) {
767: savests = sphi();
768: outb(KBDATA, LEDCMD);
769: ledcmd = 1;
770: spl(savests);
771: }
772: }
773:
774: /*
775: * Process numeric keypad for virtual terminals.
776: */
777: vtnumeric(c)
778: int c;
779: {
780: switch (c) {
781: case 71: case 72: case 73: /* ctrl 7/8/9 (vt7, vt8, vt9) */
782: defer(isvtswitch, c + 16);
783: break;
784: case 74: /* ctrl - */
785: defer(isvtswitch, vtp);
786: break;
787: case 75: case 76: case 77: /* ctrl 4/5/6 (vt5, vt6, vt7) */
788: defer(isvtswitch, c + 10);
789: break;
790: case 78: /* ctrl + */
791: defer(isvtswitch, vtn);
792: break;
793: case 79: case 80: case 81: /* ctrl 1/2/3 */
794: defer(isvtswitch, c + 2);
795: break;
796: case 82: /* ctrl 0 (vt0) */
797: defer(isvtswitch, vt0);
798: break;
799: case 83: /* ctrl del (toggle) */
800: c = vtt;
801: defer(isvtswitch, vtt);
802: break;
803: }
804: }
805:
806: /*
807: * Handle special input sequences.
808: * The character passed is the key number.
809: *
810: * The keypad is translated by the following table,
811: * the first entry is the normal sequence, the second the shifted,
812: * and the third the alternate keypad sequence.
813: */
814: static char *keypad[][3] = {
815: { "\33[H", "7", "\33?w" }, /* 71 */
816: { "\33[A", "8", "\33?x" }, /* 72 */
817: { "\33[V", "9", "\33?y" }, /* 73 */
818: { "\33[D", "4", "\33?t" }, /* 75 */
819: { "\0337", "5", "\33?u" }, /* 76 */
820: { "\33[C", "6", "\33?v" }, /* 77 */
821: { "\33[24H","1", "\33?q" }, /* 79 */
822: { "\33[B", "2", "\33?r" }, /* 80 */
823: { "\33[U", "3", "\33?s" }, /* 81 */
824: { "\33[@", "0", "\33?p" }, /* 82 */
825: { "\33[P", ".", "\33?n" } /* 83 */
826: };
827:
828: isspecial(c)
829: int c;
830: {
831: register char *cp;
832: register int s;
833: int update_leds = 0;
834:
835: cp = 0;
836:
837: switch (c) {
838: case 15: /* cursor back tab */
839: cp = "\033[Z";
840: break;
841: case 53:
842: if (extmode)
843: cp = "/";
844: else if (shift & SES)
845: cp = "_";
846: else
847: cp = "-";
848: break;
849: case 55: /* ignore PrtScr */
850: if (!extmode)
851: cp = "*";
852: break;
853: case 59: case 60: case 61: case 62: case 63: /* Function keys */
854: case 64: case 65: case 66:
855: /* offset to function string */
856: /* Magic numbers 21 and 61 to mach vtnkb constants */
857: if ( shift & ALS )
858: defer(isvtswitch, c + 21);
859: else
860: cp = isfval[c-59];
861: break;
862: case 67: case 68:
863: /* offset to function string */
864: if ( shift & ALS )
865: defer(isvtswitch, c + 61);
866: else
867: cp = isfval[c-59];
868: break;
869: case 70: /* Scroll Lock -- stop/start output */
870: {
871: static char cbuf[2];
872:
873: cp = &cbuf[0]; /* working buffer */
874: if (!(vttty[vtactive]->t_sgttyb.sg_flags
875: & RAWIN)) { /* not if in RAW mode */
876:
877: ++update_leds;
878: if (vttty[vtactive]->t_flags&T_STOP){/* output stopped? */
879: cbuf[0] = vttty[vtactive]->t_tchars.t_startc;
880: scrollkb = 0;
881: } else {
882: cbuf[0] = vttty[vtactive]->t_tchars.t_stopc;
883: scrollkb = 1;
884: }
885: }
886: break;
887: }
888:
889: case 79: /* 1/End */
890: case 80: /* 2/DOWN */
891: case 81: /* 3/PgDn */
892: case 82: /* 0/Ins */
893: case 83: /* ./Del */
894: --c; /* adjust code */
895: case 75: /* 4/LEFT */
896: case 76: /* 5 */
897: case 77: /* 6/RIGHT */
898: --c; /* adjust code */
899: case 71: /* 7/Home/Clear */
900: case 72: /* 8/UP */
901: case 73: /* 9/PgUp */
902: s = 0; /* start off with normal keypad */
903: if (shift & NMLS) /* num lock? */
904: s = 1; /* set shift pad */
905: if (shift & SES) /* shift? */
906: s ^= 1; /* toggle shift pad */
907: if (shift & AKPS) /* alternate pad? */
908: s = 2; /* set alternate pad */
909: if (extmode) /* not from keypad? */
910: s = 0; /* force normal sequence */
911: cp = keypad[c-71][s]; /* get keypad value */
912: break;
913: }
914: if (cp) /* send string */
915: while ((*cp != 0) && (*cp != -1))
916: isin( *cp++ & 0377 );
917: return update_leds;
918: }
919:
920: /**
921: *
922: * void
923: * ismmfunc( c ) -- process keyboard related output escape sequences
924: * char c;
925: */
926: void
927: ismmfunc(c)
928: register int c;
929: {
930: switch (c) {
931: case 't': /* Enter numlock */
932: shift |= NMLS;
933: updleds(); /* update LED status */
934: break;
935: case 'u': /* Leave numlock */
936: shift &= ~NMLS;
937: updleds(); /* update LED status */
938: break;
939: case '=': /* Enter alternate keypad */
940: shift |= AKPS;
941: break;
942: case '>': /* Exit alternate keypad */
943: shift &= ~AKPS;
944: break;
945: case 'c': /* Reset terminal */
946: islock = 0;
947: shift = 0;
948: initkeys();
949: updleds(); /* update LED status */
950: break;
951: }
952: }
953:
954: /**
955: *
956: * void
957: * isin( c ) -- append character to raw input silo
958: * char c;
959: */
960: static
961: isin( c )
962: register int c;
963: {
964: int cache_it = 1;
965: TTY * tp = vttty[vtactive];
966:
967: /*
968: * If using software incoming flow control, process and
969: * discard t_stopc and t_startc.
970: */
971: if (ISIXON) {
972: #if _I386
973: if (ISSTART || (ISIXANY && ISXSTOP)) {
974: tp->t_flags &= ~(T_STOP | T_XSTOP);
975: ttstart(tp);
976: cache_it = 0;
977: } else if (ISSTOP) {
978: if ((tp->t_flags&T_STOP) == 0)
979: tp->t_flags |= (T_STOP | T_XSTOP);
980: cache_it = 0;
981: }
982: #else
983: if (ISSTOP) {
984: if ((tp->t_flags&T_STOP) == 0)
985: tp->t_flags |= T_STOP;
986: cache_it = 0;
987: }
988: if (ISSTART) {
989: tp->t_flags &= ~T_STOP;
990: ttstart(tp);
991: cache_it = 0;
992: }
993: #endif
994: }
995: /*
996: * If the tty is not open the character is
997: * just tossed away.
998: */
999: if (vttty[vtactive]->t_open == 0)
1000: return;
1001:
1002:
1003: /*
1004: * Cache received character.
1005: */
1006: if (cache_it) {
1007: in_silo.si_buf[ in_silo.si_ix ] = c;
1008:
1009: if ( ++in_silo.si_ix >= sizeof(in_silo.si_buf) )
1010: in_silo.si_ix = 0;
1011: }
1012: }
1013:
1014: /**
1015: *
1016: * void
1017: * isbatch() -- raw input conversion routine
1018: *
1019: * Action: Enable the video display.
1020: * Canonize the raw input silo.
1021: *
1022: * Notes: isbatch() was scheduled as a deferred process by isrint().
1023: */
1024: static void
1025: isbatch( tp )
1026: register TTY * tp;
1027: {
1028: register int c;
1029: static int lastc;
1030: VTDATA *vp = tp->t_ddp;
1031:
1032: /*
1033: * Ensure video display is enabled.
1034: */
1035: if (vp->vmm_visible)
1036: mm_von(vp);
1037:
1038: isbusy = 0;
1039:
1040: /*
1041: * Process all cached characters.
1042: */
1043: while ( in_silo.si_ix != in_silo.si_ox ) {
1044:
1045: /*
1046: * Get next cached char.
1047: */
1048: c = in_silo.si_buf[ in_silo.si_ox ];
1049:
1050: if ( in_silo.si_ox >= sizeof(in_silo.si_buf) - 1 )
1051: in_silo.si_ox = 0;
1052: else
1053: in_silo.si_ox++;
1054:
1055: if ( (islock == 0) || ISINTR || ISQUIT ) {
1056: ttin( tp, c );
1057: }
1058:
1059: else if ( (c == 'b') && (lastc == '\033') ) {
1060: islock = 0;
1061: ttin( tp, lastc );
1062: ttin( tp, c );
1063: }
1064:
1065: else if ( (c == 'c') && (lastc == '\033') ) {
1066: ttin( tp, lastc );
1067: ttin( tp, c );
1068: }
1069:
1070: else
1071: putchar('\007');
1072:
1073: lastc = c;
1074: }
1075: }
1076:
1077: /*
1078: * update the keyboard status LEDS
1079: */
1080: updleds()
1081: {
1082: int s;
1083:
1084: s = sphi();
1085: outb(KBDATA, LEDCMD);
1086: ledcmd = 1;
1087: spl(s);
1088: }
1089:
1090: /*
1091: * unlock the scroll in case an interrupt character is received
1092: */
1093: kbunscroll()
1094: {
1095: scrollkb = 0;
1096: updleds();
1097: }
1098: int
1099: VTttyinit(i)
1100: int i;
1101: {
1102: TTY *tp;
1103:
1104: /*
1105: * get pointer to TTY structure from kernal memory space
1106: */
1107: if( (tp = vttty[i] = (TTY *)kalloc(sizeof (TTY))) == NULL )
1108: return(0);
1109: PRINTV( " vttty[%d]: @%x, ", i, tp );
1110:
1111: #if FAR_TTY
1112: /*
1113: * get pointers to the buffers pointed to by the TTY structure
1114: * from user memory space
1115: */
1116: tp->t_buffer = salloc( (fsize_t)NCIB+2*SI_BUFSIZ, SFSYST|SFNSWP );
1117: tp->t_ib = 0;
1118: tp->t_rawin.si_buf = NCIB;
1119: tp->t_rawout.si_buf = NCIB+SI_BUFSIZ;
1120: #endif
1121: tp->t_param = NULL;
1122: tp->t_start = &mmstart;
1123:
1124: #ifndef _I386
1125: #if VT_MAJOR == KB_MAJOR
1126: tp->t_cs_sel = 0;
1127: #else
1128: tp->t_cs_sel = cs_sel();
1129: #endif
1130: #endif
1131: tp->t_ddp = vtdata[i];
1132: PRINTV( "data @%lx\n", tp->t_ddp );
1133: return(1);
1134: }
1135:
1136: vtdatainit(vp)
1137: VTDATA *vp;
1138: {
1139: #ifndef _I386
1140: VT_FARSEG vt_farseg;
1141: #endif
1142: /*
1143: * vtdata init - vmm part
1144: */
1145: vp->vmm_invis = -1; /* cursor invisible */
1146:
1147: #ifdef _I386
1148: vp->vt_buffer = kalloc( TEXTBLOCK );
1149: vp->vmm_seg = vp->vmm_mseg = ds_sel();
1150: vp->vmm_off = vp->vmm_moff = vp->vt_buffer;
1151: #else
1152: vp->vt_buffer = salloc ( (fsize_t)TEXTBLOCK, SFSYST|SFNSWP|SFHIGH );
1153: vp->vmm_seg = vp->vmm_mseg = FP_SEG( vp->vt_buffer->vt_faddr );
1154: vp->vmm_off = vp->vmm_moff = FP_OFF( vp->vt_buffer->vt_faddr );
1155: #endif
1156: PRINTV( "vt@%x init index %d,%d), seg %x, off %x\n",
1157: vp, vp->vt_ind, vp->vmm_mseg, vp->vmm_moff );
1158: /*
1159: * vtdata init - vnkb part
1160: */
1161: /* Make the first memory block active, if present */
1162: vp->vnkb_lastc = 0;
1163: vp->vnkb_fnkeys = 0;
1164: vp->vnkb_funkeyp = 0;
1165: vp->vnkb_fk_loaded = 0; /* no Fn keys yet */
1166: }
1167:
1168: /*
1169: * Given device number, return index for vtdata[], vttty[], etc.
1170: *
1171: * Major number must be VT_MAJOR for CPU to get here.
1172: *
1173: * Minor Number Index Value
1174: * ----- ------ ----- -----
1175: * 0000 0000 vtactive ... device (2,0) is the active screen
1176: * 0000 0001 0
1177: * 0000 0010 1
1178: * 0000 0011 2
1179: * ....
1180: * 0000 1111 14
1181: *
1182: * 0100 xxxx xxxx ... color devices only
1183: * 0101 xxxx xxxx - (# of color devices found) ... monochrome only
1184: *
1185: * Return value is in range 0 to vtcount-1 for valid minor numbers,
1186: * -1 for invalid minor numbers.
1187: */
1188: int
1189: vtindex( dev )
1190: dev_t dev;
1191: {
1192: register int ret = -1;
1193:
1194: if ( dev & VT_PHYSICAL ) {
1195: int hw = ( dev >> 4 ) & 3;
1196: int hw_index = dev & 0x0F;
1197:
1198: if( hw_index < vtHWtable[hw]->found )
1199: ret = vtHWtable[hw]->start + hw_index;
1200: } else {
1201: int lg_index = dev & 0x0F;
1202:
1203: if (lg_index == 0)
1204: ret = vtactive;
1205: if (lg_index > 0 && lg_index <= vtcount )
1206: ret = lg_index-1;
1207: }
1208: if (ret >= 0)
1209: ret %= vtcount;
1210: else
1211: PRINTV( "vtindex: (%x) %d. invalid !\n", dev, ret );
1212: return ret;
1213: }
1214:
1215: /*
1216: *
1217: * void
1218: * isvtswitch() -- deferred virtual terminal switch
1219: *
1220: * Action: - save current shift key status
1221: * - determine new active virtual terminal
1222: * - deactivate shift key status of the current virtual terminal
1223: * - deactivate current virtual terminal
1224: * - activate shift key status of the new virtual terminal with
1225: * the previously saved shift key status
1226: * - activate new virtual terminal
1227: *
1228: * Notes: isvtswitch() was scheduled as a deferred process by
1229: * process_key() which is a function called by isrint().
1230: */
1231: void
1232: isvtswitch(key_val)
1233: {
1234: register int new_index, i;
1235: unsigned lockshift, nolockshift;
1236: VTDATA *vp = vtdata[vtactive];
1237: VTDATA *vp_old, *vp_new;
1238: static int vtprevious;
1239:
1240: lockshift = shift & (CPLS | NMLS);
1241: nolockshift = shift & ~(CPLS | NMLS);
1242: PRINTV( "F%d: %d", key_val, vtactive );
1243:
1244: switch (key_val) {
1245: case VTKEY_HOME:
1246: new_index = 0;
1247: break;
1248: case VTKEY_NEXT:
1249: new_index = vtactive;
1250: for( i = 0; i < vtcount; ++i ) {
1251: new_index = ++new_index % vtcount;
1252: if( vttty[new_index]->t_open )
1253: break;
1254: }
1255: break;
1256: case VTKEY_PREV:
1257: new_index = vtactive;
1258: for( i = 0; i < vtcount; ++i ) {
1259: new_index = (--new_index+vtcount) % vtcount;
1260: if( vttty[new_index]->t_open )
1261: break;
1262: }
1263: break;
1264: case VTKEY_TOGL:
1265: new_index = vtprevious;
1266: break;
1267: default:
1268: new_index = vtindex(vtkey_to_dev(key_val));
1269: if( new_index < 0) {
1270: putchar( '\007' );
1271: return;
1272: }
1273: }
1274:
1275: T_CON(8, printf("%d->%d ", vtactive, new_index));
1276: if( new_index == vtactive )
1277: return;
1278:
1279: /* Save which locking shift states are in effect. */
1280:
1281: vp_old = vtdata[vtactive];
1282: vp_new = vtdata[new_index];
1283:
1284: vp_old->vnkb_shift = lockshift;
1285: vtdeactivate(vp_new, vp_old); /* deactivate old virtual terminal */
1286:
1287: /* Restore shift lock state, append current momentary shift state. */
1288: shift = vp_new->vnkb_shift | nolockshift;
1289:
1290: vtactivate(vp_new); /* activate new virtual terminal */
1291: updterminal(new_index);
1292: vtprevious = vtactive;
1293: vtactive = new_index; /* update vtactive */
1294: }
1295:
1296: vtdeactivate(vp_new, vp_old)
1297: register VTDATA *vp_new, *vp_old;
1298: {
1299: register i;
1300: VTDATA *vpi;
1301:
1302: /* store old screen contents in memory segment */
1303: FFCOPY( vp_old->vmm_voff, vp_old->vmm_vseg,
1304: vp_old->vmm_moff, vp_old->vmm_mseg, TEXTBLOCK );
1305:
1306: /*
1307: * if changing to another screen on same video board
1308: * for all screens on same board as new screen
1309: * deactivate, but don't update
1310: * else - changing to a screen on different board
1311: * for all screens NOT on same board as new screen
1312: * deactivate, but don't update
1313: */
1314: if ( vp_old->vmm_port == vp_new->vmm_port ) {
1315: T_CON(8, printf("deactivate on %x ", vp_new->vmm_port));
1316: for (i = 0; i < vtcount; ++i) {
1317: vpi = vtdata[i];
1318: if ( vpi->vmm_port == vp_new->vmm_port ) {
1319: /* deactivate, but don't update */
1320: vpi->vmm_invis = ~0;
1321: vpi->vmm_visible = VNKB_FALSE;
1322: vpi->vmm_seg = vpi->vmm_mseg;
1323: vpi->vmm_off = vpi->vmm_moff;
1324: if( vpi->vmm_seg == 0 )
1325: printf( "[1]vpi->vmm_seg = 0\n" );
1326: PRINTV( "vt.back %d. seg %x off %x\n", i,
1327: vpi->vmm_seg, vpi->vmm_off );
1328: }
1329: }
1330: } else {
1331: T_CON(8, printf("deactivate %x->%x ",
1332: vp_old->vmm_port, vp_new->vmm_port));
1333: for (i = 0; i < vtcount; ++i) {
1334: vpi = vtdata[i];
1335: if ( (vpi->vmm_port != vp_new->vmm_port)
1336: && (vpi->vmm_invis == 0) ) {
1337: /* update, but don't deactivate */
1338: vpi->vmm_invis = ~0;
1339: updscreen(i);
1340: }
1341: }
1342: }
1343: }
1344:
1345: vtactivate(vp)
1346: VTDATA *vp;
1347: {
1348: register VTDATA *vpi;
1349: register i;
1350:
1351: /*
1352: * copy from screen contents from heap segment to video memory
1353: * only if necessary
1354: */
1355: if ( vp->vmm_visible == VNKB_FALSE )
1356: FFCOPY( vp->vmm_moff, vp->vmm_mseg,
1357: vp->vmm_voff, vp->vmm_vseg, TEXTBLOCK );
1358:
1359: for (i = 0; i < vtcount; ++i) {
1360: vpi = vtdata[i];
1361: if (vpi->vmm_port == vp->vmm_port) {
1362: vpi->vmm_invis = -1;
1363: vpi->vmm_visible = VNKB_FALSE;
1364: vpi->vmm_seg = vpi->vmm_mseg;
1365: vpi->vmm_off = vpi->vmm_moff;
1366: if( vpi->vmm_seg == 0 )
1367: printf( "[2]vpi->vmm_seg = 0\n" );
1368: PRINTV( "vt.back seg %x off %x\n",
1369: vpi->vmm_seg, vpi->vmm_off );
1370: }
1371: }
1372: /*
1373: * Set new active terminal
1374: */
1375: vp->vmm_invis = 0;
1376: vp->vmm_visible = VNKB_TRUE;
1377: vp->vmm_seg = vp->vmm_vseg;
1378: vp->vmm_off = vp->vmm_voff;
1379: if( vp->vmm_seg == 0 )
1380: printf( "vp->vmm_seg = 0\n" );
1381: }
1382:
1383: /*
1384: * update the terminal to match vtactive
1385: */
1386: updterminal(index)
1387: int index;
1388: {
1389: updscreen(index);
1390: updleds();
1391: }
1392:
1393: #undef si
1394: asmdump( cs, ds, es, di, si, bp, sp, bx, dx, cx, i, ip, ax )
1395: int cs, ds, es, di, si, bp, sp, bx, dx, cx, i, ip, ax;
1396: {
1397: if( vt_verbose < 2 )
1398: return;
1399:
1400: printf( "asmdump %d: es %x, ds %x, cs:ip %x:%x\n", i, es, ds, cs, ip );
1401: printf( " ax %x, bx %x, cx %x, dx %x\n", ax, bx, cx, dx );
1402: printf( " di %x, si %x, bp %x, sp %d\n", di, si, bp, sp );
1403: #if USING_RS232
1404: if( vt_verbose > 2 )
1405: getchar();
1406: #endif
1407: }
1408:
1409: vtdataprint( vp )
1410: register VTDATA *vp;
1411: {
1412: if( vt_verbose < 2 )
1413: return;
1414:
1415: printf( "VTDATA: @%x, esc %x, func %x()\n",
1416: vp, vp->vmm_esc, vp->vmm_func );
1417: printf( " hw: port %x, seg %x, off %x\n",
1418: vp->vmm_port, vp->vmm_vseg, vp->vmm_voff );
1419: printf( " memory: size %x, seg %x, off %x\n",
1420: 0/*vp->vmm_size*/, vp->vmm_mseg, vp->vmm_moff );
1421: printf( " cursor: seg %x, off %x, visible %d\n",
1422: vp->vmm_seg, vp->vmm_off, !vp->vmm_invis );
1423: printf( " row %d, col %d = offset %d.\n",
1424: vp->vmm_rowl, vp->vmm_col, vp->vmm_pos );
1425: printf( " saved row %d, col %d\n",
1426: vp->vmm_srow, vp->vmm_scol );
1427: printf( " screen: visible %d, attr %x, wrap %d, slow %d\n",
1428: vp->vmm_visible, vp->vmm_attr, vp->vmm_wrap, vp->vmm_slow );
1429: printf( " row base %d, end %d, limit %d\n",
1430: vp->vmm_brow, vp->vmm_erow, vp->vmm_lrow );
1431: printf( " row initial base %d, initial end %d\n",
1432: vp->vmm_ibrow, vp->vmm_ierow );
1433: #if USING_RS232
1434: if( vt_verbose > 2 )
1435: getchar();
1436: #endif
1437: }
1438:
1439: FFCOPY( src_off, src_seg, dst_off, dst_seg, count )
1440: {
1441: register i;
1442:
1443: #if 0
1444: i = ffcopy( src_off, src_seg, dst_off, dst_seg, count );
1445: #else
1446: for( i = 0; i < count; i += 2 ) {
1447: register word = ffword( src_off, src_seg );
1448: sfword( dst_off, dst_seg, word );
1449: src_off += 2;
1450: dst_off += 2;
1451: }
1452: #endif
1453: return i;
1454: }
1455:
1456: /*
1457: * Given a function key number (e.g. vt0),
1458: * return the corresponding minor device number.
1459: *
1460: * Assume valid key number (VTKEY(fnum) is true) by the time we get here.
1461: */
1462: int
1463: vtkey_to_dev(fnum)
1464: int fnum;
1465: {
1466: if (fnum >=vt0 && fnum <= vt15)
1467: return fnum-vt0+1;
1468: if (fnum >=color0 && fnum <= color15)
1469: return (fnum-color0)|(VT_PHYSICAL|VT_HW_COLOR);
1470: if (fnum >=mono0 && fnum <= mono15)
1471: return (fnum-mono0)|(VT_PHYSICAL|VT_HW_MONO);
1472: printf("vtkey_to_dev(%d)! ", fnum);
1473: return 0;
1474: }
1475: /* End of vtkb_f.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.