diff --git a/partition/README.md b/partition/README.md index ec8d769..18a594e 100644 --- a/partition/README.md +++ b/partition/README.md @@ -1,4 +1,4 @@ -# Simple partition table format +# Minitel Partition Table (MTPT) This document specifies a general partition table format suitable for both unmanaged disks, and tapes. diff --git a/partition/driveboot.lua b/partition/driveboot.lua new file mode 100644 index 0000000..390fc69 --- /dev/null +++ b/partition/driveboot.lua @@ -0,0 +1,68 @@ +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 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) + return parsePartitions(drive.readSector(drive.getCapacity() / drive.getSectorSize())) +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) + local rv = "" + for i = 1, part[4] do + rv=rv .. readSector(drive,part,i) + end + return rv +end + +local candidates={computer.getBootAddress()} +for a,_ in component.list("drive") do + candidates[#candidates+1] = a +end +for i,a in ipairs(candidates) do + computer.beep(("."):rep(i)) + local d = getProxy(a) + if type(d) == "table" then + for k,v in ipairs(getPartitions(d)) do + if v[2] == "boot" then + local rv = load(readPart(d,v)) + if rv then + computer.beep("-") + computer.setBootAddress(a) + return rv + end + end + end + end +end +end)()()