Implement cpu link interface for z80
This commit is contained in:
parent
945cf5d334
commit
666cb39392
|
@ -7,13 +7,15 @@
|
|||
// the JITer to generate much faster code than calling a Func<> or Action<>.
|
||||
public interface IF3850Link
|
||||
{
|
||||
// Memory Access
|
||||
byte ReadMemory(ushort address);
|
||||
void WriteMemory(ushort address, byte value);
|
||||
|
||||
// Hardware I/O Port Access
|
||||
byte ReadHardware(ushort address);
|
||||
void WriteHardware(ushort address, byte value);
|
||||
|
||||
// This only calls when the first byte of an instruction is fetched.
|
||||
// This is only called when the first byte of an instruction is fetched.
|
||||
void OnExecFetch(ushort address);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
public partial class Z80A<TLink>
|
||||
{
|
||||
public long TotalExecutedCycles;
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
// Interface that has all the methods required by the Z80A to talk to
|
||||
// the emulator core.
|
||||
// Should only be used as a generic type argument for the Z80A, 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 IZ80ALink
|
||||
{
|
||||
// Memory Access
|
||||
byte FetchMemory(ushort address);
|
||||
byte ReadMemory(ushort address);
|
||||
void WriteMemory(ushort address, byte value);
|
||||
|
||||
// Hardware I/O Port Access
|
||||
byte ReadHardware(ushort address);
|
||||
void WriteHardware(ushort address, byte value);
|
||||
|
||||
// Data Bus
|
||||
// Interrupting Devices are responsible for putting a value onto the data bus
|
||||
// for as long as the interrupt is valid
|
||||
byte FetchDB();
|
||||
|
||||
// This is only called when the first byte of an instruction is fetched.
|
||||
void OnExecFetch(ushort address);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
public partial class Z80A<TLink>
|
||||
{
|
||||
private bool iff1;
|
||||
public bool IFF1
|
||||
|
|
|
@ -5,29 +5,10 @@ using BizHawk.Emulation.Common;
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public sealed partial class Z80A : IDisassemblable
|
||||
public static class Z80ADisassembler
|
||||
{
|
||||
private static string Result(string format, Func<ushort, byte> read, ref ushort addr)
|
||||
{
|
||||
//d immediately succeeds the opcode
|
||||
//n immediate succeeds the opcode and the displacement (if present)
|
||||
//nn immediately succeeds the opcode and the displacement (if present)
|
||||
|
||||
if (format.ContainsOrdinal("nn")) format = format.Replace("nn", $"{read(addr++) + (read(addr++) << 8):X4}h"); // LSB is read first
|
||||
if (format.ContainsOrdinal('n')) format = format.Replace("n", $"{read(addr++):X2}h");
|
||||
|
||||
format = format.Replace("+d", "d");
|
||||
if (format.ContainsOrdinal('d'))
|
||||
{
|
||||
var b = unchecked ((sbyte) read(addr++));
|
||||
format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h");
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
private static readonly string[] mnemonics =
|
||||
{
|
||||
[
|
||||
"NOP", "LD BC, nn", "LD (BC), A", "INC BC", //0x04
|
||||
"INC B", "DEC B", "LD B, n", "RLCA", //0x08
|
||||
"EX AF, AF'", "ADD HL, BC", "LD A, (BC)", "DEC BC", //0x0C
|
||||
|
@ -92,10 +73,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
"CALL P, nn", "PUSH AF", "OR n", "RST $30", //0xF8
|
||||
"RET M", "LD SP, HL", "JP M, nn", "EI", //0xFC
|
||||
"CALL M, nn", "[FD]", "CP n", "RST $38", //0x100
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly string[] mnemonicsDD =
|
||||
{
|
||||
[
|
||||
"NOP", "LD BC, nn", "LD (BC), A", "INC BC", //0x04
|
||||
"INC B", "DEC B", "LD B, n", "RLCA", //0x08
|
||||
"EX AF, AF'", "ADD IX, BC", "LD A, (BC)", "DEC BC", //0x0C
|
||||
|
@ -160,10 +141,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
"CALL P, nn", "PUSH AF", "OR n", "RST $30", //0xF8
|
||||
"RET M", "LD SP, IX", "JP M, nn", "EI", //0xFC
|
||||
"CALL M, nn", "[!!DD FD!!]", "CP n", "RST $38", //0x100
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly string[] mnemonicsFD =
|
||||
{
|
||||
[
|
||||
"NOP", "LD BC, nn", "LD (BC), A", "INC BC", //0x04
|
||||
"INC B", "DEC B", "LD B, n", "RLCA", //0x08
|
||||
"EX AF, AF'", "ADD IY, BC", "LD A, (BC)", "DEC BC", //0x0C
|
||||
|
@ -228,10 +209,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
"CALL P, nn", "PUSH AF", "OR n", "RST $30", //0xF8
|
||||
"RET M", "LD SP, IY", "JP M, nn", "EI", //0xFC
|
||||
"CALL M, nn", "[!FD FD!]", "CP n", "RST $38", //0x100
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly string[] mnemonicsDDCB =
|
||||
{
|
||||
[
|
||||
"RLC (IX+d)->B", "RLC (IX+d)->C", "RLC (IX+d)->D", "RLC (IX+d)->E", "RLC (IX+d)->H", "RLC (IX+d)->L", "RLC (IX+d)", "RLC (IX+d)->A",
|
||||
"RRC (IX+d)->B", "RRC (IX+d)->C", "RRC (IX+d)->D", "RRC (IX+d)->E", "RRC (IX+d)->H", "RRC (IX+d)->L", "RRC (IX+d)", "RRC (IX+d)->A",
|
||||
"RL (IX+d)->B", "RL (IX+d)->C", "RL (IX+d)->D", "RL (IX+d)->E", "RL (IX+d)->H", "RL (IX+d)->L", "RL (IX+d)", "RL (IX+d)->A",
|
||||
|
@ -264,10 +245,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
"SET 5 (IX+d)->B", "SET 5 (IX+d)->C", "SET 5 (IX+d)->D", "SET 5 (IX+d)->E", "SET 5 (IX+d)->H", "SET 5 (IX+d)->L", "SET 5 (IX+d)", "SET 5 (IX+d)->A",
|
||||
"SET 6 (IX+d)->B", "SET 6 (IX+d)->C", "SET 6 (IX+d)->D", "SET 6 (IX+d)->E", "SET 6 (IX+d)->H", "SET 6 (IX+d)->L", "SET 6 (IX+d)", "SET 6 (IX+d)->A",
|
||||
"SET 7 (IX+d)->B", "SET 7 (IX+d)->C", "SET 7 (IX+d)->D", "SET 7 (IX+d)->E", "SET 7 (IX+d)->H", "SET 7 (IX+d)->L", "SET 7 (IX+d)", "SET 7 (IX+d)->A",
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly string[] mnemonicsFDCB =
|
||||
{
|
||||
[
|
||||
"RLC (IY+d)->B", "RLC (IY+d)->C", "RLC (IY+d)->D", "RLC (IY+d)->E", "RLC (IY+d)->H", "RLC (IY+d)->L", "RLC (IY+d)", "RLC (IY+d)->A",
|
||||
"RRC (IY+d)->B", "RRC (IY+d)->C", "RRC (IY+d)->D", "RRC (IY+d)->E", "RRC (IY+d)->H", "RRC (IY+d)->L", "RRC (IY+d)", "RRC (IY+d)->A",
|
||||
"RL (IY+d)->B", "RL (IY+d)->C", "RL (IY+d)->D", "RL (IY+d)->E", "RL (IY+d)->H", "RL (IY+d)->L", "RL (IY+d)", "RL (IY+d)->A",
|
||||
|
@ -300,10 +281,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
"SET 5 (IY+d)->B", "SET 5 (IY+d)->C", "SET 5 (IY+d)->D", "SET 5 (IY+d)->E", "SET 5 (IY+d)->H", "SET 5 (IY+d)->L", "SET 5 (IY+d)", "SET 5 (IY+d)->A",
|
||||
"SET 6 (IY+d)->B", "SET 6 (IY+d)->C", "SET 6 (IY+d)->D", "SET 6 (IY+d)->E", "SET 6 (IY+d)->H", "SET 6 (IY+d)->L", "SET 6 (IY+d)", "SET 6 (IY+d)->A",
|
||||
"SET 7 (IY+d)->B", "SET 7 (IY+d)->C", "SET 7 (IY+d)->D", "SET 7 (IY+d)->E", "SET 7 (IY+d)->H", "SET 7 (IY+d)->L", "SET 7 (IY+d)", "SET 7 (IY+d)->A",
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly string[] mnemonicsCB =
|
||||
{
|
||||
[
|
||||
"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (HL)", "RLC A",
|
||||
"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (HL)", "RRC A",
|
||||
"RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (HL)", "RL A",
|
||||
|
@ -336,10 +317,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
"SET 5, B", "SET 5, C", "SET 5, D", "SET 5, E", "SET 5, H", "SET 5, L", "SET 5, (HL)", "SET 5, A",
|
||||
"SET 6, B", "SET 6, C", "SET 6, D", "SET 6, E", "SET 6, H", "SET 6, L", "SET 6, (HL)", "SET 6, A",
|
||||
"SET 7, B", "SET 7, C", "SET 7, D", "SET 7, E", "SET 7, H", "SET 7, L", "SET 7, (HL)", "SET 7, A",
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly string[] mnemonicsED =
|
||||
{
|
||||
[
|
||||
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP",
|
||||
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP",
|
||||
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP",
|
||||
|
@ -378,7 +359,26 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0xE0
|
||||
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0xF0
|
||||
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0x100
|
||||
};
|
||||
];
|
||||
|
||||
private static string Result(string format, Func<ushort, byte> read, ref ushort addr)
|
||||
{
|
||||
//d immediately succeeds the opcode
|
||||
//n immediate succeeds the opcode and the displacement (if present)
|
||||
//nn immediately succeeds the opcode and the displacement (if present)
|
||||
|
||||
if (format.ContainsOrdinal("nn")) format = format.Replace("nn", $"{read(addr++) + (read(addr++) << 8):X4}h"); // LSB is read first
|
||||
if (format.ContainsOrdinal('n')) format = format.Replace("n", $"{read(addr++):X2}h");
|
||||
|
||||
format = format.Replace("+d", "d");
|
||||
if (format.ContainsOrdinal('d'))
|
||||
{
|
||||
var b = unchecked ((sbyte) read(addr++));
|
||||
format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h");
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
public static string Disassemble(ushort addr, Func<ushort, byte> read, out int size)
|
||||
{
|
||||
|
@ -430,7 +430,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed partial class Z80A<TLink> : IDisassemblable
|
||||
{
|
||||
public string Cpu
|
||||
{
|
||||
get => "Z80";
|
||||
|
@ -442,9 +445,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
public IEnumerable<string> AvailableCpus { get; } = [ "Z80" ];
|
||||
|
||||
public string Disassemble(MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
string ret = Disassemble((ushort)addr, a => m.PeekByte(a), out length);
|
||||
return ret;
|
||||
}
|
||||
=> Z80ADisassembler.Disassemble((ushort)addr, a => m.PeekByte(a), out length);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,24 +2,24 @@
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
public partial class Z80A<TLink>
|
||||
{
|
||||
public void Read_Func(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[dest] = _link.ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
}
|
||||
|
||||
public void Read_INC_Func(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[dest] = _link.ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
INC16_Func(src_l, src_h);
|
||||
}
|
||||
|
||||
public void Read_INC_TR_PC_Func(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest_h] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[dest_h] = _link.ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest_h];
|
||||
INC16_Func(src_l, src_h);
|
||||
TR16_Func(PCl, PCh, dest_l, dest_h);
|
||||
|
@ -28,46 +28,46 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
public void Write_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
_link.WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
}
|
||||
|
||||
public void Write_INC_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
_link.WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
INC16_Func(dest_l, dest_h);
|
||||
}
|
||||
|
||||
public void Write_DEC_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
_link.WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
DEC16_Func(dest_l, dest_h);
|
||||
}
|
||||
|
||||
public void Write_TR_PC_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
_link.WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
TR16_Func(PCl, PCh, Z, W);
|
||||
}
|
||||
|
||||
public void OUT_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
WriteHardware((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)(Regs[src]));
|
||||
_link.WriteHardware((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)(Regs[src]));
|
||||
}
|
||||
|
||||
public void OUT_INC_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
WriteHardware((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)(Regs[src]));
|
||||
_link.WriteHardware((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)(Regs[src]));
|
||||
INC16_Func(dest_l, dest_h);
|
||||
}
|
||||
|
||||
public void IN_Func(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest] = ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[dest] = _link.ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
|
||||
FlagZ = Regs[dest] == 0;
|
||||
|
@ -81,7 +81,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
|
||||
public void IN_INC_Func(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest] = ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[dest] = _link.ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
|
||||
FlagZ = Regs[dest] == 0;
|
||||
|
@ -97,7 +97,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
|
||||
public void IN_A_N_INC_Func(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest] = ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[dest] = _link.ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
INC16_Func(src_l, src_h);
|
||||
}
|
||||
|
@ -808,7 +808,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
|
||||
public void FTCH_DB_Func()
|
||||
{
|
||||
Regs[DB] = FetchDB();
|
||||
Regs[DB] = _link.FetchDB();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
public partial class Z80A<TLink>
|
||||
{
|
||||
// registers
|
||||
public ushort PCl = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
public partial class Z80A<TLink>
|
||||
{
|
||||
// this contains the vectors of instrcution operations
|
||||
// NOTE: This list is NOT confirmed accurate for each individual cycle
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
public partial class Z80A<TLink>
|
||||
{
|
||||
private void INT_OP_IND(ushort operation, ushort src_l, ushort src_h)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
|
@ -6,7 +7,7 @@ using BizHawk.Common.NumberExtensions;
|
|||
// Z80A CPU
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public sealed partial class Z80A
|
||||
public sealed partial class Z80A<TLink> where TLink : IZ80ALink
|
||||
{
|
||||
// operations that can take place in an instruction
|
||||
public const ushort IDLE = 0;
|
||||
|
@ -90,8 +91,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
public ushort Ztemp1, Ztemp2, Ztemp3, Ztemp4;
|
||||
public byte temp_R;
|
||||
|
||||
public Z80A()
|
||||
private TLink _link;
|
||||
|
||||
public Z80A(TLink link)
|
||||
{
|
||||
_link = link;
|
||||
Reset();
|
||||
InitTableParity();
|
||||
}
|
||||
|
@ -240,52 +244,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; set; }
|
||||
|
||||
// Memory Access
|
||||
public Func<ushort, byte> FetchMemory;
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
public Func<ushort, byte> PeekMemory;
|
||||
public Func<ushort, byte> DummyReadMemory;
|
||||
|
||||
// Hardware I/O Port Access
|
||||
public Func<ushort, byte> ReadHardware;
|
||||
public Action<ushort, byte> WriteHardware;
|
||||
|
||||
// Data Bus
|
||||
// Interrupting Devices are responsible for putting a value onto the data bus
|
||||
// for as long as the interrupt is valid
|
||||
public Func<byte> FetchDB;
|
||||
|
||||
//this only calls when the first byte of an instruction is fetched.
|
||||
public Action<ushort> OnExecFetch;
|
||||
|
||||
public void UnregisterMemoryMapper()
|
||||
{
|
||||
ReadMemory = null;
|
||||
WriteMemory = null;
|
||||
PeekMemory = null;
|
||||
DummyReadMemory = null;
|
||||
ReadHardware = null;
|
||||
WriteHardware = null;
|
||||
}
|
||||
|
||||
public void SetCallbacks
|
||||
(
|
||||
Func<ushort, byte> ReadMemory,
|
||||
Func<ushort, byte> DummyReadMemory,
|
||||
Func<ushort, byte> PeekMemory,
|
||||
Action<ushort, byte> WriteMemory,
|
||||
Func<ushort, byte> ReadHardware,
|
||||
Action<ushort, byte> WriteHardware
|
||||
)
|
||||
{
|
||||
this.ReadMemory = ReadMemory;
|
||||
this.DummyReadMemory = DummyReadMemory;
|
||||
this.PeekMemory = PeekMemory;
|
||||
this.WriteMemory = WriteMemory;
|
||||
this.ReadHardware = ReadHardware;
|
||||
this.WriteHardware = WriteHardware;
|
||||
}
|
||||
public void SetCpuLink(TLink link)
|
||||
=> _link = link;
|
||||
|
||||
// Execute instructions
|
||||
public void ExecuteOne()
|
||||
|
@ -302,9 +262,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
break;
|
||||
case OP_F:
|
||||
// Read the opcode of the next instruction
|
||||
OnExecFetch?.Invoke(RegPC);
|
||||
_link.OnExecFetch(RegPC);
|
||||
TraceCallback?.Invoke(State());
|
||||
opcode = FetchMemory(RegPC++);
|
||||
opcode = _link.FetchMemory(RegPC++);
|
||||
FetchInstruction();
|
||||
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
|
@ -521,7 +481,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
}
|
||||
|
||||
opcode = FetchMemory(RegPC++);
|
||||
opcode = _link.FetchMemory(RegPC++);
|
||||
FetchInstruction();
|
||||
instr_pntr = bus_pntr = mem_pntr = irq_pntr = 0;
|
||||
I_skip = true;
|
||||
|
@ -854,12 +814,12 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
int bytes_read = 0;
|
||||
|
||||
string disasm = disassemble ? Disassemble(RegPC, ReadMemory, out bytes_read) : "---";
|
||||
string disasm = disassemble ? Z80ADisassembler.Disassemble(RegPC, _link.ReadMemory, out bytes_read) : "---";
|
||||
string byte_code = null;
|
||||
|
||||
for (ushort i = 0; i < bytes_read; i++)
|
||||
{
|
||||
byte_code += $"{ReadMemory((ushort)(RegPC + i)):X2}";
|
||||
byte_code += $"{_link.ReadMemory((ushort)(RegPC + i)):X2}";
|
||||
if (i < (bytes_read - 1))
|
||||
{
|
||||
byte_code += " ";
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Cores.Calculators.Emu83
|
|||
LibEmu83.TI83_GetRegs(Context, regs);
|
||||
ushort PC = (ushort)regs[10];
|
||||
|
||||
string disasm = Z80A.Disassemble(PC, addr => LibEmu83.TI83_ReadMemory(Context, addr), out int bytes_read);
|
||||
string disasm = Z80ADisassembler.Disassemble(PC, addr => LibEmu83.TI83_ReadMemory(Context, addr), out int bytes_read);
|
||||
string byte_code = null;
|
||||
|
||||
for (ushort i = 0; i < bytes_read; i++)
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Calculators.Emu83
|
|||
|
||||
public override string Disassemble(MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
var ret = Z80A.Disassemble((ushort) addr, a => m.PeekByte(a), out var tmp);
|
||||
var ret = Z80ADisassembler.Disassemble((ushort) addr, a => m.PeekByte(a), out var tmp);
|
||||
length = tmp;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Calculators.TI83
|
||||
{
|
||||
public partial class TI83
|
||||
{
|
||||
public readonly struct CpuLink(TI83 ti83) : IZ80ALink
|
||||
{
|
||||
public byte FetchMemory(ushort address)
|
||||
=> ti83.ReadMemory(address);
|
||||
|
||||
public byte ReadMemory(ushort address)
|
||||
=> ti83.ReadMemory(address);
|
||||
|
||||
public void WriteMemory(ushort address, byte value)
|
||||
=> ti83.WriteMemory(address, value);
|
||||
|
||||
public byte ReadHardware(ushort address)
|
||||
=> ti83.ReadHardware(address);
|
||||
|
||||
public void WriteHardware(ushort address, byte value)
|
||||
=> ti83.WriteHardware(address, value);
|
||||
|
||||
public byte FetchDB()
|
||||
=> 0xFF;
|
||||
|
||||
public void OnExecFetch(ushort address)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,12 +19,12 @@ namespace BizHawk.Emulation.Cores.Calculators.TI83
|
|||
(addr) =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
return _cpu.ReadMemory((ushort)addr);
|
||||
return ReadMemory((ushort)addr);
|
||||
},
|
||||
(addr, value) =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
_cpu.WriteMemory((ushort)addr, value);
|
||||
WriteMemory((ushort)addr, value);
|
||||
}, 1);
|
||||
|
||||
domains.Add(systemBusDomain);
|
||||
|
|
|
@ -16,14 +16,12 @@ namespace BizHawk.Emulation.Cores.Calculators.TI83
|
|||
ServiceProvider = ser;
|
||||
PutSettings(lp.Settings ?? new TI83CommonSettings());
|
||||
|
||||
_cpu.FetchMemory = ReadMemory;
|
||||
_cpu.ReadMemory = ReadMemory;
|
||||
_cpu.WriteMemory = WriteMemory;
|
||||
_cpu.ReadHardware = ReadHardware;
|
||||
_cpu.WriteHardware = WriteHardware;
|
||||
_cpu.IRQCallback = IRQCallback;
|
||||
_cpu.NMICallback = NMICallback;
|
||||
_cpu.MemoryCallbacks = MemoryCallbacks;
|
||||
_cpu = new Z80A<CpuLink>(new CpuLink(this))
|
||||
{
|
||||
IRQCallback = IRQCallback,
|
||||
NMICallback = NMICallback,
|
||||
MemoryCallbacks = MemoryCallbacks
|
||||
};
|
||||
|
||||
_rom = lp.Comm.CoreFileProvider.GetFirmwareOrThrow(new("TI83", "Rom"));
|
||||
LinkPort = new TI83LinkPort(this);
|
||||
|
@ -41,7 +39,7 @@ namespace BizHawk.Emulation.Cores.Calculators.TI83
|
|||
|
||||
private readonly TraceBuffer _tracer;
|
||||
|
||||
private readonly Z80A _cpu = new Z80A();
|
||||
private readonly Z80A<CpuLink> _cpu;
|
||||
private readonly byte[] _rom;
|
||||
|
||||
// configuration
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||
{
|
||||
public partial class AmstradCPC
|
||||
{
|
||||
public readonly struct CpuLink(CPCBase machine) : IZ80ALink
|
||||
{
|
||||
public byte FetchMemory(ushort address)
|
||||
=> machine.ReadMemory(address);
|
||||
|
||||
public byte ReadMemory(ushort address)
|
||||
=> machine.ReadMemory(address);
|
||||
|
||||
public void WriteMemory(ushort address, byte value)
|
||||
=> machine.WriteMemory(address, value);
|
||||
|
||||
public byte ReadHardware(ushort address)
|
||||
=> machine.ReadPort(address);
|
||||
|
||||
public void WriteHardware(ushort address, byte value)
|
||||
=> machine.WritePort(address, value);
|
||||
|
||||
public byte FetchDB()
|
||||
=> machine.PushBus();
|
||||
|
||||
public void OnExecFetch(ushort address)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,12 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
ServiceProvider = ser;
|
||||
CoreComm = lp.Comm;
|
||||
_gameInfo = lp.Roms.Select(r => r.Game).ToList();
|
||||
_cpu = new Z80A();
|
||||
|
||||
_cpu = new Z80A<CpuLink>(default)
|
||||
{
|
||||
MemoryCallbacks = MemoryCallbacks
|
||||
};
|
||||
|
||||
_tracer = new TraceBuffer(_cpu.TraceHeader);
|
||||
_files = lp.Roms.Select(r => r.RomData).ToList();
|
||||
|
||||
|
@ -50,19 +55,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
throw new InvalidOperationException("Machine not yet emulated");
|
||||
}
|
||||
|
||||
_cpu.MemoryCallbacks = MemoryCallbacks;
|
||||
|
||||
HardReset = _machine.HardReset;
|
||||
SoftReset = _machine.SoftReset;
|
||||
|
||||
_cpu.FetchMemory = _machine.ReadMemory;
|
||||
_cpu.ReadMemory = _machine.ReadMemory;
|
||||
_cpu.WriteMemory = _machine.WriteMemory;
|
||||
_cpu.ReadHardware = _machine.ReadPort;
|
||||
_cpu.WriteHardware = _machine.WritePort;
|
||||
_cpu.FetchDB = _machine.PushBus;
|
||||
_cpu.SetCpuLink(new CpuLink(_machine));
|
||||
_cpu.IRQACKCallback = _machine.GateArray.IORQA;
|
||||
//_cpu.OnExecFetch = _machine.CPUMon.OnExecFetch;
|
||||
|
||||
ser.Register<ITraceable>(_tracer);
|
||||
ser.Register<IDisassemblable>(_cpu);
|
||||
|
@ -97,7 +94,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
public Action HardReset;
|
||||
public Action SoftReset;
|
||||
|
||||
private readonly Z80A _cpu;
|
||||
private readonly Z80A<CpuLink> _cpu;
|
||||
private readonly TraceBuffer _tracer;
|
||||
public IController _controller;
|
||||
public CPCBase _machine;
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
public sealed class DatacorderDevice
|
||||
{
|
||||
private CPCBase _machine;
|
||||
private Z80A _cpu => _machine.CPU;
|
||||
private Z80A<AmstradCPC.CpuLink> _cpu => _machine.CPU;
|
||||
private IBeeperDevice _buzzer => _machine.TapeBuzzer;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
public class AmstradGateArray : IPortIODevice, IVideoProvider
|
||||
{
|
||||
private readonly CPCBase _machine;
|
||||
private Z80A CPU => _machine.CPU;
|
||||
private Z80A<AmstradCPC.CpuLink> CPU => _machine.CPU;
|
||||
private CRCT_6845 CRCT => _machine.CRCT;
|
||||
//private CRTDevice CRT => _machine.CRT;
|
||||
private IPSG PSG => _machine.AYDevice;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public CPC464(AmstradCPC cpc, Z80A cpu, List<byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
|
||||
public CPC464(AmstradCPC cpc, Z80A<AmstradCPC.CpuLink> cpu, List<byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
|
||||
{
|
||||
CPC = cpc;
|
||||
CPU = cpu;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public CPC6128(AmstradCPC cpc, Z80A cpu, List<byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
|
||||
public CPC6128(AmstradCPC cpc, Z80A<AmstradCPC.CpuLink> cpu, List<byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
|
||||
{
|
||||
CPC = cpc;
|
||||
CPU = cpu;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// <summary>
|
||||
/// Reference to the instantiated Z80 cpu (piped in via constructor)
|
||||
/// </summary>
|
||||
public Z80A CPU { get; set; }
|
||||
public Z80A<AmstradCPC.CpuLink> CPU { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ROM and extended info
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
public int FrameLength = 79872;
|
||||
|
||||
private readonly CPCBase _machine;
|
||||
private Z80A CPU => _machine.CPU;
|
||||
private Z80A<AmstradCPC.CpuLink> CPU => _machine.CPU;
|
||||
private CRCT_6845 CRCT => _machine.CRCT;
|
||||
private IPSG PSG => _machine.AYDevice;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public sealed class DatacorderDevice : IPortIODevice
|
||||
{
|
||||
private SpectrumBase _machine { get; set; }
|
||||
private Z80A _cpu { get; set; }
|
||||
private Z80A<ZXSpectrum.CpuLink> _cpu { get; set; }
|
||||
private OneBitBeeper _buzzer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public class CPUMonitor
|
||||
{
|
||||
private readonly SpectrumBase _machine;
|
||||
private readonly Z80A _cpu;
|
||||
private readonly Z80A<ZXSpectrum.CpuLink> _cpu;
|
||||
public MachineType machineType = MachineType.ZXSpectrum48;
|
||||
|
||||
/// <summary>
|
||||
|
@ -131,17 +131,17 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
addr = (ushort)(_cpu.Regs[_cpu.R] | _cpu.Regs[_cpu.I] << 8);
|
||||
break;
|
||||
// BC
|
||||
case Z80A.BIO1:
|
||||
case Z80A.BIO2:
|
||||
case Z80A.BIO3:
|
||||
case Z80A.BIO4:
|
||||
case Z80A<ZXSpectrum.CpuLink>.BIO1:
|
||||
case Z80A<ZXSpectrum.CpuLink>.BIO2:
|
||||
case Z80A<ZXSpectrum.CpuLink>.BIO3:
|
||||
case Z80A<ZXSpectrum.CpuLink>.BIO4:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.C] | _cpu.Regs[_cpu.B] << 8);
|
||||
break;
|
||||
// WZ
|
||||
case Z80A.WIO1:
|
||||
case Z80A.WIO2:
|
||||
case Z80A.WIO3:
|
||||
case Z80A.WIO4:
|
||||
case Z80A<ZXSpectrum.CpuLink>.WIO1:
|
||||
case Z80A<ZXSpectrum.CpuLink>.WIO2:
|
||||
case Z80A<ZXSpectrum.CpuLink>.WIO3:
|
||||
case Z80A<ZXSpectrum.CpuLink>.WIO4:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.Z] | _cpu.Regs[_cpu.W] << 8);
|
||||
break;
|
||||
}
|
||||
|
@ -160,28 +160,28 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
switch (BUSRQ)
|
||||
{
|
||||
// BC: T1
|
||||
case Z80A.BIO1:
|
||||
case Z80A<ZXSpectrum.CpuLink>.BIO1:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(1))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// BC: T2
|
||||
case Z80A.BIO2:
|
||||
case Z80A<ZXSpectrum.CpuLink>.BIO2:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(2))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// BC: T3
|
||||
case Z80A.BIO3:
|
||||
case Z80A<ZXSpectrum.CpuLink>.BIO3:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(3))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// BC: T4
|
||||
case Z80A.BIO4:
|
||||
case Z80A<ZXSpectrum.CpuLink>.BIO4:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(4))
|
||||
|
@ -189,28 +189,28 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
break;
|
||||
|
||||
// WZ: T1
|
||||
case Z80A.WIO1:
|
||||
case Z80A<ZXSpectrum.CpuLink>.WIO1:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(1))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// WZ: T2
|
||||
case Z80A.WIO2:
|
||||
case Z80A<ZXSpectrum.CpuLink>.WIO2:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(2))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// WZ: T3
|
||||
case Z80A.WIO3:
|
||||
case Z80A<ZXSpectrum.CpuLink>.WIO3:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(3))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// WZ: T4
|
||||
case Z80A.WIO4:
|
||||
case Z80A<ZXSpectrum.CpuLink>.WIO4:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(4))
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public Pentagon128(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
public Pentagon128(ZXSpectrum spectrum, Z80A<ZXSpectrum.CpuLink> cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
{
|
||||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Reference to the instantiated Z80 cpu (piped in via constructor)
|
||||
/// </summary>
|
||||
public Z80A CPU { get; set; }
|
||||
public Z80A<ZXSpectrum.CpuLink> CPU { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ROM and extended info
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public ZX128(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
public ZX128(ZXSpectrum spectrum, Z80A<ZXSpectrum.CpuLink> cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
{
|
||||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public ZX128Plus2(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
public ZX128Plus2(ZXSpectrum spectrum, Z80A<ZXSpectrum.CpuLink> cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
: base(spectrum, cpu, borderType, files, joysticks)
|
||||
{
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public ZX128Plus2a(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
public ZX128Plus2a(ZXSpectrum spectrum, Z80A<ZXSpectrum.CpuLink> cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
{
|
||||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public ZX128Plus3(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
public ZX128Plus3(ZXSpectrum spectrum, Z80A<ZXSpectrum.CpuLink> cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
{
|
||||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public ZX16(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
public ZX16(ZXSpectrum spectrum, Z80A<ZXSpectrum.CpuLink> cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
: base(spectrum, cpu, borderType, files, joysticks)
|
||||
{
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
public ZX48(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
public ZX48(ZXSpectrum spectrum, Z80A<ZXSpectrum.CpuLink> cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||
{
|
||||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
{
|
||||
private readonly SpectrumBase _machine;
|
||||
|
||||
private Z80A _cpu => _machine.CPU;
|
||||
private Z80A<ZXSpectrum.CpuLink> _cpu => _machine.CPU;
|
||||
|
||||
private SZX(SpectrumBase machine)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
public partial class ZXSpectrum
|
||||
{
|
||||
public readonly struct CpuLink(ZXSpectrum spectrum, SpectrumBase machine) : IZ80ALink
|
||||
{
|
||||
public byte FetchMemory(ushort address)
|
||||
=> machine.ReadMemory(address);
|
||||
|
||||
public byte ReadMemory(ushort address)
|
||||
=> spectrum._cdl == null
|
||||
? machine.ReadMemory(address)
|
||||
: spectrum.ReadMemory_CDL(address);
|
||||
|
||||
public void WriteMemory(ushort address, byte value)
|
||||
=> machine.WriteMemory(address, value);
|
||||
|
||||
public byte ReadHardware(ushort address)
|
||||
=> machine.ReadPort(address);
|
||||
|
||||
public void WriteHardware(ushort address, byte value)
|
||||
=> machine.WritePort(address, value);
|
||||
|
||||
public byte FetchDB()
|
||||
=> machine.PushBus();
|
||||
|
||||
public void OnExecFetch(ushort address)
|
||||
=> machine.CPUMon.OnExecFetch(address);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,14 +15,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public void SetCDL(ICodeDataLog cdl)
|
||||
{
|
||||
_cdl = cdl;
|
||||
if (cdl == null || !cdl.Active)
|
||||
{
|
||||
_cpu.ReadMemory = _machine.ReadMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cpu.ReadMemory = ReadMemory_CDL;
|
||||
}
|
||||
}
|
||||
|
||||
public void NewCDL(ICodeDataLog cdl)
|
||||
|
|
|
@ -27,7 +27,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
_gameInfo = lp.Roms.Select(r => r.Game).ToList();
|
||||
|
||||
_cpu = new Z80A();
|
||||
_cpu = new Z80A<CpuLink>(default)
|
||||
{
|
||||
MemoryCallbacks = MemoryCallbacks
|
||||
};
|
||||
|
||||
_tracer = new TraceBuffer(_cpu.TraceHeader);
|
||||
|
||||
|
@ -94,18 +97,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
throw new InvalidOperationException("Machine not yet emulated");
|
||||
}
|
||||
|
||||
_cpu.MemoryCallbacks = MemoryCallbacks;
|
||||
|
||||
HardReset = _machine.HardReset;
|
||||
SoftReset = _machine.SoftReset;
|
||||
|
||||
_cpu.FetchMemory = _machine.ReadMemory;
|
||||
_cpu.ReadMemory = _machine.ReadMemory;
|
||||
_cpu.WriteMemory = _machine.WriteMemory;
|
||||
_cpu.ReadHardware = _machine.ReadPort;
|
||||
_cpu.WriteHardware = _machine.WritePort;
|
||||
_cpu.FetchDB = _machine.PushBus;
|
||||
_cpu.OnExecFetch = _machine.CPUMon.OnExecFetch;
|
||||
_cpu.SetCpuLink(new CpuLink(this, _machine));
|
||||
|
||||
ser.Register<ITraceable>(_tracer);
|
||||
ser.Register<IDisassemblable>(_cpu);
|
||||
|
@ -147,7 +142,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public Action HardReset;
|
||||
public Action SoftReset;
|
||||
|
||||
private readonly Z80A _cpu;
|
||||
private readonly Z80A<CpuLink> _cpu;
|
||||
private readonly TraceBuffer _tracer;
|
||||
public IController _controller;
|
||||
public SpectrumBase _machine;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
public partial class ColecoVision
|
||||
{
|
||||
public readonly struct CpuLink(ColecoVision coleco) : IZ80ALink
|
||||
{
|
||||
public byte FetchMemory(ushort address)
|
||||
=> coleco.ReadMemory(address);
|
||||
|
||||
public byte ReadMemory(ushort address)
|
||||
=> coleco.ReadMemory(address);
|
||||
|
||||
public void WriteMemory(ushort address, byte value)
|
||||
=> coleco.WriteMemory(address, value);
|
||||
|
||||
public byte ReadHardware(ushort address)
|
||||
=> coleco.ReadPort(address);
|
||||
|
||||
public void WriteHardware(ushort address, byte value)
|
||||
=> coleco.WritePort(address, value);
|
||||
|
||||
public byte FetchDB()
|
||||
=> 0xFF;
|
||||
|
||||
public void OnExecFetch(ushort address)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,12 +19,12 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
addr =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
return _cpu.ReadMemory((ushort)addr);
|
||||
return ReadMemory((ushort)addr);
|
||||
},
|
||||
(addr, value) =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
_cpu.WriteMemory((ushort)addr, value);
|
||||
WriteMemory((ushort)addr, value);
|
||||
}, 1)
|
||||
};
|
||||
|
||||
|
|
|
@ -17,13 +17,8 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
_syncSettings = syncSettings ?? new ColecoSyncSettings();
|
||||
bool skipBios = _syncSettings.SkipBiosIntro;
|
||||
|
||||
_cpu = new Z80A
|
||||
_cpu = new Z80A<CpuLink>(new CpuLink(this))
|
||||
{
|
||||
FetchMemory = ReadMemory,
|
||||
ReadMemory = ReadMemory,
|
||||
WriteMemory = WriteMemory,
|
||||
ReadHardware = ReadPort,
|
||||
WriteHardware = WritePort,
|
||||
MemoryCallbacks = MemoryCallbacks
|
||||
};
|
||||
|
||||
|
@ -60,7 +55,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
ser.Register<ITraceable>(_tracer = new TraceBuffer(_cpu.TraceHeader));
|
||||
}
|
||||
|
||||
private readonly Z80A _cpu;
|
||||
private readonly Z80A<CpuLink> _cpu;
|
||||
private readonly TMS9918A _vdp;
|
||||
private readonly byte[] _biosRom;
|
||||
private readonly TraceBuffer _tracer;
|
||||
|
|
|
@ -448,9 +448,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
}
|
||||
}
|
||||
|
||||
private readonly Z80A Cpu;
|
||||
private readonly Z80A<ColecoVision.CpuLink> Cpu;
|
||||
|
||||
public TMS9918A(Z80A cpu)
|
||||
public TMS9918A(Z80A<ColecoVision.CpuLink> cpu)
|
||||
{
|
||||
Cpu = cpu;
|
||||
}
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
using System.IO;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
|
||||
{
|
||||
public sealed partial class GGHawkLink : ICodeDataLogger
|
||||
{
|
||||
public void SetCDL(ICodeDataLog cdl)
|
||||
{
|
||||
CDL = cdl;
|
||||
if (cdl == null)
|
||||
{
|
||||
L.Cpu.ReadMemory = L.ReadMemory;
|
||||
L.Cpu.WriteMemory = L.WriteMemory;
|
||||
L.Cpu.FetchMemory = L.FetchMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
L.Cpu.ReadMemory = ReadMemory_CDL;
|
||||
L.Cpu.WriteMemory = L.WriteMemory;
|
||||
L.Cpu.FetchMemory = FetchMemory_CDL;
|
||||
}
|
||||
}
|
||||
|
||||
public void NewCDL(ICodeDataLog cdl)
|
||||
{
|
||||
void AddIfExists(string name)
|
||||
{
|
||||
var found = _memoryDomains[name];
|
||||
if (found is not null) cdl[name] = new byte[found.Size];
|
||||
}
|
||||
cdl["ROM"] = new byte[_memoryDomains["ROM"]!.Size];
|
||||
cdl["Main RAM"] = new byte[_memoryDomains["Main RAM"]!.Size];
|
||||
AddIfExists("Save RAM");
|
||||
AddIfExists("Cart (Volatile) RAM");
|
||||
cdl.SubType = "SMS";
|
||||
cdl.SubVer = 0;
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void DisassembleCDL(Stream s, ICodeDataLog cdl)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
private enum CDLog_AddrType
|
||||
{
|
||||
None,
|
||||
ROM,
|
||||
MainRAM,
|
||||
SaveRAM,
|
||||
CartRAM, //"Cart (Volatile) RAM" aka ExtRam
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum CDLog_Flags
|
||||
{
|
||||
ExecFirst = 0x01,
|
||||
ExecOperand = 0x02,
|
||||
Data = 0x04
|
||||
}
|
||||
|
||||
private ICodeDataLog CDL;
|
||||
|
||||
private void RunCDL(ushort address, CDLog_Flags flags)
|
||||
{
|
||||
if (L.MapMemory != null)
|
||||
{
|
||||
SMS.CDLog_MapResults results = L.MapMemory(address, false);
|
||||
switch (results.Type)
|
||||
{
|
||||
case SMS.CDLog_AddrType.None: break;
|
||||
case SMS.CDLog_AddrType.ROM: CDL["ROM"][results.Address] |= (byte)flags; break;
|
||||
case SMS.CDLog_AddrType.MainRAM: CDL["Main RAM"][results.Address] |= (byte)flags; break;
|
||||
case SMS.CDLog_AddrType.SaveRAM: CDL["Save RAM"][results.Address] |= (byte)flags; break;
|
||||
case SMS.CDLog_AddrType.CartRAM: CDL["Cart (Volatile) RAM"][results.Address] |= (byte)flags; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper for FetchMemory which inserts CDL logic
|
||||
/// </summary>
|
||||
private byte FetchMemory_CDL(ushort address)
|
||||
{
|
||||
RunCDL(address, CDLog_Flags.ExecFirst);
|
||||
return L.ReadMemory(address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper for ReadMemory which inserts CDL logic
|
||||
/// </summary>
|
||||
private byte ReadMemory_CDL(ushort address)
|
||||
{
|
||||
RunCDL(address, CDLog_Flags.Data);
|
||||
return L.ReadMemory(address);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,6 +41,7 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
|
|||
L = new SMS(lp.Comm, lp.Roms[0].Game, lp.Roms[0].RomData, temp_set_L, temp_sync_L);
|
||||
R = new SMS(lp.Comm, lp.Roms[1].Game, lp.Roms[1].RomData, temp_set_R, temp_sync_R);
|
||||
|
||||
ser.Register<ICodeDataLogger>(L);
|
||||
ser.Register<IVideoProvider>(this);
|
||||
ser.Register<ISoundProvider>(this);
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public partial class SMS
|
||||
{
|
||||
public readonly struct CpuLink(SMS sms) : IZ80ALink
|
||||
{
|
||||
public byte FetchMemory(ushort address)
|
||||
=> sms.CDL is null
|
||||
? sms.FetchMemory(address)
|
||||
: sms.FetchMemory_CDL(address);
|
||||
|
||||
public byte ReadMemory(ushort address)
|
||||
=> sms.CDL is null
|
||||
? sms.ReadMemory(address)
|
||||
: sms.ReadMemory_CDL(address);
|
||||
|
||||
public void WriteMemory(ushort address, byte value)
|
||||
=> sms.WriteMemory(address, value);
|
||||
|
||||
public byte ReadHardware(ushort address)
|
||||
=> sms.ReadPort(address);
|
||||
|
||||
public void WriteHardware(ushort address, byte value)
|
||||
=> sms.WritePort(address, value);
|
||||
|
||||
public byte FetchDB()
|
||||
=> 0xFF;
|
||||
|
||||
public void OnExecFetch(ushort address)
|
||||
=> sms.OnExecMemory(address);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,18 +8,6 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
public void SetCDL(ICodeDataLog cdl)
|
||||
{
|
||||
CDL = cdl;
|
||||
if (cdl == null)
|
||||
{
|
||||
Cpu.ReadMemory = ReadMemory;
|
||||
Cpu.WriteMemory = WriteMemory;
|
||||
Cpu.FetchMemory = FetchMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cpu.ReadMemory = ReadMemory_CDL;
|
||||
Cpu.WriteMemory = WriteMemory;
|
||||
Cpu.FetchMemory = FetchMemory_CDL;
|
||||
}
|
||||
}
|
||||
|
||||
public void NewCDL(ICodeDataLog cdl)
|
||||
|
|
|
@ -19,12 +19,12 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
(addr) =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
return Cpu.ReadMemory((ushort)addr);
|
||||
return ReadMemory((ushort)addr);
|
||||
},
|
||||
(addr, value) =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
Cpu.WriteMemory((ushort)addr, value);
|
||||
WriteMemory((ushort)addr, value);
|
||||
}, 1)
|
||||
};
|
||||
|
||||
|
|
|
@ -77,17 +77,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
HasYM2413 = true;
|
||||
}
|
||||
|
||||
Cpu = new Z80A
|
||||
Cpu = new Z80A<CpuLink>(new CpuLink(this))
|
||||
{
|
||||
ReadHardware = ReadPort,
|
||||
WriteHardware = WritePort,
|
||||
FetchMemory = FetchMemory,
|
||||
ReadMemory = ReadMemory,
|
||||
WriteMemory = WriteMemory,
|
||||
MemoryCallbacks = MemoryCallbacks,
|
||||
OnExecFetch = OnExecMemory
|
||||
MemoryCallbacks = MemoryCallbacks
|
||||
};
|
||||
|
||||
|
||||
// set this before turning off GG system for GG_in_SMS games
|
||||
bool sms_reg_compat = !IsGameGear && (_region == SmsSyncSettings.Regions.Japan);
|
||||
|
||||
|
@ -209,9 +203,6 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
ser.Register<IStatable>(new StateSerializer(SyncState));
|
||||
Vdp.ProcessOverscan();
|
||||
|
||||
Cpu.ReadMemory = ReadMemory;
|
||||
Cpu.WriteMemory = WriteMemory;
|
||||
|
||||
// Z80 SP initialization
|
||||
// stops a few SMS and GG games from crashing
|
||||
Cpu.Regs[Cpu.SPl] = 0xF0;
|
||||
|
@ -246,7 +237,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
private readonly byte[] BiosRom;
|
||||
|
||||
// Machine resources
|
||||
public Z80A Cpu;
|
||||
public Z80A<CpuLink> Cpu;
|
||||
public byte[] SystemRam;
|
||||
public VDP Vdp;
|
||||
public SN76489sms PSG;
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
private readonly SMS Sms;
|
||||
private readonly VdpMode mode;
|
||||
public DisplayType DisplayType = DisplayType.NTSC;
|
||||
private readonly Z80A Cpu;
|
||||
private readonly Z80A<SMS.CpuLink> Cpu;
|
||||
|
||||
public bool SpriteLimit;
|
||||
public int IPeriod = 228;
|
||||
|
@ -91,7 +91,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
private static readonly byte[] SMSPalXlatTable = { 0, 85, 170, 255 };
|
||||
private static readonly byte[] GGPalXlatTable = { 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 };
|
||||
|
||||
public VDP(SMS sms, Z80A cpu, VdpMode mode, DisplayType displayType, bool region_compat)
|
||||
public VDP(SMS sms, Z80A<SMS.CpuLink> cpu, VdpMode mode, DisplayType displayType, bool region_compat)
|
||||
{
|
||||
Sms = sms;
|
||||
Cpu = cpu;
|
||||
|
|
Loading…
Reference in New Issue