-- :Minify:-- local BOOT_DRIVE_PATH = ({...})[1] or "/$" ---@diagnostic disable-next-line: undefined-global local term = term local os = os local function write(text) local x, y = term.getCursorPos() local w, h = term.getSize() for i = 1, #text do local c = text:sub(i, i) if c == "\n" then y = y + 1 x = 1 elseif c == "\t" then local tabSize = 4 local spaces = tabSize - ((x - 1) % tabSize) term.write(string.rep(" ", spaces)) x = x + spaces elseif c == "\b" then if x > 1 then x = x - 1 term.setCursorPos(x, y) term.write(" ") term.setCursorPos(x, y) end else if x <= w and y <= h then term.setCursorPos(x, y) term.write(c) x = x + 1 end end if x > w then x = 1 y = y + 1 end if y - 1 >= h then term.scroll(1) y = h term.setCursorPos(x, y) end end term.setCursorPos(x, y) end local function displaySuperBadError(err) term.setBackgroundColor(0x1) term.setTextColor(0x4) term.clear() term.setCursorPos(1, 1) term.write("A critical error occurred while loading the system:") term.setCursorPos(1, 3) write(err) while true do end end term.setCursorBlink(false) local ok, err = xpcall(function() local apis = {BOOT_DRIVE_PATH = BOOT_DRIVE_PATH} local lua = { coroutine = true, debug = true, _VERSION = true, assert = true, collectgarbage = true, error = true, gcinfo = true, getfenv = true, getmetatable = true, ipairs = true, __inext = true, load = true, math = true, next = true, pairs = true, pcall = true, rawequal = true, rawget = true, rawlen = true, rawset = true, select = true, setfenv = true, setmetatable = true, string = true, table = true, tonumber = true, tostring = true, type = true, xpcall = true, _G = true } local debug = debug for i, v in pairs(_G) do if not lua[i] or lua[i] == nil then apis[i] = v _G[i] = nil end end local acekeys={ [apis.keys.enter]="\n", [apis.keys.tab]="\t", [apis.keys.backspace]="\b" } function sleep(time) local stoptime = apis.os.clock() + (time) while stoptime > apis.os.clock() do end end apis.term.setPaletteColor(0x1, 0xFFFFFF) -- #000000 apis.term.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF apis.term.setPaletteColor(0x4, 0x00FF00) -- #FF0000 apis.term.setPaletteColor(0x8, 0x0000FF) -- #00FF00 apis.term.setPaletteColor(0x10, 0x00FFFF) -- #0000FF apis.term.setPaletteColor(0x20, 0xFF00FF) -- #00FFFF apis.term.setPaletteColor(0x40, 0xFFFF00) -- #FF00FF apis.term.setPaletteColor(0x80, 0xFF6D00) -- #FFFF00 apis.term.setPaletteColor(0x100, 0x6DFF55) -- #FF6D00 apis.term.setPaletteColor(0x200, 0x24FFFF) -- #6DFF55 apis.term.setPaletteColor(0x400, 0x924900) -- #24FFFF apis.term.setPaletteColor(0x800, 0x6D6D55) -- #924900 apis.term.setPaletteColor(0x1000, 0xDBDBAA) -- #6D6D55 apis.term.setPaletteColor(0x2000, 0x6D00FF) -- #DBDBAA apis.term.setPaletteColor(0x4000, 0xB6FF00) -- #6D00FF apis.term.setPaletteColor(0x8000, 0x000000) -- #B6FF00 local function getFile(path) local file = apis.fs.open(path, "r") if not file then displaySuperBadError("Could not open file: " .. path) end local content = file.readAll() file.close() return content end local Kernel = load(getFile(BOOT_DRIVE_PATH .. "/boot/kernel.lua"),"@Kernel") local initFs = load(getFile(BOOT_DRIVE_PATH .. "/boot/cct/initdisks"),"@Init_disks")(apis) local fs = load(getFile(BOOT_DRIVE_PATH .. "/boot/initfs"), "@InitFs")() if not Kernel then displaySuperBadError("Could not load kernel.") end if not initFs then displaySuperBadError("Could not load initdisks.") end if not fs then displaySuperBadError("Could not load initfs.") end local eventQueue = {} local function queueEvent(event, ...) table.insert(eventQueue, {event, ...}) end local computer = { time = function() return apis.os.epoch("utc") end, clock = function() return apis.os.clock() * 1000 end, shutdown = apis.os.shutdown, reboot = apis.os.reboot, getMachineEvent = function() if #eventQueue > 0 then return table.unpack(table.remove(eventQueue, 1)) else return nil end end, getEEPROM = function() return getFile("/startup.lua") end, setEEPROM = function(_, text) local h = apis.fs.open("/startup.lua", "w") h.write(text) h.close() end } local icolors = { [0x1] = 1, -- #000000 [0x2] = 2, -- #FFFFFF [0x4] = 3, -- #FF0000 [0x8] = 4, -- #00FF00 [0x10] = 5, -- #0000FF [0x20] = 6, -- #00FFFF [0x40] = 7, -- #FF00FF [0x80] = 8, -- #FFFF00 [0x100] = 9, -- #FF6D00 [0x200] = 10, -- #6DFF55 [0x400] = 11, -- #24FFFF [0x800] = 12, -- #924900 [0x1000] = 13, -- #6D6D55 [0x2000] = 14, -- #DBDBAA [0x4000] = 15, -- #6D00FF [0x8000] = 16 -- #B6FF00 } local colors = { 0x0001, -- #000000 0x0002, -- #FFFFFF 0x0004, -- #FF0000 0x0008, -- #00FF00 0x0010, -- #0000FF 0x0020, -- #00FFFF 0x0040, -- #FF00FF 0x0080, -- #FFFF00 0x0100, -- #FF6D00 0x0200, -- #6DFF55 0x0400, -- #24FFFF 0x0800, -- #924900 0x1000, -- #6D6D55 0x2000, -- #DBDBAA 0x4000, -- #6D00FF 0x8000 -- #B6FF00 } apis.term.setBackgroundColor(0x8000) apis.term.setTextColor(0x1000) apis.term.clear() apis.term.setCursorPos(1, 1) local kernelCoro = coroutine.create(function() ---@diagnostic disable-next-line: param-type-mismatch local ok, err = xpcall(Kernel, debug.traceback, apis, initFs, "cct", "/sbin/init", { print = function(_, text) write(text .. "\n") end, printInline = function(_, text) write(text) end, clear = function() apis.term.clear() apis.term.setCursorPos(1, 1) end, setCursorPos = function(_, x, y) apis.term.setCursorPos(x, y) end, getCursorPos = function() return apis.term.getCursorPos() end, getSize = function() return apis.term.getSize() end, setBackgroundColor = function(_, color) apis.term.setBackgroundColor(colors[color]) end, setTextColor = function(_, color) apis.term.setTextColor(colors[color]) end, getBackgroundColor = function() return icolors[apis.term.getBackgroundColor()] end, getTextColor = function() return icolors[apis.term.getTextColor()] end }, computer, fs, "$") if not ok then displaySuperBadError(err) end end) -- time is in milliseconds function coroutine.resumeWithTimeout(co, timeout, ...) local startTime = computer.time() debug.sethook(co, function() if computer.time() > startTime + timeout then return coroutine.yield("timeout") end end, "", 1000) local ret = {coroutine.resume(co, ...)} if ret[1] and ret[2] == "timeout" then return "timeout" elseif ret[1] == false then return "error", ret[2] else debug.sethook(co) return "success", table.unpack(ret, 2) end end write("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n") while true do local status, err = coroutine.resumeWithTimeout(kernelCoro, 50) apis.os.queueEvent("NoSleep") local exit = false while not exit do local event = {coroutine.yield()} if event[1] == "key" then queueEvent("keyPressed", 1, event[2]) if acekeys[event[2]] then queueEvent("keyTyped", 1, acekeys[event[2]]) end elseif event[1] == "char" then queueEvent("keyTyped", 1, event[2]) elseif event[1] == "key_up" then queueEvent("keyReleased", 1, event[2]) elseif event[1] == "disk" then queueEvent("componentAdded", "disk") elseif event[1] == "disk_eject" then queueEvent("componentRemoved", "disk") elseif event[1] == "NoSleep" then exit = true end end if status == "error" or coroutine.status(kernelCoro) == "dead" then displaySuperBadError("Kernel error: " .. tostring(err)) coroutine.yield("key") end end end, debug.traceback) if not ok then displaySuperBadError("Fatal error during boot: " .. err) end while true do coroutine.yield() end