mirror of
https://github.com/irmen/ksim65.git
synced 2025-04-07 05:37:08 +00:00
simpler cpu loop for the vms that don't require a particular speed
This commit is contained in:
parent
8cac4fbd1f
commit
009b0c5c15
src/main/kotlin/razorvine
@ -9,7 +9,6 @@ import razorvine.ksim65.components.Ram
|
||||
import razorvine.ksim65.components.Rom
|
||||
import javax.swing.ImageIcon
|
||||
import javax.swing.JOptionPane
|
||||
import kotlin.concurrent.scheduleAtFixedRate
|
||||
|
||||
/**
|
||||
* A virtual computer constructed from the various virtual components,
|
||||
@ -22,9 +21,7 @@ class EhBasicMachine(title: String) {
|
||||
val rom = Rom(0xc000, 0xffff).also { it.load(javaClass.getResourceAsStream("/ehbasic_C000.bin").readBytes()) }
|
||||
|
||||
private val hostDisplay = MainWindow(title)
|
||||
private val display =
|
||||
Display(0xd000, 0xd00a, hostDisplay, ScreenDefs.SCREEN_WIDTH_CHARS, ScreenDefs.SCREEN_HEIGHT_CHARS, ScreenDefs.SCREEN_WIDTH,
|
||||
ScreenDefs.SCREEN_HEIGHT)
|
||||
private val display = Display(0xd000, 0xd00a, hostDisplay, ScreenDefs.SCREEN_WIDTH_CHARS, ScreenDefs.SCREEN_HEIGHT_CHARS)
|
||||
private val keyboard = Keyboard(0xd400, 0xd400, hostDisplay)
|
||||
private var paused = false
|
||||
|
||||
@ -49,23 +46,22 @@ class EhBasicMachine(title: String) {
|
||||
}
|
||||
|
||||
fun start() {
|
||||
val frameRate = 60L
|
||||
val desiredCyclesPerFrame = 500_000L/frameRate // 500 khz
|
||||
val timer = java.util.Timer("cpu-cycle", true)
|
||||
timer.scheduleAtFixedRate(500, 1000/frameRate) {
|
||||
if (!paused) {
|
||||
// a simple loop to run the cpu, not targeting a specific desired clock frequency
|
||||
// (but with a small sleep to not run flat out)
|
||||
while(true) {
|
||||
if(paused) {
|
||||
Thread.sleep(200)
|
||||
} else {
|
||||
try {
|
||||
val prevCycles = cpu.totalCycles
|
||||
while (cpu.totalCycles-prevCycles < desiredCyclesPerFrame) {
|
||||
step()
|
||||
}
|
||||
repeat(400) { step() }
|
||||
} catch (rx: RuntimeException) {
|
||||
JOptionPane.showMessageDialog(hostDisplay, "Run time error: $rx", "Error during execution", JOptionPane.ERROR_MESSAGE)
|
||||
this.cancel()
|
||||
break
|
||||
} catch (ex: Error) {
|
||||
JOptionPane.showMessageDialog(hostDisplay, "Run time error: $ex", "Error during execution", JOptionPane.ERROR_MESSAGE)
|
||||
this.cancel()
|
||||
break
|
||||
}
|
||||
Thread.sleep(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import razorvine.ksim65.components.*
|
||||
import java.io.File
|
||||
import javax.swing.ImageIcon
|
||||
import javax.swing.JOptionPane
|
||||
import kotlin.concurrent.scheduleAtFixedRate
|
||||
|
||||
|
||||
/**
|
||||
@ -21,9 +20,7 @@ class VirtualMachine(title: String) : IVirtualMachine {
|
||||
private val monitor = Monitor(bus, cpu)
|
||||
private val debugWindow = DebugWindow(this)
|
||||
private val hostDisplay = MainWindow(title)
|
||||
private val display =
|
||||
Display(0xd000, 0xd00a, hostDisplay, ScreenDefs.SCREEN_WIDTH_CHARS, ScreenDefs.SCREEN_HEIGHT_CHARS, ScreenDefs.SCREEN_WIDTH,
|
||||
ScreenDefs.SCREEN_HEIGHT)
|
||||
private val display = Display(0xd000, 0xd00a, hostDisplay, ScreenDefs.SCREEN_WIDTH_CHARS, ScreenDefs.SCREEN_HEIGHT_CHARS)
|
||||
private val mouse = Mouse(0xd300, 0xd305, hostDisplay)
|
||||
private val keyboard = Keyboard(0xd400, 0xd400, hostDisplay)
|
||||
private var paused = false
|
||||
@ -75,23 +72,22 @@ class VirtualMachine(title: String) : IVirtualMachine {
|
||||
debugWindow.updateCpu(cpu, bus)
|
||||
}.start()
|
||||
|
||||
val frameRate = 60L
|
||||
val desiredCyclesPerFrame = 500_000L/frameRate // 500 khz
|
||||
val timer = java.util.Timer("cpu-cycle", true)
|
||||
timer.scheduleAtFixedRate(500, 1000/frameRate) {
|
||||
if (!paused) {
|
||||
// a simple loop to run the cpu, not targeting a specific desired clock frequency
|
||||
// (but with a small sleep to not run flat out)
|
||||
while(true) {
|
||||
if(paused) {
|
||||
Thread.sleep(200)
|
||||
} else {
|
||||
try {
|
||||
val prevCycles = cpu.totalCycles
|
||||
while (cpu.totalCycles-prevCycles < desiredCyclesPerFrame) {
|
||||
step()
|
||||
}
|
||||
repeat(400) { step() }
|
||||
} catch (rx: RuntimeException) {
|
||||
JOptionPane.showMessageDialog(hostDisplay, "Run time error: $rx", "Error during execution", JOptionPane.ERROR_MESSAGE)
|
||||
this.cancel()
|
||||
break
|
||||
} catch (ex: Error) {
|
||||
JOptionPane.showMessageDialog(hostDisplay, "Run time error: $ex", "Error during execution", JOptionPane.ERROR_MESSAGE)
|
||||
this.cancel()
|
||||
break
|
||||
}
|
||||
Thread.sleep(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ object Version {
|
||||
}
|
||||
|
||||
val copyright: String by lazy {
|
||||
"KSim65 6502 cpu simulator v$version by Irmen de Jong (irmen@razorvine.net)"+"\nThis software is free and licensed under the MIT open-source license\n"
|
||||
"KSim65 6502 cpu simulator v$version by Irmen de Jong (irmen@razorvine.net)" +
|
||||
"\nThis software is free and licensed under the MIT open-source license\n"
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,10 @@ import kotlin.math.min
|
||||
* 0a r/w character at cursor pos, updates cursor position, scrolls up if necessary
|
||||
* control chars: 8=backspace, 9=tab, 10=newline, 12=form feed (clear screen), 13=carriage return
|
||||
*/
|
||||
class Display(startAddress: Address, endAddress: Address, private val host: IHostInterface, private val charWidth: Int,
|
||||
private val charHeight: Int, private val pixelWidth: Int, private val pixelHeight: Int) :
|
||||
class Display(startAddress: Address, endAddress: Address, private val host: IHostInterface,
|
||||
private val charWidth: Int, private val charHeight: Int) :
|
||||
MemMappedComponent(startAddress, endAddress) {
|
||||
|
||||
|
||||
init {
|
||||
require(endAddress-startAddress+1 == 11) { "display needs exactly 11 memory bytes" }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user