From 28d639e1d10f7bbefb3b8a9b9afac60dcee87b7b Mon Sep 17 00:00:00 2001 From: 20kdc Date: Wed, 30 May 2018 14:07:52 +0100 Subject: [PATCH] Fix some small metamachine issues, and make the virtual EEPROM for metamachine better. --- repository/apps/app-metamachine.lua | 24 ++-- repository/data/app-metamachine/confboot.lua | 24 ++++ repository/data/app-metamachine/lucaboot.lua | 125 ++++++++++++++++++- 3 files changed, 159 insertions(+), 14 deletions(-) diff --git a/repository/apps/app-metamachine.lua b/repository/apps/app-metamachine.lua index c45c7e3..8afcafb 100644 --- a/repository/apps/app-metamachine.lua +++ b/repository/apps/app-metamachine.lua @@ -201,10 +201,10 @@ local insertionCallbacks = { f.close() return contents end - local function setCore(fd, size, contents) + local function setCore(fd, size, contents, important) checkArg(1, contents, "string") if #contents > size then return nil, "too large" end - if ro then + if ro and important then return nil, "storage is readonly" end local f = icecap.open(fd, true) @@ -219,7 +219,7 @@ local insertionCallbacks = { return getCore(boot) end, set = function (contents) - return setCore(boot, codeSize, contents) + return setCore(boot, codeSize, contents, true) end, makeReadonly = function () ro = true @@ -237,8 +237,8 @@ local insertionCallbacks = { getData = function () return getCore(data) end, - setData = function () - return setCore(data, dataSize, contents) + setData = function (contents) + return setCore(data, dataSize, contents, false) end } end, @@ -304,7 +304,11 @@ vmComputer.energy = os.energy vmOs.energy = nil vmComputer.maxEnergy = os.maxEnergy vmOs.maxEnergy = nil -vmComputer.uptime = os.uptime + +local startupUptime = os.uptime() +vmComputer.uptime = function () + return os.uptime() - startupUptime +end vmOs.uptime = nil vmComputer.address = os.address vmOs.address = nil @@ -319,10 +323,12 @@ vmComputer.tmpAddress = function () return tmpAddress end +local eepromAddress = "k-eeprom" vmComputer.getBootAddress = function () - return "k-eeprom" + return eepromAddress end -vmComputer.setBootAddress = function () +vmComputer.setBootAddress = function (a) + eepromAddress = a end vmComputer.users = function () return {} @@ -469,7 +475,7 @@ end vmBaseCoroutineWrap = coroutine.wrap(function () vmBaseCoroutine = coroutine.running() - local eepromAddress = vmComponent.list("eeprom")() + eepromAddress = vmComponent.list("eeprom")() if not eepromAddress then error("No EEPROM") end diff --git a/repository/data/app-metamachine/confboot.lua b/repository/data/app-metamachine/confboot.lua index d992063..aa08977 100644 --- a/repository/data/app-metamachine/confboot.lua +++ b/repository/data/app-metamachine/confboot.lua @@ -1,3 +1,9 @@ +-- This is released into the public domain. +-- No warranty is provided, implied or otherwise. + +-- confboot.lua : VM configuration program +-- Authors: 20kdc + -- _MMstartVM(name) -- _MMcomList(...) -- _MMserial(str) @@ -88,6 +94,24 @@ function genEditor() genEditor() end}) end + if not currentVM["k-eeprom"] then + table.insert(menu, {"+ Virtual EEPROM (R/W, preloaded w/ LUCcABOOT)...", function () + currentVM[currentVMId .. "-eeprom"] = {"eeprom", "/vc-" .. currentVMId .. ".lua", "/vd-" .. currentVMId .. ".bin", "VM BIOS", false} + genEditor() + -- do file copy now! + local handleA = fs.open("/lucaboot.lua", "rb") + local handleB = fs.open("/vc-" .. currentVMId .. ".lua", "wb") + if not handleA then if handleB then fs.close(handleB) end return end + if not handleB then fs.close(handleA) return end + while true do + local s = fs.read(handleA, 2048) + if not s then break end + fs.write(handleB, s) + end + fs.close(handleA) + fs.close(handleB) + end}) + end table.insert(menu, {"+ Virtual FS (R/W)...", function () genFSSelector(function (fsa) if fsa then diff --git a/repository/data/app-metamachine/lucaboot.lua b/repository/data/app-metamachine/lucaboot.lua index 93edab6..5937202 100644 --- a/repository/data/app-metamachine/lucaboot.lua +++ b/repository/data/app-metamachine/lucaboot.lua @@ -1,7 +1,116 @@ +-- This is released into the public domain. +-- No warranty is provided, implied or otherwise. + +-- lucaboot.lua : Fake EEPROM for VM. +-- Authors: 20kdc + -- LUCcABOOT v0 +-- awful name I know + +local eprox = component.proxy(component.list("eeprom", true)()) +computer.getBootAddress = eprox.getData +computer.setBootAddress = eprox.setData +eprox = nil + +local logo = { + " ⣀▄⣀ ", + " ⣀▄⠶▀⠉ ⠉█⠶▄⣀ ", + " ⣀▄⠶▀⠉ ◢◤ ⠉▀⠶▄⣀ ", + " ⣀▄⠶▀⠉ ◢◤ ⠉▀⠶▄⣀ ", + " ◢⠿⣭⣀ meta ◯ machine ⣀⣭⠿◣ ", + " █ ⠉▀⠶▄⣀ ◢◤ ⣀▄⠶▀⠉ █ ", + " █ ⠉▀⠶▄⣀ ◢◤ ⣀▄⠶▀⠉ ⣀▄⠶ █ ", + " █⣀ ⠉▀⠿▄▄▄⠶▀⠉ ⠉ ⣀█ ", + " ⠉▀⠶▄⣀ █ ⣀▄⠶▀⠉ ", + " ⠉▀⠶▄⣀ █ ⣀▄⠶▀⠉ ", + " ⠉▀⠶▄⣀ █ ⣀▄⠶▀⠉ ", + " ⠉▀▀▀⠉ ", -- 12 + " metamachine virtual computing ", + " Press F3 to enter boot manager. ", + " " +} +local gpuA = component.list("gpu", true)() +local screenA = component.list("screen", true)() +local bootManager = false +if gpuA and screenA then + local gpuP = component.proxy(gpuA) + gpuP.bind(screenA) + gpuP.setResolution(33, 15) + local targetUptime = computer.uptime() + for j = 0, 10 do + targetUptime = targetUptime + 0.1 + local ej = j + if j > 5 then + -- 5 * 50 = 250 + ej = 5 - (j - 5) + ej = ej * 50 + elseif j == 5 then + targetUptime = targetUptime + 4 + ej = 255 + else + ej = ej * 50 + end + gpuP.setForeground(ej + (ej * 0x100) + (ej * 0x10000)) + gpuP.setBackground(0) + for i = 1, #logo do + gpuP.set(1, i, logo[i]) + end + while true do + local tl = targetUptime - computer.uptime() + if tl <= 0.01 then break end + local v = {computer.pullSignal(tl)} + if v[1] == "key_down" then + if v[4] == 61 then + -- boot manager + bootManager = true + logo[14] = " - Entering boot manager now. - " + break + end + end + end + end + gpuP.setForeground(0xFFFFFF) + gpuP.setBackground(0) + local selY = 1 + while bootManager do + gpuP.fill(1, 1, 33, 15, " ") + local y = 1 + local mapping = {} + for a in component.list("filesystem", true) do + local pfx = " " + if selY == y then + pfx = ">" + end + if computer.getBootAddress() == a then + pfx = pfx .. "*" + else + pfx = pfx .. " " + end + mapping[y] = a + gpuP.set(1, y, pfx .. a .. ":" .. (component.invoke(a, "getLabel") or "")) + y = y + 1 + end + while true do + local v = {computer.pullSignal()} + if v[1] == "key_down" then + if v[4] == 200 then + selY = math.max(1, selY - 1) + break + elseif v[4] == 208 then + selY = math.min(selY + 1, y - 1) + break + elseif v[3] == 13 then + computer.setBootAddress(mapping[selY] or "") + bootManager = nil + break + end + end + end + end +end local lr = "(no inits)" -for a in component.list("filesystem", true) do - local dat = component.proxy(a) +local function boot(fsa) + local dat = component.proxy(fsa) local fh = dat.open("/init.lua", "rb") if fh then local ttl = "" @@ -10,17 +119,23 @@ for a in component.list("filesystem", true) do if not chk then break end ttl = ttl .. chk end - computer.getBootAddress = function () return a end - computer.setBootAddress = function () end local fn, r = load(ttl, "=init.lua", "t") if not fn then lr = r dat.close(fh) else dat.close(fh) - return fn() + computer.setBootAddress(fsa) + fn() + error("Returned from init") end end end +if component.type(computer.getBootAddress()) then + boot(computer.getBootAddress()) +end +for a in component.list("filesystem", true) do + boot(a) +end error("No available operating systems. " .. lr)