tevd: bootloader is now entry id 1

This commit is contained in:
minjaesong
2022-12-23 05:23:54 +09:00
parent 1ecb85354b
commit 59399d84f9
6 changed files with 93 additions and 15 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -23,7 +23,17 @@ function copyFiles(destDrive) {
}) })
// bare files in the root dir // bare files in the root dir
;["!BOOTSEC", "AUTOEXEC.BAT"].forEach((name)=>{ ;["AUTOEXEC.BAT"].forEach((name)=>{
dos.cp(`A:\\tvdos\\installer\\${name}`, `${destDrive}:\\${name}`) dos.cp(`A:\\tvdos\\installer\\${name}`, `${destDrive}:\\${name}`)
}) })
// install bootloader
val bootloader = files.open("A:\\tvdos\\installer\\!BOOTSEC").sread()
let [port, poru] = _TVDOS.DRV.FS.SERIAL._toPorts(destDrive)[0]
com.sendMessage(port, "FLUSH");com.sendMessage(port, "CLOSE")
com.sendMessage(port, `NEWTEVDBOOT,${poru}`) // read-only check will be performed by the other writes
com.sendMessage(port, bootloader)
com.sendMessage(port, "FLUSH");com.sendMessage(port, "CLOSE")
} }

View File

@@ -150,6 +150,16 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
appendMode = false appendMode = false
} }
} }
else if (fileOpenMode == 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 }
else inputData
file.writeBytes(inputData)
fileOpenMode = -1
}
else { else {
val inputString = inputData.trimNull().toString(VM.CHARSET) val inputString = inputData.trimNull().toString(VM.CHARSET)
@@ -311,6 +321,21 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
return return
} }
} }
else if (inputString.startsWith("NEWTEVDBOOT")) {
var commaIndex = 0
while (commaIndex < inputString.length) {
if (inputString[commaIndex] == ',') break
commaIndex += 1
}
val driveNum = if (commaIndex >= inputString.length) null else commaIndex
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
statusCode.set(STATE_CODE_STANDBY)
fileOpen = true
fileOpenMode = 17
blockSendCount = 0
}
else if (inputString.startsWith("LOADBOOT")) { else if (inputString.startsWith("LOADBOOT")) {
var commaIndex = 0 var commaIndex = 0
while (commaIndex < inputString.length) { while (commaIndex < inputString.length) {

View File

@@ -14,7 +14,7 @@ import java.util.concurrent.atomic.AtomicBoolean
class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val theTevdPath: String, val diskUUIDstr: String) : BlockTransferInterface(false, true) { class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val theTevdPath: String, val diskUUIDstr: String) : BlockTransferInterface(false, true) {
private val DBGPRN = false private val DBGPRN = true
val diskID: UUID = UUID.fromString(diskUUIDstr) val diskID: UUID = UUID.fromString(diskUUIDstr)
@@ -30,8 +30,10 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
private var fileOpenMode = -1 // 1: 'W", 2: 'A' private var fileOpenMode = -1 // 1: 'W", 2: 'A'
private var file: TevdFileDescriptor = TevdFileDescriptor(DOM, "") private var file: TevdFileDescriptor = TevdFileDescriptor(DOM, "")
//private var readModeLength = -1 // always 4096 //private var readModeLength = -1 // always 4096
private var writeMode = false private val writeMode
private var appendMode = false get() = fileOpenMode == 1
private val appendMode
get() = fileOpenMode == 2
private var writeModeLength = -1 private var writeModeLength = -1
private val messageComposeBuffer = ByteArrayOutputStream(BLOCK_SIZE) // always use this and don't alter blockSendBuffer please private val messageComposeBuffer = ByteArrayOutputStream(BLOCK_SIZE) // always use this and don't alter blockSendBuffer please
@@ -113,13 +115,25 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
else if (writeMode) else if (writeMode)
file.writeBytes(writeBuffer) file.writeBytes(writeBuffer)
writeMode = false fileOpenMode = -1
appendMode = false
printdbg("Notifying disk commit (end of write)") printdbg("Notifying disk commit (end of write)")
notifyDiskCommit() notifyDiskCommit()
} }
} }
else if (fileOpenMode == 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 }
else inputData
file.writeBytes(inputData)
fileOpenMode = -1
printdbg("Notifying disk commit (end of bootloader write)")
notifyDiskCommit()
}
else { else {
val inputString = inputData.trimNull().toString(VM.CHARSET) val inputString = inputData.trimNull().toString(VM.CHARSET)
@@ -131,7 +145,6 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
file = TevdFileDescriptor(DOM, "") file = TevdFileDescriptor(DOM, "")
blockSendCount = 0 blockSendCount = 0
statusCode.set(TestDiskDrive.STATE_CODE_STANDBY) statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
writeMode = false
writeModeLength = -1 writeModeLength = -1
} }
else if (inputString.startsWith("DEVSTU\u0017")) else if (inputString.startsWith("DEVSTU\u0017"))
@@ -297,6 +310,27 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
return return
} }
} }
else if (inputString.startsWith("NEWTEVDBOOT")) {
var commaIndex = 0
while (commaIndex < inputString.length) {
if (inputString[commaIndex] == ',') break
commaIndex += 1
}
val driveNum = if (commaIndex >= inputString.length) null else commaIndex
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
if (DOM.isReadOnly) {
printdbg("! disk is read-only")
statusCode.set(TestDiskDrive.STATE_CODE_READ_ONLY)
return
}
statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
fileOpen = true
fileOpenMode = 17
blockSendCount = 0
}
else if (inputString.startsWith("LOADBOOT")) { else if (inputString.startsWith("LOADBOOT")) {
var commaIndex = 0 var commaIndex = 0
while (commaIndex < inputString.length) { while (commaIndex < inputString.length) {
@@ -307,17 +341,17 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it // TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
val bootFile = TevdFileDescriptor(DOM, "!BOOTSEC") val bootFile = DOM.entries[1]
printdbg("bootFile = $bootFile, ID: ${bootFile.entryID}, exists = ${bootFile.exists()}") printdbg("bootFile = $bootFile, ID: 1, exists = ${bootFile != null}")
if (!bootFile.exists()) { if (bootFile == null) {
printdbg("bootfile not exists!") printdbg("bootfile not exists!")
statusCode.set(TestDiskDrive.STATE_CODE_NO_SUCH_FILE_EXISTS) statusCode.set(TestDiskDrive.STATE_CODE_NO_SUCH_FILE_EXISTS)
return return
} }
try { try {
val retMsg = bootFile.getHeadBytes(BLOCK_SIZE) val retMsg = VDUtil.getAsNormalFile(DOM, 1).getContent().sliceArray(0 until BLOCK_SIZE)
printdbg("retMsg = ${retMsg.toString(VM.CHARSET)}") printdbg("retMsg = ${retMsg.toString(VM.CHARSET)}")
@@ -412,8 +446,6 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED) statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
if (fileOpenMode == 1) { writeMode = true; appendMode = false }
else if (fileOpenMode == 2) { writeMode = false; appendMode = true }
if (!file.exists()) { if (!file.exists()) {
val f1 = file.createNewFile() val f1 = file.createNewFile()
statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED) statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED)

View File

@@ -1,7 +1,8 @@
package net.torvald.tsvm package net.torvald.tsvm
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.EntryFile
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VDUtil import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VDUtil
import net.torvald.tsvm.VM import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VDUtil.checkReadOnly
import java.io.File import java.io.File
/** /**
@@ -33,12 +34,22 @@ fun main(args: Array<String>) {
// bare file in root dir // bare file in root dir
listOf( listOf(
VDUtil.importFile(File("assets/disk0/root.bootable/!BOOTSEC"), disk.generateUniqueID(), VM.CHARSET),
VDUtil.importFile(File("assets/disk0/root.bootable/AUTOEXEC.BAT"), disk.generateUniqueID(), VM.CHARSET), VDUtil.importFile(File("assets/disk0/root.bootable/AUTOEXEC.BAT"), disk.generateUniqueID(), VM.CHARSET),
).forEach { ).forEach {
VDUtil.addFile(disk, 0, it) VDUtil.addFile(disk, 0, it)
} }
VDUtil.importFile(File("assets/disk0/root.bootable/!BOOTSEC"), 1, VM.CHARSET).let {
disk.checkReadOnly()
// disk.checkCapacity(4096)
(it.contents as EntryFile).let { file ->
val bytes = file.getContent()
bytes.appendBytes(ByteArray(4096 - bytes.size.toInt()))
}
disk.entries[1] = it
}
VDUtil.dumpToRealMachine(disk, File(args[0])) VDUtil.dumpToRealMachine(disk, File(args[0]))
} }