1
0
mirror of https://github.com/irmen/ksim65.git synced 2024-11-15 09:05:52 +00:00

implemented banking in/out the char rom

This commit is contained in:
Irmen de Jong 2020-02-03 23:53:18 +01:00
parent 9cba058fd7
commit 5deeb50c49
4 changed files with 34 additions and 6 deletions

View File

@ -0,0 +1,29 @@
package razorvine.c64emu
import razorvine.ksim65.components.Address
import razorvine.ksim65.components.UByte
/**
* The C64's bus is a bit peculiar
* Appearance of RAM or ROM in certain adress ranges can be dynamically controlled
* via the 6510's IO port register in $00/$01
* We only implement banking in or out the character rom or I/O space at $d000-$e000 for now.
* Doing it here in the bus directly is the poor man's mmu solution, I guess
*
* TODO: mapping the RAM/ROMs in and out of the other banks in the address space (controlled by loram and hiram).
*/
class Bus6510(private val ioPort: CpuIoPort, chargenData: ByteArray): razorvine.ksim65.Bus() {
private val characterData = chargenData.map { (it.toInt() and 255).toShort() }.toShortArray()
override fun read(address: Address): UByte {
if(address in 0xd000..0xe000) {
if(!ioPort.charen) {
// character rom is enabled in this address range (instead of I/O)
return characterData[address-0xd000]
}
}
return super.read(address)
}
}

View File

@ -8,7 +8,6 @@ import razorvine.ksim65.components.UByte
/**
* The 6510's IO port located at $00/$01
* Controlling the memory layout, and cassette port (not processed at all).
* TODO: actually mapping the roms in and out of the address space. This requires some MMU type logic in the Bus class.
*/
class CpuIoPort(val cpu: Cpu6502) : MemMappedComponent(0x0000, 0x0001) {

View File

@ -29,15 +29,15 @@ class C64Machine(title: String) : IVirtualMachine {
private val basicData = romsPath.resolve("basic").toFile().readBytes()
private val kernalData = romsPath.resolve("kernal").toFile().readBytes()
override val bus = Bus()
override val cpu = Cpu6502()
val cpuIoPort = CpuIoPort(cpu)
override val bus = Bus6510(cpuIoPort, chargenData)
val ram = Ram(0x0000, 0xffff)
val vic = VicII(0xd000, 0xd3ff, cpu)
val cia1 = Cia(1, 0xdc00, 0xdcff, cpu)
val cia2 = Cia(2, 0xdd00, 0xddff, cpu)
val basicRom = Rom(0xa000, 0xbfff).also { it.load(basicData) }
val kernalRom = Rom(0xe000, 0xffff).also { it.load(kernalData) }
val cpuIoPort = CpuIoPort(cpu)
private val monitor = Monitor(bus, cpu)
private val debugWindow = DebugWindow(this)

View File

@ -12,7 +12,7 @@ import razorvine.ksim65.components.*
* 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 {
open class Bus {
private val allComponents = mutableListOf<BusComponent>()
private val memComponents = mutableListOf<MemMappedComponent>()
@ -42,7 +42,7 @@ class Bus {
* 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 {
open fun read(address: Address): UByte {
memComponents.forEach {
if (address >= it.startAddress && address <= it.endAddress) {
val data = it[address]
@ -57,7 +57,7 @@ class Bus {
* Write a data byte to the given address.
* All memory mapped components that are mapped to the address, will receive the data.
*/
fun write(address: Address, data: UByte) {
open fun write(address: Address, data: UByte) {
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