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/6.1/sys/i386/isa/pcvt/pcvt_drv.c 139790 2005-01-06 22:18:23Z 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 ttyinitmode(tp, 1, 0);
301 pcvt_param(tp, &tp->t_termios);
302 ttyld_modem(tp, 1); /* fake connection */
303 winsz = 1; /* set winsize later */
304 }
305 else if (tp->t_state & TS_XCLUDE && suser(td))
306 {
307 return (EBUSY);
308 }
309
310 retval = (ttyld_open(tp, dev));
311
312 if(winsz == 1)
313 {
314 /*
315 * The line discipline has clobbered t_winsize if TS_ISOPEN
316 * was clear. (NetBSD PR #400 from Bill Sommerfeld)
317 * We have to do this after calling the open routine, because
318 * it does some other things in other/older *BSD releases -hm
319 */
320
321 s = spltty();
322
323 tp->t_winsize.ws_col = vsx->maxcol;
324 tp->t_winsize.ws_row = vsx->screen_rows;
325 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
326 tp->t_winsize.ws_ypixel = 400;
327
328 splx(s);
329 }
330 return(retval);
331 }
332
333 /*---------------------------------------------------------------------------*
334 * driver close
335 *---------------------------------------------------------------------------*/
336 static int
337 pcvt_close(struct cdev *dev, int flag, int mode, struct thread *td)
338 {
339 register struct tty *tp;
340 register struct video_state *vsx;
341 int i = minor(dev);
342
343 vsx = &vs[i];
344
345 if(i >= PCVT_NSCREENS)
346 return ENXIO;
347
348 tp = pcvt_tty[i];
349
350 ttyld_close(tp, flag);
351
352 tty_close(tp);
353
354 vsx->openf = 0;
355
356 #ifdef XSERVER
357 reset_usl_modes(vsx);
358 #endif /* XSERVER */
359
360 return(0);
361 }
362
363 /*---------------------------------------------------------------------------*
364 * driver ioctl
365 *---------------------------------------------------------------------------*/
366 static int
367 pcvt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
368 {
369 register int error;
370 register struct tty *tp;
371 int i = minor(dev);
372
373 if(i >= PCVT_NSCREENS)
374 return ENXIO;
375
376 tp = pcvt_tty[i];
377
378 /* note that some ioctl's are global, e.g. KBSTPMAT: There is
379 * only one keyboard and different repeat rates for instance between
380 * sessions are a suspicious wish. If you really need this make the
381 * appropriate variables arrays
382 */
383
384 #ifdef XSERVER
385 if((error = usl_vt_ioctl(dev, cmd, data, flag, td)) >= 0)
386 return error;
387 #endif /* XSERVER */
388
389 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
390 return error;
391
392 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
393 return error;
394
395 return (ttyioctl(dev, cmd, data, flag, td));
396 }
397
398 /*---------------------------------------------------------------------------*
399 * driver mmap
400 *---------------------------------------------------------------------------*/
401 static int
402 pcvt_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
403 {
404 if (offset > 0x20000 - PAGE_SIZE)
405 return -1;
406 *paddr = 0xa0000 + offset;
407 return 0;
408 }
409
410 /*---------------------------------------------------------------------------*
411 * timeout handler
412 *---------------------------------------------------------------------------*/
413 static void
414 pcvt_timeout(void *arg)
415 {
416 u_char *cp;
417 struct tty *tp;
418
419 #if PCVT_SLOW_INTERRUPT
420 int s;
421 #endif
422
423 pcvt_timeout_scheduled = 0;
424
425 #if PCVT_SCREENSAVER
426 pcvt_scrnsv_reset();
427 #endif /* PCVT_SCREENSAVER */
428
429 tp = pcvt_tty[current_video_screen];
430 while (pcvt_kbd_count)
431 {
432 if (((cp = sgetc(1)) != 0) &&
433 (vs[current_video_screen].openf))
434 {
435
436 #if PCVT_NULLCHARS
437 if(*cp == '\0')
438 {
439 /* pass a NULL character */
440 ttyld_rint(tp, '\0');
441 }
442 /* XXX */ else
443 #endif /* PCVT_NULLCHARS */
444
445 while (*cp)
446 ttyld_rint(tp, *cp++ & 0xff);
447 }
448
449 PCVT_DISABLE_INTR ();
450
451 if (!pcvt_kbd_count)
452 pcvt_timeout_scheduled = 0;
453
454 PCVT_ENABLE_INTR ();
455 }
456
457 return;
458 }
459
460 /*---------------------------------------------------------------------------*
461 * check for keyboard
462 *---------------------------------------------------------------------------*/
463 static void
464 detect_kbd(void *arg)
465 {
466 int unit = (int)arg;
467 int i;
468
469 if (kbd != NULL)
470 return;
471 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
472 if (i >= 0)
473 kbd = kbd_get_keyboard(i);
474 if (kbd != NULL)
475 {
476 reset_keyboard = 1; /* ok to reset the keyboard */
477 kbd_code_init();
478 return;
479 }
480 reset_keyboard = 0;
481 timeout(detect_kbd, (void *)unit, hz*2);
482 }
483
484 /*---------------------------------------------------------------------------*
485 * keyboard event handler
486 *---------------------------------------------------------------------------*/
487 static int
488 pcvt_event(keyboard_t *thiskbd, int event, void *arg)
489 {
490 int unit = (int)arg;
491
492 if (thiskbd != kbd)
493 return EINVAL; /* shouldn't happen */
494
495 switch (event) {
496 case KBDIO_KEYINPUT:
497 pcvt_rint(unit);
498 return 0;
499 case KBDIO_UNLOADING:
500 reset_keyboard = 0;
501 kbd = NULL;
502 kbd_release(thiskbd, (void *)&kbd);
503 timeout(detect_kbd, (void *)unit, hz*4);
504 return 0;
505 default:
506 return EINVAL;
507 }
508 }
509
510 /*---------------------------------------------------------------------------*
511 * (keyboard) interrupt handler
512 *---------------------------------------------------------------------------*/
513 void
514 pcvt_rint(int unit)
515 {
516 u_char dt;
517 u_char ret = -1;
518 int c;
519
520 # if PCVT_SLOW_INTERRUPT
521 int s;
522 # endif
523
524 #if PCVT_SCREENSAVER
525 pcvt_scrnsv_reset();
526 #endif /* PCVT_SCREENSAVER */
527
528 if (kbd_polling)
529 {
530 sgetc(1);
531 return;
532 }
533
534 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
535 {
536 ret = 1; /* got something */
537 dt = c;
538
539 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
540 {
541 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
542 }
543 else
544 {
545 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
546
547 PCVT_DISABLE_INTR (); /* XXX necessary ? */
548 pcvt_kbd_count++; /* update fifo count */
549 PCVT_ENABLE_INTR ();
550
551 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
552 pcvt_kbd_wptr = 0; /* wraparound pointer */
553 }
554 }
555
556 if (ret == 1) /* got data from keyboard ? */
557 {
558 if (!pcvt_timeout_scheduled) /* if not already active .. */
559 {
560 PCVT_DISABLE_INTR ();
561 pcvt_timeout_scheduled = 1; /* flag active */
562 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
563 PCVT_ENABLE_INTR ();
564 }
565 }
566 }
567
568 /*---------------------------------------------------------------------------*
569 * start output
570 *---------------------------------------------------------------------------*/
571 static void
572 pcvt_start(register struct tty *tp)
573 {
574 register struct clist *rbp;
575 int s, len;
576 u_char buf[PCVT_PCBURST];
577
578 s = spltty();
579
580 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
581 goto out;
582
583 tp->t_state |= TS_BUSY;
584
585 splx(s);
586
587 async_update(UPDATE_KERN);
588
589 rbp = &tp->t_outq;
590
591 /*
592 * Call q_to_b() at spltty() to ensure that the queue is empty when
593 * the loop terminates.
594 */
595
596 s = spltty();
597
598 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
599 {
600 if(vs[minor(tp->t_dev)].scrolling)
601 sgetc(SCROLLBACK_COOKIE);
602
603 /*
604 * We need to do this outside spl since it could be fairly
605 * expensive and we don't want our serial ports to overflow.
606 */
607 splx(s);
608 sput(&buf[0], 0, len, minor(tp->t_dev));
609 s = spltty();
610 }
611
612 tp->t_state &= ~TS_BUSY;
613
614 ttwwakeup(tp);
615
616 out:
617 splx(s);
618 }
619
620 /*---------------------------------------------------------------------------*
621 * console probe
622 *---------------------------------------------------------------------------*/
623 static void
624 pcvt_cn_probe(struct consdev *cp)
625 {
626 int unit = 0;
627
628 /* See if this driver is disabled in probe hint. */
629 if (resource_disabled("vt", unit))
630 {
631 cp->cn_pri = CN_DEAD;
632 return;
633 }
634
635 kbd_configure(KB_CONF_PROBE_ONLY);
636
637 if (kbd_find_keyboard("*", unit) < 0)
638 {
639 cp->cn_pri = CN_DEAD;
640 return;
641 }
642
643 /* initialize required fields */
644
645 sprintf(cp->cn_name, "ttyv%r", 0);
646 cp->cn_pri = CN_INTERNAL;
647 pcvt_tty[0] = ttymalloc(pcvt_tty[0]);
648 cp->cn_tp = pcvt_tty[0];
649 }
650
651 /*---------------------------------------------------------------------------*
652 * console init
653 *---------------------------------------------------------------------------*/
654 static void
655 pcvt_cn_init(struct consdev *cp)
656 {
657 int unit = 0;
658 int i;
659
660 pcvt_is_console = 1;
661 pcvt_consptr = cp;
662
663 /*
664 * Don't reset the keyboard via `kbdio' just yet.
665 * The system clock has not been calibrated...
666 */
667 reset_keyboard = 0;
668
669 if (kbd)
670 {
671 kbd_release(kbd, (void *)&kbd);
672 kbd = NULL;
673 }
674
675 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
676
677 if (i >= 0)
678 kbd = kbd_get_keyboard(i);
679
680 #if PCVT_SCANSET == 2
681 /*
682 * Turn off scancode translation early so that
683 * DDB can read the keyboard.
684 */
685 if (kbd)
686 {
687 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
688 set_controller_command_byte(*(KBDC *)kbd->kb_data,
689 KBD_TRANSLATION, 0);
690 }
691 #endif /* PCVT_SCANSET == 2 */
692 }
693
694 /*---------------------------------------------------------------------------*
695 * console finish
696 *---------------------------------------------------------------------------*/
697 static void
698 pcvt_cn_term(struct consdev *cp)
699 {
700 if (kbd)
701 {
702 kbd_release(kbd, (void *)&kbd);
703 kbd = NULL;
704 }
705 }
706
707 /*---------------------------------------------------------------------------*
708 * console put char
709 *---------------------------------------------------------------------------*/
710 static void
711 pcvt_cn_putc(struct consdev *cd, int c)
712 {
713 if (c == '\n')
714 sput("\r", 1, 1, 0);
715
716 sput((char *) &c, 1, 1, 0);
717
718 async_update(UPDATE_KERN);
719 }
720
721 /*---------------------------------------------------------------------------*
722 * console get char
723 *---------------------------------------------------------------------------*/
724 static int
725 pcvt_cn_getc(struct consdev *cd)
726 {
727 register int s;
728 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
729 register u_char c;
730
731 #ifdef XSERVER
732 if (pcvt_kbd_raw)
733 return 0;
734 #endif /* XSERVER */
735
736 if (cp && *cp)
737 {
738 /*
739 * We still have a pending key sequence, e.g.
740 * from an arrow key. Deliver this one first.
741 */
742 return (*cp++);
743 }
744
745 if (kbd == NULL)
746 return 0;
747
748 s = spltty(); /* block pcvt_rint while we poll */
749 kbd_polling = 1;
750 (*kbdsw[kbd->kb_index]->enable)(kbd);
751 cp = sgetc(0);
752 (*kbdsw[kbd->kb_index]->disable)(kbd);
753 kbd_polling = 0;
754 splx(s);
755
756 c = *cp++;
757
758 if (c && *cp)
759 {
760 /* Preserve the multi-char sequence for the next call. */
761 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
762 cp = cbuf;
763 }
764 else
765 {
766 cp = 0;
767 }
768 return c;
769 }
770
771 /*---------------------------------------------------------------------------*
772 * console check for char
773 *---------------------------------------------------------------------------*/
774 static int
775 pcvt_cn_checkc(struct consdev *cd)
776 {
777 char *cp;
778 int x;
779
780 if (kbd == NULL)
781 return 0;
782
783 x = spltty();
784 kbd_polling = 1;
785 (*kbdsw[kbd->kb_index]->enable)(kbd);
786 cp = sgetc(1);
787 (*kbdsw[kbd->kb_index]->disable)(kbd);
788 kbd_polling = 0;
789 splx(x);
790
791 return (cp == NULL ? -1 : *cp);
792 }
793
794 /*---------------------------------------------------------------------------*
795 * Set line parameters
796 *---------------------------------------------------------------------------*/
797 static int
798 pcvt_param(struct tty *tp, struct termios *t)
799 {
800 tp->t_ispeed = t->c_ispeed;
801 tp->t_ospeed = t->c_ospeed;
802 tp->t_cflag = t->c_cflag;
803
804 return(0);
805 }
806
807 /*----------------------------------------------------------------------*
808 * read initial VGA palette (as stored by VGA ROM BIOS) into
809 * palette save area
810 *----------------------------------------------------------------------*/
811 static void
812 vgapelinit(void)
813 {
814 register unsigned idx;
815 register struct rgb *val;
816
817 /* first, read all and store to first screen's save buffer */
818 for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
819 vgapaletteio(idx, val, 0 /* read it */);
820
821 /* now, duplicate for remaining screens */
822 for(idx = 1; idx < PCVT_NSCREENS; idx++)
823 bcopy(vs[0].palette, vs[idx].palette,
824 NVGAPEL * sizeof(struct rgb));
825 }
826
827 /*-------------------------- E O F -------------------------------------*/
Cache object: 4317f8e75df8fc03dd841066be016476
|