From d668879ba6a3a5ac6b7c0baedb2393ce3463c42a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 18 Jun 2017 22:03:13 -0400 Subject: [PATCH] Started trying to wade back to passing tests. Working on the new timing tests first, and focussing on getting the Objective-C test machine to compile bus operations into machine cycles, which means indicating phase to all-RAM delegates. --- .../Bridges/TestMachineZ80.mm | 69 ++++++++++-------- Processors/Z80/Z80.hpp | 2 +- Processors/Z80/Z80AllRAM.cpp | 72 ++++++++----------- Processors/Z80/Z80AllRAM.hpp | 4 +- 4 files changed, 71 insertions(+), 76 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/Bridges/TestMachineZ80.mm b/OSBindings/Mac/Clock SignalTests/Bridges/TestMachineZ80.mm index 2a5c0cf7f..4137bc8a3 100644 --- a/OSBindings/Mac/Clock SignalTests/Bridges/TestMachineZ80.mm +++ b/OSBindings/Mac/Clock SignalTests/Bridges/TestMachineZ80.mm @@ -11,7 +11,11 @@ #import "TestMachine+ForSubclassEyesOnly.h" @interface CSTestMachineZ80 () -- (void)testMachineDidPerformBusOperation:(CPU::Z80::MachineCycle::Operation)operation address:(uint16_t)address value:(uint8_t)value timeStamp:(int)time_stamp; +- (void)testMachineDidPerformBusOperation:(CPU::Z80::MachineCycle::Operation)operation + phase:(CPU::Z80::MachineCycle::Phase)phase + address:(uint16_t)address + value:(uint8_t)value + timeStamp:(int)time_stamp; @end #pragma mark - C++ delegate handlers @@ -20,8 +24,8 @@ class BusOperationHandler: public CPU::Z80::AllRAMProcessor::MemoryAccessDelegat public: BusOperationHandler(CSTestMachineZ80 *targetMachine) : target_(targetMachine) {} - void z80_all_ram_processor_did_perform_bus_operation(CPU::Z80::AllRAMProcessor &processor, CPU::Z80::MachineCycle::Operation operation, uint16_t address, uint8_t value, int time_stamp) { - [target_ testMachineDidPerformBusOperation:operation address:address value:value timeStamp:time_stamp]; + void z80_all_ram_processor_did_perform_bus_operation(CPU::Z80::AllRAMProcessor &processor, CPU::Z80::MachineCycle::Operation operation, CPU::Z80::MachineCycle::Phase phase, uint16_t address, uint8_t value, int time_stamp) { + [target_ testMachineDidPerformBusOperation:operation phase:phase address:address value:value timeStamp:time_stamp]; } private: @@ -152,7 +156,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) { } - (int)completedCycles { - return _processor->get_length_of_completed_machine_cycles(); + return _processor->get_timestamp(); } - (void)setNmiLine:(BOOL)nmiLine { @@ -187,7 +191,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) { _processor->set_memory_access_delegate(captureBusActivity ? _busOperationHandler : nullptr); } -- (void)testMachineDidPerformBusOperation:(CPU::Z80::MachineCycle::Operation)operation address:(uint16_t)address value:(uint8_t)value timeStamp:(int)timeStamp { +- (void)testMachineDidPerformBusOperation:(CPU::Z80::MachineCycle::Operation)operation phase:(CPU::Z80::MachineCycle::Phase)phase address:(uint16_t)address value:(uint8_t)value timeStamp:(int)timeStamp { int length = timeStamp - _lastOpcodeTime; _lastOpcodeTime = timeStamp; if(operation == CPU::Z80::MachineCycle::Operation::ReadOpcode && length < _timeSeekingReadOpcode) @@ -195,39 +199,42 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) { if(self.captureBusActivity) { CSTestMachineZ80BusOperationCapture *capture = [[CSTestMachineZ80BusOperationCapture alloc] init]; - switch(operation) { - case CPU::Z80::MachineCycle::Operation::Write: - capture.operation = CSTestMachineZ80BusOperationCaptureOperationWrite; - break; + if(phase == CPU::Z80::MachineCycle::Phase::End) { + switch(operation) { + case CPU::Z80::MachineCycle::Operation::Write: + capture.operation = CSTestMachineZ80BusOperationCaptureOperationWrite; + break; - case CPU::Z80::MachineCycle::Operation::Read: - capture.operation = CSTestMachineZ80BusOperationCaptureOperationRead; - break; + case CPU::Z80::MachineCycle::Operation::Read: + capture.operation = CSTestMachineZ80BusOperationCaptureOperationRead; + break; - case CPU::Z80::MachineCycle::Operation::ReadOpcode: - capture.operation = CSTestMachineZ80BusOperationCaptureOperationReadOpcode; - break; + case CPU::Z80::MachineCycle::Operation::ReadOpcode: + case CPU::Z80::MachineCycle::Operation::Refresh: + capture.operation = CSTestMachineZ80BusOperationCaptureOperationReadOpcode; + break; - case CPU::Z80::MachineCycle::Operation::Input: - capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortRead; - break; + case CPU::Z80::MachineCycle::Operation::Input: + capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortRead; + break; - case CPU::Z80::MachineCycle::Operation::Output: - capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortWrite; - break; + case CPU::Z80::MachineCycle::Operation::Output: + capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortWrite; + break; - case CPU::Z80::MachineCycle::Operation::Internal: - capture.operation = CSTestMachineZ80BusOperationCaptureOperationInternalOperation; - break; + case CPU::Z80::MachineCycle::Operation::Internal: + capture.operation = CSTestMachineZ80BusOperationCaptureOperationInternalOperation; + break; - default: - return; + default: + return; + } + capture.address = address; + capture.value = value; + capture.timeStamp = timeStamp; + + [_busOperationCaptures addObject:capture]; } - capture.address = address; - capture.value = value; - capture.timeStamp = timeStamp; - - [_busOperationCaptures addObject:capture]; } } diff --git a/Processors/Z80/Z80.hpp b/Processors/Z80/Z80.hpp index 927e66a8f..7734b116c 100644 --- a/Processors/Z80/Z80.hpp +++ b/Processors/Z80/Z80.hpp @@ -86,7 +86,7 @@ struct MachineCycle { // Elemental bus operations #define ReadOpcodeStart(addr, val) {MachineCycle::ReadOpcode, MachineCycle::Phase::Start, 2, &addr.full, &val, false} #define ReadOpcodeWait(addr, val) {MachineCycle::ReadOpcode, MachineCycle::Phase::Wait, 1, &addr.full, &val, true} -#define Refresh(len) {MachineCycle::Refresh, MachineCycle::Phase::Start, 2, &ir_.full, nullptr, false} +#define Refresh(len) {MachineCycle::Refresh, MachineCycle::Phase::End, 2, &ir_.full, nullptr, false} #define ReadStart(addr, val) {MachineCycle::Read, MachineCycle::Phase::Start, 2, &addr.full, &val, false} #define ReadWait(l, addr, val, f) {MachineCycle::Read, MachineCycle::Phase::Wait, l, &addr.full, &val, f} diff --git a/Processors/Z80/Z80AllRAM.cpp b/Processors/Z80/Z80AllRAM.cpp index 99340657c..7a25b5cae 100644 --- a/Processors/Z80/Z80AllRAM.cpp +++ b/Processors/Z80/Z80AllRAM.cpp @@ -14,49 +14,47 @@ namespace { class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor { public: - ConcreteAllRAMProcessor() : AllRAMProcessor(), completed_cycles(0) {} + ConcreteAllRAMProcessor() : AllRAMProcessor() {} inline int perform_machine_cycle(const MachineCycle &cycle) { - completed_cycles += cycle.length; uint16_t address = cycle.address ? *cycle.address : 0x0000; - switch(cycle.operation) { - case MachineCycle::Operation::ReadOpcode: -// printf("! "); - check_address_for_trap(address); - case MachineCycle::Operation::Read: -// printf("r %04x [%02x] AF:%04x BC:%04x DE:%04x HL:%04x SP:%04x\n", address, memory_[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 MachineCycle::Operation::Write: -// printf("w %04x\n", address); - memory_[address] = *cycle.value; - break; +// if(cycle.phase == MachineCycle::Phase::End) { + switch(cycle.operation) { + case MachineCycle::Operation::ReadOpcode: + check_address_for_trap(address); + case MachineCycle::Operation::Read: + *cycle.value = memory_[address]; + break; + case MachineCycle::Operation::Write: + memory_[address] = *cycle.value; + break; - case MachineCycle::Operation::Output: - break; - case MachineCycle::Operation::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 MachineCycle::Operation::Output: + break; + case MachineCycle::Operation::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 MachineCycle::Operation::Internal: - break; + case MachineCycle::Operation::Internal: + break; - case MachineCycle::Operation::Interrupt: - // A pick that means LD HL, (nn) if interpreted as an instruction but is otherwise - // arbitrary. - *cycle.value = 0x21; - break; + case MachineCycle::Operation::Interrupt: + // A pick that means LD HL, (nn) if interpreted as an instruction but is otherwise + // arbitrary. + *cycle.value = 0x21; + break; - default: - printf("???\n"); - break; - } + 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_); + delegate_->z80_all_ram_processor_did_perform_bus_operation(*this, cycle.operation, cycle.phase, address, cycle.value ? *cycle.value : 0x00, timestamp_); } return 0; @@ -89,14 +87,6 @@ class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor::set_non_maskable_interrupt_line(value); } - - int get_length_of_completed_machine_cycles() { - return completed_cycles; - } - - private: - int completed_cycles; - }; } diff --git a/Processors/Z80/Z80AllRAM.hpp b/Processors/Z80/Z80AllRAM.hpp index 778437f7c..3c77f943c 100644 --- a/Processors/Z80/Z80AllRAM.hpp +++ b/Processors/Z80/Z80AllRAM.hpp @@ -22,7 +22,7 @@ class AllRAMProcessor: static AllRAMProcessor *Processor(); struct MemoryAccessDelegate { - virtual void z80_all_ram_processor_did_perform_bus_operation(AllRAMProcessor &processor, MachineCycle::Operation operation, uint16_t address, uint8_t value, int time_stamp) = 0; + virtual void z80_all_ram_processor_did_perform_bus_operation(CPU::Z80::AllRAMProcessor &processor, CPU::Z80::MachineCycle::Operation operation, CPU::Z80::MachineCycle::Phase phase, uint16_t address, uint8_t value, int time_stamp) = 0; }; inline void set_memory_access_delegate(MemoryAccessDelegate *delegate) { delegate_ = delegate; @@ -36,8 +36,6 @@ class AllRAMProcessor: virtual void set_interrupt_line(bool value) = 0; virtual void set_non_maskable_interrupt_line(bool value) = 0; - virtual int get_length_of_completed_machine_cycles() = 0; - protected: MemoryAccessDelegate *delegate_; AllRAMProcessor() : ::CPU::AllRAMProcessor(65536), delegate_(nullptr) {}