mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-06 15:00:05 +00:00
Merge branch 'Z80' into StraightPointer
This commit is contained in:
commit
b5ad910b81
@ -157,15 +157,11 @@ struct MicroOp {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@abstact An abstract base class for emulation of a 6502 processor via the curiously recurring template pattern/f-bounded polymorphism.
|
@abstact An abstract base class for emulation of a Z80 processor via the curiously recurring template pattern/f-bounded polymorphism.
|
||||||
|
|
||||||
@discussion Subclasses should implement @c perform_bus_operation(BusOperation operation, uint16_t address, uint8_t *value) in
|
@discussion Subclasses should implement @c perform_machine_cycle in
|
||||||
order to provide the bus on which the 6502 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.
|
||||||
|
|
||||||
Additional functionality can be provided by the host machine by providing a jam handler and inserting jam opcodes where appropriate;
|
|
||||||
that will cause call outs when the program counter reaches those addresses. @c return_from_subroutine can be used to exit from a
|
|
||||||
jammed state.
|
|
||||||
*/
|
*/
|
||||||
template <class T> class Processor: public MicroOpScheduler<MicroOp> {
|
template <class T> class Processor: public MicroOpScheduler<MicroOp> {
|
||||||
private:
|
private:
|
||||||
@ -668,7 +664,7 @@ template <class T> class Processor: public MicroOpScheduler<MicroOp> {
|
|||||||
/*!
|
/*!
|
||||||
Runs the Z80 for a supplied number of cycles.
|
Runs the Z80 for a supplied number of cycles.
|
||||||
|
|
||||||
@discussion Subclasses must implement @c perform_machine_cycle(MachineCycle *cycle) .
|
@discussion Subclasses must implement @c perform_machine_cycle(const MachineCycle &cycle) .
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@ -699,7 +695,7 @@ template <class T> class Processor: public MicroOpScheduler<MicroOp> {
|
|||||||
case MicroOp::BusOperation:
|
case MicroOp::BusOperation:
|
||||||
if(number_of_cycles_ < operation->machine_cycle.length) { scheduled_program_counter_--; return; }
|
if(number_of_cycles_ < operation->machine_cycle.length) { scheduled_program_counter_--; return; }
|
||||||
number_of_cycles_ -= operation->machine_cycle.length;
|
number_of_cycles_ -= operation->machine_cycle.length;
|
||||||
number_of_cycles_ -= static_cast<T *>(this)->perform_machine_cycle(&operation->machine_cycle);
|
number_of_cycles_ -= static_cast<T *>(this)->perform_machine_cycle(operation->machine_cycle);
|
||||||
break;
|
break;
|
||||||
case MicroOp::MoveToNextProgram:
|
case MicroOp::MoveToNextProgram:
|
||||||
move_to_next_program();
|
move_to_next_program();
|
||||||
@ -1407,7 +1403,7 @@ template <class T> class Processor: public MicroOpScheduler<MicroOp> {
|
|||||||
*/
|
*/
|
||||||
void flush() {}
|
void flush() {}
|
||||||
|
|
||||||
int perform_machine_cycle(const MachineCycle *cycle) {
|
int perform_machine_cycle(const MachineCycle &cycle) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,19 +13,19 @@ using namespace CPU::Z80;
|
|||||||
|
|
||||||
AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536), delegate_(nullptr) {}
|
AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536), delegate_(nullptr) {}
|
||||||
|
|
||||||
int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
|
int AllRAMProcessor::perform_machine_cycle(const MachineCycle &cycle) {
|
||||||
uint16_t address = cycle->address ? *cycle->address : 0x0000;
|
uint16_t address = cycle.address ? *cycle.address : 0x0000;
|
||||||
switch(cycle->operation) {
|
switch(cycle.operation) {
|
||||||
case BusOperation::ReadOpcode:
|
case BusOperation::ReadOpcode:
|
||||||
// printf("%04x %02x [BC=%02x]\n", *cycle->address, memory_[*cycle->address], get_value_of_register(CPU::Z80::Register::BC));
|
// printf("%04x %02x [BC=%02x]\n", *cycle->address, memory_[*cycle->address], get_value_of_register(CPU::Z80::Register::BC));
|
||||||
check_address_for_trap(address);
|
check_address_for_trap(address);
|
||||||
case BusOperation::Read:
|
case BusOperation::Read:
|
||||||
// printf("r %04x [%02x] AF:%04x BC:%04x DE:%04x HL:%04x SP:%04x\n", *cycle->address, memory_[*cycle->address], get_value_of_register(CPU::Z80::Register::AF), get_value_of_register(CPU::Z80::Register::BC), get_value_of_register(CPU::Z80::Register::DE), get_value_of_register(CPU::Z80::Register::HL), get_value_of_register(CPU::Z80::Register::StackPointer));
|
// printf("r %04x [%02x] AF:%04x BC:%04x DE:%04x HL:%04x SP:%04x\n", *cycle->address, memory_[*cycle->address], get_value_of_register(CPU::Z80::Register::AF), get_value_of_register(CPU::Z80::Register::BC), get_value_of_register(CPU::Z80::Register::DE), get_value_of_register(CPU::Z80::Register::HL), get_value_of_register(CPU::Z80::Register::StackPointer));
|
||||||
*cycle->value = memory_[address];
|
*cycle.value = memory_[address];
|
||||||
break;
|
break;
|
||||||
case BusOperation::Write:
|
case BusOperation::Write:
|
||||||
// printf("w %04x\n", *cycle->address);
|
// printf("w %04x\n", *cycle->address);
|
||||||
memory_[address] = *cycle->value;
|
memory_[address] = *cycle.value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BusOperation::Output:
|
case BusOperation::Output:
|
||||||
@ -33,7 +33,7 @@ int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
|
|||||||
case BusOperation::Input:
|
case BusOperation::Input:
|
||||||
// This logic is selected specifically because it seems to match
|
// This logic is selected specifically because it seems to match
|
||||||
// the FUSE unit tests. It might need factoring out.
|
// the FUSE unit tests. It might need factoring out.
|
||||||
*cycle->value = address >> 8;
|
*cycle.value = address >> 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BusOperation::Internal:
|
case BusOperation::Internal:
|
||||||
@ -43,10 +43,10 @@ int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
|
|||||||
printf("???\n");
|
printf("???\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
timestamp_ += cycle->length;
|
timestamp_ += cycle.length;
|
||||||
|
|
||||||
if(delegate_ != nullptr) {
|
if(delegate_ != nullptr) {
|
||||||
delegate_->z80_all_ram_processor_did_perform_bus_operation(*this, cycle->operation, address, cycle->value ? *cycle->value : 0x00, timestamp_);
|
delegate_->z80_all_ram_processor_did_perform_bus_operation(*this, cycle.operation, address, cycle.value ? *cycle.value : 0x00, timestamp_);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -22,7 +22,7 @@ class AllRAMProcessor:
|
|||||||
public:
|
public:
|
||||||
AllRAMProcessor();
|
AllRAMProcessor();
|
||||||
|
|
||||||
int perform_machine_cycle(const MachineCycle *cycle);
|
int perform_machine_cycle(const MachineCycle &cycle);
|
||||||
|
|
||||||
struct MemoryAccessDelegate {
|
struct MemoryAccessDelegate {
|
||||||
virtual void z80_all_ram_processor_did_perform_bus_operation(AllRAMProcessor &processor, BusOperation operation, uint16_t address, uint8_t value, int time_stamp) = 0;
|
virtual void z80_all_ram_processor_did_perform_bus_operation(AllRAMProcessor &processor, BusOperation operation, uint16_t address, uint8_t value, int time_stamp) = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user