mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Attempts to preserve scheduled_program_counter_.
This commit is contained in:
parent
4f619de675
commit
11d936331d
@ -127,8 +127,6 @@ class ProcessorStorage {
|
|||||||
InstructionPage() : r_step(1), is_indexed(false) {}
|
InstructionPage() : r_step(1), is_indexed(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef MicroOp InstructionTable[256][30];
|
|
||||||
|
|
||||||
ProcessorStorage();
|
ProcessorStorage();
|
||||||
void install_default_instruction_set();
|
void install_default_instruction_set();
|
||||||
|
|
||||||
@ -223,6 +221,7 @@ class ProcessorStorage {
|
|||||||
carry_result_ = flags;
|
carry_result_ = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef MicroOp InstructionTable[256][30];
|
||||||
virtual void assemble_page(InstructionPage &target, InstructionTable &table, bool add_offsets) = 0;
|
virtual void assemble_page(InstructionPage &target, InstructionTable &table, bool add_offsets) = 0;
|
||||||
virtual void copy_program(const MicroOp *source, std::vector<MicroOp> &destination) = 0;
|
virtual void copy_program(const MicroOp *source, std::vector<MicroOp> &destination) = 0;
|
||||||
|
|
||||||
|
@ -45,6 +45,55 @@ State::State(const ProcessorBase &src): State() {
|
|||||||
execution_state.operation = src.operation_;
|
execution_state.operation = src.operation_;
|
||||||
execution_state.flag_adjustment_history = src.flag_adjustment_history_;
|
execution_state.flag_adjustment_history = src.flag_adjustment_history_;
|
||||||
execution_state.pc_increment = src.pc_increment_;
|
execution_state.pc_increment = src.pc_increment_;
|
||||||
|
execution_state.refresh_address = src.refresh_addr_.full;
|
||||||
|
execution_state.half_cycles_into_step = src.number_of_cycles_.as<int>();
|
||||||
|
|
||||||
|
// Search for the current holder of the scheduled_program_counter_.
|
||||||
|
#define ContainedBy(x) (src.scheduled_program_counter_ >= &src.x[0]) && (src.scheduled_program_counter_ < &src.x[src.x.size()])
|
||||||
|
#define Populate(x, y) \
|
||||||
|
execution_state.phase = ExecutionState::Phase::x; \
|
||||||
|
execution_state.steps_into_phase = int(src.scheduled_program_counter_ - &src.y[0]);
|
||||||
|
|
||||||
|
if(ContainedBy(conditional_call_untaken_program_)) {
|
||||||
|
Populate(UntakenConditionalCall, conditional_call_untaken_program_);
|
||||||
|
} else if(ContainedBy(reset_program_)) {
|
||||||
|
Populate(Reset, reset_program_);
|
||||||
|
} else if(ContainedBy(irq_program_[0])) {
|
||||||
|
Populate(IRQMode0, irq_program_[0]);
|
||||||
|
} else if(ContainedBy(irq_program_[1])) {
|
||||||
|
Populate(IRQMode1, irq_program_[1]);
|
||||||
|
} else if(ContainedBy(irq_program_[2])) {
|
||||||
|
Populate(IRQMode2, irq_program_[2]);
|
||||||
|
} else if(ContainedBy(nmi_program_)) {
|
||||||
|
Populate(NMI, nmi_program_);
|
||||||
|
} else {
|
||||||
|
if(src.current_instruction_page_ == &src.base_page_) {
|
||||||
|
execution_state.instruction_page = 0;
|
||||||
|
} else if(src.current_instruction_page_ == &src.ed_page_) {
|
||||||
|
execution_state.instruction_page = 0xed;
|
||||||
|
} else if(src.current_instruction_page_ == &src.fd_page_) {
|
||||||
|
execution_state.instruction_page = 0xfd;
|
||||||
|
} else if(src.current_instruction_page_ == &src.dd_page_) {
|
||||||
|
execution_state.instruction_page = 0xdd;
|
||||||
|
} else if(src.current_instruction_page_ == &src.cb_page_) {
|
||||||
|
execution_state.instruction_page = 0xcb;
|
||||||
|
} else if(src.current_instruction_page_ == &src.fdcb_page_) {
|
||||||
|
execution_state.instruction_page = 0xfdcb;
|
||||||
|
} else if(src.current_instruction_page_ == &src.ddcb_page_) {
|
||||||
|
execution_state.instruction_page = 0xddcb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ContainedBy(current_instruction_page_->fetch_decode_execute)) {
|
||||||
|
Populate(FetchDecode, current_instruction_page_->fetch_decode_execute);
|
||||||
|
} else {
|
||||||
|
// There's no need to determine which opcode because that knowledge is already
|
||||||
|
// contained in the dedicated opcode field.
|
||||||
|
Populate(Operation, current_instruction_page_->instructions[src.operation_]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef Populate
|
||||||
|
#undef ContainedBy
|
||||||
}
|
}
|
||||||
|
|
||||||
void State::apply(ProcessorBase &target) {
|
void State::apply(ProcessorBase &target) {
|
||||||
@ -82,8 +131,30 @@ void State::apply(ProcessorBase &target) {
|
|||||||
target.operation_ = execution_state.operation;
|
target.operation_ = execution_state.operation;
|
||||||
target.flag_adjustment_history_ = execution_state.flag_adjustment_history;
|
target.flag_adjustment_history_ = execution_state.flag_adjustment_history;
|
||||||
target.pc_increment_ = execution_state.pc_increment;
|
target.pc_increment_ = execution_state.pc_increment;
|
||||||
|
target.refresh_addr_.full = execution_state.refresh_address;
|
||||||
|
target.number_of_cycles_ = HalfCycles(execution_state.half_cycles_into_step);
|
||||||
|
|
||||||
// TODO: scheduled_program_counter_ and number_of_cycles_.
|
switch(execution_state.instruction_page) {
|
||||||
|
default: target.current_instruction_page_ = &target.base_page_; break;
|
||||||
|
case 0xed: target.current_instruction_page_ = &target.ed_page_; break;
|
||||||
|
case 0xdd: target.current_instruction_page_ = &target.dd_page_; break;
|
||||||
|
case 0xcb: target.current_instruction_page_ = &target.cb_page_; break;
|
||||||
|
case 0xfd: target.current_instruction_page_ = &target.fd_page_; break;
|
||||||
|
case 0xfdcb: target.current_instruction_page_ = &target.fdcb_page_; break;
|
||||||
|
case 0xddcb: target.current_instruction_page_ = &target.ddcb_page_; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(execution_state.phase) {
|
||||||
|
case ExecutionState::Phase::UntakenConditionalCall: target.scheduled_program_counter_ = &target.conditional_call_untaken_program_[0]; break;
|
||||||
|
case ExecutionState::Phase::Reset: target.scheduled_program_counter_ = &target.reset_program_[0]; break;
|
||||||
|
case ExecutionState::Phase::IRQMode0: target.scheduled_program_counter_ = &target.irq_program_[0][0]; break;
|
||||||
|
case ExecutionState::Phase::IRQMode1: target.scheduled_program_counter_ = &target.irq_program_[1][0]; break;
|
||||||
|
case ExecutionState::Phase::IRQMode2: target.scheduled_program_counter_ = &target.irq_program_[2][0]; break;
|
||||||
|
case ExecutionState::Phase::NMI: target.scheduled_program_counter_ = &target.nmi_program_[0]; break;
|
||||||
|
case ExecutionState::Phase::FetchDecode: target.scheduled_program_counter_ = &target.current_instruction_page_->fetch_decode_execute[0]; break;
|
||||||
|
case ExecutionState::Phase::Operation: target.scheduled_program_counter_ = target.current_instruction_page_->instructions[target.operation_]; break;
|
||||||
|
}
|
||||||
|
target.scheduled_program_counter_ += execution_state.steps_into_phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Boilerplate follows here, to establish 'reflection'.
|
// Boilerplate follows here, to establish 'reflection'.
|
||||||
@ -127,6 +198,13 @@ State::ExecutionState::ExecutionState() {
|
|||||||
DeclareField(temp16);
|
DeclareField(temp16);
|
||||||
DeclareField(flag_adjustment_history);
|
DeclareField(flag_adjustment_history);
|
||||||
DeclareField(pc_increment);
|
DeclareField(pc_increment);
|
||||||
|
DeclareField(refresh_address);
|
||||||
|
|
||||||
|
AnnounceEnum(Phase);
|
||||||
|
DeclareField(phase);
|
||||||
|
DeclareField(half_cycles_into_step);
|
||||||
|
DeclareField(steps_into_phase);
|
||||||
|
DeclareField(instruction_page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +46,10 @@ struct State: public Reflection::StructImpl<State> {
|
|||||||
related to an access cycle.
|
related to an access cycle.
|
||||||
*/
|
*/
|
||||||
struct Inputs: public Reflection::StructImpl<Inputs> {
|
struct Inputs: public Reflection::StructImpl<Inputs> {
|
||||||
bool irq;
|
bool irq = false;
|
||||||
bool nmi;
|
bool nmi = false;
|
||||||
bool bus_request;
|
bool bus_request = false;
|
||||||
bool wait;
|
bool wait = false;
|
||||||
|
|
||||||
Inputs();
|
Inputs();
|
||||||
} inputs;
|
} inputs;
|
||||||
@ -69,6 +69,17 @@ struct State: public Reflection::StructImpl<State> {
|
|||||||
uint16_t temp16;
|
uint16_t temp16;
|
||||||
unsigned int flag_adjustment_history;
|
unsigned int flag_adjustment_history;
|
||||||
uint16_t pc_increment;
|
uint16_t pc_increment;
|
||||||
|
uint16_t refresh_address;
|
||||||
|
|
||||||
|
ReflectableEnum(Phase,
|
||||||
|
UntakenConditionalCall, Reset, IRQMode0, IRQMode1, IRQMode2,
|
||||||
|
NMI, FetchDecode, Operation
|
||||||
|
);
|
||||||
|
|
||||||
|
Phase phase;
|
||||||
|
int half_cycles_into_step;
|
||||||
|
int steps_into_phase;
|
||||||
|
uint16_t instruction_page = 0;
|
||||||
|
|
||||||
ExecutionState();
|
ExecutionState();
|
||||||
} execution_state;
|
} execution_state;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user