aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/cpuops.c211
-rw-r--r--source/memmap.c33
2 files changed, 240 insertions, 4 deletions
diff --git a/source/cpuops.c b/source/cpuops.c
index d7f90e6..977f97e 100644
--- a/source/cpuops.c
+++ b/source/cpuops.c
@@ -3424,6 +3424,31 @@ static inline void CPUShutdown()
#define CPUShutdown()
#endif
+// From the speed-hacks branch of CatSFC
+static inline void ForceShutdown()
+{
+#ifdef CPU_SHUTDOWN
+#ifndef SA1_OPCODES
+ CPU.WaitAddress = NULL;
+ if (Settings.SA1)
+ S9xSA1ExecuteDuringSleep ();
+ CPU.Cycles = CPU.NextEvent;
+ if (IAPU.APUExecuting)
+ {
+ ICPU.CPUExecuting = false;
+ do
+ {
+ APU_EXECUTE1();
+ } while (APU.Cycles < CPU.NextEvent);
+ ICPU.CPUExecuting = true;
+ }
+#else
+ SA1.Executing = false;
+ SA1.CPUExecuting = false;
+#endif
+#endif
+}
+
/* BCC */
static void Op90(void)
{
@@ -5008,16 +5033,194 @@ static void OpCB(void)
#endif // SA1_OPCODES
}
-// STP
+// Usually an STP opcode
+// SNESAdvance speed hack, not implemented in Snes9xTYL | Snes9x-Euphoria (from the speed-hacks branch of CatSFC)
static void OpDB(void)
{
- CPU.PC--;
- CPU.Flags |= DEBUG_MODE_FLAG;
+#if !defined NO_SPEEDHACKS && defined CPU_SHUTDOWN
+ uint8_t NextByte = *CPU.PC++;
+
+ ForceShutdown();
+
+ int8_t BranchOffset = (NextByte & 0x7F) | ((NextByte & 0x40) << 1);
+ // ^ -64 .. +63, sign extend bit 6 into 7 for unpacking
+ long TargetAddress = ((int) (CPU.PC - CPU.PCBase) + BranchOffset) & 0xffff;
+
+ switch (NextByte & 0x80)
+ {
+ case 0x00: // BNE
+ BranchCheck1 ();
+ if (!CheckZero ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ case 0x80: // BEQ
+ BranchCheck2 ();
+ if (CheckZero ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ }
+#else
+ CPU.PC--;
+ CPU.Flags |= DEBUG_MODE_FLAG;
+#endif
}
-// Reserved S9xOpcode
+// SNESAdvance speed hack, as implemented in Snes9xTYL / Snes9x-Euphoria (from the speed-hacks branch of CatSFC)
static void Op42(void)
{
+#if !defined NO_SPEEDHACKS && defined CPU_SHUTDOWN
+ uint8_t NextByte = *CPU.PC++;
+
+ ForceShutdown();
+
+ int8_t BranchOffset = 0xF0 | (NextByte & 0xF); // always negative
+ long TargetAddress = ((int) (CPU.PC - CPU.PCBase) + BranchOffset) & 0xffff;
+
+ switch (NextByte & 0xF0)
+ {
+ case 0x10: // BPL
+ BranchCheck1 ();
+ if (!CheckNegative ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ case 0x30: // BMI
+ BranchCheck1 ();
+ if (CheckNegative ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ case 0x50: // BVC
+ BranchCheck0 ();
+ if (!CheckOverflow ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ case 0x70: // BVS
+ BranchCheck0 ();
+ if (CheckOverflow ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ case 0x80: // BRA
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ return;
+ case 0x90: // BCC
+ BranchCheck0 ();
+ if (!CheckCarry ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ case 0xB0: // BCS
+ BranchCheck0 ();
+ if (CheckCarry ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ case 0xD0: // BNE
+ BranchCheck1 ();
+ if (!CheckZero ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ case 0xF0: // BEQ
+ BranchCheck2 ();
+ if (CheckZero ()) {
+ CPU.PC = CPU.PCBase + TargetAddress;
+#ifdef VAR_CYCLES
+ CPU.Cycles += ONE_CYCLE;
+#else
+#ifndef SA1_OPCODES
+ CPU.Cycles++;
+#endif
+#endif
+ CPUShutdown ();
+ }
+ return;
+ }
+#endif
}
/*****************************************************************************/
diff --git a/source/memmap.c b/source/memmap.c
index 1eb9ff9..6dfaaff 100644
--- a/source/memmap.c
+++ b/source/memmap.c
@@ -922,6 +922,39 @@ again:
S9xMessage(S9X_ERROR, S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!");
}
+#ifndef NO_SPEEDHACKS
+ // SNESAdvance speed hacks (from the speed-hacks branch of CatSFC)
+ if (strncmp("YOSHI'S ISLAND", (char *) &Memory.ROM[0x7FC0], 14) == 0)
+ {
+ Memory.ROM[0x0000F4] = 0x42; Memory.ROM[0x0000F5] = 0x3B;
+ }
+ else if (strncmp("SUPER MARIOWORLD", (char *) &Memory.ROM[0x7FC0], 16) == 0)
+ {
+ Memory.ROM[0x00006D] = 0x42;
+ }
+ else if (strncmp("ALL_STARS + WORLD", (char *) &Memory.ROM[0x7FC0], 17) == 0)
+ {
+ Memory.ROM[0x0003D0] = 0x42; Memory.ROM[0x0003D1] = 0x5B;
+ Memory.ROM[0x018522] = 0x42; Memory.ROM[0x018523] = 0x5B;
+ Memory.ROM[0x02C804] = 0x42; Memory.ROM[0x02C805] = 0xBA;
+ Memory.ROM[0x0683B5] = 0x42; Memory.ROM[0x0683B6] = 0x5B;
+ Memory.ROM[0x0696AC] = 0x42; Memory.ROM[0x0696AD] = 0xBA;
+ Memory.ROM[0x089233] = 0xDB; Memory.ROM[0x089234] = 0x61;
+ Memory.ROM[0x0895DF] = 0x42; Memory.ROM[0x0895E0] = 0x5B;
+ Memory.ROM[0x0A7A9D] = 0x42; Memory.ROM[0x0A7A9E] = 0xBA;
+ Memory.ROM[0x1072E7] = 0x42; Memory.ROM[0x1072E8] = 0xD9;
+ Memory.ROM[0x107355] = 0x42; Memory.ROM[0x107356] = 0x5B;
+ Memory.ROM[0x1073CF] = 0x42; Memory.ROM[0x1073D0] = 0x5B;
+ Memory.ROM[0x107443] = 0x42; Memory.ROM[0x107444] = 0x5B;
+ Memory.ROM[0x107498] = 0x42; Memory.ROM[0x107499] = 0x5B;
+ Memory.ROM[0x107505] = 0x42; Memory.ROM[0x107506] = 0x5B;
+ Memory.ROM[0x107539] = 0x42; Memory.ROM[0x10753A] = 0x5B;
+ Memory.ROM[0x107563] = 0x42; Memory.ROM[0x107564] = 0x5B;
+ Memory.ROM[0x1801D4] = 0x42; Memory.ROM[0x1801D5] = 0x10;
+ Memory.ROM[0x18041D] = 0x42; Memory.ROM[0x18041E] = 0x79;
+ }
+#endif
+
int hi_score=ScoreHiROM(true, 0);
int lo_score=ScoreLoROM(true, 0);