SerialHelper would work as intended MINUS the wait function

This commit is contained in:
minjaesong
2020-10-22 14:16:36 +09:00
parent eefc33a8b0
commit d0ef473adc
11 changed files with 110 additions and 27 deletions

14
assets/serialtest.js Normal file
View 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")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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. */

View File

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

View File

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

View File

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

View File

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