diff --git a/BizHawk.Emulation/Consoles/Nintendo/GBA/LibMeteor.cs b/BizHawk.Emulation/Consoles/Nintendo/GBA/LibMeteor.cs index 0b75031d9d..b0a4d749df 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/GBA/LibMeteor.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/GBA/LibMeteor.cs @@ -111,5 +111,26 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void libmeteor_setkeycallback(InputCallback callback); + /// + /// parameter to libmeteor_getmemoryarea + /// + public enum MemoryArea : int + { + bios = 0, + ewram = 1, + iwram = 2, + palram = 3, + vram = 4, + oam = 5, + rom = 6 + } + + /// + /// return a pointer to a memory area + /// + /// + /// IntPtr.Zero if which is unrecognized + [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr libmeteor_getmemoryarea(MemoryArea which); } } diff --git a/BizHawk.Emulation/Consoles/Nintendo/GBA/Meteor.cs b/BizHawk.Emulation/Consoles/Nintendo/GBA/Meteor.cs index b804db5dc8..feefac8c6d 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/GBA/Meteor.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/GBA/Meteor.cs @@ -29,6 +29,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA LibMeteor.libmeteor_reset(); LibMeteor.libmeteor_loadbios(bios, (uint)bios.Length); LibMeteor.libmeteor_loadrom(rom, (uint)rom.Length); + + SetUpMemoryDomains(); } public void FrameAdvance(bool render, bool rendersound = true) @@ -110,16 +112,63 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA public CoreOutputComm CoreOutputComm { get { return _CoreOutputComm; } } - public IList MemoryDomains - { - get { return null; } - } + #region memorydomains + List _MemoryDomains = new List(); + public IList MemoryDomains { get { return _MemoryDomains; } } public MemoryDomain MainMemory { - get { return null; } + // some core tools assume MainMemory == MemoryDomains[0], so do that anyway + get { return MemoryDomains[0]; } } + void AddMemoryDomain(LibMeteor.MemoryArea which, int size, string name) + { + IntPtr data = LibMeteor.libmeteor_getmemoryarea(which); + if (data == IntPtr.Zero) + throw new Exception("libmeteor_getmemoryarea() returned NULL??"); + + MemoryDomain md = new MemoryDomain(name, size, Endian.Little, + delegate(int addr) + { + unsafe + { + byte* d = (byte*)data; + if (addr < 0 || addr >= size) + throw new IndexOutOfRangeException(); + return d[addr]; + } + }, + delegate(int addr, byte val) + { + unsafe + { + byte* d = (byte*)data; + if (addr < 0 || addr >= size) + throw new IndexOutOfRangeException(); + d[addr] = val; + } + }); + _MemoryDomains.Add(md); + } + + void SetUpMemoryDomains() + { + _MemoryDomains.Clear(); + // this must be first to coincide with "main memory" + // note that ewram could also be considered main memory depending on which hairs you split + AddMemoryDomain(LibMeteor.MemoryArea.iwram, 32 * 1024, "IWRAM"); + AddMemoryDomain(LibMeteor.MemoryArea.ewram, 256 * 1024, "EWRAM"); + AddMemoryDomain(LibMeteor.MemoryArea.bios, 16 * 1024, "BIOS"); + AddMemoryDomain(LibMeteor.MemoryArea.palram, 1024, "PALRAM"); + AddMemoryDomain(LibMeteor.MemoryArea.vram, 96 * 1024, "VRAM"); + AddMemoryDomain(LibMeteor.MemoryArea.oam, 1024, "OAM"); + // even if the rom is less than 32MB, the whole is still valid in meteor + AddMemoryDomain(LibMeteor.MemoryArea.rom, 32 * 1024 * 1024, "ROM"); + } + + #endregion + /// like libsnes, the library is single-instance static GBA attachedcore; /// hold pointer to message callback so it won't get GCed @@ -191,6 +240,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA inputcallback = null; LibMeteor.libmeteor_setmessagecallback(messagecallback); LibMeteor.libmeteor_setkeycallback(inputcallback); + _MemoryDomains.Clear(); } } diff --git a/BizHawk.MultiClient/output/dll/libmeteor.dll b/BizHawk.MultiClient/output/dll/libmeteor.dll index 5335be733a..71bbcdb549 100644 Binary files a/BizHawk.MultiClient/output/dll/libmeteor.dll and b/BizHawk.MultiClient/output/dll/libmeteor.dll differ diff --git a/libmeteor/cinterface.cpp b/libmeteor/cinterface.cpp index 0856955f39..c0a640735b 100644 --- a/libmeteor/cinterface.cpp +++ b/libmeteor/cinterface.cpp @@ -130,5 +130,10 @@ EXPORT void libmeteor_loadbios(const void *data, unsigned size) AMeteor::_memory.LoadBios((const uint8_t*)data, size); } -// TODO: memory domains +EXPORT uint8_t *libmeteor_getmemoryarea(int which) +{ + return AMeteor::_memory.GetMemoryArea(which); +} + +// TODO: cartram and system bus memory domains diff --git a/libmeteor/include/ameteor/memory.hpp b/libmeteor/include/ameteor/memory.hpp index b3b919aaee..0b167cfe8c 100644 --- a/libmeteor/include/ameteor/memory.hpp +++ b/libmeteor/include/ameteor/memory.hpp @@ -120,6 +120,8 @@ namespace AMeteor void TimeEvent (); + uint8_t* GetMemoryArea(int which); + private : // times for a 8 or 16 bits access uint8_t m_memtime[0xF]; diff --git a/libmeteor/source/memory.cpp b/libmeteor/source/memory.cpp index 3bcab840ff..5532ea2f53 100644 --- a/libmeteor/source/memory.cpp +++ b/libmeteor/source/memory.cpp @@ -820,4 +820,27 @@ namespace AMeteor if (m_cart->Write(add, val)) CLOCK.SetBattery(CART_SAVE_TIME); } + + uint8_t *Memory::GetMemoryArea(int which) + { + switch (which) + { + case 0: + return m_brom; // BIOS - System ROM + case 1: + return m_wbram; // WRAM - On-board Work RAM + case 2: + return m_wcram; // WRAM - In-chip Work RAM + case 3: + return m_pram; // BG/OBJ Palette RAM + case 4: + return m_vram; // VRAM - Video RAM + case 5: + return m_oram; // OAM - OBJ Attributes + case 6: + return m_rom; // Game Pake ROM/FlashROM (max 32MB) + default: + return 0; + } + } }