mirror of https://github.com/irmen/ksim65.git
112 lines
5.5 KiB
Kotlin
112 lines
5.5 KiB
Kotlin
package razorvine.ksim65
|
|
|
|
import kotlin.math.max
|
|
|
|
class Monitor(val bus: Bus, val cpu: Cpu6502) {
|
|
|
|
private val disassembler = Disassembler(cpu)
|
|
|
|
fun command(command: String): IVirtualMachine.MonitorCmdResult {
|
|
if (command.isEmpty()) return IVirtualMachine.MonitorCmdResult("", "", false)
|
|
|
|
return when (command[0]) {
|
|
'h', '?' -> {
|
|
val text = "h)elp m)emory i)nspect f)ill p)oke g)o a)ssemble d)isassemble\n$ # % for hex, dec, bin number"
|
|
IVirtualMachine.MonitorCmdResult(text, "", false)
|
|
}
|
|
'f' -> {
|
|
val parts = command.substring(1).trim().split(' ')
|
|
if (parts.size != 3) IVirtualMachine.MonitorCmdResult("?syntax error", command, false)
|
|
else {
|
|
val start = Assembler.parseNumber(parts[0])
|
|
val end = Assembler.parseNumber(parts[1])
|
|
val value = Assembler.parseNumber(parts[2]).toShort()
|
|
for (addr in start..end) {
|
|
bus.write(addr, value)
|
|
}
|
|
IVirtualMachine.MonitorCmdResult("ok", "", true)
|
|
}
|
|
}
|
|
'm' -> {
|
|
val addresses = command.substring(1).trim().split(' ')
|
|
val start = Assembler.parseNumber(addresses[0])
|
|
val end = if (addresses.size > 1) Assembler.parseNumber(addresses[1]) else start+1
|
|
val result = mutableListOf<String>()
|
|
for (addr in start until end step 16) {
|
|
result.add("m$${hexW(addr)} "+(0..15).joinToString(" ") { hexB(bus.read(addr+it)) }+" "+(0..15).joinToString("") {
|
|
val chr = bus.read(addr+it).toInt().toChar()
|
|
if (chr.isLetterOrDigit()) chr.toString()
|
|
else "."
|
|
})
|
|
}
|
|
IVirtualMachine.MonitorCmdResult(result.joinToString("\n"), "", true)
|
|
}
|
|
'p' -> {
|
|
val numbers = command.substring(1).trim().split(' ')
|
|
val address = Assembler.parseNumber(numbers[0])
|
|
val values = numbers.drop(1).map { Assembler.parseNumber(it) }
|
|
values.forEachIndexed { index, i -> bus.write(address+index, i.toShort()) }
|
|
IVirtualMachine.MonitorCmdResult("ok", "", true)
|
|
}
|
|
'i' -> {
|
|
val addresses = command.substring(1).trim().split(' ')
|
|
val start = Assembler.parseNumber(addresses[0])
|
|
val end = if (addresses.size > 1) Assembler.parseNumber(addresses[1]) else start+1
|
|
val result = mutableListOf<String>()
|
|
for (addr in start until end step 64) {
|
|
result.add("i$${hexW(addr)} "+(0..63).joinToString("") {
|
|
val chr = bus.read(addr+it).toInt().toChar()
|
|
if (chr.isLetterOrDigit()) chr.toString()
|
|
else "."
|
|
})
|
|
}
|
|
IVirtualMachine.MonitorCmdResult(result.joinToString("\n"), "", true)
|
|
}
|
|
'$' -> {
|
|
val number = Assembler.parseNumber(command)
|
|
val output = "$${hexW(number)} #$number %${number.toString(2)}"
|
|
IVirtualMachine.MonitorCmdResult(output, "", true)
|
|
}
|
|
'#' -> {
|
|
val number = Assembler.parseNumber(command)
|
|
val output = "$${hexW(number)} #$number %${number.toString(2)}"
|
|
IVirtualMachine.MonitorCmdResult(output, "", true)
|
|
}
|
|
'%' -> {
|
|
val number = Assembler.parseNumber(command)
|
|
val output = "$${hexW(number)} #$number %${number.toString(2)}"
|
|
IVirtualMachine.MonitorCmdResult(output, "", true)
|
|
}
|
|
'g' -> {
|
|
val address = Assembler.parseNumber(command.substring(1))
|
|
cpu.regPC = address
|
|
IVirtualMachine.MonitorCmdResult("", "", true)
|
|
}
|
|
'a' -> {
|
|
val parts = command.substring(1).trim().split(' ')
|
|
val address = if(parts.size>=2) Assembler.parseNumber(parts[0]) else 0
|
|
val assembler = Assembler(cpu, bus.memoryComponentFor(address), address)
|
|
val result = assembler.assemble(command.substring(1).trimStart())
|
|
if(result.success) {
|
|
val memory = (result.startAddress..result.startAddress+result.numBytes).map { bus[it] }.toTypedArray()
|
|
val d = disassembler.disassembleOneInstruction(memory, 0, result.startAddress)
|
|
IVirtualMachine.MonitorCmdResult(d.first, "a$${hexW(result.startAddress+result.numBytes)} ", false)
|
|
}
|
|
else
|
|
IVirtualMachine.MonitorCmdResult(result.error, command, false)
|
|
}
|
|
'd' -> {
|
|
val addresses = command.substring(1).trim().split(' ')
|
|
val start = Assembler.parseNumber(addresses[0])
|
|
val end = if (addresses.size > 1) Assembler.parseNumber(addresses[1]) else start
|
|
val memory = (start .. max(0xffff, end+3)).map {bus[it]}.toTypedArray()
|
|
val disassem = disassembler.disassemble(memory, 0 .. end-start, start)
|
|
IVirtualMachine.MonitorCmdResult(disassem.first.joinToString("\n") { "d$it" }, "d$${hexW(disassem.second)}", false)
|
|
}
|
|
else -> {
|
|
IVirtualMachine.MonitorCmdResult("?unknown command", "", true)
|
|
}
|
|
}
|
|
}
|
|
}
|