mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
Clean up some TODOs, eliminate one further conditional.
This commit is contained in:
parent
4d03c73222
commit
4299334e24
@ -48,7 +48,6 @@ IntT Executor<model, BusHandler>::read(uint32_t address, bool is_from_pc) {
|
|||||||
throw AccessException(code, address, Exception::AddressError | (int(is_from_pc) << 3) | (1 << 4));
|
throw AccessException(code, address, Exception::AddressError | (int(is_from_pc) << 3) | (1 << 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: omit generation of the FunctionCode if the BusHandler doesn't receive it.
|
|
||||||
return bus_handler_.template read<IntT>(address, code);
|
return bus_handler_.template read<IntT>(address, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,11 +119,8 @@ typename Executor<model, BusHandler>::EffectiveAddress Executor<model, BusHandle
|
|||||||
// Operands that don't have effective addresses, which are returned as values.
|
// Operands that don't have effective addresses, which are returned as values.
|
||||||
//
|
//
|
||||||
case AddressingMode::DataRegisterDirect:
|
case AddressingMode::DataRegisterDirect:
|
||||||
ea.value = Dn(instruction.reg(index));
|
|
||||||
ea.requires_fetch = false;
|
|
||||||
break;
|
|
||||||
case AddressingMode::AddressRegisterDirect:
|
case AddressingMode::AddressRegisterDirect:
|
||||||
ea.value = An(instruction.reg(index));
|
ea.value = registers_[instruction.lreg(index)];
|
||||||
ea.requires_fetch = false;
|
ea.requires_fetch = false;
|
||||||
break;
|
break;
|
||||||
case AddressingMode::Quick:
|
case AddressingMode::Quick:
|
||||||
@ -201,9 +197,6 @@ typename Executor<model, BusHandler>::EffectiveAddress Executor<model, BusHandle
|
|||||||
//
|
//
|
||||||
// PC-relative addresses.
|
// PC-relative addresses.
|
||||||
//
|
//
|
||||||
// TODO: rephrase these in terms of instruction_address_. Just for security
|
|
||||||
// against whatever mutations the PC has been through already to get to here.
|
|
||||||
//
|
|
||||||
case AddressingMode::ProgramCounterIndirectWithDisplacement:
|
case AddressingMode::ProgramCounterIndirectWithDisplacement:
|
||||||
ea.value.l = program_counter_.l + int16_t(read_pc<uint16_t>());
|
ea.value.l = program_counter_.l + int16_t(read_pc<uint16_t>());
|
||||||
ea.requires_fetch = true;
|
ea.requires_fetch = true;
|
||||||
@ -214,9 +207,7 @@ typename Executor<model, BusHandler>::EffectiveAddress Executor<model, BusHandle
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// TODO.
|
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ea;
|
return ea;
|
||||||
@ -318,20 +309,14 @@ void Executor<model, BusHandler>::run(int &count) {
|
|||||||
// operands by default both: (i) because they might be values,
|
// operands by default both: (i) because they might be values,
|
||||||
// rather than addresses; and (ii) then they'll be there for use
|
// rather than addresses; and (ii) then they'll be there for use
|
||||||
// by LEA and PEA.
|
// by LEA and PEA.
|
||||||
//
|
|
||||||
// TODO: much of this work should be performed by a full Decoder,
|
|
||||||
// so that it can be cached.
|
|
||||||
effective_address_[0] = calculate_effective_address(instruction, instruction_opcode_, 0);
|
effective_address_[0] = calculate_effective_address(instruction, instruction_opcode_, 0);
|
||||||
effective_address_[1] = calculate_effective_address(instruction, instruction_opcode_, 1);
|
effective_address_[1] = calculate_effective_address(instruction, instruction_opcode_, 1);
|
||||||
operand_[0] = effective_address_[0].value;
|
operand_[0] = effective_address_[0].value;
|
||||||
operand_[1] = effective_address_[1].value;
|
operand_[1] = effective_address_[1].value;
|
||||||
|
|
||||||
// Obtain the appropriate sequence.
|
// Obtain the appropriate sequence.
|
||||||
//
|
|
||||||
// TODO: make a decision about whether this goes into a fully-decoded Instruction.
|
|
||||||
const auto flags = operand_flags<model>(instruction.operation);
|
const auto flags = operand_flags<model>(instruction.operation);
|
||||||
|
|
||||||
// TODO: potential alignment exception, here and in store.
|
|
||||||
#define fetch_operand(n) \
|
#define fetch_operand(n) \
|
||||||
if(effective_address_[n].requires_fetch) { \
|
if(effective_address_[n].requires_fetch) { \
|
||||||
read(instruction.operand_size(), effective_address_[n].value.l, operand_[n]); \
|
read(instruction.operand_size(), effective_address_[n].value.l, operand_[n]); \
|
||||||
@ -344,14 +329,9 @@ void Executor<model, BusHandler>::run(int &count) {
|
|||||||
|
|
||||||
perform<model>(instruction, operand_[0], operand_[1], status_, *this);
|
perform<model>(instruction, operand_[0], operand_[1], status_, *this);
|
||||||
|
|
||||||
// TODO: rephrase to avoid conditional below.
|
|
||||||
#define store_operand(n) \
|
#define store_operand(n) \
|
||||||
if(!effective_address_[n].requires_fetch) { \
|
if(!effective_address_[n].requires_fetch) { \
|
||||||
if(instruction.mode(n) == AddressingMode::DataRegisterDirect) { \
|
registers_[instruction.lreg(n)] = operand_[n]; \
|
||||||
Dn(instruction.reg(n)) = operand_[n]; \
|
|
||||||
} else { \
|
|
||||||
An(instruction.reg(n)) = operand_[n]; \
|
|
||||||
} \
|
|
||||||
} else { \
|
} else { \
|
||||||
write(instruction.operand_size(), effective_address_[n].value.l, operand_[n]); \
|
write(instruction.operand_size(), effective_address_[n].value.l, operand_[n]); \
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ class Preinstruction {
|
|||||||
// other than 0 and 1 are undefined.
|
// other than 0 and 1 are undefined.
|
||||||
|
|
||||||
AddressingMode mode(int index) const {
|
AddressingMode mode(int index) const {
|
||||||
return AddressingMode(operands_[index] & 0x1f);
|
return AddressingMode(operands_[index] >> 3);
|
||||||
}
|
}
|
||||||
template <int index> AddressingMode mode() const {
|
template <int index> AddressingMode mode() const {
|
||||||
if constexpr (index > 1) {
|
if constexpr (index > 1) {
|
||||||
@ -287,7 +287,7 @@ class Preinstruction {
|
|||||||
return mode(index);
|
return mode(index);
|
||||||
}
|
}
|
||||||
int reg(int index) const {
|
int reg(int index) const {
|
||||||
return operands_[index] >> 5;
|
return operands_[index] & 7;
|
||||||
}
|
}
|
||||||
template <int index> int reg() const {
|
template <int index> int reg() const {
|
||||||
if constexpr (index > 1) {
|
if constexpr (index > 1) {
|
||||||
@ -296,6 +296,13 @@ class Preinstruction {
|
|||||||
return reg(index);
|
return reg(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @returns 0–7 to indicate data registers 0 to 7, or 8–15 to indicate address registers 0 to 7 respectively.
|
||||||
|
/// Provides undefined results if the addressing mode is not either @c DataRegisterDirect or
|
||||||
|
/// @c AddressRegisterDirect.
|
||||||
|
int lreg(int index) const {
|
||||||
|
return operands_[index] & 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
bool requires_supervisor() const {
|
bool requires_supervisor() const {
|
||||||
return flags_ & 0x80;
|
return flags_ & 0x80;
|
||||||
}
|
}
|
||||||
@ -321,8 +328,8 @@ class Preinstruction {
|
|||||||
DataSize size,
|
DataSize size,
|
||||||
Condition condition) : operation(operation)
|
Condition condition) : operation(operation)
|
||||||
{
|
{
|
||||||
operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5);
|
operands_[0] = uint8_t((uint8_t(op1_mode) << 3) | op1_reg);
|
||||||
operands_[1] = uint8_t(op2_mode) | uint8_t(op2_reg << 5);
|
operands_[1] = uint8_t((uint8_t(op2_mode) << 3) | op2_reg);
|
||||||
flags_ = uint8_t(
|
flags_ = uint8_t(
|
||||||
(is_supervisor ? 0x80 : 0x00) |
|
(is_supervisor ? 0x80 : 0x00) |
|
||||||
(int(condition) << 2) |
|
(int(condition) << 2) |
|
||||||
|
Loading…
Reference in New Issue
Block a user