From 4318a82965fef73a49e2fda3518dd5976df1c4c6 Mon Sep 17 00:00:00 2001 From: Jane Roxanne Date: Fri, 10 Apr 2020 10:38:52 -0500 Subject: [PATCH] We got a console now. --- mods/util_luaconsole/.nomin | 0 mods/util_luaconsole/init.lua | 102 +++++++++++++++++ mods/util_luaconsole/tty.lua | 178 ++++++++++++++++++++++++++++++ mods/util_searchpaths/init.lua | 4 +- mods/vdev_vbios/.nomin | 0 release.lua | 6 +- util/OpenOS/config.d/96_vbios.lua | 11 +- util/OpenOS/zyvbios-new.lua | 82 ++++++++++++++ util/init.lua | 2 + 9 files changed, 376 insertions(+), 9 deletions(-) create mode 100644 mods/util_luaconsole/.nomin create mode 100644 mods/util_luaconsole/init.lua create mode 100644 mods/util_luaconsole/tty.lua create mode 100644 mods/vdev_vbios/.nomin create mode 100644 util/OpenOS/zyvbios-new.lua diff --git a/mods/util_luaconsole/.nomin b/mods/util_luaconsole/.nomin new file mode 100644 index 0000000..e69de29 diff --git a/mods/util_luaconsole/init.lua b/mods/util_luaconsole/init.lua new file mode 100644 index 0000000..53748dc --- /dev/null +++ b/mods/util_luaconsole/init.lua @@ -0,0 +1,102 @@ +--#include "tty.lua" +return function(autorun) + local keys = { + lcontrol = 0x1D, + back = 0x0E, -- backspace + delete = 0xD3, + down = 0xD0, + enter = 0x1C, + home = 0xC7, + left = 0xCB, + lshift = 0x2A, + pageDown = 0xD1, + rcontrol = 0x9D, + right = 0xCD, + rmenu = 0xB8, -- right Alt + rshift = 0x36, + space = 0x39, + tab = 0x0F, + up = 0xC8, + ["end"] = 0xCF, + tab = 0x0F, + numpadenter = 0x9C, + } + tty.clear() + tty.utf() + tty.setcursor(1, 1) + tty.update() + tty.setcolor(0xF) + tty.print("Zorya NEO Lua Terminal") + tty.print("Zorya NEO ".._ZVSTR.." ".._ZGIT) + local buffer = "" + function print(...) + tty.print(...) + end + function exit() + exit = nil + print = nil + end + if (autorun) then + load(autorun)() + end + tty.print("") + tty.setcolor(2) + tty.write("boot> ") + tty.setcolor(0xF0) + tty.write(" ") + tty.setcolor(0xF) + while exit do + local sig = {computer.pullSignal()} + if (sig[1] == "key_down") then + if (sig[3] > 31 and sig[3] ~= 127) then + local x, y = tty.getcursor() + tty.setcursor(x-1, y) + tty.setcolor(0xF) + tty.write(utf8.char(sig[3])) + tty.setcolor(0xF0) + tty.write(" ") + buffer = buffer .. utf8.char(sig[3]) + elseif (sig[4] == keys.back) then + if (#buffer > 0) then + local x, y = tty.getcursor() + tty.setcursor(x-2, y) + tty.setcolor(0xF0) + tty.write(" ") + tty.setcolor(0xF) + tty.write(" ") + tty.setcursor(x-1, y) + buffer = buffer:sub(1, #buffer-1) + end + elseif (sig[4] == keys.enter) then + if (buffer:sub(1,1) == "=") then + buffer = "return "..buffer:sub(2) + end + local s, e = load(buffer) + local x, y = tty.getcursor() + tty.setcursor(x-1, y) + tty.setcolor(0xF) + tty.write(" ") + tty.print(" ") + buffer = "" + if not s then + tty.setcolor(0x4) + tty.print(e) + tty.setcolor(0xf) + else + tty.setcolor(0xf) + xpcall(function() + tty.print(s()) + end, function(e) + tty.setcolor(0x4) + tty.print(debug.traceback(e):gsub("\t", " "):gsub("\r", "")) + end) + end + tty.setcolor(2) + tty.write("boot> ") + tty.setcolor(0xF0) + tty.write(" ") + tty.setcolor(0xF) + end + end + end +end \ No newline at end of file diff --git a/mods/util_luaconsole/tty.lua b/mods/util_luaconsole/tty.lua new file mode 100644 index 0000000..9ff023b --- /dev/null +++ b/mods/util_luaconsole/tty.lua @@ -0,0 +1,178 @@ +-- Super basic TTY driver. Supports unicode if enabled with tty.utf. +tty = {} +do + local gpu = component.proxy(component.list("gpu")()) + local gfg = -1 + local gbg = -1 + + local ttyc = 12 + local ttyx, ttyy = 1, 1 + + local w, h = gpu.maxResolution() + + local depth = gpu.maxDepth() + + gpu.setResolution(w, h) + gpu.setDepth(depth) + + if (depth == 4) then --pregen color + for i=0, 15 do + local hi = i >> 3 + local b = (i >> 2) & 1 + local g = (i >> 1) & 1 + local r = i & 1 + local fr = (r * 0x7F) | (hi << 7) + local fg = (g * 0x7F) | (hi << 7) + local fb = (b * 0x7F) | (hi << 7) + gpu.setPaletteColor(i, (fr << 16) | (fg << 8) | fb) + end + end + + function colors(i) + if (depth == 1) then + return ((i > 0) and 0xFFFFFF) or 0 + elseif (depth == 4) then + return i, true + else -- e x p a n d + local hi = i >> 3 + local r = (i >> 2) & 1 + local g = (i >> 1) & 1 + local b = i & 1 + local fr = (r * 0x7F) | (hi << 7) + local fg = (g * 0x7F) | (hi << 7) + local fb = (b * 0x7F) | (hi << 7) + return (fr << 16) | (fg << 8) | fb + end + end + + local buffer = string.char(0xF, 32):rep(w*h) + + local cwidth = 1 + + local function get_segments(spos, max) + spos = spos or 1 + if spos < 1 then spos = 1 end + max = max or #buffer//(1+cwidth) + local cur_color = -1 + local segments = {} + local _buffer = "" + local cpos = spos-1 --((spos-1)*(1+cwidth)) + local start_pos = cpos + for i=((spos-1)*(1+cwidth))+1, max*(1+cwidth), 1+cwidth do + local c, code = string.unpack("BI"..cwidth, buffer:sub(i, i+cwidth)) -- buffer:sub(i,i), buffer:sub(i+1, i+cwidth) + if (c ~= cur_color or cpos%w == 0) then + if (buffer ~= "") then + segments[#segments+1] = {(start_pos//w)+1, (start_pos%w)+1, cur_color, _buffer} + end + cur_color = c + start_pos = cpos + _buffer = "" + end + cpos = cpos + 1 + _buffer = _buffer .. utf8.char(code) + end + if (buffer ~= "") then + segments[#segments+1] = {((start_pos)//w)+1, ((start_pos)%w)+1, cur_color, _buffer} + end + return segments + end + + local function draw_segments(segs) + for i=1, #segs do + local fg, bg = segs[i][3] & 0xF, segs[i][3] >> 4 + if (fg ~= gfg) then + gpu.setForeground(colors(fg)) + end + if (bg ~= gbg) then + gpu.setBackground(colors(bg)) + end + gpu.set(segs[i][2], segs[i][1], segs[i][4]) + end + end + + function tty.setcolor(c) + ttyc = c + end + + function tty.utf() -- Cannot be undone cleanly! + if cwidth == 3 then return end + local newbuf = "" + for i=1, #buffer, 2 do + local a, b = string.unpack("BB", buffer:sub(i, i+1)) + newbuf = newbuf .. string.pack("BI3", a, b) + end + buffer = newbuf + cwidth = 3 + end + + function tty.moveup() + gpu.copy(1, 2, w, h-1, 0, -1) + buffer = buffer:sub((w*(1+cwidth))+1)..(string.rep(string.pack("BI"..cwidth, 0xF, 32), w)) + gpu.fill(1, h, w, 1, " ") + end + + function tty.clear() + x = 1 + y = 1 + buffer = string.rep("\x0F"..string.pack("I"..cwidth, 32), w*h) + end + + function tty.setcursor(x, y) + ttyx = x or 1 + ttyy = y or 1 + end + + function tty.getcursor() + return ttyx, ttyy + end + + function tty.write(s) + -- Convert to color/codepoint + local charmask = string.unpack("I"..cwidth, string.rep("\xFF", cwidth)) + local _buffer = "" + for i=1, utf8.len(s) do + _buffer = _buffer .. string.pack("BI"..cwidth, ttyc, utf8.codepoint(s, i) & charmask) + end + local bpos = (((ttyx-1)+((ttyy-1)*w))*(1+cwidth))+1 + local b1, b2 = buffer:sub(1, bpos-1), buffer:sub(bpos+#_buffer) + buffer = b1 .. _buffer .. b2 + local mod = 0 + if (#buffer > w*h*(1+cwidth)) then + -- Scroll smoothly + buffer = buffer .. string.rep("\x0F"..string.pack("I"..cwidth, 32), w-((#buffer/(1+cwidth)) % w)) + buffer = buffer:sub(#buffer-(w*h*(1+cwidth))+1) + tty.update() + mod = -w + else + -- Update what changed here. + draw_segments(get_segments((ttyx-1)+((ttyy-1)*w)+1, ((ttyx-1)+((ttyy-1)*w))+utf8.len(s))) + end + local pz = (((ttyx-1)+((ttyy-1)*w)) + utf8.len(s)) + mod + ttyx = (pz % w)+1 + ttyy = (pz // w)+1 + end + + function tty.print(...) + local args = {...} + for i=1, #args do + args[i] = tostring(args[i]) + end + local str = table.concat(args, " ").."\n" + for m in str:gmatch("(.*)\n") do + tty.write(m) + local x, y = tty.getcursor() + if (x ~= 1) then + ttyy = y + 1 + ttyx = 1 + if (ttyy > h) then + tty.moveup() + ttyy = h + end + end + end + end + + function tty.update() + draw_segments(get_segments()) + end +end \ No newline at end of file diff --git a/mods/util_searchpaths/init.lua b/mods/util_searchpaths/init.lua index 767ba2d..d04635f 100644 --- a/mods/util_searchpaths/init.lua +++ b/mods/util_searchpaths/init.lua @@ -11,10 +11,10 @@ function sp.add_mod_path(drive, path) zy.add_mod_search(function(mod) if (px.exists(path.."/"..mod..".zy2m")) then local h = px.open(path.."/"..mod..".zy2m", "r") - return utils.load_lua(utils.readfile(drive, h)) + return utils.load_lua(utils.readfile(drive, h))() elseif (px.exists(path.."/"..mod.."/init.zy2m")) then local h = px.open(path.."/"..mod.."/init.zy2m", "r") - return utils.load_lua(utils.readfile(drive, h)) + return utils.load_lua(utils.readfile(drive, h))() end end) end diff --git a/mods/vdev_vbios/.nomin b/mods/vdev_vbios/.nomin new file mode 100644 index 0000000..e69de29 diff --git a/release.lua b/release.lua index 530aacb..aaa3d03 100644 --- a/release.lua +++ b/release.lua @@ -24,7 +24,11 @@ status("\n\nBuilding modules.") if (os.execute("stat mods 1>/dev/null 2>&1")) then for l in io.popen("ls mods"):lines() do status("MOD\t"..l) - os.execute("sh -c 'cd mods/"..l.."; luacomp -mluamin init.lua | lua ../../utils/zlua.lua > ../../pkg/mods/"..l..".zy2m'") + if (os.execute("stat mods/"..l.."/.nomin 1>/dev/null 2>&1")) then + os.execute("sh -c 'cd mods/"..l.."; luacomp -mnone init.lua | lua ../../utils/zlua.lua > ../../pkg/mods/"..l..".zy2m'") + else + os.execute("sh -c 'cd mods/"..l.."; luacomp -mluamin init.lua | lua ../../utils/zlua.lua > ../../pkg/mods/"..l..".zy2m'") + end end end status("Module build complete.\n\nBuilding libraries.") diff --git a/util/OpenOS/config.d/96_vbios.lua b/util/OpenOS/config.d/96_vbios.lua index d15562b..fd4dd20 100644 --- a/util/OpenOS/config.d/96_vbios.lua +++ b/util/OpenOS/config.d/96_vbios.lua @@ -1,9 +1,6 @@ local cfgadd = ... -local addr = require("component").eeprom.getData() +--local addr = require("component").eeprom.getData() local fs = require("filesystem") -if not fs.exists("/.zy2/vbios/") then - return -end cfgadd([[ do local function add_bios(drive, path) @@ -16,8 +13,10 @@ do end) end ]]) -for ent in fs.list("/.zy2/vbios") do - cfgadd(string.format([[ add_bios("%s", ".zy2/vbios/%s")]].."\n", addr, ent:sub(1, #ent-1))) +for ent in fs.list("/etc/zorya-neo/vbios/") do + local prox, path = fs.get("/etc/zorya-neo/vbios/"..ent) + local rpath = ("/etc/zorya-neo/vbios/"..ent):sub(#path+1) + cfgadd(string.format([[ add_bios("%s", "%s")]].."\n", prox.address, rpath:sub(1, #rpath-1))) end cfgadd[[ end diff --git a/util/OpenOS/zyvbios-new.lua b/util/OpenOS/zyvbios-new.lua new file mode 100644 index 0000000..ac48585 --- /dev/null +++ b/util/OpenOS/zyvbios-new.lua @@ -0,0 +1,82 @@ +local args = {...} +local fs = require("filesystem") +local comp = require("computer") +local luabios = [[ +local init +do + local component_invoke = component.invoke + local function boot_invoke(address, method, ...) + local result = table.pack(pcall(component_invoke, address, method, ...)) + if not result[1] then + return nil, result[2] + else + return table.unpack(result, 2, result.n) + end + end + + -- backwards compatibility, may remove later + local eeprom = component.list("eeprom")() + computer.getBootAddress = function() + return boot_invoke(eeprom, "getData") + end + computer.setBootAddress = function(address) + return boot_invoke(eeprom, "setData", address) + end + + do + local screen = component.list("screen")() + local gpu = component.list("gpu")() + if gpu and screen then + boot_invoke(gpu, "bind", screen) + end + end + local function tryLoadFrom(address) + local handle, reason = boot_invoke(address, "open", "/init.lua") + if not handle then + return nil, reason + end + local buffer = "" + repeat + local data, reason = boot_invoke(address, "read", handle, math.huge) + if not data and reason then + return nil, reason + end + buffer = buffer .. (data or "") + until not data + boot_invoke(address, "close", handle) + return load(buffer, "=init") + end + local reason + if computer.getBootAddress() then + init, reason = tryLoadFrom(computer.getBootAddress()) + end + if not init then + computer.setBootAddress() + for address in component.list("filesystem") do + init, reason = tryLoadFrom(address) + if init then + computer.setBootAddress(address) + break + end + end + end + if not init then + error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0) + end + computer.beep(1000, 0.2) +end +init() +]] + +fs.makeDirectory("/etc/zorya-neo/vbios/"..args[1]) +local f = io.open("/etc/zorya-neo/vbios/"..args[1].."/code.lua", "w") +f:write(luabios) +f:close() + +local f = io.open("/etc/zorya-neo/vbios/"..args[1].."/label.txt", "w") +f:write("EEPROM (Lua BIOS)") +f:close() + +local f = io.open("/etc/zorya-neo/vbios/"..args[1].."/data.bin", "w") +f:write(comp.getBootAddress()) +f:close() \ No newline at end of file diff --git a/util/init.lua b/util/init.lua index 9462fab..f304c65 100644 --- a/util/init.lua +++ b/util/init.lua @@ -104,9 +104,11 @@ fs.makeDirectory("/etc/zorya-neo/mods") fs.makeDirectory("/etc/zorya-neo/lib") fs.makeDirectory("/etc/zorya-neo/config.d") fs.makeDirectory("/etc/zorya-neo/initramfs.d") +fs.makeDirectory("/etc/zorya-neo/vbios") print("Installing utils to /usr") fs.makeDirectory("/usr/bin") writefile("/usr/bin/zyneo-gencfg.lua", getfile("OpenOS/zyneo-gencfg.lua")) +writefile("/usr/bin/zyvbios-new.lua", getfile("OpenOS/zyvbios-new.lua")) writefile("/usr/bin/zyneo-geninitramfs.lua", getfile("OpenOS/zyneo-geninitramfs.lua")) writefile("/usr/bin/zyneo-update.lua", getfile("OpenOS/zyneo-update.lua")) print("Installing scripts...")