codes split into modules: tsvm_core, tsvm_executable, TerranBASICexecutable

This commit is contained in:
minjaesong
2021-12-03 11:57:31 +09:00
parent 20b34c8d19
commit 5e290061f4
49 changed files with 582 additions and 281 deletions

View File

@@ -1,13 +1,32 @@
<component name="ArtifactManager">
<artifact type="jar" name="TSVM-Executable">
<output-path>$PROJECT_DIR$/out/artifacts/TSVM_Executable</output-path>
<root id="archive" name="TSVM-Executable.jar">
<element id="module-output" name="tsvm" />
<artifact type="jar" name="TerranBASIC">
<output-path>$PROJECT_DIR$/out/artifacts/TerranBASIC</output-path>
<root id="archive" name="TerranBASIC.jar">
<element id="directory" name="META-INF">
<element id="file-copy" path="$PROJECT_DIR$/META-INF/MANIFEST.MF" />
<element id="file-copy" path="$PROJECT_DIR$/TerranBASICexecutable/META-INF/MANIFEST.MF" />
</element>
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-backend-lwjgl3-1.10.0.jar" path-in-jar="/" />
<element id="module-output" name="tsvm_core" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/TerranVirtualDisk.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/kotlinx-coroutines-core-1.4.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/kotlin-stdlib-1.4.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/annotations-13.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/kotlin-stdlib-common-1.4.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/truffle-api-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/graal-sdk-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/icu4j-68.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-scriptengine-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-test.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk7.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk8.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-21.1.0-edit.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/regex-21.1.0-edit.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/GetCpuName.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.10.0-natives-desktop.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-1.10.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.10.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-backend-lwjgl3-1.10.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/lwjgl-3.2.3.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/lwjgl-3.2.3-natives-windows.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/lwjgl-3.2.3-natives-windows-x86.jar" path-in-jar="/" />
@@ -45,25 +64,7 @@
<element id="extracted-dir" path="$PROJECT_DIR$/lib/lwjgl-openal-3.2.3-natives-macos.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jlayer-1.0.1-gdx.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jorbis-0.0.17.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.10.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.10.0-natives-desktop.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/GetCpuName.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-test.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk7.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk8.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/kotlinx-coroutines-core-1.4.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/kotlin-stdlib-1.4.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/annotations-13.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/kotlin-stdlib-common-1.4.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/TerranVirtualDisk.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-scriptengine-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/graal-sdk-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/truffle-api-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/icu4j-68.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-21.1.0-edit.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/regex-21.1.0-edit.jar" path-in-jar="/" />
<element id="module-output" name="TerranBASICexecutable" />
</root>
</artifact>
</component>

8
.idea/artifacts/TerrarumTSVM.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="TerrarumTSVM">
<output-path>$PROJECT_DIR$/out/artifacts/TerrarumTSVM</output-path>
<root id="archive" name="TerrarumTSVM.jar">
<element id="module-output" name="tsvm_core" />
</root>
</artifact>
</component>

5
.idea/modules.xml generated
View File

@@ -2,7 +2,10 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/tsvm.iml" filepath="$PROJECT_DIR$/tsvm.iml" />
<module fileurl="file://$PROJECT_DIR$/TerranBASICexecutable/TerranBASICexecutable.iml" filepath="$PROJECT_DIR$/TerranBASICexecutable/TerranBASICexecutable.iml" />
<module fileurl="file://$PROJECT_DIR$/tsvm_core/tsvm_core.iml" filepath="$PROJECT_DIR$/tsvm_core/tsvm_core.iml" />
<module fileurl="file://$PROJECT_DIR$/tsvm_dummymodule.iml" filepath="$PROJECT_DIR$/tsvm_dummymodule.iml" />
<module fileurl="file://$PROJECT_DIR$/tsvm_executable.iml" filepath="$PROJECT_DIR$/tsvm_executable.iml" />
</modules>
</component>
</project>

10
.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

124
.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: net.torvald.tsvm.TerranBASIC

View File

@@ -7,16 +7,17 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1" level="project" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx:1.10.0" level="project" />
<orderEntry type="module" module-name="tsvm_core" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx-backend-lwjgl3:1.10.0" level="project" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx-platform:1.10.0" level="project" />
<orderEntry type="library" name="org.graalvm.js:js:21.1.0" level="project" />
<orderEntry type="library" name="org.graalvm.js:js-scriptengine:21.1.0" level="project" />
<orderEntry type="library" name="TerranVirtualDisk" level="project" />
<orderEntry type="library" name="GetCpuName" level="project" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx:1.10.0" level="project" />
<orderEntry type="library" name="gdx-platform-1.10.0-natives-desktop" level="project" />
<orderEntry type="library" name="GetCpuName" level="project" />
<orderEntry type="library" name="js-21.1.0-edit" level="project" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="org.graalvm.js:js-scriptengine:21.1.0" level="project" />
<orderEntry type="library" name="org.graalvm.js:js:21.1.0" level="project" />
<orderEntry type="library" name="org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1" level="project" />
<orderEntry type="library" name="TerranVirtualDisk" level="project" />
</component>
</module>

View File

@@ -0,0 +1,32 @@
package net.torvald.tsvm;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import net.torvald.tsvm.peripheral.*;
public class TerranBASIC {
public static String appTitle = "TerranBASIC";
public static Lwjgl3ApplicationConfiguration appConfig;
public static int WIDTH = 640;
public static int HEIGHT = 480;
public static void main(String[] args) {
ShaderProgram.pedantic = false;
appConfig = new Lwjgl3ApplicationConfiguration();
appConfig.setIdleFPS(60);
appConfig.setForegroundFPS(60);
appConfig.useVsync(false);
appConfig.setResizable(false);
appConfig.setTitle(appTitle);
appConfig.setWindowedMode(WIDTH, HEIGHT);
VM tbasvm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{TBASRelBios.INSTANCE});
EmulInstance tbasrunner = new EmulInstance(tbasvm, "net.torvald.tsvm.peripheral.ReferenceGraphicsAdapter", "assets/disk0", 560, 448);
new Lwjgl3Application(new VMGUI(tbasrunner, WIDTH, HEIGHT), appConfig);
}
}

View File

@@ -0,0 +1,264 @@
package net.torvald.tsvm
import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import kotlinx.coroutines.*
import net.torvald.tsvm.peripheral.*
import java.io.File
class EmulInstance(
val vm: VM,
val display: String?,
val diskPath: String = "assets/disk0",
val drawWidth: Int,
val drawHeight: Int,
) {
var extraPeripherals: List<Pair<Int, PeripheralEntry2>> = listOf(); private set
constructor(
vm: VM,
display: String?,
diskPath: String = "assets/disk0",
drawWidth: Int,
drawHeight: Int,
extraPeripherals: List<Pair<Int, PeripheralEntry2>>
) : this(vm, display, diskPath, drawWidth, drawHeight) {
this.extraPeripherals = extraPeripherals
}
}
class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHeight: Int) : ApplicationAdapter() {
val vm = loaderInfo.vm
lateinit var batch: SpriteBatch
lateinit var camera: OrthographicCamera
var gpu: GraphicsAdapter? = null
lateinit var vmRunner: VMRunner
lateinit var coroutineJob: Job
lateinit var fullscreenQuad: Mesh
override fun create() {
super.create()
fullscreenQuad = Mesh(
true, 4, 6,
VertexAttribute.Position(),
VertexAttribute.ColorUnpacked(),
VertexAttribute.TexCoords(0)
)
updateFullscreenQuad(TerranBASIC.WIDTH, TerranBASIC.HEIGHT)
batch = SpriteBatch()
camera = OrthographicCamera(TerranBASIC.WIDTH.toFloat(), TerranBASIC.HEIGHT.toFloat())
camera.setToOrtho(false)
camera.update()
batch.projectionMatrix = camera.combined
init()
}
private fun init() {
if (loaderInfo.display != null) {
val loadedClass = Class.forName(loaderInfo.display)
val loadedClassConstructor = loadedClass.getConstructor(vm::class.java)
val loadedClassInstance = loadedClassConstructor.newInstance(vm)
gpu = (loadedClassInstance as GraphicsAdapter)
vm.getIO().blockTransferPorts[0].attachDevice(TestDiskDrive(vm, 0, File(loaderInfo.diskPath)))
vm.peripheralTable[1] = PeripheralEntry(
gpu,
GraphicsAdapter.VRAM_SIZE,
16,
0
)
vm.getPrintStream = { gpu!!.getPrintStream() }
vm.getErrorStream = { gpu!!.getErrorStream() }
vm.getInputStream = { gpu!!.getInputStream() }
}
else {
vm.getPrintStream = { System.out }
vm.getErrorStream = { System.err }
vm.getInputStream = { System.`in` }
}
loaderInfo.extraPeripherals.forEach { (port, peri) ->
val typeargs = peri.args.map { it.javaClass }.toTypedArray()
val loadedClass = Class.forName(peri.peripheralClassname)
val loadedClassConstructor = loadedClass.getConstructor(*typeargs)
val loadedClassInstance = loadedClassConstructor.newInstance(*peri.args)
vm.peripheralTable[port] = PeripheralEntry(
loadedClassInstance as PeriBase,
peri.memsize,
peri.mmioSize,
peri.interruptCount
)
}
Gdx.input.inputProcessor = vm.getIO()
vmRunner = VMRunnerFactory(vm, "js")
coroutineJob = GlobalScope.launch {
vmRunner.executeCommand(vm.roms[0]!!.readAll())
}
}
private var rebootRequested = false
private fun reboot() {
vmRunner.close()
coroutineJob.cancel("reboot requested")
vm.init()
init()
}
private var updateAkku = 0.0
private var updateRate = 1f / 60f
override fun render() {
gdxClearAndSetBlend(.094f, .094f, .094f, 0f)
setCameraPosition(0f, 0f)
// update window title with contents of the 'built-in status display'
val msg = (1024L until 1048L).map { cp437toUni[vm.getIO().mmio_read(it)!!.toInt().and(255)] }.joinToString("").trim()
Gdx.graphics.setTitle("$msg $EMDASH F: ${Gdx.graphics.framesPerSecond}")
super.render()
val dt = Gdx.graphics.rawDeltaTime
updateAkku += dt
var i = 0L
while (updateAkku >= updateRate) {
updateGame(updateRate)
updateAkku -= updateRate
i += 1
}
renderGame(dt)
}
private fun updateGame(delta: Float) {
if (!vm.resetDown && rebootRequested) {
reboot()
rebootRequested = false
}
vm.update(delta)
if (vm.resetDown) rebootRequested = true
}
fun poke(addr: Long, value: Byte) = vm.poke(addr, value)
private val defaultGuiBackgroundColour = Color(0x444444ff)
private fun renderGame(delta: Float) {
val clearCol = gpu?.getBackgroundColour() ?: defaultGuiBackgroundColour
Gdx.gl.glClearColor(clearCol.r, clearCol.g, clearCol.b, clearCol.a)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
gpu?.render(delta, batch, (viewportWidth - loaderInfo.drawWidth).div(2).toFloat(), (viewportHeight - loaderInfo.drawHeight).div(2).toFloat())
vm.findPeribyType("oled")?.let {
val disp = it.peripheral as ExtDisp
disp.render(batch,
(viewportWidth - loaderInfo.drawWidth).div(2).toFloat() + (gpu?.config?.width ?: 0),
(viewportHeight - loaderInfo.drawHeight).div(2).toFloat())
}
}
private fun setCameraPosition(newX: Float, newY: Float) {
camera.position.set((-newX + TerranBASIC.WIDTH / 2), (-newY + TerranBASIC.HEIGHT / 2), 0f) // deliberate integer division
camera.update()
batch.setProjectionMatrix(camera.combined)
}
private fun gdxClearAndSetBlend(r: Float, g: Float, b: Float, a: Float) {
Gdx.gl.glClearColor(r,g,b,a)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D)
Gdx.gl.glEnable(GL20.GL_BLEND)
}
private fun updateFullscreenQuad(WIDTH: Int, HEIGHT: Int) { // NOT y-flipped quads!
fullscreenQuad.setVertices(floatArrayOf(
0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 1f,
WIDTH.toFloat(), 0f, 0f, 1f, 1f, 1f, 1f, 1f, 1f,
WIDTH.toFloat(), HEIGHT.toFloat(), 0f, 1f, 1f, 1f, 1f, 1f, 0f,
0f, HEIGHT.toFloat(), 0f, 1f, 1f, 1f, 1f, 0f, 0f
))
fullscreenQuad.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0))
}
override fun dispose() {
super.dispose()
batch.dispose()
fullscreenQuad.dispose()
coroutineJob.cancel()
vm.dispose()
}
companion object {
val cp437toUni = hashMapOf<Int, Char>(
0 to 32.toChar(),
1 to 0x263A.toChar(),
2 to 0x263B.toChar(),
3 to 0x2665.toChar(),
4 to 0x2666.toChar(),
5 to 0x2663.toChar(),
6 to 0x2660.toChar(),
7 to 0x2022.toChar(),
8 to 0x25D8.toChar(),
9 to 0x25CB.toChar(),
10 to 0x25D9.toChar(),
11 to 0x2642.toChar(),
12 to 0x2640.toChar(),
13 to 0x266A.toChar(),
14 to 0x266B.toChar(),
15 to 0x00A4.toChar(),
16 to 0x25BA.toChar(),
17 to 0x25C4.toChar(),
18 to 0x2195.toChar(),
19 to 0x203C.toChar(),
20 to 0x00B6.toChar(),
21 to 0x00A7.toChar(),
22 to 0x25AC.toChar(),
23 to 0x21A8.toChar(),
24 to 0x2191.toChar(),
25 to 0x2193.toChar(),
26 to 0x2192.toChar(),
27 to 0x2190.toChar(),
28 to 0x221F.toChar(),
29 to 0x2194.toChar(),
30 to 0x25B2.toChar(),
31 to 0x25BC.toChar(),
127 to 0x2302.toChar(),
158 to 0x2610.toChar(),
159 to 0x2611.toChar()
)
init {
for (k in 32..126) {
cp437toUni[k] = k.toChar()
}
}
}
}
const val EMDASH = 0x2014.toChar()

View File

@@ -1,194 +0,0 @@
package net.torvald.random;
import java.util.Random;
/**
* Xoroshiro128
*
* Note: low 4 bits are considered "dirty"; avoid these bits for making random set of booleans
*
* see https://github.com/SquidPony/SquidLib/blob/master/squidlib-util/src/main/java/squidpony/squidmath/XoRoRNG.java
*/
public class HQRNG extends Random {
private static final long DOUBLE_MASK = (1L << 53) - 1;
private static final double NORM_53 = 1. / (1L << 53);
private static final long FLOAT_MASK = (1L << 24) - 1;
private static final double NORM_24 = 1. / (1L << 24);
private static final long serialVersionUID = 1018744536171610262L;
private long state0, state1;
public long getState0() {
return state0;
}
public long getState1() {
return state1;
}
/**
* Creates a new generator seeded using four calls to Math.random().
*/
public HQRNG() {
this((long) ((Math.random() - 0.5) * 0x10000000000000L)
^ (long) (((Math.random() - 0.5) * 2.0) * 0x8000000000000000L),
(long) ((Math.random() - 0.5) * 0x10000000000000L)
^ (long) (((Math.random() - 0.5) * 2.0) * 0x8000000000000000L));
}
/**
* Constructs this XoRoRNG by dispersing the bits of seed using {@link #setSeed(long)} across the two parts of state
* this has.
* @param seed a long that won't be used exactly, but will affect both components of state
*/
public HQRNG(final long seed) {
setSeed(seed);
}
/**
* Constructs this XoRoRNG by calling {@link #setSeed(long, long)} on the arguments as given; see that method for
* the specific details (stateA and stateB are kept as-is unless they are both 0).
* @param stateA the number to use as the first part of the state; this will be 1 instead if both seeds are 0
* @param stateB the number to use as the second part of the state
*/
public HQRNG(final long stateA, final long stateB) {
setSeed(stateA, stateB);
}
@Override
public final int next(int bits) {
final long s0 = state0;
long s1 = state1;
final int result = (int)(s0 + s1) >>> (32 - bits);
s1 ^= s0;
state0 = (s0 << 55 | s0 >>> 9) ^ s1 ^ (s1 << 14); // a, b
state1 = (s1 << 36 | s1 >>> 28); // c
return result;
}
@Override
public final long nextLong() {
final long s0 = state0;
long s1 = state1;
final long result = s0 + s1;
s1 ^= s0;
state0 = (s0 << 55 | s0 >>> 9) ^ s1 ^ (s1 << 14); // a, b
state1 = (s1 << 36 | s1 >>> 28); // c
/*
state0 = Long.rotateLeft(s0, 55) ^ s1 ^ (s1 << 14); // a, b
state1 = Long.rotateLeft(s1, 36); // c
*/
return result;
}
/**
* Can return any int, positive or negative, of any size permissible in a 32-bit signed integer.
* @return any int, all 32 bits are random
*/
public int nextInt() {
return (int)nextLong();
}
/**
* Exclusive on the outer bound; the inner bound is 0. The bound may be negative, which will produce a non-positive
* result.
* @param bound the outer exclusive bound; may be positive or negative
* @return a random int between 0 (inclusive) and bound (exclusive)
*/
public int nextInt(final int bound) {
return (int) ((bound * (nextLong() >>> 33)) >> 31);
}
/**
* Inclusive lower, exclusive upper.
* @param inner the inner bound, inclusive, can be positive or negative
* @param outer the outer bound, exclusive, should be positive, should usually be greater than inner
* @return a random int that may be equal to inner and will otherwise be between inner and outer
*/
public int nextInt(final int inner, final int outer) {
return inner + nextInt(outer - inner);
}
/**
* Exclusive on the outer bound; the inner bound is 0. The bound may be negative, which will produce a non-positive
* result.
* @param bound the outer exclusive bound; may be positive or negative
* @return a random long between 0 (inclusive) and bound (exclusive)
*/
public long nextLong(long bound) {
long rand = nextLong();
final long randLow = rand & 0xFFFFFFFFL;
final long boundLow = bound & 0xFFFFFFFFL;
rand >>>= 32;
bound >>= 32;
final long z = (randLow * boundLow >> 32);
long t = rand * boundLow + z;
final long tLow = t & 0xFFFFFFFFL;
t >>>= 32;
return rand * bound + t + (tLow + randLow * bound >> 32) - (z >> 63) - (bound >> 63);
}
/**
* Inclusive inner, exclusive outer; both inner and outer can be positive or negative.
* @param inner the inner bound, inclusive, can be positive or negative
* @param outer the outer bound, exclusive, can be positive or negative and may be greater than or less than inner
* @return a random long that may be equal to inner and will otherwise be between inner and outer
*/
public long nextLong(final long inner, final long outer) {
return inner + nextLong(outer - inner);
}
public double nextDouble() {
return (nextLong() & DOUBLE_MASK) * NORM_53;
}
public float nextFloat() {
return (float) ((nextLong() & FLOAT_MASK) * NORM_24);
}
public boolean nextBoolean() {
return nextLong() < 0L;
}
public void nextBytes(final byte[] bytes) {
int i = bytes.length, n = 0;
while (i != 0) {
n = Math.min(i, 8);
for (long bits = nextLong(); n-- != 0; bits >>>= 8) {
bytes[--i] = (byte) bits;
}
}
}
/**
* Sets the seed of this generator using one long, running that through LightRNG's algorithm twice to get the state.
* @param seed the number to use as the seed
*/
public void setSeed(final long seed) {
long state = seed + 0x9E3779B97F4A7C15L,
z = state;
z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L;
z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL;
state0 = z ^ (z >>> 31);
state += 0x9E3779B97F4A7C15L;
z = state;
z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L;
z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL;
state1 = z ^ (z >>> 31);
}
/**
* Sets the seed of this generator using two longs, using them without changes unless both are 0 (then it makes the
* state variable corresponding to stateA 1 instead).
* @param stateA the number to use as the first part of the state; this will be 1 instead if both seeds are 0
* @param stateB the number to use as the second part of the state
*/
public void setSeed(final long stateA, final long stateB) {
state0 = stateA;
state1 = stateB;
if((stateA | stateB) == 0L)
state0 = 1L;
}
}

View File

@@ -1,4 +1,4 @@
package net.torvald.util
package net.torvald.tsvm
import java.util.*
@@ -13,7 +13,7 @@ import java.util.*
*
* Created by minjaesong on 2017-01-22.
*/
class CircularArray<T>(val size: Int, val overwriteOnOverflow: Boolean): Iterable<T> {
internal class CircularArray<T>(val size: Int, val overwriteOnOverflow: Boolean): Iterable<T> {
/**
* What to do RIGHT BEFORE old element is being overridden by the new element (only makes sense when ```overwriteOnOverflow = true```)

View File

@@ -0,0 +1,18 @@
package net.torvald.tsvm
import com.badlogic.gdx.graphics.glutils.ShaderProgram
/**
* Created by minjaesong on 2021-12-03.
*/
internal object LoadShader {
operator fun invoke(vert: String, frag: String): ShaderProgram {
val s = ShaderProgram(vert, frag)
if (s.log.toLowerCase().contains("error")) {
throw Error(String.format("Shader program loaded with %s, %s failed:\n%s", vert, frag, s.log))
}
return s
}
}

View File

@@ -22,7 +22,7 @@
* SOFTWARE.
*/
package net.torvald.terrarumsansbitmap.gdx
package net.torvald.tsvm
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Texture

View File

@@ -34,7 +34,7 @@ class VM(
val peripheralTable = Array(8) { PeripheralEntry() }
internal fun getIO(): IOSpace = peripheralTable[0].peripheral as IOSpace
fun getIO(): IOSpace = peripheralTable[0].peripheral as IOSpace
//lateinit var printStream: OutputStream
//lateinit var errorStream: OutputStream
@@ -121,7 +121,7 @@ class VM(
}
}
internal fun poke(addr: Long, value: Byte) {
fun poke(addr: Long, value: Byte) {
val (memspace, offset) = translateAddr(addr)
if (memspace == null)
throw ErrorIllegalAccess(this, addr)
@@ -135,7 +135,7 @@ class VM(
(memspace as PeriBase).poke(offset, value)
}
internal fun peek(addr:Long): Byte? {
fun peek(addr:Long): Byte? {
val (memspace, offset) = translateAddr(addr)
return if (memspace == null)
null

View File

@@ -1,7 +1,5 @@
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.HostAccess
import java.io.FileReader
@@ -27,7 +25,7 @@ object VMRunnerFactory {
}
return when (extension) {
"vt2" -> {
/*"vt2" -> {
object : VMRunner(extension) {
val engine =
@@ -45,7 +43,7 @@ object VMRunnerFactory {
TODO("Not yet implemented")
}
}
}
}*/
"js" -> {
object : VMRunner(extension) {
private val context = Context.newBuilder("js")

View File

@@ -97,3 +97,5 @@ fun ByteArray.trimNull(): ByteArray {
}
return this.sliceArray(0..cnt)
}
fun ByteArray.startsWith(other: ByteArray) = this.sliceArray(other.indices).contentEquals(other)

View File

@@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toUlong
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import net.torvald.tsvm.TextureRegionPack
import net.torvald.tsvm.VM
class CharacterLCDdisplay(vm: VM) : GraphicsAdapter(vm, AdapterConfig(

View File

@@ -5,7 +5,7 @@ import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.math.Matrix4
import net.torvald.tsvm.AppLoader
import net.torvald.tsvm.LoadShader
import net.torvald.tsvm.VM
/**
@@ -28,7 +28,7 @@ class ExtDisp(val vm: VM, val width: Int, val height: Int) : PeriBase {
internal val framebuffer = Pixmap(width, height, Pixmap.Format.Alpha)
private val outFBObatch = SpriteBatch()
protected val drawShader = AppLoader.loadShaderInline(GraphicsAdapter.DRAW_SHADER_VERT, OLED_PAL_SHADER)
protected val drawShader = LoadShader(GraphicsAdapter.DRAW_SHADER_VERT, OLED_PAL_SHADER)
init {
// no orthographic camera, must be "raw" Matrix4

View File

@@ -11,7 +11,7 @@ import com.badlogic.gdx.math.Matrix4
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.UnsafeHelper
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toUint
import net.torvald.tsvm.AppLoader
import net.torvald.tsvm.LoadShader
import net.torvald.tsvm.VM
import net.torvald.tsvm.kB
import net.torvald.tsvm.peripheral.GraphicsAdapter.Companion.DRAW_SHADER_FRAG
@@ -79,8 +79,8 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super
internal val textArea = UnsafeHelper.allocate(7682)
internal val unusedArea = UnsafeHelper.allocate(1024)
protected val paletteShader = AppLoader.loadShaderInline(DRAW_SHADER_VERT, config.paletteShader)
protected val textShader = AppLoader.loadShaderInline(DRAW_SHADER_VERT, config.fragShader)
protected val paletteShader = LoadShader(DRAW_SHADER_VERT, config.paletteShader)
protected val textShader = LoadShader(DRAW_SHADER_VERT, config.fragShader)
override var blinkCursor = true
override var ttyRawMode = false

View File

@@ -4,9 +4,8 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input
import com.badlogic.gdx.InputProcessor
import net.torvald.UnsafeHelper
import net.torvald.tsvm.CircularArray
import net.torvald.tsvm.VM
import net.torvald.util.CircularArray
import java.io.File
import kotlin.experimental.and
class IOSpace(val vm: VM) : PeriBase, InputProcessor {

View File

@@ -3,7 +3,6 @@ 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
open class VMProgramRom(path: String) {

View File

@@ -39,11 +39,11 @@ class V2kRunTest : ApplicationAdapter() {
)
batch = SpriteBatch()
camera = OrthographicCamera(AppLoader.WIDTH.toFloat(), AppLoader.WIDTH.toFloat())
camera = OrthographicCamera(net.torvald.tsvm.AppLoader.WIDTH.toFloat(), net.torvald.tsvm.AppLoader.WIDTH.toFloat())
camera.setToOrtho(false)
camera.update()
batch.projectionMatrix = camera.combined
Gdx.gl20.glViewport(0, 0, AppLoader.WIDTH, AppLoader.HEIGHT)
Gdx.gl20.glViewport(0, 0, net.torvald.tsvm.AppLoader.WIDTH, net.torvald.tsvm.AppLoader.HEIGHT)
vm.getPrintStream = { gpu.getPrintStream() }
vm.getErrorStream = { gpu.getErrorStream() }
@@ -64,7 +64,7 @@ class V2kRunTest : ApplicationAdapter() {
private var updateRate = 1f / 60f
override fun render() {
Gdx.graphics.setTitle("${AppLoader.appTitle} $EMDASH F: ${Gdx.graphics.framesPerSecond} $EMDASH VF: ${(1.0 / vdc.statsFrameTime).toInt()}")
Gdx.graphics.setTitle("${net.torvald.tsvm.AppLoader.appTitle} $EMDASH F: ${Gdx.graphics.framesPerSecond} $EMDASH VF: ${(1.0 / vdc.statsFrameTime).toInt()}")
super.render()

View File

@@ -1,7 +1,7 @@
package net.torvald.tsvm.vdc
import net.torvald.UnsafeHelper
import net.torvald.random.HQRNG
import torvald.random.HQRNG
import net.torvald.tsvm.peripheral.GraphicsAdapter
import java.lang.NumberFormatException
import java.util.*
@@ -149,7 +149,7 @@ class Videotron2K(var gpu: GraphicsAdapter?) {
private val infoPrint = true
private val debugPrint = false
private val rng = HQRNG()
private val rng = torvald.random.HQRNG()
fun eval(command: String) {
val rootStatements = parseCommands(command)

23
tsvm_core/tsvm_core.iml Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/src/net/torvald/tsvm/vdc" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx-backend-lwjgl3:1.10.0" level="project" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx-platform:1.10.0" level="project" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx:1.10.0" level="project" />
<orderEntry type="library" name="gdx-platform-1.10.0-natives-desktop" level="project" />
<orderEntry type="library" name="GetCpuName" level="project" />
<orderEntry type="library" name="js-21.1.0-edit" level="project" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="org.graalvm.js:js-scriptengine:21.1.0" level="project" />
<orderEntry type="library" name="org.graalvm.js:js:21.1.0" level="project" />
<orderEntry type="library" name="org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1" level="project" />
<orderEntry type="library" name="TerranVirtualDisk" level="project" />
</component>
</module>

9
tsvm_dummymodule.iml Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

23
tsvm_executable.iml Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/tsvm_executable">
<sourceFolder url="file://$MODULE_DIR$/tsvm_executable/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx-backend-lwjgl3:1.10.0" level="project" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx-platform:1.10.0" level="project" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx:1.10.0" level="project" />
<orderEntry type="library" name="gdx-platform-1.10.0-natives-desktop" level="project" />
<orderEntry type="library" name="GetCpuName" level="project" />
<orderEntry type="library" name="js-21.1.0-edit" level="project" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="org.graalvm.js:js-scriptengine:21.1.0" level="project" />
<orderEntry type="library" name="org.graalvm.js:js:21.1.0" level="project" />
<orderEntry type="library" name="org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1" level="project" />
<orderEntry type="library" name="TerranVirtualDisk" level="project" />
<orderEntry type="module" module-name="tsvm_core" />
</component>
</module>

View File

@@ -34,18 +34,13 @@ public class AppLoader {
// VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{TandemBios.INSTANCE, BasicRom.INSTANCE});
// VM vm = new VM(128 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, WPBios.INSTANCE});
VM vm = new VM(2048 << 10, new TheRealWorld(), new VMProgramRom[]{TsvmBios.INSTANCE});
VM pipvm = new VM(4096, new TheRealWorld(), new VMProgramRom[]{PipBios.INSTANCE, PipROM.INSTANCE});
// uncomment to target the TerranBASIC runner
// VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{TBASRelBios.INSTANCE});
EmulInstance reference = new EmulInstance(vm, "net.torvald.tsvm.peripheral.ReferenceGraphicsAdapter", "assets/disk0", 560, 448);
EmulInstance reference2 = new EmulInstance(vm, "net.torvald.tsvm.peripheral.ReferenceLikeLCD", "assets/disk0", 560, 448);
EmulInstance term = new EmulInstance(vm, "net.torvald.tsvm.peripheral.Term", "assets/disk0", 720, 480);
EmulInstance portable = new EmulInstance(vm, "net.torvald.tsvm.peripheral.CharacterLCDdisplay", "assets/disk0", 628, 302);
EmulInstance wp = new EmulInstance(vm, "net.torvald.tsvm.peripheral.WpTerm", "assets/wpdisk", 810, 360);
EmulInstance pip = new EmulInstance(pipvm, null, "assets/disk0", 640, 480, CollectionsKt.listOf(new Pair(1, new PeripheralEntry2(
32768L,
1,
@@ -56,24 +51,4 @@ public class AppLoader {
new Lwjgl3Application(new VMGUI(pip, WIDTH, HEIGHT), appConfig);
}
public static ShaderProgram loadShaderFromFile(String vert, String frag) {
ShaderProgram s = new ShaderProgram(Gdx.files.internal(vert), Gdx.files.internal(frag));
if (s.getLog().toLowerCase().contains("error")) {
throw new Error(String.format("Shader program loaded with %s, %s failed:\n%s", vert, frag, s.getLog()));
}
return s;
}
public static ShaderProgram loadShaderInline(String vert, String frag) {
ShaderProgram s = new ShaderProgram(vert, frag);
if (s.getLog().toLowerCase().contains("error")) {
throw new Error(String.format("Shader program loaded with %s, %s failed:\n%s", vert, frag, s.getLog()));
}
return s;
}
}

View File

@@ -6,12 +6,9 @@ import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import kotlinx.coroutines.*
import net.torvald.terrarum.modulecomputers.tsvmperipheral.WorldRadar
import net.torvald.tsvm.CompressorDelegate.GZIP_HEADER
import net.torvald.tsvm.peripheral.*
import java.io.File
fun ByteArray.startsWith(other: ByteArray) = this.sliceArray(other.indices).contentEquals(other)
class EmulInstance(
val vm: VM,
val display: String?,
@@ -97,7 +94,13 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
vm.getInputStream = { System.`in` }
}
vm.getIO().blockTransferPorts[1].attachDevice(WorldRadar(Gdx.files.internal("test_assets/test_terrain.png")))
vm.getIO().blockTransferPorts[1].attachDevice(
WorldRadar(
Gdx.files.internal(
"test_assets/test_terrain.png"
)
)
)
loaderInfo.extraPeripherals.forEach { (port, peri) ->
val typeargs = peri.args.map { it.javaClass }.toTypedArray()