From d873cc1288bbc84f8e5d49e43a8439be793e5e04 Mon Sep 17 00:00:00 2001 From: XeonSquared Date: Tue, 1 Aug 2017 23:59:44 +1000 Subject: [PATCH] add SKS Enhanced BIOS (SEBIOS) --- sebios.lua | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 sebios.lua diff --git a/sebios.lua b/sebios.lua new file mode 100644 index 0000000..30bf3da --- /dev/null +++ b/sebios.lua @@ -0,0 +1,102 @@ +local component_invoke = component.invoke +function boot_invoke(address, method, ...) + local result = table.pack(pcall(component_invoke, address, method, ...)) + if not result[1] then + return nil, result[2] + else + return table.unpack(result, 2, result.n) + end +end + +-- backwards compatibility, may remove later +local eeprom = component.list("eeprom")() +computer.getBootAddress = function() + return boot_invoke(eeprom, "getData") +end +computer.setBootAddress = function(address) + return boot_invoke(eeprom, "setData", address) +end + +do + local screen = component.list("screen")() + local gpu = component.list("gpu")() + if gpu and screen then + boot_invoke(gpu, "bind", screen) + end +end +local function tryLoadFrom(address) + if component.type(address) == "filesystem" then + local handle, reason = boot_invoke(address, "open", "/init.lua") + if not handle then + return nil, reason + end + local buffer = "" + repeat + local data, reason = boot_invoke(address, "read", handle, math.huge) + if not data and reason then + return nil, reason + end + buffer = buffer .. (data or "") + until not data + boot_invoke(address, "close", handle) + return load(buffer, "=init") + elseif component.type(address) == "tape_drive" then + boot_invoke(address,"seek",-math.huge) + local boottype = boot_invoke(address,"read",1) + if boottype == "!" then + local rl = tonumber(boot_invoke(address,"read",8)) + local buffer = boot_invoke(address,"read",rl) + return load(buffer, "=init") + end + end +end + +local bootdevs = {} +for address in component.list("filesystem") do + bootdevs[#bootdevs+1] = address +end +for address in component.list("tape_drive") do + bootdevs[#bootdevs+1] = address +end + +do + local gA,sA = component.list("gpu")(),component.list("screen")() + if gA and sA then + local gP,cy = component.proxy(gA),1 + gP.bind(sA) + local function wl(s) + gP.set(1,cy,s) + cy=cy+1 + end + wl("SKS Enhanced BIOS v1") + wl("Memory: "..tostring(computer.totalMemory()/1024).."K") + wl("") + for k,v in ipairs(bootdevs) do + wl(tostring(k).." "..v) + end + end +end + +while computer.uptime() < 2 do + computer.pullSignal(0.5) +end + +local init, reason +if computer.getBootAddress() then + init, reason = tryLoadFrom(computer.getBootAddress()) +end +if not init then + computer.setBootAddress() + for k,address in ipairs(bootdevs) do + init, reason = tryLoadFrom(address) + if init then + computer.setBootAddress(address) + break + end + end +end +if not init then + error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0) +end +computer.beep(1000, 0.2) +init()