core: dma: Count cycles passed in DMA transfers
Former-commit-id: 751f2e42f9c5c19f2fcc901754950d1e3797303b Former-commit-id: 30d31be99daec4324532d4663390945a55f641b1
This commit is contained in:
parent
b6e2d55550
commit
44c9e2c875
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue