diff --git a/Makefile b/Makefile index 98bd46bf..394e75db 100755 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ include nall/Makefile snes := snes -profile := performance +profile := accuracy ui := qt # compiler diff --git a/cc.bat b/cc.bat index 8e0e8454..165ca913 100755 --- a/cc.bat +++ b/cc.bat @@ -1 +1,2 @@ @mingw32-make -j 2 +@pause diff --git a/launcher/launcher.cpp b/launcher/launcher.cpp index 3a2acfd7..9f422a34 100755 --- a/launcher/launcher.cpp +++ b/launcher/launcher.cpp @@ -7,54 +7,42 @@ #include using namespace nall; -#if defined(PLATFORM_X) || defined(PLATFORM_OSX) +#if !defined(PLATFORM_WIN) char* userpath(char *path) { *path = 0; struct passwd *userinfo = getpwuid(getuid()); if(userinfo) strcpy(path, userinfo->pw_dir); return path; } - - char *getcwd(char *path) { - return getcwd(path, PATH_MAX); - } -#elif defined(PLATFORM_WIN) +#else #include #include #include #include char* realpath(const char *filename, char *resolvedname) { - wchar_t fn[_MAX_PATH] = L""; - _wfullpath(fn, nall::utf16_t(filename), _MAX_PATH); + wchar_t fn[PATH_MAX] = L""; + _wfullpath(fn, nall::utf16_t(filename), PATH_MAX); strcpy(resolvedname, nall::utf8_t(fn)); return resolvedname; } char* userpath(char *path) { - wchar_t fp[_MAX_PATH] = L""; + wchar_t fp[PATH_MAX] = L""; SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, fp); strcpy(path, nall::utf8_t(fp)); return path; } - - char* getcwd(char *path) { - wchar_t fp[_MAX_PATH] = L""; - _wgetcwd(fp, _MAX_PATH); - strcpy(path, nall::utf8_t(fp)); - return path; - } - - intptr_t execv(const char *cmdname, const char *const *argv) { - int argc = __argc; - wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &argc); - return _wexecv(nall::utf16_t(cmdname), wargv); - } #endif int main(int argc, char **argv) { char path[PATH_MAX], *unused; + #if !defined(PLATFORM_WIN) unused = realpath(argv[0], path); + #else + wchar_t **argw = CommandLineToArgvW(GetCommandLineW(), &argc); + unused = realpath(nall::utf8_t(argw[0]), path); + #endif string realPath = dir(path); string basePath = string(dir(path), "bsnes.cfg"); unused = userpath(path); @@ -71,19 +59,24 @@ int main(int argc, char **argv) { #if defined(PLATFORM_WIN) binaryName << ".dll"; #endif + string fileName = string(realPath, binaryName); - string fileName = string("/usr/local/bin/", binaryName); - if(!file::exists(fileName)) fileName = string("/usr/bin/", binaryName); - if(!file::exists(fileName)) fileName = string(realPath, binaryName); - if(!file::exists(fileName)) { - #if defined(PLATFORM_WIN) - MessageBox(0, string("Error: unable to locate binary file :", binaryName), "bsnes", MB_OK); - #else - print("[bsnes] Error: unable to locate binary file: ", binaryName, "\n"); - #endif - return 0; + #if !defined(PLATFORM_WIN) + char **args = new char*[argc + 1]; + args[0] = strdup(binaryName); + for(unsigned i = 1; i < argc; i++) args[i] = strdup(argv[i]); + args[argc] = 0; + execvp(args[0], args); + execv(fileName, args); + print("[bsnes] Error: unable to locate binary file: ", binaryName, "\n"); + #else + STARTUPINFOW si; + PROCESS_INFORMATION pi; + memset(&si, 0, sizeof(STARTUPINFOW)); + if(!CreateProcessW(nall::utf16_t(fileName), GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + MessageBox(0, string("Error: unable to locate binary file: ", binaryName), "bsnes", MB_OK); } + #endif - execv(fileName, argv); return 0; } diff --git a/nall/function.hpp b/nall/function.hpp index 036e4c9e..76995dd7 100755 --- a/nall/function.hpp +++ b/nall/function.hpp @@ -1,6 +1,7 @@ #ifndef NALL_FUNCTION_HPP #define NALL_FUNCTION_HPP +#include #include #include diff --git a/snes/chip/sdd1/sdd1.cpp b/snes/chip/sdd1/sdd1.cpp index 4a2eabfe..83119f14 100755 --- a/snes/chip/sdd1/sdd1.cpp +++ b/snes/chip/sdd1/sdd1.cpp @@ -14,7 +14,7 @@ void SDD1::enable() { //hook S-CPU DMA MMIO registers to gather information for struct dma[]; //buffer address and transfer size information for use in SDD1::read() for(unsigned i = 0x4300; i <= 0x437f; i++) { - cpu_mmio[i & 0x7f] = memory::mmio.mmio[i - 0x2000]; + cpu_mmio[i & 0x7f] = memory::mmio.handle(i); memory::mmio.map(i, *this); } } diff --git a/snes/chip/serial/serial.cpp b/snes/chip/serial/serial.cpp index b9404adb..d8adfe44 100755 --- a/snes/chip/serial/serial.cpp +++ b/snes/chip/serial/serial.cpp @@ -73,10 +73,10 @@ void Serial::init() { } void Serial::enable() { - r4016 = memory::mmio.mmio[0x4016 - 0x2000]; - r4017 = memory::mmio.mmio[0x4017 - 0x2000]; - memory::mmio.mmio[0x4016 - 0x2000] = this; - memory::mmio.mmio[0x4017 - 0x2000] = this; + r4016 = memory::mmio.handle(0x4016); + r4017 = memory::mmio.handle(0x4017); + memory::mmio.map(0x4016, *this); + memory::mmio.map(0x4017, *this); if(opened()) close(); string name = notdir(cartridge.basename()); diff --git a/snes/chip/supergameboy/supergameboy.cpp b/snes/chip/supergameboy/supergameboy.cpp index eee2c8c9..562cd9be 100755 --- a/snes/chip/supergameboy/supergameboy.cpp +++ b/snes/chip/supergameboy/supergameboy.cpp @@ -103,10 +103,9 @@ void SuperGameBoy::init() { } void SuperGameBoy::enable() { - mmio[0] = memory::mmio.mmio[0x2181 - 0x2000]; - mmio[1] = memory::mmio.mmio[0x2182 - 0x2000]; - mmio[2] = memory::mmio.mmio[0x420b - 0x2000]; - + mmio[0] = memory::mmio.handle(0x2181); + mmio[1] = memory::mmio.handle(0x2182); + mmio[2] = memory::mmio.handle(0x420b); memory::mmio.map(0x2181, *this); memory::mmio.map(0x2182, *this); memory::mmio.map(0x420b, *this); diff --git a/snes/fast/cpu/mmio.cpp b/snes/fast/cpu/mmio.cpp index cc7ce5fa..1c23a751 100755 --- a/snes/fast/cpu/mmio.cpp +++ b/snes/fast/cpu/mmio.cpp @@ -1,303 +1,303 @@ #ifdef CPU_CPP uint8 CPU::mmio_read(unsigned addr) { - addr &= 0xffff; - if((addr & 0xffc0) == 0x2140) { synchronize_smp(); return smp.port_read(addr & 3); } - if(addr == 0x2180) { - uint8 result = bus.read(0x7e0000 | status.wram_addr); - status.wram_addr = (status.wram_addr + 1) & 0x01ffff; - return result; + switch(addr & 0xffff) { + case 0x2180: { + uint8 result = bus.read(0x7e0000 | status.wram_addr); + status.wram_addr = (status.wram_addr + 1) & 0x01ffff; + return result; + } + + case 0x4016: { + uint8 result = regs.mdr & 0xfc; + result |= input.port_read(0) & 3; + return result; + } + + case 0x4017: { + uint8 result = (regs.mdr & 0xe0) | 0x1c; + result |= input.port_read(1) & 3; + return result; + } + + case 0x4210: { + uint8 result = (regs.mdr & 0x70); + result |= status.nmi_line << 7; + result |= 0x02; //CPU revision + status.nmi_line = false; + return result; + } + + case 0x4211: { + uint8 result = (regs.mdr & 0x7f); + result |= status.irq_line << 7; + status.irq_line = false; + return result; + } + + case 0x4212: { + uint8 result = (regs.mdr & 0x3e); + unsigned vbstart = ppu.overscan() == false ? 225 : 240; + + if(vcounter() >= vbstart && vcounter() <= vbstart + 2) result |= 0x01; + if(hcounter() <= 2 || hcounter() >= 1096) result |= 0x40; + if(vcounter() >= vbstart) result |= 0x80; + + return result; + } + + case 0x4213: return status.pio; + + case 0x4214: return status.rddiv >> 0; + case 0x4215: return status.rddiv >> 8; + case 0x4216: return status.rdmpy >> 0; + case 0x4217: return status.rdmpy >> 8; + + case 0x4218: return status.joy1l; + case 0x4219: return status.joy1h; + case 0x421a: return status.joy2l; + case 0x421b: return status.joy2h; + case 0x421c: return status.joy3l; + case 0x421d: return status.joy3h; + case 0x421e: return status.joy4l; + case 0x421f: return status.joy4h; } - if(addr == 0x4016) { - uint8 result = regs.mdr & 0xfc; - result |= input.port_read(0) & 3; - return result; - } - - if(addr == 0x4017) { - uint8 result = (regs.mdr & 0xe0) | 0x1c; - result |= input.port_read(1) & 3; - return result; - } - - if(addr == 0x4210) { - uint8 result = (regs.mdr & 0x70); - result |= status.nmi_line << 7; - result |= 0x02; //CPU revision - status.nmi_line = false; - return result; - } - - if(addr == 0x4211) { - uint8 result = (regs.mdr & 0x7f); - result |= status.irq_line << 7; - status.irq_line = false; - return result; - } - - if(addr == 0x4212) { - uint8 result = (regs.mdr & 0x3e); - unsigned vbstart = ppu.overscan() == false ? 225 : 240; - - if(vcounter() >= vbstart && vcounter() <= vbstart + 2) result |= 0x01; - if(hcounter() <= 2 || hcounter() >= 1096) result |= 0x40; - if(vcounter() >= vbstart) result |= 0x80; - - return result; - } - - if(addr == 0x4213) return status.pio; - - if(addr == 0x4214) return status.rddiv >> 0; - if(addr == 0x4215) return status.rddiv >> 8; - if(addr == 0x4216) return status.rdmpy >> 0; - if(addr == 0x4217) return status.rdmpy >> 8; - - if(addr == 0x4218) return status.joy1l; - if(addr == 0x4219) return status.joy1h; - if(addr == 0x421a) return status.joy2l; - if(addr == 0x421b) return status.joy2h; - if(addr == 0x421c) return status.joy3l; - if(addr == 0x421d) return status.joy3h; - if(addr == 0x421e) return status.joy4l; - if(addr == 0x421f) return status.joy4h; - if((addr & 0xff80) == 0x4300) { unsigned i = (addr >> 4) & 7; - addr &= 0xff8f; + switch(addr & 0xff8f) { + case 0x4300: { + return (channel[i].direction << 7) + | (channel[i].indirect << 6) + | (channel[i].unused << 5) + | (channel[i].reverse_transfer << 4) + | (channel[i].fixed_transfer << 3) + | (channel[i].transfer_mode << 0); + } - if(addr == 0x4300) { - return (channel[i].direction << 7) - | (channel[i].indirect << 6) - | (channel[i].unused << 5) - | (channel[i].reverse_transfer << 4) - | (channel[i].fixed_transfer << 3) - | (channel[i].transfer_mode << 0); + case 0x4301: return channel[i].dest_addr; + case 0x4302: return channel[i].source_addr >> 0; + case 0x4303: return channel[i].source_addr >> 8; + case 0x4304: return channel[i].source_bank; + case 0x4305: return channel[i].transfer_size >> 0; + case 0x4306: return channel[i].transfer_size >> 8; + case 0x4307: return channel[i].indirect_bank; + case 0x4308: return channel[i].hdma_addr >> 0; + case 0x4309: return channel[i].hdma_addr >> 8; + case 0x430a: return channel[i].line_counter; + case 0x430b: case 0x430f: return channel[i].unknown; } - - if(addr == 0x4301) return channel[i].dest_addr; - if(addr == 0x4302) return channel[i].source_addr >> 0; - if(addr == 0x4303) return channel[i].source_addr >> 8; - if(addr == 0x4304) return channel[i].source_bank; - if(addr == 0x4305) return channel[i].transfer_size >> 0; - if(addr == 0x4306) return channel[i].transfer_size >> 8; - if(addr == 0x4307) return channel[i].indirect_bank; - if(addr == 0x4308) return channel[i].hdma_addr >> 0; - if(addr == 0x4309) return channel[i].hdma_addr >> 8; - if(addr == 0x430a) return channel[i].line_counter; - if(addr == 0x430b || addr == 0x430f) return channel[i].unknown; } return regs.mdr; } void CPU::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - if((addr & 0xffc0) == 0x2140) { synchronize_smp(); port_write(addr & 3, data); return; } - if(addr == 0x2180) { - bus.write(0x7e0000 | status.wram_addr, data); - status.wram_addr = (status.wram_addr + 1) & 0x01ffff; - return; - } - - if(addr == 0x2181) { - status.wram_addr = (status.wram_addr & 0x01ff00) | (data << 0); - return; - } - - if(addr == 0x2182) { - status.wram_addr = (status.wram_addr & 0x0100ff) | (data << 8); - return; - } - - if(addr == 0x2183) { - status.wram_addr = (status.wram_addr & 0x00ffff) | ((data & 1) << 16); - return; - } - - if(addr == 0x4016) { - bool old_latch = status.joypad_strobe_latch; - bool new_latch = data & 1; - status.joypad_strobe_latch = new_latch; - if(old_latch != new_latch) input.poll(); - return; - } - - if(addr == 0x4200) { - bool nmi_enabled = status.nmi_enabled; - bool virq_enabled = status.virq_enabled; - bool hirq_enabled = status.hirq_enabled; - - status.nmi_enabled = data & 0x80; - status.virq_enabled = data & 0x20; - status.hirq_enabled = data & 0x10; - status.auto_joypad_poll_enabled = data & 0x01; - - if(!nmi_enabled && status.nmi_enabled && status.nmi_line) { - status.nmi_transition = true; + switch(addr & 0xffff) { + case 0x2180: { + bus.write(0x7e0000 | status.wram_addr, data); + status.wram_addr = (status.wram_addr + 1) & 0x01ffff; + return; } - if(status.virq_enabled && !status.hirq_enabled && status.irq_line) { - status.irq_transition = true; + case 0x2181: { + status.wram_addr = (status.wram_addr & 0x01ff00) | (data << 0); + return; } - if(!status.virq_enabled && !status.hirq_enabled) { - status.irq_line = false; - status.irq_transition = false; + case 0x2182: { + status.wram_addr = (status.wram_addr & 0x0100ff) | (data << 8); + return; } - status.irq_lock = true; - return; - } + case 0x2183: { + status.wram_addr = (status.wram_addr & 0x00ffff) | ((data & 1) << 16); + return; + } - if(addr == 0x4201) { - if((status.pio & 0x80) && !(data & 0x80)) ppu.latch_counters(); - status.pio = data; - } + case 0x4016: { + bool old_latch = status.joypad_strobe_latch; + bool new_latch = data & 1; + status.joypad_strobe_latch = new_latch; + if(old_latch != new_latch) input.poll(); + return; + } - if(addr == 0x4202) { - status.wrmpya = data; - return; - } + case 0x4200: { + bool nmi_enabled = status.nmi_enabled; + bool virq_enabled = status.virq_enabled; + bool hirq_enabled = status.hirq_enabled; - if(addr == 0x4203) { - status.wrmpyb = data; - status.rdmpy = status.wrmpya * status.wrmpyb; - return; - } + status.nmi_enabled = data & 0x80; + status.virq_enabled = data & 0x20; + status.hirq_enabled = data & 0x10; + status.auto_joypad_poll_enabled = data & 0x01; - if(addr == 0x4204) { - status.wrdiva = (status.wrdiva & 0xff00) | (data << 0); - return; - } + if(!nmi_enabled && status.nmi_enabled && status.nmi_line) { + status.nmi_transition = true; + } - if(addr == 0x4205) { - status.wrdiva = (data << 8) | (status.wrdiva & 0x00ff); - return; - } + if(status.virq_enabled && !status.hirq_enabled && status.irq_line) { + status.irq_transition = true; + } - if(addr == 0x4206) { - status.wrdivb = data; - status.rddiv = status.wrdivb ? status.wrdiva / status.wrdivb : 0xffff; - status.rdmpy = status.wrdivb ? status.wrdiva % status.wrdivb : status.wrdiva; - return; - } + if(!status.virq_enabled && !status.hirq_enabled) { + status.irq_line = false; + status.irq_transition = false; + } - if(addr == 0x4207) { - status.htime = (status.htime & 0x0100) | (data << 0); - return; - } + status.irq_lock = true; + return; + } - if(addr == 0x4208) { - status.htime = ((data & 1) << 8) | (status.htime & 0x00ff); - return; - } + case 0x4201: { + if((status.pio & 0x80) && !(data & 0x80)) ppu.latch_counters(); + status.pio = data; + } - if(addr == 0x4209) { - status.vtime = (status.vtime & 0x0100) | (data << 0); - return; - } + case 0x4202: { + status.wrmpya = data; + return; + } - if(addr == 0x420a) { - status.vtime = ((data & 1) << 8) | (status.vtime & 0x00ff); - return; - } + case 0x4203: { + status.wrmpyb = data; + status.rdmpy = status.wrmpya * status.wrmpyb; + return; + } - if(addr == 0x420b) { - for(unsigned i = 0; i < 8; i++) channel[i].dma_enabled = data & (1 << i); - if(data) dma_run(); - return; - } + case 0x4204: { + status.wrdiva = (status.wrdiva & 0xff00) | (data << 0); + return; + } - if(addr == 0x420c) { - for(unsigned i = 0; i < 8; i++) channel[i].hdma_enabled = data & (1 << i); - return; - } + case 0x4205: { + status.wrdiva = (data << 8) | (status.wrdiva & 0x00ff); + return; + } - if(addr == 0x420d) { - status.rom_speed = data & 1 ? 6 : 8; - return; + case 0x4206: { + status.wrdivb = data; + status.rddiv = status.wrdivb ? status.wrdiva / status.wrdivb : 0xffff; + status.rdmpy = status.wrdivb ? status.wrdiva % status.wrdivb : status.wrdiva; + return; + } + + case 0x4207: { + status.htime = (status.htime & 0x0100) | (data << 0); + return; + } + + case 0x4208: { + status.htime = ((data & 1) << 8) | (status.htime & 0x00ff); + return; + } + + case 0x4209: { + status.vtime = (status.vtime & 0x0100) | (data << 0); + return; + } + + case 0x420a: { + status.vtime = ((data & 1) << 8) | (status.vtime & 0x00ff); + return; + } + + case 0x420b: { + for(unsigned i = 0; i < 8; i++) channel[i].dma_enabled = data & (1 << i); + if(data) dma_run(); + return; + } + + case 0x420c: { + for(unsigned i = 0; i < 8; i++) channel[i].hdma_enabled = data & (1 << i); + return; + } + + case 0x420d: { + status.rom_speed = data & 1 ? 6 : 8; + return; + } } if((addr & 0xff80) == 0x4300) { unsigned i = (addr >> 4) & 7; - addr &= 0xff8f; + switch(addr & 0xff8f) { + case 0x4300: { + channel[i].direction = data & 0x80; + channel[i].indirect = data & 0x40; + channel[i].unused = data & 0x20; + channel[i].reverse_transfer = data & 0x10; + channel[i].fixed_transfer = data & 0x08; + channel[i].transfer_mode = data & 0x07; + return; + } - if(addr == 0x4300) { - channel[i].direction = data & 0x80; - channel[i].indirect = data & 0x40; - channel[i].unused = data & 0x20; - channel[i].reverse_transfer = data & 0x10; - channel[i].fixed_transfer = data & 0x08; - channel[i].transfer_mode = data & 0x07; - return; - } + case 0x4301: { + channel[i].dest_addr = data; + return; + } - if(addr == 0x4301) { - channel[i].dest_addr = data; - return; - } + case 0x4302: { + channel[i].source_addr = (channel[i].source_addr & 0xff00) | (data << 0); + return; + } - if(addr == 0x4302) { - channel[i].source_addr = (channel[i].source_addr & 0xff00) | (data << 0); - return; - } + case 0x4303: { + channel[i].source_addr = (data << 8) | (channel[i].source_addr & 0x00ff); + return; + } - if(addr == 0x4303) { - channel[i].source_addr = (data << 8) | (channel[i].source_addr & 0x00ff); - return; - } + case 0x4304: { + channel[i].source_bank = data; + return; + } - if(addr == 0x4304) { - channel[i].source_bank = data; - return; - } + case 0x4305: { + channel[i].transfer_size = (channel[i].transfer_size & 0xff00) | (data << 0); + return; + } - if(addr == 0x4305) { - channel[i].transfer_size = (channel[i].transfer_size & 0xff00) | (data << 0); - return; - } + case 0x4306: { + channel[i].transfer_size = (data << 8) | (channel[i].transfer_size & 0x00ff); + return; + } - if(addr == 0x4306) { - channel[i].transfer_size = (data << 8) | (channel[i].transfer_size & 0x00ff); - return; - } + case 0x4307: { + channel[i].indirect_bank = data; + return; + } - if(addr == 0x4307) { - channel[i].indirect_bank = data; - return; - } + case 0x4308: { + channel[i].hdma_addr = (channel[i].hdma_addr & 0xff00) | (data << 0); + return; + } - if(addr == 0x4308) { - channel[i].hdma_addr = (channel[i].hdma_addr & 0xff00) | (data << 0); - return; - } + case 0x4309: { + channel[i].hdma_addr = (data << 8) | (channel[i].hdma_addr & 0x00ff); + return; + } - if(addr == 0x4309) { - channel[i].hdma_addr = (data << 8) | (channel[i].hdma_addr & 0x00ff); - return; - } + case 0x430a: { + channel[i].line_counter = data; + return; + } - if(addr == 0x430a) { - channel[i].line_counter = data; - return; - } - - if(addr == 0x430b || addr == 0x430f) { - channel[i].unknown = data; - return; + case 0x430b: case 0x430f: { + channel[i].unknown = data; + return; + } } } } diff --git a/snes/fast/cpu/timing.cpp b/snes/fast/cpu/timing.cpp index 04ac1aa5..8210cd33 100755 --- a/snes/fast/cpu/timing.cpp +++ b/snes/fast/cpu/timing.cpp @@ -50,6 +50,8 @@ void CPU::add_clocks(unsigned clocks) { status.irq_valid = vcounter() == status.vtime; if(!irq_valid && status.irq_valid) status.irq_line = true; if(status.irq_line) status.irq_transition = true; + } else { + status.irq_valid = false; } tick(clocks); diff --git a/snes/memory/memory-inline.hpp b/snes/memory/memory-inline.hpp index d49f8d48..71127ca3 100755 --- a/snes/memory/memory-inline.hpp +++ b/snes/memory/memory-inline.hpp @@ -51,7 +51,7 @@ MappedRAM::MappedRAM() : data_(0), size_(-1U), write_protect_(false) {} //Bus -uint8 Bus::read(unsigned addr) { +uint8 Bus::read(uint24 addr) { #if defined(CHEAT_SYSTEM) if(cheat.active() && cheat.exists(addr)) { uint8 r; @@ -63,7 +63,7 @@ uint8 Bus::read(unsigned addr) { return p.access->read(p.offset + addr); } -void Bus::write(unsigned addr, uint8 data) { +void Bus::write(uint24 addr, uint8 data) { Page &p = page[addr >> 8]; return p.access->write(p.offset + addr, data); } diff --git a/snes/memory/memory.cpp b/snes/memory/memory.cpp index affd4f2e..9c4a13bb 100755 --- a/snes/memory/memory.cpp +++ b/snes/memory/memory.cpp @@ -9,14 +9,14 @@ Bus bus; namespace memory { MMIOAccess mmio; - StaticRAM wram(128 * 1024); - StaticRAM apuram(64 * 1024); - StaticRAM vram(64 * 1024); - StaticRAM oam(544); - StaticRAM cgram(512); + StaticRAM wram(128 * 1024); + StaticRAM apuram(64 * 1024); + StaticRAM vram(64 * 1024); + StaticRAM oam(544); + StaticRAM cgram(512); UnmappedMemory memory_unmapped; - UnmappedMMIO mmio_unmapped; + UnmappedMMIO mmio_unmapped; }; unsigned UnmappedMemory::size() const { return 16 * 1024 * 1024; } @@ -26,6 +26,10 @@ void UnmappedMemory::write(unsigned, uint8) {} uint8 UnmappedMMIO::mmio_read(unsigned) { return cpu.regs.mdr; } void UnmappedMMIO::mmio_write(unsigned, uint8) {} +MMIO* MMIOAccess::handle(unsigned addr) { + return mmio[(addr - 0x2000) & 0x3fff]; +} + void MMIOAccess::map(unsigned addr, MMIO &access) { //MMIO: $[00-3f]:[2000-5fff] mmio[(addr - 0x2000) & 0x3fff] = &access; diff --git a/snes/memory/memory.hpp b/snes/memory/memory.hpp index 1492d7d8..a6aaa883 100755 --- a/snes/memory/memory.hpp +++ b/snes/memory/memory.hpp @@ -58,10 +58,12 @@ private: }; struct MMIOAccess : Memory { + MMIO* handle(unsigned addr); void map(unsigned addr, MMIO &access); uint8 read(unsigned addr); void write(unsigned addr, uint8 data); +private: MMIO *mmio[0x4000]; }; @@ -74,8 +76,8 @@ struct Bus { uint16 addr_lo, uint16 addr_hi, Memory &access, unsigned offset = 0, unsigned size = 0); - alwaysinline uint8 read(unsigned addr); - alwaysinline void write(unsigned addr, uint8 data); + alwaysinline uint8 read(uint24 addr); + alwaysinline void write(uint24 addr, uint8 data); bool load_cart(); void unload_cart(); @@ -97,15 +99,15 @@ private: }; namespace memory { - extern MMIOAccess mmio; //S-CPU, S-PPU - extern StaticRAM wram; //S-CPU - extern StaticRAM apuram; //S-SMP, S-DSP - extern StaticRAM vram; //S-PPU - extern StaticRAM oam; //S-PPU - extern StaticRAM cgram; //S-PPU + extern MMIOAccess mmio; //S-CPU, S-PPU + extern StaticRAM wram; //S-CPU + extern StaticRAM apuram; //S-SMP, S-DSP + extern StaticRAM vram; //S-PPU + extern StaticRAM oam; //S-PPU + extern StaticRAM cgram; //S-PPU extern UnmappedMemory memory_unmapped; - extern UnmappedMMIO mmio_unmapped; + extern UnmappedMMIO mmio_unmapped; }; extern Bus bus; diff --git a/snes/snes.hpp b/snes/snes.hpp index fffcad96..6635521d 100755 --- a/snes/snes.hpp +++ b/snes/snes.hpp @@ -1,7 +1,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "067.23"; + static const char Version[] = "067.24"; static const unsigned SerializerVersion = 12; } }