Add DMA to SNES
This commit is contained in:
@@ -6,6 +6,7 @@ add_executable(
|
||||
app/emu/audio/spc700.cc
|
||||
app/emu/audio/dsp.cc
|
||||
app/emu/video/ppu.cc
|
||||
app/emu/memory/dma.cc
|
||||
app/emu/cpu.cc
|
||||
app/emu/snes.cc
|
||||
${YAZE_APP_CORE_SRC}
|
||||
|
||||
75
src/app/emu/memory/dma.cc
Normal file
75
src/app/emu/memory/dma.cc
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "app/emu/memory/dma.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace yaze {
|
||||
namespace app {
|
||||
namespace emu {
|
||||
|
||||
void DMA::StartDMATransfer(uint8_t channelMask) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ((channelMask & (1 << i)) != 0) {
|
||||
Channel& ch = channels[i];
|
||||
|
||||
// Validate channel parameters (e.g., DMAPn, BBADn, A1Tn, DASn)
|
||||
// ...
|
||||
|
||||
// Determine the transfer direction based on the DMAPn register
|
||||
bool fromMemory = (ch.DMAPn & 0x80) != 0;
|
||||
|
||||
// Determine the transfer size based on the DMAPn register
|
||||
bool transferTwoBytes = (ch.DMAPn & 0x40) != 0;
|
||||
|
||||
// Perform the DMA transfer based on the channel parameters
|
||||
std::cout << "Starting DMA transfer for channel " << i << std::endl;
|
||||
|
||||
for (uint16_t j = 0; j < ch.DASn; ++j) {
|
||||
// Read a byte or two bytes from memory based on the transfer size
|
||||
// ...
|
||||
|
||||
// Write the data to the B-bus address (BBADn) if transferring from
|
||||
// memory
|
||||
// ...
|
||||
|
||||
// Update the A1Tn register based on the transfer direction
|
||||
if (fromMemory) {
|
||||
ch.A1Tn += transferTwoBytes ? 2 : 1;
|
||||
} else {
|
||||
ch.A1Tn -= transferTwoBytes ? 2 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the channel registers after the transfer (e.g., A1Tn, DASn)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
MDMAEN = channelMask; // Set the MDMAEN register to the channel mask
|
||||
}
|
||||
|
||||
void DMA::EnableHDMATransfers(uint8_t channelMask) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ((channelMask & (1 << i)) != 0) {
|
||||
Channel& ch = channels[i];
|
||||
|
||||
// Validate channel parameters (e.g., DMAPn, BBADn, A1Tn, A2An, NLTRn)
|
||||
// ...
|
||||
|
||||
// Perform the HDMA setup based on the channel parameters
|
||||
std::cout << "Enabling HDMA transfer for channel " << i << std::endl;
|
||||
|
||||
// Read the HDMA table from memory starting at A1Tn
|
||||
// ...
|
||||
|
||||
// Update the A2An register based on the HDMA table
|
||||
// ...
|
||||
|
||||
// Update the NLTRn register based on the HDMA table
|
||||
// ...
|
||||
}
|
||||
}
|
||||
HDMAEN = channelMask; // Set the HDMAEN register to the channel mask
|
||||
}
|
||||
|
||||
} // namespace emu
|
||||
} // namespace app
|
||||
} // namespace yaze
|
||||
@@ -58,70 +58,6 @@ void audio_callback(void* userdata, uint8_t* stream, int len) {
|
||||
|
||||
} // namespace
|
||||
|
||||
void DMA::StartDMATransfer(uint8_t channelMask) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ((channelMask & (1 << i)) != 0) {
|
||||
Channel& ch = channels[i];
|
||||
|
||||
// Validate channel parameters (e.g., DMAPn, BBADn, A1Tn, DASn)
|
||||
// ...
|
||||
|
||||
// Determine the transfer direction based on the DMAPn register
|
||||
bool fromMemory = (ch.DMAPn & 0x80) != 0;
|
||||
|
||||
// Determine the transfer size based on the DMAPn register
|
||||
bool transferTwoBytes = (ch.DMAPn & 0x40) != 0;
|
||||
|
||||
// Perform the DMA transfer based on the channel parameters
|
||||
std::cout << "Starting DMA transfer for channel " << i << std::endl;
|
||||
|
||||
for (uint16_t j = 0; j < ch.DASn; ++j) {
|
||||
// Read a byte or two bytes from memory based on the transfer size
|
||||
// ...
|
||||
|
||||
// Write the data to the B-bus address (BBADn) if transferring from
|
||||
// memory
|
||||
// ...
|
||||
|
||||
// Update the A1Tn register based on the transfer direction
|
||||
if (fromMemory) {
|
||||
ch.A1Tn += transferTwoBytes ? 2 : 1;
|
||||
} else {
|
||||
ch.A1Tn -= transferTwoBytes ? 2 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the channel registers after the transfer (e.g., A1Tn, DASn)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
MDMAEN = channelMask; // Set the MDMAEN register to the channel mask
|
||||
}
|
||||
|
||||
void DMA::EnableHDMATransfers(uint8_t channelMask) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ((channelMask & (1 << i)) != 0) {
|
||||
Channel& ch = channels[i];
|
||||
|
||||
// Validate channel parameters (e.g., DMAPn, BBADn, A1Tn, A2An, NLTRn)
|
||||
// ...
|
||||
|
||||
// Perform the HDMA setup based on the channel parameters
|
||||
std::cout << "Enabling HDMA transfer for channel " << i << std::endl;
|
||||
|
||||
// Read the HDMA table from memory starting at A1Tn
|
||||
// ...
|
||||
|
||||
// Update the A2An register based on the HDMA table
|
||||
// ...
|
||||
|
||||
// Update the NLTRn register based on the HDMA table
|
||||
// ...
|
||||
}
|
||||
}
|
||||
HDMAEN = channelMask; // Set the HDMAEN register to the channel mask
|
||||
}
|
||||
|
||||
ROMInfo SNES::ReadRomHeader(uint32_t offset) {
|
||||
ROMInfo romInfo;
|
||||
|
||||
@@ -289,9 +225,7 @@ void SNES::Run() {
|
||||
running_ = true;
|
||||
|
||||
const double targetFPS = 60.0; // 60 frames per second
|
||||
|
||||
const double frameTime = 1.0 / targetFPS;
|
||||
|
||||
const double frame_time = 1.0 / targetFPS;
|
||||
double frame_accumulated_time = 0.0;
|
||||
|
||||
auto last_time = std::chrono::high_resolution_clock::now();
|
||||
@@ -316,9 +250,9 @@ void SNES::Run() {
|
||||
apu.UpdateClock(delta_time);
|
||||
apu.Update();
|
||||
|
||||
if (frame_accumulated_time >= frameTime) {
|
||||
if (frame_accumulated_time >= frame_time) {
|
||||
// renderer.Render();
|
||||
frame_accumulated_time -= frameTime;
|
||||
frame_accumulated_time -= frame_time;
|
||||
}
|
||||
|
||||
HandleInput();
|
||||
@@ -376,7 +310,6 @@ void SNES::NmiIsr() {
|
||||
void SNES::VBlankRoutine() {
|
||||
// Execute code that needs to run during VBlank, such as transferring data to
|
||||
// the PPU
|
||||
// ...
|
||||
}
|
||||
|
||||
void SNES::BootAPUWithIPL() {
|
||||
|
||||
Reference in New Issue
Block a user