diff --git a/assets/disk0/tvdos/TVDOS.SYS b/assets/disk0/tvdos/TVDOS.SYS index 52e51d1..dd6255a 100644 --- a/assets/disk0/tvdos/TVDOS.SYS +++ b/assets/disk0/tvdos/TVDOS.SYS @@ -723,11 +723,24 @@ Object.freeze(_TVDOS.DRV.FS.DEVCON) /////////////////////////////////////////////////////////////////////////////// +let mkvtcontext = (index, VMEM) => { + return { // VT0 is reserved for symlink to physical terminal + isActive: (index === 0 || index === "0"), + buffer: (index === 0 || index === "0") ? undefined : VMEM + // TODO: getCursorYX, setCursorYX, setCursorX, setCursorY, getTextForeBack, setTextFore, setTextBack + // all read/write form the VMEM + } +} + // byte-to-byte copy of the 512 KB of VRAM function mkdevvt(index) { +// VT0 is reserved for symlink to the physical terminal +if (isNaN(index)) return false // check for non-numerics and undefined +if (index !== index || index <= 0) return false // check for NaN, 0 and negative values + // check if the device already exists -if (_TVDOS.DRV.FS['DEV'+index] != undefined) return false +if (_TVDOS.DRV.FS['DEVVT'+index] != undefined) return false let VDEV = {} let VMEM = new Int8Array(512 * 1024) @@ -782,6 +795,7 @@ VDEV.mkFile = () => {} VDEV.remove = () => {} VDEV.exists = () => true +_TVDOS.VT_CONTEXTS[index] = mkvtcontext(index, VMEM) _TVDOS.DRV.FS['DEVVT'+index] = VDEV Object.freeze(_TVDOS.DRV.FS['DEVVT'+index]) @@ -846,6 +860,9 @@ _TVDOS.DRV.FS.DEVPT.mkDir = () => {} _TVDOS.DRV.FS.DEVPT.mkFile = () => {} _TVDOS.DRV.FS.DEVPT.remove = () => {} _TVDOS.DRV.FS.DEVPT.exists = () => true + +mkvtcontext(0) + Object.freeze(_TVDOS.DRV.FS.DEVPT) /////////////////////////////////////////////////////////////////////////////// diff --git a/assets/disk0/tvdos/hyve.SYS b/assets/disk0/tvdos/hyve.SYS index a817c84..04b707b 100644 --- a/assets/disk0/tvdos/hyve.SYS +++ b/assets/disk0/tvdos/hyve.SYS @@ -56,11 +56,33 @@ let runner = undefined function startNewInstance() { runner = parallel.attachProgram("TVDOS", parallel.spawnNewContext(), bios) + serial.println("Starting new instance "+runner) + parallel.launch(runner) sys.sleep(1000) } +function startNewInstanceOnVT(vtIndex) { + if (isNaN(index) || index !== index) throw Error("VT index must be a numeric value") + if (index <= 0) throw Error(`VT index cannot be zero or negative (${vtIndex})`) + + // Ensure VT exists + if (!_TVDOS.VT_CONTEXTS[vtIndex]) { + mkdevvt(vtIndex) + } + + // Create context with VT binding + let contextInit = `_TVDOS.CURRENT_VT = ${vtIndex};${bios}` + + runner = parallel.attachProgram(`TVDOS-VT${vtIndex}`, parallel.spawnNewContext(), contextInit) + + serial.println(`Starting new instance ${runner} on VT${vtIndex}`) + + parallel.launch(runner) + sys.sleep(50) +} + const randomkeypusher = ` while (1) { sys.poke(-38, 65 + (Math.random()*26)|0) diff --git a/tsvm_core/src/net/torvald/tsvm/JS_INIT.js b/tsvm_core/src/net/torvald/tsvm/JS_INIT.js index a9caea7..bb67f80 100644 --- a/tsvm_core/src/net/torvald/tsvm/JS_INIT.js +++ b/tsvm_core/src/net/torvald/tsvm/JS_INIT.js @@ -456,7 +456,11 @@ con.move = function(y, x) { //print("\x1B["+(y|0)+";"+(x|0)+"H"); // NOT using ANSI escape sequence as it conflicts with some multilingual drive which redefines PRINT function // and obviously this method is faster albeit less genuine :p - graphics.setCursorYX(y|0, x|0); + + let activeVT = _TVDOS.ACTIVE_VT || 0 // 0 is physical terminal + let vt = _TVDOS.VT_CONTEXTS[activeVT] + + vt.setCursorYX(y|0, x|0) }; con.addch = function(c) { graphics.putSymbol(c|0); @@ -474,22 +478,25 @@ con.getmaxyx = function() { return graphics.getTermDimension(); // [rows, cols] }; con.getyx = function() { - return graphics.getCursorYX(); + let activeVT = _TVDOS.ACTIVE_VT || 0 // 0 is physical terminal + let vt = _TVDOS.VT_CONTEXTS[activeVT] + + return vt.getCursorYX() }; con.curs_up = function() { - let [y,x] = graphics.getCursorYX(); + let [y,x] = con.getyx(); con.move(y-1,x); }; con.curs_down = function() { - let [y,x] = graphics.getCursorYX(); + let [y,x] = con.getyx(); con.move(y+1,x); }; con.curs_left = function() { - let [y,x] = graphics.getCursorYX(); + let [y,x] = con.getyx(); con.move(y,x-1); }; con.curs_right = function() { - let [y,x] = graphics.getCursorYX(); + let [y,x] = con.getyx(); con.move(y,x+1); }; con.hitterminate = function() { // ^C diff --git a/tsvm_core/src/net/torvald/tsvm/VM.kt b/tsvm_core/src/net/torvald/tsvm/VM.kt index df39501..048f041 100644 --- a/tsvm_core/src/net/torvald/tsvm/VM.kt +++ b/tsvm_core/src/net/torvald/tsvm/VM.kt @@ -4,6 +4,7 @@ import net.torvald.UnsafeHelper import net.torvald.UnsafePtr import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toHex import net.torvald.tsvm.peripheral.* +import org.graalvm.polyglot.Context import java.io.InputStream import java.io.OutputStream import java.nio.charset.Charset @@ -67,6 +68,51 @@ class VM( var stopDown = false var sysrqDown = false + + private var currentContext: Context? = null + + fun setCurrentJSContext(context: Context) { + currentContext = context + } + + private fun getCurrentJSContext(): Context { + return currentContext ?: throw IllegalStateException("No JavaScript context available") + } + + + + // VT tracking of the VM + private var currentVTIndex = 0 // default to physical terminal + private val vtOutputStream = mutableMapOf() + private val vtInputStream = mutableMapOf() + + fun getCurrentVT(): Int { + // try to read from JS context + try { + val context = getCurrentJSContext() + val currentVT = context.eval("js", "_TVDOS.CURRENT_VT || 0").asInt() + return currentVT + } + catch (e: Exception) { + return currentVTIndex + } + } + + fun setCurrentVT(vtIndex: Int) { + currentVTIndex = vtIndex + // Also update JavaScript context if available + try { + val context = getCurrentJSContext() + context.eval("js", "_TVDOS.CURRENT_VT = $vtIndex") + } + catch (e: Exception) { + // Context not available, continue with local tracking + } + } + + + + var romMapping = 255 internal set diff --git a/tsvm_core/src/net/torvald/tsvm/VMJSR223Delegate.kt b/tsvm_core/src/net/torvald/tsvm/VMJSR223Delegate.kt index ef57828..96b6c5e 100644 --- a/tsvm_core/src/net/torvald/tsvm/VMJSR223Delegate.kt +++ b/tsvm_core/src/net/torvald/tsvm/VMJSR223Delegate.kt @@ -143,14 +143,16 @@ class VMJSR223Delegate(private val vm: VM) { } fun print(s: Any) { - //System.out.print("[Nashorn] $s") - //System.out.print(s) - vm.getPrintStream().write("$s".toByteArray(VM.CHARSET)) + //vm.getPrintStream().write("$s".toByteArray(VM.CHARSET)) + val vtIndex = vm.getCurrentVT() // Get current VT from VM context + val outputStream = vm.getVTOutputStream(vtIndex) + outputStream.write("$s".toByteArray(VM.CHARSET)) } fun println(s: Any = "") { - System.out.println("[Graal] $s") - //System.out.println(s) - vm.getPrintStream().write(("$s\n").toByteArray(VM.CHARSET)) + //vm.getPrintStream().write(("$s\n").toByteArray(VM.CHARSET)) + val vtIndex = vm.getCurrentVT() // Get current VT from VM context + val outputStream = vm.getVTOutputStream(vtIndex) + outputStream.write("$s\n".toByteArray(VM.CHARSET)) } /** diff --git a/tsvm_core/src/net/torvald/tsvm/VMRunnerFactory.kt b/tsvm_core/src/net/torvald/tsvm/VMRunnerFactory.kt index 2604c5c..33a0cb5 100644 --- a/tsvm_core/src/net/torvald/tsvm/VMRunnerFactory.kt +++ b/tsvm_core/src/net/torvald/tsvm/VMRunnerFactory.kt @@ -80,6 +80,9 @@ object VMRunnerFactory { val fr = this::class.java.classLoader.getResourceAsStream("net/torvald/tsvm/JS_INIT.js") val prg = fr.readAllBytes().decodeToString() + + vm.setCurrentJSContext(context) + context.eval("js", sanitiseJS(prg)) }