#include "crc32.h"
#include "ppu.h"
+#include "movie.h"
+
#define Pal (PALRAM)
+#ifdef DEBUG_ASM_6502
+extern int cpu_repeat;
+extern int cpu_lastval;
+#endif
+
static void (*RefreshLine)(uint8 *P, uint32 vofs) = NULL;
static void PRefreshLine(void);
static writefunc *BWriteG;
static int RWWrap=0;
+#ifdef ASM_6502
+static void asmcpu_update(int32 cycles)
+{
+ // timestamp..
+ timestamp += ((cycles >> 4) * 43) >> 7; // aproximating /= 48
+
+ // some code from x6502.c
+ fhcnt-=cycles;
+ if(fhcnt<=0)
+ {
+ FrameSoundUpdate();
+ fhcnt+=fhinc;
+ }
+
+ if(PCMIRQCount>0)
+ {
+ PCMIRQCount-=cycles;
+ if(PCMIRQCount<=0)
+ {
+ vdis=1;
+ if((PSG[0x10]&0x80) && !(PSG[0x10]&0x40))
+ {
+ extern uint8 SIRQStat;
+ SIRQStat|=0x80;
+ X6502_IRQBegin(FCEU_IQDPCM);
+ }
+ }
+ }
+}
+
+void asmcpu_unpack(void)
+{
+ nes_registers[0] = X.A << 24;
+ nes_registers[1] = X.X;
+ nes_registers[2] = X.Y;
+ pc_base = 0;
+ nes_registers[3] = X.PC;
+ X6502_rebase_a();
+ nes_registers[4] = X.S << 24;
+ nes_registers[4]|= X.IRQlow << 8;
+ nes_registers[7] = (uint32)X.count;
+
+ // NVUB DIZC
+ nes_registers[4]|= X.P & 0x5d;
+ nes_registers[5] = X.P << 24; // N
+ if (!(X.P&0x02)) nes_registers[5] |= 1; // Z
+}
+
+void asmcpu_pack(void)
+{
+ X.A = nes_registers[0] >> 24;
+ X.X = nes_registers[1];
+ X.Y = nes_registers[2];
+ X.PC= nes_registers[3] - pc_base;
+ X.S = nes_registers[4] >> 24;
+ X.IRQlow = nes_registers[4] >> 8;
+ X.count = (int32) nes_registers[7];
+
+ // NVUB DIZC
+ X.P = nes_registers[4] & 0x5d;
+ if ( nes_registers[5]&0x80000000) X.P |= 0x80; // N
+ if (!(nes_registers[5]&0x000000ff)) X.P |= 0x02; // Z
+}
+#endif
+
DECLFW(BNull)
{
/* scanline is equal to the current visible scanline we're on. */
int scanline;
-static uint32 scanlines_per_frame;
+
+uint8 GameMemBlock[131072] __attribute__ ((aligned (4)));
+uint8 NTARAM[0x800] __attribute__ ((aligned (4)));
+uint8 PALRAM[0x20] __attribute__ ((aligned (4)));
+#if !defined(ASM_6502) || defined(DEBUG_ASM_6502)
+uint8 RAM[0x800] __attribute__ ((aligned (4)));
+#endif
uint8 PPU[4];
uint8 PPUSPL;
-uint8 GameMemBlock[131072];
-uint8 NTARAM[0x800],PALRAM[0x20];
-uint8 RAM[0x800];
-
uint8 PAL=0;
static DECLFR(A2002)
{
uint8 ret;
+#ifdef DEBUG_ASM_6502
+ if (cpu_repeat) return cpu_lastval;
+#endif
ret = PPU_status;
vtoggle=0;
PPU_status&=0x7F;
+#ifdef DEBUG_ASM_6502
+ cpu_lastval=ret|(PPUGenLatch&0x1F);
+#endif
return ret|(PPUGenLatch&0x1F);
}
{
uint8 ret;
uint32 tmp=RefreshAddr&0x3FFF;
+#ifdef DEBUG_ASM_6502
+ if (cpu_repeat) return cpu_lastval;
+#endif
PPUGenLatch=ret=VRAMBuffer;
if(PPU_hook) PPU_hook(tmp);
if (INC32) RefreshAddr+=32;
else RefreshAddr++;
if(PPU_hook) PPU_hook(RefreshAddr&0x3fff);
+#ifdef DEBUG_ASM_6502
+ cpu_lastval=ret;
+#endif
return ret;
}
{
uint32 t=V<<8;
int x;
+#ifdef DEBUG_ASM_6502
+ if (cpu_repeat) { X6502_AddCycles_a(512); return; }
+ for(x=0;x<256;x++)
+ B2004(0x2004,X.DB=ARead[t+x](t+x));
+ X6502_AddCycles_c(512);
+#else
for(x=0;x<256;x++)
B2004(0x2004,X.DB=ARead[t+x](t+x));
X6502_AddCycles(512);
+#endif
}
void BGRender(uint8 *target)
if(!(PPU[1]&2))
{
- tem=Pal[0]|(Pal[0]<<8)|(Pal[0]<<16)|(Pal[0]<<24);
- tem|=0x40404040;
+ tem=Pal[0]|0x40;
+ tem|=tem<<8;
+ tem|=tem<<16;
*(uint32 *)target=*(uint32 *)(target+4)=tem;
}
}
{
uint32 tem;
int x;
- uint8 *target=XBuf+(scanline<<8)+(scanline<<4)+8;
+ uint8 *target=XBuf+scanline*320+32;
if(ScreenON || SpriteON)
{
if(PPU[1]&0x01)
{
for(x=63;x>=0;x--)
- *(uint32 *)&target[x<<2]=(*(uint32*)&target[x<<2])&0xF0F0F0F0;
+ ((uint32 *)target)[x]=((uint32*)target)[x]&0xF0F0F0F0;
}
if((PPU[1]>>5)==0x7)
for(x=63;x>=0;x--)
- *(uint32 *)&target[x<<2]=((*(uint32*)&target[x<<2])&0x3f3f3f3f)|0x40404040;
+ ((uint32 *)target)[x]=(((uint32*)target)[x]&0x3f3f3f3f)|0x40404040;
else if(PPU[1]&0xE0)
for(x=63;x>=0;x--)
- *(uint32 *)&target[x<<2]=(*(uint32*)&target[x<<2])|0xC0C0C0C0;
+ ((uint32 *)target)[x]=((uint32*)target)[x]|0xC0C0C0C0;
else
for(x=63;x>=0;x--)
- *(uint32 *)&target[x<<2]=(*(uint32*)&target[x<<2])&0x3f3f3f3f;
-
+ ((uint32 *)target)[x]=((uint32*)target)[x]&0x3f3f3f3f;
+ FCEU_dwmemset(target- 8,0x3f3f3f3f,8);
+ FCEU_dwmemset(target+256,0x3f3f3f3f,8);
#ifdef FRAMESKIP
}
#endif
}
}
-static void RefreshLine_normal(uint8 *P, uint32 vofs)
+static void RefreshLine_normal(uint8 *P, uint32 vofs) // vofs is 0x107 max
{
int8 X1;
+ uint32 rfraddr = RefreshAddr;
+ uint8 *page = vnapage[(rfraddr>>10)&3];
+ uint32 cc2=0;
- for(X1=33;X1;X1--,P+=8)
+ if ((rfraddr&0xc)!=0)
+ cc2=*(uint32 *) (page + ((rfraddr&0x380)>>4) + ((rfraddr&0x10)>>2) + 0x3c0);
+
+ for (X1=33;X1;X1--,P+=8)
{
- uint8 *C;
- uint8 cc,zz,zz2;
+ uint8 cc,*C;
uint32 vadr;
- zz=RefreshAddr&0x1F;
- zz2=(RefreshAddr>>10)&3;
- vadr=(vnapage[zz2][RefreshAddr&0x3ff]<<4)+vofs;
+ vadr=(page[rfraddr&0x3ff]<<4)+vofs;
C = VRAMADR(vadr);
- cc=vnapage[zz2][0x3c0+(zz>>2)+((RefreshAddr&0x380)>>4)];
- cc=((cc >> ((zz&2) + ((RefreshAddr&0x40)>>4))) &3) <<2;
- {
- uint8 *S=PALRAM+cc;
- uint8 c1,c2;
-
- c1=((C[0]>>1)&0x55)|(C[8]&0xAA);
- c2=(C[0]&0x55)|((C[8]<<1)&0xAA);
-
- P[6]=S[c1&3];
- P[7]=S[c2&3];
- P[4]=S[(c1>>2)&3];
- P[5]=S[(c2>>2)&3];
- P[2]=S[(c1>>4)&3];
- P[3]=S[(c2>>4)&3];
+ if ((rfraddr&0xc)==0)
+ cc2=*(uint32 *) (page + ((rfraddr&0x380)>>4) + ((rfraddr&0x10)>>2) + 0x3c0);
+ cc=((cc2 >> ((rfraddr&2) + ((rfraddr&0x40)>>4) + ((rfraddr&0xc)<<1))) & 3) << 2;
- P[0]=S[c1>>6];
- P[1]=S[c2>>6];
- }
+ #include "fceline.h"
- if((RefreshAddr&0x1f)==0x1f)
- RefreshAddr^=0x41F;
- else
- RefreshAddr++;
+ if((rfraddr&0x1f)==0x1f) {
+ rfraddr^=0x41F;
+ page = vnapage[(rfraddr>>10)&3];
+ } else
+ rfraddr++;
}
+ RefreshAddr = rfraddr;
}
static void SetRefreshLine(void)
}
}
-static INLINE void Fixit2(void)
+//static INLINE
+void Fixit2(void)
{
if(ScreenON || SpriteON)
{
}
}
-static INLINE void Fixit1(void)
+//static INLINE
+void Fixit1(void)
{
if(ScreenON || SpriteON)
{
}
}
+//#define NEW_TRY
+
/* This is called at the beginning of all h-blanks on visible lines. */
+#ifndef NEW_TRY
static void DoHBlank(void)
{
if(ScreenON || SpriteON)
//PPU_hook(0,-1);
//fprintf(stderr,"%3d: $%04x\n",scanline,RefreshAddr);
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+#endif
// ============================//
FCEUGameInfo.inputfc=-1;
}
+char lastLoadedGameName [2048];
+
FCEUGI *FCEUI_LoadGame(char *name)
{
+ char name2[512];
+ int have_movie = 0;
int fp;
Exit=1;
ResetGameLoaded();
- fp=FCEU_fopen(name,"rb");
+ strncpy(name2, name, sizeof(name2));
+ name2[sizeof(name2)-1] = 0;
+
+ fp=FCEU_fopen(name2,"rb");
if(!fp)
{
FCEU_PrintError("Error opening \"%s\"!",name);
return 0;
}
- GetFileBase(name);
- if(iNESLoad(name,fp))
+ {
+ char *p = name2 + strlen(name2) - 4;
+ if (strcmp(p, ".fcm") == 0)
+ {
+ // movie detected
+ printf("movie detected\n");
+ FCEU_fclose(fp);
+ *p = 0;
+ fp=FCEU_fopen(name2,"rb");
+ if (!fp) {
+ printf("no ROM for movie\n");
+ return 0;
+ }
+ have_movie = 1;
+ }
+ }
+
+ strcpy(lastLoadedGameName, name2);
+
+ GetFileBase(name2);
+ if(iNESLoad(name2,fp))
goto endlseq;
if(NSFLoad(fp))
goto endlseq;
- if(FDSLoad(name,fp))
+ if(FDSLoad(name2,fp))
goto endlseq;
- if(UNIFLoad(name,fp))
+ if(UNIFLoad(name2,fp))
goto endlseq;
FCEU_PrintError("An error occurred while loading the file.");
FCEU_ResetPalette();
Exit=0;
+
+ if (have_movie)
+ FCEUI_LoadMovie(name, 1);
return(&FCEUGameInfo);
}
if(w)
{
PAL=1;
- scanlines_per_frame=312;
FSettings.FirstSLine=FSettings.UsrFirstSLine[1];
FSettings.LastSLine=FSettings.UsrLastSLine[1];
}
else
{
PAL=0;
- scanlines_per_frame=262;
FSettings.FirstSLine=FSettings.UsrFirstSLine[0];
FSettings.LastSLine=FSettings.UsrLastSLine[0];
}
static INLINE void Thingo(void)
{
Loop6502();
+#ifndef NEW_TRY
if(tosprite>=256)
{
tosprite=256;
}
DoHBlank();
+#else
+ X6502_Run_scanline();
+#endif
}
#undef harko
{
for(;;)
{
+ uint32 scanlines_per_frame = PAL ? 312 : 262;
+ //extern int asdc;
+ //printf("asdc: %i\n", asdc);
+ //asdc=0;
ApplyPeriodicCheats();
X6502_Run(256+85);
else if(VBlankON)
TriggerNMI();
- X6502_Run((scanlines_per_frame-242)*(256+85)-12);
+ X6502_Run(256+85-12);
+ for(scanline=242+1;scanline<scanlines_per_frame;scanline++)
+ X6502_Run(256+85);
PPU_status&=0x1f;
if(PPU_hook) PPU_hook(RefreshAddr&0x3fff);
}
if(FCEUGameInfo.type==GIT_NSF)
+ {
X6502_Run((256+85)*240);
+ }
else
{
int x,max,maxref;