xref: /freebsd/lib/libvgl/main.c (revision b478da3630df5f29cd33dec5774ea52477eaf8fc)
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  *
28b478da36SSøren Schmidt  *  $Id: main.c,v 1.1 1997/08/17 21:09:34 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);
649a57b7d2SSøren Schmidt   ioctl(0, _IO('S', VGLOldMode), 0);
659a57b7d2SSøren Schmidt   ioctl(0, KDDISABIO, 0);
669a57b7d2SSøren Schmidt   ioctl(0, KDSETMODE, KD_TEXT);
679a57b7d2SSøren Schmidt   smode.mode = VT_AUTO;
689a57b7d2SSøren Schmidt   ioctl(0, VT_SETMODE, &smode);
699a57b7d2SSøren Schmidt   free(VGLBuf);
709a57b7d2SSøren Schmidt   free(VGLDisplay);
71b478da36SSøren Schmidt   VGLKeyboardEnd();
729a57b7d2SSøren Schmidt }
739a57b7d2SSøren Schmidt 
749a57b7d2SSøren Schmidt static void
759a57b7d2SSøren Schmidt VGLAbort()
769a57b7d2SSøren Schmidt {
779a57b7d2SSøren Schmidt   VGLEnd();
789a57b7d2SSøren Schmidt   exit(0);
799a57b7d2SSøren Schmidt }
809a57b7d2SSøren Schmidt 
819a57b7d2SSøren Schmidt static void
829a57b7d2SSøren Schmidt VGLSwitch()
839a57b7d2SSøren Schmidt {
849a57b7d2SSøren Schmidt   if (!VGLOnDisplay)
859a57b7d2SSøren Schmidt     VGLOnDisplay = 1;
869a57b7d2SSøren Schmidt   else
879a57b7d2SSøren Schmidt     VGLOnDisplay = 0;
889a57b7d2SSøren Schmidt   VGLSwitchPending = 1;
899a57b7d2SSøren Schmidt   signal(SIGUSR1, VGLSwitch);
909a57b7d2SSøren Schmidt }
919a57b7d2SSøren Schmidt 
929a57b7d2SSøren Schmidt int
939a57b7d2SSøren Schmidt VGLInit(int mode)
949a57b7d2SSøren Schmidt {
959a57b7d2SSøren Schmidt   struct vt_mode smode;
969a57b7d2SSøren Schmidt   struct winsize winsz;
979a57b7d2SSøren Schmidt   int error;
989a57b7d2SSøren Schmidt 
999a57b7d2SSøren Schmidt   signal(SIGUSR1, VGLSwitch);
1009a57b7d2SSøren Schmidt   signal(SIGINT, VGLAbort);
1019a57b7d2SSøren Schmidt   signal(SIGSEGV, VGLAbort);
1029a57b7d2SSøren Schmidt   signal(SIGBUS, VGLAbort);
1039a57b7d2SSøren Schmidt 
1049a57b7d2SSøren Schmidt   VGLOnDisplay = 1;
1059a57b7d2SSøren Schmidt   VGLSwitchPending = 0;
1069a57b7d2SSøren Schmidt 
1079a57b7d2SSøren Schmidt   ioctl(0, CONS_GET, &VGLOldMode);
1089a57b7d2SSøren Schmidt 
1099a57b7d2SSøren Schmidt   VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE,
1109a57b7d2SSøren Schmidt                           open("/dev/mem", O_RDWR), 0xA0000);
1119a57b7d2SSøren Schmidt   if (VGLMem <= (byte*)0)
1129a57b7d2SSøren Schmidt     return 1;
1139a57b7d2SSøren Schmidt 
1149a57b7d2SSøren Schmidt   VGLBuf = (byte*)malloc(256*1024);
1159a57b7d2SSøren Schmidt   if (VGLBuf == NULL)
1169a57b7d2SSøren Schmidt     return 1;
1179a57b7d2SSøren Schmidt 
1189a57b7d2SSøren Schmidt   VGLDisplay = (VGLBitmap*) malloc(sizeof(VGLBitmap));
1199a57b7d2SSøren Schmidt   if (VGLDisplay == NULL) {
1209a57b7d2SSøren Schmidt     free(VGLBuf);
1219a57b7d2SSøren Schmidt     return 1;
1229a57b7d2SSøren Schmidt   }
1239a57b7d2SSøren Schmidt 
1249a57b7d2SSøren Schmidt   switch (mode) {
1259a57b7d2SSøren Schmidt   case SW_BG640x480: case SW_CG640x480:
1269a57b7d2SSøren Schmidt     VGLDisplay->Type = VIDBUF4;
1279a57b7d2SSøren Schmidt     break;
1289a57b7d2SSøren Schmidt   case SW_VGA_CG320:
1299a57b7d2SSøren Schmidt     VGLDisplay->Type = VIDBUF8;
1309a57b7d2SSøren Schmidt     break;
1319a57b7d2SSøren Schmidt   case SW_VGA_MODEX:
1329a57b7d2SSøren Schmidt     VGLDisplay->Type = VIDBUF8X;
1339a57b7d2SSøren Schmidt     break;
1349a57b7d2SSøren Schmidt   default:
1359a57b7d2SSøren Schmidt     VGLEnd();
1369a57b7d2SSøren Schmidt     return 1;
1379a57b7d2SSøren Schmidt   }
1389a57b7d2SSøren Schmidt 
1399a57b7d2SSøren Schmidt   if ((error = ioctl(0, KDENABIO, 0)))
1409a57b7d2SSøren Schmidt     return error;
1419a57b7d2SSøren Schmidt 
1429a57b7d2SSøren Schmidt   ioctl(0, VT_WAITACTIVE, 0);
1439a57b7d2SSøren Schmidt   ioctl(0, KDSETMODE, KD_GRAPHICS);
1449a57b7d2SSøren Schmidt   if ((error = ioctl(0, mode, 0))) {
1459a57b7d2SSøren Schmidt     ioctl(0, KDSETMODE, KD_TEXT);
1469a57b7d2SSøren Schmidt     ioctl(0, KDDISABIO, 0);
1479a57b7d2SSøren Schmidt     return error;
1489a57b7d2SSøren Schmidt   }
1499a57b7d2SSøren Schmidt 
1509a57b7d2SSøren Schmidt   VGLMode = mode;
1519a57b7d2SSøren Schmidt 
1529a57b7d2SSøren Schmidt   outb(0x3c4, 0x02);
1539a57b7d2SSøren Schmidt   outb(0x3c5, 0x0f);
1549a57b7d2SSøren Schmidt   bzero(VGLMem, 64*1024);
1559a57b7d2SSøren Schmidt 
1569a57b7d2SSøren Schmidt   if (ioctl(0, TIOCGWINSZ, &winsz)) {
1579a57b7d2SSøren Schmidt     VGLEnd();
1589a57b7d2SSøren Schmidt     return 1;
1599a57b7d2SSøren Schmidt   }
1609a57b7d2SSøren Schmidt 
1619a57b7d2SSøren Schmidt   VGLDisplay->Bitmap = VGLMem;
1629a57b7d2SSøren Schmidt   VGLDisplay->Xsize = winsz.ws_xpixel;
1639a57b7d2SSøren Schmidt   VGLDisplay->Ysize = winsz.ws_ypixel;
1649a57b7d2SSøren Schmidt   VGLSavePalette();
1659a57b7d2SSøren Schmidt 
1669a57b7d2SSøren Schmidt   smode.mode = VT_PROCESS;
1679a57b7d2SSøren Schmidt   smode.waitv = 0;
1689a57b7d2SSøren Schmidt   smode.relsig = SIGUSR1;
1699a57b7d2SSøren Schmidt   smode.acqsig = SIGUSR1;
1709a57b7d2SSøren Schmidt   smode.frsig  = SIGINT;
1719a57b7d2SSøren Schmidt   if (ioctl(0, VT_SETMODE, &smode) == -1) {
1729a57b7d2SSøren Schmidt     VGLEnd();
1739a57b7d2SSøren Schmidt     return 1;
1749a57b7d2SSøren Schmidt   }
1759a57b7d2SSøren Schmidt   VGLTextSetFontFile((byte*)0);
176b478da36SSøren Schmidt   VGLInitDone = 1;
1779a57b7d2SSøren Schmidt   return 0;
1789a57b7d2SSøren Schmidt }
1799a57b7d2SSøren Schmidt 
1809a57b7d2SSøren Schmidt void
1819a57b7d2SSøren Schmidt VGLCheckSwitch()
1829a57b7d2SSøren Schmidt {
1839a57b7d2SSøren Schmidt   if (VGLSwitchPending) {
1849a57b7d2SSøren Schmidt     int i;
1859a57b7d2SSøren Schmidt 
1869a57b7d2SSøren Schmidt     VGLSwitchPending = 0;
1879a57b7d2SSøren Schmidt     if (VGLOnDisplay) {
1889a57b7d2SSøren Schmidt       ioctl(0, KDENABIO, 0);
1899a57b7d2SSøren Schmidt       ioctl(0, KDSETMODE, KD_GRAPHICS);
1909a57b7d2SSøren Schmidt       ioctl(0, VGLMode, 0);
1919a57b7d2SSøren Schmidt       outb(0x3c6, 0xff);
1929a57b7d2SSøren Schmidt       for (i=0; i<4; i++) {
1939a57b7d2SSøren Schmidt         outb(0x3c4, 0x02);
1949a57b7d2SSøren Schmidt         outb(0x3c5, 0x01<<i);
1959a57b7d2SSøren Schmidt         bcopy(&VGLBuf[i*64*1024], VGLMem, 64*1024);
1969a57b7d2SSøren Schmidt       }
1979a57b7d2SSøren Schmidt       VGLRestorePalette();
1989a57b7d2SSøren Schmidt       ioctl(0, VT_RELDISP, VT_ACKACQ);
1999a57b7d2SSøren Schmidt       VGLDisplay->Bitmap = VGLMem;
2009a57b7d2SSøren Schmidt       switch (VGLMode) {
2019a57b7d2SSøren Schmidt       case SW_BG640x480: case SW_CG640x480:
2029a57b7d2SSøren Schmidt         VGLDisplay->Type = VIDBUF4;
2039a57b7d2SSøren Schmidt         break;
2049a57b7d2SSøren Schmidt       case SW_VGA_CG320:
2059a57b7d2SSøren Schmidt         VGLDisplay->Type = VIDBUF8;
2069a57b7d2SSøren Schmidt         break;
2079a57b7d2SSøren Schmidt       case SW_VGA_MODEX:
2089a57b7d2SSøren Schmidt         VGLDisplay->Type = VIDBUF8X;
2099a57b7d2SSøren Schmidt         break;
2109a57b7d2SSøren Schmidt       default:
2119a57b7d2SSøren Schmidt         VGLDisplay->Type = VIDBUF8;			/* XXX */
2129a57b7d2SSøren Schmidt         break;
2139a57b7d2SSøren Schmidt       }
2149a57b7d2SSøren Schmidt     }
2159a57b7d2SSøren Schmidt     else {
2169a57b7d2SSøren Schmidt       for (i=0; i<4; i++) {
2179a57b7d2SSøren Schmidt         outb(0x3ce, 0x04);
2189a57b7d2SSøren Schmidt         outb(0x3cf, i);
2199a57b7d2SSøren Schmidt         bcopy(VGLMem, &VGLBuf[i*64*1024], 64*1024);
2209a57b7d2SSøren Schmidt       }
2219a57b7d2SSøren Schmidt       ioctl(0, VGLOldMode, 0);
2229a57b7d2SSøren Schmidt       ioctl(0, KDSETMODE, KD_TEXT);
2239a57b7d2SSøren Schmidt       ioctl(0, KDDISABIO, 0);
2249a57b7d2SSøren Schmidt       ioctl(0, VT_RELDISP, VT_TRUE);
2259a57b7d2SSøren Schmidt       VGLDisplay->Bitmap = VGLBuf;
2269a57b7d2SSøren Schmidt       VGLDisplay->Type = MEMBUF;
2279a57b7d2SSøren Schmidt     }
2289a57b7d2SSøren Schmidt   }
2299a57b7d2SSøren Schmidt   while (!VGLOnDisplay) pause();
2309a57b7d2SSøren Schmidt }
2319a57b7d2SSøren Schmidt 
232