Backport Reduced version of Vitor's fix for SA1 speed throttle

This commit is contained in:
bladeoner 2019-01-10 22:10:18 +01:00 committed by Etienne Haarsma
parent 5517ec7567
commit 5ddfffd8fe
7 changed files with 77 additions and 53 deletions

View File

@ -263,6 +263,9 @@ void S9xDoHEventProcessing (void)
if (Timings.NextIRQTimer != 0x0fffffff)
Timings.NextIRQTimer -= Timings.H_Max;
S9xAPUSetReferenceTime(CPU.Cycles);
if (Settings.SA1)
SA1.Cycles -= Timings.H_Max * 3;
CPU.V_Counter++;
if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1

View File

@ -2612,13 +2612,13 @@ void S9xOpcode_IRQ (void)
#ifdef SA1_OPCODES
OpenBus = Memory.FillRAM[0x2208];
AddCycles(2 * SLOW_ONE_CYCLE);
AddCycles(2 * ONE_CYCLE);
S9xSA1SetPCBase(Memory.FillRAM[0x2207] | (Memory.FillRAM[0x2208] << 8));
#else
if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x40))
{
OpenBus = Memory.FillRAM[0x220f];
AddCycles(2 * SLOW_ONE_CYCLE);
AddCycles(2 * ONE_CYCLE);
S9xSetPCBase(Memory.FillRAM[0x220e] | (Memory.FillRAM[0x220f] << 8));
}
else
@ -2640,13 +2640,13 @@ void S9xOpcode_IRQ (void)
#ifdef SA1_OPCODES
OpenBus = Memory.FillRAM[0x2208];
AddCycles(2 * SLOW_ONE_CYCLE);
AddCycles(2 * ONE_CYCLE);
S9xSA1SetPCBase(Memory.FillRAM[0x2207] | (Memory.FillRAM[0x2208] << 8));
#else
if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x40))
{
OpenBus = Memory.FillRAM[0x220f];
AddCycles(2 * SLOW_ONE_CYCLE);
AddCycles(2 * ONE_CYCLE);
S9xSetPCBase(Memory.FillRAM[0x220e] | (Memory.FillRAM[0x220f] << 8));
}
else
@ -2687,13 +2687,13 @@ void S9xOpcode_NMI (void)
#ifdef SA1_OPCODES
OpenBus = Memory.FillRAM[0x2206];
AddCycles(2 * SLOW_ONE_CYCLE);
AddCycles(2 * ONE_CYCLE);
S9xSA1SetPCBase(Memory.FillRAM[0x2205] | (Memory.FillRAM[0x2206] << 8));
#else
if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x10))
{
OpenBus = Memory.FillRAM[0x220d];
AddCycles(2 * SLOW_ONE_CYCLE);
AddCycles(2 * ONE_CYCLE);
S9xSetPCBase(Memory.FillRAM[0x220c] | (Memory.FillRAM[0x220d] << 8));
}
else
@ -2715,13 +2715,13 @@ void S9xOpcode_NMI (void)
#ifdef SA1_OPCODES
OpenBus = Memory.FillRAM[0x2206];
AddCycles(2 * SLOW_ONE_CYCLE);
AddCycles(2 * ONE_CYCLE);
S9xSA1SetPCBase(Memory.FillRAM[0x2205] | (Memory.FillRAM[0x2206] << 8));
#else
if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x10))
{
OpenBus = Memory.FillRAM[0x220d];
AddCycles(2 * SLOW_ONE_CYCLE);
AddCycles(2 * ONE_CYCLE);
S9xSetPCBase(Memory.FillRAM[0x220c] | (Memory.FillRAM[0x220d] << 8));
}
else
@ -2780,21 +2780,33 @@ static void Op02 (void)
static void OpDC (void)
{
S9xSetPCBase(AbsoluteIndirectLong(JUMP));
#ifdef SA1_OPCODES
AddCycles(ONE_CYCLE);
#endif
}
static void OpDCSlow (void)
{
S9xSetPCBase(AbsoluteIndirectLongSlow(JUMP));
#ifdef SA1_OPCODES
AddCycles(ONE_CYCLE);
#endif
}
static void Op5C (void)
{
S9xSetPCBase(AbsoluteLong(JUMP));
#ifdef SA1_OPCODES
AddCycles(ONE_CYCLE);
#endif
}
static void Op5CSlow (void)
{
S9xSetPCBase(AbsoluteLongSlow(JUMP));
#ifdef SA1_OPCODES
AddCycles(ONE_CYCLE);
#endif
}
/* JMP ********************************************************************* */

View File

@ -3156,13 +3156,13 @@ void CMemory::Map_SA1LoROMMap (void)
map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0);
map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM);
map_space(0x80, 0xbf, 0x3000, 0x3fff, FillRAM);
map_space(0x00, 0x3f, 0x3000, 0x37ff, FillRAM);
map_space(0x80, 0xbf, 0x3000, 0x37ff, FillRAM);
map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O);
map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O);
for (int c = 0x40; c < 0x80; c++)
map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000);
for (int c = 0x40; c < 0x4f; c++)
map_space(c, c, 0x0000, 0xffff, SRAM + (c & 3) * 0x10000);
map_WRAM();
@ -3180,6 +3180,10 @@ void CMemory::Map_SA1LoROMMap (void)
SA1.WriteMap[c + 0] = SA1.WriteMap[c + 0x800] = FillRAM + 0x3000;
SA1.WriteMap[c + 1] = SA1.WriteMap[c + 0x801] = (uint8 *) MAP_NONE;
}
// SA-1 Banks 40->4f
for (int c = 0x400; c < 0x500; c++)
SA1.Map[c] = SA1.WriteMap[c] = (uint8*)MAP_HIROM_SRAM;
// SA-1 Banks 60->6f
for (int c = 0x600; c < 0x700; c++)
@ -3696,13 +3700,6 @@ void CMemory::ApplyROMFixes (void)
match_id ("A35") || // Mechwarrior 3050 / Battle Tech 3050
match_na ("DOOM TROOPERS")) // Doom Troopers
Timings.APUAllowTimeOverflow = TRUE;
if (match_id("AKFJ") || match_id("AKFE")) { // Hoshi no Kirby / Kirby Super Star
Timings.SA1Cycles = 5;
}
else {
Timings.SA1Cycles = 3;
}
#endif
}

View File

@ -63,8 +63,8 @@ void S9xSA1Init (void)
SA1SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
SA1ClearFlags(Decimal);
SA1.MemSpeed = SLOW_ONE_CYCLE;
SA1.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
SA1.MemSpeed = ONE_CYCLE;
SA1.MemSpeedx2 = ONE_CYCLE * 2;
SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
SA1.S9xOpLengths = S9xOpLengthsM1X1;
@ -103,7 +103,7 @@ static void S9xSA1SetBWRAMMemMap (uint8 val)
SA1.WriteMap[c + 7] = SA1.WriteMap[c + 0x807] = (uint8 *) CMemory::MAP_BWRAM;
}
SA1.BWRAM = Memory.SRAM + (val & 7) * 0x2000;
SA1.BWRAM = Memory.SRAM + (val & 0x1f) * 0x2000;
}
}
@ -116,7 +116,7 @@ void S9xSA1PostLoadState (void)
S9xSA1UnpackStatus();
S9xSA1FixCycles();
SA1.VirtualBitmapFormat = (Memory.FillRAM[0x223f] & 0x80) ? 2 : 4;
Memory.BWRAM = Memory.SRAM + (Memory.FillRAM[0x2224] & 7) * 0x2000;
Memory.BWRAM = Memory.SRAM + (Memory.FillRAM[0x2224] & 0x1f) * 0x2000;
S9xSA1SetBWRAMMemMap(Memory.FillRAM[0x2225]);
S9xSetSA1(Memory.FillRAM[0x2220], 0x2220);
S9xSetSA1(Memory.FillRAM[0x2221], 0x2221);
@ -232,7 +232,7 @@ uint8 S9xGetSA1 (uint32 address)
}
case 0x230e: // version code register
return (0x01);
return (0x23);
default:
break;
@ -419,7 +419,7 @@ void S9xSetSA1 (uint8 byte, uint32 address)
break;
case 0x2224: // S-CPU BW-RAM mapping
Memory.BWRAM = Memory.SRAM + (byte & 7) * 0x2000;
Memory.BWRAM = Memory.SRAM + (byte & 0x1f) * 0x2000;
break;
case 0x2225: // SA-1 BW-RAM mapping
@ -760,36 +760,48 @@ uint8 S9xSA1GetByte (uint32 address)
{
uint8 *GetAddress = SA1.Map[(address & 0xffffff) >> MEMMAP_SHIFT];
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
if (GetAddress >= (uint8 *)CMemory::MAP_LAST)
{
SA1.Cycles += SA1.MemSpeed;
return (*(GetAddress + (address & 0xffff)));
}
switch ((pint) GetAddress)
{
case CMemory::MAP_PPU:
SA1.Cycles += ONE_CYCLE;
return (S9xGetSA1(address & 0xffff));
case CMemory::MAP_LOROM_SRAM:
case CMemory::MAP_HIROM_SRAM:
case CMemory::MAP_SA1RAM:
return (*(Memory.SRAM + (address & 0xffff)));
SA1.Cycles += ONE_CYCLE * 2;
return (*(Memory.SRAM + (address & 0x3ffff)));
case CMemory::MAP_BWRAM:
return (*(SA1.BWRAM + ((address & 0x7fff) - 0x6000)));
SA1.Cycles += ONE_CYCLE * 2;
return (*(SA1.BWRAM + (address & 0x1fff)));
case CMemory::MAP_BWRAM_BITMAP:
SA1.Cycles += ONE_CYCLE * 2;
address -= 0x600000;
if (SA1.VirtualBitmapFormat == 2)
return ((Memory.SRAM[(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3);
return ((Memory.SRAM[(address >> 2) & 0x3ffff] >> ((address & 3) << 1)) & 3);
else
return ((Memory.SRAM[(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15);
return ((Memory.SRAM[(address >> 1) & 0x3ffff] >> ((address & 1) << 2)) & 15);
case CMemory::MAP_BWRAM_BITMAP2:
SA1.Cycles += ONE_CYCLE * 2;
address = (address & 0xffff) - 0x6000;
if (SA1.VirtualBitmapFormat == 2)
return ((SA1.BWRAM[(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3);
return ((SA1.BWRAM[(address >> 2) & 0x3ffff] >> ((address & 3) << 1)) & 3);
else
return ((SA1.BWRAM[(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15);
return ((SA1.BWRAM[(address >> 1) & 0x3ffff] >> ((address & 1) << 2)) & 15);
default:
SA1.Cycles += ONE_CYCLE;
return (SA1OpenBus);
}
}
@ -835,25 +847,26 @@ void S9xSA1SetByte (uint8 byte, uint32 address)
return;
case CMemory::MAP_LOROM_SRAM:
case CMemory::MAP_HIROM_SRAM:
case CMemory::MAP_SA1RAM:
*(Memory.SRAM + (address & 0xffff)) = byte;
*(Memory.SRAM + (address & 0x3ffff)) = byte;
return;
case CMemory::MAP_BWRAM:
*(SA1.BWRAM + ((address & 0x7fff) - 0x6000)) = byte;
*(SA1.BWRAM + (address & 0x1fff)) = byte;
return;
case CMemory::MAP_BWRAM_BITMAP:
address -= 0x600000;
if (SA1.VirtualBitmapFormat == 2)
{
uint8 *ptr = &Memory.SRAM[(address >> 2) & 0xffff];
uint8 *ptr = &Memory.SRAM[(address >> 2) & 0x3ffff];
*ptr &= ~(3 << ((address & 3) << 1));
*ptr |= (byte & 3) << ((address & 3) << 1);
}
else
{
uint8 *ptr = &Memory.SRAM[(address >> 1) & 0xffff];
uint8 *ptr = &Memory.SRAM[(address >> 1) & 0x3ffff];
*ptr &= ~(15 << ((address & 1) << 2));
*ptr |= (byte & 15) << ((address & 1) << 2);
}
@ -864,13 +877,13 @@ void S9xSA1SetByte (uint8 byte, uint32 address)
address = (address & 0xffff) - 0x6000;
if (SA1.VirtualBitmapFormat == 2)
{
uint8 *ptr = &SA1.BWRAM[(address >> 2) & 0xffff];
uint8 *ptr = &SA1.BWRAM[(address >> 2) & 0x3ffff];
*ptr &= ~(3 << ((address & 3) << 1));
*ptr |= (byte & 3) << ((address & 3) << 1);
}
else
{
uint8 *ptr = &SA1.BWRAM[(address >> 1) & 0xffff];
uint8 *ptr = &SA1.BWRAM[(address >> 1) & 0x3ffff];
*ptr &= ~(15 << ((address & 1) << 2));
*ptr |= (byte & 15) << ((address & 1) << 2);
}
@ -919,7 +932,12 @@ void S9xSA1SetPCBase (uint32 address)
SA1.ShiftedPB = address & 0xff0000;
// FIXME
SA1.MemSpeed = memory_speed(address);
SA1.MemSpeed = ONE_CYCLE;
if ((address & 0xc00000) == 0x400000 || (address & 0x40e000) == 0x6000)
{
SA1.MemSpeed = TWO_CYCLES;
}
SA1.MemSpeedx2 = SA1.MemSpeed << 1;
uint8 *GetAddress = SA1.Map[(address & 0xffffff) >> MEMMAP_SHIFT];

View File

@ -126,12 +126,11 @@ void S9xSA1MainLoop (void)
S9xSA1Opcode_IRQ();
}
}
#ifdef GEKKO
for (int i = 0; i < Timings.SA1Cycles && !(Memory.FillRAM[0x2200] & 0x60); i++)
#else
for (int i = 0; i < 5 && !(Memory.FillRAM[0x2200] & 0x60); i++)
#endif
#undef CPU
int cycles = CPU.Cycles * 3;
#define CPU SA1
for (; SA1.Cycles < cycles && !(Memory.FillRAM[0x2200] & 0x60);)
{
#ifdef DEBUGGER
if (SA1.Flags & TRACE_FLAG)
@ -145,6 +144,7 @@ void S9xSA1MainLoop (void)
{
SA1OpenBus = Op = SA1.PCBase[Registers.PCw];
Opcodes = SA1.S9xOpcodes;
SA1.Cycles += SA1.MemSpeed;
}
else
{
@ -194,9 +194,6 @@ static void S9xSA1UpdateTimer (void) // FIXME
}
}
if (SA1.Cycles >= Timings.H_Max_Master)
SA1.Cycles -= Timings.H_Max_Master;
SA1.PrevCycles = SA1.Cycles;
bool8 thisIRQ = Memory.FillRAM[0x2210] & 0x03;

View File

@ -1634,8 +1634,8 @@ int S9xUnfreezeFromStream (STREAM stream)
SA1.HCounter = 0;
SA1.VCounter = 0;
SA1.PrevHCounter = 0;
SA1.MemSpeed = SLOW_ONE_CYCLE;
SA1.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
SA1.MemSpeed = ONE_CYCLE;
SA1.MemSpeedx2 = ONE_CYCLE * 2;
}
}

View File

@ -184,9 +184,6 @@ struct STimings
int32 IRQFlagChanging; // This value is just a hack.
int32 APUSpeedup;
bool8 APUAllowTimeOverflow;
#ifdef GEKKO
int32 SA1Cycles;
#endif
};
struct SSettings