main.c revision 28328
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.14 1997/08/15 12:32:59 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 40VGLBitmap *VGLDisplay; 41 42static int VGLMode; 43static int VGLOldMode; 44static byte *VGLBuf; 45static byte *VGLMem; 46static int VGLSwitchPending; 47static int VGLOnDisplay; 48 49void 50VGLEnd() 51{ 52struct vt_mode smode; 53 54/* 55 while (!VGLOnDisplay) pause(); 56 VGLCheckSwitch();; 57*/ 58 outb(0x3c4, 0x02); 59 outb(0x3c5, 0x0f); 60 bzero(VGLMem, 64*1024); 61 ioctl(0, _IO('S', VGLOldMode), 0); 62 ioctl(0, KDDISABIO, 0); 63 ioctl(0, KDSETMODE, KD_TEXT); 64 smode.mode = VT_AUTO; 65 ioctl(0, VT_SETMODE, &smode); 66 free(VGLBuf); 67 free(VGLDisplay); 68} 69 70static void 71VGLAbort() 72{ 73 VGLEnd(); 74 exit(0); 75} 76 77static void 78VGLSwitch() 79{ 80 if (!VGLOnDisplay) 81 VGLOnDisplay = 1; 82 else 83 VGLOnDisplay = 0; 84 VGLSwitchPending = 1; 85 signal(SIGUSR1, VGLSwitch); 86} 87 88int 89VGLInit(int mode) 90{ 91 struct vt_mode smode; 92 struct winsize winsz; 93 int error; 94 95 signal(SIGUSR1, VGLSwitch); 96 signal(SIGINT, VGLAbort); 97 signal(SIGSEGV, VGLAbort); 98 signal(SIGBUS, VGLAbort); 99 100 VGLOnDisplay = 1; 101 VGLSwitchPending = 0; 102 103 ioctl(0, CONS_GET, &VGLOldMode); 104 105 VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE, 106 open("/dev/mem", O_RDWR), 0xA0000); 107 if (VGLMem <= (byte*)0) 108 return 1; 109 110 VGLBuf = (byte*)malloc(256*1024); 111 if (VGLBuf == NULL) 112 return 1; 113 114 VGLDisplay = (VGLBitmap*) malloc(sizeof(VGLBitmap)); 115 if (VGLDisplay == NULL) { 116 free(VGLBuf); 117 return 1; 118 } 119 120 switch (mode) { 121 case SW_BG640x480: case SW_CG640x480: 122 VGLDisplay->Type = VIDBUF4; 123 break; 124 case SW_VGA_CG320: 125 VGLDisplay->Type = VIDBUF8; 126 break; 127 case SW_VGA_MODEX: 128 VGLDisplay->Type = VIDBUF8X; 129 break; 130 default: 131 VGLEnd(); 132 return 1; 133 } 134 135 if ((error = ioctl(0, KDENABIO, 0))) 136 return error; 137 138 ioctl(0, VT_WAITACTIVE, 0); 139 ioctl(0, KDSETMODE, KD_GRAPHICS); 140 if ((error = ioctl(0, mode, 0))) { 141 ioctl(0, KDSETMODE, KD_TEXT); 142 ioctl(0, KDDISABIO, 0); 143 return error; 144 } 145 146 VGLMode = mode; 147 148 outb(0x3c4, 0x02); 149 outb(0x3c5, 0x0f); 150 bzero(VGLMem, 64*1024); 151 152 if (ioctl(0, TIOCGWINSZ, &winsz)) { 153 VGLEnd(); 154 return 1; 155 } 156 157 VGLDisplay->Bitmap = VGLMem; 158 VGLDisplay->Xsize = winsz.ws_xpixel; 159 VGLDisplay->Ysize = winsz.ws_ypixel; 160 VGLSavePalette(); 161 162 smode.mode = VT_PROCESS; 163 smode.waitv = 0; 164 smode.relsig = SIGUSR1; 165 smode.acqsig = SIGUSR1; 166 smode.frsig = SIGINT; 167 if (ioctl(0, VT_SETMODE, &smode) == -1) { 168 VGLEnd(); 169 return 1; 170 } 171 VGLTextSetFontFile((byte*)0); 172 return 0; 173} 174 175void 176VGLCheckSwitch() 177{ 178 if (VGLSwitchPending) { 179 int i; 180 181 VGLSwitchPending = 0; 182 if (VGLOnDisplay) { 183 ioctl(0, KDENABIO, 0); 184 ioctl(0, KDSETMODE, KD_GRAPHICS); 185 ioctl(0, VGLMode, 0); 186 outb(0x3c6, 0xff); 187 for (i=0; i<4; i++) { 188 outb(0x3c4, 0x02); 189 outb(0x3c5, 0x01<<i); 190 bcopy(&VGLBuf[i*64*1024], VGLMem, 64*1024); 191 } 192 VGLRestorePalette(); 193 ioctl(0, VT_RELDISP, VT_ACKACQ); 194 VGLDisplay->Bitmap = VGLMem; 195 switch (VGLMode) { 196 case SW_BG640x480: case SW_CG640x480: 197 VGLDisplay->Type = VIDBUF4; 198 break; 199 case SW_VGA_CG320: 200 VGLDisplay->Type = VIDBUF8; 201 break; 202 case SW_VGA_MODEX: 203 VGLDisplay->Type = VIDBUF8X; 204 break; 205 default: 206 VGLDisplay->Type = VIDBUF8; /* XXX */ 207 break; 208 } 209 } 210 else { 211 for (i=0; i<4; i++) { 212 outb(0x3ce, 0x04); 213 outb(0x3cf, i); 214 bcopy(VGLMem, &VGLBuf[i*64*1024], 64*1024); 215 } 216 ioctl(0, VGLOldMode, 0); 217 ioctl(0, KDSETMODE, KD_TEXT); 218 ioctl(0, KDDISABIO, 0); 219 ioctl(0, VT_RELDISP, VT_TRUE); 220 VGLDisplay->Bitmap = VGLBuf; 221 VGLDisplay->Type = MEMBUF; 222 } 223 } 224 while (!VGLOnDisplay) pause(); 225} 226 227