1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-29 16:55:59 +00:00

Made an attempt, flawed so far, to find a neat way for processor subclasses to offer bus management as an inline function.

This commit is contained in:
Thomas Harte 2017-05-30 22:41:23 -04:00
parent b5c1773d59
commit 5119997122
4 changed files with 82 additions and 55 deletions

View File

@ -104,7 +104,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
#pragma mark - Test class
@implementation CSTestMachineZ80 {
CPU::Z80::AllRAMProcessor _processor;
CPU::Z80::AllRAMProcessor *_processor;
MachineTrapHandler *_cppTrapHandler;
BusOperationHandler *_busOperationHandler;
@ -118,6 +118,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
- (instancetype)init {
if(self = [super init]) {
_processor = CPU::Z80::AllRAMProcessor::Processor();
_cppTrapHandler = new MachineTrapHandler(self);
_busOperationHandler = new BusOperationHandler(self);
_busOperationCaptures = [[NSMutableArray alloc] init];
@ -133,34 +134,34 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
#pragma mark - Accessors
- (void)setData:(NSData *)data atAddress:(uint16_t)startAddress {
_processor.set_data_at_address(startAddress, data.length, (const uint8_t *)data.bytes);
_processor->set_data_at_address(startAddress, data.length, (const uint8_t *)data.bytes);
}
- (void)runForNumberOfCycles:(int)cycles {
_processor.run_for_cycles(cycles);
_processor->run_for_cycles(cycles);
}
- (void)setValue:(uint16_t)value forRegister:(CSTestMachineZ80Register)reg {
_processor.set_value_of_register(registerForRegister(reg), value);
_processor->set_value_of_register(registerForRegister(reg), value);
}
- (void)setValue:(uint8_t)value atAddress:(uint16_t)address {
_processor.set_data_at_address(address, 1, &value);
_processor->set_data_at_address(address, 1, &value);
}
- (uint8_t)valueAtAddress:(uint16_t)address {
uint8_t value;
_processor.get_data_at_address(address, 1, &value);
_processor->get_data_at_address(address, 1, &value);
return value;
}
- (uint16_t)valueForRegister:(CSTestMachineZ80Register)reg {
return _processor.get_value_of_register(registerForRegister(reg));
return _processor->get_value_of_register(registerForRegister(reg));
}
- (void)addTrapAddress:(uint16_t)trapAddress {
_processor.set_trap_handler(_cppTrapHandler);
_processor.add_trap_address(trapAddress);
_processor->set_trap_handler(_cppTrapHandler);
_processor->add_trap_address(trapAddress);
}
- (void)testMachineDidTrapAtAddress:(uint16_t)address {
@ -168,7 +169,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
}
- (BOOL)isHalted {
return _processor.get_halt_line() ? YES : NO;
return _processor->get_halt_line() ? YES : NO;
}
#pragma mark - Z80-specific Runner
@ -178,7 +179,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
_timeSeekingReadOpcode = 0;
while(!_isAtReadOpcode) {
_timeSeekingReadOpcode++;
_processor.run_for_cycles(1);
_processor->run_for_cycles(1);
}
}
@ -186,7 +187,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
- (void)setCaptureBusActivity:(BOOL)captureBusActivity {
_captureBusActivity = captureBusActivity;
_processor.set_memory_access_delegate(captureBusActivity ? _busOperationHandler : nullptr);
_processor->set_memory_access_delegate(captureBusActivity ? _busOperationHandler : nullptr);
}
- (void)testMachineDidPerformBusOperation:(CPU::Z80::BusOperation)operation address:(uint16_t)address value:(uint8_t)value timeStamp:(int)timeStamp {

View File

@ -167,9 +167,9 @@ class FUSETests: XCTestCase {
let name = itemDictionary["name"] as! String
// if name != "d3_1" {
// continue;
// }
if name != "02" {
continue;
}
let initialState = RegisterState(dictionary: itemDictionary["state"] as! [String: Any])
let targetState = RegisterState(dictionary: outputDictionary["state"] as! [String: Any])

View File

@ -10,44 +10,67 @@
#include <algorithm>
using namespace CPU::Z80;
namespace {
AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536), delegate_(nullptr) {}
class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<ConcreteAllRAMProcessor> {
public:
ConcreteAllRAMProcessor() : AllRAMProcessor() {}
int AllRAMProcessor::perform_machine_cycle(const MachineCycle &cycle) {
uint16_t address = cycle.address ? *cycle.address : 0x0000;
switch(cycle.operation) {
case BusOperation::ReadOpcode:
// printf("%04x %02x [BC=%02x]\n", *cycle->address, memory_[*cycle->address], get_value_of_register(CPU::Z80::Register::BC));
check_address_for_trap(address);
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));
*cycle.value = memory_[address];
break;
case BusOperation::Write:
// printf("w %04x\n", *cycle->address);
memory_[address] = *cycle.value;
break;
inline int perform_machine_cycle(const MachineCycle &cycle) {
uint16_t address = cycle.address ? *cycle.address : 0x0000;
switch(cycle.operation) {
case BusOperation::ReadOpcode:
check_address_for_trap(address);
case BusOperation::Read:
*cycle.value = memory_[address];
break;
case BusOperation::Write:
memory_[address] = *cycle.value;
break;
case BusOperation::Output:
break;
case BusOperation::Input:
// This logic is selected specifically because it seems to match
// the FUSE unit tests. It might need factoring out.
*cycle.value = address >> 8;
break;
case BusOperation::Output:
break;
case BusOperation::Input:
// This logic is selected specifically because it seems to match
// the FUSE unit tests. It might need factoring out.
*cycle.value = address >> 8;
break;
case BusOperation::Internal:
break;
case BusOperation::Internal:
break;
default:
printf("???\n");
break;
}
timestamp_ += cycle.length;
default:
printf("???\n");
break;
}
timestamp_ += cycle.length;
if(delegate_ != nullptr) {
delegate_->z80_all_ram_processor_did_perform_bus_operation(*this, cycle.operation, address, cycle.value ? *cycle.value : 0x00, timestamp_);
}
if(delegate_ != nullptr) {
delegate_->z80_all_ram_processor_did_perform_bus_operation(*this, cycle.operation, address, cycle.value ? *cycle.value : 0x00, timestamp_);
}
return 0;
}
void run_for_cycles(int cycles) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::run_for_cycles(cycles);
}
uint16_t get_value_of_register(Register r) {
return CPU::Z80::Processor<ConcreteAllRAMProcessor>::get_value_of_register(r);
}
void set_value_of_register(Register r, uint16_t value) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_value_of_register(r, value);
}
bool get_halt_line() {
return CPU::Z80::Processor<ConcreteAllRAMProcessor>::get_halt_line();
}
};
return 0;
}
AllRAMProcessor *AllRAMProcessor::Processor() {
return new ConcreteAllRAMProcessor;
}

View File

@ -16,23 +16,26 @@ namespace CPU {
namespace Z80 {
class AllRAMProcessor:
public ::CPU::AllRAMProcessor,
public Processor<AllRAMProcessor> {
public ::CPU::AllRAMProcessor {
public:
AllRAMProcessor();
int perform_machine_cycle(const MachineCycle &cycle);
static AllRAMProcessor *Processor();
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;
};
void set_memory_access_delegate(MemoryAccessDelegate *delegate) {
inline void set_memory_access_delegate(MemoryAccessDelegate *delegate) {
delegate_ = delegate;
}
private:
virtual void run_for_cycles(int cycles) = 0;
virtual uint16_t get_value_of_register(Register r) = 0;
virtual void set_value_of_register(Register r, uint16_t value) = 0;
virtual bool get_halt_line() = 0;
protected:
MemoryAccessDelegate *delegate_;
AllRAMProcessor() : ::CPU::AllRAMProcessor(65536), delegate_(nullptr) {}
};
}