diff --git a/src/cpu/arm/software_interrupt.zig b/src/cpu/arm/software_interrupt.zig index fb41864..8e9dd80 100644 --- a/src/cpu/arm/software_interrupt.zig +++ b/src/cpu/arm/software_interrupt.zig @@ -6,7 +6,7 @@ pub fn armSoftwareInterrupt() InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, _: u32) void { // Copy Values from Current Mode - const r15 = cpu.r[15]; + const ret_addr = cpu.r[15] - 4; const cpsr = cpu.cpsr.raw; // Switch Mode @@ -14,9 +14,10 @@ pub fn armSoftwareInterrupt() InstrFn { cpu.cpsr.t.write(false); // Force ARM Mode cpu.cpsr.i.write(true); // Disable normal interrupts - cpu.r[14] = r15; // Resume Execution + cpu.r[14] = ret_addr; // Resume Execution cpu.spsr.raw = cpsr; // Previous mode CPSR cpu.r[15] = 0x0000_0008; + cpu.pipe.flush(); } }.inner; } diff --git a/src/cpu/thumb/software_interrupt.zig b/src/cpu/thumb/software_interrupt.zig index daa4f34..73f098d 100644 --- a/src/cpu/thumb/software_interrupt.zig +++ b/src/cpu/thumb/software_interrupt.zig @@ -6,7 +6,7 @@ pub fn thumbSoftwareInterrupt() InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, _: u16) void { // Copy Values from Current Mode - const r15 = cpu.r[15]; + const ret_addr = cpu.r[15] - 2; const cpsr = cpu.cpsr.raw; // Switch Mode @@ -14,9 +14,10 @@ pub fn thumbSoftwareInterrupt() InstrFn { cpu.cpsr.t.write(false); // Force ARM Mode cpu.cpsr.i.write(true); // Disable normal interrupts - cpu.r[14] = r15; // Resume Execution + cpu.r[14] = ret_addr; // Resume Execution cpu.spsr.raw = cpsr; // Previous mode CPSR cpu.r[15] = 0x0000_0008; + cpu.pipe.flush(); } }.inner; }