function computer.getBootAddress() return component.invoke(component.list("eeprom")(),"getData") end function computer.setBootAddress(a) return component.invoke(component.list("eeprom")(),"setData",a) end return (function() local rv local function getProxy(addr) if type(addr) == "string" then return component.proxy(addr) end return addr end local function aop(td,n,mn,...) local rts = td.seek(-math.huge) td.seek(n) local rv = {td[mn](...)} td.seek(-math.huge) td.seek(rts) return table.unpack(rv) end local eformat = "c20c4>I4>I4" function parsePartitions(s) local rt = {} for i = 1, s:len(), 32 do local n, t, start, length = string.unpack(eformat, s, i) n = n:gsub("\0", "") if n ~= "" then rt[#rt+1] = {n,t,start,length} end end return rt end function getPartitions(drive) local rv if drive.type == "tape_drive" then local ts = drive.getSize() local lso = (math.floor(ts / 512) - 1) * 512 rv = parsePartitions(aop(drive, lso, "read", ts - lso)) else rv = parsePartitions(drive.readSector(drive.getCapacity() / drive.getSectorSize())) end return rv[1][2] == "mtpt" and rv end local function offsetSector(part,sector) if sector < 1 or sector > part[4] then error("invalid offset, not in a usable sector") end return (part[3] - 1) + sector end local function readSector(drive,part,sector) return drive.readSector(offsetSector(part,sector)):gsub("\0+$","") end local function readPart(drive,part) if drive.type == "tape_drive" then return aop(drive, (part[3]-1)*512, "read", part[4] * 512) end local rv = "" for i = 1, part[4] do rv=rv .. readSector(drive,part,i) end return rv end local pB = computer.getBootAddress() local candidates={pB,[pB] = true} if not component.type(pB) then candidates[1] = nil end for a,t in component.list() do candidates[#candidates+1] = not candidates[a] and (t == "drive" or t == "filesystem" or t == "tape_drive") and a or nil candidates[a] = true end local function wL() return false end local cL = wL local ga, sa = component.list("gpu")(), component.list("screen")() if ga and sa then local g, cl = component.proxy(ga), 1 g.bind(sa) g.setResolution(g.maxResolution()) function wL(s) g.set(1,cl,s) cl = cl + 1 end function cL() g.fill(1,1,160,50, " ") cl = 1 end local function drawOptions() cL() wL(string.format("SKS Enhanced BIOS - %0.0fK RAM",computer.totalMemory()/1024)) cl=cl+1 wL(tostring(#candidates).." devices, press listed key to select") wL("key address type label") for k,v in ipairs(candidates) do wL(string.format("[%s] %s %10s %s",string.char(k+96),v:sub(1,8), component.type(v), component.invoke(v, "getLabel") or "")) end end local to = computer.uptime() + 2.5 drawOptions() repeat local tE = {computer.pullSignal(to - computer.uptime())} if tE[1] == "key_down" and candidates[tE[3]-96] then to = computer.uptime() + 2.5 table.insert(candidates, 1, table.remove(candidates,tE[3]-96)) drawOptions() end until computer.uptime() >= to end for i,a in ipairs(candidates) do computer.beep(("."):rep(i)) wL("Attempting to load from "..a) local d = getProxy(a) if type(d) == "table" and d.type == "filesystem" then if d.exists("/init.lua") then local rb, b = "", "" local f = d.open("/init.lua","rb") repeat b = d.read(f, 2048) or "" rb = rb .. b until b == "" d.close(f) local rv = load(rb,a.."/init.lua") if rv then computer.beep("-") computer.setBootAddress(a) cL() return rv end end elseif type(d) == "table" and (d.type == "drive" or d.type == "tape_drive") then for k,v in ipairs(getPartitions(d)) do if v[2] == "boot" then local rv = load(readPart(d,v), a.."/"..tostring(k)) if rv then computer.beep("-") computer.setBootAddress(a) cL() return rv end end end end end error("no bootable devices found") end)()()