Files
mtmc-web/src/jvmMain/kotlin/mtmc/emulator/MTMCClock.kt

72 lines
1.8 KiB
Kotlin

package mtmc.emulator
import mtmc.emulator.MonTanaMiniComputer.ComputerStatus
import kotlin.math.max
/**
*
* @author jbanes
*/
class MTMCClock
(private val computer: MonTanaMiniComputer) {
fun run() {
var instructions: Long = 0
var ips: Long = 0
var expected: Long = 0
var virtual: Long = 0
var startTime = System.currentTimeMillis()
var deltaStart: Long
var delta: Long
var speed: Long = 0
var pulse: Long
var ms: Long = 10
while (computer.getStatus() == ComputerStatus.EXECUTING) {
speed = max(computer.speed, 0).toLong()
pulse = (if (speed <= 0) 1000000 else max(speed / 100, 1))
ms = (if (pulse < 10) 1000 / speed else 10)
deltaStart = System.currentTimeMillis()
delta = ms - (System.currentTimeMillis() - deltaStart)
/* We've lost more than a second. Recalibrate. */
if ((expected - virtual) > pulse * 100) {
startTime = deltaStart
virtual = 0
}
/* Throttles to every 10ms, but "catches up" if we're behind */
if (delta > 0 && (expected - virtual) < pulse && speed != 0L) {
try {
Thread.sleep(delta)
} catch (e: InterruptedException) {
}
}
instructions += computer.pulse(pulse)
virtual += pulse
ips = (virtual * 1000) / max(1, System.currentTimeMillis() - startTime)
expected = (System.currentTimeMillis() - startTime) * speed / 1000
}
System.err.println("Executed " + instructions + " instructions at a rate of " + ips + " ips (speed = " + speed + ")")
}
fun step() {
computer.fetchAndExecute()
computer.fetchCurrentInstruction()
computer.notifyOfStepExecution()
}
fun back() {
computer.rewind()
computer.fetchCurrentInstruction()
computer.notifyOfStepExecution()
}
}