mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
412 lines
10 KiB
Kotlin
412 lines
10 KiB
Kotlin
package net.torvald.tsvm
|
|
|
|
import com.badlogic.gdx.ApplicationAdapter
|
|
import com.badlogic.gdx.Gdx
|
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|
import kotlinx.coroutines.*
|
|
import net.torvald.tsvm.peripheral.GraphicsAdapter
|
|
import java.io.FileReader
|
|
|
|
class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter() {
|
|
|
|
val vm = VM(64.kB(), TheRealWorld())
|
|
lateinit var gpu: GraphicsAdapter
|
|
|
|
lateinit var batch: SpriteBatch
|
|
lateinit var camera: OrthographicCamera
|
|
|
|
lateinit var vmRunner: VMRunner
|
|
|
|
lateinit var coroutineJob: Job
|
|
|
|
lateinit var memvwr: Memvwr
|
|
|
|
override fun create() {
|
|
super.create()
|
|
|
|
gpu = GraphicsAdapter(vm, lcdMode = false)
|
|
|
|
vm.peripheralTable[1] = PeripheralEntry(
|
|
VM.PERITYPE_GPU_AND_TERM,
|
|
gpu,
|
|
GraphicsAdapter.VRAM_SIZE,
|
|
16,
|
|
0
|
|
)
|
|
|
|
batch = SpriteBatch()
|
|
camera = OrthographicCamera(appConfig.width.toFloat(), appConfig.height.toFloat())
|
|
camera.setToOrtho(false)
|
|
camera.update()
|
|
batch.projectionMatrix = camera.combined
|
|
Gdx.gl20.glViewport(0, 0, appConfig.width, appConfig.height)
|
|
|
|
vm.getPrintStream = { gpu.getPrintStream() }
|
|
vm.getErrorStream = { gpu.getErrorStream() }
|
|
vm.getInputStream = { gpu.getInputStream() }
|
|
|
|
memvwr = Memvwr(vm)
|
|
|
|
// TEST PRG
|
|
//val fr = FileReader("./assets/tvdos/command.js")
|
|
//val fr = FileReader("./assets/jscon.js")
|
|
|
|
val fr1 = FileReader("./assets/bios1.js")
|
|
//val fr1 = FileReader("./assets/phototest.js")
|
|
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/zippytest.js")
|
|
val fr = FileReader("./assets/serialtest.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.evalGlobal(bios + "\n" + tvgl)
|
|
vmRunner.executeCommand(prg)
|
|
}
|
|
|
|
|
|
Gdx.input.inputProcessor = vm.getIO()
|
|
}
|
|
|
|
private var updateAkku = 0.0
|
|
private var updateRate = 1f / 60f
|
|
|
|
override fun render() {
|
|
Gdx.graphics.setTitle("${AppLoader.appTitle} $EMDASH F: ${Gdx.graphics.framesPerSecond}")
|
|
|
|
memvwr.update()
|
|
|
|
super.render()
|
|
|
|
val dt = Gdx.graphics.rawDeltaTime
|
|
updateAkku += dt
|
|
|
|
var i = 0L
|
|
while (updateAkku >= updateRate) {
|
|
updateGame(updateRate)
|
|
updateAkku -= updateRate
|
|
i += 1
|
|
}
|
|
|
|
renderGame(dt)
|
|
}
|
|
|
|
private var latch = true
|
|
|
|
private fun updateGame(delta: Float) {
|
|
vm.update(delta)
|
|
}
|
|
|
|
fun poke(addr: Long, value: Byte) = vm.poke(addr, value)
|
|
|
|
private fun renderGame(delta: Float) {
|
|
gpu.render(delta, batch, 0f, 0f)
|
|
|
|
}
|
|
|
|
|
|
override fun dispose() {
|
|
super.dispose()
|
|
batch.dispose()
|
|
coroutineJob.cancel()
|
|
vm.dispose()
|
|
}
|
|
|
|
private val gpuTestPaletteKt = """
|
|
val w = 560
|
|
val h = 448
|
|
val hwoff = 1048576
|
|
|
|
fun inthash(x: Int): Int {
|
|
var x = (x.shr(16) xor x) * 0x45d9f3b
|
|
x = (x.shr(16) xor x) * 0x45d9f3b
|
|
x = (x.shr(16) xor x)
|
|
return x
|
|
}
|
|
|
|
var rng = (Math.floor(Math.random() * 2147483647) + 1).toInt()
|
|
|
|
while (true) {
|
|
val tstart: Long = System.nanoTime()
|
|
for (y1 in 0..359) {
|
|
for (x1 in 0 until w) {
|
|
val palnum = 20 * (y1 / 30) + (x1 / 28)
|
|
vm.poke(-(y1 * w + x1 + 1) - hwoff, inthash(palnum + rng))
|
|
}
|
|
}
|
|
for (y2 in 360 until h) {
|
|
for (x2 in 0 until w) {
|
|
val palnum = 240 + x2 / 35
|
|
vm.poke(-(y2 * w + x2 + 1) - hwoff, palnum)
|
|
}
|
|
}
|
|
|
|
for (k in 0 until 2560) {
|
|
vm.poke(-(253952 + k + 1) - hwoff, -2) // white
|
|
vm.poke(-(253952 + 2560 + k + 1) - hwoff, -1) // transparent
|
|
vm.poke(-(253952 + 2560 * 2 + k + 1) - hwoff, Math.round(Math.random() * 255).toInt())
|
|
}
|
|
|
|
rng = inthash(rng)
|
|
val tend: Long = System.nanoTime()
|
|
println("Apparent FPS: " + 1000000000.0 / (tend - tstart))
|
|
}
|
|
""".trimIndent()
|
|
|
|
private val gpuTestPaletteKt2 = """
|
|
val w = 560
|
|
val h = 448
|
|
val hwoff = 1048576
|
|
|
|
fun inthash(x: Int): Int {
|
|
var x = (x.shr(16) xor x) * 0x45d9f3b
|
|
x = (x.shr(16) xor x) * 0x45d9f3b
|
|
x = (x.shr(16) xor x)
|
|
return x
|
|
}
|
|
|
|
var rng = ((Math.random() * 2147483647) + 1).toInt()
|
|
|
|
while (true) {
|
|
for (y1 in 0..359) {
|
|
for (x1 in 0 until w) {
|
|
val palnum = 20 * (y1 / 30) + (x1 / 28)
|
|
vm.poke(-(y1 * w + x1 + 1) - hwoff, palnum)//inthash(palnum + rng))
|
|
}
|
|
}
|
|
for (y2 in 360 until h) {
|
|
for (x2 in 0 until w) {
|
|
val palnum = 240 + x2 / 35
|
|
vm.poke(-(y2 * w + x2 + 1) - hwoff, palnum)
|
|
}
|
|
}
|
|
|
|
for (k in 0 until 255) {
|
|
graphics.setPalette(k, (Math.random() * 15).toInt(), (Math.random() * 15).toInt(), (Math.random() * 15).toInt())
|
|
}
|
|
|
|
println("arst")
|
|
}
|
|
""".trimIndent()
|
|
|
|
|
|
private val gpuTestPalette = """
|
|
local vm = require("rawmem")
|
|
local bit = require("bit32")
|
|
local w = 560
|
|
local h = 448
|
|
local hwoff = 1048576
|
|
|
|
local function inthash(x)
|
|
local x = bit.bxor(bit.arshift(x, 16), x) * 0x45d9f3b
|
|
x = bit.bxor(bit.arshift(x, 16), x) * 0x45d9f3b
|
|
x = bit.bxor(bit.arshift(x, 16), x)
|
|
return x
|
|
end
|
|
|
|
local rng = math.floor(math.random() * 2147483647)
|
|
|
|
while true do
|
|
local tstart = vm.nanoTime()
|
|
|
|
for y = 0, 359 do
|
|
for x = 0, w - 1 do
|
|
palnum = 20 * int(y / 30) + int(x / 28)
|
|
vm.poke(-(y * w + x + 1) - hwoff, inthash(palnum + rng))
|
|
end
|
|
end
|
|
|
|
for y = 360, h - 1 do
|
|
for x = 0, w - 1 do
|
|
palnum = 240 + int(x / 35)
|
|
vm.poke(-(y * w + x + 1) - hwoff, palnum)
|
|
end
|
|
end
|
|
|
|
for k = 0, 2239 do
|
|
vm.poke(-(253952 + k + 1) - hwoff, 254)
|
|
vm.poke(-(253952 + 2560 + k + 1) - hwoff, 255)
|
|
vm.poke(-(253952 + 2560*2 + k + 1) - hwoff, math.floor(math.random() * 255.0))
|
|
end
|
|
|
|
rng = inthash(rng)
|
|
|
|
local tend = vm.nanoTime()
|
|
|
|
print("Apparent FPS: "..tostring(1000000000.0 / (tend - tstart)))
|
|
end
|
|
""".trimIndent()
|
|
|
|
private val gpuTestPaletteJs = """
|
|
var w = 560;
|
|
var h = 448;
|
|
var hwoff = 1048576;
|
|
|
|
function inthash(x) {
|
|
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
|
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
|
x = (x >> 16) ^ x;
|
|
return x;
|
|
}
|
|
|
|
var rng = Math.floor(Math.random() * 2147483647) + 1;
|
|
|
|
while (true) {
|
|
|
|
var tstart = vm.nanoTime();
|
|
|
|
for (var y = 0; y < 360; y++) {
|
|
for (var x = 0; x < w; x++) {
|
|
var palnum = 20 * Math.floor(y / 30) + Math.floor(x / 28);
|
|
vm.poke(-(y * w + x + 1) - hwoff, inthash(palnum + rng));
|
|
}
|
|
}
|
|
|
|
for (var y = 360; y < h; y++) {
|
|
for (var x = 0; x < w; x++) {
|
|
var palnum = 240 + Math.floor(x / 35);
|
|
vm.poke(-(y * w + x + 1) - hwoff, palnum);
|
|
}
|
|
}
|
|
|
|
for (var k = 0; k < 2560; k++) {
|
|
vm.poke(-(253952 + k + 1) - hwoff, -2); // transparent
|
|
vm.poke(-(253952 + 2560 + k + 1) - hwoff, -1); // white
|
|
/*vm.poke(-(253952 + 2560*2 + k + 1) - hwoff, Math.round(Math.random() * 255));*/
|
|
}
|
|
|
|
rng = inthash(rng);
|
|
|
|
var tend = vm.nanoTime();
|
|
|
|
println("Apparent FPS: " + (1000000000 / (tend - tstart)));
|
|
}
|
|
""".trimIndent()
|
|
|
|
private val shitcode = """
|
|
println("064 KB OK");
|
|
println("");
|
|
println("Starting TVDOS...");
|
|
println("TSVM Disk Operating System, version 1.20");
|
|
println("");
|
|
print("C:\\\\>");
|
|
|
|
while (true) {
|
|
var s = read();
|
|
println("String read: " + s + "@");
|
|
}
|
|
""".trimIndent()
|
|
|
|
private val gpuTestPaletteJava = """
|
|
int w = 560;
|
|
int h = 448;
|
|
int hwoff = 1048576;
|
|
|
|
int inthash(double x) {
|
|
return inthash((int) x);
|
|
}
|
|
|
|
int inthash(int x) {
|
|
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
|
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
|
x = (x >> 16) ^ x;
|
|
return x;
|
|
}
|
|
|
|
int rng = Math.floor(Math.random() * 2147483647) + 1;
|
|
|
|
while (true) {
|
|
|
|
long tstart = nanoTime.invoke();
|
|
|
|
for (int y1 = 0; y1 < 360; y1++) {
|
|
for (int x1 = 0; x1 < w; x1++) {
|
|
int palnum = 20 * (y1 / 30) + (x1 / 28);
|
|
poke.invoke(-(y1 * w + x1 + 1) - hwoff, inthash(palnum + rng));
|
|
}
|
|
}
|
|
|
|
for (int y2 = 360; y2 < h; y2++) {
|
|
for (int x2 = 0; x2 < w; x2++) {
|
|
int palnum = 240 + x2 / 35;
|
|
poke.invoke(-(y2 * w + x2 + 1) - hwoff, palnum);
|
|
}
|
|
}
|
|
|
|
for (int k = 0; k < 2560; k++) {
|
|
poke.invoke(-(253952 + k + 1) - hwoff, -2); // white
|
|
poke.invoke(-(253952 + 2560 + k + 1) - hwoff, -1); // transparent
|
|
poke.invoke(-(253952 + 2560*2 + k + 1) - hwoff, Math.round(Math.random() * 255));
|
|
}
|
|
|
|
rng = inthash(rng);
|
|
|
|
long tend = nanoTime.invoke();
|
|
|
|
System.out.println("Apparent FPS: " + (1000000000.0 / (tend - tstart)));
|
|
}
|
|
|
|
""".trimIndent()
|
|
|
|
|
|
private val gpuTestPalettePy = """
|
|
import math
|
|
import random
|
|
|
|
w = 560
|
|
h = 448
|
|
hwoff = 1048576
|
|
|
|
|
|
def inthash(x):
|
|
x = ((x >> 16) ^ x) * 0x45d9f3b
|
|
x = ((x >> 16) ^ x) * 0x45d9f3b
|
|
x = (x >> 16) ^ x
|
|
return x
|
|
|
|
rng = random.randint(1, 2147483647)
|
|
|
|
while True:
|
|
|
|
tstart = nanoTime.invoke()
|
|
|
|
for y1 in range(0, 360):
|
|
for x1 in range(0, w):
|
|
palnum = 20 * int(y1 / 30) + int(x1 / 28)
|
|
poke.invoke(-(y1 * w + x1 + 1) - hwoff, inthash(palnum + rng))
|
|
|
|
for y2 in range(360, h):
|
|
for x2 in range(0, w):
|
|
palnum = 240 + int(x2 / 35)
|
|
poke.invoke(-(y2 * w + x2 + 1) - hwoff, palnum)
|
|
|
|
for k in range(0, 2560):
|
|
poke.invoke(-(253952 + k + 1) - hwoff, -2)
|
|
poke.invoke(-(253952 + 2560 + k + 1) - hwoff, -1)
|
|
poke.invoke(-(253952 + 2560*2 + k + 1) - hwoff, random.randint(0, 255))
|
|
|
|
rng = inthash(rng)
|
|
|
|
tend = nanoTime.invoke()
|
|
|
|
print("Apparent FPS: " + str(1000000000.0 / (tend - tstart)))
|
|
|
|
""".trimIndent()
|
|
}
|
|
|
|
const val EMDASH = 0x2014.toChar() |