fceux/attic/pc/dos-video.c

247 lines
5.1 KiB
C

/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 1998 \Firebug\
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <string.h>
#include <dpmi.h>
#include <sys/farptr.h>
#include <go32.h>
#include <pc.h>
#include "dos.h"
#include "dos-video.h"
#define TEXT 3
#define G320x200x256 0x13
static void vga_waitretrace(void)
{
while(inp(0x3da)&0x8);
while(!(inp(0x3da)&0x8));
}
static void vga_setmode(int mode)
{
__dpmi_regs regs;
memset(&regs,0,sizeof(regs));
regs.x.ax=mode;
__dpmi_int(0x10,&regs);
}
void vga_setpalette(int i, int r, int g, int b)
{
outp(0x3c8,i);
outp(0x3c9,r);
outp(0x3c9,g);
outp(0x3c9,b);
}
int FCEUDvmode=1;
static int vidready=0;
/* Part of the VGA low-level mass register setting code derived from
code by \Firebug\.
*/
#include "vgatweak.c"
void SetBorder(void)
{
inportb(0x3da);
outportb(0x3c0,(0x11|0x20));
outportb(0x3c0,0x80);
}
void TweakVGA(int VGAMode)
{
int I;
vga_waitretrace();
outportb(0x3C8,0x00);
for(I=0;I<768;I++) outportb(0x3C9,0x00);
outportb(0x3D4,0x11);
I=inportb(0x3D5)&0x7F;
outportb(0x3D4,0x11);
outportb(0x3D5,I);
switch(VGAMode)
{
case 1: for(I=0;I<25;I++) VGAPortSet(v256x240[I]);break;
case 2: for(I=0;I<25;I++) VGAPortSet(v256x256[I]);break;
case 3: for(I=0;I<25;I++) VGAPortSet(v256x256S[I]);break;
case 6: for(I=0;I<25;I++) VGAPortSet(v256x224S[I]);break;
case 8: for(I=0;I<25;I++) VGAPortSet(v256x224_103[I]);break;
default: break;
}
outportb(0x3da,0);
}
static uint8 palettedbr[256],palettedbg[256],palettedbb[256];
static void FlushPalette(void)
{
int x;
for(x=0;x<256;x++)
{
int z=x;
vga_setpalette(z,palettedbr[x]>>2,palettedbg[x]>>2,palettedbb[x]>>2);
}
}
void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
{
palettedbr[index]=r;
palettedbg[index]=g;
palettedbb[index]=b;
if(vidready)
{
vga_setpalette(index,r>>2,g>>2,b>>2);
}
}
void FCEUD_GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b)
{
*r=palettedbr[i];
*g=palettedbg[i];
*b=palettedbb[i];
}
static uint32 ScreenLoc;
int InitVideo(void)
{
vidready=0;
switch(FCEUDvmode)
{
default:
case 1:
case 2:
case 3:
case 6:
case 8:
vga_setmode(G320x200x256);
vidready|=1;
ScreenLoc=0xa0000;
TweakVGA(FCEUDvmode);
SetBorder();
DOSMemSet(ScreenLoc, 128, 256*256);
break;
}
vidready|=2;
FlushPalette();
return 1;
}
void KillVideo(void)
{
if(vidready)
{
vga_setmode(TEXT);
vidready=0;
}
}
void LockConsole(void){}
void UnlockConsole(void){}
void BlitScreen(uint8 *XBuf)
{
uint32 dest;
int tlines;
if(eoptions&4 && !NoWaiting)
vga_waitretrace();
tlines=erendline-srendline+1;
dest=ScreenLoc;
switch(FCEUDvmode)
{
case 1:dest+=(((240-tlines)>>1)<<8);break;
case 2:
case 3:dest+=(((256-tlines)>>1)<<8);break;
case 4:
case 5:dest+=(((240-tlines)>>1)*640+((640-512)>>1));break;
case 8:
case 6:if(tlines>224) tlines=224;dest+=(((224-tlines)>>1)<<8);break;
}
XBuf+=(srendline<<8)+(srendline<<4);
_farsetsel(_dos_ds);
if(eoptions&DO_CLIPSIDES)
{
asm volatile(
"agoop1:\n\t"
"movl $30,%%eax\n\t"
"agoop2:\n\t"
"movl (%%esi),%%edx\n\t"
"movl 4(%%esi),%%ecx\n\t"
".byte 0x64 \n\t"
"movl %%edx,(%%edi)\n\t"
".byte 0x64 \n\t"
"movl %%ecx,4(%%edi)\n\t"
"addl $8,%%esi\n\t"
"addl $8,%%edi\n\t"
"decl %%eax\n\t"
"jne agoop2\n\t"
"addl $32,%%esi\n\t"
"addl $16,%%edi\n\t"
"decb %%bl\n\t"
"jne agoop1\n\t"
:
: "S" (XBuf+8), "D" (dest+8), "b" (tlines)
: "%eax","%cc","%edx","%ecx" );
}
else
{
asm volatile(
"goop1:\n\t"
"movl $32,%%eax\n\t"
"goop2:\n\t"
"movl (%%esi),%%edx\n\t"
"movl 4(%%esi),%%ecx\n\t"
".byte 0x64 \n\t"
"movl %%edx,(%%edi)\n\t"
".byte 0x64 \n\t"
"movl %%ecx,4(%%edi)\n\t"
"addl $8,%%esi\n\t"
"addl $8,%%edi\n\t"
"decl %%eax\n\t"
"jne goop2\n\t"
"addl $16,%%esi\n\t"
"decb %%bl\n\t"
"jne goop1\n\t"
:
: "S" (XBuf), "D" (dest), "b" (tlines)
: "%eax","%cc","%edx","%ecx" );
}
}