mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-16 05:27:43 +00:00
There's finally a loop in here, at least.
This commit is contained in:
@@ -41,6 +41,12 @@ template <class T> class MicroOpScheduler {
|
|||||||
scheduled_programs_[schedule_programs_write_pointer_] = program;
|
scheduled_programs_[schedule_programs_write_pointer_] = program;
|
||||||
schedule_programs_write_pointer_ = (schedule_programs_write_pointer_+1)&3;
|
schedule_programs_write_pointer_ = (schedule_programs_write_pointer_+1)&3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void move_to_next_program() {
|
||||||
|
scheduled_programs_[schedule_programs_read_pointer_] = NULL;
|
||||||
|
schedule_programs_read_pointer_ = (schedule_programs_read_pointer_+1)&3;
|
||||||
|
schedule_program_program_counter_ = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#define Z80_hpp
|
#define Z80_hpp
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
#include "../MicroOpScheduler.hpp"
|
#include "../MicroOpScheduler.hpp"
|
||||||
#include "../RegisterSizes.hpp"
|
#include "../RegisterSizes.hpp"
|
||||||
@@ -61,19 +62,29 @@ enum Flag: uint8_t {
|
|||||||
@c None is reserved for internal use. It will never be requested from a subclass.
|
@c None is reserved for internal use. It will never be requested from a subclass.
|
||||||
*/
|
*/
|
||||||
enum BusOperation {
|
enum BusOperation {
|
||||||
ReadOpcode,
|
ReadOpcode = 0,
|
||||||
Read, Write,
|
Read, Write,
|
||||||
Input, Output,
|
Input, Output,
|
||||||
Interrupt,
|
Interrupt,
|
||||||
BusRequest, BusAcknowledge,
|
// BusRequest, BusAcknowledge,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MachineCycle {
|
||||||
|
BusOperation operation;
|
||||||
|
const uint16_t *address;
|
||||||
|
uint8_t *value;
|
||||||
|
};
|
||||||
|
|
||||||
struct MicroOp {
|
struct MicroOp {
|
||||||
enum {
|
enum {
|
||||||
|
BusOperation,
|
||||||
|
DecodeOperation,
|
||||||
|
MoveToNextProgram
|
||||||
} type;
|
} type;
|
||||||
void *source;
|
void *source;
|
||||||
void *destination;
|
void *destination;
|
||||||
|
MachineCycle machine_cycle;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -95,19 +106,58 @@ template <class T> class Processor: public MicroOpScheduler<MicroOp> {
|
|||||||
RegisterPair ix_, iy_, pc_, sp_;
|
RegisterPair ix_, iy_, pc_, sp_;
|
||||||
uint8_t carry_flag_, sign_result_, bit5_result_, half_carry_flag_, bit3_result_, parity_overflow_flag_, subtract_flag_;
|
uint8_t carry_flag_, sign_result_, bit5_result_, half_carry_flag_, bit3_result_, parity_overflow_flag_, subtract_flag_;
|
||||||
|
|
||||||
|
int number_of_cycles_;
|
||||||
|
|
||||||
|
uint8_t operation_;
|
||||||
|
|
||||||
|
constexpr static int cycles_by_bus_operation[6] = {
|
||||||
|
4,
|
||||||
|
3, 3,
|
||||||
|
3, 3,
|
||||||
|
3
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
Runs the Z80 for a supplied number of cycles.
|
Runs the Z80 for a supplied number of cycles.
|
||||||
|
|
||||||
@discussion Subclasses must implement @c perform_bus_operation(BusOperation operation, uint16_t address, uint8_t *value) .
|
@discussion Subclasses must implement @c perform_machine_cycle(MachineCycle *cycle) .
|
||||||
The Z80 will call that method for all bus accesses.
|
|
||||||
|
|
||||||
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 number_of_cycles The number of cycles to run the Z80 for.
|
||||||
*/
|
*/
|
||||||
void run_for_cycles(int number_of_cycles) {
|
void run_for_cycles(int number_of_cycles) {
|
||||||
// TODO (!)
|
static const MicroOp fetch_decode_execute[] = {
|
||||||
|
{ MicroOp::BusOperation, nullptr, nullptr, {ReadOpcode, &pc_.full, &operation_}},
|
||||||
|
{ MicroOp::DecodeOperation },
|
||||||
|
{ MicroOp::MoveToNextProgram }
|
||||||
|
};
|
||||||
|
schedule_program(fetch_decode_execute);
|
||||||
|
|
||||||
|
MicroOp *operation = &scheduled_programs_[schedule_programs_read_pointer_][schedule_program_program_counter_];
|
||||||
|
number_of_cycles_ += number_of_cycles;
|
||||||
|
while(1) {
|
||||||
|
switch(operation->type) {
|
||||||
|
case MicroOp::BusOperation:
|
||||||
|
if(number_of_cycles_ < cycles_by_bus_operation[operation->type]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
perform_machine_cycle(&operation->machine_cycle);
|
||||||
|
break;
|
||||||
|
case MicroOp::MoveToNextProgram:
|
||||||
|
move_to_next_program();
|
||||||
|
operation--;
|
||||||
|
schedule_program_program_counter_--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("Unhandled Z80 operation %d\n", operation->type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
operation++;
|
||||||
|
schedule_program_program_counter_++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -117,6 +167,9 @@ template <class T> class Processor: public MicroOpScheduler<MicroOp> {
|
|||||||
*/
|
*/
|
||||||
void flush() {}
|
void flush() {}
|
||||||
|
|
||||||
|
void perform_machine_cycle(const MachineCycle *cycle) {
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Gets the flags register.
|
Gets the flags register.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user