Refactor DMA handling: rename functions for clarity, remove unused header, and optimize memory initialization

This commit is contained in:
scawful
2024-12-30 07:50:06 -05:00
parent f48cd171e1
commit f8f7d361a7
6 changed files with 71 additions and 119 deletions

View File

@@ -2,15 +2,12 @@
#include <cstdint> #include <cstdint>
#include <regex> #include <regex>
#include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "absl/strings/str_cat.h" #include "absl/strings/match.h"
#include "absl/strings/str_split.h"
#include "app/emu/cpu/internal/opcodes.h"
namespace yaze { namespace yaze {
namespace emu { namespace emu {
@@ -443,5 +440,4 @@ class AsmParser {
}; };
} // namespace emu } // namespace emu
} // namespace yaze
} // namespace yaze

View File

@@ -1,11 +1,7 @@
#include "app/emu/memory/dma.h" #include "app/emu/memory/dma.h"
#include <iostream>
namespace yaze { namespace yaze {
namespace emu { namespace emu {
namespace memory {
namespace dma {
static const int bAdrOffsets[8][4] = {{0, 0, 0, 0}, {0, 1, 0, 1}, {0, 0, 0, 0}, static const int bAdrOffsets[8][4] = {{0, 0, 0, 0}, {0, 1, 0, 1}, {0, 0, 0, 0},
{0, 0, 1, 1}, {0, 1, 2, 3}, {0, 1, 0, 1}, {0, 0, 1, 1}, {0, 1, 2, 3}, {0, 1, 0, 1},
@@ -13,7 +9,7 @@ static const int bAdrOffsets[8][4] = {{0, 0, 0, 0}, {0, 1, 0, 1}, {0, 0, 0, 0},
static const int transferLength[8] = {1, 2, 2, 4, 4, 4, 2, 4}; static const int transferLength[8] = {1, 2, 2, 4, 4, 4, 2, 4};
void Reset(MemoryImpl* memory) { void ResetDma(MemoryImpl* memory) {
auto channel = memory->dma_channels(); auto channel = memory->dma_channels();
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
channel[i].b_addr = 0xff; channel[i].b_addr = 0xff;
@@ -40,7 +36,7 @@ void Reset(MemoryImpl* memory) {
memory->set_hdma_run_requested(false); memory->set_hdma_run_requested(false);
} }
uint8_t Read(MemoryImpl* memory, uint16_t adr) { uint8_t ReadDma(MemoryImpl* memory, uint16_t adr) {
auto channel = memory->dma_channels(); auto channel = memory->dma_channels();
uint8_t c = (adr & 0x70) >> 4; uint8_t c = (adr & 0x70) >> 4;
switch (adr & 0xf) { switch (adr & 0xf) {
@@ -93,7 +89,7 @@ uint8_t Read(MemoryImpl* memory, uint16_t adr) {
} }
} }
void Write(MemoryImpl* memory, uint16_t adr, uint8_t val) { void WriteDma(MemoryImpl* memory, uint16_t adr, uint8_t val) {
auto channel = memory->dma_channels(); auto channel = memory->dma_channels();
uint8_t c = (adr & 0x70) >> 4; uint8_t c = (adr & 0x70) >> 4;
switch (adr & 0xf) { switch (adr & 0xf) {
@@ -157,7 +153,7 @@ void Write(MemoryImpl* memory, uint16_t adr, uint8_t val) {
} }
} }
void DoDma(SNES* snes, MemoryImpl* memory, int cpuCycles) { void DoDma(Snes* snes, MemoryImpl* memory, int cpuCycles) {
auto channel = memory->dma_channels(); auto channel = memory->dma_channels();
snes->cpu().set_int_delay(true); snes->cpu().set_int_delay(true);
@@ -191,7 +187,7 @@ void DoDma(SNES* snes, MemoryImpl* memory, int cpuCycles) {
snes->SyncCycles(false, cpuCycles); snes->SyncCycles(false, cpuCycles);
} }
void HandleDma(SNES* snes, MemoryImpl* memory, int cpu_cycles) { void HandleDma(Snes* snes, MemoryImpl* memory, int cpu_cycles) {
// if hdma triggered, do it, except if dmastate indicates dma will be done now // if hdma triggered, do it, except if dmastate indicates dma will be done now
// (it will be done as part of the dma in that case) // (it will be done as part of the dma in that case)
if (memory->hdma_init_requested() && memory->dma_state() != 2) if (memory->hdma_init_requested() && memory->dma_state() != 2)
@@ -209,7 +205,7 @@ void HandleDma(SNES* snes, MemoryImpl* memory, int cpu_cycles) {
} }
} }
void WaitCycle(SNES* snes, MemoryImpl* memory) { void WaitCycle(Snes* snes, MemoryImpl* memory) {
// run hdma if requested, no sync (already sycned due to dma) // run hdma if requested, no sync (already sycned due to dma)
if (memory->hdma_init_requested()) InitHdma(snes, memory, false, 0); if (memory->hdma_init_requested()) InitHdma(snes, memory, false, 0);
if (memory->hdma_run_requested()) DoHdma(snes, memory, false, 0); if (memory->hdma_run_requested()) DoHdma(snes, memory, false, 0);
@@ -217,7 +213,7 @@ void WaitCycle(SNES* snes, MemoryImpl* memory) {
snes->RunCycles(8); snes->RunCycles(8);
} }
void InitHdma(SNES* snes, MemoryImpl* memory, bool do_sync, int cpu_cycles) { void InitHdma(Snes* snes, MemoryImpl* memory, bool do_sync, int cpu_cycles) {
auto channel = memory->dma_channels(); auto channel = memory->dma_channels();
memory->set_hdma_init_requested(false); memory->set_hdma_init_requested(false);
bool hdmaEnabled = false; bool hdmaEnabled = false;
@@ -257,7 +253,7 @@ void InitHdma(SNES* snes, MemoryImpl* memory, bool do_sync, int cpu_cycles) {
if (do_sync) snes->SyncCycles(false, cpu_cycles); if (do_sync) snes->SyncCycles(false, cpu_cycles);
} }
void DoHdma(SNES* snes, MemoryImpl* memory, bool do_sync, int cycles) { void DoHdma(Snes* snes, MemoryImpl* memory, bool do_sync, int cycles) {
auto channel = memory->dma_channels(); auto channel = memory->dma_channels();
memory->set_hdma_run_requested(false); memory->set_hdma_run_requested(false);
bool hdmaActive = false; bool hdmaActive = false;
@@ -332,7 +328,7 @@ void DoHdma(SNES* snes, MemoryImpl* memory, bool do_sync, int cycles) {
if (do_sync) snes->SyncCycles(false, cycles); if (do_sync) snes->SyncCycles(false, cycles);
} }
void TransferByte(SNES* snes, MemoryImpl* memory, uint16_t aAdr, uint8_t aBank, void TransferByte(Snes* snes, MemoryImpl* memory, uint16_t aAdr, uint8_t aBank,
uint8_t bAdr, bool fromB) { uint8_t bAdr, bool fromB) {
// accessing 0x2180 via b-bus while a-bus accesses ram gives open bus // accessing 0x2180 via b-bus while a-bus accesses ram gives open bus
bool validB = bool validB =
@@ -368,8 +364,5 @@ void StartDma(MemoryImpl* memory, uint8_t val, bool hdma) {
} }
} }
} // namespace dma
} // namespace memory
} // namespace emu } // namespace emu
} // namespace yaze
} // namespace yaze

View File

@@ -8,29 +8,24 @@
namespace yaze { namespace yaze {
namespace emu { namespace emu {
namespace memory {
namespace dma {
void Reset(MemoryImpl* memory); void ResetDma(MemoryImpl* memory);
void HandleDma(SNES* snes, MemoryImpl* memory, int cpu_cycles); void HandleDma(Snes* snes, MemoryImpl* memory, int cpu_cycles);
void WaitCycle(SNES* snes, MemoryImpl* memory); void WaitCycle(Snes* snes, MemoryImpl* memory);
void InitHdma(SNES* snes, MemoryImpl* memory, bool do_sync, int cycles); void InitHdma(Snes* snes, MemoryImpl* memory, bool do_sync, int cycles);
void DoHdma(SNES* snes, MemoryImpl* memory, bool do_sync, int cycles); void DoHdma(Snes* snes, MemoryImpl* memory, bool do_sync, int cycles);
void TransferByte(SNES* snes, MemoryImpl* memory, uint16_t aAdr, uint8_t aBank, void TransferByte(Snes* snes, MemoryImpl* memory, uint16_t aAdr, uint8_t aBank,
uint8_t bAdr, bool fromB); uint8_t bAdr, bool fromB);
uint8_t Read(MemoryImpl* memory, uint16_t address); uint8_t ReadDma(MemoryImpl* memory, uint16_t address);
void Write(MemoryImpl* memory, uint16_t address, uint8_t data); void WriteDma(MemoryImpl* memory, uint16_t address, uint8_t data);
void StartDma(MemoryImpl* memory, uint8_t val, bool hdma); void StartDma(MemoryImpl* memory, uint8_t val, bool hdma);
void DoDma(SNES* snes, MemoryImpl* memory, int cycles); void DoDma(Snes* snes, MemoryImpl* memory, int cycles);
} // namespace dma
} // namespace memory
} // namespace emu } // namespace emu
} // namespace yaze } // namespace yaze
#endif // YAZE_APP_EMU_MEMORY_DMA_H #endif // YAZE_APP_EMU_MEMORY_DMA_H

View File

@@ -1,36 +0,0 @@
#ifndef YAZE_APP_EMU_MEMORY_DMA_CHANNEL_H
#define YAZE_APP_EMU_MEMORY_DMA_CHANNEL_H
#include <cstdint>
namespace yaze {
namespace emu {
namespace memory {
typedef struct DmaChannel {
uint8_t b_addr;
uint16_t a_addr;
uint8_t a_bank;
uint16_t size; // also indirect hdma adr
uint8_t ind_bank; // hdma
uint16_t table_addr; // hdma
uint8_t rep_count; // hdma
uint8_t unusedByte;
bool dma_active;
bool hdma_active;
uint8_t mode;
bool fixed;
bool decrement;
bool indirect; // hdma
bool from_b;
bool unusedBit;
bool do_transfer; // hdma
bool terminated; // hdma
} DmaChannel;
} // namespace memory
} // namespace emu
} // namespace yaze
#endif // YAZE_APP_EMU_MEMORY_DMA_CHANNEL_H

View File

@@ -1,15 +1,10 @@
#include "app/emu/memory/memory.h" #include "app/emu/memory/memory.h"
#include <cstdint> #include <cstdint>
#include <iostream>
#include <string>
#include <vector> #include <vector>
#include "imgui/imgui.h"
namespace yaze { namespace yaze {
namespace emu { namespace emu {
namespace memory {
void MemoryImpl::Initialize(const std::vector<uint8_t>& rom_data, void MemoryImpl::Initialize(const std::vector<uint8_t>& rom_data,
bool verbose) { bool verbose) {
@@ -22,13 +17,9 @@ void MemoryImpl::Initialize(const std::vector<uint8_t>& rom_data,
rom_.resize(rom_size_); rom_.resize(rom_size_);
// Copy memory into rom_ // Copy memory into rom_
for (size_t i = 0; i < rom_size_; i++) { std::copy(rom_data.begin(), rom_data.begin() + rom_size_, rom_.begin());
rom_[i] = rom_data[i];
}
ram_.resize(sram_size_); ram_.resize(sram_size_);
for (size_t i = 0; i < sram_size_; i++) { std::fill(ram_.begin(), ram_.end(), 0);
ram_[i] = 0;
}
// Clear memory // Clear memory
memory_.resize(0x1000000); // 16 MB memory_.resize(0x1000000); // 16 MB
@@ -164,7 +155,5 @@ uint32_t MemoryImpl::GetMappedAddress(uint32_t address) const {
return address; // Return the original address if no mapping is defined return address; // Return the original address if no mapping is defined
} }
} // namespace memory
} // namespace emu } // namespace emu
} // namespace yaze
} // namespace yaze

View File

@@ -1,14 +1,11 @@
#ifndef MEM_H #ifndef YAZE_APP_EMU_MEMORY_H
#define MEM_H #define YAZE_APP_EMU_MEMORY_H
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
#include <string>
#include <vector> #include <vector>
#include "app/emu/memory/dma_channel.h"
// LoROM (Mode 20): // LoROM (Mode 20):
// Banks Offset Purpose // Banks Offset Purpose
@@ -28,7 +25,27 @@
namespace yaze { namespace yaze {
namespace emu { namespace emu {
namespace memory {
typedef struct DmaChannel {
uint8_t b_addr;
uint16_t a_addr;
uint8_t a_bank;
uint16_t size; // also indirect hdma adr
uint8_t ind_bank; // hdma
uint16_t table_addr; // hdma
uint8_t rep_count; // hdma
uint8_t unusedByte;
bool dma_active;
bool hdma_active;
uint8_t mode;
bool fixed;
bool decrement;
bool indirect; // hdma
bool from_b;
bool unusedBit;
bool do_transfer; // hdma
bool terminated; // hdma
} DmaChannel;
typedef struct CpuCallbacks { typedef struct CpuCallbacks {
std::function<uint8_t(uint32_t)> read_byte; std::function<uint8_t(uint32_t)> read_byte;
@@ -45,7 +62,7 @@ constexpr uint32_t kRAMSize = 0x20000;
* @brief Memory interface * @brief Memory interface
*/ */
class Memory { class Memory {
public: public:
virtual ~Memory() = default; virtual ~Memory() = default;
virtual uint8_t ReadByte(uint32_t address) const = 0; virtual uint8_t ReadByte(uint32_t address) const = 0;
virtual uint16_t ReadWord(uint32_t address) const = 0; virtual uint16_t ReadWord(uint32_t address) const = 0;
@@ -99,25 +116,25 @@ class Memory {
* *
*/ */
class MemoryImpl : public Memory { class MemoryImpl : public Memory {
public: public:
void Initialize(const std::vector<uint8_t>& romData, bool verbose = false); void Initialize(const std::vector<uint8_t> &romData, bool verbose = false);
uint16_t GetHeaderOffset() { uint16_t GetHeaderOffset() {
uint16_t offset; uint16_t offset;
switch (memory_[(0x00 << 16) + 0xFFD5] & 0x07) { switch (memory_[(0x00 << 16) + 0xFFD5] & 0x07) {
case 0: // LoROM case 0: // LoROM
offset = 0x7FC0; offset = 0x7FC0;
break; break;
case 1: // HiROM case 1: // HiROM
offset = 0xFFC0; offset = 0xFFC0;
break; break;
case 5: // ExHiROM case 5: // ExHiROM
offset = 0x40; offset = 0x40;
break; break;
default: default:
throw std::invalid_argument( throw std::invalid_argument(
"Unable to locate supported ROM mapping mode in the provided ROM " "Unable to locate supported ROM mapping mode in the provided ROM "
"file. Please try another ROM file."); "file. Please try another ROM file.");
} }
return offset; return offset;
@@ -220,7 +237,7 @@ class MemoryImpl : public Memory {
// Stack Pointer access. // Stack Pointer access.
uint16_t SP() const override { return SP_; } uint16_t SP() const override { return SP_; }
auto mutable_sp() -> uint16_t& { return SP_; } auto mutable_sp() -> uint16_t & { return SP_; }
void SetSP(uint16_t value) override { SP_ = value; } void SetSP(uint16_t value) override { SP_ = value; }
void ClearMemory() override { std::fill(memory_.begin(), memory_.end(), 0); } void ClearMemory() override { std::fill(memory_.begin(), memory_.end(), 0); }
@@ -260,15 +277,15 @@ class MemoryImpl : public Memory {
auto v_pos() const -> uint16_t override { return v_pos_; } auto v_pos() const -> uint16_t override { return v_pos_; }
auto pal_timing() const -> bool override { return pal_timing_; } auto pal_timing() const -> bool override { return pal_timing_; }
auto dma_state() -> uint8_t& { return dma_state_; } auto dma_state() -> uint8_t & { return dma_state_; }
void set_dma_state(uint8_t value) { dma_state_ = value; } void set_dma_state(uint8_t value) { dma_state_ = value; }
auto dma_channels() -> DmaChannel* { return channel; } auto dma_channels() -> DmaChannel * { return channel; }
// Define memory regions // Define memory regions
std::vector<uint8_t> rom_; std::vector<uint8_t> rom_;
std::vector<uint8_t> ram_; std::vector<uint8_t> ram_;
private: private:
uint32_t GetMappedAddress(uint32_t address) const; uint32_t GetMappedAddress(uint32_t address) const;
bool verbose_ = false; bool verbose_ = false;
@@ -306,9 +323,7 @@ class MemoryImpl : public Memory {
std::vector<uint8_t> memory_; std::vector<uint8_t> memory_;
}; };
} // namespace memory } // namespace emu
} // namespace emu } // namespace yaze
} // namespace yaze #endif // YAZE_APP_EMU_MEMORY_H
#endif // MEM_H