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:
parent
8a0b0cb3d7
commit
ba088e5545
@ -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) {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user