mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-15 14:27:29 +00:00
Made an attempt to introduce checking of bus activity against the FUSE tests. Appears to suggest 54 new failures.
This commit is contained in:
@@ -12,19 +12,21 @@
|
|||||||
@class CSTestMachineZ80;
|
@class CSTestMachineZ80;
|
||||||
|
|
||||||
@protocol CSTestMachineTrapHandler
|
@protocol CSTestMachineTrapHandler
|
||||||
- (void)testMachine:(CSTestMachineZ80 *)testMachine didTrapAtAddress:(uint16_t)address;
|
- (void)testMachine:(nonnull CSTestMachineZ80 *)testMachine didTrapAtAddress:(uint16_t)address;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, CSTestMachineZ80BusOperationCaptureOperation) {
|
typedef NS_ENUM(NSInteger, CSTestMachineZ80BusOperationCaptureOperation) {
|
||||||
CSTestMachineZ80BusOperationCaptureOperationRead,
|
CSTestMachineZ80BusOperationCaptureOperationRead,
|
||||||
CSTestMachineZ80BusOperationCaptureOperationWrite
|
CSTestMachineZ80BusOperationCaptureOperationWrite,
|
||||||
|
CSTestMachineZ80BusOperationCaptureOperationPortRead,
|
||||||
|
CSTestMachineZ80BusOperationCaptureOperationPortWrite,
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface CSTestMachineZ80BusOperationCapture: NSObject
|
@interface CSTestMachineZ80BusOperationCapture: NSObject
|
||||||
@property(nonatomic, assign) CSTestMachineZ80BusOperationCaptureOperation operation;
|
@property(nonatomic, readonly) CSTestMachineZ80BusOperationCaptureOperation operation;
|
||||||
@property(nonatomic, assign) uint16_t address;
|
@property(nonatomic, readonly) uint16_t address;
|
||||||
@property(nonatomic, assign) uint8_t value;
|
@property(nonatomic, readonly) uint8_t value;
|
||||||
@property(nonatomic, assign) int timeStamp;
|
@property(nonatomic, readonly) int timeStamp;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
|
typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
|
||||||
@@ -46,7 +48,7 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
|
|||||||
|
|
||||||
@interface CSTestMachineZ80 : NSObject
|
@interface CSTestMachineZ80 : NSObject
|
||||||
|
|
||||||
- (void)setData:(NSData *)data atAddress:(uint16_t)startAddress;
|
- (void)setData:(nonnull NSData *)data atAddress:(uint16_t)startAddress;
|
||||||
- (void)setValue:(uint8_t)value atAddress:(uint16_t)address;
|
- (void)setValue:(uint8_t)value atAddress:(uint16_t)address;
|
||||||
- (uint8_t)valueAtAddress:(uint16_t)address;
|
- (uint8_t)valueAtAddress:(uint16_t)address;
|
||||||
|
|
||||||
@@ -56,11 +58,11 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
|
|||||||
- (void)setValue:(uint16_t)value forRegister:(CSTestMachineZ80Register)reg;
|
- (void)setValue:(uint16_t)value forRegister:(CSTestMachineZ80Register)reg;
|
||||||
- (uint16_t)valueForRegister:(CSTestMachineZ80Register)reg;
|
- (uint16_t)valueForRegister:(CSTestMachineZ80Register)reg;
|
||||||
|
|
||||||
@property(nonatomic, weak) id<CSTestMachineTrapHandler> trapHandler;
|
@property(nonatomic, weak, nullable) id<CSTestMachineTrapHandler> trapHandler;
|
||||||
- (void)addTrapAddress:(uint16_t)trapAddress;
|
- (void)addTrapAddress:(uint16_t)trapAddress;
|
||||||
|
|
||||||
@property(nonatomic, assign) BOOL captureBusActivity;
|
@property(nonatomic, assign) BOOL captureBusActivity;
|
||||||
@property(nonatomic, readonly) NSArray<CSTestMachineZ80BusOperationCapture *> *busOperationCaptures;
|
@property(nonatomic, readonly, nonnull) NSArray<CSTestMachineZ80BusOperationCapture *> *busOperationCaptures;
|
||||||
|
|
||||||
@property(nonatomic, readonly) BOOL isHalted;
|
@property(nonatomic, readonly) BOOL isHalted;
|
||||||
|
|
||||||
|
@@ -79,6 +79,13 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
|||||||
|
|
||||||
#pragma mark - Capture class
|
#pragma mark - Capture class
|
||||||
|
|
||||||
|
@interface CSTestMachineZ80BusOperationCapture()
|
||||||
|
@property(nonatomic, assign) CSTestMachineZ80BusOperationCaptureOperation operation;
|
||||||
|
@property(nonatomic, assign) uint16_t address;
|
||||||
|
@property(nonatomic, assign) uint8_t value;
|
||||||
|
@property(nonatomic, assign) int timeStamp;
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation CSTestMachineZ80BusOperationCapture
|
@implementation CSTestMachineZ80BusOperationCapture
|
||||||
|
|
||||||
- (NSString *)description {
|
- (NSString *)description {
|
||||||
@@ -106,6 +113,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
|||||||
if(self = [super init]) {
|
if(self = [super init]) {
|
||||||
_cppTrapHandler = new MachineTrapHandler(self);
|
_cppTrapHandler = new MachineTrapHandler(self);
|
||||||
_busOperationHandler = new BusOperationHandler(self);
|
_busOperationHandler = new BusOperationHandler(self);
|
||||||
|
_busOperationCaptures = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
_processor.set_trap_handler(_cppTrapHandler);
|
_processor.set_trap_handler(_cppTrapHandler);
|
||||||
_processor.set_memory_access_delegate(_busOperationHandler);
|
_processor.set_memory_access_delegate(_busOperationHandler);
|
||||||
@@ -178,17 +186,33 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
|||||||
_isAtReadOpcode = YES;
|
_isAtReadOpcode = YES;
|
||||||
|
|
||||||
if(self.captureBusActivity) {
|
if(self.captureBusActivity) {
|
||||||
if(!_busOperationCaptures) _busOperationCaptures = [[NSMutableArray alloc] init];
|
CSTestMachineZ80BusOperationCapture *capture = [[CSTestMachineZ80BusOperationCapture alloc] init];
|
||||||
|
switch(operation) {
|
||||||
|
case CPU::Z80::BusOperation::Write:
|
||||||
|
capture.operation = CSTestMachineZ80BusOperationCaptureOperationWrite;
|
||||||
|
break;
|
||||||
|
|
||||||
if(operation == CPU::Z80::BusOperation::Read || operation == CPU::Z80::BusOperation::ReadOpcode || operation == CPU::Z80::BusOperation::Write) {
|
case CPU::Z80::BusOperation::Read:
|
||||||
CSTestMachineZ80BusOperationCapture *capture = [[CSTestMachineZ80BusOperationCapture alloc] init];
|
case CPU::Z80::BusOperation::ReadOpcode:
|
||||||
capture.operation = (operation == CPU::Z80::BusOperation::Write) ? CSTestMachineZ80BusOperationCaptureOperationWrite : CSTestMachineZ80BusOperationCaptureOperationRead;
|
capture.operation = CSTestMachineZ80BusOperationCaptureOperationRead;
|
||||||
capture.address = address;
|
break;
|
||||||
capture.value = value;
|
|
||||||
capture.timeStamp = timeStamp;
|
|
||||||
|
|
||||||
[_busOperationCaptures addObject:capture];
|
case CPU::Z80::BusOperation::Input:
|
||||||
|
capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortRead;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPU::Z80::BusOperation::Output:
|
||||||
|
capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortWrite;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
capture.address = address;
|
||||||
|
capture.value = value;
|
||||||
|
capture.timeStamp = timeStamp;
|
||||||
|
|
||||||
|
[_busOperationCaptures addObject:capture];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -175,6 +175,7 @@ class FUSETests: XCTestCase {
|
|||||||
let targetState = RegisterState(dictionary: outputDictionary["state"] as! [String: Any])
|
let targetState = RegisterState(dictionary: outputDictionary["state"] as! [String: Any])
|
||||||
|
|
||||||
let machine = CSTestMachineZ80()
|
let machine = CSTestMachineZ80()
|
||||||
|
machine.captureBusActivity = true
|
||||||
initialState.set(onMachine: machine)
|
initialState.set(onMachine: machine)
|
||||||
|
|
||||||
let inputMemoryGroups = itemDictionary["memory"] as? [Any]
|
let inputMemoryGroups = itemDictionary["memory"] as? [Any]
|
||||||
@@ -211,7 +212,51 @@ class FUSETests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO compare bus operations
|
// Compare bus operations.
|
||||||
|
let capturedBusActivity = machine.busOperationCaptures
|
||||||
|
var capturedBusAcivityIndex = 0;
|
||||||
|
|
||||||
|
let desiredBusActivity = outputDictionary["busActivity"] as? [[String: Any]]
|
||||||
|
if let desiredBusActivity = desiredBusActivity {
|
||||||
|
for action in desiredBusActivity {
|
||||||
|
let type = action["type"] as! String
|
||||||
|
let time = action["time"] as! Int32
|
||||||
|
let address = action["address"] as! UInt16
|
||||||
|
let value = action["value"] as? UInt8
|
||||||
|
|
||||||
|
if type == "MC" || type == "PC" {
|
||||||
|
// Don't do anything with FUSE's contended memory records; it's
|
||||||
|
// presently unclear to me exactly what they're supposed to communicate
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var operation: CSTestMachineZ80BusOperationCaptureOperation = .read
|
||||||
|
switch type {
|
||||||
|
case "MR":
|
||||||
|
operation = .read
|
||||||
|
|
||||||
|
case "MW":
|
||||||
|
operation = .write
|
||||||
|
|
||||||
|
case "PR":
|
||||||
|
operation = .portRead
|
||||||
|
|
||||||
|
case "PW":
|
||||||
|
operation = .portWrite
|
||||||
|
|
||||||
|
default:
|
||||||
|
print("Unhandled activity type \(type)!")
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssert(
|
||||||
|
capturedBusActivity[capturedBusAcivityIndex].address == address &&
|
||||||
|
capturedBusActivity[capturedBusAcivityIndex].value == value! &&
|
||||||
|
capturedBusActivity[capturedBusAcivityIndex].timeStamp == time &&
|
||||||
|
capturedBusActivity[capturedBusAcivityIndex].operation == operation,
|
||||||
|
"Failed bus operation match \(name)")
|
||||||
|
capturedBusAcivityIndex += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,7 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMachine(_ testMachine: CSTestMachineZ80!, didTrapAtAddress address: UInt16) {
|
func testMachine(_ testMachine: CSTestMachineZ80, didTrapAtAddress address: UInt16) {
|
||||||
switch address {
|
switch address {
|
||||||
case 0x0005:
|
case 0x0005:
|
||||||
let cRegister = testMachine.value(for: .C)
|
let cRegister = testMachine.value(for: .C)
|
||||||
@@ -67,7 +67,8 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 0x0000:
|
case 0x0000:
|
||||||
done = true;
|
done = true
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536), delegate_(nu
|
|||||||
int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
|
int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
|
||||||
switch(cycle->operation) {
|
switch(cycle->operation) {
|
||||||
case BusOperation::ReadOpcode:
|
case BusOperation::ReadOpcode:
|
||||||
// printf("! %02x\n", memory_[*cycle->address]);
|
// printf("%04x %02x [BC=%02x]\n", *cycle->address, memory_[*cycle->address], get_value_of_register(CPU::Z80::Register::BC));
|
||||||
check_address_for_trap(*cycle->address);
|
check_address_for_trap(*cycle->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));
|
||||||
|
Reference in New Issue
Block a user