nes-fiddle around with board irq signal tracking system. break every NES savestate. fix a desync bug in a bunch of mappers

This commit is contained in:
zeromus 2012-06-25 06:32:54 +00:00
parent 690fb786a5
commit 1d254c3705
16 changed files with 50 additions and 49 deletions

View File

@ -39,6 +39,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
byte[] ROM { get; set; } byte[] ROM { get; set; }
byte[] VROM { get; set; } byte[] VROM { get; set; }
void SyncState(Serializer ser); void SyncState(Serializer ser);
bool IRQSignal { get; }
//mixes the board's custom audio into the supplied sample buffer //mixes the board's custom audio into the supplied sample buffer
void ApplyCustomAudio(short[] samples); void ApplyCustomAudio(short[] samples);
@ -74,13 +75,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("vram", ref vram, true); ser.Sync("vram", ref vram, true);
ser.Sync("wram", ref wram, true); ser.Sync("wram", ref wram, true);
for (int i = 0; i < 4; i++) ser.Sync("mirroring" + i, ref mirroring[i]); for (int i = 0; i < 4; i++) ser.Sync("mirroring" + i, ref mirroring[i]);
ser.Sync("irq_signal", ref irq_signal);
} }
public virtual void SyncIRQ(bool flag) public virtual void SyncIRQ(bool flag)
{ {
NES.irq_cart = flag; IRQSignal = flag;
} }
private bool irq_signal;
public bool IRQSignal { get { return irq_signal; } set { irq_signal = value; } }
public virtual void Dispose() { } public virtual void Dispose() { }
int[] mirroring = new int[4]; int[] mirroring = new int[4];

View File

@ -53,11 +53,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_asserted", ref irq_asserted); ser.Sync("irq_asserted", ref irq_asserted);
ser.Sync("clock_counter", ref clock_counter); ser.Sync("clock_counter", ref clock_counter);
if (ser.IsReader) SyncPRG();
{ SyncIrq();
SyncPRG();
SyncIrq();
}
} }
public override void Dispose() public override void Dispose()
@ -169,7 +166,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIrq() void SyncIrq()
{ {
NES.irq_cart = irq_asserted; IRQSignal = irq_asserted;
} }
void ClockCPU() void ClockCPU()

View File

@ -66,12 +66,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("last_nt_read", ref last_nt_read); ser.Sync("last_nt_read", ref last_nt_read);
ser.Sync("EXRAM", ref EXRAM, false); ser.Sync("EXRAM", ref EXRAM, false);
if (ser.IsReader) SyncPRGBanks();
{ SyncCHRBanks();
SyncPRGBanks(); SyncMultiplier();
SyncCHRBanks(); SyncIRQ();
SyncMultiplier();
}
} }
public override void Dispose() public override void Dispose()
@ -451,7 +449,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = (irq_pending && irq_enabled); IRQSignal = (irq_pending && irq_enabled);
} }
public override void ClockPPU() public override void ClockPPU()

View File

@ -40,6 +40,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_counter", ref irq_counter); ser.Sync("irq_counter", ref irq_counter);
ser.Sync("irq_reload", ref irq_reload); ser.Sync("irq_reload", ref irq_reload);
ser.Sync("clock_counter", ref clock_counter); ser.Sync("clock_counter", ref clock_counter);
SyncIRQ();
} }
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
@ -89,7 +90,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = irq_asserted; IRQSignal = irq_asserted;
} }
public override byte ReadPRG(int addr) public override byte ReadPRG(int addr)

View File

@ -74,6 +74,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
public void Sync() public void Sync()
{ {
SyncIRQ();
if (prg_mode) if (prg_mode)
{ {
prg_regs_8k[0] = 0xFE; prg_regs_8k[0] = 0xFE;
@ -138,7 +139,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
Sync(); Sync();
} }
protected virtual void SyncIRQ() //some MMC3 variants pass along the irq signal differently (primarily different delay)
//this is overrideable so that those boards can get signals whenever this mmc3 base class code manipulates the irq line
public virtual void SyncIRQ()
{ {
board.SyncIRQ(irq_pending); board.SyncIRQ(irq_pending);
} }

View File

@ -63,6 +63,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_enabled", ref irq_enabled); ser.Sync("irq_enabled", ref irq_enabled);
ser.Sync("irq_asserted", ref irq_asserted); ser.Sync("irq_asserted", ref irq_asserted);
ser.Sync("clock_counter", ref clock_counter); ser.Sync("clock_counter", ref clock_counter);
SyncIrq();
} }
public override void Dispose() public override void Dispose()
@ -171,7 +172,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIrq() void SyncIrq()
{ {
NES.irq_cart = irq_asserted; IRQSignal = irq_asserted;
} }
void ClockCPU() void ClockCPU()

View File

@ -45,6 +45,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_enabled", ref irq_enabled); ser.Sync("irq_enabled", ref irq_enabled);
ser.Sync("irq_cycles", ref irq_cycles); ser.Sync("irq_cycles", ref irq_cycles);
ser.Sync("irq_pending", ref irq_pending); ser.Sync("irq_pending", ref irq_pending);
SyncIRQ();
} }
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
@ -256,7 +257,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = (irq_pending && irq_enabled); IRQSignal = (irq_pending && irq_enabled);
} }
void TriggerIRQ() void TriggerIRQ()

View File

@ -30,6 +30,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_enable", ref irq_enable); ser.Sync("irq_enable", ref irq_enable);
ser.Sync("irq_asserted", ref irq_asserted); ser.Sync("irq_asserted", ref irq_asserted);
ser.Sync("clock_counter", ref clock_counter); ser.Sync("clock_counter", ref clock_counter);
SyncIRQ();
} }
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
@ -63,7 +64,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = irq_asserted; IRQSignal = irq_asserted;
} }
public override void WritePRG(int addr, byte value) public override void WritePRG(int addr, byte value)

View File

@ -54,8 +54,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_reload_pending", ref irq_reload_pending); ser.Sync("irq_reload_pending", ref irq_reload_pending);
ser.Sync("separator_counter", ref separator_counter); ser.Sync("separator_counter", ref separator_counter);
if (ser.IsReader) Sync();
Sync();
} }
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
@ -83,6 +82,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void Sync() void Sync()
{ {
SyncIRQ();
if (prg_mode) if (prg_mode)
{ {
prg_banks_8k[0] = regs[0xF] & prg_bank_mask_8k; prg_banks_8k[0] = regs[0xF] & prg_bank_mask_8k;
@ -189,7 +190,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
} }
} }
public override byte ReadPRG(int addr) public override byte ReadPRG(int addr)
{ {
int bank_8k = addr >> 13; int bank_8k = addr >> 13;
@ -216,7 +216,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = irq_pending; IRQSignal = irq_pending;
} }
void ClockIRQ() void ClockIRQ()

View File

@ -38,14 +38,14 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.EndSection(); ser.EndSection();
} }
protected override void SyncIRQ() public override void SyncIRQ()
{ {
if (irq_pending && !pending) if (irq_pending && !pending)
delay = 12; //supposed to be 4 cpu clocks delay = 12; //supposed to be 4 cpu clocks
if (!irq_pending) if (!irq_pending)
{ {
delay = 0; delay = 0;
board.NES.irq_cart = false; board.IRQSignal = false;
} }
pending = irq_pending; pending = irq_pending;
} }
@ -58,7 +58,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{ {
delay--; delay--;
if(delay==0) if(delay==0)
board.NES.irq_cart = true; board.IRQSignal = true;
} }
} }
} }

View File

@ -51,11 +51,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_prescaler", ref irq_prescaler); ser.Sync("irq_prescaler", ref irq_prescaler);
ser.Sync("extra_vrom", ref extra_vrom); ser.Sync("extra_vrom", ref extra_vrom);
if (ser.IsReader) SyncPRG();
{ SyncCHR();
SyncPRG(); SyncIRQ();
SyncCHR();
}
} }
void SyncPRG() void SyncPRG()
@ -93,7 +91,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = (irq_pending && irq_enabled); IRQSignal = (irq_pending && irq_enabled);
} }
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)

View File

@ -36,11 +36,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_reload", ref irq_reload); ser.Sync("irq_reload", ref irq_reload);
ser.Sync("irq_counter", ref irq_counter); ser.Sync("irq_counter", ref irq_counter);
ser.Sync("irq_cycles", ref irq_cycles); ser.Sync("irq_cycles", ref irq_cycles);
SyncIRQ();
} }
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = (irq_pending && irq_enabled); IRQSignal = (irq_pending && irq_enabled);
} }
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)

View File

@ -43,10 +43,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_counter", ref irq_counter); ser.Sync("irq_counter", ref irq_counter);
ser.Sync("irq_prescaler", ref irq_prescaler); ser.Sync("irq_prescaler", ref irq_prescaler);
if (ser.IsReader) SyncPRG();
{ SyncIRQ();
SyncPRG();
}
} }
void SyncPRG() void SyncPRG()
@ -59,7 +57,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = (irq_pending && irq_enabled); IRQSignal = (irq_pending && irq_enabled);
} }
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)

View File

@ -43,11 +43,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("irq_reload", ref irq_reload); ser.Sync("irq_reload", ref irq_reload);
ser.Sync("irq_counter", ref irq_counter); ser.Sync("irq_counter", ref irq_counter);
ser.Sync("irq_prescaler", ref irq_prescaler); ser.Sync("irq_prescaler", ref irq_prescaler);
SyncIRQ();
} }
void SyncIRQ() void SyncIRQ()
{ {
NES.irq_cart = (irq_pending && irq_enabled); IRQSignal = (irq_pending && irq_enabled);
} }
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)

View File

@ -24,15 +24,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo
INESBoard board; //the board hardware that is currently driving things INESBoard board; //the board hardware that is currently driving things
public bool SoundOn = true; public bool SoundOn = true;
int sprdma_countdown; //used to int sprdma_countdown; //used to
bool _irq_apu, _irq_cart; //various irq signals that get merged to the cpu irq pin bool _irq_apu; //various irq signals that get merged to the cpu irq pin
//irq state management //irq state management
public bool irq_apu { get { return _irq_apu; } set { _irq_apu = value; sync_irq(); } } public bool irq_apu { get { return _irq_apu; } set { _irq_apu = value; } }
public bool irq_cart { get { return _irq_cart; } set { _irq_cart = value; sync_irq(); } }
void sync_irq()
{
cpu.IRQ = _irq_apu || _irq_cart;
}
//user configuration //user configuration
int[,] palette = new int[64,3]; int[,] palette = new int[64,3];
@ -119,10 +114,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo
} }
} }
if(cpu_deadcounter>0) if (cpu_deadcounter > 0)
cpu_deadcounter--; cpu_deadcounter--;
else else
{
cpu.IRQ = _irq_apu || board.IRQSignal;
cpu.ExecuteOne(); cpu.ExecuteOne();
}
if (SoundOn) apu.RunOne(); //THIS ISNT SAFE!!!!!!!!! SOUND MUST ALWAYS RUN!!!! if (SoundOn) apu.RunOne(); //THIS ISNT SAFE!!!!!!!!! SOUND MUST ALWAYS RUN!!!!
ppu.PostCpuInstructionOne(); ppu.PostCpuInstructionOne();

View File

@ -590,12 +590,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ser.Sync("CIRAM", ref CIRAM, false); ser.Sync("CIRAM", ref CIRAM, false);
ser.Sync("cpu_accumulate", ref cpu_accumulate); ser.Sync("cpu_accumulate", ref cpu_accumulate);
ser.Sync("_irq_apu", ref _irq_apu); ser.Sync("_irq_apu", ref _irq_apu);
ser.Sync("_irq_cart", ref _irq_cart);
ser.Sync("sprdma_countdown", ref sprdma_countdown); ser.Sync("sprdma_countdown", ref sprdma_countdown);
ser.Sync("cpu_step", ref cpu_step); ser.Sync("cpu_step", ref cpu_step);
ser.Sync("cpu_stepcounter", ref cpu_stepcounter); ser.Sync("cpu_stepcounter", ref cpu_stepcounter);
ser.Sync("cpu_deadcounter", ref cpu_deadcounter); ser.Sync("cpu_deadcounter", ref cpu_deadcounter);
sync_irq();
board.SyncState(ser); board.SyncState(ser);
ppu.SyncState(ser); ppu.SyncState(ser);
apu.SyncState(ser); apu.SyncState(ser);