mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-08 14:25:05 +00:00
Ensured that wait states don't appear unless requested (TODO: requesting), and made the output of my timing tests a little easier to parse.
This commit is contained in:
@@ -10,9 +10,25 @@ import XCTest
|
|||||||
|
|
||||||
class Z80MachineCycleTests: XCTestCase {
|
class Z80MachineCycleTests: XCTestCase {
|
||||||
|
|
||||||
private struct MachineCycle {
|
private struct MachineCycle: CustomDebugStringConvertible {
|
||||||
var operation: CSTestMachineZ80BusOperationCaptureOperation
|
var operation: CSTestMachineZ80BusOperationCaptureOperation
|
||||||
var length: Int32
|
var length: Int32
|
||||||
|
|
||||||
|
public var debugDescription: String {
|
||||||
|
get {
|
||||||
|
var opName = ""
|
||||||
|
switch operation {
|
||||||
|
case .readOpcode: opName = "ro"
|
||||||
|
case .read: opName = "r"
|
||||||
|
case .write: opName = "w"
|
||||||
|
case .portRead: opName = "i"
|
||||||
|
case .portWrite: opName = "o"
|
||||||
|
case .internalOperation: opName = "iop"
|
||||||
|
}
|
||||||
|
return "\(opName) \(length)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func test(program : [UInt8], busCycles : [MachineCycle]) {
|
private func test(program : [UInt8], busCycles : [MachineCycle]) {
|
||||||
@@ -34,6 +50,7 @@ class Z80MachineCycleTests: XCTestCase {
|
|||||||
// Check the results
|
// Check the results
|
||||||
totalCycles = 0
|
totalCycles = 0
|
||||||
var index = 0
|
var index = 0
|
||||||
|
var matches = true
|
||||||
for cycle in machine.busOperationCaptures {
|
for cycle in machine.busOperationCaptures {
|
||||||
let length = cycle.timeStamp - totalCycles
|
let length = cycle.timeStamp - totalCycles
|
||||||
totalCycles += length
|
totalCycles += length
|
||||||
@@ -44,12 +61,16 @@ class Z80MachineCycleTests: XCTestCase {
|
|||||||
// array access
|
// array access
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
XCTAssertEqual(length, busCycles[index].length)
|
if length != busCycles[index].length || cycle.operation != busCycles[index].operation {
|
||||||
XCTAssertEqual(cycle.operation, busCycles[index].operation)
|
matches = false
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XCTAssert(matches, "Z80 performed \(machine.busOperationCaptures); was expected to perform \(busCycles)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// LD r, r
|
// LD r, r
|
||||||
|
@@ -694,10 +694,11 @@ template <class T> class Processor {
|
|||||||
void assemble_fetch_decode_execute(InstructionPage &target, int length) {
|
void assemble_fetch_decode_execute(InstructionPage &target, int length) {
|
||||||
const MicroOp normal_fetch_decode_execute[] = {
|
const MicroOp normal_fetch_decode_execute[] = {
|
||||||
BusOp(ReadOpcodeStart(pc_, operation_)),
|
BusOp(ReadOpcodeStart(pc_, operation_)),
|
||||||
|
BusOp(ReadOpcodeWait(pc_, operation_)),
|
||||||
{ MicroOp::DecodeOperation }
|
{ MicroOp::DecodeOperation }
|
||||||
};
|
};
|
||||||
const MicroOp short_fetch_decode_execute[] = {
|
const MicroOp short_fetch_decode_execute[] = {
|
||||||
BusOp(ReadOpcodeStart(pc_, operation_)),
|
Read3(pc_, operation_),
|
||||||
{ MicroOp::DecodeOperation }
|
{ MicroOp::DecodeOperation }
|
||||||
};
|
};
|
||||||
copy_program((length == 4) ? normal_fetch_decode_execute : short_fetch_decode_execute, target.fetch_decode_execute);
|
copy_program((length == 4) ? normal_fetch_decode_execute : short_fetch_decode_execute, target.fetch_decode_execute);
|
||||||
@@ -843,6 +844,9 @@ template <class T> class Processor {
|
|||||||
|
|
||||||
switch(operation->type) {
|
switch(operation->type) {
|
||||||
case MicroOp::BusOperation:
|
case MicroOp::BusOperation:
|
||||||
|
if(operation->machine_cycle.was_requested) { // TODO: && !wait_line_
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(number_of_cycles_ < operation->machine_cycle.length) {
|
if(number_of_cycles_ < operation->machine_cycle.length) {
|
||||||
scheduled_program_counter_--;
|
scheduled_program_counter_--;
|
||||||
static_cast<T *>(this)->flush();
|
static_cast<T *>(this)->flush();
|
||||||
|
Reference in New Issue
Block a user