diff --git a/assets/tbas/basic.js b/assets/tbas/basic.js index bd123d9..8456324 100644 --- a/assets/tbas/basic.js +++ b/assets/tbas/basic.js @@ -123,12 +123,12 @@ function parseSigil(s) { function resolve(variable) { if (variable.type == "string" || variable.type == "number") return variable.value; - else if (variable.type == "literal") { + else if (variable.type == "literal") return basicInterpreterStatus.variables[parseSigil(variable.value).name].literal; - } - else { + else if (variable.type == "null") + return undefined; + else throw "InternalError: unknown variable with type "+variable.type+", with value "+variable.value - } } var basicInterpreterStatus = {}; basicInterpreterStatus.gosubStack = []; @@ -237,11 +237,33 @@ basicInterpreterStatus.builtin = { if (args.length == 0) println(); - else - println(args.map(function(it) { - var it2 = resolve(it); - return ((!isNaN(it2)) ? " " : "") + it2; // BASIC always put a space before a number - }).join("\t")); + else { + if (args[args.length - 1].type == "null") { + print(args.slice(0, args.length - 1).map(function(it) { + var it2 = resolve(it); + return ((!isNaN(it2)) ? " " : "") + it2; // BASIC always put a space before a number + }).join("\t")); + } + else { + println(args.map(function(it) { + var it2 = resolve(it); + return ((!isNaN(it2)) ? " " : "") + it2; // BASIC always put a space before a number + }).join("\t")); + } + } +}, +"EMIT" : function(lnum, args) { + if (args.length > 0) { + for (var llll = 0; llll < args.length; llll++) { + var lvalll = resolve(args[llll]); + if (isNaN(lvalll)) { + print(lvalll); + } + else { + con.addch(lvalll); + } + } + } }, "POKE" : function(lnum, args) { if (args.length != 2) throw lang.syntaxfehler(lnum); @@ -1040,7 +1062,7 @@ basicFunctions._executeSyntaxTree = function(lnum, syntaxTree, recDepth) { if (_debugExec) serial.println(recWedge+"@@ EXECUTE @@"); if (syntaxTree === undefined) - throw "InternalError: tree is undefined"; + return new SyntaxTreeReturnObj("null", undefined, lnum + 1); else if (syntaxTree.type == "function" || syntaxTree.type == "operator") { if (_debugExec) serial.println(recWedge+"function|operator"); if (_debugExec) serial.println(recWedge+syntaxTree.toString()); diff --git a/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt b/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt index 3a76e4b..d4eca70 100644 --- a/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt +++ b/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt @@ -71,6 +71,8 @@ class GraphicsJSR223Delegate(val vm: VM) { fun putSymbol(char: Byte) { getFirstGPU()?.let { val (cx, cy) = it.getCursorPos() + + it.putChar(cx, cy, char) it.setCursorPos(cx + 1, cy) } diff --git a/src/net/torvald/tsvm/peripheral/GlassTty.kt b/src/net/torvald/tsvm/peripheral/GlassTty.kt index 1eaf772..df1742c 100644 --- a/src/net/torvald/tsvm/peripheral/GlassTty.kt +++ b/src/net/torvald/tsvm/peripheral/GlassTty.kt @@ -34,13 +34,7 @@ abstract class GlassTty(val TEXT_ROWS: Int, val TEXT_COLS: Int) { abstract fun putChar(x: Int, y: Int, text: Byte, foreColour: Byte = ttyFore.toByte(), backColour: Byte = ttyBack.toByte()) fun writeOut(char: Byte) { - // deal with y-axis out-of-bounds - var (cx, cy) = getCursorPos() - if (cy >= TEXT_ROWS) { - scrollUp(cy - TEXT_ROWS + 1) - setCursorPos(cx, TEXT_ROWS - 1) - cy = TEXT_ROWS - 1 - } + val (cx, cy) = getCursorPos() val printable = acceptChar(char) // this function processes the escape codes and CRLFs diff --git a/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt b/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt index 0fee135..7333f3d 100644 --- a/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt +++ b/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt @@ -69,11 +69,7 @@ class GraphicsAdapter(val vm: VM, val lcdMode: Boolean = false, lcdInvert: Boole set(value) { spriteAndTextArea.setShort(memTextCursorPosOffset, value.toShort()) } override fun getCursorPos() = rawCursorPos % TEXT_COLS to rawCursorPos / TEXT_COLS - /** - * Think of it as a real paper tty; - * setCursorPos must "wrap" the cursor properly when x-value goes out of screen bound. - * For y-value, only when y < 0, set y to zero and don't care about the y-value goes out of bound. - */ + override fun setCursorPos(x: Int, y: Int) { var newx = x var newy = y @@ -89,6 +85,11 @@ class GraphicsAdapter(val vm: VM, val lcdMode: Boolean = false, lcdInvert: Boole if (newy < 0) { newy = 0 // DON'T SCROLL when cursor goes ABOVE the screen } + else if (newy >= TEXT_ROWS) { + scrollUp(newy - TEXT_ROWS + 1) + setCursorPos(newy, TEXT_ROWS - 1) + newy = TEXT_ROWS - 1 + } rawCursorPos = toTtyTextOffset(newx, newy) }