diff --git a/Machines/ZX8081/ZX8081.cpp b/Machines/ZX8081/ZX8081.cpp index 1c0475698..ccaf83b8a 100644 --- a/Machines/ZX8081/ZX8081.cpp +++ b/Machines/ZX8081/ZX8081.cpp @@ -50,7 +50,7 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) { } video_->run_for(Cycles(horizontal_counter_ - vsync_end_cycle_)); } else { - video_->run_for(Cycles(cycle.length)); + video_->run_for(cycle.length); } if(is_zx81_) horizontal_counter_ %= 207; @@ -206,7 +206,7 @@ std::shared_ptr Machine::get_speaker() { } void Machine::run_for(const Cycles &cycles) { - CPU::Z80::Processor::run_for_cycles(int(cycles)); + CPU::Z80::Processor::run_for(cycles); } void Machine::configure_as_target(const StaticAnalyser::Target &target) { diff --git a/Processors/Z80/Z80.hpp b/Processors/Z80/Z80.hpp index 7d260855a..ad00d3d6a 100644 --- a/Processors/Z80/Z80.hpp +++ b/Processors/Z80/Z80.hpp @@ -15,6 +15,7 @@ #include #include "../RegisterSizes.hpp" +#include "../../Components/ClockReceiver.hpp" namespace CPU { namespace Z80 { @@ -87,7 +88,7 @@ struct PartialMachineCycle { InputStart, OutputStart, } operation; - int length; + Cycles length; uint16_t *address; uint8_t *value; bool was_requested; @@ -104,28 +105,28 @@ struct PartialMachineCycle { }; // Elemental bus operations -#define ReadOpcodeStart() {PartialMachineCycle::ReadOpcodeStart, 2, &pc_.full, &operation_, false} -#define ReadOpcodeWait(length, f) {PartialMachineCycle::ReadOpcodeWait, length, &pc_.full, &operation_, f} -#define Refresh(len) {PartialMachineCycle::Refresh, len, &refresh_addr_.full, nullptr, false} +#define ReadOpcodeStart() {PartialMachineCycle::ReadOpcodeStart, Cycles(2), &pc_.full, &operation_, false} +#define ReadOpcodeWait(length, f) {PartialMachineCycle::ReadOpcodeWait, Cycles(length), &pc_.full, &operation_, f} +#define Refresh(len) {PartialMachineCycle::Refresh, Cycles(len), &refresh_addr_.full, nullptr, false} -#define ReadStart(addr, val) {PartialMachineCycle::ReadStart, 2, &addr.full, &val, false} -#define ReadWait(l, addr, val, f) {PartialMachineCycle::ReadWait, l, &addr.full, &val, f} -#define ReadEnd(addr, val) {PartialMachineCycle::Read, 1, &addr.full, &val, false} +#define ReadStart(addr, val) {PartialMachineCycle::ReadStart, Cycles(2), &addr.full, &val, false} +#define ReadWait(l, addr, val, f) {PartialMachineCycle::ReadWait, Cycles(l), &addr.full, &val, f} +#define ReadEnd(addr, val) {PartialMachineCycle::Read, Cycles(1), &addr.full, &val, false} -#define WriteStart(addr, val) {PartialMachineCycle::WriteStart, 2, &addr.full, &val, false} -#define WriteWait(l, addr, val, f) {PartialMachineCycle::WriteWait, l, &addr.full, &val, f} -#define WriteEnd(addr, val) {PartialMachineCycle::Write, 1, &addr.full, &val, false} +#define WriteStart(addr, val) {PartialMachineCycle::WriteStart, Cycles(2), &addr.full, &val, false} +#define WriteWait(l, addr, val, f) {PartialMachineCycle::WriteWait, Cycles(l), &addr.full, &val, f} +#define WriteEnd(addr, val) {PartialMachineCycle::Write, Cycles(1), &addr.full, &val, false} -#define InputStart(addr, val) {PartialMachineCycle::InputStart, 2, &addr.full, &val, false} -#define InputWait(addr, val, f) {PartialMachineCycle::InputWait, 1, &addr.full, &val, f} -#define InputEnd(addr, val) {PartialMachineCycle::Input, 1, &addr.full, &val, false} +#define InputStart(addr, val) {PartialMachineCycle::InputStart, Cycles(2), &addr.full, &val, false} +#define InputWait(addr, val, f) {PartialMachineCycle::InputWait, Cycles(1), &addr.full, &val, f} +#define InputEnd(addr, val) {PartialMachineCycle::Input, Cycles(1), &addr.full, &val, false} -#define OutputStart(addr, val) {PartialMachineCycle::OutputStart, 2, &addr.full, &val, false} -#define OutputWait(addr, val, f) {PartialMachineCycle::OutputWait, 1, &addr.full, &val, f} -#define OutputEnd(addr, val) {PartialMachineCycle::Output, 1, &addr.full, &val, false} +#define OutputStart(addr, val) {PartialMachineCycle::OutputStart, Cycles(2), &addr.full, &val, false} +#define OutputWait(addr, val, f) {PartialMachineCycle::OutputWait, Cycles(1), &addr.full, &val, f} +#define OutputEnd(addr, val) {PartialMachineCycle::Output, Cycles(1), &addr.full, &val, false} -#define IntAck(length, val) {PartialMachineCycle::Interrupt, length, nullptr, &val, false} -#define IntWait(val) {PartialMachineCycle::InterruptWait, 1, nullptr, &val, true} +#define IntAck(length, val) {PartialMachineCycle::Interrupt, Cycles(length), nullptr, &val, false} +#define IntWait(val) {PartialMachineCycle::InterruptWait, Cycles(1), nullptr, &val, true} // A wrapper to express a bus operation as a micro-op #define BusOp(op) {MicroOp::BusOperation, nullptr, nullptr, op} @@ -163,7 +164,7 @@ struct PartialMachineCycle { order to provide the bus on which the Z80 operates and @c flush(), which is called upon completion of a continuous run of cycles to allow a subclass to bring any on-demand activities up to date. */ -template class Processor { +template class Processor: public ClockReceiver> { private: uint8_t a_; RegisterPair bc_, de_, hl_; @@ -856,9 +857,9 @@ template class Processor { If it is a read operation then @c value will be seeded with the value 0xff. - @param number_of_cycles The number of cycles to run the Z80 for. + @param cycles The number of cycles to run for. */ - void run_for_cycles(int number_of_cycles) { + void run_for(const Cycles &cycles) { #define advance_operation() \ pc_increment_ = 1; \ @@ -878,7 +879,7 @@ template class Processor { scheduled_program_counter_ = base_page_.fetch_decode_execute_data; \ } - number_of_cycles_ += number_of_cycles; + number_of_cycles_ += int(cycles); if(!scheduled_program_counter_) { advance_operation(); }