1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-04-09 15:39:08 +00:00

Takes a shot a set_state.

This commit is contained in:
Thomas Harte 2020-03-29 22:50:30 -04:00
parent 1810ef60be
commit 4f2ebad8e0
2 changed files with 42 additions and 8 deletions

View File

@ -163,7 +163,7 @@ class ProcessorBase: public ProcessorStorage {
*/
struct ExecutionState: public Reflection::StructImpl<Registers> {
ReflectableEnum(Phase,
Instruction, Stopped, Waiting, Jammed
Instruction, Stopped, Waiting, Jammed, Ready
);
/// Current executon phase, e.g. standard instruction flow or responding to an IRQ.

View File

@ -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];
}