main.c revision 50141
128328Ssos/*-
228328Ssos * Copyright (c) 1991-1997 S�ren Schmidt
328328Ssos * All rights reserved.
428328Ssos *
528328Ssos * Redistribution and use in source and binary forms, with or without
628328Ssos * modification, are permitted provided that the following conditions
728328Ssos * are met:
828328Ssos * 1. Redistributions of source code must retain the above copyright
928328Ssos *    notice, this list of conditions and the following disclaimer
1028328Ssos *    in this position and unchanged.
1128328Ssos * 2. Redistributions in binary form must reproduce the above copyright
1228328Ssos *    notice, this list of conditions and the following disclaimer in the
1328328Ssos *    documentation and/or other materials provided with the distribution.
1428328Ssos * 3. The name of the author may not be used to endorse or promote products
1528328Ssos *    derived from this software withough specific prior written permission
1628328Ssos *
1728328Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1828328Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1928328Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2028328Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2128328Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2228328Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2328328Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2428328Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2528328Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2628328Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2728328Ssos *
2850141Syokota *  $Id: main.c,v 1.2 1997/10/01 20:53:39 sos Exp $
2928328Ssos */
3028328Ssos
3128328Ssos#include <stdio.h>
3228328Ssos#include <sys/types.h>
3328328Ssos#include <sys/signal.h>
3428328Ssos#include <sys/file.h>
3528328Ssos#include <sys/ioctl.h>
3628328Ssos#include <sys/mman.h>
3728328Ssos#include <machine/console.h>
3828328Ssos#include "vgl.h"
3928328Ssos
4028328SsosVGLBitmap *VGLDisplay;
4128328Ssos
4228328Ssosstatic int VGLMode;
4328328Ssosstatic int VGLOldMode;
4428328Ssosstatic byte *VGLBuf;
4528328Ssosstatic byte *VGLMem;
4628328Ssosstatic int VGLSwitchPending;
4728328Ssosstatic int VGLOnDisplay;
4830044Ssosstatic int VGLInitDone = 0;
4928328Ssos
5028328Ssosvoid
5128328SsosVGLEnd()
5228328Ssos{
5328328Ssosstruct vt_mode smode;
5428328Ssos
5530044Ssos  if (!VGLInitDone)
5630044Ssos    return;
5728328Ssos/*
5828328Ssos  while (!VGLOnDisplay) pause();
5928328Ssos  VGLCheckSwitch();;
6028328Ssos*/
6128328Ssos  outb(0x3c4, 0x02);
6228328Ssos  outb(0x3c5, 0x0f);
6328328Ssos  bzero(VGLMem, 64*1024);
6450141Syokota  if (VGLOldMode >= M_VESA_BASE) {
6550141Syokota    /* ugly, but necessary */
6650141Syokota    ioctl(0, _IO('V', VGLOldMode - M_VESA_BASE), 0);
6750141Syokota    if (VGLOldMode == M_VESA_800x600) {
6850141Syokota      int size[3];
6950141Syokota      size[0] = 80;
7050141Syokota      size[1] = 25;
7150141Syokota      size[2] = 16;
7250141Syokota      ioctl(0, KDRASTER, size);
7350141Syokota    }
7450141Syokota  } else {
7550141Syokota    ioctl(0, _IO('S', VGLOldMode), 0);
7650141Syokota  }
7728328Ssos  ioctl(0, KDDISABIO, 0);
7828328Ssos  ioctl(0, KDSETMODE, KD_TEXT);
7928328Ssos  smode.mode = VT_AUTO;
8028328Ssos  ioctl(0, VT_SETMODE, &smode);
8128328Ssos  free(VGLBuf);
8228328Ssos  free(VGLDisplay);
8330044Ssos  VGLKeyboardEnd();
8428328Ssos}
8528328Ssos
8628328Ssosstatic void
8728328SsosVGLAbort()
8828328Ssos{
8928328Ssos  VGLEnd();
9028328Ssos  exit(0);
9128328Ssos}
9228328Ssos
9328328Ssosstatic void
9428328SsosVGLSwitch()
9528328Ssos{
9628328Ssos  if (!VGLOnDisplay)
9728328Ssos    VGLOnDisplay = 1;
9828328Ssos  else
9928328Ssos    VGLOnDisplay = 0;
10028328Ssos  VGLSwitchPending = 1;
10128328Ssos  signal(SIGUSR1, VGLSwitch);
10228328Ssos}
10328328Ssos
10428328Ssosint
10528328SsosVGLInit(int mode)
10628328Ssos{
10728328Ssos  struct vt_mode smode;
10828328Ssos  struct winsize winsz;
10928328Ssos  int error;
11028328Ssos
11128328Ssos  signal(SIGUSR1, VGLSwitch);
11228328Ssos  signal(SIGINT, VGLAbort);
11328328Ssos  signal(SIGSEGV, VGLAbort);
11428328Ssos  signal(SIGBUS, VGLAbort);
11528328Ssos
11628328Ssos  VGLOnDisplay = 1;
11728328Ssos  VGLSwitchPending = 0;
11828328Ssos
11928328Ssos  ioctl(0, CONS_GET, &VGLOldMode);
12028328Ssos
12128328Ssos  VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE,
12228328Ssos                          open("/dev/mem", O_RDWR), 0xA0000);
12328328Ssos  if (VGLMem <= (byte*)0)
12428328Ssos    return 1;
12528328Ssos
12628328Ssos  VGLBuf = (byte*)malloc(256*1024);
12728328Ssos  if (VGLBuf == NULL)
12828328Ssos    return 1;
12928328Ssos
13028328Ssos  VGLDisplay = (VGLBitmap*) malloc(sizeof(VGLBitmap));
13128328Ssos  if (VGLDisplay == NULL) {
13228328Ssos    free(VGLBuf);
13328328Ssos    return 1;
13428328Ssos  }
13528328Ssos
13628328Ssos  switch (mode) {
13728328Ssos  case SW_BG640x480: case SW_CG640x480:
13828328Ssos    VGLDisplay->Type = VIDBUF4;
13928328Ssos    break;
14028328Ssos  case SW_VGA_CG320:
14128328Ssos    VGLDisplay->Type = VIDBUF8;
14228328Ssos    break;
14328328Ssos  case SW_VGA_MODEX:
14428328Ssos    VGLDisplay->Type = VIDBUF8X;
14528328Ssos    break;
14628328Ssos  default:
14728328Ssos    VGLEnd();
14828328Ssos    return 1;
14928328Ssos  }
15028328Ssos
15128328Ssos  if ((error = ioctl(0, KDENABIO, 0)))
15228328Ssos    return error;
15328328Ssos
15428328Ssos  ioctl(0, VT_WAITACTIVE, 0);
15528328Ssos  ioctl(0, KDSETMODE, KD_GRAPHICS);
15628328Ssos  if ((error = ioctl(0, mode, 0))) {
15728328Ssos    ioctl(0, KDSETMODE, KD_TEXT);
15828328Ssos    ioctl(0, KDDISABIO, 0);
15928328Ssos    return error;
16028328Ssos  }
16128328Ssos
16228328Ssos  VGLMode = mode;
16328328Ssos
16428328Ssos  outb(0x3c4, 0x02);
16528328Ssos  outb(0x3c5, 0x0f);
16628328Ssos  bzero(VGLMem, 64*1024);
16728328Ssos
16828328Ssos  if (ioctl(0, TIOCGWINSZ, &winsz)) {
16928328Ssos    VGLEnd();
17028328Ssos    return 1;
17128328Ssos  }
17228328Ssos
17328328Ssos  VGLDisplay->Bitmap = VGLMem;
17428328Ssos  VGLDisplay->Xsize = winsz.ws_xpixel;
17528328Ssos  VGLDisplay->Ysize = winsz.ws_ypixel;
17628328Ssos  VGLSavePalette();
17728328Ssos
17828328Ssos  smode.mode = VT_PROCESS;
17928328Ssos  smode.waitv = 0;
18028328Ssos  smode.relsig = SIGUSR1;
18128328Ssos  smode.acqsig = SIGUSR1;
18228328Ssos  smode.frsig  = SIGINT;
18328328Ssos  if (ioctl(0, VT_SETMODE, &smode) == -1) {
18428328Ssos    VGLEnd();
18528328Ssos    return 1;
18628328Ssos  }
18728328Ssos  VGLTextSetFontFile((byte*)0);
18830044Ssos  VGLInitDone = 1;
18928328Ssos  return 0;
19028328Ssos}
19128328Ssos
19228328Ssosvoid
19328328SsosVGLCheckSwitch()
19428328Ssos{
19528328Ssos  if (VGLSwitchPending) {
19628328Ssos    int i;
19728328Ssos
19828328Ssos    VGLSwitchPending = 0;
19928328Ssos    if (VGLOnDisplay) {
20028328Ssos      ioctl(0, KDENABIO, 0);
20128328Ssos      ioctl(0, KDSETMODE, KD_GRAPHICS);
20228328Ssos      ioctl(0, VGLMode, 0);
20328328Ssos      outb(0x3c6, 0xff);
20428328Ssos      for (i=0; i<4; i++) {
20528328Ssos        outb(0x3c4, 0x02);
20628328Ssos        outb(0x3c5, 0x01<<i);
20728328Ssos        bcopy(&VGLBuf[i*64*1024], VGLMem, 64*1024);
20828328Ssos      }
20928328Ssos      VGLRestorePalette();
21028328Ssos      ioctl(0, VT_RELDISP, VT_ACKACQ);
21128328Ssos      VGLDisplay->Bitmap = VGLMem;
21228328Ssos      switch (VGLMode) {
21328328Ssos      case SW_BG640x480: case SW_CG640x480:
21428328Ssos        VGLDisplay->Type = VIDBUF4;
21528328Ssos        break;
21628328Ssos      case SW_VGA_CG320:
21728328Ssos        VGLDisplay->Type = VIDBUF8;
21828328Ssos        break;
21928328Ssos      case SW_VGA_MODEX:
22028328Ssos        VGLDisplay->Type = VIDBUF8X;
22128328Ssos        break;
22228328Ssos      default:
22328328Ssos        VGLDisplay->Type = VIDBUF8;			/* XXX */
22428328Ssos        break;
22528328Ssos      }
22628328Ssos    }
22728328Ssos    else {
22828328Ssos      for (i=0; i<4; i++) {
22928328Ssos        outb(0x3ce, 0x04);
23028328Ssos        outb(0x3cf, i);
23128328Ssos        bcopy(VGLMem, &VGLBuf[i*64*1024], 64*1024);
23228328Ssos      }
23328328Ssos      ioctl(0, VGLOldMode, 0);
23428328Ssos      ioctl(0, KDSETMODE, KD_TEXT);
23528328Ssos      ioctl(0, KDDISABIO, 0);
23628328Ssos      ioctl(0, VT_RELDISP, VT_TRUE);
23728328Ssos      VGLDisplay->Bitmap = VGLBuf;
23828328Ssos      VGLDisplay->Type = MEMBUF;
23928328Ssos    }
24028328Ssos  }
24128328Ssos  while (!VGLOnDisplay) pause();
24228328Ssos}
24328328Ssos
244