1
0
mirror of https://github.com/irmen/ksim65.git synced 2024-06-06 07:29:29 +00:00

fix disassembly of address wrap arounds

This commit is contained in:
Irmen de Jong 2020-02-09 16:36:57 +01:00
parent b7ebf6c922
commit 7f3dd9c95d
3 changed files with 47 additions and 58 deletions

View File

@ -94,6 +94,8 @@ open class Cpu6502 : BusComponent() {
val regP = StatusRegister()
var currentOpcode: Int = 0
protected set
var currentOpcodeAddress: Address = 0 // the PC can be changed already depending on the addressing mode
protected set
var instrCycles: Int = 0
protected set
@ -167,8 +169,7 @@ open class Cpu6502 : BusComponent() {
// addressing mode used by the 65C02, put here for convenience rather than the subclass
val zpAddr = memory[location+1]
val rel = memory[location+2]
val target = if (rel <= 0x7f) location+3+rel+baseAddress
else location+3-(256-rel)+baseAddress
val target = (if (rel <= 0x7f) location+3+rel+baseAddress else location+3-(256-rel)+baseAddress) and 0xffff
Pair(line+"${hexB(zpAddr)} ${hexB(rel)} $spacing3 ${opcode.mnemonic} \$${hexB(zpAddr)}, \$${hexW(target, true)}", 3)
}
AddrMode.Izp -> {
@ -193,8 +194,7 @@ open class Cpu6502 : BusComponent() {
}
AddrMode.Rel -> {
val rel = memory[location+1]
val target = if (rel <= 0x7f) location+2+rel+baseAddress
else location+2-(256-rel)+baseAddress
val target = (if (rel <= 0x7f) location+2+rel+baseAddress else location+2-(256-rel)+baseAddress) and 0xffff
Pair(line+"${hexB(rel)} $spacing2 ${opcode.mnemonic} \$${hexW(target, true)}", 2)
}
AddrMode.Abs -> {
@ -268,6 +268,7 @@ open class Cpu6502 : BusComponent() {
currentInstruction = instructions[0]
} else {
// no interrupt, fetch next instruction from memory
currentOpcodeAddress = regPC
currentOpcode = read(regPC)
currentInstruction = instructions[currentOpcode]
@ -1386,75 +1387,75 @@ open class Cpu6502 : BusComponent() {
// unofficial/illegal 6502 instructions
private fun iAhx() {
TODO("ahx - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - ahx - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iAlr() {
TODO("alr=asr - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - alr=asr - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iAnc() {
TODO("anc - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - anc - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iArr() {
TODO("arr - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - arr - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iAxs() {
TODO("axs - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - axs - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iDcp() {
TODO("dcp - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - dcp - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iIsc() {
TODO("isc=isb - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - isc=isb - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iLas() {
TODO("las=lar - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - las=lar - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iLax() {
TODO("lax - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - lax - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iRla() {
TODO("rla - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - rla - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iRra() {
TODO("rra - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - rra - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iSax() {
TODO("sax - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - sax - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iShx() {
TODO("shx - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - shx - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iShy() {
TODO("shy - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - shy - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iSlo() {
TODO("slo=aso - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - slo=aso - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iSre() {
TODO("sre=lse - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - sre=lse - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iTas() {
TODO("tas - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - tas - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
private fun iXaa() {
TODO("xaa - ('illegal' instruction)")
TODO("\$${hexB(currentOpcode)} - xaa - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
}
// invalid instruction (JAM / KIL)

View File

@ -14,7 +14,7 @@ fun hexB(number: Short): String = hexB(number.toInt())
fun hexB(number: Int): String {
val hexdigits = "0123456789abcdef"
val loNibble = number and 15
val hiNibble = number ushr 4
val hiNibble = (number and 65535) ushr 4
return hexdigits[hiNibble].toString()+hexdigits[loNibble]
}

View File

@ -52,7 +52,7 @@ class Test6502Klaus2m5Functional {
}
@Test
fun testFunctional65C02() {
fun testExtendedOpcodes65C02() {
val cpu = Cpu65C02()
val bus = Bus()
val ram = Ram(0, 0xffff)
@ -61,28 +61,22 @@ class Test6502Klaus2m5Functional {
bus.add(ram)
cpu.reset()
cpu.regPC = 0x0400
cpu.addBreakpoint(0x24f1) { _, _ ->
// reaching this address means successful test result
if(cpu.currentOpcode==0x4c)
throw SuccessfulTestResult()
Cpu6502.BreakpointResultAction(null, null)
}
try {
while (cpu.totalCycles < 100000000) {
cpu.clock()
}
} catch (sx: SuccessfulTestResult) {
println("test successful")
return
do {
val previousPC = cpu.regPC
cpu.step()
} while(cpu.regPC!=previousPC)
} catch(nx: NotImplementedError) {
println("encountered a not yet implemented feature: ${nx.message}")
}
println(cpu.snapshot())
val d = cpu.disassemble(ram, max(0, cpu.regPC-20), min(65535, cpu.regPC+20))
println(d.first.joinToString ("\n"))
fail("test failed")
// the test is successful if address 0x24f1 is reached ("success" label in source code)
if(cpu.regPC!=0x24f1) {
println(cpu.snapshot())
val d = cpu.disassemble(ram, max(0, cpu.regPC-20), min(65535, cpu.regPC+20))
println(d.first.joinToString("\n"))
fail("test failed")
}
}
@Test
@ -96,28 +90,22 @@ class Test6502Klaus2m5Functional {
bus.add(ram)
cpu.reset()
cpu.regPC = 0x0400
// cpu.addBreakpoint(0x3469) { _, _ ->
// // reaching this address means successful test result
// if(cpu.currentOpcode==0x4c)
// throw SuccessfulTestResult()
// Cpu6502.BreakpointResultAction(null, null)
// }
try {
while (cpu.totalCycles < 100000000) {
cpu.clock()
}
} catch (sx: SuccessfulTestResult) {
println("test successful ${cpu.totalCycles}")
return
do {
val previousPC = cpu.regPC
cpu.step()
} while(cpu.regPC!=previousPC)
} catch(nx: NotImplementedError) {
println("encountered a not yet implemented feature: ${nx.message}")
}
println(cpu.snapshot())
val d = cpu.disassemble(ram, max(0, cpu.regPC-20), min(65535, cpu.regPC+20))
println(d.first.joinToString ("\n"))
fail("test failed")
// the test is successful if address 0x06f5 is reached ("success" label in source code)
if(cpu.regPC!=0x06f5) {
println(cpu.snapshot())
val d = cpu.disassemble(ram, max(0, cpu.regPC-20), min(65535, cpu.regPC+20))
println(d.first.joinToString("\n"))
fail("test failed")
}
}
@Test