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