mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
some random shits
This commit is contained in:
BIN
FontROM7x14.kra
BIN
FontROM7x14.kra
Binary file not shown.
BIN
FontROM7x7.kra
LFS
Normal file
BIN
FontROM7x7.kra
LFS
Normal file
Binary file not shown.
@@ -60,6 +60,12 @@ con.color_pair = function(fore, back) { // 0..255
|
||||
print(String.fromCharCode(27,91)+"38;5;"+fore+"m");
|
||||
print(String.fromCharCode(27,91)+"48;5;"+back+"m");
|
||||
};
|
||||
con.clear = function() {
|
||||
print(String.fromCharCode(27,91)+"2J");
|
||||
};
|
||||
con.curs_set = function(arg) {
|
||||
print(String.fromCharCode(27,91)+"?25"+((arg == 0) ? "l" : "h"));
|
||||
};
|
||||
Object.freeze(con);
|
||||
// system management function
|
||||
var system = {};
|
||||
|
||||
10
assets/tvdos/fsh.js
Normal file
10
assets/tvdos/fsh.js
Normal file
@@ -0,0 +1,10 @@
|
||||
graphics.setBackground(3,3,3);
|
||||
|
||||
var _fsh = {};
|
||||
_fsh.titlebartex = new GL.Tex(2, 14, [254, 239, 254, 254, 253, 254, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 253, 253, 252, 252, 252, 252, 251, 251, 251]);
|
||||
|
||||
GL.drawTexPattern(_fsh.titlebartex, 0, 0, 560, 14);
|
||||
|
||||
con.color_pair(254, 255);
|
||||
con.clear();
|
||||
con.curs_set(0);
|
||||
26
assets/tvdos/gl.js
Normal file
26
assets/tvdos/gl.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
TVDOS Graphics Library
|
||||
|
||||
Has no affiliation with OpenGL by Khronos Group
|
||||
*/
|
||||
|
||||
var GL = {};
|
||||
GL.Tex = function(w, h, bytes) {
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
this.texData = bytes;
|
||||
};
|
||||
GL.drawTexPattern = function(tex, x, y, width, height) {
|
||||
for (var yy = 0; yy < height; yy++) {
|
||||
for (var xx = 0; xx < width; xx++) {
|
||||
var tx = xx % tex.width;
|
||||
var ty = yy % tex.height;
|
||||
var c = tex.texData[ty * tex.width + tx];
|
||||
graphics.plotPixel(x + xx, y + yy, c);
|
||||
}
|
||||
}
|
||||
};
|
||||
GL.drawTexImage = function(tex, x, y) {
|
||||
GL.drawTexPattern(tex, x, y, tex.width, tex.height);
|
||||
};
|
||||
Object.freeze(GL);
|
||||
BIN
shell_mockup.kra
LFS
Normal file
BIN
shell_mockup.kra
LFS
Normal file
Binary file not shown.
@@ -65,6 +65,20 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
return intArrayOf(-1, -1)
|
||||
}
|
||||
|
||||
fun setBackground(r: Int, g: Int, b: Int) {
|
||||
getFirstGPU()?.let {
|
||||
it.poke(250880, r.toByte())
|
||||
it.poke(250881, g.toByte())
|
||||
it.poke(250882, b.toByte())
|
||||
}
|
||||
}
|
||||
|
||||
fun clearText() {
|
||||
getFirstGPU()?.let {
|
||||
it.eraseInDisp(2)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* prints a char as-is; won't interpret them as an escape sequence
|
||||
*/
|
||||
|
||||
@@ -58,16 +58,23 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter()
|
||||
val bios = fr1.readText()
|
||||
fr1.close()
|
||||
|
||||
|
||||
val fr2 = FileReader("./assets/tvdos/gl.js")
|
||||
val tvgl = fr2.readText()
|
||||
fr2.close()
|
||||
|
||||
|
||||
//val fr = FileReader("./assets/tvdos/command.js")
|
||||
val fr = FileReader("./assets/tbas/basic.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()
|
||||
fr.close()
|
||||
|
||||
vmRunner = VMRunnerFactory(vm, "js")
|
||||
coroutineJob = GlobalScope.launch {
|
||||
vmRunner.executeCommand(sanitiseJS(bios))
|
||||
vmRunner.executeCommand(sanitiseJS(prg))
|
||||
vmRunner.evalGlobal(bios + "\n" + tvgl)
|
||||
vmRunner.executeCommand(prg)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import kotlin.test.assertNotNull
|
||||
abstract class VMRunner(val extension: String) {
|
||||
|
||||
abstract suspend fun executeCommand(command: String)
|
||||
abstract suspend fun evalGlobal(command: String)
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +37,10 @@ object VMRunnerFactory {
|
||||
override suspend fun executeCommand(command: String) {
|
||||
vmLua.lua.load(command).call()
|
||||
}
|
||||
|
||||
override suspend fun evalGlobal(command: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
"vt2" -> {
|
||||
@@ -47,6 +52,10 @@ object VMRunnerFactory {
|
||||
override suspend fun executeCommand(command: String) {
|
||||
engine.eval(command)
|
||||
}
|
||||
|
||||
override suspend fun evalGlobal(command: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
@@ -76,7 +85,11 @@ object VMRunnerFactory {
|
||||
}
|
||||
|
||||
override suspend fun executeCommand(command: String) {
|
||||
engine.eval("\"use strict\";{$command}", context)
|
||||
engine.eval("\"use strict\";" + sanitiseJS(toSingleLine(command)), context)
|
||||
}
|
||||
|
||||
override suspend fun evalGlobal(command: String) {
|
||||
engine.eval("\"use strict\";" + toSingleLine(command), context)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,7 +97,8 @@ object VMRunnerFactory {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun toSingleLine(code: String) = code.replace(Regex("//[^\\n]*"), "").replace('\n', ' ')
|
||||
fun sanitiseJS(code: String) = "eval('${toSingleLine(code).replace("\\", "\\\\")}')"
|
||||
private fun toSingleLine(code: String) = code.replace(Regex("//[^\\n]*"), "").replace('\n', ' ')
|
||||
private fun sanitiseJS(code: String) = "eval('${toSingleLine(code).replace("\\", "\\\\")}')"
|
||||
|
||||
}
|
||||
|
||||
@@ -276,6 +276,16 @@ class GraphicsAdapter(val vm: VM, val lcdMode: Boolean = false, lcdInvert: Boole
|
||||
|
||||
override fun eraseInDisp(arg: Int) {
|
||||
when (arg) {
|
||||
2 -> {
|
||||
val foreBits = ttyFore or ttyFore.shl(8) or ttyFore.shl(16) or ttyFore.shl(24)
|
||||
val backBits = ttyBack or ttyBack.shl(8) or ttyBack.shl(16) or ttyBack.shl(24)
|
||||
for (i in 0 until TEXT_COLS * TEXT_ROWS step 4) {
|
||||
spriteAndTextArea.setInt(memTextForeOffset + i, foreBits)
|
||||
spriteAndTextArea.setInt(memTextBackOffset + i, backBits)
|
||||
spriteAndTextArea.setInt(memTextOffset + i, -1)
|
||||
}
|
||||
spriteAndTextArea.setShort(memTextCursorPosOffset, 0)
|
||||
}
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,6 +224,8 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
|
||||
val wordsUpper = stmtUpper.split(reTokenizer)
|
||||
|
||||
if (stmtUpper.startsWith("SCENE_")) { // indexed scene
|
||||
if (currentScene != 0L) throw IllegalStateException("Line $lnum: Scenes cannot be nested")
|
||||
|
||||
val scenenumStr = stmt.substring(6)
|
||||
try {
|
||||
val scenenum = scenenumStr.toLong()
|
||||
@@ -235,6 +237,8 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
|
||||
}
|
||||
}
|
||||
else if (stmtUpper.startsWith("SCENE ")) { // named scene
|
||||
if (currentScene != 0L) throw IllegalStateException("Line $lnum: Scenes cannot be nested")
|
||||
|
||||
val sceneName = wordsUpper[1]
|
||||
if (sceneName.isNullOrBlank()) {
|
||||
throw IllegalArgumentException("Line $lnum: Illegal scene name on $stmt")
|
||||
@@ -246,9 +250,7 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
|
||||
currentScene = registerNewVariable(sceneName) // scenes use same addr space as vars, to make things easier on the backend
|
||||
}
|
||||
else if (wordsUpper[0] == "END" && wordsUpper[1] == "SCENE") { // END SCENE
|
||||
if (currentScene == 0L) {
|
||||
throw IllegalArgumentException("Line $lnum: END SCENE is called without matching SCENE definition")
|
||||
}
|
||||
if (currentScene == 0L) throw IllegalArgumentException("Line $lnum: END SCENE is called without matching SCENE definition")
|
||||
|
||||
scenes[currentScene] = sceneStatements.toTypedArray()
|
||||
|
||||
@@ -532,7 +534,7 @@ object Command {
|
||||
instance.sleepLatch = true
|
||||
|
||||
val timeTook = (System.nanoTime() - instance.performanceCounterTmr).toDouble()
|
||||
instance.statsFrameTime = timeTook / 1000000000.0
|
||||
instance.statsFrameTime = timeTook * 0.000001
|
||||
instance.performanceCounterTmr = System.nanoTime()
|
||||
}
|
||||
instSet[CMP shr 3] = { instance, args -> // CMP rA rB rC
|
||||
|
||||
@@ -136,15 +136,15 @@ From the start of the memory space:
|
||||
write to this address FIRST and then write to "command" to execute the command
|
||||
86 bytes
|
||||
*Unused*
|
||||
IF graphics_mode THEN
|
||||
(41 sprites : 260 bytes each -> 10660 bytes)
|
||||
0th sprite is always the GUI cursor
|
||||
IF hires_text THEN
|
||||
418 bytes
|
||||
*Unused*
|
||||
2 bytes
|
||||
Ob hv0000xy yyyyyyyy (h: horizontal flip, v: vertical flip, x: show/hide, y: y-position)
|
||||
2 bytes
|
||||
0b rr0000xx xxxxxxxx (r: rotation, x: x-position)
|
||||
256 bytes
|
||||
16x16 texture for the sprite
|
||||
Cursor position in: (y*64 + x)
|
||||
5120 bytes
|
||||
Text fore/back colours, 16 colours, LSB is foreground
|
||||
5120 bytes
|
||||
Text buffer of 80x64 (7x7 character size)
|
||||
ELSE
|
||||
2978 bytes
|
||||
*Unused*
|
||||
@@ -155,12 +155,24 @@ ELSE
|
||||
2560 bytes
|
||||
Text background colours
|
||||
2560 bytes
|
||||
Text buffer of 70x32 (8x14 character size, and yes: actual character data is on the bottom)
|
||||
Text buffer of 80x32 (7x14 character size, and yes: actual character data is on the bottom)
|
||||
FI
|
||||
512 bytes
|
||||
Palette stored in following pattern: 0b rrrr gggg, 0b bbbb aaaa, ....
|
||||
Palette number 255 is always full transparent (bits being all zero)
|
||||
|
||||
Optional Sprite Card
|
||||
16 bytes
|
||||
Reserved
|
||||
65520 bytes:
|
||||
(0th sprite is always the GUI cursor, thus 251 sprites)
|
||||
2 bytes
|
||||
Ob hv000pxy yyyyyyyy (p: 0 for above-text, 1 for below-text, h: horizontal flip, v: vertical flip, x: show/hide, y: y-position)
|
||||
2 bytes
|
||||
0b rr0000xx xxxxxxxx (r: rotation, x: x-position)
|
||||
256 bytes
|
||||
16x16 texture for the sprite
|
||||
|
||||
MMIO
|
||||
|
||||
0..1 RO
|
||||
|
||||
Reference in New Issue
Block a user