diff --git a/assets/bios1.js b/assets/bios/bios1.js similarity index 100% rename from assets/bios1.js rename to assets/bios/bios1.js diff --git a/assets/bios_source.js b/assets/bios/bios_source.js similarity index 100% rename from assets/bios_source.js rename to assets/bios/bios_source.js diff --git a/assets/romtest.js b/assets/romtest.js new file mode 100644 index 0000000..b737fc7 --- /dev/null +++ b/assets/romtest.js @@ -0,0 +1,2 @@ +sys.mapRom((exec_args[1]|0)||0); +println(sys.romReadAll()); \ No newline at end of file diff --git a/src/net/torvald/tsvm/AppLoader.java b/src/net/torvald/tsvm/AppLoader.java index 0105fe6..047b3f7 100644 --- a/src/net/torvald/tsvm/AppLoader.java +++ b/src/net/torvald/tsvm/AppLoader.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.backends.lwjgl.LwjglApplication; import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; import com.badlogic.gdx.graphics.glutils.ShaderProgram; +import net.torvald.tsvm.peripheral.GenericBios; public class AppLoader { @@ -24,7 +25,10 @@ public class AppLoader { appConfig.width = 560; appConfig.height = 448; - new LwjglApplication(new VMGUI(appConfig), appConfig); + + // val vm = VM(64.kB(), TheRealWorld(), arrayOf(GenericBios)) + VM vm = new VM(64 << 10, new TheRealWorld(), new GenericBios[]{GenericBios.INSTANCE}); + new LwjglApplication(new VMGUI(vm, appConfig), appConfig); } public static ShaderProgram loadShaderFromFile(String vert, String frag) { diff --git a/src/net/torvald/tsvm/VM.kt b/src/net/torvald/tsvm/VM.kt index 99b843b..ecd2671 100644 --- a/src/net/torvald/tsvm/VM.kt +++ b/src/net/torvald/tsvm/VM.kt @@ -3,59 +3,22 @@ package net.torvald.tsvm import net.torvald.UnsafeHelper import net.torvald.UnsafePtr import net.torvald.tsvm.firmware.Firmware -import net.torvald.tsvm.firmware.Firmware.Companion.toLuaValue import net.torvald.tsvm.peripheral.IOSpace import net.torvald.tsvm.peripheral.PeriBase -import org.luaj.vm2.LuaValue +import net.torvald.tsvm.peripheral.VMProgramRom import java.io.InputStream import java.io.OutputStream -import java.io.PrintStream import java.util.* import kotlin.math.ceil -import kotlin.random.Random /** - * 1 byte = 2 pixels - * - * 560x448@4bpp = 125 440 bytes - * 560x448@8bpp = 250 880 bytes - * - * -> 262144 bytes (256 kB) - * - * [USER AREA | HW AREA] - * Number of pheripherals = 8, of which the computer itself is considered as a peri. - * - * HW AREA = [Peripherals | MMIO | INTVEC] - * - * User area: 8 MB, hardware area: 8 MB - * - * 8192 kB - * User Space - * 1024 kB - * Peripheral #8 - * 1024 kB - * Peripheral #7 - * ... - * 1024 kB - * MMIO and Interrupt Vectors - * 128 kB - * MMIO for Peri #8 - * 128 kB - * MMIO for Peri #7 - * ... - * 128 kB - * MMIO for the computer - * 130816 bytes - * MMIO for Ports, etc. - * 256 bytes - * Vectors for 64 interrupts - * - * + * A class representing an instance of a Virtual Machine */ class VM( _memsize: Long, - val worldInterface: WorldInterface + val worldInterface: WorldInterface, + val roms: Array // first ROM must contain the BIOS ) { val id = java.util.Random().nextInt() @@ -81,6 +44,9 @@ class VM( val startTime: Long + var romMapping = 255 + internal set + init { peripheralTable[0] = PeripheralEntry( "io", @@ -217,9 +183,6 @@ class VM( mallocSizes.remove(index) } - //fun Byte.toLuaValue() = LuaValue.valueOf(this.toInt()) - - internal data class VMNativePtr(val address: Int, val size: Int) } diff --git a/src/net/torvald/tsvm/VMGUI.kt b/src/net/torvald/tsvm/VMGUI.kt index b891ecb..01a6745 100644 --- a/src/net/torvald/tsvm/VMGUI.kt +++ b/src/net/torvald/tsvm/VMGUI.kt @@ -7,14 +7,14 @@ import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.g2d.SpriteBatch import kotlinx.coroutines.* import net.torvald.tsvm.CompressorDelegate.GZIP_HEADER +import net.torvald.tsvm.peripheral.GenericBios import net.torvald.tsvm.peripheral.GraphicsAdapter import java.io.File fun ByteArray.startsWith(other: ByteArray) = this.sliceArray(other.indices).contentEquals(other) -class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter() { +class VMGUI(val vm: VM, val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter() { - val vm = VM(64.kB(), TheRealWorld()) lateinit var gpu: GraphicsAdapter lateinit var batch: SpriteBatch @@ -54,19 +54,10 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter() memvwr = Memvwr(vm) - // load test bios - - val bios = File("./assets/bios1.bin").readBytes() - // check if bios is compressed in gzip - val biosStr = if (bios.startsWith(GZIP_HEADER)) - CompressorDelegate.decomp(bios).toString(VM.CHARSET) - else - bios.toString(VM.CHARSET) vmRunner = VMRunnerFactory(vm, "js") coroutineJob = GlobalScope.launch { - //vmRunner.executeCommand(File("./assets/zippytest.js").readText(VM.CHARSET)) - vmRunner.executeCommand(biosStr) + vmRunner.executeCommand(vm.roms[0]!!.readAll()) } } diff --git a/src/net/torvald/tsvm/VMJSR223Delegate.kt b/src/net/torvald/tsvm/VMJSR223Delegate.kt index 71ffea7..bb0f072 100644 --- a/src/net/torvald/tsvm/VMJSR223Delegate.kt +++ b/src/net/torvald/tsvm/VMJSR223Delegate.kt @@ -13,6 +13,13 @@ class VMJSR223Delegate(val vm: VM) { fun nanoTime() = System.nanoTime() fun malloc(size: Int) = vm.malloc(size) fun free(ptr: Int) = vm.free(ptr) + fun mapRom(slot: Int) { + vm.romMapping = slot.and(255) + } + fun romReadAll(): String { + if (vm.romMapping == 255) return "" + return vm.roms[vm.romMapping]!!.readAll() + } fun uptime(): Long { vm.poke(-69, -1) diff --git a/src/net/torvald/tsvm/peripheral/IOSpace.kt b/src/net/torvald/tsvm/peripheral/IOSpace.kt index 3cf0d81..34ef993 100644 --- a/src/net/torvald/tsvm/peripheral/IOSpace.kt +++ b/src/net/torvald/tsvm/peripheral/IOSpace.kt @@ -93,6 +93,8 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor { in 72..79 -> systemUptime.ushr((adi - 72) * 8).and(255).toByte() in 80..87 -> rtc.ushr((adi - 80) * 8).and(255).toByte() + 88L -> vm.romMapping.toByte() + 4076L -> blockTransferPorts[0].statusCode.toByte() 4077L -> blockTransferPorts[1].statusCode.toByte() 4078L -> blockTransferPorts[2].statusCode.toByte() @@ -119,6 +121,8 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor { in 12288..16383 -> blockTransferRx[2][addr - 12288] in 16384..20479 -> blockTransferRx[3][addr - 16384] + in 65536..131071 -> if (vm.romMapping == -1) 255.toByte() else vm.roms[vm.romMapping]?.get(adi - 65536) + in 131072..262143 -> vm.peripheralTable[1].peripheral?.mmio_read(addr - 131072) in 262144..393215 -> vm.peripheralTable[2].peripheral?.mmio_read(addr - 262144) in 393216..524287 -> vm.peripheralTable[3].peripheral?.mmio_read(addr - 393216) @@ -147,6 +151,8 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor { RTClatched = byte.and(0b10).isNonZero() } + 88L -> vm.romMapping = bi + 4076L -> blockTransferPorts[0].statusCode = bi 4077L -> blockTransferPorts[1].statusCode = bi 4078L -> blockTransferPorts[2].statusCode = bi diff --git a/src/net/torvald/tsvm/peripheral/VMProgramRom.kt b/src/net/torvald/tsvm/peripheral/VMProgramRom.kt new file mode 100644 index 0000000..94621ee --- /dev/null +++ b/src/net/torvald/tsvm/peripheral/VMProgramRom.kt @@ -0,0 +1,31 @@ +package net.torvald.tsvm.peripheral + +import net.torvald.tsvm.CompressorDelegate +import net.torvald.tsvm.CompressorDelegate.GZIP_HEADER +import net.torvald.tsvm.VM +import net.torvald.tsvm.startsWith +import java.io.File + +interface VMProgramRom { + fun readAll(): String + operator fun get(addr: Int): Byte +} + +object GenericBios : VMProgramRom { + private val contents: ByteArray + + init { + val bytes = File("./assets/bios/bios1.bin").readBytes() + contents = bytes.sliceArray(0 until minOf(65536, bytes.size)) + } + + override fun readAll(): String { + // check if bios is compressed in gzip + return if (contents.startsWith(GZIP_HEADER)) + CompressorDelegate.decomp(contents).toString(VM.CHARSET) + else + contents.toString(VM.CHARSET) + } + + override fun get(addr: Int): Byte = contents[addr] +} \ No newline at end of file diff --git a/src/net/torvald/tsvm/vdc/V2kRunTest.kt b/src/net/torvald/tsvm/vdc/V2kRunTest.kt index d34d07b..1ec2c4e 100644 --- a/src/net/torvald/tsvm/vdc/V2kRunTest.kt +++ b/src/net/torvald/tsvm/vdc/V2kRunTest.kt @@ -15,7 +15,7 @@ import net.torvald.tsvm.peripheral.GraphicsAdapter class V2kRunTest(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter() { - val vm = VM(64.kB(), TheRealWorld()) + val vm = VM(64.kB(), TheRealWorld(), arrayOf()) lateinit var gpu: GraphicsAdapter lateinit var batch: SpriteBatch diff --git a/terranmon.txt b/terranmon.txt index 067fda1..666fbd2 100644 --- a/terranmon.txt +++ b/terranmon.txt @@ -82,6 +82,8 @@ MMIO 72..79 RO: System uptime in nanoseconds 80..87 RO: RTC in microseconds +88 RW: Rom mapping + 4076..4079 RW: 8-bit status code for the port 4080..4083 RO: 8-bit status code for connected device @@ -119,6 +121,8 @@ MMIO 12288..16383 RW: Buffer for block transfer lane #3 16384..20479 RW: Buffer for block transfer lane #4 +65536..131071 RO: Mapped to ROM + -------------------------------------------------------------------------------- VRAM Bank 0 (256 kB)