1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Continued filling in tests, fleshing out what the test machine captures as a result.

This commit is contained in:
Thomas Harte 2017-06-15 20:59:59 -04:00
parent ac37424878
commit cf795562bf
4 changed files with 165 additions and 5 deletions

View File

@ -13,10 +13,12 @@
@class CSTestMachineZ80; @class CSTestMachineZ80;
typedef NS_ENUM(NSInteger, CSTestMachineZ80BusOperationCaptureOperation) { typedef NS_ENUM(NSInteger, CSTestMachineZ80BusOperationCaptureOperation) {
CSTestMachineZ80BusOperationCaptureOperationReadOpcode,
CSTestMachineZ80BusOperationCaptureOperationRead, CSTestMachineZ80BusOperationCaptureOperationRead,
CSTestMachineZ80BusOperationCaptureOperationWrite, CSTestMachineZ80BusOperationCaptureOperationWrite,
CSTestMachineZ80BusOperationCaptureOperationPortRead, CSTestMachineZ80BusOperationCaptureOperationPortRead,
CSTestMachineZ80BusOperationCaptureOperationPortWrite, CSTestMachineZ80BusOperationCaptureOperationPortWrite,
CSTestMachineZ80BusOperationCaptureOperationInternalOperation,
}; };
@interface CSTestMachineZ80BusOperationCapture: NSObject @interface CSTestMachineZ80BusOperationCapture: NSObject

View File

@ -199,10 +199,13 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
break; break;
case CPU::Z80::BusOperation::Read: case CPU::Z80::BusOperation::Read:
case CPU::Z80::BusOperation::ReadOpcode:
capture.operation = CSTestMachineZ80BusOperationCaptureOperationRead; capture.operation = CSTestMachineZ80BusOperationCaptureOperationRead;
break; break;
case CPU::Z80::BusOperation::ReadOpcode:
capture.operation = CSTestMachineZ80BusOperationCaptureOperationReadOpcode;
break;
case CPU::Z80::BusOperation::Input: case CPU::Z80::BusOperation::Input:
capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortRead; capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortRead;
break; break;
@ -211,6 +214,10 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortWrite; capture.operation = CSTestMachineZ80BusOperationCaptureOperationPortWrite;
break; break;
case CPU::Z80::BusOperation::Internal:
capture.operation = CSTestMachineZ80BusOperationCaptureOperationInternalOperation;
break;
default: default:
return; return;
} }

View File

@ -246,19 +246,24 @@ class FUSETests: XCTestCase {
// it counts a port access as occurring on the second. timeOffset is used to adjust // it counts a port access as occurring on the second. timeOffset is used to adjust
// the FUSE numbers as required. // the FUSE numbers as required.
var operation: CSTestMachineZ80BusOperationCaptureOperation = .read var operation: CSTestMachineZ80BusOperationCaptureOperation = .read
var alternativeOperation: CSTestMachineZ80BusOperationCaptureOperation = .read
var timeOffset: Int32 = 0 var timeOffset: Int32 = 0
switch type { switch type {
case "MR": case "MR":
operation = .read operation = .read
alternativeOperation = .readOpcode
case "MW": case "MW":
alternativeOperation = .write
operation = .write operation = .write
case "PR": case "PR":
alternativeOperation = .portRead
operation = .portRead operation = .portRead
timeOffset = 3 timeOffset = 3
case "PW": case "PW":
alternativeOperation = .portWrite
operation = .portWrite operation = .portWrite
timeOffset = 3 timeOffset = 3
@ -270,7 +275,10 @@ class FUSETests: XCTestCase {
capturedBusActivity[capturedBusAcivityIndex].address == address && capturedBusActivity[capturedBusAcivityIndex].address == address &&
capturedBusActivity[capturedBusAcivityIndex].value == value! && capturedBusActivity[capturedBusAcivityIndex].value == value! &&
capturedBusActivity[capturedBusAcivityIndex].timeStamp == (time + timeOffset) && capturedBusActivity[capturedBusAcivityIndex].timeStamp == (time + timeOffset) &&
capturedBusActivity[capturedBusAcivityIndex].operation == operation, (
capturedBusActivity[capturedBusAcivityIndex].operation == operation ||
capturedBusActivity[capturedBusAcivityIndex].operation == alternativeOperation
),
"Failed bus operation match \(name) (at time \(time) with address \(address), value was \(value != nil ? value! : 0), tracking index \(capturedBusAcivityIndex) amongst \(capturedBusActivity))") "Failed bus operation match \(name) (at time \(time) with address \(address), value was \(value != nil ? value! : 0), tracking index \(capturedBusAcivityIndex) amongst \(capturedBusActivity))")
capturedBusAcivityIndex += 1 capturedBusAcivityIndex += 1
} }

View File

@ -10,12 +10,12 @@ import XCTest
class Z80MachineCycleTests: XCTestCase { class Z80MachineCycleTests: XCTestCase {
struct MachineCycle { private struct MachineCycle {
var operation: CSTestMachineZ80BusOperationCaptureOperation var operation: CSTestMachineZ80BusOperationCaptureOperation
var length: Int32 var length: Int32
} }
func test(program : Array<UInt8>, busCycles : [MachineCycle]) { private func test(program : [UInt8], busCycles : [MachineCycle]) {
// Create a machine and install the supplied program at address 0, setting the PC to run from there // Create a machine and install the supplied program at address 0, setting the PC to run from there
let machine = CSTestMachineZ80() let machine = CSTestMachineZ80()
machine.setValue(0x0000, for: .programCounter) machine.setValue(0x0000, for: .programCounter)
@ -45,13 +45,156 @@ class Z80MachineCycleTests: XCTestCase {
} }
} }
// LD r, r
func testLDrs() { func testLDrs() {
test( test(
program: [0x40], program: [0x40],
busCycles: [ busCycles: [
MachineCycle(operation: .read, length: 4) MachineCycle(operation: .readOpcode, length: 4)
] ]
) )
} }
// LD r, nn
func testLDrn() {
test(
program: [0x3e, 0x00],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .read, length: 3),
]
)
}
// LD r, (HL)
func testLDrHL() {
test(
program: [0x46],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .read, length: 3),
]
)
}
// LD (HL), r
func testLDHLr() {
test(
program: [0x70],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .write, length: 3),
]
)
}
// LD r, (IX+d)
func testLDrIXd() {
test(
program: [0xdd, 0x7e, 0x10],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .read, length: 3),
MachineCycle(operation: .internalOperation, length: 5),
MachineCycle(operation: .read, length: 3),
]
)
}
// LD (IX+d), r
func testLDIXdr() {
test(
program: [0xdd, 0x70, 0x10],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .read, length: 3),
MachineCycle(operation: .internalOperation, length: 5),
MachineCycle(operation: .write, length: 3),
]
)
}
// LD (HL), n
func testLDHLn() {
test(
program: [0x36, 0x10],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .read, length: 3),
MachineCycle(operation: .write, length: 3),
]
)
}
// LD A, (DE)
func testLDADE() {
test(
program: [0x1a],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .read, length: 3),
]
)
}
// LD (DE), A
func testLDDEA() {
test(
program: [0x12],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .write, length: 3),
]
)
}
// LD A, (nn)
func testLDAnn() {
test(
program: [0x3a, 0x23, 0x45],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .read, length: 3),
MachineCycle(operation: .read, length: 3),
MachineCycle(operation: .read, length: 3),
]
)
}
// LD (nn), A
func testLDnnA() {
test(
program: [0x32, 0x23, 0x45],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .read, length: 3),
MachineCycle(operation: .read, length: 3),
MachineCycle(operation: .write, length: 3),
]
)
}
// LD A, I
func testLDAI() {
test(
program: [0xed, 0x57],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .readOpcode, length: 5),
]
)
}
// LD I, A
func testLDIA() {
test(
program: [0xed, 0x47],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),
MachineCycle(operation: .readOpcode, length: 5),
]
)
}
} }