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

Switched the Z80 to being something a machine has, not something a machine is.

This commit is contained in:
Thomas Harte 2017-08-02 22:09:59 -04:00
parent a54ccd1969
commit 039811ce6a
2 changed files with 30 additions and 17 deletions

View File

@ -108,6 +108,14 @@ struct PartialMachineCycle {
}
};
class BusHandler {
public:
void flush() {}
HalfCycles perform_machine_cycle(const PartialMachineCycle &cycle) {
return HalfCycles(0);
}
};
// Elemental bus operations
#define ReadOpcodeStart() {PartialMachineCycle::ReadOpcodeStart, HalfCycles(3), &pc_.full, &operation_, false}
#define ReadOpcodeWait(f) {PartialMachineCycle::ReadOpcodeWait, HalfCycles(2), &pc_.full, &operation_, f}
@ -174,6 +182,8 @@ struct PartialMachineCycle {
*/
template <class T> class Processor {
private:
T &bus_handler_;
uint8_t a_;
RegisterPair bc_, de_, hl_;
RegisterPair afDash_, bcDash_, deDash_, hlDash_;
@ -296,7 +306,6 @@ template <class T> class Processor {
};
const MicroOp *scheduled_program_counter_;
struct InstructionPage {
std::vector<MicroOp *> instructions;
std::vector<MicroOp> all_operations;
@ -774,7 +783,7 @@ template <class T> class Processor {
}
public:
Processor() :
Processor(T &bus_handler) :
halt_mask_(0xff),
interrupt_mode_(0),
wait_line_(false),
@ -784,7 +793,8 @@ template <class T> class Processor {
nmi_line_(false),
bus_request_line_(false),
pc_increment_(1),
scheduled_program_counter_(nullptr) {
scheduled_program_counter_(nullptr),
bus_handler_(bus_handler) {
set_flags(0xff);
MicroOp conditional_call_untaken_program[] = Sequence(ReadInc(pc_, temp16_.bytes.high));
@ -901,9 +911,9 @@ template <class T> class Processor {
while(bus_request_line_) {
static PartialMachineCycle bus_acknowledge_cycle = {PartialMachineCycle::BusAcknowledge, HalfCycles(2), nullptr, nullptr, false};
number_of_cycles_ -= static_cast<T *>(this)->perform_machine_cycle(bus_acknowledge_cycle) + HalfCycles(1);
number_of_cycles_ -= bus_handler_.perform_machine_cycle(bus_acknowledge_cycle) + HalfCycles(1);
if(!number_of_cycles_) {
static_cast<T *>(this)->flush();
bus_handler_.flush();
return;
}
}
@ -922,7 +932,7 @@ template <class T> class Processor {
case MicroOp::BusOperation:
if(number_of_cycles_ < operation->machine_cycle.length) {
scheduled_program_counter_--;
static_cast<T *>(this)->flush();
bus_handler_.flush();
return;
}
if(operation->machine_cycle.was_requested) {
@ -934,7 +944,7 @@ template <class T> class Processor {
}
number_of_cycles_ -= operation->machine_cycle.length;
last_request_status_ = request_status_;
number_of_cycles_ -= static_cast<T *>(this)->perform_machine_cycle(operation->machine_cycle);
number_of_cycles_ -= bus_handler_.perform_machine_cycle(operation->machine_cycle);
break;
case MicroOp::MoveToNextProgram:
advance_operation();

View File

@ -12,9 +12,9 @@
using namespace CPU::Z80;
namespace {
class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<ConcreteAllRAMProcessor> {
class ConcreteAllRAMProcessor: public AllRAMProcessor, public BusHandler {
public:
ConcreteAllRAMProcessor() : AllRAMProcessor() {}
ConcreteAllRAMProcessor() : AllRAMProcessor(), z80_(*this) {}
inline HalfCycles perform_machine_cycle(const PartialMachineCycle &cycle) {
timestamp_ += cycle.length;
@ -64,36 +64,39 @@ class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<Concrete
}
void run_for(const Cycles cycles) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::run_for(cycles);
z80_.run_for(cycles);
}
uint16_t get_value_of_register(Register r) {
return CPU::Z80::Processor<ConcreteAllRAMProcessor>::get_value_of_register(r);
return z80_.get_value_of_register(r);
}
void set_value_of_register(Register r, uint16_t value) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_value_of_register(r, value);
z80_.set_value_of_register(r, value);
}
bool get_halt_line() {
return CPU::Z80::Processor<ConcreteAllRAMProcessor>::get_halt_line();
return z80_.get_halt_line();
}
void reset_power_on() {
return CPU::Z80::Processor<ConcreteAllRAMProcessor>::reset_power_on();
return z80_.reset_power_on();
}
void set_interrupt_line(bool value) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_interrupt_line(value);
z80_.set_interrupt_line(value);
}
void set_non_maskable_interrupt_line(bool value) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_non_maskable_interrupt_line(value);
z80_.set_non_maskable_interrupt_line(value);
}
void set_wait_line(bool value) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_wait_line(value);
z80_.set_wait_line(value);
}
private:
CPU::Z80::Processor<ConcreteAllRAMProcessor> z80_;
};
}