mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-24 07:02:27 +01:00
byuu says: Changelog: - emulator/interface: removed unused Region struct - gba/cpu: optimized CPU::step() as much as I could for a slight speedup¹ - gba/cpu: synchronize the APU better during FIFO updates - higan/md, icarus: add automatic region detection; make it the default option [hex\_usr] - picks NTSC-J if there's more than one match ... eventually, this will be a setting - higan/md, icarus: support all three combinations of SRAM (8-bit low, 8-bit high, 16-bit) - processor/arm7tdmi: fix bug when changing to THUMB mode via MSR [MerryMage] - tomoko: redesigned crash detector to only occur once for all three ruby drivers - this will reduce disk thrashing since the configuration file only needs to be written out one extra time - technically, it's twice ... but we should've always been writing one out on first run in case it crashes then - tomoko: defaulted back to the safest ruby drivers, given the optimal drivers have some stability concerns ¹: minor errata: spotted a typo saying `synchronize(cpu)` when the CPU is stopped, instead of `synchronize(ppu)`. This will be fixed in the v104 official 7zip archives. I'm kind of rushing here but, it's really good timing for me to push out a new official release. The blocking issues are resolved or close to it, and we need lots of testing of the new major changes. I'm going to consider this a semi-stable testing release and leave links to v103 just in case.
77 lines
1.8 KiB
C++
77 lines
1.8 KiB
C++
auto CPU::DMA::run() -> bool {
|
|
if(!active || waiting) return false;
|
|
|
|
transfer();
|
|
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
|
|
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
|
|
return true;
|
|
}
|
|
|
|
auto CPU::DMA::transfer() -> void {
|
|
uint seek = size ? 4 : 2;
|
|
uint mode = size ? Word : Half;
|
|
mode |= latch.length == length ? Nonsequential : Sequential;
|
|
|
|
if(mode & Nonsequential) {
|
|
if((source & 0x0800'0000) && (target & 0x0800'0000)) {
|
|
//ROM -> ROM transfer
|
|
} else {
|
|
cpu.idle();
|
|
cpu.idle();
|
|
}
|
|
}
|
|
|
|
if(latch.source < 0x0200'0000) {
|
|
cpu.idle(); //cannot access BIOS
|
|
} else {
|
|
uint32 addr = latch.source;
|
|
if(mode & Word) addr &= ~3;
|
|
if(mode & Half) addr &= ~1;
|
|
data = cpu.get(mode, addr);
|
|
}
|
|
|
|
if(latch.target < 0x0200'0000) {
|
|
cpu.idle(); //cannot access BIOS
|
|
} else {
|
|
uint32 addr = latch.target;
|
|
if(mode & Word) addr &= ~3;
|
|
if(mode & Half) addr &= ~1;
|
|
cpu.set(mode, addr, data);
|
|
}
|
|
|
|
switch(sourceMode) {
|
|
case 0: latch.source += seek; break;
|
|
case 1: latch.source -= seek; break;
|
|
}
|
|
|
|
switch(targetMode) {
|
|
case 0: latch.target += seek; break;
|
|
case 1: latch.target -= seek; break;
|
|
case 3: latch.target += seek; break;
|
|
}
|
|
|
|
if(--latch.length == 0) {
|
|
active = false;
|
|
if(targetMode == 3) latch.target = target;
|
|
if(repeat == 1) latch.length = length;
|
|
if(repeat == 0) enable = false;
|
|
}
|
|
}
|
|
|
|
auto CPU::dmaVblank() -> void {
|
|
for(auto& dma : this->dma) {
|
|
if(dma.enable && dma.timingMode == 1) dma.active = true;
|
|
}
|
|
}
|
|
|
|
auto CPU::dmaHblank() -> void {
|
|
for(auto& dma : this->dma) {
|
|
if(dma.enable && dma.timingMode == 2) dma.active = true;
|
|
}
|
|
}
|
|
|
|
auto CPU::dmaHDMA() -> void {
|
|
auto& dma = this->dma[3];
|
|
if(dma.enable && dma.timingMode == 3) dma.active = true;
|
|
}
|