mirror of https://github.com/bsnes-emu/bsnes.git
111 lines
2.9 KiB
C++
111 lines
2.9 KiB
C++
#include <gba/gba.hpp>
|
|
|
|
namespace GameBoyAdvance {
|
|
|
|
CPU cpu;
|
|
#include "prefetch.cpp"
|
|
#include "bus.cpp"
|
|
#include "io.cpp"
|
|
#include "memory.cpp"
|
|
#include "dma.cpp"
|
|
#include "timer.cpp"
|
|
#include "keypad.cpp"
|
|
#include "serialization.cpp"
|
|
|
|
auto CPU::Enter() -> void {
|
|
while(true) scheduler.synchronize(), cpu.main();
|
|
}
|
|
|
|
auto CPU::main() -> void {
|
|
ARM7TDMI::irq = irq.ime && (irq.enable & irq.flag);
|
|
|
|
if(stopped()) {
|
|
if(!(irq.enable & irq.flag & Interrupt::Keypad)) {
|
|
Thread::step(16);
|
|
synchronize(ppu);
|
|
synchronize(apu);
|
|
}
|
|
context.stopped = false;
|
|
}
|
|
|
|
if(halted()) {
|
|
if(!(irq.enable & irq.flag)) {
|
|
return step(16);
|
|
}
|
|
context.halted = false;
|
|
}
|
|
|
|
instruction();
|
|
}
|
|
|
|
auto CPU::step(uint clocks) -> void {
|
|
dma[0].waiting = max(0, dma[0].waiting - (int)clocks);
|
|
dma[1].waiting = max(0, dma[1].waiting - (int)clocks);
|
|
dma[2].waiting = max(0, dma[2].waiting - (int)clocks);
|
|
dma[3].waiting = max(0, dma[3].waiting - (int)clocks);
|
|
|
|
if(!context.dmaActive) {
|
|
context.dmaActive = true;
|
|
while(dma[0].run() | dma[1].run() | dma[2].run() | dma[3].run());
|
|
context.dmaActive = false;
|
|
}
|
|
|
|
for(auto _ : range(clocks)) {
|
|
timer[0].run();
|
|
timer[1].run();
|
|
timer[2].run();
|
|
timer[3].run();
|
|
context.clock++;
|
|
}
|
|
|
|
Thread::step(clocks);
|
|
synchronize(ppu);
|
|
synchronize(apu);
|
|
}
|
|
|
|
auto CPU::power() -> void {
|
|
ARM7TDMI::power();
|
|
create(CPU::Enter, system.frequency());
|
|
|
|
for(auto& byte : iwram) byte = 0x00;
|
|
for(auto& byte : ewram) byte = 0x00;
|
|
|
|
for(auto n : range(4)) dma[n] = {n};
|
|
for(auto n : range(4)) timer[n] = {n};
|
|
serial = {};
|
|
keypad = {};
|
|
joybus = {};
|
|
irq = {};
|
|
wait = {};
|
|
memory = {};
|
|
prefetch = {};
|
|
context = {};
|
|
|
|
dma[0].source.resize(27); dma[0].latch.source.resize(27);
|
|
dma[0].target.resize(27); dma[0].latch.target.resize(27);
|
|
dma[0].length.resize(14); dma[0].latch.length.resize(14);
|
|
|
|
dma[1].source.resize(28); dma[1].latch.source.resize(28);
|
|
dma[1].target.resize(27); dma[1].latch.target.resize(27);
|
|
dma[1].length.resize(14); dma[1].latch.length.resize(14);
|
|
|
|
dma[2].source.resize(28); dma[2].latch.source.resize(28);
|
|
dma[2].target.resize(27); dma[2].latch.target.resize(27);
|
|
dma[2].length.resize(14); dma[2].latch.length.resize(14);
|
|
|
|
dma[3].source.resize(28); dma[3].latch.source.resize(28);
|
|
dma[3].target.resize(28); dma[3].latch.target.resize(28);
|
|
dma[3].length.resize(16); dma[3].latch.length.resize(16);
|
|
|
|
for(uint n = 0x0b0; n <= 0x0df; n++) bus.io[n] = this; //DMA
|
|
for(uint n = 0x100; n <= 0x10f; n++) bus.io[n] = this; //Timers
|
|
for(uint n = 0x120; n <= 0x12b; n++) bus.io[n] = this; //Serial
|
|
for(uint n = 0x130; n <= 0x133; n++) bus.io[n] = this; //Keypad
|
|
for(uint n = 0x134; n <= 0x159; n++) bus.io[n] = this; //Serial
|
|
for(uint n = 0x200; n <= 0x209; n++) bus.io[n] = this; //System
|
|
for(uint n = 0x300; n <= 0x301; n++) bus.io[n] = this; //System
|
|
//0x080-0x083 mirrored via gba/memory/memory.cpp //System
|
|
}
|
|
|
|
}
|