mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
tevd disk drive update and fixes
This commit is contained in:
@@ -29,7 +29,8 @@ public class TerranBASIC {
|
||||
appConfig.setWindowedMode(WIDTH, HEIGHT);
|
||||
|
||||
HashMap<String, VMWatchdog> watchdogs = new HashMap<>();
|
||||
watchdogs.put("TEVD_SYNC", TevdSyncWatchdog.INSTANCE);
|
||||
watchdogs.put("TEVD_COMMIT", TevdPartialDomCommitWatchdog.INSTANCE);
|
||||
watchdogs.put("TEVD_SYNC", TevdPartialDomSyncWatchdog.INSTANCE);
|
||||
|
||||
VM tbasvm = new VM("./assets", 64 << 10, new TheRealWorld(), new VMProgramRom[]{TBASRelBios.INSTANCE}, 2, watchdogs);
|
||||
EmulInstance tbasrunner = new EmulInstance(tbasvm, "net.torvald.tsvm.peripheral.ReferenceGraphicsAdapter", "assets/disk0", 560, 448);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
package net.torvald.tsvm
|
||||
|
||||
import com.badlogic.gdx.utils.Queue
|
||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.PartialDOM
|
||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VDUtil
|
||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VirtualDisk
|
||||
import java.io.File
|
||||
@@ -29,15 +29,15 @@ abstract class VMWatchdog(val interval: Float) {
|
||||
}
|
||||
|
||||
|
||||
object TevdSyncWatchdog : VMWatchdog(5f) {
|
||||
object TevdPartialDomCommitWatchdog : VMWatchdog(5f) {
|
||||
|
||||
private val messageQueue = ArrayList<Pair<File, VirtualDisk>>()
|
||||
private val messageQueue = ArrayList<Pair<File, PartialDOM>>()
|
||||
|
||||
override fun consumeMessages() {
|
||||
synchronized(this) {
|
||||
messageQueue.forEach { (outfile, dom) ->
|
||||
VDUtil.dumpToRealMachine(dom, outfile)
|
||||
// println("[${this.javaClass.simpleName}] dump ${outfile.path}")
|
||||
dom.commit()
|
||||
println("[${this.javaClass.simpleName}] commit ${outfile.path}")
|
||||
}
|
||||
messageQueue.clear()
|
||||
}
|
||||
@@ -45,7 +45,33 @@ object TevdSyncWatchdog : VMWatchdog(5f) {
|
||||
|
||||
override fun addMessage(message: Array<Any?>) {
|
||||
val file = message[0] as File
|
||||
val dom = message[1] as VirtualDisk
|
||||
val dom = message[1] as PartialDOM
|
||||
|
||||
val hasDup = messageQueue.fold(false) { acc, pair -> acc or (pair.first.path == file.path) }
|
||||
if (!hasDup) {
|
||||
messageQueue.add(file to dom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object TevdPartialDomSyncWatchdog : VMWatchdog(120f) {
|
||||
|
||||
private val messageQueue = ArrayList<Pair<File, PartialDOM>>()
|
||||
|
||||
override fun consumeMessages() {
|
||||
synchronized(this) {
|
||||
messageQueue.forEach { (outfile, dom) ->
|
||||
dom.sync()
|
||||
println("[${this.javaClass.simpleName}] sync ${outfile.path}")
|
||||
}
|
||||
messageQueue.clear()
|
||||
}
|
||||
}
|
||||
|
||||
override fun addMessage(message: Array<Any?>) {
|
||||
val file = message[0] as File
|
||||
val dom = message[1] as PartialDOM
|
||||
|
||||
val hasDup = messageQueue.fold(false) { acc, pair -> acc or (pair.first.path == file.path) }
|
||||
if (!hasDup) {
|
||||
|
||||
@@ -47,9 +47,15 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var tevdSyncFilteringCounter = 0
|
||||
fun notifyDiskCommit() {
|
||||
vm.watchdogs["TEVD_SYNC"]?.addMessage(arrayOf(tevdPath, DOM))
|
||||
vm.watchdogs["TEVD_COMMIT"]?.addMessage(arrayOf(tevdPath, DOM))
|
||||
|
||||
if (tevdSyncFilteringCounter >= 1) {
|
||||
vm.watchdogs["TEVD_SYNC"]?.addMessage(arrayOf(tevdPath, DOM))
|
||||
tevdSyncFilteringCounter = 0
|
||||
}
|
||||
tevdSyncFilteringCounter += 1
|
||||
}
|
||||
|
||||
|
||||
@@ -98,12 +104,24 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
override fun writeoutImpl(inputData: ByteArray) {
|
||||
printdbg("inputString=${inputData.trimNull().toString(VM.CHARSET)}")
|
||||
|
||||
if (writeMode || appendMode) {
|
||||
if ((writeMode || appendMode) && writeModeLength >= 0) {
|
||||
printdbg("writeout with inputdata length of ${inputData.size}")
|
||||
//println("[DiskDrive] writeout with inputdata length of ${inputData.size}")
|
||||
//println("[DiskDriveMsg] ${inputData.toString(Charsets.UTF_8)}")
|
||||
|
||||
if (!fileOpen) throw InternalError("File is not open but the drive is in write mode")
|
||||
|
||||
if (!file.exists()) {
|
||||
printdbg("File '${file.path}' not exists, creating new...")
|
||||
val (result, failReason) = file.createNewFile()
|
||||
if (failReason != null) {
|
||||
throw failReason
|
||||
}
|
||||
else {
|
||||
printdbg("Operation successful")
|
||||
}
|
||||
}
|
||||
|
||||
System.arraycopy(inputData, 0, writeBuffer, writeBufferUsage, minOf(writeModeLength - writeBufferUsage, inputData.size, BLOCK_SIZE))
|
||||
writeBufferUsage += inputData.size
|
||||
|
||||
@@ -121,6 +139,8 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
}
|
||||
}
|
||||
else if (fileOpenMode == 17) {
|
||||
printdbg("File open mode 17")
|
||||
|
||||
if (!fileOpen) throw InternalError("Bootloader file is not open but the drive is in boot write mode")
|
||||
|
||||
val inputData = if (inputData.size != BLOCK_SIZE) ByteArray(BLOCK_SIZE) { if (it < inputData.size) inputData[it] else 0 }
|
||||
@@ -140,6 +160,8 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
notifyDiskCommit()
|
||||
}
|
||||
else {
|
||||
printdbg("(cmd mode)")
|
||||
|
||||
val inputString = inputData.trimNull().toString(VM.CHARSET)
|
||||
|
||||
if (inputString.startsWith("DEVRST\u0017")) {
|
||||
@@ -222,7 +244,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
return
|
||||
}
|
||||
try {
|
||||
val successful = file.delete()
|
||||
val (successful, whyFailed) = file.delete()
|
||||
if (!successful) {
|
||||
statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_FAILED)
|
||||
return
|
||||
@@ -381,7 +403,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
return
|
||||
}
|
||||
try {
|
||||
val status = file.mkdir()
|
||||
val (status, whyFailed) = file.mkdir()
|
||||
statusCode.set(if (status) 0 else 1)
|
||||
if (status) {
|
||||
printdbg("Notifying disk commit (mkdir)")
|
||||
@@ -402,7 +424,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
return
|
||||
}
|
||||
try {
|
||||
val f1 = file.createNewFile()
|
||||
val (f1, whyFailed) = file.createNewFile()
|
||||
statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED)
|
||||
if (f1) {
|
||||
printdbg("Notifying disk commit (mkfile)")
|
||||
@@ -427,7 +449,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
return
|
||||
}
|
||||
try {
|
||||
val f1 = file.setLastModified(vm.worldInterface.currentTimeInMills())
|
||||
val (f1, whyFailed) = file.setLastModified(vm.worldInterface.currentTimeInMills())
|
||||
statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED)
|
||||
if (f1) {
|
||||
printdbg("Notifying disk commit (touch)")
|
||||
@@ -452,11 +474,16 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
return
|
||||
}
|
||||
if (!file.exists()) {
|
||||
val f1 = file.createNewFile()
|
||||
val (f1, whyFailed) = file.createNewFile()
|
||||
statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED)
|
||||
if (!f1) { return }
|
||||
}
|
||||
// if (fileOpenMode == 1) { writeMode = true; appendMode = false }
|
||||
// else if (fileOpenMode == 2) { writeMode = false; appendMode = true }
|
||||
writeModeLength = inputString.substring(5, inputString.length).toInt()
|
||||
|
||||
printdbg("WRITE issued with len $writeModeLength")
|
||||
|
||||
writeBuffer = ByteArray(writeModeLength)
|
||||
writeBufferUsage = 0
|
||||
statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
|
||||
@@ -493,8 +520,10 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
// DOM.entries.clear()
|
||||
// DOM.diskName = newName.toByteArray(VM.CHARSET)
|
||||
}
|
||||
else
|
||||
else {
|
||||
printdbg("Illegal command: ${inputString}")
|
||||
statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,12 @@ import java.io.IOException
|
||||
*/
|
||||
class TevdFileDescriptor(val DOM: PartialDOM, _pathstr: String) {
|
||||
|
||||
val path = _pathstr.replace('\\', '/')
|
||||
val path = _pathstr.replace('\\', '/').let {
|
||||
var s = it.substring(0)
|
||||
while (s.startsWith("/"))
|
||||
s = s.substring(1)
|
||||
s
|
||||
}
|
||||
val vdPath = VDUtil.VDPath(path, VM.CHARSET)
|
||||
|
||||
val entryID: EntryID?
|
||||
@@ -84,16 +89,19 @@ class TevdFileDescriptor(val DOM: PartialDOM, _pathstr: String) {
|
||||
return (DOM.requestFile(path) != null)
|
||||
}
|
||||
|
||||
fun delete(): Boolean {
|
||||
fun delete(): Pair<Boolean, Throwable?> {
|
||||
return try {
|
||||
val parentDir = vdPath.getParent().toString()
|
||||
DOM.removeFile(path)
|
||||
DOM.requestFile(parentDir)!!.modificationDate = VDUtil.currentUnixtime
|
||||
DOM.requestFile(parentDir)!!.let {
|
||||
it.modificationDate = VDUtil.currentUnixtime
|
||||
DOM.touchFile(it)
|
||||
}
|
||||
|
||||
true
|
||||
true to null
|
||||
}
|
||||
catch (e: KotlinNullPointerException) {
|
||||
false
|
||||
false to e
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +127,7 @@ class TevdFileDescriptor(val DOM: PartialDOM, _pathstr: String) {
|
||||
return fileContent.getContent().toByteArray()
|
||||
}
|
||||
|
||||
fun mkdir(): Boolean {
|
||||
fun mkdir(): Pair<Boolean, Throwable?> {
|
||||
return try {
|
||||
val parentDir = vdPath.getParent().toString()
|
||||
|
||||
@@ -131,18 +139,19 @@ class TevdFileDescriptor(val DOM: PartialDOM, _pathstr: String) {
|
||||
val newDir = DiskEntry(newID, dir.entryID, nameBytes, newTime, newTime, EntryDirectory())
|
||||
|
||||
DOM.addNewFile(newDir)
|
||||
DOM.touchFile(dir)
|
||||
dirContent.add(newID)
|
||||
|
||||
dir.modificationDate = newTime
|
||||
|
||||
true
|
||||
true to null
|
||||
}
|
||||
catch (e: KotlinNullPointerException) {
|
||||
false
|
||||
false to e
|
||||
}
|
||||
}
|
||||
|
||||
fun createNewFile(): Boolean {
|
||||
fun createNewFile(): Pair<Boolean, Throwable?> {
|
||||
val fileContent = EntryFile(ByteArray64())
|
||||
val time_t = System.currentTimeMillis() / 1000
|
||||
val newFile = DiskEntry(-1, -1, nameBytes, time_t, time_t, fileContent)
|
||||
@@ -159,24 +168,28 @@ class TevdFileDescriptor(val DOM: PartialDOM, _pathstr: String) {
|
||||
newFile.parentEntryID = dir.entryID
|
||||
|
||||
DOM.addNewFile(newFile)
|
||||
DOM.touchFile(dir)
|
||||
dirContent.add(newID)
|
||||
|
||||
dir.modificationDate = newTime
|
||||
|
||||
true
|
||||
true to null
|
||||
}
|
||||
catch (e: KotlinNullPointerException) {
|
||||
false
|
||||
false to e
|
||||
}
|
||||
}
|
||||
|
||||
fun setLastModified(newTime_t: Long): Boolean {
|
||||
fun setLastModified(newTime_t: Long): Pair<Boolean, Throwable?> {
|
||||
return try {
|
||||
DOM.requestFile(path)!!.modificationDate = newTime_t
|
||||
true
|
||||
DOM.requestFile(path)!!.let {
|
||||
it.modificationDate = newTime_t
|
||||
DOM.touchFile(it)
|
||||
}
|
||||
true to null
|
||||
}
|
||||
catch (e: KotlinNullPointerException) {
|
||||
false
|
||||
false to e
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,8 @@ 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 kotlin.Pair;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import net.torvald.tsvm.peripheral.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class AppLoader {
|
||||
@@ -32,7 +29,8 @@ public class AppLoader {
|
||||
appConfig.setWindowedMode(WIDTH, HEIGHT);
|
||||
|
||||
HashMap<String, VMWatchdog> watchdogs = new HashMap<>();
|
||||
watchdogs.put("TEVD_SYNC", TevdSyncWatchdog.INSTANCE);
|
||||
watchdogs.put("TEVD_COMMIT", TevdPartialDomCommitWatchdog.INSTANCE);
|
||||
watchdogs.put("TEVD_SYNC", TevdPartialDomSyncWatchdog.INSTANCE);
|
||||
|
||||
|
||||
String diskPath = "assets/disk0";
|
||||
|
||||
@@ -65,9 +65,13 @@ class VMEmuExecutableWrapper(val windowWidth: Int, val windowHeight: Int, var pa
|
||||
*/
|
||||
class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: Int, var panelsY: Int, val diskPathRoot: String) : ApplicationAdapter() {
|
||||
|
||||
val TEVD_SYNC = TevdSyncWatchdog
|
||||
val TEVD_COMMIT = TevdPartialDomCommitWatchdog
|
||||
val TEVD_SYNC = TevdPartialDomCommitWatchdog
|
||||
|
||||
val watchdogs = hashMapOf<String, VMWatchdog>("TEVD_SYNC" to TEVD_SYNC)
|
||||
val watchdogs = hashMapOf<String, VMWatchdog>(
|
||||
"TEVD_COMMIT" to TEVD_COMMIT,
|
||||
"TEVD_SYNC" to TEVD_SYNC
|
||||
)
|
||||
|
||||
data class VMRunnerInfo(val vm: VM, val profileName: String)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user