add memory namespace, update comments
This commit is contained in:
@@ -15,12 +15,32 @@ namespace app {
|
|||||||
namespace emu {
|
namespace emu {
|
||||||
namespace audio {
|
namespace audio {
|
||||||
|
|
||||||
|
using namespace memory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int kApuClockSpeed = 1024000; // 1.024 MHz
|
||||||
|
const int apuSampleRate = 32000; // 32 KHz
|
||||||
|
const int apuClocksPerSample = 64; // 64 clocks per sample
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Apu
|
||||||
|
* @brief The Apu class represents the Audio Processing Unit (APU) of a system.
|
||||||
|
*
|
||||||
|
* The Apu class is responsible for generating audio samples and managing the
|
||||||
|
* APU state. It interacts with the Memory, AudioRam, and Clock classes to
|
||||||
|
* read/write data and update the clock. The class also implements the Observer
|
||||||
|
* interface to receive notifications from the system.
|
||||||
|
*
|
||||||
|
* @par IPL ROM Info
|
||||||
* 64 kilobytes of RAM are mapped across the 16-bit memory space of the SPC-700.
|
* 64 kilobytes of RAM are mapped across the 16-bit memory space of the SPC-700.
|
||||||
* Some regions of this space are overlaid with special hardware functions.
|
* Some regions of this space are overlaid with special hardware functions.
|
||||||
*
|
*
|
||||||
* Range Note
|
* @par Range Note
|
||||||
* $0000-00EF Zero Page RAM
|
* $0000-00EF Zero Page RAM
|
||||||
* $00F0-00FF Sound CPU Registers
|
* $00F0-00FF Sound CPU Registers
|
||||||
* $0100-01FF Stack Page RAM
|
* $0100-01FF Stack Page RAM
|
||||||
@@ -31,13 +51,7 @@ namespace audio {
|
|||||||
* underlying RAM can always be written to, and the high bit of the Control
|
* underlying RAM can always be written to, and the high bit of the Control
|
||||||
* register $F1 can be cleared to unmap the IPL ROM and allow read access to
|
* register $F1 can be cleared to unmap the IPL ROM and allow read access to
|
||||||
* this RAM.
|
* this RAM.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const int kApuClockSpeed = 1024000; // 1.024 MHz
|
|
||||||
const int apuSampleRate = 32000; // 32 KHz
|
|
||||||
const int apuClocksPerSample = 64; // 64 clocks per sample
|
|
||||||
|
|
||||||
class Apu : public Observer {
|
class Apu : public Observer {
|
||||||
public:
|
public:
|
||||||
Apu(MemoryImpl &memory, AudioRam &aram, Clock &clock)
|
Apu(MemoryImpl &memory, AudioRam &aram, Clock &clock)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ using SampleFetcher = std::function<uint8_t(uint16_t)>;
|
|||||||
using SamplePusher = std::function<void(int16_t)>;
|
using SamplePusher = std::function<void(int16_t)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* The S-DSP is a digital signal processor generating the sound data.
|
* The S-DSP is a digital signal processor generating the sound data.
|
||||||
*
|
*
|
||||||
* A DSP register can be selected with $F2, after which it can be read or
|
* A DSP register can be selected with $F2, after which it can be read or
|
||||||
@@ -35,21 +34,19 @@ using SamplePusher = std::function<void(int16_t)>;
|
|||||||
* There are 8 voices, numbered 0 to 7.
|
* There are 8 voices, numbered 0 to 7.
|
||||||
* Each voice X has 10 registers in the range $X0-$X9.
|
* Each voice X has 10 registers in the range $X0-$X9.
|
||||||
*
|
*
|
||||||
* Name Address Bits Notes
|
* | Name | Address | Bits | Notes |
|
||||||
* VOL (L) $X0 SVVV VVVV Left channel volume, signed.
|
* |---------|---------|-----------|--------------------------------------------------------|
|
||||||
* VOL (R) $X1 SVVV VVVV Right channel volume, signed.
|
* | VOL (L) | $X0 | SVVV VVVV | Left channel volume, signed. |
|
||||||
* P (L) $X2 LLLL LLLL Low 8 bits of sample pitch.
|
* | VOL (R) | $X1 | SVVV VVVV | Right channel volume, signed. |
|
||||||
* P (H) $X3 --HH HHHH High 6 bits of sample pitch.
|
* | P (L) | $X2 | LLLL LLLL | Low 8 bits of sample pitch. |
|
||||||
* SCRN $X4 SSSS SSSS Selects a sample source entry from the
|
* | P (H) | $X3 | --HH HHHH | High 6 bits of sample pitch. |
|
||||||
* directory ADSR (1) $X5 EDDD AAAA ADSR enable (E), decay rate (D),
|
* | SCRN | $X4 | SSSS SSSS | Selects a sample source entry from the directory. |
|
||||||
* attack rate (A).
|
* | ADSR (1)| $X5 | EDDD AAAA | ADSR enable (E), decay rate (D), attack rate (A). |
|
||||||
* ADSR (2) $X6 SSSR RRRR Sustain level (S), release rate (R).
|
* | ADSR (2)| $X6 | SSSR RRRR | Sustain level (S), release rate (R). |
|
||||||
* GAIN $X7 0VVV VVVV 1MMV VVVV Mode (M), value (V).
|
* | GAIN | $X7 | 0VVV VVVV 1MMV VVVV | Mode (M), value (V). |
|
||||||
* ENVX $X8 0VVV VVVV Reads current 7-bit value of ADSR/GAIN
|
* | ENVX | $X8 | 0VVV VVVV | Reads current 7-bit value of ADSR/GAIN envelope. |
|
||||||
* envelope.
|
* | OUTX | $X9 | SVVV VVVV | Reads signed 8-bit value of current sample wave |
|
||||||
* OUTX $X9 SVVV VVVV Reads signed 8-bit value of current
|
* | | | | multiplied by ENVX, before applying VOL. |
|
||||||
* sample wave multiplied by ENVX, before applying VOL.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DigitalSignalProcessor {
|
class DigitalSignalProcessor {
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ namespace app {
|
|||||||
namespace emu {
|
namespace emu {
|
||||||
namespace audio {
|
namespace audio {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AudioRam is an interface for the Audio RAM used by the SPC700.
|
||||||
|
*/
|
||||||
class AudioRam {
|
class AudioRam {
|
||||||
public:
|
public:
|
||||||
virtual ~AudioRam() = default;
|
virtual ~AudioRam() = default;
|
||||||
@@ -20,6 +23,9 @@ class AudioRam {
|
|||||||
virtual void write(uint16_t address, uint8_t value) = 0;
|
virtual void write(uint16_t address, uint8_t value) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AudioRamImpl is an implementation of the AudioRam interface.
|
||||||
|
*/
|
||||||
class AudioRamImpl : public AudioRam {
|
class AudioRamImpl : public AudioRam {
|
||||||
static const int ARAM_SIZE = 0x10000;
|
static const int ARAM_SIZE = 0x10000;
|
||||||
std::vector<uint8_t> ram = std::vector<uint8_t>(ARAM_SIZE, 0);
|
std::vector<uint8_t> ram = std::vector<uint8_t>(ARAM_SIZE, 0);
|
||||||
@@ -41,6 +47,17 @@ class AudioRamImpl : public AudioRam {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Spc700
|
||||||
|
* @brief The Spc700 class represents the SPC700 processor.
|
||||||
|
*
|
||||||
|
* The Spc700 class provides the functionality to execute instructions, read and
|
||||||
|
* write memory, and handle various addressing modes. It also contains registers
|
||||||
|
* and flags specific to the SPC700.
|
||||||
|
*
|
||||||
|
* @note This class assumes the existence of an `AudioRam` object for memory
|
||||||
|
* access.
|
||||||
|
*/
|
||||||
class Spc700 {
|
class Spc700 {
|
||||||
private:
|
private:
|
||||||
AudioRam& aram_;
|
AudioRam& aram_;
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ class InstructionEntry {
|
|||||||
|
|
||||||
const int kCpuClockSpeed = 21477272; // 21.477272 MHz
|
const int kCpuClockSpeed = 21477272; // 21.477272 MHz
|
||||||
|
|
||||||
class Cpu : public Memory, public Loggable, public core::ExperimentFlags {
|
class Cpu : public memory::Memory,
|
||||||
|
public Loggable,
|
||||||
|
public core::ExperimentFlags {
|
||||||
public:
|
public:
|
||||||
explicit Cpu(Memory& mem, Clock& vclock) : memory(mem), clock(vclock) {}
|
explicit Cpu(Memory& mem, Clock& vclock) : memory(mem), clock(vclock) {}
|
||||||
enum class UpdateMode { Run, Step, Pause };
|
enum class UpdateMode { Run, Step, Pause };
|
||||||
|
|||||||
@@ -5,8 +5,9 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
|
namespace memory {
|
||||||
|
|
||||||
void DMA::StartDMATransfer(uint8_t channelMask) {
|
void DirectMemoryAccess::StartDMATransfer(uint8_t channelMask) {
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
if ((channelMask & (1 << i)) != 0) {
|
if ((channelMask & (1 << i)) != 0) {
|
||||||
Channel& ch = channels[i];
|
Channel& ch = channels[i];
|
||||||
@@ -20,8 +21,9 @@ void DMA::StartDMATransfer(uint8_t channelMask) {
|
|||||||
// Determine the transfer size based on the DMAPn register
|
// Determine the transfer size based on the DMAPn register
|
||||||
bool transferTwoBytes = (ch.DMAPn & 0x40) != 0;
|
bool transferTwoBytes = (ch.DMAPn & 0x40) != 0;
|
||||||
|
|
||||||
// Perform the DMA transfer based on the channel parameters
|
// Perform the DirectMemoryAccess transfer based on the channel parameters
|
||||||
std::cout << "Starting DMA transfer for channel " << i << std::endl;
|
std::cout << "Starting DirectMemoryAccess transfer for channel " << i
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
for (uint16_t j = 0; j < ch.DASn; ++j) {
|
for (uint16_t j = 0; j < ch.DASn; ++j) {
|
||||||
// Read a byte or two bytes from memory based on the transfer size
|
// Read a byte or two bytes from memory based on the transfer size
|
||||||
@@ -46,7 +48,7 @@ void DMA::StartDMATransfer(uint8_t channelMask) {
|
|||||||
MDMAEN = channelMask; // Set the MDMAEN register to the channel mask
|
MDMAEN = channelMask; // Set the MDMAEN register to the channel mask
|
||||||
}
|
}
|
||||||
|
|
||||||
void DMA::EnableHDMATransfers(uint8_t channelMask) {
|
void DirectMemoryAccess::EnableHDMATransfers(uint8_t channelMask) {
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
if ((channelMask & (1 << i)) != 0) {
|
if ((channelMask & (1 << i)) != 0) {
|
||||||
Channel& ch = channels[i];
|
Channel& ch = channels[i];
|
||||||
@@ -70,6 +72,7 @@ void DMA::EnableHDMATransfers(uint8_t channelMask) {
|
|||||||
HDMAEN = channelMask; // Set the HDMAEN register to the channel mask
|
HDMAEN = channelMask; // Set the HDMAEN register to the channel mask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace memory
|
||||||
} // namespace emu
|
} // namespace emu
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -6,11 +6,11 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
|
namespace memory {
|
||||||
|
|
||||||
// Direct Memory Address
|
class DirectMemoryAccess {
|
||||||
class DMA {
|
|
||||||
public:
|
public:
|
||||||
DMA() {
|
DirectMemoryAccess() {
|
||||||
// Initialize DMA and HDMA channels
|
// Initialize DMA and HDMA channels
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
channels[i].DMAPn = 0;
|
channels[i].DMAPn = 0;
|
||||||
@@ -52,6 +52,8 @@ class DMA {
|
|||||||
uint8_t MDMAEN = 0; // Start DMA transfer
|
uint8_t MDMAEN = 0; // Start DMA transfer
|
||||||
uint8_t HDMAEN = 0; // Enable HDMA transfers
|
uint8_t HDMAEN = 0; // Enable HDMA transfers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace memory
|
||||||
} // namespace emu
|
} // namespace emu
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
|
namespace memory {
|
||||||
|
|
||||||
void DrawSnesMemoryMapping(const MemoryImpl& memory) {
|
void DrawSnesMemoryMapping(const MemoryImpl& memory) {
|
||||||
// Using those as a base value to create width/height that are factor of the
|
// Using those as a base value to create width/height that are factor of the
|
||||||
@@ -77,6 +78,7 @@ void DrawSnesMemoryMapping(const MemoryImpl& memory) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace memory
|
||||||
} // namespace emu
|
} // namespace emu
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -28,12 +28,13 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
|
namespace memory {
|
||||||
|
|
||||||
enum ROMSpeed { SLOW_ROM = 0x00, FAST_ROM = 0x07 };
|
enum RomSpeed { SLOW_ROM = 0x00, FAST_ROM = 0x07 };
|
||||||
|
|
||||||
enum BankSize { LOW_ROM = 0x00, HI_ROM = 0x01 };
|
enum BankSize { LOW_ROM = 0x00, HI_ROM = 0x01 };
|
||||||
|
|
||||||
enum ROMType {
|
enum RomType {
|
||||||
ROM_DEFAULT = 0x00,
|
ROM_DEFAULT = 0x00,
|
||||||
ROM_RAM = 0x01,
|
ROM_RAM = 0x01,
|
||||||
ROM_SRAM = 0x02,
|
ROM_SRAM = 0x02,
|
||||||
@@ -43,7 +44,7 @@ enum ROMType {
|
|||||||
FX = 0x06
|
FX = 0x06
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ROMSize {
|
enum RomSize {
|
||||||
SIZE_2_MBIT = 0x08,
|
SIZE_2_MBIT = 0x08,
|
||||||
SIZE_4_MBIT = 0x09,
|
SIZE_4_MBIT = 0x09,
|
||||||
SIZE_8_MBIT = 0x0A,
|
SIZE_8_MBIT = 0x0A,
|
||||||
@@ -51,7 +52,7 @@ enum ROMSize {
|
|||||||
SIZE_32_MBIT = 0x0C
|
SIZE_32_MBIT = 0x0C
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SRAMSize {
|
enum SramSize {
|
||||||
NO_SRAM = 0x00,
|
NO_SRAM = 0x00,
|
||||||
SRAM_16_KBIT = 0x01,
|
SRAM_16_KBIT = 0x01,
|
||||||
SRAM_32_KBIT = 0x02,
|
SRAM_32_KBIT = 0x02,
|
||||||
@@ -73,14 +74,14 @@ enum License {
|
|||||||
// ... and other licenses
|
// ... and other licenses
|
||||||
};
|
};
|
||||||
|
|
||||||
class ROMInfo {
|
class RomInfo {
|
||||||
public:
|
public:
|
||||||
std::string title;
|
std::string title;
|
||||||
ROMSpeed romSpeed;
|
RomSpeed romSpeed;
|
||||||
BankSize bankSize;
|
BankSize bankSize;
|
||||||
ROMType romType;
|
RomType romType;
|
||||||
ROMSize romSize;
|
RomSize romSize;
|
||||||
SRAMSize sramSize;
|
SramSize sramSize;
|
||||||
CountryCode countryCode;
|
CountryCode countryCode;
|
||||||
License license;
|
License license;
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
@@ -105,7 +106,9 @@ constexpr uint32_t kVRAMSize = 0x10000;
|
|||||||
constexpr uint32_t kOAMStart = 0x218000;
|
constexpr uint32_t kOAMStart = 0x218000;
|
||||||
constexpr uint32_t kOAMSize = 0x220;
|
constexpr uint32_t kOAMSize = 0x220;
|
||||||
|
|
||||||
// memory.h
|
/**
|
||||||
|
* @brief Memory interface
|
||||||
|
*/
|
||||||
class Memory {
|
class Memory {
|
||||||
public:
|
public:
|
||||||
virtual ~Memory() = default;
|
virtual ~Memory() = default;
|
||||||
@@ -137,6 +140,29 @@ class Memory {
|
|||||||
|
|
||||||
enum class MemoryMapping { SNES_LOROM = 0, PC_ADDRESS = 1 };
|
enum class MemoryMapping { SNES_LOROM = 0, PC_ADDRESS = 1 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class MemoryImpl
|
||||||
|
* @brief Implementation of the Memory interface for emulating memory in a SNES
|
||||||
|
* system.
|
||||||
|
*
|
||||||
|
* The MemoryImpl class provides methods for initializing and accessing memory
|
||||||
|
* in a SNES system. It implements the Memory interface and inherits from the
|
||||||
|
* Loggable class.
|
||||||
|
*
|
||||||
|
* The class supports different memory mappings, including LoROM and PC_ADDRESS
|
||||||
|
* mappings. It provides methods for reading and writing bytes, words, and longs
|
||||||
|
* from/to memory. It also supports stack operations for pushing and popping
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* The class maintains separate vectors for ROM, RAM, VRAM, and OAM memory
|
||||||
|
* regions. It provides methods for accessing these memory regions and
|
||||||
|
* retrieving their sizes.
|
||||||
|
*
|
||||||
|
* The class also allows adding observers to be notified when memory is read or
|
||||||
|
* written.
|
||||||
|
*
|
||||||
|
* @note This class assumes a 16-bit address space.
|
||||||
|
*/
|
||||||
class MemoryImpl : public Memory, public Loggable {
|
class MemoryImpl : public Memory, public Loggable {
|
||||||
public:
|
public:
|
||||||
void Initialize(const std::vector<uint8_t>& romData, bool verbose = false,
|
void Initialize(const std::vector<uint8_t>& romData, bool verbose = false,
|
||||||
@@ -396,6 +422,7 @@ class MemoryImpl : public Memory, public Loggable {
|
|||||||
|
|
||||||
void DrawSnesMemoryMapping(const MemoryImpl& memory);
|
void DrawSnesMemoryMapping(const MemoryImpl& memory);
|
||||||
|
|
||||||
|
} // namespace memory
|
||||||
} // namespace emu
|
} // namespace emu
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -8,10 +8,14 @@
|
|||||||
#include "app/emu/cpu/cpu.h"
|
#include "app/emu/cpu/cpu.h"
|
||||||
#include "app/emu/memory/memory.h"
|
#include "app/emu/memory/memory.h"
|
||||||
|
|
||||||
using yaze::app::emu::Clock;
|
namespace yaze {
|
||||||
using yaze::app::emu::Cpu;
|
namespace app {
|
||||||
using yaze::app::emu::Memory;
|
namespace emu {
|
||||||
|
namespace memory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mock CPU class for testing
|
||||||
|
*/
|
||||||
class MockClock : public Clock {
|
class MockClock : public Clock {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD(void, UpdateClock, (double delta), (override));
|
MOCK_METHOD(void, UpdateClock, (double delta), (override));
|
||||||
@@ -21,9 +25,23 @@ class MockClock : public Clock {
|
|||||||
MOCK_METHOD(float, GetFrequency, (), (const, override));
|
MOCK_METHOD(float, GetFrequency, (), (const, override));
|
||||||
};
|
};
|
||||||
|
|
||||||
// 0x1000000 is 16 MB, simplifying the memory layout for testing
|
/**
|
||||||
// 2 MB is = 0x200000
|
* @class MockMemory
|
||||||
|
* @brief A mock implementation of the Memory class.
|
||||||
|
*
|
||||||
|
* This class is used for testing purposes and provides a mock implementation of
|
||||||
|
* the Memory class. It allows for reading and writing bytes, words, and longs
|
||||||
|
* to memory, as well as pushing and popping values onto and from the stack. It
|
||||||
|
* also provides methods for setting and getting the stack pointer, initializing
|
||||||
|
* memory with ROM data, and clearing memory.
|
||||||
|
*
|
||||||
|
* The mock memory is represented by a vector of uint8_t values, where each
|
||||||
|
* element represents a byte of memory. The memory can be accessed using the []
|
||||||
|
* operator, and its contents can be set using the SetMemoryContents() method.
|
||||||
|
*
|
||||||
|
* @note This class is intended for testing purposes only and should not be used
|
||||||
|
* in production code.
|
||||||
|
*/
|
||||||
class MockMemory : public Memory {
|
class MockMemory : public Memory {
|
||||||
public:
|
public:
|
||||||
MOCK_CONST_METHOD1(ReadByte, uint8_t(uint32_t address));
|
MOCK_CONST_METHOD1(ReadByte, uint8_t(uint32_t address));
|
||||||
@@ -85,6 +103,8 @@ class MockMemory : public Memory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 16MB = 0x1000000
|
||||||
|
// 02MB = 0x200000
|
||||||
void Initialize(const std::vector<uint8_t>& romData) {
|
void Initialize(const std::vector<uint8_t>& romData) {
|
||||||
// 16 MB, simplifying the memory layout for testing
|
// 16 MB, simplifying the memory layout for testing
|
||||||
memory_.resize(0x1000000);
|
memory_.resize(0x1000000);
|
||||||
@@ -186,4 +206,9 @@ class MockMemory : public Memory {
|
|||||||
uint16_t SP_ = 0x01FF;
|
uint16_t SP_ = 0x01FF;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace memory
|
||||||
|
} // namespace emu
|
||||||
|
} // namespace app
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
#endif // YAZE_TEST_MOCK_MOCK_MEMORY_H
|
#endif // YAZE_TEST_MOCK_MOCK_MEMORY_H
|
||||||
@@ -57,8 +57,8 @@ void audio_callback(void* userdata, uint8_t* stream, int len) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ROMInfo SNES::ReadRomHeader(uint32_t offset) {
|
RomInfo SNES::ReadRomHeader(uint32_t offset) {
|
||||||
ROMInfo romInfo;
|
RomInfo romInfo;
|
||||||
|
|
||||||
// Read cartridge title
|
// Read cartridge title
|
||||||
char title[22];
|
char title[22];
|
||||||
@@ -70,17 +70,17 @@ ROMInfo SNES::ReadRomHeader(uint32_t offset) {
|
|||||||
|
|
||||||
// Read ROM speed and memory map mode
|
// Read ROM speed and memory map mode
|
||||||
uint8_t romSpeedAndMapMode = cpu_.ReadByte(offset + 0x15);
|
uint8_t romSpeedAndMapMode = cpu_.ReadByte(offset + 0x15);
|
||||||
romInfo.romSpeed = (ROMSpeed)(romSpeedAndMapMode & 0x07);
|
romInfo.romSpeed = (RomSpeed)(romSpeedAndMapMode & 0x07);
|
||||||
romInfo.bankSize = (BankSize)((romSpeedAndMapMode >> 5) & 0x01);
|
romInfo.bankSize = (BankSize)((romSpeedAndMapMode >> 5) & 0x01);
|
||||||
|
|
||||||
// Read ROM type
|
// Read ROM type
|
||||||
romInfo.romType = (ROMType)cpu_.ReadByte(offset + 0x16);
|
romInfo.romType = (RomType)cpu_.ReadByte(offset + 0x16);
|
||||||
|
|
||||||
// Read ROM size
|
// Read ROM size
|
||||||
romInfo.romSize = (ROMSize)cpu_.ReadByte(offset + 0x17);
|
romInfo.romSize = (RomSize)cpu_.ReadByte(offset + 0x17);
|
||||||
|
|
||||||
// Read RAM size
|
// Read RAM size
|
||||||
romInfo.sramSize = (SRAMSize)cpu_.ReadByte(offset + 0x18);
|
romInfo.sramSize = (SramSize)cpu_.ReadByte(offset + 0x18);
|
||||||
|
|
||||||
// Read country code
|
// Read country code
|
||||||
romInfo.countryCode = (CountryCode)cpu_.ReadByte(offset + 0x19);
|
romInfo.countryCode = (CountryCode)cpu_.ReadByte(offset + 0x19);
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ namespace yaze {
|
|||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
|
|
||||||
class SNES : public DMA {
|
using namespace memory;
|
||||||
|
|
||||||
|
class SNES : public DirectMemoryAccess {
|
||||||
public:
|
public:
|
||||||
SNES() = default;
|
SNES() = default;
|
||||||
~SNES() = default;
|
~SNES() = default;
|
||||||
|
|
||||||
ROMInfo ReadRomHeader(uint32_t offset);
|
RomInfo ReadRomHeader(uint32_t offset);
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
void Init(ROM& rom);
|
void Init(ROM& rom);
|
||||||
@@ -95,7 +97,7 @@ class SNES : public DMA {
|
|||||||
audio::Apu apu_{memory_, audio_ram_, clock_};
|
audio::Apu apu_{memory_, audio_ram_, clock_};
|
||||||
|
|
||||||
// Helper classes
|
// Helper classes
|
||||||
ROMInfo rom_info_;
|
RomInfo rom_info_;
|
||||||
Debugger debugger;
|
Debugger debugger;
|
||||||
|
|
||||||
// Currently loaded ROM
|
// Currently loaded ROM
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace emu {
|
|||||||
namespace video {
|
namespace video {
|
||||||
|
|
||||||
using namespace PpuRegisters;
|
using namespace PpuRegisters;
|
||||||
|
using namespace memory;
|
||||||
|
|
||||||
class PpuInterface {
|
class PpuInterface {
|
||||||
public:
|
public:
|
||||||
@@ -267,7 +268,7 @@ const int kPpuClockSpeed = 5369318; // 5.369318 MHz
|
|||||||
class Ppu : public Observer, public SharedROM {
|
class Ppu : public Observer, public SharedROM {
|
||||||
public:
|
public:
|
||||||
// Initializes the PPU with the necessary resources and dependencies
|
// Initializes the PPU with the necessary resources and dependencies
|
||||||
Ppu(Memory& memory, Clock& clock) : memory_(memory), clock_(clock) {}
|
Ppu(memory::Memory& memory, Clock& clock) : memory_(memory), clock_(clock) {}
|
||||||
|
|
||||||
// Initialize the frame buffer
|
// Initialize the frame buffer
|
||||||
void Init() {
|
void Init() {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class DungeonObjectRenderer : public SharedROM {
|
|||||||
std::vector<uint8_t> tilemap_;
|
std::vector<uint8_t> tilemap_;
|
||||||
uint16_t pc_with_rts_;
|
uint16_t pc_with_rts_;
|
||||||
std::vector<uint8_t> rom_data_;
|
std::vector<uint8_t> rom_data_;
|
||||||
emu::MemoryImpl memory_;
|
emu::memory::MemoryImpl memory_;
|
||||||
emu::ClockImpl clock_;
|
emu::ClockImpl clock_;
|
||||||
emu::Cpu cpu{memory_, clock_};
|
emu::Cpu cpu{memory_, clock_};
|
||||||
emu::video::Ppu ppu{memory_, clock_};
|
emu::video::Ppu ppu{memory_, clock_};
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ class CpuTest : public ::testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AsmParser asm_parser;
|
AsmParser asm_parser;
|
||||||
MockMemory mock_memory;
|
memory::MockMemory mock_memory;
|
||||||
MockClock mock_clock;
|
memory::MockClock mock_clock;
|
||||||
Cpu cpu{mock_memory, mock_clock};
|
Cpu cpu{mock_memory, mock_clock};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ using ::testing::Return;
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
TEST_F(CpuTest, CheckMemoryContents) {
|
TEST_F(CpuTest, CheckMemoryContents) {
|
||||||
MockMemory memory;
|
memory::MockMemory memory;
|
||||||
std::vector<uint8_t> data = {0x00, 0x01, 0x02, 0x03, 0x04};
|
std::vector<uint8_t> data = {0x00, 0x01, 0x02, 0x03, 0x04};
|
||||||
memory.SetMemoryContents(data);
|
memory.SetMemoryContents(data);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user