1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-24 12:29:06 +00:00

Makes all of PartialMachineCycle const, with the exception of the target of *value, since that's intended to be writeable by recipients.

This commit is contained in:
Thomas Harte 2017-08-24 21:32:33 -04:00
parent 7af3de010e
commit 95d360251d

View File

@ -92,11 +92,12 @@ struct PartialMachineCycle {
InputStart, InputStart,
OutputStart, OutputStart,
InterruptStart, InterruptStart,
} operation; };
HalfCycles length; const Operation operation;
uint16_t *address; const HalfCycles length;
uint8_t *value; const uint16_t *const address;
bool was_requested; uint8_t *const value;
const bool was_requested;
inline bool expects_action() const { inline bool expects_action() const {
return operation <= Operation::Interrupt; return operation <= Operation::Interrupt;
@ -107,6 +108,17 @@ struct PartialMachineCycle {
inline bool is_wait() const { inline bool is_wait() const {
return operation >= Operation::ReadOpcodeWait && operation <= Operation::InterruptWait; return operation >= Operation::ReadOpcodeWait && operation <= Operation::InterruptWait;
} }
PartialMachineCycle(const PartialMachineCycle &rhs) :
operation(rhs.operation),
length(rhs.length),
address(rhs.address),
value(rhs.value),
was_requested(rhs.was_requested) {}
PartialMachineCycle(Operation operation, HalfCycles length, uint16_t *address, uint8_t *value, bool was_requested) :
operation(operation), length(length), address(address), value(value), was_requested(was_requested) {}
PartialMachineCycle() :
operation(Internal), length(0), address(nullptr), value(nullptr), was_requested(false) {}
}; };
class BusHandler { class BusHandler {
@ -118,31 +130,31 @@ class BusHandler {
}; };
// Elemental bus operations // Elemental bus operations
#define ReadOpcodeStart() {PartialMachineCycle::ReadOpcodeStart, HalfCycles(3), &pc_.full, &operation_, false} #define ReadOpcodeStart() PartialMachineCycle(PartialMachineCycle::ReadOpcodeStart, HalfCycles(3), &pc_.full, &operation_, false)
#define ReadOpcodeWait(f) {PartialMachineCycle::ReadOpcodeWait, HalfCycles(2), &pc_.full, &operation_, f} #define ReadOpcodeWait(f) PartialMachineCycle(PartialMachineCycle::ReadOpcodeWait, HalfCycles(2), &pc_.full, &operation_, f)
#define ReadOpcodeEnd() {PartialMachineCycle::ReadOpcode, HalfCycles(1), &pc_.full, &operation_, false} #define ReadOpcodeEnd() PartialMachineCycle(PartialMachineCycle::ReadOpcode, HalfCycles(1), &pc_.full, &operation_, false)
#define Refresh(len) {PartialMachineCycle::Refresh, HalfCycles(len), &refresh_addr_.full, nullptr, false} #define Refresh(len) PartialMachineCycle(PartialMachineCycle::Refresh, HalfCycles(len), &refresh_addr_.full, nullptr, false)
#define ReadStart(addr, val) {PartialMachineCycle::ReadStart, HalfCycles(3), &addr.full, &val, false} #define ReadStart(addr, val) PartialMachineCycle(PartialMachineCycle::ReadStart, HalfCycles(3), &addr.full, &val, false)
#define ReadWait(l, addr, val, f) {PartialMachineCycle::ReadWait, HalfCycles(l), &addr.full, &val, f} #define ReadWait(l, addr, val, f) PartialMachineCycle(PartialMachineCycle::ReadWait, HalfCycles(l), &addr.full, &val, f)
#define ReadEnd(addr, val) {PartialMachineCycle::Read, HalfCycles(3), &addr.full, &val, false} #define ReadEnd(addr, val) PartialMachineCycle(PartialMachineCycle::Read, HalfCycles(3), &addr.full, &val, false)
#define WriteStart(addr, val) {PartialMachineCycle::WriteStart,HalfCycles(3), &addr.full, &val, false} #define WriteStart(addr, val) PartialMachineCycle(PartialMachineCycle::WriteStart,HalfCycles(3), &addr.full, &val, false)
#define WriteWait(l, addr, val, f) {PartialMachineCycle::WriteWait, HalfCycles(l), &addr.full, &val, f} #define WriteWait(l, addr, val, f) PartialMachineCycle(PartialMachineCycle::WriteWait, HalfCycles(l), &addr.full, &val, f)
#define WriteEnd(addr, val) {PartialMachineCycle::Write, HalfCycles(3), &addr.full, &val, false} #define WriteEnd(addr, val) PartialMachineCycle(PartialMachineCycle::Write, HalfCycles(3), &addr.full, &val, false)
#define InputStart(addr, val) {PartialMachineCycle::InputStart, HalfCycles(3), &addr.full, &val, false} #define InputStart(addr, val) PartialMachineCycle(PartialMachineCycle::InputStart, HalfCycles(3), &addr.full, &val, false)
#define InputWait(addr, val, f) {PartialMachineCycle::InputWait, HalfCycles(2), &addr.full, &val, f} #define InputWait(addr, val, f) PartialMachineCycle(PartialMachineCycle::InputWait, HalfCycles(2), &addr.full, &val, f)
#define InputEnd(addr, val) {PartialMachineCycle::Input, HalfCycles(3), &addr.full, &val, false} #define InputEnd(addr, val) PartialMachineCycle(PartialMachineCycle::Input, HalfCycles(3), &addr.full, &val, false)
#define OutputStart(addr, val) {PartialMachineCycle::OutputStart, HalfCycles(3), &addr.full, &val, false} #define OutputStart(addr, val) PartialMachineCycle(PartialMachineCycle::OutputStart, HalfCycles(3), &addr.full, &val, false)
#define OutputWait(addr, val, f) {PartialMachineCycle::OutputWait, HalfCycles(2), &addr.full, &val, f} #define OutputWait(addr, val, f) PartialMachineCycle(PartialMachineCycle::OutputWait, HalfCycles(2), &addr.full, &val, f)
#define OutputEnd(addr, val) {PartialMachineCycle::Output, HalfCycles(3), &addr.full, &val, false} #define OutputEnd(addr, val) PartialMachineCycle(PartialMachineCycle::Output, HalfCycles(3), &addr.full, &val, false)
#define IntAckStart(length, val) {PartialMachineCycle::InterruptStart, HalfCycles(length), nullptr, &val, false} #define IntAckStart(length, val) PartialMachineCycle(PartialMachineCycle::InterruptStart, HalfCycles(length), nullptr, &val, false)
#define IntWait(val) {PartialMachineCycle::InterruptWait, HalfCycles(2), nullptr, &val, true} #define IntWait(val) PartialMachineCycle(PartialMachineCycle::InterruptWait, HalfCycles(2), nullptr, &val, true)
#define IntAckEnd(val) {PartialMachineCycle::Interrupt, HalfCycles(3), nullptr, &val, false} #define IntAckEnd(val) PartialMachineCycle(PartialMachineCycle::Interrupt, HalfCycles(3), nullptr, &val, false)
// A wrapper to express a bus operation as a micro-op // A wrapper to express a bus operation as a micro-op
@ -438,13 +450,13 @@ template <class T, bool uses_bus_request> class Processor {
} }
// Allocate a landing area. // Allocate a landing area.
target.all_operations.resize(number_of_micro_ops); std::vector<size_t> operation_indices;
target.instructions.resize(256, nullptr); target.instructions.resize(256, nullptr);
// Copy in all programs and set pointers. // Copy in all programs, recording where they go.
size_t destination = 0; size_t destination = 0;
for(size_t c = 0; c < 256; c++) { for(size_t c = 0; c < 256; c++) {
target.instructions[c] = &target.all_operations[destination]; operation_indices.push_back(target.all_operations.size());
for(size_t t = 0; t < lengths[c];) { for(size_t t = 0; t < lengths[c];) {
// Skip zero-length bus cycles. // Skip zero-length bus cycles.
if(table[c][t].type == MicroOp::BusOperation && table[c][t].machine_cycle.length.as_int() == 0) { if(table[c][t].type == MicroOp::BusOperation && table[c][t].machine_cycle.length.as_int() == 0) {
@ -462,11 +474,18 @@ template <class T, bool uses_bus_request> class Processor {
t++; t++;
} }
} }
target.all_operations[destination] = table[c][t]; target.all_operations.emplace_back(table[c][t]);
destination++; destination++;
t++; t++;
} }
} }
// Since the vector won't change again, it's now safe to set pointers.
size_t c = 0;
for(size_t index : operation_indices) {
target.instructions[c] = &target.all_operations[index];
c++;
}
} }
void assemble_ed_page(InstructionPage &target) { void assemble_ed_page(InstructionPage &target) {
@ -774,10 +793,11 @@ template <class T, bool uses_bus_request> class Processor {
void copy_program(const MicroOp *source, std::vector<MicroOp> &destination) { void copy_program(const MicroOp *source, std::vector<MicroOp> &destination) {
size_t length = 0; size_t length = 0;
while(!isTerminal(source[length].type)) length++; while(!isTerminal(source[length].type)) length++;
destination.resize(length + 1); // destination.resize(length + 1);
size_t pointer = 0; size_t pointer = 0;
while(true) { while(true) {
destination[pointer] = source[pointer]; destination.emplace_back(source[pointer]);
// destination[pointer] = source[pointer];
if(isTerminal(source[pointer].type)) break; if(isTerminal(source[pointer].type)) break;
pointer++; pointer++;
} }