diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs index df85cb3d6a..49f8aacd65 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs @@ -17,13 +17,38 @@ namespace BizHawk.Emulation.Consoles.Nintendo public PPU ppu; public APU apu; byte[] ram; - MemoryDomain.FreezeData[] sysbus_freeze = new MemoryDomain.FreezeData[65536]; NESWatch[] sysbus_watch = new NESWatch[65536]; public byte[] CIRAM; //AKA nametables string game_name; //friendly name exposed to user and used as filename base CartInfo cart; //the current cart prototype. should be moved into the board, perhaps INESBoard board; //the board hardware that is currently driving things + private struct FreezeRecord + { + public int Address; + public MemoryDomain.FreezeData Data; + } + List sysbus_freeze_list = new List(); + List ppubus_freeze_list = new List(); + + MemoryDomain.FreezeData GetFreeze(List list, int addr) + { + int index = list.FindIndex((fd) => fd.Address == addr); + if (index == -1) return MemoryDomain.FreezeData.Empty; + return list[index].Data; + } + + void SetFreeze(List list, int addr, MemoryDomain.FreezeData data) + { + int index = list.FindIndex((fd) => fd.Address == addr); + if (index != -1) list.RemoveAt(index); + if(!data.IsFrozen) return; + FreezeRecord fr = new FreezeRecord(); + fr.Data = data; + fr.Address = addr; + list.Add(fr); + } + bool _irq_apu, _irq_cart; public bool irq_apu { get { return _irq_apu; } set { _irq_apu = value; sync_irq(); } } public bool irq_cart { get { return _irq_cart; } set { _irq_cart = value; sync_irq(); } } @@ -239,9 +264,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo else if (addr < 0x8000) ret = board.ReadWRAM(addr - 0x6000); else ret = board.ReadPRG(addr - 0x8000); - //apply freeze - if (sysbus_freeze[addr].IsFrozen) ret = sysbus_freeze[addr].value; - //handle breakpoints and stuff. //the idea is that each core can implement its own watch class on an address which will track all the different kinds of monitors and breakpoints and etc. //but since freeze is a common case, it was implemented through its own mechanisms diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs index cefb6f5588..acb0cac5f5 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs @@ -291,14 +291,14 @@ namespace BizHawk.Emulation.Consoles.Nintendo var CIRAMdomain = new MemoryDomain("CIRAM (nametables)", 0x800, Endian.Little, addr => CIRAM[addr & 0x07FF], (addr, value) => CIRAM[addr & 0x07FF] = value); - SystemBus.GetFreeze = addr => sysbus_freeze[addr]; - SystemBus.SetFreeze = (addr, value) => sysbus_freeze[addr] = value; + SystemBus.GetFreeze = addr => GetFreeze(sysbus_freeze_list, addr); + SystemBus.SetFreeze = (addr, value) => SetFreeze(sysbus_freeze_list, addr, value); - RAM.GetFreeze = addr => sysbus_freeze[addr & 0x07FF]; - RAM.SetFreeze = (addr, value) => sysbus_freeze[addr & 0x07FF] = value; + RAM.GetFreeze = addr => GetFreeze(sysbus_freeze_list, addr); + RAM.SetFreeze = (addr, value) => SetFreeze(sysbus_freeze_list, addr & 0x07FF, value); - PPUBus.GetFreeze = addr => ppu.ppubus_freeze[addr]; - PPUBus.SetFreeze = (addr, value) => ppu.ppubus_freeze[addr] = value; + PPUBus.GetFreeze = addr => GetFreeze(ppubus_freeze_list, addr); + PPUBus.SetFreeze = (addr, value) => SetFreeze(ppubus_freeze_list, addr, value); //demo a game genie code GetWatch(NESWatch.EDomain.Sysbus, 0xB424).SetGameGenie(-1, 0x10); diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs index ef69c07206..53771c0386 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs @@ -23,7 +23,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo public DebugCallback NTViewCallback; public DebugCallback PPUViewCallback; - public MemoryDomain.FreezeData[] ppubus_freeze = new MemoryDomain.FreezeData[16384]; //when the ppu issues a write it goes through here and into the game board public void ppubus_write(int addr, byte value) @@ -40,11 +39,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo return 0xFF; nes.board.AddressPPU(addr); - //apply freeze - if (ppubus_freeze[addr].IsFrozen) - return ppubus_freeze[addr].value; - else - return nes.board.ReadPPU(addr); + + return nes.board.ReadPPU(addr); } //debug tools peek into the ppu through this