1
0
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:
Thomas Harte 2022-05-13 11:17:57 -04:00
parent 4d03c73222
commit 4299334e24
2 changed files with 13 additions and 26 deletions

View File

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

View File

@ -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 07 to indicate data registers 0 to 7, or 815 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) |