288 lines
8.6 KiB
Diff
288 lines
8.6 KiB
Diff
From 5bc96b8aeea26729ef4399c2d8d5e562894616e1 Mon Sep 17 00:00:00 2001
|
|
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
|
Date: Tue, 20 Jan 2015 10:04:58 +0200
|
|
Subject: [PATCH 22/27] Support DMA tracing
|
|
|
|
---
|
|
snes/alt/ppu-compatibility/mmio/mmio.cpp | 18 +++++++
|
|
snes/alt/ppu-compatibility/ppu.cpp | 1 +
|
|
snes/alt/ppu-compatibility/ppu.hpp | 4 ++
|
|
snes/cpu/cpu.cpp | 1 +
|
|
snes/cpu/cpu.hpp | 1 +
|
|
snes/cpu/dma/dma.cpp | 84 ++++++++++++++++++++++++++++++++
|
|
snes/cpu/dma/dma.hpp | 5 ++
|
|
snes/ppu/mmio/mmio.cpp | 18 +++++++
|
|
snes/ppu/ppu.cpp | 1 +
|
|
snes/ppu/ppu.hpp | 3 ++
|
|
snes/snes.hpp | 1 +
|
|
11 files changed, 137 insertions(+)
|
|
|
|
diff --git a/snes/alt/ppu-compatibility/mmio/mmio.cpp b/snes/alt/ppu-compatibility/mmio/mmio.cpp
|
|
index aedb67c1..0a269cc0 100755
|
|
--- a/snes/alt/ppu-compatibility/mmio/mmio.cpp
|
|
+++ b/snes/alt/ppu-compatibility/mmio/mmio.cpp
|
|
@@ -1,5 +1,23 @@
|
|
#ifdef PPU_CPP
|
|
|
|
+size_t PPU::get_dma_oam_subaddr(char* buf)
|
|
+{
|
|
+ return sprintf(buf, "[%03x]", regs.oam_addr);
|
|
+}
|
|
+
|
|
+size_t PPU::get_dma_cgram_subaddr(char* buf)
|
|
+{
|
|
+ return sprintf(buf, "[%02x%c]", regs.cgram_addr >> 1, (regs.cgram_addr & 1) ?
|
|
+ 'H' : 'L');
|
|
+}
|
|
+
|
|
+size_t PPU::get_dma_vram_subaddr(char* buf)
|
|
+{
|
|
+ return sprintf(buf, "[%04x map%d inc %d on %s]", regs.vram_addr << 1,
|
|
+ regs.vram_mapping, 2 * regs.vram_incsize, regs.vram_incmode ? "high" :
|
|
+ "low");
|
|
+}
|
|
+
|
|
//INIDISP
|
|
void PPU::mmio_w2100(uint8 value) {
|
|
if(regs.display_disabled == true && cpu.vcounter() == (!overscan() ? 225 : 240)) {
|
|
diff --git a/snes/alt/ppu-compatibility/ppu.cpp b/snes/alt/ppu-compatibility/ppu.cpp
|
|
index 122b1430..ac886edc 100755
|
|
--- a/snes/alt/ppu-compatibility/ppu.cpp
|
|
+++ b/snes/alt/ppu-compatibility/ppu.cpp
|
|
@@ -1,4 +1,5 @@
|
|
#include <snes/snes.hpp>
|
|
+#include <cstdio>
|
|
|
|
#define PPU_CPP
|
|
namespace SNES {
|
|
diff --git a/snes/alt/ppu-compatibility/ppu.hpp b/snes/alt/ppu-compatibility/ppu.hpp
|
|
index 4adac4c4..b0eabf7c 100755
|
|
--- a/snes/alt/ppu-compatibility/ppu.hpp
|
|
+++ b/snes/alt/ppu-compatibility/ppu.hpp
|
|
@@ -14,6 +14,10 @@ public:
|
|
alwaysinline void step(unsigned clocks);
|
|
alwaysinline void synchronize_cpu();
|
|
|
|
+ size_t get_dma_oam_subaddr(char* buf);
|
|
+ size_t get_dma_cgram_subaddr(char* buf);
|
|
+ size_t get_dma_vram_subaddr(char* buf);
|
|
+
|
|
#include "memory/memory.hpp"
|
|
#include "mmio/mmio.hpp"
|
|
#include "render/render.hpp"
|
|
diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
|
|
index 39da6b16..ce112afa 100755
|
|
--- a/snes/cpu/cpu.cpp
|
|
+++ b/snes/cpu/cpu.cpp
|
|
@@ -1,4 +1,5 @@
|
|
#include <snes/snes.hpp>
|
|
+#include <cstdio>
|
|
|
|
#define CPU_CPP
|
|
namespace SNES {
|
|
diff --git a/snes/cpu/cpu.hpp b/snes/cpu/cpu.hpp
|
|
index 49445773..fd665b1f 100755
|
|
--- a/snes/cpu/cpu.hpp
|
|
+++ b/snes/cpu/cpu.hpp
|
|
@@ -26,6 +26,7 @@ struct CPU : public Processor, public CPUcore, public PPUcounter {
|
|
~CPU();
|
|
|
|
bool controller_flag;
|
|
+ function<void(const char*)> dma_trace_fn;
|
|
private:
|
|
#include "dma/dma.hpp"
|
|
#include "memory/memory.hpp"
|
|
diff --git a/snes/cpu/dma/dma.cpp b/snes/cpu/dma/dma.cpp
|
|
index 0a00bfea..8f7be263 100755
|
|
--- a/snes/cpu/dma/dma.cpp
|
|
+++ b/snes/cpu/dma/dma.cpp
|
|
@@ -144,6 +144,7 @@ void CPU::dma_run() {
|
|
|
|
for(unsigned i = 0; i < 8; i++) {
|
|
if(channel[i].dma_enabled == false) continue;
|
|
+ dma_trace_start(i);
|
|
|
|
unsigned index = 0;
|
|
do {
|
|
@@ -155,6 +156,7 @@ void CPU::dma_run() {
|
|
dma_write(false);
|
|
dma_edge();
|
|
|
|
+ dma_trace_end(i);
|
|
channel[i].dma_enabled = false;
|
|
}
|
|
|
|
@@ -202,6 +204,7 @@ void CPU::hdma_run() {
|
|
channel[i].dma_enabled = false; //HDMA run during DMA will stop DMA mid-transfer
|
|
|
|
if(channel[i].hdma_do_transfer) {
|
|
+ dma_trace_hdma(i);
|
|
static const unsigned transfer_length[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
|
|
unsigned length = transfer_length[channel[i].transfer_mode];
|
|
for(unsigned index = 0; index < length; index++) {
|
|
@@ -286,4 +289,85 @@ void CPU::dma_reset() {
|
|
pipe.data = 0;
|
|
}
|
|
|
|
+size_t CPU::dma_trace_subaddr(char* buf, uint8 b_addr)
|
|
+{
|
|
+ if(b_addr == 0x04 || b_addr == 0x38) {
|
|
+ return ppu.get_dma_oam_subaddr(buf);
|
|
+ }
|
|
+ if(b_addr == 0x22 || b_addr == 0x3B) {
|
|
+ return ppu.get_dma_cgram_subaddr(buf);
|
|
+ }
|
|
+ if(b_addr == 0x18 || b_addr == 0x19 || b_addr == 0x39 || b_addr == 0x3A) {
|
|
+ return ppu.get_dma_vram_subaddr(buf);
|
|
+ }
|
|
+ if(b_addr == 0x80) {
|
|
+ return sprintf(buf, "[%06x]", 0x7e0000 | status.wram_addr);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void CPU::dma_trace_start(unsigned i)
|
|
+{
|
|
+ if(!dma_trace_fn) return;
|
|
+ char buf[512];
|
|
+ size_t ptr = 0;
|
|
+ unsigned bytes = channel[i].transfer_size;
|
|
+ if(!bytes) bytes = 0x10000;
|
|
+ ptr += sprintf(buf + ptr, "-- DMA%i %d(%x) bytes ", i, bytes, bytes);
|
|
+ if(channel[i].direction) {
|
|
+ //B->A
|
|
+ ptr += sprintf(buf + ptr, "%02x", channel[i].dest_addr);
|
|
+ ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
|
|
+ ptr += sprintf(buf + ptr, "-> %02x%04x", channel[i].source_bank,
|
|
+ channel[i].source_addr);
|
|
+ } else {
|
|
+ //A->B
|
|
+ ptr += sprintf(buf + ptr, "%02x%04x -> %02x", channel[i].source_bank,
|
|
+ channel[i].source_addr, channel[i].dest_addr);
|
|
+ ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
|
|
+ }
|
|
+ if(channel[i].fixed_transfer)
|
|
+ ptr += sprintf(buf + ptr, " fixed");
|
|
+ else if(channel[i].reverse_transfer)
|
|
+ ptr += sprintf(buf + ptr, " decrement");
|
|
+ else
|
|
+ ptr += sprintf(buf + ptr, " incrment");
|
|
+ ptr += sprintf(buf + ptr, " mode%d --", channel[i].transfer_mode);
|
|
+ dma_trace_fn(buf);
|
|
+}
|
|
+
|
|
+void CPU::dma_trace_end(unsigned i)
|
|
+{
|
|
+ if(!dma_trace_fn) return;
|
|
+ if(!channel[i].transfer_size) return; //No message for complete DMA.
|
|
+ char buf[512];
|
|
+ size_t ptr = 0;
|
|
+ sprintf(buf, "-- DMA%i aborted with %d(0x%x) bytes remaining --", i,
|
|
+ (int)channel[i].transfer_size, (unsigned)channel[i].transfer_size);
|
|
+ dma_trace_fn(buf);
|
|
+}
|
|
+
|
|
+void CPU::dma_trace_hdma(unsigned i)
|
|
+{
|
|
+ if(!dma_trace_fn) return;
|
|
+ char buf[512];
|
|
+ size_t ptr = 0;
|
|
+ unsigned addr = channel[i].indirect ?
|
|
+ (channel[i].indirect_bank << 16) | (channel[i].indirect_addr) :
|
|
+ (channel[i].source_bank << 16) | (channel[i].hdma_addr);
|
|
+ ptr += sprintf(buf + ptr, "-- HDMA%i %06x -> %02x", i, addr,
|
|
+ channel[i].dest_addr);
|
|
+ ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
|
|
+ if(channel[i].indirect)
|
|
+ ptr += sprintf(buf + ptr, " indirect");
|
|
+ if(channel[i].fixed_transfer)
|
|
+ ptr += sprintf(buf + ptr, " fixed");
|
|
+ else if(channel[i].reverse_transfer)
|
|
+ ptr += sprintf(buf + ptr, " decrement");
|
|
+ else
|
|
+ ptr += sprintf(buf + ptr, " incrment");
|
|
+ ptr += sprintf(buf + ptr, " mode%d --", channel[i].transfer_mode);
|
|
+ dma_trace_fn(buf);
|
|
+}
|
|
+
|
|
#endif
|
|
diff --git a/snes/cpu/dma/dma.hpp b/snes/cpu/dma/dma.hpp
|
|
index 33755bde..8740bb3a 100755
|
|
--- a/snes/cpu/dma/dma.hpp
|
|
+++ b/snes/cpu/dma/dma.hpp
|
|
@@ -77,3 +77,8 @@ void hdma_init();
|
|
|
|
void dma_power();
|
|
void dma_reset();
|
|
+
|
|
+size_t dma_trace_subaddr(char* buf, uint8 b_addr);
|
|
+void dma_trace_start(unsigned i);
|
|
+void dma_trace_end(unsigned i);
|
|
+void dma_trace_hdma(unsigned i);
|
|
diff --git a/snes/ppu/mmio/mmio.cpp b/snes/ppu/mmio/mmio.cpp
|
|
index 302f74f8..4a4fb9ce 100755
|
|
--- a/snes/ppu/mmio/mmio.cpp
|
|
+++ b/snes/ppu/mmio/mmio.cpp
|
|
@@ -1,5 +1,23 @@
|
|
#ifdef PPU_CPP
|
|
|
|
+size_t PPU::get_dma_oam_subaddr(char* buf)
|
|
+{
|
|
+ return sprintf(buf, "[%03x]", regs.oam_addr);
|
|
+}
|
|
+
|
|
+size_t PPU::get_dma_cgram_subaddr(char* buf)
|
|
+{
|
|
+ return sprintf(buf, "[%02x%c]", regs.cgram_addr >> 1, (regs.cgram_addr & 1) ?
|
|
+ 'H' : 'L');
|
|
+}
|
|
+
|
|
+size_t PPU::get_dma_vram_subaddr(char* buf)
|
|
+{
|
|
+ return sprintf(buf, "[%04x map%d inc %d on %s]", regs.vram_addr << 1,
|
|
+ regs.vram_mapping, 2 * regs.vram_incsize, regs.vram_incmode ? "high" :
|
|
+ "low");
|
|
+}
|
|
+
|
|
bool PPU::interlace() const {
|
|
return display.interlace;
|
|
}
|
|
diff --git a/snes/ppu/ppu.cpp b/snes/ppu/ppu.cpp
|
|
index 13e231cf..58742098 100755
|
|
--- a/snes/ppu/ppu.cpp
|
|
+++ b/snes/ppu/ppu.cpp
|
|
@@ -1,4 +1,5 @@
|
|
#include <snes/snes.hpp>
|
|
+#include <cstdio>
|
|
|
|
#define PPU_CPP
|
|
namespace SNES {
|
|
diff --git a/snes/ppu/ppu.hpp b/snes/ppu/ppu.hpp
|
|
index fdba113c..0addb775 100755
|
|
--- a/snes/ppu/ppu.hpp
|
|
+++ b/snes/ppu/ppu.hpp
|
|
@@ -21,6 +21,9 @@ struct PPU : public Processor, public PPUcounter {
|
|
PPU();
|
|
~PPU();
|
|
|
|
+ size_t get_dma_oam_subaddr(char* buf);
|
|
+ size_t get_dma_cgram_subaddr(char* buf);
|
|
+ size_t get_dma_vram_subaddr(char* buf);
|
|
private:
|
|
uint32 *surface;
|
|
uint32 *output;
|
|
diff --git a/snes/snes.hpp b/snes/snes.hpp
|
|
index 3bdca7e5..7c48ebb3 100755
|
|
--- a/snes/snes.hpp
|
|
+++ b/snes/snes.hpp
|
|
@@ -4,6 +4,7 @@
|
|
#define BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
|
|
#define BSNES_SUPPORTS_ALT_TIMINGS
|
|
#define BSNES_SUPPORTS_TRACE_SA1
|
|
+#define BSNES_SUPPORTS_DMA_TRACE
|
|
|
|
namespace SNES {
|
|
namespace Info {
|
|
--
|
|
2.15.0.rc1
|
|
|