Fixes/cleanups C# for GPGX (mainly for SMS/GG mode)
This commit is contained in:
parent
1b742cf356
commit
e9af682975
|
@ -280,6 +280,8 @@ namespace BizHawk.Emulation.Common
|
|||
var jp_mcd_beta = File("F30D109D1C2F7C9FEAF38600C65834261DB73D1F", 131072, "MCD_jp_beta.bin", "Mega CD JP (Beta)");
|
||||
var eu_mcd_221 = File("9DE4EDA59F544DB2D5FD7E6514601F7B648D8EB4", 131072, "MCD_eu_221.bin", "Mega CD EU (v2.21)");
|
||||
|
||||
FirmwareAndOption("1C470A9A8D0B211C5FEEA1C1C2376AA1F7934B16", 4096, "GEN", "TMSS", "TMSS.md", "Mega Drive TMSS Boot Rom (Japan)");
|
||||
|
||||
Firmware("GEN", "CD_BIOS_EU", "Mega CD Bios (Europe)");
|
||||
Firmware("GEN", "CD_BIOS_JP", "Mega CD Bios (Japan)");
|
||||
Firmware("GEN", "CD_BIOS_US", "Sega CD Bios (USA)");
|
||||
|
|
|
@ -11,20 +11,19 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
{
|
||||
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
|
||||
{
|
||||
LibGPGX.RegisterInfo[] regs = new LibGPGX.RegisterInfo[Core.gpgx_getmaxnumregs()];
|
||||
|
||||
int n = Core.gpgx_getregs(regs);
|
||||
var regs = new LibGPGX.RegisterInfo[Core.gpgx_getmaxnumregs()];
|
||||
var n = Core.gpgx_getregs(regs);
|
||||
if (n > regs.Length)
|
||||
throw new InvalidOperationException("A buffer overrun has occured!");
|
||||
var ret = new Dictionary<string, RegisterValue>();
|
||||
using (_elf.EnterExit())
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
for (var i = 0; i < n; i++)
|
||||
{
|
||||
// el hacko
|
||||
string name = Marshal.PtrToStringAnsi(regs[i].Name);
|
||||
var name = Marshal.PtrToStringAnsi(regs[i].Name);
|
||||
byte size = 32;
|
||||
if (name.Contains("68K SR") || name.StartsWithOrdinal("Z80"))
|
||||
if (name!.Contains("68K SR") || name.StartsWithOrdinal("Z80"))
|
||||
size = 16;
|
||||
|
||||
ret[name] = new RegisterValue((ulong)regs[i].Value, size);
|
||||
|
@ -40,17 +39,28 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks => _memoryCallbacks;
|
||||
public IMemoryCallbackSystem MemoryCallbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SystemId == VSystemID.Raw.GEN)
|
||||
{
|
||||
return _memoryCallbacks;
|
||||
}
|
||||
|
||||
public bool CanStep(StepType type) { return false; }
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanStep(StepType type) => false;
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void Step(StepType type) { throw new NotImplementedException(); }
|
||||
public void Step(StepType type) => throw new NotImplementedException();
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public long TotalExecutedCycles => throw new NotImplementedException();
|
||||
|
||||
private readonly MemoryCallbackSystem _memoryCallbacks = new MemoryCallbackSystem(new[] { "M68K BUS" });
|
||||
private readonly MemoryCallbackSystem _memoryCallbacks = new(new[] { "M68K BUS" });
|
||||
|
||||
private LibGPGX.mem_cb ExecCallback;
|
||||
private LibGPGX.mem_cb ReadCallback;
|
||||
|
@ -59,30 +69,30 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
private void InitMemCallbacks()
|
||||
{
|
||||
ExecCallback = new LibGPGX.mem_cb(a =>
|
||||
ExecCallback = a =>
|
||||
{
|
||||
if (MemoryCallbacks.HasExecutes)
|
||||
{
|
||||
uint flags = (uint)MemoryCallbackFlags.AccessExecute;
|
||||
const uint flags = (uint)MemoryCallbackFlags.AccessExecute;
|
||||
MemoryCallbacks.CallMemoryCallbacks(a, 0, flags, "M68K BUS");
|
||||
}
|
||||
});
|
||||
ReadCallback = new LibGPGX.mem_cb(a =>
|
||||
};
|
||||
ReadCallback = a =>
|
||||
{
|
||||
if (MemoryCallbacks.HasReads)
|
||||
{
|
||||
uint flags = (uint)MemoryCallbackFlags.AccessRead;
|
||||
const uint flags = (uint)MemoryCallbackFlags.AccessRead;
|
||||
MemoryCallbacks.CallMemoryCallbacks(a, 0, flags, "M68K BUS");
|
||||
}
|
||||
});
|
||||
WriteCallback = new LibGPGX.mem_cb(a =>
|
||||
};
|
||||
WriteCallback = a =>
|
||||
{
|
||||
if (MemoryCallbacks.HasWrites)
|
||||
{
|
||||
uint flags = (uint)MemoryCallbackFlags.AccessWrite;
|
||||
const uint flags = (uint)MemoryCallbackFlags.AccessWrite;
|
||||
MemoryCallbacks.CallMemoryCallbacks(a, 0, flags, "M68K BUS");
|
||||
}
|
||||
});
|
||||
};
|
||||
_memoryCallbacks.ActiveChanged += RefreshMemCallbacks;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
continue;
|
||||
var name = Marshal.PtrToStringAnsi(pName)!;
|
||||
|
||||
var endian = name == "Z80 RAM"
|
||||
// typically Genesis domains will be 2 bytes large (and thus big endian and byteswapped)
|
||||
var oneByteWidth = name is "Z80 RAM" or "Main RAM" or "ROM" or "Cart (Volatile) RAM" or "SRAM";
|
||||
|
||||
var endian = oneByteWidth
|
||||
? MemoryDomain.Endian.Little
|
||||
: MemoryDomain.Endian.Big;
|
||||
|
||||
|
@ -33,44 +36,86 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
{
|
||||
// vram pokes need to go through hook which invalidates cached tiles
|
||||
var p = (byte*)area;
|
||||
mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
using (_elf.EnterExit())
|
||||
return p![addr ^ 1];
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
Core.gpgx_poke_vram((int)addr ^ 1, val);
|
||||
},
|
||||
wordSize: 2));
|
||||
if (SystemId == VSystemID.Raw.GEN)
|
||||
{
|
||||
// Genesis has more VRAM, and GPGX byteswaps it
|
||||
mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
using (_elf.EnterExit())
|
||||
return p![addr ^ 1];
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
Core.gpgx_poke_vram((int)addr ^ 1, val);
|
||||
},
|
||||
wordSize: 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
if (addr is < 0 or > 0x3FFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
using (_elf.EnterExit())
|
||||
return p![addr];
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
if (addr is < 0 or > 0x3FFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
Core.gpgx_poke_vram((int)addr, val);
|
||||
},
|
||||
wordSize: 1));
|
||||
}
|
||||
}
|
||||
else if (name == "CRAM")
|
||||
{
|
||||
// CRAM in the core is internally a different format than what it is natively
|
||||
// this internal format isn't really useful, so let's convert it back
|
||||
var p = (byte*)area;
|
||||
mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
if (addr is < 0 or > 0x7F) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
using (_elf.EnterExit())
|
||||
if (SystemId == VSystemID.Raw.GEN)
|
||||
{
|
||||
// CRAM for Genesis in the core is internally a different format than what it is natively
|
||||
// this internal format isn't really useful, so let's convert it back
|
||||
mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
var c = *(ushort*)&p![addr & ~1];
|
||||
c = (ushort)(((c & 0x1C0) << 3) | ((c & 0x038) << 2) | ((c & 0x007) << 1));
|
||||
return (byte)((addr & 1) != 0 ? c & 0xFF : c >> 8);
|
||||
}
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
if (addr is < 0 or > 0x7F) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
Core.gpgx_poke_cram((int)addr, val);
|
||||
},
|
||||
wordSize: 2));
|
||||
if (addr is < 0 or > 0x7F) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
using (_elf.EnterExit())
|
||||
{
|
||||
var c = *(ushort*)&p![addr & ~1];
|
||||
c = (ushort)(((c & 0x1C0) << 3) | ((c & 0x038) << 2) | ((c & 0x007) << 1));
|
||||
return (byte)((addr & 1) != 0 ? c & 0xFF : c >> 8);
|
||||
}
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
if (addr is < 0 or > 0x7F) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
Core.gpgx_poke_cram((int)addr, val);
|
||||
},
|
||||
wordSize: 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
if (addr is < 0 or > 0x3F) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
using (_elf.EnterExit())
|
||||
{
|
||||
var c = *(ushort*)&p![addr & ~1];
|
||||
return (byte)((addr & 1) != 0 ? c & 0xFF : c >> 8);
|
||||
}
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
if (addr is < 0 or > 0x3F) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
|
||||
Core.gpgx_poke_cram((int)addr, val);
|
||||
},
|
||||
wordSize: 2));
|
||||
}
|
||||
}
|
||||
else if (name.Contains("Z80"))
|
||||
else if (oneByteWidth)
|
||||
{
|
||||
mm.Add(new MemoryDomainIntPtrMonitor(name, endian, area, size, true, 1, _elf));
|
||||
}
|
||||
|
@ -79,44 +124,64 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
mm.Add(new MemoryDomainIntPtrSwap16Monitor(name, endian, area, size, true, _elf));
|
||||
}
|
||||
}
|
||||
var m68Bus = new MemoryDomainDelegate("M68K BUS", 0x1000000, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
return Core.gpgx_peek_m68k_bus(a);
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
Core.gpgx_write_m68k_bus(a, val);
|
||||
}, 2);
|
||||
|
||||
mm.Add(m68Bus);
|
||||
|
||||
if (IsMegaCD)
|
||||
MemoryDomain systemBus;
|
||||
if (SystemId == VSystemID.Raw.GEN)
|
||||
{
|
||||
var s68Bus = new MemoryDomainDelegate("S68K BUS", 0x1000000, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
return Core.gpgx_peek_s68k_bus(a);
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
Core.gpgx_write_s68k_bus(a, val);
|
||||
}, 2);
|
||||
systemBus = new MemoryDomainDelegate("M68K BUS", 0x1000000, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
return Core.gpgx_peek_m68k_bus(a);
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
Core.gpgx_write_m68k_bus(a, val);
|
||||
}, 2);
|
||||
|
||||
mm.Add(systemBus);
|
||||
|
||||
mm.Add(s68Bus);
|
||||
if (IsMegaCD)
|
||||
{
|
||||
var s68Bus = new MemoryDomainDelegate("S68K BUS", 0x1000000, MemoryDomain.Endian.Big,
|
||||
addr =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
return Core.gpgx_peek_s68k_bus(a);
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
Core.gpgx_write_s68k_bus(a, val);
|
||||
}, 2);
|
||||
|
||||
mm.Add(s68Bus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
systemBus = new MemoryDomainDelegate("Z80 BUS", 0x10000, MemoryDomain.Endian.Little,
|
||||
addr =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
return Core.gpgx_peek_z80_bus(a);
|
||||
},
|
||||
(addr, val) =>
|
||||
{
|
||||
var a = (uint)addr;
|
||||
if (a > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), a, message: "address out of range");
|
||||
Core.gpgx_write_z80_bus(a, val);
|
||||
}, 1);
|
||||
}
|
||||
mm.Add(_elf.GetPagesDomain());
|
||||
|
||||
_memoryDomains = new MemoryDomainList(mm) { SystemBus = m68Bus };
|
||||
mm.Add(_elf.GetPagesDomain());
|
||||
_memoryDomains = new MemoryDomainList(mm) { SystemBus = systemBus };
|
||||
((BasicServiceProvider) ServiceProvider).Register(_memoryDomains);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,7 +263,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
[DefaultValue(LibGPGX.Region.Autodetect)]
|
||||
public LibGPGX.Region Region { get; set; }
|
||||
|
||||
[DisplayName("[SMS/GG] Load BIOS")]
|
||||
[DisplayName("Load BIOS")]
|
||||
[Description("Indicates whether to load the system BIOS rom.")]
|
||||
[DefaultValue(false)]
|
||||
public bool LoadBIOS { get; set; }
|
||||
|
|
|
@ -104,6 +104,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
var initSettings = _syncSettings.GetNativeSettings(lp.Game);
|
||||
var initResult = Core.gpgx_init(romExtension, LoadCallback, ref initSettings);
|
||||
|
||||
// if a firmware request failed and we're recording a movie, fail now
|
||||
// we should do this as to enforce the sync settings of the movie
|
||||
// init might still work fine, so don't throw for more casual users
|
||||
if (_firmwareRequestFailed && lp.DeterministicEmulationRequested)
|
||||
{
|
||||
throw new MissingFirmwareException("A GPGX firmware request failed in deterministic mode.");
|
||||
}
|
||||
|
||||
if (!initResult)
|
||||
{
|
||||
throw new Exception($"{nameof(Core.gpgx_init)}() failed");
|
||||
|
@ -183,6 +191,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
private bool _disposed = false;
|
||||
|
||||
private LibGPGX.load_archive_cb LoadCallback;
|
||||
private bool _firmwareRequestFailed;
|
||||
|
||||
private readonly LibGPGX.InputData input = new LibGPGX.InputData();
|
||||
|
||||
|
@ -252,6 +261,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
FirmwareID? firmwareID = filename switch
|
||||
{
|
||||
"MD_BIOS" => new(system: VSystemID.Raw.GEN, firmware: "TMSS"),
|
||||
"CD_BIOS_EU" => new(system: VSystemID.Raw.GEN, firmware: "CD_BIOS_EU"),
|
||||
"CD_BIOS_JP" => new(system: VSystemID.Raw.GEN, firmware: "CD_BIOS_JP"),
|
||||
"CD_BIOS_US" => new(system: VSystemID.Raw.GEN, firmware: "CD_BIOS_US"),
|
||||
|
@ -268,6 +278,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
srcdata = CoreComm.CoreFileProvider.GetFirmware(firmwareID.Value, "GPGX firmwares are usually required.");
|
||||
if (srcdata == null)
|
||||
{
|
||||
_firmwareRequestFailed = true;
|
||||
Console.WriteLine($"Frontend couldn't satisfy firmware request {firmwareID}");
|
||||
return 0;
|
||||
}
|
||||
|
@ -407,7 +418,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
{
|
||||
private readonly IMonitor _m;
|
||||
|
||||
public VDPView(LibGPGX.VDPView v, IMonitor m)
|
||||
public VDPView(in LibGPGX.VDPView v, IMonitor m)
|
||||
{
|
||||
_m = m;
|
||||
VRAM = v.VRAM;
|
||||
|
@ -439,12 +450,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
public VDPView UpdateVDPViewContext()
|
||||
{
|
||||
var v = new LibGPGX.VDPView();
|
||||
Core.gpgx_get_vdp_view(v);
|
||||
Core.gpgx_get_vdp_view(out var v);
|
||||
Core.gpgx_flush_vram(); // fully regenerate internal caches as needed
|
||||
return new VDPView(v, _elf);
|
||||
return new VDPView(in v, _elf);
|
||||
}
|
||||
|
||||
|
||||
public int AddDeepFreezeValue(int address, byte value)
|
||||
{
|
||||
return Core.gpgx_add_deepfreeze_list_entry(address, value);
|
||||
|
|
|
@ -98,6 +98,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
|
||||
public abstract bool gpgx_get_control([Out]InputData dest, int bytes);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
|
||||
public abstract bool gpgx_put_control([In]InputData src, int bytes);
|
||||
|
||||
|
@ -331,7 +332,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
public abstract void gpgx_set_cdd_callback(cd_read_cb cddcb);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
|
||||
public abstract void gpgx_swap_disc(CDData toc);
|
||||
public abstract void gpgx_swap_disc([In] CDData toc);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct VDPNameTable
|
||||
|
@ -342,7 +343,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class VDPView
|
||||
public struct VDPView
|
||||
{
|
||||
public IntPtr VRAM;
|
||||
public IntPtr PatternCache;
|
||||
|
@ -352,8 +353,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
public VDPNameTable NTW;
|
||||
}
|
||||
|
||||
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
|
||||
public abstract void gpgx_get_vdp_view([Out] VDPView view);
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract void gpgx_get_vdp_view(out VDPView view);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract void gpgx_poke_cram(int addr, byte value);
|
||||
|
@ -383,8 +384,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract int gpgx_getmaxnumregs();
|
||||
|
||||
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
|
||||
public abstract int gpgx_getregs([Out] RegisterInfo[] regs);
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract int gpgx_getregs(RegisterInfo[] regs);
|
||||
|
||||
[Flags]
|
||||
public enum DrawMask : int
|
||||
|
@ -398,15 +399,25 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract void gpgx_set_draw_mask(DrawMask mask);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract void gpgx_set_sprite_limit_enabled(bool enabled);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract void gpgx_write_z80_bus(uint addr, byte data);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract void gpgx_write_m68k_bus(uint addr, byte data);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract void gpgx_write_s68k_bus(uint addr, byte data);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract byte gpgx_peek_z80_bus(uint addr);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract byte gpgx_peek_m68k_bus(uint addr);
|
||||
|
||||
[BizImport(CallingConvention.Cdecl)]
|
||||
public abstract byte gpgx_peek_s68k_bus(uint addr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue