mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
6502 simulator passes all tests for regular opcodes
This commit is contained in:
parent
fec8db6a75
commit
bdcd10512f
@ -16,6 +16,7 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
|
<sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="openjdk-11" jdkType="JavaSDK" />
|
<orderEntry type="jdk" jdkName="openjdk-11" jdkType="JavaSDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
@ -1,89 +1,44 @@
|
|||||||
package sim65
|
package sim65
|
||||||
|
|
||||||
import kotlinx.cli.*
|
|
||||||
import sim65.components.*
|
import sim65.components.*
|
||||||
import sim65.components.Cpu6502.Companion.hexB
|
import sim65.components.Cpu6502.Companion.RESET_vector
|
||||||
import kotlin.system.exitProcess
|
|
||||||
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
printSoftwareHeader2()
|
printSoftwareHeader()
|
||||||
startSimulator2(args)
|
startSimulator(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun printSoftwareHeader2() {
|
internal fun printSoftwareHeader() {
|
||||||
val buildVersion = object {}.javaClass.getResource("/version.txt").readText().trim()
|
val buildVersion = object {}.javaClass.getResource("/version.txt").readText().trim()
|
||||||
println("\nSim65 6502 cpu simulator v$buildVersion by Irmen de Jong (irmen@razorvine.net)")
|
println("\nSim65 6502 cpu simulator v$buildVersion by Irmen de Jong (irmen@razorvine.net)")
|
||||||
println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
|
println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun startSimulator2(args: Array<String>) {
|
private fun startSimulator(args: Array<String>) {
|
||||||
val bootRom = listOf<UByte>(
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0x00,0x90, // NMI vector
|
|
||||||
0x00,0x10, // RESET vector
|
|
||||||
0x00,0xa0 // IRQ vector
|
|
||||||
).toTypedArray()
|
|
||||||
|
|
||||||
|
// create a computer system.
|
||||||
|
// note that the order in which components are added to the bus, is important:
|
||||||
|
// it determines the priority of reads and writes.
|
||||||
val cpu = Cpu6502(true)
|
val cpu = Cpu6502(true)
|
||||||
cpu.tracing = true
|
val ram = Ram(0, 0xffff)
|
||||||
|
ram[RESET_vector] = 0x00
|
||||||
|
ram[RESET_vector + 1] = 0x10
|
||||||
|
|
||||||
|
val parallel = ParallelPort(0xd000, 0xd001)
|
||||||
|
val timer = Timer(0xd100, 0xd103)
|
||||||
|
|
||||||
// create the system bus and add device to it.
|
|
||||||
// note that the order is relevant w.r.t. where reads and writes are going.
|
|
||||||
val bus = Bus()
|
val bus = Bus()
|
||||||
bus.add(cpu)
|
bus.add(cpu)
|
||||||
bus.add(Rom(0xff00, 0xffff, bootRom))
|
bus.add(parallel)
|
||||||
bus.add(Parallel(0xd000, 0xd001))
|
bus.add(timer)
|
||||||
bus.add(Timer(0xd100, 0xd103))
|
|
||||||
val ram = Ram(0, 0xffff)
|
|
||||||
bus.add(ram)
|
bus.add(ram)
|
||||||
|
|
||||||
bus.reset()
|
bus.reset()
|
||||||
|
|
||||||
ram.load("sim65/test/testfiles/ram.bin", 0x8000)
|
cpu.tracing = true
|
||||||
ram.load("sim65/test/testfiles/bcdtest.bin", 0x1000)
|
|
||||||
//ram.dump(0x8000, 0x802f)
|
|
||||||
//cpu.disassemble(ram, 0x8000, 0x802f)
|
|
||||||
|
|
||||||
try {
|
|
||||||
while (true) {
|
while (true) {
|
||||||
bus.clock()
|
bus.clock()
|
||||||
}
|
}
|
||||||
} catch(e: InstructionError) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ram[0x0400] ==0.toShort())
|
|
||||||
println("BCD TEST: OK!")
|
|
||||||
else {
|
|
||||||
val code = ram[0x0400]
|
|
||||||
val v1 = ram[0x0401]
|
|
||||||
val v2 = ram[0x0402]
|
|
||||||
val predictedA = ram[0x00fc]
|
|
||||||
val actualA = ram[0x00fd]
|
|
||||||
val predictedF = ram[0x00fe]
|
|
||||||
val actualF = ram[0x00ff]
|
|
||||||
println("BCD TEST: FAIL!! code=${hexB(code)} value1=${hexB(v1)} value2=${hexB(v2)}")
|
|
||||||
println(" predictedA=${hexB(predictedA)}")
|
|
||||||
println(" actualA=${hexB(actualA)}")
|
|
||||||
println(" predictedF=${predictedF.toString(2).padStart(8,'0')}")
|
|
||||||
println(" actualF=${actualF.toString(2).padStart(8,'0')}")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,13 @@ abstract class BusComponent {
|
|||||||
abstract class MemMappedComponent(val startAddress: Address, val endAddress: Address): BusComponent() {
|
abstract class MemMappedComponent(val startAddress: Address, val endAddress: Address): BusComponent() {
|
||||||
abstract operator fun get(address: Address): UByte
|
abstract operator fun get(address: Address): UByte
|
||||||
abstract operator fun set(address: Address, data: UByte)
|
abstract operator fun set(address: Address, data: UByte)
|
||||||
abstract fun cloneMem(): Array<UByte>
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
require(endAddress>=startAddress)
|
require(endAddress>=startAddress)
|
||||||
require(startAddress>=0 && endAddress <= 0xffff) { "can only have 16-bit address space" }
|
require(startAddress>=0 && endAddress <= 0xffff) { "can only have 16-bit address space" }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dump(from: Address, to: Address) {
|
fun hexDump(from: Address, to: Address) {
|
||||||
(from .. to).chunked(16).forEach {
|
(from .. to).chunked(16).forEach {
|
||||||
print("\$${it.first().toString(16).padStart(4, '0')} ")
|
print("\$${it.first().toString(16).padStart(4, '0')} ")
|
||||||
val bytes = it.map { address -> get(address) }
|
val bytes = it.map { address -> get(address) }
|
||||||
@ -31,5 +30,8 @@ abstract class MemMappedComponent(val startAddress: Address, val endAddress: Add
|
|||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MemoryComponent(startAddress: Address, endAddress: Address): MemMappedComponent(startAddress, endAddress) {
|
||||||
|
abstract fun cloneContents(): Array<UByte>
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ class InstructionError(msg: String) : RuntimeException(msg)
|
|||||||
|
|
||||||
interface ICpu {
|
interface ICpu {
|
||||||
fun disassemble(memory: Array<UByte>, baseAddress: Address, from: Address, to: Address): List<String>
|
fun disassemble(memory: Array<UByte>, baseAddress: Address, from: Address, to: Address): List<String>
|
||||||
fun disassemble(component: MemMappedComponent, from: Address, to: Address) =
|
fun disassemble(component: MemoryComponent, from: Address, to: Address) =
|
||||||
disassemble(component.cloneMem(), component.startAddress, from, to)
|
disassemble(component.cloneContents(), component.startAddress, from, to)
|
||||||
|
|
||||||
fun clock()
|
fun clock()
|
||||||
fun reset()
|
fun reset()
|
||||||
@ -16,6 +16,7 @@ interface ICpu {
|
|||||||
val totalCycles: Long
|
val totalCycles: Long
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 the optional additional cycles to certain instructions and addressing modes
|
||||||
// TODO: add IRQ and NMI signaling.
|
// TODO: add IRQ and NMI signaling.
|
||||||
// TODO: make a 65c02 variant as well (and re-enable the unit tests for that).
|
// TODO: make a 65c02 variant as well (and re-enable the unit tests for that).
|
||||||
@ -68,7 +69,7 @@ class Cpu6502(private val stopOnBrk: Boolean) : BusComponent(), ICpu {
|
|||||||
IzY
|
IzY
|
||||||
}
|
}
|
||||||
|
|
||||||
class Instruction(val opcode: UByte, val mnemonic: String, val mode: AddrMode, val cycles: Int, val official: Boolean, val execute: () -> Unit) {
|
class Instruction(val opcode: UByte, val mnemonic: String, val mode: AddrMode, val cycles: Int, val execute: () -> Unit) {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "[${hexB(opcode)}: $mnemonic $mode]"
|
return "[${hexB(opcode)}: $mnemonic $mode]"
|
||||||
}
|
}
|
||||||
@ -331,12 +332,12 @@ class Cpu6502(private val stopOnBrk: Boolean) : BusComponent(), ICpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun amZpx() {
|
private fun amZpx() {
|
||||||
// note: zeropage index will not leave Zp when page boundray is crossed
|
// note: zeropage index will not leave Zp when page boundary is crossed
|
||||||
fetchedAddress = (readPc() + X) and 0xff
|
fetchedAddress = (readPc() + X) and 0xff
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun amZpy() {
|
private fun amZpy() {
|
||||||
// note: zeropage index will not leave Zp when page boundray is crossed
|
// note: zeropage index will not leave Zp when page boundary is crossed
|
||||||
fetchedAddress = (readPc() + Y) and 0xff
|
fetchedAddress = (readPc() + Y) and 0xff
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,17 +421,17 @@ class Cpu6502(private val stopOnBrk: Boolean) : BusComponent(), ICpu {
|
|||||||
pushStack(status.asByte().toInt())
|
pushStack(status.asByte().toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun pushStack(data: Int) {
|
private fun pushStack(data: Int) {
|
||||||
write(SP or 0x0100, data)
|
write(SP or 0x0100, data)
|
||||||
SP = (SP - 1) and 0xff
|
SP = (SP - 1) and 0xff
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun popStack(): Int {
|
private fun popStack(): Int {
|
||||||
SP = (SP + 1) and 0xff
|
SP = (SP + 1) and 0xff
|
||||||
return read(SP or 0x0100)
|
return read(SP or 0x0100)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun popStackAddr(): Address {
|
private fun popStackAddr(): Address {
|
||||||
val lo = popStack()
|
val lo = popStack()
|
||||||
val hi = popStack()
|
val hi = popStack()
|
||||||
return lo or (hi shl 8)
|
return lo or (hi shl 8)
|
||||||
@ -442,262 +443,262 @@ class Cpu6502(private val stopOnBrk: Boolean) : BusComponent(), ICpu {
|
|||||||
|
|
||||||
// opcodes table from http://www.oxyron.de/html/opcodes02.html
|
// opcodes table from http://www.oxyron.de/html/opcodes02.html
|
||||||
private val opcodes = listOf(
|
private val opcodes = listOf(
|
||||||
Instruction(0x00, "brk", AddrMode.Imp, 7, true, ::iBrk),
|
Instruction(0x00, "brk", AddrMode.Imp, 7, ::iBrk),
|
||||||
Instruction(0x01, "ora", AddrMode.IzX, 6, true, ::iOra),
|
Instruction(0x01, "ora", AddrMode.IzX, 6, ::iOra),
|
||||||
Instruction(0x02, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x02, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x03, "slo", AddrMode.IzX, 8, false, ::iSlo),
|
Instruction(0x03, "slo", AddrMode.IzX, 8, ::iSlo),
|
||||||
Instruction(0x04, "nop", AddrMode.Zp, 3, false, ::iNop),
|
Instruction(0x04, "nop", AddrMode.Zp, 3, ::iNop),
|
||||||
Instruction(0x05, "ora", AddrMode.Zp, 3, true, ::iOra),
|
Instruction(0x05, "ora", AddrMode.Zp, 3, ::iOra),
|
||||||
Instruction(0x06, "asl", AddrMode.Zp, 5, true, ::iAsl),
|
Instruction(0x06, "asl", AddrMode.Zp, 5, ::iAsl),
|
||||||
Instruction(0x07, "slo", AddrMode.Zp, 5, false, ::iSlo),
|
Instruction(0x07, "slo", AddrMode.Zp, 5, ::iSlo),
|
||||||
Instruction(0x08, "php", AddrMode.Imp, 3, true, ::iPhp),
|
Instruction(0x08, "php", AddrMode.Imp, 3, ::iPhp),
|
||||||
Instruction(0x09, "ora", AddrMode.Imm, 2, true, ::iOra),
|
Instruction(0x09, "ora", AddrMode.Imm, 2, ::iOra),
|
||||||
Instruction(0x0a, "asl", AddrMode.Acc, 2, true, ::iAsl),
|
Instruction(0x0a, "asl", AddrMode.Acc, 2, ::iAsl),
|
||||||
Instruction(0x0b, "anc", AddrMode.Imm, 2, false, ::iAnc),
|
Instruction(0x0b, "anc", AddrMode.Imm, 2, ::iAnc),
|
||||||
Instruction(0x0c, "nop", AddrMode.Abs, 4, false, ::iNop),
|
Instruction(0x0c, "nop", AddrMode.Abs, 4, ::iNop),
|
||||||
Instruction(0x0d, "ora", AddrMode.Abs, 4, true, ::iOra),
|
Instruction(0x0d, "ora", AddrMode.Abs, 4, ::iOra),
|
||||||
Instruction(0x0e, "asl", AddrMode.Abs, 6, true, ::iAsl),
|
Instruction(0x0e, "asl", AddrMode.Abs, 6, ::iAsl),
|
||||||
Instruction(0x0f, "slo", AddrMode.Abs, 6, false, ::iSlo),
|
Instruction(0x0f, "slo", AddrMode.Abs, 6, ::iSlo),
|
||||||
Instruction(0x10, "bpl", AddrMode.Rel, 2, true, ::iBpl),
|
Instruction(0x10, "bpl", AddrMode.Rel, 2, ::iBpl),
|
||||||
Instruction(0x11, "ora", AddrMode.IzY, 5, true, ::iOra),
|
Instruction(0x11, "ora", AddrMode.IzY, 5, ::iOra),
|
||||||
Instruction(0x12, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x12, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x13, "slo", AddrMode.IzY, 6, false, ::iSlo),
|
Instruction(0x13, "slo", AddrMode.IzY, 6, ::iSlo),
|
||||||
Instruction(0x14, "nop", AddrMode.ZpX, 4, false, ::iNop),
|
Instruction(0x14, "nop", AddrMode.ZpX, 4, ::iNop),
|
||||||
Instruction(0x15, "ora", AddrMode.ZpX, 4, true, ::iOra),
|
Instruction(0x15, "ora", AddrMode.ZpX, 4, ::iOra),
|
||||||
Instruction(0x16, "asl", AddrMode.ZpX, 6, true, ::iAsl),
|
Instruction(0x16, "asl", AddrMode.ZpX, 6, ::iAsl),
|
||||||
Instruction(0x17, "slo", AddrMode.ZpX, 6, false, ::iSlo),
|
Instruction(0x17, "slo", AddrMode.ZpX, 6, ::iSlo),
|
||||||
Instruction(0x18, "clc", AddrMode.Imp, 2, true, ::iClc),
|
Instruction(0x18, "clc", AddrMode.Imp, 2, ::iClc),
|
||||||
Instruction(0x19, "ora", AddrMode.AbsY, 4, true, ::iOra),
|
Instruction(0x19, "ora", AddrMode.AbsY, 4, ::iOra),
|
||||||
Instruction(0x1a, "nop", AddrMode.Imp, 2, false, ::iNop),
|
Instruction(0x1a, "nop", AddrMode.Imp, 2, ::iNop),
|
||||||
Instruction(0x1b, "slo", AddrMode.AbsY, 7, false, ::iSlo),
|
Instruction(0x1b, "slo", AddrMode.AbsY, 7, ::iSlo),
|
||||||
Instruction(0x1c, "nop", AddrMode.AbsX, 4, false, ::iNop),
|
Instruction(0x1c, "nop", AddrMode.AbsX, 4, ::iNop),
|
||||||
Instruction(0x1d, "ora", AddrMode.AbsX, 4, true, ::iOra),
|
Instruction(0x1d, "ora", AddrMode.AbsX, 4, ::iOra),
|
||||||
Instruction(0x1e, "asl", AddrMode.AbsX, 7, true, ::iAsl),
|
Instruction(0x1e, "asl", AddrMode.AbsX, 7, ::iAsl),
|
||||||
Instruction(0x1f, "slo", AddrMode.AbsX, 7, false, ::iSlo),
|
Instruction(0x1f, "slo", AddrMode.AbsX, 7, ::iSlo),
|
||||||
Instruction(0x20, "jsr", AddrMode.Abs, 6, true, ::iJsr),
|
Instruction(0x20, "jsr", AddrMode.Abs, 6, ::iJsr),
|
||||||
Instruction(0x21, "and", AddrMode.IzX, 6, true, ::iAnd),
|
Instruction(0x21, "and", AddrMode.IzX, 6, ::iAnd),
|
||||||
Instruction(0x22, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x22, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x23, "rla", AddrMode.IzX, 8, false, ::iRla),
|
Instruction(0x23, "rla", AddrMode.IzX, 8, ::iRla),
|
||||||
Instruction(0x24, "bit", AddrMode.Zp, 3, true, ::iBit),
|
Instruction(0x24, "bit", AddrMode.Zp, 3, ::iBit),
|
||||||
Instruction(0x25, "and", AddrMode.Zp, 3, true, ::iAnd),
|
Instruction(0x25, "and", AddrMode.Zp, 3, ::iAnd),
|
||||||
Instruction(0x26, "rol", AddrMode.Zp, 5, true, ::iRol),
|
Instruction(0x26, "rol", AddrMode.Zp, 5, ::iRol),
|
||||||
Instruction(0x27, "rla", AddrMode.Zp, 5, false, ::iRla),
|
Instruction(0x27, "rla", AddrMode.Zp, 5, ::iRla),
|
||||||
Instruction(0x28, "plp", AddrMode.Imp, 4, true, ::iPlp),
|
Instruction(0x28, "plp", AddrMode.Imp, 4, ::iPlp),
|
||||||
Instruction(0x29, "and", AddrMode.Imm, 2, true, ::iAnd),
|
Instruction(0x29, "and", AddrMode.Imm, 2, ::iAnd),
|
||||||
Instruction(0x2a, "rol", AddrMode.Acc, 2, true, ::iRol),
|
Instruction(0x2a, "rol", AddrMode.Acc, 2, ::iRol),
|
||||||
Instruction(0x2b, "anc", AddrMode.Imm, 2, false, ::iAnc),
|
Instruction(0x2b, "anc", AddrMode.Imm, 2, ::iAnc),
|
||||||
Instruction(0x2c, "bit", AddrMode.Abs, 4, true, ::iBit),
|
Instruction(0x2c, "bit", AddrMode.Abs, 4, ::iBit),
|
||||||
Instruction(0x2d, "and", AddrMode.Abs, 4, true, ::iAnd),
|
Instruction(0x2d, "and", AddrMode.Abs, 4, ::iAnd),
|
||||||
Instruction(0x2e, "rol", AddrMode.Abs, 6, true, ::iRol),
|
Instruction(0x2e, "rol", AddrMode.Abs, 6, ::iRol),
|
||||||
Instruction(0x2f, "rla", AddrMode.Abs, 6, false, ::iRla),
|
Instruction(0x2f, "rla", AddrMode.Abs, 6, ::iRla),
|
||||||
Instruction(0x30, "bmi", AddrMode.Rel, 2, true, ::iBmi),
|
Instruction(0x30, "bmi", AddrMode.Rel, 2, ::iBmi),
|
||||||
Instruction(0x31, "and", AddrMode.IzY, 5, true, ::iAnd),
|
Instruction(0x31, "and", AddrMode.IzY, 5, ::iAnd),
|
||||||
Instruction(0x32, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x32, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x33, "rla", AddrMode.IzY, 8, false, ::iRla),
|
Instruction(0x33, "rla", AddrMode.IzY, 8, ::iRla),
|
||||||
Instruction(0x34, "nop", AddrMode.ZpX, 4, false, ::iNop),
|
Instruction(0x34, "nop", AddrMode.ZpX, 4, ::iNop),
|
||||||
Instruction(0x35, "and", AddrMode.ZpX, 4, true, ::iAnd),
|
Instruction(0x35, "and", AddrMode.ZpX, 4, ::iAnd),
|
||||||
Instruction(0x36, "rol", AddrMode.ZpX, 6, true, ::iRol),
|
Instruction(0x36, "rol", AddrMode.ZpX, 6, ::iRol),
|
||||||
Instruction(0x37, "rla", AddrMode.ZpX, 6, false, ::iRla),
|
Instruction(0x37, "rla", AddrMode.ZpX, 6, ::iRla),
|
||||||
Instruction(0x38, "sec", AddrMode.Imp, 2, true, ::iSec),
|
Instruction(0x38, "sec", AddrMode.Imp, 2, ::iSec),
|
||||||
Instruction(0x39, "and", AddrMode.AbsY, 4, true, ::iAnd),
|
Instruction(0x39, "and", AddrMode.AbsY, 4, ::iAnd),
|
||||||
Instruction(0x3a, "nop", AddrMode.Imp, 2, false, ::iNop),
|
Instruction(0x3a, "nop", AddrMode.Imp, 2, ::iNop),
|
||||||
Instruction(0x3b, "rla", AddrMode.AbsY, 7, false, ::iRla),
|
Instruction(0x3b, "rla", AddrMode.AbsY, 7, ::iRla),
|
||||||
Instruction(0x3c, "nop", AddrMode.AbsX, 4, false, ::iNop),
|
Instruction(0x3c, "nop", AddrMode.AbsX, 4, ::iNop),
|
||||||
Instruction(0x3d, "and", AddrMode.AbsX, 4, true, ::iAnd),
|
Instruction(0x3d, "and", AddrMode.AbsX, 4, ::iAnd),
|
||||||
Instruction(0x3e, "rol", AddrMode.AbsX, 7, true, ::iRol),
|
Instruction(0x3e, "rol", AddrMode.AbsX, 7, ::iRol),
|
||||||
Instruction(0x3f, "rla", AddrMode.AbsX, 7, false, ::iRla),
|
Instruction(0x3f, "rla", AddrMode.AbsX, 7, ::iRla),
|
||||||
Instruction(0x40, "rti", AddrMode.Imp, 6, true, ::iRti),
|
Instruction(0x40, "rti", AddrMode.Imp, 6, ::iRti),
|
||||||
Instruction(0x41, "eor", AddrMode.IzX, 6, true, ::iEor),
|
Instruction(0x41, "eor", AddrMode.IzX, 6, ::iEor),
|
||||||
Instruction(0x42, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x42, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x43, "sre", AddrMode.IzX, 8, false, ::iSre),
|
Instruction(0x43, "sre", AddrMode.IzX, 8, ::iSre),
|
||||||
Instruction(0x44, "nop", AddrMode.Zp, 3, false, ::iNop),
|
Instruction(0x44, "nop", AddrMode.Zp, 3, ::iNop),
|
||||||
Instruction(0x45, "eor", AddrMode.Zp, 3, true, ::iEor),
|
Instruction(0x45, "eor", AddrMode.Zp, 3, ::iEor),
|
||||||
Instruction(0x46, "lsr", AddrMode.Zp, 5, true, ::iLsr),
|
Instruction(0x46, "lsr", AddrMode.Zp, 5, ::iLsr),
|
||||||
Instruction(0x47, "sre", AddrMode.Zp, 5, false, ::iSre),
|
Instruction(0x47, "sre", AddrMode.Zp, 5, ::iSre),
|
||||||
Instruction(0x48, "pha", AddrMode.Imp, 3, true, ::iPha),
|
Instruction(0x48, "pha", AddrMode.Imp, 3, ::iPha),
|
||||||
Instruction(0x49, "eor", AddrMode.Imm, 2, true, ::iEor),
|
Instruction(0x49, "eor", AddrMode.Imm, 2, ::iEor),
|
||||||
Instruction(0x4a, "lsr", AddrMode.Acc, 2, true, ::iLsr),
|
Instruction(0x4a, "lsr", AddrMode.Acc, 2, ::iLsr),
|
||||||
Instruction(0x4b, "alr", AddrMode.Imm, 2, false, ::iAlr),
|
Instruction(0x4b, "alr", AddrMode.Imm, 2, ::iAlr),
|
||||||
Instruction(0x4c, "jmp", AddrMode.Abs, 3, true, ::iJmp),
|
Instruction(0x4c, "jmp", AddrMode.Abs, 3, ::iJmp),
|
||||||
Instruction(0x4d, "eor", AddrMode.Abs, 4, true, ::iEor),
|
Instruction(0x4d, "eor", AddrMode.Abs, 4, ::iEor),
|
||||||
Instruction(0x4e, "lsr", AddrMode.Abs, 6, true, ::iLsr),
|
Instruction(0x4e, "lsr", AddrMode.Abs, 6, ::iLsr),
|
||||||
Instruction(0x4f, "sre", AddrMode.Abs, 6, false, ::iSre),
|
Instruction(0x4f, "sre", AddrMode.Abs, 6, ::iSre),
|
||||||
Instruction(0x50, "bvc", AddrMode.Rel, 2, true, ::iBvc),
|
Instruction(0x50, "bvc", AddrMode.Rel, 2, ::iBvc),
|
||||||
Instruction(0x51, "eor", AddrMode.IzY, 5, true, ::iEor),
|
Instruction(0x51, "eor", AddrMode.IzY, 5, ::iEor),
|
||||||
Instruction(0x52, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x52, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x53, "sre", AddrMode.IzY, 8, false, ::iSre),
|
Instruction(0x53, "sre", AddrMode.IzY, 8, ::iSre),
|
||||||
Instruction(0x54, "nop", AddrMode.ZpX, 4, false, ::iNop),
|
Instruction(0x54, "nop", AddrMode.ZpX, 4, ::iNop),
|
||||||
Instruction(0x55, "eor", AddrMode.ZpX, 4, true, ::iEor),
|
Instruction(0x55, "eor", AddrMode.ZpX, 4, ::iEor),
|
||||||
Instruction(0x56, "lsr", AddrMode.ZpX, 6, true, ::iLsr),
|
Instruction(0x56, "lsr", AddrMode.ZpX, 6, ::iLsr),
|
||||||
Instruction(0x57, "sre", AddrMode.ZpX, 6, false, ::iSre),
|
Instruction(0x57, "sre", AddrMode.ZpX, 6, ::iSre),
|
||||||
Instruction(0x58, "cli", AddrMode.Imp, 2, true, ::iCli),
|
Instruction(0x58, "cli", AddrMode.Imp, 2, ::iCli),
|
||||||
Instruction(0x59, "eor", AddrMode.AbsY, 4, true, ::iEor),
|
Instruction(0x59, "eor", AddrMode.AbsY, 4, ::iEor),
|
||||||
Instruction(0x5a, "nop", AddrMode.Imp, 2, false, ::iNop),
|
Instruction(0x5a, "nop", AddrMode.Imp, 2, ::iNop),
|
||||||
Instruction(0x5b, "sre", AddrMode.AbsY, 7, false, ::iSre),
|
Instruction(0x5b, "sre", AddrMode.AbsY, 7, ::iSre),
|
||||||
Instruction(0x5c, "nop", AddrMode.AbsX, 4, false, ::iNop),
|
Instruction(0x5c, "nop", AddrMode.AbsX, 4, ::iNop),
|
||||||
Instruction(0x5d, "eor", AddrMode.AbsX, 4, true, ::iEor),
|
Instruction(0x5d, "eor", AddrMode.AbsX, 4, ::iEor),
|
||||||
Instruction(0x5e, "lsr", AddrMode.AbsX, 7, true, ::iLsr),
|
Instruction(0x5e, "lsr", AddrMode.AbsX, 7, ::iLsr),
|
||||||
Instruction(0x5f, "sre", AddrMode.AbsX, 7, false, ::iSre),
|
Instruction(0x5f, "sre", AddrMode.AbsX, 7, ::iSre),
|
||||||
Instruction(0x60, "rts", AddrMode.Imp, 6, true, ::iRts),
|
Instruction(0x60, "rts", AddrMode.Imp, 6, ::iRts),
|
||||||
Instruction(0x61, "adc", AddrMode.IzX, 6, true, ::iAdc),
|
Instruction(0x61, "adc", AddrMode.IzX, 6, ::iAdc),
|
||||||
Instruction(0x62, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x62, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x63, "rra", AddrMode.IzX, 8, false, ::iRra),
|
Instruction(0x63, "rra", AddrMode.IzX, 8, ::iRra),
|
||||||
Instruction(0x64, "nop", AddrMode.Zp, 3, false, ::iNop),
|
Instruction(0x64, "nop", AddrMode.Zp, 3, ::iNop),
|
||||||
Instruction(0x65, "adc", AddrMode.Zp, 3, true, ::iAdc),
|
Instruction(0x65, "adc", AddrMode.Zp, 3, ::iAdc),
|
||||||
Instruction(0x66, "ror", AddrMode.Zp, 5, true, ::iRor),
|
Instruction(0x66, "ror", AddrMode.Zp, 5, ::iRor),
|
||||||
Instruction(0x67, "rra", AddrMode.Zp, 5, false, ::iRra),
|
Instruction(0x67, "rra", AddrMode.Zp, 5, ::iRra),
|
||||||
Instruction(0x68, "pla", AddrMode.Imp, 4, true, ::iPla),
|
Instruction(0x68, "pla", AddrMode.Imp, 4, ::iPla),
|
||||||
Instruction(0x69, "adc", AddrMode.Imm, 2, true, ::iAdc),
|
Instruction(0x69, "adc", AddrMode.Imm, 2, ::iAdc),
|
||||||
Instruction(0x6a, "ror", AddrMode.Acc, 2, true, ::iRor),
|
Instruction(0x6a, "ror", AddrMode.Acc, 2, ::iRor),
|
||||||
Instruction(0x6b, "arr", AddrMode.Imm, 2, false, ::iArr),
|
Instruction(0x6b, "arr", AddrMode.Imm, 2, ::iArr),
|
||||||
Instruction(0x6c, "jmp", AddrMode.Ind, 5, true, ::iJmp),
|
Instruction(0x6c, "jmp", AddrMode.Ind, 5, ::iJmp),
|
||||||
Instruction(0x6d, "adc", AddrMode.Abs, 4, true, ::iAdc),
|
Instruction(0x6d, "adc", AddrMode.Abs, 4, ::iAdc),
|
||||||
Instruction(0x6e, "ror", AddrMode.Abs, 6, true, ::iRor),
|
Instruction(0x6e, "ror", AddrMode.Abs, 6, ::iRor),
|
||||||
Instruction(0x6f, "rra", AddrMode.Abs, 6, false, ::iRra),
|
Instruction(0x6f, "rra", AddrMode.Abs, 6, ::iRra),
|
||||||
Instruction(0x70, "bvs", AddrMode.Rel, 2, true, ::iBvs),
|
Instruction(0x70, "bvs", AddrMode.Rel, 2, ::iBvs),
|
||||||
Instruction(0x71, "adc", AddrMode.IzY, 5, true, ::iAdc),
|
Instruction(0x71, "adc", AddrMode.IzY, 5, ::iAdc),
|
||||||
Instruction(0x72, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x72, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x73, "rra", AddrMode.IzY, 8, false, ::iRra),
|
Instruction(0x73, "rra", AddrMode.IzY, 8, ::iRra),
|
||||||
Instruction(0x74, "nop", AddrMode.ZpX, 4, false, ::iNop),
|
Instruction(0x74, "nop", AddrMode.ZpX, 4, ::iNop),
|
||||||
Instruction(0x75, "adc", AddrMode.ZpX, 4, true, ::iAdc),
|
Instruction(0x75, "adc", AddrMode.ZpX, 4, ::iAdc),
|
||||||
Instruction(0x76, "ror", AddrMode.ZpX, 6, true, ::iRor),
|
Instruction(0x76, "ror", AddrMode.ZpX, 6, ::iRor),
|
||||||
Instruction(0x77, "rra", AddrMode.ZpX, 6, false, ::iRra),
|
Instruction(0x77, "rra", AddrMode.ZpX, 6, ::iRra),
|
||||||
Instruction(0x78, "sei", AddrMode.Imp, 2, true, ::iSei),
|
Instruction(0x78, "sei", AddrMode.Imp, 2, ::iSei),
|
||||||
Instruction(0x79, "adc", AddrMode.AbsY, 4, true, ::iAdc),
|
Instruction(0x79, "adc", AddrMode.AbsY, 4, ::iAdc),
|
||||||
Instruction(0x7a, "nop", AddrMode.Imp, 2, false, ::iNop),
|
Instruction(0x7a, "nop", AddrMode.Imp, 2, ::iNop),
|
||||||
Instruction(0x7b, "rra", AddrMode.AbsY, 7, false, ::iRra),
|
Instruction(0x7b, "rra", AddrMode.AbsY, 7, ::iRra),
|
||||||
Instruction(0x7c, "nop", AddrMode.AbsX, 4, false, ::iNop),
|
Instruction(0x7c, "nop", AddrMode.AbsX, 4, ::iNop),
|
||||||
Instruction(0x7d, "adc", AddrMode.AbsX, 4, true, ::iAdc),
|
Instruction(0x7d, "adc", AddrMode.AbsX, 4, ::iAdc),
|
||||||
Instruction(0x7e, "ror", AddrMode.AbsX, 7, true, ::iRor),
|
Instruction(0x7e, "ror", AddrMode.AbsX, 7, ::iRor),
|
||||||
Instruction(0x7f, "rra", AddrMode.AbsX, 7, false, ::iRra),
|
Instruction(0x7f, "rra", AddrMode.AbsX, 7, ::iRra),
|
||||||
Instruction(0x80, "nop", AddrMode.Imm, 2, false, ::iNop),
|
Instruction(0x80, "nop", AddrMode.Imm, 2, ::iNop),
|
||||||
Instruction(0x81, "sta", AddrMode.IzX, 6, true, ::iSta),
|
Instruction(0x81, "sta", AddrMode.IzX, 6, ::iSta),
|
||||||
Instruction(0x82, "nop", AddrMode.Imm, 2, false, ::iNop),
|
Instruction(0x82, "nop", AddrMode.Imm, 2, ::iNop),
|
||||||
Instruction(0x83, "sax", AddrMode.IzX, 6, false, ::iSax),
|
Instruction(0x83, "sax", AddrMode.IzX, 6, ::iSax),
|
||||||
Instruction(0x84, "sty", AddrMode.Zp, 3, true, ::iSty),
|
Instruction(0x84, "sty", AddrMode.Zp, 3, ::iSty),
|
||||||
Instruction(0x85, "sta", AddrMode.Zp, 3, true, ::iSta),
|
Instruction(0x85, "sta", AddrMode.Zp, 3, ::iSta),
|
||||||
Instruction(0x86, "stx", AddrMode.Zp, 3, true, ::iStx),
|
Instruction(0x86, "stx", AddrMode.Zp, 3, ::iStx),
|
||||||
Instruction(0x87, "sax", AddrMode.Zp, 3, false, ::iSax),
|
Instruction(0x87, "sax", AddrMode.Zp, 3, ::iSax),
|
||||||
Instruction(0x88, "dey", AddrMode.Imp, 2, true, ::iDey),
|
Instruction(0x88, "dey", AddrMode.Imp, 2, ::iDey),
|
||||||
Instruction(0x89, "nop", AddrMode.Imm, 2, false, ::iNop),
|
Instruction(0x89, "nop", AddrMode.Imm, 2, ::iNop),
|
||||||
Instruction(0x8a, "txa", AddrMode.Imp, 2, true, ::iTxa),
|
Instruction(0x8a, "txa", AddrMode.Imp, 2, ::iTxa),
|
||||||
Instruction(0x8b, "xaa", AddrMode.Imm, 2, false, ::iXaa),
|
Instruction(0x8b, "xaa", AddrMode.Imm, 2, ::iXaa),
|
||||||
Instruction(0x8c, "sty", AddrMode.Abs, 4, true, ::iSty),
|
Instruction(0x8c, "sty", AddrMode.Abs, 4, ::iSty),
|
||||||
Instruction(0x8d, "sta", AddrMode.Abs, 4, true, ::iSta),
|
Instruction(0x8d, "sta", AddrMode.Abs, 4, ::iSta),
|
||||||
Instruction(0x8e, "stx", AddrMode.Abs, 4, true, ::iStx),
|
Instruction(0x8e, "stx", AddrMode.Abs, 4, ::iStx),
|
||||||
Instruction(0x8f, "sax", AddrMode.Abs, 4, true, ::iSax),
|
Instruction(0x8f, "sax", AddrMode.Abs, 4, ::iSax),
|
||||||
Instruction(0x90, "bcc", AddrMode.Rel, 2, true, ::iBcc),
|
Instruction(0x90, "bcc", AddrMode.Rel, 2, ::iBcc),
|
||||||
Instruction(0x91, "sta", AddrMode.IzY, 6, true, ::iSta),
|
Instruction(0x91, "sta", AddrMode.IzY, 6, ::iSta),
|
||||||
Instruction(0x92, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0x92, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0x93, "ahx", AddrMode.IzY, 6, false, ::iAhx),
|
Instruction(0x93, "ahx", AddrMode.IzY, 6, ::iAhx),
|
||||||
Instruction(0x94, "sty", AddrMode.ZpX, 4, true, ::iSty),
|
Instruction(0x94, "sty", AddrMode.ZpX, 4, ::iSty),
|
||||||
Instruction(0x95, "sta", AddrMode.ZpX, 4, true, ::iSta),
|
Instruction(0x95, "sta", AddrMode.ZpX, 4, ::iSta),
|
||||||
Instruction(0x96, "stx", AddrMode.ZpY, 4, true, ::iStx),
|
Instruction(0x96, "stx", AddrMode.ZpY, 4, ::iStx),
|
||||||
Instruction(0x97, "sax", AddrMode.ZpY, 4, false, ::iSax),
|
Instruction(0x97, "sax", AddrMode.ZpY, 4, ::iSax),
|
||||||
Instruction(0x98, "tya", AddrMode.Imp, 2, true, ::iTya),
|
Instruction(0x98, "tya", AddrMode.Imp, 2, ::iTya),
|
||||||
Instruction(0x99, "sta", AddrMode.AbsY, 5, true, ::iSta),
|
Instruction(0x99, "sta", AddrMode.AbsY, 5, ::iSta),
|
||||||
Instruction(0x9a, "txs", AddrMode.Imp, 2, true, ::iTxs),
|
Instruction(0x9a, "txs", AddrMode.Imp, 2, ::iTxs),
|
||||||
Instruction(0x9b, "tas", AddrMode.AbsY, 5, false, ::iTas),
|
Instruction(0x9b, "tas", AddrMode.AbsY, 5, ::iTas),
|
||||||
Instruction(0x9c, "shy", AddrMode.AbsX, 5, false, ::iShy),
|
Instruction(0x9c, "shy", AddrMode.AbsX, 5, ::iShy),
|
||||||
Instruction(0x9d, "sta", AddrMode.AbsX, 5, true, ::iSta),
|
Instruction(0x9d, "sta", AddrMode.AbsX, 5, ::iSta),
|
||||||
Instruction(0x9e, "shx", AddrMode.AbsY, 5, false, ::iShx),
|
Instruction(0x9e, "shx", AddrMode.AbsY, 5, ::iShx),
|
||||||
Instruction(0x9f, "ahx", AddrMode.AbsY, 5, false, ::iAhx),
|
Instruction(0x9f, "ahx", AddrMode.AbsY, 5, ::iAhx),
|
||||||
Instruction(0xa0, "ldy", AddrMode.Imm, 2, true, ::iLdy),
|
Instruction(0xa0, "ldy", AddrMode.Imm, 2, ::iLdy),
|
||||||
Instruction(0xa1, "lda", AddrMode.IzX, 6, true, ::iLda),
|
Instruction(0xa1, "lda", AddrMode.IzX, 6, ::iLda),
|
||||||
Instruction(0xa2, "ldx", AddrMode.Imm, 2, true, ::iLdx),
|
Instruction(0xa2, "ldx", AddrMode.Imm, 2, ::iLdx),
|
||||||
Instruction(0xa3, "lax", AddrMode.IzX, 6, false, ::iLax),
|
Instruction(0xa3, "lax", AddrMode.IzX, 6, ::iLax),
|
||||||
Instruction(0xa4, "ldy", AddrMode.Zp, 3, true, ::iLdy),
|
Instruction(0xa4, "ldy", AddrMode.Zp, 3, ::iLdy),
|
||||||
Instruction(0xa5, "lda", AddrMode.Zp, 3, true, ::iLda),
|
Instruction(0xa5, "lda", AddrMode.Zp, 3, ::iLda),
|
||||||
Instruction(0xa6, "ldx", AddrMode.Zp, 3, true, ::iLdx),
|
Instruction(0xa6, "ldx", AddrMode.Zp, 3, ::iLdx),
|
||||||
Instruction(0xa7, "lax", AddrMode.Zp, 3, false, ::iLax),
|
Instruction(0xa7, "lax", AddrMode.Zp, 3, ::iLax),
|
||||||
Instruction(0xa8, "tay", AddrMode.Imp, 2, true, ::iTay),
|
Instruction(0xa8, "tay", AddrMode.Imp, 2, ::iTay),
|
||||||
Instruction(0xa9, "lda", AddrMode.Imm, 2, true, ::iLda),
|
Instruction(0xa9, "lda", AddrMode.Imm, 2, ::iLda),
|
||||||
Instruction(0xaa, "tax", AddrMode.Imp, 2, true, ::iTax),
|
Instruction(0xaa, "tax", AddrMode.Imp, 2, ::iTax),
|
||||||
Instruction(0xab, "lax", AddrMode.Imm, 2, false, ::iLax),
|
Instruction(0xab, "lax", AddrMode.Imm, 2, ::iLax),
|
||||||
Instruction(0xac, "ldy", AddrMode.Abs, 4, true, ::iLdy),
|
Instruction(0xac, "ldy", AddrMode.Abs, 4, ::iLdy),
|
||||||
Instruction(0xad, "lda", AddrMode.Abs, 4, true, ::iLda),
|
Instruction(0xad, "lda", AddrMode.Abs, 4, ::iLda),
|
||||||
Instruction(0xae, "ldx", AddrMode.Abs, 4, true, ::iLdx),
|
Instruction(0xae, "ldx", AddrMode.Abs, 4, ::iLdx),
|
||||||
Instruction(0xaf, "lax", AddrMode.Abs, 4, false, ::iLax),
|
Instruction(0xaf, "lax", AddrMode.Abs, 4, ::iLax),
|
||||||
Instruction(0xb0, "bcs", AddrMode.Rel, 2, true, ::iBcs),
|
Instruction(0xb0, "bcs", AddrMode.Rel, 2, ::iBcs),
|
||||||
Instruction(0xb1, "lda", AddrMode.IzY, 5, true, ::iLda),
|
Instruction(0xb1, "lda", AddrMode.IzY, 5, ::iLda),
|
||||||
Instruction(0xb2, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0xb2, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0xb3, "lax", AddrMode.IzY, 5, false, ::iLax),
|
Instruction(0xb3, "lax", AddrMode.IzY, 5, ::iLax),
|
||||||
Instruction(0xb4, "ldy", AddrMode.ZpX, 4, true, ::iLdy),
|
Instruction(0xb4, "ldy", AddrMode.ZpX, 4, ::iLdy),
|
||||||
Instruction(0xb5, "lda", AddrMode.ZpX, 4, true, ::iLda),
|
Instruction(0xb5, "lda", AddrMode.ZpX, 4, ::iLda),
|
||||||
Instruction(0xb6, "ldx", AddrMode.ZpY, 4, true, ::iLdx),
|
Instruction(0xb6, "ldx", AddrMode.ZpY, 4, ::iLdx),
|
||||||
Instruction(0xb7, "lax", AddrMode.ZpY, 4, false, ::iLax),
|
Instruction(0xb7, "lax", AddrMode.ZpY, 4, ::iLax),
|
||||||
Instruction(0xb8, "clv", AddrMode.Imp, 2, true, ::iClv),
|
Instruction(0xb8, "clv", AddrMode.Imp, 2, ::iClv),
|
||||||
Instruction(0xb9, "lda", AddrMode.AbsY, 4, true, ::iLda),
|
Instruction(0xb9, "lda", AddrMode.AbsY, 4, ::iLda),
|
||||||
Instruction(0xba, "tsx", AddrMode.Imp, 2, true, ::iTsx),
|
Instruction(0xba, "tsx", AddrMode.Imp, 2, ::iTsx),
|
||||||
Instruction(0xbb, "las", AddrMode.AbsY, 4, false, ::iLas),
|
Instruction(0xbb, "las", AddrMode.AbsY, 4, ::iLas),
|
||||||
Instruction(0xbc, "ldy", AddrMode.AbsX, 4, true, ::iLdy),
|
Instruction(0xbc, "ldy", AddrMode.AbsX, 4, ::iLdy),
|
||||||
Instruction(0xbd, "lda", AddrMode.AbsX, 4, true, ::iLda),
|
Instruction(0xbd, "lda", AddrMode.AbsX, 4, ::iLda),
|
||||||
Instruction(0xbe, "ldx", AddrMode.AbsY, 4, true, ::iLdx),
|
Instruction(0xbe, "ldx", AddrMode.AbsY, 4, ::iLdx),
|
||||||
Instruction(0xbf, "lax", AddrMode.AbsY, 4, false, ::iLax),
|
Instruction(0xbf, "lax", AddrMode.AbsY, 4, ::iLax),
|
||||||
Instruction(0xc0, "cpy", AddrMode.Imm, 2, true, ::iCpy),
|
Instruction(0xc0, "cpy", AddrMode.Imm, 2, ::iCpy),
|
||||||
Instruction(0xc1, "cmp", AddrMode.IzX, 6, true, ::iCmp),
|
Instruction(0xc1, "cmp", AddrMode.IzX, 6, ::iCmp),
|
||||||
Instruction(0xc2, "nop", AddrMode.Imm, 2, false, ::iNop),
|
Instruction(0xc2, "nop", AddrMode.Imm, 2, ::iNop),
|
||||||
Instruction(0xc3, "dcp", AddrMode.IzX, 8, false, ::iDcp),
|
Instruction(0xc3, "dcp", AddrMode.IzX, 8, ::iDcp),
|
||||||
Instruction(0xc4, "cpy", AddrMode.Zp, 3, true, ::iCpy),
|
Instruction(0xc4, "cpy", AddrMode.Zp, 3, ::iCpy),
|
||||||
Instruction(0xc5, "cmp", AddrMode.Zp, 3, true, ::iCmp),
|
Instruction(0xc5, "cmp", AddrMode.Zp, 3, ::iCmp),
|
||||||
Instruction(0xc6, "dec", AddrMode.Zp, 5, true, ::iDec),
|
Instruction(0xc6, "dec", AddrMode.Zp, 5, ::iDec),
|
||||||
Instruction(0xc7, "dcp", AddrMode.Zp, 5, false, ::iDcp),
|
Instruction(0xc7, "dcp", AddrMode.Zp, 5, ::iDcp),
|
||||||
Instruction(0xc8, "iny", AddrMode.Imp, 2, true, ::iIny),
|
Instruction(0xc8, "iny", AddrMode.Imp, 2, ::iIny),
|
||||||
Instruction(0xc9, "cmp", AddrMode.Imm, 2, true, ::iCmp),
|
Instruction(0xc9, "cmp", AddrMode.Imm, 2, ::iCmp),
|
||||||
Instruction(0xca, "dex", AddrMode.Imp, 2, true, ::iDex),
|
Instruction(0xca, "dex", AddrMode.Imp, 2, ::iDex),
|
||||||
Instruction(0xcb, "axs", AddrMode.Imm, 2, false, ::iAxs),
|
Instruction(0xcb, "axs", AddrMode.Imm, 2, ::iAxs),
|
||||||
Instruction(0xcc, "cpy", AddrMode.Abs, 4, true, ::iCpy),
|
Instruction(0xcc, "cpy", AddrMode.Abs, 4, ::iCpy),
|
||||||
Instruction(0xcd, "cmp", AddrMode.Abs, 4, true, ::iCmp),
|
Instruction(0xcd, "cmp", AddrMode.Abs, 4, ::iCmp),
|
||||||
Instruction(0xce, "dec", AddrMode.Abs, 6, true, ::iDec),
|
Instruction(0xce, "dec", AddrMode.Abs, 6, ::iDec),
|
||||||
Instruction(0xcf, "dcp", AddrMode.Abs, 6, false, ::iDcp),
|
Instruction(0xcf, "dcp", AddrMode.Abs, 6, ::iDcp),
|
||||||
Instruction(0xd0, "bne", AddrMode.Rel, 2, true, ::iBne),
|
Instruction(0xd0, "bne", AddrMode.Rel, 2, ::iBne),
|
||||||
Instruction(0xd1, "cmp", AddrMode.IzY, 5, true, ::iCmp),
|
Instruction(0xd1, "cmp", AddrMode.IzY, 5, ::iCmp),
|
||||||
Instruction(0xd2, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0xd2, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0xd3, "dcp", AddrMode.IzY, 8, false, ::iDcp),
|
Instruction(0xd3, "dcp", AddrMode.IzY, 8, ::iDcp),
|
||||||
Instruction(0xd4, "nop", AddrMode.ZpX, 4, false, ::iNop),
|
Instruction(0xd4, "nop", AddrMode.ZpX, 4, ::iNop),
|
||||||
Instruction(0xd5, "cmp", AddrMode.ZpX, 4, true, ::iCmp),
|
Instruction(0xd5, "cmp", AddrMode.ZpX, 4, ::iCmp),
|
||||||
Instruction(0xd6, "dec", AddrMode.ZpX, 6, true, ::iDec),
|
Instruction(0xd6, "dec", AddrMode.ZpX, 6, ::iDec),
|
||||||
Instruction(0xd7, "dcp", AddrMode.ZpX, 6, false, ::iDcp),
|
Instruction(0xd7, "dcp", AddrMode.ZpX, 6, ::iDcp),
|
||||||
Instruction(0xd8, "cld", AddrMode.Imp, 2, true, ::iCld),
|
Instruction(0xd8, "cld", AddrMode.Imp, 2, ::iCld),
|
||||||
Instruction(0xd9, "cmp", AddrMode.AbsY, 4, true, ::iCmp),
|
Instruction(0xd9, "cmp", AddrMode.AbsY, 4, ::iCmp),
|
||||||
Instruction(0xda, "nop", AddrMode.Imp, 2, false, ::iNop),
|
Instruction(0xda, "nop", AddrMode.Imp, 2, ::iNop),
|
||||||
Instruction(0xdb, "dcp", AddrMode.AbsY, 7, false, ::iDcp),
|
Instruction(0xdb, "dcp", AddrMode.AbsY, 7, ::iDcp),
|
||||||
Instruction(0xdc, "nop", AddrMode.AbsX, 4, false, ::iNop),
|
Instruction(0xdc, "nop", AddrMode.AbsX, 4, ::iNop),
|
||||||
Instruction(0xdd, "cmp", AddrMode.AbsX, 4, true, ::iCmp),
|
Instruction(0xdd, "cmp", AddrMode.AbsX, 4, ::iCmp),
|
||||||
Instruction(0xde, "dec", AddrMode.AbsX, 7, true, ::iDec),
|
Instruction(0xde, "dec", AddrMode.AbsX, 7, ::iDec),
|
||||||
Instruction(0xdf, "dcp", AddrMode.AbsX, 7, false, ::iDcp),
|
Instruction(0xdf, "dcp", AddrMode.AbsX, 7, ::iDcp),
|
||||||
Instruction(0xe0, "cpx", AddrMode.Imm, 2, true, ::iCpx),
|
Instruction(0xe0, "cpx", AddrMode.Imm, 2, ::iCpx),
|
||||||
Instruction(0xe1, "sbc", AddrMode.IzX, 6, true, ::iSbc),
|
Instruction(0xe1, "sbc", AddrMode.IzX, 6, ::iSbc),
|
||||||
Instruction(0xe2, "nop", AddrMode.Imm, 2, false, ::iNop),
|
Instruction(0xe2, "nop", AddrMode.Imm, 2, ::iNop),
|
||||||
Instruction(0xe3, "isc", AddrMode.IzX, 8, false, ::iIsc),
|
Instruction(0xe3, "isc", AddrMode.IzX, 8, ::iIsc),
|
||||||
Instruction(0xe4, "cpx", AddrMode.Zp, 3, true, ::iCpx),
|
Instruction(0xe4, "cpx", AddrMode.Zp, 3, ::iCpx),
|
||||||
Instruction(0xe5, "sbc", AddrMode.Zp, 3, true, ::iSbc),
|
Instruction(0xe5, "sbc", AddrMode.Zp, 3, ::iSbc),
|
||||||
Instruction(0xe6, "inc", AddrMode.Zp, 5, true, ::iInc),
|
Instruction(0xe6, "inc", AddrMode.Zp, 5, ::iInc),
|
||||||
Instruction(0xe7, "isc", AddrMode.Zp, 5, false, ::iIsc),
|
Instruction(0xe7, "isc", AddrMode.Zp, 5, ::iIsc),
|
||||||
Instruction(0xe8, "inx", AddrMode.Imp, 2, true, ::iInx),
|
Instruction(0xe8, "inx", AddrMode.Imp, 2, ::iInx),
|
||||||
Instruction(0xe9, "sbc", AddrMode.Imm, 2, true, ::iSbc),
|
Instruction(0xe9, "sbc", AddrMode.Imm, 2, ::iSbc),
|
||||||
Instruction(0xea, "nop", AddrMode.Imp, 2, true, ::iNop),
|
Instruction(0xea, "nop", AddrMode.Imp, 2, ::iNop),
|
||||||
Instruction(0xeb, "sbc", AddrMode.Imm, 2, false, ::iSbc),
|
Instruction(0xeb, "sbc", AddrMode.Imm, 2, ::iSbc),
|
||||||
Instruction(0xec, "cpx", AddrMode.Abs, 4, true, ::iCpx),
|
Instruction(0xec, "cpx", AddrMode.Abs, 4, ::iCpx),
|
||||||
Instruction(0xed, "sbc", AddrMode.Abs, 4, true, ::iSbc),
|
Instruction(0xed, "sbc", AddrMode.Abs, 4, ::iSbc),
|
||||||
Instruction(0xee, "inc", AddrMode.Abs, 6, true, ::iInc),
|
Instruction(0xee, "inc", AddrMode.Abs, 6, ::iInc),
|
||||||
Instruction(0xef, "isc", AddrMode.Abs, 6, true, ::iIsc),
|
Instruction(0xef, "isc", AddrMode.Abs, 6, ::iIsc),
|
||||||
Instruction(0xf0, "beq", AddrMode.Rel, 2, true, ::iBeq),
|
Instruction(0xf0, "beq", AddrMode.Rel, 2, ::iBeq),
|
||||||
Instruction(0xf1, "sbc", AddrMode.IzY, 5, true, ::iSbc),
|
Instruction(0xf1, "sbc", AddrMode.IzY, 5, ::iSbc),
|
||||||
Instruction(0xf2, "???", AddrMode.Imp, 0, false, ::iInvalid),
|
Instruction(0xf2, "???", AddrMode.Imp, 0, ::iInvalid),
|
||||||
Instruction(0xf3, "isc", AddrMode.IzY, 8, false, ::iIsc),
|
Instruction(0xf3, "isc", AddrMode.IzY, 8, ::iIsc),
|
||||||
Instruction(0xf4, "nop", AddrMode.ZpX, 4, false, ::iNop),
|
Instruction(0xf4, "nop", AddrMode.ZpX, 4, ::iNop),
|
||||||
Instruction(0xf5, "sbc", AddrMode.ZpX, 4, true, ::iSbc),
|
Instruction(0xf5, "sbc", AddrMode.ZpX, 4, ::iSbc),
|
||||||
Instruction(0xf6, "inc", AddrMode.ZpX, 6, true, ::iInc),
|
Instruction(0xf6, "inc", AddrMode.ZpX, 6, ::iInc),
|
||||||
Instruction(0xf7, "isc", AddrMode.ZpX, 6, false, ::iIsc),
|
Instruction(0xf7, "isc", AddrMode.ZpX, 6, ::iIsc),
|
||||||
Instruction(0xf8, "sed", AddrMode.Imp, 2, true, ::iSed),
|
Instruction(0xf8, "sed", AddrMode.Imp, 2, ::iSed),
|
||||||
Instruction(0xf9, "sbc", AddrMode.AbsY, 4, true, ::iSbc),
|
Instruction(0xf9, "sbc", AddrMode.AbsY, 4, ::iSbc),
|
||||||
Instruction(0xfa, "nop", AddrMode.Imp, 2, false, ::iNop),
|
Instruction(0xfa, "nop", AddrMode.Imp, 2, ::iNop),
|
||||||
Instruction(0xfb, "isc", AddrMode.AbsY, 7, false, ::iIsc),
|
Instruction(0xfb, "isc", AddrMode.AbsY, 7, ::iIsc),
|
||||||
Instruction(0xfc, "nop", AddrMode.AbsX, 4, false, ::iNop),
|
Instruction(0xfc, "nop", AddrMode.AbsX, 4, ::iNop),
|
||||||
Instruction(0xfd, "sbc", AddrMode.AbsX, 4, true, ::iSbc),
|
Instruction(0xfd, "sbc", AddrMode.AbsX, 4, ::iSbc),
|
||||||
Instruction(0xfe, "inc", AddrMode.AbsX, 7, true, ::iInc),
|
Instruction(0xfe, "inc", AddrMode.AbsX, 7, ::iInc),
|
||||||
Instruction(0xff, "isc", AddrMode.AbsX, 7, false, ::iIsc)
|
Instruction(0xff, "isc", AddrMode.AbsX, 7, ::iIsc)
|
||||||
).toTypedArray()
|
).toTypedArray()
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import sim65.Petscii
|
|||||||
* First address = data byte (8 parallel bits)
|
* First address = data byte (8 parallel bits)
|
||||||
* Second address = control byte (bit 0 high = write byte)
|
* Second address = control byte (bit 0 high = write byte)
|
||||||
*/
|
*/
|
||||||
class Parallel(startAddress: Address, endAddress: Address) : MemMappedComponent(startAddress, endAddress) {
|
class ParallelPort(startAddress: Address, endAddress: Address) : MemMappedComponent(startAddress, endAddress) {
|
||||||
private var dataByte: UByte = 0
|
private var dataByte: UByte = 0
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -34,6 +34,4 @@ class Parallel(startAddress: Address, endAddress: Address) : MemMappedComponent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cloneMem(): Array<UByte> = listOf(dataByte, 0).toTypedArray()
|
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ package sim65.components
|
|||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class Ram(startAddress: Address, endAddress: Address): MemMappedComponent(startAddress, endAddress) {
|
class Ram(startAddress: Address, endAddress: Address): MemoryComponent(startAddress, endAddress) {
|
||||||
private val memory = ShortArray(endAddress-startAddress+1)
|
private val memory = ShortArray(endAddress-startAddress+1)
|
||||||
|
|
||||||
override operator fun get(address: Address): UByte = memory[address-startAddress]
|
override operator fun get(address: Address): UByte = memory[address-startAddress]
|
||||||
@ -11,7 +11,7 @@ class Ram(startAddress: Address, endAddress: Address): MemMappedComponent(startA
|
|||||||
memory[address-startAddress] = data
|
memory[address-startAddress] = data
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cloneMem(): Array<UByte> = memory.toTypedArray()
|
override fun cloneContents(): Array<UByte> = memory.toTypedArray()
|
||||||
|
|
||||||
override fun clock() { }
|
override fun clock() { }
|
||||||
|
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
package sim65.components
|
package sim65.components
|
||||||
|
|
||||||
class Rom(startAddress: Address, endAddress: Address, data: Array<UByte>): MemMappedComponent(startAddress, endAddress) {
|
class Rom(startAddress: Address, endAddress: Address, data: Array<UByte>? = null) : MemoryComponent(startAddress, endAddress) {
|
||||||
private val memory = ShortArray(data.size) { index -> data[index] }
|
private val memory =
|
||||||
|
if (data == null)
|
||||||
|
ShortArray(endAddress - startAddress - 1)
|
||||||
|
else
|
||||||
|
ShortArray(data.size) { index -> data[index] }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
if (data != null)
|
||||||
require(endAddress - startAddress + 1 == data.size) { "rom address range doesn't match size of data bytes" }
|
require(endAddress - startAddress + 1 == data.size) { "rom address range doesn't match size of data bytes" }
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun get(address: Address): UByte = memory[address - startAddress]
|
override operator fun get(address: Address): UByte = memory[address - startAddress]
|
||||||
override operator fun set(address: Address, data: UByte) {}
|
override operator fun set(address: Address, data: UByte) {}
|
||||||
override fun cloneMem(): Array<UByte> = memory.toTypedArray()
|
override fun cloneContents(): Array<UByte> = memory.toTypedArray()
|
||||||
override fun clock() {}
|
override fun clock() {}
|
||||||
override fun reset() {}
|
override fun reset() {}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,28 @@
|
|||||||
package sim65.components
|
package sim65.components
|
||||||
|
|
||||||
class Timer(startAddress: Address, endAddress: Address): MemMappedComponent(startAddress, endAddress) {
|
class Timer(startAddress: Address, endAddress: Address): MemMappedComponent(startAddress, endAddress) {
|
||||||
private var cycle: Long = 0
|
private var counter: Long = 0
|
||||||
|
|
||||||
init {
|
init {
|
||||||
require(endAddress - startAddress + 1 == 4) { "timer needs exactly 4 memory bytes" }
|
require(endAddress - startAddress + 1 == 4) { "timer needs exactly 4 memory bytes" }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clock() {
|
override fun clock() {
|
||||||
cycle++
|
counter++
|
||||||
if (cycle > 0xffffffff)
|
if (counter > 0xffffffff)
|
||||||
cycle = 0
|
counter = 0
|
||||||
|
println("TIMER CLOCK $counter")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reset() {
|
override fun reset() {
|
||||||
cycle = 0
|
counter = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun get(address: Address): UByte {
|
override operator fun get(address: Address): UByte {
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
TODO("timer read $address")
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun set(address: Address, data: UByte) {
|
override operator fun set(address: Address, data: UByte) {
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
TODO("timer write $address = $data")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cloneMem(): Array<UByte> = TODO("clonemem timer")
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.fail
|
||||||
import sim65.components.Bus
|
import sim65.components.Bus
|
||||||
import sim65.components.Cpu6502
|
import sim65.components.Cpu6502
|
||||||
|
import sim65.components.InstructionError
|
||||||
|
import sim65.components.Ram
|
||||||
|
import kotlin.system.measureNanoTime
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class Test6502CpuBasics {
|
class Test6502CpuBasics {
|
||||||
@ -23,4 +27,75 @@ class Test6502CpuBasics {
|
|||||||
assertEquals(0b00100100, cpu.Status.asByte())
|
assertEquals(0b00100100, cpu.Status.asByte())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCpuPerformance() {
|
||||||
|
val cpu = Cpu6502(true)
|
||||||
|
val ram = Ram(0x1000, 0x2000)
|
||||||
|
// load a simple program that loops a few instructions
|
||||||
|
for(b in listOf(0xa9, 0x63, 0xaa, 0x86, 0x22, 0x8e, 0x22, 0x22, 0x91, 0x22, 0x6d, 0x33, 0x33, 0xcd, 0x55, 0x55, 0xd0, 0xee, 0xf0, 0xec).withIndex()) {
|
||||||
|
ram[0x1000+b.index] = b.value.toShort()
|
||||||
|
}
|
||||||
|
|
||||||
|
val bus = Bus()
|
||||||
|
bus.add(cpu)
|
||||||
|
bus.add(ram)
|
||||||
|
cpu.reset()
|
||||||
|
cpu.PC = 0x1000
|
||||||
|
|
||||||
|
// warmup
|
||||||
|
while(cpu.totalCycles<1000000)
|
||||||
|
cpu.clock()
|
||||||
|
|
||||||
|
// timing
|
||||||
|
val cycles = 50000000
|
||||||
|
val duration = measureNanoTime {
|
||||||
|
while (cpu.totalCycles < cycles)
|
||||||
|
cpu.clock()
|
||||||
|
}
|
||||||
|
val seconds = duration.toDouble() / 1e9
|
||||||
|
val mhz = (cycles.toDouble() / seconds) / 1e6
|
||||||
|
println("duration $seconds sec for $cycles = $mhz Mhz")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testBCD() {
|
||||||
|
val cpu = Cpu6502(true)
|
||||||
|
val bus = Bus()
|
||||||
|
bus.add(cpu)
|
||||||
|
val ram = Ram(0, 0xffff)
|
||||||
|
ram[Cpu6502.RESET_vector] = 0x00
|
||||||
|
ram[Cpu6502.RESET_vector +1] = 0x10
|
||||||
|
ram.load("test/testfiles/bcdtest.bin", 0x1000)
|
||||||
|
bus.add(ram)
|
||||||
|
bus.reset()
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
bus.clock()
|
||||||
|
}
|
||||||
|
} catch(e: InstructionError) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ram[0x0400] ==0.toShort()) {
|
||||||
|
println("BCD TEST: OK!")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val code = ram[0x0400]
|
||||||
|
val v1 = ram[0x0401]
|
||||||
|
val v2 = ram[0x0402]
|
||||||
|
val predictedA = ram[0x00fc]
|
||||||
|
val actualA = ram[0x00fd]
|
||||||
|
val predictedF = ram[0x00fe]
|
||||||
|
val actualF = ram[0x00ff]
|
||||||
|
println("BCD TEST: FAIL!! code=${Cpu6502.hexB(code)} value1=${Cpu6502.hexB(v1)} value2=${Cpu6502.hexB(v2)}")
|
||||||
|
println(" predictedA=${Cpu6502.hexB(predictedA)}")
|
||||||
|
println(" actualA=${Cpu6502.hexB(actualA)}")
|
||||||
|
println(" predictedF=${predictedF.toString(2).padStart(8,'0')}")
|
||||||
|
println(" actualF=${actualF.toString(2).padStart(8,'0')}")
|
||||||
|
fail("BCD test failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.fail
|
||||||
import sim65.components.Bus
|
import sim65.components.Bus
|
||||||
import sim65.components.Cpu6502
|
import sim65.components.Cpu6502
|
||||||
import sim65.components.Ram
|
import sim65.components.Ram
|
||||||
import kotlin.test.assertEquals
|
import java.lang.Exception
|
||||||
|
|
||||||
class Test6502Functional {
|
class Test6502Functional {
|
||||||
|
|
||||||
|
private class SuccessfulTestResult: Exception()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFunctional() {
|
fun testFunctional() {
|
||||||
val cpu = Cpu6502(false)
|
val cpu = Cpu6502(false)
|
||||||
@ -16,14 +19,25 @@ class Test6502Functional {
|
|||||||
bus.add(ram)
|
bus.add(ram)
|
||||||
cpu.reset()
|
cpu.reset()
|
||||||
cpu.PC = 0x0400
|
cpu.PC = 0x0400
|
||||||
|
cpu.breakpoint(0x3469) { _, _ ->
|
||||||
|
// reaching this address means successful test result
|
||||||
|
if(cpu.currentOpcode==0x4c)
|
||||||
|
throw SuccessfulTestResult()
|
||||||
|
}
|
||||||
|
|
||||||
while(cpu.totalCycles < 50000000) {
|
try {
|
||||||
|
while (cpu.totalCycles < 900000000) {
|
||||||
cpu.clock()
|
cpu.clock()
|
||||||
}
|
}
|
||||||
|
} catch (sx: SuccessfulTestResult) {
|
||||||
|
println("test successful")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
cpu.printState()
|
cpu.printState()
|
||||||
val d = cpu.disassemble(ram, cpu.PC-20, cpu.PC+20)
|
val d = cpu.disassemble(ram, cpu.PC-20, cpu.PC+20)
|
||||||
println(d.joinToString ("\n"))
|
println(d.joinToString ("\n"))
|
||||||
|
fail("test failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import sim65.components.InstructionError
|
|||||||
import sim65.components.Ram
|
import sim65.components.Ram
|
||||||
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
|
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
|
||||||
|
@Disabled("this test suite takes a long time")
|
||||||
class Test6502TestSuite {
|
class Test6502TestSuite {
|
||||||
|
|
||||||
val cpu: Cpu6502 = Cpu6502(stopOnBrk = false)
|
val cpu: Cpu6502 = Cpu6502(stopOnBrk = false)
|
||||||
|
Loading…
Reference in New Issue
Block a user