1 /*- 2 * Copyright (c) 1991-1997 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software withough specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $Id: main.c,v 1.1 1997/08/17 21:09:34 sos Exp $ 29 */ 30 31 #include <stdio.h> 32 #include <sys/types.h> 33 #include <sys/signal.h> 34 #include <sys/file.h> 35 #include <sys/ioctl.h> 36 #include <sys/mman.h> 37 #include <machine/console.h> 38 #include "vgl.h" 39 40 VGLBitmap *VGLDisplay; 41 42 static int VGLMode; 43 static int VGLOldMode; 44 static byte *VGLBuf; 45 static byte *VGLMem; 46 static int VGLSwitchPending; 47 static int VGLOnDisplay; 48 static int VGLInitDone = 0; 49 50 void 51 VGLEnd() 52 { 53 struct vt_mode smode; 54 55 if (!VGLInitDone) 56 return; 57 /* 58 while (!VGLOnDisplay) pause(); 59 VGLCheckSwitch();; 60 */ 61 outb(0x3c4, 0x02); 62 outb(0x3c5, 0x0f); 63 bzero(VGLMem, 64*1024); 64 ioctl(0, _IO('S', VGLOldMode), 0); 65 ioctl(0, KDDISABIO, 0); 66 ioctl(0, KDSETMODE, KD_TEXT); 67 smode.mode = VT_AUTO; 68 ioctl(0, VT_SETMODE, &smode); 69 free(VGLBuf); 70 free(VGLDisplay); 71 VGLKeyboardEnd(); 72 } 73 74 static void 75 VGLAbort() 76 { 77 VGLEnd(); 78 exit(0); 79 } 80 81 static void 82 VGLSwitch() 83 { 84 if (!VGLOnDisplay) 85 VGLOnDisplay = 1; 86 else 87 VGLOnDisplay = 0; 88 VGLSwitchPending = 1; 89 signal(SIGUSR1, VGLSwitch); 90 } 91 92 int 93 VGLInit(int mode) 94 { 95 struct vt_mode smode; 96 struct winsize winsz; 97 int error; 98 99 signal(SIGUSR1, VGLSwitch); 100 signal(SIGINT, VGLAbort); 101 signal(SIGSEGV, VGLAbort); 102 signal(SIGBUS, VGLAbort); 103 104 VGLOnDisplay = 1; 105 VGLSwitchPending = 0; 106 107 ioctl(0, CONS_GET, &VGLOldMode); 108 109 VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE, 110 open("/dev/mem", O_RDWR), 0xA0000); 111 if (VGLMem <= (byte*)0) 112 return 1; 113 114 VGLBuf = (byte*)malloc(256*1024); 115 if (VGLBuf == NULL) 116 return 1; 117 118 VGLDisplay = (VGLBitmap*) malloc(sizeof(VGLBitmap)); 119 if (VGLDisplay == NULL) { 120 free(VGLBuf); 121 return 1; 122 } 123 124 switch (mode) { 125 case SW_BG640x480: case SW_CG640x480: 126 VGLDisplay->Type = VIDBUF4; 127 break; 128 case SW_VGA_CG320: 129 VGLDisplay->Type = VIDBUF8; 130 break; 131 case SW_VGA_MODEX: 132 VGLDisplay->Type = VIDBUF8X; 133 break; 134 default: 135 VGLEnd(); 136 return 1; 137 } 138 139 if ((error = ioctl(0, KDENABIO, 0))) 140 return error; 141 142 ioctl(0, VT_WAITACTIVE, 0); 143 ioctl(0, KDSETMODE, KD_GRAPHICS); 144 if ((error = ioctl(0, mode, 0))) { 145 ioctl(0, KDSETMODE, KD_TEXT); 146 ioctl(0, KDDISABIO, 0); 147 return error; 148 } 149 150 VGLMode = mode; 151 152 outb(0x3c4, 0x02); 153 outb(0x3c5, 0x0f); 154 bzero(VGLMem, 64*1024); 155 156 if (ioctl(0, TIOCGWINSZ, &winsz)) { 157 VGLEnd(); 158 return 1; 159 } 160 161 VGLDisplay->Bitmap = VGLMem; 162 VGLDisplay->Xsize = winsz.ws_xpixel; 163 VGLDisplay->Ysize = winsz.ws_ypixel; 164 VGLSavePalette(); 165 166 smode.mode = VT_PROCESS; 167 smode.waitv = 0; 168 smode.relsig = SIGUSR1; 169 smode.acqsig = SIGUSR1; 170 smode.frsig = SIGINT; 171 if (ioctl(0, VT_SETMODE, &smode) == -1) { 172 VGLEnd(); 173 return 1; 174 } 175 VGLTextSetFontFile((byte*)0); 176 VGLInitDone = 1; 177 return 0; 178 } 179 180 void 181 VGLCheckSwitch() 182 { 183 if (VGLSwitchPending) { 184 int i; 185 186 VGLSwitchPending = 0; 187 if (VGLOnDisplay) { 188 ioctl(0, KDENABIO, 0); 189 ioctl(0, KDSETMODE, KD_GRAPHICS); 190 ioctl(0, VGLMode, 0); 191 outb(0x3c6, 0xff); 192 for (i=0; i<4; i++) { 193 outb(0x3c4, 0x02); 194 outb(0x3c5, 0x01<<i); 195 bcopy(&VGLBuf[i*64*1024], VGLMem, 64*1024); 196 } 197 VGLRestorePalette(); 198 ioctl(0, VT_RELDISP, VT_ACKACQ); 199 VGLDisplay->Bitmap = VGLMem; 200 switch (VGLMode) { 201 case SW_BG640x480: case SW_CG640x480: 202 VGLDisplay->Type = VIDBUF4; 203 break; 204 case SW_VGA_CG320: 205 VGLDisplay->Type = VIDBUF8; 206 break; 207 case SW_VGA_MODEX: 208 VGLDisplay->Type = VIDBUF8X; 209 break; 210 default: 211 VGLDisplay->Type = VIDBUF8; /* XXX */ 212 break; 213 } 214 } 215 else { 216 for (i=0; i<4; i++) { 217 outb(0x3ce, 0x04); 218 outb(0x3cf, i); 219 bcopy(VGLMem, &VGLBuf[i*64*1024], 64*1024); 220 } 221 ioctl(0, VGLOldMode, 0); 222 ioctl(0, KDSETMODE, KD_TEXT); 223 ioctl(0, KDDISABIO, 0); 224 ioctl(0, VT_RELDISP, VT_TRUE); 225 VGLDisplay->Bitmap = VGLBuf; 226 VGLDisplay->Type = MEMBUF; 227 } 228 } 229 while (!VGLOnDisplay) pause(); 230 } 231 232