1
0
mirror of https://github.com/Adorable-Catgirl/Zorya-NEO.git synced 2024-11-23 10:48:06 +11:00

Oh yeah, biiig update.

This commit is contained in:
Jane Roxanne 2020-01-14 20:07:27 -05:00
parent 56170cff84
commit 2a9eec0ad8
22 changed files with 993 additions and 66 deletions

View File

@ -1,13 +1,14 @@
{
{name="zlan", cat="util", path="lib/util_zlan.zy2l"},
--{name="openos", cat="loader", path="mods/loader_openos.zy2m"},
{name="openos", cat="loader", path="mods/loader_openos.zy2m"},
{name="fuchas", cat="loader", path="mods/loader_fuchas.zy2m"},
--{name="tsuki", cat="loader", path="mods/loader_tsuki.zy2m"},
--{name="romfs", cat="util", path="mods/util_romfs.zy2m"},
--{name="cpio", cat="util", path="mods/util_cpio.zy2m"},
{name="cpio", cat="util", path="lib/util_cpio.zy2l"},
--{name="frequest", cat="util", path="mods/util_frequest.zy2m"},
--{name="loadfile", cat="loader", path="mods/loader_loadfile.zy2m"},
{name="minitel", cat="net", path="lib/net_minitel.zy2l"},
{name="vdev", cat="util", path="mods/util_vdev.zy2m"},
--{name="vdev", cat="util", path="mods/util_vdev.zy2m"},
{name="menu", cat="menu", path="mods/menu_classic.zy2m"},
--{name="vdevrt", cat="rtmod", path="mods/rtmod_vdevrt.zy2m"},
--{name="tsukinet", cat="net", path="mods/net_tsukinet"},

View File

@ -52,6 +52,9 @@ function thd.run()
if (c_status(threads[i][2]) ~= "running") then
local er, dl = c_resume(threads[i][2], unpack(last_sig))
if (not er) then error(threads[i][1]..": "..dl) end
if (dl == "k") then
threads[i][6] = true
end
dl = computer.uptime() + (dl or math.huge)
threads[i][4] = dl
sigs[#sigs+1] = {ps(0)}
@ -59,13 +62,11 @@ function thd.run()
end
end
local t = {}
for k,v in pairs(threads) do
for i=1, #threads do
local v = threads[i]
if (c_status(v[2]) ~= "dead" and not v[6]) then
if (type(k) == "number") then
t[#t+1] = v
else
t[k] = v
end
t[#t+1] = v
t[v[2]] = v
end
end
threads = t

View File

@ -0,0 +1,82 @@
local comp = component
local cpio = {}
local arc = {}
local function read(f, h, n)
local d = f.read(h, n)
return d
end
local function readint(f, h, amt, rev)
local tmp = 0
for i=(rev and amt) or 1, (rev and 1) or amt, (rev and -1) or 1 do
tmp = tmp | (read(f, h, 1):byte() << ((i-1)*8))
end
return tmp
end
function cpio.read(drive, path)
local f = comp.proxy(drive)
local h = f.open(path)
local tbl = {}
while true do
local dent = {}
dent.magic = readint(f, h, 2)
local rev = false
if (dent.magic ~= tonumber("070707", 8)) then rev = true end
dent.dev = readint(f, h, 2)
dent.ino = readint(f, h, 2)
dent.mode = readint(f, h, 2)
dent.uid = readint(f, h, 2)
dent.gid = readint(f, h, 2)
dent.nlink = readint(f, h, 2)
dent.rdev = readint(f, h, 2)
dent.mtime = (readint(f, h, 2) << 16) | readint(f, h, 2)
dent.namesize = readint(f, h, 2)
dent.filesize = (readint(f, h, 2) << 16) | readint(f, h, 2)
local name = read(f, h, dent.namesize):sub(1, dent.namesize-1)
if (name == "TRAILER!!!") then break end
--for k, v in pairs(dent) do
-- print(k, v)
--end
dent.name = name
if (dent.namesize % 2 ~= 0) then
f.seek(h, "cur", 1)
end
if (dent.mode & 32768 ~= 0) then
--fwrite()
end
dent.pos = f.seek(h, "cur", 0)
f.seek(h, "cur", dent.filesize)
if (dent.filesize % 2 ~= 0) then
f.seek(h, "cur", 1)
end
tbl[#tbl+1] = dent
end
return setmetatable({
tbl = tbl,
fs = f,
handle = h
}, {__index=arc})
end
function arc:fetch(path)
for i=1, #self.tbl do
if (self.tbl[i].name == path and self.tbl[i].mode &32768 > 0) then
self.fs.seek(self.handle, "set", self.tbl[i].pos)
return self.fs.read(self.handle, self.tbl[i].filesize)
end
end
return nil, "file not found"
end
function arc:close()
self.fs.close(self.handle)
self.tbl = {}
end
function arc:list_dir(path)
--soon:tm:
end
return cpio

View File

@ -17,6 +17,283 @@ local function read_ali(fs, h)
return tmp
end
local function read_int(fs, h, count)
local tmp = 0
for i=0, count-1 do
tmp = tmp | (fs.read(h, 1):byte() << (count*8))
end
return tmp
end
local function read_string(fs, h)
local len = read_ali(fs, h)
return fs.read(h, len)
end
local xdec = {
["NAME"] = function(fs, h)
return read_string(fs, h)
end,
["PERM"] = function(fs, h)
return read_int(fs, h, 2)
end,
["W32P"] = function(fs, h)
return fs.read(h, 1):byte()
end,
["OTIM"] = function(fs, h)
return read_int(fs, h, 8)
end,
["MTIM"] = function(fs, h)
return read_int(fs, h, 8)
end,
["CTIM"] = function(fs, h)
return read_int(fs, h, 8)
end,
["ATIM"] = function(fs, h)
return read_int(fs, h, 8)
end,,
["SCOS"] = function(fs, h)
return read_string(fs, h)
end
}
local decode = {
["X"] = function(fs, h, size)
local oid = read_ali(fs, h)
local xtype = fs.read(h, 4)
return {
type = "meta",
id = oid,
key = xtype,
value = xdec[xtype](fs, h)
}
end,
["F"] = function(fs, h, size)
return {
type="file",
name = read_string(fs, h),
offset = read_ali(fs, h),
size = read_ali(fs, h),
id = read_ali(fs, h),
pid = read_ali(fs, h)
}
end,
["D"] = function(fs, h, size)
return {
type="dir",
name = read_string(fs, h),
id = read_ali(fs, h),
pid = read_ali(fs, h)
}
end,
["Z"] = function(fs, h, size)
return {
type="eoh"
size = read_ali(fs, h)
}
end
}
local function read_entrydat(fs, h)
local etype = fs.read(h, 1):byte()
end
local etype = fs.read(h, 1)
local ebyte = etype:byte()
local size = read_ali(fs, h)
if (ebyte & flag_crit > 0 and not decode[etype]) then error("Unknown critical entry.") end
if (ebyte & flag_required == 0) then error("Required flag not set.") end
if (decode[etype]) then
return decode[etype](fs, h, size)
end
return {type="unknown"}
end
local function get_offset(fs, h)
fs.seek(h, "set", 9)
local ent = {}
while ent.type ~= "eoh" do
ent = read_entrydat(fs, h)
end
return fs.seek(h, "cur", 0), ent.size
end
local function path_part_iter(path)
path = path:gsub("/+", "/"):gsub("^/", ""):gsub("/$", "")
local lpos = 1
return function()
if not lpos then return nil end
local s, e = path:find("(.-)/", lpos)
if not s then
local lp = lpos
lpos = nil
return path:sub(lp)
end
local rtn = path:sub(s, e-1)
lpos = e+1
return rtn
end
end
local unpack = unpack or table.unpack
local function sfpcall(a, func, ...)
local ptr = a.fs.seek(a.h, "cur", 0)
local rv = {func(...)}
a.fs.seek(a.h, "set", ptr)
return unpack(rv)
end
local function cache_obj(a, objdat)
a.cache = a.cache or {}
a.cache[#a.cache+1] = objdat
end
local function get_obj_prop(a, obj, name)
name = name:upper()
if (a.cache) then
for i=1, #a.cache do
if (a.cache[i].type=="meta" and a.cache[i].id==obj and a.cache[i].key == name) then return a.cache[i].value end
end
end
fs.seek(h, "set", 9)
local ent = {}
while ent.type ~= "eoh" do
ent = read_entrydat(fs, h)
if (ent.type=="meta" and ent.id==obj and ent.key == name) then
cache_obj(a, ent)
return ent.value
end
end
end
local function path_to_obj(a, path)
if (path == "/" or path == "") then
return {
type = "dir",
name = "/root\\",
id = 0,
pid = 0
}
end
local tbl = {}
for p in path_part_iter(path) do
tbl[#tbl+1] = p
end
local part = 1
local pid = 0
--search cache
if (a.cache) then
local i = 0
while i < #a.cache do
i = i+1
if (a.cache[i].type == "file" or a.cache[i].type == "dir") then
if (a.cache[i].pid == pid and (a.cache[i].name == tbl[part] or get_obj_prop(a, a.cache[i].id, "NAME") == tbl[part])) then
part = part+1
pid = a.cache[i].id
i=0
if (part == #tbl) then
return a.cache[i], pid
end
end
end
end
end
-- Now we search the hard way, then cache along the way.
fs.seek(h, "set", 9)
local ent = {}
while ent.type ~= "eoh" do
ent = read_entrydat(fs, h)
if (ent.type == "file" or ent.type=="dir") then
if (ent.name == tbl[part] or sfpcall(get_obj_prop, a, ent.id, "NAME") == tbl[part]) then
pid = ent.id
cache_obj(a, ent)
part = part + 1
end
if (part == #tbl) then
break
end
end
end
return ent, pid
end
local function get_by_id(a, id)
if (a.cache) then
for i=1, #a.cache do
if ((a.cache[i].type=="file" or a.cache[i].type=="dir") and a.cache[i].id==id) then return a.cache[i] end
end
end
fs.seek(h, "set", 9)
local ent = {}
while ent.type ~= "eoh" do
ent = read_entrydat(fs, h)
if ((ent.type=="file" or ent.type=="dir") and ent.id==id) then
cache_obj(a, ent)
return ent
end
end
end
local function id_to_path(a, id)
local ne = get_by_id(a, id)
if not ne then return nil, "not found" end
local path = get_obj_prop(a, id, "NAME") or ne.name
path = "/" .. path
while ne and ne.pid > 0 do
ne = get_by_id(a, ne.pid)
if not ne then return nil, "not found" end
path = "/" .. (get_obj_prop(a, ne.id, "NAME") or ne.name) .. path
end
return path
end
local urf = {}
function urf.open(drive, path)
local fs = component.proxy(drive)
local hand = fs.open(path)
if fs.read(hand, 8) ~= "URF\x11\1\1\x12\0" then return nil, "bad signature" end
local e, z = get_offset(fs, hand)
return setmetatable({
fs = fs,
h = hand,
cache = {},
epos = e,
bsize = z
}, {__index=arc})
end
local arc = {}
function arc:fetch(path)
local obj = path_to_obj(self, path)
if (obj.type ~= "file") then return nil, "not a file" end
self.fs.seek(self.h, "set", self.epos+obj.offset)
return self.fs.read(self.h, obj.size)
end
function arc:close()
self.cache = nil
self.fs.close(self.h)
self.fs = nil
end
function arc:list_dir(path)
local obj = path_to_obj(self, path)
if (obj.type ~= "dir") then return nil, "not a dir" end
local objects = {}
for i=1, self.cache do
if (self.cache[i].pid == obj.id) then
objects[#objects+1] = (get_obj_prop(self, self.cache[i].id, "NAME") or self.cache[i].name)
end
end
self.fs.seek(self.h, "set", 9)
local ent = {}
while ent.type ~= "eoh" do
ent = read_entrydat(self.fs, self.h)
if ((ent.type=="file" or ent.type=="dir") and ent.pid==obj.id) then
cache_obj(self, ent)
objects[#objects+1] = sfpcall(get_obj_prop, self, ent.id, "NAME") or ent.name
end
end
return objects
end
return urf

View File

@ -0,0 +1,22 @@
local zy = krequire("zorya")
--zy.loadmod("vdev_biosdev")
local utils = krequire("utils")
local thd = krequire("thd")
--local vdev = krequire("zorya").loadmod("util_vdev")
local oefi = zy.loadmod("util_oefiv2")
-- No low-level loading yet.
return function(addr, args)
--oefi.getExtensions().ZyNeo_ExecOEFIApp(addr, ".efi/fuchas.efi2", ...)
--We don't do that here.
local env = oefi.getExtensions().ZyNeo_GetOEFIEnv(addr)
env.computer.supportsOEFI = function()
return true
end
env.os_arguments = args
env.loadfile = env.oefi.loadfile
thd.add("fuchas", function()
env.loadfile("Fuchas/Kernel/boot.lua")() --This is how we do.
computer.pushSignal("fuchas_dead")
end)
while true do if computer.pullSignal() == "fuchas_dead" then break end end
end

View File

@ -0,0 +1,17 @@
local zy = krequire("zorya")
--zy.loadmod("vdev_biosdev")
local utils = krequire("utils")
--local vdev = krequire("zorya").loadmod("util_vdev")
return function(addr)
local fs = component.proxy(addr)
local kr = krequire
krequire = nil
--vdev.overwrite(_G)
function computer.getBootAddress()
return addr
end
function computer.setBootAddress()end
--log(env, env.computer, env.computer.getBootAddress, env.computer.getBootAddress())
load(utils.readfile(fs.address, fs.open("init.lua")), "=init.lua", "t")()
krequire = kr
end

View File

@ -0,0 +1,10 @@
return function(filter)
filter = filter or function() return true end
return function()
for f in component.list("filesystem") do
if (filter(f) and component.invoke(f, "spaceTotal") ) then
end
end
end
end

View File

View File

@ -5,4 +5,5 @@ gpu.bind(component.list("screen")())
gpu.set(1, 1, "Zorya NEO v2.0 BIOS/Bootloader")
gpu.set(1, 2, "(c) 2020 Adorable-Catgirl")
gpu.set(1, 4, "Memory: "..math.floor(computer.totalMemory()/1024).."K")
gpu.set(1, 4, "Memory: "..math.floor(computer.totalMemory()/1024).."K")
--gpu.set(1, 5)

View File

@ -35,7 +35,8 @@ function menu.draw()
gpu.setForeground(fg)
cls()
--Draw some things
gpu.set((w/2)-7, 1, "Zorya NEO BIOS")
local namestr = _BIOS .. " " .. string.format("%.1f.%d %s", _ZVER, _ZPAT, _ZGIT)
gpu.set((w/2)-(#namestr/2), 1, namestr)
gpu.set(1, 2, border_chars[1])
gpu.set(2, 2, border_chars[2]:rep(w-2))
gpu.set(w, 2, border_chars[3])

59
mods/util_oefiv1/init.lua Normal file
View File

@ -0,0 +1,59 @@
local comp = component
local computer = computer
local thd = krequire("thd")
local zy = krequire("zorya")
local utils = krequire("utils")
local oefi = {}
local function load_oefi(drive, path, uuid)
local oefi_env = {}
local env = {}
utils.deepcopy(_G, env)
env.krequire = nil
env._BIOS = nil
env._ZVER = nil
env._ZVSTR = nil
env._ZPAT = nil
env.oefi = setmetatable(oefi_env, {__index=oefi})
function env.computer.getBootAddress()
return drive
end
function oefi_env.returnToOEFI()
computer.pushSignal("oefi_killall")
computer.pullSignal("k") --It actually kills the application
end
local h = comp.invoke(drive, "open", path)
local dat = utils.readfile(drive, h)
comp.invoke(drive, "close", h)
return load(dat, "="..path, "t", env)
end
function oefi.getAPIVersion()
return 1
end
function oefi.getImplementationName()
return _BIOS
end
function oefi.getImplementationVersion()
return _ZVER
end
function oefi.execOEFIApp(fs, path)
local uuid = string.char(math.random(0,255),math.random(0,255),math.random(0,255),math.random(0,255))
local func, manifest = load_oefi(drive, path, uuid)
local args = {}
local name = "oefi$"..manifest.name:gsub(" ", "_")
thd.add(name, function()
func(unpack(args))
os.pushSignal("oefi_end", uuid)
end) --ez
while true do
local s, i = computer.pullSignal()
if (s == "oefi_end" and i == uuid) or s == "oefi_killall" then
break
end
end
end

25
mods/util_oefiv2/bios.lua Normal file
View File

@ -0,0 +1,25 @@
local function gen_proto(drive)
return {
methods = {
get = function()
return "< Virtual BIOS >"
end,
getData = function()
return string.char(2)..drive.."Zorya NEO BIOS"..string.char(0):rep(6)
end,
setData = function()
return ""
end,
set = function()
return ""
end,
getLabel = function()
return "Virtual OEFI BIOS"
end,
setLabel = function()
return "Virtual OEFI BIOS"
end
},
docs = {}
}
end

View File

@ -0,0 +1,166 @@
local comp = component
local computer = computer
local thd = krequire("thd")
local zy = krequire("zorya")
local utils = krequire("utils")
local oefi = {}
local ext = {}
local unpack = unpack or table.unpack
---#include "bios.lua"
local function load_oefi_env(file, envx)
utils.debug_log(file, envx.fs)
local cpio = krequire("util_cpio")
local vdev = zy.loadmod("util_vdev")
local arc = cpio.read(envx.fs, file)
local oefi_env = {}
local env = {}
utils.deepcopy(_G, env)
env.krequire = nil
env._BIOS = nil
env._ZVER = nil
env._ZVSTR = nil
env._ZPAT = nil
env.oefi = setmetatable(oefi_env, {__index=oefi})
local fs = component.proxy(envx.fs)
function oefi_env.loadfile(path)
local h = fs.open(path)
local fd = utils.readfile(envx.fs, h)
fs.close(h)
return load(fd, "="..path, "t", env)
end
function oefi_env.loadInternalFile(path)
return arc:fetch(path)
end
function oefi_env.returnToOEFI()
computer.pushSignal("oefi_killall")
computer.pullSignal("k") --It actually kills the application
end
function env.computer.pullSignal(...)
local s = {computer.pullSignal(...)}
if (s[1] == "oefi_killall") then
computer.pullSignal("k")
end
return unpack(s)
end
function oefi_env.getBootAddress()
return envx.fs
end
--vdev.overwrite(env)
--vdev.register_type("eeprom_oefiemu", gen_proto(baddr(envx.fs.address)))
--vdev.add_device("biosemu", "eeprom_oefiemu")
local dat = env.oefi.loadInternalFile("app.exe")
local func = load(dat, "="..file..":/app.exe", "t", env)
local cfgdat = env.oefi.loadInternalFile("app.cfg")
local cfg = {}
for line in cfgdat:gmatch("(.-)[\r\n]+") do
utils.debug_log("CONFIG", line)
local k, v = line:match("(.+)=(.+)")
utils.debug_log("PARSED", k, v)
cfg[k] = v
end
return func, cfg
end
local function load_oefi(drive, path)
local ext = path:sub(#path-4, #path)
return load_oefi_env(path, {fs = drive, uuid=uuid})
end
function oefi.getAPIVersion()
return 2.1
end
function oefi.getImplementationName()
return _BIOS
end
function oefi.getImplementationVersion()
return _ZVER
end
function oefi.execOEFIApp(drive, path)
local uuid = string.char(math.random(0,255),math.random(0,255),math.random(0,255),math.random(0,255))
local func, manifest = load_oefi(drive, path, uuid)
local args = {}
local name = "oefi$"..manifest.name:gsub(" ", "_")
thd.add(name, function()
func(unpack(args))
os.pushSignal("oefi_end", uuid)
end) --ez
while true do
local s, i = computer.pullSignal()
if (s == "oefi_end" and i == uuid) or s == "oefi_killall" then
break
end
end
end
function oefi.getExtensions()
return ext
end
function oefi.getApplications()
return {}
end
function ext.ZyNeo_GetOEFIEnv(drive, arc)
local oefi_env = {}
local env = {}
utils.deepcopy(_G, env)
env.krequire = nil
env._BIOS = nil
env._ZVER = nil
env._ZVSTR = nil
env._ZPAT = nil
env.oefi = setmetatable(oefi_env, {__index=oefi})
local fs = component.proxy(drive)
function oefi_env.loadfile(path)
local h = fs.open(path)
local fd = utils.readfile(drive, h)
fs.close(h)
return load(fd, "="..path, "t", env)
end
function oefi_env.loadInternalFile(path)
if (arc) then
return arc:fetch(path)
end
end
function oefi_env.returnToOEFI()
computer.pushSignal("oefi_killall")
computer.pullSignal("k") --It actually kills the application
end
function env.computer.pullSignal(...)
local s = {computer.pullSignal(...)}
if (s[1] == "oefi_killall") then
computer.pullSignal("k")
end
return unpack(s)
end
function oefi_env.getBootAddress()
return drive
end
return env
end
function ext.ZyNeo_ExecOEFIApp(drive, path, ...)
local uuid = string.char(math.random(0,255),math.random(0,255),math.random(0,255),math.random(0,255))
local func, manifest = load_oefi(drive, path, uuid)
local args = {...}
local name = "oefi$"..manifest.name:gsub(" ", "_")
thd.add(name, function()
func(unpack(args))
os.pushSignal("oefi_end", uuid)
end) --ez
while true do
local s, i = computer.pullSignal()
if (s == "oefi_end" and i == uuid) or s == "oefi_killall" then
break
end
end
end
return oefi

View File

@ -38,13 +38,15 @@ end
local cdevinfo = computer.getDeviceInfo
component = {}
vdev.component = {}
vdev.computer = {}
for k, v in pairs(comp) do
component[k] = v
vdev.component[k] = v
end
function component.list(dtype)
function vdev.component.list(dtype, match)
dtype = dtype or ""
local lpos = 0
local func = comp.list(dtype)
local ft = {}
@ -52,7 +54,7 @@ function component.list(dtype)
ft[k] = v
end
for i=1, #devices do
if (devices[i].type:find(dtype, true) == 1) then
if (dtype == devices[i].type or (not match and devices[i].type:sub(1, #dtype) == dtype)) then
ft[ devices[i].addr ] = devices[i].type
end
end
@ -65,22 +67,28 @@ function component.list(dtype)
if (lpos > #devices) then
return func()
end
if (devices[lpos].type:find(dtype, true) == 1) then
if (dtype == devices[lpos].type or (not match and devices[lpos].type:sub(1, #dtype) == dtype)) then
return devices[lpos].addr
end
end
end})
end
function component.proxy(addr)
local function debug_log(...)
log("return", ...)
return ...
end
function vdev.component.proxy(addr)
for i=1, #devices do
if (devices[i].addr == addr) then
return setmetatable({}, {__index=function(self, index)
if (types[devices[i].type].methods[index]) then
local func = setmetatable({}, {__call=function(...)
log("proxy", addr, index, ...)
return types[devices[i].type].methods[index](devices[i].addr, ...)
end, __tostring = function()
return types[devices[i].type].doc[index]
return types[devices[i].type].doc[index] or (index.."(...):any")
end})
self[index] = func
end
@ -90,22 +98,23 @@ function component.proxy(addr)
return comp.proxy(addr)
end
function component.invoke(addr, meth, ...)
function vdev.component.invoke(addr, meth, ...)
log("invoke", addr, meth, ...)
for i=1, #devices do
if (devices[i].addr == addr) then
if (types[devices[i].type][meth]) then
types[devices[i].type].methods[meth](addr, ...)
if (types[devices[i].type].methods[meth]) then
return debug_log("invoke", types[devices[i].type].methods[meth](addr, ...))
end
end
end
return comp.invoke(addr, meth, ...)
end
function component.doc(addr, meth)
function vdev.component.doc(addr, meth)
for i=1, #devices do
if (devices[i].addr == addr) then
if (types[devices[i].type].methods[meth]) then
return types[devices[i].type].doc[meth]
return types[devices[i].type].doc[meth] or (index.."(...):any")
end
return
end
@ -113,7 +122,7 @@ function component.doc(addr, meth)
return comp.doc(addr, meth)
end
function component.type(addr)
function vdev.component.type(addr)
for i=1, #devices do
if (devices[i].addr == addr) then
return devices[i].type
@ -122,7 +131,7 @@ function component.type(addr)
return comp.type(addr)
end
function component.slot(addr)
function vdev.component.slot(addr)
for i=1, #devices do
if (devices[i].addr == addr) then
return -1
@ -131,7 +140,7 @@ function component.slot(addr)
return comp.slot(addr)
end
function component.methods(addr)
function vdev.component.methods(addr)
for i=1, #devices do
if (devices[i].addr == addr) then
local m = {}
@ -144,7 +153,7 @@ function component.methods(addr)
return comp.methods(addr)
end
function computer.getDeviceInfo()
function vdev.computer.getDeviceInfo()
local tbl = cdevinfo()
for i=1, #devices do
local info = {}
@ -158,4 +167,14 @@ function computer.getDeviceInfo()
return tbl
end
function vdev.overwrite(env)
for k, v in pairs(vdev) do
if (type(v) == "table") then
for j, b in pairs(v) do
env[k][j] = b
end
end
end
end
return vdev

View File

@ -0,0 +1,31 @@
local zy = krequire("zorya")
local vdev = zy.loadmod("util_vdev")
vdev.register_type("zybios", {
methods = {
get_threads_info = function()
local threads = {}
for i=1, zy.lkthdn() do
local info = zy.lkthdi(i)
threads[i] = {
name = info[1],
deadline = info[6]
}
end
return threads
end,
get_version = function()
return string.format("%f.%d", _ZVER, _ZPAT)
end,
get_git_revision = function()
return _ZGIT
end
},
docs = {
get_threads_info = "get_threads_info():table -- Returns the BIOS thread information.",
get_version = "get_version():string -- Returns the Zorya NEO version.",
get_git_revision = "get_git_revision():string -- Returns the git revision of the build."
}
})
vdev.add_device("ZORYA_BIOS", "zybios")
return true

View File

@ -1,19 +1,40 @@
--Makes a release CPIO
local start = os.time()
function status(s)
io.stderr:write(s.."\n")
end
status("Cleaning last build...")
os.execute("rm -rf pkg")
status("Making directories...")
os.execute("mkdir -p pkg/mods")
os.execute("mkdir -p pkg/lib")
os.execute("mkdir -p pkg/bios")
status("Building EEPROM...")
os.execute("luacomp src/loader.lua -O pkg/bios/managed.bios")
if (os.execute("[[ $(stat --printf=%s pkg/bios/managed.bios) > 4096 ]]")) then
io.stderr:write("WARNING: BIOS is over 4KiB!\n")
end
status("\n\nBuilding modules.")
if (os.execute("stat mods 1>/dev/null 2>&1")) then
for l in io.popen("ls mods"):lines() do
os.execute("zsh -c 'cd mods/"..l.."; luacomp init.lua | lua ../../utils/zlua.lua > ../../pkg/mods/"..l..".zy2m'")
status("MOD\t"..l)
os.execute("zsh -c 'cd mods/"..l.."; luacomp init.lua -mnone | lua ../../utils/zlua.lua > ../../pkg/mods/"..l..".zy2m'")
end
end
status("Module build complete.\n\nBuilding libraries.")
if (os.execute("stat lib 1>/dev/null 2>&1")) then
for l in io.popen("ls lib"):lines() do
os.execute("zsh -c 'cd lib/"..l.."; luacomp init.lua -mluamin | lua ../../utils/zlua.lua > ../../pkg/lib/"..l..".zy2l'")
status("LIB\t"..l)
os.execute("zsh -c 'cd lib/"..l.."; luacomp init.lua -mnone | lua ../../utils/zlua.lua > ../../pkg/lib/"..l..".zy2l'")
end
end
status("Library build complete.\n\nBuilding installer...")
os.execute("cp utils/ser.lua pkg/init.lua")
os.execute("cp -r installer_dat pkg")
os.execute("cd pkg; find * -depth | cpio -o | lua ../utils/mkselfextract.lua > ../zorya-neo-installer.lua")
status("Packing installer...")
os.execute("cd pkg; find * -depth | cpio -o | lua ../utils/mkselfextract.lua > ../zorya-neo-installer.lua")
status("Build complete.")
status(string.format("Took %ds.", os.time()-start))

61
src/zy-neo/utils.lua Normal file
View File

@ -0,0 +1,61 @@
builtins.utils = function()
local utils = {}
function utils.debug_log(...)
local sb = component.list("sandbox")() or component.list("ocemu")()
if (sb) then component.invoke(sb, "log", ...) end
end
function utils.baddr(address)
local address = address:gsub("-", "", true)
local b = ""
for i=1, #address, 2 do
b = b .. string.char(tonumber(address:sub(i, i+1), 16))
end
return b
end
function utils.readfile(f,h)
local b=""
local d,r=component.invoke(f,"read",h,math.huge)
if not d and r then error(r)end
b=d
while d do
local d,r=component.invoke(f,"read",h,math.huge)
b=b..(d or "")
if(not d)then break end
end
component.invoke(f,"close",h)
return b
end
-- Hell yeah, deepcopy time.
function utils.deepcopy(src, dest)
dest = dest or {}
local coppied = {[src] = dest}
local cin = {src}
local cout = {dest}
while #cin > 0 do
for k, v in pairs(cin[1]) do
if (type(v) ~= "table") then
cout[1][k] = v
else
if (coppied[v]) then
cout[1][k] = coppied[v]
else
local t = {}
cout[1][k] = t
cin[#cin+1] = v
cout[#cout+1] = t
coppied[v] = t
end
end
end
table.remove(cout, 1)
table.remove(cin, 1)
end
return dest
end
return utils
end

View File

@ -1,9 +1,10 @@
local lzss_decompress = {...}
local lzss_decompress = ...
--Zorya NEO itself.
_BIOS = "Zorya NEO"
_ZVSTR = "2.0"
_ZVER = 2.0
_ZPAT = 0
_ZGIT = "$[[git rev-parse --short HEAD]]"
--#include "ksrc/kinit.lua"
local thd = krequire("thd")
local util = krequire("util")
@ -12,32 +13,39 @@ local component = component
local computer = computer
local booted = false
local zcfg = {}
function log(...)
component.proxy(component.list("ocemu")()).log(...)
end
local th_i = 0
local function th_a(func)
thd.add("zyneo$"..th_i, func)
end
local builtins = {}
--#include "src/zy-neo/utils.lua"
sys.add_lib("zorya", (function()
local mod_search = {}
local zy = {}
function zy.get_bootlist()
--function zy.get_bootlist()
end
--end
function zy.boot(i)
th_a(zcfg[i][2](zcfg[i][3]))
booted = true
end
--function zy.boot(i)
-- th_a(zcfg[i][2](zcfg[i][3]))
-- booted = true
--end
local loaded_mods = {}
function zy.loadmod(mod)
if (loaded_mods[mod]) then return loaded_mods[mod] end
for i=1, #mod_search do
log(i, #mod_search, mod)
local r = mod_search[i](mod)
if r then return r end
if r then loaded_mods[mod] = r return r end
end
end
@ -47,6 +55,7 @@ sys.add_lib("zorya", (function()
function zy.add_mod_search(func)
mod_search[#mod_search+1] = func
log(#mod_search)
end
function zy.lkthdn()
@ -61,15 +70,11 @@ end)())
--#include "src/zy-neo/init.lua"
builtins["menu"] = (function()
--#include "src/zy-neo/builtins/mod_menu/init.lua"
end)
local function load_lua(src, ...)
if (src:sub(1, 4) == "\27ZLS") then
src = lzss_decompress(src:sub(5))
end
return assert(load(src, ...))
return load(src, ...)
end
-- Zorya's handler thread.
@ -77,23 +82,23 @@ th_a(function()
local er
xpcall(function()
local zy = krequire("zorya")
zy.add_mod_search(function(mod)
if (builtins[mod]) then
return builtins[mod]
end
end)
zy.add_mod_search(function(mod)
if (bfs.exists(".zy2/mods/"..mod..".zy2m")) then
return assert(load_lua(bfs.getfile(".zy2/mods/"..mod..".zy2m"), "=.zy2/mods/"..mod..".zy2m")())
return load_lua(bfs.getfile(".zy2/mods/"..mod..".zy2m"), "=.zy2/mods/"..mod..".zy2m")()
elseif (bfs.exists(".zy2/mods/"..mod.."/init.zy2m")) then
return load_lua(bfs.getfile(".zy2/mods/"..mod.."/init.zy2m"), "=.zy2/mods/"..mod.."/init.zy2m")()
end
end)
sys.add_search(function(mod)
if (builtins[mod]) then
return builtins[mod]
end
end)
sys.add_search(function(mod)
if (bfs.exists(".zy2/lib/"..mod..".zy2l")) then
return load_lua(bfs.getfile(".zy2/lib/"..mod.."..zy2l"), "=.zy2/lib/"..mod.."..zy2l")()
return load_lua(bfs.getfile(".zy2/lib/"..mod..".zy2l"), "=.zy2/lib/"..mod..".zy2l")
elseif (bfs.exists(".zy2/lib/"..mod.."/init..zy2l")) then
return load_lua(bfs.getfile(".zy2/lib/"..mod.."/init..zy2l"), "=.zy2/lib/"..mod.."/init..zy2l")()
return load_lua(bfs.getfile(".zy2/lib/"..mod.."/init.zy2l"), "=.zy2/lib/"..mod.."/init.zy2l")
end
end)
local zycfg = bfs.getfile(".zy2/cfg.lua")

View File

@ -17,19 +17,20 @@ for i=1, #f do
end
end
io.stdout:write("\"\n")]]
local rep = {
["\0"] = "\\0",
["\\"] = "\\\\",
["\""] = "\\\"",
["\n"] = "\\n",
["\r"] = "\\r",
["\t"] = "\\t",
[" "] = "\x20"
}
local function mkstr(d)
local dat = "\""
for i=1, #f do
if (d:byte(i) == 0) then
dat = dat .. "\0"
elseif (d:sub(i,i) == "\\") then
dat = dat .. ("\\\\")
elseif (d:sub(i,i) == "\"") then
dat = dat .. ("\\\"")
elseif (d:sub(i,i) == "\n") then
dat = dat .. ("\\n")
elseif (d:sub(i,i) == "\r") then
dat = dat .. ("\\r")
if (rep[d:sub(i, i)]) then
dat = dat .. rep[d:sub(i, i)]
else
dat = dat .. (d:sub(i,i))
end

View File

@ -41,7 +41,7 @@ function lzss_decompress(input)
return table.concat(output)
end
print("Decompressing CPIO...")
--print("Decompressing CPIO...")
local code = lzss_decompress(@[{io.stdin:read("*a")}])
local dat = code
local tbl = {}

View File

@ -41,7 +41,7 @@ local characters = {
}
local computer = computer or require("computer")
local fsaddr = args[1] or computer.getBootAddress()
print(fsaddr)
--print(fsaddr)
local component = component or require("component")
local proxy, list = component.proxy, component.list
local gpu = proxy(list("gpu")())
@ -87,6 +87,7 @@ function setBar(pos)
gpu.fill(8, (h/2)+1, w-16, 1, " ")
gpu.setBackground(2, true)
gpu.fill(8, (h/2)+1, ((w-16)/100)*pos, 1, " ")
computer.pullSignal(0)
end
function writeFile(fs, path, data)
@ -146,6 +147,13 @@ eeprom.setData(fs.address)
eeprom.setLabel("Zorya NEO BIOS v2.0")
setBar(100)
setStatus("Rebooting in 5 seconds...")
if not fs.exists(".zy2/cfg.lua") then
writeFile(fs, ".zy2/cfg.lua", string.format([[local menu = loadmod("menu_classic")
menu.add("OpenOS on %s", function()
return loadmod("loader_openos")("%s")
end)
menu.draw()]], fsaddr:sub(1, 3), fsaddr))
end
computer = computer or require("computer")
local stime = computer.uptime()
while true do

119
utils/unzlua.lua Normal file
View File

@ -0,0 +1,119 @@
local f = io.stdin:read("*a")
if (f:sub(1, 4) ~= "\27ZLS") then io.stderr:write("Not a zlua script!\n") os.exit(1) end
--[[----------------------------------------------------------------------------
LZSS - encoder / decoder
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
--]]----------------------------------------------------------------------------
--------------------------------------------------------------------------------
local M = {}
local string, table = string, table
--------------------------------------------------------------------------------
local POS_BITS = 12
local LEN_BITS = 16 - POS_BITS
local POS_SIZE = 1 << POS_BITS
local LEN_SIZE = 1 << LEN_BITS
local LEN_MIN = 3
--------------------------------------------------------------------------------
function M.compress(input)
local offset, output = 1, {}
local window = ''
local function search()
for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do
local str = string.sub(input, offset, offset + i - 1)
local pos = string.find(window, str, 1, true)
if pos then
return pos, str
end
end
end
while offset <= #input do
local flags, buffer = 0, {}
for i = 0, 7 do
if offset <= #input then
local pos, str = search()
if pos and #str >= LEN_MIN then
local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN)
buffer[#buffer + 1] = string.pack('>I2', tmp)
else
flags = flags | (1 << i)
str = string.sub(input, offset, offset)
buffer[#buffer + 1] = str
end
window = string.sub(window .. str, -POS_SIZE)
offset = offset + #str
else
break
end
end
if #buffer > 0 then
output[#output + 1] = string.char(flags)
output[#output + 1] = table.concat(buffer)
end
end
return table.concat(output)
end
--------------------------------------------------------------------------------
function M.decompress(input)
local offset, output = 1, {}
local window = ''
while offset <= #input do
local flags = string.byte(input, offset)
offset = offset + 1
for i = 1, 8 do
local str = nil
if (flags & 1) ~= 0 then
if offset <= #input then
str = string.sub(input, offset, offset)
offset = offset + 1
end
else
if offset + 1 <= #input then
local tmp = string.unpack('>I2', input, offset)
offset = offset + 2
local pos = (tmp >> LEN_BITS) + 1
local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN
str = string.sub(window, pos, pos + len - 1)
end
end
flags = flags >> 1
if str then
output[#output + 1] = str
window = string.sub(window .. str, -POS_SIZE)
end
end
end
return table.concat(output)
end
io.stdout:write(M.decompress(f:sub(5)))