Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
png183 authored and LukeUsher committed Feb 10, 2025
1 parent 32e5894 commit 9f44460
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 58 deletions.
46 changes: 26 additions & 20 deletions ares/gba/cartridge/cartridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,30 +113,36 @@ auto Cartridge::power() -> void {

#define RAM_ANALYZE

auto Cartridge::read(u32 mode, n32 address) -> n32 {
if(address < 0x0e00'0000) {
if(has.eeprom && (address & eeprom.mask) == eeprom.test) return eeprom.read();
return mrom.read(mode, address);
} else {
n32 word = 0xff;
if(has.sram) word = sram.read(address);
if(has.flash) word = flash.read(address);
word |= word << 8;
word |= word << 16;
auto Cartridge::readRom(u32 mode, n32 address) -> n32 {
if(mode & Word) {
n32 word = 0;
word |= readRom(mode & ~Word | Half, (address & ~3) + 0) << 0;
word |= readRom(mode & ~Word | Half, (address & ~3) + 2) << 16;
return word;
}

if(has.eeprom && (address & eeprom.mask) == eeprom.test) return eeprom.read();
return mrom.read(mode, address);
}

auto Cartridge::write(u32 mode, n32 address, n32 word) -> void {
if(address < 0x0e00'0000) {
if(has.eeprom && (address & eeprom.mask) == eeprom.test) return eeprom.write(word & 1);
return mrom.write(mode, address, word);
} else {
if(mode & Word) word = word >> (8 * (address & 3));
if(mode & Half) word = word >> (8 * (address & 1));
if(has.sram) return sram.write(address, word);
if(has.flash) return flash.write(address, word);
}
auto Cartridge::readBackup(u32 mode, n32 address) -> n32 {
n32 word = 0xff;
if(has.sram) word = sram.read(address);
if(has.flash) word = flash.read(address);
word *= 0x01010101;
return word;
}

auto Cartridge::writeRom(u32 mode, n32 address, n32 word) -> void {
if(has.eeprom && (address & eeprom.mask) == eeprom.test) return eeprom.write(word & 1);
return mrom.write(mode, address, word);
}

auto Cartridge::writeBackup(u32 mode, n32 address, n32 word) -> void {
if(mode & Word) word = word >> (8 * (address & 3));
if(mode & Half) word = word >> (8 * (address & 1));
if(has.sram) return sram.write(address, word);
if(has.flash) return flash.write(address, word);
}

}
6 changes: 4 additions & 2 deletions ares/gba/cartridge/cartridge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ struct Cartridge {
auto save() -> void;
auto power() -> void;

auto read(u32 mode, n32 address) -> n32;
auto write(u32 mode, n32 address, n32 word) -> void;
auto readRom(u32 mode, n32 address) -> n32;
auto readBackup(u32 mode, n32 address) -> n32;
auto writeRom(u32 mode, n32 address, n32 word) -> void;
auto writeBackup(u32 mode, n32 address, n32 word) -> void;

auto serialize(serializer&) -> void;

Expand Down
3 changes: 1 addition & 2 deletions ares/gba/cartridge/memory.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
struct MROM {
//mrom.cpp
auto read(u32 mode, n32 address) -> n32;
auto readBus(u32 mode, n32 address) -> n16;
auto read(u32 mode, n32 address) -> n16;
auto write(u32 mode, n32 address, n32 word) -> void;

//serialization.cpp
Expand Down
16 changes: 2 additions & 14 deletions ares/gba/cartridge/mrom.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@
auto Cartridge::MROM::read(u32 mode, n32 address) -> n32 {
if(mode & Word) {
n32 word = 0;
word |= readBus(mode & ~Word | Half, (address & ~3) + 0) << 0;
word |= readBus(mode & ~Word | Half, (address & ~3) + 2) << 16;
return word;
}

return readBus(mode, address);
}

auto Cartridge::MROM::readBus(u32 mode, n32 address) -> n16 {
auto Cartridge::MROM::read(u32 mode, n32 address) -> n16 {
address &= 0x01ff'ffff;

if(address >= size) {
Expand All @@ -20,8 +9,7 @@ auto Cartridge::MROM::readBus(u32 mode, n32 address) -> n16 {
if(mode & Half) address &= ~1;
auto p = data + address;
if(mode & Half) return p[0] << 0 | p[1] << 8;
if(mode & Byte) return p[0] << 0;
return 0; //should never occur
return p[0] << 0;
}

auto Cartridge::MROM::write(u32 mode, n32 address, n32 word) -> void {
Expand Down
22 changes: 18 additions & 4 deletions ares/gba/cpu/bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,26 @@ inline auto CPU::getBus(u32 mode, n32 address) -> n32 {
word = ppu.readOAM(mode, address);
break;

case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d:
if(mode & Prefetch && wait.prefetch) {
prefetchSync(address);
prefetchStep(1);
word = prefetchRead();
if(mode & Word) word |= prefetchRead() << 16;
} else {
if(context.dmaActive) context.dmaRomAccess = true;
if constexpr(!UseDebugger) prefetchReset();
if constexpr(!UseDebugger) step(waitCartridge(mode, address));
word = cartridge.read(mode, address);
word = cartridge.readRom(mode, address);
}
break;

case 0x0e: case 0x0f:
if constexpr(!UseDebugger) prefetchReset();
if constexpr(!UseDebugger) step(waitCartridge(mode, address));
word = cartridge.readBackup(mode, address);
break;

default:
if constexpr(!UseDebugger) prefetchStep(1);
return openBus.get(mode, address);
Expand Down Expand Up @@ -117,10 +124,17 @@ auto CPU::set(u32 mode, n32 address, n32 word) -> void {
ppu.writeOAM(mode, address, word);
break;

case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d:
if(context.dmaActive) context.dmaRomAccess = true;
prefetchReset();
step(waitCartridge(mode, address));
cartridge.writeRom(mode, address, word);
break;

case 0x0e: case 0x0f:
prefetchReset();
step(waitCartridge(mode, address));
cartridge.write(mode, address, word);
cartridge.writeBackup(mode, address, word);
break;

default:
Expand Down
9 changes: 8 additions & 1 deletion ares/gba/cpu/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,18 @@ auto CPU::main() -> void {
auto CPU::dmaRun() -> void {
if(!context.dmaActive && !context.busLocked) {
context.dmaActive = true;
while(dma[0].run() | dma[1].run() | dma[2].run() | dma[3].run());
while(true) {
if(dma[0].run()) continue;
if(dma[1].run()) continue;
if(dma[2].run()) continue;
if(dma[3].run()) continue;
break;
}
if(context.dmaRan) {
idle();
context.dmaRan = false;
context.dmaRomAccess = false;
context.dmaActiveChannel = 0; //assign burst to a channel that cannot access ROM
}
context.dmaActive = false;
}
Expand Down
1 change: 1 addition & 0 deletions ares/gba/cpu/cpu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ struct CPU : ARM7TDMI, Thread, IO {
n1 dmaRan;
n1 dmaRomAccess;
n1 dmaActive;
n2 dmaActiveChannel;
n1 timerLatched;
n1 busLocked;
} context;
Expand Down
25 changes: 12 additions & 13 deletions ares/gba/cpu/dma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,39 @@ inline auto CPU::DMA::run() -> bool {
auto CPU::DMA::transfer() -> void {
u32 seek = size ? 4 : 2;
u32 mode = size ? Word : Half;
mode |= latch.length() == length() ? Nonsequential : Sequential;

if(!cpu.context.dmaRan) {
cpu.context.dmaRan = true;
cpu.idle();
}

if(cpu.context.dmaActiveChannel != id) {
//channel has switched - new burst transfer must be started
cpu.context.dmaRomAccess = 0;
cpu.context.dmaActiveChannel = id;
}

if(latch.source() < 0x0200'0000) {
cpu.idle(); //cannot access BIOS
} else {
n32 addr = latch.source();
if(mode & Word) addr &= ~3;
if(mode & Half) addr &= ~1;
if(addr & 0x0800'0000) cpu.context.dmaRomAccess = true;
latch.data = cpu.get(mode, addr);
u32 sequential = Nonsequential;
if(cpu.context.dmaRomAccess) sequential = Sequential;
latch.data = cpu.get(mode | sequential, addr);
if(mode & Half) latch.data |= latch.data << 16;
}

if(mode & Nonsequential) {
if((source() & 0x0800'0000) && (target() & 0x0800'0000)) {
//ROM -> ROM transfer
mode |= Sequential;
mode ^= Nonsequential;
}
}

if(latch.target() < 0x0200'0000) {
cpu.idle(); //cannot access BIOS
} else {
n32 addr = latch.target();
if(mode & Word) addr &= ~3;
if(mode & Half) addr &= ~1;
if(addr & 0x0800'0000) cpu.context.dmaRomAccess = true;
cpu.set(mode, addr, latch.data >> (addr & 2) * 8);
u32 sequential = Nonsequential;
if(cpu.context.dmaRomAccess) sequential = Sequential;
cpu.set(mode | sequential, addr, latch.data >> (addr & 2) * 8);
}

switch(sourceMode) {
Expand Down
2 changes: 1 addition & 1 deletion ares/gba/cpu/prefetch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ auto CPU::prefetchStep(u32 clocks) -> void {

while(!prefetch.full() && clocks--) {
if(--prefetch.wait) continue;
prefetch.slot[prefetch.load >> 1 & 7] = cartridge.read(Half, prefetch.load);
prefetch.slot[prefetch.load >> 1 & 7] = cartridge.readRom(Half, prefetch.load);
prefetch.load += 2;
prefetch.wait = waitCartridge(Half | Sequential, prefetch.load);
}
Expand Down
1 change: 1 addition & 0 deletions ares/gba/cpu/serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ auto CPU::serialize(serializer& s) -> void {
s(context.dmaRan);
s(context.dmaRomAccess);
s(context.dmaActive);
s(context.dmaActiveChannel);
s(context.timerLatched);
s(context.busLocked);
}
2 changes: 1 addition & 1 deletion ares/gba/system/serialization.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
static const string SerializerVersion = "v141.6";
static const string SerializerVersion = "v142";

auto System::serialize(bool synchronize) -> serializer {
if(synchronize) scheduler.enter(Scheduler::Mode::Synchronize);
Expand Down

0 comments on commit 9f44460

Please sign in to comment.