diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs index 246b08825b..aafe6cda6d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs @@ -310,83 +310,32 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx #region saveram - // this all feels very messy - - struct SaveRamInfo - { - public int totalsize; - public IntPtr[] areas; - public int[] sizes; - - public int arraysize { get { return totalsize + 4 * LibGPGX.MAX_SRAM_TYPES; } } - } - - SaveRamInfo GetSaveRamInfo() - { - SaveRamInfo ret = new SaveRamInfo - { - areas = new IntPtr[LibGPGX.MAX_SRAM_TYPES], - sizes = new int[LibGPGX.MAX_SRAM_TYPES], - }; - for (int i = 0; i < LibGPGX.MAX_SRAM_TYPES; i++) - { - IntPtr area = IntPtr.Zero; - int size = 0; - LibGPGX.gpgx_get_sram(ref area, ref size, i); - ret.areas[i] = area; - ret.sizes[i] = size; - ret.totalsize += size; - } - return ret; - } - public byte[] ReadSaveRam() { - var sri = GetSaveRamInfo(); - if (sri.totalsize == 0) + int size = 0; + IntPtr area = IntPtr.Zero; + LibGPGX.gpgx_get_sram(ref area, ref size); + if (size <= 0 || area == IntPtr.Zero) return new byte[0]; + LibGPGX.gpgx_sram_prepread(); - byte[] ret = new byte[sri.arraysize]; - - MemoryStream ms = new MemoryStream(ret, true); - BinaryWriter bw = new BinaryWriter(ms); - - for (int i = 0; i < LibGPGX.MAX_SRAM_TYPES; i++) - { - bw.Write(sri.sizes[i]); - if (sri.areas[i] != IntPtr.Zero) - { - byte[] data = new byte[sri.sizes[i]]; - Marshal.Copy(sri.areas[i], data, 0, sri.sizes[i]); - bw.Write(data); - } - } - bw.Flush(); - ms.Close(); + byte[] ret = new byte[size]; + Marshal.Copy(area, ret, 0, size); return ret; } public void StoreSaveRam(byte[] data) { - var sri = GetSaveRamInfo(); - if (sri.arraysize!= data.Length) - throw new Exception("Unexpected SaveRam size"); + int size = 0; + IntPtr area = IntPtr.Zero; + LibGPGX.gpgx_get_sram(ref area, ref size); + if (size <= 0 || area == IntPtr.Zero) + return; + if (size != data.Length) + throw new Exception("Unexpected saveram size"); - MemoryStream ms = new MemoryStream(data, false); - BinaryReader br = new BinaryReader(ms); - - for (int i = 0; i < LibGPGX.MAX_SRAM_TYPES; i++) - { - int size = br.ReadInt32(); - if (size != sri.sizes[i]) - throw new Exception("Unexpected SaveRam size"); - if (sri.areas[i] != IntPtr.Zero) - { - byte[] tmp = new byte[sri.sizes[i]]; - br.Read(tmp, 0, sri.sizes[i]); - Marshal.Copy(tmp, 0, sri.areas[i], sri.sizes[i]); - } - } + Marshal.Copy(data, 0, area, size); + LibGPGX.gpgx_sram_commitwrite(); } public void ClearSaveRam() @@ -398,7 +347,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx { get { - return GetSaveRamInfo().totalsize > 0; + int size = 0; + IntPtr area = IntPtr.Zero; + LibGPGX.gpgx_get_sram(ref area, ref size); + return size > 0 && area != IntPtr.Zero; } set { diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs index fde17bd54b..0fcc7822fa 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs @@ -38,13 +38,21 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] public static extern bool gpgx_put_control(IntPtr src, int bytes); - public const int MAX_SRAM_TYPES = 3; [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void gpgx_get_sram(ref IntPtr area, ref int size, int type); + public static extern void gpgx_get_sram(ref IntPtr area, ref int size); [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void gpgx_clear_sram(); + // call this before reading sram returned by gpgx_get_sram() + [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void gpgx_sram_prepread(); + + // call this after writing sram returned by gpgx_get_sram() + [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void gpgx_sram_commitwrite(); + + public static bool gpgx_get_control(InputData dest) { int bytes = Marshal.SizeOf(typeof(InputData)); diff --git a/genplus-gx/cinterface/cinterface.c b/genplus-gx/cinterface/cinterface.c index 712e6bfc8b..6624159aec 100644 --- a/genplus-gx/cinterface/cinterface.c +++ b/genplus-gx/cinterface/cinterface.c @@ -181,59 +181,82 @@ GPGX_EX void gpgx_advance(void) GPGX_EX void gpgx_clear_sram(void) { // clear sram - if (sram.sram) - memset(sram.sram, 0, 0x10000); + if (sram.on) + memset(sram.sram, 0xff, 0x10000); - // clear and format bram - memset(scd.bram, 0, 0x2000); - brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00; - brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (sizeof(scd.bram) / 64) - 3; - memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40); + if (cdd.loaded) + { + // clear and format bram + memset(scd.bram, 0, 0x2000); + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (sizeof(scd.bram) / 64) - 3; + memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40); - // clear and format ebram - memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1); - brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8; - brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff; - memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - 0x40, brm_format, 0x40); -} - -GPGX_EX void gpgx_get_sram(void **area, int *size, int type) -{ - if (type == 0) - { - // cart sram - if (sram.on) - { - if (area) - *area = sram.sram; - if (size) - *size = 0x10000; - } - } - else if (type == 1) - { - // bram - if (cdd.loaded) - { - if (area) - *area = scd.bram; - if (size) - *size = 0x2000; - } - } - else if (type == 2) - { - // external bram if (scd.cartridge.id) { - if (area) - *area = scd.cartridge.area; - if (size) - *size = scd.cartridge.mask + 1; + // clear and format ebram + memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1); + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff; + memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - 0x40, brm_format, 0x40); } } } +// a bit hacky: +// in order to present a single memory block to the frontend, +// we copy the bram bits next to the ebram bits + +GPGX_EX void gpgx_sram_prepread(void) +{ + if (!sram.on && cdd.loaded && scd.cartridge.id) + { + void *dest = scd.cartridge.area + scd.cartridge.mask + 1; + memcpy(dest, scd.bram, 0x2000); + } +} + +GPGX_EX void gpgx_sram_commitwrite(void) +{ + if (!sram.on && cdd.loaded && scd.cartridge.id) + { + void *src = scd.cartridge.area + scd.cartridge.mask + 1; + memcpy(scd.bram, src, 0x2000); + } +} + +GPGX_EX void gpgx_get_sram(void **area, int *size) +{ + if (sram.on) + { + if (area) + *area = sram.sram; + if (size) + *size = 0x10000; + } + else if (scd.cartridge.id) + { + if (area) + *area = scd.cartridge.area; + if (size) + *size = scd.cartridge.mask + 1 + 0x2000; + } + else if (cdd.loaded) + { + if (area) + *area = scd.bram; + if (size) + *size = 0x2000; + } + else + { + if (area) + *area = NULL; + if (size) + *size = 0; + } +} + GPGX_EX int gpgx_init(const char *feromextension, int (*feload_archive_cb)(const char *filename, unsigned char *buffer, int maxsize), int sixbutton, char system_a, char system_b) { zap(); diff --git a/genplus-gx/core/cd_hw/cd_cart.c b/genplus-gx/core/cd_hw/cd_cart.c index 954222162b..ca77d544a4 100644 --- a/genplus-gx/core/cd_hw/cd_cart.c +++ b/genplus-gx/core/cd_hw/cd_cart.c @@ -190,7 +190,9 @@ void cd_cart_init(void) else { /* enable 512K backup RAM cartridge when booting from CD (Mode 2) */ - scd.cartridge.id = 6; + //scd.cartridge.id = 6; + scd.cartridge.id = 4; // use 128K instead, which is the size of a real ebram cart + // bizhawk doesn't need the extra space because it gives each game its own anyway } /* RAM cartridge enabled ? */ diff --git a/output/dll/libgenplusgx.dll b/output/dll/libgenplusgx.dll index b9e6b3126c..6b24d4a3f4 100644 Binary files a/output/dll/libgenplusgx.dll and b/output/dll/libgenplusgx.dll differ