implement proper tape support, also speed up loading from tapes.

This commit is contained in:
Izaya 2023-08-05 10:19:07 +10:00
parent 2e959ebbbf
commit a144937e24

View File

@ -1,10 +1,11 @@
return (function()
local component = component
function computer.getBootAddress() function computer.getBootAddress()
return component.invoke(component.list("eeprom")(),"getData") return component.invoke(component.list("eeprom")(),"getData")
end end
function computer.setBootAddress(a) function computer.setBootAddress(a)
return component.invoke(component.list("eeprom")(),"setData",a) return component.invoke(component.list("eeprom")(),"setData",a)
end end
return (function()
local rv local rv
local function getProxy(addr) local function getProxy(addr)
if type(addr) == "string" then if type(addr) == "string" then
@ -13,14 +14,22 @@ local function getProxy(addr)
return addr return addr
end end
local function aop(td,n,mn,...) local function aop(td,n,mn,...)
local rv
if td.getPosition then
local rts = td.getPosition()
if rts ~= n then
td.seek(n - rts)
end
rv = {td[mn](...)}
else
local rts = td.seek(-math.huge) local rts = td.seek(-math.huge)
td.seek(n) td.seek(n)
local rv = {td[mn](...)} rv = {td[mn](...)}
td.seek(-math.huge) td.seek(-math.huge)
td.seek(rts) td.seek(rts)
end
return table.unpack(rv) return table.unpack(rv)
end end
local eformat = "c20c4>I4>I4" local eformat = "c20c4>I4>I4"
function parsePartitions(s) function parsePartitions(s)
local rt = {} local rt = {}
@ -33,7 +42,6 @@ function parsePartitions(s)
end end
return rt return rt
end end
function getPartitions(drive) function getPartitions(drive)
local rv local rv
if drive.type == "tape_drive" then if drive.type == "tape_drive" then
@ -45,7 +53,6 @@ function getPartitions(drive)
end end
return rv[1][2] == "mtpt" and rv return rv[1][2] == "mtpt" and rv
end end
local function offsetSector(part,sector) local function offsetSector(part,sector)
if sector < 1 or sector > part[4] then error("invalid offset, not in a usable sector") end if sector < 1 or sector > part[4] then error("invalid offset, not in a usable sector") end
return (part[3] - 1) + sector return (part[3] - 1) + sector
@ -54,16 +61,16 @@ 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
if drive.type == "tape_drive" then
rv=rv .. aop(drive, ((part[3]-2) + i)*512, "read", 512):gsub("\0+$","")
else
rv=rv .. readSector(drive,part,i) rv=rv .. readSector(drive,part,i)
end end
end
return rv return rv
end end
local pB = computer.getBootAddress() local pB = computer.getBootAddress()
local candidates={pB,[pB] = true} local candidates={pB,[pB] = true}
if not component.type(pB) then candidates[1] = nil end if not component.type(pB) then candidates[1] = nil end
@ -71,7 +78,6 @@ 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[#candidates+1] = not candidates[a] and (t == "drive" or t == "filesystem" or t == "tape_drive") and a or nil
candidates[a] = true candidates[a] = true
end end
local function wL() local function wL()
return false return false
end end
@ -110,7 +116,6 @@ if ga and sa then
end end
until computer.uptime() >= to until computer.uptime() >= to
end 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) wL("Attempting to load from "..a)