Add overclocking - backported from FCEUX with mods
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
15
src/ppu.c
15
src/ppu.c
@@ -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) {
|
||||||
|
|||||||
15
src/sound.c
15
src/sound.c
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
Reference in New Issue
Block a user