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

View File

@ -12,9 +12,9 @@
using namespace CPU::Z80; using namespace CPU::Z80;
namespace { namespace {
class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<ConcreteAllRAMProcessor> { class ConcreteAllRAMProcessor: public AllRAMProcessor, public BusHandler {
public: public:
ConcreteAllRAMProcessor() : AllRAMProcessor() {} ConcreteAllRAMProcessor() : AllRAMProcessor(), z80_(*this) {}
inline HalfCycles perform_machine_cycle(const PartialMachineCycle &cycle) { inline HalfCycles perform_machine_cycle(const PartialMachineCycle &cycle) {
timestamp_ += cycle.length; timestamp_ += cycle.length;
@ -64,36 +64,39 @@ class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<Concrete
} }
void run_for(const Cycles cycles) { 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) { 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) { 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() { bool get_halt_line() {
return CPU::Z80::Processor<ConcreteAllRAMProcessor>::get_halt_line(); return z80_.get_halt_line();
} }
void reset_power_on() { void reset_power_on() {
return CPU::Z80::Processor<ConcreteAllRAMProcessor>::reset_power_on(); return z80_.reset_power_on();
} }
void set_interrupt_line(bool value) { 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) { 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) { 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_;
}; };
} }