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:
parent
9cba058fd7
commit
5deeb50c49
29
src/main/kotlin/razorvine/c64emu/Bus6510.kt
Normal file
29
src/main/kotlin/razorvine/c64emu/Bus6510.kt
Normal 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)
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user