mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-10 08:04:45 +00:00
Marginally refactor, to avoid repetition of read/write branch.
This commit is contained in:
parent
42927c1e32
commit
0b19bbff8d
@ -29,6 +29,37 @@ void Executor<model, BusHandler>::reset() {
|
||||
program_counter_.l = bus_handler_.template read<uint32_t>(4);
|
||||
}
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
void Executor<model, BusHandler>::read(DataSize size, uint32_t address, CPU::SlicedInt32 &value) {
|
||||
switch(size) {
|
||||
case DataSize::Byte:
|
||||
value.b = bus_handler_.template read<uint8_t>(address);
|
||||
break;
|
||||
case DataSize::Word:
|
||||
value.w = bus_handler_.template read<uint16_t>(address);
|
||||
break;
|
||||
case DataSize::LongWord:
|
||||
value.l = bus_handler_.template read<uint32_t>(address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
void Executor<model, BusHandler>::write(DataSize size, uint32_t address, CPU::SlicedInt32 value) {
|
||||
switch(size) {
|
||||
case DataSize::Byte:
|
||||
bus_handler_.template write<uint8_t>(address, value.b);
|
||||
break;
|
||||
case DataSize::Word:
|
||||
bus_handler_.template write<uint16_t>(address, value.w);
|
||||
break;
|
||||
case DataSize::LongWord:
|
||||
bus_handler_.template write<uint32_t>(address, value.l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
typename Executor<model, BusHandler>::EffectiveAddress Executor<model, BusHandler>::calculate_effective_address(Preinstruction instruction, uint16_t opcode, int index) {
|
||||
EffectiveAddress ea;
|
||||
@ -42,15 +73,20 @@ typename Executor<model, BusHandler>::EffectiveAddress Executor<model, BusHandle
|
||||
// Operands that don't have effective addresses, which are returned as values.
|
||||
//
|
||||
case AddressingMode::DataRegisterDirect:
|
||||
ea.value = data_[instruction.reg(index)];
|
||||
ea.value.l = data_[instruction.reg(index)];
|
||||
ea.is_address = false;
|
||||
break;
|
||||
case AddressingMode::AddressRegisterDirect:
|
||||
ea.value = address_[instruction.reg(index)];
|
||||
ea.value.l = address_[instruction.reg(index)];
|
||||
ea.is_address = false;
|
||||
break;
|
||||
case AddressingMode::Quick:
|
||||
ea.value = quick(instruction.operation, opcode);
|
||||
ea.value.l = quick(instruction.operation, opcode);
|
||||
ea.is_address = false;
|
||||
break;
|
||||
case AddressingMode::ImmediateData:
|
||||
read(instruction.size(), program_counter_.l, ea.value.l);
|
||||
program_counter_.l += (instruction.size() == DataSize::LongWord) ? 4 : 2;
|
||||
ea.is_address = false;
|
||||
break;
|
||||
|
||||
@ -79,6 +115,8 @@ void Executor<model, BusHandler>::run_for_instructions(int count) {
|
||||
const Preinstruction instruction = decoder_.decode(opcode);
|
||||
program_counter_.l += 2;
|
||||
|
||||
// TODO: check privilege level.
|
||||
|
||||
// Temporary storage.
|
||||
CPU::SlicedInt32 operand_[2];
|
||||
EffectiveAddress effective_address_[2];
|
||||
@ -91,8 +129,8 @@ void Executor<model, BusHandler>::run_for_instructions(int count) {
|
||||
// TODO: this work should be performed by a full Decoder, so that it can be cached.
|
||||
effective_address_[0] = calculate_effective_address(instruction, opcode, 0);
|
||||
effective_address_[1] = calculate_effective_address(instruction, opcode, 1);
|
||||
operand_[0].l = effective_address_[0].value;
|
||||
operand_[1].l = effective_address_[1].value;
|
||||
operand_[0] = effective_address_[0].value;
|
||||
operand_[1] = effective_address_[1].value;
|
||||
|
||||
// Obtain the appropriate sequence.
|
||||
//
|
||||
@ -114,18 +152,7 @@ void Executor<model, BusHandler>::run_for_instructions(int count) {
|
||||
if(!effective_address_[index].is_address) continue;
|
||||
|
||||
// TODO: potential bus alignment exception.
|
||||
|
||||
switch(instruction.size()) {
|
||||
case DataSize::Byte:
|
||||
operand_[index].l = bus_handler_.template read<uint8_t>(effective_address_[index].value);
|
||||
break;
|
||||
case DataSize::Word:
|
||||
operand_[index].l = bus_handler_.template read<uint16_t>(effective_address_[index].value);
|
||||
break;
|
||||
case DataSize::LongWord:
|
||||
operand_[index].l = bus_handler_.template read<uint32_t>(effective_address_[index].value);
|
||||
break;
|
||||
}
|
||||
read(instruction.size(), effective_address_[index].value, operand_[index]);
|
||||
} break;
|
||||
|
||||
case Step::Perform:
|
||||
@ -154,18 +181,7 @@ void Executor<model, BusHandler>::run_for_instructions(int count) {
|
||||
}
|
||||
|
||||
// TODO: potential bus alignment exception.
|
||||
|
||||
switch(instruction.size()) {
|
||||
case DataSize::Byte:
|
||||
bus_handler_.write(effective_address_[index].value, operand_[index].b);
|
||||
break;
|
||||
case DataSize::Word:
|
||||
bus_handler_.write(effective_address_[index].value, operand_[index].w);
|
||||
break;
|
||||
case DataSize::LongWord:
|
||||
bus_handler_.write(effective_address_[index].value, operand_[index].l);
|
||||
break;
|
||||
}
|
||||
write(instruction.size(), effective_address_[index].value, operand_[index]);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
@ -43,11 +43,14 @@ template <Model model, typename BusHandler> class Executor {
|
||||
|
||||
void reset();
|
||||
struct EffectiveAddress {
|
||||
uint32_t value;
|
||||
CPU::SlicedInt32 value;
|
||||
bool is_address;
|
||||
};
|
||||
EffectiveAddress calculate_effective_address(Preinstruction instruction, uint16_t opcode, int index);
|
||||
|
||||
void read(DataSize size, uint32_t address, CPU::SlicedInt32 &value);
|
||||
void write(DataSize size, uint32_t address, CPU::SlicedInt32 value);
|
||||
|
||||
// Processor state.
|
||||
Status status_;
|
||||
CPU::SlicedInt32 program_counter_;
|
||||
|
Loading…
Reference in New Issue
Block a user