From 35cbe4e3ca539004ece8e9192256c67dfcd22227 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 20 Feb 2020 00:01:54 +0100 Subject: [PATCH] tweak 6510 io port and fix overflow bug in TOD --- src/main/kotlin/razorvine/c64emu/Cia.kt | 2 + src/main/kotlin/razorvine/c64emu/CpuIoPort.kt | 23 +++-- src/main/kotlin/razorvine/c64emu/c64Main.kt | 4 +- .../kotlin/Test6502TestSuiteC64Specific.kt | 59 ++++++++----- src/test/kotlin/TestC64Components.kt | 88 +++++++++++++++++++ 5 files changed, 144 insertions(+), 32 deletions(-) create mode 100644 src/test/kotlin/TestC64Components.kt diff --git a/src/main/kotlin/razorvine/c64emu/Cia.kt b/src/main/kotlin/razorvine/c64emu/Cia.kt index 9a7218e..ca8f8fc 100644 --- a/src/main/kotlin/razorvine/c64emu/Cia.kt +++ b/src/main/kotlin/razorvine/c64emu/Cia.kt @@ -52,6 +52,8 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address, val cpu: if (updatedAt != latchedTime) { updatedAt = latchedTime var elapsedSeconds = (latchedTime.toDouble()-startedAt)/1000.0+userStartTime + if(elapsedSeconds>60*3600) + elapsedSeconds=0.0 // TOD counds max 60 hours hours = (elapsedSeconds/3600).toInt() elapsedSeconds -= hours*3600 minutes = (elapsedSeconds/60).toInt() diff --git a/src/main/kotlin/razorvine/c64emu/CpuIoPort.kt b/src/main/kotlin/razorvine/c64emu/CpuIoPort.kt index a8b23ca..d2144c5 100644 --- a/src/main/kotlin/razorvine/c64emu/CpuIoPort.kt +++ b/src/main/kotlin/razorvine/c64emu/CpuIoPort.kt @@ -1,6 +1,5 @@ package razorvine.c64emu -import razorvine.ksim65.Cpu6502 import razorvine.ksim65.components.MemMappedComponent import razorvine.ksim65.components.UByte @@ -9,10 +8,11 @@ import razorvine.ksim65.components.UByte * Controlling the memory layout, and cassette port (not processed at all). * */ -class CpuIoPort(val cpu: Cpu6502) : MemMappedComponent(0x0000, 0x0001) { +class CpuIoPort : MemMappedComponent(0x0000, 0x0001) { private var dataDirections: Int = 0 - private var ioPort: Int = 0xff + private var ioPort: Int = 0 + var loram: Boolean = false // Bit 0: LORAM signal. Selects ROM or RAM at 40960 ($A000). 1=BASIC, 0=RAM private set var hiram: Boolean = false // Bit 1: HIRAM signal. Selects ROM or RAM at 57344 ($E000). 1=Kernal, 0=RAM @@ -28,8 +28,13 @@ class CpuIoPort(val cpu: Cpu6502) : MemMappedComponent(0x0000, 0x0001) { } override operator fun get(offset: Int): UByte { - return if(offset==0) dataDirections.toShort() else { - (ioPort or dataDirections.inv() and 0b00111111).toShort() + return if(offset==0) { + dataDirections.toShort() + } else { + if(dataDirections and 0b00100000 == 0) + (ioPort and 0b11011111).toShort() // bit 5 is low when input + else + ioPort.toShort() } } @@ -38,14 +43,14 @@ class CpuIoPort(val cpu: Cpu6502) : MemMappedComponent(0x0000, 0x0001) { dataDirections = data.toInt() determineRoms() } else { - ioPort = data.toInt() + ioPort = (ioPort and dataDirections.inv()) or (data.toInt() and dataDirections) determineRoms() } } private fun determineRoms() { - if (dataDirections and 0b00000001 != 0) loram = ioPort and 0b00000001 != 0 - if (dataDirections and 0b00000010 != 0) hiram = ioPort and 0b00000010 != 0 - if (dataDirections and 0b00000100 != 0) charen = ioPort and 0b00000100 != 0 + loram = ioPort and 0b00000001 != 0 + hiram = ioPort and 0b00000010 != 0 + charen = ioPort and 0b00000100 != 0 } } diff --git a/src/main/kotlin/razorvine/c64emu/c64Main.kt b/src/main/kotlin/razorvine/c64emu/c64Main.kt index ed1dc83..8dbb402 100644 --- a/src/main/kotlin/razorvine/c64emu/c64Main.kt +++ b/src/main/kotlin/razorvine/c64emu/c64Main.kt @@ -39,12 +39,12 @@ class C64Machine(title: String) : IVirtualMachine { it.load(kernalData) } - override val cpu = Cpu6502() - val cpuIoPort = CpuIoPort(cpu) + val cpuIoPort = CpuIoPort() // This bus contains "mmu" logic to control the memory bank switching controlled by the 6510's io port in $00/$01. // Therefore we provide it the various roms directly and not "connect" these to the bus in the default way. override val bus = Bus6510(cpuIoPort, chargenRom, basicRom, kernalRom) + override val cpu = Cpu6502() // the C64 has 64KB of RAM. Some of it may be banked out and replaced by ROM. val ram = Ram(0x0000, 0xffff) diff --git a/src/test/kotlin/Test6502TestSuiteC64Specific.kt b/src/test/kotlin/Test6502TestSuiteC64Specific.kt index c0c3844..365ec73 100644 --- a/src/test/kotlin/Test6502TestSuiteC64Specific.kt +++ b/src/test/kotlin/Test6502TestSuiteC64Specific.kt @@ -9,14 +9,11 @@ import razorvine.ksim65.components.Ram import razorvine.ksim65.components.Rom import kotlin.test.* -// TODO: run these tests by using the C64 machine emulation components - @Execution(ExecutionMode.CONCURRENT) -@Disabled("need to fix more c64 specific stuff here") class Test6502TestSuiteC64Specific { val cpu: Cpu6502 = Cpu6502() - val ioPort = CpuIoPort(cpu) + val ioPort = CpuIoPort() val ram = Ram(0, 0xffff) val bus: Bus val kernalStubs = C64KernalStubs(ram) @@ -108,106 +105,136 @@ class Test6502TestSuiteC64Specific { } @Test + @Disabled("tests c64 specific hardware") fun testCia1pb6() { runTest("cia1pb6") } @Test + @Disabled("tests c64 specific hardware") fun testCia1pb7() { runTest("cia1pb7") } @Test + @Disabled("tests c64 specific hardware") fun testCia1ta() { runTest("cia1ta") } @Test + @Disabled("tests c64 specific hardware") fun testCia1tab() { runTest("cia1tab") } @Test + @Disabled("tests c64 specific hardware") fun testCia1tb() { runTest("cia1tb") } @Test + @Disabled("tests c64 specific hardware") fun testCia1tb123() { runTest("cia1tb123") } @Test + @Disabled("tests c64 specific hardware") fun testCia2pb6() { runTest("cia2pb6") } @Test + @Disabled("tests c64 specific hardware") fun testCia2pb7() { runTest("cia2pb7") } @Test + @Disabled("tests c64 specific hardware") fun testCia2ta() { runTest("cia2ta") } @Test + @Disabled("tests c64 specific hardware") fun testCia2tb() { runTest("cia2tb") } @Test + @Disabled("tests c64 specific hardware") fun testCia2tb123() { runTest("cia2tb123") } @Test + @Disabled("tests c64 specific hardware") fun testCntdef() { runTest("cntdef") } @Test + @Disabled("tests c64 specific hardware") fun testCnto2() { - // todo fix: When the timer input is switched from o2 to CNT or from CNT back to o2, there must be a two clock delay until the switch is recognized. runTest("cnto2") } @Test - fun testCpuport() { - runTest("cpuport") - } - - @Test + @Disabled("tests c64 specific hardware") fun testCputiming() { - runTest("cputiming") + runTest("cputiming") // TODO fix this test once the cycle times are correct? } @Test + @Disabled("tests c64 specific hardware") fun testFlipos() { runTest("flipos") } @Test + @Disabled("tests c64 specific hardware") fun testIcr01() { runTest("icr01") } @Test + @Disabled("tests c64 specific hardware") fun testImr() { runTest("imr") } @Test + @Disabled("tests c64 specific hardware") fun testIrq() { runTest("irq") } @Test + @Disabled("tests c64 specific hardware") fun testLoadth() { runTest("loadth") } + @Test + @Disabled("tests c64 specific hardware") + fun testNmi() { + runTest("nmi") + } + + @Test + @Disabled("tests c64 specific hardware") + fun testOneshot() { + runTest("oneshot") + } + + @Test + fun testCpuport() { + runTest("cpuport") + } + @Test fun testMmu() { runTest("mmu") @@ -217,14 +244,4 @@ class Test6502TestSuiteC64Specific { fun testMmufetch() { runTest("mmufetch") } - - @Test - fun testNmi() { - runTest("nmi") - } - - @Test - fun testOneshot() { - runTest("oneshot") - } } diff --git a/src/test/kotlin/TestC64Components.kt b/src/test/kotlin/TestC64Components.kt new file mode 100644 index 0000000..0261eee --- /dev/null +++ b/src/test/kotlin/TestC64Components.kt @@ -0,0 +1,88 @@ +import razorvine.c64emu.CpuIoPort +import kotlin.test.* + + +class TestC64Components { + + @Test + fun testCpuIoPort() { + val io = CpuIoPort() + io.reset() + + assertEquals(0xef, io[0]) + assertEquals(0x37, io[1]) + + io[0] = 0b11111111 + io[1] = 0b11111111 + assertEquals(0b11111111,io[0]) + assertEquals(0b11111111,io[1]) + io[0] = 0 + assertEquals(0b11011111,io[1], "bit 5 (cassette motor) is drawn low if input") + io[0] = 0b11111111 + assertEquals(0b11111111,io[1], "bit 5 (cassette motor) is high if output") + + io[1] = 0x37 + io[0] = 0b00100000 + assertEquals(0b00100000, io[0]) + assertEquals(0x37, io[1]) + + io[0] = 0xff + assertEquals(0xff, io[0]) + assertEquals(0x37, io[1]) + + io[1] = 0b11110000 + assertEquals(0b11110000, io[1]) + + io[0] = 0b00100000 + io[1] = 0b01010101 + assertEquals(0b11010000, io[1]) + io[0] = 0b00100001 + assertEquals(0b11010000, io[1]) + io[1] = 0b01010101 + assertEquals(0b11010001, io[1]) + + io[0] = 0b11000011 + assertEquals(0b11010001, io[1]) + io[1] = 0b00100000 + assertEquals(0b00010000, io[1]) + io[1] = 0b11111111 + assertEquals(0b11010011, io[1]) + } + + @Test + fun testRoms() { + val io = CpuIoPort() + io.reset() + + assertTrue(io.loram) + assertTrue(io.hiram) + assertTrue(io.charen) + + io[0] = 0 + io[1] = 0 + assertTrue(io.loram) + assertTrue(io.hiram) + assertTrue(io.charen) + + io[0] = 255 + assertTrue(io.loram) + assertTrue(io.hiram) + assertTrue(io.charen) + io[1] = 0b1111110 + assertFalse(io.loram) + assertTrue(io.hiram) + assertTrue(io.charen) + io[1] = 0b1111101 + assertTrue(io.loram) + assertFalse(io.hiram) + assertTrue(io.charen) + io[1] = 0b1111011 + assertTrue(io.loram) + assertTrue(io.hiram) + assertFalse(io.charen) + + } + +} + +