tevd disk drive update and fixes

This commit is contained in:
minjaesong
2023-03-04 21:10:52 +09:00
parent 57a84ccfae
commit 2d000013b7
10 changed files with 108 additions and 37 deletions

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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_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,10 +520,12 @@ 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)
}
}
}
private fun sanitisePath(s: String) = s.replace('\\','/').replace(Regex("""\?<>:\*\|"""),"-")

View File

@@ -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
}
}

View File

@@ -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";

View File

@@ -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)