subneshawk - delete a bunch of code by using the underlying core for services, cleanup, and implement some services that were missing
This commit is contained in:
parent
4d4496af0d
commit
dedd618db4
|
@ -31,7 +31,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
else if (core is SubNESHawk subNesHawk)
|
else if (core is SubNESHawk subNesHawk)
|
||||||
{
|
{
|
||||||
ss = subNesHawk.GetSyncSettings();
|
ss = subNesHawk.GetSyncSettings();
|
||||||
isFds = subNesHawk.IsFDS;
|
isFds = subNesHawk.IsFds;
|
||||||
fdsButtonCount = subNesHawk.ControllerDefinition.BoolButtons.Count(b => b.StartsWith("FDS Insert "));
|
fdsButtonCount = subNesHawk.ControllerDefinition.BoolButtons.Count(b => b.StartsWith("FDS Insert "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -293,7 +293,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
_controller = controller;
|
_controller = controller;
|
||||||
|
|
||||||
if (Tracer.Enabled)
|
if (Tracer.Enabled)
|
||||||
cpu.TraceCallback = (s) => Tracer.Put(s);
|
cpu.TraceCallback = s => Tracer.Put(s);
|
||||||
else
|
else
|
||||||
cpu.TraceCallback = null;
|
cpu.TraceCallback = null;
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
{
|
{
|
||||||
public partial class NES : ISettable<NES.NESSettings, NES.NESSyncSettings>
|
public partial class NES : ISettable<NES.NESSettings, NES.NESSyncSettings>
|
||||||
{
|
{
|
||||||
public NESSettings GetSettings()
|
public NESSettings GetSettings() => Settings.Clone();
|
||||||
{
|
|
||||||
return Settings.Clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public NESSyncSettings GetSyncSettings()
|
public NESSyncSettings GetSyncSettings() => SyncSettings.Clone();
|
||||||
{
|
|
||||||
return SyncSettings.Clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool PutSettings(NESSettings o)
|
public bool PutSettings(NESSettings o)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,12 +67,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
LoadStateCallback = SetupMemoryDomains
|
LoadStateCallback = SetupMemoryDomains
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Board is BANDAI_FCG_1)
|
if (Board is BANDAI_FCG_1 bandai)
|
||||||
{
|
{
|
||||||
var reader = (Board as BANDAI_FCG_1).reader;
|
var reader = bandai.reader;
|
||||||
// not all BANDAI FCG 1 boards have a barcode reader
|
// not all BANDAI FCG 1 boards have a barcode reader
|
||||||
if (reader != null)
|
if (reader != null)
|
||||||
ser.Register<DatachBarcode>(reader);
|
{
|
||||||
|
ser.Register(reader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using BizHawk.Emulation.Common;
|
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
|
||||||
{
|
|
||||||
public partial class SubNESHawk : IDebuggable
|
|
||||||
{
|
|
||||||
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters() => subnes.GetCpuFlagsAndRegisters();
|
|
||||||
|
|
||||||
public void SetCpuRegister(string register, int value) => subnes.SetCpuRegister(register, value);
|
|
||||||
|
|
||||||
public bool CanStep(StepType type) => false;
|
|
||||||
|
|
||||||
public IMemoryCallbackSystem MemoryCallbacks => subnes.MemoryCallbacks;
|
|
||||||
|
|
||||||
[FeatureNotImplemented]
|
|
||||||
public void Step(StepType type) => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public long TotalExecutedCycles => subnes.cpu.TotalExecutedCycles;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,18 +7,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
{
|
{
|
||||||
public IEmulatorServiceProvider ServiceProvider { get; }
|
public IEmulatorServiceProvider ServiceProvider { get; }
|
||||||
|
|
||||||
public ControllerDefinition ControllerDefinition => subnes.ControllerDefinition;
|
public ControllerDefinition ControllerDefinition => _nesCore.ControllerDefinition;
|
||||||
|
|
||||||
public bool FrameAdvance(IController controller, bool render, bool renderSound)
|
public bool FrameAdvance(IController controller, bool render, bool renderSound)
|
||||||
{
|
{
|
||||||
//Console.WriteLine("-----------------------FRAME-----------------------");
|
//Console.WriteLine("-----------------------FRAME-----------------------");
|
||||||
if (_tracer.Enabled)
|
if (_tracer.Enabled)
|
||||||
{
|
{
|
||||||
subnes.cpu.TraceCallback = s => _tracer.Put(s);
|
_nesCore.cpu.TraceCallback = s => _tracer.Put(s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
subnes.cpu.TraceCallback = null;
|
_nesCore.cpu.TraceCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_frame++;
|
_frame++;
|
||||||
|
@ -38,22 +38,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
reset_cycle_int = (int)Math.Floor(reset_cycle);
|
reset_cycle_int = (int)Math.Floor(reset_cycle);
|
||||||
|
|
||||||
_isLag = true;
|
_isLag = true;
|
||||||
subnes.alt_lag = true;
|
_nesCore.alt_lag = true;
|
||||||
|
|
||||||
InputCallbacks.Call();
|
InputCallbacks.Call();
|
||||||
|
|
||||||
do_frame(controller);
|
DoFrame(controller);
|
||||||
|
|
||||||
bool ret = pass_a_frame;
|
bool ret = pass_a_frame;
|
||||||
|
|
||||||
if (pass_a_frame)
|
if (pass_a_frame)
|
||||||
{
|
{
|
||||||
subnes.videoProvider.FillFrameBuffer();
|
_nesCore.videoProvider.FillFrameBuffer();
|
||||||
current_cycle = 0;
|
current_cycle = 0;
|
||||||
subnes.cpu.ext_ppu_cycle = current_cycle;
|
_nesCore.cpu.ext_ppu_cycle = current_cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
_isLag = subnes.alt_lag;
|
_isLag = _nesCore.alt_lag;
|
||||||
|
|
||||||
if (_isLag)
|
if (_isLag)
|
||||||
{
|
{
|
||||||
|
@ -65,15 +65,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool stop_cur_frame;
|
private bool stop_cur_frame;
|
||||||
public bool pass_new_input;
|
private bool pass_new_input;
|
||||||
public bool pass_a_frame;
|
private bool pass_a_frame;
|
||||||
public bool reset_frame;
|
private bool reset_frame;
|
||||||
public int current_cycle;
|
private int current_cycle;
|
||||||
public float reset_cycle;
|
private float reset_cycle;
|
||||||
public int reset_cycle_int;
|
private int reset_cycle_int;
|
||||||
|
|
||||||
public void do_frame(IController controller)
|
private void DoFrame(IController controller)
|
||||||
{
|
{
|
||||||
stop_cur_frame = false;
|
stop_cur_frame = false;
|
||||||
while (!stop_cur_frame)
|
while (!stop_cur_frame)
|
||||||
|
@ -83,9 +83,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
SoftReset();
|
SoftReset();
|
||||||
reset_frame = false;
|
reset_frame = false;
|
||||||
}
|
}
|
||||||
subnes.do_single_step(controller, out pass_new_input, out pass_a_frame);
|
_nesCore.do_single_step(controller, out pass_new_input, out pass_a_frame);
|
||||||
current_cycle++;
|
current_cycle++;
|
||||||
subnes.cpu.ext_ppu_cycle = current_cycle;
|
_nesCore.cpu.ext_ppu_cycle = current_cycle;
|
||||||
stop_cur_frame |= pass_a_frame;
|
stop_cur_frame |= pass_a_frame;
|
||||||
stop_cur_frame |= pass_new_input;
|
stop_cur_frame |= pass_new_input;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
|
|
||||||
public string SystemId => "NES";
|
public string SystemId => "NES";
|
||||||
|
|
||||||
public bool DeterministicEmulation { get; set; }
|
public bool DeterministicEmulation => _nesCore.DeterministicEmulation;
|
||||||
|
|
||||||
public void ResetCounters()
|
public void ResetCounters()
|
||||||
{
|
{
|
||||||
|
@ -104,116 +104,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
_isLag = false;
|
_isLag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CoreComm CoreComm { get; }
|
public CoreComm CoreComm => _nesCore.CoreComm;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose() => _nesCore.Dispose();
|
||||||
{
|
|
||||||
subnes.Dispose();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
#region Video provider
|
|
||||||
|
|
||||||
public int _frameHz = 60;
|
|
||||||
|
|
||||||
public int[] _vidbuffer = new int[160 * 2 * 144];
|
|
||||||
public int[] buff_L = new int[160 * 144];
|
|
||||||
public int[] buff_R = new int[160 * 144];
|
|
||||||
|
|
||||||
public int[] GetVideoBuffer()
|
|
||||||
{
|
|
||||||
// combine the 2 video buffers from the instances
|
|
||||||
for (int i = 0; i < 144; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 160; j++)
|
|
||||||
{
|
|
||||||
_vidbuffer[i * 320 + j] = buff_L[i * 160 + j];
|
|
||||||
_vidbuffer[i * 320 + j + 160] = buff_R[i * 160 + j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _vidbuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int VirtualWidth => 160 * 2;
|
|
||||||
public int VirtualHeight => 144;
|
|
||||||
public int BufferWidth => 160 * 2;
|
|
||||||
public int BufferHeight => 144;
|
|
||||||
public int BackgroundColor => unchecked((int)0xFF000000);
|
|
||||||
public int VsyncNumerator => _frameHz;
|
|
||||||
public int VsyncDenominator => 1;
|
|
||||||
|
|
||||||
public static readonly uint[] color_palette_BW = { 0xFFFFFFFF , 0xFFAAAAAA, 0xFF555555, 0xFF000000 };
|
|
||||||
public static readonly uint[] color_palette_Gr = { 0xFFA4C505, 0xFF88A905, 0xFF1D551D, 0xFF052505 };
|
|
||||||
|
|
||||||
public uint[] color_palette = new uint[4];
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region audio
|
|
||||||
|
|
||||||
public bool CanProvideAsync => false;
|
|
||||||
|
|
||||||
public void SetSyncMode(SyncSoundMode mode)
|
|
||||||
{
|
|
||||||
if (mode != SyncSoundMode.Sync)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Only Sync mode is supported_");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SyncSoundMode SyncMode => SyncSoundMode.Sync;
|
|
||||||
|
|
||||||
public void GetSamplesSync(out short[] samples, out int nsamp)
|
|
||||||
{
|
|
||||||
short[] temp_samp_L;
|
|
||||||
short[] temp_samp_R;
|
|
||||||
|
|
||||||
int nsamp_L;
|
|
||||||
int nsamp_R;
|
|
||||||
|
|
||||||
L.audio.GetSamplesSync(out temp_samp_L, out nsamp_L);
|
|
||||||
R.audio.GetSamplesSync(out temp_samp_R, out nsamp_R);
|
|
||||||
|
|
||||||
if (linkSettings.AudioSet == GBLinkSettings.AudioSrc.Left)
|
|
||||||
{
|
|
||||||
samples = temp_samp_L;
|
|
||||||
nsamp = nsamp_L;
|
|
||||||
}
|
|
||||||
else if (linkSettings.AudioSet == GBLinkSettings.AudioSrc.Right)
|
|
||||||
{
|
|
||||||
samples = temp_samp_R;
|
|
||||||
nsamp = nsamp_R;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
samples = new short[0];
|
|
||||||
nsamp = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetSamplesAsync(short[] samples)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("Async is not available");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DiscardSamples()
|
|
||||||
{
|
|
||||||
L.audio.DiscardSamples();
|
|
||||||
R.audio.DiscardSamples();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetSamples(short[] samples)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisposeSound()
|
|
||||||
{
|
|
||||||
L.audio.DisposeSound();
|
|
||||||
R.audio.DisposeSound();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using BizHawk.Emulation.Common;
|
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
|
||||||
{
|
|
||||||
public partial class SubNESHawk
|
|
||||||
{
|
|
||||||
private MemoryDomainList _memoryDomains;
|
|
||||||
private bool _memoryDomainsSetup = false;
|
|
||||||
|
|
||||||
private void SetupMemoryDomains()
|
|
||||||
{
|
|
||||||
var domains = new List<MemoryDomain>();
|
|
||||||
var RAM = new MemoryDomainByteArray("RAM", MemoryDomain.Endian.Little, subnes.ram, true, 1);
|
|
||||||
var SystemBus = new MemoryDomainDelegate("System Bus", 0x10000, MemoryDomain.Endian.Little,
|
|
||||||
addr => subnes.PeekMemory((ushort)addr), (addr, value) => subnes.ApplySystemBusPoke((int)addr, value), 1);
|
|
||||||
var PPUBus = new MemoryDomainDelegate("PPU Bus", 0x4000, MemoryDomain.Endian.Little,
|
|
||||||
addr => subnes.ppu.ppubus_peek((int)addr), (addr, value) => subnes.ppu.ppubus_write((int)addr, value), 1);
|
|
||||||
var CIRAMdomain = new MemoryDomainByteArray("CIRAM (nametables)", MemoryDomain.Endian.Little, subnes.CIRAM, true, 1);
|
|
||||||
var OAMdoman = new MemoryDomainByteArray("OAM", MemoryDomain.Endian.Unknown, subnes.ppu.OAM, true, 1);
|
|
||||||
|
|
||||||
domains.Add(RAM);
|
|
||||||
domains.Add(SystemBus);
|
|
||||||
domains.Add(PPUBus);
|
|
||||||
domains.Add(CIRAMdomain);
|
|
||||||
domains.Add(OAMdoman);
|
|
||||||
|
|
||||||
if (!(subnes.Board is NES.FDS) && subnes.Board.SaveRam != null)
|
|
||||||
{
|
|
||||||
var BatteryRam = new MemoryDomainByteArray("Battery RAM", MemoryDomain.Endian.Little, subnes.Board.SaveRam, true, 1);
|
|
||||||
domains.Add(BatteryRam);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subnes.Board.ROM != null)
|
|
||||||
{
|
|
||||||
var PRGROM = new MemoryDomainByteArray("PRG ROM", MemoryDomain.Endian.Little, subnes.Board.ROM, true, 1);
|
|
||||||
domains.Add(PRGROM);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subnes.Board.VROM != null)
|
|
||||||
{
|
|
||||||
var CHRROM = new MemoryDomainByteArray("CHR VROM", MemoryDomain.Endian.Little, subnes.Board.VROM, true, 1);
|
|
||||||
domains.Add(CHRROM);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subnes.Board.VRAM != null)
|
|
||||||
{
|
|
||||||
var VRAM = new MemoryDomainByteArray("VRAM", MemoryDomain.Endian.Little, subnes.Board.VRAM, true, 1);
|
|
||||||
domains.Add(VRAM);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subnes.Board.WRAM != null)
|
|
||||||
{
|
|
||||||
var WRAM = new MemoryDomainByteArray("WRAM", MemoryDomain.Endian.Little, subnes.Board.WRAM, true, 1);
|
|
||||||
domains.Add(WRAM);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there were more boards with special ram sets, we'd want to do something more general
|
|
||||||
if (subnes.Board is NES.FDS)
|
|
||||||
{
|
|
||||||
domains.Add((subnes.Board as NES.FDS).GetDiskPeeker());
|
|
||||||
}
|
|
||||||
else if (subnes.Board is NES.ExROM)
|
|
||||||
{
|
|
||||||
domains.Add((subnes.Board as NES.ExROM).GetExRAM());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_memoryDomainsSetup)
|
|
||||||
{
|
|
||||||
_memoryDomains = new MemoryDomainList(domains);
|
|
||||||
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(_memoryDomains);
|
|
||||||
_memoryDomainsSetup = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var src = new MemoryDomainList(domains);
|
|
||||||
_memoryDomains.MergeList(src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
using System;
|
|
||||||
using BizHawk.Emulation.Common;
|
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
|
||||||
{
|
|
||||||
public partial class SubNESHawk : ISaveRam
|
|
||||||
{
|
|
||||||
public bool SaveRamModified
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (subnes.Board == null) return false;
|
|
||||||
if (subnes.Board is NES.FDS) return true;
|
|
||||||
if (subnes.Board.SaveRam == null) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] CloneSaveRam()
|
|
||||||
{
|
|
||||||
if (subnes.Board is NES.FDS fds)
|
|
||||||
{
|
|
||||||
return fds.ReadSaveRam();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (byte[]) subnes.Board?.SaveRam?.Clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StoreSaveRam(byte[] data)
|
|
||||||
{
|
|
||||||
if (subnes.Board is NES.FDS fds)
|
|
||||||
{
|
|
||||||
fds.StoreSaveRam(data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subnes.Board?.SaveRam == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Array.Copy(data, subnes.Board.SaveRam, data.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
using BizHawk.Emulation.Common;
|
||||||
using System.Linq;
|
|
||||||
using BizHawk.Emulation.Common;
|
|
||||||
|
|
||||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
|
@ -12,213 +9,84 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
isPorted: false,
|
isPorted: false,
|
||||||
isReleased: true)]
|
isReleased: true)]
|
||||||
[ServiceNotApplicable(new [] { typeof(IDriveLight) })]
|
[ServiceNotApplicable(new [] { typeof(IDriveLight) })]
|
||||||
public partial class SubNESHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable,
|
public partial class SubNESHawk : IEmulator, IStatable, IInputPollable,
|
||||||
IBoardInfo, ISettable<NES.NES.NESSettings, NES.NES.NESSyncSettings>, INESPPUViewable
|
ISettable<NES.NES.NESSettings, NES.NES.NESSyncSettings>
|
||||||
{
|
{
|
||||||
public NES.NES subnes;
|
|
||||||
|
|
||||||
// needed for movies to accurately calculate timing
|
|
||||||
public int VBL_CNT;
|
|
||||||
|
|
||||||
[CoreConstructor("NES")]
|
[CoreConstructor("NES")]
|
||||||
public SubNESHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
|
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();
|
var subNesSettings = (NES.NES.NESSettings)settings ?? new NES.NES.NESSettings();
|
||||||
subnesSyncSettings = (NES.NES.NESSyncSettings)syncSettings ?? new NES.NES.NESSyncSettings();
|
var subNesSyncSettings = (NES.NES.NESSyncSettings)syncSettings ?? new NES.NES.NESSyncSettings();
|
||||||
|
|
||||||
CoreComm = comm;
|
_nesCore = new NES.NES(new CoreComm(comm.ShowMessage, comm.Notify) {CoreFileProvider = comm.CoreFileProvider},
|
||||||
|
game, rom, subNesSettings, subNesSyncSettings)
|
||||||
|
{
|
||||||
|
using_reset_timing = true
|
||||||
|
};
|
||||||
|
|
||||||
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);
|
|
||||||
ser.Register<IDisassemblable>(subnes.cpu);
|
|
||||||
ServiceProvider = ser;
|
|
||||||
|
|
||||||
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(subnes._memoryDomains);
|
|
||||||
|
|
||||||
subnes.using_reset_timing = true;
|
|
||||||
HardReset();
|
HardReset();
|
||||||
current_cycle = 0;
|
current_cycle = 0;
|
||||||
subnes.cpu.ext_ppu_cycle = current_cycle;
|
_nesCore.cpu.ext_ppu_cycle = current_cycle;
|
||||||
VBL_CNT = 0;
|
VBL_CNT = 0;
|
||||||
|
|
||||||
_nesStatable = subnes.ServiceProvider.GetService<IStatable>();
|
_nesStatable = _nesCore.ServiceProvider.GetService<IStatable>();
|
||||||
|
|
||||||
var barCodeService = subnes.ServiceProvider.GetService<DatachBarcode>();
|
var ser = new BasicServiceProvider(this);
|
||||||
|
ServiceProvider = ser;
|
||||||
|
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<IVideoProvider>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<ISoundProvider>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<ITraceable>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<IDisassemblable>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<IMemoryDomains>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<INESPPUViewable>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<IBoardInfo>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<ISaveRam>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<IDebuggable>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<IRegionable>());
|
||||||
|
ser.Register(_nesCore.ServiceProvider.GetService<ICodeDataLogger>());
|
||||||
|
|
||||||
|
_tracer = new TraceBuffer { Header = "6502: PC, machine code, mnemonic, operands, registers (A, X, Y, P, SP), flags (NVTBDIZCR), CPU Cycle, PPU Cycle" };
|
||||||
|
ser.Register(_tracer);
|
||||||
|
|
||||||
|
|
||||||
|
var barCodeService = _nesCore.ServiceProvider.GetService<DatachBarcode>();
|
||||||
if (barCodeService != null)
|
if (barCodeService != null)
|
||||||
{
|
{
|
||||||
ser.Register(barCodeService);
|
ser.Register(barCodeService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HardReset() => subnes.HardReset();
|
private readonly NES.NES _nesCore;
|
||||||
|
|
||||||
public void SoftReset()
|
// needed for movies to accurately calculate timing
|
||||||
|
public int VBL_CNT;
|
||||||
|
|
||||||
|
public void HardReset() => _nesCore.HardReset();
|
||||||
|
|
||||||
|
private void SoftReset()
|
||||||
{
|
{
|
||||||
subnes.Board.NESSoftReset();
|
_nesCore.Board.NESSoftReset();
|
||||||
subnes.cpu.NESSoftReset();
|
_nesCore.cpu.NESSoftReset();
|
||||||
subnes.apu.NESSoftReset();
|
_nesCore.apu.NESSoftReset();
|
||||||
subnes.ppu.NESSoftReset();
|
_nesCore.ppu.NESSoftReset();
|
||||||
current_cycle = 0;
|
current_cycle = 0;
|
||||||
subnes.cpu.ext_ppu_cycle = current_cycle;
|
_nesCore.cpu.ext_ppu_cycle = current_cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayType Region => DisplayType.NTSC;
|
private int _frame;
|
||||||
|
|
||||||
public int _frame = 0;
|
public bool IsFds => _nesCore.IsFDS;
|
||||||
|
|
||||||
public bool IsFDS => subnes.IsFDS;
|
public bool IsVs => _nesCore.IsVS;
|
||||||
|
|
||||||
public bool IsVs => subnes.IsVS;
|
|
||||||
|
|
||||||
public bool HasMapperProperties
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var fields = subnes.Board.GetType().GetFields();
|
|
||||||
foreach (var field in fields)
|
|
||||||
{
|
|
||||||
var attrib = field.GetCustomAttributes(typeof(MapperPropAttribute), false).OfType<MapperPropAttribute>().SingleOrDefault();
|
|
||||||
if (attrib != null)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly ITraceable _tracer;
|
private readonly ITraceable _tracer;
|
||||||
|
public bool HasMapperProperties => _nesCore.HasMapperProperties;
|
||||||
|
|
||||||
public string BoardName => subnes.Board.GetType().Name;
|
public NES.NES.NESSettings GetSettings() => _nesCore.GetSettings();
|
||||||
|
public NES.NES.NESSyncSettings GetSyncSettings() => _nesCore.GetSyncSettings();
|
||||||
#region ISettable
|
public bool PutSettings(NES.NES.NESSettings o) => _nesCore.PutSettings(o);
|
||||||
private NES.NES.NESSettings subnesSettings = new NES.NES.NESSettings();
|
public bool PutSyncSettings(NES.NES.NESSyncSettings o) => _nesCore.PutSyncSettings(o);
|
||||||
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 => subnes.ppu.reg_2000.bg_pattern_hi;
|
|
||||||
|
|
||||||
public bool SPBaseHigh => subnes.ppu.reg_2000.obj_pattern_hi;
|
|
||||||
|
|
||||||
public bool SPTall => 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() => subnes.ppu.PALRAM;
|
|
||||||
|
|
||||||
public byte[] GetOam() => subnes.ppu.OAM;
|
|
||||||
|
|
||||||
public byte PeekPPU(int addr) => subnes.Board.PeekPPU(addr);
|
|
||||||
|
|
||||||
public byte[] GetExTiles()
|
|
||||||
{
|
|
||||||
if (subnes.Board is ExROM)
|
|
||||||
{
|
|
||||||
return subnes.Board.VROM ?? subnes.Board.VRAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ExActive => subnes.Board is ExROM && (subnes.Board as ExROM).ExAttrActive;
|
|
||||||
|
|
||||||
public byte[] GetExRam()
|
|
||||||
{
|
|
||||||
if (subnes.Board is ExROM)
|
|
||||||
{
|
|
||||||
return (subnes.Board as ExROM).GetExRAMArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MemoryDomain GetCHRROM() => _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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,6 +202,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=avisynth/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=avisynth/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=backbuffer/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=backbuffer/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=backcolor/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=backcolor/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bandai/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitched/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitched/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitching/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitching/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bezier/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bezier/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
Loading…
Reference in New Issue