Use generic interface type on MOS 6052X for talking to the emulator core (#1189)
* Use generic interface type on MOS 6052X for talking to the emulator core * Change CpuLink constructors to not use expression-bodies, to get the AppVeyor build to pass. * Add comment explaining why IMOS6502XLink exists.
This commit is contained in:
parent
e650f14d24
commit
f3ea6fe025
|
@ -1301,6 +1301,7 @@
|
|||
<Compile Include="CPUs\LR35902\Registers.cs" />
|
||||
<Compile Include="CPUs\LR35902\Tables_Direct.cs" />
|
||||
<Compile Include="CPUs\LR35902\Tables_Indirect.cs" />
|
||||
<Compile Include="CPUs\MOS 6502X\IMOS6502XLink.cs" />
|
||||
<Compile Include="CPUs\W65816\Disassembler.cs" />
|
||||
<Compile Include="CPUs\68000\Diassembler.cs" />
|
||||
<Compile Include="CPUs\68000\Instructions\BitArithemetic.cs" />
|
||||
|
@ -1441,6 +1442,7 @@
|
|||
<None Include="Consoles\Nintendo\NES\Docs\BoardTable.xlsx" />
|
||||
<None Include="Consoles\Nintendo\NES\Docs\MapperCompatibilityList.url" />
|
||||
<None Include="Consoles\Nintendo\NES\Docs\nesasm.pdf" />
|
||||
<Compile Include="Consoles\Nintendo\NES\NES.CpuLink.cs" />
|
||||
<None Include="Resources\128.ROM.gz" />
|
||||
<None Include="Resources\48.ROM.gz" />
|
||||
<None Include="Resources\cgb_boot.bin.gz" />
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Components.M6502
|
||||
{
|
||||
public partial class MOS6502X : IDisassemblable
|
||||
public partial class MOS6502X<TLink> : IDisassemblable
|
||||
{
|
||||
private static ushort peeker_word(ushort address, Func<ushort, byte> peeker)
|
||||
{
|
||||
|
@ -15,7 +15,43 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
|
||||
public string Disassemble(ushort pc, out int bytesToAdvance)
|
||||
{
|
||||
return Disassemble(pc, out bytesToAdvance, PeekMemory);
|
||||
return MOS6502X.Disassemble(pc, out bytesToAdvance, _link.PeekMemory);
|
||||
}
|
||||
|
||||
public string Cpu
|
||||
{
|
||||
get
|
||||
{
|
||||
return "6502";
|
||||
}
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public string PCRegisterName
|
||||
{
|
||||
get { return "PC"; }
|
||||
}
|
||||
|
||||
public IEnumerable<string> AvailableCpus
|
||||
{
|
||||
get { yield return "6502"; }
|
||||
}
|
||||
|
||||
public string Disassemble(MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
return MOS6502X.Disassemble((ushort)addr, out length, a => m.PeekByte((int)a));
|
||||
}
|
||||
}
|
||||
|
||||
public static class MOS6502X
|
||||
{
|
||||
private static ushort peeker_word(ushort address, Func<ushort, byte> peeker)
|
||||
{
|
||||
byte l = peeker(address);
|
||||
byte h = peeker(++address);
|
||||
return (ushort)((h << 8) | l);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -208,31 +244,5 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
bytesToAdvance = 1;
|
||||
return "???";
|
||||
}
|
||||
|
||||
public string Cpu
|
||||
{
|
||||
get
|
||||
{
|
||||
return "6502";
|
||||
}
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public string PCRegisterName
|
||||
{
|
||||
get { return "PC"; }
|
||||
}
|
||||
|
||||
public IEnumerable<string> AvailableCpus
|
||||
{
|
||||
get { yield return "6502"; }
|
||||
}
|
||||
|
||||
public string Disassemble(MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
return Disassemble((ushort)addr, out length, a => m.PeekByte((int)a));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,18 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.M6502
|
||||
{
|
||||
// Interface that has all the methods required by the MOS 6502X to talk to
|
||||
// the emulator core.
|
||||
// Should only be used as a generic type argument for the MOS 6502X, and
|
||||
// implementations should be structs where possible. This combination allows
|
||||
// the JITer to generate much faster code than calling a Func<> or Action<>.
|
||||
public interface IMOS6502XLink
|
||||
{
|
||||
byte ReadMemory(ushort address);
|
||||
byte DummyReadMemory(ushort address);
|
||||
byte PeekMemory(ushort address);
|
||||
void WriteMemory(ushort address, byte value);
|
||||
|
||||
// This only calls when the first byte of an instruction is fetched.
|
||||
void OnExecFetch(ushort address);
|
||||
}
|
||||
}
|
|
@ -6,10 +6,13 @@ using BizHawk.Emulation.Common;
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Components.M6502
|
||||
{
|
||||
public sealed partial class MOS6502X
|
||||
public sealed partial class MOS6502X<TLink> where TLink : IMOS6502XLink
|
||||
{
|
||||
public MOS6502X()
|
||||
private readonly TLink _link;
|
||||
|
||||
public MOS6502X(TLink link)
|
||||
{
|
||||
_link = link;
|
||||
InitOpcodeHandlers();
|
||||
Reset();
|
||||
}
|
||||
|
@ -62,7 +65,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
rawbytes += string.Format(" {0:X2}", PeekMemory((ushort)(PC + i)));
|
||||
rawbytes += string.Format(" {0:X2}", _link.PeekMemory((ushort)(PC + i)));
|
||||
}
|
||||
|
||||
return new TraceInfo
|
||||
|
@ -206,39 +209,17 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
|
||||
public long TotalExecutedCycles;
|
||||
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Func<ushort, byte> DummyReadMemory;
|
||||
public Func<ushort, byte> PeekMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
|
||||
//this only calls when the first byte of an instruction is fetched.
|
||||
public Action<ushort> OnExecFetch;
|
||||
|
||||
public void SetCallbacks
|
||||
(
|
||||
Func<ushort, byte> ReadMemory,
|
||||
Func<ushort, byte> DummyReadMemory,
|
||||
Func<ushort, byte> PeekMemory,
|
||||
Action<ushort, byte> WriteMemory
|
||||
)
|
||||
{
|
||||
this.ReadMemory = ReadMemory;
|
||||
this.DummyReadMemory = DummyReadMemory;
|
||||
this.PeekMemory = PeekMemory;
|
||||
this.WriteMemory = WriteMemory;
|
||||
}
|
||||
|
||||
public ushort ReadWord(ushort address)
|
||||
{
|
||||
byte l = ReadMemory(address);
|
||||
byte h = ReadMemory(++address);
|
||||
byte l = _link.ReadMemory(address);
|
||||
byte h = _link.ReadMemory(++address);
|
||||
return (ushort)((h << 8) | l);
|
||||
}
|
||||
|
||||
public ushort PeekWord(ushort address)
|
||||
{
|
||||
byte l = PeekMemory(address);
|
||||
byte h = PeekMemory(++address);
|
||||
byte l = _link.PeekMemory(address);
|
||||
byte h = _link.PeekMemory(++address);
|
||||
return (ushort)((h << 8) | l);
|
||||
}
|
||||
|
||||
|
@ -246,14 +227,14 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
{
|
||||
byte l = (byte)(value & 0xFF);
|
||||
byte h = (byte)(value >> 8);
|
||||
WriteMemory(address, l);
|
||||
WriteMemory(++address, h);
|
||||
_link.WriteMemory(address, l);
|
||||
_link.WriteMemory(++address, h);
|
||||
}
|
||||
|
||||
private ushort ReadWordPageWrap(ushort address)
|
||||
{
|
||||
ushort highAddress = (ushort)((address & 0xFF00) + ((address + 1) & 0xFF));
|
||||
return (ushort)(ReadMemory(address) | (ReadMemory(highAddress) << 8));
|
||||
return (ushort)(_link.ReadMemory(address) | (_link.ReadMemory(highAddress) << 8));
|
||||
}
|
||||
|
||||
// SO pin
|
||||
|
|
|
@ -10,11 +10,31 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
public sealed partial class Chip6510
|
||||
{
|
||||
// ------------------------------------
|
||||
private readonly MOS6502X _cpu;
|
||||
private readonly MOS6502X<CpuLink> _cpu;
|
||||
private bool _pinNmiLast;
|
||||
private LatchedPort _port;
|
||||
private bool _thisNmi;
|
||||
|
||||
private struct CpuLink : IMOS6502XLink
|
||||
{
|
||||
private readonly Chip6510 _chip;
|
||||
|
||||
public CpuLink(Chip6510 chip)
|
||||
{
|
||||
_chip = chip;
|
||||
}
|
||||
|
||||
public byte DummyReadMemory(ushort address) => unchecked((byte)_chip.Read(address));
|
||||
|
||||
public void OnExecFetch(ushort address) { }
|
||||
|
||||
public byte PeekMemory(ushort address) => unchecked((byte)_chip.Peek(address));
|
||||
|
||||
public byte ReadMemory(ushort address) => unchecked((byte)_chip.Read(address));
|
||||
|
||||
public void WriteMemory(ushort address, byte value) => _chip.Write(address, value);
|
||||
}
|
||||
|
||||
public Func<int, int> PeekMemory;
|
||||
public Action<int, int> PokeMemory;
|
||||
public Func<bool> ReadAec;
|
||||
|
@ -33,13 +53,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
public Chip6510()
|
||||
{
|
||||
// configure cpu r/w
|
||||
_cpu = new MOS6502X
|
||||
{
|
||||
DummyReadMemory = CpuRead,
|
||||
ReadMemory = CpuRead,
|
||||
WriteMemory = CpuWrite,
|
||||
PeekMemory = CpuPeek
|
||||
};
|
||||
_cpu = new MOS6502X<CpuLink>(new CpuLink(this));
|
||||
|
||||
// perform hard reset
|
||||
HardReset();
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial
|
|||
private bool _motorEnabled;
|
||||
private bool _ledEnabled;
|
||||
private int _motorStep;
|
||||
private readonly MOS6502X _cpu;
|
||||
private readonly MOS6502X<CpuLink> _cpu;
|
||||
private int[] _ram;
|
||||
public readonly Via Via0;
|
||||
public readonly Via Via1;
|
||||
|
@ -31,15 +31,31 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial
|
|||
public Action DebuggerStep;
|
||||
public readonly Chip23128 DriveRom;
|
||||
|
||||
private struct CpuLink : IMOS6502XLink
|
||||
{
|
||||
private readonly Drive1541 _drive;
|
||||
|
||||
public CpuLink(Drive1541 drive)
|
||||
{
|
||||
_drive = drive;
|
||||
}
|
||||
|
||||
public byte DummyReadMemory(ushort address) => unchecked((byte)_drive.Read(address));
|
||||
|
||||
public void OnExecFetch(ushort address) { }
|
||||
|
||||
public byte PeekMemory(ushort address) => unchecked((byte)_drive.Peek(address));
|
||||
|
||||
public byte ReadMemory(ushort address) => unchecked((byte)_drive.Read(address));
|
||||
|
||||
public void WriteMemory(ushort address, byte value) => _drive.Write(address, value);
|
||||
}
|
||||
|
||||
public Drive1541(int clockNum, int clockDen)
|
||||
{
|
||||
DriveRom = new Chip23128();
|
||||
_cpu = new MOS6502X
|
||||
_cpu = new MOS6502X<CpuLink>(new CpuLink(this))
|
||||
{
|
||||
ReadMemory = CpuRead,
|
||||
WriteMemory = CpuWrite,
|
||||
DummyReadMemory = CpuRead,
|
||||
PeekMemory = CpuPeek,
|
||||
NMI = false
|
||||
};
|
||||
|
||||
|
|
|
@ -28,11 +28,31 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
private bool _leftDifficultySwitchHeld;
|
||||
private bool _rightDifficultySwitchHeld;
|
||||
|
||||
internal MOS6502X Cpu { get; private set; }
|
||||
internal MOS6502X<CpuLink> Cpu { get; private set; }
|
||||
internal byte[] Ram => _ram;
|
||||
internal byte[] Rom { get; }
|
||||
internal int DistinctAccessCount { get; private set; }
|
||||
|
||||
internal struct CpuLink : IMOS6502XLink
|
||||
{
|
||||
private readonly Atari2600 _atari2600;
|
||||
|
||||
public CpuLink(Atari2600 atari2600)
|
||||
{
|
||||
_atari2600 = atari2600;
|
||||
}
|
||||
|
||||
public byte DummyReadMemory(ushort address) => _atari2600.ReadMemory(address);
|
||||
|
||||
public void OnExecFetch(ushort address) => _atari2600.ExecFetch(address);
|
||||
|
||||
public byte PeekMemory(ushort address) => _atari2600.ReadMemory(address);
|
||||
|
||||
public byte ReadMemory(ushort address) => _atari2600.ReadMemory(address);
|
||||
|
||||
public void WriteMemory(ushort address, byte value) => _atari2600.WriteMemory(address, value);
|
||||
}
|
||||
|
||||
// keeps track of tia cycles, 3 cycles per CPU cycle
|
||||
private int cyc_counter;
|
||||
|
||||
|
@ -292,14 +312,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
_mapper.Core = this;
|
||||
|
||||
_lagcount = 0;
|
||||
Cpu = new MOS6502X
|
||||
{
|
||||
ReadMemory = ReadMemory,
|
||||
WriteMemory = WriteMemory,
|
||||
PeekMemory = PeekMemory,
|
||||
DummyReadMemory = ReadMemory,
|
||||
OnExecFetch = ExecFetch
|
||||
};
|
||||
Cpu = new MOS6502X<CpuLink>(new CpuLink(this));
|
||||
|
||||
if (_game["PAL"])
|
||||
{
|
||||
|
@ -334,14 +347,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
_ram = new byte[128];
|
||||
_mapper.HardReset();
|
||||
|
||||
Cpu = new MOS6502X
|
||||
{
|
||||
ReadMemory = ReadMemory,
|
||||
WriteMemory = WriteMemory,
|
||||
PeekMemory = PeekMemory,
|
||||
DummyReadMemory = ReadMemory,
|
||||
OnExecFetch = ExecFetch
|
||||
};
|
||||
Cpu = new MOS6502X<CpuLink>(new CpuLink(this));
|
||||
|
||||
_tia.Reset();
|
||||
_m6532 = new M6532(this);
|
||||
|
|
|
@ -44,13 +44,33 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
|
||||
private readonly ITraceable _tracer;
|
||||
|
||||
public MOS6502X cpu;
|
||||
public MOS6502X<CpuLink> cpu;
|
||||
public Maria maria;
|
||||
public bool _isPAL;
|
||||
public M6532 m6532;
|
||||
public TIA tia;
|
||||
public Pokey pokey;
|
||||
|
||||
public struct CpuLink : IMOS6502XLink
|
||||
{
|
||||
private readonly A7800Hawk _a7800;
|
||||
|
||||
public CpuLink(A7800Hawk a7800)
|
||||
{
|
||||
_a7800 = a7800;
|
||||
}
|
||||
|
||||
public byte DummyReadMemory(ushort address) => _a7800.ReadMemory(address);
|
||||
|
||||
public void OnExecFetch(ushort address) => _a7800.ExecFetch(address);
|
||||
|
||||
public byte PeekMemory(ushort address) => _a7800.ReadMemory(address);
|
||||
|
||||
public byte ReadMemory(ushort address) => _a7800.ReadMemory(address);
|
||||
|
||||
public void WriteMemory(ushort address, byte value) => _a7800.WriteMemory(address, value);
|
||||
}
|
||||
|
||||
public A7800Hawk(CoreComm comm, GameInfo game, byte[] rom, string gameDbFn, object settings, object syncSettings)
|
||||
{
|
||||
var ser = new BasicServiceProvider(this);
|
||||
|
@ -60,14 +80,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
m6532 = new M6532();
|
||||
pokey = new Pokey();
|
||||
|
||||
cpu = new MOS6502X
|
||||
{
|
||||
ReadMemory = ReadMemory,
|
||||
WriteMemory = WriteMemory,
|
||||
PeekMemory = ReadMemory,
|
||||
DummyReadMemory = ReadMemory,
|
||||
OnExecFetch = ExecFetch
|
||||
};
|
||||
cpu = new MOS6502X<CpuLink>(new CpuLink(this));
|
||||
|
||||
maria = new Maria
|
||||
{
|
||||
|
@ -255,7 +268,6 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
|
||||
tia.Reset();
|
||||
cpu.Reset();
|
||||
cpu.SetCallbacks(ReadMemory, ReadMemory, ReadMemory, WriteMemory);
|
||||
|
||||
maria.Reset();
|
||||
m6532.Reset();
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
public partial class NES : IEmulator, ICycleTiming
|
||||
{
|
||||
//hardware/state
|
||||
public MOS6502X cpu;
|
||||
public MOS6502X<CpuLink> cpu;
|
||||
public PPU ppu;
|
||||
public APU apu;
|
||||
public byte[] ram;
|
||||
|
@ -159,11 +159,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
public void HardReset()
|
||||
{
|
||||
cpu = new MOS6502X();
|
||||
cpu.SetCallbacks(ReadMemory, ReadMemory, PeekMemory, WriteMemory);
|
||||
cpu = new MOS6502X<CpuLink>(new CpuLink(this))
|
||||
{
|
||||
BCD_Enabled = false
|
||||
};
|
||||
|
||||
cpu.BCD_Enabled = false;
|
||||
cpu.OnExecFetch = ExecFetch;
|
||||
ppu = new PPU(this);
|
||||
ram = new byte[0x800];
|
||||
CIRAM = new byte[0x800];
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
using BizHawk.Emulation.Cores.Components.M6502;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||
{
|
||||
public partial class NES
|
||||
{
|
||||
public struct CpuLink : IMOS6502XLink
|
||||
{
|
||||
private readonly NES _nes;
|
||||
|
||||
public CpuLink(NES nes)
|
||||
{
|
||||
_nes = nes;
|
||||
}
|
||||
|
||||
public byte DummyReadMemory(ushort address) => _nes.ReadMemory(address);
|
||||
|
||||
public void OnExecFetch(ushort address) => _nes.ExecFetch(address);
|
||||
|
||||
public byte PeekMemory(ushort address) => _nes.CDL == null ? _nes.PeekMemory(address) : _nes.FetchMemory_CDL(address);
|
||||
|
||||
public byte ReadMemory(ushort address) => _nes.CDL == null ? _nes.ReadMemory(address) : _nes.ReadMemory_CDL(address);
|
||||
|
||||
public void WriteMemory(ushort address, byte value) => _nes.WriteMemory(address, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,18 +9,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
public void SetCDL(ICodeDataLog cdl)
|
||||
{
|
||||
CDL = cdl;
|
||||
if (cdl == null)
|
||||
{
|
||||
cpu.ReadMemory = ReadMemory;
|
||||
cpu.WriteMemory = WriteMemory;
|
||||
cpu.PeekMemory = PeekMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu.ReadMemory = ReadMemory_CDL;
|
||||
cpu.WriteMemory = WriteMemory;
|
||||
cpu.PeekMemory = FetchMemory_CDL;
|
||||
}
|
||||
}
|
||||
|
||||
public void NewCDL(ICodeDataLog cdl)
|
||||
|
|
Loading…
Reference in New Issue