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

code style tweaks

This commit is contained in:
Irmen de Jong 2019-09-23 22:09:00 +02:00
parent fce84a6881
commit bb4819c6d0
5 changed files with 48 additions and 61 deletions

View File

@ -230,6 +230,14 @@ class MainC64Window(title: String, chargenData: ByteArray, val ram: MemoryCompon
repaintTimer.start()
}
/**
* Map a key to the corresponding PETSCII character,
* that is inserted directly into the C64's character buffer.
* This avoids having to deal with the 'real' keyboard matrix,
* but it can't map keys like RUN/STOP and RESTORE properly.
*
* TODO: replace this by the real keyboard matrix including RUN/STOP and RESTORE handling.
*/
private fun keyEventToPetscii(ke: KeyEvent): UByte {
if(ke.isActionKey) {
// function keys, cursor keys etc.

View File

@ -26,6 +26,7 @@ class C64Machine(title: String) : IVirtualMachine {
val vic = VicII(0xd000, 0xd3ff)
val basicRom = Rom(0xa000, 0xbfff).also { it.load(basicData) }
val kernalRom = Rom(0xe000, 0xffff).also { it.load(kernalData) }
// TODO: implement the two CIAs to add timer and joystick support, and the keyboard matrix.
private val debugWindow = DebugWindow(this)
private val hostDisplay = MainC64Window(title, chargenData, ram)

View File

@ -8,49 +8,45 @@ import razorvine.ksim65.components.*
*
* It distributes reset and clock signals to every connected component.
* Data bytes can be read from the bus or written to the bus. It's distributed to the corresponding component(s).
*
* NOTE: currently the bus address mapping is STATIC: there is no possibility for Bank-switching.
* (such as what the C-64 has; the ability to swap ROMs in and out of the address space).
*/
class Bus {
private val components = mutableListOf<BusComponent>()
private val allComponents = mutableListOf<BusComponent>()
private val memComponents = mutableListOf<MemMappedComponent>()
fun reset() {
components.forEach { it.reset() }
memComponents.forEach { it.reset() }
}
fun reset() = allComponents.forEach { it.reset() }
fun clock() = allComponents.forEach { it.clock() }
fun clock() {
components.forEach { it.clock() }
memComponents.forEach { it.clock() }
}
operator fun plusAssign(memcomponent: MemMappedComponent) = add(memcomponent)
operator fun plusAssign(memComponent: MemMappedComponent) = add(memComponent)
operator fun plusAssign(component: BusComponent) = add(component)
operator fun get(address: Address): UByte = read(address)
operator fun set(address: Address, data: UByte) = write(address, data)
fun add(component: BusComponent) {
components.add(component)
allComponents.add(component)
component.bus = this
}
fun add(component: MemMappedComponent) {
memComponents.add(component)
component.bus = this
fun add(memComponent: MemMappedComponent) {
memComponents.add(memComponent)
allComponents.add(memComponent)
memComponent.bus = this
}
/**
* Read a data byte at the given address.
* The first memory mapped component that listens to that address, will respond.
* The first registered memory mapped component that listens to that address, will respond.
* If no component is available, some CPUs generate a BUS ERROR but we return 0xff instead.
*/
fun read(address: Address): UByte {
memComponents.forEach {
if (address >= it.startAddress && address <= it.endAddress) {
val data = it[address]
require(data in 0..255) {
"data must be a byte 0..255"
}
require(data in 0..255) { "data at address $address must be a byte 0..255" }
return data
}
}
@ -59,20 +55,16 @@ class Bus {
/**
* Write a data byte to the given address.
* Any memory mapped component that listens to the address, will receive the data.
* All memory mapped components that are mapped to the address, will receive the data.
*/
fun write(address: Address, data: UByte) {
require(data in 0..255) {
"data must be a byte 0..255"
}
require(data in 0..255) { "data written to address $address must be a byte 0..255" }
memComponents.forEach {
if (address >= it.startAddress && address <= it.endAddress)
it[address] = data
}
}
fun memoryComponentFor(address: Address): MemoryComponent =
memComponents.first {
it is MemoryComponent && address >= it.startAddress && address <= it.endAddress
} as MemoryComponent
fun memoryComponentFor(address: Address) =
memComponents.first { it is MemoryComponent && address >= it.startAddress && address <= it.endAddress } as MemoryComponent
}

View File

@ -189,26 +189,22 @@ open class Cpu6502(private val stopOnBrk: Boolean = false) : BusComponent() {
val spacing3 = " "
val location = address-baseAddress
val byte = memory[location]
var line = "\$${hexW(location+baseAddress)} ${hexB(byte)} "
val line = "\$${hexW(location+baseAddress)} ${hexB(byte)} "
val opcode = instructions[byte.toInt()]
return when (opcode.mode) {
AddrMode.Acc -> {
line += "$spacing1 ${opcode.mnemonic} a"
Pair(line, 1)
Pair(line + "$spacing1 ${opcode.mnemonic} a", 1)
}
AddrMode.Imp -> {
line += "$spacing1 ${opcode.mnemonic}"
Pair(line, 1)
Pair(line + "$spacing1 ${opcode.mnemonic}", 1)
}
AddrMode.Imm -> {
val value = memory[location+1]
line += "${hexB(value)} $spacing2 ${opcode.mnemonic} #\$${hexB(value)}"
Pair(line, 2)
Pair(line + "${hexB(value)} $spacing2 ${opcode.mnemonic} #\$${hexB(value)}", 2)
}
AddrMode.Zp -> {
val zpAddr = memory[location+1]
line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB(zpAddr)}"
Pair(line, 2)
Pair(line + "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB(zpAddr)}", 2)
}
AddrMode.Zpr -> {
// addressing mode used by the 65C02, put here for convenience
@ -219,32 +215,27 @@ open class Cpu6502(private val stopOnBrk: Boolean = false) : BusComponent() {
location + 3 + rel + baseAddress
else
location + 3 - (256 - rel) + baseAddress
line += "${hexB(zpAddr)} ${hexB(rel)} $spacing3 ${opcode.mnemonic} \$${hexB(zpAddr)}, \$${hexW(target, true)}"
Pair(line, 3)
Pair(line + "${hexB(zpAddr)} ${hexB(rel)} $spacing3 ${opcode.mnemonic} \$${hexB(zpAddr)}, \$${hexW(target, true)}", 3)
}
AddrMode.Izp -> {
// addressing mode used by the 65C02, put here for convenience
val zpAddr = memory[location+1]
line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$(${hexB(zpAddr)})"
Pair(line, 2)
Pair(line + "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$(${hexB(zpAddr)})", 2)
}
AddrMode.IaX -> {
// addressing mode used by the 65C02, put here for convenience
val lo = memory[location+1]
val hi = memory[location+2]
val absAddr = lo.toInt() or (hi.toInt() shl 8)
line += "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} \$(${hexW(absAddr)},x)"
Pair(line, 3)
Pair(line + "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} \$(${hexW(absAddr)},x)", 3)
}
AddrMode.ZpX -> {
val zpAddr = memory[location+1]
line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB(zpAddr)},x"
Pair(line, 2)
Pair(line + "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB(zpAddr)},x", 2)
}
AddrMode.ZpY -> {
val zpAddr = memory[location+1]
line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB(zpAddr)},y"
Pair(line, 2)
Pair(line + "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB(zpAddr)},y", 2)
}
AddrMode.Rel -> {
val rel = memory[location+1]
@ -253,46 +244,39 @@ open class Cpu6502(private val stopOnBrk: Boolean = false) : BusComponent() {
location + 2 + rel + baseAddress
else
location + 2 - (256 - rel) + baseAddress
line += "${hexB(rel)} $spacing2 ${opcode.mnemonic} \$${hexW(target, true)}"
Pair(line, 2)
Pair(line + "${hexB(rel)} $spacing2 ${opcode.mnemonic} \$${hexW(target, true)}", 2)
}
AddrMode.Abs -> {
val lo = memory[location+1]
val hi = memory[location+2]
val absAddr = lo.toInt() or (hi.toInt() shl 8)
line += "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)}"
Pair(line, 3)
Pair(line + "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)}", 3)
}
AddrMode.AbsX -> {
val lo = memory[location+1]
val hi = memory[location+2]
val absAddr = lo.toInt() or (hi.toInt() shl 8)
line += "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)},x"
Pair(line, 3)
Pair(line + "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)},x", 3)
}
AddrMode.AbsY -> {
val lo = memory[location+1]
val hi = memory[location+2]
val absAddr = lo.toInt() or (hi.toInt() shl 8)
line += "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)},y"
Pair(line, 3)
Pair(line + "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)},y", 3)
}
AddrMode.Ind -> {
val lo = memory[location+1]
val hi = memory[location+2]
val indirectAddr = lo.toInt() or (hi.toInt() shl 8)
line += "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} (\$${hexW(indirectAddr)})"
Pair(line, 3)
Pair(line + "${hexB(lo)} ${hexB(hi)} $spacing3 ${opcode.mnemonic} (\$${hexW(indirectAddr)})", 3)
}
AddrMode.IzX -> {
val zpAddr = memory[location+1]
line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} (\$${hexB(zpAddr)},x)"
Pair(line, 2)
Pair(line + "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} (\$${hexB(zpAddr)},x)", 2)
}
AddrMode.IzY -> {
val zpAddr = memory[location+1]
line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} (\$${hexB(zpAddr)}),y"
Pair(line, 2)
Pair(line + "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} (\$${hexB(zpAddr)}),y", 2)
}
}
}

View File

@ -5,7 +5,7 @@ import razorvine.ksim65.IHostInterface
import kotlin.math.min
/**
* Text mode and graphics (bitmap) mode display.
* Monochrome Text mode and graphics (bitmap) mode display.
* Note that the character matrix and pixel matrix are NOT memory mapped,
* this display device is controlled by sending char/pixel commands to it.
* Also, the blinking cursor is 'hardware controlled' (by the host display),
@ -53,6 +53,8 @@ class Display(
override fun clock() {
// if the system clock is synced to the display refresh,
// you *could* add a Vertical Blank interrupt here.
// It's usually better to rely on a (real time) timer instead for that,
// to avoid having the Vertical blank tied to the simulation speed
}
override fun reset() {