Add overclocking - backported from FCEUX with mods

This commit is contained in:
twinaphex
2016-02-22 18:36:09 +01:00
parent 479d5d8e37
commit 417b8c6022
8 changed files with 114 additions and 33 deletions

View File

@@ -22,8 +22,8 @@
#include "../../unif.h" #include "../../unif.h"
#include "../../fds.h" #include "../../fds.h"
#include "../../vsuni.h" #include "../../vsuni.h"
#include "../../video.h"
#include <string.h>
#include "../../memstream.h" #include "../../memstream.h"
#if defined(_3DS) #if defined(_3DS)
@@ -41,6 +41,15 @@ static bool use_raw_palette;
/* emulator-specific variables */ /* emulator-specific variables */
/* overclock the console by adding dummy scanlines to PPU loop
* disables DMC DMA and WaveHi filling for these dummies
* doesn't work with new PPU */
unsigned overclocked = 0;
/* 7-bit samples have priority over overclocking */
unsigned skip_7bit_overclocking = 1;
unsigned normal_scanlines = 240;
unsigned extrascanlines = 0;
int FCEUnetplay; int FCEUnetplay;
#ifdef PSP #ifdef PSP
#include "pspgu.h" #include "pspgu.h"
@@ -52,9 +61,6 @@ static uint16_t* fceu_video_out;
/* Some timing-related variables. */ /* Some timing-related variables. */
static int maxconbskip = 9; /* Maximum consecutive blit skips. */
static int ffbskip = 9; /* Blit skips per blit when FF-ing */
static int soundo = 1; static int soundo = 1;
static volatile int nofocus = 0; static volatile int nofocus = 0;
@@ -467,8 +473,9 @@ void retro_set_controller_port_device(unsigned a, unsigned b)
void retro_set_environment(retro_environment_t cb) void retro_set_environment(retro_environment_t cb)
{ {
static const struct retro_variable vars[] = { static const struct retro_variable vars[] = {
{ "nes_palette", "Color Palette; asqrealc|loopy|quor|chris|matt|pasofami|crashman|mess|zaphod-cv|zaphod-smb|vs-drmar|vs-cv|vs-smb|nintendo-vc|raw" }, { "fceumm_palette", "Color Palette; asqrealc|loopy|quor|chris|matt|pasofami|crashman|mess|zaphod-cv|zaphod-smb|vs-drmar|vs-cv|vs-smb|nintendo-vc|raw" },
{ "nes_nospritelimit", "No Sprite Limit; disabled|enabled" }, { "fceumm_nospritelimit", "No Sprite Limit; disabled|enabled" },
{ "fceumm_overclocking", "Overclocking; disabled|2x" },
{ NULL, NULL }, { NULL, NULL },
}; };
@@ -608,57 +615,91 @@ static const keymap bindmap[] = {
static void check_variables(void) static void check_variables(void)
{ {
static int overclock_state = -1;
struct retro_variable var = {0}; struct retro_variable var = {0};
var.key = "nes_palette"; var.key = "fceumm_palette";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{ {
unsigned orig_value = current_palette; unsigned orig_value = current_palette;
if (strcmp(var.value, "asqrealc") == 0) if (!strcmp(var.value, "asqrealc"))
current_palette = 0; current_palette = 0;
else if (strcmp(var.value, "loopy") == 0) else if (!strcmp(var.value, "loopy"))
current_palette = 1; current_palette = 1;
else if (strcmp(var.value, "quor") == 0) else if (!strcmp(var.value, "quor"))
current_palette = 2; current_palette = 2;
else if (strcmp(var.value, "chris") == 0) else if (!strcmp(var.value, "chris"))
current_palette = 3; current_palette = 3;
else if (strcmp(var.value, "matt") == 0) else if (!strcmp(var.value, "matt"))
current_palette = 4; current_palette = 4;
else if (strcmp(var.value, "matt") == 0) else if (!strcmp(var.value, "matt"))
current_palette = 5; current_palette = 5;
else if (strcmp(var.value, "pasofami") == 0) else if (!strcmp(var.value, "pasofami"))
current_palette = 6; current_palette = 6;
else if (strcmp(var.value, "crashman") == 0) else if (!strcmp(var.value, "crashman"))
current_palette = 7; current_palette = 7;
else if (strcmp(var.value, "mess") == 0) else if (!strcmp(var.value, "mess"))
current_palette = 8; current_palette = 8;
else if (strcmp(var.value, "zaphod-cv") == 0) else if (!strcmp(var.value, "zaphod-cv"))
current_palette = 9; current_palette = 9;
else if (strcmp(var.value, "zaphod-smb") == 0) else if (!strcmp(var.value, "zaphod-smb"))
current_palette = 10; current_palette = 10;
else if (strcmp(var.value, "vs-drmar") == 0) else if (!strcmp(var.value, "vs-drmar"))
current_palette = 11; current_palette = 11;
else if (strcmp(var.value, "vs-cv") == 0) else if (!strcmp(var.value, "vs-cv"))
current_palette = 12; current_palette = 12;
else if (strcmp(var.value, "vs-smb") == 0) else if (!strcmp(var.value, "vs-smb"))
current_palette = 13; current_palette = 13;
else if (strcmp(var.value, "nintendo-vc") == 0) else if (!strcmp(var.value, "nintendo-vc"))
current_palette = 14; current_palette = 14;
else if (strcmp(var.value, "raw") == 0) else if (!strcmp(var.value, "raw"))
current_palette = 15; current_palette = 15;
if (current_palette != orig_value) if (current_palette != orig_value)
retro_set_custom_palette(); retro_set_custom_palette();
} }
var.key = "nes_nospritelimit";
var.key = "fceumm_nospritelimit";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{ {
int no_sprite_limit = (strcmp(var.value, "enabled") == 0) ? 1 : 0; int no_sprite_limit = (!strcmp(var.value, "enabled")) ? 1 : 0;
FCEUI_DisableSpriteLimitation(no_sprite_limit); FCEUI_DisableSpriteLimitation(no_sprite_limit);
} }
var.key = "fceumm_overclocking";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
bool do_reinit = false;
if (!strcmp(var.value, "disabled")
&& overclock_state != 0)
{
overclocked = 0;
skip_7bit_overclocking = 1;
extrascanlines = 0;
overclock_state = 0;
do_reinit = true;
}
else if (!strcmp(var.value, "2x")
&& overclock_state != 1)
{
overclocked = 1;
skip_7bit_overclocking = 1;
extrascanlines = 266;
overclock_state = 1;
do_reinit = true;
}
if (do_reinit)
{
FCEU_KillVirtualVideo();
FCEU_InitVirtualVideo();
}
}
} }
/* /*

View File

@@ -23,6 +23,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include "fceu.h"
#include "fceu-types.h" #include "fceu-types.h"
#include "x6502.h" #include "x6502.h"
#include "fceu.h" #include "fceu.h"
@@ -48,6 +49,7 @@
uint64 timestampbase; uint64 timestampbase;
extern int totalscanlines;
FCEUGI *GameInfo = NULL; FCEUGI *GameInfo = NULL;
void (*GameInterface)(int h); void (*GameInterface)(int h);
@@ -460,6 +462,8 @@ void FCEU_ResetVidSys(void)
PAL = w ? 1 : 0; PAL = w ? 1 : 0;
totalscanlines = normal_scanlines + (overclocked ? extrascanlines : 0);
FCEUPPU_SetVideoSystem(w); FCEUPPU_SetVideoSystem(w);
SetSoundVariables(); SetSoundVariables();
} }

View File

@@ -4,6 +4,14 @@
#include "fceu-types.h" #include "fceu-types.h"
extern int fceuindbg; extern int fceuindbg;
extern unsigned overclocked;
extern unsigned skip_7bit_overclocking;
extern unsigned DMC_7bit;
extern unsigned normal_scanlines;
extern unsigned extrascanlines;
void ResetGameLoaded(void); void ResetGameLoaded(void);
#define DECLFR(x) uint8 FP_FASTAPASS(1) x(uint32 A) #define DECLFR(x) uint8 FP_FASTAPASS(1) x(uint32 A)

View File

@@ -127,6 +127,8 @@ static int maxsprites = 8;
int scanline; int scanline;
static uint32 scanlines_per_frame; static uint32 scanlines_per_frame;
int totalscanlines;
uint8 PPU[4]; uint8 PPU[4];
uint8 PPUSPL; uint8 PPUSPL;
uint8 NTARAM[0x800], PALRAM[0x20], SPRAM[0x100], SPRBUF[0x100]; uint8 NTARAM[0x800], PALRAM[0x20], SPRAM[0x100], SPRBUF[0x100];
@@ -1180,7 +1182,7 @@ int FCEUPPU_Loop(int skip) {
kook ^= 1; kook ^= 1;
} }
if (GameInfo->type == GIT_NSF) if (GameInfo->type == GIT_NSF)
X6502_Run((256 + 85) * 240); X6502_Run((256 + 85) * normal_scanlines);
#ifdef FRAMESKIP #ifdef FRAMESKIP
else if (skip) { else if (skip) {
int y; int y;
@@ -1209,11 +1211,20 @@ int FCEUPPU_Loop(int skip) {
int x, max, maxref; int x, max, maxref;
deemp = PPU[1] >> 5; deemp = PPU[1] >> 5;
for (scanline = 0; scanline < 240; ) { //scanline is incremented in DoLine. Evil. :/
// manual samples can't play correctly with overclocking
if (DMC_7bit && skip_7bit_overclocking)
totalscanlines = normal_scanlines;
else
totalscanlines = normal_scanlines + (overclocked ? extrascanlines : 0);
for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/
deempcnt[deemp]++; deempcnt[deemp]++;
if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1); if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1);
DoLine(); DoLine();
} }
DMC_7bit = 0;
if (MMC5Hack && (ScreenON || SpriteON)) MMC5_hb(scanline); if (MMC5Hack && (ScreenON || SpriteON)) MMC5_hb(scanline);
for (x = 1, max = 0, maxref = 0; x < 7; x++) { for (x = 1, max = 0, maxref = 0; x < 7; x++) {
if (deempcnt[x] > max) { if (deempcnt[x] > max) {

View File

@@ -61,6 +61,7 @@ typedef struct {
int reloaddec; int reloaddec;
} ENVUNIT; } ENVUNIT;
unsigned DMC_7bit = 0; // used to skip overclocking
static ENVUNIT EnvUnits[3]; static ENVUNIT EnvUnits[3];
static const int RectDuties[4] = { 1, 2, 4, 6 }; static const int RectDuties[4] = { 1, 2, 4, 6 };
@@ -276,9 +277,19 @@ static DECLFW(Write_DMCRegs) {
break; break;
case 0x01: DoPCM(); case 0x01: DoPCM();
RawDALatch = V & 0x7F; RawDALatch = V & 0x7F;
if (RawDALatch)
DMC_7bit = 1;
break; break;
case 0x02: DMCAddressLatch = V; break; case 0x02:
case 0x03: DMCSizeLatch = V; break; DMCAddressLatch = V;
if (V)
DMC_7bit = 0;
break;
case 0x03:
DMCSizeLatch = V;
if (V)
DMC_7bit = 0;
break;
} }
} }

View File

@@ -48,7 +48,7 @@ int FCEU_InitVirtualVideo(void)
{ {
// 256 bytes per scanline, * 240 scanline maximum, +8 for alignment, // 256 bytes per scanline, * 240 scanline maximum, +8 for alignment,
if (!XBuf) if (!XBuf)
XBuf = (uint8*)(FCEU_malloc(256 * 256 + 8)); XBuf = (uint8*)(FCEU_malloc(256 * (256 + extrascanlines + 8)));
if (!XBuf) if (!XBuf)
return 0; return 0;
@@ -60,7 +60,7 @@ int FCEU_InitVirtualVideo(void)
m = (4 - m) & 3; m = (4 - m) & 3;
XBuf += m; XBuf += m;
} }
memset(XBuf, 128, 256 * 256); memset(XBuf, 128, 256 * (256 + extrascanlines));
return 1; return 1;
} }

View File

@@ -20,6 +20,7 @@
#include <string.h> #include <string.h>
#include "fceu.h"
#include "fceu-types.h" #include "fceu-types.h"
#include "x6502.h" #include "x6502.h"
#include "fceu.h" #include "fceu.h"
@@ -51,7 +52,7 @@ void FP_FASTAPASS(1) (*MapIRQHook)(int a);
int __x = x; \ int __x = x; \
_tcount += __x; \ _tcount += __x; \
_count -= __x * 48; \ _count -= __x * 48; \
timestamp += __x; \ if (scanline < normal_scanlines || scanline == totalscanlines) timestamp+= __x; \
} }
static INLINE uint8 RdMemNorm(uint32 A) { static INLINE uint8 RdMemNorm(uint32 A) {
@@ -509,7 +510,8 @@ static void X6502_RunDebug(int32 cycles) {
_tcount = 0; _tcount = 0;
if (MapIRQHook) MapIRQHook(temp); if (MapIRQHook) MapIRQHook(temp);
FCEU_SoundCPUHook(temp); if (scanline < normal_scanlines || scanline == totalscanlines)
FCEU_SoundCPUHook(temp);
_PC++; _PC++;
switch (b1) { switch (b1) {

View File

@@ -23,6 +23,10 @@
#include "x6502struct.h" #include "x6502struct.h"
extern int scanline;
extern unsigned normal_scanlines;
extern int totalscanlines;
#ifdef FCEUDEF_DEBUGGER #ifdef FCEUDEF_DEBUGGER
void X6502_Debug(void (*CPUHook)(X6502 *), void X6502_Debug(void (*CPUHook)(X6502 *),
uint8 (*ReadHook)(X6502 *, uint32), uint8 (*ReadHook)(X6502 *, uint32),