1 From 5bc96b8aeea26729ef4399c2d8d5e562894616e1 Mon Sep 17 00:00:00 2001
2 From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
3 Date: Tue, 20 Jan 2015 10:04:58 +0200
4 Subject: [PATCH 22/26] Support DMA tracing
7 snes/alt/ppu-compatibility/mmio/mmio.cpp | 18 +++++++
8 snes/alt/ppu-compatibility/ppu.cpp | 1 +
9 snes/alt/ppu-compatibility/ppu.hpp | 4 ++
10 snes/cpu/cpu.cpp | 1 +
11 snes/cpu/cpu.hpp | 1 +
12 snes/cpu/dma/dma.cpp | 84 ++++++++++++++++++++++++++++++++
13 snes/cpu/dma/dma.hpp | 5 ++
14 snes/ppu/mmio/mmio.cpp | 18 +++++++
15 snes/ppu/ppu.cpp | 1 +
16 snes/ppu/ppu.hpp | 3 ++
18 11 files changed, 137 insertions(+)
20 diff --git a/snes/alt/ppu-compatibility/mmio/mmio.cpp b/snes/alt/ppu-compatibility/mmio/mmio.cpp
21 index aedb67c..0a269cc 100755
22 --- a/snes/alt/ppu-compatibility/mmio/mmio.cpp
23 +++ b/snes/alt/ppu-compatibility/mmio/mmio.cpp
27 +size_t PPU::get_dma_oam_subaddr(char* buf)
29 + return sprintf(buf, "[%03x]", regs.oam_addr);
32 +size_t PPU::get_dma_cgram_subaddr(char* buf)
34 + return sprintf(buf, "[%02x%c]", regs.cgram_addr >> 1, (regs.cgram_addr & 1) ?
38 +size_t PPU::get_dma_vram_subaddr(char* buf)
40 + return sprintf(buf, "[%04x map%d inc %d on %s]", regs.vram_addr << 1,
41 + regs.vram_mapping, 2 * regs.vram_incsize, regs.vram_incmode ? "high" :
46 void PPU::mmio_w2100(uint8 value) {
47 if(regs.display_disabled == true && cpu.vcounter() == (!overscan() ? 225 : 240)) {
48 diff --git a/snes/alt/ppu-compatibility/ppu.cpp b/snes/alt/ppu-compatibility/ppu.cpp
49 index 122b143..ac886ed 100755
50 --- a/snes/alt/ppu-compatibility/ppu.cpp
51 +++ b/snes/alt/ppu-compatibility/ppu.cpp
53 #include <snes/snes.hpp>
58 diff --git a/snes/alt/ppu-compatibility/ppu.hpp b/snes/alt/ppu-compatibility/ppu.hpp
59 index 4adac4c..b0eabf7 100755
60 --- a/snes/alt/ppu-compatibility/ppu.hpp
61 +++ b/snes/alt/ppu-compatibility/ppu.hpp
62 @@ -14,6 +14,10 @@ public:
63 alwaysinline void step(unsigned clocks);
64 alwaysinline void synchronize_cpu();
66 + size_t get_dma_oam_subaddr(char* buf);
67 + size_t get_dma_cgram_subaddr(char* buf);
68 + size_t get_dma_vram_subaddr(char* buf);
70 #include "memory/memory.hpp"
71 #include "mmio/mmio.hpp"
72 #include "render/render.hpp"
73 diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
74 index 39da6b1..ce112af 100755
75 --- a/snes/cpu/cpu.cpp
76 +++ b/snes/cpu/cpu.cpp
78 #include <snes/snes.hpp>
83 diff --git a/snes/cpu/cpu.hpp b/snes/cpu/cpu.hpp
84 index 4944577..fd665b1 100755
85 --- a/snes/cpu/cpu.hpp
86 +++ b/snes/cpu/cpu.hpp
87 @@ -26,6 +26,7 @@ struct CPU : public Processor, public CPUcore, public PPUcounter {
91 + function<void(const char*)> dma_trace_fn;
93 #include "dma/dma.hpp"
94 #include "memory/memory.hpp"
95 diff --git a/snes/cpu/dma/dma.cpp b/snes/cpu/dma/dma.cpp
96 index 0a00bfe..8f7be26 100755
97 --- a/snes/cpu/dma/dma.cpp
98 +++ b/snes/cpu/dma/dma.cpp
99 @@ -144,6 +144,7 @@ void CPU::dma_run() {
101 for(unsigned i = 0; i < 8; i++) {
102 if(channel[i].dma_enabled == false) continue;
103 + dma_trace_start(i);
107 @@ -155,6 +156,7 @@ void CPU::dma_run() {
112 channel[i].dma_enabled = false;
115 @@ -202,6 +204,7 @@ void CPU::hdma_run() {
116 channel[i].dma_enabled = false; //HDMA run during DMA will stop DMA mid-transfer
118 if(channel[i].hdma_do_transfer) {
120 static const unsigned transfer_length[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
121 unsigned length = transfer_length[channel[i].transfer_mode];
122 for(unsigned index = 0; index < length; index++) {
123 @@ -286,4 +289,85 @@ void CPU::dma_reset() {
127 +size_t CPU::dma_trace_subaddr(char* buf, uint8 b_addr)
129 + if(b_addr == 0x04 || b_addr == 0x38) {
130 + return ppu.get_dma_oam_subaddr(buf);
132 + if(b_addr == 0x22 || b_addr == 0x3B) {
133 + return ppu.get_dma_cgram_subaddr(buf);
135 + if(b_addr == 0x18 || b_addr == 0x19 || b_addr == 0x39 || b_addr == 0x3A) {
136 + return ppu.get_dma_vram_subaddr(buf);
138 + if(b_addr == 0x80) {
139 + return sprintf(buf, "[%06x]", 0x7e0000 | status.wram_addr);
144 +void CPU::dma_trace_start(unsigned i)
146 + if(!dma_trace_fn) return;
149 + unsigned bytes = channel[i].transfer_size;
150 + if(!bytes) bytes = 0x10000;
151 + ptr += sprintf(buf + ptr, "-- DMA%i %d(%x) bytes ", i, bytes, bytes);
152 + if(channel[i].direction) {
154 + ptr += sprintf(buf + ptr, "%02x", channel[i].dest_addr);
155 + ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
156 + ptr += sprintf(buf + ptr, "-> %02x%04x", channel[i].source_bank,
157 + channel[i].source_addr);
160 + ptr += sprintf(buf + ptr, "%02x%04x -> %02x", channel[i].source_bank,
161 + channel[i].source_addr, channel[i].dest_addr);
162 + ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
164 + if(channel[i].fixed_transfer)
165 + ptr += sprintf(buf + ptr, " fixed");
166 + else if(channel[i].reverse_transfer)
167 + ptr += sprintf(buf + ptr, " decrement");
169 + ptr += sprintf(buf + ptr, " incrment");
170 + ptr += sprintf(buf + ptr, " mode%d --", channel[i].transfer_mode);
174 +void CPU::dma_trace_end(unsigned i)
176 + if(!dma_trace_fn) return;
177 + if(!channel[i].transfer_size) return; //No message for complete DMA.
180 + sprintf(buf, "-- DMA%i aborted with %d(0x%x) bytes remaining --", i,
181 + (int)channel[i].transfer_size, (unsigned)channel[i].transfer_size);
185 +void CPU::dma_trace_hdma(unsigned i)
187 + if(!dma_trace_fn) return;
190 + unsigned addr = channel[i].indirect ?
191 + (channel[i].indirect_bank << 16) | (channel[i].indirect_addr) :
192 + (channel[i].source_bank << 16) | (channel[i].hdma_addr);
193 + ptr += sprintf(buf + ptr, "-- HDMA%i %06x -> %02x", i, addr,
194 + channel[i].dest_addr);
195 + ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
196 + if(channel[i].indirect)
197 + ptr += sprintf(buf + ptr, " indirect");
198 + if(channel[i].fixed_transfer)
199 + ptr += sprintf(buf + ptr, " fixed");
200 + else if(channel[i].reverse_transfer)
201 + ptr += sprintf(buf + ptr, " decrement");
203 + ptr += sprintf(buf + ptr, " incrment");
204 + ptr += sprintf(buf + ptr, " mode%d --", channel[i].transfer_mode);
209 diff --git a/snes/cpu/dma/dma.hpp b/snes/cpu/dma/dma.hpp
210 index 33755bd..8740bb3 100755
211 --- a/snes/cpu/dma/dma.hpp
212 +++ b/snes/cpu/dma/dma.hpp
213 @@ -77,3 +77,8 @@ void hdma_init();
218 +size_t dma_trace_subaddr(char* buf, uint8 b_addr);
219 +void dma_trace_start(unsigned i);
220 +void dma_trace_end(unsigned i);
221 +void dma_trace_hdma(unsigned i);
222 diff --git a/snes/ppu/mmio/mmio.cpp b/snes/ppu/mmio/mmio.cpp
223 index 302f74f..4a4fb9c 100755
224 --- a/snes/ppu/mmio/mmio.cpp
225 +++ b/snes/ppu/mmio/mmio.cpp
229 +size_t PPU::get_dma_oam_subaddr(char* buf)
231 + return sprintf(buf, "[%03x]", regs.oam_addr);
234 +size_t PPU::get_dma_cgram_subaddr(char* buf)
236 + return sprintf(buf, "[%02x%c]", regs.cgram_addr >> 1, (regs.cgram_addr & 1) ?
240 +size_t PPU::get_dma_vram_subaddr(char* buf)
242 + return sprintf(buf, "[%04x map%d inc %d on %s]", regs.vram_addr << 1,
243 + regs.vram_mapping, 2 * regs.vram_incsize, regs.vram_incmode ? "high" :
247 bool PPU::interlace() const {
248 return display.interlace;
250 diff --git a/snes/ppu/ppu.cpp b/snes/ppu/ppu.cpp
251 index 13e231c..5874209 100755
252 --- a/snes/ppu/ppu.cpp
253 +++ b/snes/ppu/ppu.cpp
255 #include <snes/snes.hpp>
260 diff --git a/snes/ppu/ppu.hpp b/snes/ppu/ppu.hpp
261 index fdba113..0addb77 100755
262 --- a/snes/ppu/ppu.hpp
263 +++ b/snes/ppu/ppu.hpp
264 @@ -21,6 +21,9 @@ struct PPU : public Processor, public PPUcounter {
268 + size_t get_dma_oam_subaddr(char* buf);
269 + size_t get_dma_cgram_subaddr(char* buf);
270 + size_t get_dma_vram_subaddr(char* buf);
274 diff --git a/snes/snes.hpp b/snes/snes.hpp
275 index 3bdca7e..7c48ebb 100755
279 #define BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
280 #define BSNES_SUPPORTS_ALT_TIMINGS
281 #define BSNES_SUPPORTS_TRACE_SA1
282 +#define BSNES_SUPPORTS_DMA_TRACE