1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Edges towards working short absolute addressing mode.

This commit is contained in:
Thomas Harte 2020-10-03 21:30:24 -04:00
parent da78dea98f
commit bdc1136b96
2 changed files with 78 additions and 10 deletions

View File

@ -52,7 +52,7 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
case CycleFetchIncrementPC: case CycleFetchIncrementPC:
case CycleFetchOpcode: case CycleFetchOpcode:
bus_address = pc_ | program_bank_; bus_address = pc_ | program_bank_;
bus_value = instruction_buffer_.next(); bus_value = instruction_buffer_.next_input();
bus_operation = (operation == CycleFetchOpcode) ? MOS6502Esque::ReadOpcode : MOS6502Esque::Read; bus_operation = (operation == CycleFetchOpcode) ? MOS6502Esque::ReadOpcode : MOS6502Esque::Read;
// TODO: split this action when I'm happy that my route to bus accesses is settled, to avoid repeating the conditional // TODO: split this action when I'm happy that my route to bus accesses is settled, to avoid repeating the conditional
// embedded into the `switch`. // embedded into the `switch`.
@ -65,6 +65,43 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
bus_operation = MOS6502Esque::Read; bus_operation = MOS6502Esque::Read;
break; break;
//
// Data fetches and stores.
//
case CycleFetchData:
bus_address = data_address_;
bus_value = data_buffer_.next_input();
bus_operation = MOS6502Esque::Read;
break;
case CycleFetchIncrementData:
bus_address = data_address_;
bus_value = data_buffer_.next_input();
bus_operation = MOS6502Esque::Read;
++data_address_;
break;
case CycleStoreData:
bus_address = data_address_;
bus_value = data_buffer_.next_output();
bus_operation = MOS6502Esque::Read;
break;
case CycleStoreIncrementData:
bus_address = data_address_;
bus_value = data_buffer_.next_output();
bus_operation = MOS6502Esque::Read;
++data_address_;
break;
case CycleStoreDecrementData:
bus_address = data_address_;
bus_value = data_buffer_.next_output();
bus_operation = MOS6502Esque::Read;
--data_address_;
break;
// //
// Data movement. // Data movement.
// //
@ -78,6 +115,14 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
data_buffer_ = instruction_buffer_; data_buffer_ = instruction_buffer_;
break; break;
//
// Address construction.
//
case OperationConstructAbsolute:
data_address_ = instruction_buffer_.value | data_bank_;
break;
// //
// Performance. // Performance.
// //
@ -118,6 +163,11 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
#undef LD #undef LD
case STA:
data_buffer_.value = a_.full & m_masks_[1];
data_buffer_.size = 2 - mx_flags_[0];
break;
default: default:
assert(false); assert(false);
} }

View File

@ -204,7 +204,7 @@ struct ProcessorStorage {
// Flags aplenty. // Flags aplenty.
uint8_t carry_flag_, negative_result_, zero_result_, decimal_flag_, overflow_flag_, inverse_interrupt_flag_ = 0; uint8_t carry_flag_, negative_result_, zero_result_, decimal_flag_, overflow_flag_, inverse_interrupt_flag_ = 0;
uint8_t mx_flags_[2] = {1, 1}; // [0] = m; [1] = x. In both cases either `0` or `1`. uint8_t mx_flags_[2] = {1, 1}; // [0] = m; [1] = x. In both cases either `0` or `1`; `1` => 8-bit.
uint16_t m_masks_[2] = {0xff00, 0x00ff}; // [0] = src mask; [1] = dst mask. uint16_t m_masks_[2] = {0xff00, 0x00ff}; // [0] = src mask; [1] = dst mask.
uint16_t x_masks_[2] = {0xff00, 0x00ff}; // [0] = src mask; [1] = dst mask. uint16_t x_masks_[2] = {0xff00, 0x00ff}; // [0] = src mask; [1] = dst mask.
int instruction_offset_ = 0; int instruction_offset_ = 0;
@ -228,24 +228,42 @@ struct ProcessorStorage {
struct Buffer { struct Buffer {
uint32_t value = 0; uint32_t value = 0;
int size = 0; int size = 0;
int read = 0;
void clear() { void clear() {
value = 0; value = 0;
size = 0; size = 0;
read = 0;
} }
uint8_t *next() { uint8_t *next_input() {
#if TARGET_RT_BIG_ENDIAN uint8_t *const next = byte(size);
uint8_t *const target = reinterpret_cast<uint8_t *>(&value) + (3 ^ size);
#else
uint8_t *const target = reinterpret_cast<uint8_t *>(&value) + size;
#endif
++size; ++size;
return target; return next;
} }
uint8_t *next_output() {
uint8_t *const next = byte(read);
++read;
return next;
}
uint8_t *next_stack() {
--size;
return byte(size);
}
private:
uint8_t *byte(int pointer) {
#if TARGET_RT_BIG_ENDIAN
return reinterpret_cast<uint8_t *>(&value) + (3 ^ pointer);
#else
return reinterpret_cast<uint8_t *>(&value) + pointer;
#endif
}
}; };
Buffer instruction_buffer_, data_buffer_; Buffer instruction_buffer_, data_buffer_;
uint32_t data_address_;
std::vector<MicroOp> micro_ops_; std::vector<MicroOp> micro_ops_;
MicroOp *next_op_ = nullptr; MicroOp *next_op_ = nullptr;