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

Custom c64 key mapping to make typing on a modern keyboard tolerable. Connected Restore key (backslash) to NMI.

This commit is contained in:
Irmen de Jong 2019-09-25 22:58:58 +02:00
parent bfdd9aa656
commit 88c1688a41
4 changed files with 274 additions and 114 deletions

View File

@ -15,6 +15,7 @@
<option value="$PROJECT_DIR$" />
</set>
</option>
<option name="useAutoImport" value="true" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>

View File

@ -9,11 +9,13 @@ import java.awt.event.KeyEvent
* Minimal simulation of the MOS 6526 CIA chip.
* Depending on what CIA it is (1 or 2), some registers do different things on the C64.
*/
class Cia(val number: Int, startAddress: Address, endAddress: Address): MemMappedComponent(startAddress, endAddress) {
class Cia(val number: Int, startAddress: Address, endAddress: Address) : MemMappedComponent(startAddress, endAddress) {
private var ramBuffer = Array<UByte>(endAddress - startAddress + 1) { 0x00 }
private var pra = 0xff
private val hostKeyPresses = mutableSetOf<Int>()
private data class HostKeyPress(val code: Int, val rightSide: Boolean, val numpad: Boolean)
private val hostKeyPresses = mutableSetOf<HostKeyPress>()
init {
require(endAddress - startAddress + 1 == 256) { "cia requires exactly 256 memory bytes (16*16 mirrored)" }
@ -24,134 +26,165 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address): MemMappe
}
override fun reset() {
hostKeyPresses.clear()
// TODO: reset TOD timer, timer A and B
}
override fun get(address: Address): UByte {
fun scanColumn(keys: List<HostKeyPress>): UByte {
var bits = 0b10000000
var presses = 0
for (key in keys) {
if (key in hostKeyPresses) presses = presses or bits
bits = bits ushr 1
}
return (presses.inv() and 255).toShort()
}
val register = (address - startAddress) and 15
if(number==1) {
if (number == 1) {
return if (register == 0x01) {
// register 1 on CIA#1 is the keyboard data port
// if bit is cleared in PRA, contains keys pressed in that column of the matrix
// TODO tweak the keyboard mapping so that keys like '=' can be pressed,
// RESTORE works (this is not a normal key but connected to the cpu's NMI line),
// Cursor up/down/left/right all work and left/right shift are different.
when(pra) {
when (pra) {
0b00000000 -> {
// check if any keys are pressed at all (by checking all columns at once)
if(hostKeyPresses.isEmpty()) 0xff.toShort() else 0x00.toShort()
if (hostKeyPresses.isEmpty()) 0xff.toShort() else 0x00.toShort()
}
0b11111110 -> {
// read column 0
val presses =
(if (KeyEvent.VK_DOWN in hostKeyPresses) 0b10000000 else 0) or
(if (KeyEvent.VK_F5 in hostKeyPresses) 0b01000000 else 0) or
(if (KeyEvent.VK_F3 in hostKeyPresses) 0b00100000 else 0) or
(if (KeyEvent.VK_F1 in hostKeyPresses) 0b00010000 else 0) or
(if (KeyEvent.VK_F7 in hostKeyPresses) 0b00001000 else 0) or
(if (KeyEvent.VK_RIGHT in hostKeyPresses) 0b00000100 else 0) or
(if (KeyEvent.VK_ENTER in hostKeyPresses) 0b00000010 else 0) or
(if (KeyEvent.VK_BACK_SPACE in hostKeyPresses) 0b00000001 else 0)
(presses.inv() and 255).toShort()
scanColumn(
listOf(
HostKeyPress(KeyEvent.VK_DOWN, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_F5, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_F3, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_F1, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_F7, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_RIGHT, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_ENTER, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_BACK_SPACE, rightSide = false, numpad = false)
)
)
}
0b11111101 -> {
// read column 1
val presses =
(if(KeyEvent.VK_SHIFT in hostKeyPresses) 0b10000000 else 0) or // TODO make it LEFT shift only
(if(KeyEvent.VK_E in hostKeyPresses) 0b01000000 else 0) or
(if(KeyEvent.VK_S in hostKeyPresses) 0b00100000 else 0) or
(if(KeyEvent.VK_Z in hostKeyPresses) 0b00010000 else 0) or
(if(KeyEvent.VK_4 in hostKeyPresses) 0b00001000 else 0) or
(if(KeyEvent.VK_A in hostKeyPresses) 0b00000100 else 0) or
(if(KeyEvent.VK_W in hostKeyPresses) 0b00000010 else 0) or
(if(KeyEvent.VK_3 in hostKeyPresses) 0b00000001 else 0)
(presses.inv() and 255).toShort()
scanColumn(
listOf(
HostKeyPress(KeyEvent.VK_SHIFT, rightSide = false, numpad = false), // left shift
HostKeyPress(KeyEvent.VK_E, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_S, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_Z, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_4, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_A, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_W, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_3, rightSide = false, numpad = false)
)
)
}
0b11111011 -> {
// read column 2
val presses =
(if (KeyEvent.VK_X in hostKeyPresses) 0b10000000 else 0) or
(if (KeyEvent.VK_T in hostKeyPresses) 0b01000000 else 0) or
(if (KeyEvent.VK_F in hostKeyPresses) 0b00100000 else 0) or
(if (KeyEvent.VK_C in hostKeyPresses) 0b00010000 else 0) or
(if (KeyEvent.VK_6 in hostKeyPresses) 0b00001000 else 0) or
(if (KeyEvent.VK_D in hostKeyPresses) 0b00000100 else 0) or
(if (KeyEvent.VK_R in hostKeyPresses) 0b00000010 else 0) or
(if (KeyEvent.VK_5 in hostKeyPresses) 0b00000001 else 0)
(presses.inv() and 255).toShort()
scanColumn(
listOf(
HostKeyPress(KeyEvent.VK_X, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_T, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_F, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_C, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_6, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_D, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_R, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_5, rightSide = false, numpad = false)
)
)
}
0b11110111 -> {
// read column 3
val presses =
(if (KeyEvent.VK_V in hostKeyPresses) 0b10000000 else 0) or
(if (KeyEvent.VK_U in hostKeyPresses) 0b01000000 else 0) or
(if (KeyEvent.VK_H in hostKeyPresses) 0b00100000 else 0) or
(if (KeyEvent.VK_B in hostKeyPresses) 0b00010000 else 0) or
(if (KeyEvent.VK_8 in hostKeyPresses) 0b00001000 else 0) or
(if (KeyEvent.VK_G in hostKeyPresses) 0b00000100 else 0) or
(if (KeyEvent.VK_Y in hostKeyPresses) 0b00000010 else 0) or
(if (KeyEvent.VK_7 in hostKeyPresses) 0b00000001 else 0)
(presses.inv() and 255).toShort()
scanColumn(
listOf(
HostKeyPress(KeyEvent.VK_V, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_U, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_H, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_B, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_8, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_G, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_Y, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_7, rightSide = false, numpad = false)
)
)
}
0b11101111 -> {
// read column 4
val presses =
(if (KeyEvent.VK_N in hostKeyPresses) 0b10000000 else 0) or
(if (KeyEvent.VK_O in hostKeyPresses) 0b01000000 else 0) or
(if (KeyEvent.VK_K in hostKeyPresses) 0b00100000 else 0) or
(if (KeyEvent.VK_M in hostKeyPresses) 0b00010000 else 0) or
(if (KeyEvent.VK_0 in hostKeyPresses) 0b00001000 else 0) or
(if (KeyEvent.VK_J in hostKeyPresses) 0b00000100 else 0) or
(if (KeyEvent.VK_I in hostKeyPresses) 0b00000010 else 0) or
(if (KeyEvent.VK_9 in hostKeyPresses) 0b00000001 else 0)
(presses.inv() and 255).toShort()
scanColumn(
listOf(
HostKeyPress(KeyEvent.VK_N, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_O, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_K, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_M, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_0, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_J, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_I, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_9, rightSide = false, numpad = false)
)
)
}
0b11011111 -> {
// read column 5
val presses =
(if (KeyEvent.VK_COMMA in hostKeyPresses) 0b10000000 else 0) or
(if (KeyEvent.VK_OPEN_BRACKET in hostKeyPresses) 0b01000000 else 0) or // '[' = @
(if (KeyEvent.VK_SEMICOLON in hostKeyPresses) 0b00100000 else 0) or // ';' -> :
(if (KeyEvent.VK_PERIOD in hostKeyPresses) 0b00010000 else 0) or
(if (KeyEvent.VK_MINUS in hostKeyPresses) 0b00001000 else 0) or
(if (KeyEvent.VK_L in hostKeyPresses) 0b00000100 else 0) or
(if (KeyEvent.VK_P in hostKeyPresses) 0b00000010 else 0) or
(if (KeyEvent.VK_PLUS in hostKeyPresses) 0b00000001 else 0)
(presses.inv() and 255).toShort()
scanColumn(
listOf(
HostKeyPress(KeyEvent.VK_COMMA, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_AT, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_COLON, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_PERIOD, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_MINUS, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_L, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_P, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_PLUS, rightSide = false, numpad = false)
)
)
}
0b10111111 -> {
// read column 6
val presses =
(if (KeyEvent.VK_SLASH in hostKeyPresses) 0b10000000 else 0) or
(if (KeyEvent.VK_BACK_SLASH in hostKeyPresses) 0b01000000 else 0) or // '\' -> up arrow
(if (KeyEvent.VK_EQUALS in hostKeyPresses) 0b00100000 else 0) or
(if (KeyEvent.VK_SHIFT in hostKeyPresses) 0b00010000 else 0) or // TODO RIGHT shift only
(if (KeyEvent.VK_HOME in hostKeyPresses) 0b00001000 else 0) or
(if (KeyEvent.VK_QUOTE in hostKeyPresses) 0b00000100 else 0) or // ' -> ;
(if (KeyEvent.VK_CLOSE_BRACKET in hostKeyPresses) 0b00000010 else 0) or // ']' = *
(if (KeyEvent.VK_END in hostKeyPresses) 0b00000001 else 0) // END -> pound key
(presses.inv() and 255).toShort()
scanColumn(
listOf(
HostKeyPress(KeyEvent.VK_SLASH, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_CIRCUMFLEX, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_EQUALS, rightSide = false, numpad = false),
HostKeyPress(
KeyEvent.VK_SHIFT,
rightSide = true,
numpad = false
), // right shift
HostKeyPress(KeyEvent.VK_HOME, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_SEMICOLON, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_ASTERISK, rightSide = false, numpad = false),
HostKeyPress(
KeyEvent.VK_DEAD_TILDE,
rightSide = false,
numpad = false
) // pound sign
)
)
}
0b01111111 -> {
// read column 7
val presses =
(if (KeyEvent.VK_ESCAPE in hostKeyPresses) 0b10000000 else 0) or // esc -> STOP
(if (KeyEvent.VK_Q in hostKeyPresses) 0b01000000 else 0) or
(if (KeyEvent.VK_ALT in hostKeyPresses) 0b00100000 else 0) or // alt -> Commodore
(if (KeyEvent.VK_SPACE in hostKeyPresses) 0b00010000 else 0) or
(if (KeyEvent.VK_2 in hostKeyPresses) 0b00001000 else 0) or
(if (KeyEvent.VK_CONTROL in hostKeyPresses) 0b00000100 else 0) or
(if (KeyEvent.VK_BACK_QUOTE in hostKeyPresses) 0b00000010 else 0) or // '`' -> left arrow
(if (KeyEvent.VK_1 in hostKeyPresses) 0b00000001 else 0)
(presses.inv() and 255).toShort()
scanColumn(
listOf(
HostKeyPress(KeyEvent.VK_ESCAPE, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_Q, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_ALT, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_SPACE, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_2, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_CONTROL, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_BACK_QUOTE, rightSide = false, numpad = false),
HostKeyPress(KeyEvent.VK_1, rightSide = false, numpad = false)
)
)
}
else -> {
else -> {
// invalid column selection
0xff
}
}
}
else ramBuffer[register]
} else ramBuffer[register]
}
// CIA #2 is not emulated yet
@ -161,7 +194,7 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address): MemMappe
override fun set(address: Address, data: UByte) {
val register = (address - startAddress) and 15
ramBuffer[register] = data
if(number==1) {
if (number == 1) {
when (register) {
0x00 -> {
// PRA data port A (select keyboard matrix column)
@ -173,9 +206,127 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address): MemMappe
}
fun hostKeyPressed(event: KeyEvent) {
if(event.id==KeyEvent.KEY_PRESSED)
hostKeyPresses.add(event.keyCode)
else if(event.id==KeyEvent.KEY_RELEASED)
hostKeyPresses.remove(event.keyCode)
val rightSide = event.keyLocation == KeyEvent.KEY_LOCATION_RIGHT
val numpad = event.keyLocation == KeyEvent.KEY_LOCATION_NUMPAD
val shift = HostKeyPress(KeyEvent.VK_SHIFT, rightSide = true, numpad = false)
fun register(eventId: Int, vararg keys: HostKeyPress) {
if (eventId == KeyEvent.KEY_PRESSED) keys.forEach { hostKeyPresses.add(it) }
else keys.forEach { hostKeyPresses.remove(it) }
}
fun unregister(keyCode: Int) {
hostKeyPresses.removeAll { it.code == keyCode }
}
// to avoid some 'stuck' keys, if we receive a shift/control/alt RELEASE, we wipe the keyboard buffer
// (this can happen becase we're changing the keycode for some pressed keys below,
// and a released key doesn't always match the pressed keycode anymore then)
if (event.id == KeyEvent.KEY_RELEASED && event.keyCode in listOf(
KeyEvent.VK_SHIFT,
KeyEvent.VK_CONTROL,
KeyEvent.VK_ALT,
KeyEvent.VK_ALT_GRAPH
)
) hostKeyPresses.clear()
// try to remap the keys a bit so a modern PC keyboard maps better to the keys of the C64
when {
event.keyChar == '@' -> {
unregister(KeyEvent.VK_SHIFT)
register(event.id, HostKeyPress(KeyEvent.VK_AT, rightSide = false, numpad = false))
}
event.keyChar == '^' -> {
unregister(KeyEvent.VK_SHIFT)
register(event.id, HostKeyPress(KeyEvent.VK_CIRCUMFLEX, rightSide = false, numpad = false))
}
event.keyChar == '&' -> {
register(event.id, shift, HostKeyPress(KeyEvent.VK_6, rightSide = false, numpad = false))
}
event.keyChar == '*' -> {
unregister(KeyEvent.VK_SHIFT)
register(event.id, HostKeyPress(KeyEvent.VK_ASTERISK, rightSide = false, numpad = false))
}
event.keyChar == '(' -> {
register(event.id, shift, HostKeyPress(KeyEvent.VK_8, rightSide = false, numpad = false))
}
event.keyChar == ')' -> {
register(event.id, shift, HostKeyPress(KeyEvent.VK_9, rightSide = false, numpad = false))
}
event.keyChar == '[' -> {
register(event.id, shift, HostKeyPress(KeyEvent.VK_COLON, rightSide = false, numpad = false))
}
event.keyChar == ']' -> {
register(event.id, shift, HostKeyPress(KeyEvent.VK_SEMICOLON, rightSide = false, numpad = false))
}
event.keyChar == '+' -> {
unregister(KeyEvent.VK_SHIFT)
register(event.id, HostKeyPress(KeyEvent.VK_PLUS, rightSide = false, numpad = false))
}
event.keyChar == '"' -> {
register(event.id, HostKeyPress(KeyEvent.VK_2, rightSide = false, numpad = false))
}
event.keyChar == ':' -> {
unregister(KeyEvent.VK_SHIFT)
register(event.id, HostKeyPress(KeyEvent.VK_COLON, rightSide = false, numpad = false))
}
event.keyChar == '~' -> {
unregister(KeyEvent.VK_SHIFT)
register(event.id, HostKeyPress(KeyEvent.VK_DEAD_TILDE, rightSide = false, numpad = false))
}
event.keyChar == '\'' -> {
register(event.id, shift, HostKeyPress(KeyEvent.VK_7, rightSide = false, numpad = false))
}
else -> when (event.keyCode) {
KeyEvent.VK_CONTROL, KeyEvent.VK_TAB -> {
// both controls and the tab key map to the 'single left control'
register(event.id, HostKeyPress(KeyEvent.VK_CONTROL, rightSide = false, numpad = false))
}
KeyEvent.VK_ALT, KeyEvent.VK_ALT_GRAPH -> {
// both alts map to the 'commodore key' (same left alt)
register(event.id, HostKeyPress(KeyEvent.VK_ALT, rightSide = false, numpad = false))
}
KeyEvent.VK_F2 -> {
// F2 = shift+F1
val func = HostKeyPress(KeyEvent.VK_F1, rightSide = false, numpad = false)
register(event.id, shift, func)
}
KeyEvent.VK_F4 -> {
// F4 = shift+F3
val func = HostKeyPress(KeyEvent.VK_F3, rightSide = false, numpad = false)
register(event.id, shift, func)
}
KeyEvent.VK_F6 -> {
// F6 = shift+F5
val func = HostKeyPress(KeyEvent.VK_F5, rightSide = false, numpad = false)
register(event.id, shift, func)
}
KeyEvent.VK_F8 -> {
// F8 = shift+F7
val func = HostKeyPress(KeyEvent.VK_F7, rightSide = false, numpad = false)
register(event.id, shift, func)
}
KeyEvent.VK_INSERT -> {
// insert = shift+backspace(del)
val backspace = HostKeyPress(KeyEvent.VK_BACK_SPACE, rightSide = false, numpad = false)
register(event.id, shift, backspace)
}
KeyEvent.VK_UP -> {
// up = shift+down
val cursor = HostKeyPress(KeyEvent.VK_DOWN, rightSide = false, numpad = false)
register(event.id, shift, cursor)
}
KeyEvent.VK_LEFT -> {
// left = shift+right
val cursor = HostKeyPress(KeyEvent.VK_RIGHT, rightSide = false, numpad = false)
register(event.id, shift, cursor)
}
else -> {
// just map the key as usual
val hostkey = HostKeyPress(event.keyCode, rightSide, numpad)
register(event.id, hostkey)
}
}
}
}
}

View File

@ -1,5 +1,6 @@
package razorvine.c64emu
import razorvine.ksim65.Cpu6502
import razorvine.ksim65.components.MemoryComponent
import java.awt.*
import java.awt.image.BufferedImage
@ -60,13 +61,13 @@ private class BitmapScreenPanel(val chargenData: ByteArray, val ram: MemoryCompo
private fun loadCharacters(shifted: Boolean): Array<BufferedImage> {
val chars = Array(256) { BufferedImage(8, 8, BufferedImage.TYPE_BYTE_BINARY) }
val offset = if(shifted) 256*8 else 0
val offset = if (shifted) 256 * 8 else 0
// val color = ScreenDefs.colorPalette[14].rgb
for(char in 0..255) {
for(line in 0..7) {
val charbyte = chargenData[offset + char*8 + line].toInt()
for(x in 0..7) {
if(charbyte and (0b10000000 ushr x) !=0 )
for (char in 0..255) {
for (line in 0..7) {
val charbyte = chargenData[offset + char * 8 + line].toInt()
for (x in 0..7) {
if (charbyte and (0b10000000 ushr x) != 0)
chars[char].setRGB(x, line, 0xffffff)
}
}
@ -92,10 +93,10 @@ private class BitmapScreenPanel(val chargenData: ByteArray, val ram: MemoryCompo
val shifted = (ram[0xd018].toInt() and 0b00000010) != 0
g2d.background = ScreenDefs.colorPalette[ram[0xd021].toInt() and 15]
g2d.clearRect(0, 0, ScreenDefs.SCREEN_WIDTH, ScreenDefs.SCREEN_HEIGHT)
for(y in 0 until ScreenDefs.SCREEN_HEIGHT_CHARS) {
for(x in 0 until ScreenDefs.SCREEN_WIDTH_CHARS) {
val char = ram[screen + x + y*ScreenDefs.SCREEN_WIDTH_CHARS].toInt()
val color = ram[colors + x + y*ScreenDefs.SCREEN_WIDTH_CHARS].toInt()
for (y in 0 until ScreenDefs.SCREEN_HEIGHT_CHARS) {
for (x in 0 until ScreenDefs.SCREEN_WIDTH_CHARS) {
val char = ram[screen + x + y * ScreenDefs.SCREEN_WIDTH_CHARS].toInt()
val color = ram[colors + x + y * ScreenDefs.SCREEN_WIDTH_CHARS].toInt()
drawColoredChar(x, y, char, color and 15, shifted)
}
}
@ -105,18 +106,18 @@ private class BitmapScreenPanel(val chargenData: ByteArray, val ram: MemoryCompo
private fun drawColoredChar(x: Int, y: Int, char: Int, color: Int, shifted: Boolean) {
var cached = coloredCharacters[Triple(char, color, shifted)]
if(cached==null) {
cached = if(shifted) shiftedCharacters[char] else normalCharacters[char]
if (cached == null) {
cached = if (shifted) shiftedCharacters[char] else normalCharacters[char]
val colored = g2d.deviceConfiguration.createCompatibleImage(8, 8, BufferedImage.BITMASK)
val sourceRaster = cached.raster
val coloredRaster = colored.raster
val pixelArray = IntArray(4)
val javaColor = ScreenDefs.colorPalette[color]
val coloredPixel = listOf(javaColor.red, javaColor.green, javaColor.blue, javaColor.alpha).toIntArray()
for(pixelY in 0..7) {
for(pixelX in 0..7) {
for (pixelY in 0..7) {
for (pixelX in 0..7) {
val source = sourceRaster.getPixel(pixelX, pixelY, pixelArray)
if(source[0]!=0) {
if (source[0] != 0) {
coloredRaster.setPixel(pixelX, pixelY, coloredPixel)
}
}
@ -132,6 +133,7 @@ class MainC64Window(
title: String,
chargenData: ByteArray,
val ram: MemoryComponent,
val cpu: Cpu6502,
val keypressCia: Cia
) : JFrame(title), KeyListener {
private val canvas = BitmapScreenPanel(chargenData, ram)
@ -195,7 +197,7 @@ class MainC64Window(
addKeyListener(this)
pack()
setLocationRelativeTo(null)
location = Point(location.x/2, location.y)
location = Point(location.x / 2, location.y)
setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, mutableSetOf())
setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, mutableSetOf())
requestFocusInWindow()
@ -218,8 +220,14 @@ class MainC64Window(
override fun keyTyped(event: KeyEvent) {}
override fun keyPressed(event: KeyEvent) {
keypressCia.hostKeyPressed(event)
// '\' is mapped as RESTORE, this causes a NMI on the cpu
if (event.keyChar == '\\') {
cpu.nmi()
} else {
keypressCia.hostKeyPressed(event)
}
}
override fun keyReleased(event: KeyEvent) {
keypressCia.hostKeyPressed(event)
}

View File

@ -32,7 +32,7 @@ class C64Machine(title: String) : IVirtualMachine {
// TODO: implement something so that RND(0) actually works in basic. (cia timer?)
private val debugWindow = DebugWindow(this)
private val hostDisplay = MainC64Window(title, chargenData, ram, cia1)
private val hostDisplay = MainC64Window(title, chargenData, ram, cpu, cia1)
private var paused = false
init {