diff --git a/src/main/kotlin/razorvine/c64emu/Cia.kt b/src/main/kotlin/razorvine/c64emu/Cia.kt index c632787..b0f9f23 100644 --- a/src/main/kotlin/razorvine/c64emu/Cia.kt +++ b/src/main/kotlin/razorvine/c64emu/Cia.kt @@ -54,6 +54,7 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address) : MemMapp } } + private var totalCycles = 0 private var tod = TimeOfDay() private var timerAset = 0 private var timerBset = 0 @@ -69,7 +70,13 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address) : MemMapp } override fun clock() { - tod.update() + totalCycles++ + + if(totalCycles % 20000 == 0) { + // TOD resolution is 0.1 second, no need to update it in every cycle + tod.update() + } + if(ramBuffer[0x0e].toInt() and 1 != 0) { timerAactual-- if(timerAactual<0) @@ -232,19 +239,9 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address) : MemMapp tod.start() (tod.tenths and 0x0f).toShort() } - 0x09 -> { - toBCD(tod.seconds) - } - 0x0a -> { - toBCD(tod.minutes) - } - 0x0b -> { - val hours = toBCD(tod.hours) - if (tod.hours >= 12) - (hours.toInt() or 0x10000000).toShort() - else - hours - } + 0x09 -> toBCD(tod.seconds) + 0x0a -> toBCD(tod.minutes) + 0x0b -> toBCD(tod.hours) else -> ramBuffer[register] } } @@ -301,8 +298,6 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address) : MemMapp 0x0b -> { tod.stop() tod.hours = fromBCD(data) - if (data >= 12) - tod.hours = tod.hours or 0b10000000 } // the timer A and B control registers are simply provided by the rambuffer for now. } @@ -323,7 +318,7 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address) : MemMapp } // to avoid some 'stuck' keys, if we receive a shift/control/alt RELEASE, we wipe the keyboard buffer - // (this can happen becase we're changing the keycode for some pressed keys below, + // (this can happen because we're changing the keycode for some pressed keys below, // and a released key doesn't always match the pressed keycode anymore then) if (event.id == KeyEvent.KEY_RELEASED && event.keyCode in listOf( KeyEvent.VK_SHIFT, diff --git a/src/main/kotlin/razorvine/c64emu/GUI.kt b/src/main/kotlin/razorvine/c64emu/GUI.kt index 9442962..9fbed43 100644 --- a/src/main/kotlin/razorvine/c64emu/GUI.kt +++ b/src/main/kotlin/razorvine/c64emu/GUI.kt @@ -43,7 +43,6 @@ object ScreenDefs { private class BitmapScreenPanel(val chargenData: ByteArray, val ram: MemoryComponent) : JPanel() { - private val fullscreenImage: VolatileImage private val fullscreenG2d: Graphics2D private val normalCharacters = loadCharacters(false) @@ -183,9 +182,9 @@ class MainC64Window( requestFocusInWindow() } - fun start() { - // repaint the screen's back buffer ~60 times per second - val repaintTimer = Timer(1000 / 60) { + fun start(updateRate: Int) { + // repaint the screen's back buffer + val repaintTimer = Timer(1000 / updateRate) { repaint() } repaintTimer.initialDelay = 0 diff --git a/src/main/kotlin/razorvine/c64emu/c64Main.kt b/src/main/kotlin/razorvine/c64emu/c64Main.kt index e3bbb01..e780b5a 100644 --- a/src/main/kotlin/razorvine/c64emu/c64Main.kt +++ b/src/main/kotlin/razorvine/c64emu/c64Main.kt @@ -59,7 +59,7 @@ class C64Machine(title: String) : IVirtualMachine { debugWindow.setLocation(hostDisplay.location.x + hostDisplay.width, hostDisplay.location.y) debugWindow.isVisible = true hostDisplay.isVisible = true - hostDisplay.start() + hostDisplay.start(30) } fun breakpointKernelLoad(cpu: Cpu6502, pc: Address): Cpu6502.BreakpointResultAction { diff --git a/src/main/kotlin/razorvine/examplemachines/GUI.kt b/src/main/kotlin/razorvine/examplemachines/GUI.kt index 6e6d579..4ab0643 100644 --- a/src/main/kotlin/razorvine/examplemachines/GUI.kt +++ b/src/main/kotlin/razorvine/examplemachines/GUI.kt @@ -382,10 +382,10 @@ class MainWindow(title: String) : JFrame(title), KeyListener, MouseInputListener requestFocusInWindow() } - fun start() { - // repaint the screen's back buffer ~60 times per second + fun start(updateRate: Int) { + // repaint the screen's back buffer var cursorBlink = 0L - val repaintTimer = javax.swing.Timer(1000 / 60) { + val repaintTimer = javax.swing.Timer(1000 / updateRate) { repaint() if(it.`when` - cursorBlink > 200L) { cursorBlink = it.`when` diff --git a/src/main/kotlin/razorvine/examplemachines/ehBasicMain.kt b/src/main/kotlin/razorvine/examplemachines/ehBasicMain.kt index a274cd7..b73f1d2 100644 --- a/src/main/kotlin/razorvine/examplemachines/ehBasicMain.kt +++ b/src/main/kotlin/razorvine/examplemachines/ehBasicMain.kt @@ -37,7 +37,7 @@ class EhBasicMachine(title: String) { bus.reset() hostDisplay.isVisible = true - hostDisplay.start() + hostDisplay.start(30) } private fun step() { diff --git a/src/main/kotlin/razorvine/examplemachines/machineMain.kt b/src/main/kotlin/razorvine/examplemachines/machineMain.kt index c783ffe..556b53f 100644 --- a/src/main/kotlin/razorvine/examplemachines/machineMain.kt +++ b/src/main/kotlin/razorvine/examplemachines/machineMain.kt @@ -49,7 +49,7 @@ class VirtualMachine(title: String) : IVirtualMachine { debugWindow.isVisible = true hostDisplay.isVisible = true - hostDisplay.start() + hostDisplay.start(30) } override fun getZeroAndStackPages(): Array = ram.getPages(0, 2) diff --git a/src/main/kotlin/razorvine/ksim65/Cpu6502.kt b/src/main/kotlin/razorvine/ksim65/Cpu6502.kt index 9de1110..4bbfb7a 100644 --- a/src/main/kotlin/razorvine/ksim65/Cpu6502.kt +++ b/src/main/kotlin/razorvine/ksim65/Cpu6502.kt @@ -333,7 +333,8 @@ open class Cpu6502 : BusComponent() { } /** - * Process once clock cycle in the cpu + * Process once clock cycle in the cpu. + * Use this if goal is cycle-perfect emulation. */ override fun clock() { if (instrCycles == 0) { @@ -395,12 +396,15 @@ open class Cpu6502 : BusComponent() { } /** - * Execute one single complete instruction + * Execute one single complete instruction. + * Use this when the goal is emulation performance and not a cycle perfect system. */ open fun step() { - while (instrCycles > 0) clock() + totalCycles += instrCycles + instrCycles = 0 clock() - while (instrCycles > 0) clock() + totalCycles += instrCycles + instrCycles = 0 } fun nmi() { diff --git a/src/main/kotlin/razorvine/ksim65/Cpu65C02.kt b/src/main/kotlin/razorvine/ksim65/Cpu65C02.kt index 68c2c9d..bd34d82 100644 --- a/src/main/kotlin/razorvine/ksim65/Cpu65C02.kt +++ b/src/main/kotlin/razorvine/ksim65/Cpu65C02.kt @@ -26,6 +26,7 @@ class Cpu65C02 : Cpu6502() { /** * Process once clock cycle in the cpu + * Use this if goal is cycle-perfect emulation. */ override fun clock() { when (waiting) { @@ -47,18 +48,16 @@ class Cpu65C02 : Cpu6502() { } /** - * Execute one single complete instruction + * Execute one single complete instruction. + * Use this when the goal is emulation performance and not a cycle perfect system. */ override fun step() { + totalCycles += instrCycles + instrCycles = 0 if (waiting == Wait.Normal) { - while (instrCycles > 0) clock() clock() - if (waiting == Wait.Normal) - while (instrCycles > 0) clock() - else { - totalCycles += instrCycles - instrCycles = 0 - } + totalCycles += instrCycles + instrCycles = 0 } }