diff --git a/Processors/6502/6502.hpp b/Processors/6502/6502.hpp index 067399fbd..ac5e2e486 100644 --- a/Processors/6502/6502.hpp +++ b/Processors/6502/6502.hpp @@ -163,7 +163,7 @@ class ProcessorBase: public ProcessorStorage { */ struct ExecutionState: public Reflection::StructImpl { ReflectableEnum(Phase, - Instruction, Stopped, Waiting, Jammed + Instruction, Stopped, Waiting, Jammed, Ready ); /// Current executon phase, e.g. standard instruction flow or responding to an IRQ. diff --git a/Processors/6502/Implementation/6502Base.cpp b/Processors/6502/Implementation/6502Base.cpp index 7e4e677e3..fee80c91e 100644 --- a/Processors/6502/Implementation/6502Base.cpp +++ b/Processors/6502/Implementation/6502Base.cpp @@ -65,7 +65,9 @@ ProcessorBase::State ProcessorBase::get_state() { state.execution_state.operand = operand_; state.execution_state.address = address_.full; state.execution_state.next_address = next_address_.full; - if(is_jammed_) { + if(ready_is_active_) { + state.execution_state.phase = State::ExecutionState::Phase::Ready; + } else if(is_jammed_) { state.execution_state.phase = State::ExecutionState::Phase::Jammed; } else if(wait_is_active_) { state.execution_state.phase = State::ExecutionState::Phase::Waiting; @@ -73,13 +75,45 @@ ProcessorBase::State ProcessorBase::get_state() { state.execution_state.phase = State::ExecutionState::Phase::Stopped; } else { state.execution_state.phase = State::ExecutionState::Phase::Instruction; - - const auto micro_offset = size_t(scheduled_program_counter_ - &operations_[0][0]); - const auto list_length = sizeof(InstructionList) / sizeof(MicroOp); - - state.execution_state.micro_program = int(micro_offset / list_length); - state.execution_state.micro_program_offset = int(micro_offset % list_length); } + const auto micro_offset = size_t(scheduled_program_counter_ - &operations_[0][0]); + const auto list_length = sizeof(InstructionList) / sizeof(MicroOp); + + state.execution_state.micro_program = int(micro_offset / list_length); + state.execution_state.micro_program_offset = int(micro_offset % list_length); + return state; } + +void ProcessorBase::set_state(const State &state) { + // Grab registers. + pc_.full = state.registers.program_counter; + s_ = state.registers.stack_pointer; + set_flags(state.registers.flags); + a_ = state.registers.a; + x_ = state.registers.x; + y_ = state.registers.y; + + // Grab other inputs. + ready_line_is_enabled_ = state.inputs.ready; + set_irq_line(state.inputs.irq); + set_nmi_line(state.inputs.nmi); + set_reset_line(state.inputs.reset); + + // Set execution state. + ready_is_active_ = is_jammed_ = wait_is_active_ = stop_is_active_ = false; + switch(state.execution_state.phase) { + case State::ExecutionState::Phase::Ready: ready_is_active_ = true; break; + case State::ExecutionState::Phase::Jammed: is_jammed_ = true; break; + case State::ExecutionState::Phase::Stopped: stop_is_active_ = true; break; + case State::ExecutionState::Phase::Waiting: wait_is_active_ = true; break; + case State::ExecutionState::Phase::Instruction: break; + } + + operation_ = state.execution_state.operation; + operand_ = state.execution_state.operand; + address_.full = state.execution_state.address; + next_address_.full = state.execution_state.next_address; + scheduled_program_counter_ = &operations_[state.execution_state.micro_program][state.execution_state.micro_program_offset]; +}