mirror of https://github.com/bsnes-emu/bsnes.git
92 lines
2.4 KiB
C++
92 lines
2.4 KiB
C++
//note: timings are completely unverified
|
|
//due to the ST018 chip design (on-die ROM), testing is nearly impossible
|
|
|
|
auto ArmDSP::_idle() -> void {
|
|
step(1);
|
|
}
|
|
|
|
auto ArmDSP::_read(uint mode, uint32 addr) -> uint32 {
|
|
step(1);
|
|
|
|
static auto memory = [&](const uint8* memory, uint mode, uint32 addr) -> uint32 {
|
|
if(mode & Word) {
|
|
memory += addr & ~3;
|
|
return memory[0] << 0 | memory[1] << 8 | memory[2] << 16 | memory[3] << 24;
|
|
} else if(mode & Byte) {
|
|
return memory[addr];
|
|
} else {
|
|
return 0; //should never occur
|
|
}
|
|
};
|
|
|
|
switch(addr & 0xe000'0000) {
|
|
case 0x0000'0000: return memory(programROM, mode, addr & 0x1ffff);
|
|
case 0x2000'0000: return pipeline.fetch.instruction;
|
|
case 0x4000'0000: break;
|
|
case 0x6000'0000: return 0x40404001;
|
|
case 0x8000'0000: return pipeline.fetch.instruction;
|
|
case 0xa000'0000: return memory(dataROM, mode, addr & 0x7fff);
|
|
case 0xc000'0000: return pipeline.fetch.instruction;
|
|
case 0xe000'0000: return memory(programRAM, mode, addr & 0x3fff);
|
|
}
|
|
|
|
addr &= 0xe000'003f;
|
|
|
|
if(addr == 0x4000'0010) {
|
|
if(bridge.cputoarm.ready) {
|
|
bridge.cputoarm.ready = false;
|
|
return bridge.cputoarm.data;
|
|
}
|
|
}
|
|
|
|
if(addr == 0x4000'0020) {
|
|
return bridge.status();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
auto ArmDSP::_write(uint mode, uint32 addr, uint32 word) -> void {
|
|
step(1);
|
|
|
|
static auto memory = [](uint8* memory, uint mode, uint32 addr, uint32 word) {
|
|
if(mode & Word) {
|
|
memory += addr & ~3;
|
|
*memory++ = word >> 0;
|
|
*memory++ = word >> 8;
|
|
*memory++ = word >> 16;
|
|
*memory++ = word >> 24;
|
|
} else if(mode & Byte) {
|
|
memory += addr;
|
|
*memory++ = word >> 0;
|
|
}
|
|
};
|
|
|
|
switch(addr & 0xe000'0000) {
|
|
case 0x0000'0000: return;
|
|
case 0x2000'0000: return;
|
|
case 0x4000'0000: break;
|
|
case 0x6000'0000: return;
|
|
case 0x8000'0000: return;
|
|
case 0xa000'0000: return;
|
|
case 0xc000'0000: return;
|
|
case 0xe000'0000: return memory(programRAM, mode, addr & 0x3fff, word);
|
|
}
|
|
|
|
addr &= 0xe000'003f;
|
|
word &= 0x0000'00ff;
|
|
|
|
if(addr == 0x4000'0000) {
|
|
bridge.armtocpu.ready = true;
|
|
bridge.armtocpu.data = word;
|
|
}
|
|
|
|
if(addr == 0x4000'0010) bridge.signal = true;
|
|
|
|
if(addr == 0x4000'0020) bridge.timerlatch.byte(0) = word;
|
|
if(addr == 0x4000'0024) bridge.timerlatch.byte(1) = word;
|
|
if(addr == 0x4000'0028) bridge.timerlatch.byte(2) = word;
|
|
|
|
if(addr == 0x4000'002c) bridge.timer = bridge.timerlatch;
|
|
}
|