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

implemented a bunch of 65c02 opcodes

This commit is contained in:
Irmen de Jong 2019-09-13 00:14:49 +02:00
parent d191b757c6
commit 8a49302e3c
3 changed files with 738 additions and 392 deletions

View File

@ -2,12 +2,15 @@ package razorvine.ksim65.components
// TODO: implement the illegal opcodes, see http://www.ffd2.com/fridge/docs/6502-NMOS.extra.opcodes
// TODO: add the optional additional cycles to certain instructions and addressing modes
// TODO: add 6510 behavior mode (is there even a difference to be simulated here?)
/**
* 6502 cpu simulation (the NMOS version) including the 'illegal' opcodes.
*/
open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
var tracing: Boolean = false
var totalCycles: Long = 0
private set
protected set
class InstructionError(msg: String) : RuntimeException(msg)
@ -23,6 +26,7 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
Acc,
Imm,
Zp,
Zpr, // special addressing mode used by the 65C02
ZpX,
ZpY,
Rel,
@ -31,7 +35,8 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
AbsY,
Ind,
IzX,
IzY
IzY,
Izp // special addressing mode used by the 65C02
}
class Instruction(val mnemonic: String, val mode: AddrMode, val cycles: Int)
@ -89,7 +94,7 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
var PC: Address = 0
val Status = StatusRegister()
var currentOpcode: Int = 0
private lateinit var currentInstruction: Instruction
protected lateinit var currentInstruction: Instruction
// has an interrupt been requested?
protected var pendingInterrupt: Pair<Boolean, BusComponent>? = null
@ -98,7 +103,7 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
private var fetchedData: Int = 0
// all other addressing modes yield a fetched memory address
private var fetchedAddress: Address = 0
protected var fetchedAddress: Address = 0
private val breakpoints = mutableMapOf<Address, (cpu: Cpu6502, pc: Address) -> Unit>()
@ -162,6 +167,14 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
zpAddr
)}"
}
AddrMode.Zpr -> {
// addressing mode used by the 65C02 only
TODO("ZPR addressing mode")
}
AddrMode.Izp -> {
// addressing mode used by the 65C02 only
TODO("ZPI addressing mode")
}
AddrMode.ZpX -> {
val zpAddr = memory[address++]
line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB(
@ -300,7 +313,7 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
totalCycles++
}
fun step() {
open fun step() {
// step a whole instruction
while (instrCycles > 0) clock() // remaining instruction subcycles from the previous instruction
clock() // the actual instruction execution cycle
@ -343,16 +356,16 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
else
read(fetchedAddress)
private fun readPc(): Int = bus.read(PC++).toInt()
protected fun readPc(): Int = bus.read(PC++).toInt()
private fun pushStackAddr(address: Address) {
protected fun pushStackAddr(address: Address) {
val lo = address and 0xff
val hi = (address ushr 8)
pushStack(hi)
pushStack(lo)
}
private fun pushStack(status: StatusRegister) {
protected fun pushStack(status: StatusRegister) {
pushStack(status.asByte().toInt())
}
@ -372,271 +385,273 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
return lo or (hi shl 8)
}
private fun read(address: Address): Int = bus.read(address).toInt()
protected fun read(address: Address): Int = bus.read(address).toInt()
protected fun readWord(address: Address): Int = bus.read(address).toInt() or (bus.read(address + 1).toInt() shl 8)
private fun write(address: Address, data: Int) = bus.write(address, data.toShort())
protected fun write(address: Address, data: Int) = bus.write(address, data.toShort())
// opcodes table from http://www.oxyron.de/html/opcodes02.html
private val instructions = listOf(
Instruction("brk", AddrMode.Imp, 7),
Instruction("ora", AddrMode.IzX, 6),
Instruction("???", AddrMode.Imp, 0),
Instruction("slo", AddrMode.IzX, 8),
Instruction("nop", AddrMode.Zp, 3),
Instruction("ora", AddrMode.Zp, 3),
Instruction("asl", AddrMode.Zp, 5),
Instruction("slo", AddrMode.Zp, 5),
Instruction("php", AddrMode.Imp, 3),
Instruction("ora", AddrMode.Imm, 2),
Instruction("asl", AddrMode.Acc, 2),
Instruction("anc", AddrMode.Imm, 2),
Instruction("nop", AddrMode.Abs, 4),
Instruction("ora", AddrMode.Abs, 4),
Instruction("asl", AddrMode.Abs, 6),
Instruction("slo", AddrMode.Abs, 6),
Instruction("bpl", AddrMode.Rel, 2),
Instruction("ora", AddrMode.IzY, 5),
Instruction("???", AddrMode.Imp, 0),
Instruction("slo", AddrMode.IzY, 6),
Instruction("nop", AddrMode.ZpX, 4),
Instruction("ora", AddrMode.ZpX, 4),
Instruction("asl", AddrMode.ZpX, 6),
Instruction("slo", AddrMode.ZpX, 6),
Instruction("clc", AddrMode.Imp, 2),
Instruction("ora", AddrMode.AbsY, 4),
Instruction("nop", AddrMode.Imp, 2),
Instruction("slo", AddrMode.AbsY, 7),
Instruction("nop", AddrMode.AbsX, 4),
Instruction("ora", AddrMode.AbsX, 4),
Instruction("asl", AddrMode.AbsX, 7),
Instruction("slo", AddrMode.AbsX, 7),
Instruction("jsr", AddrMode.Abs, 6),
Instruction("and", AddrMode.IzX, 6),
Instruction("???", AddrMode.Imp, 0),
Instruction("rla", AddrMode.IzX, 8),
Instruction("bit", AddrMode.Zp, 3),
Instruction("and", AddrMode.Zp, 3),
Instruction("rol", AddrMode.Zp, 5),
Instruction("rla", AddrMode.Zp, 5),
Instruction("plp", AddrMode.Imp, 4),
Instruction("and", AddrMode.Imm, 2),
Instruction("rol", AddrMode.Acc, 2),
Instruction("anc", AddrMode.Imm, 2),
Instruction("bit", AddrMode.Abs, 4),
Instruction("and", AddrMode.Abs, 4),
Instruction("rol", AddrMode.Abs, 6),
Instruction("rla", AddrMode.Abs, 6),
Instruction("bmi", AddrMode.Rel, 2),
Instruction("and", AddrMode.IzY, 5),
Instruction("???", AddrMode.Imp, 0),
Instruction("rla", AddrMode.IzY, 8),
Instruction("nop", AddrMode.ZpX, 4),
Instruction("and", AddrMode.ZpX, 4),
Instruction("rol", AddrMode.ZpX, 6),
Instruction("rla", AddrMode.ZpX, 6),
Instruction("sec", AddrMode.Imp, 2),
Instruction("and", AddrMode.AbsY, 4),
Instruction("nop", AddrMode.Imp, 2),
Instruction("rla", AddrMode.AbsY, 7),
Instruction("nop", AddrMode.AbsX, 4),
Instruction("and", AddrMode.AbsX, 4),
Instruction("rol", AddrMode.AbsX, 7),
Instruction("rla", AddrMode.AbsX, 7),
Instruction("rti", AddrMode.Imp, 6),
Instruction("eor", AddrMode.IzX, 6),
Instruction("???", AddrMode.Imp, 0),
Instruction("sre", AddrMode.IzX, 8),
Instruction("nop", AddrMode.Zp, 3),
Instruction("eor", AddrMode.Zp, 3),
Instruction("lsr", AddrMode.Zp, 5),
Instruction("sre", AddrMode.Zp, 5),
Instruction("pha", AddrMode.Imp, 3),
Instruction("eor", AddrMode.Imm, 2),
Instruction("lsr", AddrMode.Acc, 2),
Instruction("alr", AddrMode.Imm, 2),
Instruction("jmp", AddrMode.Abs, 3),
Instruction("eor", AddrMode.Abs, 4),
Instruction("lsr", AddrMode.Abs, 6),
Instruction("sre", AddrMode.Abs, 6),
Instruction("bvc", AddrMode.Rel, 2),
Instruction("eor", AddrMode.IzY, 5),
Instruction("???", AddrMode.Imp, 0),
Instruction("sre", AddrMode.IzY, 8),
Instruction("nop", AddrMode.ZpX, 4),
Instruction("eor", AddrMode.ZpX, 4),
Instruction("lsr", AddrMode.ZpX, 6),
Instruction("sre", AddrMode.ZpX, 6),
Instruction("cli", AddrMode.Imp, 2),
Instruction("eor", AddrMode.AbsY, 4),
Instruction("nop", AddrMode.Imp, 2),
Instruction("sre", AddrMode.AbsY, 7),
Instruction("nop", AddrMode.AbsX, 4),
Instruction("eor", AddrMode.AbsX, 4),
Instruction("lsr", AddrMode.AbsX, 7),
Instruction("sre", AddrMode.AbsX, 7),
Instruction("rts", AddrMode.Imp, 6),
Instruction("adc", AddrMode.IzX, 6),
Instruction("???", AddrMode.Imp, 0),
Instruction("rra", AddrMode.IzX, 8),
Instruction("nop", AddrMode.Zp, 3),
Instruction("adc", AddrMode.Zp, 3),
Instruction("ror", AddrMode.Zp, 5),
Instruction("rra", AddrMode.Zp, 5),
Instruction("pla", AddrMode.Imp, 4),
Instruction("adc", AddrMode.Imm, 2),
Instruction("ror", AddrMode.Acc, 2),
Instruction("arr", AddrMode.Imm, 2),
Instruction("jmp", AddrMode.Ind, 5),
Instruction("adc", AddrMode.Abs, 4),
Instruction("ror", AddrMode.Abs, 6),
Instruction("rra", AddrMode.Abs, 6),
Instruction("bvs", AddrMode.Rel, 2),
Instruction("adc", AddrMode.IzY, 5),
Instruction("???", AddrMode.Imp, 0),
Instruction("rra", AddrMode.IzY, 8),
Instruction("nop", AddrMode.ZpX, 4),
Instruction("adc", AddrMode.ZpX, 4),
Instruction("ror", AddrMode.ZpX, 6),
Instruction("rra", AddrMode.ZpX, 6),
Instruction("sei", AddrMode.Imp, 2),
Instruction("adc", AddrMode.AbsY, 4),
Instruction("nop", AddrMode.Imp, 2),
Instruction("rra", AddrMode.AbsY, 7),
Instruction("nop", AddrMode.AbsX, 4),
Instruction("adc", AddrMode.AbsX, 4),
Instruction("ror", AddrMode.AbsX, 7),
Instruction("rra", AddrMode.AbsX, 7),
Instruction("nop", AddrMode.Imm, 2),
Instruction("sta", AddrMode.IzX, 6),
Instruction("nop", AddrMode.Imm, 2),
Instruction("sax", AddrMode.IzX, 6),
Instruction("sty", AddrMode.Zp, 3),
Instruction("sta", AddrMode.Zp, 3),
Instruction("stx", AddrMode.Zp, 3),
Instruction("sax", AddrMode.Zp, 3),
Instruction("dey", AddrMode.Imp, 2),
Instruction("nop", AddrMode.Imm, 2),
Instruction("txa", AddrMode.Imp, 2),
Instruction("xaa", AddrMode.Imm, 2),
Instruction("sty", AddrMode.Abs, 4),
Instruction("sta", AddrMode.Abs, 4),
Instruction("stx", AddrMode.Abs, 4),
Instruction("sax", AddrMode.Abs, 4),
Instruction("bcc", AddrMode.Rel, 2),
Instruction("sta", AddrMode.IzY, 6),
Instruction("???", AddrMode.Imp, 0),
Instruction("ahx", AddrMode.IzY, 6),
Instruction("sty", AddrMode.ZpX, 4),
Instruction("sta", AddrMode.ZpX, 4),
Instruction("stx", AddrMode.ZpY, 4),
Instruction("sax", AddrMode.ZpY, 4),
Instruction("tya", AddrMode.Imp, 2),
Instruction("sta", AddrMode.AbsY, 5),
Instruction("txs", AddrMode.Imp, 2),
Instruction("tas", AddrMode.AbsY, 5),
Instruction("shy", AddrMode.AbsX, 5),
Instruction("sta", AddrMode.AbsX, 5),
Instruction("shx", AddrMode.AbsY, 5),
Instruction("ahx", AddrMode.AbsY, 5),
Instruction("ldy", AddrMode.Imm, 2),
Instruction("lda", AddrMode.IzX, 6),
Instruction("ldx", AddrMode.Imm, 2),
Instruction("lax", AddrMode.IzX, 6),
Instruction("ldy", AddrMode.Zp, 3),
Instruction("lda", AddrMode.Zp, 3),
Instruction("ldx", AddrMode.Zp, 3),
Instruction("lax", AddrMode.Zp, 3),
Instruction("tay", AddrMode.Imp, 2),
Instruction("lda", AddrMode.Imm, 2),
Instruction("tax", AddrMode.Imp, 2),
Instruction("lax", AddrMode.Imm, 2),
Instruction("ldy", AddrMode.Abs, 4),
Instruction("lda", AddrMode.Abs, 4),
Instruction("ldx", AddrMode.Abs, 4),
Instruction("lax", AddrMode.Abs, 4),
Instruction("bcs", AddrMode.Rel, 2),
Instruction("lda", AddrMode.IzY, 5),
Instruction("???", AddrMode.Imp, 0),
Instruction("lax", AddrMode.IzY, 5),
Instruction("ldy", AddrMode.ZpX, 4),
Instruction("lda", AddrMode.ZpX, 4),
Instruction("ldx", AddrMode.ZpY, 4),
Instruction("lax", AddrMode.ZpY, 4),
Instruction("clv", AddrMode.Imp, 2),
Instruction("lda", AddrMode.AbsY, 4),
Instruction("tsx", AddrMode.Imp, 2),
Instruction("las", AddrMode.AbsY, 4),
Instruction("ldy", AddrMode.AbsX, 4),
Instruction("lda", AddrMode.AbsX, 4),
Instruction("ldx", AddrMode.AbsY, 4),
Instruction("lax", AddrMode.AbsY, 4),
Instruction("cpy", AddrMode.Imm, 2),
Instruction("cmp", AddrMode.IzX, 6),
Instruction("nop", AddrMode.Imm, 2),
Instruction("dcp", AddrMode.IzX, 8),
Instruction("cpy", AddrMode.Zp, 3),
Instruction("cmp", AddrMode.Zp, 3),
Instruction("dec", AddrMode.Zp, 5),
Instruction("dcp", AddrMode.Zp, 5),
Instruction("iny", AddrMode.Imp, 2),
Instruction("cmp", AddrMode.Imm, 2),
Instruction("dex", AddrMode.Imp, 2),
Instruction("axs", AddrMode.Imm, 2),
Instruction("cpy", AddrMode.Abs, 4),
Instruction("cmp", AddrMode.Abs, 4),
Instruction("dec", AddrMode.Abs, 6),
Instruction("dcp", AddrMode.Abs, 6),
Instruction("bne", AddrMode.Rel, 2),
Instruction("cmp", AddrMode.IzY, 5),
Instruction("???", AddrMode.Imp, 0),
Instruction("dcp", AddrMode.IzY, 8),
Instruction("nop", AddrMode.ZpX, 4),
Instruction("cmp", AddrMode.ZpX, 4),
Instruction("dec", AddrMode.ZpX, 6),
Instruction("dcp", AddrMode.ZpX, 6),
Instruction("cld", AddrMode.Imp, 2),
Instruction("cmp", AddrMode.AbsY, 4),
Instruction("nop", AddrMode.Imp, 2),
Instruction("dcp", AddrMode.AbsY, 7),
Instruction("nop", AddrMode.AbsX, 4),
Instruction("cmp", AddrMode.AbsX, 4),
Instruction("dec", AddrMode.AbsX, 7),
Instruction("dcp", AddrMode.AbsX, 7),
Instruction("cpx", AddrMode.Imm, 2),
Instruction("sbc", AddrMode.IzX, 6),
Instruction("nop", AddrMode.Imm, 2),
Instruction("isc", AddrMode.IzX, 8),
Instruction("cpx", AddrMode.Zp, 3),
Instruction("sbc", AddrMode.Zp, 3),
Instruction("inc", AddrMode.Zp, 5),
Instruction("isc", AddrMode.Zp, 5),
Instruction("inx", AddrMode.Imp, 2),
Instruction("sbc", AddrMode.Imm, 2),
Instruction("nop", AddrMode.Imp, 2),
Instruction("sbc", AddrMode.Imm, 2),
Instruction("cpx", AddrMode.Abs, 4),
Instruction("sbc", AddrMode.Abs, 4),
Instruction("inc", AddrMode.Abs, 6),
Instruction("isc", AddrMode.Abs, 6),
Instruction("beq", AddrMode.Rel, 2),
Instruction("sbc", AddrMode.IzY, 5),
Instruction("???", AddrMode.Imp, 0),
Instruction("isc", AddrMode.IzY, 8),
Instruction("nop", AddrMode.ZpX, 4),
Instruction("sbc", AddrMode.ZpX, 4),
Instruction("inc", AddrMode.ZpX, 6),
Instruction("isc", AddrMode.ZpX, 6),
Instruction("sed", AddrMode.Imp, 2),
Instruction("sbc", AddrMode.AbsY, 4),
Instruction("nop", AddrMode.Imp, 2),
Instruction("isc", AddrMode.AbsY, 7),
Instruction("nop", AddrMode.AbsX, 4),
Instruction("sbc", AddrMode.AbsX, 4),
Instruction("inc", AddrMode.AbsX, 7),
Instruction("isc", AddrMode.AbsX, 7)
).toTypedArray()
protected open val instructions: Array<Instruction> by lazy {
listOf(
/* 00 */ Instruction("brk", AddrMode.Imp, 7),
/* 01 */ Instruction("ora", AddrMode.IzX, 6),
/* 02 */ Instruction("???", AddrMode.Imp, 2),
/* 03 */ Instruction("slo", AddrMode.IzX, 8),
/* 04 */ Instruction("nop", AddrMode.Zp, 3),
/* 05 */ Instruction("ora", AddrMode.Zp, 3),
/* 06 */ Instruction("asl", AddrMode.Zp, 5),
/* 07 */ Instruction("slo", AddrMode.Zp, 5),
/* 08 */ Instruction("php", AddrMode.Imp, 3),
/* 09 */ Instruction("ora", AddrMode.Imm, 2),
/* 0a */ Instruction("asl", AddrMode.Acc, 2),
/* 0b */ Instruction("anc", AddrMode.Imm, 2),
/* 0c */ Instruction("nop", AddrMode.Abs, 4),
/* 0d */ Instruction("ora", AddrMode.Abs, 4),
/* 0e */ Instruction("asl", AddrMode.Abs, 6),
/* 0f */ Instruction("slo", AddrMode.Abs, 6),
/* 10 */ Instruction("bpl", AddrMode.Rel, 2),
/* 11 */ Instruction("ora", AddrMode.IzY, 5),
/* 12 */ Instruction("???", AddrMode.Imp, 2),
/* 13 */ Instruction("slo", AddrMode.IzY, 8),
/* 14 */ Instruction("nop", AddrMode.ZpX, 4),
/* 15 */ Instruction("ora", AddrMode.ZpX, 4),
/* 16 */ Instruction("asl", AddrMode.ZpX, 6),
/* 17 */ Instruction("slo", AddrMode.ZpX, 6),
/* 18 */ Instruction("clc", AddrMode.Imp, 2),
/* 19 */ Instruction("ora", AddrMode.AbsY, 4),
/* 1a */ Instruction("nop", AddrMode.Imp, 2),
/* 1b */ Instruction("slo", AddrMode.AbsY, 7),
/* 1c */ Instruction("nop", AddrMode.AbsX, 4),
/* 1d */ Instruction("ora", AddrMode.AbsX, 4),
/* 1e */ Instruction("asl", AddrMode.AbsX, 7),
/* 1f */ Instruction("slo", AddrMode.AbsX, 7),
/* 20 */ Instruction("jsr", AddrMode.Abs, 6),
/* 21 */ Instruction("and", AddrMode.IzX, 6),
/* 22 */ Instruction("???", AddrMode.Imp, 2),
/* 23 */ Instruction("rla", AddrMode.IzX, 8),
/* 24 */ Instruction("bit", AddrMode.Zp, 3),
/* 25 */ Instruction("and", AddrMode.Zp, 3),
/* 26 */ Instruction("rol", AddrMode.Zp, 5),
/* 27 */ Instruction("rla", AddrMode.Zp, 5),
/* 28 */ Instruction("plp", AddrMode.Imp, 4),
/* 29 */ Instruction("and", AddrMode.Imm, 2),
/* 2a */ Instruction("rol", AddrMode.Acc, 2),
/* 2b */ Instruction("anc", AddrMode.Imm, 2),
/* 2c */ Instruction("bit", AddrMode.Abs, 4),
/* 2d */ Instruction("and", AddrMode.Abs, 4),
/* 2e */ Instruction("rol", AddrMode.Abs, 6),
/* 2f */ Instruction("rla", AddrMode.Abs, 6),
/* 30 */ Instruction("bmi", AddrMode.Rel, 2),
/* 31 */ Instruction("and", AddrMode.IzY, 5),
/* 32 */ Instruction("???", AddrMode.Imp, 2),
/* 33 */ Instruction("rla", AddrMode.IzY, 8),
/* 34 */ Instruction("nop", AddrMode.ZpX, 4),
/* 35 */ Instruction("and", AddrMode.ZpX, 4),
/* 36 */ Instruction("rol", AddrMode.ZpX, 6),
/* 37 */ Instruction("rla", AddrMode.ZpX, 6),
/* 38 */ Instruction("sec", AddrMode.Imp, 2),
/* 39 */ Instruction("and", AddrMode.AbsY, 4),
/* 3a */ Instruction("nop", AddrMode.Imp, 2),
/* 3b */ Instruction("rla", AddrMode.AbsY, 7),
/* 3c */ Instruction("nop", AddrMode.AbsX, 4),
/* 3d */ Instruction("and", AddrMode.AbsX, 4),
/* 3e */ Instruction("rol", AddrMode.AbsX, 7),
/* 3f */ Instruction("rla", AddrMode.AbsX, 7),
/* 40 */ Instruction("rti", AddrMode.Imp, 6),
/* 41 */ Instruction("eor", AddrMode.IzX, 6),
/* 42 */ Instruction("???", AddrMode.Imp, 2),
/* 43 */ Instruction("sre", AddrMode.IzX, 8),
/* 44 */ Instruction("nop", AddrMode.Zp, 3),
/* 45 */ Instruction("eor", AddrMode.Zp, 3),
/* 46 */ Instruction("lsr", AddrMode.Zp, 5),
/* 47 */ Instruction("sre", AddrMode.Zp, 5),
/* 48 */ Instruction("pha", AddrMode.Imp, 3),
/* 49 */ Instruction("eor", AddrMode.Imm, 2),
/* 4a */ Instruction("lsr", AddrMode.Acc, 2),
/* 4b */ Instruction("alr", AddrMode.Imm, 2),
/* 4c */ Instruction("jmp", AddrMode.Abs, 3),
/* 4d */ Instruction("eor", AddrMode.Abs, 4),
/* 4e */ Instruction("lsr", AddrMode.Abs, 6),
/* 4f */ Instruction("sre", AddrMode.Abs, 6),
/* 50 */ Instruction("bvc", AddrMode.Rel, 2),
/* 51 */ Instruction("eor", AddrMode.IzY, 5),
/* 52 */ Instruction("???", AddrMode.Imp, 2),
/* 53 */ Instruction("sre", AddrMode.IzY, 8),
/* 54 */ Instruction("nop", AddrMode.ZpX, 4),
/* 55 */ Instruction("eor", AddrMode.ZpX, 4),
/* 56 */ Instruction("lsr", AddrMode.ZpX, 6),
/* 57 */ Instruction("sre", AddrMode.ZpX, 6),
/* 58 */ Instruction("cli", AddrMode.Imp, 2),
/* 59 */ Instruction("eor", AddrMode.AbsY, 4),
/* 5a */ Instruction("nop", AddrMode.Imp, 2),
/* 5b */ Instruction("sre", AddrMode.AbsY, 7),
/* 5c */ Instruction("nop", AddrMode.AbsX, 4),
/* 5d */ Instruction("eor", AddrMode.AbsX, 4),
/* 5e */ Instruction("lsr", AddrMode.AbsX, 7),
/* 5f */ Instruction("sre", AddrMode.AbsX, 7),
/* 60 */ Instruction("rts", AddrMode.Imp, 6),
/* 61 */ Instruction("adc", AddrMode.IzX, 6),
/* 62 */ Instruction("???", AddrMode.Imp, 2),
/* 63 */ Instruction("rra", AddrMode.IzX, 8),
/* 64 */ Instruction("nop", AddrMode.Zp, 3),
/* 65 */ Instruction("adc", AddrMode.Zp, 3),
/* 66 */ Instruction("ror", AddrMode.Zp, 5),
/* 67 */ Instruction("rra", AddrMode.Zp, 5),
/* 68 */ Instruction("pla", AddrMode.Imp, 4),
/* 69 */ Instruction("adc", AddrMode.Imm, 2),
/* 6a */ Instruction("ror", AddrMode.Acc, 2),
/* 6b */ Instruction("arr", AddrMode.Imm, 2),
/* 6c */ Instruction("jmp", AddrMode.Ind, 5),
/* 6d */ Instruction("adc", AddrMode.Abs, 4),
/* 6e */ Instruction("ror", AddrMode.Abs, 6),
/* 6f */ Instruction("rra", AddrMode.Abs, 6),
/* 70 */ Instruction("bvs", AddrMode.Rel, 2),
/* 71 */ Instruction("adc", AddrMode.IzY, 5),
/* 72 */ Instruction("???", AddrMode.Imp, 2),
/* 73 */ Instruction("rra", AddrMode.IzY, 8),
/* 74 */ Instruction("nop", AddrMode.ZpX, 4),
/* 75 */ Instruction("adc", AddrMode.ZpX, 4),
/* 76 */ Instruction("ror", AddrMode.ZpX, 6),
/* 77 */ Instruction("rra", AddrMode.ZpX, 6),
/* 78 */ Instruction("sei", AddrMode.Imp, 2),
/* 79 */ Instruction("adc", AddrMode.AbsY, 4),
/* 7a */ Instruction("nop", AddrMode.Imp, 2),
/* 7b */ Instruction("rra", AddrMode.AbsY, 7),
/* 7c */ Instruction("nop", AddrMode.AbsX, 4),
/* 7d */ Instruction("adc", AddrMode.AbsX, 4),
/* 7e */ Instruction("ror", AddrMode.AbsX, 7),
/* 7f */ Instruction("rra", AddrMode.AbsX, 7),
/* 80 */ Instruction("nop", AddrMode.Imm, 2),
/* 81 */ Instruction("sta", AddrMode.IzX, 6),
/* 82 */ Instruction("nop", AddrMode.Imm, 2),
/* 83 */ Instruction("sax", AddrMode.IzX, 6),
/* 84 */ Instruction("sty", AddrMode.Zp, 3),
/* 85 */ Instruction("sta", AddrMode.Zp, 3),
/* 86 */ Instruction("stx", AddrMode.Zp, 3),
/* 87 */ Instruction("sax", AddrMode.Zp, 3),
/* 88 */ Instruction("dey", AddrMode.Imp, 2),
/* 89 */ Instruction("nop", AddrMode.Imm, 2),
/* 8a */ Instruction("txa", AddrMode.Imp, 2),
/* 8b */ Instruction("xaa", AddrMode.Imm, 2),
/* 8c */ Instruction("sty", AddrMode.Abs, 4),
/* 8d */ Instruction("sta", AddrMode.Abs, 4),
/* 8e */ Instruction("stx", AddrMode.Abs, 4),
/* 8f */ Instruction("sax", AddrMode.Abs, 4),
/* 90 */ Instruction("bcc", AddrMode.Rel, 2),
/* 91 */ Instruction("sta", AddrMode.IzY, 6),
/* 92 */ Instruction("???", AddrMode.Imp, 2),
/* 93 */ Instruction("ahx", AddrMode.IzY, 6),
/* 94 */ Instruction("sty", AddrMode.ZpX, 4),
/* 95 */ Instruction("sta", AddrMode.ZpX, 4),
/* 96 */ Instruction("stx", AddrMode.ZpY, 4),
/* 97 */ Instruction("sax", AddrMode.ZpY, 4),
/* 98 */ Instruction("tya", AddrMode.Imp, 2),
/* 99 */ Instruction("sta", AddrMode.AbsY, 5),
/* 9a */ Instruction("txs", AddrMode.Imp, 2),
/* 9b */ Instruction("tas", AddrMode.AbsY, 5),
/* 9c */ Instruction("shy", AddrMode.AbsX, 5),
/* 9d */ Instruction("sta", AddrMode.AbsX, 5),
/* 9e */ Instruction("shx", AddrMode.AbsY, 5),
/* 9f */ Instruction("ahx", AddrMode.AbsY, 5),
/* a0 */ Instruction("ldy", AddrMode.Imm, 2),
/* a1 */ Instruction("lda", AddrMode.IzX, 6),
/* a2 */ Instruction("ldx", AddrMode.Imm, 2),
/* a3 */ Instruction("lax", AddrMode.IzX, 6),
/* a4 */ Instruction("ldy", AddrMode.Zp, 3),
/* a5 */ Instruction("lda", AddrMode.Zp, 3),
/* a6 */ Instruction("ldx", AddrMode.Zp, 3),
/* a7 */ Instruction("lax", AddrMode.Zp, 3),
/* a8 */ Instruction("tay", AddrMode.Imp, 2),
/* a9 */ Instruction("lda", AddrMode.Imm, 2),
/* aa */ Instruction("tax", AddrMode.Imp, 2),
/* ab */ Instruction("lax", AddrMode.Imm, 2),
/* ac */ Instruction("ldy", AddrMode.Abs, 4),
/* ad */ Instruction("lda", AddrMode.Abs, 4),
/* ae */ Instruction("ldx", AddrMode.Abs, 4),
/* af */ Instruction("lax", AddrMode.Abs, 4),
/* b0 */ Instruction("bcs", AddrMode.Rel, 2),
/* b1 */ Instruction("lda", AddrMode.IzY, 5),
/* b2 */ Instruction("???", AddrMode.Imp, 2),
/* b3 */ Instruction("lax", AddrMode.IzY, 5),
/* b4 */ Instruction("ldy", AddrMode.ZpX, 4),
/* b5 */ Instruction("lda", AddrMode.ZpX, 4),
/* b6 */ Instruction("ldx", AddrMode.ZpY, 4),
/* b7 */ Instruction("lax", AddrMode.ZpY, 4),
/* b8 */ Instruction("clv", AddrMode.Imp, 2),
/* b9 */ Instruction("lda", AddrMode.AbsY, 4),
/* ba */ Instruction("tsx", AddrMode.Imp, 2),
/* bb */ Instruction("las", AddrMode.AbsY, 4),
/* bc */ Instruction("ldy", AddrMode.AbsX, 4),
/* bd */ Instruction("lda", AddrMode.AbsX, 4),
/* be */ Instruction("ldx", AddrMode.AbsY, 4),
/* bf */ Instruction("lax", AddrMode.AbsY, 4),
/* c0 */ Instruction("cpy", AddrMode.Imm, 2),
/* c1 */ Instruction("cmp", AddrMode.IzX, 6),
/* c2 */ Instruction("nop", AddrMode.Imm, 2),
/* c3 */ Instruction("dcp", AddrMode.IzX, 8),
/* c4 */ Instruction("cpy", AddrMode.Zp, 3),
/* c5 */ Instruction("cmp", AddrMode.Zp, 3),
/* c6 */ Instruction("dec", AddrMode.Zp, 5),
/* c7 */ Instruction("dcp", AddrMode.Zp, 5),
/* c8 */ Instruction("iny", AddrMode.Imp, 2),
/* c9 */ Instruction("cmp", AddrMode.Imm, 2),
/* ca */ Instruction("dex", AddrMode.Imp, 2),
/* cb */ Instruction("axs", AddrMode.Imm, 2),
/* cc */ Instruction("cpy", AddrMode.Abs, 4),
/* cd */ Instruction("cmp", AddrMode.Abs, 4),
/* ce */ Instruction("dec", AddrMode.Abs, 6),
/* cf */ Instruction("dcp", AddrMode.Abs, 6),
/* d0 */ Instruction("bne", AddrMode.Rel, 2),
/* d1 */ Instruction("cmp", AddrMode.IzY, 5),
/* d2 */ Instruction("???", AddrMode.Imp, 2),
/* d3 */ Instruction("dcp", AddrMode.IzY, 8),
/* d4 */ Instruction("nop", AddrMode.ZpX, 4),
/* d5 */ Instruction("cmp", AddrMode.ZpX, 4),
/* d6 */ Instruction("dec", AddrMode.ZpX, 6),
/* d7 */ Instruction("dcp", AddrMode.ZpX, 6),
/* d8 */ Instruction("cld", AddrMode.Imp, 2),
/* d9 */ Instruction("cmp", AddrMode.AbsY, 4),
/* da */ Instruction("nop", AddrMode.Imp, 2),
/* db */ Instruction("dcp", AddrMode.AbsY, 7),
/* dc */ Instruction("nop", AddrMode.AbsX, 4),
/* dd */ Instruction("cmp", AddrMode.AbsX, 4),
/* de */ Instruction("dec", AddrMode.AbsX, 7),
/* df */ Instruction("dcp", AddrMode.AbsX, 7),
/* e0 */ Instruction("cpx", AddrMode.Imm, 2),
/* e1 */ Instruction("sbc", AddrMode.IzX, 6),
/* e2 */ Instruction("nop", AddrMode.Imm, 2),
/* e3 */ Instruction("isc", AddrMode.IzX, 8),
/* e4 */ Instruction("cpx", AddrMode.Zp, 3),
/* e5 */ Instruction("sbc", AddrMode.Zp, 3),
/* e6 */ Instruction("inc", AddrMode.Zp, 5),
/* e7 */ Instruction("isc", AddrMode.Zp, 5),
/* e8 */ Instruction("inx", AddrMode.Imp, 2),
/* e9 */ Instruction("sbc", AddrMode.Imm, 2),
/* ea */ Instruction("nop", AddrMode.Imp, 2),
/* eb */ Instruction("sbc", AddrMode.Imm, 2),
/* ec */ Instruction("cpx", AddrMode.Abs, 4),
/* ed */ Instruction("sbc", AddrMode.Abs, 4),
/* ee */ Instruction("inc", AddrMode.Abs, 6),
/* ef */ Instruction("isc", AddrMode.Abs, 6),
/* f0 */ Instruction("beq", AddrMode.Rel, 2),
/* f1 */ Instruction("sbc", AddrMode.IzY, 5),
/* f2 */ Instruction("???", AddrMode.Imp, 2),
/* f3 */ Instruction("isc", AddrMode.IzY, 8),
/* f4 */ Instruction("nop", AddrMode.ZpX, 4),
/* f5 */ Instruction("sbc", AddrMode.ZpX, 4),
/* f6 */ Instruction("inc", AddrMode.ZpX, 6),
/* f7 */ Instruction("isc", AddrMode.ZpX, 6),
/* f8 */ Instruction("sed", AddrMode.Imp, 2),
/* f9 */ Instruction("sbc", AddrMode.AbsY, 4),
/* fa */ Instruction("nop", AddrMode.Imp, 2),
/* fb */ Instruction("isc", AddrMode.AbsY, 7),
/* fc */ Instruction("nop", AddrMode.AbsX, 4),
/* fd */ Instruction("sbc", AddrMode.AbsX, 4),
/* fe */ Instruction("inc", AddrMode.AbsX, 7),
/* ff */ Instruction("isc", AddrMode.AbsX, 7)
).toTypedArray()
}
private fun applyAddressingMode(addrMode: AddrMode) {
protected open fun applyAddressingMode(addrMode: AddrMode) {
when (addrMode) {
AddrMode.Imp, AddrMode.Acc -> {
fetchedData = A
@ -707,6 +722,10 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
val hi = read((fetchedAddress + 1) and 0xff)
fetchedAddress = Y + (lo or (hi shl 8)) and 0xffff
}
AddrMode.Zpr, AddrMode.Izp -> {
// addressing mode used by the 65C02 only
throw InstructionError("65c02 addressing mode not implemented on 6502")
}
}
}
@ -968,7 +987,8 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
0xfd -> iSbc()
0xfe -> iInc()
0xff -> iIsc()
else -> { /* can't occur */ }
else -> { /* can't occur */
}
}
}
@ -1060,7 +1080,7 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
if (!Status.N) PC = fetchedAddress
}
protected fun iBrk() {
protected open fun iBrk() {
// handle BRK ('software interrupt') or a real hardware IRQ
val interrupt = pendingInterrupt
val nmi = interrupt?.first == true
@ -1073,7 +1093,7 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
Status.B = interrupt == null
pushStack(Status)
Status.I = true // interrupts are now disabled
// NMOS 6502 doesn't clear the D flag (CMOS version does...)
// NMOS 6502 doesn't clear the D flag (CMOS 65C02 version does...)
PC = readWord(if (nmi) NMI_vector else IRQ_vector)
pendingInterrupt = null
}
@ -1123,7 +1143,7 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
Status.N = ((Y - fetched) and 0b10000000) != 0
}
protected fun iDec() {
protected open fun iDec() {
val data = (read(fetchedAddress) - 1) and 0xff
write(fetchedAddress, data)
Status.Z = data == 0
@ -1148,7 +1168,7 @@ open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() {
Status.N = (A and 0b10000000) != 0
}
protected fun iInc() {
protected open fun iInc() {
val data = (read(fetchedAddress) + 1) and 0xff
write(fetchedAddress, data)
Status.Z = data == 0

View File

@ -1,5 +1,8 @@
package razorvine.ksim65.components
/**
* 65C02 cpu simulation (the CMOS version of the 6502).
*/
class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
enum class Wait {
@ -10,8 +13,6 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
var waiting: Wait = Wait.Normal
// TODO implement this CPU type 65C02, and re-enable the unit tests for that
companion object {
const val NMI_vector = Cpu6502.NMI_vector
const val RESET_vector = Cpu6502.RESET_vector
@ -20,17 +21,17 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
}
override fun clock() {
when(waiting) {
when (waiting) {
Wait.Normal -> super.clock()
Wait.Waiting -> {
if(pendingInterrupt!=null) {
if (pendingInterrupt != null) {
// continue execution after hardware interrupt
waiting = Wait.Normal
instrCycles = 1
}
}
Wait.Stopped -> {
if(pendingInterrupt!=null) {
if (pendingInterrupt != null) {
// jump to reset vector after hardware interrupt
PC = readWord(RESET_vector)
}
@ -38,7 +39,46 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
}
}
// opcode list: http://www.oxyron.de/html/opcodesc02.html
override fun step() {
// step a whole instruction
if (waiting == Wait.Normal) {
while (instrCycles > 0) clock() // remaining instruction subcycles from the previous instruction
clock() // the actual instruction execution cycle
if (waiting == Wait.Normal)
while (instrCycles > 0) clock() // instruction subcycles
else {
totalCycles += instrCycles
instrCycles = 0
}
}
}
override fun applyAddressingMode(addrMode: AddrMode) {
when (addrMode) {
AddrMode.Imp, AddrMode.Acc, AddrMode.Imm,
AddrMode.Zp, AddrMode.ZpX, AddrMode.ZpY,
AddrMode.Rel, AddrMode.Abs, AddrMode.AbsX, AddrMode.AbsY,
AddrMode.IzX, AddrMode.IzY-> {
super.applyAddressingMode(addrMode)
}
AddrMode.Ind -> {
// not able to fetch an address which crosses the page boundary (6502, fixed in 65C02)
TODO("IND addrmode fixed for 65c02")
}
AddrMode.Zpr -> {
// addressing mode used by the 65C02 only
TODO("ZPR addressing mode")
}
AddrMode.Izp -> {
// addressing mode used by the 65C02 only
fetchedAddress = readPc()
val lo = read((fetchedAddress) and 0xff)
val hi = read((fetchedAddress + 1) and 0xff)
fetchedAddress = lo or (hi shl 8)
}
}
}
override fun dispatchOpcode(opcode: Int) {
when (opcode) {
0x00 -> iBrk()
@ -56,8 +96,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x0c -> iTsb()
0x0d -> iOra()
0x0e -> iAsl()
0x0f -> iBrr0()
0x0f -> iBbr0()
0x10 -> iBpl()
0x11 -> iOra()
0x12 -> iOra()
@ -73,8 +112,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x1c -> iTrb()
0x1d -> iOra()
0x1e -> iAsl()
0x1f -> iBrr1()
0x1f -> iBbr1()
0x20 -> iJsr()
0x21 -> iAnd()
0x22 -> iNop()
@ -90,8 +128,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x2c -> iBit()
0x2d -> iAnd()
0x2e -> iRol()
0x2f -> iBrr2()
0x2f -> iBbr2()
0x30 -> iBmi()
0x31 -> iAnd()
0x32 -> iAnd()
@ -107,8 +144,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x3c -> iBit()
0x3d -> iAnd()
0x3e -> iRol()
0x3f -> iBrr3()
0x3f -> iBbr3()
0x40 -> iRti()
0x41 -> iEor()
0x42 -> iNop()
@ -124,8 +160,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x4c -> iJmp()
0x4d -> iEor()
0x4e -> iLsr()
0x4f -> iBrr4()
0x4f -> iBbr4()
0x50 -> iBvc()
0x51 -> iEor()
0x52 -> iEor()
@ -141,8 +176,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x5c -> iNop()
0x5d -> iEor()
0x5e -> iLsr()
0x5f -> iBrr5()
0x5f -> iBbr5()
0x60 -> iRts()
0x61 -> iAdc()
0x62 -> iNop()
@ -158,8 +192,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x6c -> iJmp()
0x6d -> iAdc()
0x6e -> iRor()
0x6f -> iBrr6()
0x6f -> iBbr6()
0x70 -> iBvs()
0x71 -> iAdc()
0x72 -> iAdc()
@ -175,8 +208,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x7c -> iJmp()
0x7d -> iAdc()
0x7e -> iRor()
0x7f -> iBrr7()
0x7f -> iBbr7()
0x80 -> iBra()
0x81 -> iSta()
0x82 -> iNop()
@ -193,7 +225,6 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x8d -> iSta()
0x8e -> iStx()
0x8f -> iBbs0()
0x90 -> iBcc()
0x91 -> iSta()
0x92 -> iSta()
@ -210,7 +241,6 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0x9d -> iSta()
0x9e -> iStz()
0x9f -> iBbs1()
0xa0 -> iLdy()
0xa1 -> iLda()
0xa2 -> iLdx()
@ -227,7 +257,6 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0xad -> iLda()
0xae -> iLdx()
0xaf -> iBbs2()
0xb0 -> iBcs()
0xb1 -> iLda()
0xb2 -> iLda()
@ -244,7 +273,6 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0xbd -> iLda()
0xbe -> iLdx()
0xbf -> iBbs3()
0xc0 -> iCpy()
0xc1 -> iCmp()
0xc2 -> iNop()
@ -261,7 +289,6 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0xcd -> iCmp()
0xce -> iDec()
0xcf -> iBbs4()
0xd0 -> iBne()
0xd1 -> iCmp()
0xd2 -> iCmp()
@ -278,7 +305,6 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0xdd -> iCmp()
0xde -> iDec()
0xdf -> iBbs5()
0xe0 -> iCpx()
0xe1 -> iSbc()
0xe2 -> iNop()
@ -295,7 +321,6 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
0xed -> iSbc()
0xee -> iInc()
0xef -> iBbs6()
0xf0 -> iBeq()
0xf1 -> iSbc()
0xf2 -> iSbc()
@ -317,8 +342,309 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
}
}
// opcode list: http://www.oxyron.de/html/opcodesc02.html
// TODO fix cycle counts
// TODO add optional additional cycles
override val instructions: Array<Instruction> by lazy {
listOf(
/* 00 */ Instruction("brk", AddrMode.Imp, 7),
/* 01 */ Instruction("ora", AddrMode.IzX, 6),
/* 02 */ Instruction("nop", AddrMode.Imm, 2),
/* 03 */ Instruction("nop", AddrMode.Imp, 1),
/* 04 */ Instruction("tsb", AddrMode.Zp, 5),
/* 05 */ Instruction("ora", AddrMode.Zp, 3),
/* 06 */ Instruction("asl", AddrMode.Zp, 5),
/* 07 */ Instruction("rmb0", AddrMode.Zp, 5),
/* 08 */ Instruction("php", AddrMode.Imp, 3),
/* 09 */ Instruction("ora", AddrMode.Imm, 2),
/* 0a */ Instruction("asl", AddrMode.Acc, 2),
/* 0b */ Instruction("nop", AddrMode.Imp, 1),
/* 0c */ Instruction("tsb", AddrMode.Abs, 6),
/* 0d */ Instruction("ora", AddrMode.Abs, 4),
/* 0e */ Instruction("asl", AddrMode.Abs, 6),
/* 0f */ Instruction("bbr0", AddrMode.Zpr, 5),
/* 10 */ Instruction("bpl", AddrMode.Rel, 2),
/* 11 */ Instruction("ora", AddrMode.IzY, 5),
/* 12 */ Instruction("ora", AddrMode.Izp, 5),
/* 13 */ Instruction("nop", AddrMode.Imp, 1),
/* 14 */ Instruction("trb", AddrMode.Zp, 5),
/* 15 */ Instruction("ora", AddrMode.ZpX, 4),
/* 16 */ Instruction("asl", AddrMode.ZpX, 6),
/* 17 */ Instruction("rmb1", AddrMode.Zp, 5),
/* 18 */ Instruction("clc", AddrMode.Imp, 2),
/* 19 */ Instruction("ora", AddrMode.AbsY, 4),
/* 1a */ Instruction("inc", AddrMode.Acc, 2),
/* 1b */ Instruction("nop", AddrMode.Imp, 1),
/* 1c */ Instruction("trb", AddrMode.Abs, 6),
/* 1d */ Instruction("ora", AddrMode.AbsX, 4),
/* 1e */ Instruction("asl", AddrMode.AbsX, 7),
/* 1f */ Instruction("bbr1", AddrMode.Zpr, 5),
/* 20 */ Instruction("jsr", AddrMode.Abs, 6),
/* 21 */ Instruction("and", AddrMode.IzX, 6),
/* 22 */ Instruction("nop", AddrMode.Imm, 2),
/* 23 */ Instruction("nop", AddrMode.Imp, 1),
/* 24 */ Instruction("bit", AddrMode.Zp, 3),
/* 25 */ Instruction("and", AddrMode.Zp, 3),
/* 26 */ Instruction("rol", AddrMode.Zp, 5),
/* 27 */ Instruction("rmb2", AddrMode.Zp, 5),
/* 28 */ Instruction("plp", AddrMode.Imp, 4),
/* 29 */ Instruction("and", AddrMode.Imm, 2),
/* 2a */ Instruction("rol", AddrMode.Acc, 2),
/* 2b */ Instruction("nop", AddrMode.Imp, 1),
/* 2c */ Instruction("bit", AddrMode.Abs, 4),
/* 2d */ Instruction("and", AddrMode.Abs, 4),
/* 2e */ Instruction("rol", AddrMode.Abs, 6),
/* 2f */ Instruction("bbr2", AddrMode.Zpr, 5),
/* 30 */ Instruction("bmi", AddrMode.Rel, 2),
/* 31 */ Instruction("and", AddrMode.IzY, 5),
/* 32 */ Instruction("and", AddrMode.Izp, 5),
/* 33 */ Instruction("nop", AddrMode.Imp, 1),
/* 34 */ Instruction("bit", AddrMode.ZpX, 4),
/* 35 */ Instruction("and", AddrMode.ZpX, 4),
/* 36 */ Instruction("rol", AddrMode.ZpX, 6),
/* 37 */ Instruction("rmb3", AddrMode.Zp, 5),
/* 38 */ Instruction("sec", AddrMode.Imp, 2),
/* 39 */ Instruction("and", AddrMode.AbsY, 4),
/* 3a */ Instruction("dec", AddrMode.Acc, 2),
/* 3b */ Instruction("nop", AddrMode.Imp, 1),
/* 3c */ Instruction("bit", AddrMode.AbsX, 4),
/* 3d */ Instruction("and", AddrMode.AbsX, 4),
/* 3e */ Instruction("rol", AddrMode.AbsX, 7),
/* 3f */ Instruction("bbr3", AddrMode.Zpr, 5),
/* 40 */ Instruction("rti", AddrMode.Imp, 6),
/* 41 */ Instruction("eor", AddrMode.IzX, 6),
/* 42 */ Instruction("nop", AddrMode.Imm, 2),
/* 43 */ Instruction("nop", AddrMode.Imp, 1),
/* 44 */ Instruction("nop", AddrMode.Zp, 3),
/* 45 */ Instruction("eor", AddrMode.Zp, 3),
/* 46 */ Instruction("lsr", AddrMode.Zp, 5),
/* 47 */ Instruction("rmb4", AddrMode.Zp, 5),
/* 48 */ Instruction("pha", AddrMode.Imp, 3),
/* 49 */ Instruction("eor", AddrMode.Imm, 2),
/* 4a */ Instruction("lsr", AddrMode.Acc, 2),
/* 4b */ Instruction("nop", AddrMode.Imp, 1),
/* 4c */ Instruction("jmp", AddrMode.Abs, 3),
/* 4d */ Instruction("eor", AddrMode.Abs, 4),
/* 4e */ Instruction("lsr", AddrMode.Abs, 6),
/* 4f */ Instruction("bbr4", AddrMode.Zpr, 5),
/* 50 */ Instruction("bvc", AddrMode.Rel, 2),
/* 51 */ Instruction("eor", AddrMode.IzY, 5),
/* 52 */ Instruction("eor", AddrMode.Izp, 5),
/* 53 */ Instruction("nop", AddrMode.Imp, 1),
/* 54 */ Instruction("nop", AddrMode.ZpX, 4),
/* 55 */ Instruction("eor", AddrMode.ZpX, 4),
/* 56 */ Instruction("lsr", AddrMode.ZpX, 6),
/* 57 */ Instruction("rmb5", AddrMode.Zp, 5),
/* 58 */ Instruction("cli", AddrMode.Imp, 2),
/* 59 */ Instruction("eor", AddrMode.AbsY, 4),
/* 5a */ Instruction("phy", AddrMode.Imp, 3),
/* 5b */ Instruction("nop", AddrMode.Imp, 1),
/* 5c */ Instruction("nop", AddrMode.Abs, 8),
/* 5d */ Instruction("eor", AddrMode.AbsX, 4),
/* 5e */ Instruction("lsr", AddrMode.AbsX, 7),
/* 5f */ Instruction("bbr5", AddrMode.Zpr, 5),
/* 60 */ Instruction("rts", AddrMode.Imp, 6),
/* 61 */ Instruction("adc", AddrMode.IzX, 6),
/* 62 */ Instruction("nop", AddrMode.Imm, 2),
/* 63 */ Instruction("nop", AddrMode.Imp, 1),
/* 64 */ Instruction("stz", AddrMode.Zp, 3),
/* 65 */ Instruction("adc", AddrMode.Zp, 3),
/* 66 */ Instruction("ror", AddrMode.Zp, 5),
/* 67 */ Instruction("rmb6", AddrMode.Zp, 5),
/* 68 */ Instruction("pla", AddrMode.Imp, 4),
/* 69 */ Instruction("adc", AddrMode.Imm, 2),
/* 6a */ Instruction("ror", AddrMode.Acc, 2),
/* 6b */ Instruction("nop", AddrMode.Imp, 1),
/* 6c */ Instruction("jmp", AddrMode.Ind, 5),
/* 6d */ Instruction("adc", AddrMode.Abs, 4),
/* 6e */ Instruction("ror", AddrMode.Abs, 6),
/* 6f */ Instruction("bbr6", AddrMode.Zpr, 5),
/* 70 */ Instruction("bvs", AddrMode.Rel, 2),
/* 71 */ Instruction("adc", AddrMode.IzY, 5),
/* 72 */ Instruction("adc", AddrMode.Izp, 5),
/* 73 */ Instruction("nop", AddrMode.Imp, 1),
/* 74 */ Instruction("stz", AddrMode.ZpX, 4),
/* 75 */ Instruction("adc", AddrMode.ZpX, 4),
/* 76 */ Instruction("ror", AddrMode.ZpX, 6),
/* 77 */ Instruction("rmb7", AddrMode.Zp, 5),
/* 78 */ Instruction("sei", AddrMode.Imp, 2),
/* 79 */ Instruction("adc", AddrMode.AbsY, 4),
/* 7a */ Instruction("ply", AddrMode.Imp, 2),
/* 7b */ Instruction("nop", AddrMode.Imp, 1),
/* 7c */ Instruction("jmp", AddrMode.AbsX, 4),
/* 7d */ Instruction("adc", AddrMode.AbsX, 4),
/* 7e */ Instruction("ror", AddrMode.AbsX, 7),
/* 7f */ Instruction("bbr7", AddrMode.Zpr, 5),
/* 80 */ Instruction("bra", AddrMode.Rel, 3),
/* 81 */ Instruction("sta", AddrMode.IzX, 6),
/* 82 */ Instruction("nop", AddrMode.Imm, 2),
/* 83 */ Instruction("nop", AddrMode.Imp, 1),
/* 84 */ Instruction("sty", AddrMode.Zp, 3),
/* 85 */ Instruction("sta", AddrMode.Zp, 3),
/* 86 */ Instruction("stx", AddrMode.Zp, 3),
/* 87 */ Instruction("smb0", AddrMode.Zp, 5),
/* 88 */ Instruction("dey", AddrMode.Imp, 2),
/* 89 */ Instruction("bit", AddrMode.Imm, 2),
/* 8a */ Instruction("txa", AddrMode.Imp, 2),
/* 8b */ Instruction("nop", AddrMode.Imp, 1),
/* 8c */ Instruction("sty", AddrMode.Abs, 4),
/* 8d */ Instruction("sta", AddrMode.Abs, 4),
/* 8e */ Instruction("stx", AddrMode.Abs, 4),
/* 8f */ Instruction("bbs0", AddrMode.Zpr, 5),
/* 90 */ Instruction("bcc", AddrMode.Rel, 2),
/* 91 */ Instruction("sta", AddrMode.IzY, 6),
/* 92 */ Instruction("sta", AddrMode.Izp, 5),
/* 93 */ Instruction("nop", AddrMode.Imp, 1),
/* 94 */ Instruction("sty", AddrMode.ZpX, 4),
/* 95 */ Instruction("sta", AddrMode.ZpX, 4),
/* 96 */ Instruction("stx", AddrMode.ZpY, 4),
/* 97 */ Instruction("smb1", AddrMode.Zp, 5),
/* 98 */ Instruction("tya", AddrMode.Imp, 2),
/* 99 */ Instruction("sta", AddrMode.AbsY, 5),
/* 9a */ Instruction("txs", AddrMode.Imp, 2),
/* 9b */ Instruction("nop", AddrMode.Imp, 1),
/* 9c */ Instruction("stz", AddrMode.Abs, 4),
/* 9d */ Instruction("sta", AddrMode.AbsX, 5),
/* 9e */ Instruction("stz", AddrMode.AbsX, 5),
/* 9f */ Instruction("bbs1", AddrMode.Zpr, 5),
/* a0 */ Instruction("ldy", AddrMode.Imm, 2),
/* a1 */ Instruction("lda", AddrMode.IzX, 6),
/* a2 */ Instruction("ldx", AddrMode.Imm, 2),
/* a3 */ Instruction("nop", AddrMode.Imp, 1),
/* a4 */ Instruction("ldy", AddrMode.Zp, 3),
/* a5 */ Instruction("lda", AddrMode.Zp, 3),
/* a6 */ Instruction("ldx", AddrMode.Zp, 3),
/* a7 */ Instruction("smb2", AddrMode.Zp, 5),
/* a8 */ Instruction("tay", AddrMode.Imp, 2),
/* a9 */ Instruction("lda", AddrMode.Imm, 2),
/* aa */ Instruction("tax", AddrMode.Imp, 2),
/* ab */ Instruction("nop", AddrMode.Imp, 1),
/* ac */ Instruction("ldy", AddrMode.Abs, 4),
/* ad */ Instruction("lda", AddrMode.Abs, 4),
/* ae */ Instruction("ldx", AddrMode.Abs, 4),
/* af */ Instruction("bbs2", AddrMode.Zpr, 5),
/* b0 */ Instruction("bcs", AddrMode.Rel, 2),
/* b1 */ Instruction("lda", AddrMode.IzY, 5),
/* b2 */ Instruction("lda", AddrMode.Izp, 5),
/* b3 */ Instruction("nop", AddrMode.Imp, 1),
/* b4 */ Instruction("ldy", AddrMode.ZpX, 4),
/* b5 */ Instruction("lda", AddrMode.ZpX, 4),
/* b6 */ Instruction("ldx", AddrMode.ZpY, 4),
/* b7 */ Instruction("smb3", AddrMode.Zp, 5),
/* b8 */ Instruction("clv", AddrMode.Imp, 2),
/* b9 */ Instruction("lda", AddrMode.AbsY, 4),
/* ba */ Instruction("tsx", AddrMode.Imp, 2),
/* bb */ Instruction("nop", AddrMode.Imp, 1),
/* bc */ Instruction("ldy", AddrMode.AbsX, 4),
/* bd */ Instruction("lda", AddrMode.AbsX, 4),
/* be */ Instruction("ldx", AddrMode.AbsY, 4),
/* bf */ Instruction("bbs3", AddrMode.Zpr, 5),
/* c0 */ Instruction("cpy", AddrMode.Imm, 2),
/* c1 */ Instruction("cmp", AddrMode.IzX, 6),
/* c2 */ Instruction("nop", AddrMode.Imm, 2),
/* c3 */ Instruction("nop", AddrMode.Imp, 1),
/* c4 */ Instruction("cpy", AddrMode.Zp, 3),
/* c5 */ Instruction("cmp", AddrMode.Zp, 3),
/* c6 */ Instruction("dec", AddrMode.Zp, 5),
/* c7 */ Instruction("smb4", AddrMode.Zp, 5),
/* c8 */ Instruction("iny", AddrMode.Imp, 2),
/* c9 */ Instruction("cmp", AddrMode.Imm, 2),
/* ca */ Instruction("dex", AddrMode.Imp, 2),
/* cb */ Instruction("wai", AddrMode.Imp, 3),
/* cc */ Instruction("cpy", AddrMode.Abs, 4),
/* cd */ Instruction("cmp", AddrMode.Abs, 4),
/* ce */ Instruction("dec", AddrMode.Abs, 6),
/* cf */ Instruction("bbs4", AddrMode.Zpr, 5),
/* d0 */ Instruction("bne", AddrMode.Rel, 2),
/* d1 */ Instruction("cmp", AddrMode.IzY, 5),
/* d2 */ Instruction("cmp", AddrMode.Izp, 5),
/* d3 */ Instruction("nop", AddrMode.Imp, 1),
/* d4 */ Instruction("nop", AddrMode.ZpX, 4),
/* d5 */ Instruction("cmp", AddrMode.ZpX, 4),
/* d6 */ Instruction("dec", AddrMode.ZpX, 6),
/* d7 */ Instruction("smb5", AddrMode.Zp, 5),
/* d8 */ Instruction("cld", AddrMode.Imp, 2),
/* d9 */ Instruction("cmp", AddrMode.AbsY, 4),
/* da */ Instruction("phx", AddrMode.Imp, 3),
/* db */ Instruction("stp", AddrMode.Imp, 3),
/* dc */ Instruction("nop", AddrMode.Abs, 4),
/* dd */ Instruction("cmp", AddrMode.AbsX, 4),
/* de */ Instruction("dec", AddrMode.AbsX, 7),
/* df */ Instruction("bbs5", AddrMode.Zpr, 5),
/* e0 */ Instruction("cpx", AddrMode.Imm, 2),
/* e1 */ Instruction("sbc", AddrMode.IzX, 6),
/* e2 */ Instruction("nop", AddrMode.Imm, 2),
/* e3 */ Instruction("nop", AddrMode.Imp, 1),
/* e4 */ Instruction("cpx", AddrMode.Zp, 3),
/* e5 */ Instruction("sbc", AddrMode.Zp, 3),
/* e6 */ Instruction("inc", AddrMode.Zp, 5),
/* e7 */ Instruction("smb6", AddrMode.Zp, 5),
/* e8 */ Instruction("inx", AddrMode.Imp, 2),
/* e9 */ Instruction("sbc", AddrMode.Imm, 2),
/* ea */ Instruction("nop", AddrMode.Imp, 2),
/* eb */ Instruction("nop", AddrMode.Imp, 1),
/* ec */ Instruction("cpx", AddrMode.Abs, 4),
/* ed */ Instruction("sbc", AddrMode.Abs, 4),
/* ee */ Instruction("inc", AddrMode.Abs, 6),
/* ef */ Instruction("bbs6", AddrMode.Zpr, 5),
/* f0 */ Instruction("beq", AddrMode.Rel, 2),
/* f1 */ Instruction("sbc", AddrMode.IzY, 5),
/* f2 */ Instruction("sbc", AddrMode.Izp, 5),
/* f3 */ Instruction("nop", AddrMode.Imp, 1),
/* f4 */ Instruction("nop", AddrMode.ZpX, 4),
/* f5 */ Instruction("sbc", AddrMode.ZpX, 4),
/* f6 */ Instruction("inc", AddrMode.ZpX, 6),
/* f7 */ Instruction("smb7", AddrMode.Zp, 5),
/* f8 */ Instruction("sed", AddrMode.Imp, 2),
/* f9 */ Instruction("sbc", AddrMode.AbsY, 4),
/* fa */ Instruction("plx", AddrMode.Imp, 4),
/* fb */ Instruction("nop", AddrMode.Imp, 1),
/* fc */ Instruction("nop", AddrMode.AbsX, 4),
/* fd */ Instruction("sbc", AddrMode.AbsX, 4),
/* fe */ Instruction("inc", AddrMode.AbsX, 7),
/* ff */ Instruction("bbs7", AddrMode.Zpr, 5)
).toTypedArray()
}
override fun iBrk() {
// handle BRK ('software interrupt') or a real hardware IRQ
val interrupt = pendingInterrupt
val nmi = interrupt?.first == true
if (interrupt != null) {
pushStackAddr(PC - 1)
} else {
PC++
pushStackAddr(PC)
}
Status.B = interrupt == null
pushStack(Status)
Status.I = true // interrupts are now disabled
Status.D = false // this is different from NMOS 6502
PC = readWord(if (nmi) Cpu6502.NMI_vector else Cpu6502.IRQ_vector)
pendingInterrupt = null
}
// TODO some opcodes gained a new addressing mode that we have to deal with
override fun iDec() {
if(currentInstruction.mode==AddrMode.Acc) {
TODO("dec A")
// Status.Z = data == 0
// Status.N = (data and 0b10000000) != 0
} else super.iDec()
}
override fun iInc() {
if(currentInstruction.mode==AddrMode.Acc) {
TODO("inc A")
// Status.Z = data == 0
// Status.N = (data and 0b10000000) != 0
} else super.iInc()
}
private fun iBra() {
TODO("bra")
// unconditional branch
PC = fetchedAddress
}
private fun iTrb() {
@ -330,17 +656,15 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
}
private fun iStz() {
TODO("stz")
write(fetchedAddress, 0)
}
private fun iWai() {
waiting = Wait.Waiting
PC--
}
private fun iStp() {
waiting = Wait.Stopped
PC--
}
private fun iPhx() {
@ -363,38 +687,38 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
Status.N = (Y and 0b10000000) != 0
}
private fun iBrr0() {
private fun iBbr0() {
TODO("brr0")
val x = hexB(2)
val y = hexW(2)
val z = hexB(3.toShort())
}
private fun iBrr1() {
private fun iBbr1() {
TODO("brr1")
}
private fun iBrr2() {
private fun iBbr2() {
TODO("brr2")
}
private fun iBrr3() {
private fun iBbr3() {
TODO("brr3")
}
private fun iBrr4() {
private fun iBbr4() {
TODO("brr4")
}
private fun iBrr5() {
private fun iBbr5() {
TODO("brr5")
}
private fun iBrr6() {
private fun iBbr6() {
TODO("brr6")
}
private fun iBrr7() {
private fun iBbr7() {
TODO("brr7")
}
@ -443,7 +767,7 @@ class Cpu65C02(stopOnBrk: Boolean) : Cpu6502(stopOnBrk) {
}
private fun iSmb3() {
TODO("sm30")
TODO("smb3")
}
private fun iSmb4() {

View File

@ -65,7 +65,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x00
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, mpu.A)
assertFalse(mpu.Status.C)
assertFalse(mpu.Status.N)
@ -83,7 +83,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x00
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x01, mpu.A)
assertFalse(mpu.Status.N)
assertFalse(mpu.Status.Z)
@ -100,7 +100,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0xFE
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0xFF, mpu.A)
assertTrue(mpu.Status.N)
assertFalse(mpu.Status.C)
@ -117,7 +117,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0xFF
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x01, mpu.A)
assertTrue(mpu.Status.C)
assertFalse(mpu.Status.N)
@ -212,7 +212,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x00
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, mpu.A)
assertTrue(mpu.Status.Z)
assertFalse(mpu.Status.N)
@ -228,7 +228,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0xAA
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0xAA, mpu.A)
assertTrue(mpu.Status.N)
assertFalse(mpu.Status.Z)
@ -246,7 +246,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0xFF
mpu.step()
assertTrue(mpu.Status.N)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x0003, mpu.PC)
}
@ -260,7 +260,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0xFF
mpu.step()
assertFalse(mpu.Status.N)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x0003, mpu.PC)
}
@ -274,7 +274,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0xFF
mpu.step()
assertTrue(mpu.Status.V)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x0003, mpu.PC)
}
@ -288,7 +288,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0xFF
mpu.step()
assertFalse(mpu.Status.V)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x0003, mpu.PC)
}
@ -304,7 +304,7 @@ class Test65C02 : TestCommon6502() {
assertTrue(mpu.Status.Z)
assertEquals(0x01, mpu.A)
assertEquals(0x00, memory[0xFEED])
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x0003, mpu.PC)
}
@ -320,7 +320,7 @@ class Test65C02 : TestCommon6502() {
assertFalse(mpu.Status.Z) // result of AND is non-zero
assertEquals(0x01, mpu.A)
assertEquals(0x01, memory[0xFEED])
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x0003, mpu.PC)
}
@ -336,7 +336,7 @@ class Test65C02 : TestCommon6502() {
assertTrue(mpu.Status.Z) // result of AND is zero
assertEquals(0x01, mpu.A)
assertEquals(0x00, memory[0xFEED])
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x0003, mpu.PC)
}
@ -353,7 +353,7 @@ class Test65C02 : TestCommon6502() {
assertTrue(mpu.Status.N)
assertTrue(mpu.Status.V)
assertEquals(0x00, mpu.A)
assertEquals(2, mpu.totalCycles)
assertEquals(2 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x02, mpu.PC)
}
@ -366,7 +366,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertTrue(mpu.Status.Z)
assertEquals(0x01, mpu.A)
assertEquals(2, mpu.totalCycles)
assertEquals(2 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x02, mpu.PC)
}
@ -379,7 +379,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertFalse(mpu.Status.Z) // result of AND is non-zero
assertEquals(0x01, mpu.A)
assertEquals(2, mpu.totalCycles)
assertEquals(2 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x02, mpu.PC)
}
@ -392,7 +392,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertTrue(mpu.Status.Z) // result of AND is zero
assertEquals(0x01, mpu.A)
assertEquals(2, mpu.totalCycles)
assertEquals(2 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x02, mpu.PC)
}
@ -408,7 +408,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0xFF
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertTrue(mpu.Status.N)
}
@ -422,7 +422,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0xFF
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertFalse(mpu.Status.N)
}
@ -436,7 +436,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0xFF
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertTrue(mpu.Status.V)
}
@ -450,7 +450,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0xFF
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertFalse(mpu.Status.V)
}
@ -465,7 +465,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertTrue(mpu.Status.Z)
assertEquals(0x0002, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x01, mpu.A)
assertEquals(0x00, memory[0x0010 + mpu.X])
}
@ -481,7 +481,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertFalse(mpu.Status.Z) // result of AND is non-zero
assertEquals(0x0002, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x01, mpu.A)
assertEquals(0x01, memory[0x0010 + mpu.X])
}
@ -496,7 +496,7 @@ class Test65C02 : TestCommon6502() {
mpu.A = 0x01
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertTrue(mpu.Status.Z) // result of AND is zero
assertEquals(0x01, mpu.A)
assertEquals(0x00, memory[0x0010 + mpu.X])
@ -527,7 +527,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x42
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x42, mpu.A)
assertTrue(mpu.Status.Z)
assertFalse(mpu.Status.N)
@ -543,7 +543,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x42
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x43, mpu.A)
assertFalse(mpu.Status.Z)
assertFalse(mpu.Status.N)
@ -561,7 +561,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0xFF
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, mpu.A)
assertEquals(0xFF, memory[0xABCD])
assertTrue(mpu.Status.Z)
@ -577,7 +577,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0xFF
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0xFF, mpu.A)
assertEquals(0xFF, memory[0xABCD])
assertTrue(mpu.Status.N)
@ -628,7 +628,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0, listOf(0x6c, 0xFF, 0x10))
mpu.step()
assertEquals(0xABCD, mpu.PC)
assertEquals(6, mpu.totalCycles)
assertEquals(6 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// JMP Indirect Absolute X-Indexed
@ -642,7 +642,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0xABCF, listOf(0x34, 0x12))
mpu.step()
assertEquals(0x1234, mpu.PC)
assertEquals(6, mpu.totalCycles)
assertEquals(6 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// LDA Zero Page, Indirect
@ -657,7 +657,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x80
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x80, mpu.A)
assertTrue(mpu.Status.N)
assertFalse(mpu.Status.Z)
@ -673,7 +673,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x00
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, mpu.A)
assertTrue(mpu.Status.Z)
assertFalse(mpu.Status.N)
@ -694,7 +694,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x00
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, mpu.A)
assertTrue(mpu.Status.Z)
}
@ -710,7 +710,7 @@ class Test65C02 : TestCommon6502() {
memory[0xABCD] = 0x82
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x83, mpu.A)
assertTrue(mpu.Status.N)
assertFalse(mpu.Status.Z)
@ -721,6 +721,7 @@ class Test65C02 : TestCommon6502() {
@Test
fun test_phx_pushes_x_and_updates_sp() {
mpu.X = 0xAB
mpu.SP = 0xff
// $0000 PHX
memory[0x0000] = 0xDA
mpu.step()
@ -728,7 +729,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0xAB, mpu.X)
assertEquals(0xAB, memory[0x01FF])
assertEquals(0xFE, mpu.SP)
assertEquals(3, mpu.totalCycles)
assertEquals(3 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// PHY
@ -736,6 +737,7 @@ class Test65C02 : TestCommon6502() {
@Test
fun test_phy_pushes_y_and_updates_sp() {
mpu.Y = 0xAB
mpu.SP = 0xff
// $0000 PHY
memory[0x0000] = 0x5A
mpu.step()
@ -743,7 +745,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0xAB, mpu.Y)
assertEquals(0xAB, memory[0x01FF])
assertEquals(0xFE, mpu.SP)
assertEquals(3, mpu.totalCycles)
assertEquals(3 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// PLX
@ -758,7 +760,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0x0001, mpu.PC)
assertEquals(0xAB, mpu.X)
assertEquals(0xFF, mpu.SP)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// PLY
@ -773,7 +775,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0x0001, mpu.PC)
assertEquals(0xAB, mpu.Y)
assertEquals(0xFF, mpu.SP)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// RMB0
@ -785,7 +787,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x07, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b11111110
assertEquals(expected, memory[0x0043].toInt())
}
@ -810,7 +812,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x17, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b11111101
assertEquals(expected, memory[0x0043].toInt())
}
@ -835,7 +837,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x27, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b11111011
assertEquals(expected, memory[0x0043].toInt())
@ -861,7 +863,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x37, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b11110111
assertEquals(expected, memory[0x0043].toInt())
}
@ -886,7 +888,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x47, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b11101111
assertEquals(expected, memory[0x0043].toInt())
}
@ -911,7 +913,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x57, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b11011111
assertEquals(expected, memory[0x0043].toInt())
}
@ -936,7 +938,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x67, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b10111111
assertEquals(expected, memory[0x0043].toInt())
}
@ -961,7 +963,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x77, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b01111111
assertEquals(expected, memory[0x0043].toInt())
@ -992,7 +994,7 @@ class Test65C02 : TestCommon6502() {
memory[0xFEED] = 0x00
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0xFF, memory[0xFEED])
assertEquals(0xFF, mpu.A)
assertEquals(flags, mpu.Status.asByte().toInt())
@ -1010,7 +1012,7 @@ class Test65C02 : TestCommon6502() {
memory[0xFEED] = 0xFF
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, memory[0xFEED])
assertEquals(0x00, mpu.A)
assertEquals(flags, mpu.Status.asByte().toInt())
@ -1025,7 +1027,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x87, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5, mpu.totalCycles.toInt())
val expected = 0b00000001
assertEquals(expected, memory[0x0043].toInt())
}
@ -1050,7 +1052,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x97, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b00000010
assertEquals(expected, memory[0x0043].toInt())
}
@ -1075,7 +1077,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0xA7, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b00000100
assertEquals(expected, memory[0x0043].toInt())
@ -1101,7 +1103,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0xB7, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b00001000
assertEquals(expected, memory[0x0043].toInt())
@ -1127,7 +1129,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0xC7, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b00010000
assertEquals(expected, memory[0x0043].toInt())
@ -1153,7 +1155,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0xD7, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b00100000
assertEquals(expected, memory[0x0043].toInt())
}
@ -1178,7 +1180,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0xE7, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b01000000
assertEquals(expected, memory[0x0043].toInt())
}
@ -1203,7 +1205,7 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0xF7, 0x43))
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
val expected = 0b10000000
assertEquals(expected, memory[0x0043].toInt())
}
@ -1233,7 +1235,7 @@ class Test65C02 : TestCommon6502() {
memory[0xFEED] = 0x00
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, mpu.A)
assertFalse(mpu.Status.N)
assertTrue(mpu.Status.C)
@ -1252,7 +1254,7 @@ class Test65C02 : TestCommon6502() {
memory[0xFEED] = 0x01
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, mpu.A)
assertFalse(mpu.Status.N)
assertTrue(mpu.Status.C)
@ -1271,7 +1273,7 @@ class Test65C02 : TestCommon6502() {
memory[0xFEED] = 0x00
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x00, mpu.A)
assertFalse(mpu.Status.N)
assertTrue(mpu.Status.C)
@ -1290,7 +1292,7 @@ class Test65C02 : TestCommon6502() {
memory[0xFEED] = 0x02
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
assertEquals(0x04, mpu.A)
assertFalse(mpu.Status.N)
assertFalse(mpu.Status.Z)
@ -1309,7 +1311,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertEquals(0x00, memory[0x0032])
assertEquals(0x0002, mpu.PC)
assertEquals(3, mpu.totalCycles)
assertEquals(3 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// STZ Zero Page, X-Indexed
@ -1324,7 +1326,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertEquals(0x00, memory[0x0032])
assertEquals(0x0002, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// STZ Absolute
@ -1338,7 +1340,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertEquals(0x00, memory[0xFEED])
assertEquals(0x0003, mpu.PC)
assertEquals(4, mpu.totalCycles)
assertEquals(4 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// STZ Absolute, X-Indexed
@ -1354,7 +1356,7 @@ class Test65C02 : TestCommon6502() {
mpu.step()
assertEquals(0x00, memory[0xFEED])
assertEquals(0x0003, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// TSB Zero Page
@ -1370,7 +1372,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0xF0, memory[0x00BB])
assertFalse(mpu.Status.Z)
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
@Test
@ -1384,7 +1386,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0xE0, memory[0x00BB])
assertTrue(mpu.Status.Z)
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// TSB Absolute
@ -1400,7 +1402,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0xF0, memory[0xFEED])
assertFalse(mpu.Status.Z)
assertEquals(0x0003, mpu.PC)
assertEquals(6, mpu.totalCycles)
assertEquals(6 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
@Test
@ -1414,7 +1416,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0xE0, memory[0xFEED])
assertTrue(mpu.Status.Z)
assertEquals(0x0003, mpu.PC)
assertEquals(6, mpu.totalCycles)
assertEquals(6 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// TRB Zero Page
@ -1430,7 +1432,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0x80, memory[0x00BB])
assertFalse(mpu.Status.Z)
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
@Test
@ -1444,7 +1446,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0x80, memory[0x00BB])
assertTrue(mpu.Status.Z)
assertEquals(0x0002, mpu.PC)
assertEquals(5, mpu.totalCycles)
assertEquals(5 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
// TRB Absolute
@ -1460,7 +1462,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0x80, memory[0xFEED])
assertFalse(mpu.Status.Z)
assertEquals(0x0003, mpu.PC)
assertEquals(6, mpu.totalCycles)
assertEquals(6 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
@Test
@ -1474,7 +1476,7 @@ class Test65C02 : TestCommon6502() {
assertEquals(0x80, memory[0xFEED])
assertTrue(mpu.Status.Z)
assertEquals(0x0003, mpu.PC)
assertEquals(6, mpu.totalCycles)
assertEquals(6 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
@Test
@ -1516,17 +1518,17 @@ class Test65C02 : TestCommon6502() {
writeMem(memory, 0x0000, listOf(0x80, 0x10))
mpu.step()
assertEquals(0x12, mpu.PC)
assertEquals(2, mpu.totalCycles)
assertEquals(2 + Cpu65C02.resetCycles, mpu.totalCycles.toInt())
}
@Test
fun test_bra_backward() {
// $0240 BRA $F0
writeMem(memory, 0x0000, listOf(0x80, 0xF0))
writeMem(memory, 0x0204, listOf(0x80, 0xF0))
mpu.PC = 0x0204
mpu.step()
assertEquals(0x1F6, mpu.PC)
assertEquals(3, mpu.totalCycles) // Crossed boundry
assertEquals(3 + Cpu65C02.resetCycles, mpu.totalCycles.toInt()) // Crossed boundry
}
// WAI