snes: waterboxification phase 1

This commit is contained in:
nattthebear 2017-06-10 09:46:38 -04:00
parent a7ef10322e
commit 9975a05695
22 changed files with 361 additions and 259 deletions

View File

@ -5,51 +5,60 @@ using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Cores.Waterbox;
using BizHawk.Common.BizInvoke;
namespace BizHawk.Emulation.Cores.Nintendo.SNES namespace BizHawk.Emulation.Cores.Nintendo.SNES
{ {
public unsafe partial class LibsnesApi : IDisposable public unsafe partial class LibsnesApi : IDisposable
{ {
InstanceDll instanceDll; /*[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
string InstanceName; public static unsafe extern void* CopyMemory(void* dest, void* src, ulong count);*/
[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] private PeRunner _exe;
public static unsafe extern void* CopyMemory(void* dest, void* src, ulong count); private CoreImpl _core;
private bool _disposed;
private CommStruct* _comm;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] private abstract class CoreImpl
delegate IntPtr DllInit(); {
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract IntPtr DllInit();
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract void Message(eMessage msg);
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract void CopyBuffer(int id, void* ptr, int size);
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract void SetBuffer(int id, void* ptr, int size);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void MessageApi(eMessage msg);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void BufferApi(int id, void* ptr, int size);
CommStruct* comm;
MessageApi Message;
BufferApi _copyBuffer; //TODO: consider making private and wrapping
BufferApi _setBuffer; //TODO: consider making private and wrapping
public LibsnesApi(string dllPath) public LibsnesApi(string dllPath)
{ {
InstanceName = "libsneshawk_" + Guid.NewGuid().ToString(); _exe = new PeRunner(new PeRunnerOptions
instanceDll = new InstanceDll(dllPath); {
var dllinit = (DllInit)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("DllInit"), typeof(DllInit)); Filename = "libsnes.wbx",
Message = (MessageApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("Message"), typeof(MessageApi)); Path = dllPath,
_copyBuffer = (BufferApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("CopyBuffer"), typeof(BufferApi)); SbrkHeapSizeKB = 32 * 1024,
_setBuffer = (BufferApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("SetBuffer"), typeof(BufferApi)); InvisibleHeapSizeKB = 32 * 1024,
MmapHeapSizeKB = 32 * 1024,
PlainHeapSizeKB = 32 * 1024,
SealedHeapSizeKB = 32 * 1024
});
comm = (CommStruct*)dllinit().ToPointer(); _core = BizInvoker.GetInvoker<CoreImpl>(_exe, _exe);
_comm = (CommStruct*)_core.DllInit().ToPointer();
} }
public void Dispose() public void Dispose()
{ {
instanceDll.Dispose(); if (!_disposed)
{
foreach (var smb in DeallocatedMemoryBlocks.Values) smb.Dispose(); _exe.Dispose();
foreach (var smb in SharedMemoryBlocks.Values) smb.Dispose(); _exe = null;
SharedMemoryBlocks.Clear(); _core = null;
DeallocatedMemoryBlocks.Clear(); _comm = null;
}
} }
/// <summary> /// <summary>
@ -57,8 +66,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
/// </summary> /// </summary>
public void CopyAscii(int id, string str) public void CopyAscii(int id, string str)
{ {
fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str+"\0")) fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str + "\0"))
_copyBuffer(id, cp, str.Length + 1); {
_core.CopyBuffer(id, cp, str.Length + 1);
}
} }
/// <summary> /// <summary>
@ -67,7 +78,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public void CopyBytes(int id, byte[] bytes) public void CopyBytes(int id, byte[] bytes)
{ {
fixed (byte* bp = bytes) fixed (byte* bp = bytes)
_copyBuffer(id, bp, bytes.Length); {
_core.CopyBuffer(id, bp, bytes.Length);
}
} }
/// <summary> /// <summary>
@ -81,7 +94,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
{ {
fixed (byte* bp = bytes) fixed (byte* bp = bytes)
{ {
_setBuffer(id, bp, bytes.Length); _core.SetBuffer(id, bp, bytes.Length);
andThen(); andThen();
} }
} }
@ -91,9 +104,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
/// </summary> /// </summary>
public void SetAscii(int id, string str, Action andThen) public void SetAscii(int id, string str, Action andThen)
{ {
fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str+"\0")) fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str + "\0"))
{ {
_setBuffer(id, cp, str.Length + 1); _core.SetBuffer(id, cp, str.Length + 1);
andThen(); andThen();
} }
} }
@ -124,8 +137,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
BRR = 0x80, BRR = 0x80,
}; };
Dictionary<string, SharedMemoryBlock> SharedMemoryBlocks = new Dictionary<string, SharedMemoryBlock>(); //Dictionary<string, SharedMemoryBlock> SharedMemoryBlocks = new Dictionary<string, SharedMemoryBlock>();
Dictionary<string, SharedMemoryBlock> DeallocatedMemoryBlocks = new Dictionary<string, SharedMemoryBlock>(); //Dictionary<string, SharedMemoryBlock> DeallocatedMemoryBlocks = new Dictionary<string, SharedMemoryBlock>();
snes_video_refresh_t video_refresh; snes_video_refresh_t video_refresh;
snes_input_poll_t input_poll; snes_input_poll_t input_poll;
@ -177,7 +190,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public bool BG3_Prio1 { get { return _BG3_Prio1 != 0; } set { _BG3_Prio1 = (byte)(value ? 1 : 0); } } public bool BG3_Prio1 { get { return _BG3_Prio1 != 0; } set { _BG3_Prio1 = (byte)(value ? 1 : 0); } }
public bool BG4_Prio0 { get { return _BG4_Prio0 != 0; } set { _BG4_Prio0 = (byte)(value ? 1 : 0); } } public bool BG4_Prio0 { get { return _BG4_Prio0 != 0; } set { _BG4_Prio0 = (byte)(value ? 1 : 0); } }
public bool BG4_Prio1 { get { return _BG4_Prio1 != 0; } set { _BG4_Prio1 = (byte)(value ? 1 : 0); } } public bool BG4_Prio1 { get { return _BG4_Prio1 != 0; } set { _BG4_Prio1 = (byte)(value ? 1 : 0); } }
public bool Obj_Prio0 { get { return _Obj_Prio0 != 0; } set { _Obj_Prio0 = (byte)(value ? 1 : 0); } } public bool Obj_Prio0 { get { return _Obj_Prio0 != 0; } set { _Obj_Prio0 = (byte)(value ? 1 : 0); } }
public bool Obj_Prio1 { get { return _Obj_Prio1 != 0; } set { _Obj_Prio1 = (byte)(value ? 1 : 0); } } public bool Obj_Prio1 { get { return _Obj_Prio1 != 0; } set { _Obj_Prio1 = (byte)(value ? 1 : 0); } }
public bool Obj_Prio2 { get { return _Obj_Prio2 != 0; } set { _Obj_Prio2 = (byte)(value ? 1 : 0); } } public bool Obj_Prio2 { get { return _Obj_Prio2 != 0; } set { _Obj_Prio2 = (byte)(value ? 1 : 0); } }
@ -226,27 +239,52 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public unsafe string GetAscii() { return _getAscii(str); } public unsafe string GetAscii() { return _getAscii(str); }
public bool GetBool() { return value != 0; } public bool GetBool() { return value != 0; }
private unsafe string _getAscii(sbyte* ptr) { private unsafe string _getAscii(sbyte* ptr)
{
int len = 0; int len = 0;
sbyte* junko = (sbyte*)ptr; sbyte* junko = (sbyte*)ptr;
while(junko[len] != 0) len++; while (junko[len] != 0) len++;
return new string((sbyte*)str, 0, len, System.Text.Encoding.ASCII); return new string((sbyte*)str, 0, len, System.Text.Encoding.ASCII);
} }
} }
public SNES_REGION Region { get { return comm->region; } } public SNES_REGION Region
public SNES_MAPPER Mapper { get { return comm->mapper; } } {
get
{
using (_exe.EnterExit())
{
return _comm->region;
}
}
}
public SNES_MAPPER Mapper
{
get
{
using (_exe.EnterExit())
{
return _comm->mapper;
}
}
}
public void SetLayerEnables(ref LayerEnables enables) public void SetLayerEnables(ref LayerEnables enables)
{ {
comm->layerEnables = enables; using (_exe.EnterExit())
QUERY_set_layer_enable(); {
_comm->layerEnables = enables;
QUERY_set_layer_enable();
}
} }
public void SetInputPortBeforeInit(int port, SNES_INPUT_PORT type) public void SetInputPortBeforeInit(int port, SNES_INPUT_PORT type)
{ {
comm->inports[port] = (int)type; using (_exe.EnterExit())
{
_comm->inports[port] = (int)type;
}
} }
} }
} }

View File

@ -8,42 +8,38 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
{ {
bool Handle_BRK(eMessage msg) bool Handle_BRK(eMessage msg)
{ {
switch (msg) using (_exe.EnterExit())
{ {
default: switch (msg)
return false; {
default:
return false;
case eMessage.eMessage_BRK_hook_exec: case eMessage.eMessage_BRK_hook_exec:
{ ExecHook(_comm->addr);
ExecHook(comm->addr);
break; break;
} case eMessage.eMessage_BRK_hook_read:
case eMessage.eMessage_BRK_hook_read: ReadHook(_comm->addr);
{
ReadHook(comm->addr);
break; break;
} case eMessage.eMessage_BRK_hook_write:
case eMessage.eMessage_BRK_hook_write: WriteHook(_comm->addr, (byte)_comm->value);
{
WriteHook(comm->addr, (byte)comm->value);
break; break;
}
//not supported yet //not supported yet
case eMessage.eMessage_BRK_hook_nmi: case eMessage.eMessage_BRK_hook_nmi:
break; break;
case eMessage.eMessage_BRK_hook_irq: case eMessage.eMessage_BRK_hook_irq:
break; break;
case eMessage.eMessage_BRK_scanlineStart: case eMessage.eMessage_BRK_scanlineStart:
if (scanlineStart != null) scanlineStart?.Invoke(_comm->scanline);
scanlineStart(comm->scanline); break;
break;
} //switch(msg) } //switch(msg)
Message(eMessage.eMessage_Resume); _core.Message(eMessage.eMessage_Resume);
return true; return true;
}
} }
} }
} }

View File

@ -6,98 +6,86 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
{ {
unsafe partial class LibsnesApi unsafe partial class LibsnesApi
{ {
public bool CMD_serialize(IntPtr data, int size)
{
comm->buf[0] = (uint)data.ToInt32();
comm->buf_size[0] = size;
Message(eMessage.eMessage_CMD_serialize);
WaitForCMD();
bool ret = comm->GetBool();
return ret;
}
void WaitForCMD() void WaitForCMD()
{ {
for (; ; ) using (_exe.EnterExit())
{ {
if (comm->status == eStatus.eStatus_Idle) for (;;)
break; {
if (Handle_SIG(comm->reason)) continue; if (_comm->status == eStatus.eStatus_Idle)
if (Handle_BRK(comm->reason)) continue; break;
if (Handle_SIG(_comm->reason)) continue;
if (Handle_BRK(_comm->reason)) continue;
}
} }
} }
public bool CMD_unserialize(IntPtr data, int size)
{
comm->buf[0] = (uint)data.ToInt32();
comm->buf_size[0] = size;
Message(eMessage.eMessage_CMD_unserialize);
WaitForCMD();
bool ret = comm->GetBool();
return ret;
}
public void CMD_init() public void CMD_init()
{ {
Message(eMessage.eMessage_CMD_init); _core.Message(eMessage.eMessage_CMD_init);
WaitForCMD(); WaitForCMD();
} }
public void CMD_power() public void CMD_power()
{ {
Message(eMessage.eMessage_CMD_power); _core.Message(eMessage.eMessage_CMD_power);
WaitForCMD(); WaitForCMD();
} }
public void CMD_reset() public void CMD_reset()
{ {
Message(eMessage.eMessage_CMD_reset); _core.Message(eMessage.eMessage_CMD_reset);
WaitForCMD(); WaitForCMD();
} }
public void CMD_run() public void CMD_run()
{ {
Message(eMessage.eMessage_CMD_run); _core.Message(eMessage.eMessage_CMD_run);
WaitForCMD(); WaitForCMD();
} }
public bool CMD_load_cartridge_super_game_boy(string rom_xml, byte[] rom_data, uint rom_size, byte[] dmg_data) public bool CMD_load_cartridge_super_game_boy(string rom_xml, byte[] rom_data, uint rom_size, byte[] dmg_data)
{ {
SetAscii(0, rom_xml ?? "", () => using (_exe.EnterExit())
SetBytes(1, rom_data, () => {
SetBytes(2, dmg_data, () => SetAscii(0, rom_xml ?? "", () =>
{ SetBytes(1, rom_data, () =>
Message(eMessage.eMessage_CMD_load_cartridge_sgb); SetBytes(2, dmg_data, () =>
WaitForCMD(); {
}) _core.Message(eMessage.eMessage_CMD_load_cartridge_sgb);
) WaitForCMD();
); })
return comm->GetBool(); )
);
return _comm->GetBool();
}
} }
public bool CMD_load_cartridge_normal(byte[] rom_xml, byte[] rom_data) public bool CMD_load_cartridge_normal(byte[] rom_xml, byte[] rom_data)
{ {
//why don't we need this for the other loads? I dont know, our XML handling is really confusing using (_exe.EnterExit())
string xml = rom_xml == null ? null : System.Text.Encoding.ASCII.GetString(rom_xml); {
//why don't we need this for the other loads? I dont know, our XML handling is really confusing
string xml = rom_xml == null ? null : System.Text.Encoding.ASCII.GetString(rom_xml);
SetAscii(0, xml ?? "", () => SetAscii(0, xml ?? "", () =>
SetBytes(1, rom_data, () => SetBytes(1, rom_data, () =>
{ {
Message(eMessage.eMessage_CMD_load_cartridge_normal); _core.Message(eMessage.eMessage_CMD_load_cartridge_normal);
WaitForCMD(); WaitForCMD();
}) })
); );
return comm->GetBool(); return _comm->GetBool();
}
} }
public void CMD_term() public void CMD_term()
{ {
Message(eMessage.eMessage_CMD_term); _core.Message(eMessage.eMessage_CMD_term);
WaitForCMD(); WaitForCMD();
} }
public void CMD_unload_cartridge() public void CMD_unload_cartridge()
{ {
Message(eMessage.eMessage_CMD_unload_cartridge); _core.Message(eMessage.eMessage_CMD_unload_cartridge);
WaitForCMD(); WaitForCMD();
} }
} }
} }

View File

@ -10,16 +10,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
{ {
public int QUERY_get_memory_size(SNES_MEMORY id) public int QUERY_get_memory_size(SNES_MEMORY id)
{ {
comm->value = (uint)id; using (_exe.EnterExit())
Message(eMessage.eMessage_QUERY_get_memory_size); {
return (int)comm->value; _comm->value = (uint)id;
_core.Message(eMessage.eMessage_QUERY_get_memory_size);
return (int)_comm->value;
}
} }
string QUERY_MemoryNameForId(SNES_MEMORY id) string QUERY_MemoryNameForId(SNES_MEMORY id)
{ {
comm->id = (uint)id; using (_exe.EnterExit())
Message(eMessage.eMessage_QUERY_GetMemoryIdName); {
return comm->GetAscii(); _comm->id = (uint)id;
_core.Message(eMessage.eMessage_QUERY_GetMemoryIdName);
return _comm->GetAscii();
}
} }
public byte* QUERY_get_memory_data(SNES_MEMORY id) public byte* QUERY_get_memory_data(SNES_MEMORY id)
@ -32,147 +38,169 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public byte QUERY_peek(SNES_MEMORY id, uint addr) public byte QUERY_peek(SNES_MEMORY id, uint addr)
{ {
comm->id = (uint)id; using (_exe.EnterExit())
comm->addr = addr; {
Message(eMessage.eMessage_QUERY_peek); _comm->id = (uint)id;
return (byte)comm->value; _comm->addr = addr;
_core.Message(eMessage.eMessage_QUERY_peek);
return (byte)_comm->value;
}
} }
public void QUERY_poke(SNES_MEMORY id, uint addr, byte val) public void QUERY_poke(SNES_MEMORY id, uint addr, byte val)
{ {
comm->id = (uint)id; using (_exe.EnterExit())
comm->addr = addr;
comm->value = (byte)val;
Message(eMessage.eMessage_QUERY_poke);
}
public int QUERY_serialize_size()
{
for (; ; )
{ {
Message(eMessage.eMessage_QUERY_serialize_size); _comm->id = (uint)id;
int ret = (int)comm->size; _comm->addr = addr;
if (ret > 100) _comm->value = (byte)val;
{ _core.Message(eMessage.eMessage_QUERY_poke);
return ret;
}
else Console.WriteLine("WHY????????");
} }
} }
public void QUERY_set_color_lut(IntPtr colors) public void QUERY_set_color_lut(IntPtr colors)
{ {
comm->ptr = colors.ToPointer(); using (_exe.EnterExit())
Message(eMessage.eMessage_QUERY_set_color_lut); {
_comm->ptr = colors.ToPointer();
_core.Message(eMessage.eMessage_QUERY_set_color_lut);
}
} }
public void QUERY_set_state_hook_exec(bool state) public void QUERY_set_state_hook_exec(bool state)
{ {
comm->value = state ? 1u : 0u; using (_exe.EnterExit())
Message(eMessage.eMessage_QUERY_state_hook_exec); {
_comm->value = state ? 1u : 0u;
_core.Message(eMessage.eMessage_QUERY_state_hook_exec);
}
} }
public void QUERY_set_state_hook_read(bool state) public void QUERY_set_state_hook_read(bool state)
{ {
comm->value = state ? 1u : 0u; using (_exe.EnterExit())
Message(eMessage.eMessage_QUERY_state_hook_read); {
_comm->value = state ? 1u : 0u;
_core.Message(eMessage.eMessage_QUERY_state_hook_read);
}
} }
public void QUERY_set_state_hook_write(bool state) public void QUERY_set_state_hook_write(bool state)
{ {
comm->value = state ? 1u : 0u; using (_exe.EnterExit())
Message(eMessage.eMessage_QUERY_state_hook_write); {
_comm->value = state ? 1u : 0u;
_core.Message(eMessage.eMessage_QUERY_state_hook_write);
}
} }
public void QUERY_set_trace_callback(int mask, snes_trace_t callback) public void QUERY_set_trace_callback(int mask, snes_trace_t callback)
{ {
this.traceCallback = callback; using (_exe.EnterExit())
comm->value = (uint)mask; {
Message(eMessage.eMessage_QUERY_enable_trace); this.traceCallback = callback;
_comm->value = (uint)mask;
_core.Message(eMessage.eMessage_QUERY_enable_trace);
}
} }
public void QUERY_set_scanlineStart(snes_scanlineStart_t scanlineStart) public void QUERY_set_scanlineStart(snes_scanlineStart_t scanlineStart)
{ {
this.scanlineStart = scanlineStart; using (_exe.EnterExit())
comm->value = (scanlineStart != null) ? 1u : 0u; {
Message(eMessage.eMessage_QUERY_enable_scanline); this.scanlineStart = scanlineStart;
_comm->value = (scanlineStart != null) ? 1u : 0u;
_core.Message(eMessage.eMessage_QUERY_enable_scanline);
}
} }
public void QUERY_set_audio_sample(snes_audio_sample_t audio_sample) public void QUERY_set_audio_sample(snes_audio_sample_t audio_sample)
{ {
this.audio_sample = audio_sample; using (_exe.EnterExit())
comm->value = (audio_sample!=null) ? 1u : 0u; {
Message(eMessage.eMessage_QUERY_enable_audio); this.audio_sample = audio_sample;
_comm->value = (audio_sample != null) ? 1u : 0u;
_core.Message(eMessage.eMessage_QUERY_enable_audio);
}
} }
public void QUERY_set_layer_enable() public void QUERY_set_layer_enable()
{ {
Message(eMessage.eMessage_QUERY_set_layer_enable); _core.Message(eMessage.eMessage_QUERY_set_layer_enable);
} }
public void QUERY_set_backdropColor(int backdropColor) public void QUERY_set_backdropColor(int backdropColor)
{ {
comm->value = (uint)backdropColor; using (_exe.EnterExit())
Message(eMessage.eMessage_QUERY_set_backdropColor); {
_comm->value = (uint)backdropColor;
_core.Message(eMessage.eMessage_QUERY_set_backdropColor);
}
} }
public int QUERY_peek_logical_register(SNES_REG reg) public int QUERY_peek_logical_register(SNES_REG reg)
{ {
comm->id = (uint)reg; using (_exe.EnterExit())
Message(eMessage.eMessage_QUERY_peek_logical_register); {
return (int)comm->value; _comm->id = (uint)reg;
_core.Message(eMessage.eMessage_QUERY_peek_logical_register);
return (int)_comm->value;
}
} }
public unsafe void QUERY_peek_cpu_regs(out CPURegs ret) public unsafe void QUERY_peek_cpu_regs(out CPURegs ret)
{ {
Message(eMessage.eMessage_QUERY_peek_cpu_regs); using (_exe.EnterExit())
ret = comm->cpuregs; {
_core.Message(eMessage.eMessage_QUERY_peek_cpu_regs);
ret = _comm->cpuregs;
}
} }
public void QUERY_set_cdl(ICodeDataLog cdl) public void QUERY_set_cdl(ICodeDataLog cdl)
{ {
for (int i = 0; i < 8; i++) using (_exe.EnterExit())
{ {
comm->cdl_ptr[i] = 0; for (int i = 0; i < 8; i++)
comm->cdl_size[i] = 0;
}
if (cdl != null)
{
comm->cdl_ptr[0] = cdl.GetPin("CARTROM").ToInt64();
comm->cdl_size[0] = cdl["CARTROM"].Length;
if (cdl.Has("CARTRAM"))
{ {
comm->cdl_ptr[1] = cdl.GetPin("CARTRAM").ToInt64(); _comm->cdl_ptr[i] = 0;
comm->cdl_size[1] = cdl["CARTRAM"].Length; _comm->cdl_size[i] = 0;
} }
comm->cdl_ptr[2] = cdl.GetPin("WRAM").ToInt64(); if (cdl != null)
comm->cdl_size[2] = cdl["WRAM"].Length;
comm->cdl_ptr[3] = cdl.GetPin("APURAM").ToInt64();
comm->cdl_size[3] = cdl["APURAM"].Length;
if (cdl.Has("SGB_CARTROM"))
{ {
comm->cdl_ptr[4] = cdl.GetPin("SGB_CARTROM").ToInt64(); _comm->cdl_ptr[0] = cdl.GetPin("CARTROM").ToInt64();
comm->cdl_size[4] = cdl["SGB_CARTROM"].Length; _comm->cdl_size[0] = cdl["CARTROM"].Length;
if (cdl.Has("CARTRAM"))
if (cdl.Has("SGB_CARTRAM"))
{ {
comm->cdl_ptr[5] = cdl.GetPin("SGB_CARTRAM").ToInt64(); _comm->cdl_ptr[1] = cdl.GetPin("CARTRAM").ToInt64();
comm->cdl_size[5] = cdl["SGB_CARTRAM"].Length; _comm->cdl_size[1] = cdl["CARTRAM"].Length;
} }
comm->cdl_ptr[6] = cdl.GetPin("SGB_WRAM").ToInt64(); _comm->cdl_ptr[2] = cdl.GetPin("WRAM").ToInt64();
comm->cdl_size[6] = cdl["SGB_WRAM"].Length; _comm->cdl_size[2] = cdl["WRAM"].Length;
comm->cdl_ptr[7] = cdl.GetPin("SGB_HRAM").ToInt64(); _comm->cdl_ptr[3] = cdl.GetPin("APURAM").ToInt64();
comm->cdl_size[7] = cdl["SGB_HRAM"].Length; _comm->cdl_size[3] = cdl["APURAM"].Length;
if (cdl.Has("SGB_CARTROM"))
{
_comm->cdl_ptr[4] = cdl.GetPin("SGB_CARTROM").ToInt64();
_comm->cdl_size[4] = cdl["SGB_CARTROM"].Length;
if (cdl.Has("SGB_CARTRAM"))
{
_comm->cdl_ptr[5] = cdl.GetPin("SGB_CARTRAM").ToInt64();
_comm->cdl_size[5] = cdl["SGB_CARTRAM"].Length;
}
_comm->cdl_ptr[6] = cdl.GetPin("SGB_WRAM").ToInt64();
_comm->cdl_size[6] = cdl["SGB_WRAM"].Length;
_comm->cdl_ptr[7] = cdl.GetPin("SGB_HRAM").ToInt64();
_comm->cdl_size[7] = cdl["SGB_HRAM"].Length;
}
} }
}
Message(eMessage.eMessage_QUERY_set_cdl); _core.Message(eMessage.eMessage_QUERY_set_cdl);
}
} }
} }
} }

42
waterbox/libsnes/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,42 @@
{
"files.associations": {
"ostream": "cpp",
"algorithm": "cpp",
"cmath": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"cwchar": "cpp",
"deque": "cpp",
"exception": "cpp",
"initializer_list": "cpp",
"ios": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"limits": "cpp",
"memory": "cpp",
"new": "cpp",
"queue": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string": "cpp",
"system_error": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"vector": "cpp",
"xfacet": "cpp",
"xiosbase": "cpp",
"xlocale": "cpp",
"xlocinfo": "cpp",
"xlocnum": "cpp",
"xmemory": "cpp",
"xmemory0": "cpp",
"xstddef": "cpp",
"xstring": "cpp",
"xtr1common": "cpp",
"xutility": "cpp"
}
}

View File

@ -3,11 +3,15 @@ CC = x86_64-nt64-midipix-g++
# -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast # -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast
#-std=c99 -fomit-frame-pointer -fvisibility=hidden #-std=c99 -fomit-frame-pointer -fvisibility=hidden
#-DPROFILE_PERFORMANCE #-DPROFILE_PERFORMANCE
#-fno-exceptions -fno-rtti
CCFLAGS:= -DHOOKS -DBIZHAWK -DPROFILE_COMPATIBILITY -DGAMEBOY \ CCFLAGS:= -DHOOKS -DBIZHAWK -DPROFILE_COMPATIBILITY -DGAMEBOY \
-D_GNU_SOURCE \
-Werror=pointer-to-int-cast -Werror=int-to-pointer-cast \ -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast \
-I../emulibc -I../libco \ -I../emulibc -I../libco -I./bsnes \
-Wall -Werror=implicit-function-declaration \ -Wall -Werror=implicit-function-declaration \
-fno-exceptions -fno-rtti -fvisibility=hidden \ -Wno-parentheses -Wno-sign-compare \
-Wno-unused-variable -Wno-unused-function \
-fvisibility=hidden \
-std=c++0x \ -std=c++0x \
-O0 -g -O0 -g
@ -16,16 +20,22 @@ TARGET = libsnes.wbx
LDFLAGS = -Wl,--dynamicbase,--export-all-symbols LDFLAGS = -Wl,--dynamicbase,--export-all-symbols
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
SRCS:= \
# $(ROOT_DIR)/bsnes/snes/alt/cpu/cpu.cpp \ #perf only SRCS_PERF:= \
# $(ROOT_DIR)/bsnes/snes/alt/ppu-performance/ppu.cpp \ #perf only $(ROOT_DIR)/bsnes/snes/alt/cpu/cpu.cpp \
# $(ROOT_DIR)/bsnes/snes/alt/smp/smp.cpp \ # perf only $(ROOT_DIR)/bsnes/snes/alt/ppu-performance/ppu.cpp \
$(ROOT_DIR)/bsnes/snes/alt/ppu-compatibility/ppu.cpp \ #compat only $(ROOT_DIR)/bsnes/snes/alt/smp/smp.cpp
SRCS_COMPAT:= \
$(ROOT_DIR)/bsnes/snes/alt/ppu-compatibility/ppu.cpp \
$(ROOT_DIR)/bsnes/snes/cpu/cpu.cpp \
$(ROOT_DIR)/bsnes/snes/smp/smp.cpp
SRCS_ALL:= \
$(ROOT_DIR)/bsnes/base/base.cpp \ $(ROOT_DIR)/bsnes/base/base.cpp \
$(ROOT_DIR)/bsnes/gameboy/apu/apu.cpp \ $(ROOT_DIR)/bsnes/gameboy/apu/apu.cpp \
$(ROOT_DIR)/bsnes/gameboy/cartridge/cartridge.cpp \ $(ROOT_DIR)/bsnes/gameboy/cartridge/cartridge.cpp \
$(ROOT_DIR)/bsnes/gameboy/cheat/cheat.cpp \ $(ROOT_DIR)/bsnes/gameboy/cheat/cheat.cpp \
$(ROOT_DIR)/bsnes/gameboy/cpu/cpu.cpp \ $(ROOT_DIR)/bsnes/gameboy/cpu/cpu.cpp \
$(ROOT_DIR)/bsnes/snes/alt/dsp/dsp.cpp \
$(ROOT_DIR)/bsnes/gameboy/interface/interface.cpp \ $(ROOT_DIR)/bsnes/gameboy/interface/interface.cpp \
$(ROOT_DIR)/bsnes/gameboy/lcd/lcd.cpp \ $(ROOT_DIR)/bsnes/gameboy/lcd/lcd.cpp \
$(ROOT_DIR)/bsnes/gameboy/memory/memory.cpp \ $(ROOT_DIR)/bsnes/gameboy/memory/memory.cpp \
@ -58,6 +68,7 @@ SRCS:= \
$(ROOT_DIR)/bsnes/snes/system/system.cpp \ $(ROOT_DIR)/bsnes/snes/system/system.cpp \
$(ROOT_DIR)/bsnes/target-libsnes/libsnes.cpp \ $(ROOT_DIR)/bsnes/target-libsnes/libsnes.cpp \
$(ROOT_DIR)/bsnes/target-libsnes/libsnes_pwrap.cpp $(ROOT_DIR)/bsnes/target-libsnes/libsnes_pwrap.cpp
SRCS:=$(SRCS_ALL) $(SRCS_COMPAT)
OBJ_DIR:=$(ROOT_DIR)/obj OBJ_DIR:=$(ROOT_DIR)/obj

View File

@ -17,7 +17,7 @@ namespace GameBoy {
project started: 2010-12-27 project started: 2010-12-27
*/ */
#include <libco/libco.h> #include <libco.h>
#include <nall/gameboy/cartridge.hpp> #include <nall/gameboy/cartridge.hpp>
namespace GameBoy { namespace GameBoy {

View File

@ -50,7 +50,7 @@ void ResampleAverage::sample() {
void ResampleAverage::sampleLinear() { void ResampleAverage::sampleLinear() {
while(fraction <= 1.0) { while(fraction <= 1.0) {
real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); std::vector<real> channel(dsp.settings.channels);
for(unsigned n = 0; n < dsp.settings.channels; n++) { for(unsigned n = 0; n < dsp.settings.channels; n++) {
real a = dsp.buffer.read(n, -1); real a = dsp.buffer.read(n, -1);
@ -61,7 +61,7 @@ void ResampleAverage::sampleLinear() {
channel[n] = a * (1.0 - mu) + b * mu; channel[n] = a * (1.0 - mu) + b * mu;
} }
dsp.write(channel); dsp.write(channel.data());
fraction += step; fraction += step;
} }

View File

@ -21,7 +21,7 @@ void ResampleCosine::clear() {
void ResampleCosine::sample() { void ResampleCosine::sample() {
while(fraction <= 1.0) { while(fraction <= 1.0) {
real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); std::vector<real> channel(dsp.settings.channels);
for(unsigned n = 0; n < dsp.settings.channels; n++) { for(unsigned n = 0; n < dsp.settings.channels; n++) {
@ -34,7 +34,7 @@ void ResampleCosine::sample() {
channel[n] = a * (1.0 - mu) + b * mu; channel[n] = a * (1.0 - mu) + b * mu;
} }
dsp.write(channel); dsp.write(channel.data());
fraction += step; fraction += step;
} }

View File

@ -21,7 +21,7 @@ void ResampleCubic::clear() {
void ResampleCubic::sample() { void ResampleCubic::sample() {
while(fraction <= 1.0) { while(fraction <= 1.0) {
real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); std::vector<real> channel(dsp.settings.channels);
for(unsigned n = 0; n < dsp.settings.channels; n++) { for(unsigned n = 0; n < dsp.settings.channels; n++) {
real a = dsp.buffer.read(n, -3); real a = dsp.buffer.read(n, -3);
@ -39,7 +39,7 @@ void ResampleCubic::sample() {
channel[n] = A * (mu * 3) + B * (mu * 2) + C * mu + D; channel[n] = A * (mu * 3) + B * (mu * 2) + C * mu + D;
} }
dsp.write(channel); dsp.write(channel.data());
fraction += step; fraction += step;
} }

View File

@ -21,7 +21,7 @@ void ResampleHermite::clear() {
void ResampleHermite::sample() { void ResampleHermite::sample() {
while(fraction <= 1.0) { while(fraction <= 1.0) {
real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); std::vector<real> channel(dsp.settings.channels);
for(unsigned n = 0; n < dsp.settings.channels; n++) { for(unsigned n = 0; n < dsp.settings.channels; n++) {
real a = dsp.buffer.read(n, -3); real a = dsp.buffer.read(n, -3);
@ -51,7 +51,7 @@ void ResampleHermite::sample() {
channel[n] = (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c); channel[n] = (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c);
} }
dsp.write(channel); dsp.write(channel.data());
fraction += step; fraction += step;
} }

View File

@ -21,7 +21,7 @@ void ResampleLinear::clear() {
void ResampleLinear::sample() { void ResampleLinear::sample() {
while(fraction <= 1.0) { while(fraction <= 1.0) {
real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); std::vector<real> channel(dsp.settings.channels);
for(unsigned n = 0; n < dsp.settings.channels; n++) { for(unsigned n = 0; n < dsp.settings.channels; n++) {
real a = dsp.buffer.read(n, -1); real a = dsp.buffer.read(n, -1);
@ -32,7 +32,7 @@ void ResampleLinear::sample() {
channel[n] = a * (1.0 - mu) + b * mu; channel[n] = a * (1.0 - mu) + b * mu;
} }
dsp.write(channel); dsp.write(channel.data());
fraction += step; fraction += step;
} }

View File

@ -21,7 +21,7 @@ void ResampleNearest::clear() {
void ResampleNearest::sample() { void ResampleNearest::sample() {
while(fraction <= 1.0) { while(fraction <= 1.0) {
real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); std::vector<real> channel(dsp.settings.channels);
for(unsigned n = 0; n < dsp.settings.channels; n++) { for(unsigned n = 0; n < dsp.settings.channels; n++) {
real a = dsp.buffer.read(n, -1); real a = dsp.buffer.read(n, -1);
@ -32,7 +32,7 @@ void ResampleNearest::sample() {
channel[n] = mu < 0.5 ? a : b; channel[n] = mu < 0.5 ? a : b;
} }
dsp.write(channel); dsp.write(channel.data());
fraction += step; fraction += step;
} }

View File

@ -26,6 +26,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <limits.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

View File

@ -5,6 +5,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include <algorithm> #include <algorithm>
#include <initializer_list> #include <initializer_list>

View File

@ -166,15 +166,15 @@ template<unsigned length_, char padding> string decimal(uintmax_t value) {
buffer[size] = 0; buffer[size] = 0;
unsigned length = (length_ == 0 ? size : length_); unsigned length = (length_ == 0 ? size : length_);
char* result = (char*)alloca(length + 1); std::vector<char> result(length + 1);
memset(result, padding, length); memset(result.data(), padding, length);
result[length] = 0; result[length] = 0;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
result[x] = buffer[y]; result[x] = buffer[y];
} }
return (const char*)result; return (const char*)result.data();
} }
template<unsigned length_, char padding> string ldecimal(uintmax_t value) { template<unsigned length_, char padding> string ldecimal(uintmax_t value) {
@ -211,15 +211,15 @@ template<unsigned length_, char padding> string hex(uintmax_t value) {
} while(value); } while(value);
unsigned length = (length_ == 0 ? size : length_); unsigned length = (length_ == 0 ? size : length_);
char *result = (char*)alloca(length + 1); std::vector<char> result(length + 1);
memset(result, padding, length); memset(result.data(), padding, length);
result[length] = 0; result[length] = 0;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
result[x] = buffer[y]; result[x] = buffer[y];
} }
return (const char*)result; return (const char*)result.data();
} }
template<unsigned length_, char padding> string binary(uintmax_t value) { template<unsigned length_, char padding> string binary(uintmax_t value) {

View File

@ -259,11 +259,10 @@ void Cartridge::parse_markup_necdsp(XML::Node &root) {
if(!sha256.empty()) { if(!sha256.empty()) {
//XML file specified SHA256 sum for program. Verify file matches the hash. //XML file specified SHA256 sum for program. Verify file matches the hash.
fp.seek(0); fp.seek(0);
//uint8_t data[filesize]; //test std::vector<uint8_t> data(filesize);
uint8_t *data = (uint8_t*)alloca(filesize); fp.read(data.data(), filesize);
fp.read(data, filesize);
if(sha256 != nall::sha256(data, filesize)) { if(sha256 != nall::sha256(data.data(), filesize)) {
interface()->message({ "Warning: NEC DSP firmware ", firmware, " SHA256 sum is incorrect." }); interface()->message({ "Warning: NEC DSP firmware ", firmware, " SHA256 sum is incorrect." });
} }
} }

View File

@ -89,7 +89,7 @@ USART::USART(bool port) : Controller(port) {
txdata = 0; txdata = 0;
string filename = interface()->path(Cartridge::Slot::Base, "usart.so"); string filename = interface()->path(Cartridge::Slot::Base, "usart.so");
if(open_absolute(filename)) { if(0 /*open_absolute(filename)*/) {
init = sym("usart_init"); init = sym("usart_init");
main = sym("usart_main"); main = sym("usart_main");
if(init && main) create(Controller::Enter, 1000000); if(init && main) create(Controller::Enter, 1000000);

View File

@ -24,6 +24,5 @@ alwaysinline void op_writedp(uint8 addr, uint8 data) {
alwaysinline void op_next() { alwaysinline void op_next() {
opcode = op_readpcfirst(); opcode = op_readpcfirst();
uindex = -1;
} }

View File

@ -17,7 +17,7 @@ namespace SNES {
project started: 2004-10-14 project started: 2004-10-14
*/ */
#include <libco/libco.h> #include <libco.h>
#if defined(GAMEBOY) #if defined(GAMEBOY)
#include <gameboy/gameboy.hpp> #include <gameboy/gameboy.hpp>

View File

@ -6,8 +6,6 @@
#include <queue> #include <queue>
#include <Windows.h>
using namespace nall; using namespace nall;
struct Interface : public SNES::Interface { struct Interface : public SNES::Interface {

View File

@ -4,13 +4,11 @@
//sig: core->frontend: "core signal" a synchronous operation called from the emulation process which the frontend should handle immediately without issuing any calls into the core //sig: core->frontend: "core signal" a synchronous operation called from the emulation process which the frontend should handle immediately without issuing any calls into the core
//brk: core->frontend: "core break" the emulation process has suspended. the frontend is free to do whatever it wishes. //brk: core->frontend: "core break" the emulation process has suspended. the frontend is free to do whatever it wishes.
#include <Windows.h>
#define LIBSNES_IMPORT #define LIBSNES_IMPORT
#include "snes/snes.hpp" #include "snes/snes.hpp"
#include "libsnes.hpp" #include "libsnes.hpp"
#include <libco/libco.h> #include <libco.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -570,12 +568,10 @@ void new_emuthread()
//------------------------------------------------ //------------------------------------------------
//DLL INTERFACE //DLL INTERFACE
BOOL WINAPI DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) #include <emulibc.h>
{ #define EXPORT extern "C" ECL_EXPORT
return TRUE;
}
extern "C" dllexport void* __cdecl DllInit() EXPORT void* DllInit()
{ {
memset(&comm,0,sizeof(comm)); memset(&comm,0,sizeof(comm));
@ -586,7 +582,7 @@ extern "C" dllexport void* __cdecl DllInit()
return &comm; return &comm;
} }
extern "C" dllexport void __cdecl Message(eMessage msg) EXPORT void Message(eMessage msg)
{ {
if (msg == eMessage_Resume) if (msg == eMessage_Resume)
{ {
@ -625,13 +621,18 @@ extern "C" dllexport void __cdecl Message(eMessage msg)
//receives the given buffer and COPIES it. use this for returning values from SIGs //receives the given buffer and COPIES it. use this for returning values from SIGs
extern "C" dllexport void __cdecl CopyBuffer(int id, void* ptr, int32 size) EXPORT void CopyBuffer(int id, void* ptr, int32 size)
{ {
comm.CopyBuffer(id, ptr, size); comm.CopyBuffer(id, ptr, size);
} }
//receives the given buffer and STASHES IT. use this (carefully) for sending params for CMDs //receives the given buffer and STASHES IT. use this (carefully) for sending params for CMDs
extern "C" dllexport void __cdecl SetBuffer(int id, void* ptr, int32 size) EXPORT void SetBuffer(int id, void* ptr, int32 size)
{ {
comm.SetBuffer(id, ptr, size); comm.SetBuffer(id, ptr, size);
} }
int main()
{
return 0;
}