mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-12 15:44:05 +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)+"38;5;"+fore+"m");
|
||||||
print(String.fromCharCode(27,91)+"48;5;"+back+"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);
|
Object.freeze(con);
|
||||||
// system management function
|
// system management function
|
||||||
var system = {};
|
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)
|
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
|
* 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()
|
val bios = fr1.readText()
|
||||||
fr1.close()
|
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/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 fr = FileReader("./assets/jscon.js")
|
||||||
val prg = fr.readText()
|
val prg = fr.readText()
|
||||||
fr.close()
|
fr.close()
|
||||||
|
|
||||||
vmRunner = VMRunnerFactory(vm, "js")
|
vmRunner = VMRunnerFactory(vm, "js")
|
||||||
coroutineJob = GlobalScope.launch {
|
coroutineJob = GlobalScope.launch {
|
||||||
vmRunner.executeCommand(sanitiseJS(bios))
|
vmRunner.evalGlobal(bios + "\n" + tvgl)
|
||||||
vmRunner.executeCommand(sanitiseJS(prg))
|
vmRunner.executeCommand(prg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import kotlin.test.assertNotNull
|
|||||||
abstract class VMRunner(val extension: String) {
|
abstract class VMRunner(val extension: String) {
|
||||||
|
|
||||||
abstract suspend fun executeCommand(command: 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) {
|
override suspend fun executeCommand(command: String) {
|
||||||
vmLua.lua.load(command).call()
|
vmLua.lua.load(command).call()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun evalGlobal(command: String) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"vt2" -> {
|
"vt2" -> {
|
||||||
@@ -47,6 +52,10 @@ object VMRunnerFactory {
|
|||||||
override suspend fun executeCommand(command: String) {
|
override suspend fun executeCommand(command: String) {
|
||||||
engine.eval(command)
|
engine.eval(command)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun evalGlobal(command: String) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -76,7 +85,11 @@ object VMRunnerFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun executeCommand(command: String) {
|
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', ' ')
|
private fun toSingleLine(code: String) = code.replace(Regex("//[^\\n]*"), "").replace('\n', ' ')
|
||||||
fun sanitiseJS(code: String) = "eval('${toSingleLine(code).replace("\\", "\\\\")}')"
|
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) {
|
override fun eraseInDisp(arg: Int) {
|
||||||
when (arg) {
|
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()
|
else -> TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,6 +224,8 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
|
|||||||
val wordsUpper = stmtUpper.split(reTokenizer)
|
val wordsUpper = stmtUpper.split(reTokenizer)
|
||||||
|
|
||||||
if (stmtUpper.startsWith("SCENE_")) { // indexed scene
|
if (stmtUpper.startsWith("SCENE_")) { // indexed scene
|
||||||
|
if (currentScene != 0L) throw IllegalStateException("Line $lnum: Scenes cannot be nested")
|
||||||
|
|
||||||
val scenenumStr = stmt.substring(6)
|
val scenenumStr = stmt.substring(6)
|
||||||
try {
|
try {
|
||||||
val scenenum = scenenumStr.toLong()
|
val scenenum = scenenumStr.toLong()
|
||||||
@@ -235,6 +237,8 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (stmtUpper.startsWith("SCENE ")) { // named scene
|
else if (stmtUpper.startsWith("SCENE ")) { // named scene
|
||||||
|
if (currentScene != 0L) throw IllegalStateException("Line $lnum: Scenes cannot be nested")
|
||||||
|
|
||||||
val sceneName = wordsUpper[1]
|
val sceneName = wordsUpper[1]
|
||||||
if (sceneName.isNullOrBlank()) {
|
if (sceneName.isNullOrBlank()) {
|
||||||
throw IllegalArgumentException("Line $lnum: Illegal scene name on $stmt")
|
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
|
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
|
else if (wordsUpper[0] == "END" && wordsUpper[1] == "SCENE") { // END SCENE
|
||||||
if (currentScene == 0L) {
|
if (currentScene == 0L) throw IllegalArgumentException("Line $lnum: END SCENE is called without matching SCENE definition")
|
||||||
throw IllegalArgumentException("Line $lnum: END SCENE is called without matching SCENE definition")
|
|
||||||
}
|
|
||||||
|
|
||||||
scenes[currentScene] = sceneStatements.toTypedArray()
|
scenes[currentScene] = sceneStatements.toTypedArray()
|
||||||
|
|
||||||
@@ -532,7 +534,7 @@ object Command {
|
|||||||
instance.sleepLatch = true
|
instance.sleepLatch = true
|
||||||
|
|
||||||
val timeTook = (System.nanoTime() - instance.performanceCounterTmr).toDouble()
|
val timeTook = (System.nanoTime() - instance.performanceCounterTmr).toDouble()
|
||||||
instance.statsFrameTime = timeTook / 1000000000.0
|
instance.statsFrameTime = timeTook * 0.000001
|
||||||
instance.performanceCounterTmr = System.nanoTime()
|
instance.performanceCounterTmr = System.nanoTime()
|
||||||
}
|
}
|
||||||
instSet[CMP shr 3] = { instance, args -> // CMP rA rB rC
|
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
|
write to this address FIRST and then write to "command" to execute the command
|
||||||
86 bytes
|
86 bytes
|
||||||
*Unused*
|
*Unused*
|
||||||
IF graphics_mode THEN
|
IF hires_text THEN
|
||||||
(41 sprites : 260 bytes each -> 10660 bytes)
|
418 bytes
|
||||||
0th sprite is always the GUI cursor
|
*Unused*
|
||||||
2 bytes
|
2 bytes
|
||||||
Ob hv0000xy yyyyyyyy (h: horizontal flip, v: vertical flip, x: show/hide, y: y-position)
|
Cursor position in: (y*64 + x)
|
||||||
2 bytes
|
5120 bytes
|
||||||
0b rr0000xx xxxxxxxx (r: rotation, x: x-position)
|
Text fore/back colours, 16 colours, LSB is foreground
|
||||||
256 bytes
|
5120 bytes
|
||||||
16x16 texture for the sprite
|
Text buffer of 80x64 (7x7 character size)
|
||||||
ELSE
|
ELSE
|
||||||
2978 bytes
|
2978 bytes
|
||||||
*Unused*
|
*Unused*
|
||||||
@@ -155,12 +155,24 @@ ELSE
|
|||||||
2560 bytes
|
2560 bytes
|
||||||
Text background colours
|
Text background colours
|
||||||
2560 bytes
|
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
|
FI
|
||||||
512 bytes
|
512 bytes
|
||||||
Palette stored in following pattern: 0b rrrr gggg, 0b bbbb aaaa, ....
|
Palette stored in following pattern: 0b rrrr gggg, 0b bbbb aaaa, ....
|
||||||
Palette number 255 is always full transparent (bits being all zero)
|
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
|
MMIO
|
||||||
|
|
||||||
0..1 RO
|
0..1 RO
|
||||||
|
|||||||
Reference in New Issue
Block a user