Refactor Snes class and enhance Apu functionality

- Updated Snes constructor to initialize CPU callbacks directly, improving readability and maintainability.
- Removed unnecessary CpuCallbacks parameter from Cpu constructor, streamlining the class design.
- Added new methods in Apu for retrieving cycles, status, control, and handling DMA transfers, enhancing audio processing capabilities.
- Introduced unit tests for Apu to validate initialization, sample generation, and handshake timing, ensuring robust audio functionality.
This commit is contained in:
scawful
2025-09-24 12:51:29 -04:00
parent f1b1c91986
commit 3734884ba3
7 changed files with 289 additions and 18 deletions

View File

@@ -65,6 +65,18 @@ class Apu {
auto dsp() -> Dsp & { return dsp_; }
auto spc700() -> Spc700 & { return spc700_; }
uint64_t GetCycles() const { return cycles_; }
uint8_t GetStatus() const { return ram[0x00]; }
uint8_t GetControl() const { return ram[0x01]; }
void GetSamples(int16_t *buffer, int count, bool loop = false) {
dsp_.GetSamples(buffer, count, loop);
}
void WriteDma(uint16_t address, const uint8_t *data, int count) {
for (int i = 0; i < count; i++) {
ram[address + i] = data[i];
}
}
// Port buffers (equivalent to $2140 to $2143 for the main CPU)
std::array<uint8_t, 6> in_ports_; // includes 2 bytes of ram
std::array<uint8_t, 4> out_ports_;

View File

@@ -31,10 +31,12 @@ class InstructionEntry {
class Cpu {
public:
explicit Cpu(Memory& mem, CpuCallbacks& callbacks)
: memory(mem), callbacks_(callbacks) {}
explicit Cpu(Memory& mem) : memory(mem) {}
void Reset(bool hard = false);
auto& callbacks() { return callbacks_; }
const auto& callbacks() const { return callbacks_; }
void RunOpcode();
void ExecuteInstruction(uint8_t opcode);
@@ -781,8 +783,8 @@ class Cpu {
bool int_wanted_ = false;
bool int_delay_ = false;
CpuCallbacks callbacks_;
Memory& memory;
CpuCallbacks callbacks_;
};
} // namespace emu

View File

@@ -2,6 +2,8 @@
#define YAZE_APP_EMU_SNES_H
#include <cstdint>
#include <functional>
#include <memory>
#include "app/emu/audio/apu.h"
#include "app/emu/cpu/cpu.h"
@@ -21,7 +23,11 @@ struct Input {
class Snes {
public:
Snes() = default;
Snes() {
cpu_.callbacks().read_byte = [this](uint32_t adr) { return CpuRead(adr); };
cpu_.callbacks().write_byte = [this](uint32_t adr, uint8_t val) { CpuWrite(adr, val); };
cpu_.callbacks().idle = [this](bool waiting) { CpuIdle(waiting); };
}
~Snes() = default;
void Init(std::vector<uint8_t>& rom_data);
@@ -61,14 +67,11 @@ class Snes {
auto get_ram() -> uint8_t* { return ram; }
auto mutable_cycles() -> uint64_t& { return cycles_; }
bool fast_mem_ = false;
private:
MemoryImpl memory_;
CpuCallbacks cpu_callbacks_ = {
[&](uint32_t adr) { return CpuRead(adr); },
[&](uint32_t adr, uint8_t val) { CpuWrite(adr, val); },
[&](bool waiting) { CpuIdle(waiting); },
};
Cpu cpu_{memory_, cpu_callbacks_};
Cpu cpu_{memory_};
Ppu ppu_{memory_};
Apu apu_{memory_};
@@ -111,12 +114,9 @@ class Snes {
bool auto_joy_read_ = false;
uint16_t auto_joy_timer_ = 0;
bool ppu_latch_;
bool fast_mem_ = false;
};
} // namespace emu
} // namespace yaze
#endif // YAZE_APP_EMU_SNES_H