xref: /freebsd/lib/libvgl/main.c (revision 5e7a62b28b77ba1f47da67d5ef2d31abf7ab1700)
19a57b7d2SSøren Schmidt /*-
29a57b7d2SSøren Schmidt  * Copyright (c) 1991-1997 S�ren Schmidt
39a57b7d2SSøren Schmidt  * All rights reserved.
49a57b7d2SSøren Schmidt  *
59a57b7d2SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
69a57b7d2SSøren Schmidt  * modification, are permitted provided that the following conditions
79a57b7d2SSøren Schmidt  * are met:
89a57b7d2SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
99a57b7d2SSøren Schmidt  *    notice, this list of conditions and the following disclaimer
109a57b7d2SSøren Schmidt  *    in this position and unchanged.
119a57b7d2SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
129a57b7d2SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
139a57b7d2SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
149a57b7d2SSøren Schmidt  * 3. The name of the author may not be used to endorse or promote products
159a57b7d2SSøren Schmidt  *    derived from this software withough specific prior written permission
169a57b7d2SSøren Schmidt  *
179a57b7d2SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
189a57b7d2SSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
199a57b7d2SSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
209a57b7d2SSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
219a57b7d2SSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
229a57b7d2SSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239a57b7d2SSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249a57b7d2SSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259a57b7d2SSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
269a57b7d2SSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279a57b7d2SSøren Schmidt  *
285e7a62b2SKazutaka YOKOTA  *  $Id: main.c,v 1.2 1997/10/01 20:53:39 sos Exp $
299a57b7d2SSøren Schmidt  */
309a57b7d2SSøren Schmidt 
319a57b7d2SSøren Schmidt #include <stdio.h>
329a57b7d2SSøren Schmidt #include <sys/types.h>
339a57b7d2SSøren Schmidt #include <sys/signal.h>
349a57b7d2SSøren Schmidt #include <sys/file.h>
359a57b7d2SSøren Schmidt #include <sys/ioctl.h>
369a57b7d2SSøren Schmidt #include <sys/mman.h>
379a57b7d2SSøren Schmidt #include <machine/console.h>
389a57b7d2SSøren Schmidt #include "vgl.h"
399a57b7d2SSøren Schmidt 
409a57b7d2SSøren Schmidt VGLBitmap *VGLDisplay;
419a57b7d2SSøren Schmidt 
429a57b7d2SSøren Schmidt static int VGLMode;
439a57b7d2SSøren Schmidt static int VGLOldMode;
449a57b7d2SSøren Schmidt static byte *VGLBuf;
459a57b7d2SSøren Schmidt static byte *VGLMem;
469a57b7d2SSøren Schmidt static int VGLSwitchPending;
479a57b7d2SSøren Schmidt static int VGLOnDisplay;
48b478da36SSøren Schmidt static int VGLInitDone = 0;
499a57b7d2SSøren Schmidt 
509a57b7d2SSøren Schmidt void
519a57b7d2SSøren Schmidt VGLEnd()
529a57b7d2SSøren Schmidt {
539a57b7d2SSøren Schmidt struct vt_mode smode;
549a57b7d2SSøren Schmidt 
55b478da36SSøren Schmidt   if (!VGLInitDone)
56b478da36SSøren Schmidt     return;
579a57b7d2SSøren Schmidt /*
589a57b7d2SSøren Schmidt   while (!VGLOnDisplay) pause();
599a57b7d2SSøren Schmidt   VGLCheckSwitch();;
609a57b7d2SSøren Schmidt */
619a57b7d2SSøren Schmidt   outb(0x3c4, 0x02);
629a57b7d2SSøren Schmidt   outb(0x3c5, 0x0f);
639a57b7d2SSøren Schmidt   bzero(VGLMem, 64*1024);
645e7a62b2SKazutaka YOKOTA   if (VGLOldMode >= M_VESA_BASE) {
655e7a62b2SKazutaka YOKOTA     /* ugly, but necessary */
665e7a62b2SKazutaka YOKOTA     ioctl(0, _IO('V', VGLOldMode - M_VESA_BASE), 0);
675e7a62b2SKazutaka YOKOTA     if (VGLOldMode == M_VESA_800x600) {
685e7a62b2SKazutaka YOKOTA       int size[3];
695e7a62b2SKazutaka YOKOTA       size[0] = 80;
705e7a62b2SKazutaka YOKOTA       size[1] = 25;
715e7a62b2SKazutaka YOKOTA       size[2] = 16;
725e7a62b2SKazutaka YOKOTA       ioctl(0, KDRASTER, size);
735e7a62b2SKazutaka YOKOTA     }
745e7a62b2SKazutaka YOKOTA   } else {
759a57b7d2SSøren Schmidt     ioctl(0, _IO('S', VGLOldMode), 0);
765e7a62b2SKazutaka YOKOTA   }
779a57b7d2SSøren Schmidt   ioctl(0, KDDISABIO, 0);
789a57b7d2SSøren Schmidt   ioctl(0, KDSETMODE, KD_TEXT);
799a57b7d2SSøren Schmidt   smode.mode = VT_AUTO;
809a57b7d2SSøren Schmidt   ioctl(0, VT_SETMODE, &smode);
819a57b7d2SSøren Schmidt   free(VGLBuf);
829a57b7d2SSøren Schmidt   free(VGLDisplay);
83b478da36SSøren Schmidt   VGLKeyboardEnd();
849a57b7d2SSøren Schmidt }
859a57b7d2SSøren Schmidt 
869a57b7d2SSøren Schmidt static void
879a57b7d2SSøren Schmidt VGLAbort()
889a57b7d2SSøren Schmidt {
899a57b7d2SSøren Schmidt   VGLEnd();
909a57b7d2SSøren Schmidt   exit(0);
919a57b7d2SSøren Schmidt }
929a57b7d2SSøren Schmidt 
939a57b7d2SSøren Schmidt static void
949a57b7d2SSøren Schmidt VGLSwitch()
959a57b7d2SSøren Schmidt {
969a57b7d2SSøren Schmidt   if (!VGLOnDisplay)
979a57b7d2SSøren Schmidt     VGLOnDisplay = 1;
989a57b7d2SSøren Schmidt   else
999a57b7d2SSøren Schmidt     VGLOnDisplay = 0;
1009a57b7d2SSøren Schmidt   VGLSwitchPending = 1;
1019a57b7d2SSøren Schmidt   signal(SIGUSR1, VGLSwitch);
1029a57b7d2SSøren Schmidt }
1039a57b7d2SSøren Schmidt 
1049a57b7d2SSøren Schmidt int
1059a57b7d2SSøren Schmidt VGLInit(int mode)
1069a57b7d2SSøren Schmidt {
1079a57b7d2SSøren Schmidt   struct vt_mode smode;
1089a57b7d2SSøren Schmidt   struct winsize winsz;
1099a57b7d2SSøren Schmidt   int error;
1109a57b7d2SSøren Schmidt 
1119a57b7d2SSøren Schmidt   signal(SIGUSR1, VGLSwitch);
1129a57b7d2SSøren Schmidt   signal(SIGINT, VGLAbort);
1139a57b7d2SSøren Schmidt   signal(SIGSEGV, VGLAbort);
1149a57b7d2SSøren Schmidt   signal(SIGBUS, VGLAbort);
1159a57b7d2SSøren Schmidt 
1169a57b7d2SSøren Schmidt   VGLOnDisplay = 1;
1179a57b7d2SSøren Schmidt   VGLSwitchPending = 0;
1189a57b7d2SSøren Schmidt 
1199a57b7d2SSøren Schmidt   ioctl(0, CONS_GET, &VGLOldMode);
1209a57b7d2SSøren Schmidt 
1219a57b7d2SSøren Schmidt   VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE,
1229a57b7d2SSøren Schmidt                           open("/dev/mem", O_RDWR), 0xA0000);
1239a57b7d2SSøren Schmidt   if (VGLMem <= (byte*)0)
1249a57b7d2SSøren Schmidt     return 1;
1259a57b7d2SSøren Schmidt 
1269a57b7d2SSøren Schmidt   VGLBuf = (byte*)malloc(256*1024);
1279a57b7d2SSøren Schmidt   if (VGLBuf == NULL)
1289a57b7d2SSøren Schmidt     return 1;
1299a57b7d2SSøren Schmidt 
1309a57b7d2SSøren Schmidt   VGLDisplay = (VGLBitmap*) malloc(sizeof(VGLBitmap));
1319a57b7d2SSøren Schmidt   if (VGLDisplay == NULL) {
1329a57b7d2SSøren Schmidt     free(VGLBuf);
1339a57b7d2SSøren Schmidt     return 1;
1349a57b7d2SSøren Schmidt   }
1359a57b7d2SSøren Schmidt 
1369a57b7d2SSøren Schmidt   switch (mode) {
1379a57b7d2SSøren Schmidt   case SW_BG640x480: case SW_CG640x480:
1389a57b7d2SSøren Schmidt     VGLDisplay->Type = VIDBUF4;
1399a57b7d2SSøren Schmidt     break;
1409a57b7d2SSøren Schmidt   case SW_VGA_CG320:
1419a57b7d2SSøren Schmidt     VGLDisplay->Type = VIDBUF8;
1429a57b7d2SSøren Schmidt     break;
1439a57b7d2SSøren Schmidt   case SW_VGA_MODEX:
1449a57b7d2SSøren Schmidt     VGLDisplay->Type = VIDBUF8X;
1459a57b7d2SSøren Schmidt     break;
1469a57b7d2SSøren Schmidt   default:
1479a57b7d2SSøren Schmidt     VGLEnd();
1489a57b7d2SSøren Schmidt     return 1;
1499a57b7d2SSøren Schmidt   }
1509a57b7d2SSøren Schmidt 
1519a57b7d2SSøren Schmidt   if ((error = ioctl(0, KDENABIO, 0)))
1529a57b7d2SSøren Schmidt     return error;
1539a57b7d2SSøren Schmidt 
1549a57b7d2SSøren Schmidt   ioctl(0, VT_WAITACTIVE, 0);
1559a57b7d2SSøren Schmidt   ioctl(0, KDSETMODE, KD_GRAPHICS);
1569a57b7d2SSøren Schmidt   if ((error = ioctl(0, mode, 0))) {
1579a57b7d2SSøren Schmidt     ioctl(0, KDSETMODE, KD_TEXT);
1589a57b7d2SSøren Schmidt     ioctl(0, KDDISABIO, 0);
1599a57b7d2SSøren Schmidt     return error;
1609a57b7d2SSøren Schmidt   }
1619a57b7d2SSøren Schmidt 
1629a57b7d2SSøren Schmidt   VGLMode = mode;
1639a57b7d2SSøren Schmidt 
1649a57b7d2SSøren Schmidt   outb(0x3c4, 0x02);
1659a57b7d2SSøren Schmidt   outb(0x3c5, 0x0f);
1669a57b7d2SSøren Schmidt   bzero(VGLMem, 64*1024);
1679a57b7d2SSøren Schmidt 
1689a57b7d2SSøren Schmidt   if (ioctl(0, TIOCGWINSZ, &winsz)) {
1699a57b7d2SSøren Schmidt     VGLEnd();
1709a57b7d2SSøren Schmidt     return 1;
1719a57b7d2SSøren Schmidt   }
1729a57b7d2SSøren Schmidt 
1739a57b7d2SSøren Schmidt   VGLDisplay->Bitmap = VGLMem;
1749a57b7d2SSøren Schmidt   VGLDisplay->Xsize = winsz.ws_xpixel;
1759a57b7d2SSøren Schmidt   VGLDisplay->Ysize = winsz.ws_ypixel;
1769a57b7d2SSøren Schmidt   VGLSavePalette();
1779a57b7d2SSøren Schmidt 
1789a57b7d2SSøren Schmidt   smode.mode = VT_PROCESS;
1799a57b7d2SSøren Schmidt   smode.waitv = 0;
1809a57b7d2SSøren Schmidt   smode.relsig = SIGUSR1;
1819a57b7d2SSøren Schmidt   smode.acqsig = SIGUSR1;
1829a57b7d2SSøren Schmidt   smode.frsig  = SIGINT;
1839a57b7d2SSøren Schmidt   if (ioctl(0, VT_SETMODE, &smode) == -1) {
1849a57b7d2SSøren Schmidt     VGLEnd();
1859a57b7d2SSøren Schmidt     return 1;
1869a57b7d2SSøren Schmidt   }
1879a57b7d2SSøren Schmidt   VGLTextSetFontFile((byte*)0);
188b478da36SSøren Schmidt   VGLInitDone = 1;
1899a57b7d2SSøren Schmidt   return 0;
1909a57b7d2SSøren Schmidt }
1919a57b7d2SSøren Schmidt 
1929a57b7d2SSøren Schmidt void
1939a57b7d2SSøren Schmidt VGLCheckSwitch()
1949a57b7d2SSøren Schmidt {
1959a57b7d2SSøren Schmidt   if (VGLSwitchPending) {
1969a57b7d2SSøren Schmidt     int i;
1979a57b7d2SSøren Schmidt 
1989a57b7d2SSøren Schmidt     VGLSwitchPending = 0;
1999a57b7d2SSøren Schmidt     if (VGLOnDisplay) {
2009a57b7d2SSøren Schmidt       ioctl(0, KDENABIO, 0);
2019a57b7d2SSøren Schmidt       ioctl(0, KDSETMODE, KD_GRAPHICS);
2029a57b7d2SSøren Schmidt       ioctl(0, VGLMode, 0);
2039a57b7d2SSøren Schmidt       outb(0x3c6, 0xff);
2049a57b7d2SSøren Schmidt       for (i=0; i<4; i++) {
2059a57b7d2SSøren Schmidt         outb(0x3c4, 0x02);
2069a57b7d2SSøren Schmidt         outb(0x3c5, 0x01<<i);
2079a57b7d2SSøren Schmidt         bcopy(&VGLBuf[i*64*1024], VGLMem, 64*1024);
2089a57b7d2SSøren Schmidt       }
2099a57b7d2SSøren Schmidt       VGLRestorePalette();
2109a57b7d2SSøren Schmidt       ioctl(0, VT_RELDISP, VT_ACKACQ);
2119a57b7d2SSøren Schmidt       VGLDisplay->Bitmap = VGLMem;
2129a57b7d2SSøren Schmidt       switch (VGLMode) {
2139a57b7d2SSøren Schmidt       case SW_BG640x480: case SW_CG640x480:
2149a57b7d2SSøren Schmidt         VGLDisplay->Type = VIDBUF4;
2159a57b7d2SSøren Schmidt         break;
2169a57b7d2SSøren Schmidt       case SW_VGA_CG320:
2179a57b7d2SSøren Schmidt         VGLDisplay->Type = VIDBUF8;
2189a57b7d2SSøren Schmidt         break;
2199a57b7d2SSøren Schmidt       case SW_VGA_MODEX:
2209a57b7d2SSøren Schmidt         VGLDisplay->Type = VIDBUF8X;
2219a57b7d2SSøren Schmidt         break;
2229a57b7d2SSøren Schmidt       default:
2239a57b7d2SSøren Schmidt         VGLDisplay->Type = VIDBUF8;			/* XXX */
2249a57b7d2SSøren Schmidt         break;
2259a57b7d2SSøren Schmidt       }
2269a57b7d2SSøren Schmidt     }
2279a57b7d2SSøren Schmidt     else {
2289a57b7d2SSøren Schmidt       for (i=0; i<4; i++) {
2299a57b7d2SSøren Schmidt         outb(0x3ce, 0x04);
2309a57b7d2SSøren Schmidt         outb(0x3cf, i);
2319a57b7d2SSøren Schmidt         bcopy(VGLMem, &VGLBuf[i*64*1024], 64*1024);
2329a57b7d2SSøren Schmidt       }
2339a57b7d2SSøren Schmidt       ioctl(0, VGLOldMode, 0);
2349a57b7d2SSøren Schmidt       ioctl(0, KDSETMODE, KD_TEXT);
2359a57b7d2SSøren Schmidt       ioctl(0, KDDISABIO, 0);
2369a57b7d2SSøren Schmidt       ioctl(0, VT_RELDISP, VT_TRUE);
2379a57b7d2SSøren Schmidt       VGLDisplay->Bitmap = VGLBuf;
2389a57b7d2SSøren Schmidt       VGLDisplay->Type = MEMBUF;
2399a57b7d2SSøren Schmidt     }
2409a57b7d2SSøren Schmidt   }
2419a57b7d2SSøren Schmidt   while (!VGLOnDisplay) pause();
2429a57b7d2SSøren Schmidt }
2439a57b7d2SSøren Schmidt 
244