From 537651993e922b2dff3ba2ea602cfa4a3088da01 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Tue, 10 May 2022 12:47:53 +0900 Subject: [PATCH] BIOS with selectable boot device --- assets/bios/openbios.js | 162 ++++++++++++++++++ .../torvald/tsvm/peripheral/VMProgramRom.kt | 2 +- .../tsvmperipheral/WorldRadar.kt | 6 + .../src/net/torvald/tsvm/AppLoader.java | 3 +- 4 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 assets/bios/openbios.js diff --git a/assets/bios/openbios.js b/assets/bios/openbios.js new file mode 100644 index 0000000..cb5968a --- /dev/null +++ b/assets/bios/openbios.js @@ -0,0 +1,162 @@ +let SKIP_MEMTEST = 1 +let BOOT_OVERRIDE = undefined // undefined or port number (int) + +con.reset_graphics();con.curs_set(0);con.clear() +graphics.resetPalette() + +const BIOS_VERSION_STR = "1.0" + +function probeBootable() { + let driveStatus = 0 + let bootable = [0,0,0,0] + for (let portNumber = 0; portNumber < 4; portNumber++) { + if (com.areYouThere(portNumber)) { + com.sendMessage(portNumber, "LOADBOOT") + driveStatus = com.getStatusCode(portNumber) + if (driveStatus == 0) bootable[portNumber] = 1 + } + } + return bootable +} + +function bootFromPort(port) { + con.clear() + try { + com.sendMessage(port, "LOADBOOT") + let driveStatus = com.getStatusCode(port) + if (driveStatus == 0) {Function(`"use strict";var _BIOS={};_BIOS.FIRST_BOOTABLE_PORT=[${port},1];Object.freeze(_BIOS);`+com.fetchResponse(port).trimNull())()} + else throw "No Bootsector" + } + catch (e) { + printerrln(`No bootable medium on COM ${port+1}`) + } +} + +function showSplash() { + println(`OpenBIOS version ${BIOS_VERSION_STR}`) +} + +function showHowtoEnterMenu() { + let s = `Hit Ctrl+Shift+S+Q or SysRq to enter boot menu` + let [h,w] = con.getmaxyx() + con.move(h, (w-s.length)/2) + print(s) +} + +function bootFromFirst() { + con.clear() + let port = (BOOT_OVERRIDE != undefined) ? BOOT_OVERRIDE : bootable.findIndex(it=>it==1) + if (port < 0) printerrln("No bootable medium found.") + else bootFromPort(port) +} + +function runConfigurator() { + sys.unsetSysrq() + con.clear() + con.move(2,2);print("Devices:") + for (let i = 0; i < 4; i++) { + con.move(i*2+4, 2) + let bootableMark = (bootable[i]) ? "* " : " " + + let deviceName = undefined + try { + com.sendMessage(i, "DEVNAM\x17") + deviceName = com.fetchResponse(i).substring(0,40) + } + catch (e) { + deviceName = `(device not connected)` + } + + println(bootableMark + `Serial port #${i+1}: ` + deviceName) + } + + let bootnum = undefined + while (true) { + con.move(12,1) + con.curs_set(1) + print("\n Hit 1, 2, 3 or 4 to boot from the specified device: ") + let dev = Number(read()) + serial.println(dev) + if (Number.isInteger(dev) && dev >= 1 && dev <= 4) { + bootnum = dev - 1 + break + } + } + bootFromPort(bootnum) +} + + + +/////////////////////////////////////////////////////////////////////////////// + +// Perform memtest + +if (!SKIP_MEMTEST) { +let memptr = 0 +let reportedMemsize = system.maxmem() +const memtestptn = (reportedMemsize >= 4194304) ? +[ + [0x00,0xFF,0xAA,0x55] +] : (reportedMemsize >= 1048576) ? +[ + [0x00,0xFF,0xAA,0x55 , 0x69,0x0F,0xA5,0x1E] +] : (reportedMemsize >= 262144) ? +[ + [0x00,0xFF,0xAA,0x55 , 0x69,0x0F,0xA5,0x1E , 0xC7,0x71,0x8E,0xE3 , 0xCA,0xFE,0xBA,0xBE] +] : +[ + [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] +] + +con.move(2,1) +print(" 000 KB OK") + +try { + while (memptr < (8 << 20)) { + // just print a number + con.move(2,1) + var memptrtext = ""+(1 + ((memptr) >> 10)) + print((memptrtext < 10) ? " 00"+memptrtext : (memptrtext < 100) ? " 0"+memptrtext : (memptrtext < 1000) ? " "+memptrtext : memptrtext) + + // perform memory test + for (var ptn = 0; ptn < memtestptn.length; ptn++) { + for (var bi = 0; bi < memtestptn[ptn].length; bi++) { + sys.poke(memptr + bi, memtestptn[ptn][bi]) + if (memtestptn[ptn][bi] != sys.peek(memptr + bi)) throw "Memory Error" + } + /*for (var bi = 0; bi < memtestptn[ptn].length; bi++) { + sys.poke(memptr + bi, 255 - memtestptn[ptn][bi]) + if (255 - memtestptn[ptn][bi] != sys.peek(memptr + bi)) throw "Memory Error" + }*/ + } + + memptr += memtestptn[0].length + } + throw undefined +} +catch (e) { + if (e == "Memory Error") + println(" "+e) + else + println(" KB OK!") +} +} + +/////////////////////////////////////////////////////////////////////////////// + + +showSplash() +showHowtoEnterMenu() + +let bootable = probeBootable() +let sysRq = false +let tmr = sys.nanoTime() +while (sys.nanoTime() - tmr < 5 * 1000000000.0) { + sysRq = sys.getSysrq() + if (sysRq) break + sys.spin() +} + +if (!sysRq) bootFromFirst() +else runConfigurator() diff --git a/tsvm_core/src/net/torvald/tsvm/peripheral/VMProgramRom.kt b/tsvm_core/src/net/torvald/tsvm/peripheral/VMProgramRom.kt index 0ba4666..c4b4fa9 100644 --- a/tsvm_core/src/net/torvald/tsvm/peripheral/VMProgramRom.kt +++ b/tsvm_core/src/net/torvald/tsvm/peripheral/VMProgramRom.kt @@ -33,6 +33,6 @@ object TsvmBios : VMProgramRom("./assets/bios/tsvmbios.js") object BasicRom : VMProgramRom("./assets/bios/basic.bin") object TBASRelBios : VMProgramRom("./assets/bios/tbasdist.js") object WPBios : VMProgramRom("./assets/bios/wp.js") - +object OpenBios : VMProgramRom("./assets/bios/openbios.js") object PipBios : VMProgramRom("./assets/bios/pipboot.rom") object PipROM : VMProgramRom("./assets/bios/pipcode.bas") \ No newline at end of file diff --git a/tsvm_executable/src/net/torvald/terrarum/modulecomputers/tsvmperipheral/WorldRadar.kt b/tsvm_executable/src/net/torvald/terrarum/modulecomputers/tsvmperipheral/WorldRadar.kt index 598a950..9b7cbf9 100644 --- a/tsvm_executable/src/net/torvald/terrarum/modulecomputers/tsvmperipheral/WorldRadar.kt +++ b/tsvm_executable/src/net/torvald/terrarum/modulecomputers/tsvmperipheral/WorldRadar.kt @@ -128,6 +128,12 @@ class WorldRadar(pngfile: FileHandle) : BlockTransferInterface(false, true) { } oldCmdbuf = cmdbuf + + statusCode = TestDiskDrive.STATE_CODE_STANDBY + } + else { + resetBuf() + statusCode = TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND } } } \ No newline at end of file diff --git a/tsvm_executable/src/net/torvald/tsvm/AppLoader.java b/tsvm_executable/src/net/torvald/tsvm/AppLoader.java index 4163ed0..440f0d2 100644 --- a/tsvm_executable/src/net/torvald/tsvm/AppLoader.java +++ b/tsvm_executable/src/net/torvald/tsvm/AppLoader.java @@ -32,7 +32,8 @@ public class AppLoader { // VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{OEMBios.INSTANCE, BasicRom.INSTANCE}); // VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{TandemBios.INSTANCE, BasicRom.INSTANCE}); // VM vm = new VM(128 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, WPBios.INSTANCE}); - VM vm = new VM("./assets", 8192 << 10, new TheRealWorld(), new VMProgramRom[]{TsvmBios.INSTANCE}); +// VM vm = new VM("./assets", 8192 << 10, new TheRealWorld(), new VMProgramRom[]{TsvmBios.INSTANCE}); + VM vm = new VM("./assets", 8192 << 10, new TheRealWorld(), new VMProgramRom[]{OpenBios.INSTANCE}); VM pipvm = new VM("./assets", 4096, new TheRealWorld(), new VMProgramRom[]{PipBios.INSTANCE, PipROM.INSTANCE}); String diskPath = "assets/disk0";