fix: mmio-based readKey() having delayed event because of race condition

This commit is contained in:
minjaesong
2025-12-20 11:17:50 +09:00
parent 64026be133
commit 5d5576c077
2 changed files with 16 additions and 18 deletions

View File

@@ -208,25 +208,19 @@ class VMJSR223Delegate(private val vm: VM) {
* ^A-^Z: 1 through 26
*/
fun readKey(): Int {
val inputStream = vm.getInputStream()
var key: Int = inputStream.read()
inputStream.close()
return key
// impl that doesn't rely on InputStream
// fixme it's causing event-wise delay
/*vm.getIO().let {
it.mmio_write(38, 1)
// MMIO-based implementation that can be replicated by JS via MMIO read/writes
vm.getIO().let {
it.mmio_write(38, 1) // Set keyboardInputRequested = true (also clears buffer)
vm.isIdle.set(true)
while (it.mmio_read(49L) == 0.toByte()) {
while (it.mmio_read(49L) == 0.toByte()) { // Wait for keyPushed flag
Thread.sleep(6L)
}
vm.isIdle.set(false)
it.mmio_write(38, 0)
return it.mmio_read(37L)!!.toUint()
}*/
it.mmio_write(38, 0) // Clear keyboardInputRequested
return it.mmio_read(37L)!!.toUint() // Read and remove key from buffer
}
}
/**

View File

@@ -99,7 +99,11 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
in 32..33 -> (mouseX.toInt() shr (adi - 32).times(8)).toByte()
in 34..35 -> (mouseY.toInt() shr (adi - 34).times(8)).toByte()
36L -> mouseDown.toInt().toByte()
37L -> keyboardBuffer.removeTail() ?: -1
37L -> {
val key = keyboardBuffer.removeTail() ?: -1
keyPushed = !keyboardBuffer.isEmpty // Clear flag when buffer becomes empty
key
}
38L -> keyboardInputRequested.toInt().toByte()
39L -> rawInputFunctionLatched.toInt().toByte()
in 40..47 -> keyEventBuffers[adi - 40]
@@ -174,6 +178,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
keyboardInputRequested = (byte.isNonZero())
if (keyboardInputRequested) {
keyboardBuffer.clear()
keyPushed = false // Reset flag when buffer is cleared
vm.isIdle.set(true)
}
else
@@ -344,14 +349,11 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
override fun keyTyped(p0: Char): Boolean {
if (keyboardInputRequested && p0.toInt() > 0) {
//println("[IO] key typed = ${p0.toInt()}")
keyPushed = true
keyboardBuffer.appendHead(p0.toByte())
Thread.sleep(6L)
keyPushed = false
keyPushed = true // Set after append; cleared when buffer is emptied via mmio_read(37)
return true
}
else {
keyPushed = false
return false
}
}
@@ -389,11 +391,13 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
if (keyboardInputRequested) {
if (p0 in Input.Keys.A..Input.Keys.Z && (Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT) || Gdx.input.isKeyPressed(Input.Keys.CONTROL_RIGHT))) {
keyboardBuffer.appendHead((p0 - 28).toByte())
keyPushed = true
}
else {
specialKeys[p0]?.let {
//println("[IO] key special = ${it.toUInt()}")
keyboardBuffer.appendHead(it)
keyPushed = true
}
}
return true