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.4/sys/i386/isa/pcvt/pcvt_drv.c 141090 2005-01-31 23:27:04Z imp $
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 static struct cdevsw vt_cdevsw = {
97 .d_version = D_VERSION,
98 .d_open = pcvt_open,
99 .d_close = pcvt_close,
100 .d_ioctl = pcvt_ioctl,
101 .d_mmap = pcvt_mmap,
102 .d_name = "vt",
103 .d_flags = D_TTY | D_NEEDGIANT,
104 };
105
106 static int pcvt_probe(device_t dev);
107 static int pcvt_attach(device_t dev);
108 static void pcvt_identify (driver_t *driver, device_t parent);
109
110 static device_method_t pcvt_methods[] = {
111 DEVMETHOD(device_identify, pcvt_identify),
112 DEVMETHOD(device_probe, pcvt_probe),
113 DEVMETHOD(device_attach, pcvt_attach),
114 DEVMETHOD(bus_print_child, bus_generic_print_child),
115 { 0, 0 }
116 };
117
118 static driver_t pcvt_driver = {
119 "vt",
120 pcvt_methods,
121 0
122 };
123
124 static devclass_t pcvt_devclass;
125
126 DRIVER_MODULE(pcvt, isa, pcvt_driver, pcvt_devclass, 0, 0);
127
128 /*---------------------------------------------------------------------------*
129 * driver identify
130 *---------------------------------------------------------------------------*/
131 static void
132 pcvt_identify (driver_t *driver, device_t parent)
133 {
134 BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "vt", 0);
135 }
136
137 /*---------------------------------------------------------------------------*
138 * driver probe
139 *---------------------------------------------------------------------------*/
140 static int
141 pcvt_probe(device_t dev)
142 {
143 int i;
144 device_t bus;
145
146 int unit = device_get_unit(dev);
147
148 /* No pnp support */
149 if(isa_get_vendorid(dev))
150 return ENXIO;
151
152 if(unit != 0)
153 return ENXIO;
154
155 device_set_desc(dev, "pcvt VT220 console driver");
156
157 bus = device_get_parent(dev);
158 bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3b0, 0x30);
159 bus_set_resource(dev, SYS_RES_MEMORY, 0, (u_long) Crtat, 0x8000);
160
161 if (kbd == NULL)
162 {
163 reset_keyboard = 0;
164 kbd_configure(KB_CONF_PROBE_ONLY);
165 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)&vs[unit]);
166 if ((i < 0) || ((kbd = kbd_get_keyboard(i)) == NULL))
167 return 0;
168 }
169 reset_keyboard = 1; /* it's now safe to do kbd reset */
170
171 kbd_code_init();
172
173 return 0;
174 }
175
176 /*---------------------------------------------------------------------------*
177 * driver attach
178 *---------------------------------------------------------------------------*/
179 static int
180 pcvt_attach(device_t dev)
181 {
182 int i;
183 struct resource *port;
184 struct resource *mem;
185
186 int unit = device_get_unit(dev);
187
188 if(unit != 0)
189 return ENXIO;
190
191 i = 0;
192 port = bus_alloc_resource(dev, SYS_RES_IOPORT, &i, 0, ~0, 0,
193 RF_ACTIVE | RF_SHAREABLE);
194
195 i = 0;
196 mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &i, 0, ~0, 0,
197 RF_ACTIVE | RF_SHAREABLE);
198
199 vt_coldmalloc(); /* allocate memory for screens */
200
201 if (kbd == NULL)
202 timeout(detect_kbd, (void *)&vs[unit], hz*2);
203
204 printf("vt%d: ", unit);
205
206 switch(adaptor_type)
207 {
208 case MDA_ADAPTOR:
209 printf("MDA");
210 break;
211
212 case CGA_ADAPTOR:
213 printf("CGA");
214 break;
215
216 case EGA_ADAPTOR:
217 printf("EGA");
218 break;
219
220 case VGA_ADAPTOR:
221 printf("%s VGA, ", (char *)vga_string(vga_type));
222 if(can_do_132col)
223 printf("80/132 columns");
224 else
225 printf("80 columns");
226 vgapelinit();
227 break;
228
229 default:
230 printf("unknown");
231 break;
232 }
233
234 if(color == 0)
235 printf(", mono");
236 else
237 printf(", color");
238
239 printf(", %d screens, ", totalscreens);
240
241 switch(keyboard_type)
242 {
243 case KB_AT:
244 printf("AT-");
245 break;
246
247 case KB_MFII:
248 printf("MF2-");
249 break;
250
251 default:
252 printf("unknown ");
253 break;
254 }
255
256 printf("keyboard\n");
257
258 for(i = 0; i < totalscreens; i++)
259 {
260 pcvt_tty[i] = ttymalloc(pcvt_tty[i]);
261 vs[i].vs_tty = pcvt_tty[i];
262 make_dev(&vt_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
263 }
264
265 async_update(UPDATE_START); /* start asynchronous updates */
266
267 return 0;
268 }
269
270 /*---------------------------------------------------------------------------*
271 * driver open
272 *---------------------------------------------------------------------------*/
273 static int
274 pcvt_open(struct cdev *dev, int flag, int mode, struct thread *td)
275 {
276 register struct tty *tp;
277 register struct video_state *vsx;
278 int s, retval;
279 int winsz = 0;
280 int i = minor(dev);
281
282 vsx = &vs[i];
283
284 if(i >= PCVT_NSCREENS)
285 return ENXIO;
286
287 tp = pcvt_tty[i];
288
289 dev->si_tty = tp;
290
291 vsx->openf++;
292
293 tp->t_oproc = pcvt_start;
294 tp->t_param = pcvt_param;
295 tp->t_stop = nottystop;
296 tp->t_dev = dev;
297
298 if ((tp->t_state & TS_ISOPEN) == 0)
299 {
300 ttychars(tp);
301 tp->t_iflag = TTYDEF_IFLAG;
302 tp->t_oflag = TTYDEF_OFLAG;
303 tp->t_cflag = TTYDEF_CFLAG;
304 tp->t_lflag = TTYDEF_LFLAG;
305 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
306 pcvt_param(tp, &tp->t_termios);
307 ttyld_modem(tp, 1); /* fake connection */
308 winsz = 1; /* set winsize later */
309 }
310 else if (tp->t_state & TS_XCLUDE && suser(td))
311 {
312 return (EBUSY);
313 }
314
315 retval = (ttyld_open(tp, dev));
316
317 if(winsz == 1)
318 {
319 /*
320 * The line discipline has clobbered t_winsize if TS_ISOPEN
321 * was clear. (NetBSD PR #400 from Bill Sommerfeld)
322 * We have to do this after calling the open routine, because
323 * it does some other things in other/older *BSD releases -hm
324 */
325
326 s = spltty();
327
328 tp->t_winsize.ws_col = vsx->maxcol;
329 tp->t_winsize.ws_row = vsx->screen_rows;
330 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
331 tp->t_winsize.ws_ypixel = 400;
332
333 splx(s);
334 }
335 return(retval);
336 }
337
338 /*---------------------------------------------------------------------------*
339 * driver close
340 *---------------------------------------------------------------------------*/
341 static int
342 pcvt_close(struct cdev *dev, int flag, int mode, struct thread *td)
343 {
344 register struct tty *tp;
345 register struct video_state *vsx;
346 int i = minor(dev);
347
348 vsx = &vs[i];
349
350 if(i >= PCVT_NSCREENS)
351 return ENXIO;
352
353 tp = pcvt_tty[i];
354
355 ttyld_close(tp, flag);
356
357 tty_close(tp);
358
359 vsx->openf = 0;
360
361 #ifdef XSERVER
362 reset_usl_modes(vsx);
363 #endif /* XSERVER */
364
365 return(0);
366 }
367
368 /*---------------------------------------------------------------------------*
369 * driver ioctl
370 *---------------------------------------------------------------------------*/
371 static int
372 pcvt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
373 {
374 register int error;
375 register struct tty *tp;
376 int i = minor(dev);
377
378 if(i >= PCVT_NSCREENS)
379 return ENXIO;
380
381 tp = pcvt_tty[i];
382
383 /* note that some ioctl's are global, e.g. KBSTPMAT: There is
384 * only one keyboard and different repeat rates for instance between
385 * sessions are a suspicious wish. If you really need this make the
386 * appropriate variables arrays
387 */
388
389 #ifdef XSERVER
390 if((error = usl_vt_ioctl(dev, cmd, data, flag, td)) >= 0)
391 return error;
392 #endif /* XSERVER */
393
394 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
395 return error;
396
397 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
398 return error;
399
400 return (ttyioctl(dev, cmd, data, flag, td));
401 }
402
403 /*---------------------------------------------------------------------------*
404 * driver mmap
405 *---------------------------------------------------------------------------*/
406 static int
407 pcvt_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
408 {
409 if (offset > 0x20000 - PAGE_SIZE)
410 return -1;
411 *paddr = 0xa0000 + offset;
412 return 0;
413 }
414
415 /*---------------------------------------------------------------------------*
416 * timeout handler
417 *---------------------------------------------------------------------------*/
418 static void
419 pcvt_timeout(void *arg)
420 {
421 u_char *cp;
422 struct tty *tp;
423
424 #if PCVT_SLOW_INTERRUPT
425 int s;
426 #endif
427
428 pcvt_timeout_scheduled = 0;
429
430 #if PCVT_SCREENSAVER
431 pcvt_scrnsv_reset();
432 #endif /* PCVT_SCREENSAVER */
433
434 tp = pcvt_tty[current_video_screen];
435 while (pcvt_kbd_count)
436 {
437 if (((cp = sgetc(1)) != 0) &&
438 (vs[current_video_screen].openf))
439 {
440
441 #if PCVT_NULLCHARS
442 if(*cp == '\0')
443 {
444 /* pass a NULL character */
445 ttyld_rint(tp, '\0');
446 }
447 /* XXX */ else
448 #endif /* PCVT_NULLCHARS */
449
450 while (*cp)
451 ttyld_rint(tp, *cp++ & 0xff);
452 }
453
454 PCVT_DISABLE_INTR ();
455
456 if (!pcvt_kbd_count)
457 pcvt_timeout_scheduled = 0;
458
459 PCVT_ENABLE_INTR ();
460 }
461
462 return;
463 }
464
465 /*---------------------------------------------------------------------------*
466 * check for keyboard
467 *---------------------------------------------------------------------------*/
468 static void
469 detect_kbd(void *arg)
470 {
471 int unit = (int)arg;
472 int i;
473
474 if (kbd != NULL)
475 return;
476 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
477 if (i >= 0)
478 kbd = kbd_get_keyboard(i);
479 if (kbd != NULL)
480 {
481 reset_keyboard = 1; /* ok to reset the keyboard */
482 kbd_code_init();
483 return;
484 }
485 reset_keyboard = 0;
486 timeout(detect_kbd, (void *)unit, hz*2);
487 }
488
489 /*---------------------------------------------------------------------------*
490 * keyboard event handler
491 *---------------------------------------------------------------------------*/
492 static int
493 pcvt_event(keyboard_t *thiskbd, int event, void *arg)
494 {
495 int unit = (int)arg;
496
497 if (thiskbd != kbd)
498 return EINVAL; /* shouldn't happen */
499
500 switch (event) {
501 case KBDIO_KEYINPUT:
502 pcvt_rint(unit);
503 return 0;
504 case KBDIO_UNLOADING:
505 reset_keyboard = 0;
506 kbd = NULL;
507 kbd_release(thiskbd, (void *)&kbd);
508 timeout(detect_kbd, (void *)unit, hz*4);
509 return 0;
510 default:
511 return EINVAL;
512 }
513 }
514
515 /*---------------------------------------------------------------------------*
516 * (keyboard) interrupt handler
517 *---------------------------------------------------------------------------*/
518 void
519 pcvt_rint(int unit)
520 {
521 u_char dt;
522 u_char ret = -1;
523 int c;
524
525 # if PCVT_SLOW_INTERRUPT
526 int s;
527 # endif
528
529 #if PCVT_SCREENSAVER
530 pcvt_scrnsv_reset();
531 #endif /* PCVT_SCREENSAVER */
532
533 if (kbd_polling)
534 {
535 sgetc(1);
536 return;
537 }
538
539 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
540 {
541 ret = 1; /* got something */
542 dt = c;
543
544 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
545 {
546 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
547 }
548 else
549 {
550 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
551
552 PCVT_DISABLE_INTR (); /* XXX necessary ? */
553 pcvt_kbd_count++; /* update fifo count */
554 PCVT_ENABLE_INTR ();
555
556 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
557 pcvt_kbd_wptr = 0; /* wraparound pointer */
558 }
559 }
560
561 if (ret == 1) /* got data from keyboard ? */
562 {
563 if (!pcvt_timeout_scheduled) /* if not already active .. */
564 {
565 PCVT_DISABLE_INTR ();
566 pcvt_timeout_scheduled = 1; /* flag active */
567 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
568 PCVT_ENABLE_INTR ();
569 }
570 }
571 }
572
573 /*---------------------------------------------------------------------------*
574 * start output
575 *---------------------------------------------------------------------------*/
576 static void
577 pcvt_start(register struct tty *tp)
578 {
579 register struct clist *rbp;
580 int s, len;
581 u_char buf[PCVT_PCBURST];
582
583 s = spltty();
584
585 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
586 goto out;
587
588 tp->t_state |= TS_BUSY;
589
590 splx(s);
591
592 async_update(UPDATE_KERN);
593
594 rbp = &tp->t_outq;
595
596 /*
597 * Call q_to_b() at spltty() to ensure that the queue is empty when
598 * the loop terminates.
599 */
600
601 s = spltty();
602
603 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
604 {
605 if(vs[minor(tp->t_dev)].scrolling)
606 sgetc(SCROLLBACK_COOKIE);
607
608 /*
609 * We need to do this outside spl since it could be fairly
610 * expensive and we don't want our serial ports to overflow.
611 */
612 splx(s);
613 sput(&buf[0], 0, len, minor(tp->t_dev));
614 s = spltty();
615 }
616
617 tp->t_state &= ~TS_BUSY;
618
619 ttwwakeup(tp);
620
621 out:
622 splx(s);
623 }
624
625 /*---------------------------------------------------------------------------*
626 * console probe
627 *---------------------------------------------------------------------------*/
628 static void
629 pcvt_cn_probe(struct consdev *cp)
630 {
631 int unit = 0;
632
633 /* See if this driver is disabled in probe hint. */
634 if (resource_disabled("vt", unit))
635 {
636 cp->cn_pri = CN_DEAD;
637 return;
638 }
639
640 kbd_configure(KB_CONF_PROBE_ONLY);
641
642 if (kbd_find_keyboard("*", unit) < 0)
643 {
644 cp->cn_pri = CN_DEAD;
645 return;
646 }
647
648 /* initialize required fields */
649
650 sprintf(cp->cn_name, "ttyv%r", 0);
651 cp->cn_pri = CN_INTERNAL;
652 pcvt_tty[0] = ttymalloc(pcvt_tty[0]);
653 cp->cn_tp = pcvt_tty[0];
654 }
655
656 /*---------------------------------------------------------------------------*
657 * console init
658 *---------------------------------------------------------------------------*/
659 static void
660 pcvt_cn_init(struct consdev *cp)
661 {
662 int unit = 0;
663 int i;
664
665 pcvt_is_console = 1;
666 pcvt_consptr = cp;
667
668 /*
669 * Don't reset the keyboard via `kbdio' just yet.
670 * The system clock has not been calibrated...
671 */
672 reset_keyboard = 0;
673
674 if (kbd)
675 {
676 kbd_release(kbd, (void *)&kbd);
677 kbd = NULL;
678 }
679
680 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
681
682 if (i >= 0)
683 kbd = kbd_get_keyboard(i);
684
685 #if PCVT_SCANSET == 2
686 /*
687 * Turn off scancode translation early so that
688 * DDB can read the keyboard.
689 */
690 if (kbd)
691 {
692 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
693 set_controller_command_byte(*(KBDC *)kbd->kb_data,
694 KBD_TRANSLATION, 0);
695 }
696 #endif /* PCVT_SCANSET == 2 */
697 }
698
699 /*---------------------------------------------------------------------------*
700 * console finish
701 *---------------------------------------------------------------------------*/
702 static void
703 pcvt_cn_term(struct consdev *cp)
704 {
705 if (kbd)
706 {
707 kbd_release(kbd, (void *)&kbd);
708 kbd = NULL;
709 }
710 }
711
712 /*---------------------------------------------------------------------------*
713 * console put char
714 *---------------------------------------------------------------------------*/
715 static void
716 pcvt_cn_putc(struct consdev *cd, int c)
717 {
718 if (c == '\n')
719 sput("\r", 1, 1, 0);
720
721 sput((char *) &c, 1, 1, 0);
722
723 async_update(UPDATE_KERN);
724 }
725
726 /*---------------------------------------------------------------------------*
727 * console get char
728 *---------------------------------------------------------------------------*/
729 static int
730 pcvt_cn_getc(struct consdev *cd)
731 {
732 register int s;
733 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
734 register u_char c;
735
736 #ifdef XSERVER
737 if (pcvt_kbd_raw)
738 return 0;
739 #endif /* XSERVER */
740
741 if (cp && *cp)
742 {
743 /*
744 * We still have a pending key sequence, e.g.
745 * from an arrow key. Deliver this one first.
746 */
747 return (*cp++);
748 }
749
750 if (kbd == NULL)
751 return 0;
752
753 s = spltty(); /* block pcvt_rint while we poll */
754 kbd_polling = 1;
755 (*kbdsw[kbd->kb_index]->enable)(kbd);
756 cp = sgetc(0);
757 (*kbdsw[kbd->kb_index]->disable)(kbd);
758 kbd_polling = 0;
759 splx(s);
760
761 c = *cp++;
762
763 if (c && *cp)
764 {
765 /* Preserve the multi-char sequence for the next call. */
766 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
767 cp = cbuf;
768 }
769 else
770 {
771 cp = 0;
772 }
773 return c;
774 }
775
776 /*---------------------------------------------------------------------------*
777 * console check for char
778 *---------------------------------------------------------------------------*/
779 static int
780 pcvt_cn_checkc(struct consdev *cd)
781 {
782 char *cp;
783 int x;
784
785 if (kbd == NULL)
786 return 0;
787
788 x = spltty();
789 kbd_polling = 1;
790 (*kbdsw[kbd->kb_index]->enable)(kbd);
791 cp = sgetc(1);
792 (*kbdsw[kbd->kb_index]->disable)(kbd);
793 kbd_polling = 0;
794 splx(x);
795
796 return (cp == NULL ? -1 : *cp);
797 }
798
799 /*---------------------------------------------------------------------------*
800 * Set line parameters
801 *---------------------------------------------------------------------------*/
802 static int
803 pcvt_param(struct tty *tp, struct termios *t)
804 {
805 tp->t_ispeed = t->c_ispeed;
806 tp->t_ospeed = t->c_ospeed;
807 tp->t_cflag = t->c_cflag;
808
809 return(0);
810 }
811
812 /*----------------------------------------------------------------------*
813 * read initial VGA palette (as stored by VGA ROM BIOS) into
814 * palette save area
815 *----------------------------------------------------------------------*/
816 static void
817 vgapelinit(void)
818 {
819 register unsigned idx;
820 register struct rgb *val;
821
822 /* first, read all and store to first screen's save buffer */
823 for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
824 vgapaletteio(idx, val, 0 /* read it */);
825
826 /* now, duplicate for remaining screens */
827 for(idx = 1; idx < PCVT_NSCREENS; idx++)
828 bcopy(vs[0].palette, vs[idx].palette,
829 NVGAPEL * sizeof(struct rgb));
830 }
831
832 /*-------------------------- E O F -------------------------------------*/
Cache object: 3b5eba554e085250765b4d06c010e144
|