1 /*
2 * Copyright (c) 1999, 2000 Hellmuth Michaelis
3 *
4 * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
5 *
6 * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner.
7 *
8 * Copyright (c) 1993 Charles Hannum.
9 *
10 * All rights reserved.
11 *
12 * Parts of this code regarding the NetBSD interface were written
13 * by Charles Hannum.
14 *
15 * This code is derived from software contributed to Berkeley by
16 * William Jolitz and Don Ahn.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by
29 * Hellmuth Michaelis, Brian Dunford-Shore, Joerg Wunsch, Scott Turner
30 * and Charles Hannum.
31 * 4. The name authors may not be used to endorse or promote products
32 * derived from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
35 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
39 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
40 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
41 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 */
45
46 /*---------------------------------------------------------------------------*
47 *
48 * pcvt_drv.c VT220 Driver Main Module / OS - Interface
49 * ---------------------------------------------------------
50 *
51 * Last Edit-Date: [Sat Jul 15 15:06:06 2000]
52 *
53 * $FreeBSD: releng/5.0/sys/i386/isa/pcvt/pcvt_drv.c 94275 2002-04-09 11:18:46Z phk $
54 *
55 *---------------------------------------------------------------------------*/
56
57 #define MAIN
58 #include <i386/isa/pcvt/pcvt_hdr.h>
59 #undef MAIN
60
61
62 #include <sys/resource.h>
63 #include <sys/bus.h>
64 #include <sys/rman.h>
65
66 #include <machine/resource.h>
67 #include <machine/bus.h>
68
69 #include <isa/isareg.h>
70 #include <isa/isavar.h>
71
72 static kbd_callback_func_t pcvt_event;
73 static int pcvt_kbd_wptr = 0;
74 static u_char pcvt_timeout_scheduled = 0;
75
76 static void vgapelinit(void);
77 static void detect_kbd(void *arg);
78 static void pcvt_start(register struct tty *tp);
79 static int pcvt_param(struct tty *tp, struct termios *t);
80
81 static cn_probe_t pcvt_cn_probe;
82 static cn_init_t pcvt_cn_init;
83 static cn_term_t pcvt_cn_term;
84 static cn_getc_t pcvt_cn_getc;
85 static cn_checkc_t pcvt_cn_checkc;
86 static cn_putc_t pcvt_cn_putc;
87
88 CONS_DRIVER(vt, pcvt_cn_probe, pcvt_cn_init, pcvt_cn_term, pcvt_cn_getc,
89 pcvt_cn_checkc, pcvt_cn_putc, NULL);
90
91 static d_open_t pcvt_open;
92 static d_close_t pcvt_close;
93 static d_ioctl_t pcvt_ioctl;
94 static d_mmap_t pcvt_mmap;
95
96 #define CDEV_MAJOR 12
97
98 static struct cdevsw vt_cdevsw = {
99 /* open */ pcvt_open,
100 /* close */ pcvt_close,
101 /* read */ ttyread,
102 /* write */ ttywrite,
103 /* ioctl */ pcvt_ioctl,
104 /* poll */ ttypoll,
105 /* mmap */ pcvt_mmap,
106 /* strategy */ nostrategy,
107 /* name */ "vt",
108 /* maj */ CDEV_MAJOR,
109 /* dump */ nodump,
110 /* psize */ nopsize,
111 /* flags */ D_TTY | D_KQFILTER,
112 /* kqfilter */ ttykqfilter,
113 };
114
115 static int pcvt_probe(device_t dev);
116 static int pcvt_attach(device_t dev);
117 static void pcvt_identify (driver_t *driver, device_t parent);
118
119 static device_method_t pcvt_methods[] = {
120 DEVMETHOD(device_identify, pcvt_identify),
121 DEVMETHOD(device_probe, pcvt_probe),
122 DEVMETHOD(device_attach, pcvt_attach),
123 DEVMETHOD(bus_print_child, bus_generic_print_child),
124 { 0, 0 }
125 };
126
127 static driver_t pcvt_driver = {
128 "vt",
129 pcvt_methods,
130 0
131 };
132
133 static devclass_t pcvt_devclass;
134
135 DRIVER_MODULE(pcvt, isa, pcvt_driver, pcvt_devclass, 0, 0);
136
137 /*---------------------------------------------------------------------------*
138 * driver identify
139 *---------------------------------------------------------------------------*/
140 static void
141 pcvt_identify (driver_t *driver, device_t parent)
142 {
143 BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "vt", 0);
144 }
145
146 /*---------------------------------------------------------------------------*
147 * driver probe
148 *---------------------------------------------------------------------------*/
149 static int
150 pcvt_probe(device_t dev)
151 {
152 int i;
153 device_t bus;
154
155 int unit = device_get_unit(dev);
156
157 /* No pnp support */
158 if(isa_get_vendorid(dev))
159 return ENXIO;
160
161 if(unit != 0)
162 return ENXIO;
163
164 device_set_desc(dev, "pcvt VT220 console driver");
165
166 bus = device_get_parent(dev);
167 bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3b0, 0x30);
168 bus_set_resource(dev, SYS_RES_MEMORY, 0, (u_long) Crtat, 0x8000);
169
170 if (kbd == NULL)
171 {
172 reset_keyboard = 0;
173 kbd_configure(KB_CONF_PROBE_ONLY);
174 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)&vs[unit]);
175 if ((i < 0) || ((kbd = kbd_get_keyboard(i)) == NULL))
176 return 0;
177 }
178 reset_keyboard = 1; /* it's now safe to do kbd reset */
179
180 kbd_code_init();
181
182 return 0;
183 }
184
185 /*---------------------------------------------------------------------------*
186 * driver attach
187 *---------------------------------------------------------------------------*/
188 static int
189 pcvt_attach(device_t dev)
190 {
191 int i;
192 struct resource *port;
193 struct resource *mem;
194
195 int unit = device_get_unit(dev);
196
197 if(unit != 0)
198 return ENXIO;
199
200 i = 0;
201 port = bus_alloc_resource(dev, SYS_RES_IOPORT, &i, 0, ~0, 0,
202 RF_ACTIVE | RF_SHAREABLE);
203
204 i = 0;
205 mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &i, 0, ~0, 0,
206 RF_ACTIVE | RF_SHAREABLE);
207
208 vt_coldmalloc(); /* allocate memory for screens */
209
210 if (kbd == NULL)
211 timeout(detect_kbd, (void *)&vs[unit], hz*2);
212
213 printf("vt%d: ", unit);
214
215 switch(adaptor_type)
216 {
217 case MDA_ADAPTOR:
218 printf("MDA");
219 break;
220
221 case CGA_ADAPTOR:
222 printf("CGA");
223 break;
224
225 case EGA_ADAPTOR:
226 printf("EGA");
227 break;
228
229 case VGA_ADAPTOR:
230 printf("%s VGA, ", (char *)vga_string(vga_type));
231 if(can_do_132col)
232 printf("80/132 columns");
233 else
234 printf("80 columns");
235 vgapelinit();
236 break;
237
238 default:
239 printf("unknown");
240 break;
241 }
242
243 if(color == 0)
244 printf(", mono");
245 else
246 printf(", color");
247
248 printf(", %d screens, ", totalscreens);
249
250 switch(keyboard_type)
251 {
252 case KB_AT:
253 printf("AT-");
254 break;
255
256 case KB_MFII:
257 printf("MF2-");
258 break;
259
260 default:
261 printf("unknown ");
262 break;
263 }
264
265 printf("keyboard\n");
266
267 for(i = 0; i < totalscreens; i++)
268 {
269 ttyregister(&pcvt_tty[i]);
270 vs[i].vs_tty = &pcvt_tty[i];
271 make_dev(&vt_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
272 }
273
274 async_update(UPDATE_START); /* start asynchronous updates */
275
276 return 0;
277 }
278
279 /*---------------------------------------------------------------------------*
280 * driver open
281 *---------------------------------------------------------------------------*/
282 static int
283 pcvt_open(dev_t dev, int flag, int mode, struct thread *td)
284 {
285 register struct tty *tp;
286 register struct video_state *vsx;
287 int s, retval;
288 int winsz = 0;
289 int i = minor(dev);
290
291 vsx = &vs[i];
292
293 if(i >= PCVT_NSCREENS)
294 return ENXIO;
295
296 tp = &pcvt_tty[i];
297
298 dev->si_tty = tp;
299
300 vsx->openf++;
301
302 tp->t_oproc = pcvt_start;
303 tp->t_param = pcvt_param;
304 tp->t_stop = nottystop;
305 tp->t_dev = dev;
306
307 if ((tp->t_state & TS_ISOPEN) == 0)
308 {
309 ttychars(tp);
310 tp->t_iflag = TTYDEF_IFLAG;
311 tp->t_oflag = TTYDEF_OFLAG;
312 tp->t_cflag = TTYDEF_CFLAG;
313 tp->t_lflag = TTYDEF_LFLAG;
314 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
315 pcvt_param(tp, &tp->t_termios);
316 (*linesw[tp->t_line].l_modem)(tp, 1); /* fake connection */
317 winsz = 1; /* set winsize later */
318 }
319 else if (tp->t_state & TS_XCLUDE && suser(td))
320 {
321 return (EBUSY);
322 }
323
324 retval = ((*linesw[tp->t_line].l_open)(dev, tp));
325
326 if(winsz == 1)
327 {
328 /*
329 * The line discipline has clobbered t_winsize if TS_ISOPEN
330 * was clear. (NetBSD PR #400 from Bill Sommerfeld)
331 * We have to do this after calling the open routine, because
332 * it does some other things in other/older *BSD releases -hm
333 */
334
335 s = spltty();
336
337 tp->t_winsize.ws_col = vsx->maxcol;
338 tp->t_winsize.ws_row = vsx->screen_rows;
339 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
340 tp->t_winsize.ws_ypixel = 400;
341
342 splx(s);
343 }
344 return(retval);
345 }
346
347 /*---------------------------------------------------------------------------*
348 * driver close
349 *---------------------------------------------------------------------------*/
350 static int
351 pcvt_close(dev_t dev, int flag, int mode, struct thread *td)
352 {
353 register struct tty *tp;
354 register struct video_state *vsx;
355 int i = minor(dev);
356
357 vsx = &vs[i];
358
359 if(i >= PCVT_NSCREENS)
360 return ENXIO;
361
362 tp = &pcvt_tty[i];
363
364 (*linesw[tp->t_line].l_close)(tp, flag);
365
366 ttyclose(tp);
367
368 vsx->openf = 0;
369
370 #ifdef XSERVER
371 reset_usl_modes(vsx);
372 #endif /* XSERVER */
373
374 return(0);
375 }
376
377 /*---------------------------------------------------------------------------*
378 * driver ioctl
379 *---------------------------------------------------------------------------*/
380 static int
381 pcvt_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
382 {
383 register int error;
384 register struct tty *tp;
385 int i = minor(dev);
386
387 if(i >= PCVT_NSCREENS)
388 return ENXIO;
389
390 tp = &pcvt_tty[i];
391
392 /* note that some ioctl's are global, e.g. KBSTPMAT: There is
393 * only one keyboard and different repeat rates for instance between
394 * sessions are a suspicious wish. If you really need this make the
395 * appropriate variables arrays
396 */
397
398 #ifdef XSERVER
399 if((error = usl_vt_ioctl(dev, cmd, data, flag, td)) >= 0)
400 return error;
401 #endif /* XSERVER */
402
403 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
404 return error;
405
406 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
407 return error;
408
409 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td))
410 != ENOIOCTL)
411 return (error);
412
413 if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
414 return (error);
415
416 return (ENOTTY);
417 }
418
419 /*---------------------------------------------------------------------------*
420 * driver mmap
421 *---------------------------------------------------------------------------*/
422 static int
423 pcvt_mmap(dev_t dev, vm_offset_t offset, int nprot)
424 {
425 if (offset > 0x20000 - PAGE_SIZE)
426 return -1;
427 return i386_btop((0xa0000 + offset));
428 }
429
430 /*---------------------------------------------------------------------------*
431 * timeout handler
432 *---------------------------------------------------------------------------*/
433 static void
434 pcvt_timeout(void *arg)
435 {
436 u_char *cp;
437
438 #if PCVT_SLOW_INTERRUPT
439 int s;
440 #endif
441
442 pcvt_timeout_scheduled = 0;
443
444 #if PCVT_SCREENSAVER
445 pcvt_scrnsv_reset();
446 #endif /* PCVT_SCREENSAVER */
447
448 while (pcvt_kbd_count)
449 {
450 if (((cp = sgetc(1)) != 0) &&
451 (vs[current_video_screen].openf))
452 {
453
454 #if PCVT_NULLCHARS
455 if(*cp == '\0')
456 {
457 /* pass a NULL character */
458 (*linesw[pcvt_ttyp->t_line].l_rint)('\0', pcvt_ttyp);
459 }
460 /* XXX */ else
461 #endif /* PCVT_NULLCHARS */
462
463 while (*cp)
464 (*linesw[pcvt_ttyp->t_line].l_rint)(*cp++ & 0xff, pcvt_ttyp);
465 }
466
467 PCVT_DISABLE_INTR ();
468
469 if (!pcvt_kbd_count)
470 pcvt_timeout_scheduled = 0;
471
472 PCVT_ENABLE_INTR ();
473 }
474
475 return;
476 }
477
478 /*---------------------------------------------------------------------------*
479 * check for keyboard
480 *---------------------------------------------------------------------------*/
481 static void
482 detect_kbd(void *arg)
483 {
484 int unit = (int)arg;
485 int i;
486
487 if (kbd != NULL)
488 return;
489 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
490 if (i >= 0)
491 kbd = kbd_get_keyboard(i);
492 if (kbd != NULL)
493 {
494 reset_keyboard = 1; /* ok to reset the keyboard */
495 kbd_code_init();
496 return;
497 }
498 reset_keyboard = 0;
499 timeout(detect_kbd, (void *)unit, hz*2);
500 }
501
502 /*---------------------------------------------------------------------------*
503 * keyboard event handler
504 *---------------------------------------------------------------------------*/
505 static int
506 pcvt_event(keyboard_t *thiskbd, int event, void *arg)
507 {
508 int unit = (int)arg;
509
510 if (thiskbd != kbd)
511 return EINVAL; /* shouldn't happen */
512
513 switch (event) {
514 case KBDIO_KEYINPUT:
515 pcvt_rint(unit);
516 return 0;
517 case KBDIO_UNLOADING:
518 reset_keyboard = 0;
519 kbd = NULL;
520 kbd_release(thiskbd, (void *)&kbd);
521 timeout(detect_kbd, (void *)unit, hz*4);
522 return 0;
523 default:
524 return EINVAL;
525 }
526 }
527
528 /*---------------------------------------------------------------------------*
529 * (keyboard) interrupt handler
530 *---------------------------------------------------------------------------*/
531 void
532 pcvt_rint(int unit)
533 {
534 u_char dt;
535 u_char ret = -1;
536 int c;
537
538 # if PCVT_SLOW_INTERRUPT
539 int s;
540 # endif
541
542 #if PCVT_SCREENSAVER
543 pcvt_scrnsv_reset();
544 #endif /* PCVT_SCREENSAVER */
545
546 if (kbd_polling)
547 {
548 sgetc(1);
549 return;
550 }
551
552 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
553 {
554 ret = 1; /* got something */
555 dt = c;
556
557 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
558 {
559 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
560 }
561 else
562 {
563 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
564
565 PCVT_DISABLE_INTR (); /* XXX necessary ? */
566 pcvt_kbd_count++; /* update fifo count */
567 PCVT_ENABLE_INTR ();
568
569 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
570 pcvt_kbd_wptr = 0; /* wraparound pointer */
571 }
572 }
573
574 if (ret == 1) /* got data from keyboard ? */
575 {
576 if (!pcvt_timeout_scheduled) /* if not already active .. */
577 {
578 PCVT_DISABLE_INTR ();
579 pcvt_timeout_scheduled = 1; /* flag active */
580 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
581 PCVT_ENABLE_INTR ();
582 }
583 }
584 }
585
586 /*---------------------------------------------------------------------------*
587 * start output
588 *---------------------------------------------------------------------------*/
589 static void
590 pcvt_start(register struct tty *tp)
591 {
592 register struct clist *rbp;
593 int s, len;
594 u_char buf[PCVT_PCBURST];
595
596 s = spltty();
597
598 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
599 goto out;
600
601 tp->t_state |= TS_BUSY;
602
603 splx(s);
604
605 async_update(UPDATE_KERN);
606
607 rbp = &tp->t_outq;
608
609 /*
610 * Call q_to_b() at spltty() to ensure that the queue is empty when
611 * the loop terminates.
612 */
613
614 s = spltty();
615
616 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
617 {
618 if(vs[minor(tp->t_dev)].scrolling)
619 sgetc(SCROLLBACK_COOKIE);
620
621 /*
622 * We need to do this outside spl since it could be fairly
623 * expensive and we don't want our serial ports to overflow.
624 */
625 splx(s);
626 sput(&buf[0], 0, len, minor(tp->t_dev));
627 s = spltty();
628 }
629
630 tp->t_state &= ~TS_BUSY;
631
632 ttwwakeup(tp);
633
634 out:
635 splx(s);
636 }
637
638 /*---------------------------------------------------------------------------*
639 * console probe
640 *---------------------------------------------------------------------------*/
641 static void
642 pcvt_cn_probe(struct consdev *cp)
643 {
644 int unit = 0;
645 int i;
646
647 /* See if this driver is disabled in probe hint. */
648 if (resource_int_value("vt", unit, "disabled", &i) == 0 && i)
649 {
650 cp->cn_pri = CN_DEAD;
651 return;
652 }
653
654 kbd_configure(KB_CONF_PROBE_ONLY);
655
656 if (kbd_find_keyboard("*", unit) < 0)
657 {
658 cp->cn_pri = CN_DEAD;
659 return;
660 }
661
662 /* initialize required fields */
663
664 cp->cn_dev = makedev(CDEV_MAJOR, 0);
665 cp->cn_pri = CN_INTERNAL;
666 cp->cn_tp = &pcvt_tty[0];
667 }
668
669 /*---------------------------------------------------------------------------*
670 * console init
671 *---------------------------------------------------------------------------*/
672 static void
673 pcvt_cn_init(struct consdev *cp)
674 {
675 int unit = 0;
676 int i;
677
678 pcvt_is_console = 1;
679
680 /*
681 * Don't reset the keyboard via `kbdio' just yet.
682 * The system clock has not been calibrated...
683 */
684 reset_keyboard = 0;
685
686 if (kbd)
687 {
688 kbd_release(kbd, (void *)&kbd);
689 kbd = NULL;
690 }
691
692 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
693
694 if (i >= 0)
695 kbd = kbd_get_keyboard(i);
696
697 #if PCVT_SCANSET == 2
698 /*
699 * Turn off scancode translation early so that
700 * DDB can read the keyboard.
701 */
702 if (kbd)
703 {
704 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
705 set_controller_command_byte(*(KBDC *)kbd->kb_data,
706 KBD_TRANSLATION, 0);
707 }
708 #endif /* PCVT_SCANSET == 2 */
709 }
710
711 /*---------------------------------------------------------------------------*
712 * console finish
713 *---------------------------------------------------------------------------*/
714 static void
715 pcvt_cn_term(struct consdev *cp)
716 {
717 if (kbd)
718 {
719 kbd_release(kbd, (void *)&kbd);
720 kbd = NULL;
721 }
722 }
723
724 /*---------------------------------------------------------------------------*
725 * console put char
726 *---------------------------------------------------------------------------*/
727 static void
728 pcvt_cn_putc(dev_t dev, int c)
729 {
730 if (c == '\n')
731 sput("\r", 1, 1, 0);
732
733 sput((char *) &c, 1, 1, 0);
734
735 async_update(UPDATE_KERN);
736 }
737
738 /*---------------------------------------------------------------------------*
739 * console get char
740 *---------------------------------------------------------------------------*/
741 static int
742 pcvt_cn_getc(dev_t dev)
743 {
744 register int s;
745 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
746 register u_char c;
747
748 #ifdef XSERVER
749 if (pcvt_kbd_raw)
750 return 0;
751 #endif /* XSERVER */
752
753 if (cp && *cp)
754 {
755 /*
756 * We still have a pending key sequence, e.g.
757 * from an arrow key. Deliver this one first.
758 */
759 return (*cp++);
760 }
761
762 if (kbd == NULL)
763 return 0;
764
765 s = spltty(); /* block pcvt_rint while we poll */
766 kbd_polling = 1;
767 (*kbdsw[kbd->kb_index]->enable)(kbd);
768 cp = sgetc(0);
769 (*kbdsw[kbd->kb_index]->disable)(kbd);
770 kbd_polling = 0;
771 splx(s);
772
773 c = *cp++;
774
775 if (c && *cp)
776 {
777 /* Preserve the multi-char sequence for the next call. */
778 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
779 cp = cbuf;
780 }
781 else
782 {
783 cp = 0;
784 }
785 return c;
786 }
787
788 /*---------------------------------------------------------------------------*
789 * console check for char
790 *---------------------------------------------------------------------------*/
791 static int
792 pcvt_cn_checkc(dev_t dev)
793 {
794 char *cp;
795 int x;
796
797 if (kbd == NULL)
798 return 0;
799
800 x = spltty();
801 kbd_polling = 1;
802 (*kbdsw[kbd->kb_index]->enable)(kbd);
803 cp = sgetc(1);
804 (*kbdsw[kbd->kb_index]->disable)(kbd);
805 kbd_polling = 0;
806 splx(x);
807
808 return (cp == NULL ? -1 : *cp);
809 }
810
811 /*---------------------------------------------------------------------------*
812 * Set line parameters
813 *---------------------------------------------------------------------------*/
814 static int
815 pcvt_param(struct tty *tp, struct termios *t)
816 {
817 tp->t_ispeed = t->c_ispeed;
818 tp->t_ospeed = t->c_ospeed;
819 tp->t_cflag = t->c_cflag;
820
821 return(0);
822 }
823
824 /*----------------------------------------------------------------------*
825 * read initial VGA palette (as stored by VGA ROM BIOS) into
826 * palette save area
827 *----------------------------------------------------------------------*/
828 static void
829 vgapelinit(void)
830 {
831 register unsigned idx;
832 register struct rgb *val;
833
834 /* first, read all and store to first screen's save buffer */
835 for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
836 vgapaletteio(idx, val, 0 /* read it */);
837
838 /* now, duplicate for remaining screens */
839 for(idx = 1; idx < PCVT_NSCREENS; idx++)
840 bcopy(vs[0].palette, vs[idx].palette,
841 NVGAPEL * sizeof(struct rgb));
842 }
843
844 /*-------------------------- E O F -------------------------------------*/
Cache object: 4edcf5d327da39b4a4090ad02b63d86d
|