SubNESHawk: Fix memorydomain callbacks i think

This commit is contained in:
alyosha-tas 2019-06-28 15:59:21 -04:00
parent 5188b7a2e7
commit c29c3f0391
2 changed files with 224 additions and 230 deletions

View File

@ -61,7 +61,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
return false;
}
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
public IMemoryCallbackSystem MemoryCallbacks => subnes.MemoryCallbacks;
[FeatureNotImplemented]
public void Step(StepType type) { throw new NotImplementedException(); }

View File

@ -1,230 +1,224 @@
using System;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.NES;
namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
{
[Core(
"SubNESHawk",
"",
isPorted: false,
isReleased: true)]
[ServiceNotApplicable(typeof(IDriveLight))]
public partial class SubNESHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable,
ISettable<NES.NES.NESSettings, NES.NES.NESSyncSettings>, INESPPUViewable
{
public NES.NES subnes;
// needed for movies to accurately calculate timing
public int VBL_CNT;
[CoreConstructor("NES")]
public SubNESHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
{
var ser = new BasicServiceProvider(this);
subnesSettings = (NES.NES.NESSettings)settings ?? new NES.NES.NESSettings();
subnesSyncSettings = (NES.NES.NESSyncSettings)syncSettings ?? new NES.NES.NESSyncSettings();
CoreComm = comm;
subnes = new NES.NES(new CoreComm(comm.ShowMessage, comm.Notify) { CoreFileProvider = comm.CoreFileProvider },
game, rom, subnesSettings, subnesSyncSettings);
ser.Register<IVideoProvider>(subnes.videoProvider);
ser.Register<ISoundProvider>(subnes);
_tracer = new TraceBuffer { Header = "6502: PC, machine code, mnemonic, operands, registers (A, X, Y, P, SP), flags (NVTBDIZCR), CPU Cycle, PPU Cycle" };
ser.Register<ITraceable>(_tracer);
ServiceProvider = ser;
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(subnes._memoryDomains);
subnes.using_reset_timing = true;
HardReset();
current_cycle = 0;
subnes.cpu.ext_ppu_cycle = current_cycle;
VBL_CNT = 0;
}
public void HardReset()
{
subnes.HardReset();
}
public void SoftReset()
{
subnes.Board.NESSoftReset();
subnes.cpu.NESSoftReset();
subnes.apu.NESSoftReset();
subnes.ppu.NESSoftReset();
current_cycle = 0;
subnes.cpu.ext_ppu_cycle = current_cycle;
}
public DisplayType Region => DisplayType.NTSC;
public int _frame = 0;
private readonly ITraceable _tracer;
private void ExecFetch(ushort addr)
using System;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.NES;
namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
{
[Core(
"SubNESHawk",
"",
isPorted: false,
isReleased: true)]
[ServiceNotApplicable(typeof(IDriveLight))]
public partial class SubNESHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable,
ISettable<NES.NES.NESSettings, NES.NES.NESSyncSettings>, INESPPUViewable
{
public NES.NES subnes;
// needed for movies to accurately calculate timing
public int VBL_CNT;
[CoreConstructor("NES")]
public SubNESHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
{
uint flags = (uint)(MemoryCallbackFlags.AccessExecute);
MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "System Bus");
}
#region ISettable
private NES.NES.NESSettings subnesSettings = new NES.NES.NESSettings();
public NES.NES.NESSyncSettings subnesSyncSettings = new NES.NES.NESSyncSettings();
public NES.NES.NESSettings GetSettings()
{
return subnesSettings.Clone();
}
public NES.NES.NESSyncSettings GetSyncSettings()
{
return subnesSyncSettings.Clone();
}
public bool PutSettings(NES.NES.NESSettings o)
{
subnesSettings = o;
if (subnesSettings.ClipLeftAndRight)
{
subnes.videoProvider.left = 8;
subnes.videoProvider.right = 247;
}
else
{
subnes.videoProvider.left = 0;
subnes.videoProvider.right = 255;
}
CoreComm.ScreenLogicalOffsetX = subnes.videoProvider.left;
CoreComm.ScreenLogicalOffsetY = Region == DisplayType.NTSC ? subnesSettings.NTSC_TopLine : subnesSettings.PAL_TopLine;
subnes.SetPalette(subnesSettings.Palette);
subnes.apu.m_vol = subnesSettings.APU_vol;
return false;
}
public bool PutSyncSettings(NES.NES.NESSyncSettings o)
{
bool ret = NES.NES.NESSyncSettings.NeedsReboot(subnesSyncSettings, o);
subnesSyncSettings = o;
return ret;
}
#endregion
#region PPU Viewable
public int[] GetPalette()
{
return subnes.palette_compiled;
}
public bool BGBaseHigh
{
get { return subnes.ppu.reg_2000.bg_pattern_hi; }
}
public bool SPBaseHigh
{
get { return subnes.ppu.reg_2000.obj_pattern_hi; }
}
public bool SPTall
{
get { return subnes.ppu.reg_2000.obj_size_16; }
}
public byte[] GetPPUBus()
{
byte[] ret = new byte[0x3000];
for (int i = 0; i < 0x3000; i++)
{
ret[i] = subnes.ppu.ppubus_peek(i);
}
return ret;
}
public byte[] GetPalRam()
{
return subnes.ppu.PALRAM;
}
public byte[] GetOam()
{
return subnes.ppu.OAM;
}
public byte PeekPPU(int addr)
{
return subnes.Board.PeekPPU(addr);
}
public byte[] GetExTiles()
{
if (subnes.Board is ExROM)
{
return subnes.Board.VROM ?? subnes.Board.VRAM;
}
else
{
throw new InvalidOperationException();
}
}
public bool ExActive
{
get { return subnes.Board is ExROM && (subnes.Board as ExROM).ExAttrActive; }
}
public byte[] GetExRam()
{
if (subnes.Board is ExROM)
{
return (subnes.Board as ExROM).GetExRAMArray();
}
else
{
throw new InvalidOperationException();
}
}
public MemoryDomain GetCHRROM()
{
return _memoryDomains["CHR VROM"];
}
public void InstallCallback1(Action cb, int sl)
{
subnes.ppu.NTViewCallback = new PPU.DebugCallback { Callback = cb, Scanline = sl };
}
public void InstallCallback2(Action cb, int sl)
{
subnes.ppu.PPUViewCallback = new PPU.DebugCallback { Callback = cb, Scanline = sl };
}
public void RemoveCallback1()
{
subnes.ppu.NTViewCallback = null;
}
public void RemoveCallback2()
{
subnes.ppu.PPUViewCallback = null;
}
#endregion
}
}
var ser = new BasicServiceProvider(this);
subnesSettings = (NES.NES.NESSettings)settings ?? new NES.NES.NESSettings();
subnesSyncSettings = (NES.NES.NESSyncSettings)syncSettings ?? new NES.NES.NESSyncSettings();
CoreComm = comm;
subnes = new NES.NES(new CoreComm(comm.ShowMessage, comm.Notify) { CoreFileProvider = comm.CoreFileProvider },
game, rom, subnesSettings, subnesSyncSettings);
ser.Register<IVideoProvider>(subnes.videoProvider);
ser.Register<ISoundProvider>(subnes);
_tracer = new TraceBuffer { Header = "6502: PC, machine code, mnemonic, operands, registers (A, X, Y, P, SP), flags (NVTBDIZCR), CPU Cycle, PPU Cycle" };
ser.Register<ITraceable>(_tracer);
ServiceProvider = ser;
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(subnes._memoryDomains);
subnes.using_reset_timing = true;
HardReset();
current_cycle = 0;
subnes.cpu.ext_ppu_cycle = current_cycle;
VBL_CNT = 0;
}
public void HardReset()
{
subnes.HardReset();
}
public void SoftReset()
{
subnes.Board.NESSoftReset();
subnes.cpu.NESSoftReset();
subnes.apu.NESSoftReset();
subnes.ppu.NESSoftReset();
current_cycle = 0;
subnes.cpu.ext_ppu_cycle = current_cycle;
}
public DisplayType Region => DisplayType.NTSC;
public int _frame = 0;
private readonly ITraceable _tracer;
#region ISettable
private NES.NES.NESSettings subnesSettings = new NES.NES.NESSettings();
public NES.NES.NESSyncSettings subnesSyncSettings = new NES.NES.NESSyncSettings();
public NES.NES.NESSettings GetSettings()
{
return subnesSettings.Clone();
}
public NES.NES.NESSyncSettings GetSyncSettings()
{
return subnesSyncSettings.Clone();
}
public bool PutSettings(NES.NES.NESSettings o)
{
subnesSettings = o;
if (subnesSettings.ClipLeftAndRight)
{
subnes.videoProvider.left = 8;
subnes.videoProvider.right = 247;
}
else
{
subnes.videoProvider.left = 0;
subnes.videoProvider.right = 255;
}
CoreComm.ScreenLogicalOffsetX = subnes.videoProvider.left;
CoreComm.ScreenLogicalOffsetY = Region == DisplayType.NTSC ? subnesSettings.NTSC_TopLine : subnesSettings.PAL_TopLine;
subnes.SetPalette(subnesSettings.Palette);
subnes.apu.m_vol = subnesSettings.APU_vol;
return false;
}
public bool PutSyncSettings(NES.NES.NESSyncSettings o)
{
bool ret = NES.NES.NESSyncSettings.NeedsReboot(subnesSyncSettings, o);
subnesSyncSettings = o;
return ret;
}
#endregion
#region PPU Viewable
public int[] GetPalette()
{
return subnes.palette_compiled;
}
public bool BGBaseHigh
{
get { return subnes.ppu.reg_2000.bg_pattern_hi; }
}
public bool SPBaseHigh
{
get { return subnes.ppu.reg_2000.obj_pattern_hi; }
}
public bool SPTall
{
get { return subnes.ppu.reg_2000.obj_size_16; }
}
public byte[] GetPPUBus()
{
byte[] ret = new byte[0x3000];
for (int i = 0; i < 0x3000; i++)
{
ret[i] = subnes.ppu.ppubus_peek(i);
}
return ret;
}
public byte[] GetPalRam()
{
return subnes.ppu.PALRAM;
}
public byte[] GetOam()
{
return subnes.ppu.OAM;
}
public byte PeekPPU(int addr)
{
return subnes.Board.PeekPPU(addr);
}
public byte[] GetExTiles()
{
if (subnes.Board is ExROM)
{
return subnes.Board.VROM ?? subnes.Board.VRAM;
}
else
{
throw new InvalidOperationException();
}
}
public bool ExActive
{
get { return subnes.Board is ExROM && (subnes.Board as ExROM).ExAttrActive; }
}
public byte[] GetExRam()
{
if (subnes.Board is ExROM)
{
return (subnes.Board as ExROM).GetExRAMArray();
}
else
{
throw new InvalidOperationException();
}
}
public MemoryDomain GetCHRROM()
{
return _memoryDomains["CHR VROM"];
}
public void InstallCallback1(Action cb, int sl)
{
subnes.ppu.NTViewCallback = new PPU.DebugCallback { Callback = cb, Scanline = sl };
}
public void InstallCallback2(Action cb, int sl)
{
subnes.ppu.PPUViewCallback = new PPU.DebugCallback { Callback = cb, Scanline = sl };
}
public void RemoveCallback1()
{
subnes.ppu.NTViewCallback = null;
}
public void RemoveCallback2()
{
subnes.ppu.PPUViewCallback = null;
}
#endregion
}
}