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

blinking cursor, fixed resource loading

This commit is contained in:
Irmen de Jong 2019-09-16 23:52:25 +02:00
parent 067f134100
commit 261b6738b4
6 changed files with 43 additions and 10 deletions

View File

@ -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()

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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() {

View File

@ -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 ->