slight improvements to the long-abandoned v2k

This commit is contained in:
minjaesong
2022-06-29 04:12:26 +09:00
parent 8a0e89f5b9
commit 31c1d313c6
5 changed files with 61 additions and 31 deletions

View File

@@ -1,5 +1,7 @@
package net.torvald.tsvm package net.torvald.tsvm
import net.torvald.tsvm.peripheral.GraphicsAdapter
import net.torvald.tsvm.vdc.Videotron2K
import org.graalvm.polyglot.Context import org.graalvm.polyglot.Context
import org.graalvm.polyglot.HostAccess import org.graalvm.polyglot.HostAccess
import java.io.FileReader import java.io.FileReader
@@ -26,7 +28,7 @@ object VMRunnerFactory {
} }
return when (extension) { return when (extension) {
/*"vt2" -> { "vt2" -> {
object : VMRunner(extension) { object : VMRunner(extension) {
val engine = val engine =
@@ -36,6 +38,10 @@ object VMRunnerFactory {
engine.eval(command) engine.eval(command)
} }
override fun eval(command: String) {
TODO("Not yet implemented")
}
override suspend fun evalGlobal(command: String) { override suspend fun evalGlobal(command: String) {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
@@ -44,7 +50,7 @@ object VMRunnerFactory {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
} }
}*/ }
"js" -> { "js" -> {
object : VMRunner(extension) { object : VMRunner(extension) {
private val ringOneParallel = Parallel(vm) private val ringOneParallel = Parallel(vm)

View File

@@ -1667,6 +1667,11 @@ void main() {
560, 448, 80, 32, 253, 255, 256.kB(), "FontROM7x14.png", 0.64f, TEXT_TILING_SHADER_LCD, DRAW_SHADER_FRAG_LCD 560, 448, 80, 32, 253, 255, 256.kB(), "FontROM7x14.png", 0.64f, TEXT_TILING_SHADER_LCD, DRAW_SHADER_FRAG_LCD
) )
val DEFAULT_CONFIG_FOR_TESTING = AdapterConfig(
"crt_color",
560, 448, 80, 32, 253, 255, 256.kB(), "FontROM7x14.png", 0f, TEXT_TILING_SHADER_COLOUR
)
val DEFAULT_PALETTE = intArrayOf( // 0b rrrrrrrr gggggggg bbbbbbbb aaaaaaaa val DEFAULT_PALETTE = intArrayOf( // 0b rrrrrrrr gggggggg bbbbbbbb aaaaaaaa
255, 255,

View File

@@ -15,7 +15,7 @@ import net.torvald.tsvm.peripheral.GraphicsAdapter
class V2kRunTest : ApplicationAdapter() { class V2kRunTest : ApplicationAdapter() {
val vm = VM(64.kB(), TheRealWorld(), arrayOf()) val vm = VM("./assets", 64.kB(), TheRealWorld(), arrayOf())
lateinit var gpu: GraphicsAdapter lateinit var gpu: GraphicsAdapter
lateinit var batch: SpriteBatch lateinit var batch: SpriteBatch
@@ -29,7 +29,7 @@ class V2kRunTest : ApplicationAdapter() {
override fun create() { override fun create() {
super.create() super.create()
gpu = GraphicsAdapter(vm, GraphicsAdapter.DEFAULT_CONFIG_COLOR_CRT) gpu = GraphicsAdapter("./assets", vm, GraphicsAdapter.DEFAULT_CONFIG_FOR_TESTING)
vm.peripheralTable[1] = PeripheralEntry( vm.peripheralTable[1] = PeripheralEntry(
gpu, gpu,
@@ -39,11 +39,11 @@ class V2kRunTest : ApplicationAdapter() {
) )
batch = SpriteBatch() batch = SpriteBatch()
camera = OrthographicCamera(net.torvald.tsvm.AppLoader.WIDTH.toFloat(), net.torvald.tsvm.AppLoader.WIDTH.toFloat()) camera = OrthographicCamera(560f, 448f)
camera.setToOrtho(false) camera.setToOrtho(false)
camera.update() camera.update()
batch.projectionMatrix = camera.combined batch.projectionMatrix = camera.combined
Gdx.gl20.glViewport(0, 0, net.torvald.tsvm.AppLoader.WIDTH, net.torvald.tsvm.AppLoader.HEIGHT) Gdx.gl20.glViewport(0, 0, 560, 448)
vm.getPrintStream = { gpu.getPrintStream() } vm.getPrintStream = { gpu.getPrintStream() }
vm.getErrorStream = { gpu.getErrorStream() } vm.getErrorStream = { gpu.getErrorStream() }
@@ -51,7 +51,7 @@ class V2kRunTest : ApplicationAdapter() {
vdc = Videotron2K(gpu) vdc = Videotron2K(gpu)
vmRunner = VMRunnerFactory(vm, "js") vmRunner = VMRunnerFactory("./assets", vm, "js")
coroutineJob = GlobalScope.launch { coroutineJob = GlobalScope.launch {
vdc.eval(Videotron2K.screenfiller) vdc.eval(Videotron2K.screenfiller)
} }
@@ -64,7 +64,7 @@ class V2kRunTest : ApplicationAdapter() {
private var updateRate = 1f / 60f private var updateRate = 1f / 60f
override fun render() { override fun render() {
Gdx.graphics.setTitle("${net.torvald.tsvm.AppLoader.appTitle} $EMDASH F: ${Gdx.graphics.framesPerSecond} $EMDASH VF: ${(1.0 / vdc.statsFrameTime).toInt()}") Gdx.graphics.setTitle("V2K — F: ${Gdx.graphics.framesPerSecond} VF: ${(1.0 / vdc.statsFrameTime).toInt()}")
super.render() super.render()

View File

@@ -1,8 +1,8 @@
package net.torvald.tsvm.vdc package net.torvald.tsvm.vdc
import net.torvald.UnsafeHelper import net.torvald.UnsafeHelper
import torvald.random.HQRNG
import net.torvald.tsvm.peripheral.GraphicsAdapter import net.torvald.tsvm.peripheral.GraphicsAdapter
import net.torvald.tsvm.vdc.Command.instSet
import java.lang.NumberFormatException import java.lang.NumberFormatException
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@@ -72,21 +72,27 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
*/ */
val screenfiller = """ val screenfiller = """
DEFINE RATEF 60 DEFINE RATEF 6000000
DEFINE height 448 DEFINE height 448
DEFINE width 560 DEFINE width 560
mov r6 12345 mov r6 0
SCENE rng ; r6 is RNG value SCENE rng ; r6 is RNG value
mul r6 r6 48271 mul r6 r6 48271
mod r6 r6 2147483647 mod r6 r6 2147483647
exit exit
END SCENE END SCENE
SCENE next_colour
add r6 r6 20
mod r6 r6 255
exit
END SCENE
SCENE fill_line SCENE fill_line
@ mov px 0 @ mov px 0
perform rng ; perform rng
plot r6 plot r6
; plot c1 ; will auto-increment px by one ; plot c1 ; will auto-increment px by one
; inc c1 ; inc c1
@@ -101,12 +107,19 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
inc py inc py
cmp r1 py 448 cmp r1 py 448
movzr r1 py 0 movzr r1 py 0
performzr r1 next_colour
next next
; exeunt ; exeunt
; there's no EXIT command so this scene will make the program to go loop indefinitely ; there's no EXIT command so this scene will make the program to go loop indefinitely
END SCENE END SCENE
perform loop_frame SCENE fill_loop_frame
fillscr r6
perform next_colour
next
END SCENE
perform fill_loop_frame
""".trimIndent() """.trimIndent()
} }
@@ -149,7 +162,7 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
private val infoPrint = true private val infoPrint = true
private val debugPrint = false private val debugPrint = false
private val rng = torvald.random.HQRNG() private val rng = Random()//HQRNG()
fun eval(command: String) { fun eval(command: String) {
val rootStatements = parseCommands(command) val rootStatements = parseCommands(command)
@@ -180,8 +193,8 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
if (it.prefix != StatementPrefix.INIT || it.prefix == StatementPrefix.INIT && !pcLoopedBack) { if (it.prefix != StatementPrefix.INIT || it.prefix == StatementPrefix.INIT && !pcLoopedBack) {
if (debugPrint) println("Run-Scene: ${currentScene and 0xFFFFFFFFL}, Lindex: $currentLineIndex, Inst: $it") if (debugPrint) println("Run-Scene: ${currentScene and 0xFFFFFFFFL}, Lindex: $currentLineIndex, Inst: $it")
Command.checkConditionAndRun(it.command, this, it.args) Command.checkConditionAndRun(it.command, it.function, this, it.args)
if (debugPrint) println("Reg-r1: ${regs.getInt((REG_R1 and 0xF) * 4)}, c1: ${regs.getInt((REG_C1 and 0xF) * 4)}, px: ${regs.getInt((REG_PX and 0xF) * 4)}") if (debugPrint) println("Reg-r1: ${regs.getInt((REG_R1 and 0xF))}, c1: ${regs.getInt((REG_C1 and 0xF))}, px: ${regs.getInt((REG_PX and 0xF))}")
} }
@@ -283,6 +296,7 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
lnum, lnum,
if (isInit) StatementPrefix.INIT else StatementPrefix.NONE, if (isInit) StatementPrefix.INIT else StatementPrefix.NONE,
cmd, cmd,
instSet[cmd shr 3],
args.toLongArray() args.toLongArray()
) )
} }
@@ -321,7 +335,7 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
private fun hasVar(name: String) = (varIdTable.containsKey(name.toUpperCase())) private fun hasVar(name: String) = (varIdTable.containsKey(name.toUpperCase()))
private class VT2Statement(val lnum: Int, val prefix: Int = StatementPrefix.NONE, val command: Int, val args: LongArray) { private class VT2Statement(val lnum: Int, val prefix: Int = StatementPrefix.NONE, val command: Int, val function: (Videotron2K, LongArray) -> Unit, val args: LongArray) {
override fun toString(): String { override fun toString(): String {
return "L ${lnum.toString().padEnd(5, ' ')}" + StatementPrefix.toString(prefix) + " " + Command.reverseDict[command] + " " + (args.map { argsToString(it) }) return "L ${lnum.toString().padEnd(5, ' ')}" + StatementPrefix.toString(prefix) + " " + Command.reverseDict[command] + " " + (args.map { argsToString(it) })
} }
@@ -508,7 +522,7 @@ object Command {
instSet[MOV shr 3] = { instance, args -> // MOV register value instSet[MOV shr 3] = { instance, args -> // MOV register value
if (args.size != 2) throw ArgsCountMismatch(2, args) if (args.size != 2) throw ArgsCountMismatch(2, args)
checkRegisterLH(args[0]) checkRegisterLH(args[0])
instance.regs.setInt((args[0] and 0xF) * 4, resolveVar(instance, args[1])) instance.regs.setInt((args[0] and 0xF), resolveVar(instance, args[1]))
} }
instSet[MUL shr 3] = { instance, args -> // MUL ACC LH RH instSet[MUL shr 3] = { instance, args -> // MUL ACC LH RH
twoArgArithmetic(instance, args) { a,b -> a*b } twoArgArithmetic(instance, args) { a,b -> a*b }
@@ -522,15 +536,15 @@ object Command {
instSet[INC shr 3] = { instance, args -> // INC register instSet[INC shr 3] = { instance, args -> // INC register
if (args.size != 1) throw ArgsCountMismatch(1, args) if (args.size != 1) throw ArgsCountMismatch(1, args)
checkRegisterLH(args[0]) checkRegisterLH(args[0])
instance.regs.setInt((args[0] and 0xF) * 4, 1 + instance.regs.getInt((args[0] and 0xF) * 4)) instance.regs.setInt((args[0] and 0xF), 1 + instance.regs.getInt((args[0] and 0xF)))
} }
instSet[DEC shr 3] = { instance, args -> // DEC register instSet[DEC shr 3] = { instance, args -> // DEC register
if (args.size != 1) throw ArgsCountMismatch(1, args) if (args.size != 1) throw ArgsCountMismatch(1, args)
checkRegisterLH(args[0]) checkRegisterLH(args[0])
instance.regs.setInt((args[0] and 0xF) * 4, 1 - instance.regs.getInt((args[0] and 0xF) * 4)) instance.regs.setInt((args[0] and 0xF), 1 - instance.regs.getInt((args[0] and 0xF)))
} }
instSet[NEXT shr 3] = { instance, _ -> instSet[NEXT shr 3] = { instance, _ ->
instance.regs.setInt((Videotron2K.REG_FRM and 0xF) * 4, 1 + instance.regs.getInt((Videotron2K.REG_FRM and 0xF) * 4)) instance.regs.setInt((Videotron2K.REG_FRM and 0xF), 1 + instance.regs.getInt((Videotron2K.REG_FRM and 0xF)))
instance.sleepLatch = true instance.sleepLatch = true
val timeTook = (System.nanoTime() - instance.performanceCounterTmr).toDouble() val timeTook = (System.nanoTime() - instance.performanceCounterTmr).toDouble()
@@ -542,8 +556,8 @@ object Command {
} }
instSet[PLOT shr 3] = { instance, args -> // PLOT vararg-bytes instSet[PLOT shr 3] = { instance, args -> // PLOT vararg-bytes
if (args.isNotEmpty()) { if (args.isNotEmpty()) {
val px = instance.regs.getInt((Videotron2K.REG_PX and 0xF) * 4) val px = instance.regs.getInt((Videotron2K.REG_PX and 0xF))
val py = instance.regs.getInt((Videotron2K.REG_PY and 0xF) * 4) val py = instance.regs.getInt((Videotron2K.REG_PY and 0xF))
val width = instance.variableMap[Videotron2K.VARIABLE_WIDTH]!! val width = instance.variableMap[Videotron2K.VARIABLE_WIDTH]!!
val memAddr = py * width + px val memAddr = py * width + px
@@ -553,7 +567,7 @@ object Command {
} }
// write back auto-incremented value // write back auto-incremented value
instance.regs.setInt((Videotron2K.REG_PX and 0xF) * 4, (px + args.size) fmod width) instance.regs.setInt((Videotron2K.REG_PX and 0xF), (px + args.size) fmod width)
} }
} }
instSet[PERFORM shr 3] = { instance, args -> // PERFORM scene instSet[PERFORM shr 3] = { instance, args -> // PERFORM scene
@@ -571,6 +585,10 @@ object Command {
instSet[EXEUNT shr 3] = { instance, _ -> instSet[EXEUNT shr 3] = { instance, _ ->
instance.exeunt = true instance.exeunt = true
} }
instSet[FILLSCR shr 3] = { instance, args ->
instance.gpu?.poke(250884L, instance.regs.getInt(args[0] and 0xF).toByte())
instance.gpu?.poke(250883L, 2)
}
} }
private inline fun twoArgArithmetic(instance: Videotron2K, args: LongArray, operation: (Int, Int) -> Int) { private inline fun twoArgArithmetic(instance: Videotron2K, args: LongArray, operation: (Int, Int) -> Int) {
@@ -578,16 +596,17 @@ object Command {
checkRegisterLH(args[0]) checkRegisterLH(args[0])
val lh = resolveVar(instance, args[1]) val lh = resolveVar(instance, args[1])
val rh = resolveVar(instance, args[2]) val rh = resolveVar(instance, args[2])
instance.regs.setInt((args[0] and 0xF) * 4, operation(lh, rh)) instance.regs.setInt((args[0] and 0xF), operation(lh, rh))
} }
fun checkConditionAndRun(inst: Int, instance: Videotron2K, args: LongArray) { fun checkConditionAndRun(inst: Int, operation: (Videotron2K, LongArray) -> Unit, instance: Videotron2K, args: LongArray) {
val opcode = inst shr 3 // val opcode = inst shr 3
val condCode = inst and 7 val condCode = inst and 7
if (condCode == 0) { if (condCode == 0) {
//if (inst !in transferInst) instance.currentLineIndex += 1 //if (inst !in transferInst) instance.currentLineIndex += 1
instSet[opcode].invoke(instance, args) // instSet[opcode].invoke(instance, args)
operation.invoke(instance, args)
return return
} }
@@ -603,13 +622,14 @@ object Command {
if (condition) { if (condition) {
//if (inst !in transferInst) instance.currentLineIndex += 1 //if (inst !in transferInst) instance.currentLineIndex += 1
instSet[opcode].invoke(instance, args.sliceArray(1 until args.size)) // instSet[opcode].invoke(instance, args.sliceArray(1 until args.size))
operation.invoke(instance, args.sliceArray(1 until args.size))
} }
} }
private fun resolveVar(instance: Videotron2K, arg: Long): Int { private fun resolveVar(instance: Videotron2K, arg: Long): Int {
return if (arg and Videotron2K.REGISTER_PREFIX == Videotron2K.REGISTER_PREFIX) { return if (arg and Videotron2K.REGISTER_PREFIX == Videotron2K.REGISTER_PREFIX) {
instance.regs.getInt((arg and 0xF) * 4) instance.regs.getInt((arg and 0xF))
} }
else if (arg and Videotron2K.VARIABLE_PREFIX == Videotron2K.VARIABLE_PREFIX) { else if (arg and Videotron2K.VARIABLE_PREFIX == Videotron2K.VARIABLE_PREFIX) {
instance.variableMap[arg] ?: throw NullVar() instance.variableMap[arg] ?: throw NullVar()

View File

@@ -4,7 +4,6 @@
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/src/net/torvald/tsvm/vdc" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />