1
0
mirror of https://github.com/irmen/ksim65.git synced 2024-06-09 11:29:30 +00:00

tweak 6510 io port and fix overflow bug in TOD

This commit is contained in:
Irmen de Jong 2020-02-20 00:01:54 +01:00
parent 99d8f5cd97
commit 35cbe4e3ca
5 changed files with 144 additions and 32 deletions

View File

@ -52,6 +52,8 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address, val cpu:
if (updatedAt != latchedTime) { if (updatedAt != latchedTime) {
updatedAt = latchedTime updatedAt = latchedTime
var elapsedSeconds = (latchedTime.toDouble()-startedAt)/1000.0+userStartTime var elapsedSeconds = (latchedTime.toDouble()-startedAt)/1000.0+userStartTime
if(elapsedSeconds>60*3600)
elapsedSeconds=0.0 // TOD counds max 60 hours
hours = (elapsedSeconds/3600).toInt() hours = (elapsedSeconds/3600).toInt()
elapsedSeconds -= hours*3600 elapsedSeconds -= hours*3600
minutes = (elapsedSeconds/60).toInt() minutes = (elapsedSeconds/60).toInt()

View File

@ -1,6 +1,5 @@
package razorvine.c64emu package razorvine.c64emu
import razorvine.ksim65.Cpu6502
import razorvine.ksim65.components.MemMappedComponent import razorvine.ksim65.components.MemMappedComponent
import razorvine.ksim65.components.UByte 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). * 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 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 var loram: Boolean = false // Bit 0: LORAM signal. Selects ROM or RAM at 40960 ($A000). 1=BASIC, 0=RAM
private set private set
var hiram: Boolean = false // Bit 1: HIRAM signal. Selects ROM or RAM at 57344 ($E000). 1=Kernal, 0=RAM 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 { override operator fun get(offset: Int): UByte {
return if(offset==0) dataDirections.toShort() else { return if(offset==0) {
(ioPort or dataDirections.inv() and 0b00111111).toShort() 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() dataDirections = data.toInt()
determineRoms() determineRoms()
} else { } else {
ioPort = data.toInt() ioPort = (ioPort and dataDirections.inv()) or (data.toInt() and dataDirections)
determineRoms() determineRoms()
} }
} }
private fun determineRoms() { private fun determineRoms() {
if (dataDirections and 0b00000001 != 0) loram = ioPort and 0b00000001 != 0 loram = ioPort and 0b00000001 != 0
if (dataDirections and 0b00000010 != 0) hiram = ioPort and 0b00000010 != 0 hiram = ioPort and 0b00000010 != 0
if (dataDirections and 0b00000100 != 0) charen = ioPort and 0b00000100 != 0 charen = ioPort and 0b00000100 != 0
} }
} }

View File

@ -39,12 +39,12 @@ class C64Machine(title: String) : IVirtualMachine {
it.load(kernalData) it.load(kernalData)
} }
override val cpu = Cpu6502() val cpuIoPort = CpuIoPort()
val cpuIoPort = CpuIoPort(cpu)
// This bus contains "mmu" logic to control the memory bank switching controlled by the 6510's io port in $00/$01. // 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. // 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 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. // the C64 has 64KB of RAM. Some of it may be banked out and replaced by ROM.
val ram = Ram(0x0000, 0xffff) val ram = Ram(0x0000, 0xffff)

View File

@ -9,14 +9,11 @@ import razorvine.ksim65.components.Ram
import razorvine.ksim65.components.Rom import razorvine.ksim65.components.Rom
import kotlin.test.* import kotlin.test.*
// TODO: run these tests by using the C64 machine emulation components
@Execution(ExecutionMode.CONCURRENT) @Execution(ExecutionMode.CONCURRENT)
@Disabled("need to fix more c64 specific stuff here")
class Test6502TestSuiteC64Specific { class Test6502TestSuiteC64Specific {
val cpu: Cpu6502 = Cpu6502() val cpu: Cpu6502 = Cpu6502()
val ioPort = CpuIoPort(cpu) val ioPort = CpuIoPort()
val ram = Ram(0, 0xffff) val ram = Ram(0, 0xffff)
val bus: Bus val bus: Bus
val kernalStubs = C64KernalStubs(ram) val kernalStubs = C64KernalStubs(ram)
@ -108,106 +105,136 @@ class Test6502TestSuiteC64Specific {
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia1pb6() { fun testCia1pb6() {
runTest("cia1pb6") runTest("cia1pb6")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia1pb7() { fun testCia1pb7() {
runTest("cia1pb7") runTest("cia1pb7")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia1ta() { fun testCia1ta() {
runTest("cia1ta") runTest("cia1ta")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia1tab() { fun testCia1tab() {
runTest("cia1tab") runTest("cia1tab")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia1tb() { fun testCia1tb() {
runTest("cia1tb") runTest("cia1tb")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia1tb123() { fun testCia1tb123() {
runTest("cia1tb123") runTest("cia1tb123")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia2pb6() { fun testCia2pb6() {
runTest("cia2pb6") runTest("cia2pb6")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia2pb7() { fun testCia2pb7() {
runTest("cia2pb7") runTest("cia2pb7")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia2ta() { fun testCia2ta() {
runTest("cia2ta") runTest("cia2ta")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia2tb() { fun testCia2tb() {
runTest("cia2tb") runTest("cia2tb")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCia2tb123() { fun testCia2tb123() {
runTest("cia2tb123") runTest("cia2tb123")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCntdef() { fun testCntdef() {
runTest("cntdef") runTest("cntdef")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testCnto2() { 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") runTest("cnto2")
} }
@Test @Test
fun testCpuport() { @Disabled("tests c64 specific hardware")
runTest("cpuport")
}
@Test
fun testCputiming() { fun testCputiming() {
runTest("cputiming") runTest("cputiming") // TODO fix this test once the cycle times are correct?
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testFlipos() { fun testFlipos() {
runTest("flipos") runTest("flipos")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testIcr01() { fun testIcr01() {
runTest("icr01") runTest("icr01")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testImr() { fun testImr() {
runTest("imr") runTest("imr")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testIrq() { fun testIrq() {
runTest("irq") runTest("irq")
} }
@Test @Test
@Disabled("tests c64 specific hardware")
fun testLoadth() { fun testLoadth() {
runTest("loadth") 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 @Test
fun testMmu() { fun testMmu() {
runTest("mmu") runTest("mmu")
@ -217,14 +244,4 @@ class Test6502TestSuiteC64Specific {
fun testMmufetch() { fun testMmufetch() {
runTest("mmufetch") runTest("mmufetch")
} }
@Test
fun testNmi() {
runTest("nmi")
}
@Test
fun testOneshot() {
runTest("oneshot")
}
} }

View File

@ -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)
}
}