diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesApi.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesApi.cs index 96d2c606e5..4b4b704cd6 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesApi.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesApi.cs @@ -1106,8 +1106,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES BSX_PRAM = 3, SUFAMI_TURBO_A_RAM = 4, SUFAMI_TURBO_B_RAM = 5, - GAME_BOY_RAM = 6, - GAME_BOY_RTC = 7, + SGB_CARTRAM = 6, + SGB_RTC = 7, + SGB_WRAM = 8, + SGB_HRAM = 9, WRAM = 100, APURAM = 101, diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs index 4d96d132a5..966b2b0116 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -258,7 +258,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES api.snes_power(); - SetupMemoryDomains(romData); + SetupMemoryDomains(romData,sgbRomData); this.DeterministicEmulation = DeterministicEmulation; if (DeterministicEmulation) // save frame-0 savestate now @@ -863,28 +863,49 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES MemoryDomains.Add(md); return md; - - } - void SetupMemoryDomains(byte[] romData) + void SetupMemoryDomains(byte[] romData, byte[] sgbRomData) { MemoryDomains = new List(); // remember, MainMemory must always be the same as MemoryDomains[0], else GIANT DRAGONS - MainMemory = MakeMemoryDomain("WRAM", LibsnesApi.SNES_MEMORY.WRAM, Endian.Little); + // - this is stupid. - if (romData != null) + //lets just do this entirely differently for SGB + if (IsSGB) { + //NOTE: CGB has 32K of wram, and DMG has 8KB of wram. Not sure how to control this right now.. bsnes might not have any ready way of doign that? I couldnt spot it. + //You wouldnt expect a DMG game to access excess wram, but what if it tried to? maybe an oversight in bsnes? + MakeMemoryDomain("SGB WRAM", LibsnesApi.SNES_MEMORY.SGB_WRAM, Endian.Little); + + + var romDomain = new MemoryDomain("SGB CARTROM", romData.Length, Endian.Little, + (addr) => romData[addr], + (addr, value) => romData[addr] = value); + MemoryDomains.Add(romDomain); + + + //the last 1 byte of this is special.. its an interrupt enable register, instead of ram. weird. maybe its actually ram and just getting specially used? + MakeMemoryDomain("SGB HRAM", LibsnesApi.SNES_MEMORY.SGB_HRAM, Endian.Little); + + MakeMemoryDomain("SGB CARTRAM", LibsnesApi.SNES_MEMORY.SGB_CARTRAM, Endian.Little); + + MainMemory = MakeMemoryDomain("WRAM", LibsnesApi.SNES_MEMORY.WRAM, Endian.Little); + + var sgbromDomain = new MemoryDomain("SGB.SFC ROM", sgbRomData.Length, Endian.Little, + (addr) => sgbRomData[addr], + (addr, value) => sgbRomData[addr] = value); + MemoryDomains.Add(sgbromDomain); + } + else + { + MainMemory = MakeMemoryDomain("WRAM", LibsnesApi.SNES_MEMORY.WRAM, Endian.Little); + var romDomain = new MemoryDomain("CARTROM", romData.Length, Endian.Little, (addr) => romData[addr], (addr, value) => romData[addr] = value); MemoryDomains.Add(romDomain); - } - - //someone needs to comprehensively address these in SGB mode, and go hook them up in the gameboy core - if (!IsSGB) - { MakeMemoryDomain("CARTRAM", LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM, Endian.Little); MakeMemoryDomain("VRAM", LibsnesApi.SNES_MEMORY.VRAM, Endian.Little); MakeMemoryDomain("OAM", LibsnesApi.SNES_MEMORY.OAM, Endian.Little); @@ -895,8 +916,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES MemoryDomains.Add(new MemoryDomain("BUS", 0x1000000, Endian.Little, (addr) => api.peek(LibsnesApi.SNES_MEMORY.SYSBUS, (uint)addr), (addr, val) => api.poke(LibsnesApi.SNES_MEMORY.SYSBUS, (uint)addr, val))); + } } + public IList MemoryDomains { get; private set; } public MemoryDomain MainMemory { get; private set; } diff --git a/BizHawk.MultiClient/output/dll/libsneshawk-32-compatibility.exe b/BizHawk.MultiClient/output/dll/libsneshawk-32-compatibility.exe index f3c4d6633d..ad37f7b1a5 100644 Binary files a/BizHawk.MultiClient/output/dll/libsneshawk-32-compatibility.exe and b/BizHawk.MultiClient/output/dll/libsneshawk-32-compatibility.exe differ diff --git a/BizHawk.MultiClient/output/dll/libsneshawk-32-performance.exe b/BizHawk.MultiClient/output/dll/libsneshawk-32-performance.exe index 8204147cb9..525dd8bc10 100644 Binary files a/BizHawk.MultiClient/output/dll/libsneshawk-32-performance.exe and b/BizHawk.MultiClient/output/dll/libsneshawk-32-performance.exe differ diff --git a/BizHawk.MultiClient/tools/HexEditor.cs b/BizHawk.MultiClient/tools/HexEditor.cs index 5b3b4e4901..076a2b4a60 100644 --- a/BizHawk.MultiClient/tools/HexEditor.cs +++ b/BizHawk.MultiClient/tools/HexEditor.cs @@ -441,14 +441,18 @@ namespace BizHawk.MultiClient private void SetMemoryDomain(int pos) { + // THIS IS HORRIBLE. if (pos == 999) { + // THIS IS HORRIBLE. ROM = GetRomBytes() ?? new byte[] { 0xFF }; + // THIS IS HORRIBLE. ROMDomain = new MemoryDomain("ROM File", ROM.Length, Endian.Little, i => ROM[i], (i, value) => ROM[i] = value); - + + // THIS IS HORRIBLE. Domain = ROMDomain; } else if (pos < Global.Emulator.MemoryDomains.Count) //Sanity check @@ -498,6 +502,7 @@ namespace BizHawk.MultiClient } //Add ROM File memory domain + // THIS IS HORRIBLE. var rom_item = new ToolStripMenuItem {Text = "ROM File"}; rom_item.Click += (o, ev) => SetMemoryDomain(999); //999 will denote ROM file memoryDomainsToolStripMenuItem.DropDownItems.Add(rom_item); diff --git a/libsnes/bsnes/gameboy/cartridge/cartridge.cpp b/libsnes/bsnes/gameboy/cartridge/cartridge.cpp index 34ef7b11a0..a29506df85 100644 --- a/libsnes/bsnes/gameboy/cartridge/cartridge.cpp +++ b/libsnes/bsnes/gameboy/cartridge/cartridge.cpp @@ -60,7 +60,7 @@ void Cartridge::load(System::Revision revision, const string &markup, const uint case Mapper::HuC3: mapper = &huc3; break; } - ramdata = (uint8_t*)interface->allocSharedMemory("GAME_BOY_RAM",ramsize = info.ramsize); + ramdata = (uint8_t*)interface->allocSharedMemory("SGB_CARTRAM",ramsize = info.ramsize); system.load(revision); loaded = true; diff --git a/libsnes/bsnes/gameboy/cpu/cpu.cpp b/libsnes/bsnes/gameboy/cpu/cpu.cpp index 306e3aa10c..f157273baa 100644 --- a/libsnes/bsnes/gameboy/cpu/cpu.cpp +++ b/libsnes/bsnes/gameboy/cpu/cpu.cpp @@ -1,5 +1,7 @@ #include +#include + #define CPU_CPP namespace GameBoy { @@ -129,8 +131,8 @@ void CPU::power() { bus.mmio[0xff77] = this; //??? } - for(auto &n : wram) n = 0x00; - for(auto &n : hram) n = 0x00; + for(unsigned n = 0; n < 32768; n++) wram[n] = 0x00; + for(unsigned n = 0; n < 8192; n++) hram[n] = 0x00; r[PC] = 0x0000; r[SP] = 0x0000; @@ -195,8 +197,24 @@ void CPU::power() { status.interrupt_enable_vblank = 0; } -CPU::CPU() : trace(false) { +CPU::CPU() + : trace(false) + , wram(nullptr) + , hram(nullptr) +{ initialize_opcode_table(); } +CPU::~CPU() +{ + SNES::interface()->freeSharedMemory(wram); + SNES::interface()->freeSharedMemory(hram); } + +void CPU::initialize() +{ + wram = (uint8*)SNES::interface()->allocSharedMemory("SGB_WRAM", 32768); + hram = (uint8*)SNES::interface()->allocSharedMemory("SGB_HRAM", 8192); +} + +} //namespace GameBoy diff --git a/libsnes/bsnes/gameboy/cpu/cpu.hpp b/libsnes/bsnes/gameboy/cpu/cpu.hpp index 65e73acb2a..983a3f5b43 100644 --- a/libsnes/bsnes/gameboy/cpu/cpu.hpp +++ b/libsnes/bsnes/gameboy/cpu/cpu.hpp @@ -88,8 +88,8 @@ struct CPU : Processor, MMIO { bool interrupt_enable_vblank; } status; - uint8 wram[32768]; //GB=8192, GBC=32768 - uint8 hram[128]; + uint8* wram; //[32768]; //GB=8192, GBC=32768 + uint8* hram; //[128]; static void Main(); void main(); @@ -99,7 +99,9 @@ struct CPU : Processor, MMIO { void power(); void serialize(serializer&); + void initialize(); CPU(); + ~CPU(); }; extern CPU cpu; diff --git a/libsnes/bsnes/gameboy/cpu/serialization.cpp b/libsnes/bsnes/gameboy/cpu/serialization.cpp index 5a2b8d5ccd..0b4c75ba20 100644 --- a/libsnes/bsnes/gameboy/cpu/serialization.cpp +++ b/libsnes/bsnes/gameboy/cpu/serialization.cpp @@ -3,8 +3,8 @@ void CPU::serialize(serializer &s) { Processor::serialize(s); - s.array(wram); - s.array(hram); + s.array(wram,32768); + s.array(hram,8192); s.integer(r.a.data); s.integer(r.f.z); diff --git a/libsnes/bsnes/target-libsnes/libsnes.cpp b/libsnes/bsnes/target-libsnes/libsnes.cpp index beb51916a2..6e2e7d97e8 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.cpp +++ b/libsnes/bsnes/target-libsnes/libsnes.cpp @@ -252,6 +252,10 @@ void snes_init(void) { reconstruct(&SNES::ppu); SNES::ppu.initialize(); SNES::system.init(); + + //zero 26-aug-2013 - yup. still more + reconstruct(&GameBoy::cpu); GameBoy::cpu.initialize(); + SNES::input.connect(SNES::Controller::Port1, SNES::Input::Device::Joypad); SNES::input.connect(SNES::Controller::Port2, SNES::Input::Device::Joypad); } @@ -559,12 +563,18 @@ uint8_t* snes_get_memory_data(unsigned id) { case SNES_MEMORY_SUFAMI_TURBO_B_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; return SNES::sufamiturbo.slotB.ram.data(); - case SNES_MEMORY_GAME_BOY_RAM: + case SNES_MEMORY_GAME_BOY_CARTRAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; return GameBoy::cartridge.ramdata; //case SNES_MEMORY_GAME_BOY_RTC: // if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; // return GameBoy::cartridge.rtcdata; + case SNES_MEMORY_GAME_BOY_WRAM: + if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; + return GameBoy::cpu.wram; + case SNES_MEMORY_GAME_BOY_HRAM: + if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; + return GameBoy::cpu.hram; case SNES_MEMORY_WRAM: return SNES::cpu.wram; @@ -603,13 +613,20 @@ const char* snes_get_memory_id_name(unsigned id) { case SNES_MEMORY_SUFAMI_TURBO_B_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; return "SUFAMI_SLOTBRAM"; - case SNES_MEMORY_GAME_BOY_RAM: + case SNES_MEMORY_GAME_BOY_CARTRAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; //return GameBoy::cartridge.ramdata; return "SGB_CARTRAM"; //case SNES_MEMORY_GAME_BOY_RTC: // if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; // return GameBoy::cartridge.rtcdata; + case SNES_MEMORY_GAME_BOY_WRAM: + if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; + //see notes in SetupMemoryDomains in bizhawk + return "SGB_WRAM"; + case SNES_MEMORY_GAME_BOY_HRAM: + if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; + return "SGB_HRAM"; case SNES_MEMORY_WRAM: //return SNES::cpu.wram; @@ -655,7 +672,7 @@ unsigned snes_get_memory_size(unsigned id) { if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; size = SNES::sufamiturbo.slotB.ram.size(); break; - case SNES_MEMORY_GAME_BOY_RAM: + case SNES_MEMORY_GAME_BOY_CARTRAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; size = GameBoy::cartridge.ramsize; break; @@ -663,6 +680,15 @@ unsigned snes_get_memory_size(unsigned id) { // if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; // size = GameBoy::cartridge.rtcsize; // break; + case SNES_MEMORY_GAME_BOY_WRAM: + if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; + //see notes in SetupMemoryDomains in bizhawk + size = 32768; + break; + case SNES_MEMORY_GAME_BOY_HRAM: + if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; + size = 128; + break; case SNES_MEMORY_WRAM: size = 128 * 1024; diff --git a/libsnes/bsnes/target-libsnes/libsnes.hpp b/libsnes/bsnes/target-libsnes/libsnes.hpp index d13ac870ab..3709b7ac69 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.hpp +++ b/libsnes/bsnes/target-libsnes/libsnes.hpp @@ -67,8 +67,10 @@ extern "C" { #define SNES_MEMORY_BSX_PRAM 3 #define SNES_MEMORY_SUFAMI_TURBO_A_RAM 4 #define SNES_MEMORY_SUFAMI_TURBO_B_RAM 5 -#define SNES_MEMORY_GAME_BOY_RAM 6 +#define SNES_MEMORY_GAME_BOY_CARTRAM 6 #define SNES_MEMORY_GAME_BOY_RTC 7 +#define SNES_MEMORY_GAME_BOY_WRAM 8 +#define SNES_MEMORY_GAME_BOY_HRAM 9 #define SNES_MEMORY_WRAM 100 #define SNES_MEMORY_APURAM 101