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

simplified cpu clock timing

This commit is contained in:
Irmen de Jong 2019-10-07 23:28:04 +02:00
parent 9e15946f84
commit 3a97adafa4
4 changed files with 41 additions and 56 deletions

View File

@ -7,13 +7,18 @@ import razorvine.ksim65.components.UByte
/**
* Minimal simulation of the VIC-II graphics chip
* It only has some logic to keep track of the raster line
* This chip is the PAL version (50 Hz screen refresh, 312 vertical raster lines)
*/
class VicII(startAddress: Address, endAddress: Address): MemMappedComponent(startAddress, endAddress) {
private var ramBuffer = Array<UByte>(endAddress - startAddress + 1) { 0xff }
private var rasterIrqLine = 0
var currentRasterLine = 1
private var scanlineClocks = 0
private var interruptStatusRegisterD019 = 0
var currentRasterLine = 1
val vsync: Boolean
get() = currentRasterLine==0
val framerate = 50
val numRasterLines = 312
init {
require(endAddress - startAddress + 1 == 0x400) { "vic-II requires exactly 1024 memory bytes (64*16 mirrored)" }
@ -24,7 +29,7 @@ class VicII(startAddress: Address, endAddress: Address): MemMappedComponent(star
if(scanlineClocks == 63) {
scanlineClocks = 0
currentRasterLine++
if(currentRasterLine >= 312)
if(currentRasterLine >= numRasterLines)
currentRasterLine = 0
interruptStatusRegisterD019 = if(currentRasterLine == rasterIrqLine) {
// signal that current raster line is equal to the desired IRQ raster line

View File

@ -13,6 +13,7 @@ import java.io.IOException
import java.nio.file.Path
import java.nio.file.Paths
import javax.swing.ImageIcon
import kotlin.concurrent.scheduleAtFixedRate
/**
* The virtual representation of the Commodore-64
@ -243,28 +244,16 @@ class C64Machine(title: String) : IVirtualMachine {
debugWindow.updateCpu(cpu, bus)
}.start()
// busy waiting loop, averaging cpu speed to ~1 Mhz:
var numInstructionsteps = 600
val targetSpeedKhz = 1000
while (true) {
if (paused) {
Thread.sleep(100)
} else {
cpu.startSpeedMeasureInterval()
Thread.sleep(0, 1000)
repeat(numInstructionsteps) {
step()
if (vic.currentRasterLine == 255) {
// we force an irq here ourselves rather than fully emulating the VIC-II's raster IRQ
// or the CIA timer IRQ/NMI.
cpu.irq()
}
}
val speed = cpu.measureAvgIntervalSpeedKhz()
if (speed < targetSpeedKhz - 50)
numInstructionsteps++
else if (speed > targetSpeedKhz + 50)
numInstructionsteps--
val timer = java.util.Timer("cpu-cycle", true)
timer.scheduleAtFixedRate(0, 1000L/vic.framerate) {
if(!paused) {
// we synchronise cpu cycles to the vertical blank of the Vic chip
// this should result in ~1 Mhz cpu speed
while(vic.vsync) step()
while(!vic.vsync) step()
// we force an irq here ourselves rather than fully emulating the VIC-II's raster IRQ
// or the CIA timer IRQ/NMI.
cpu.irq()
}
}
}

View File

@ -8,6 +8,7 @@ import razorvine.ksim65.components.Keyboard
import razorvine.ksim65.components.Ram
import razorvine.ksim65.components.Rom
import javax.swing.ImageIcon
import kotlin.concurrent.scheduleAtFixedRate
/**
* A virtual computer constructed from the various virtual components,
@ -47,21 +48,15 @@ class EhBasicMachine(title: String) {
}
fun start() {
// busy waiting loop, averaging cpu speed to ~1 Mhz:
var numInstructionsteps = 600
val targetSpeedKhz = 1000
while (true) {
if (paused) {
Thread.sleep(100)
} else {
cpu.startSpeedMeasureInterval()
Thread.sleep(0, 1000)
repeat(numInstructionsteps) { step() }
val speed = cpu.measureAvgIntervalSpeedKhz()
if (speed < targetSpeedKhz - 50)
numInstructionsteps++
else if (speed > targetSpeedKhz + 50)
numInstructionsteps--
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) {
val prevCycles = cpu.totalCycles
while(cpu.totalCycles - prevCycles < desiredCyclesPerFrame) {
step()
}
}
}
}

View File

@ -1,12 +1,14 @@
package razorvine.examplemachines
import java.io.File
import javax.swing.ImageIcon
import kotlin.concurrent.scheduleAtFixedRate
import razorvine.ksim65.Bus
import razorvine.ksim65.Cpu6502
import razorvine.ksim65.IVirtualMachine
import razorvine.ksim65.Version
import razorvine.ksim65.components.*
import java.io.File
import javax.swing.ImageIcon
/**
* A virtual computer constructed from the various virtual components
@ -76,21 +78,15 @@ class VirtualMachine(title: String) : IVirtualMachine {
debugWindow.updateCpu(cpu, bus)
}.start()
// busy waiting loop, averaging cpu speed to ~1 Mhz:
var numInstructionsteps = 600
val targetSpeedKhz = 1000
while (true) {
if (paused) {
Thread.sleep(100)
} else {
cpu.startSpeedMeasureInterval()
Thread.sleep(0, 1000)
repeat(numInstructionsteps) { step() }
val speed = cpu.measureAvgIntervalSpeedKhz()
if (speed < targetSpeedKhz - 50)
numInstructionsteps++
else if (speed > targetSpeedKhz + 50)
numInstructionsteps--
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) {
val prevCycles = cpu.totalCycles
while(cpu.totalCycles - prevCycles < desiredCyclesPerFrame) {
step()
}
}
}
}