1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-23 20:29:42 +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_));
} 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<Outputs::Speaker> Machine::get_speaker() {
}
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) {

View File

@ -15,6 +15,7 @@
#include <vector>
#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 T> class Processor {
template <class T> class Processor: public ClockReceiver<Processor<T>> {
private:
uint8_t a_;
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.
@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 T> 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();
}