diff --git a/partition/driveboot.lua b/partition/driveboot.lua index 390fc69..20c7b10 100644 --- a/partition/driveboot.lua +++ b/partition/driveboot.lua @@ -12,6 +12,14 @@ local function getProxy(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) @@ -27,7 +35,15 @@ function parsePartitions(s) end function getPartitions(drive) - return parsePartitions(drive.readSector(drive.getCapacity() / drive.getSectorSize())) + 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) @@ -38,6 +54,9 @@ 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) @@ -45,24 +64,87 @@ local function readPart(drive,part) return rv end -local candidates={computer.getBootAddress()} -for a,_ in component.list("drive") do - candidates[#candidates+1] = a +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" then + 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)) + 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)()()