mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-09 00:37:27 +00:00
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.
This commit is contained in:
parent
cb140aa06e
commit
d668879ba6
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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}
|
||||
|
@ -14,49 +14,47 @@ namespace {
|
||||
|
||||
class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<ConcreteAllRAMProcessor> {
|
||||
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<Concrete
|
||||
void set_non_maskable_interrupt_line(bool value) {
|
||||
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_non_maskable_interrupt_line(value);
|
||||
}
|
||||
|
||||
int get_length_of_completed_machine_cycles() {
|
||||
return completed_cycles;
|
||||
}
|
||||
|
||||
private:
|
||||
int completed_cycles;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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) {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user