diff --git a/Assets/dll/libgambatte.dll b/Assets/dll/libgambatte.dll
index d91f7c7995..424d58a062 100644
Binary files a/Assets/dll/libgambatte.dll and b/Assets/dll/libgambatte.dll differ
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
index d686d9290c..4a8bbed838 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
@@ -24,18 +24,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
["F"] = (byte)(data[(int)LibGambatte.RegIndices.F] & 0xff),
["H"] = (byte)(data[(int)LibGambatte.RegIndices.H] & 0xff),
["L"] = (byte)(data[(int)LibGambatte.RegIndices.L] & 0xff),
- ["ROM Bank"] = LibGambatte.gambatte_getrombank(GambatteState),
- ["SRAM Bank"] = LibGambatte.gambatte_getsrambank(GambatteState)
+ // banks
+ ["ROM0 BANK"] = (ushort)LibGambatte.gambatte_getbank(GambatteState, LibGambatte.BankType.ROM0),
+ ["ROMX BANK"] = (ushort)LibGambatte.gambatte_getbank(GambatteState, LibGambatte.BankType.ROMX),
+ ["VRAM BANK"] = (byte)LibGambatte.gambatte_getbank(GambatteState, LibGambatte.BankType.VRAM),
+ ["SRAM BANK"] = (byte)LibGambatte.gambatte_getbank(GambatteState, LibGambatte.BankType.SRAM),
+ ["WRAM BANK"] = (byte)LibGambatte.gambatte_getbank(GambatteState, LibGambatte.BankType.WRAM),
+ // todo: maybe do [bc]/[de]/[hl]?
};
}
public void SetCpuRegister(string register, int value)
{
- int[] data = new int[10];
- LibGambatte.gambatte_getregs(GambatteState, data);
- LibGambatte.RegIndices index = (LibGambatte.RegIndices)Enum.Parse(typeof(LibGambatte.RegIndices), register);
- data[(int)index] = value & (index <= LibGambatte.RegIndices.SP ? 0xffff : 0xff);
- LibGambatte.gambatte_setregs(GambatteState, data);
+ if (register.Length == 9 && register.Substring(4, 5).ToUpperInvariant() == " BANK")
+ {
+ LibGambatte.BankType type = (LibGambatte.BankType)Enum.Parse(typeof(LibGambatte.BankType), register.Substring(0, 4).ToUpperInvariant());
+ LibGambatte.gambatte_setbank(GambatteState, type, value);
+ }
+ else
+ {
+ int[] data = new int[10];
+ LibGambatte.gambatte_getregs(GambatteState, data);
+ LibGambatte.RegIndices index = (LibGambatte.RegIndices)Enum.Parse(typeof(LibGambatte.RegIndices), register.ToUpperInvariant());
+ data[(int)index] = value & (index <= LibGambatte.RegIndices.SP ? 0xffff : 0xff);
+ LibGambatte.gambatte_setregs(GambatteState, data);
+ }
}
public bool CanStep(StepType type) => false;
@@ -73,13 +86,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
if (getHasCBOfType())
{
MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "System Bus");
+ var bank = LibGambatte.gambatte_getaddrbank(GambatteState, (ushort)address);
if (address < 0x4000u) // always rom bank 0 for most mbcs (todo: edge mbcs where this doesn't apply)
{
MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "ROM");
}
else if (address < 0x8000u) // rom bank x
{
- var bank = LibGambatte.gambatte_getrombank(GambatteState); // this will return 1 in case there is no mbc (0 is valid for some mbcs too)
address += (uint)(bank * 0x4000);
address -= 0x4000u;
MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "ROM");
@@ -88,7 +101,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
if (IsCGBMode() && !IsCGBDMGMode())
{
- var bank = LibGambatte.gambatte_cpuread(GambatteState, 0xFF4F) & 1;
address += (uint)(bank * 0x2000);
}
address -= 0x8000u;
@@ -96,7 +108,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
}
else if (address < 0xC000u) // sram (may be banked)
{
- var bank = LibGambatte.gambatte_getsrambank(GambatteState); // this will return 0 in case there is only one bank
address += (uint)(bank * 0x2000);
address -= 0xA000u;
MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "SRAM");
@@ -110,7 +121,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
if (IsCGBMode() && !IsCGBDMGMode())
{
- var bank = Math.Max(LibGambatte.gambatte_cpuread(GambatteState, 0xFF70) & 7, 1);
address += (uint)(bank * 0x1000);
}
address -= 0xD000u;
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
index fb1074723f..2f17030c35 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
@@ -454,7 +454,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
/// write a single byte to the cpu bus. while there is no cycle cost to these writes, there can be quite a few side effects.
/// use at your own risk.
///
- /// opaque state pointe
+ /// opaque state pointer
/// system bus address
/// byte to write
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
@@ -463,24 +463,57 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
///
/// link cable stuff; never touch for normal operation
///
- /// opaque state pointe
+ /// opaque state pointer
/// todo
/// todo
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_linkstatus(IntPtr core, int which);
///
- /// get current rom bank
+ /// get current bank for type of memory
///
- /// opaque state pointe
- /// current rom bank
+ /// opaque state pointer
+ /// type of memory
+ /// current bank
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
- public static extern int gambatte_getrombank(IntPtr core);
+ public static extern int gambatte_getbank(IntPtr core, BankType type);
+
+ ///
+ /// get current bank for type of memory at address
+ ///
+ /// opaque state pointer
+ /// address for memory type
+ /// current bank, or 0 if not applicable
+ [DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int gambatte_getaddrbank(IntPtr core, ushort addr);
+
+ ///
+ /// set current bank for type of memory
+ ///
+ /// opaque state pointer
+ /// type of memory
+ /// bank to set
+ [DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void gambatte_setbank(IntPtr core, BankType type, int bank);
+
+ ///
+ /// set current bank for type of memory at address
+ ///
+ /// opaque state pointer
+ /// address for memory type
+ /// bank to set
+ [DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void gambatte_setbank(IntPtr core, ushort addr, int bank);
+
+ public enum BankType : int
+ {
+ ROM0, ROMX, VRAM, SRAM, WRAM
+ }
///
/// get current sram bank
///
- /// opaque state pointe
+ /// opaque state pointer
/// current sram bank
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_getsrambank(IntPtr core);
diff --git a/submodules/gambatte b/submodules/gambatte
index dc50297053..13c15f2a5a 160000
--- a/submodules/gambatte
+++ b/submodules/gambatte
@@ -1 +1 @@
-Subproject commit dc50297053a3e8fff285629d735a9618b9406245
+Subproject commit 13c15f2a5ad4e80e3aeeaf973a0bba46e10299af