SNES: Support VRAM, OAM, CGRAM and APURAM breakpoints
This commit is contained in:
parent
d210680315
commit
47b5e9b6be
19 changed files with 656 additions and 35 deletions
|
@ -1,7 +1,7 @@
|
|||
From b19b3b2d1d7a522af695f4482abb28e52804326b Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Wed, 9 Nov 2011 00:30:36 +0200
|
||||
Subject: [PATCH 01/17] Make libsnes compile
|
||||
Subject: [PATCH 01/18] Make libsnes compile
|
||||
|
||||
Changes between v083 and v084 had broken libsnes. Fix it so it at least
|
||||
compiles.
|
||||
|
@ -78,5 +78,5 @@ index fbb4482..5f5ded6 100755
|
|||
}
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, xmlrom);
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From bb2fed04fbfe62a89e4bcfe90f44b4738f7c7c1a Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Wed, 9 Nov 2011 00:31:59 +0200
|
||||
Subject: [PATCH 02/17] Fix bsnes version number in libsnes to be v085, not
|
||||
Subject: [PATCH 02/18] Fix bsnes version number in libsnes to be v085, not
|
||||
v083
|
||||
|
||||
---
|
||||
|
@ -22,5 +22,5 @@ index 5f5ded6..0e63075 100755
|
|||
|
||||
unsigned snes_library_revision_major(void) {
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 7379b4570e5755a5a1da25181ba4f5d1ca461a98 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Wed, 9 Nov 2011 00:37:44 +0200
|
||||
Subject: [PATCH 03/17] Don't use time() in emulating chips
|
||||
Subject: [PATCH 03/18] Don't use time() in emulating chips
|
||||
|
||||
Instead of using time() in chip emulation, create new interface method
|
||||
currentTime(), defaulting to time(0). This way frontend can cleanly
|
||||
|
@ -80,5 +80,5 @@ index f1a48c0..df975e8 100755
|
|||
|
||||
extern Interface *interface;
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From efe1b5884c316ce070953edd87c6c9aeffffaa94 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Wed, 9 Nov 2011 01:52:08 +0200
|
||||
Subject: [PATCH 04/17] Save controller state when savestating
|
||||
Subject: [PATCH 04/18] Save controller state when savestating
|
||||
|
||||
When savestating, save the controller state and restore it upon loadstate.
|
||||
Prevents libsnes from mixing up buttons.
|
||||
|
@ -342,5 +342,5 @@ index f7d6f3b..08e7051 100755
|
|||
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
|
||||
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From cdf2f46490f128308eb7f399d03530936ebeda0a Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Fri, 11 Nov 2011 03:05:48 +0200
|
||||
Subject: [PATCH 05/17] Fix unserialization of 64-bit signed integers
|
||||
Subject: [PATCH 05/18] Fix unserialization of 64-bit signed integers
|
||||
|
||||
---
|
||||
nall/serializer.hpp | 2 +-
|
||||
|
@ -21,5 +21,5 @@ index ff2337a..e6bc8fa 100755
|
|||
isize += size;
|
||||
}
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 4dc46334ec175e26277632fee4aea80768749af9 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Fri, 11 Nov 2011 19:49:46 +0200
|
||||
Subject: [PATCH 06/17] Allow frontend to control random number seed
|
||||
Subject: [PATCH 06/18] Allow frontend to control random number seed
|
||||
|
||||
---
|
||||
snes/interface/interface.cpp | 5 +++++
|
||||
|
@ -49,5 +49,5 @@ index c19a7c5..dbd912d 100755
|
|||
region = config.region;
|
||||
expansion = config.expansion_port;
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From eeaf6dc52d39ca9c150ff61864c11297d200d968 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Wed, 7 Mar 2012 16:57:18 +0200
|
||||
Subject: [PATCH 07/17] Fix mouse polling
|
||||
Subject: [PATCH 07/18] Fix mouse polling
|
||||
|
||||
Don't poll for mouse motion excessive number of times (no need to poll it for
|
||||
each bit!)
|
||||
|
@ -59,5 +59,5 @@ index b66ea51..b07c8ab 100755
|
|||
+ int _position_y;
|
||||
};
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 7018377c93553071fc404db872b2746d40ac3bce Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Sat, 1 Sep 2012 11:23:34 +0300
|
||||
Subject: [PATCH 08/17] Fix uninitialized variables
|
||||
Subject: [PATCH 08/18] Fix uninitialized variables
|
||||
|
||||
These uninitialized variables cause a lot of desyncs in Shadowrun.
|
||||
---
|
||||
|
@ -138,5 +138,5 @@ index 9080624..d4ccf42 100755
|
|||
|
||||
void SMP::reset() {
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 6e0364c9a86caa71623a188a720b2d68b304b89b Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Mon, 24 Sep 2012 21:46:09 +0300
|
||||
Subject: [PATCH 09/17] Add needed support for detecting true polls as opposed
|
||||
Subject: [PATCH 09/18] Add needed support for detecting true polls as opposed
|
||||
to just autopolling
|
||||
|
||||
---
|
||||
|
@ -65,5 +65,5 @@ index 8b6aaa6..c5ee930 100755
|
|||
//DMAPx
|
||||
uint8 CPU::mmio_r43x0(uint8 i) {
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From e397bd46f17d6ea00c8c96d5a8e0c5f5b4a6f642 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Sun, 14 Oct 2012 23:31:36 +0300
|
||||
Subject: [PATCH 10/17] Fix compiling on GCC 4.7
|
||||
Subject: [PATCH 10/18] Fix compiling on GCC 4.7
|
||||
|
||||
---
|
||||
nall/string.hpp | 2 +-
|
||||
|
@ -22,5 +22,5 @@ index 1b255ce..07a64df 100755
|
|||
#include <nall/string/convert.hpp>
|
||||
#include <nall/string/cstring.hpp>
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From e047aa8eb9883f60e4141effba8128a4a555d8be Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Sun, 27 Oct 2013 10:52:45 +0200
|
||||
Subject: [PATCH 11/17] Support notifying latches
|
||||
Subject: [PATCH 11/18] Support notifying latches
|
||||
|
||||
---
|
||||
snes/cpu/mmio/mmio.cpp | 1 +
|
||||
|
@ -61,5 +61,5 @@ index 30ee7fd..203f7b0 100755
|
|||
|
||||
extern Interface *interface;
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
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/17] Support unlimited number of breakpoints
|
||||
Subject: [PATCH 12/18] Support unlimited number of breakpoints
|
||||
|
||||
---
|
||||
snes/alt/cpu/cpu.cpp | 22 +++++++-------
|
||||
|
@ -795,5 +795,5 @@ index dffeeee..37ed1fe 100755
|
|||
namespace SNES {
|
||||
namespace Info {
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 8bc6bb381e680616dcc843c99889799aedd43163 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Sat, 30 Nov 2013 10:27:37 +0200
|
||||
Subject: [PATCH 13/17] Support auto-detecting bsnes version
|
||||
Subject: [PATCH 13/18] Support auto-detecting bsnes version
|
||||
|
||||
---
|
||||
bsnes.mk | 3 +++
|
||||
|
@ -18,5 +18,5 @@ index 0000000..20f22f6
|
|||
+LIBSNES_DIR=ui-libsnes
|
||||
+BSNES_VERSION=085
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 40c456dadd79cb2c94379fda8b41a4d0ba051ad1 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Sat, 7 Dec 2013 23:32:44 +0200
|
||||
Subject: [PATCH 14/17] Support alternate (more accurate) poll timings
|
||||
Subject: [PATCH 14/18] Support alternate (more accurate) poll timings
|
||||
|
||||
---
|
||||
snes/config/config.cpp | 1 +
|
||||
|
@ -134,5 +134,5 @@ index 37ed1fe..4e3ba64 100755
|
|||
namespace SNES {
|
||||
namespace Info {
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 863bde899b53ae31e854096ac5258208c848a293 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Thu, 6 Mar 2014 21:07:54 +0200
|
||||
Subject: [PATCH 15/17] Fix mouse speed support
|
||||
Subject: [PATCH 15/18] Fix mouse speed support
|
||||
|
||||
---
|
||||
snes/config/config.cpp | 1 +
|
||||
|
@ -99,5 +99,5 @@ index b07c8ab..13a9313 100755
|
|||
int _position_y;
|
||||
};
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 60267d1f22fd2ff3197c6c829640f66304c89283 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Sun, 16 Mar 2014 16:40:55 +0200
|
||||
Subject: [PATCH 16/17] Fix tracelog of controller registers
|
||||
Subject: [PATCH 16/18] Fix tracelog of controller registers
|
||||
|
||||
---
|
||||
snes/cpu/core/disassembler/disassembler.cpp | 2 ++
|
||||
|
@ -21,5 +21,5 @@ index ab8dde2..624a80c 100755
|
|||
//$[00-3f|80-bf]:[2000-5fff]
|
||||
//do not read MMIO registers within debugger
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From de71f12eb59a41899a5c77d797e144e6f0919777 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Mon, 17 Mar 2014 14:22:58 +0200
|
||||
Subject: [PATCH 17/17] Fix performance problem with non-bus breakpoints
|
||||
Subject: [PATCH 17/18] Fix performance problem with non-bus breakpoints
|
||||
|
||||
---
|
||||
snes/memory/memory.cpp | 35 ++++++++++++++++++++++++++---------
|
||||
|
@ -101,5 +101,5 @@ index 4e3ba64..9589db9 100755
|
|||
|
||||
#include <gameboy/gameboy.hpp>
|
||||
--
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
|
|
|
@ -0,0 +1,537 @@
|
|||
From 6bd069191d29ad70d38c82d59dd72cd0996fc45c Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Mon, 31 Mar 2014 20:17:46 +0300
|
||||
Subject: [PATCH 18/18] Support VRAM, OAM, CGRAM and APURAM breakpoints
|
||||
|
||||
---
|
||||
snes/alt/ppu-compatibility/memory/memory.cpp | 44 +++++++++++++++++++++--
|
||||
snes/alt/ppu-compatibility/ppu.hpp | 6 ++++
|
||||
snes/cartridge/cartridge.hpp | 4 +++
|
||||
snes/smp/core/core.hpp | 2 +-
|
||||
snes/smp/core/memory.hpp | 6 ++--
|
||||
snes/smp/core/opcodes.cpp | 36 +++++++++----------
|
||||
snes/smp/debugger/debugger.cpp | 4 +--
|
||||
snes/smp/debugger/debugger.hpp | 2 +-
|
||||
snes/smp/memory/memory.cpp | 54 +++++++++++++++++++---------
|
||||
snes/smp/memory/memory.hpp | 4 +--
|
||||
snes/smp/smp.hpp | 4 +++
|
||||
snes/snes.hpp | 1 +
|
||||
12 files changed, 122 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/snes/alt/ppu-compatibility/memory/memory.cpp b/snes/alt/ppu-compatibility/memory/memory.cpp
|
||||
index 3f120d8..e47cf20 100755
|
||||
--- a/snes/alt/ppu-compatibility/memory/memory.cpp
|
||||
+++ b/snes/alt/ppu-compatibility/memory/memory.cpp
|
||||
@@ -47,20 +47,31 @@ uint8 PPU::vram_mmio_read(uint16 addr) {
|
||||
data = vram[addr];
|
||||
}
|
||||
}
|
||||
-
|
||||
+ if(__builtin_expect(vram_debugflags[addr] & 0x1, 0)) {
|
||||
+ debug_read(13, addr, data);
|
||||
+ }
|
||||
return data;
|
||||
}
|
||||
|
||||
void PPU::vram_mmio_write(uint16 addr, uint8 data) {
|
||||
if(regs.display_disabled == true) {
|
||||
+ if(__builtin_expect(vram_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(13, addr, data);
|
||||
+ }
|
||||
vram[addr] = data;
|
||||
} else {
|
||||
uint16 v = cpu.vcounter();
|
||||
uint16 h = cpu.hcounter();
|
||||
if(v == 0) {
|
||||
if(h <= 4) {
|
||||
+ if(__builtin_expect(vram_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(13, addr, data);
|
||||
+ }
|
||||
vram[addr] = data;
|
||||
} else if(h == 6) {
|
||||
+ if(__builtin_expect(vram_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(13, addr, cpu.regs.mdr);
|
||||
+ }
|
||||
vram[addr] = cpu.regs.mdr;
|
||||
} else {
|
||||
//no write
|
||||
@@ -71,9 +82,15 @@ void PPU::vram_mmio_write(uint16 addr, uint8 data) {
|
||||
if(h <= 4) {
|
||||
//no write
|
||||
} else {
|
||||
+ if(__builtin_expect(vram_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(13, addr, data);
|
||||
+ }
|
||||
vram[addr] = data;
|
||||
}
|
||||
} else {
|
||||
+ if(__builtin_expect(vram_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(13, addr, data);
|
||||
+ }
|
||||
vram[addr] = data;
|
||||
}
|
||||
}
|
||||
@@ -93,7 +110,9 @@ uint8 PPU::oam_mmio_read(uint16 addr) {
|
||||
data = oam[addr];
|
||||
}
|
||||
}
|
||||
-
|
||||
+ if(__builtin_expect(oam_debugflags[addr] & 0x1, 0)) {
|
||||
+ debug_read(14, addr, data);
|
||||
+ }
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -104,13 +123,22 @@ void PPU::oam_mmio_write(uint16 addr, uint8 data) {
|
||||
sprite_list_valid = false;
|
||||
|
||||
if(regs.display_disabled == true) {
|
||||
+ if(__builtin_expect(oam_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(14, addr, data);
|
||||
+ }
|
||||
oam[addr] = data;
|
||||
update_sprite_list(addr, data);
|
||||
} else {
|
||||
if(cpu.vcounter() < (!overscan() ? 225 : 240)) {
|
||||
+ if(__builtin_expect(oam_debugflags[regs.ioamaddr] & 0x2, 0)) {
|
||||
+ debug_write(14, regs.ioamaddr, data);
|
||||
+ }
|
||||
oam[regs.ioamaddr] = data;
|
||||
update_sprite_list(regs.ioamaddr, data);
|
||||
} else {
|
||||
+ if(__builtin_expect(oam_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(14, addr, data);
|
||||
+ }
|
||||
oam[addr] = data;
|
||||
update_sprite_list(addr, data);
|
||||
}
|
||||
@@ -134,6 +162,9 @@ uint8 PPU::cgram_mmio_read(uint16 addr) {
|
||||
}
|
||||
|
||||
if(addr & 1) data &= 0x7f;
|
||||
+ if(__builtin_expect(cgram_debugflags[addr] & 0x1, 0)) {
|
||||
+ debug_read(15, addr, data);
|
||||
+ }
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -142,13 +173,22 @@ void PPU::cgram_mmio_write(uint16 addr, uint8 data) {
|
||||
if(addr & 1) data &= 0x7f;
|
||||
|
||||
if(1 || regs.display_disabled == true) {
|
||||
+ if(__builtin_expect(cgram_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(15, addr, data);
|
||||
+ }
|
||||
cgram[addr] = data;
|
||||
} else {
|
||||
uint16 v = cpu.vcounter();
|
||||
uint16 h = cpu.hcounter();
|
||||
if(v < (!overscan() ? 225 : 240) && h >= 128 && h < 1096) {
|
||||
+ if(__builtin_expect(cgram_debugflags[regs.icgramaddr] & 0x2, 0)) {
|
||||
+ debug_write(15, regs.icgramaddr, data & 0x7f);
|
||||
+ }
|
||||
cgram[regs.icgramaddr] = data & 0x7f;
|
||||
} else {
|
||||
+ if(__builtin_expect(cgram_debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(15, addr, data);
|
||||
+ }
|
||||
cgram[addr] = data;
|
||||
}
|
||||
}
|
||||
diff --git a/snes/alt/ppu-compatibility/ppu.hpp b/snes/alt/ppu-compatibility/ppu.hpp
|
||||
index cccaabb..4adac4c 100755
|
||||
--- a/snes/alt/ppu-compatibility/ppu.hpp
|
||||
+++ b/snes/alt/ppu-compatibility/ppu.hpp
|
||||
@@ -3,6 +3,12 @@ public:
|
||||
uint8 vram[128 * 1024];
|
||||
uint8 oam[544];
|
||||
uint8 cgram[512];
|
||||
+ //4 is read, 2 is write.
|
||||
+ uint8 vram_debugflags[128 * 1024];
|
||||
+ uint8 oam_debugflags[544];
|
||||
+ uint8 cgram_debugflags[512];
|
||||
+ function<void (uint8, unsigned, uint8)> debug_read;
|
||||
+ function<void (uint8, unsigned, uint8)> debug_write;
|
||||
|
||||
enum : bool { Threaded = true };
|
||||
alwaysinline void step(unsigned clocks);
|
||||
diff --git a/snes/cartridge/cartridge.hpp b/snes/cartridge/cartridge.hpp
|
||||
index 82e73c4..2358c08 100755
|
||||
--- a/snes/cartridge/cartridge.hpp
|
||||
+++ b/snes/cartridge/cartridge.hpp
|
||||
@@ -26,6 +26,10 @@ struct Cartridge : property<Cartridge> {
|
||||
SUFAMITURBO_RAMA = 10,
|
||||
SUFAMITURBO_RAMB = 11,
|
||||
BSXFLASH = 12,
|
||||
+ VRAM = 13,
|
||||
+ OAM = 14,
|
||||
+ CGRAM = 15,
|
||||
+ APURAM = 16,
|
||||
};
|
||||
|
||||
enum class Slot : unsigned {
|
||||
diff --git a/snes/smp/core/core.hpp b/snes/smp/core/core.hpp
|
||||
index 13d6936..03f9ac6 100755
|
||||
--- a/snes/smp/core/core.hpp
|
||||
+++ b/snes/smp/core/core.hpp
|
||||
@@ -1,6 +1,6 @@
|
||||
struct SMPcore {
|
||||
virtual void op_io() = 0;
|
||||
- virtual uint8 op_read(uint16 addr) = 0;
|
||||
+ virtual uint8 op_read(uint16 addr, bool exec) = 0;
|
||||
virtual void op_write(uint16 addr, uint8 data) = 0;
|
||||
virtual void op_step();
|
||||
|
||||
diff --git a/snes/smp/core/memory.hpp b/snes/smp/core/memory.hpp
|
||||
index c4b6d99..c297962 100755
|
||||
--- a/snes/smp/core/memory.hpp
|
||||
+++ b/snes/smp/core/memory.hpp
|
||||
@@ -1,9 +1,9 @@
|
||||
alwaysinline uint8 op_readpc() {
|
||||
- return op_read(regs.pc++);
|
||||
+ return op_read(regs.pc++, true);
|
||||
}
|
||||
|
||||
alwaysinline uint8 op_readsp() {
|
||||
- return op_read(0x0100 | ++regs.s);
|
||||
+ return op_read(0x0100 | ++regs.s, false);
|
||||
}
|
||||
|
||||
alwaysinline void op_writesp(uint8 data) {
|
||||
@@ -11,7 +11,7 @@ alwaysinline void op_writesp(uint8 data) {
|
||||
}
|
||||
|
||||
alwaysinline uint8 op_readdp(uint8 addr) {
|
||||
- return op_read((regs.p.p << 8) + addr);
|
||||
+ return op_read((regs.p.p << 8) + addr, false);
|
||||
}
|
||||
|
||||
alwaysinline void op_writedp(uint8 addr, uint8 data) {
|
||||
diff --git a/snes/smp/core/opcodes.cpp b/snes/smp/core/opcodes.cpp
|
||||
index 95b9844..43db081 100755
|
||||
--- a/snes/smp/core/opcodes.cpp
|
||||
+++ b/snes/smp/core/opcodes.cpp
|
||||
@@ -11,7 +11,7 @@ template<uint8 (SMPcore::*op)(uint8)>
|
||||
void SMPcore::op_adjust_addr() {
|
||||
dp.l = op_readpc();
|
||||
dp.h = op_readpc();
|
||||
- rd = op_read(dp);
|
||||
+ rd = op_read(dp, false);
|
||||
rd = call(rd);
|
||||
op_write(dp, rd);
|
||||
}
|
||||
@@ -78,7 +78,7 @@ template<uint8 (SMPcore::*op)(uint8, uint8)>
|
||||
void SMPcore::op_read_addr(uint8 &r) {
|
||||
dp.l = op_readpc();
|
||||
dp.h = op_readpc();
|
||||
- rd = op_read(dp);
|
||||
+ rd = op_read(dp, false);
|
||||
r = call(r, rd);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ void SMPcore::op_read_addri(uint8 &r) {
|
||||
dp.l = op_readpc();
|
||||
dp.h = op_readpc();
|
||||
op_io();
|
||||
- rd = op_read(dp + r);
|
||||
+ rd = op_read(dp + r, false);
|
||||
regs.a = call(regs.a, rd);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ void SMPcore::op_read_idpx() {
|
||||
op_io();
|
||||
sp.l = op_readdp(dp++);
|
||||
sp.h = op_readdp(dp++);
|
||||
- rd = op_read(sp);
|
||||
+ rd = op_read(sp, false);
|
||||
regs.a = call(regs.a, rd);
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ void SMPcore::op_read_idpy() {
|
||||
op_io();
|
||||
sp.l = op_readdp(dp++);
|
||||
sp.h = op_readdp(dp++);
|
||||
- rd = op_read(sp + regs.y);
|
||||
+ rd = op_read(sp + regs.y, false);
|
||||
regs.a = call(regs.a, rd);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ void SMPcore::op_set_addr_bit() {
|
||||
dp.h = op_readpc();
|
||||
bit = dp >> 13;
|
||||
dp &= 0x1fff;
|
||||
- rd = op_read(dp);
|
||||
+ rd = op_read(dp, false);
|
||||
switch(opcode >> 5) {
|
||||
case 0: //orc addr:bit
|
||||
case 1: //orc !addr:bit
|
||||
@@ -198,10 +198,10 @@ void SMPcore::op_set_flag(bool &flag, bool data) {
|
||||
void SMPcore::op_test_addr(bool set) {
|
||||
dp.l = op_readpc();
|
||||
dp.h = op_readpc();
|
||||
- rd = op_read(dp);
|
||||
+ rd = op_read(dp, false);
|
||||
regs.p.n = (regs.a - rd) & 0x80;
|
||||
regs.p.z = (regs.a - rd) == 0;
|
||||
- op_read(dp);
|
||||
+ op_read(dp, false);
|
||||
op_write(dp, set ? rd | regs.a : rd & ~regs.a);
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ void SMPcore::op_transfer(uint8 &from, uint8 &to) {
|
||||
void SMPcore::op_write_addr(uint8 &r) {
|
||||
dp.l = op_readpc();
|
||||
dp.h = op_readpc();
|
||||
- op_read(dp);
|
||||
+ op_read(dp, false);
|
||||
op_write(dp, r);
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ void SMPcore::op_write_addri(uint8 &i) {
|
||||
dp.h = op_readpc();
|
||||
op_io();
|
||||
dp += i;
|
||||
- op_read(dp);
|
||||
+ op_read(dp, false);
|
||||
op_write(dp, regs.a);
|
||||
}
|
||||
|
||||
@@ -317,8 +317,8 @@ void SMPcore::op_bne_ydec() {
|
||||
}
|
||||
|
||||
void SMPcore::op_brk() {
|
||||
- rd.l = op_read(0xffde);
|
||||
- rd.h = op_read(0xffdf);
|
||||
+ rd.l = op_read(0xffde, false);
|
||||
+ rd.h = op_read(0xffdf, false);
|
||||
op_io();
|
||||
op_io();
|
||||
op_writesp(regs.pc.h);
|
||||
@@ -411,8 +411,8 @@ void SMPcore::op_jmp_iaddrx() {
|
||||
dp.h = op_readpc();
|
||||
op_io();
|
||||
dp += regs.x;
|
||||
- rd.l = op_read(dp++);
|
||||
- rd.h = op_read(dp++);
|
||||
+ rd.l = op_read(dp++, false);
|
||||
+ rd.h = op_read(dp++, false);
|
||||
regs.pc = rd;
|
||||
}
|
||||
|
||||
@@ -438,8 +438,8 @@ void SMPcore::op_jsr_addr() {
|
||||
|
||||
void SMPcore::op_jst() {
|
||||
dp = 0xffde - ((opcode >> 4) << 1);
|
||||
- rd.l = op_read(dp++);
|
||||
- rd.h = op_read(dp++);
|
||||
+ rd.l = op_read(dp++, false);
|
||||
+ rd.h = op_read(dp++, false);
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
@@ -505,7 +505,7 @@ void SMPcore::op_sta_idpx() {
|
||||
op_io();
|
||||
dp.l = op_readdp(sp++);
|
||||
dp.h = op_readdp(sp++);
|
||||
- op_read(dp);
|
||||
+ op_read(dp, false);
|
||||
op_write(dp, regs.a);
|
||||
}
|
||||
|
||||
@@ -515,7 +515,7 @@ void SMPcore::op_sta_idpy() {
|
||||
dp.h = op_readdp(sp++);
|
||||
op_io();
|
||||
dp += regs.y;
|
||||
- op_read(dp);
|
||||
+ op_read(dp, false);
|
||||
op_write(dp, regs.a);
|
||||
}
|
||||
|
||||
diff --git a/snes/smp/debugger/debugger.cpp b/snes/smp/debugger/debugger.cpp
|
||||
index 9546c11..894fdac 100755
|
||||
--- a/snes/smp/debugger/debugger.cpp
|
||||
+++ b/snes/smp/debugger/debugger.cpp
|
||||
@@ -18,8 +18,8 @@ void SMPDebugger::op_step() {
|
||||
synchronize_cpu();
|
||||
}
|
||||
|
||||
-uint8 SMPDebugger::op_read(uint16 addr) {
|
||||
- uint8 data = SMP::op_read(addr);
|
||||
+uint8 SMPDebugger::op_read(uint16 addr, bool exec) {
|
||||
+ uint8 data = SMP::op_read(addr, exec);
|
||||
usage[addr] |= UsageRead;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Read, addr, data);
|
||||
return data;
|
||||
diff --git a/snes/smp/debugger/debugger.hpp b/snes/smp/debugger/debugger.hpp
|
||||
index d5d28e5..26bc7af 100755
|
||||
--- a/snes/smp/debugger/debugger.hpp
|
||||
+++ b/snes/smp/debugger/debugger.hpp
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
bool opcode_edge;
|
||||
|
||||
void op_step();
|
||||
- uint8 op_read(uint16 addr);
|
||||
+ uint8 op_read(uint16 addr, bool exec);
|
||||
void op_write(uint16 addr, uint8 data);
|
||||
|
||||
SMPDebugger();
|
||||
diff --git a/snes/smp/memory/memory.cpp b/snes/smp/memory/memory.cpp
|
||||
index 391324c..58c1191 100755
|
||||
--- a/snes/smp/memory/memory.cpp
|
||||
+++ b/snes/smp/memory/memory.cpp
|
||||
@@ -19,61 +19,83 @@ void SMP::port_write(uint2 port, uint8 data) {
|
||||
apuram[0xf4 + port] = data;
|
||||
}
|
||||
|
||||
-alwaysinline uint8 SMP::op_busread(uint16 addr) {
|
||||
+alwaysinline uint8 SMP::op_busread(uint16 addr, bool exec) {
|
||||
unsigned result;
|
||||
+ uint8 data;
|
||||
|
||||
switch(addr) {
|
||||
case 0xf0: //TEST -- write-only register
|
||||
- return 0x00;
|
||||
+ data = 0x00;
|
||||
+ break;
|
||||
|
||||
case 0xf1: //CONTROL -- write-only register
|
||||
- return 0x00;
|
||||
+ data = 0x00;
|
||||
+ break;
|
||||
|
||||
case 0xf2: //DSPADDR
|
||||
- return status.dsp_addr;
|
||||
+ data = status.dsp_addr;
|
||||
+ break;
|
||||
|
||||
case 0xf3: //DSPDATA
|
||||
//0x80-0xff are read-only mirrors of 0x00-0x7f
|
||||
- return dsp.read(status.dsp_addr & 0x7f);
|
||||
+ data = dsp.read(status.dsp_addr & 0x7f);
|
||||
+ break;
|
||||
|
||||
case 0xf4: //CPUIO0
|
||||
case 0xf5: //CPUIO1
|
||||
case 0xf6: //CPUIO2
|
||||
case 0xf7: //CPUIO3
|
||||
synchronize_cpu();
|
||||
- return cpu.port_read(addr);
|
||||
+ data = cpu.port_read(addr);
|
||||
+ break;
|
||||
|
||||
case 0xf8: //RAM0
|
||||
- return status.ram00f8;
|
||||
+ data = status.ram00f8;
|
||||
+ break;
|
||||
|
||||
case 0xf9: //RAM1
|
||||
- return status.ram00f9;
|
||||
+ data = status.ram00f9;
|
||||
+ break;
|
||||
|
||||
case 0xfa: //T0TARGET
|
||||
case 0xfb: //T1TARGET
|
||||
case 0xfc: //T2TARGET -- write-only registers
|
||||
- return 0x00;
|
||||
+ data = 0x00;
|
||||
+ break;
|
||||
|
||||
case 0xfd: //T0OUT -- 4-bit counter value
|
||||
result = timer0.stage3_ticks;
|
||||
timer0.stage3_ticks = 0;
|
||||
- return result;
|
||||
+ data = result;
|
||||
+ break;
|
||||
|
||||
case 0xfe: //T1OUT -- 4-bit counter value
|
||||
result = timer1.stage3_ticks;
|
||||
timer1.stage3_ticks = 0;
|
||||
- return result;
|
||||
+ data = result;
|
||||
+ break;
|
||||
|
||||
case 0xff: //T2OUT -- 4-bit counter value
|
||||
result = timer2.stage3_ticks;
|
||||
timer2.stage3_ticks = 0;
|
||||
- return result;
|
||||
+ data = result;
|
||||
+ break;
|
||||
+ default:
|
||||
+ data = ram_read(addr);
|
||||
+ break;
|
||||
}
|
||||
-
|
||||
- return ram_read(addr);
|
||||
+ uint8 flag = exec ? 0x04 : 0x01;
|
||||
+ if(__builtin_expect(debugflags[addr] & flag, 0)) {
|
||||
+ debug_read(16, addr, data, exec);
|
||||
+ }
|
||||
+ return data;
|
||||
}
|
||||
|
||||
alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
|
||||
+ if(__builtin_expect(debugflags[addr] & 0x2, 0)) {
|
||||
+ debug_write(16, addr, data);
|
||||
+ }
|
||||
+
|
||||
switch(addr) {
|
||||
case 0xf0: //TEST
|
||||
if(regs.p.p) break; //writes only valid when P flag is clear
|
||||
@@ -180,9 +202,9 @@ void SMP::op_io() {
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
-uint8 SMP::op_read(uint16 addr) {
|
||||
+uint8 SMP::op_read(uint16 addr, bool exec) {
|
||||
add_clocks(12);
|
||||
- uint8 r = op_busread(addr);
|
||||
+ uint8 r = op_busread(addr, exec);
|
||||
add_clocks(12);
|
||||
cycle_edge();
|
||||
return r;
|
||||
diff --git a/snes/smp/memory/memory.hpp b/snes/smp/memory/memory.hpp
|
||||
index 1a07445..faa28da 100755
|
||||
--- a/snes/smp/memory/memory.hpp
|
||||
+++ b/snes/smp/memory/memory.hpp
|
||||
@@ -1,9 +1,9 @@
|
||||
uint8 ram_read(uint16 addr);
|
||||
void ram_write(uint16 addr, uint8 data);
|
||||
|
||||
-uint8 op_busread(uint16 addr);
|
||||
+uint8 op_busread(uint16 addr, bool exec);
|
||||
void op_buswrite(uint16 addr, uint8 data);
|
||||
|
||||
void op_io();
|
||||
-debugvirtual uint8 op_read(uint16 addr);
|
||||
+debugvirtual uint8 op_read(uint16 addr, bool exec);
|
||||
debugvirtual void op_write(uint16 addr, uint8 data);
|
||||
diff --git a/snes/smp/smp.hpp b/snes/smp/smp.hpp
|
||||
index 6b387cb..6b6ae83 100755
|
||||
--- a/snes/smp/smp.hpp
|
||||
+++ b/snes/smp/smp.hpp
|
||||
@@ -1,6 +1,10 @@
|
||||
struct SMP : public Processor, public SMPcore {
|
||||
static const uint8 iplrom[64];
|
||||
uint8 apuram[64 * 1024];
|
||||
+ uint8 debugflags[64 * 1024];
|
||||
+
|
||||
+ function<void (uint8, unsigned, uint8, bool)> debug_read;
|
||||
+ function<void (uint8, unsigned, uint8)> debug_write;
|
||||
|
||||
enum : bool { Threaded = true };
|
||||
alwaysinline void step(unsigned clocks);
|
||||
diff --git a/snes/snes.hpp b/snes/snes.hpp
|
||||
index 9589db9..27632bf 100755
|
||||
--- a/snes/snes.hpp
|
||||
+++ b/snes/snes.hpp
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef SNES_HPP
|
||||
#define SNES_HPP
|
||||
#define BSNES_SUPPORTS_ADV_BREAKPOINTS
|
||||
+#define BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
|
||||
#define BSNES_SUPPORTS_ALT_TIMINGS
|
||||
|
||||
namespace SNES {
|
||||
--
|
||||
1.9.1
|
||||
|
|
@ -931,6 +931,18 @@ namespace
|
|||
return 0x30000000 + offset;
|
||||
case 12: //BSX flash.
|
||||
return 0x90000000 + offset;
|
||||
#ifdef BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
|
||||
#ifdef BSNES_IS_COMPAT
|
||||
case 13: //VRAM.
|
||||
return 0x00010000 + offset;
|
||||
case 14: //OAM.
|
||||
return 0x00020000 + offset;
|
||||
case 15: //GCRAM.
|
||||
return 0x00021000 + offset;
|
||||
#endif
|
||||
case 16: //APURAM
|
||||
return 0x00000000 + offset;
|
||||
#endif
|
||||
default: //Other, including bus.
|
||||
return 0xFFFFFFFFFFFFFFFFULL;
|
||||
}
|
||||
|
@ -952,6 +964,28 @@ namespace
|
|||
ecore_callbacks->memory_read(0x1000000 + addr, val);
|
||||
}
|
||||
|
||||
void bsnes_debug_read2(uint8_t clazz, unsigned offset, uint8_t val, bool exec)
|
||||
{
|
||||
if(disable_breakpoints) return;
|
||||
uint64_t _addr = translate_class_address(clazz, offset);
|
||||
if(_addr != 0xFFFFFFFFFFFFFFFFULL) {
|
||||
//SMP uses this, so CPU#1.
|
||||
if(exec)
|
||||
ecore_callbacks->memory_execute(_addr, 1);
|
||||
else
|
||||
ecore_callbacks->memory_read(_addr, val);
|
||||
}
|
||||
}
|
||||
|
||||
void bsnes_debug_read3(uint8_t clazz, unsigned offset, uint8_t val)
|
||||
{
|
||||
if(disable_breakpoints) return;
|
||||
uint64_t _addr = translate_class_address(clazz, offset);
|
||||
if(_addr != 0xFFFFFFFFFFFFFFFFULL) {
|
||||
ecore_callbacks->memory_read(_addr, val);
|
||||
}
|
||||
}
|
||||
|
||||
void bsnes_debug_write(uint8_t clazz, unsigned offset, unsigned addr, uint8_t val)
|
||||
{
|
||||
if(disable_breakpoints) return;
|
||||
|
@ -961,6 +995,14 @@ namespace
|
|||
ecore_callbacks->memory_write(0x1000000 + addr, val);
|
||||
}
|
||||
|
||||
void bsnes_debug_write2(uint8_t clazz, unsigned offset, uint8_t val)
|
||||
{
|
||||
if(disable_breakpoints) return;
|
||||
uint64_t _addr = translate_class_address(clazz, offset);
|
||||
if(_addr != 0xFFFFFFFFFFFFFFFFULL)
|
||||
ecore_callbacks->memory_write(_addr, val);
|
||||
}
|
||||
|
||||
void redraw_cover_fbinfo();
|
||||
|
||||
struct _bsnes_core : public core_core
|
||||
|
@ -1103,6 +1145,14 @@ namespace
|
|||
#ifdef BSNES_SUPPORTS_ADV_BREAKPOINTS
|
||||
SNES::bus.debug_read = bsnes_debug_read;
|
||||
SNES::bus.debug_write = bsnes_debug_write;
|
||||
#endif
|
||||
#ifdef BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
|
||||
#ifdef BSNES_IS_COMPAT
|
||||
SNES::ppu.debug_read = bsnes_debug_read3;
|
||||
SNES::ppu.debug_write = bsnes_debug_write2;
|
||||
#endif
|
||||
SNES::smp.debug_read = bsnes_debug_read2;
|
||||
SNES::smp.debug_write = bsnes_debug_write2;
|
||||
#endif
|
||||
basic_init();
|
||||
old = SNES::interface;
|
||||
|
@ -1307,6 +1357,22 @@ again2:
|
|||
auto _addr = recognize_address(addr);
|
||||
if(_addr.first == ADDR_KIND_ALL)
|
||||
SNES::bus.debugFlags(sflags & 7, cflags & 7);
|
||||
#ifdef BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
|
||||
#ifdef BSNES_IS_COMPAT
|
||||
else if(_addr.first == 13) //VRAM.
|
||||
SNES::ppu.vram_debugflags[_addr.second] =
|
||||
SNES::ppu.vram_debugflags[_addr.second] & ~(cflags & 7) | (sflags & 7);
|
||||
else if(_addr.first == 14) //OAM.
|
||||
SNES::ppu.oam_debugflags[_addr.second] =
|
||||
SNES::ppu.oam_debugflags[_addr.second] & ~(cflags & 7) | (sflags & 7);
|
||||
else if(_addr.first == 15) //CGRAM.
|
||||
SNES::ppu.cgram_debugflags[_addr.second] =
|
||||
SNES::ppu.cgram_debugflags[_addr.second] & ~(cflags & 7) | (sflags & 7);
|
||||
#endif
|
||||
else if(_addr.first == 16) //APURAM.
|
||||
SNES::smp.debugflags[_addr.second] =
|
||||
SNES::smp.debugflags[_addr.second] & ~(cflags & 7) | (sflags & 7);
|
||||
#endif
|
||||
else if(_addr.first != ADDR_KIND_NONE && ((sflags | cflags) & 7))
|
||||
SNES::bus.debugFlags(sflags & 7, cflags & 7, _addr.first, _addr.second);
|
||||
#endif
|
||||
|
@ -1316,7 +1382,9 @@ again2:
|
|||
#ifdef BSNES_SUPPORTS_ADV_BREAKPOINTS
|
||||
bool s = false;
|
||||
auto _addr = recognize_address(addr);
|
||||
if(_addr.first == ADDR_KIND_NONE || _addr.first == ADDR_KIND_ALL)
|
||||
//13-16 are VRAM, OAM, CGRAM and APURAM, can't cheat on those (yet).
|
||||
if(_addr.first == ADDR_KIND_NONE || _addr.first == ADDR_KIND_ALL ||
|
||||
(_addr.first >= 13 && _addr.first <= 16))
|
||||
return;
|
||||
unsigned x = 0;
|
||||
while(x < 0x1000000) {
|
||||
|
@ -1349,6 +1417,14 @@ again2:
|
|||
#ifdef BSNES_SUPPORTS_ADV_BREAKPOINTS
|
||||
SNES::bus.clearDebugFlags();
|
||||
SNES::cheat.reset();
|
||||
#ifdef BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
|
||||
#ifdef BSNES_IS_COMPAT
|
||||
memset(SNES::ppu.vram_debugflags, 0, sizeof(SNES::ppu.vram_debugflags));
|
||||
memset(SNES::ppu.oam_debugflags, 0, sizeof(SNES::ppu.oam_debugflags));
|
||||
memset(SNES::ppu.cgram_debugflags, 0, sizeof(SNES::ppu.cgram_debugflags));
|
||||
#endif
|
||||
memset(SNES::smp.debugflags, 0, sizeof(SNES::smp.debugflags));
|
||||
#endif
|
||||
#endif
|
||||
trace_cpu_enable = false;
|
||||
trace_smp_enable = false;
|
||||
|
@ -1658,6 +1734,14 @@ again2:
|
|||
return std::make_pair(2, addr - 0x10000000);
|
||||
if(addr >= 0x007E0000 && addr <= 0x007FFFFF) //WRAM.
|
||||
return std::make_pair(3, addr - 0x007E0000);
|
||||
if(addr >= 0x00010000 && addr <= 0x00020000) //VRAM.
|
||||
return std::make_pair(13, addr - 0x00010000);
|
||||
if(addr >= 0x00020000 && addr <= 0x0002021F) //OAM.
|
||||
return std::make_pair(14, addr - 0x00020000);
|
||||
if(addr >= 0x00021000 && addr <= 0x000211FF) //CGRAM.
|
||||
return std::make_pair(15, addr - 0x00021000);
|
||||
if(addr >= 0x00000000 && addr <= 0x0000FFFF) //APURAM.
|
||||
return std::make_pair(16, addr - 0x00000000);
|
||||
if(internal_rom == &type_sufamiturbo) {
|
||||
if(addr >= 0x90000000 && addr <= 0x9FFFFFFF) //SufamiTurboA Rom.
|
||||
return std::make_pair(8, addr - 0x90000000);
|
||||
|
|
Loading…
Add table
Reference in a new issue