From 59399d84f991d796335acbffe3d7ed94fbc2e763 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Fri, 23 Dec 2022 05:23:54 +0900 Subject: [PATCH] tevd: bootloader is now entry id 1 --- assets/DOSBOOT.tevd | Bin 125642 -> 130830 bytes assets/DOSBOOT.tevd.original | Bin 125642 -> 130830 bytes assets/disk0/tvdos/installer/install.js | 12 +++- .../torvald/tsvm/peripheral/TestDiskDrive.kt | 25 ++++++++ .../torvald/tsvm/peripheral/TevdDiskDrive.kt | 56 ++++++++++++++---- .../net/torvald/tsvm/BuildTvdosBootable.kt | 15 ++++- 6 files changed, 93 insertions(+), 15 deletions(-) diff --git a/assets/DOSBOOT.tevd b/assets/DOSBOOT.tevd index ee152ab5fe6048a510b5431f7ea30c13c2622151..e564ad38a38f710ba624bcd59cf0e008b6a9a8ca 100644 GIT binary patch delta 2091 zcmbVNeM}o=9PX9dxORMPWqgdmULd0_ALS#PY$9q!iDJ!g~be_*&=Qc%w{5+I1FHnGeg1m_a5|v`IndU((C*D zp6B^}^mi90V+WRFkL9z&XSYub+v1rWr-IMubUeAIq_;SAF?Y%m{yH>%@Wvy@v+O#Z zj#1C$aEvJgdbpC~y*eg+R`FX409bN}ZPs10!6A8g+I@-pvIKj&D+5K>Vu z7{>K1SW#ar=a_=f!PL8n%eoB^;rAQ2%*}dc&cA-U>+inaH*PsgY?SFUYZTL1e*Gp6 zfRxR<7`BQkyJ_$y%CcAZcC@cE239I?XoB-9cub}3yq{p!;332j7pWk!D7>Vg z`?O-&+=A4qxCYzbX14BjIb@(FrMB_pyIrBs2peD*+5x91yAqk7mdyB_3(0xK#iXx7 zmq3UWmw?=&Bp{#SkQGsCMJ=+|gUrZm#6Jxrr-C;Ux@Hdb^dO+abx&mA+ChWKa+kgp zkAAcx9<(90pc0iDamUe&{on)~pi0tEa73s8u@kN9QY9)ud3p4VD3<_^)_}xOF|7uW zNGeH$@04XogeD8?iNYeOmcleZG{*G3`K8iGXysI&sL6%<&t zxwnuqSdBRFrfHK+>v(CowE_?CPQ?qqaS#57D=TUyqudrA7pMbV#Hl3sS8ck;voIX~1Y1boEK0CA1Bk7M#jCB~y#tMPx+GX*lj8ed0TnDJSdjgTAEakIUX{$( z-I{qI{;-sC+B1;J@42@BCF9(slieTM`ffBnH~v^>VXo^AtU}NTo}7xdaAuk*j7tCr z*kBZIC-1@|+;VueFImoTu<-QX;l*txwfN&vJqNNhqhABjbhlq)9=bmXlqsD{@H;y_ z?SybCIh@i&$>0#8o#33UG znNsQLU!tT3XJ?ry4r&6YYX6nUN~517a?p2b=u3T6{ug6z rvhgq+G}tZpe2~&g*h277AJd=6!MxD;AJU`ZZ*DugapN+%R?`0kkGT6d delta 1023 zcmeDC$A0Q6`vff(sbu#H8})b@wHKTGVPHrGlAMIw6J3!N>0i zOkKnO3M9sql$ke~k>!69NGU`^_R8Dy83Yn%J~*aw%fhX&?1uA&y-GLzGm@1LXuV)G zd-GbJx4dy;Glr%T-Rp@-)Glo((46(Byy62|n@lG36a zy{zJij=wnJmTcenknuSS2gp>As?D`REQ|=*&0WH$nK<5B|Jwj^<93q?jL5Rv9VasC z@Nj@^0_olE_#IW+?+4>9HWrX?w^v7t(;0w( zu_q_BM4`ZTGNZQS<|$0Mj4YtQ+Wy@Ts2btC=^Vz4PXs}}2m3HBF{d~c=)viY-i*I> z;ARF^I;(-qWZ*0U1wo#Ip*1K#!CFd+O2IllS}^`m!L7r<8WauS0O}D(4uZ`yB_g;v zK;aG!0mZ8*AuwI<8lwj|$~Q-faWI;}E%h(--2b7t(vn30jV{gBDVnCCrrlotPZLnz$$ zeV+F@@B8*S-_NFvt)`uW90NMR22JU2lAuw=H>DBh5!9CnfdGfL-)VF z%KH$nNQz2c=2omsiLNI)S2AtP1U*pCs116R0F=O{Z6H@qy7*Dns^LB$356^+6)L9@cpb8#Zz@@38-=XtBl_4Tk z78)%U^3sWtW>(gt_KPw_)-$R#HB_OX${y)C(X07rbclU!!CR~R3}9i|q?s?>yawsw z!!?)>b<=EKkzM_Q77o$M6*9+`R5e9Z3D2>?rz0~&5`>FjBHs%;;f zL6<~}B}vkFS)8;a`Nye9oZB#rTR8Kv^vohZr|M>tH3B?lUI^`eaQDz2~ z+PQ9EkBoJ97_z~vX2nmx1}3l_aK_OapBEMHZOP+1uFXG|(JR|N_K%hFJLaA~Zdv^4 z-SDJqI+nR)LN*~S2fw42ZSKt+| XAP)3Visi(kevpFBq^7RY=WfxzGehC? delta 1023 zcmeDC$A0Q6`vfhPm!E!gZ`9*uG+b=T%D|8eBu~$;eaXNQv8pVlc+#9(jBdZQ+h*6; zZkpXN&$>&DoiRPNq_ikUFROT><1bFQrtKRaGCpTv0qNLYb&ZjOQ5-IHiRpbW1H*(| zc6E^c?TS|!Sr`!-r|Vr~^xy%>fNW$+%FLV0$nrk|wV`v0O%C-K)r z=b3;1-h1GpU@K|-dP~GLz0w6sr|j`t$~1XnPiWs}!y5`xxge`R&i(s)U9`ib37fR1 zh!ujw!PYN$hGPBpwa*!Q_&GqvfuuLr3L!ggbC>XGCIOHgAW6p5l*|&K$ESa^VElvd z!S+@kMkhNCkPE>^^oXMvF;gOfTj-%*aTLgZjHSi#h2^P5C6&|dCoult1_wCApW6ei z8FhFBK%N9!R#H@&3bRZF9vXp_&T0%Gz*z)}hdc!XYmoOrI=0Wej_S2#HyFRM3xh%n zY+!PJZf;^;3OMF|h#&&E=|x&I$i#Bf&9An|acn+wXhZ7u9u3BHP9adJg7u~pWtOED zqeuGmrg@CFIY7Y-w*Pz=s{MDm83R~2KrsN8cKnVi?e~Lm7n?9B62Vp!9CKFKI;W!Z(?ku2mzBvl0PZA#1#vwh^K>@?qlapGaP+&WmQCo8J6sBB8 z4mq)wB_Ojl|5QeaYc|!Rec+t4IZ}*+Q5$ZOizBZ%11re++(kE9K)OM$0VN6$AMC1v zU8t_A-OX4c!2wF{;K2K0j4I7&%J_g;5R~GWA+l!G}46XkG!GB2r DZ$MpY diff --git a/assets/disk0/tvdos/installer/install.js b/assets/disk0/tvdos/installer/install.js index 7907664..0893f3c 100644 --- a/assets/disk0/tvdos/installer/install.js +++ b/assets/disk0/tvdos/installer/install.js @@ -23,7 +23,17 @@ function copyFiles(destDrive) { }) // bare files in the root dir - ;["!BOOTSEC", "AUTOEXEC.BAT"].forEach((name)=>{ + ;["AUTOEXEC.BAT"].forEach((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") + + } \ No newline at end of file diff --git a/tsvm_core/src/net/torvald/tsvm/peripheral/TestDiskDrive.kt b/tsvm_core/src/net/torvald/tsvm/peripheral/TestDiskDrive.kt index 55b09f2..7852d8c 100644 --- a/tsvm_core/src/net/torvald/tsvm/peripheral/TestDiskDrive.kt +++ b/tsvm_core/src/net/torvald/tsvm/peripheral/TestDiskDrive.kt @@ -150,6 +150,16 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath: 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 { val inputString = inputData.trimNull().toString(VM.CHARSET) @@ -311,6 +321,21 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath: 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")) { var commaIndex = 0 while (commaIndex < inputString.length) { diff --git a/tsvm_core/src/net/torvald/tsvm/peripheral/TevdDiskDrive.kt b/tsvm_core/src/net/torvald/tsvm/peripheral/TevdDiskDrive.kt index 39a4167..03963a8 100644 --- a/tsvm_core/src/net/torvald/tsvm/peripheral/TevdDiskDrive.kt +++ b/tsvm_core/src/net/torvald/tsvm/peripheral/TevdDiskDrive.kt @@ -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) { - private val DBGPRN = false + private val DBGPRN = true 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 file: TevdFileDescriptor = TevdFileDescriptor(DOM, "") //private var readModeLength = -1 // always 4096 - private var writeMode = false - private var appendMode = false + private val writeMode + get() = fileOpenMode == 1 + private val appendMode + get() = fileOpenMode == 2 private var writeModeLength = -1 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) file.writeBytes(writeBuffer) - writeMode = false - appendMode = false + fileOpenMode = -1 printdbg("Notifying disk commit (end of write)") 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 { 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, "") blockSendCount = 0 statusCode.set(TestDiskDrive.STATE_CODE_STANDBY) - writeMode = false writeModeLength = -1 } else if (inputString.startsWith("DEVSTU\u0017")) @@ -297,6 +310,27 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t 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")) { var commaIndex = 0 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 - 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!") statusCode.set(TestDiskDrive.STATE_CODE_NO_SUCH_FILE_EXISTS) return } 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)}") @@ -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) return } - if (fileOpenMode == 1) { writeMode = true; appendMode = false } - else if (fileOpenMode == 2) { writeMode = false; appendMode = true } if (!file.exists()) { val f1 = file.createNewFile() statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED) diff --git a/tsvm_executable/src/net/torvald/tsvm/BuildTvdosBootable.kt b/tsvm_executable/src/net/torvald/tsvm/BuildTvdosBootable.kt index d19ae71..3b68357 100644 --- a/tsvm_executable/src/net/torvald/tsvm/BuildTvdosBootable.kt +++ b/tsvm_executable/src/net/torvald/tsvm/BuildTvdosBootable.kt @@ -1,7 +1,8 @@ package net.torvald.tsvm +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.EntryFile 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 /** @@ -33,12 +34,22 @@ fun main(args: Array) { // bare file in root dir 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), ).forEach { 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])) }