From 055b825cca8df66037201dbb31c83515482f1644 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 31 Oct 2020 22:23:26 +0900 Subject: [PATCH] booting entirely from the bios --- assets/JS_INIT.js | 14 +++++++ assets/bios1.js | 40 ++++++++----------- src/net/torvald/tsvm/SerialHelper.kt | 6 ++- src/net/torvald/tsvm/VMGUI.kt | 26 ++---------- .../tsvm/peripheral/BlockTransferInterface.kt | 18 ++++----- .../torvald/tsvm/peripheral/TestDiskDrive.kt | 38 +++++++++++++++++- .../tsvm/peripheral/TestFunctionGenerator.kt | 4 +- 7 files changed, 86 insertions(+), 60 deletions(-) diff --git a/assets/JS_INIT.js b/assets/JS_INIT.js index 1babea0..2a617d1 100644 --- a/assets/JS_INIT.js +++ b/assets/JS_INIT.js @@ -300,9 +300,23 @@ function println(s) { else sys.println(s); } +function printerr(s) { + print("\x1B[31m"+s+"\x1B[m"); +} +function printerrln(s) { + println("\x1B[31m"+s+"\x1B[m"); +} function read() { return sys.read(); } +String.prototype.trimNull = function() { + let cnt = this.length - 1 + while (cnt >= 0) { + if (this.charCodeAt(cnt) != 0) break; + cnt -= 1; + } + return this.slice(0, cnt + 1); +} // ncurses-like terminal control var con = {}; con.getch = function() { diff --git a/assets/bios1.js b/assets/bios1.js index c193e58..53a8349 100644 --- a/assets/bios1.js +++ b/assets/bios1.js @@ -7,27 +7,6 @@ println("TERRAN Megatrends inc."); let memptr = 0; const memtestptn = [ - // Overclockers will LOVE this! - //[0x00,0x00,0x00,0x00 , 0xFF,0xFF,0xFF,0xFF , 0x00,0x00,0x00,0x00 , 0xFF,0xFF,0xFF,0xFF], - - //[0xAA,0x55,0xAA,0x55 , 0xAA,0x55,0xAA,0x55 , 0xAA,0x55,0xAA,0x55 , 0xAA,0x55,0xAA,0x55], - //[0x00,0xFF,0x00,0xFF , 0xFF,0x00,0xFF,0x00 , 0x00,0xFF,0x00,0xFF , 0xFF,0x00,0xFF,0x00], - - //[0x69,0x69,0x69,0x69 , 0xA5,0xA5,0xA5,0xA5 , 0x69,0x69,0x69,0x69 , 0xA5,0xA5,0xA5,0xA5], - //[0x0F,0x0F,0x0F,0x0F , 0x1E,0x1E,0x1E,0x1E , 0x3C,0x3C,0x3C,0x3C , 0x78,0x78,0x78,0x78], - - //[0xC7,0x1C,0x71,0xC7 , 0x8E,0x38,0xE3,0x8E , 0x1C,0x71,0xC7,0x1C , 0x38,0xE3,0x8E,0x38], - //[0x71,0xC7,0x1C,0x71 , 0xE3,0x8E,0x38,0xE3 , 0x01,0x02,0x04,0x08 , 0x10,0x20,0x40,0x80], - - //[0x00,0x00,0xFF,0xFF , 0x00,0x00,0xFF,0xFF , 0x00,0x01,0xFF,0xFE , 0x00,0x01,0xFF,0xFE], - //[0x00,0x03,0xFF,0xFC , 0x00,0x03,0xFF,0xFC , 0x00,0x07,0xFF,0xF8 , 0x00,0x07,0xFF,0xF8], - //[0x00,0x0F,0xFF,0xF0 , 0x00,0x0F,0xFF,0xF0 , 0x00,0x1F,0xFF,0xE0 , 0x00,0x1F,0xFF,0xE0], - //[0x00,0x3F,0xFF,0xC0 , 0x00,0x3F,0xFF,0xC0 , 0x00,0x7F,0xFF,0x80 , 0x00,0x7F,0xFF,0x80], - //[0x00,0xFF,0xFF,0x00 , 0x00,0xFF,0xFF,0x00 , 0x01,0xFF,0xFE,0x00 , 0x01,0xFF,0xFE,0x00], - //[0x03,0xFF,0xFC,0x00 , 0x03,0xFF,0xFC,0x00 , 0x07,0xFF,0xF8,0x00 , 0x07,0xFF,0xF8,0x00], - //[0x0F,0xFF,0xF0,0x00 , 0x0F,0xFF,0xF0,0x00 , 0x1F,0xFF,0xE0,0x00 , 0x1F,0xFF,0xE0,0x00], - //[0x3F,0xFF,0xC0,0x00 , 0x3F,0xFF,0xC0,0x00 , 0x7F,0xFF,0x80,0x00 , 0x7F,0xFF,0x80,0x00], - [0x00,0xFF,0xAA,0x55 , 0x69,0x0F,0xA5,0x1E , 0xC7,0x71,0x8E,0xE3 , 0xCA,0xFE,0xBA,0xBE], [0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF] ]; @@ -82,5 +61,20 @@ Object.freeze(_BIOS); /////////////////////////////////////////////////////////////////////////////// -// TODO load a bootsector using 'LOADBOOT' -con.move(4,1); \ No newline at end of file +// load a bootsector using 'LOADBOOT' +let portNumber = 0; +let driveStatus = 0; +while (portNumber < 4) { + if (com.areYouThere(portNumber)) { + com.sendMessage(portNumber, "LOADBOOT"); + driveStatus = com.getStatusCode(portNumber); + if (driveStatus == 0) break; + } + portNumber += 1; +} +if (portNumber < 4) { + eval(com.fetchResponse(portNumber).trimNull()); +} +else { + printerrln("No bootable medium found."); +} \ No newline at end of file diff --git a/src/net/torvald/tsvm/SerialHelper.kt b/src/net/torvald/tsvm/SerialHelper.kt index 25901ef..d411550 100644 --- a/src/net/torvald/tsvm/SerialHelper.kt +++ b/src/net/torvald/tsvm/SerialHelper.kt @@ -4,6 +4,7 @@ import net.torvald.UnsafeHelper import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toUint import net.torvald.tsvm.peripheral.BlockTransferInterface.Companion.BLOCK_SIZE import net.torvald.tsvm.peripheral.BlockTransferInterface.Companion.END_OF_SEND_BLOCK +import net.torvald.tsvm.peripheral.trimNull import java.io.ByteArrayOutputStream import kotlin.experimental.and import kotlin.experimental.or @@ -95,10 +96,10 @@ object SerialHelper { fun getStatusCode(vm: VM, portNo: Int) = vm.getIO().mmio_read(4080L + portNo) - private fun checkIfDeviceIsThere(vm: VM, portNo: Int) = + fun checkIfDeviceIsThere(vm: VM, portNo: Int) = (vm.getIO().mmio_read(4092L + portNo)!! and 1.toByte()) == 1.toByte() - private fun checkIfDeviceIsReady(vm: VM, portNo: Int) = + fun checkIfDeviceIsReady(vm: VM, portNo: Int) = (vm.getIO().mmio_read(4092L + portNo)!! and 0b111.toByte()) == 0b011.toByte() private fun initiateWriting(vm: VM, portNo: Int) { @@ -145,4 +146,5 @@ class SerialHelperDelegate(val vm: VM) { fun getStatusCode(portNo: Int) = SerialHelper.getStatusCode(vm, portNo) /** @return Object where { code: , message: } */ fun getDeviceStatus(portNo: Int) = SerialHelper.getDeviceStatus(vm, portNo) + fun areYouThere(portNo: Int) = SerialHelper.checkIfDeviceIsThere(vm, portNo) } \ No newline at end of file diff --git a/src/net/torvald/tsvm/VMGUI.kt b/src/net/torvald/tsvm/VMGUI.kt index f0c2ecf..f1d5050 100644 --- a/src/net/torvald/tsvm/VMGUI.kt +++ b/src/net/torvald/tsvm/VMGUI.kt @@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.g2d.SpriteBatch import kotlinx.coroutines.* import net.torvald.tsvm.peripheral.GraphicsAdapter +import java.io.File import java.io.FileReader class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter() { @@ -51,31 +52,10 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter() memvwr = Memvwr(vm) - // TEST PRG - //val fr = FileReader("./assets/tvdos/command.js") - //val fr = FileReader("./assets/jscon.js") - - val fr1 = FileReader("./assets/bios1.js") - //val fr1 = FileReader("./assets/phototest.js") - val bios = fr1.readText() - fr1.close() - - //val fr = FileReader("./assets/tvdos/command.js") - //val fr = FileReader("./assets/zippytest.js") - //val fr = FileReader("./assets/serialtest.js") - //val fr = FileReader("./assets/tvdos/fsh.js") - //val fr = FileReader("./assets/tvdos/flsh.js") - //val fr = FileReader("./assets/tbas/basic.js") - //val fr = FileReader("./assets/jscon.js") - val fr = FileReader("./assets/!BOOTSEC") - val prg = fr.readText() - fr.close() - + // load test bios vmRunner = VMRunnerFactory(vm, "js") coroutineJob = GlobalScope.launch { - //vmRunner.evalGlobal("$bios") - //vmRunner.executeCommand(prg) - vmRunner.executeCommand("$bios\n$prg") + vmRunner.executeCommand(File("./assets/bios1.js").readText(VM.CHARSET)) } } diff --git a/src/net/torvald/tsvm/peripheral/BlockTransferInterface.kt b/src/net/torvald/tsvm/peripheral/BlockTransferInterface.kt index 211a6be..3c95247 100644 --- a/src/net/torvald/tsvm/peripheral/BlockTransferInterface.kt +++ b/src/net/torvald/tsvm/peripheral/BlockTransferInterface.kt @@ -86,14 +86,14 @@ abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolea const val BAD_NEWS = 0x15.toByte() const val UNIT_SEP = 0x1F.toByte() const val END_OF_SEND_BLOCK = 0x17.toByte() - - fun trimNull(ba: ByteArray): ByteArray { - var cnt = BLOCK_SIZE - 1 - while (cnt >= 0) { - if (ba[cnt] != 0.toByte()) break - cnt -= 1 - } - return ba.sliceArray(0..cnt) - } } +} + +fun ByteArray.trimNull(): ByteArray { + var cnt = BlockTransferInterface.BLOCK_SIZE - 1 + while (cnt >= 0) { + if (this[cnt] != 0.toByte()) break + cnt -= 1 + } + return this.sliceArray(0..cnt) } \ No newline at end of file diff --git a/src/net/torvald/tsvm/peripheral/TestDiskDrive.kt b/src/net/torvald/tsvm/peripheral/TestDiskDrive.kt index 8e416c1..519a7a5 100644 --- a/src/net/torvald/tsvm/peripheral/TestDiskDrive.kt +++ b/src/net/torvald/tsvm/peripheral/TestDiskDrive.kt @@ -3,6 +3,7 @@ package net.torvald.tsvm.peripheral import net.torvald.tsvm.VM import java.io.ByteArrayOutputStream import java.io.File +import java.io.FileInputStream import java.io.IOException import java.util.* @@ -122,7 +123,7 @@ class TestDiskDrive(private val driveNum: Int, theRootPath: File? = null) : Bloc } } else { - val inputString = trimNull(inputData).toString(VM.CHARSET) + val inputString = inputData.trimNull().toString(VM.CHARSET) if (inputString.startsWith("DEVRST\u0017")) { println("[TestDiskDrive] Device Reset") @@ -217,6 +218,37 @@ class TestDiskDrive(private val driveNum: Int, theRootPath: File? = null) : Bloc return } } + else if (inputString.startsWith("LOADBOOT")) { + 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 + + val bootFile = File(rootPath, "!BOOTSEC") + + if (!bootFile.exists()) { + statusCode = STATE_CODE_FILE_NOT_FOUND + return + } + val fis = FileInputStream(bootFile) + try { + val retMsg = ByteArray(BLOCK_SIZE) + fis.read(retMsg) + recipient?.writeout(retMsg) + statusCode = STATE_CODE_STANDBY + } + catch (e: IOException) { + statusCode = STATE_CODE_SYSTEM_IO_ERROR + return + } + finally { + fis.close() + } + } else if (inputString.startsWith("WRITE")) { if (!fileOpen || fileOpenMode < 0) { statusCode = STATE_CODE_OPERATION_NOT_PERMITTED @@ -228,8 +260,10 @@ class TestDiskDrive(private val driveNum: Int, theRootPath: File? = null) : Bloc } writeMode = true writeModeLength = inputString.substring(5, inputString.length).toInt() - statusCode = 0 + statusCode = STATE_CODE_STANDBY } + else + statusCode = STATE_CODE_ILLEGAL_COMMAND } } diff --git a/src/net/torvald/tsvm/peripheral/TestFunctionGenerator.kt b/src/net/torvald/tsvm/peripheral/TestFunctionGenerator.kt index a2c1dad..ef7224a 100644 --- a/src/net/torvald/tsvm/peripheral/TestFunctionGenerator.kt +++ b/src/net/torvald/tsvm/peripheral/TestFunctionGenerator.kt @@ -149,7 +149,7 @@ Nunc mollis nibh vitae sapien consequat, ut vestibulum sem pharetra. Aliquam iac } } else { - val inputString = trimNull(inputData).toString(VM.CHARSET) + val inputString = inputData.trimNull().toString(VM.CHARSET) if (inputString.startsWith("DEVRST\u0017")) { fileOpen = false @@ -171,6 +171,8 @@ Nunc mollis nibh vitae sapien consequat, ut vestibulum sem pharetra. Aliquam iac writeModeLength = inputString.substring(5, inputString.length).toInt() statusCode = 0 } + else + statusCode = 128 blockSendCount = 0 }