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