1
0
mirror of https://github.com/irmen/ksim65.git synced 2024-06-13 22:29:29 +00:00
ksim65/src/test/kotlin/Test6502Klaus2m5Functional.kt
2020-02-16 22:45:54 +01:00

204 lines
6.6 KiB
Kotlin

import razorvine.ksim65.Bus
import razorvine.ksim65.components.Ram
import razorvine.ksim65.Cpu6502
import razorvine.ksim65.Cpu65C02
import razorvine.ksim65.components.Address
import razorvine.ksim65.components.MemMappedComponent
import razorvine.ksim65.components.UByte
import razorvine.ksim65.hexW
import java.lang.Exception
import kotlin.test.*
/**
* This runs the 'functional 6502/65c02' tests from Klaus2m5
* (Klaus Dormann, sourced from here https://github.com/Klaus2m5/6502_65C02_functional_tests)
*/
class Test6502Klaus2m5Functional {
private class SuccessfulTestResult: Exception()
@Test
fun testFunctional6502() {
val cpu = Cpu6502()
val bus = Bus()
val ram = Ram(0, 0xffff)
ram.load("src/test/kotlin/6502_functional_tests/bin_files/6502_functional_test.bin", 0)
bus.add(cpu)
bus.add(ram)
cpu.reset()
cpu.regPC = 0x0400
try {
do {
val previousPC = cpu.regPC
cpu.step()
} while(cpu.regPC!=previousPC)
} catch(nx: NotImplementedError) {
println("encountered a not yet implemented feature: ${nx.message}")
}
// the test is successful if address 0x3469 is reached ("success" label in source code)
val testnum = bus[0x200].toInt()
if(cpu.regPC!=0x3469 || testnum!=0xf0) {
println(cpu.snapshot())
fail("test failed")
}
}
@Test
fun testExtendedOpcodes65C02() {
val cpu = Cpu65C02()
val bus = Bus()
val ram = Ram(0, 0xffff)
ram.load("src/test/kotlin/6502_functional_tests/bin_files/65C02_extended_opcodes_test.bin", 0)
bus.add(cpu)
bus.add(ram)
cpu.reset()
cpu.regPC = 0x0400
try {
do {
val previousPC = cpu.regPC
cpu.step()
} while(cpu.regPC!=previousPC)
} catch(nx: NotImplementedError) {
println("encountered a not yet implemented feature: ${nx.message}")
}
// the test is successful if address 0x24f1 is reached ("success" label in source code)
val testnum = bus[0x202].toInt()
println(testnum)
if(cpu.regPC!=0x24f1 || testnum!=0xf0) {
println(cpu.snapshot())
fail("test failed")
}
}
@Test
fun testInterrupts6502() {
val cpu = Cpu6502()
class Trigger(startAddress: Address, endAddress: Address) : MemMappedComponent(startAddress, endAddress) {
var value: UByte = 0
var lastIRQpc: Address = 0
var lastNMIpc: Address = 0
override fun get(offset: Int): UByte = value
override fun set(offset: Int, data: UByte) {
value = data
when(value.toInt()) {
1 -> {
// println("IRQ at pc ${hexW(cpu.regPC)}")
lastIRQpc = cpu.regPC
cpu.irqAsserted = true
}
2 -> {
// println("NMI at pc ${hexW(cpu.regPC)}")
lastNMIpc = cpu.regPC
cpu.nmiAsserted = true
}
3 -> {
// println("IRQ+NMI at pc ${hexW(cpu.regPC)}")
lastIRQpc = cpu.regPC
lastNMIpc = cpu.regPC
cpu.nmiAsserted = true
cpu.irqAsserted = true
}
}
}
override fun clock() {}
override fun reset() {}
}
val bus = Bus()
val ram = Ram(0, 0xffff)
val irqtrigger = Trigger(0xbffc, 0xbffc)
ram.load("src/test/kotlin/6502_functional_tests/bin_files/6502_interrupt_test.bin", 0)
bus.add(cpu)
bus.add(irqtrigger)
bus.add(ram)
cpu.reset()
cpu.regPC = 0x0400
try {
do {
val previousPC = cpu.regPC
cpu.step()
} while(cpu.regPC!=previousPC)
} catch(nx: NotImplementedError) {
println("encountered a not yet implemented feature: ${nx.message}")
}
// the test is successful if address 0x06f5 is reached ("success" label in source code)
if(cpu.regPC!=0x06f5) {
println("Last IRQ triggered at ${hexW(irqtrigger.lastIRQpc)} last NMI at ${hexW(irqtrigger.lastNMIpc)}")
println(cpu.snapshot())
fail("test failed")
}
}
@Test
fun testDecimal6502() {
val cpu = Cpu6502()
val bus = Bus()
val ram = Ram(0, 0xffff)
ram.load("src/test/kotlin/6502_functional_tests/bin_files/6502_decimal_test.bin", 0x0200)
bus.add(cpu)
bus.add(ram)
cpu.reset()
cpu.regPC = 0x0200
cpu.breakpointForBRK = { _, address ->
if(address==0x024b) { // test end address
val error=bus.read(0x000b) // the 'ERROR' variable is stored here
if(error==0.toShort())
throw SuccessfulTestResult()
}
Cpu6502.BreakpointResultAction(null, null)
}
try {
while (cpu.totalCycles < 100000000) {
cpu.clock()
}
} catch (sx: SuccessfulTestResult) {
println("test successful ${cpu.totalCycles}")
return
} catch(nx: NotImplementedError) {
println("encountered a not yet implemented feature: ${nx.message}")
}
println(cpu.snapshot())
fail("test failed")
}
@Test
fun testDecimal65C02() {
val cpu = Cpu65C02()
val bus = Bus()
val ram = Ram(0, 0xffff)
ram.load("src/test/kotlin/6502_functional_tests/bin_files/65C02_decimal_test.bin", 0x0200)
bus.add(cpu)
bus.add(ram)
cpu.reset()
cpu.regPC = 0x0200
cpu.breakpointForBRK = { _, address ->
if(address==0x024b) { // test end address
val error=bus.read(0x000b) // the 'ERROR' variable is stored here
if(error==0.toShort())
throw SuccessfulTestResult()
}
Cpu6502.BreakpointResultAction(null, null)
}
try {
while (cpu.totalCycles < 100000000) {
cpu.clock()
}
} catch (sx: SuccessfulTestResult) {
println("test successful ${cpu.totalCycles}")
return
} catch(nx: NotImplementedError) {
println("encountered a not yet implemented feature: ${nx.message}")
}
println(cpu.snapshot())
fail("test failed")
}
}