Don't try to enter loadstate with loadstate already in progress
[lsnes.git] / bsnes-patches / v085 / 0022-Support-DMA-tracing.patch
blob818055fac5874050900342b5948aa23c5ca5211e
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
6 ---
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 ++
17 snes/snes.hpp | 1 +
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
24 @@ -1,5 +1,23 @@
25 #ifdef PPU_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) ?
35 + 'H' : 'L');
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" :
42 + "low");
45 //INIDISP
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
52 @@ -1,4 +1,5 @@
53 #include <snes/snes.hpp>
54 +#include <cstdio>
56 #define PPU_CPP
57 namespace SNES {
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
77 @@ -1,4 +1,5 @@
78 #include <snes/snes.hpp>
79 +#include <cstdio>
81 #define CPU_CPP
82 namespace SNES {
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 {
88 ~CPU();
90 bool controller_flag;
91 + function<void(const char*)> dma_trace_fn;
92 private:
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);
105 unsigned index = 0;
106 do {
107 @@ -155,6 +156,7 @@ void CPU::dma_run() {
108 dma_write(false);
109 dma_edge();
111 + dma_trace_end(i);
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) {
119 + dma_trace_hdma(i);
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() {
124 pipe.data = 0;
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);
141 + return 0;
144 +void CPU::dma_trace_start(unsigned i)
146 + if(!dma_trace_fn) return;
147 + char buf[512];
148 + size_t ptr = 0;
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) {
153 + //B->A
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);
158 + } else {
159 + //A->B
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");
168 + else
169 + ptr += sprintf(buf + ptr, " incrment");
170 + ptr += sprintf(buf + ptr, " mode%d --", channel[i].transfer_mode);
171 + dma_trace_fn(buf);
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.
178 + char buf[512];
179 + size_t ptr = 0;
180 + sprintf(buf, "-- DMA%i aborted with %d(0x%x) bytes remaining --", i,
181 + (int)channel[i].transfer_size, (unsigned)channel[i].transfer_size);
182 + dma_trace_fn(buf);
185 +void CPU::dma_trace_hdma(unsigned i)
187 + if(!dma_trace_fn) return;
188 + char buf[512];
189 + size_t ptr = 0;
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");
202 + else
203 + ptr += sprintf(buf + ptr, " incrment");
204 + ptr += sprintf(buf + ptr, " mode%d --", channel[i].transfer_mode);
205 + dma_trace_fn(buf);
208 #endif
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();
215 void dma_power();
216 void dma_reset();
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
226 @@ -1,5 +1,23 @@
227 #ifdef PPU_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) ?
237 + 'H' : 'L');
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" :
244 + "low");
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
254 @@ -1,4 +1,5 @@
255 #include <snes/snes.hpp>
256 +#include <cstdio>
258 #define PPU_CPP
259 namespace SNES {
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 {
265 PPU();
266 ~PPU();
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);
271 private:
272 uint32 *surface;
273 uint32 *output;
274 diff --git a/snes/snes.hpp b/snes/snes.hpp
275 index 3bdca7e..7c48ebb 100755
276 --- a/snes/snes.hpp
277 +++ b/snes/snes.hpp
278 @@ -4,6 +4,7 @@
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
284 namespace SNES {
285 namespace Info {
287 2.8.1