Skip to content

Commit

Permalink
arm7tdmi, gba: IRQ timing improvements (ares-emulator#1702)
Browse files Browse the repository at this point in the history
- Adds 1-cycle latch for IME register, similarly to IE and IF
- IRQ line is now checked between pipeline flush and instruction fetch
  • Loading branch information
png183 authored Nov 21, 2024
1 parent a0d8ce2 commit de2d7d8
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 12 deletions.
4 changes: 3 additions & 1 deletion ares/component/processor/arm7tdmi/instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ auto ARM7TDMI::instruction() -> void {
pipeline.fetch.instruction = read(Prefetch | size | Nonsequential, pipeline.fetch.address);
fetch();
}

n1 irqRaised = irq;
fetch();

if(irq && !cpsr().i) {
if(irqRaised && !cpsr().i) {
exception(PSR::IRQ, 0x18);
if(pipeline.execute.thumb) r(14).data += 2;
return;
Expand Down
7 changes: 3 additions & 4 deletions ares/gba/cpu/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ auto CPU::unload() -> void {
}

auto CPU::main() -> void {
ARM7TDMI::irq = irq.synchronizer[0];

if(stopped()) {
if(!keypad.conditionMet) {
stepIRQ();
Expand Down Expand Up @@ -75,10 +73,11 @@ auto CPU::setInterruptFlag(u32 source) -> void {
}

inline auto CPU::stepIRQ() -> void {
irq.synchronizer[0] = irq.synchronizer[1];
irq.synchronizer[1] = irq.ime && (irq.enable[0] & irq.flag[0]);
ARM7TDMI::irq = irq.synchronizer;
irq.synchronizer = irq.ime[0] && (irq.enable[0] & irq.flag[0]);
irq.enable[0] = irq.enable[1];
irq.flag[0] = irq.flag[1];
irq.ime[0] = irq.ime[1];
}

auto CPU::step(u32 clocks) -> void {
Expand Down
4 changes: 2 additions & 2 deletions ares/gba/cpu/cpu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ struct CPU : ARM7TDMI, Thread, IO {
} joybus;

struct IRQ {
n1 ime;
n1 synchronizer[2];
n1 ime[2];
n1 synchronizer;
n16 enable[2];
n16 flag[2];
} irq;
Expand Down
4 changes: 2 additions & 2 deletions ares/gba/cpu/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ auto CPU::readIO(n32 address) -> n8 {
case 0x0400'0207: return 0;

//IME
case 0x0400'0208: return irq.ime;
case 0x0400'0208: return irq.ime[0];
case 0x0400'0209: return 0;

//zero
Expand Down Expand Up @@ -442,7 +442,7 @@ auto CPU::writeIO(n32 address, n8 data) -> void {
return;

//IME
case 0x0400'0208: irq.ime = data.bit(0); return;
case 0x0400'0208: irq.ime[1] = data.bit(0); return;
case 0x0400'0209: return;

//POSTFLG, HALTCNT
Expand Down
4 changes: 2 additions & 2 deletions ares/gba/cpu/serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ auto CPU::serialize(serializer& s) -> void {
s(joybus.sendFlag);
s(joybus.generalFlag);

s(irq.ime);
for(auto& flag : irq.synchronizer) s(flag);
for(auto& flag : irq.ime) s(flag);
s(irq.synchronizer);
for(auto& flag : irq.enable) s(flag);
for(auto& flag : irq.flag) s(flag);

Expand Down
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";
static const string SerializerVersion = "v141.1";

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

0 comments on commit de2d7d8

Please sign in to comment.