From 423d9ba00dc608df40faa0a264f0ea96f0f19cba Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sat, 13 Aug 2011 13:51:29 +1000 Subject: [PATCH] Update to v081r01 release. byuu says: - EI takes an extra cycle to raise IME; fixes Bubble Bobble [for the Gameboy], and likely many more games [Jonas Quinn] - nall/gameboy/cartridge.hpp descrambles MMM01 images (header can be at top or bottom of image now) - screenshot timestamps use filename-yyyy-mm-dd hh.mm.ss.bmp format; so that they can save on Windows - closing the emulator will switch to windowed mode first, so that geometry is preserved --- bsnes/gameboy/cartridge/mmm01/mmm01.cpp | 2 +- bsnes/gameboy/cpu/core/core.cpp | 3 ++- bsnes/gameboy/cpu/cpu.cpp | 1 + bsnes/gameboy/cpu/cpu.hpp | 1 + bsnes/gameboy/cpu/serialization.cpp | 1 + bsnes/gameboy/cpu/timing/opcode.cpp | 10 ++++++++++ bsnes/gameboy/cpu/timing/timing.hpp | 1 + bsnes/nall/gameboy/cartridge.hpp | 18 ++++++++++++++++-- bsnes/snes/profile-performance.hpp | 4 ++++ bsnes/snes/snes.hpp | 2 +- bsnes/ui/interface.cpp | 7 ++++--- bsnes/ui/main.cpp | 1 + 12 files changed, 43 insertions(+), 8 deletions(-) diff --git a/bsnes/gameboy/cartridge/mmm01/mmm01.cpp b/bsnes/gameboy/cartridge/mmm01/mmm01.cpp index 8eb0267c..4ad9fae0 100755 --- a/bsnes/gameboy/cartridge/mmm01/mmm01.cpp +++ b/bsnes/gameboy/cartridge/mmm01/mmm01.cpp @@ -55,7 +55,7 @@ void Cartridge::MMM01::mmio_write(uint16 addr, uint8 data) { void Cartridge::MMM01::power() { rom_mode = 0; - rom_base = 0x00; + rom_base = 0; ram_enable = false; rom_select = 0x01; diff --git a/bsnes/gameboy/cpu/core/core.cpp b/bsnes/gameboy/cpu/core/core.cpp index e1e226e2..04f72c96 100755 --- a/bsnes/gameboy/cpu/core/core.cpp +++ b/bsnes/gameboy/cpu/core/core.cpp @@ -580,7 +580,8 @@ void CPU::op_di() { } void CPU::op_ei() { - status.ime = 1; + status.ei = true; +//status.ime = 1; } //jump commands diff --git a/bsnes/gameboy/cpu/cpu.cpp b/bsnes/gameboy/cpu/cpu.cpp index b78aac8b..d68a130d 100755 --- a/bsnes/gameboy/cpu/cpu.cpp +++ b/bsnes/gameboy/cpu/cpu.cpp @@ -114,6 +114,7 @@ void CPU::power() { status.clock = 0; status.halt = false; status.stop = false; + status.ei = false; status.ime = 0; status.p15 = 0; diff --git a/bsnes/gameboy/cpu/cpu.hpp b/bsnes/gameboy/cpu/cpu.hpp index cbfe193a..81d6337b 100755 --- a/bsnes/gameboy/cpu/cpu.hpp +++ b/bsnes/gameboy/cpu/cpu.hpp @@ -17,6 +17,7 @@ struct CPU : Processor, MMIO { unsigned clock; bool halt; bool stop; + bool ei; bool ime; //$ff00 JOYP diff --git a/bsnes/gameboy/cpu/serialization.cpp b/bsnes/gameboy/cpu/serialization.cpp index f122f97f..73eab0f6 100755 --- a/bsnes/gameboy/cpu/serialization.cpp +++ b/bsnes/gameboy/cpu/serialization.cpp @@ -21,6 +21,7 @@ void CPU::serialize(serializer &s) { s.integer(status.clock); s.integer(status.halt); s.integer(status.stop); + s.integer(status.ei); s.integer(status.ime); s.integer(status.p15); diff --git a/bsnes/gameboy/cpu/timing/opcode.cpp b/bsnes/gameboy/cpu/timing/opcode.cpp index b952e3d6..5774670b 100755 --- a/bsnes/gameboy/cpu/timing/opcode.cpp +++ b/bsnes/gameboy/cpu/timing/opcode.cpp @@ -1,18 +1,28 @@ #ifdef CPU_CPP void CPU::op_io() { + cycle_edge(); add_clocks(4); } uint8 CPU::op_read(uint16 addr) { + cycle_edge(); uint8 r = bus.read(addr); add_clocks(4); return r; } void CPU::op_write(uint16 addr, uint8 data) { + cycle_edge(); bus.write(addr, data); add_clocks(4); } +void CPU::cycle_edge() { + if(status.ei) { + status.ei = false; + status.ime = 1; + } +} + #endif diff --git a/bsnes/gameboy/cpu/timing/timing.hpp b/bsnes/gameboy/cpu/timing/timing.hpp index 9fead0ea..04c1c5ce 100755 --- a/bsnes/gameboy/cpu/timing/timing.hpp +++ b/bsnes/gameboy/cpu/timing/timing.hpp @@ -9,3 +9,4 @@ void timer_4096hz(); void op_io(); uint8 op_read(uint16 addr); void op_write(uint16 addr, uint8 data); +void cycle_edge(); diff --git a/bsnes/nall/gameboy/cartridge.hpp b/bsnes/nall/gameboy/cartridge.hpp index 3ab00e34..af04e0bb 100755 --- a/bsnes/nall/gameboy/cartridge.hpp +++ b/bsnes/nall/gameboy/cartridge.hpp @@ -6,7 +6,7 @@ namespace nall { class GameBoyCartridge { public: string xml; - inline GameBoyCartridge(const uint8_t *data, unsigned size); + inline GameBoyCartridge(uint8_t *data, unsigned size); //private: struct Information { @@ -21,7 +21,7 @@ public: } info; }; -GameBoyCartridge::GameBoyCartridge(const uint8_t *romdata, unsigned romsize) { +GameBoyCartridge::GameBoyCartridge(uint8_t *romdata, unsigned romsize) { xml = "\n"; if(romsize < 0x4000) return; @@ -34,6 +34,20 @@ GameBoyCartridge::GameBoyCartridge(const uint8_t *romdata, unsigned romsize) { info.romsize = 0; info.ramsize = 0; + unsigned base = romsize - 0x8000; + if(romdata[base + 0x0104] == 0xce && romdata[base + 0x0105] == 0xed + && romdata[base + 0x0106] == 0x66 && romdata[base + 0x0107] == 0x66 + && romdata[base + 0x0108] == 0xcc && romdata[base + 0x0109] == 0x0d + && romdata[base + 0x0147] >= 0x0b && romdata[base + 0x0147] <= 0x0d + ) { + //MMM01 stores header at bottom of image + //flip this around for consistency with all other mappers + uint8_t header[0x8000]; + memcpy(header, romdata + base, 0x8000); + memmove(romdata + 0x8000, romdata, romsize - 0x8000); + memcpy(romdata, header, 0x8000); + } + switch(romdata[0x0147]) { case 0x00: info.mapper = "none"; break; case 0x01: info.mapper = "MBC1"; break; diff --git a/bsnes/snes/profile-performance.hpp b/bsnes/snes/profile-performance.hpp index 791e7478..1d379fdc 100755 --- a/bsnes/snes/profile-performance.hpp +++ b/bsnes/snes/profile-performance.hpp @@ -2,6 +2,10 @@ namespace Info { static const char Profile[] = "Performance"; } +#if defined(DEBUGGER) + #error "bsnes: debugger not supported with performance profile." +#endif + #include #include #include diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index bf31da0f..593846eb 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -1,7 +1,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "081"; + static const char Version[] = "081.01"; static const unsigned SerializerVersion = 21; } } diff --git a/bsnes/ui/interface.cpp b/bsnes/ui/interface.cpp index 23a8259b..9a9c1b0c 100755 --- a/bsnes/ui/interface.cpp +++ b/bsnes/ui/interface.cpp @@ -129,10 +129,11 @@ void Interface::video_refresh(const uint16_t *data, bool hires, bool interlace, tm *info = localtime(¤tTime); string filename = { "-", decimal<4, '0'>(info->tm_year + 1900), "-", decimal<2, '0'>(info->tm_mon + 1), "-", decimal<2, '0'>(info->tm_mday), " ", - decimal<2, '0'>(info->tm_hour), ":", decimal<2, '0'>(info->tm_min), ":", decimal<2, '0'>(info->tm_sec), ".bmp" + decimal<2, '0'>(info->tm_hour), ".", decimal<2, '0'>(info->tm_min), ".", decimal<2, '0'>(info->tm_sec), ".bmp" }; - bmp::write(path(utility.slotPath(), filename), buffer, outwidth, outheight, outpitch, false); - utility.showMessage("Screenshot captured"); + if(bmp::write(path(utility.slotPath(), filename), buffer, outwidth, outheight, outpitch, false)) { + utility.showMessage("Screenshot captured"); + } } } diff --git a/bsnes/ui/main.cpp b/bsnes/ui/main.cpp index 1c2023ad..30e49cd1 100755 --- a/bsnes/ui/main.cpp +++ b/bsnes/ui/main.cpp @@ -144,6 +144,7 @@ void Application::main(int argc, char **argv) { } cartridge.unload(); + utility.setFullScreen(false); saveGeometry(); foreach(window, windows) window->setVisible(false); OS::processEvents();