Different IRQ handling.
This commit is contained in:
parent
aaae363257
commit
f6864c422f
3
cpu.cpp
3
cpu.cpp
@ -229,8 +229,6 @@ static void S9xSoftResetCPU (void)
|
||||
CPU.PCBase = NULL;
|
||||
CPU.NMIPending = FALSE;
|
||||
CPU.IRQLine = FALSE;
|
||||
CPU.IRQTransition = FALSE;
|
||||
CPU.IRQLastState = FALSE;
|
||||
CPU.IRQExternal = FALSE;
|
||||
CPU.IRQPending = Timings.IRQPendCount;
|
||||
CPU.MemSpeed = SLOW_ONE_CYCLE;
|
||||
@ -268,6 +266,7 @@ static void S9xSoftResetCPU (void)
|
||||
Timings.H_Max = Timings.H_Max_Master;
|
||||
Timings.V_Max = Timings.V_Max_Master;
|
||||
Timings.NMITriggerPos = 0xffff;
|
||||
Timings.NextTimer = 0xffff;
|
||||
if (Model->_5A22 == 2)
|
||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2;
|
||||
else
|
||||
|
11
cpuexec.cpp
11
cpuexec.cpp
@ -229,7 +229,7 @@ void S9xMainLoop (void)
|
||||
}
|
||||
}
|
||||
|
||||
if (CPU.IRQTransition || CPU.IRQExternal)
|
||||
if (CPU.Cycles >= Timings.NextTimer || CPU.IRQExternal)
|
||||
{
|
||||
if (CPU.IRQPending)
|
||||
CPU.IRQPending--;
|
||||
@ -241,7 +241,7 @@ void S9xMainLoop (void)
|
||||
Registers.PCw++;
|
||||
}
|
||||
|
||||
CPU.IRQTransition = FALSE;
|
||||
S9xUpdateIRQPositions();
|
||||
CPU.IRQPending = Timings.IRQPendCount;
|
||||
|
||||
if (!CheckFlag(IRQ))
|
||||
@ -288,9 +288,7 @@ void S9xMainLoop (void)
|
||||
if (CPU.PCBase)
|
||||
{
|
||||
Op = CPU.PCBase[Registers.PCw];
|
||||
CPU.PrevCycles = CPU.Cycles;
|
||||
CPU.Cycles += CPU.MemSpeed;
|
||||
S9xCheckInterrupts();
|
||||
Opcodes = ICPU.S9xOpcodes;
|
||||
}
|
||||
else
|
||||
@ -414,9 +412,10 @@ void S9xDoHEventProcessing (void)
|
||||
|
||||
S9xAPUEndScanline();
|
||||
CPU.Cycles -= Timings.H_Max;
|
||||
CPU.PrevCycles -= Timings.H_Max;
|
||||
if (Timings.NMITriggerPos != 0xffff)
|
||||
Timings.NMITriggerPos -= Timings.H_Max;
|
||||
if (Timings.NextTimer != 0xffff)
|
||||
Timings.NextTimer -= Timings.H_Max;
|
||||
S9xAPUSetReferenceTime(CPU.Cycles);
|
||||
|
||||
CPU.V_Counter++;
|
||||
@ -557,9 +556,7 @@ void S9xDoHEventProcessing (void)
|
||||
S9xTraceFormattedMessage("*** WRAM Refresh HC:%04d", CPU.Cycles);
|
||||
#endif
|
||||
|
||||
CPU.PrevCycles = CPU.Cycles;
|
||||
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
|
||||
S9xCheckInterrupts();
|
||||
|
||||
S9xReschedule();
|
||||
|
||||
|
42
cpuexec.h
42
cpuexec.h
@ -287,46 +287,4 @@ static inline void S9xFixCycles (void)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void S9xCheckInterrupts (void)
|
||||
{
|
||||
bool8 thisIRQ = PPU.HTimerEnabled | PPU.VTimerEnabled;
|
||||
|
||||
if (CPU.IRQLine & thisIRQ)
|
||||
CPU.IRQTransition = TRUE;
|
||||
|
||||
if (PPU.HTimerEnabled)
|
||||
{
|
||||
int32 htimepos = PPU.HTimerPosition;
|
||||
if ((CPU.Cycles >= Timings.H_Max) & (htimepos < CPU.PrevCycles))
|
||||
htimepos += Timings.H_Max;
|
||||
|
||||
if ((CPU.PrevCycles >= htimepos) | (CPU.Cycles < htimepos))
|
||||
thisIRQ = FALSE;
|
||||
}
|
||||
|
||||
if (PPU.VTimerEnabled)
|
||||
{
|
||||
int32 vcounter = CPU.V_Counter;
|
||||
if ((CPU.Cycles >= Timings.H_Max) & ((!PPU.HTimerEnabled) | (PPU.HTimerPosition < CPU.PrevCycles))) {
|
||||
vcounter++;
|
||||
if(vcounter >= Timings.V_Max)
|
||||
vcounter = 0;
|
||||
}
|
||||
|
||||
if (vcounter != PPU.VTimerPosition)
|
||||
thisIRQ = FALSE;
|
||||
}
|
||||
|
||||
if ((!CPU.IRQLastState) & thisIRQ)
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceFormattedMessage("--- /IRQ High->Low prev HC:%04d curr HC:%04d HTimer:%d Pos:%04d VTimer:%d Pos:%03d",
|
||||
CPU.PrevCycles, CPU.Cycles, PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition);
|
||||
#endif
|
||||
CPU.IRQLine = TRUE;
|
||||
}
|
||||
|
||||
CPU.IRQLastState = thisIRQ;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -205,7 +205,7 @@
|
||||
#ifdef SA1_OPCODES
|
||||
#define AddCycles(n) { SA1.Cycles += (n); }
|
||||
#else
|
||||
#define AddCycles(n) { CPU.PrevCycles = CPU.Cycles; CPU.Cycles += (n); S9xCheckInterrupts(); while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); }
|
||||
#define AddCycles(n) { CPU.Cycles += (n); while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); }
|
||||
#endif
|
||||
|
||||
#include "cpuaddr.h"
|
||||
|
2
dma.cpp
2
dma.cpp
@ -200,7 +200,7 @@
|
||||
#include "missing.h"
|
||||
#endif
|
||||
|
||||
#define ADD_CYCLES(n) { CPU.PrevCycles = CPU.Cycles; CPU.Cycles += (n); S9xCheckInterrupts(); }
|
||||
#define ADD_CYCLES(n) { CPU.Cycles += (n); }
|
||||
|
||||
extern uint8 *HDMAMemPointers[8];
|
||||
extern int HDMA_ModeByteCounts[8];
|
||||
|
4
getset.h
4
getset.h
@ -206,9 +206,7 @@
|
||||
#define addCyclesInMemoryAccess \
|
||||
if (!CPU.InDMAorHDMA) \
|
||||
{ \
|
||||
CPU.PrevCycles = CPU.Cycles; \
|
||||
CPU.Cycles += speed; \
|
||||
S9xCheckInterrupts(); \
|
||||
while (CPU.Cycles >= CPU.NextEvent) \
|
||||
S9xDoHEventProcessing(); \
|
||||
}
|
||||
@ -216,9 +214,7 @@
|
||||
#define addCyclesInMemoryAccess_x2 \
|
||||
if (!CPU.InDMAorHDMA) \
|
||||
{ \
|
||||
CPU.PrevCycles = CPU.Cycles; \
|
||||
CPU.Cycles += speed << 1; \
|
||||
S9xCheckInterrupts(); \
|
||||
while (CPU.Cycles >= CPU.NextEvent) \
|
||||
S9xDoHEventProcessing(); \
|
||||
}
|
||||
|
72
ppu.cpp
72
ppu.cpp
@ -269,7 +269,43 @@ static inline void S9xTryGunLatch (bool force)
|
||||
}
|
||||
}
|
||||
|
||||
void S9xUpdateHVTimerPosition (void)
|
||||
static int CyclesUntilNext (int hc, int vc)
|
||||
{
|
||||
int32 total = 0;
|
||||
int vpos = CPU.V_Counter;
|
||||
|
||||
// Advance to next hc
|
||||
total = (hc - CPU.Cycles);
|
||||
if (total < 0)
|
||||
{
|
||||
total += Timings.H_Max;
|
||||
vpos++;
|
||||
}
|
||||
|
||||
if (vc - vpos >= 0)
|
||||
{
|
||||
// It's still in this frame */
|
||||
// Add number of lines
|
||||
total += (vc - vpos) * Timings.H_Max;
|
||||
// If line 240 is in there and we're odd, subtract a dot
|
||||
if (vpos <= 240 && vc > 240 && Timings.InterlaceField)
|
||||
total -= ONE_DOT_CYCLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
total += (Timings.V_Max - vpos) * Timings.H_Max;
|
||||
if (vpos <= 240 && Timings.InterlaceField)
|
||||
total -= ONE_DOT_CYCLE;
|
||||
|
||||
total += (vc) * Timings.H_Max;
|
||||
if (vc > 240 && !Timings.InterlaceField)
|
||||
total -= ONE_DOT_CYCLE;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void S9xUpdateIRQPositions (void)
|
||||
{
|
||||
PPU.HTimerPosition = PPU.IRQHBeamPos * ONE_DOT_CYCLE + Timings.IRQTriggerCycles;
|
||||
if (Timings.H_Max == Timings.H_Max_Master) // 1364
|
||||
@ -291,6 +327,16 @@ void S9xUpdateHVTimerPosition (void)
|
||||
PPU.VTimerPosition = 0;
|
||||
}
|
||||
|
||||
if (!PPU.HTimerEnabled && !PPU.VTimerEnabled)
|
||||
{
|
||||
Timings.NextTimer = 0xffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
Timings.NextTimer =
|
||||
CyclesUntilNext (PPU.HTimerEnabled ? PPU.HTimerPosition : 0,
|
||||
PPU.VTimerEnabled ? PPU.VTimerPosition : 0);
|
||||
}
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceFormattedMessage("--- IRQ Timer set HTimer:%d Pos:%04d VTimer:%d Pos:%03d",
|
||||
PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition);
|
||||
@ -1502,14 +1548,10 @@ void S9xSetCPU (uint8 Byte, uint16 Address)
|
||||
else
|
||||
PPU.HTimerEnabled = FALSE;
|
||||
|
||||
if (CPU.IRQLine && !PPU.HTimerEnabled && PPU.VTimerEnabled)
|
||||
CPU.IRQTransition = TRUE;
|
||||
|
||||
if (!PPU.HTimerEnabled && !PPU.VTimerEnabled)
|
||||
{
|
||||
if (!(Byte & 0x10) && !(Byte & 0x20))
|
||||
CPU.IRQLine = FALSE;
|
||||
CPU.IRQTransition = FALSE;
|
||||
}
|
||||
|
||||
S9xUpdateIRQPositions();
|
||||
|
||||
// NMI can trigger immediately during VBlank as long as NMI_read ($4210) wasn't cleard.
|
||||
if ((Byte & 0x80) && !(Memory.FillRAM[0x4200] & 0x80) &&
|
||||
@ -1576,7 +1618,7 @@ if (Settings.TraceHCEvent)
|
||||
pos = PPU.IRQHBeamPos;
|
||||
PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff00) | Byte;
|
||||
if (PPU.IRQHBeamPos != pos)
|
||||
S9xUpdateHVTimerPosition();
|
||||
S9xUpdateIRQPositions();
|
||||
#ifdef DEBUGGER
|
||||
missing.hirq_pos = PPU.IRQHBeamPos;
|
||||
#endif
|
||||
@ -1586,7 +1628,7 @@ if (Settings.TraceHCEvent)
|
||||
pos = PPU.IRQHBeamPos;
|
||||
PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff) | ((Byte & 1) << 8);
|
||||
if (PPU.IRQHBeamPos != pos)
|
||||
S9xUpdateHVTimerPosition();
|
||||
S9xUpdateIRQPositions();
|
||||
#ifdef DEBUGGER
|
||||
missing.hirq_pos = PPU.IRQHBeamPos;
|
||||
#endif
|
||||
@ -1596,7 +1638,7 @@ if (Settings.TraceHCEvent)
|
||||
pos = PPU.IRQVBeamPos;
|
||||
PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff00) | Byte;
|
||||
if (PPU.IRQVBeamPos != pos)
|
||||
S9xUpdateHVTimerPosition();
|
||||
S9xUpdateIRQPositions();
|
||||
#ifdef DEBUGGER
|
||||
missing.virq_pos = PPU.IRQVBeamPos;
|
||||
#endif
|
||||
@ -1606,7 +1648,7 @@ if (Settings.TraceHCEvent)
|
||||
pos = PPU.IRQVBeamPos;
|
||||
PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff) | ((Byte & 1) << 8);
|
||||
if (PPU.IRQVBeamPos != pos)
|
||||
S9xUpdateHVTimerPosition();
|
||||
S9xUpdateIRQPositions();
|
||||
#ifdef DEBUGGER
|
||||
missing.virq_pos = PPU.IRQVBeamPos;
|
||||
#endif
|
||||
@ -1617,9 +1659,7 @@ if (Settings.TraceHCEvent)
|
||||
return;
|
||||
// XXX: Not quite right...
|
||||
if (Byte) {
|
||||
CPU.PrevCycles = CPU.Cycles;
|
||||
CPU.Cycles += Timings.DMACPUSync;
|
||||
S9xCheckInterrupts();
|
||||
CPU.Cycles += Timings.DMACPUSync;
|
||||
}
|
||||
if (Byte & 0x01)
|
||||
S9xDoDMA(0);
|
||||
@ -1795,7 +1835,7 @@ uint8 S9xGetCPU (uint16 Address)
|
||||
case 0x4211: // TIMEUP
|
||||
byte = CPU.IRQLine ? 0x80 : 0;
|
||||
CPU.IRQLine = FALSE;
|
||||
CPU.IRQTransition = FALSE;
|
||||
S9xUpdateIRQPositions();
|
||||
|
||||
return (byte | (OpenBus & 0x7f));
|
||||
|
||||
|
2
ppu.h
2
ppu.h
@ -389,7 +389,7 @@ void S9xSetPPU (uint8, uint16);
|
||||
uint8 S9xGetPPU (uint16);
|
||||
void S9xSetCPU (uint8, uint16);
|
||||
uint8 S9xGetCPU (uint16);
|
||||
void S9xUpdateHVTimerPosition (void);
|
||||
void S9xUpdateIRQPositions (void);
|
||||
void S9xFixColourBrightness (void);
|
||||
void S9xDoAutoJoypad (void);
|
||||
|
||||
|
@ -1780,6 +1780,7 @@ int S9xUnfreezeFromStream (STREAM stream)
|
||||
ICPU.ShiftedDB = Registers.DB << 16;
|
||||
S9xSetPCBase(Registers.PBPC);
|
||||
S9xUnpackStatus();
|
||||
S9xUpdateIRQPositions();
|
||||
S9xFixCycles();
|
||||
|
||||
for (int d = 0; d < 8; d++)
|
||||
|
Loading…
Reference in New Issue
Block a user