mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
SerialHelper would work as intended MINUS the wait function
This commit is contained in:
14
assets/serialtest.js
Normal file
14
assets/serialtest.js
Normal file
@@ -0,0 +1,14 @@
|
||||
var ba = com.sendMessageGetBytes(0, [0x44,0x45,0x56,0x4e,0x41,0x4d,0x17]);
|
||||
serial.println(ba);
|
||||
for (let k = 0; k < 4096; k++) {
|
||||
serial.print(String.fromCharCode(ba[k]));
|
||||
}
|
||||
serial.print("\n");
|
||||
|
||||
ba = com.pullMessage(0)
|
||||
for (let k = 0; k < 4096; k++) {
|
||||
serial.print(String.fromCharCode(ba[k]));
|
||||
}
|
||||
serial.print("\n");
|
||||
|
||||
serial.println("\nk bye")
|
||||
@@ -125,4 +125,7 @@ con.color_pair(201,255);
|
||||
print("cya!");
|
||||
|
||||
let konsht = 3412341241;
|
||||
print(konsht);
|
||||
println(konsht);
|
||||
|
||||
let pppp = graphics.getCursorYX();
|
||||
println(pppp.toString());
|
||||
@@ -15,28 +15,50 @@ object SerialHelper {
|
||||
fun sendMessageGetBytes(vm: VM, portNo: Int, message: ByteArray): ByteArray {
|
||||
sendMessage(vm, portNo, message)
|
||||
waitUntilReady(vm, portNo)
|
||||
return getMessage(vm, portNo)
|
||||
return fetchResponse(vm, portNo)
|
||||
}
|
||||
|
||||
fun sendMessage(vm: VM, portNo: Int, message: ByteArray) {
|
||||
if (!checkIfDeviceIsThere(vm, portNo)) throw IllegalStateException("Device not connected")
|
||||
if (message.size > BLOCK_SIZE) throw NotImplementedError("sending message greater than 4096 is a future work :p")
|
||||
|
||||
UnsafeHelper.memcpyRaw(
|
||||
/*UnsafeHelper.memcpyRaw(
|
||||
message, UnsafeHelper.getArrayOffset(message),
|
||||
null, vm.getIO().blockTransferTx[portNo].ptr,
|
||||
minOf(BLOCK_SIZE, message.size).toLong()
|
||||
)
|
||||
)*/
|
||||
|
||||
for (k in 0 until BLOCK_SIZE) {
|
||||
vm.getIO().blockTransferTx[portNo][k.toLong()] = if (k >= message.size) 0 else message[k]
|
||||
}
|
||||
|
||||
initiateWriting(vm, portNo)
|
||||
|
||||
// TODO assuming the write operation is finished... (wait for something?)
|
||||
getReady(vm, portNo)
|
||||
}
|
||||
|
||||
fun getMessage(vm: VM, portNo: Int): ByteArray {
|
||||
// Returns what's on the RX buffer after sendMessage()
|
||||
fun fetchResponse(vm: VM, portNo: Int): ByteArray {
|
||||
val incomingMsg = ByteArray(BLOCK_SIZE)
|
||||
|
||||
UnsafeHelper.memcpyRaw(
|
||||
null, vm.getIO().blockTransferRx[portNo].ptr,
|
||||
incomingMsg, UnsafeHelper.getArrayOffset(incomingMsg),
|
||||
BLOCK_SIZE.toLong()
|
||||
)
|
||||
|
||||
return incomingMsg
|
||||
}
|
||||
|
||||
// Initiates startSend() function from the connected device
|
||||
fun pullMessage(vm: VM, portNo: Int): ByteArray {
|
||||
val msgBuffer = ByteArrayOutputStream(BLOCK_SIZE)
|
||||
|
||||
// pull all the blocks of messages
|
||||
do {
|
||||
initiateReading(vm, portNo)
|
||||
while (!checkIfDeviceIsReady(vm, portNo)) { Thread.sleep(SLEEP_TIME) }
|
||||
waitUntilReady(vm, portNo)
|
||||
|
||||
val transStat = getBlockTransferStatus(vm, portNo)
|
||||
val incomingMsg = ByteArray(transStat.first)
|
||||
@@ -48,7 +70,9 @@ object SerialHelper {
|
||||
)
|
||||
|
||||
msgBuffer.write(incomingMsg)
|
||||
} while (getBlockTransferStatus(vm, portNo).second)
|
||||
} while (transStat.second)
|
||||
|
||||
getReady(vm, portNo)
|
||||
|
||||
return msgBuffer.toByteArray()
|
||||
}
|
||||
@@ -63,7 +87,8 @@ object SerialHelper {
|
||||
}
|
||||
|
||||
fun waitUntilReady(vm: VM, portNo: Int) {
|
||||
while (!checkIfDeviceIsReady(vm, portNo)) { Thread.sleep(SLEEP_TIME) }
|
||||
Thread.sleep(SLEEP_TIME)
|
||||
//while (!checkIfDeviceIsReady(vm, portNo)) { Thread.sleep(SLEEP_TIME) }
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +106,12 @@ object SerialHelper {
|
||||
vm.getIO().mmio_write(4092L + portNo, 0b0110)
|
||||
}
|
||||
|
||||
private fun getReady(vm: VM, portNo: Int) {
|
||||
val flags = vm.getIO().mmio_read(4092L + portNo)!!
|
||||
val newFlags = flags.and(0b1111_1001.toByte()).or(0b0000_0010)
|
||||
vm.getIO().mmio_write(4092L + portNo, newFlags)
|
||||
}
|
||||
|
||||
private fun setBlockTransferStatus(vm: VM, portNo: Int, blockSize: Int, moreToSend: Boolean = false) {
|
||||
vm.getIO().mmio_write(4084L + (portNo * 2), (blockSize and 255).toByte())
|
||||
vm.getIO().mmio_write(4085L + (portNo * 2),
|
||||
@@ -99,4 +130,13 @@ object SerialHelper {
|
||||
private fun Boolean.toInt() = if (this) 1 else 0
|
||||
|
||||
data class DeviceStatus(val isError: Boolean, val code: Int, val message: String)
|
||||
}
|
||||
|
||||
class SerialHelperDelegate(val vm: VM) {
|
||||
fun sendMessage(portNo: Int, message: ByteArray) = SerialHelper.sendMessage(vm, portNo, message)
|
||||
fun pullMessage(portNo: Int) = SerialHelper.pullMessage(vm, portNo)
|
||||
fun sendMessageGetBytes(portNo: Int, message: ByteArray) = SerialHelper.sendMessageGetBytes(vm, portNo, message)
|
||||
fun fetchResponse(portNo: Int) = SerialHelper.fetchResponse(vm, portNo)
|
||||
fun getDeviceStatus(portNo: Int) = SerialHelper.getDeviceStatus(vm, portNo)
|
||||
fun waitUntilReady(portNo: Int) = SerialHelper.waitUntilReady(vm, portNo)
|
||||
}
|
||||
@@ -66,7 +66,8 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter()
|
||||
|
||||
//val fr = FileReader("./assets/tvdos/command.js")
|
||||
//val fr = FileReader("./assets/zippytest.js")
|
||||
val fr = FileReader("./assets/tvdos/fsh.js")
|
||||
val fr = FileReader("./assets/serialtest.js")
|
||||
//val fr = FileReader("./assets/tvdos/fsh.js")
|
||||
//val fr = FileReader("./assets/tbas/basic.js")
|
||||
//val fr = FileReader("./assets/jscon.js")
|
||||
val prg = fr.readText()
|
||||
|
||||
@@ -100,6 +100,7 @@ class VMJSR223Delegate(val vm: VM) {
|
||||
}
|
||||
|
||||
class VMSerialDebugger(val vm: VM) {
|
||||
fun print(s: String) = System.out.print(s)
|
||||
fun println(s: String) = System.out.println(s)
|
||||
fun printerr(s: String) = System.err.println(s)
|
||||
}
|
||||
@@ -79,6 +79,7 @@ object VMRunnerFactory {
|
||||
bind.put("serial", VMSerialDebugger(vm))
|
||||
bind.put("gzip", CompressorDelegate())
|
||||
bind.put("base64", Base64Delegate())
|
||||
bind.put("com", SerialHelperDelegate(vm))
|
||||
|
||||
if (extension == "js") {
|
||||
val fr = FileReader("./assets/JS_INIT.js")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.torvald.tsvm.peripheral
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolean) {
|
||||
|
||||
protected var recipient: BlockTransferInterface? = null
|
||||
@@ -23,7 +25,7 @@ abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolea
|
||||
abstract fun startSend()
|
||||
/** The actual implementation */
|
||||
protected fun startSend(sendfun: ((BlockTransferInterface) -> Unit)? = null) {
|
||||
if (areYouReady()) {
|
||||
//if (areYouReady()) {
|
||||
busy = true
|
||||
ready = false
|
||||
|
||||
@@ -33,13 +35,16 @@ abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolea
|
||||
|
||||
busy = false
|
||||
ready = true
|
||||
}
|
||||
//}
|
||||
//else {
|
||||
// throw IOException("${this.javaClass.canonicalName}: Device '${recipient?.javaClass?.canonicalName}' is not ready to receive")
|
||||
//}
|
||||
}
|
||||
|
||||
/** Ask the recipient to start send its thing to me so that I can 'read'
|
||||
*/
|
||||
open fun startRead() {
|
||||
recipient?.startSend(null)
|
||||
recipient?.startSend()
|
||||
}
|
||||
|
||||
/** A method called by the sender so it can ACTUALLY write its thing onto me. */
|
||||
|
||||
@@ -12,19 +12,30 @@ class BlockTransferPort(val vm: VM, val portno: Int) : BlockTransferInterface(tr
|
||||
|
||||
override fun startSend() {
|
||||
startSend { recipient ->
|
||||
val ba = ByteArray(BLOCK_SIZE) { vm.getIO().blockTransferRx[portno][it.toLong()] }
|
||||
val ba = ByteArray(BLOCK_SIZE) { vm.getIO().blockTransferTx[portno][it.toLong()] }
|
||||
recipient.writeout(ba)
|
||||
}
|
||||
|
||||
this.ready = true
|
||||
this.busy = false
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = hasNext
|
||||
|
||||
override fun writeout(inputData: ByteArray) {
|
||||
writeout(inputData) {
|
||||
val copySize = minOf(BLOCK_SIZE, inputData.size).toLong()
|
||||
val arrayOffset = UnsafeHelper.getArrayOffset(inputData)
|
||||
UnsafeHelper.memcpyRaw(inputData, arrayOffset, null, vm.getIO().blockTransferRx[portno].ptr, copySize)
|
||||
//val copySize = minOf(BLOCK_SIZE, inputData.size).toLong()
|
||||
//val arrayOffset = UnsafeHelper.getArrayOffset(inputData)
|
||||
//UnsafeHelper.memcpyRaw(inputData, arrayOffset, null, vm.getIO().blockTransferRx[portno].ptr, copySize)
|
||||
|
||||
// not exposing raw memory to block probable security hole
|
||||
for (k in 0 until BLOCK_SIZE) {
|
||||
vm.getIO().blockTransferRx[portno][k.toLong()] = if (k >= inputData.size) 0 else inputData[k]
|
||||
}
|
||||
}
|
||||
|
||||
this.ready = true
|
||||
this.busy = false
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
|
||||
private val keyEventBuffers = ByteArray(8)
|
||||
|
||||
init {
|
||||
//blockTransferPorts[0].attachDevice(TestFunctionGenerator())
|
||||
blockTransferPorts[0].attachDevice(TestDiskDrive(0))
|
||||
blockTransferPorts[0].attachDevice(TestFunctionGenerator())
|
||||
blockTransferPorts[1].attachDevice(TestDiskDrive(0))
|
||||
}
|
||||
|
||||
private fun composeBlockTransferStatus(portno: Int): Int {
|
||||
@@ -55,10 +55,14 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
|
||||
blockTransferPorts[portno].setMode(bits.and(0b0000_1000) != 0.toByte())
|
||||
blockTransferPorts[portno].ready = bits.and(0b0000_0010) != 0.toByte()
|
||||
if (bits.and(0b0000_0100) != 0.toByte()) {
|
||||
if (blockTransferPorts[portno].getMode())
|
||||
if (blockTransferPorts[portno].getMode()) {
|
||||
println("[IOSpace] startSend()")
|
||||
blockTransferPorts[portno].startSend()
|
||||
else
|
||||
}
|
||||
else {
|
||||
println("[IOSpace] startRead()")
|
||||
blockTransferPorts[portno].startRead()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.torvald.tsvm.peripheral
|
||||
|
||||
import net.torvald.tsvm.VM
|
||||
import java.util.ArrayList
|
||||
|
||||
class TestFunctionGenerator : BlockTransferInterface(true, false) {
|
||||
@@ -33,16 +34,16 @@ Nunc mollis nibh vitae sapien consequat, ut vestibulum sem pharetra. Aliquam iac
|
||||
}
|
||||
|
||||
override fun startSend() {
|
||||
if (readModeLength > 0) {
|
||||
readModeLength = 0
|
||||
startSend { it.writeout(filecontent_lorem) }
|
||||
}
|
||||
println("[TestFunctionGenerator] startSend()")
|
||||
startSend { it.writeout(filecontent_lorem) }
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = false
|
||||
|
||||
override fun writeout(inputData: ByteArray) {
|
||||
val inputString = inputData.toString()
|
||||
val inputString = inputData.toString(VM.CHARSET)
|
||||
|
||||
println("InputString: $inputString")
|
||||
|
||||
if (inputString.startsWith("DEVRST\u0017")) {
|
||||
readModeLength = -1
|
||||
@@ -50,8 +51,10 @@ Nunc mollis nibh vitae sapien consequat, ut vestibulum sem pharetra. Aliquam iac
|
||||
}
|
||||
else if (inputString.startsWith("DEVTYP\u0017"))
|
||||
startSend { it.writeout(composeSerialAns("STOR")) }
|
||||
else if (inputString.startsWith("DEVNAM\u0017"))
|
||||
else if (inputString.startsWith("DEVNAM\u0017")) {
|
||||
println("Device name?")
|
||||
startSend { it.writeout(composeSerialAns("Testtec Virtual Disk Drive")) }
|
||||
}
|
||||
else if (inputString.startsWith("OPENR\""))
|
||||
fileOpen = true
|
||||
else if (inputString.startsWith("CLOSE"))
|
||||
|
||||
@@ -101,7 +101,7 @@ MMIO
|
||||
|
||||
a: 1 for send, 0 for receive
|
||||
|
||||
b-write: 1 to start sending if a-bit is set; if f-bit is unset, make other device to start sending
|
||||
b-write: 1 to start sending if a-bit is set; if a-bit is unset, make other device to start sending
|
||||
b-read: if this bit is set, you're currently receiving something (aka busy)
|
||||
|
||||
c-write: I'm ready to receive
|
||||
|
||||
Reference in New Issue
Block a user