Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / dev / video / pcvt / i386 / pcvt_drv.c
1 /*
2  * Copyright (c) 1999 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: [Mon Dec 27 14:03:36 1999]
52  *
53  * $FreeBSD: src/sys/i386/isa/pcvt/pcvt_drv.c,v 1.63.2.1 2001/02/26 04:23:13 jlemon Exp $
54  *
55  *---------------------------------------------------------------------------*/
56
57 #include "vt.h"
58 #if NVT > 0
59
60 #define EXTERN                  /* allocate mem */
61
62 #include <i386/isa/pcvt/pcvt_hdr.h>     /* global include */
63
64 #if PCVT_FREEBSD >= 200
65 #include <sys/bus.h>
66 #include <machine/stdarg.h>
67 #else
68 #include "machine/stdarg.h"
69 #endif
70
71 extern int getchar __P((void));
72
73 #if PCVT_NETBSD
74         extern u_short *Crtat;
75 #endif /* PCVT_NETBSD */
76
77 static void vgapelinit(void);   /* read initial VGA DAC palette */
78
79 #if defined XSERVER && !PCVT_USL_VT_COMPAT
80 static int pcvt_xmode_set(int on, struct proc *p); /* initialize for X mode */
81 #endif /* XSERVER && !PCVT_USL_VT_COMPAT */
82
83 #ifdef _DEV_KBD_KBDREG_H_
84 static void detect_kbd(void *arg);
85 static kbd_callback_func_t pcevent;
86 #endif
87
88 static cn_probe_t       pccnprobe;
89 static cn_init_t        pccninit;
90 static cn_term_t        pccnterm;
91 static cn_getc_t        pccngetc;
92 static cn_checkc_t      pccncheckc;
93 static cn_putc_t        pccnputc;
94
95 CONS_DRIVER(pc, pccnprobe, pccninit, pccnterm, pccngetc, pccncheckc, pccnputc,
96             NULL);
97
98 static  d_open_t        pcopen;
99 static  d_close_t       pcclose;
100 static  d_ioctl_t       pcioctl;
101 static  d_mmap_t        pcmmap;
102
103 #define CDEV_MAJOR      12
104 static struct cdevsw pc_cdevsw = {
105         /* open */      pcopen,
106         /* close */     pcclose,
107         /* read */      ttyread,
108         /* write */     ttywrite,
109         /* ioctl */     pcioctl,
110         /* poll */      ttypoll,
111         /* mmap */      pcmmap,
112         /* strategy */  nostrategy,
113         /* name */      "vt",
114         /* maj */       CDEV_MAJOR,
115         /* dump */      nodump,
116         /* psize */     nopsize,
117         /* flags */     D_TTY | D_KQFILTER,
118         /* bmaj */      -1,
119         /* kqfilter */  ttykqfilter,
120 };
121
122 #if PCVT_NETBSD > 100   /* NetBSD-current Feb 20 1995 */
123 int
124 pcprobe(struct device *parent, void *match, void *aux)
125 #else
126 #if PCVT_NETBSD > 9
127 int
128 pcprobe(struct device *parent, struct device *self, void *aux)
129 #else
130 int
131 pcprobe(struct isa_device *dev)
132 #endif /* PCVT_NETBSD > 9 */
133 #endif /* PCVT_NETBSD > 100 */
134 {
135 #ifdef _DEV_KBD_KBDREG_H_
136         int i;
137
138         if (kbd == NULL) {
139                 reset_keyboard = 0;
140                 kbd_configure(KB_CONF_PROBE_ONLY);
141                 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)dev->id_unit);
142                 if ((i < 0) || ((kbd = kbd_get_keyboard(i)) == NULL))
143                         return (-1);
144         }
145         reset_keyboard = 1;             /* it's now safe to do kbd reset */
146 #endif /* _DEV_KBD_KBDREG_H_ */
147
148         kbd_code_init();
149
150 #if PCVT_NETBSD > 9
151         ((struct isa_attach_args *)aux)->ia_iosize = 16;
152         return 1;
153 #else
154 #ifdef _DEV_KBD_KBDREG_H_
155         return (-1);
156 #elif PCVT_NETBSD || PCVT_FREEBSD
157         return (16);
158 #else
159         return 1;
160 #endif /* PCVT_NETBSD || PCVT_FREEBSD */
161 #endif /* PCVT_NETBSD > 9 */
162
163 }
164
165 #if PCVT_NETBSD > 9
166 void
167 pcattach(struct device *parent, struct device *self, void *aux)
168 {
169         struct isa_attach_args *ia = aux;
170         static struct intrhand vthand;
171 #else
172 int
173 pcattach(struct isa_device *dev)
174 {
175 #endif /* PCVT_NETBSD > 9 */
176
177         int i;
178
179         vt_coldmalloc();                /* allocate memory for screens */
180
181 #ifdef _DEV_KBD_KBDREG_H_
182         if (kbd == NULL)
183                 timeout(detect_kbd, (void *)dev->id_unit, hz*2);
184 #endif /* _DEV_KBD_KBDREG_H_ */
185
186 #if PCVT_NETBSD || PCVT_FREEBSD
187
188 #if PCVT_NETBSD > 9
189         printf(": ");
190 #else
191         printf("vt%d: ", dev->id_unit);
192 #endif /* PCVT_NETBSD > 9 */
193
194         switch(adaptor_type)
195         {
196                 case MDA_ADAPTOR:
197                         printf("mda");
198                         break;
199
200                 case CGA_ADAPTOR:
201                         printf("cga");
202                         break;
203
204                 case EGA_ADAPTOR:
205                         printf("ega");
206                         break;
207
208                 case VGA_ADAPTOR:
209                         printf("%s, ", (char *)vga_string(vga_type));
210                         if(can_do_132col)
211                                 printf("80/132 col");
212                         else
213                                 printf("80 col");
214                         vgapelinit();
215                         break;
216
217                 default:
218                         printf("unknown");
219                         break;
220         }
221
222         if(color == 0)
223                 printf(", mono");
224         else
225                 printf(", color");
226
227         printf(", %d scr, ", totalscreens);
228
229         switch(keyboard_type)
230         {
231                 case KB_AT:
232                         printf("at-");
233                         break;
234
235                 case KB_MFII:
236                         printf("mf2-");
237                         break;
238
239                 default:
240                         printf("unknown ");
241                         break;
242         }
243
244         printf("kbd, [R%s]\n", PCVT_REL);
245
246 #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
247
248         for(i = 0; i < totalscreens; i++)
249         {
250
251 #if PCVT_NETBSD
252                 pc_tty[i] = ttymalloc();
253                 vs[i].vs_tty = pc_tty[i];
254 #else /* !PCVT_NETBSD */
255                 pccons[i] = ttymalloc(pccons[i]);
256                 vs[i].vs_tty = pccons[i];
257 #endif /* PCVT_NETBSD */
258
259         }
260
261 #if PCVT_EMU_MOUSE
262 #if PCVT_NETBSD
263         pc_tty[totalscreens] = ttymalloc(); /* the mouse emulator tty */
264 #else /* !PCVT_NETBSD */
265         /* the mouse emulator tty */
266         pc_tty[totalscreens] = ttymalloc(pccons[totalscreens]);
267 #endif /* PCVT_NETBSD */
268 #endif /* PCVT_EMU_MOUSE */
269
270 #if PCVT_NETBSD
271         pcconsp = pc_tty[0];
272 #else  /* !PCVT_NETBSD */
273         pcconsp = pccons[0];
274 #endif  /* PCVT_NETBSD */
275
276 #endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
277
278 #else /* !PCVT_NETBSD && !PCVT_FREEBSD*/
279
280         switch(adaptor_type)
281         {
282                 case MDA_ADAPTOR:
283                         printf(" <mda");
284                         break;
285
286                 case CGA_ADAPTOR:
287                         printf(" <cga");
288                         break;
289
290                 case EGA_ADAPTOR:
291                         printf(" <ega");
292                         break;
293
294                 case VGA_ADAPTOR:
295                         printf(" <%s,", (char *)vga_string(vga_type));
296                         if(can_do_132col)
297                                 printf("80/132 col");
298                         else
299                                 printf("80 col");
300                         vgapelinit();
301                         break;
302
303                 default:
304                         printf(" <unknown");
305                         break;
306         }
307
308         if(color == 0)
309                 printf(",mono");
310         else
311                 printf(",color");
312
313         printf(",%d scr,", totalscreens);
314
315         switch(keyboard_type)
316         {
317                 case KB_AT:
318                         printf("at-");
319                         break;
320
321                 case KB_MFII:
322                         printf("mf2-");
323                         break;
324
325                 default:
326                         printf("unknown ");
327                         break;
328         }
329
330         printf("kbd,[R%s]>", PCVT_REL);
331
332 #endif  /* PCVT_NETBSD || PCVT_FREEBSD */
333
334 #if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
335         for(i = 0; i < totalscreens; i++)
336         {
337                 ttyregister(&pccons[i]);
338                 vs[i].vs_tty = &pccons[i];
339                 make_dev(&pc_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
340         }
341 #endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
342
343         async_update(UPDATE_START);     /* start asynchronous updates */
344
345 #if PCVT_NETBSD > 9
346
347         vthand.ih_fun = pcrint;
348         vthand.ih_arg = 0;
349         vthand.ih_level = IPL_TTY;
350
351 #if (PCVT_NETBSD > 100) && defined(IST_EDGE)
352         intr_establish(ia->ia_irq, IST_EDGE, &vthand);
353 #else /* PCVT_NETBSD > 100 */
354         intr_establish(ia->ia_irq, &vthand);
355 #endif /* PCVT_NETBSD > 100 */
356
357 #else /* PCVT_NETBSD > 9 */
358
359         dev->id_ointr = pcrint;
360
361         return 1;
362
363 #endif /* PCVT_NETBSD > 9 */
364
365 }
366
367 /* had a look at the friedl driver */
368
369 #if !PCVT_NETBSD
370
371 struct tty *
372 get_pccons(Dev_t dev)
373 {
374         register int i = minor(dev);
375
376 #if PCVT_EMU_MOUSE
377         if(i == totalscreens)
378 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
379                 return(&pccons[i]);
380 #else
381                 return(pccons[i]);
382 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
383 #endif /* PCVT_EMU_MOUSE */
384
385         if(i >= PCVT_NSCREENS)
386                 return(NULL);
387 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
388         return(&pccons[i]);
389 #else
390         return(pccons[i]);
391 #endif
392 }
393
394 #else
395
396 struct tty *
397 get_pccons(Dev_t dev)
398 {
399         register int i = minor(dev);
400
401 #if PCVT_EMU_MOUSE
402         if(i == totalscreens)
403                 return(pc_tty[i]);
404 #endif /* PCVT_EMU_MOUSE */
405
406         if(i >= PCVT_NSCREENS)
407                 return(NULL);
408         return(pc_tty[i]);
409 }
410
411 #endif /* !PCVT_NETBSD */
412
413 /*---------------------------------------------------------------------------*
414  *              /dev/ttyc0, /dev/ttyc1, etc.
415  *---------------------------------------------------------------------------*/
416 int
417 pcopen(Dev_t dev, int flag, int mode, struct proc *p)
418 {
419         register struct tty *tp;
420         register struct video_state *vsx;
421         int s, retval;
422         int winsz = 0;
423         int i = minor(dev);
424
425 #if PCVT_EMU_MOUSE
426         if(i == totalscreens)
427                 vsx = 0;
428         else
429 #endif /* PCVT_EMU_MOUSE */
430
431         vsx = &vs[i];
432
433         if((tp = get_pccons(dev)) == NULL)
434                 return ENXIO;
435
436         dev->si_tty = tp;
437
438 #if PCVT_EMU_MOUSE
439         if(i == totalscreens)
440         {
441                 if(mouse.opened == 0)
442                         mouse.buttons = mouse.extendedseen =
443                                 mouse.breakseen = mouse.lastmove.tv_sec = 0;
444                 mouse.minor = i;
445                 mouse.opened++;
446         }
447         else
448 #endif /* PCVT_EMU_MOUSE */
449
450         vsx->openf++;
451
452         tp->t_oproc = pcstart;
453         tp->t_param = pcparam;
454         tp->t_stop = nottystop;
455         tp->t_dev = dev;
456
457         if ((tp->t_state & TS_ISOPEN) == 0)
458         {
459
460 #ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
461                 tp->t_state |= TS_WOPEN;
462 #endif
463
464                 ttychars(tp);
465                 tp->t_iflag = TTYDEF_IFLAG;
466                 tp->t_oflag = TTYDEF_OFLAG;
467                 tp->t_cflag = TTYDEF_CFLAG;
468                 tp->t_lflag = TTYDEF_LFLAG;
469                 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
470                 pcparam(tp, &tp->t_termios);
471                 (*linesw[tp->t_line].l_modem)(tp, 1);   /* fake connection */
472                 winsz = 1;                      /* set winsize later */
473         }
474         else if (tp->t_state & TS_XCLUDE && suser(p))
475                 return (EBUSY);
476
477 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
478         retval = ((*linesw[tp->t_line].l_open)(dev, tp));
479 #else
480         retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
481 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
482
483         if(winsz == 1)
484         {
485
486                 /*
487                  * The line discipline has clobbered t_winsize if TS_ISOPEN
488                  * was clear. (NetBSD PR #400 from Bill Sommerfeld)
489                  * We have to do this after calling the open routine, because
490                  * it does some other things in other/older *BSD releases -hm
491                  */
492
493                 s = spltty();
494
495                 tp->t_winsize.ws_col = vsx->maxcol;
496                 tp->t_winsize.ws_row = vsx->screen_rows;
497                 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
498                 tp->t_winsize.ws_ypixel = 400;
499
500                 splx(s);
501         }
502
503         return(retval);
504 }
505
506 int
507 pcclose(Dev_t dev, int flag, int mode, struct proc *p)
508 {
509         register struct tty *tp;
510         register struct video_state *vsx;
511         int i = minor(dev);
512
513 #if PCVT_EMU_MOUSE
514         if(i == totalscreens)
515                 vsx = 0;
516         else
517 #endif /* PCVT_EMU_MOUSE */
518
519         vsx = &vs[i];
520
521         if((tp = get_pccons(dev)) == NULL)
522                 return ENXIO;
523
524         (*linesw[tp->t_line].l_close)(tp, flag);
525         ttyclose(tp);
526
527 #if PCVT_EMU_MOUSE
528         if(i == totalscreens)
529                 mouse.opened = 0;
530         else
531 #endif /* PCVT_EMU_MOUSE */
532
533         vsx->openf = 0;
534
535 #if PCVT_USL_VT_COMPAT
536 #if PCVT_EMU_MOUSE
537
538         if(i == totalscreens)
539                 return (0);
540
541 #endif /* PCVT_EMU_MOUSE */
542
543         reset_usl_modes(vsx);
544
545 #endif /* PCVT_USL_VT_COMPAT */
546
547         return(0);
548 }
549
550 int
551 pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
552 {
553         register int error;
554         register struct tty *tp;
555
556         if((tp = get_pccons(dev)) == NULL)
557                 return(ENXIO);
558
559         /* note that some ioctl's are global, e.g.  KBSTPMAT: There is
560          * only one keyboard and different repeat rates for instance between
561          * sessions are a suspicious wish. If you really need this make the
562          * appropriate variables arrays
563          */
564
565 #if PCVT_EMU_MOUSE
566         if(minor(dev) == totalscreens)
567         {
568                 if((error = mouse_ioctl(dev, cmd, data)) >= 0)
569                         return error;
570                 goto do_standard;
571         }
572 #endif /* PCVT_EMU_MOUSE */
573
574 #ifdef XSERVER
575 #if PCVT_USL_VT_COMPAT
576
577         if((error = usl_vt_ioctl(dev, cmd, data, flag, p)) >= 0)
578                 return error;
579
580         /*
581          * just for compatibility:
582          * XFree86 < 2.0 and SuperProbe still might use it
583          *
584          * NB: THIS IS A HACK! Do not use it unless you explicitly need.
585          * Especially, since the vty is not put into process-controlled
586          * mode (this would require the application to co-operate), any
587          * attempts to switch vtys while this kind of X mode is active
588          * may cause serious trouble.
589          */
590         switch(cmd)
591         {
592           case CONSOLE_X_MODE_ON:
593           {
594             int i;
595
596             if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, p)) > 0)
597               return error;
598
599             i = KD_GRAPHICS;
600             if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p))
601                > 0)
602               return error;
603
604             i = K_RAW;
605             error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p);
606             return error;
607           }
608
609           case CONSOLE_X_MODE_OFF:
610           {
611             int i;
612
613             (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, p);
614
615             i = KD_TEXT;
616             (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p);
617
618             i = K_XLATE;
619             (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p);
620             return 0;
621           }
622
623
624           case CONSOLE_X_BELL:
625
626                 /*
627                  * If `data' is non-null, the first int value denotes
628                  * the pitch, the second a duration. Otherwise, behaves
629                  * like BEL.
630                  */
631
632                 if (data)
633                 {
634
635 #if PCVT_NETBSD
636                         sysbeep(((int *)data)[0],
637                                 ((int *)data)[1] * hz / 1000);
638 #else /* PCVT_NETBSD */
639                         sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
640                                 ((int *)data)[1] * hz / 3000);
641 #endif /* PCVT_NETBSD */
642
643                 }
644                 else
645                 {
646                         sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
647                 }
648                 return (0);
649
650           default: /* fall through */ ;
651         }
652
653 #else /* PCVT_USL_VT_COMPAT */
654
655         switch(cmd)
656         {
657           case CONSOLE_X_MODE_ON:
658                 return pcvt_xmode_set(1, p);
659
660           case CONSOLE_X_MODE_OFF:
661                 return pcvt_xmode_set(0, p);
662
663           case CONSOLE_X_BELL:
664
665                 /*
666                  * If `data' is non-null, the first int value denotes
667                  * the pitch, the second a duration. Otherwise, behaves
668                  * like BEL.
669                  */
670
671                 if (data)
672                 {
673
674 #if PCVT_NETBSD
675                         sysbeep(((int *)data)[0],
676                                 ((int *)data)[1] * hz / 1000);
677 #else /* PCVT_NETBSD */
678                         sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
679                                 ((int *)data)[1] * hz / 3000);
680 #endif /* PCVT_NETBSD */
681
682                 }
683                 else
684                 {
685                         sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
686                 }
687                 return (0);
688
689           default: /* fall through */ ;
690         }
691
692 #endif /* PCVT_USL_VT_COMPAT */
693 #endif /* XSERVER */
694
695         if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
696                 return error;
697
698         if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
699                 return error;
700
701 #if PCVT_EMU_MOUSE
702 do_standard:
703 #endif
704
705 #if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
706         if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p))
707             != ENOIOCTL)
708                 return (error);
709 #else
710         if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
711                 return(error);
712 #endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
713
714 #if PCVT_NETBSD > 9
715         if((error = ttioctl(tp, cmd, data, flag, p)) >= 0)
716                 return (error);
717 #else
718         if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
719                 return (error);
720 #endif /* PCVT_NETBSD > 9 */
721
722         return (ENOTTY);
723 }
724
725 int
726 pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
727 {
728         if (offset > 0x20000 - PAGE_SIZE)
729                 return -1;
730         return i386_btop((0xa0000 + offset));
731 }
732
733 /*---------------------------------------------------------------------------*
734  *
735  *      handle a keyboard receive interrupt
736  *
737  *      NOTE: the keyboard is multiplexed by means of "pcconsp"
738  *      between virtual screens. pcconsp - switching is done in
739  *      the vgapage() routine
740  *
741  *---------------------------------------------------------------------------*/
742
743 #if PCVT_KBD_FIFO
744
745 u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
746 static int pcvt_kbd_wptr = 0;
747 int pcvt_kbd_rptr = 0;
748 short pcvt_kbd_count= 0;
749 static u_char pcvt_timeout_scheduled = 0;
750
751 static void
752 pcvt_timeout(void *arg)
753 {
754         u_char *cp;
755
756 #if PCVT_SLOW_INTERRUPT
757         int     s;
758 #endif
759
760         pcvt_timeout_scheduled = 0;
761
762 #if PCVT_SCREENSAVER
763         pcvt_scrnsv_reset();
764 #endif /* PCVT_SCREENSAVER */
765
766         while (pcvt_kbd_count)
767         {
768                 if (((cp = sgetc(1)) != 0) &&
769                     (vs[current_video_screen].openf))
770                 {
771
772 #if PCVT_NULLCHARS
773                         if(*cp == '\0')
774                         {
775                                 /* pass a NULL character */
776                                 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
777                         }
778 /* XXX */               else
779 #endif /* PCVT_NULLCHARS */
780
781                         while (*cp)
782                                 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
783                 }
784
785                 PCVT_DISABLE_INTR ();
786
787                 if (!pcvt_kbd_count)
788                         pcvt_timeout_scheduled = 0;
789
790                 PCVT_ENABLE_INTR ();
791         }
792
793         return;
794 }
795 #endif
796
797 #ifdef _DEV_KBD_KBDREG_H_
798 static void
799 detect_kbd(void *arg)
800 {
801         int unit = (int)arg;
802         int i;
803
804         if (kbd != NULL)
805                 return;
806         i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
807         if (i >= 0)
808                 kbd = kbd_get_keyboard(i);
809         if (kbd != NULL)
810         {
811                 reset_keyboard = 1;     /* ok to reset the keyboard */
812                 kbd_code_init();
813                 return;
814         }
815         reset_keyboard = 0;
816         timeout(detect_kbd, (void *)unit, hz*2);
817 }
818
819 int
820 pcevent(keyboard_t *thiskbd, int event, void *arg)
821 {
822         int unit = (int)arg;
823
824         if (thiskbd != kbd)
825                 return EINVAL;          /* shouldn't happen */
826
827         switch (event) {
828         case KBDIO_KEYINPUT:
829                 pcrint(unit);
830                 return 0;
831         case KBDIO_UNLOADING:
832                 reset_keyboard = 0;
833                 kbd = NULL;
834                 kbd_release(thiskbd, (void *)&kbd);
835                 timeout(detect_kbd, (void *)unit, hz*4);
836                 return 0;
837         default:
838                 return EINVAL;
839         }
840 }
841 #endif /* _DEV_KBD_KBDREG_H_ */
842
843 void
844 pcrint(int unit)
845 {
846
847 #if PCVT_KBD_FIFO
848         u_char  dt;
849         u_char  ret = -1;
850
851 # if PCVT_SLOW_INTERRUPT
852         int     s;
853 # endif
854
855 # ifdef _DEV_KBD_KBDREG_H_
856         int     c;
857 # endif
858
859 #else /* !PCVT_KBD_FIFO */
860         u_char  *cp;
861 #endif /* PCVT_KBD_FIFO */
862
863 #if PCVT_SCREENSAVER
864         pcvt_scrnsv_reset();
865 #endif /* PCVT_SCREENSAVER */
866
867 #if PCVT_KBD_FIFO
868         if (kbd_polling)
869         {
870                 sgetc(1);
871                 return;
872         }
873
874 # ifndef _DEV_KBD_KBDREG_H_
875         while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)    /* check 8042 buffer */
876         {
877                 ret = 1;                                /* got something */
878
879                 PCVT_KBD_DELAY();                       /* 7 us delay */
880
881                 dt = inb(CONTROLLER_DATA);              /* get it 8042 data */
882 # else 
883         while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
884         {
885                 ret = 1;                                /* got something */
886                 dt = c;
887 # endif /* _DEV_KBD_KBDREG_H_ */
888
889                 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
890                 {
891                         log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
892                 }
893                 else
894                 {
895                         pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
896
897                         PCVT_DISABLE_INTR ();   /* XXX necessary ? */
898                         pcvt_kbd_count++;               /* update fifo count */
899                         PCVT_ENABLE_INTR ();
900
901                         if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
902                                 pcvt_kbd_wptr = 0;      /* wraparound pointer */
903                 }
904         }
905
906         if (ret == 1)   /* got data from keyboard ? */
907         {
908                 if (!pcvt_timeout_scheduled)    /* if not already active .. */
909                 {
910                         PCVT_DISABLE_INTR ();
911                         pcvt_timeout_scheduled = 1;     /* flag active */
912                         timeout(pcvt_timeout, NULL, hz / 100);  /* fire off */
913                         PCVT_ENABLE_INTR ();
914                 }
915         }
916
917 #else /* !PCVT_KBD_FIFO */
918
919         if((cp = sgetc(1)) == 0)
920                 return;
921
922         if (kbd_polling)
923                 return;
924
925         if(!(vs[current_video_screen].openf))   /* XXX was vs[minor(dev)] */
926                 return;
927
928 #if PCVT_NULLCHARS
929         if(*cp == '\0')
930         {
931                 /* pass a NULL character */
932                 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
933                 return;
934         }
935 #endif /* PCVT_NULLCHARS */
936
937         while (*cp)
938                 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
939
940 #endif /* PCVT_KBD_FIFO */
941 }
942
943
944 #if PCVT_NETBSD || PCVT_FREEBSD >= 200
945
946 void
947 pcstart(register struct tty *tp)
948 {
949         register struct clist *rbp;
950         int s, len;
951         u_char buf[PCVT_PCBURST];
952
953         s = spltty();
954
955         if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
956                 goto out;
957
958         tp->t_state |= TS_BUSY;
959
960         splx(s);
961
962         async_update(UPDATE_KERN);
963
964         rbp = &tp->t_outq;
965
966         /*
967          * Call q_to_b() at spltty() to ensure that the queue is empty when
968          * the loop terminates.
969          */
970
971         s = spltty();
972
973         while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
974         {
975                 if(vs[minor(tp->t_dev)].scrolling)
976                         sgetc(31337);
977                 
978                 /*
979                  * We need to do this outside spl since it could be fairly
980                  * expensive and we don't want our serial ports to overflow.
981                  */
982                 splx(s);
983                 sput(&buf[0], 0, len, minor(tp->t_dev));
984                 s = spltty();
985         }
986
987         tp->t_state &= ~TS_BUSY;
988
989 #ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
990         ttwwakeup(tp);
991 #else
992         if (rbp->c_cc <= tp->t_lowat)
993         {
994                 if (tp->t_state&TS_ASLEEP)
995                 {
996                         tp->t_state &= ~TS_ASLEEP;
997                         wakeup((caddr_t)rbp);
998                 }
999                 selwakeup(&tp->t_wsel);
1000         }
1001 #endif
1002 out:
1003         splx(s);
1004 }
1005
1006 void
1007 pcstop(struct tty *tp, int flag)
1008 {
1009 }
1010
1011 #else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1012
1013 void
1014 pcstart(struct tty *tp)
1015 {
1016         int s;
1017         unsigned char c;
1018
1019         s = spltty();
1020
1021         if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
1022         {
1023                 goto out;
1024         }
1025
1026         for(;;)
1027         {
1028
1029 #if !(PCVT_FREEBSD > 114)
1030
1031 #if !(PCVT_FREEBSD > 111)
1032                 if (RB_LEN(&tp->t_out) <= tp->t_lowat)
1033 #else
1034                 if (RB_LEN(tp->t_out) <= tp->t_lowat)
1035 #endif
1036                 {
1037                         if (tp->t_state&TS_ASLEEP)
1038                         {
1039                                 tp->t_state &= ~TS_ASLEEP;
1040 #if !(PCVT_FREEBSD > 111)
1041                                 wakeup((caddr_t)&tp->t_out);
1042 #else
1043                                 wakeup((caddr_t)tp->t_out);
1044 #endif
1045                         }
1046
1047                         if (tp->t_wsel)
1048                         {
1049                                 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
1050                                 tp->t_wsel = 0;
1051                                 tp->t_state &= ~TS_WCOLL;
1052                         }
1053                 }
1054
1055 #else /* PCVT_FREEBSD > 114 */
1056                 if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
1057                     || tp->t_wsel) {
1058                         ttwwakeup(tp);
1059                 }
1060 #endif /* !PCVT_FREEBSD > 114 */
1061
1062 #if !(PCVT_FREEBSD > 111)
1063                 if (RB_LEN(&tp->t_out) == 0)
1064 #else
1065                 if (RB_LEN(tp->t_out) == 0)
1066 #endif
1067                 {
1068                         goto out;
1069                 }
1070
1071 #if !(PCVT_FREEBSD > 111)
1072                 c = getc(&tp->t_out);
1073 #else
1074                 c = getc(tp->t_out);
1075 #endif
1076
1077                 tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */
1078                 splx(s);
1079                 sput(&c, 0, 1, minor(tp->t_dev));
1080                 spltty();
1081                 tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
1082         }
1083 out:
1084         splx(s);
1085 }
1086
1087 #endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1088
1089 /*---------------------------------------------------------------------------*
1090  *              /dev/console
1091  *---------------------------------------------------------------------------*/
1092
1093 #if !PCVT_NETBSD        /* has moved to cons.c in netbsd-current */
1094 void
1095 consinit()              /* init for kernel messages during boot */
1096 {
1097 }
1098 #endif /* PCVT_NETBSD */
1099
1100 #if PCVT_FREEBSD > 205
1101 static void
1102 #else
1103 int
1104 #endif
1105 pccnprobe(struct consdev *cp)
1106 {
1107         int unit = 0;
1108         int i;
1109
1110         /* See if this driver is disabled in probe hint. */ 
1111         if (resource_int_value("vt", unit, "disabled", &i) == 0 && i) {
1112                 cp->cn_pri = CN_DEAD;
1113                 return;
1114         }
1115
1116 #ifdef _DEV_KBD_KBDREG_H_
1117         kbd_configure(KB_CONF_PROBE_ONLY);
1118         if (kbd_find_keyboard("*", unit) < 0)
1119         {
1120                 cp->cn_pri = CN_DEAD;
1121                 return;
1122         }
1123 #endif /* _DEV_KBD_KBDREG_H_ */
1124
1125         /* initialize required fields */
1126
1127         cp->cn_dev = makedev(CDEV_MAJOR, 0);
1128         cp->cn_pri = CN_INTERNAL;
1129
1130 #if !PCVT_NETBSD
1131
1132 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
1133         cp->cn_tp = &pccons[0];
1134 #else
1135         cp->cn_tp = pccons[0];
1136 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
1137
1138 #endif /* !PCVT_NETBSD */
1139
1140 #if PCVT_FREEBSD <= 205
1141         return 1;
1142 #endif
1143 }
1144
1145 #if PCVT_FREEBSD > 205
1146 static void
1147 #else
1148 int
1149 #endif
1150 pccninit(struct consdev *cp)
1151 {
1152         int unit = 0;
1153         int i;
1154
1155         pcvt_is_console = 1;
1156
1157 #ifdef _DEV_KBD_KBDREG_H_
1158         /*
1159          * Don't reset the keyboard via `kbdio' just yet.
1160          * The system clock has not been calibrated...
1161          */
1162         reset_keyboard = 0;
1163
1164         if (kbd)
1165         {
1166                 kbd_release(kbd, (void *)&kbd);
1167                 kbd = NULL;
1168         }
1169         i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
1170         if (i >= 0)
1171                 kbd = kbd_get_keyboard(i);
1172
1173 #if PCVT_SCANSET == 2
1174         /*
1175          * Turn off scancode translation early so that UserConfig 
1176          * and DDB can read the keyboard.
1177          */
1178         if (kbd)
1179         {
1180                 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
1181                 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1182                                             KBD_TRANSLATION, 0);
1183         }
1184 #endif /* PCVT_SCANSET == 2 */
1185
1186 #endif /* _DEV_KBD_KBDREG_H_ */
1187
1188 #if PCVT_FREEBSD <= 205
1189         return 0;
1190 #endif
1191 }
1192
1193 static void
1194 pccnterm(struct consdev *cp)
1195 {
1196 #ifdef _DEV_KBD_KBDREG_H_
1197         if (kbd)
1198         {
1199                 kbd_release(kbd, (void *)&kbd);
1200                 kbd = NULL;
1201         }
1202 #endif /* _DEV_KBD_KBDREG_H_ */
1203 }
1204
1205 #if PCVT_FREEBSD > 205
1206 static void
1207 #else
1208 int
1209 #endif
1210 pccnputc(Dev_t dev, U_char c)
1211 {
1212
1213 #if PCVT_SW0CNOUTP
1214
1215         if(current_video_screen != 0)
1216         {
1217
1218 #if !PCVT_USL_VT_COMPAT
1219                 vgapage(0);
1220 #else
1221                 switch_screen(0, 0);
1222 #endif /* !PCVT_USL_VT_COMPAT */
1223
1224         }
1225
1226 #endif /* PCVT_SW0CNOUTP */
1227
1228         if (c == '\n')
1229                 sput("\r", 1, 1, 0);
1230
1231         sput((char *) &c, 1, 1, 0);
1232
1233         async_update(UPDATE_KERN);
1234
1235 #if PCVT_FREEBSD <= 205
1236         return 0;
1237 #endif
1238 }
1239
1240 static int
1241 pccngetc(Dev_t dev)
1242 {
1243         register int s;
1244         static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
1245         register u_char c;
1246
1247 #ifdef XSERVER
1248
1249 #if !PCVT_USL_VT_COMPAT
1250         if (pcvt_xmode)
1251                 return 0;
1252 #else /* !PCVT_USL_VT_COMPAT */
1253         if (pcvt_kbd_raw)
1254                 return 0;
1255 #endif /* !PCVT_USL_VT_COMPAT */
1256
1257 #endif /* XSERVER */
1258
1259         if (cp && *cp)
1260                 /*
1261                  * We still have a pending key sequence, e.g.
1262                  * from an arrow key.  Deliver this one first.
1263                  */
1264                 return (*cp++);
1265
1266 #ifdef _DEV_KBD_KBDREG_H_
1267         if (kbd == NULL)
1268                 return 0;
1269 #endif  
1270
1271         s = spltty();           /* block pcrint while we poll */
1272         kbd_polling = 1;
1273 #ifdef _DEV_KBD_KBDREG_H_
1274         (*kbdsw[kbd->kb_index]->enable)(kbd);
1275 #endif  
1276         cp = sgetc(0);
1277 #ifdef _DEV_KBD_KBDREG_H_
1278         (*kbdsw[kbd->kb_index]->disable)(kbd);
1279 #endif  
1280         kbd_polling = 0;
1281         splx(s);
1282         c = *cp++;
1283         if (c && *cp) {
1284                 /* Preserve the multi-char sequence for the next call. */
1285                 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
1286                 cp = cbuf;
1287         } else
1288                 cp = 0;
1289
1290 #if ! (PCVT_FREEBSD >= 201)
1291         /* this belongs to cons.c */
1292         if (c == '\r')
1293                 c = '\n';
1294 #endif /* ! (PCVT_FREEBSD >= 201) */
1295
1296         return c;
1297 }
1298
1299 #if PCVT_FREEBSD >= 200
1300 static int
1301 pccncheckc(Dev_t dev)
1302 {
1303         char *cp;
1304         int x;
1305
1306 #ifdef _DEV_KBD_KBDREG_H_
1307         if (kbd == NULL)
1308                 return 0;
1309 #endif  
1310
1311         x = spltty();
1312         kbd_polling = 1;
1313 #ifdef _DEV_KBD_KBDREG_H_
1314         (*kbdsw[kbd->kb_index]->enable)(kbd);
1315 #endif  
1316         cp = sgetc(1);
1317 #ifdef _DEV_KBD_KBDREG_H_
1318         (*kbdsw[kbd->kb_index]->disable)(kbd);
1319 #endif  
1320         kbd_polling = 0;
1321         splx(x);
1322         return (cp == NULL ? -1 : *cp);
1323 }
1324 #endif /* PCVT_FREEBSD >= 200 */
1325
1326 #if PCVT_NETBSD >= 100
1327 void
1328 pccnpollc(Dev_t dev, int on)
1329 {
1330         kbd_polling = on;
1331         if (!on) {
1332                 register int s;
1333
1334                 /*
1335                  * If disabling polling, make sure there are no bytes left in
1336                  * the FIFO, holding up the interrupt line.  Otherwise we
1337                  * won't get any further interrupts.
1338                  */
1339                 s = spltty();
1340                 pcrint();
1341                 splx(s);
1342         }
1343 }
1344 #endif /* PCVT_NETBSD >= 100 */
1345
1346 /*---------------------------------------------------------------------------*
1347  *      Set line parameters
1348  *---------------------------------------------------------------------------*/
1349 int
1350 pcparam(struct tty *tp, struct termios *t)
1351 {
1352         register int cflag = t->c_cflag;
1353
1354         /* and copy to tty */
1355
1356         tp->t_ispeed = t->c_ispeed;
1357         tp->t_ospeed = t->c_ospeed;
1358         tp->t_cflag = cflag;
1359
1360         return(0);
1361 }
1362
1363 /*----------------------------------------------------------------------*
1364  *      read initial VGA palette (as stored by VGA ROM BIOS) into
1365  *      palette save area
1366  *----------------------------------------------------------------------*/
1367 void
1368 vgapelinit(void)
1369 {
1370         register unsigned idx;
1371         register struct rgb *val;
1372
1373         /* first, read all and store to first screen's save buffer */
1374         for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
1375                 vgapaletteio(idx, val, 0 /* read it */);
1376
1377         /* now, duplicate for remaining screens */
1378         for(idx = 1; idx < PCVT_NSCREENS; idx++)
1379                 bcopy(vs[0].palette, vs[idx].palette,
1380                       NVGAPEL * sizeof(struct rgb));
1381 }
1382
1383 #if defined XSERVER && !PCVT_USL_VT_COMPAT
1384 /*----------------------------------------------------------------------*
1385  *      initialize for X mode
1386  *      i.e.: grant current process (the X server) all IO privileges,
1387  *      and mark in static variable so other hooks can test for it,
1388  *      save all loaded fonts and screen pages to pageable buffers;
1389  *      if parameter `on' is false, the same procedure is done reverse.
1390  *----------------------------------------------------------------------*/
1391 static int
1392 pcvt_xmode_set(int on, struct proc *p)
1393 {
1394         static unsigned char *saved_fonts[NVGAFONTS];
1395
1396 #if PCVT_SCREENSAVER
1397         static unsigned saved_scrnsv_tmo = 0;
1398 #endif /* PCVT_SCREENSAVER */
1399
1400 #if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
1401         struct trapframe *fp;
1402 #else
1403         struct syscframe *fp;
1404 #endif /* PCVT_NETBSD > 9 */
1405
1406         int error, i;
1407
1408         /* X will only run on VGA and Hercules adaptors */
1409
1410         if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
1411                 return (EINVAL);
1412
1413 #if PCVT_NETBSD > 9
1414         fp = (struct trapframe *)p->p_regs;
1415 #else
1416         fp = (struct syscframe *)p->p_regs;
1417 #endif /* PCVT_NETBSD > 9 */
1418
1419         if(on)
1420         {
1421                 /*
1422                  * Test whether the calling process has super-user privileges
1423                  * and we're in insecure mode.
1424                  * This prevents us from granting the potential security hole
1425                  * `IO priv' to insufficiently privileged processes.
1426                  */
1427                 error = suser(p);
1428                 if (error != 0)
1429                         return (error);
1430                 if (securelevel > 0)
1431                         return (EPERM);
1432
1433                 if(pcvt_xmode)
1434                         return 0;
1435
1436                 pcvt_xmode = pcvt_kbd_raw = 1;
1437
1438                 for(i = 0; i < totalfonts; i++)
1439                 {
1440                         if(vgacs[i].loaded)
1441                         {
1442                                 saved_fonts[i] = (unsigned char *)
1443                                         malloc(32 * 256, M_DEVBUF, M_WAITOK);
1444                                 if(saved_fonts[i] == 0)
1445                                 {
1446                                         printf(
1447                                   "pcvt_xmode_set: no font buffer available\n");
1448                                         return (EAGAIN);
1449                                 }
1450                                 else
1451                                 {
1452                                         vga_move_charset(i, saved_fonts[i], 1);
1453                                 }
1454                         }
1455                         else
1456                         {
1457                                 saved_fonts[i] = 0;
1458                         }
1459                 }
1460
1461 #if PCVT_SCREENSAVER
1462                 if(saved_scrnsv_tmo = scrnsv_timeout)
1463                         pcvt_set_scrnsv_tmo(0); /* turn it off */
1464 #endif /* PCVT_SCREENSAVER */
1465
1466                 async_update(UPDATE_STOP);      /* turn off */
1467
1468                 /* disable text output and save screen contents */
1469                 /* video board memory -> kernel memory */
1470
1471                 bcopy(vsp->Crtat, vsp->Memory,
1472                        vsp->screen_rowsize * vsp->maxcol * CHR);
1473
1474                 vsp->Crtat = vsp->Memory;       /* operate in memory now */
1475
1476 #ifndef _DEV_KBD_KBDREG_H_
1477
1478 #if PCVT_SCANSET == 2
1479                 /* put keyboard to return ancient PC scan codes */
1480                 kbc_8042cmd(CONTR_WRITE);
1481 #if PCVT_USEKBDSEC              /* security enabled */
1482                 outb(CONTROLLER_DATA,
1483                  (COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1484 #else                           /* security disabled */
1485                 outb(CONTROLLER_DATA,
1486                  (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1487 #endif /* PCVT_USEKBDSEC */
1488 #endif /* PCVT_SCANSET == 2 */
1489
1490 #else /* _DEV_KBD_KBDREG_H_ */
1491
1492 #if PCVT_SCANSET == 2
1493                 /* put keyboard to return ancient PC scan codes */
1494                 set_controller_command_byte(*(KBDC *)kbd->kb_data, 
1495                         KBD_TRANSLATION, KBD_TRANSLATION); 
1496 #endif /* PCVT_SCANSET == 2 */
1497
1498 #endif /* !_DEV_KBD_KBDREG_H_ */
1499
1500 #if PCVT_NETBSD > 9
1501                 fp->tf_eflags |= PSL_IOPL;
1502 #else
1503                 fp->sf_eflags |= PSL_IOPL;
1504 #endif /* PCVT_NETBSD > 9 */
1505
1506         }
1507         else
1508         {
1509                 if(!pcvt_xmode)         /* verify if in X */
1510                         return 0;
1511
1512                 pcvt_xmode = pcvt_kbd_raw = 0;
1513
1514                 for(i = 0; i < totalfonts; i++)
1515                 {
1516                         if(saved_fonts[i])
1517                         {
1518                                 vga_move_charset(i, saved_fonts[i], 0);
1519                                 free(saved_fonts[i], M_DEVBUF);
1520                                 saved_fonts[i] = 0;
1521                         }
1522                 }
1523
1524 #if PCVT_NETBSD > 9
1525                 fp->tf_eflags &= ~PSL_IOPL;
1526 #else
1527                 fp->sf_eflags &= ~PSL_IOPL;
1528 #endif /* PCVT_NETBSD > 9 */
1529
1530 #if PCVT_SCREENSAVER
1531                 if(saved_scrnsv_tmo)
1532                         pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
1533 #endif /* PCVT_SCREENSAVER */
1534
1535 #ifndef _DEV_KBD_KBDREG_H_
1536
1537 #if PCVT_SCANSET == 2
1538                 kbc_8042cmd(CONTR_WRITE);
1539 #if PCVT_USEKBDSEC              /* security enabled */
1540                 outb(CONTROLLER_DATA,
1541                  (COMMAND_SYSFLG|COMMAND_IRQEN));
1542 #else                           /* security disabled */
1543                 outb(CONTROLLER_DATA,
1544                  (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN));
1545 #endif /* PCVT_USEKBDSEC */
1546 #endif /* PCVT_SCANSET == 2 */
1547
1548 #else /* _DEV_KBD_KBDREG_H_ */
1549
1550 #if PCVT_SCANSET == 2
1551                 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1552                         KBD_TRANSLATION, 0);
1553 #endif /* PCVT_SCANSET == 2 */
1554
1555 #endif /* !_DEV_KBD_KBDREG_H_ */
1556
1557                 if(adaptor_type == MDA_ADAPTOR)
1558                 {
1559                     /*
1560                      * Due to the fact that HGC registers are write-only,
1561                      * the Xserver can only make guesses about the state
1562                      * the HGC adaptor has been before turning on X mode.
1563                      * Thus, the display must be re-enabled now, and the
1564                      * cursor shape and location restored.
1565                      */
1566                     outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
1567                     outb(addr_6845, CRTC_CURSORH); /* select high register */
1568                     outb(addr_6845+1,
1569                          ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
1570                     outb(addr_6845, CRTC_CURSORL); /* select low register */
1571                     outb(addr_6845+1,
1572                          ((vsp->Crtat + vsp->cur_offset) - Crtat));
1573
1574                     outb(addr_6845, CRTC_CURSTART); /* select high register */
1575                     outb(addr_6845+1, vsp->cursor_start);
1576                     outb(addr_6845, CRTC_CUREND); /* select low register */
1577                     outb(addr_6845+1, vsp->cursor_end);
1578                   }
1579
1580                 /* restore screen and re-enable text output */
1581                 /* kernel memory -> video board memory */
1582
1583                 bcopy(vsp->Memory, Crtat,
1584                        vsp->screen_rowsize * vsp->maxcol * CHR);
1585
1586                 vsp->Crtat = Crtat;     /* operate on-screen now */
1587
1588                 /* set crtc screen memory start address */
1589
1590                 outb(addr_6845, CRTC_STARTADRH);
1591                 outb(addr_6845+1, (vsp->Crtat - Crtat) >> 8);
1592                 outb(addr_6845, CRTC_STARTADRL);
1593                 outb(addr_6845+1, (vsp->Crtat - Crtat));
1594
1595                 async_update(UPDATE_START);
1596         }
1597         return 0;
1598 }
1599 #endif  /* XSERVER && !PCVT_USL_VT_COMPAT */
1600
1601 #endif  /* NVT > 0 */
1602
1603 /*-------------------------- E O F -------------------------------------*/