mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-12 15:44:05 +09:00
virtual terminal wip
This commit is contained in:
@@ -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
|
// byte-to-byte copy of the 512 KB of VRAM
|
||||||
function mkdevvt(index) {
|
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
|
// 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 VDEV = {}
|
||||||
let VMEM = new Int8Array(512 * 1024)
|
let VMEM = new Int8Array(512 * 1024)
|
||||||
@@ -782,6 +795,7 @@ VDEV.mkFile = () => {}
|
|||||||
VDEV.remove = () => {}
|
VDEV.remove = () => {}
|
||||||
VDEV.exists = () => true
|
VDEV.exists = () => true
|
||||||
|
|
||||||
|
_TVDOS.VT_CONTEXTS[index] = mkvtcontext(index, VMEM)
|
||||||
_TVDOS.DRV.FS['DEVVT'+index] = VDEV
|
_TVDOS.DRV.FS['DEVVT'+index] = VDEV
|
||||||
|
|
||||||
Object.freeze(_TVDOS.DRV.FS['DEVVT'+index])
|
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.mkFile = () => {}
|
||||||
_TVDOS.DRV.FS.DEVPT.remove = () => {}
|
_TVDOS.DRV.FS.DEVPT.remove = () => {}
|
||||||
_TVDOS.DRV.FS.DEVPT.exists = () => true
|
_TVDOS.DRV.FS.DEVPT.exists = () => true
|
||||||
|
|
||||||
|
mkvtcontext(0)
|
||||||
|
|
||||||
Object.freeze(_TVDOS.DRV.FS.DEVPT)
|
Object.freeze(_TVDOS.DRV.FS.DEVPT)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -56,11 +56,33 @@ let runner = undefined
|
|||||||
|
|
||||||
function startNewInstance() {
|
function startNewInstance() {
|
||||||
runner = parallel.attachProgram("TVDOS", parallel.spawnNewContext(), bios)
|
runner = parallel.attachProgram("TVDOS", parallel.spawnNewContext(), bios)
|
||||||
|
|
||||||
serial.println("Starting new instance "+runner)
|
serial.println("Starting new instance "+runner)
|
||||||
|
|
||||||
parallel.launch(runner)
|
parallel.launch(runner)
|
||||||
sys.sleep(1000)
|
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 = `
|
const randomkeypusher = `
|
||||||
while (1) {
|
while (1) {
|
||||||
sys.poke(-38, 65 + (Math.random()*26)|0)
|
sys.poke(-38, 65 + (Math.random()*26)|0)
|
||||||
|
|||||||
@@ -456,7 +456,11 @@ con.move = function(y, x) {
|
|||||||
//print("\x1B["+(y|0)+";"+(x|0)+"H");
|
//print("\x1B["+(y|0)+";"+(x|0)+"H");
|
||||||
// NOT using ANSI escape sequence as it conflicts with some multilingual drive which redefines PRINT function
|
// 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
|
// 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) {
|
con.addch = function(c) {
|
||||||
graphics.putSymbol(c|0);
|
graphics.putSymbol(c|0);
|
||||||
@@ -474,22 +478,25 @@ con.getmaxyx = function() {
|
|||||||
return graphics.getTermDimension(); // [rows, cols]
|
return graphics.getTermDimension(); // [rows, cols]
|
||||||
};
|
};
|
||||||
con.getyx = function() {
|
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() {
|
con.curs_up = function() {
|
||||||
let [y,x] = graphics.getCursorYX();
|
let [y,x] = con.getyx();
|
||||||
con.move(y-1,x);
|
con.move(y-1,x);
|
||||||
};
|
};
|
||||||
con.curs_down = function() {
|
con.curs_down = function() {
|
||||||
let [y,x] = graphics.getCursorYX();
|
let [y,x] = con.getyx();
|
||||||
con.move(y+1,x);
|
con.move(y+1,x);
|
||||||
};
|
};
|
||||||
con.curs_left = function() {
|
con.curs_left = function() {
|
||||||
let [y,x] = graphics.getCursorYX();
|
let [y,x] = con.getyx();
|
||||||
con.move(y,x-1);
|
con.move(y,x-1);
|
||||||
};
|
};
|
||||||
con.curs_right = function() {
|
con.curs_right = function() {
|
||||||
let [y,x] = graphics.getCursorYX();
|
let [y,x] = con.getyx();
|
||||||
con.move(y,x+1);
|
con.move(y,x+1);
|
||||||
};
|
};
|
||||||
con.hitterminate = function() { // ^C
|
con.hitterminate = function() { // ^C
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import net.torvald.UnsafeHelper
|
|||||||
import net.torvald.UnsafePtr
|
import net.torvald.UnsafePtr
|
||||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toHex
|
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toHex
|
||||||
import net.torvald.tsvm.peripheral.*
|
import net.torvald.tsvm.peripheral.*
|
||||||
|
import org.graalvm.polyglot.Context
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@@ -67,6 +68,51 @@ class VM(
|
|||||||
var stopDown = false
|
var stopDown = false
|
||||||
var sysrqDown = 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<Int, OutputStream>()
|
||||||
|
private val vtInputStream = mutableMapOf<Int, InputStream>()
|
||||||
|
|
||||||
|
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
|
var romMapping = 255
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
|
|||||||
@@ -143,14 +143,16 @@ class VMJSR223Delegate(private val vm: VM) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun print(s: Any) {
|
fun print(s: Any) {
|
||||||
//System.out.print("[Nashorn] $s")
|
//vm.getPrintStream().write("$s".toByteArray(VM.CHARSET))
|
||||||
//System.out.print(s)
|
val vtIndex = vm.getCurrentVT() // Get current VT from VM context
|
||||||
vm.getPrintStream().write("$s".toByteArray(VM.CHARSET))
|
val outputStream = vm.getVTOutputStream(vtIndex)
|
||||||
|
outputStream.write("$s".toByteArray(VM.CHARSET))
|
||||||
}
|
}
|
||||||
fun println(s: Any = "") {
|
fun println(s: Any = "") {
|
||||||
System.out.println("[Graal] $s")
|
//vm.getPrintStream().write(("$s\n").toByteArray(VM.CHARSET))
|
||||||
//System.out.println(s)
|
val vtIndex = vm.getCurrentVT() // Get current VT from VM context
|
||||||
vm.getPrintStream().write(("$s\n").toByteArray(VM.CHARSET))
|
val outputStream = vm.getVTOutputStream(vtIndex)
|
||||||
|
outputStream.write("$s\n".toByteArray(VM.CHARSET))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ object VMRunnerFactory {
|
|||||||
|
|
||||||
val fr = this::class.java.classLoader.getResourceAsStream("net/torvald/tsvm/JS_INIT.js")
|
val fr = this::class.java.classLoader.getResourceAsStream("net/torvald/tsvm/JS_INIT.js")
|
||||||
val prg = fr.readAllBytes().decodeToString()
|
val prg = fr.readAllBytes().decodeToString()
|
||||||
|
|
||||||
|
vm.setCurrentJSContext(context)
|
||||||
|
|
||||||
context.eval("js", sanitiseJS(prg))
|
context.eval("js", sanitiseJS(prg))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user