diff --git a/libsnes/bsnes/snes/alt/cpu/cpu.cpp b/libsnes/bsnes/snes/alt/cpu/cpu.cpp index 9b67166be0..edaf423425 100644 --- a/libsnes/bsnes/snes/alt/cpu/cpu.cpp +++ b/libsnes/bsnes/snes/alt/cpu/cpu.cpp @@ -72,7 +72,9 @@ void CPU::enter() { op_irq(); } - op_step(); + if(regs.hang == HangType::Wait) this->op_wai(); + else if (regs.hang == HangType::Stop) this->op_stp(); + else op_step(); } } diff --git a/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp b/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp index 68d1bf91d9..f4e87f75d3 100644 --- a/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp +++ b/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp @@ -72,18 +72,22 @@ L rd.h = op_readlong(vectorN + 1); } void CPUcore::op_stp() { + regs.hang = HangType::Stop; while(regs.wai = true) { L op_io(); scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } + regs.hang = HangType::None; } void CPUcore::op_wai() { regs.wai = true; + regs.hang = HangType::Wait; while(regs.wai) { L op_io(); scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } + regs.hang = HangType::None; op_io(); } diff --git a/libsnes/bsnes/snes/cpu/core/registers.hpp b/libsnes/bsnes/snes/cpu/core/registers.hpp index adcf797fd8..46fea03208 100644 --- a/libsnes/bsnes/snes/cpu/core/registers.hpp +++ b/libsnes/bsnes/snes/cpu/core/registers.hpp @@ -1,3 +1,5 @@ +enum class HangType: unsigned { None, Wait, Stop }; + struct flag_t { bool n, v, m, x, d, i, z, c; @@ -73,11 +75,14 @@ struct regs_t { bool irq; //IRQ pin (0 = low, 1 = trigger) bool wai; //raised during wai, cleared after interrupt triggered + uint8 mdr; //memory data register uint16 vector; //interrupt vector address + HangType hang; + regs_t(): - a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0), vector(0) { + a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0), vector(0), hang(HangType::None) { z = 0; } };