some random shits

This commit is contained in:
minjaesong
2020-09-20 21:29:26 +09:00
parent 75fa682735
commit 50b567d9ce
12 changed files with 127 additions and 20 deletions

Binary file not shown.

BIN
FontROM7x7.kra LFS Normal file

Binary file not shown.

View File

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

Binary file not shown.

View File

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

View File

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

View File

@@ -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("\\", "\\\\")}')"
}

View File

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

View File

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

View File

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