diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/build.sh b/build.sh index 222171f..6338dcc 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1,2 @@ #!/usr/bin/env sh -luacomp build.lua 2>/dev/null | lua - $@ \ No newline at end of file +luacomp build.lua 2>/dev/null | lua5.3 - $@ \ No newline at end of file diff --git a/installer_dat/package_list.lua b/installer_dat/package_list.lua index 0c14e76..8c4f8d8 100644 --- a/installer_dat/package_list.lua +++ b/installer_dat/package_list.lua @@ -7,6 +7,7 @@ {name="oefiv2", cat="util", path="mods/util_oefiv2.velx"}, {name="oefiv1", cat="util", path="mods/util_oefiv1.velx"}, {name="openos", cat="loader", path="mods/loader_openos.velx"}, + {name="monolith", cat="loader", path="mods/loader_monolith.velx"}, {name="fuchas", cat="loader", path="mods/loader_fuchas.velx"}, {name="vbios", cat="vdev", path="mods/vdev_vbios.velx"}, {name="biosdev", cat="vdev", path="mods/vdev_biosdev.velx"}, diff --git a/lib/exec_velx/init.lua b/lib/exec_velx/init.lua new file mode 100644 index 0000000..e69de29 diff --git a/luabuild.lua b/luabuild.lua new file mode 100644 index 0000000..75d0473 --- /dev/null +++ b/luabuild.lua @@ -0,0 +1,297 @@ +--#!/usr/bin/env luajit +EXPORT = {} + +local version = "0.1.0" +local lanes = require("lanes").configure({ + demote_full_userdata = true +}) +local argparse = require("argparse") + +local nproc = 0 +do + local h = io.popen("nproc", "r") + local n = h:read("*a"):match("%d+") + h:close() + if n and tonumber(n) then + nproc = tonumber(n) + end +end + +_NPROC = nproc + +local tags = { + ["info"] = "\27[36mINFO\27[0m", + ["warning"] = "\27[93mWARNING\27[0m", + ["error"] = "\27[91mERROR\27[0m", + ["build"] = "\27[35mBUILD\27[0m", + ["ok"] = "\27[92mOK\27[0m", + ["link"] = "\27[34mLINK\27[0m", + ["pack"] = "\27[95mPACK\27[0m", +} + +function lastmod(path) + +end + +local function wait_start(t) + while t.status == "pending" do lanes.sleep() end +end + +local function getwh() + local f = io.popen("stty size", "r") + local w, h = f:read("*n"), f:read("*n") + f:close() + return tonumber(w), tonumber(h) +end + +local function draw_bar(tag, object, max, current) + if (#object > 15) then + object = object:sub(1, 12).."..." + end + os.execute("stty raw -echo 2> /dev/null") -- i cannot comprehend what retardation lead me to have to do this + io.stdout:write("\27[6n") + io.stdout:flush() + local lc = "" + while lc ~= "\27" do + -- print(string.byte(lc) or "") + lc = io.stdin:read(1) + -- print(string.byte(lc)) + end + io.stdin:read(1) + local buf = "" + while lc ~= "R" do + lc = io.stdin:read(1) + buf = buf .. lc + end + os.execute("stty sane 2> /dev/null") + --print(buf) + local y, x = buf:match("(%d+);(%d+)") + x = tonumber(x) + y = tonumber(y) + --print(os.getenv("LINES"), os.getenv("COLUMNS")) + --local l = tonumber(os.getenv("LINES")) + --local c = tonumber(os.getenv("COLUMNS")) + --print(l, c) + local l, c = getwh() -- WHY + if (y == l) then + print("") + y = y - 1 + end + local mx = string.format("%x", max) + local cur = string.format("%."..#mx.."x", current) + local bar = (current/max)*(c-(26+#mx*2)) + if bar ~= bar then bar = 0 end + io.stdout:write("\27["..l.."H") + local pad = 6-#tag + local opad = 16-#object + --print(math.floor(bar)) + local hashes = string.rep("#", math.floor(bar)) + local dashes = string.rep("-", c-(26+#mx*2+#hashes)) + io.stdout:write(tags[tag], string.rep(" ", pad), object, string.rep(" ", opad), cur, "/", mx, " [", hashes, dashes, "]") + io.stdout:write("\27[", x, ";", y, "H") +end + +function status(tag, msg) + print(tags[tag], msg) +end + +local threads = {} + +local stat = status + +local function run(cmd) + if not status then status = stat end + local h = io.popen(cmd.." 2>&1", "r") + local out = h:read("*a") + local rtn = h:close() + return rtn, out +end + +local tasks = {} +local reflect = {} + +function task(name, stuff) + tasks[#tasks+1] = {name, stuff, false} +end + +reflect.task = task +reflect._NPROC = nproc +reflect.status = status +reflect.draw_bar = draw_bar + +function dep(name) + if not status then setmetatable(_G, {__index=reflect}) end + for i=1, #tasks do + if (tasks[i][1] == name) then + if not tasks[i][3] then + tasks[i][3] = true + tasks[i][2]() + end + return + end + end + status("error", "Task `"..name.."' not found!") + os.exit(1) +end + +reflect.dep = dep + +local function sync() + local errors = {} + while #threads > 0 do + for i=1, #threads do + if (threads[j].status ~= "running") then + if not threads[j][1] then + errors[#errors+1] = threads[j][2] + end + table.remove(threads, j) + break + end + end + end + return errors +end + +reflect.sync = sync + +local CC_STATE = { + compiler = "clang", + flags = {}, + args = {}, + libs = {}, +} + +local run_t = lanes.gen("*", run) + +local function compile(file) + local compiler_command = compiler .. " -fdiagnostics-color=always " + for i=1, #CC_STATE.flags do + compiler_command = compiler_command .. "-f"..CC_STATE.flags[i].." " + end + for i=1, #CC_STATE.args do + compiler_command = compiler_command .. CC_STATE.args[i].." " + end + compiler_command = compiler_command .. file + return run_t(compiler_command) +end + +local function link(target, files) + local nfiles = {} + for i=1, #files do + nfiles[i] = files[i]:gsub("%.c$", ".o") + end + + local compiler_command = compiler .. " -fdiagnostics-color=always " + for i=1, #CC_STATE.libs do + compiler_command = compiler_command .. "-l"..CC_STATE.args[i].." " + end + compiler_command = compiler_command "-o "..target.. " " .. table.concat(files, " ") + run(compiler_command) +end + +function build(target, files) + status("build", target.." ("..#files.." source files)") + draw_bar("build", target, 0, #files) + for i=1, #files do + if (#threads == nproc) then + while true do + for j=1, #threads do + if (threads[j].status ~= "running") then + if not threads[j][1] then + status("error", "Error in compile, waiting for all threads to finish...") + local errors = sync() + print(threads[j][2]) + for k=1, #errors do + print(errors[k]) + end + os.exit(1) + else + threads[j] = compile(files[i]) + wait_start(threads[j]) + break + end + end + end + lanes.sleep() + end + else + threads[#threads+1] = compile(files[i]) + end + draw_bar("build", target, #files, i) + end + local errors = sync() + if #errors > 0 then + for i=1, #errors do + print(errors[i]) + end + os.exit(1) + end + status("link", target) + draw_bar("link", target, 1, 1) + link(target, files) +end + +reflect.build = build +reflect.EXPORT = EXPORT + +function find(path) + local entries = {} + local h = io.popen("find "..path, "r") + for l in h:lines() do + entries[#entries+1] = l + end + return entries +end + +reflect.find = find + +local files = find(".build") +for i=1, #files do + if (files[i]:match("%.lua$")) then + dofile(files[i]) + end +end + +task("list", function() + for i=1, #tasks do + print(tasks[i][1]) + end +end) + +local dep_t = lanes.gen("*", dep) + +local function run_task(task) + local t = dep_t(task) + wait_start(t) + while true do + if (t.status ~= "running") then + if (t.status ~= "done") then + status("error", "Task '"..task.."' has run into an error!") + print(t[1]) + end + break + end + end + lanes.sleep() +end + +local parser = argparse("luabuild", "High-speed lua build system.") +parser:option("-j --threads", "Number of threads", nproc) +parser:argument("tasks", "Tasks to run"):args("*") +local args = parser:parse() +status("info", "luabuild version is "..version) +status("info", "lua verison is ".._VERSION) +if not tonumber(args.threads) then + status("error", "Number of threads must be a number!") + os.exit(1) +end +nproc = tonumber(args.threads) +status("info", "core count: "..nproc) +for i=1, #args.tasks do + status("info", "Current task: "..args.tasks[i]) + local st = os.clock() + run_task(args.tasks[i]) + local dur = os.clock()-st + status("ok", "Task `"..args.tasks[i].."' completed in "..string.format("%.2fs", dur)) +end +status("ok", "Build completed in "..string.format("%.2fs", os.clock())) \ No newline at end of file diff --git a/mods/menu_bios/config.lua b/mods/menu_bios/config.lua new file mode 100644 index 0000000..7a15dae --- /dev/null +++ b/mods/menu_bios/config.lua @@ -0,0 +1,17 @@ +local cfg = {} +local function b2a(data) + return string.format(string.format("%s-%s%s",string.rep("%.2x", 4),string.rep("%.2x%.2x-",3),string.rep("%.2x",6)),string.byte(data, 1,#data)) +end +local function a2b(addr) + addr=addr:gsub("%-", "") + local baddr = "" + for i=1, #addr, 2 do + baddr = baddr .. string.char(tonumber(addr:sub(i, i+1), 16)) + end + return baddr +end +do + -- Get EEPROM config data. + local eep = component.proxy(component.list("eeprom")()) + local dat = eep.getData():sub(37) +end \ No newline at end of file diff --git a/mods/menu_bios/init.lua b/mods/menu_bios/init.lua index 911a01a..d0d7459 100644 --- a/mods/menu_bios/init.lua +++ b/mods/menu_bios/init.lua @@ -1,9 +1,54 @@ +local computer = computer or require("computer") +local component = component or require("component") + local menu = {} local gpu = component.proxy(component.list("gpu")()) -gpu.bind(component.list("screen")()) +--gpu.bind((component.list("screen")())) -gpu.set(1, 1, "Zorya NEO v2.0 BIOS/Bootloader") +gpu.set(1, 1, _BIOS.." ".._ZVSTR.." BIOS/Bootloader") gpu.set(1, 2, "(c) 2020 Adorable-Catgirl") -gpu.set(1, 4, "Memory: "..math.floor(computer.totalMemory()/1024).."K") ---gpu.set(1, 5) \ No newline at end of file +gpu.set(1, 3, "Git Revsion: ".._ZGIT) +gpu.set(1, 5, "Memory: "..math.floor(computer.totalMemory()/1024).."K") +--gpu.set(1, 5) + +local logo = { +" ⣾⣷ ", +" ⢠⡟⢻⡄ ", +" ⢀⡾⢡⡌⢷⡀ ", +"⣠⣤⣤⠶⠞⣋⣴⣿⣿⣦⣙⠳⠶⣤⣤⣄", +"⠙⠛⠛⠶⢦⣍⠻⣿⣿⠟⣩⡴⠶⠛⠛⠋", +" ⠈⢷⡘⢃⡾⠁ ", +" ⠘⣧⣼⠃ ", +" ⢿⡿ " +} + +local w, h = gpu.getViewport() +gpu.setForeground(0x770077) +for i=1, #logo do + gpu.set(w-18, 1+i, logo[i]) +end +gpu.setForeground(0xFFFFFF) + +gpu.set(1, h, "F1 for setup; F2 for boot options.") + +local y = 0 +local my = h-9 +function status(msg) + msg = msg:sub(1, w-18) + y = y + 1 + if y > my then + gpu.copy(2, 9, w, h-10, 0, -1) + y = my + end + gpu.set(1, y+8, msg) +end + +for c, t in component.list("") do + status("Found "..t..": "..c) +end + +local et = computer.uptime()+5 +while et>=computer.uptime() do + computer.pullSignal(et-computer.uptime()) +end \ No newline at end of file diff --git a/mods/util_velx/velx.lua b/mods/util_velx/velx.lua index db2d9ad..f592c2c 100644 --- a/mods/util_velx/velx.lua +++ b/mods/util_velx/velx.lua @@ -9,6 +9,7 @@ local function load_velx(read, seek, close, name) end if (osid & 0x80 > 0) then return nil, "not an executable" + end if (compression > 1) then return nil, "bad compression" end diff --git a/src/zy-neo/builtins/util_velx.lua b/src/zy-neo/builtins/util_velx.lua new file mode 100644 index 0000000..a9d7112 --- /dev/null +++ b/src/zy-neo/builtins/util_velx.lua @@ -0,0 +1,175 @@ +do + local velx2 = {} + + local vx_header = "c5BHlllHB" + + local vx_section = "llllI4HHB" + + local dtype = { + ["str"] = function(s) + return s + end, + ["u8"] = function(s) + return s:byte() + end, + ["u16"] = function(s, e) + return string.unpack(e.."H", s) + end, + ["u32"] = function(s, e) + return string.unpack(e.."I4", s) + end, + ["u64"] = function(s, e) + return string.unpack(e.."L", s) + end, + ["i8"] = function(s, e) + return string.unpack(e.."b", s) + end, + ["i16"] = function(s, e) + return string.unpack(e.."h", s) + end, + ["i32"] = function(s, e) + return string.unpack(e.."i4", s) + end, + ["i64"] = function(s, e) + return string.unpack(e.."l", s) + end, + ["bool"] = function(s) + return s:byte() > 0 + end, + ["f32"] = function(s, e) + return string.unpack(e.."f", s) + end, + ["f64"] = function(s, e) + return string.unpack(e.."d", s) + end + } + + function util.velx2(read, seek, close, name) + -- Read main header. + local h = read(vx_header:packsize()) + local magic, ver, etest = " 0 do + local spoon = 1024*1024 + if (ramt < spoon) then + spoon = ramt + end + local d = read(spoon) + csum:update(d) + sec_csum:update(d) + ramt = ramt - spoon + end + local c_scsum = sec_csum:digest() + if (c_scsum ~= section.csum) then + section.invalid = true + -- some warning here + end + sections[#sections+1] = section + end + local c_csum = csum:digest() + if (c_csum ~= checksum) then + return nil, string.format("checksum mismatch %x ~= %x", c_csum, checksum) + end + return setmetatable({ + read = read, + seek = seek, + close = close, + sections = sections, + flags = flags, + offset = offset, + type = btype, + }, {__index=velx2}) + end + + function velx2:getsection(osid, sec) + for i=1, #self.sections do + local sec = self.sections[i] + if (sec.id == osid and sec.name == name or sec.id == 0) then + self.seek(sec.pos-self.seek()) + local dat = self.read(sec.size) + if (sec.tags.compression == "lz4") then + dat = lz4_decompress(dat) + end + return dat + end + end + end + + function velx2:gettag(osid, sec, tag) + for i=1, #self.sections do + local sec = self.sections[i] + if (sec.id == osid and sec.name == name or sec.id == 0) then + return sec.tags[tag] + end + end + end + + function velx2:getsecinfo(osid, sec) + for i=1, #self.sections do + local sec = self.sections[i] + if (sec.id == osid and sec.name == name or sec.id == 0) then + return sec + end + end + end + + function velx2:getstream(osid, sec) + for i=1, #self.sections do + local sec = self.sections[i] + if (sec.id == osid and sec.name == name or sec.id == 0) then + local ptr = 0 + return function(a) + self.seek((sec.pos+ptr)-self.seek()) + if (ptr+a+1 > sec.size) then + a = sec.size - ptr + end + if (a < 1) then + return "" + end + return self.read(a) + end, function(a) + a = a-1 or 0 + ptr = ptr + a + if (ptr < 0) then + ptr = 0 + elseif (ptr > sec.size-1) then + ptr = self.size-1 + end + return ptr+1 + end, function() end + end + end + end +end \ No newline at end of file diff --git a/src/zy-neo/builtins/util_xxh64.lua b/src/zy-neo/builtins/util_xxh64.lua new file mode 100644 index 0000000..cab7c23 --- /dev/null +++ b/src/zy-neo/builtins/util_xxh64.lua @@ -0,0 +1,177 @@ +-- i can't see "v2" without thinking of ace combat zero + +local prime1, prime2, prime3, prime4, prime5 = 0x9E3779B185EBCA87, 0xC2B2AE3D27D4EB4F, 0x165667B19E3779F9, 0x85EBCA77C2B2AE63, 0x27D4EB2F165667C5 + +local function rotl64(x, r) + return (((x) << (r)) | ((x) >> (64 - (r)))) +end + +local function round(acc, input) + acc = acc + (input * prime2) + acc = rotl64(acc, 31) + acc = acc * prime1 + return acc +end + +local function merge_round(acc, val) + val = round(0, val) + acc = acc ~ val + acc = acc * prime1 + prime4 + return acc +end + +local function avalanche(h64) + h64 = h64 ~ (h64 >> 33) + h64 = h64 * prime2 + h64 = h64 ~ (h64 >> 29) + h64 = h64 * prime3 + h64 = h64 ~ (h64 >> 32) + return h64 +end + +local function finalize(h64, input) + while #input & 31 > 0 do + if (#input < 8) then + if (#input < 4) then + for i=1, #input do + h64 = h64 ~ (input:byte() * prime5) + input = input:sub(2) + h64 = rotl64(h64, 11) * prime1 + end + else + h64 = h64 ~ (string.unpack("= 32) then + local v1 = seed + prime1 + prime2 + local v2 = seed + prime2 -- << It's time. >> + local v3 = seed + local v4 = seed - prime1 + + repeat + v1 = round(v1, string.unpack("> + v3 = 0, + v4 = 0, + buffer = "", + size = 0 + } + setmetatable(s, {__index=state}) + s:reset(seed) + return s +end + +function state:reset(seed) + seed = seed or 0 + self.v1 = seed + prime1 + prime2 + self.v2 = seed + prime2 -- << What have borders ever given us? >> + self.v3 = seed + self.v4 = seed - prime1 + self.buffer = "" + self.size = 0 +end + +function state:update(input) + self.size = self.size + #input + input = self.buffer .. input + local data_len = #input - (#input & 31) + self.buffer = input:sub(data_len+1) + + local data = input:sub(1, data_len) + local v1 = self.v1 + local v2 = self.v2 -- << Can you see any borders from up here? >> + local v3 = self.v3 + local v4 = self.v4 + + repeat + v1 = round(v1, string.unpack("= 32) then + local v1 = self.v1 + local v2 = self.v2 + local v3 = self.v3 + local v4 = self.v4 + h64 = rotl64(v1, 1) + rotl64(v2, 7) + rotl64(v3, 12) + rotl64(v4, 18) + h64 = merge_round(h64, v1) + h64 = merge_round(h64, v2) + h64 = merge_round(h64, v3) + h64 = merge_round(h64, v4) + + else + h64 = self.v3 + prime5 + end + + h64 = h64 + self.size + + return finalize(h64, self.buffer) -- << That's what V2 is for. >> +end + +return { + sum = xxh64, + state = create_state +} diff --git a/src/zy-neo/neoinit.lua b/src/zy-neo/neoinit.lua index 019c457..9fce4ae 100644 --- a/src/zy-neo/neoinit.lua +++ b/src/zy-neo/neoinit.lua @@ -42,6 +42,10 @@ local function readfile(f,h) return b end +local xxh = (function() +--#include "src/zy-neo/builtins/util_xxh64.lua" +end)() + --#include "src/zy-neo/builtins/util_tsar.lua" @[[if not svar.get("ZY_PLATFORM") then]] --#define "ZY_PLATFORM" "managed" diff --git a/src/zy-neo/utils.lua b/src/zy-neo/utils.lua index 8fe730c..5398a63 100644 --- a/src/zy-neo/utils.lua +++ b/src/zy-neo/utils.lua @@ -53,11 +53,29 @@ end local velx_header = " 0) then + return nil, "not an executable" + end + local code = vx2:getsection(0x5A, "lua") + local t = vx2:gettag(0x5A, "archive", "type") + local env = {} + if (t and t ~= "tsar") then + return nil, "bad arctype" + elseif (t) then + env._ARCHIVE = tsar.read(vx2:getstream(0x5A, "archive")) + end + setmetatable(env, {__index=_G, __newindex=function(_, i, v) _G[i] = v end}) + return load(code, "="..(name or "(loaded velx)"), "t", env) + end if osid & 0x7F ~= 0x5A then return nil, string.format("wrong os (%x ~= 0x5A)", osid & 0x7F) end diff --git a/src/zy-neo/zinit.lua b/src/zy-neo/zinit.lua index 565449b..657b882 100644 --- a/src/zy-neo/zinit.lua +++ b/src/zy-neo/zinit.lua @@ -18,6 +18,8 @@ end local builtins = {} --#include "src/zy-neo/utils.lua" local log = utils.debug_log +builtins.utils_tsar = function() return tsar end +builtins.util_xxh64 = function() return xxh end sys.add_lib("zorya", (function() diff --git a/utils/make_tsar.lua b/utils/make_tsar.lua index 0d24173..825e891 100644 --- a/utils/make_tsar.lua +++ b/utils/make_tsar.lua @@ -73,4 +73,4 @@ do io.stdout:write(ent.name) size = size + 32 end -io.stderr:write((size//512).." blocks.\n") \ No newline at end of file +--io.stderr:write((size//512).." blocks.\n") \ No newline at end of file diff --git a/utils/mkselfextract.lua b/utils/mkselfextract.lua index 3d6a14b..6edce94 100644 --- a/utils/mkselfextract.lua +++ b/utils/mkselfextract.lua @@ -77,7 +77,7 @@ function lzss_compress(input) end local tmp = os.tmpname() -local h = io.popen("luacomp ../utils/selfextract.lua -O"..tmp, "w") +local h = io.popen("luacomp ../utils/selfextract.lua -O"..tmp.." 2>/dev/null", "w") --h:write(mkstr(lzss_compress(f))) h:write(mkstr(f)) h:close() diff --git a/utils/ser.lua b/utils/ser.lua index 82d5202..ee37c64 100644 --- a/utils/ser.lua +++ b/utils/ser.lua @@ -231,7 +231,9 @@ local bios_files = load("return "..getfile("installer_dat/bios_list.lua"))() setBar(33) local pkg_files = load("return "..getfile("installer_dat/package_list.lua"))() setBar(67) -local lang = load("return "..(getfile("installer_dat/lang/en_US.lua") or "{}"))() +local lf = load("return "..(getfile("installer_dat/lang/en_US.lua") or "{}")) +if not lf then lf = function()return {}end end +local lang = lf() setBar(100) setStatus("Extracting files...") @@ -239,7 +241,7 @@ setBar(0) for i=1, #pkg_files do setStatus("Extracting "..(lang["mod_"..pkg_files[i].cat.."_"..pkg_files[i].name.."_name"] or "#mod_"..pkg_files[i].cat.."_"..pkg_files[i].name.."_name").."... ("..i.." of "..#pkg_files..")") setBar(100*(i/#pkg_files)) - writeFile(".zy2/"..pkg_files[i].path, getfile(pkg_files[i].path)) + writeFile(".zy2/"..pkg_files[i].path, getfile(pkg_files[i].path) or "") end setStatus("Extracting EEPROM...")