1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 03:32:01 +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:
Thomas Harte 2017-05-29 15:57:27 -04:00
parent 8a8f0cef20
commit a6a4c5a936
5 changed files with 93 additions and 21 deletions

View File

@ -12,19 +12,21 @@
@class CSTestMachineZ80;
@protocol CSTestMachineTrapHandler
- (void)testMachine:(CSTestMachineZ80 *)testMachine didTrapAtAddress:(uint16_t)address;
- (void)testMachine:(nonnull CSTestMachineZ80 *)testMachine didTrapAtAddress:(uint16_t)address;
@end
typedef NS_ENUM(NSInteger, CSTestMachineZ80BusOperationCaptureOperation) {
CSTestMachineZ80BusOperationCaptureOperationRead,
CSTestMachineZ80BusOperationCaptureOperationWrite
CSTestMachineZ80BusOperationCaptureOperationWrite,
CSTestMachineZ80BusOperationCaptureOperationPortRead,
CSTestMachineZ80BusOperationCaptureOperationPortWrite,
};
@interface CSTestMachineZ80BusOperationCapture: NSObject
@property(nonatomic, assign) CSTestMachineZ80BusOperationCaptureOperation operation;
@property(nonatomic, assign) uint16_t address;
@property(nonatomic, assign) uint8_t value;
@property(nonatomic, assign) int timeStamp;
@property(nonatomic, readonly) CSTestMachineZ80BusOperationCaptureOperation operation;
@property(nonatomic, readonly) uint16_t address;
@property(nonatomic, readonly) uint8_t value;
@property(nonatomic, readonly) int timeStamp;
@end
typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
@ -46,7 +48,7 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
@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;
- (uint8_t)valueAtAddress:(uint16_t)address;
@ -56,11 +58,11 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
- (void)setValue:(uint16_t)value forRegister:(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;
@property(nonatomic, assign) BOOL captureBusActivity;
@property(nonatomic, readonly) NSArray<CSTestMachineZ80BusOperationCapture *> *busOperationCaptures;
@property(nonatomic, readonly, nonnull) NSArray<CSTestMachineZ80BusOperationCapture *> *busOperationCaptures;
@property(nonatomic, readonly) BOOL isHalted;

View File

@ -79,6 +79,13 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
#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
- (NSString *)description {
@ -106,6 +113,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
if(self = [super init]) {
_cppTrapHandler = new MachineTrapHandler(self);
_busOperationHandler = new BusOperationHandler(self);
_busOperationCaptures = [[NSMutableArray alloc] init];
_processor.set_trap_handler(_cppTrapHandler);
_processor.set_memory_access_delegate(_busOperationHandler);
@ -178,17 +186,33 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
_isAtReadOpcode = YES;
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) {
CSTestMachineZ80BusOperationCapture *capture = [[CSTestMachineZ80BusOperationCapture alloc] init];
capture.operation = (operation == CPU::Z80::BusOperation::Write) ? CSTestMachineZ80BusOperationCaptureOperationWrite : CSTestMachineZ80BusOperationCaptureOperationRead;
capture.address = address;
capture.value = value;
capture.timeStamp = timeStamp;
case CPU::Z80::BusOperation::Read:
case CPU::Z80::BusOperation::ReadOpcode:
capture.operation = CSTestMachineZ80BusOperationCaptureOperationRead;
break;
[_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];
}
}

View File

@ -175,6 +175,7 @@ class FUSETests: XCTestCase {
let targetState = RegisterState(dictionary: outputDictionary["state"] as! [String: Any])
let machine = CSTestMachineZ80()
machine.captureBusActivity = true
initialState.set(onMachine: machine)
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
}
}
}
}
}

View File

@ -41,7 +41,7 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler {
}
}
func testMachine(_ testMachine: CSTestMachineZ80!, didTrapAtAddress address: UInt16) {
func testMachine(_ testMachine: CSTestMachineZ80, didTrapAtAddress address: UInt16) {
switch address {
case 0x0005:
let cRegister = testMachine.value(for: .C)
@ -67,7 +67,8 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler {
break
}
case 0x0000:
done = true;
done = true
default:
break
}

View File

@ -16,7 +16,7 @@ AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536), delegate_(nu
int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
switch(cycle->operation) {
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);
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));