more input reading|js console app

This commit is contained in:
minjaesong
2020-05-19 11:14:27 +09:00
parent 9321dbceb1
commit 619257ecf2
10 changed files with 240 additions and 41 deletions

View File

@@ -51,7 +51,8 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter()
vm.getInputStream = { gpu.getInputStream() }
// TEST PRG
val fr = FileReader("./assets/tvdos/command.js")
//val fr = FileReader("./assets/tvdos/command.js")
val fr = FileReader("./assets/jscon.js")
val prg = fr.readText()
fr.close()

View File

@@ -23,10 +23,16 @@ class VMJSR223Delegate(val vm: VM) {
}
fun println() = print('\n')
//fun readKey() = vm.inputStream.read()
fun readKey(): Int {
val inputStream = vm.getInputStream()
var key: Int = inputStream.read()
inputStream.close()
return key
}
/**
* Read series of key inputs until Enter/Return key is pressed
* Read series of key inputs until Enter/Return key is pressed. Backspace will work but any other non-printable
* characters (e.g. arrow keys) won't work.
*/
fun read(): String {
val inputStream = vm.getInputStream()

View File

@@ -8,6 +8,7 @@ abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolea
open var busy = false
protected var sendmode = false; private set
open var blockSize = 0
open fun attachDevice(device: BlockTransferInterface?) {
recipient = device
@@ -39,10 +40,14 @@ abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolea
open fun writeout(inputData: ByteArray, writeoutfun: (() -> Unit)? = null) {
busy = true
ready = false
blockSize = minOf(inputData.size, BLOCK_SIZE)
writeoutfun?.invoke()
busy = false
ready = true
}
abstract fun hasNext(): Boolean
open fun doYouHaveNext(): Boolean = recipient?.hasNext() ?: false
open fun yourBlockSize(): Int = recipient?.blockSize ?: 0
/** @param sendmode TRUE for send, FALSE for receive */
open fun setMode(sendmode: Boolean) {
@@ -52,4 +57,8 @@ abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolea
open fun getMode(): Boolean = sendmode
open fun cableConnected(): Boolean = recipient?.recipient == this
companion object {
const val BLOCK_SIZE = 4096
}
}

View File

@@ -8,19 +8,22 @@ import net.torvald.tsvm.VM
*/
internal class BlockTransferPort(val vm: VM, val portno: Int) : BlockTransferInterface(true, false) {
internal var hasNext = false
override fun startSend(sendfun: ((BlockTransferInterface) -> Unit)?) {
super.startSend { recipient ->
val ba = ByteArray(4096) { vm.getIO().blockTransforBlock[portno][it.toLong()] }
val ba = ByteArray(BLOCK_SIZE) { vm.getIO().blockTransferRx[portno][it.toLong()] }
recipient.writeout(ba)
}
}
override fun hasNext(): Boolean = hasNext
override fun writeout(inputData: ByteArray, writeoutfun: (() -> Unit)?) {
super.writeout(inputData) {
val copySize = minOf(4096, inputData.size).toLong()
val copySize = minOf(BLOCK_SIZE, inputData.size).toLong()
val arrayOffset = UnsafeHelper.getArrayOffset(inputData).toLong()
UnsafeHelper.memcpyRaw(inputData, arrayOffset, null, vm.getIO().blockTransforBlock[portno].ptr, copySize)
UnsafeHelper.memcpyRaw(inputData, arrayOffset, null, vm.getIO().blockTransferRx[portno].ptr, copySize)
}
}

View File

@@ -18,14 +18,16 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
/** Absolute y-position of the computer GUI */
var guiPosY = 0
/** Accepts a keycode */
private val keyboardBuffer = CircularArray<Byte>(32, true)
private var mouseX: Short = 0
private var mouseY: Short = 0
private var mouseDown = false
private var keyboardInputRequested = false
internal val blockTransforBlock = arrayOf(
internal val blockTransferRx = arrayOf(
UnsafeHelper.allocate(4096),
UnsafeHelper.allocate(4096),
UnsafeHelper.allocate(4096),
UnsafeHelper.allocate(4096)
)
internal val blockTransferTx = arrayOf(
UnsafeHelper.allocate(4096),
UnsafeHelper.allocate(4096),
UnsafeHelper.allocate(4096),
@@ -33,6 +35,8 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
)
private val blockTransferPorts = Array(4) { BlockTransferPort(vm, it) }
private val keyEventBuffers = ByteArray(8)
init {
blockTransferPorts[0].attachDevice(TestFunctionGenerator())
}
@@ -71,17 +75,33 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
in 0..31 -> keyboardBuffer[(addr.toInt())] ?: -1
in 32..33 -> (mouseX.toInt() shr (adi - 32).times(8)).toByte()
in 34..35 -> (mouseY.toInt() shr (adi - 34).times(8)).toByte()
36L -> if (mouseDown) 1 else 0
36L -> mouseDown.toInt().toByte()
37L -> keyboardBuffer.removeTail() ?: -1
38L -> if (keyboardInputRequested) 1 else 0
38L -> keyboardInputRequested.toInt().toByte()
39L -> rawInputFunctionLatched.toInt().toByte()
in 40..47 -> keyEventBuffers[adi - 40]
in 64..67 -> vm.memsize.shr((adi - 64) * 8).toByte()
68L -> (uptimeCounterLatched.toInt() or RTClatched.toInt().shl(1)).toByte()
in 72..79 -> systemUptime.ushr((adi - 72) * 8).and(255).toByte()
in 80..87 -> rtc.ushr((adi - 80) * 8).and(255).toByte()
4084L -> (blockTransferPorts[0].yourBlockSize().toByte())
4085L -> (blockTransferPorts[0].doYouHaveNext().toInt().shl(7) or blockTransferPorts[0].yourBlockSize().ushr(8).and(15)).toByte()
4086L -> (blockTransferPorts[1].yourBlockSize().toByte())
4087L -> (blockTransferPorts[1].doYouHaveNext().toInt().shl(7) or blockTransferPorts[1].yourBlockSize().ushr(8).and(15)).toByte()
4088L -> (blockTransferPorts[2].yourBlockSize().toByte())
4089L -> (blockTransferPorts[2].doYouHaveNext().toInt().shl(7) or blockTransferPorts[2].yourBlockSize().ushr(8).and(15)).toByte()
4090L -> (blockTransferPorts[3].yourBlockSize().toByte())
4091L -> (blockTransferPorts[4].doYouHaveNext().toInt().shl(7) or blockTransferPorts[3].yourBlockSize().ushr(8).and(15)).toByte()
in 4092..4095 -> composeBlockTransferStatus(adi - 4092).toByte()
in 4096..8191 -> blockTransforBlock[0][addr - 4096]
in 8192..12287 -> blockTransforBlock[1][addr - 8192]
in 12288..16383 -> blockTransforBlock[2][addr - 12288]
in 16384..20479 -> blockTransforBlock[3][addr - 16384]
in 4096..8191 -> blockTransferRx[0][addr - 4096]
in 8192..12287 -> blockTransferRx[1][addr - 8192]
in 12288..16383 -> blockTransferRx[2][addr - 12288]
in 16384..20479 -> blockTransferRx[3][addr - 16384]
in 131072..262143 -> vm.peripheralTable[1].peripheral?.mmio_read(addr - 131072)
in 262144..393215 -> vm.peripheralTable[2].peripheral?.mmio_read(addr - 262144)
@@ -101,15 +121,43 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
when (addr) {
37L -> keyboardBuffer.appendHead(byte)
38L -> {
keyboardInputRequested = (byte != 0.toByte())
keyboardInputRequested = (byte.isNonZero())
if (keyboardInputRequested) keyboardBuffer.clear()
}
39L -> rawInputFunctionLatched = (byte.isNonZero())
in 40..47 -> keyEventBuffers[adi - 40] = byte
68L -> {
uptimeCounterLatched = byte.and(0b01).isNonZero()
RTClatched = byte.and(0b10).isNonZero()
}
4084L -> blockTransferPorts[0].blockSize = blockTransferPorts[0].blockSize.and(0xFF00) or byte.toInt().and(255)
4085L -> {
blockTransferPorts[0].hasNext = (byte < 0)
blockTransferPorts[0].blockSize = blockTransferPorts[0].blockSize.and(0x00FF) or byte.toInt().and(15)
}
4086L -> blockTransferPorts[1].blockSize = blockTransferPorts[1].blockSize.and(0xFF00) or byte.toInt().and(255)
4087L -> {
blockTransferPorts[1].hasNext = (byte < 0)
blockTransferPorts[1].blockSize = blockTransferPorts[1].blockSize.and(0x00FF) or byte.toInt().and(15)
}
4088L -> blockTransferPorts[2].blockSize = blockTransferPorts[2].blockSize.and(0xFF00) or byte.toInt().and(255)
4089L -> {
blockTransferPorts[2].hasNext = (byte < 0)
blockTransferPorts[2].blockSize = blockTransferPorts[2].blockSize.and(0x00FF) or byte.toInt().and(15)
}
4090L -> blockTransferPorts[3].blockSize = blockTransferPorts[3].blockSize.and(0xFF00) or byte.toInt().and(255)
4091L -> {
blockTransferPorts[3].hasNext = (byte < 0)
blockTransferPorts[3].blockSize = blockTransferPorts[3].blockSize.and(0x00FF) or byte.toInt().and(15)
}
in 4092..4095 -> setBlockTransferPortStatus(adi - 4092, byte)
in 4096..8191 -> blockTransforBlock[0][addr - 4096] = byte
in 8192..12287 -> blockTransforBlock[1][addr - 8192] = byte
in 12288..16383 -> blockTransforBlock[2][addr - 12288] = byte
in 16384..20479 -> blockTransforBlock[3][addr - 16384] = byte
in 4096..8191 -> blockTransferTx[0][addr - 4096] = byte
in 8192..12287 -> blockTransferTx[1][addr - 8192] = byte
in 12288..16383 -> blockTransferTx[2][addr - 12288] = byte
in 16384..20479 -> blockTransferTx[3][addr - 16384] = byte
in 131072..262143 -> vm.peripheralTable[1].peripheral?.mmio_write(addr - 131072, byte)
in 262144..393215 -> vm.peripheralTable[2].peripheral?.mmio_write(addr - 262144, byte)
@@ -122,13 +170,47 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
}
override fun dispose() {
blockTransforBlock.forEach { it.destroy() }
blockTransferRx.forEach { it.destroy() }
blockTransferTx.forEach { it.destroy() }
}
private var mouseX: Short = 0
private var mouseY: Short = 0
private var mouseDown = false
private var systemUptime = 0L
private var rtc = 0L
fun update(delta: Float) {
mouseX = (Gdx.input.x + guiPosX).toShort()
mouseY = (Gdx.input.y + guiPosY).toShort()
mouseDown = Gdx.input.isTouched
if (rawInputFunctionLatched) {
rawInputFunctionLatched = false
// store mouse info
mouseX = (Gdx.input.x + guiPosX).toShort()
mouseY = (Gdx.input.y + guiPosY).toShort()
mouseDown = Gdx.input.isTouched
// strobe keys to fill the key read buffer
var keysPushed = 0
keyEventBuffers.fill(0)
for (k in 1..254) {
if (Gdx.input.isKeyPressed(k)) {
keyEventBuffers[keysPushed] = k.toByte()
keysPushed += 1
}
if (keysPushed >= 8) break
}
}
if (uptimeCounterLatched) {
uptimeCounterLatched = false
systemUptime = vm.getUptime()
}
if (RTClatched) {
RTClatched = false
rtc = System.currentTimeMillis()
}
}
override fun touchUp(p0: Int, p1: Int, p2: Int, p3: Int): Boolean {
@@ -140,7 +222,8 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
}
override fun keyTyped(p0: Char): Boolean {
if (keyboardInputRequested) {
if (keyboardInputRequested && !ttySpecialKeyLatched && p0.toInt() > 0) {
println("[IO] Key typed: ${p0.toInt()}")
keyboardBuffer.appendHead(p0.toByte())
return true
}
@@ -154,15 +237,28 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
}
override fun keyUp(p0: Int): Boolean {
return false
ttySpecialKeyLatched = false
return true
}
override fun touchDragged(p0: Int, p1: Int, p2: Int): Boolean {
return false
}
private var keyboardInputRequested = false
private var uptimeCounterLatched = false
private var RTClatched = false
private var rawInputFunctionLatched = false
private var ttySpecialKeyLatched = false
// UP DN LE RI
private var specialKey = listOf(19,20,21,22).toSortedSet()
override fun keyDown(p0: Int): Boolean {
return false
if (keyboardInputRequested && !ttySpecialKeyLatched && p0 in specialKey) {
println("[IO] Key down: $p0")
keyboardBuffer.appendHead(p0.toByte())
}
return true
}
override fun touchDown(p0: Int, p1: Int, p2: Int, p3: Int): Boolean {
@@ -170,4 +266,5 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
}
private fun Boolean.toInt() = if (this) 1 else 0
}
private fun Byte.isNonZero() = this != 0.toByte()
}

View File

@@ -0,0 +1,14 @@
package net.torvald.tsvm.peripheral
import java.util.*
class SerialDiskDrive : BlockTransferInterface(false, true) {
override fun hasNext(): Boolean {
TODO("Not yet implemented")
}
val diskID: UUID = UUID(0, 0)
}

View File

@@ -18,6 +18,8 @@ Nunc mollis nibh vitae sapien consequat, ut vestibulum sem pharetra. Aliquam iac
super.startSend { it.writeout(msg) }
}
override fun hasNext(): Boolean = false
override fun writeout(inputData: ByteArray, writeoutfun: (() -> Unit)?) {
}