1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-15 05:31:30 +00:00

Adds logic to work around Nintendo dependence in the krom tests.

Let the real work begin!
This commit is contained in:
Thomas Harte 2020-11-03 14:18:40 -05:00
parent 3889646d6b
commit 426e90eebf

View File

@ -52,55 +52,103 @@ class Krom65816Tests: XCTestCase {
machine.setValue(0x00ff, for: .stackPointer)
machine.setValue(0x34, for: .flags)
// Poke some fixed values for SNES registers to get past initial setup.
machine.setValue(0x42, forAddress: 0x4210) // "RDNMI", apparently; this says: CPU version 2, vblank interrupt request.
var allowNegativeError = false
var lineNumber = 1
var previousPC = 0
for line in outputLines {
machine.runForNumber(ofInstructions: 1)
// Formulate my 65816 state in the same form as the test machine
var cpuState = ""
let emulationFlag = machine.value(for: .emulationFlag) != 0
cpuState += String(format: "%06x ", machine.value(for: .lastOperationAddress))
cpuState += String(format: "A:%04x ", machine.value(for: .A))
cpuState += String(format: "X:%04x ", machine.value(for: .X))
cpuState += String(format: "Y:%04x ", machine.value(for: .Y))
if emulationFlag {
cpuState += String(format: "S:01%02x ", machine.value(for: .stackPointer))
} else {
cpuState += String(format: "S:%04x ", machine.value(for: .stackPointer))
func machineState() -> String {
// Formulate my 65816 state in the same form as the test machine
var cpuState = ""
let emulationFlag = machine.value(for: .emulationFlag) != 0
cpuState += String(format: "%06x ", machine.value(for: .lastOperationAddress))
cpuState += String(format: "A:%04x ", machine.value(for: .A))
cpuState += String(format: "X:%04x ", machine.value(for: .X))
cpuState += String(format: "Y:%04x ", machine.value(for: .Y))
if emulationFlag {
cpuState += String(format: "S:01%02x ", machine.value(for: .stackPointer))
} else {
cpuState += String(format: "S:%04x ", machine.value(for: .stackPointer))
}
cpuState += String(format: "D:%04x ", machine.value(for: .direct))
cpuState += String(format: "DB:%02x ", machine.value(for: .dataBank))
let flags = machine.value(for: .flags)
cpuState += (flags & 0x80) != 0 ? "N" : "n"
cpuState += (flags & 0x40) != 0 ? "V" : "v"
if emulationFlag {
cpuState += "1B"
} else {
cpuState += (flags & 0x20) != 0 ? "M" : "m"
cpuState += (flags & 0x10) != 0 ? "X" : "x"
}
cpuState += (flags & 0x08) != 0 ? "D" : "d"
cpuState += (flags & 0x04) != 0 ? "I" : "i"
cpuState += (flags & 0x02) != 0 ? "Z" : "z"
cpuState += (flags & 0x01) != 0 ? "C" : "c"
cpuState += " "
return cpuState
}
cpuState += String(format: "D:%04x ", machine.value(for: .direct))
cpuState += String(format: "DB:%02x ", machine.value(for: .dataBank))
let flags = machine.value(for: .flags)
cpuState += (flags & 0x80) != 0 ? "N" : "n"
cpuState += (flags & 0x40) != 0 ? "V" : "v"
if emulationFlag {
// These logs seem always to have the break flag set (?)
cpuState += (flags & 0x20) != 0 ? "1" : "?"
cpuState += "B" //(flags & 0x10) != 0 ? "B" : "b"
} else {
cpuState += (flags & 0x20) != 0 ? "M" : "m"
cpuState += (flags & 0x10) != 0 ? "X" : "x"
// Permit a fix-up of the negative flag only if this line followed a test of $4210.
var cpuState = machineState()
if cpuState != line && allowNegativeError {
machine.setValue(machine.value(for: .flags) ^ 0x80, for: .flags)
cpuState = machineState()
}
cpuState += (flags & 0x08) != 0 ? "D" : "d"
cpuState += (flags & 0x04) != 0 ? "I" : "i"
cpuState += (flags & 0x02) != 0 ? "Z" : "z"
cpuState += (flags & 0x01) != 0 ? "C" : "c"
cpuState += " "
XCTAssertEqual(cpuState, line, "Mismatch on line #\(lineNumber)")
XCTAssertEqual(cpuState, line, "Mismatch on line #\(lineNumber); after instruction #\(String(format:"%02x", machine.value(forAddress: UInt32(previousPC))))")
if cpuState != line {
break
}
lineNumber += 1
previousPC = Int(machine.value(for: .lastOperationAddress))
// Check whether a 'RDNMI' toggle needs to happen by peeking at the next instruction;
// if it's BIT $4210 then toggle the top bit at address $4210.
//
// Coupling here: assume that by the time the test 65816 is aware it's on a new instruction
// it's because the actual 65816 has read a new opcode, and that if the 65816 has just read
// a new opcode then it has already advanced the program counter.
let programCounter = machine.value(for: .programCounter)
let nextInstr = [
machine.value(forAddress: UInt32(programCounter - 1)),
machine.value(forAddress: UInt32(programCounter + 0)),
machine.value(forAddress: UInt32(programCounter + 1))
]
allowNegativeError = nextInstr[0] == 0x2c && nextInstr[1] == 0x10 && nextInstr[2] == 0x42
}
}
// MARK: - Tests
func testADC() {
runTest("CPUADC")
}
func testADC() { runTest("CPUADC") }
func testAND() { runTest("CPUAND") }
func testASL() { runTest("CPUASL") }
func testBIT() { runTest("CPUBIT") }
func testBRA() { runTest("CPUBRA") }
func testCMP() { runTest("CPUCMP") }
func testDEC() { runTest("CPUDEC") }
func testEOR() { runTest("CPUEOR") }
func testINC() { runTest("CPUINC") }
func testJMP() { runTest("CPUJMP") }
func testLDR() { runTest("CPULDR") }
func testLSR() { runTest("CPULSR") }
func testMOV() { runTest("CPUMOV") }
func testMSC() { runTest("CPUMSC") }
func testORA() { runTest("CPUORA") }
func testPHL() { runTest("CPUPHL") }
func testPSR() { runTest("CPUPSR") }
func testROL() { runTest("CPUROL") }
func testROR() { runTest("CPUROR") }
func testSBC() { runTest("CPUSBC") }
func testSTR() { runTest("CPUSTR") }
func testTRN() { runTest("CPUTRN") }
}