From 8136aa0f031c976e78569e1e1254119b1565ca41 Mon Sep 17 00:00:00 2001 From: nattthebear Date: Wed, 23 Mar 2016 19:45:02 -0400 Subject: [PATCH] Add the basics of multiple memory arenas to elfrunner. With a bit of tweaking, gpgx core states are now 3.5MB (and could get smaller) --- .../Consoles/Sega/gpgx/GPGX.IEmulator.cs | 5 +- .../Consoles/Sega/gpgx/GPGX.ISaveRam.cs | 21 +--- .../Consoles/Sega/gpgx/GPGX.IStatable.cs | 67 +--------- .../Consoles/Sega/gpgx/GPGX.cs | 21 +--- .../Consoles/Sega/gpgx/LibGPGX.cs | 22 +--- BizHawk.Emulation.Cores/ElfRunner.cs | 107 ++++++++++++---- waterbox/gpgx/cinterface/cinterface.c | 116 +++++++++++------- waterbox/gpgx/core/cart_hw/md_cart.h | 2 +- waterbox/gpgx/core/cd_hw/cd_cart.h | 6 +- waterbox/gpgx/core/genesis.h | 2 +- waterbox/gpgx/core/loadrom.c | 28 ++--- waterbox/libc/functions/_PDCLIB/emulibc.c | 13 ++ waterbox/libc/includes/emulibc.h | 13 ++ 13 files changed, 222 insertions(+), 201 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IEmulator.cs index 3130d69470..41880b875c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IEmulator.cs @@ -89,9 +89,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx { if (!disposed) { - // KillMemCallbacks(); // not needed when not single instance - if (NativeData != null) - NativeData.Dispose(); + if (Elf != null) + Elf.Dispose(); if (CD != null) CD.Dispose(); disposed = true; diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ISaveRam.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ISaveRam.cs index 4e7e0641c0..352d702170 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ISaveRam.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ISaveRam.cs @@ -12,11 +12,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx public byte[] CloneSaveRam() { int size = 0; - IntPtr area = IntPtr.Zero; - Core.gpgx_get_sram(ref area, ref size); - if (size <= 0 || area == IntPtr.Zero) + IntPtr area = Core.gpgx_get_sram(ref size); + if (size == 0 || area == IntPtr.Zero) return new byte[0]; - Core.gpgx_sram_prepread(); byte[] ret = new byte[size]; Marshal.Copy(area, ret, 0, size); @@ -25,16 +23,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx public void StoreSaveRam(byte[] data) { - int size = 0; - IntPtr area = IntPtr.Zero; - Core.gpgx_get_sram(ref area, ref size); - if (size <= 0 || area == IntPtr.Zero) - return; - if (size != data.Length) - throw new Exception("Unexpected saveram size"); - - Marshal.Copy(data, 0, area, size); - Core.gpgx_sram_commitwrite(); + if (!Core.gpgx_put_sram(data, data.Length)) + throw new Exception("Core rejected saveram"); } public bool SaveRamModified @@ -42,8 +32,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx get { int size = 0; - IntPtr area = IntPtr.Zero; - Core.gpgx_get_sram(ref area, ref size); + IntPtr area = Core.gpgx_get_sram(ref size); return size > 0 && area != IntPtr.Zero; } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IStatable.cs index 826093bc70..7fd5b5e8a3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IStatable.cs @@ -28,71 +28,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx state.ReadFromHexFast(hex); LoadStateBinary(new BinaryReader(new MemoryStream(state))); } -#if true - - public byte[] SaveStateBinary() - { - var ms = new MemoryStream(_savebuff2, true); - var bw = new BinaryWriter(ms); - SaveStateBinary(bw); - bw.Flush(); - ms.Close(); - return _savebuff2; - } public void LoadStateBinary(BinaryReader reader) { - int newlen = reader.ReadInt32(); - if (newlen != _savebuff.Length) - { - throw new Exception("Unexpected state size"); - } - - reader.Read(_savebuff, 0, _savebuff.Length); - if (!Core.gpgx_state_load(_savebuff, _savebuff.Length)) - { - throw new Exception("gpgx_state_load() returned false"); - } - - // other variables - Frame = reader.ReadInt32(); - LagCount = reader.ReadInt32(); - IsLagFrame = reader.ReadBoolean(); - UpdateVideo(); - } - - public void SaveStateBinary(BinaryWriter writer) - { - if (!Core.gpgx_state_save(_savebuff, _savebuff.Length)) - throw new Exception("gpgx_state_save() returned false"); - - writer.Write(_savebuff.Length); - writer.Write(_savebuff); - // other variables - writer.Write(Frame); - writer.Write(LagCount); - writer.Write(IsLagFrame); - } - - private byte[] _savebuff; - private byte[] _savebuff2; - - private void InitStateBuffers() - { - byte[] tmp = new byte[Core.gpgx_state_max_size()]; - int size = Core.gpgx_state_size(tmp, tmp.Length); - if (size <= 0) - throw new Exception("Couldn't Determine GPGX internal state size!"); - _savebuff = new byte[size]; - _savebuff2 = new byte[_savebuff.Length + 13]; - Console.WriteLine("GPGX Internal State Size: {0}", size); - } - -#else - public void LoadStateBinary(BinaryReader reader) - { - var elf = (ElfRunner)NativeData; - elf.LoadStateBinary(reader); + Elf.LoadStateBinary(reader); // other variables Frame = reader.ReadInt32(); LagCount = reader.ReadInt32(); @@ -107,8 +46,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx public void SaveStateBinary(BinaryWriter writer) { - var elf = (ElfRunner)NativeData; - elf.SaveStateBinary(writer); + Elf.SaveStateBinary(writer); // other variables writer.Write(Frame); writer.Write(LagCount); @@ -128,6 +66,5 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx private void InitStateBuffers() { } -#endif } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs index ff9acfd85a..211dff652c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs @@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx IInputPollable, IDebuggable, IDriveLight, ICodeDataLogger, IDisassemblable { LibGPGX Core; - IDisposable NativeData; + ElfRunner Elf; DiscSystem.Disc CD; DiscSystem.DiscSectorReader DiscSectorReader; @@ -68,20 +68,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx try { - IImportResolver iimp; - if (IntPtr.Size == 8) // there is no 64 bit build of gpgx right now otherwise - { - var elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 65536, 40 * 1024 * 1024); - NativeData = elf; - iimp = elf; - } - else - { - var dll = new InstanceDll(Path.Combine(comm.CoreFileProvider.DllPath(), LibGPGX.DllName)); - NativeData = dll; - iimp = dll; - } - Core = BizInvoker.GetInvoker(iimp); + Elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 65536, 36 * 1024 * 1024, 4 * 1024 * 1024); + + Core = BizInvoker.GetInvoker(Elf); _syncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings(); _settings = (GPGXSettings)Settings ?? new GPGXSettings(); @@ -171,6 +160,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx Tracer = new GPGXTraceBuffer(this, MemoryDomains, this); (ServiceProvider as BasicServiceProvider).Register(Tracer); + + Elf.Seal(); } catch { diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs index fe1d8cc887..6328c1d29d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs @@ -57,22 +57,16 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx [BizImport(CallingConvention.Cdecl)] public abstract void gpgx_get_fps(ref int num, ref int den); - [BizImport(CallingConvention.Cdecl)] - public abstract int gpgx_state_max_size(); - [BizImport(CallingConvention.Cdecl)] - public abstract int gpgx_state_size(byte[] dest, int size); - [BizImport(CallingConvention.Cdecl)] - public abstract bool gpgx_state_save(byte[] dest, int size); - [BizImport(CallingConvention.Cdecl)] - public abstract bool gpgx_state_load(byte[] src, int size); - [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); [BizImport(CallingConvention.Cdecl)] - public abstract void gpgx_get_sram(ref IntPtr area, ref int size); + public abstract IntPtr gpgx_get_sram(ref int size); + + [BizImport(CallingConvention.Cdecl)] + public abstract bool gpgx_put_sram(byte[] data, int size); [BizImport(CallingConvention.Cdecl)] public abstract void gpgx_clear_sram(); @@ -85,14 +79,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx // the unmanaged char pointer was allocated in hglobal and try to free it that way public abstract IntPtr gpgx_get_memdom(int which, ref IntPtr area, ref int size); - // call this before reading sram returned by gpgx_get_sram() - [BizImport(CallingConvention.Cdecl)] - public abstract void gpgx_sram_prepread(); - - // call this after writing sram returned by gpgx_get_sram() - [BizImport(CallingConvention.Cdecl)] - public abstract void gpgx_sram_commitwrite(); - [BizImport(CallingConvention.Cdecl)] public abstract void gpgx_reset(bool hard); diff --git a/BizHawk.Emulation.Cores/ElfRunner.cs b/BizHawk.Emulation.Cores/ElfRunner.cs index 30a3acbbbf..a539133d4e 100644 --- a/BizHawk.Emulation.Cores/ElfRunner.cs +++ b/BizHawk.Emulation.Cores/ElfRunner.cs @@ -29,11 +29,31 @@ namespace BizHawk.Emulation.Cores /// private Heap _heap; + /// + /// sealed heap (writable only during init) + /// + private Heap _sealedheap; + + /// + /// invisible heap (not savestated, use with care) + /// + private Heap _invisibleheap; + private long _loadoffset; private Dictionary> _symdict; private List> _symlist; - public ElfRunner(string filename, long heapsize, long sealedheapsize) + private List _disposeList = new List(); + + private ulong GetHeapStart(ulong prevend) + { + // if relocatable, we won't have constant pointers, so put the heap anywhere + // otherwise, put the heap at a canonical location aligned 1MB from the end of the elf, then incremented 16MB + ulong heapstart = HasRelocations() ? 0 : ((prevend - 1) | 0xfffff) + 0x1000001; + return heapstart; + } + + public ElfRunner(string filename, long heapsize, long sealedheapsize, long invisibleheapsize) { using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { @@ -61,6 +81,7 @@ namespace BizHawk.Emulation.Cores try { + _disposeList.Add(_base); _base.Set(_base.Start, _base.Size, MemoryBlock.Protection.RW); foreach (var seg in loadsegs) @@ -82,10 +103,28 @@ namespace BizHawk.Emulation.Cores _base.Set((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, MemoryBlock.Protection.RW); } - // if relocatable, we won't have constant pointers, so put the heap anywhere - // otherwise, put the heap at a canonical location aligned 1MB from the end of the elf, then incremented 16MB - ulong heapstart = HasRelocations() ? 0 : ((_base.End - 1) | 0xfffff) + 0x1000001; - _heap = new Heap(heapstart, (ulong)heapsize, "sbrk-heap"); + ulong end = _base.End; + + if (heapsize > 0) + { + _heap = new Heap(GetHeapStart(end), (ulong)heapsize, "sbrk-heap"); + end = _heap.Memory.End; + _disposeList.Add(_heap); + } + + if (sealedheapsize > 0) + { + _sealedheap = new Heap(GetHeapStart(end), (ulong)sealedheapsize, "sealed-heap"); + end = _sealedheap.Memory.End; + _disposeList.Add(_sealedheap); + } + + if (invisibleheapsize > 0) + { + _invisibleheap = new Heap(GetHeapStart(end), (ulong)invisibleheapsize, "invisible-heap"); + end = _invisibleheap.Memory.End; + _disposeList.Add(_invisibleheap); + } //FixupGOT(); ConnectAllClibPatches(); @@ -99,7 +138,7 @@ namespace BizHawk.Emulation.Cores } catch { - _base.Dispose(); + Dispose(); throw; } } @@ -213,6 +252,11 @@ namespace BizHawk.Emulation.Cores //GC.SuppressFinalize(this); } + public void Seal() + { + _sealedheap.Seal(); + } + //~ElfRunner() //{ // Dispose(false); @@ -222,16 +266,9 @@ namespace BizHawk.Emulation.Cores { if (disposing) { - if (_base != null) - { - _base.Dispose(); - _base = null; - } - if (_heap != null) - { - _heap.Dispose(); - _heap = null; - } + foreach (var d in _disposeList) + d.Dispose(); + _disposeList.Clear(); } } @@ -259,6 +296,12 @@ namespace BizHawk.Emulation.Cores [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void DebugPuts_D(string s); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate IntPtr SbrkSealed_D(UIntPtr n); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate IntPtr SbrkInvisible_D(UIntPtr n); + [CLibPatch("_ecl_trap")] private void Trap() { @@ -268,9 +311,7 @@ namespace BizHawk.Emulation.Cores [CLibPatch("_ecl_sbrk")] private IntPtr Sbrk(UIntPtr n) { - var ret = Z.US(_heap.Allocate((ulong)n, 1)); - Console.WriteLine("Expanding waterbox heap to {0} bytes", _heap.Used); - return ret; + return Z.US(_heap.Allocate((ulong)n, 1)); } [CLibPatch("_ecl_debug_puts")] @@ -279,6 +320,18 @@ namespace BizHawk.Emulation.Cores Console.WriteLine("Waterbox debug puts: {0}", s); } + [CLibPatch("_ecl_sbrk_sealed")] + private IntPtr SbrkSealed(UIntPtr n) + { + return Z.US(_sealedheap.Allocate((ulong)n, 16)); + } + + [CLibPatch("_ecl_sbrk_invisible")] + private IntPtr SbrkInvisible(UIntPtr n) + { + return Z.US(_invisibleheap.Allocate((ulong)n, 16)); + } + /// /// list of delegates that need to not be GCed /// @@ -286,6 +339,8 @@ namespace BizHawk.Emulation.Cores private void ConnectAllClibPatches() { + _delegates.Clear(); // in case we're reconnecting + var methods = GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(mi => mi.GetCustomAttributes(typeof(CLibPatchAttribute), false).Length > 0); foreach (var mi in methods) @@ -344,7 +399,9 @@ namespace BizHawk.Emulation.Cores ms.CopyTo(bw.BaseStream); } - _heap.SaveStateBinary(bw); + if (_heap != null) _heap.SaveStateBinary(bw); + if (_sealedheap != null) _sealedheap.SaveStateBinary(bw); + bw.Write(MAGIC); } public void LoadStateBinary(BinaryReader br) @@ -365,7 +422,14 @@ namespace BizHawk.Emulation.Cores CopySome(br.BaseStream, ms, len); } - _heap.LoadStateBinary(br); + if (_heap != null) _heap.LoadStateBinary(br); + if (_sealedheap != null) _sealedheap.LoadStateBinary(br); + if (br.ReadUInt64() != MAGIC) + throw new InvalidOperationException("Magic not magic enough!"); + + // the syscall trampolines were overwritten in loadstate (they're in .bss), and if we're cross-session, + // are no longer valid. cores must similiarly resend any external pointers they gave the core. + ConnectAllClibPatches(); } #endregion @@ -463,6 +527,7 @@ namespace BizHawk.Emulation.Cores ulong ret = Memory.Start + Used; Memory.Set(ret, newused - Used, MemoryBlock.Protection.RW); Used = newused; + Console.WriteLine("Allocated {0} bytes on {1}", size, Name); return ret; } diff --git a/waterbox/gpgx/cinterface/cinterface.c b/waterbox/gpgx/cinterface/cinterface.c index 1e454e5723..ff3ffb92bf 100644 --- a/waterbox/gpgx/cinterface/cinterface.c +++ b/waterbox/gpgx/cinterface/cinterface.c @@ -29,8 +29,6 @@ char MS_BIOS_JP[256] = "MS_BIOS_JP"; char romextension[4]; -static uint32_t bitmap_data_[1024 * 512]; - static int16 soundbuffer[4096]; static int nsamples; @@ -65,6 +63,8 @@ ECL_ENTRY void (*biz_writecb)(unsigned addr) = NULL; CDCallback biz_cdcallback = NULL; unsigned biz_lastpc = 0; +uint8 *tempsram; + static void update_viewport(void) { vwidth = bitmap.viewport.w + (bitmap.viewport.x * 2); @@ -295,23 +295,78 @@ GPGX_EX void gpgx_clear_sram(void) // a bit hacky: // in order to present a single memory block to the frontend, -// we copy the bram bits next to the ebram bits +// we copy the both the bram and the ebram to another area -GPGX_EX void gpgx_sram_prepread(void) +GPGX_EX void* gpgx_get_sram(int *size) { - if (!sram.on && cdd.loaded && scd.cartridge.id) + if (sram.on) { - void *dest = scd.cartridge.area + scd.cartridge.mask + 1; - memcpy(dest, scd.bram, 0x2000); + *size = saveramsize(); + return sram.sram; + } + else if (cdd.loaded && scd.cartridge.id) + { + int sz = scd.cartridge.mask + 1; + memcpy(tempsram, scd.cartridge.area, sz); + memcpy(tempsram + sz, scd.bram, 0x2000); + *size = sz + 0x2000; + return tempsram; + } + else if (cdd.loaded) + { + *size = 0x2000; + return scd.bram; + } + else if (scd.cartridge.id) + { + *size = scd.cartridge.mask + 1; + return scd.cartridge.area; + } + else + { + *size = 0; + return NULL; } } -GPGX_EX void gpgx_sram_commitwrite(void) +GPGX_EX int gpgx_put_sram(const uint8 *data, int size) { - if (!sram.on && cdd.loaded && scd.cartridge.id) + if (sram.on) { - void *src = scd.cartridge.area + scd.cartridge.mask + 1; - memcpy(scd.bram, src, 0x2000); + if (size != saveramsize()) + return 0; + memcpy(sram.sram, data, size); + return 1; + } + else if (cdd.loaded && scd.cartridge.id) + { + int sz = scd.cartridge.mask + 1; + if (size != sz + 0x2000) + return 0; + memcpy(scd.cartridge.area, data, sz); + memcpy(scd.bram, data + sz, 0x2000); + return 1; + } + else if (cdd.loaded) + { + if (size != 0x2000) + return 0; + memcpy(scd.bram, data, size); + return 1; + } + else if (scd.cartridge.id) + { + int sz = scd.cartridge.mask + 1; + if (size != sz) + return 0; + memcpy(scd.cartridge.area, data, size); + return 1; + } + else + { + if (size != 0) + return 0; + return 1; // "successful"? } } @@ -460,35 +515,6 @@ GPGX_EX unsigned gpgx_peek_s68k_bus(unsigned addr) return 0xff; } -GPGX_EX void gpgx_get_sram(void **area, int *size) -{ - if (!area || !size) - return; - - if (sram.on) - { - *area = sram.sram; - *size = saveramsize(); - } - else if (scd.cartridge.id) - { - *area = scd.cartridge.area; - *size = scd.cartridge.mask + 1 + 0x2000; - } - else if (cdd.loaded) - { - *area = scd.bram; - *size = 0x2000; - } - else - { - if (area) - *area = NULL; - if (size) - *size = 0; - } -} - struct InitSettings { uint8_t Filter; @@ -504,8 +530,7 @@ struct InitSettings GPGX_EX int gpgx_init(const char *feromextension, ECL_ENTRY int (*feload_archive_cb)(const char *filename, unsigned char *buffer, int maxsize), int sixbutton, char system_a, char system_b, int region, struct InitSettings *settings) { memset(&bitmap, 0, sizeof(bitmap)); - memset(bitmap_data_, 0, sizeof(bitmap_data_)); - + strncpy(romextension, feromextension, 3); romextension[3] = 0; @@ -514,7 +539,10 @@ GPGX_EX int gpgx_init(const char *feromextension, ECL_ENTRY int (*feload_archive bitmap.width = 1024; bitmap.height = 512; bitmap.pitch = 1024 * 4; - bitmap.data = (uint8_t *)bitmap_data_; + bitmap.data = alloc_invisible(2 * 1024 * 1024); + tempsram = alloc_invisible(24 * 1024); + + ext.md_cart.rom = alloc_sealed(32 * 1024 * 1024); /* sound options */ config.psg_preamp = 150; @@ -528,7 +556,7 @@ GPGX_EX int gpgx_init(const char *feromextension, ECL_ENTRY int (*feload_archive config.lg = settings->LowGain; //1.0; config.mg = settings->MidGain; //1.0; config.hg = settings->HighGain; //1.0; - config.dac_bits = 14; /* MAX DEPTH */ + config.dac_bits = 14; /* MAX DEPTH */ config.ym2413= 2; /* AUTO */ config.mono = 0; /* STEREO output */ diff --git a/waterbox/gpgx/core/cart_hw/md_cart.h b/waterbox/gpgx/core/cart_hw/md_cart.h index 4589781969..dbf36a0d60 100644 --- a/waterbox/gpgx/core/cart_hw/md_cart.h +++ b/waterbox/gpgx/core/cart_hw/md_cart.h @@ -72,7 +72,7 @@ typedef struct /* Cartridge type */ typedef struct { - uint8 rom[MAXROMSIZE]; /* ROM area */ + uint8 *rom; /* ROM area */ uint8 *base; /* ROM base (saved for OS/Cartridge ROM swap) */ uint32 romsize; /* ROM size */ uint32 mask; /* ROM mask */ diff --git a/waterbox/gpgx/core/cd_hw/cd_cart.h b/waterbox/gpgx/core/cd_hw/cd_cart.h index e166ff496e..86ecfe4c9b 100644 --- a/waterbox/gpgx/core/cd_hw/cd_cart.h +++ b/waterbox/gpgx/core/cd_hw/cd_cart.h @@ -35,12 +35,12 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************************/ - + /* CD compatible ROM/RAM cartridge */ -typedef struct +typedef struct { - uint8 area[0x810000]; /* cartridge ROM/RAM area (max. 8MB + 64KB backup) */ + uint8 area[0x4000]; // not unioned with cartrom, so need not be a specific size for that; and we only use 16k ebram in bizhawk uint8 boot; /* cartridge boot mode (0x00: boot from CD with ROM/RAM cartridge enabled, 0x40: boot from ROM cartridge with CD enabled) */ uint8 id; /* RAM cartridge ID (related to RAM size, 0 if disabled) */ uint8 prot; /* RAM cartridge write protection */ diff --git a/waterbox/gpgx/core/genesis.h b/waterbox/gpgx/core/genesis.h index 88b086c0ef..99d9a8c96b 100644 --- a/waterbox/gpgx/core/genesis.h +++ b/waterbox/gpgx/core/genesis.h @@ -47,7 +47,7 @@ #include "scd.h" /* External Hardware */ -typedef union +typedef struct { md_cart_t md_cart; cd_hw_t cd_hw; diff --git a/waterbox/gpgx/core/loadrom.c b/waterbox/gpgx/core/loadrom.c index 77b7886bd0..b3076960e1 100644 --- a/waterbox/gpgx/core/loadrom.c +++ b/waterbox/gpgx/core/loadrom.c @@ -436,7 +436,7 @@ int load_bios(void) return size; } - + return -1; } @@ -445,7 +445,7 @@ int load_bios(void) { /* check if Game Gear BOOTROM is already loaded */ if (!(system_bios & SYSTEM_GG)) - { + { /* mark both Master System & Game Gear BOOTROM as unloaded */ system_bios &= ~(SYSTEM_SMS | SYSTEM_GG); @@ -464,7 +464,7 @@ int load_bios(void) return size; } - + return -1; } @@ -473,7 +473,7 @@ int load_bios(void) { /* check if Master System BOOTROM is already loaded */ if (!(system_bios & SYSTEM_SMS) || ((system_bios & 0x0c) != (region_code >> 4))) - { + { /* mark both Master System & Game Gear BOOTROM as unloaded */ system_bios &= ~(SYSTEM_SMS | SYSTEM_GG); @@ -506,7 +506,7 @@ int load_bios(void) return size; } - + return -1; } @@ -557,7 +557,7 @@ int load_rom(const char *filename) { /* load file into ROM buffer */ char extension[4]; - size = load_archive(filename, cart.rom, sizeof(cart.rom), extension); + size = load_archive(filename, cart.rom, 32 * 1024 * 1024, extension); if (!size) { /* mark all BOOTROM as unloaded since they could have been overwritten */ @@ -641,7 +641,7 @@ int load_rom(const char *filename) } } } - + /* initialize ROM size */ cart.romsize = size; @@ -653,7 +653,7 @@ int load_rom(const char *filename) /* CD image file */ if (system_hw == SYSTEM_MCD) - { + { /* load CD BOOT ROM */ if (!load_bios()) { @@ -950,8 +950,8 @@ int load_rom(const char *filename) /**************************************************************************** * get_region * - * Set console region from ROM header passed as parameter or - * from previous auto-detection (if NULL) + * Set console region from ROM header passed as parameter or + * from previous auto-detection (if NULL) * ****************************************************************************/ void get_region(char *romheader) @@ -972,7 +972,7 @@ void get_region(char *romheader) case 0x64: region_code = REGION_EUROPE; break; - + default: region_code = REGION_JAPAN_NTSC; break; @@ -1032,7 +1032,7 @@ void get_region(char *romheader) /* need PAL settings */ region_code = REGION_EUROPE; } - else if ((rominfo.realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL)) + else if ((rominfo.realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL)) { /* On Dal Jang Goon (Korea) needs JAPAN region code */ region_code = REGION_JAPAN_NTSC; @@ -1053,7 +1053,7 @@ void get_region(char *romheader) /* restore auto-detected region */ region_code = rom_region; } - + /* force console region if requested */ if (config.region_detect == 1) region_code = REGION_USA; else if (config.region_detect == 2) region_code = REGION_EUROPE; @@ -1091,7 +1091,7 @@ char *get_company(void) int i; char company[10]; - for (i = 3; i < 8; i++) + for (i = 3; i < 8; i++) { company[i - 3] = rominfo.copyright[i]; } diff --git a/waterbox/libc/functions/_PDCLIB/emulibc.c b/waterbox/libc/functions/_PDCLIB/emulibc.c index 5e46361cb2..27314a2c22 100644 --- a/waterbox/libc/functions/_PDCLIB/emulibc.c +++ b/waterbox/libc/functions/_PDCLIB/emulibc.c @@ -8,6 +8,19 @@ ECL_EXPORT ECL_ENTRY __attribute__((noreturn)) void (*_ecl_trap)(void); // somet ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk)(size_t n); // sbrk. won't return if the request can't be satisfied ECL_EXPORT ECL_ENTRY void (*_ecl_debug_puts)(const char *); // low level debug write, doesn't involve STDIO +ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk_sealed)(size_t n); // allocate memory; see emulibc.h +ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk_invisible)(size_t n); // allocate memory; see emulibc.h + +void *alloc_sealed(size_t size) +{ + return _ecl_sbrk_sealed(size); +} + +void *alloc_invisible(size_t size) +{ + return _ecl_sbrk_invisible(size); +} + void *_PDCLIB_sbrk(size_t n) { void *ret = _ecl_sbrk(n); diff --git a/waterbox/libc/includes/emulibc.h b/waterbox/libc/includes/emulibc.h index 9fcc9854a6..4b4a14223e 100644 --- a/waterbox/libc/includes/emulibc.h +++ b/waterbox/libc/includes/emulibc.h @@ -1,9 +1,22 @@ #ifndef _EMULIBC_H #define _EMULIBC_H +#include + // mark an entry point or callback pointer #define ECL_ENTRY __attribute__((ms_abi)) // mark a visible symbol #define ECL_EXPORT __attribute__((visibility("default"))) +// allocate memory from the "sealed" pool. this memory can never be freed, +// and can only be allocated or written to during the init phase. after that, the host +// seals the pool, making it read only and all of its contents frozen. good for LUTs and +// ROMs +void *alloc_sealed(size_t size); + +// allocate memory from the "invisible" pool. this memory can never be freed. +// this memory is not savestated! this should only be used for a large buffer whose contents +// you are absolutely sure will not harm savestates +void *alloc_invisible(size_t size); + #endif