lsnes/bsnes-patches/v085/0012-Support-unlimited-number-of-breakpoints.patch
Ilari Liusvaara f49b82c989 Bus fixes: Reading of CPU MMIO registers does not update MDR
Also fixes controller timings to be more realistic.
2017-10-25 14:22:19 +03:00

799 lines
30 KiB
Diff

From a5b380757b086e3a00b47fe14e2a63c74683e8da Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Thu, 28 Nov 2013 22:36:29 +0200
Subject: [PATCH 12/27] Support unlimited number of breakpoints
---
snes/alt/cpu/cpu.cpp | 22 +++++++-------
snes/alt/ppu-compatibility/ppu.cpp | 4 +--
snes/alt/ppu-parallel/ppu.cpp | 4 +--
snes/alt/ppu-performance/ppu.cpp | 4 +--
snes/cartridge/cartridge.hpp | 17 +++++++++++
snes/cartridge/markup.cpp | 11 +++++++
snes/cheat/cheat.cpp | 11 ++++---
snes/cheat/cheat.hpp | 1 +
snes/chip/bsx/satellaview/satellaview.cpp | 4 +--
snes/chip/hitachidsp/hitachidsp.cpp | 2 +-
snes/chip/hitachidsp/memory.cpp | 2 +-
snes/chip/nss/nss.cpp | 4 +--
snes/chip/sa1/memory/memory.cpp | 2 +-
snes/chip/sa1/memory/memory.hpp | 2 +-
snes/chip/sa1/sa1.cpp | 2 +-
snes/chip/sdd1/sdd1.cpp | 4 +--
snes/cpu/core/core.hpp | 2 +-
snes/cpu/core/disassembler/disassembler.cpp | 2 +-
snes/cpu/core/memory.hpp | 2 +-
snes/cpu/cpu.cpp | 26 ++++++++--------
snes/cpu/debugger/debugger.cpp | 4 +--
snes/cpu/debugger/debugger.hpp | 2 +-
snes/cpu/dma/dma.cpp | 4 +--
snes/cpu/memory/memory.cpp | 4 +--
snes/cpu/memory/memory.hpp | 2 +-
snes/cpu/mmio/mmio.cpp | 2 +-
snes/debugger/debugger.cpp | 2 +-
snes/memory/memory-inline.hpp | 21 +++++++++++--
snes/memory/memory.cpp | 47 ++++++++++++++++++++++++++---
snes/memory/memory.hpp | 13 +++++++-
snes/ppu/ppu.cpp | 4 +--
snes/smp/core/core.hpp | 2 +-
snes/snes.hpp | 1 +
33 files changed, 166 insertions(+), 70 deletions(-)
diff --git a/snes/alt/cpu/cpu.cpp b/snes/alt/cpu/cpu.cpp
index 814908d0..dcbb92d3 100755
--- a/snes/alt/cpu/cpu.cpp
+++ b/snes/alt/cpu/cpu.cpp
@@ -89,24 +89,24 @@ void CPU::enable() {
function<uint8 (unsigned)> read = { &CPU::mmio_read, (CPU*)&cpu };
function<void (unsigned, uint8)> write = { &CPU::mmio_write, (CPU*)&cpu };
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, 0, read, write);
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, 0, read, write);
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, 0, read, write);
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, 0, read, write);
read = [](unsigned addr) { return cpu.wram[addr]; };
write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; };
- bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, read, write, 0x000000, 0x002000);
- bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, read, write, 0x000000, 0x002000);
- bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, read, write);
+ bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, 3, read, write, 0x000000, 0x002000);
+ bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, 3, read, write, 0x000000, 0x002000);
+ bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, 3, read, write);
}
void CPU::power() {
diff --git a/snes/alt/ppu-compatibility/ppu.cpp b/snes/alt/ppu-compatibility/ppu.cpp
index a21e5e31..122b1430 100755
--- a/snes/alt/ppu-compatibility/ppu.cpp
+++ b/snes/alt/ppu-compatibility/ppu.cpp
@@ -126,8 +126,8 @@ void PPU::enable() {
function<uint8 (unsigned)> read = { &PPU::mmio_read, (PPU*)&ppu };
function<void (unsigned, uint8)> write = { &PPU::mmio_write, (PPU*)&ppu };
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, 0, read, write);
}
void PPU::power() {
diff --git a/snes/alt/ppu-parallel/ppu.cpp b/snes/alt/ppu-parallel/ppu.cpp
index 1c3dcb70..8dd118b2 100755
--- a/snes/alt/ppu-parallel/ppu.cpp
+++ b/snes/alt/ppu-parallel/ppu.cpp
@@ -36,8 +36,8 @@ void PPU::frame() {
}
void PPU::enable() {
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, { &PPU::mmio_read, this }, { &PPU::mmio_write, this });
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, { &PPU::mmio_read, this }, { &PPU::mmio_write, this });
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, 0, { &PPU::mmio_read, this }, { &PPU::mmio_write, this });
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, 0, { &PPU::mmio_read, this }, { &PPU::mmio_write, this });
}
void PPU::power() {
diff --git a/snes/alt/ppu-performance/ppu.cpp b/snes/alt/ppu-performance/ppu.cpp
index 7c231bc0..4b2b2948 100755
--- a/snes/alt/ppu-performance/ppu.cpp
+++ b/snes/alt/ppu-performance/ppu.cpp
@@ -90,8 +90,8 @@ void PPU::enable() {
function<uint8 (unsigned)> read = { &PPU::mmio_read, (PPU*)&ppu };
function<void (unsigned, uint8)> write = { &PPU::mmio_write, (PPU*)&ppu };
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, 0, read, write);
}
void PPU::power() {
diff --git a/snes/cartridge/cartridge.hpp b/snes/cartridge/cartridge.hpp
index 37555bc0..82e73c4c 100755
--- a/snes/cartridge/cartridge.hpp
+++ b/snes/cartridge/cartridge.hpp
@@ -12,6 +12,22 @@ struct Cartridge : property<Cartridge> {
PAL,
};
+ enum class MemoryClass : unsigned {
+ MISC = 0,
+ ROM = 1,
+ SRAM = 2,
+ WRAM = 3,
+ SUPERFXROM = 4,
+ SUPERFXRAM = 5,
+ SA1IRAM = 6,
+ SA1BWRAM = 7,
+ SUFAMITURBO_ROMA = 8,
+ SUFAMITURBO_ROMB = 9,
+ SUFAMITURBO_RAMA = 10,
+ SUFAMITURBO_RAMB = 11,
+ BSXFLASH = 12,
+ };
+
enum class Slot : unsigned {
Base,
Bsx,
@@ -68,6 +84,7 @@ struct Cartridge : property<Cartridge> {
unsigned addrhi;
unsigned offset;
unsigned size;
+ MemoryClass clazz;
Mapping();
Mapping(const function<uint8 (unsigned)>&, const function<void (unsigned, uint8)>&);
diff --git a/snes/cartridge/markup.cpp b/snes/cartridge/markup.cpp
index e639fe52..2dd0d646 100755
--- a/snes/cartridge/markup.cpp
+++ b/snes/cartridge/markup.cpp
@@ -74,6 +74,7 @@ void Cartridge::parse_markup_rom(XML::Node &root) {
for(auto &node : root) {
if(node.name != "map") continue;
Mapping m(rom);
+ m.clazz = MemoryClass::ROM;
parse_markup_map(m, node);
if(m.size == 0) m.size = rom.size();
mapping.append(m);
@@ -85,6 +86,7 @@ void Cartridge::parse_markup_ram(XML::Node &root) {
ram_size = parse_markup_integer(root["size"].data);
for(auto &node : root) {
Mapping m(ram);
+ m.clazz = MemoryClass::SRAM;
parse_markup_map(m, node);
if(m.size == 0) m.size = ram_size;
mapping.append(m);
@@ -133,6 +135,7 @@ void Cartridge::parse_markup_superfx(XML::Node &root) {
for(auto &leaf : node) {
if(leaf.name != "map") continue;
Mapping m(superfx.rom);
+ //m.clazz = MemoryClass::SUPERFXROM; -- Aliases ROM.
parse_markup_map(m, leaf);
mapping.append(m);
}
@@ -145,6 +148,7 @@ void Cartridge::parse_markup_superfx(XML::Node &root) {
}
if(leaf.name != "map") continue;
Mapping m(superfx.ram);
+ //m.clazz = MemoryClass::SUPERFXRAM; -- Aliases SRAM.
parse_markup_map(m, leaf);
if(m.size == 0) m.size = ram_size;
mapping.append(m);
@@ -188,6 +192,7 @@ void Cartridge::parse_markup_sa1(XML::Node &root) {
for(auto &node : iram) {
if(node.name != "map") continue;
Mapping m(sa1.cpuiram);
+ m.clazz = MemoryClass::SA1IRAM;
parse_markup_map(m, node);
if(m.size == 0) m.size = 2048;
mapping.append(m);
@@ -197,6 +202,7 @@ void Cartridge::parse_markup_sa1(XML::Node &root) {
for(auto &node : bwram) {
if(node.name != "map") continue;
Mapping m(sa1.cpubwram);
+ //m.clazz = MemoryClass::SA1BWRAM; -- Aliases SRAM
parse_markup_map(m, node);
if(m.size == 0) m.size = ram_size;
mapping.append(m);
@@ -341,6 +347,7 @@ void Cartridge::parse_markup_bsx(XML::Node &root) {
for(auto &node : root["slot"]) {
if(node.name != "map") continue;
Mapping m(bsxflash.memory);
+ m.clazz = MemoryClass::BSXFLASH;
parse_markup_map(m, node);
mapping.append(m);
}
@@ -373,6 +380,7 @@ void Cartridge::parse_markup_sufamiturbo(XML::Node &root) {
if(leaf.name != "map") continue;
Memory &memory = slotid == 0 ? sufamiturbo.slotA.rom : sufamiturbo.slotB.rom;
Mapping m(memory);
+ m.clazz = slotid ? MemoryClass::SUFAMITURBO_ROMB : MemoryClass::SUFAMITURBO_ROMA;
parse_markup_map(m, leaf);
if(m.size == 0) m.size = memory.size();
if(m.size) mapping.append(m);
@@ -384,6 +392,7 @@ void Cartridge::parse_markup_sufamiturbo(XML::Node &root) {
if(leaf.name != "map") continue;
Memory &memory = slotid == 0 ? sufamiturbo.slotA.ram : sufamiturbo.slotB.ram;
Mapping m(memory);
+ m.clazz = slotid ? MemoryClass::SUFAMITURBO_RAMB : MemoryClass::SUFAMITURBO_RAMA;
parse_markup_map(m, leaf);
if(m.size == 0) m.size = ram_size;
if(m.size) mapping.append(m);
@@ -536,11 +545,13 @@ void Cartridge::parse_markup_link(XML::Node &root) {
}
Cartridge::Mapping::Mapping() {
+ clazz = MemoryClass::MISC;
mode = Bus::MapMode::Direct;
banklo = bankhi = addrlo = addrhi = offset = size = 0;
}
Cartridge::Mapping::Mapping(Memory &memory) {
+ clazz = MemoryClass::MISC;
read = { &Memory::read, &memory };
write = { &Memory::write, &memory };
mode = Bus::MapMode::Direct;
diff --git a/snes/cheat/cheat.cpp b/snes/cheat/cheat.cpp
index 46c42d1c..3a269cc5 100755
--- a/snes/cheat/cheat.cpp
+++ b/snes/cheat/cheat.cpp
@@ -21,9 +21,9 @@ void Cheat::synchronize() {
for(unsigned i = 0; i < size(); i++) {
const CheatCode &code = operator[](i);
- unsigned addr = mirror(code.addr);
+ unsigned addr = code.nomirror ? code.addr : mirror(code.addr);
override[addr] = true;
- if((addr & 0xffe000) == 0x7e0000) {
+ if(!code.nomirror && (addr & 0xffe000) == 0x7e0000) {
//mirror $7e:0000-1fff to $00-3f|80-bf:0000-1fff
unsigned mirroraddr;
for(unsigned x = 0; x <= 0x3f; x++) {
@@ -40,11 +40,14 @@ void Cheat::synchronize() {
}
uint8 Cheat::read(unsigned addr) const {
- addr = mirror(addr);
+ unsigned raddr = mirror(addr);
for(unsigned i = 0; i < size(); i++) {
const CheatCode &code = operator[](i);
- if(addr == mirror(code.addr)) {
+ if(!code.nomirror && addr == mirror(code.addr)) {
+ return code.data;
+ }
+ if(code.nomirror && raddr == code.addr) {
return code.data;
}
}
diff --git a/snes/cheat/cheat.hpp b/snes/cheat/cheat.hpp
index 306b99b1..b4d2a42e 100755
--- a/snes/cheat/cheat.hpp
+++ b/snes/cheat/cheat.hpp
@@ -1,6 +1,7 @@
struct CheatCode {
unsigned addr;
unsigned data;
+ bool nomirror;
};
struct Cheat : public linear_vector<CheatCode> {
diff --git a/snes/chip/bsx/satellaview/satellaview.cpp b/snes/chip/bsx/satellaview/satellaview.cpp
index 3c980195..25af8e56 100755
--- a/snes/chip/bsx/satellaview/satellaview.cpp
+++ b/snes/chip/bsx/satellaview/satellaview.cpp
@@ -6,8 +6,8 @@ void BSXSatellaview::init() {
}
void BSXSatellaview::load() {
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2188, 0x219f, { &BSXSatellaview::mmio_read, &bsxsatellaview }, { &BSXSatellaview::mmio_write, &bsxsatellaview });
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2188, 0x219f, { &BSXSatellaview::mmio_read, &bsxsatellaview }, { &BSXSatellaview::mmio_write, &bsxsatellaview });
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2188, 0x219f, 0, { &BSXSatellaview::mmio_read, &bsxsatellaview }, { &BSXSatellaview::mmio_write, &bsxsatellaview });
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2188, 0x219f, 0, { &BSXSatellaview::mmio_read, &bsxsatellaview }, { &BSXSatellaview::mmio_write, &bsxsatellaview });
}
void BSXSatellaview::unload() {
diff --git a/snes/chip/hitachidsp/hitachidsp.cpp b/snes/chip/hitachidsp/hitachidsp.cpp
index 1042267e..3e5c5bdb 100755
--- a/snes/chip/hitachidsp/hitachidsp.cpp
+++ b/snes/chip/hitachidsp/hitachidsp.cpp
@@ -23,7 +23,7 @@ void HitachiDSP::enter() {
break;
case State::DMA:
for(unsigned n = 0; n < regs.dma_length; n++) {
- bus.write(regs.dma_target + n, bus.read(regs.dma_source + n));
+ bus.write(regs.dma_target + n, bus.read(regs.dma_source + n, false));
step(2);
}
state = State::Idle;
diff --git a/snes/chip/hitachidsp/memory.cpp b/snes/chip/hitachidsp/memory.cpp
index 3c9c3af1..36868e88 100755
--- a/snes/chip/hitachidsp/memory.cpp
+++ b/snes/chip/hitachidsp/memory.cpp
@@ -1,7 +1,7 @@
#ifdef HITACHIDSP_CPP
uint8 HitachiDSP::bus_read(unsigned addr) {
- if((addr & 0x408000) == 0x008000) return bus.read(addr);
+ if((addr & 0x408000) == 0x008000) return bus.read(addr, false);
return 0x00;
}
diff --git a/snes/chip/nss/nss.cpp b/snes/chip/nss/nss.cpp
index 964973d0..5946af3b 100755
--- a/snes/chip/nss/nss.cpp
+++ b/snes/chip/nss/nss.cpp
@@ -10,8 +10,8 @@ void NSS::init() {
void NSS::load() {
dip = 0x0000;
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4100, 0x4101, { &NSS::read, this }, { &NSS::write, this });
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4100, 0x4101, { &NSS::read, this }, { &NSS::write, this });
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4100, 0x4101, 0, { &NSS::read, this }, { &NSS::write, this });
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4100, 0x4101, 0, { &NSS::read, this }, { &NSS::write, this });
}
void NSS::unload() {
diff --git a/snes/chip/sa1/memory/memory.cpp b/snes/chip/sa1/memory/memory.cpp
index d13ac929..9bb4ff20 100755
--- a/snes/chip/sa1/memory/memory.cpp
+++ b/snes/chip/sa1/memory/memory.cpp
@@ -107,7 +107,7 @@ void SA1::op_io() {
tick();
}
-uint8 SA1::op_read(unsigned addr) {
+uint8 SA1::op_read(unsigned addr, bool exec) {
tick();
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
return bus_read(addr);
diff --git a/snes/chip/sa1/memory/memory.hpp b/snes/chip/sa1/memory/memory.hpp
index ffb9e9f6..ab8e1edd 100755
--- a/snes/chip/sa1/memory/memory.hpp
+++ b/snes/chip/sa1/memory/memory.hpp
@@ -3,7 +3,7 @@ void bus_write(unsigned addr, uint8 data);
uint8 vbr_read(unsigned addr);
alwaysinline void op_io();
-alwaysinline uint8 op_read(unsigned addr);
+alwaysinline uint8 op_read(unsigned addr, bool exec);
alwaysinline void op_write(unsigned addr, uint8 data);
uint8 mmc_read(unsigned addr);
diff --git a/snes/chip/sa1/sa1.cpp b/snes/chip/sa1/sa1.cpp
index 71c6310a..30e00809 100755
--- a/snes/chip/sa1/sa1.cpp
+++ b/snes/chip/sa1/sa1.cpp
@@ -37,7 +37,7 @@ void SA1::enter() {
}
void SA1::op_irq() {
- op_read(regs.pc.d);
+ op_read(regs.pc.d, false);
op_io();
if(!regs.e) op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
diff --git a/snes/chip/sdd1/sdd1.cpp b/snes/chip/sdd1/sdd1.cpp
index c9b8b1c4..5d6cc55f 100755
--- a/snes/chip/sdd1/sdd1.cpp
+++ b/snes/chip/sdd1/sdd1.cpp
@@ -14,8 +14,8 @@ void SDD1::init() {
void SDD1::load() {
//hook S-CPU DMA MMIO registers to gather information for struct dma[];
//buffer address and transfer size information for use in SDD1::mcu_read()
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 });
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 });
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, 0, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 });
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, 0, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 });
}
void SDD1::unload() {
diff --git a/snes/cpu/core/core.hpp b/snes/cpu/core/core.hpp
index 7a685a8d..9d77f3c5 100755
--- a/snes/cpu/core/core.hpp
+++ b/snes/cpu/core/core.hpp
@@ -10,7 +10,7 @@ struct CPUcore {
void powercycle();
virtual void op_io() = 0;
- virtual uint8_t op_read(uint32_t addr) = 0;
+ virtual uint8_t op_read(uint32_t addr, bool exec = false) = 0;
virtual void op_write(uint32_t addr, uint8_t data) = 0;
virtual void last_cycle() = 0;
virtual bool interrupt_pending() = 0;
diff --git a/snes/cpu/core/disassembler/disassembler.cpp b/snes/cpu/core/disassembler/disassembler.cpp
index 030b3ab5..ab8dde24 100755
--- a/snes/cpu/core/disassembler/disassembler.cpp
+++ b/snes/cpu/core/disassembler/disassembler.cpp
@@ -6,7 +6,7 @@ uint8 CPUcore::dreadb(uint32 addr) {
//do not read MMIO registers within debugger
return 0x00;
}
- return bus.read(addr);
+ return bus.read(addr, false);
}
uint16 CPUcore::dreadw(uint32 addr) {
diff --git a/snes/cpu/core/memory.hpp b/snes/cpu/core/memory.hpp
index 49926578..132501c1 100755
--- a/snes/cpu/core/memory.hpp
+++ b/snes/cpu/core/memory.hpp
@@ -1,5 +1,5 @@
alwaysinline uint8_t op_readpc() {
- return op_read((regs.pc.b << 16) + regs.pc.w++);
+ return op_read((regs.pc.b << 16) + regs.pc.w++, true);
}
alwaysinline uint8_t op_readstack() {
diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
index 2d7d3432..39da6b16 100755
--- a/snes/cpu/cpu.cpp
+++ b/snes/cpu/cpu.cpp
@@ -78,8 +78,8 @@ void CPU::enter() {
} else if(status.reset_pending) {
status.reset_pending = false;
add_clocks(186);
- regs.pc.l = bus.read(0xfffc);
- regs.pc.h = bus.read(0xfffd);
+ regs.pc.l = bus.read(0xfffc, false);
+ regs.pc.h = bus.read(0xfffd, false);
}
}
@@ -95,24 +95,24 @@ void CPU::enable() {
function<uint8 (unsigned)> read = { &CPU::mmio_read, (CPU*)&cpu };
function<void (unsigned, uint8)> write = { &CPU::mmio_write, (CPU*)&cpu };
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, 0, read, write);
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, 0, read, write);
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, 0, read, write);
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, 0, read, write);
read = [](unsigned addr) { return cpu.wram[addr]; };
write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; };
- bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, read, write, 0x000000, 0x002000);
- bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, read, write, 0x000000, 0x002000);
- bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, read, write);
+ bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, 3, read, write, 0x000000, 0x002000);
+ bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, 3, read, write, 0x000000, 0x002000);
+ bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, 3, read, write);
}
void CPU::power() {
diff --git a/snes/cpu/debugger/debugger.cpp b/snes/cpu/debugger/debugger.cpp
index a33518ed..8301bdb6 100755
--- a/snes/cpu/debugger/debugger.cpp
+++ b/snes/cpu/debugger/debugger.cpp
@@ -19,8 +19,8 @@ void CPUDebugger::op_step() {
synchronize_smp();
}
-uint8 CPUDebugger::op_read(uint32 addr) {
- uint8 data = CPU::op_read(addr);
+uint8 CPUDebugger::op_read(uint32 addr, bool exec) {
+ uint8 data = CPU::op_read(addr, exec);
usage[addr] |= UsageRead;
debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Read, addr, data);
return data;
diff --git a/snes/cpu/debugger/debugger.hpp b/snes/cpu/debugger/debugger.hpp
index 579f6f03..c3d66db5 100755
--- a/snes/cpu/debugger/debugger.hpp
+++ b/snes/cpu/debugger/debugger.hpp
@@ -16,7 +16,7 @@ public:
bool opcode_edge; //true right before an opcode execues, used to skip over opcodes
void op_step();
- uint8 op_read(uint32 addr);
+ uint8 op_read(uint32 addr, bool exec = false);
void op_write(uint32 addr, uint8 data);
CPUDebugger();
diff --git a/snes/cpu/dma/dma.cpp b/snes/cpu/dma/dma.cpp
index e8cdb3ec..0a00bfea 100755
--- a/snes/cpu/dma/dma.cpp
+++ b/snes/cpu/dma/dma.cpp
@@ -26,7 +26,7 @@ bool CPU::dma_addr_valid(uint32 abus) {
uint8 CPU::dma_read(uint32 abus) {
if(dma_addr_valid(abus) == false) return 0x00;
- return bus.read(abus);
+ return bus.read(abus, false);
}
//simulate two-stage pipeline for DMA transfers; example:
@@ -49,7 +49,7 @@ void CPU::dma_transfer(bool direction, uint8 bbus, uint32 abus) {
dma_write(dma_transfer_valid(bbus, abus), 0x2100 | bbus, regs.mdr);
} else {
dma_add_clocks(4);
- regs.mdr = dma_transfer_valid(bbus, abus) ? bus.read(0x2100 | bbus) : 0x00;
+ regs.mdr = dma_transfer_valid(bbus, abus) ? bus.read(0x2100 | bbus, false) : 0x00;
dma_add_clocks(4);
dma_write(dma_addr_valid(abus), abus, regs.mdr);
}
diff --git a/snes/cpu/memory/memory.cpp b/snes/cpu/memory/memory.cpp
index c2c8f1fa..31f82c31 100755
--- a/snes/cpu/memory/memory.cpp
+++ b/snes/cpu/memory/memory.cpp
@@ -10,11 +10,11 @@ void CPU::op_io() {
alu_edge();
}
-uint8 CPU::op_read(uint32 addr) {
+uint8 CPU::op_read(uint32 addr, bool exec) {
status.clock_count = speed(addr);
dma_edge();
add_clocks(status.clock_count - 4);
- regs.mdr = bus.read(addr);
+ regs.mdr = bus.read(addr, exec);
add_clocks(4);
alu_edge();
return regs.mdr;
diff --git a/snes/cpu/memory/memory.hpp b/snes/cpu/memory/memory.hpp
index d33861d4..fd64ba8b 100755
--- a/snes/cpu/memory/memory.hpp
+++ b/snes/cpu/memory/memory.hpp
@@ -1,4 +1,4 @@
void op_io();
-debugvirtual uint8 op_read(uint32 addr);
+debugvirtual uint8 op_read(uint32 addr, bool exec);
debugvirtual void op_write(uint32 addr, uint8 data);
alwaysinline unsigned speed(unsigned addr) const;
diff --git a/snes/cpu/mmio/mmio.cpp b/snes/cpu/mmio/mmio.cpp
index b7afff00..30048c19 100755
--- a/snes/cpu/mmio/mmio.cpp
+++ b/snes/cpu/mmio/mmio.cpp
@@ -5,7 +5,7 @@ bool CPU::joylatch() { return status.joypad_strobe_latch; }
//WMDATA
uint8 CPU::mmio_r2180() {
- return bus.read(0x7e0000 | status.wram_addr++);
+ return bus.read(0x7e0000 | status.wram_addr++, false);
}
//WMDATA
diff --git a/snes/debugger/debugger.cpp b/snes/debugger/debugger.cpp
index b1312339..e8d0f5af 100755
--- a/snes/debugger/debugger.cpp
+++ b/snes/debugger/debugger.cpp
@@ -33,7 +33,7 @@ uint8 Debugger::read(Debugger::MemorySource source, unsigned addr) {
case MemorySource::CPUBus: {
//do not read from memory-mapped registers that could affect program behavior
if(((addr - 0x2000) & 0x40c000) == 0x000000) break; //$00-3f:2000-5fff MMIO
- return bus.read(addr & 0xffffff);
+ return bus.read(addr & 0xffffff, false);
} break;
case MemorySource::APUBus: {
diff --git a/snes/memory/memory-inline.hpp b/snes/memory/memory-inline.hpp
index 70503bea..45f150c9 100755
--- a/snes/memory/memory-inline.hpp
+++ b/snes/memory/memory-inline.hpp
@@ -51,11 +51,26 @@ MappedRAM::MappedRAM() : data_(0), size_(0), write_protect_(false) {}
//Bus
-uint8 Bus::read(unsigned addr) {
- if(cheat.override[addr]) return cheat.read(addr);
- return reader[lookup[addr]](target[addr]);
+uint8 Bus::read(unsigned addr, bool exec) {
+ uint8 emask = exec ? 0x24 : 0x09;
+ uint8 val;
+ if(__builtin_expect(cheat.override[addr], 0))
+ val = cheat.read(addr);
+ else
+ val = reader[lookup[addr]](target[addr]);
+ if(__builtin_expect((u_debugflags | debugflags[addr]) & emask, 0)) {
+ unsigned daddr = target[addr];
+ uint8 mclass = classmap[addr];
+ debug_read(mclass, daddr, addr, val, exec);
+ }
+ return val;
}
void Bus::write(unsigned addr, uint8 data) {
+ if(__builtin_expect((u_debugflags | debugflags[addr]) & 0x12, 0)) {
+ unsigned daddr = target[addr];
+ uint8 mclass = classmap[addr];
+ debug_write(mclass, daddr, addr, data);
+ }
return writer[lookup[addr]](target[addr], data);
}
diff --git a/snes/memory/memory.cpp b/snes/memory/memory.cpp
index ede9cbd0..a9a484a0 100755
--- a/snes/memory/memory.cpp
+++ b/snes/memory/memory.cpp
@@ -27,6 +27,7 @@ void Bus::map(
MapMode mode,
unsigned bank_lo, unsigned bank_hi,
unsigned addr_lo, unsigned addr_hi,
+ unsigned mclass,
const function<uint8 (unsigned)> &rd,
const function<void (unsigned, uint8)> &wr,
unsigned base, unsigned length
@@ -48,6 +49,7 @@ void Bus::map(
if(mode == MapMode::Shadow) destaddr = mirror(base + destaddr, length);
lookup[(bank << 16) | addr] = id;
target[(bank << 16) | addr] = destaddr;
+ if(mclass) classmap[(bank << 16) | addr] = mclass;
}
}
}
@@ -57,23 +59,58 @@ void Bus::map_reset() {
function<void (unsigned, uint8)> writer = [](unsigned, uint8) {};
idcount = 0;
- map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, reader, writer);
+ map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, 0xFF, reader, writer);
}
void Bus::map_xml() {
for(auto &m : cartridge.mapping) {
- map(m.mode, m.banklo, m.bankhi, m.addrlo, m.addrhi, m.read, m.write, m.offset, m.size);
+ map(m.mode, m.banklo, m.bankhi, m.addrlo, m.addrhi, (unsigned)m.clazz, m.read, m.write, m.offset, m.size);
}
}
+unsigned Bus::enumerateMirrors(uint8 clazz, uint32 offset, unsigned start)
+{
+ unsigned i;
+ for(i = start; i < 0x1000000; i++)
+ if((classmap[i] == clazz && target[i] == offset) || (i == offset && clazz == 255))
+ return i;
+ return i;
+}
+
+void Bus::clearDebugFlags()
+{
+ u_debugflags = 0;
+ memset(debugflags, 0, 0x1000000);
+}
+
+void Bus::debugFlags(uint8 setf, uint8 clrf)
+{
+ u_debugflags = (u_debugflags | setf) & ~clrf;
+}
+
+void Bus::debugFlags(uint8 setf, uint8 clrf, uint8 clazz, uint32 offset)
+{
+ if(clazz == 255) {
+ setf <<= 3;
+ clrf <<= 3;
+ debugflags[offset] = (debugflags[offset] | setf) & ~clrf;
+ } else
+ for(unsigned i = 0; i < 0x1000000; i++)
+ if(classmap[i] == clazz && target[i] == offset)
+ debugflags[i] = (debugflags[i] | setf) & ~clrf;
+}
+
Bus::Bus() {
- lookup = new uint8 [16 * 1024 * 1024];
- target = new uint32[16 * 1024 * 1024];
+ u_debugflags = 0;
+ lookup = new uint8 [112 * 1024 * 1024];
+ target = (uint32*)(lookup + 0x3000000);
+ classmap = lookup + 0x1000000;
+ debugflags = lookup + 0x2000000;
+ memset(debugflags, 0, 0x1000000);
}
Bus::~Bus() {
delete[] lookup;
- delete[] target;
}
}
diff --git a/snes/memory/memory.hpp b/snes/memory/memory.hpp
index 634e0717..c20e14db 100755
--- a/snes/memory/memory.hpp
+++ b/snes/memory/memory.hpp
@@ -44,10 +44,13 @@ private:
struct Bus {
unsigned mirror(unsigned addr, unsigned size);
- alwaysinline uint8 read(unsigned addr);
+ alwaysinline uint8 read(unsigned addr, bool exec);
alwaysinline void write(unsigned addr, uint8 data);
uint8 *lookup;
+ uint8 *classmap;
+ uint8 *debugflags;
+ uint8 u_debugflags;
uint32 *target;
unsigned idcount;
@@ -59,6 +62,7 @@ struct Bus {
MapMode mode,
unsigned bank_lo, unsigned bank_hi,
unsigned addr_lo, unsigned addr_hi,
+ unsigned mclass,
const function<uint8 (unsigned)> &read,
const function<void (unsigned, uint8)> &write,
unsigned base = 0, unsigned length = 0
@@ -67,6 +71,13 @@ struct Bus {
void map_reset();
void map_xml();
+ void clearDebugFlags();
+ void debugFlags(uint8 setf, uint8 clrf);
+ void debugFlags(uint8 setf, uint8 clrf, uint8 clazz, uint32 offset);
+ unsigned enumerateMirrors(uint8 clazz, uint32 offset, unsigned start);
+ function<void (uint8, unsigned, unsigned, uint8, bool)> debug_read;
+ function<void (uint8, unsigned, unsigned, uint8)> debug_write;
+
Bus();
~Bus();
};
diff --git a/snes/ppu/ppu.cpp b/snes/ppu/ppu.cpp
index 8545175f..13e231cf 100755
--- a/snes/ppu/ppu.cpp
+++ b/snes/ppu/ppu.cpp
@@ -87,8 +87,8 @@ void PPU::enable() {
function<uint8 (unsigned)> read = { &PPU::mmio_read, (PPU*)&ppu };
function<void (unsigned, uint8)> write = { &PPU::mmio_write, (PPU*)&ppu };
- bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, read, write);
- bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, read, write);
+ bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, 0, read, write);
+ bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, 0, read, write);
}
void PPU::power() {
diff --git a/snes/smp/core/core.hpp b/snes/smp/core/core.hpp
index 1489fcef..13d69364 100755
--- a/snes/smp/core/core.hpp
+++ b/snes/smp/core/core.hpp
@@ -2,7 +2,7 @@ struct SMPcore {
virtual void op_io() = 0;
virtual uint8 op_read(uint16 addr) = 0;
virtual void op_write(uint16 addr, uint8 data) = 0;
- void op_step();
+ virtual void op_step();
#include "registers.hpp"
#include "memory.hpp"
diff --git a/snes/snes.hpp b/snes/snes.hpp
index dffeeee3..37ed1feb 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -1,5 +1,6 @@
#ifndef SNES_HPP
#define SNES_HPP
+#define BSNES_SUPPORTS_ADV_BREAKPOINTS
namespace SNES {
namespace Info {
--
2.15.0.rc1