mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-12 00:30:31 +00:00
Merge pull request #219 from TomHarte/ConstSafety
Makes all of PartialMachineCycle const
This commit is contained in:
commit
ecd3350a6f
@ -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) noexcept :
|
||||||
|
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) noexcept :
|
||||||
|
operation(operation), length(length), address(address), value(value), was_requested(was_requested) {}
|
||||||
|
PartialMachineCycle() noexcept :
|
||||||
|
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,9 @@ 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);
|
|
||||||
size_t pointer = 0;
|
size_t pointer = 0;
|
||||||
while(true) {
|
while(true) {
|
||||||
destination[pointer] = source[pointer];
|
destination.emplace_back(source[pointer]);
|
||||||
if(isTerminal(source[pointer].type)) break;
|
if(isTerminal(source[pointer].type)) break;
|
||||||
pointer++;
|
pointer++;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user