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

Adapted the Z80 into a clock receiver, which also vends Cycles rather than a raw int within its PartialMachineCycle struct. The objective is to update it to vend HalfCycles within its struct, but I think I need to do some work on cycle/half-cycle arithmetic first.

This commit is contained in:
Thomas Harte 2017-07-23 22:15:04 -04:00
parent 8a0b0cb3d7
commit ba088e5545
2 changed files with 25 additions and 24 deletions

View File

@ -50,7 +50,7 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
} }
video_->run_for(Cycles(horizontal_counter_ - vsync_end_cycle_)); video_->run_for(Cycles(horizontal_counter_ - vsync_end_cycle_));
} else { } else {
video_->run_for(Cycles(cycle.length)); video_->run_for(cycle.length);
} }
if(is_zx81_) horizontal_counter_ %= 207; if(is_zx81_) horizontal_counter_ %= 207;
@ -206,7 +206,7 @@ std::shared_ptr<Outputs::Speaker> Machine::get_speaker() {
} }
void Machine::run_for(const Cycles &cycles) { void Machine::run_for(const Cycles &cycles) {
CPU::Z80::Processor<Machine>::run_for_cycles(int(cycles)); CPU::Z80::Processor<Machine>::run_for(cycles);
} }
void Machine::configure_as_target(const StaticAnalyser::Target &target) { void Machine::configure_as_target(const StaticAnalyser::Target &target) {

View File

@ -15,6 +15,7 @@
#include <vector> #include <vector>
#include "../RegisterSizes.hpp" #include "../RegisterSizes.hpp"
#include "../../Components/ClockReceiver.hpp"
namespace CPU { namespace CPU {
namespace Z80 { namespace Z80 {
@ -87,7 +88,7 @@ struct PartialMachineCycle {
InputStart, InputStart,
OutputStart, OutputStart,
} operation; } operation;
int length; Cycles length;
uint16_t *address; uint16_t *address;
uint8_t *value; uint8_t *value;
bool was_requested; bool was_requested;
@ -104,28 +105,28 @@ struct PartialMachineCycle {
}; };
// Elemental bus operations // Elemental bus operations
#define ReadOpcodeStart() {PartialMachineCycle::ReadOpcodeStart, 2, &pc_.full, &operation_, false} #define ReadOpcodeStart() {PartialMachineCycle::ReadOpcodeStart, Cycles(2), &pc_.full, &operation_, false}
#define ReadOpcodeWait(length, f) {PartialMachineCycle::ReadOpcodeWait, length, &pc_.full, &operation_, f} #define ReadOpcodeWait(length, f) {PartialMachineCycle::ReadOpcodeWait, Cycles(length), &pc_.full, &operation_, f}
#define Refresh(len) {PartialMachineCycle::Refresh, len, &refresh_addr_.full, nullptr, false} #define Refresh(len) {PartialMachineCycle::Refresh, Cycles(len), &refresh_addr_.full, nullptr, false}
#define ReadStart(addr, val) {PartialMachineCycle::ReadStart, 2, &addr.full, &val, false} #define ReadStart(addr, val) {PartialMachineCycle::ReadStart, Cycles(2), &addr.full, &val, false}
#define ReadWait(l, addr, val, f) {PartialMachineCycle::ReadWait, l, &addr.full, &val, f} #define ReadWait(l, addr, val, f) {PartialMachineCycle::ReadWait, Cycles(l), &addr.full, &val, f}
#define ReadEnd(addr, val) {PartialMachineCycle::Read, 1, &addr.full, &val, false} #define ReadEnd(addr, val) {PartialMachineCycle::Read, Cycles(1), &addr.full, &val, false}
#define WriteStart(addr, val) {PartialMachineCycle::WriteStart, 2, &addr.full, &val, false} #define WriteStart(addr, val) {PartialMachineCycle::WriteStart, Cycles(2), &addr.full, &val, false}
#define WriteWait(l, addr, val, f) {PartialMachineCycle::WriteWait, l, &addr.full, &val, f} #define WriteWait(l, addr, val, f) {PartialMachineCycle::WriteWait, Cycles(l), &addr.full, &val, f}
#define WriteEnd(addr, val) {PartialMachineCycle::Write, 1, &addr.full, &val, false} #define WriteEnd(addr, val) {PartialMachineCycle::Write, Cycles(1), &addr.full, &val, false}
#define InputStart(addr, val) {PartialMachineCycle::InputStart, 2, &addr.full, &val, false} #define InputStart(addr, val) {PartialMachineCycle::InputStart, Cycles(2), &addr.full, &val, false}
#define InputWait(addr, val, f) {PartialMachineCycle::InputWait, 1, &addr.full, &val, f} #define InputWait(addr, val, f) {PartialMachineCycle::InputWait, Cycles(1), &addr.full, &val, f}
#define InputEnd(addr, val) {PartialMachineCycle::Input, 1, &addr.full, &val, false} #define InputEnd(addr, val) {PartialMachineCycle::Input, Cycles(1), &addr.full, &val, false}
#define OutputStart(addr, val) {PartialMachineCycle::OutputStart, 2, &addr.full, &val, false} #define OutputStart(addr, val) {PartialMachineCycle::OutputStart, Cycles(2), &addr.full, &val, false}
#define OutputWait(addr, val, f) {PartialMachineCycle::OutputWait, 1, &addr.full, &val, f} #define OutputWait(addr, val, f) {PartialMachineCycle::OutputWait, Cycles(1), &addr.full, &val, f}
#define OutputEnd(addr, val) {PartialMachineCycle::Output, 1, &addr.full, &val, false} #define OutputEnd(addr, val) {PartialMachineCycle::Output, Cycles(1), &addr.full, &val, false}
#define IntAck(length, val) {PartialMachineCycle::Interrupt, length, nullptr, &val, false} #define IntAck(length, val) {PartialMachineCycle::Interrupt, Cycles(length), nullptr, &val, false}
#define IntWait(val) {PartialMachineCycle::InterruptWait, 1, nullptr, &val, true} #define IntWait(val) {PartialMachineCycle::InterruptWait, Cycles(1), nullptr, &val, true}
// A wrapper to express a bus operation as a micro-op // A wrapper to express a bus operation as a micro-op
#define BusOp(op) {MicroOp::BusOperation, nullptr, nullptr, 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 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. of cycles to allow a subclass to bring any on-demand activities up to date.
*/ */
template <class T> class Processor { template <class T> class Processor: public ClockReceiver<Processor<T>> {
private: private:
uint8_t a_; uint8_t a_;
RegisterPair bc_, de_, hl_; RegisterPair bc_, de_, hl_;
@ -856,9 +857,9 @@ template <class T> class Processor {
If it is a read operation then @c value will be seeded with the value 0xff. 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() \ #define advance_operation() \
pc_increment_ = 1; \ pc_increment_ = 1; \
@ -878,7 +879,7 @@ template <class T> class Processor {
scheduled_program_counter_ = base_page_.fetch_decode_execute_data; \ scheduled_program_counter_ = base_page_.fetch_decode_execute_data; \
} }
number_of_cycles_ += number_of_cycles; number_of_cycles_ += int(cycles);
if(!scheduled_program_counter_) { if(!scheduled_program_counter_) {
advance_operation(); advance_operation();
} }