main.c revision 30044
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
40VGLBitmap *VGLDisplay;
41
42static int VGLMode;
43static int VGLOldMode;
44static byte *VGLBuf;
45static byte *VGLMem;
46static int VGLSwitchPending;
47static int VGLOnDisplay;
48static int VGLInitDone = 0;
49
50void
51VGLEnd()
52{
53struct 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
74static void
75VGLAbort()
76{
77  VGLEnd();
78  exit(0);
79}
80
81static void
82VGLSwitch()
83{
84  if (!VGLOnDisplay)
85    VGLOnDisplay = 1;
86  else
87    VGLOnDisplay = 0;
88  VGLSwitchPending = 1;
89  signal(SIGUSR1, VGLSwitch);
90}
91
92int
93VGLInit(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
180void
181VGLCheckSwitch()
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