mirror of
https://github.com/irmen/ksim65.git
synced 2025-04-22 11:37:45 +00:00
blinking cursor, fixed resource loading
This commit is contained in:
parent
067f134100
commit
261b6738b4
@ -10,6 +10,7 @@ plugins {
|
||||
id("org.jetbrains.dokka") version "0.9.18"
|
||||
id("com.jfrog.bintray") version "1.7.3"
|
||||
id("maven-publish")
|
||||
id("application")
|
||||
}
|
||||
|
||||
val versionProps = Properties().also {
|
||||
@ -39,6 +40,11 @@ dependencies {
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.1.0")
|
||||
}
|
||||
|
||||
application {
|
||||
applicationName = "ksim65vm"
|
||||
mainClassName = "razorvine.examplemachine.SystemMainKt"
|
||||
}
|
||||
|
||||
tasks.named<Test>("test") {
|
||||
// Enable JUnit 5 (Gradle 4.6+).
|
||||
useJUnitPlatform()
|
||||
|
@ -28,7 +28,7 @@ object ScreenDefs {
|
||||
val Characters = loadCharacters()
|
||||
|
||||
private fun loadCharacters(): Array<BufferedImage> {
|
||||
val img = ImageIO.read(javaClass.getResource("/charset/unscii8x16.png"))
|
||||
val img = ImageIO.read(javaClass.getResourceAsStream("/charset/unscii8x16.png"))
|
||||
val charactersImage = BufferedImage(img.width, img.height, BufferedImage.TYPE_INT_ARGB)
|
||||
charactersImage.createGraphics().drawImage(img, 0, 0, null)
|
||||
|
||||
@ -62,6 +62,7 @@ private class BitmapScreenPanel : JPanel() {
|
||||
private val g2d = image.graphics as Graphics2D
|
||||
private var cursorX: Int = 0
|
||||
private var cursorY: Int = 0
|
||||
private var cursorState: Boolean = false
|
||||
|
||||
init {
|
||||
val size = Dimension(
|
||||
@ -85,6 +86,16 @@ private class BitmapScreenPanel : JPanel() {
|
||||
image, 0, 0, (image.width * ScreenDefs.DISPLAY_PIXEL_SCALING).toInt(),
|
||||
(image.height * ScreenDefs.DISPLAY_PIXEL_SCALING).toInt(), null
|
||||
)
|
||||
if(cursorState) {
|
||||
val scx = (cursorX * ScreenDefs.DISPLAY_PIXEL_SCALING * 8).toInt()
|
||||
val scy = (cursorY * ScreenDefs.DISPLAY_PIXEL_SCALING * 16).toInt()
|
||||
val scw = (8 * ScreenDefs.DISPLAY_PIXEL_SCALING).toInt()
|
||||
val sch = (16 * ScreenDefs.DISPLAY_PIXEL_SCALING).toInt()
|
||||
g2d.setXORMode(Color.CYAN)
|
||||
g2d.fillRect(scx, scy, scw, sch)
|
||||
g2d.setPaintMode()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun clearScreen() {
|
||||
@ -122,6 +133,12 @@ private class BitmapScreenPanel : JPanel() {
|
||||
(pos.y / ScreenDefs.DISPLAY_PIXEL_SCALING).toInt()
|
||||
)
|
||||
}
|
||||
|
||||
fun blinkCursor(x: Int, y: Int) {
|
||||
cursorX = x
|
||||
cursorY = y
|
||||
cursorState = !cursorState
|
||||
}
|
||||
}
|
||||
|
||||
class DebugWindow(val vm: VirtualMachine) : JFrame("debugger"), ActionListener {
|
||||
@ -368,4 +385,8 @@ class MainWindow(title: String) : JFrame(title), KeyListener, MouseInputListener
|
||||
else
|
||||
keyboardBuffer.pop()
|
||||
}
|
||||
|
||||
override fun blinkCursor(x: Int, y: Int) {
|
||||
canvas.blinkCursor(x, y)
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class VirtualMachine(title: String) {
|
||||
init {
|
||||
ram[Cpu6502.RESET_vector] = 0x00
|
||||
ram[Cpu6502.RESET_vector + 1] = 0x10
|
||||
ram.loadPrg(javaClass.getResource("/vmdemo.prg").toURI())
|
||||
ram.loadPrg(javaClass.getResourceAsStream("/vmdemo.prg"))
|
||||
|
||||
bus += rtc
|
||||
bus += timer
|
||||
@ -57,7 +57,7 @@ class VirtualMachine(title: String) {
|
||||
val timer = java.util.Timer("clock", true)
|
||||
timer.scheduleAtFixedRate(1, 1) {
|
||||
if(!paused) {
|
||||
repeat(5) {
|
||||
repeat(10) {
|
||||
stepInstruction()
|
||||
}
|
||||
debugWindow.updateCpu(cpu)
|
||||
|
@ -13,6 +13,7 @@ interface IHostInterface {
|
||||
fun scrollUp()
|
||||
fun mouse(): MouseInfo
|
||||
fun keyboard(): Char?
|
||||
fun blinkCursor(x: Int, y: Int)
|
||||
|
||||
class MouseInfo(val x: Int, val y: Int, val left: Boolean, val right: Boolean, val middle: Boolean)
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import kotlin.math.min
|
||||
* Text mode and graphics (bitmap) mode display.
|
||||
* Note that the character matrix and pixel matrix are NOT memory mapped,
|
||||
* this display device is controlled by sending char/pixel commands to it.
|
||||
* Also, the blinking cursor is 'hardware controlled' (by the host display),
|
||||
* these device registers merely can set it to a different screen position.
|
||||
*
|
||||
* Requires a host display to actually view the stuff, obviously.
|
||||
*
|
||||
@ -25,8 +27,6 @@ import kotlin.math.min
|
||||
* 09 cursor Y position (r/w)
|
||||
* 0a read or write character at cursor pos, updates cursor position, scrolls up if necessary
|
||||
* control characters: 0x08=backspace, 0x09=tab, 0x0a=newline, 0x0c=formfeed(clear screen), 0x0d=carriagereturn
|
||||
*
|
||||
* TODO: cursor blinking, blink speed (0=off)
|
||||
*/
|
||||
class Display(
|
||||
startAddress: Address, endAddress: Address,
|
||||
@ -49,10 +49,16 @@ class Display(
|
||||
private var pixelX = 0
|
||||
private var pixelY = 0
|
||||
private val charMatrix = Array<ShortArray>(charHeight) { ShortArray(charWidth) } // matrix[y][x] to access
|
||||
private var cursorCycles = 0
|
||||
|
||||
override fun clock() {
|
||||
// if the system clock is synced to the display refresh,
|
||||
// you *could* add a Vertical Blank interrupt here.
|
||||
// for now, only the cursor blinking is controlled by this.
|
||||
cursorCycles++
|
||||
if(cursorCycles % 8000 == 0) {
|
||||
host.blinkCursor(cursorX, cursorY)
|
||||
}
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
|
@ -1,9 +1,8 @@
|
||||
package razorvine.ksim65.components
|
||||
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.io.InputStream
|
||||
import java.net.URL
|
||||
import java.nio.file.Paths
|
||||
|
||||
/**
|
||||
* A RAM chip with read/write memory.
|
||||
@ -33,14 +32,14 @@ class Ram(startAddress: Address, endAddress: Address) : MemoryComponent(startAdd
|
||||
* Load a c64-style prg program. This file type has the load address as the first two bytes.
|
||||
*/
|
||||
fun loadPrg(filename: String) {
|
||||
loadPrg(Paths.get(filename).toUri())
|
||||
loadPrg(File(filename).inputStream())
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a c64-style prg program. This file type has the load address as the first two bytes.
|
||||
*/
|
||||
fun loadPrg(file: URI) {
|
||||
val bytes = File(file).readBytes()
|
||||
fun loadPrg(stream: InputStream) {
|
||||
val bytes = stream.readAllBytes()
|
||||
val loadAddress = (bytes[0].toInt() or (bytes[1].toInt() shl 8)) and 65535
|
||||
val baseAddress = loadAddress - startAddress
|
||||
bytes.drop(2).forEachIndexed { index, byte ->
|
||||
|
Loading…
x
Reference in New Issue
Block a user