Merge pull request #799 from bladeoner/sa1

Backport Reduced version of Vitor's fix for SA1 speed throttle
This commit is contained in:
dborth 2019-01-12 09:30:15 -07:00 committed by GitHub
commit f61ecd0ef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 53 deletions

View File

@ -263,6 +263,9 @@ void S9xDoHEventProcessing (void)
if (Timings.NextIRQTimer != 0x0fffffff) if (Timings.NextIRQTimer != 0x0fffffff)
Timings.NextIRQTimer -= Timings.H_Max; Timings.NextIRQTimer -= Timings.H_Max;
S9xAPUSetReferenceTime(CPU.Cycles); S9xAPUSetReferenceTime(CPU.Cycles);
if (Settings.SA1)
SA1.Cycles -= Timings.H_Max * 3;
CPU.V_Counter++; CPU.V_Counter++;
if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1 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 #ifdef SA1_OPCODES
OpenBus = Memory.FillRAM[0x2208]; OpenBus = Memory.FillRAM[0x2208];
AddCycles(2 * SLOW_ONE_CYCLE); AddCycles(2 * ONE_CYCLE);
S9xSA1SetPCBase(Memory.FillRAM[0x2207] | (Memory.FillRAM[0x2208] << 8)); S9xSA1SetPCBase(Memory.FillRAM[0x2207] | (Memory.FillRAM[0x2208] << 8));
#else #else
if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x40)) if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x40))
{ {
OpenBus = Memory.FillRAM[0x220f]; OpenBus = Memory.FillRAM[0x220f];
AddCycles(2 * SLOW_ONE_CYCLE); AddCycles(2 * ONE_CYCLE);
S9xSetPCBase(Memory.FillRAM[0x220e] | (Memory.FillRAM[0x220f] << 8)); S9xSetPCBase(Memory.FillRAM[0x220e] | (Memory.FillRAM[0x220f] << 8));
} }
else else
@ -2640,13 +2640,13 @@ void S9xOpcode_IRQ (void)
#ifdef SA1_OPCODES #ifdef SA1_OPCODES
OpenBus = Memory.FillRAM[0x2208]; OpenBus = Memory.FillRAM[0x2208];
AddCycles(2 * SLOW_ONE_CYCLE); AddCycles(2 * ONE_CYCLE);
S9xSA1SetPCBase(Memory.FillRAM[0x2207] | (Memory.FillRAM[0x2208] << 8)); S9xSA1SetPCBase(Memory.FillRAM[0x2207] | (Memory.FillRAM[0x2208] << 8));
#else #else
if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x40)) if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x40))
{ {
OpenBus = Memory.FillRAM[0x220f]; OpenBus = Memory.FillRAM[0x220f];
AddCycles(2 * SLOW_ONE_CYCLE); AddCycles(2 * ONE_CYCLE);
S9xSetPCBase(Memory.FillRAM[0x220e] | (Memory.FillRAM[0x220f] << 8)); S9xSetPCBase(Memory.FillRAM[0x220e] | (Memory.FillRAM[0x220f] << 8));
} }
else else
@ -2687,13 +2687,13 @@ void S9xOpcode_NMI (void)
#ifdef SA1_OPCODES #ifdef SA1_OPCODES
OpenBus = Memory.FillRAM[0x2206]; OpenBus = Memory.FillRAM[0x2206];
AddCycles(2 * SLOW_ONE_CYCLE); AddCycles(2 * ONE_CYCLE);
S9xSA1SetPCBase(Memory.FillRAM[0x2205] | (Memory.FillRAM[0x2206] << 8)); S9xSA1SetPCBase(Memory.FillRAM[0x2205] | (Memory.FillRAM[0x2206] << 8));
#else #else
if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x10)) if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x10))
{ {
OpenBus = Memory.FillRAM[0x220d]; OpenBus = Memory.FillRAM[0x220d];
AddCycles(2 * SLOW_ONE_CYCLE); AddCycles(2 * ONE_CYCLE);
S9xSetPCBase(Memory.FillRAM[0x220c] | (Memory.FillRAM[0x220d] << 8)); S9xSetPCBase(Memory.FillRAM[0x220c] | (Memory.FillRAM[0x220d] << 8));
} }
else else
@ -2715,13 +2715,13 @@ void S9xOpcode_NMI (void)
#ifdef SA1_OPCODES #ifdef SA1_OPCODES
OpenBus = Memory.FillRAM[0x2206]; OpenBus = Memory.FillRAM[0x2206];
AddCycles(2 * SLOW_ONE_CYCLE); AddCycles(2 * ONE_CYCLE);
S9xSA1SetPCBase(Memory.FillRAM[0x2205] | (Memory.FillRAM[0x2206] << 8)); S9xSA1SetPCBase(Memory.FillRAM[0x2205] | (Memory.FillRAM[0x2206] << 8));
#else #else
if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x10)) if (Settings.SA1 && (Memory.FillRAM[0x2209] & 0x10))
{ {
OpenBus = Memory.FillRAM[0x220d]; OpenBus = Memory.FillRAM[0x220d];
AddCycles(2 * SLOW_ONE_CYCLE); AddCycles(2 * ONE_CYCLE);
S9xSetPCBase(Memory.FillRAM[0x220c] | (Memory.FillRAM[0x220d] << 8)); S9xSetPCBase(Memory.FillRAM[0x220c] | (Memory.FillRAM[0x220d] << 8));
} }
else else
@ -2780,21 +2780,33 @@ static void Op02 (void)
static void OpDC (void) static void OpDC (void)
{ {
S9xSetPCBase(AbsoluteIndirectLong(JUMP)); S9xSetPCBase(AbsoluteIndirectLong(JUMP));
#ifdef SA1_OPCODES
AddCycles(ONE_CYCLE);
#endif
} }
static void OpDCSlow (void) static void OpDCSlow (void)
{ {
S9xSetPCBase(AbsoluteIndirectLongSlow(JUMP)); S9xSetPCBase(AbsoluteIndirectLongSlow(JUMP));
#ifdef SA1_OPCODES
AddCycles(ONE_CYCLE);
#endif
} }
static void Op5C (void) static void Op5C (void)
{ {
S9xSetPCBase(AbsoluteLong(JUMP)); S9xSetPCBase(AbsoluteLong(JUMP));
#ifdef SA1_OPCODES
AddCycles(ONE_CYCLE);
#endif
} }
static void Op5CSlow (void) static void Op5CSlow (void)
{ {
S9xSetPCBase(AbsoluteLongSlow(JUMP)); S9xSetPCBase(AbsoluteLongSlow(JUMP));
#ifdef SA1_OPCODES
AddCycles(ONE_CYCLE);
#endif
} }
/* JMP ********************************************************************* */ /* JMP ********************************************************************* */

View File

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

View File

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

View File

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

View File

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

View File

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