+++ /dev/null
-/* FCE Ultra - NES/Famicom Emulator
- *
- * Copyright notice for this file:
- * Copyright (C) 1998 \Firebug\
- * Copyright (C) 2002 Ben Parnell
- *
- * 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 <vga.h>
-#include <sys/io.h>
-
-#define inportb inb
-#define outportb(port, value) outb(value, port)
-#define outportw(port, value) outw(value, port)
-
-#include "main.h"
-#include "svgalib.h"
-#include "svga-video.h"
-
-
-int vmode=1;
-
-#ifdef FRAMESKIP
-int FCEUDfskip=0;
-#endif
-
-static int vidready=0;
-static int conlock=0;
-
-void LockConsole(void)
-{
- if(!conlock)
- {
- vga_lockvc();
- conlock=1;
- FCEUI_DispMessage("Console locked.");
- }
-}
-
-void UnlockConsole(void)
-{
- if(conlock)
- {
- vga_unlockvc();
- conlock=0;
- FCEUI_DispMessage("Console unlocked.");
- }
-}
-
-void SetBorder(void)
-{
- if(!conlock)
- vga_lockvc();
- inportb(0x3da);
- outportb(0x3c0,(0x11|0x20));
- outportb(0x3c0,0x80);
- if(!conlock)
- vga_unlockvc();
-}
-
-#include "vgatweak.c"
-
-void TweakVGA(int VGAMode)
-{
- int I;
-
- if(!conlock)
- vga_lockvc();
-
- 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);
- if(!conlock)
- vga_unlockvc();
-}
-
-
-static uint8 palettedbr[256],palettedbg[256],palettedbb[256];
-
-static void FlushPalette(void)
-{
- int x;
- for(x=0;x<256;x++)
- {
- int z=x;
- if(vmode==4 || vmode==5 || vmode==7) z^=0x80;
- 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)
- {
- if(vmode==4 || vmode==5 || vmode==7) index^=0x80;
- 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 void vcfix(void)
-{
- int z;
-
- if(!conlock)
- vga_lockvc();
- z=inportb(0x3cc);
- if(!conlock)
- vga_unlockvc();
- if(z!=0xe3 && z!=0xe7) // Common value in all tweaked video modes(and not in 320x200 mode).
- {
- TweakVGA(vmode);
- SetBorder();
- FlushPalette();
- }
-}
-
-static uint8 *ScreenLoc;
-
-int InitVideo(void)
-{
- #ifdef DUMMY
- return(1);
- #endif
- vidready=0;
-
- if(vmode<=3 || vmode==6 || vmode==8)
- {
- if(vga_getcurrentchipset()==FBDEV)
- {
- puts("Tweaked VGA video modes will not work. Using a 320x240 video mode instead...");
- vmode=7;
- }
- }
-
- switch(vmode)
- {
- default:
- case 1:
- case 2:
- case 3:
- case 6:
- case 8:
- vga_setmode(G320x200x256);
- vidready|=1;
- ScreenLoc=vga_getgraphmem();
- TweakVGA(vmode);
- SetBorder();
- memset(ScreenLoc,128,256*256);
- break;
- case 4:
- case 5:
- if(!(vga_getmodeinfo(G640x480x256)->flags & CAPABLE_LINEAR))
- {
- puts("Video: No linear addressing mode available!");
- return 0;
- }
- if(vga_setmode(G640x480x256)==-1)
- {
- puts("Video: Could not set 640x480x8bpp video mode!");
- return 0;
- }
- vidready|=1;
-
- vga_setpage(0);
- if(vga_setlinearaddressing()!=-1)
- ScreenLoc=vga_getgraphmem();
- else
- {
- puts("Video: Could not set linear addressing!");
- return 0;
- }
- memset(ScreenLoc,0,640*480);
- break;
- case 7:
- if(!(vga_getmodeinfo(G320x240x256V)->flags & CAPABLE_LINEAR))
- {
- puts("Video: No linear addressing mode available!");
- return 0;
- }
- if(vga_setmode(G320x240x256V)==-1)
- {
- puts("Video: Could not set 320x240x8bpp video mode!");
- return 0;
- }
- vidready|=1;
-
- vga_setpage(0);
- if(vga_setlinearaddressing()!=-1)
- ScreenLoc=vga_getgraphmem();
- else
- {
- puts("Video: Could not set linear addressing!");
- return 0;
- }
- memset(ScreenLoc,0,320*240);
- break;
- }
- vidready|=2;
- FlushPalette(); // Needed for cheat console code(and it isn't a bad thing to do anyway...).
- return 1;
-}
-
-void KillVideo(void)
-{
- if(vidready)
- {
- vga_setmode(TEXT);
- vidready=0;
- }
-}
-
-
-void BlitScreen(uint8 *XBuf)
-{
- static int conto=0;
- uint8 *dest;
- int tlines;
- #ifdef DUMMY
- return;
- #endif
- #ifdef FRAMESKIP
- FCEUI_FrameSkip(FCEUDfskip);
- #endif
-
- if(doptions&DO_VSYNC && !NoWaiting)
- {
- vga_waitretrace();
- }
-
- tlines=erendline-srendline+1;
-
- dest=ScreenLoc;
-
- if(vmode!=4 && vmode!=5 && vmode!=7)
- {
- conto=(conto+1)&0x3F;
- if(!conto) vcfix();
- }
- switch(vmode)
- {
- 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;
- case 7:dest+=(((240-tlines)>>1)*320)+32;break;
- }
-
- XBuf+=(srendline<<8)+(srendline<<4);
-
- if(eoptions&EO_CLIPSIDES)
- {
- if(vmode==5)
- {
- asm volatile(
- "xorl %%edx, %%edx\n\t"
- "ckoop1:\n\t"
- "movb $120,%%al \n\t"
- "ckoop2:\n\t"
- "movb 1(%%esi),%%dl\n\t"
- "shl $16,%%edx\n\t"
- "movb (%%esi),%%dl\n\t"
- "xorl $0x00800080,%%edx\n\t"
- "movl %%edx,(%%edi)\n\t"
- "addl $2,%%esi\n\t"
- "addl $4,%%edi\n\t"
- "decb %%al\n\t"
- "jne ckoop2\n\t"
-
- "addl $32,%%esi\n\t"
- "addl $800,%%edi\n\t"
- "decb %%bl\n\t"
- "jne ckoop1\n\t"
- :
- : "S" (XBuf+8), "D" (dest+8), "b" (tlines)
- : "%al", "%edx", "%cc" );
- }
- else if(vmode==4)
- {
- asm volatile(
- "cyoop1:\n\t"
- "movb $120,%%al \n\t"
- "cyoop2:\n\t"
- "movb 1(%%esi),%%dh\n\t"
- "movb %%dh,%%dl\n\t"
- "shl $16,%%edx\n\t"
- "movb (%%esi),%%dl\n\t"
- "movb %%dl,%%dh\n\t" // Ugh
- "xorl $0x80808080,%%edx\n\t"
- "movl %%edx,(%%edi)\n\t"
- "addl $2,%%esi\n\t"
- "addl $4,%%edi\n\t"
- "decb %%al\n\t"
- "jne cyoop2\n\t"
-
- "addl $32,%%esi\n\t"
- "addl $800,%%edi\n\t"
- "decb %%bl\n\t"
- "jne cyoop1\n\t"
- :
- : "S" (XBuf+8), "D" (dest+8), "b" (tlines)
- : "%al", "%edx", "%cc" );
- }
- else if(vmode==7)
- {
- asm volatile(
- "cgoop81:\n\t"
- "movl $30,%%eax\n\t"
- "cgoop82:\n\t"
- "movl (%%esi),%%edx\n\t"
- "movl 4(%%esi),%%ecx\n\t"
- "xorl $0x80808080,%%edx\n\t"
- "xorl $0x80808080,%%ecx\n\t"
- "movl %%edx,(%%edi)\n\t"
- "movl %%ecx,4(%%edi)\n\t"
- "addl $8,%%esi\n\t"
- "addl $8,%%edi\n\t"
- "decl %%eax\n\t"
- "jne cgoop82\n\t"
- "addl $80,%%edi\n\t"
- "addl $32,%%esi\n\t"
- "decb %%bl\n\t"
- "jne cgoop81\n\t"
- :
- : "S" (XBuf+8), "D" (dest+8), "b" (tlines)
- : "%eax","%cc","%edx","%ecx" );
- }
- else
- {
- asm volatile(
- "cgoop1:\n\t"
- "movl $30,%%eax\n\t"
- "cgoop2:\n\t"
- "movl (%%esi),%%edx\n\t"
- "movl 4(%%esi),%%ecx\n\t"
- "movl %%edx,(%%edi)\n\t"
- "movl %%ecx,4(%%edi)\n\t"
- "addl $8,%%esi\n\t"
- "addl $8,%%edi\n\t"
- "decl %%eax\n\t"
- "jne cgoop2\n\t"
- "addl $32,%%esi\n\t"
- "addl $16,%%edi\n\t"
- "decb %%bl\n\t"
- "jne cgoop1\n\t"
- :
- : "S" (XBuf+8), "D" (dest+8), "b" (tlines)
- : "%eax","%cc","%edx","%ecx" );
- }
- }
- else
- {
- if(vmode==5)
- {
- asm volatile(
- "xorl %%edx, %%edx\n\t"
- "koop1:\n\t"
- "movb $128,%%al \n\t"
- "koop2:\n\t"
- "movb 1(%%esi),%%dl\n\t"
- "shl $16,%%edx\n\t"
- "movb (%%esi),%%dl\n\t"
- "xorl $0x00800080,%%edx\n\t"
- "movl %%edx,(%%edi)\n\t"
- "addl $2,%%esi\n\t"
- "addl $4,%%edi\n\t"
- "decb %%al\n\t"
- "jne koop2\n\t"
-
- "addl $16,%%esi\n\t"
- "addl $768,%%edi\n\t"
- "decb %%bl\n\t"
- "jne koop1\n\t"
- :
- : "S" (XBuf), "D" (dest), "b" (tlines)
- : "%al", "%edx", "%cc" );
- }
- else if(vmode==4)
- {
- asm volatile(
- "yoop1:\n\t"
- "movb $128,%%al \n\t"
- "yoop2:\n\t"
- "movb 1(%%esi),%%dh\n\t"
- "movb %%dh,%%dl\n\t"
- "shl $16,%%edx\n\t"
- "movb (%%esi),%%dl\n\t"
- "movb %%dl,%%dh\n\t" // Ugh
- "xorl $0x80808080,%%edx\n\t"
- "movl %%edx,(%%edi)\n\t"
- "addl $2,%%esi\n\t"
- "addl $4,%%edi\n\t"
- "decb %%al\n\t"
- "jne yoop2\n\t"
-
- "addl $16,%%esi\n\t"
- "addl $768,%%edi\n\t"
- "decb %%bl\n\t"
- "jne yoop1\n\t"
- :
- : "S" (XBuf), "D" (dest), "b" (tlines)
- : "%al", "%edx", "%cc" );
- }
- else if(vmode==7)
- {
- asm volatile(
- "goop81:\n\t"
- "movl $32,%%eax\n\t"
- "goop82:\n\t"
- "movl (%%esi),%%edx\n\t"
- "movl 4(%%esi),%%ecx\n\t"
- "xorl $0x80808080,%%edx\n\t"
- "xorl $0x80808080,%%ecx\n\t"
- "movl %%edx,(%%edi)\n\t"
- "movl %%ecx,4(%%edi)\n\t"
- "addl $8,%%esi\n\t"
- "addl $8,%%edi\n\t"
- "decl %%eax\n\t"
- "jne goop82\n\t"
- "addl $64,%%edi\n\t"
- "addl $16,%%esi\n\t"
- "decb %%bl\n\t"
- "jne goop81\n\t"
- :
- : "S" (XBuf), "D" (dest), "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"
- "movl %%edx,(%%edi)\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" );
- }
- }
-}
-
-