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

View File

@@ -1,11 +1,7 @@
#include "app/emu/memory/dma.h"
#include <iostream>
namespace yaze {
namespace emu {
namespace memory {
namespace dma {
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},
@@ -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};
void Reset(MemoryImpl* memory) {
void ResetDma(MemoryImpl* memory) {
auto channel = memory->dma_channels();
for (int i = 0; i < 8; i++) {
channel[i].b_addr = 0xff;
@@ -40,7 +36,7 @@ void Reset(MemoryImpl* memory) {
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();
uint8_t c = (adr & 0x70) >> 4;
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();
uint8_t c = (adr & 0x70) >> 4;
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();
snes->cpu().set_int_delay(true);
@@ -191,7 +187,7 @@ void DoDma(SNES* snes, MemoryImpl* memory, int 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
// (it will be done as part of the dma in that case)
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)
if (memory->hdma_init_requested()) InitHdma(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);
}
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();
memory->set_hdma_init_requested(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);
}
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();
memory->set_hdma_run_requested(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);
}
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) {
// accessing 0x2180 via b-bus while a-bus accesses ram gives open bus
bool validB =
@@ -368,8 +364,5 @@ void StartDma(MemoryImpl* memory, uint8_t val, bool hdma) {
}
}
} // namespace dma
} // namespace memory
} // namespace emu
} // namespace yaze
} // namespace yaze

View File

@@ -8,29 +8,24 @@
namespace yaze {
namespace emu {
namespace memory {
namespace dma {
void Reset(MemoryImpl* memory);
void HandleDma(SNES* snes, MemoryImpl* memory, int cpu_cycles);
void ResetDma(MemoryImpl* memory);
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 DoHdma(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 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 Read(MemoryImpl* memory, uint16_t address);
void Write(MemoryImpl* memory, uint16_t address, uint8_t data);
uint8_t ReadDma(MemoryImpl* memory, uint16_t address);
void WriteDma(MemoryImpl* memory, uint16_t address, uint8_t data);
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 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 <cstdint>
#include <iostream>
#include <string>
#include <vector>
#include "imgui/imgui.h"
namespace yaze {
namespace emu {
namespace memory {
void MemoryImpl::Initialize(const std::vector<uint8_t>& rom_data,
bool verbose) {
@@ -22,13 +17,9 @@ void MemoryImpl::Initialize(const std::vector<uint8_t>& rom_data,
rom_.resize(rom_size_);
// Copy memory into rom_
for (size_t i = 0; i < rom_size_; i++) {
rom_[i] = rom_data[i];
}
std::copy(rom_data.begin(), rom_data.begin() + rom_size_, rom_.begin());
ram_.resize(sram_size_);
for (size_t i = 0; i < sram_size_; i++) {
ram_[i] = 0;
}
std::fill(ram_.begin(), ram_.end(), 0);
// Clear memory
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
}
} // namespace memory
} // namespace emu
} // namespace yaze
} // namespace yaze

View File

@@ -1,14 +1,11 @@
#ifndef MEM_H
#define MEM_H
#ifndef YAZE_APP_EMU_MEMORY_H
#define YAZE_APP_EMU_MEMORY_H
#include <cstdint>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include "app/emu/memory/dma_channel.h"
// LoROM (Mode 20):
// Banks Offset Purpose
@@ -28,7 +25,27 @@
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;
typedef struct CpuCallbacks {
std::function<uint8_t(uint32_t)> read_byte;
@@ -45,7 +62,7 @@ constexpr uint32_t kRAMSize = 0x20000;
* @brief Memory interface
*/
class Memory {
public:
public:
virtual ~Memory() = default;
virtual uint8_t ReadByte(uint32_t address) const = 0;
virtual uint16_t ReadWord(uint32_t address) const = 0;
@@ -99,25 +116,25 @@ class Memory {
*
*/
class MemoryImpl : public Memory {
public:
void Initialize(const std::vector<uint8_t>& romData, bool verbose = false);
public:
void Initialize(const std::vector<uint8_t> &romData, bool verbose = false);
uint16_t GetHeaderOffset() {
uint16_t offset;
switch (memory_[(0x00 << 16) + 0xFFD5] & 0x07) {
case 0: // LoROM
offset = 0x7FC0;
break;
case 1: // HiROM
offset = 0xFFC0;
break;
case 5: // ExHiROM
offset = 0x40;
break;
default:
throw std::invalid_argument(
"Unable to locate supported ROM mapping mode in the provided ROM "
"file. Please try another ROM file.");
case 0: // LoROM
offset = 0x7FC0;
break;
case 1: // HiROM
offset = 0xFFC0;
break;
case 5: // ExHiROM
offset = 0x40;
break;
default:
throw std::invalid_argument(
"Unable to locate supported ROM mapping mode in the provided ROM "
"file. Please try another ROM file.");
}
return offset;
@@ -220,7 +237,7 @@ class MemoryImpl : public Memory {
// Stack Pointer access.
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 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 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; }
auto dma_channels() -> DmaChannel* { return channel; }
auto dma_channels() -> DmaChannel * { return channel; }
// Define memory regions
std::vector<uint8_t> rom_;
std::vector<uint8_t> ram_;
private:
private:
uint32_t GetMappedAddress(uint32_t address) const;
bool verbose_ = false;
@@ -306,9 +323,7 @@ class MemoryImpl : public Memory {
std::vector<uint8_t> memory_;
};
} // namespace memory
} // namespace emu
} // namespace emu
} // namespace yaze
} // namespace yaze
#endif // MEM_H
#endif // YAZE_APP_EMU_MEMORY_H