add initial attempt at tape support, support for booting from filesystems, and a menu to choose
This commit is contained in:
parent
2a7078d6d3
commit
2e959ebbbf
@ -12,6 +12,14 @@ local function getProxy(addr)
|
|||||||
end
|
end
|
||||||
return addr
|
return addr
|
||||||
end
|
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"
|
local eformat = "c20c4>I4>I4"
|
||||||
function parsePartitions(s)
|
function parsePartitions(s)
|
||||||
@ -27,7 +35,15 @@ function parsePartitions(s)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function getPartitions(drive)
|
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
|
end
|
||||||
|
|
||||||
local function offsetSector(part,sector)
|
local function offsetSector(part,sector)
|
||||||
@ -38,6 +54,9 @@ local function readSector(drive,part,sector)
|
|||||||
return drive.readSector(offsetSector(part,sector)):gsub("\0+$","")
|
return drive.readSector(offsetSector(part,sector)):gsub("\0+$","")
|
||||||
end
|
end
|
||||||
local function readPart(drive,part)
|
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 = ""
|
local rv = ""
|
||||||
for i = 1, part[4] do
|
for i = 1, part[4] do
|
||||||
rv=rv .. readSector(drive,part,i)
|
rv=rv .. readSector(drive,part,i)
|
||||||
@ -45,24 +64,87 @@ local function readPart(drive,part)
|
|||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
local candidates={computer.getBootAddress()}
|
local pB = computer.getBootAddress()
|
||||||
for a,_ in component.list("drive") do
|
local candidates={pB,[pB] = true}
|
||||||
candidates[#candidates+1] = a
|
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
|
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
|
for i,a in ipairs(candidates) do
|
||||||
computer.beep(("."):rep(i))
|
computer.beep(("."):rep(i))
|
||||||
|
wL("Attempting to load from "..a)
|
||||||
local d = getProxy(a)
|
local d = getProxy(a)
|
||||||
if type(d) == "table" then
|
if type(d) == "table" and d.type == "filesystem" then
|
||||||
for k,v in ipairs(getPartitions(d)) do
|
if d.exists("/init.lua") then
|
||||||
if v[2] == "boot" then
|
local rb, b = "", ""
|
||||||
local rv = load(readPart(d,v))
|
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
|
if rv then
|
||||||
computer.beep("-")
|
computer.beep("-")
|
||||||
computer.setBootAddress(a)
|
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
|
return rv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
error("no bootable devices found")
|
||||||
end)()()
|
end)()()
|
||||||
|
Loading…
Reference in New Issue
Block a user