core: dma: Count cycles passed in DMA transfers

Former-commit-id: 751f2e42f9c5c19f2fcc901754950d1e3797303b
Former-commit-id: 30d31be99daec4324532d4663390945a55f641b1
This commit is contained in:
Michel Heily 2020-10-17 06:28:04 -07:00 committed by MishMish
parent b6e2d55550
commit 44c9e2c875

View file

@ -1,9 +1,9 @@
use super::arm7tdmi::memory::{MemoryAccess, MemoryInterface};
use super::cartridge::BackupMedia; use super::cartridge::BackupMedia;
use super::interrupt::{self, Interrupt, InterruptConnect, SharedInterruptFlags}; use super::interrupt::{self, Interrupt, InterruptConnect, SharedInterruptFlags};
use super::iodev::consts::{REG_FIFO_A, REG_FIFO_B}; use super::iodev::consts::{REG_FIFO_A, REG_FIFO_B};
use super::sched::{EventType, Scheduler, SharedScheduler}; use super::sched::{EventType, Scheduler, SharedScheduler};
use super::sysbus::SysBus; use super::sysbus::SysBus;
use super::Bus;
use num::FromPrimitive; use num::FromPrimitive;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -151,22 +151,26 @@ impl DmaChannel {
let fifo_mode = self.fifo_mode; let fifo_mode = self.fifo_mode;
let mut access = MemoryAccess::NonSeq;
if fifo_mode { if fifo_mode {
for _ in 0..4 { for _ in 0..4 {
let v = sb.read_32(self.internal.src_addr & !3); let v = sb.load_32(self.internal.src_addr & !3, access);
sb.write_32(self.internal.dst_addr & !3, v); sb.store_32(self.internal.dst_addr & !3, v, access);
access = MemoryAccess::Seq;
self.internal.src_addr += 4; self.internal.src_addr += 4;
} }
} else if word_size == 4 { } else if word_size == 4 {
for _ in 0..count { for _ in 0..count {
let w = sb.read_32(self.internal.src_addr & !3); let w = sb.load_32(self.internal.src_addr & !3, access);
sb.write_32(self.internal.dst_addr & !3, w); sb.store_32(self.internal.dst_addr & !3, w, access);
access = MemoryAccess::Seq;
self.xfer_adj_addrs(word_size); self.xfer_adj_addrs(word_size);
} }
} else { } else {
for _ in 0..count { for _ in 0..count {
let hw = sb.read_16(self.internal.src_addr & !1); let hw = sb.load_16(self.internal.src_addr & !1, access);
sb.write_16(self.internal.dst_addr & !1, hw); sb.store_16(self.internal.dst_addr & !1, hw, access);
access = MemoryAccess::Seq;
self.xfer_adj_addrs(word_size) self.xfer_adj_addrs(word_size)
} }
} }
@ -240,7 +244,7 @@ impl DmaController {
if self.channels[channel_id].write_dma_ctrl(value) { if self.channels[channel_id].write_dma_ctrl(value) {
// DMA actually starts after 3 cycles // DMA actually starts after 3 cycles
self.scheduler self.scheduler
.schedule(EventType::DmaActivateChannel(channel_id), 3); .push(EventType::DmaActivateChannel(channel_id), 3);
} else { } else {
self.deactivate_channel(channel_id); self.deactivate_channel(channel_id);
} }