diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISettable.cs index 7e2ba05432..2fd947256c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISettable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISettable.cs @@ -132,6 +132,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy [DeepEqualsIgnore] private bool _equalLengthFrames; + [DisplayName("Initial DIV offset")] + [Description("Internal. Probably doesn't work. Leave this set to 0. Accepts values from 0 to 65532 in steps of 4")] + [DefaultValue(0)] + public int InitialDiv { get; set; } + public GambatteSyncSettings() { SettingsUtil.SetDefaultValues(this); @@ -146,6 +151,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy { return !DeepEquality.DeepEquals(x, y); } + + public uint GetInitialDivInternal() + { + return (uint)(InitialDiv & 0xfffc); + } } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs index d618336bb1..4fa2a67ec4 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -63,6 +63,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy real_rtc_time = !DeterministicEmulation && _syncSettings.RealTimeRTC; + DivInternal = _syncSettings.GetInitialDivInternal(); + LibGambatte.LoadFlags flags = 0; switch (_syncSettings.ConsoleMode) @@ -88,7 +90,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy flags |= LibGambatte.LoadFlags.MULTICART_COMPAT; } - if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, GetCurrentTime(), flags) != 0) + if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, GetCurrentTime(), flags, DivInternal) != 0) { throw new InvalidOperationException("gambatte_load() returned non-zero (is this not a gb or gbc rom?)"); } @@ -172,6 +174,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy /// private LibGambatte.Buttons CurrentButtons = 0; + private uint DivInternal = 0; + #region RTC /// @@ -322,7 +326,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy if (controller.IsPressed("Power")) { - LibGambatte.gambatte_reset(GambatteState, GetCurrentTime()); + LibGambatte.gambatte_reset(GambatteState, GetCurrentTime(), DivInternal); } if (Tracer.Enabled) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs index 621f8c8998..ecb9b432ca 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs @@ -57,7 +57,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy /// ORed combination of LoadFlags. /// 0 on success, negative value on failure. [DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, long now, LoadFlags flags); + public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, long now, LoadFlags flags, uint div); /// /// Load GB BIOS image. @@ -124,7 +124,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy /// opaque state pointer /// RTC time when the reset occurs [DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void gambatte_reset(IntPtr core, long now); + public static extern void gambatte_reset(IntPtr core, long now, uint div); /// /// palette type for gambatte_setdmgpalettecolor diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h index 5f1a5e4325..2b953984a9 100644 --- a/libgambatte/include/gambatte.h +++ b/libgambatte/include/gambatte.h @@ -60,7 +60,7 @@ public: * @param flags ORed combination of LoadFlags. * @return 0 on success, negative value on failure. */ - int load(const char *romfiledata, unsigned romfilelength, std::uint32_t now, unsigned flags = 0); + int load(const char *romfiledata, unsigned romfilelength, std::uint32_t now, unsigned flags, unsigned div); int loadGBCBios(const char* biosfiledata); int loadDMGBios(const char* biosfiledata); @@ -93,7 +93,7 @@ public: /** Reset to initial state. * Equivalent to reloading a ROM image, or turning a Game Boy Color off and on again. */ - void reset(std::uint32_t now); + void reset(std::uint32_t now, unsigned div); /** @param palNum 0 <= palNum < 3. One of BG_PALETTE, SP1_PALETTE and SP2_PALETTE. * @param colorNum 0 <= colorNum < 4 diff --git a/libgambatte/src/cinterface.cpp b/libgambatte/src/cinterface.cpp index 2bbabc894f..fc4d793a75 100644 --- a/libgambatte/src/cinterface.cpp +++ b/libgambatte/src/cinterface.cpp @@ -29,9 +29,9 @@ GBEXPORT void gambatte_destroy(GB *g) delete g; } -GBEXPORT int gambatte_load(GB *g, const char *romfiledata, unsigned romfilelength, long long now, unsigned flags) +GBEXPORT int gambatte_load(GB *g, const char *romfiledata, unsigned romfilelength, long long now, unsigned flags, unsigned div) { - int ret = g->load(romfiledata, romfilelength, now, flags); + int ret = g->load(romfiledata, romfilelength, now, flags, div); return ret; } @@ -65,9 +65,9 @@ GBEXPORT void gambatte_setlayers(GB *g, unsigned mask) g->setLayers(mask); } -GBEXPORT void gambatte_reset(GB *g, long long now) +GBEXPORT void gambatte_reset(GB *g, long long now, unsigned div) { - g->reset(now); + g->reset(now, div); } GBEXPORT void gambatte_setdmgpalettecolor(GB *g, unsigned palnum, unsigned colornum, unsigned rgb32) diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp index fce1dbae63..167e1093e1 100644 --- a/libgambatte/src/gambatte.cpp +++ b/libgambatte/src/gambatte.cpp @@ -81,7 +81,7 @@ void GB::blitTo(gambatte::uint_least32_t *videoBuf, int pitch) } } -void GB::reset(const std::uint32_t now) { +void GB::reset(const std::uint32_t now, const unsigned div) { if (p_->cpu.loaded()) { int length = p_->cpu.saveSavedataLength(); @@ -94,7 +94,7 @@ void GB::reset(const std::uint32_t now) { SaveState state; p_->cpu.setStatePtrs(state); - setInitState(state, !(p_->loadflags & FORCE_DMG), p_->loadflags & GBA_CGB, now); + setInitState(state, !(p_->loadflags & FORCE_DMG), p_->loadflags & GBA_CGB, now, div); p_->cpu.loadState(state); if (length > 0) { @@ -140,7 +140,7 @@ void GB::setLinkCallback(void(*callback)()) { p_->cpu.setLinkCallback(callback); } -int GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_t now, const unsigned flags) { +int GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_t now, const unsigned flags, const unsigned div) { //if (p_->cpu.loaded()) // p_->cpu.saveSavedata(); @@ -150,7 +150,7 @@ int GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_ SaveState state; p_->cpu.setStatePtrs(state); p_->loadflags = flags; - setInitState(state, !(flags & FORCE_DMG), flags & GBA_CGB, now); + setInitState(state, !(flags & FORCE_DMG), flags & GBA_CGB, now, div); p_->cpu.loadState(state); //p_->cpu.loadSavedata(); } diff --git a/libgambatte/src/initstate.cpp b/libgambatte/src/initstate.cpp index 66b86e4e8e..f8c488efcc 100644 --- a/libgambatte/src/initstate.cpp +++ b/libgambatte/src/initstate.cpp @@ -1146,7 +1146,7 @@ static void setInitialDmgIoamhram(unsigned char *const ioamhram) { } // anon namespace -void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode, const std::uint32_t now) { +void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode, const std::uint32_t now, const unsigned div) { static const unsigned char cgbObjpDump[0x40] = { 0x00, 0x00, 0xF2, 0xAB, 0x61, 0xC2, 0xD9, 0xBA, @@ -1198,7 +1198,7 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM state.mem.ioamhram.ptr[0x140] = 0; state.mem.ioamhram.ptr[0x144] = 0x00; - state.mem.divLastUpdate = 0; + state.mem.divLastUpdate = 0 - div; state.mem.timaLastUpdate = 0; state.mem.tmatime = DISABLED_TIME; state.mem.nextSerialtime = DISABLED_TIME; diff --git a/libgambatte/src/initstate.h b/libgambatte/src/initstate.h index 8d8ed5aaf6..dd20a3d07a 100644 --- a/libgambatte/src/initstate.h +++ b/libgambatte/src/initstate.h @@ -22,7 +22,7 @@ #include namespace gambatte { -void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode, std::uint32_t now); +void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode, std::uint32_t now, unsigned div); } #endif diff --git a/libgambatte/src/savestate.h b/libgambatte/src/savestate.h index de7dfbd112..014efbb4c8 100644 --- a/libgambatte/src/savestate.h +++ b/libgambatte/src/savestate.h @@ -38,7 +38,7 @@ struct SaveState { void set(T *ptr, const unsigned long sz) { this->ptr = ptr; this->sz = sz; } friend class SaverList; - friend void setInitState(SaveState &, bool, bool, std::uint32_t); + friend void setInitState(SaveState &, bool, bool, std::uint32_t, unsigned); }; struct CPU { diff --git a/output/dll/libgambatte.dll b/output/dll/libgambatte.dll index 696c1b053f..20e9164416 100644 Binary files a/output/dll/libgambatte.dll and b/output/dll/libgambatte.dll differ