15 Commits
Author SHA1 Message Date
Astronand 211b7fc75b Merge pull request '1.2 dev' (#23) from 1.2-dev into main
Reviewed-on: #23
2026-08-24 09:16:38 -04:00
Astronand 4e7cec2ce1 Merge pull request 'testing update' (#22) from 1.2-dev into main
Reviewed-on: #22
2026-08-21 07:36:55 -04:00
Astronand 7ddc527e00 Merge pull request '1.2 dev' (#21) from 1.2-dev into main
Reviewed-on: #21
2026-08-15 22:41:41 -04:00
Astronand 3a33bd0264 Merge pull request 'fix spm files' (#20) from 1.2-dev into main
Reviewed-on: #20
2026-08-14 21:13:19 -04:00
Astronand 242762ab6b Merge pull request '1.2 dev' (#19) from 1.2-dev into main
Reviewed-on: #19
2026-08-14 20:47:25 -04:00
Astronand 8c18d89489 Merge pull request '1.2-dev' (#18) from 1.2-dev into main
Reviewed-on: #18
2026-03-21 01:12:24 -04:00
Astronand 041663e1e8 Merge pull request 'made newer installer that does not require tar stuff' (#17) from 1.2-dev into main
Reviewed-on: #17
2026-03-21 00:57:16 -04:00
Astronand fcac0ff8d8 Merge pull request 'made system use full salt+pepper' (#16) from 1.2-dev into main
Reviewed-on: #16
2026-03-19 14:11:24 -04:00
Astronand d98555328b Merge pull request '1.2-dev' (#15) from 1.2-dev into main
Reviewed-on: #15
2026-03-19 12:19:44 -04:00
Astronand 61cbb91db2 Merge branch '1.2-dev' 2026-03-19 11:28:56 -04:00
Astronand b79492dbb8 Merge branch 'main' of https://git.astronand.dev/Hyperion/HyperionOS 2026-03-19 11:28:29 -04:00
Astronand bc87c53427 Merge branch '1.2-dev' 2026-03-19 11:28:28 -04:00
Astronand 030e5bfd96 Update install/data/tarbad 2026-03-12 20:59:36 -04:00
Astronand 099638c735 Merge pull request 'update tar' (#12) from 1.2-dev into main
Reviewed-on: #12
2026-03-12 20:55:22 -04:00
Astronand 5172da1b5b Merge pull request '1.2-dev' (#11) from 1.2-dev into main
Reviewed-on: #11
2026-03-12 19:32:16 -04:00
153 changed files with 5536 additions and 3276 deletions

No files matched your search

+2 -2
View File
@@ -6,10 +6,10 @@
"printf",
"printInline",
"toHex",
"loadcstr",
"userinput"
],
"Lua.diagnostics.disable": [
"need-check-nil",
"param-type-mismatch"
"need-check-nil"
]
}
@@ -1,318 +0,0 @@
--:Minify:--
local kernel=...
if not kernel.cct then return end
local plt={
[0]=0x000000,0x0b0b0b,0x222222,0x444444,0x555555,0x777777,0x888888,0xaaaaaa,
0xbbbbbb,0xdddddd,0xeeeeee,0x00000b,0x000022,0x000044,0x000055,0x000077,
0x000088,0x0000aa,0x0000bb,0x0000dd,0x0000ee,0x000b00,0x002200,0x004400,
0x005500,0x007700,0x008800,0x00aa00,0x00bb00,0x00dd00,0x00ee00,0x0b0000,
0x220000,0x440000,0x550000,0x770000,0x880000,0xaa0000,0xbb0000,0xdd0000,
0xee0000,0x000033,0x000066,0x000099,0x0000cc,0x0000ff,0x003300,0x003333,
0x003366,0x003399,0x0033cc,0x0033ff,0x006600,0x006633,0x006666,0x006699,
0x0066cc,0x0066ff,0x009900,0x009933,0x009966,0x009999,0x0099cc,0x0099ff,
0x00cc00,0x00cc33,0x00cc66,0x00cc99,0x00cccc,0x00ccff,0x00ff00,0x00ff33,
0x00ff66,0x00ff99,0x00ffcc,0x00ffff,0x330000,0x330033,0x330066,0x330099,
0x3300cc,0x3300ff,0x333300,0x333333,0x333366,0x333399,0x3333cc,0x3333ff,
0x336600,0x336633,0x336666,0x336699,0x3366cc,0x3366ff,0x339900,0x339933,
0x339966,0x339999,0x3399cc,0x3399ff,0x33cc00,0x33cc33,0x33cc66,0x33cc99,
0x33cccc,0x33ccff,0x33ff00,0x33ff33,0x33ff66,0x33ff99,0x33ffcc,0x33ffff,
0x660000,0x660033,0x660066,0x660099,0x6600cc,0x6600ff,0x663300,0x663333,
0x663366,0x663399,0x6633cc,0x6633ff,0x666600,0x666633,0x666666,0x666699,
0x6666cc,0x6666ff,0x669900,0x669933,0x669966,0x669999,0x6699cc,0x6699ff,
0x66cc00,0x66cc33,0x66cc66,0x66cc99,0x66cccc,0x66ccff,0x66ff00,0x66ff33,
0x66ff66,0x66ff99,0x66ffcc,0x66ffff,0x990000,0x990033,0x990066,0x990099,
0x9900cc,0x9900ff,0x993300,0x993333,0x993366,0x993399,0x9933cc,0x9933ff,
0x996600,0x996633,0x996666,0x996699,0x9966cc,0x9966ff,0x999900,0x999933,
0x999966,0x999999,0x9999cc,0x9999ff,0x99cc00,0x99cc33,0x99cc66,0x99cc99,
0x99cccc,0x99ccff,0x99ff00,0x99ff33,0x99ff66,0x99ff99,0x99ffcc,0x99ffff,
0xcc0000,0xcc0033,0xcc0066,0xcc0099,0xcc00cc,0xcc00ff,0xcc3300,0xcc3333,
0xcc3366,0xcc3399,0xcc33cc,0xcc33ff,0xcc6600,0xcc6633,0xcc6666,0xcc6699,
0xcc66cc,0xcc66ff,0xcc9900,0xcc9933,0xcc9966,0xcc9999,0xcc99cc,0xcc99ff,
0xcccc00,0xcccc33,0xcccc66,0xcccc99,0xcccccc,0xccccff,0xccff00,0xccff33,
0xccff66,0xccff99,0xccffcc,0xccffff,0xff0000,0xff0033,0xff0066,0xff0099,
0xff00cc,0xff00ff,0xff3300,0xff3333,0xff3366,0xff3399,0xff33cc,0xff33ff,
0xff6600,0xff6633,0xff6666,0xff6699,0xff66cc,0xff66ff,0xff9900,0xff9933,
0xff9966,0xff9999,0xff99cc,0xff99ff,0xffcc00,0xffcc33,0xffcc66,0xffcc99,
0xffcccc,0xffccff,0xffff00,0xffff33,0xffff66,0xffff99,0xffffcc,0xffffff,
}
local iplt={}
for i=0, #plt do
iplt[plt[i]]=i
end
local l1f,l1d,l2,ops={},{},{},0
local function findClosest(tbl, target)
local closest = nil
local smallestDiff = math.huge
for k, _ in pairs(tbl) do
if k==target then return k end
local diff = math.abs(k - target)
if diff < smallestDiff then
smallestDiff = diff
closest = k
end
end
return closest
end
local function aprox(c24)
ops = ops + 1
if ops % 1024 == 0 then
l1d = {}
l1f = {}
end
if ops % 8192 == 0 then
l2 = {}
end
if l2[c24] ~= nil then
return l2[c24]
end
if l1d[c24] ~= nil then
l1f[c24] = l1f[c24] + 1
if l1f[c24] >= 16 then
l2[c24] = l1d[c24]
l1d[c24] = nil
l1f[c24] = nil
return l2[c24]
end
return l1d[c24]
end
local closestKey = findClosest(iplt, c24)
if not closestKey then return nil end
local value = iplt[closestKey]
l1d[c24] = value
l1f[c24] = 1
return value
end
local function splitFramebufferToStrings(fb, w)
local rows = {}
for i = 1, #fb, w do
local row_chars = {}
for j = 0, w - 1 do
local val = fb[i + j]
if val ~= nil then
table.insert(row_chars, string.char(aprox(val)))
else
break
end
end
table.insert(rows, table.concat(row_chars))
end
return rows
end
local function creategfx(term, id)
local active=false
term.setGraphicsMode(2)
for i=0, #plt do
term.setPaletteColor(i,plt[i])
end
term.setGraphicsMode(false)
term.setPaletteColor(0x1, 0xFFFFFF)
term.setPaletteColor(0x2, 0xFF0000)
term.setPaletteColor(0x4, 0x00FF00)
term.setPaletteColor(0x8, 0x0000FF)
term.setPaletteColor(0x10, 0x00FFFF)
term.setPaletteColor(0x20, 0xFF00FF)
term.setPaletteColor(0x40, 0xFFFF00)
term.setPaletteColor(0x80, 0xFF6D00)
term.setPaletteColor(0x100, 0x6DFF55)
term.setPaletteColor(0x200, 0x24FFFF)
term.setPaletteColor(0x400, 0x924900)
term.setPaletteColor(0x800, 0x6D6D55)
term.setPaletteColor(0x1000, 0xDBDBAA)
term.setPaletteColor(0x2000, 0x6D00FF)
term.setPaletteColor(0x4000, 0xB6FF00)
term.setPaletteColor(0x8000, 0x000000)
local handle={
gplt=function()
return setmetatable({},{__index=plt,__usermeta=false,__pairs=function() return pairs(plt) end})
end,
spixel=function(x,y,c)
term.setPixel(x,y,aprox(c))
end,
gpixel=function(x,y)
return term.getPixel()
end,
drawFB=function(x,y,fb,w)
local f=splitFramebufferToStrings(fb,w)
term.drawPixels(x,y,f)
end,
box=function(x,y,w,h,c,fill)
c=aprox(c)
if not fill then
term.drawPixels(x,y,c,w,1)
term.drawPixels(x,y,c,1,h)
term.drawPixels(x+w-1,y,c,1,h)
term.drawPixels(x,y+h-1,c,w,1)
else
term.drawPixels(x,y,c,w,h)
end
end,
circle=function(xc,yc,r,c,fill)
c=aprox(c)
if not fill then
local x = 0
local y = r
local d = 3 - 2 * r
-- Helper function to plot all 8 symmetric points
local function plot8Points(x, y)
term.setPixel(xc + x, yc + y, c)
term.setPixel(xc - x, yc + y, c)
term.setPixel(xc + x, yc - y, c)
term.setPixel(xc - x, yc - y, c)
term.setPixel(xc + y, yc + x, c)
term.setPixel(xc - y, yc + x, c)
term.setPixel(xc + y, yc - x, c)
term.setPixel(xc - y, yc - x, c)
end
plot8Points(x, y)
while y >= x do
x = x + 1
if d > 0 then
y = y - 1
d = d + 4 * (x - y) + 10
else
d = d + 4 * x + 6
end
plot8Points(x, y)
end
else
local x = 0
local y = r
local d = 3 - 2 * r
-- Helper to fill rows using symmetry
local function fillRows(x, y)
-- Width is (2 * coordinate) + 1 to include the center column
local strX = string.rep(string.char(c), 2 * x + 1)
local strY = string.rep(string.char(c), 2 * y + 1)
-- Draw the horizontal spans
term.drawPixels(xc - x, yc + y, {strX})
term.drawPixels(xc - x, yc - y, {strX})
term.drawPixels(xc - y, yc + x, {strY})
term.drawPixels(xc - y, yc - x, {strY})
end
fillRows(x, y)
while y >= x do
x = x + 1
if d > 0 then
y = y - 1
d = d + 4 * (x - y) + 10
else
d = d + 4 * x + 6
end
fillRows(x, y)
end
end
end,
line=function(x1,y1,x2,y2,c)
x1=math.floor(x1+0.5)
y1=math.floor(y1+0.5)
x2=math.floor(x2+0.5)
y2=math.floor(y2+0.5)
c=aprox(c)
local w,h=term.getSize(2)
local dx=math.abs(x2-x1)
local dy=math.abs(y2-y1)
local sx=x1<x2 and 1 or -1
local sy=y1<y2 and 1 or -1
local err=dx-dy
while true do
if 0<x1 and x1<=w and 0<y1 and y1<=h then
term.setPixel(x1,y1,c)
end
if x1==x2 and y1==y2 then
break
end
local e2=2*err
if e2>-dy then
err=err-dy
x1=x1+sx
end
if e2<dx then
err=err+dx
y1=y1+sy
end
end
end,
setMode=function(state)
if state then
term.setGraphicsMode(2)
for i=0, #plt do
term.setPaletteColor(i,plt[i])
end
active=true
else
term.setGraphicsMode(false)
term.setPaletteColor(0x1, 0xFFFFFF)
term.setPaletteColor(0x2, 0xFF0000)
term.setPaletteColor(0x4, 0x00FF00)
term.setPaletteColor(0x8, 0x0000FF)
term.setPaletteColor(0x10, 0x00FFFF)
term.setPaletteColor(0x20, 0xFF00FF)
term.setPaletteColor(0x40, 0xFFFF00)
term.setPaletteColor(0x80, 0xFF6D00)
term.setPaletteColor(0x100, 0x6DFF55)
term.setPaletteColor(0x200, 0x24FFFF)
term.setPaletteColor(0x400, 0x924900)
term.setPaletteColor(0x800, 0x6D6D55)
term.setPaletteColor(0x1000, 0xDBDBAA)
term.setPaletteColor(0x2000, 0x6D00FF)
term.setPaletteColor(0x4000, 0xB6FF00)
term.setPaletteColor(0x8000, 0x000000)
active=false
end
end,
getMode=function()
return active
end,
size=function()
return term.getSize(2)
end,
drawRun=function(y,x1,x2,c)
term.drawPixels(x1,y,c,{string.rep(string.char(aprox(c)),x1-x2)})
end
}
return handle
end
for id,obj in pairs(kernel.cct.term) do
if obj.setGraphicsMode then
kernel.cct.gfx[id]=creategfx(obj, id)
end
end
+344 -3
View File
@@ -1,3 +1,344 @@
---@diagnostic disable-next-line: undefined-global
local bootdrive=__UEFI.bootDrive
--:Minify:--
local args={...}
local bootdrive=args[1]
local gpu=components:getFirst("gpu")
local screenTextBuffer=nil
local cursorX,cursorY=0,0
local screenSizeX,screenSizeY=128,25
if gpu then
screenTextBuffer=gpu:newBuffer(screenSizeX,screenSizeY)
for t,v in components:list() do
if t == "screen" then
gpu:assignBuffer(screenTextBuffer, v)
end
end
end
local function write(text)
cursorX, cursorY = screenTextBuffer:pasteText(cursorX, cursorY, "SCROLL_SPILL_CLEAR", text)
cursorY = cursorY + 1
cursorX = 0
if cursorY >= screenSizeY then
cursorY = screenSizeY-1
screenTextBuffer:newline()
end
end
local function displaySuperBadError(err)
gpu:freeAllBuffers()
screenTextBuffer=gpu:newBuffer(screenSizeX,screenSizeY)
for t,v in components:list() do
if t == "screen" then
gpu:assignBuffer(screenTextBuffer, v)
end
end
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
local ok, err = xpcall(function()
local apis = {}
local lua = {
coroutine = true,
debug = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = 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,
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 function string_file(file)
local str = file:read()
local buf = {str or ""}
local pos = 1
local closed = false
local function content()
return table.concat(buf)
end
local function set_content(s)
buf = {s}
end
local function flush()
file.write(content())
end
local file = {}
function file.read(n)
assert(not closed, "file is closed")
local s = content()
local len = #s
if not n then
local out = s:sub(pos)
pos = len + 1
return out
end
local out = s:sub(pos, pos + n - 1)
pos = pos + #out
return out
end
function file.write(data)
assert(not closed, "file is closed")
local s = content()
local before = s:sub(1, pos - 1)
local after = s:sub(pos + #data)
set_content(before .. data .. after)
pos = pos + #data
return true
end
function file.seek(whence, offset)
assert(not closed, "file is closed")
local s = content()
local len = #s
whence = whence or "cur"
offset = offset or 0
if whence == "set" then
pos = offset + 1
elseif whence == "cur" then
pos = pos + offset
elseif whence == "end" then
pos = len + offset + 1
else
error("invalid whence")
end
if pos < 1 then pos = 1 end
if pos > len + 1 then pos = len + 1 end
return pos - 1
end
function file:close()
assert(not closed, "file is closed")
flush()
closed = true
end
function file:flush()
assert(not closed, "file is closed")
flush()
end
return file
end
local function getFile(path)
local file = bootdrive:open(path, "r")
if not file then
displaySuperBadError("Could not open file: " .. path)
end
local content = file:read()
return content
end
local Kernel = load(getFile("/boot/kernel.lua"),"@Kernel")
local initFs = load(getFile("/boot/ac/initdisks"),"@Init_disks")(apis)
local fs = load(getFile("/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 computercomp=apis.components:getFirst("computer")
local uefi=apis.components:getFirst("uefi")
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()
return computercomp:getMachineEvent()
end,
getEEPROM = function() return uefi.data end,
setEEPROM = function(_, text)
uefi.data=text
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)
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] == "modem_message" then
queueEvent("modem_message", table.unpack(event, 2))
elseif event[1] == "rednet_message" then
queueEvent("rednet_message", table.unpack(event, 2))
elseif event[1] == "http_success" then
queueEvent("http_success", table.unpack(event, 2))
elseif event[1] == "http_failure" then
queueEvent("http_failure", table.unpack(event, 2))
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
@@ -1,146 +0,0 @@
local comp,disks,autocomplete,ev,ent,data,path,exit,dirty,ls,eb,sb,bp=components,{},false,nil,true,"","",false,true,{},false
local c,gpu=comp:getFirst("computer"),comp:getFirst("gpu")
if gpu then sb=gpu:newBuffer(48,32) end
--c.nvram.data="1/ac/boot.lua"
local function resetScreens()
sb=gpu:newBuffer(64,48)
for typ, obj in comp:list() do
if typ=="screen" then gpu:assignBuffer(sb,obj) end
end
end
resetScreens()
local function displayError(err)
if not gpu then return end
gpu:freeAllBuffers()
resetScreens()
sb:pasteText(0,0,"FILL_SPILL",err)
end
local function bootloader()
for typ, obj in comp:list() do
if typ~="massStorage" then goto skip end
disks[tostring(obj.diskId)]=obj
::skip::
end
local function display(text)
print(text)
if not sb then print("NO_SB") return end
sb:pasteText(0,0,"FILL_SPILL",text)
end
local function boot()
local pos = path:find("/", 1, true)
if not pos then displayError("EINVAL") sleep(5) return end
local id,p = path:sub(1,pos-1),path:sub(pos)
if not disks[id] then displayError("ENODEV") sleep(5) return end
local init,err=load(disks[id]:open(p):read(-1),"@init","t",_G)
if err then displayError(err) sleep(5) return end
local ret = {xpcall(init, debug.traceback)}
if not ret[1] then
displayError("EFI PROGRAM ERROR: "..err)
sleep(5)
return false
else
if ret[2]=="ENTER_BIOS" then
c.nvram.ENTER_BIOS=true
return true
end
return table.unpack(ret, 2)
end
end
if c.nvram then
path=c.nvram.data or ""
eb=c.nvram.ENTER_BIOS
c.nvram.ENTER_BIOS=false
end
local function drainev()
repeat
ev={c:getMachineEvent()}
if ev[1]=="charTyped" then ent=false end
until not ev[1]
end
if path=="" or eb then drainev() ent=false else
display("Press key to enter boot menu...")
sleep(3)
drainev()
if ent then return boot() end
end
local function proc(key)
if key=="\n" then exit=true
elseif key=="\b" then path=path:sub(1,#path-1) dirty=true
elseif key=="\t" then print("autocomplete")
else path=path..key dirty=true end
end
local function get()
data=""
local pos = path:find("/", 1, true)
local trailingslash=false
if path:sub(#path)=="/" then trailingslash=true end
if not pos then
for id in pairs(disks) do
if id:sub(1,#path)==path then
data=data..id.."\n"
end
end
else
if not trailingslash then
local n=""
for i=#path, 0, -1 do
if path:sub(i,i)~="/" then
n=path:sub(i,i)..n
else break end
end
local ok,ret=pcall(function()
return disks[path:sub(1,pos-1)]:list(path:sub(pos,#path-#n))
end)
if ok then
ls = ret
end
for _,p in ipairs(ls) do
if p:sub(1,#n) == n then
data=data..p.."\n"
end
end
else
local ok,ret=pcall(function()
return disks[path:sub(1,pos-1)]:list(path:sub(pos))
end)
if ok then
ls=ret
for _,p in ipairs(ls) do
data=data..p.."\n"
end
end
end
end
end
if not ent then
while true do
get()
if dirty then
for i=0,31 do sb:clearRow(i) end
display("Select boot file...\n"..path.."\n\n"..data)
dirty=false
end
ev={c:getMachineEvent()}
if ev[1]=="charTyped" then proc(ev[2]) end
if exit then return boot() end
end
end
end
local ret={xpcall(bootloader,debug.traceback)}
if not ret[1] then
displayError(ret[2])
error(ret[2])
else
return table.unpack(ret, 2)
end
@@ -1,136 +0,0 @@
local args = {...}
local apis = args[1]
local bootdrive = args[2]
local bootaddr = args[3]
local disks = {}
local internal = {}
local function createDisk(id, hw)
local disk = {
address = id,
isReadOnly = function() return hw.isReadOnly() end
}
function disk:spaceUsed() return hw.spaceUsed() end
function disk:spaceTotal() return hw.spaceTotal() end
function disk:list(path)
if not hw.exists(path) or not hw.isDirectory(path) then
return nil, "not directory"
end
return hw.list(path)
end
function disk:fileExists(path)
return hw.exists(path) and not hw.isDirectory(path)
end
function disk:directoryExists(path)
return hw.exists(path) and hw.isDirectory(path)
end
function disk:type(path)
if not hw.exists(path) then
return nil
elseif hw.isDirectory(path) then
return "directory"
else
return "file"
end
end
function disk:makeDirectory(path)
hw.makeDirectory(path)
end
function disk:remove(path)
if hw.exists(path) then hw.remove(path) end
end
function disk:setLabel(label) hw.setLabel(label) end
function disk:getLabel() return hw.getLabel() end
function disk:attributes(path)
return {
size = hw.size(path),
isDir = hw.isDirectory(path),
isReadOnly = hw.isReadOnly(),
modified = hw.lastModified(path),
created = hw.lastModified(path)
}
end
function disk:open(path, mode)
local fd = hw.open(path, mode)
if not fd then
local dir = path:match("^(.*)/[^/]+$")
if dir and not hw.exists(dir) then
local ok, err = hw.makeDirectory(dir)
if not ok then
return nil, err or "could not create parent directory"
end
end
fd = hw.open(path, mode)
if not fd then
return nil, "file not found or access denied"
end
end
return {
read = function(num) return hw.read(fd, num) end,
readAll = function()
local data = {}
while true do
local chunk = hw.read(fd, math.huge)
if not chunk then break end
data[#data + 1] = chunk
end
return table.concat(data)
end,
write = function(data) return hw.write(fd, data) end,
seek = function(whence, offset)
return hw.seek(fd, whence, offset)
end,
flush = function()
hw.close(fd)
fd = hw.open(path, mode)
end,
close = function()
hw.close(fd)
fd = nil
end
}
end
return disk
end
internal["$"] = createDisk("$", bootdrive)
local function refresh()
disks = {}
for addr in apis.component.list("filesystem") do
if addr ~= bootaddr then
disks[addr] = createDisk(addr, apis.component.proxy(addr))
end
end
end
local function iter()
refresh()
local combined = {}
for id, obj in pairs(internal) do combined[id] = obj end
for id, obj in pairs(disks) do combined[id] = obj end
return pairs(combined)
end
return {refresh = refresh, list = iter}
@@ -1,15 +0,0 @@
--:Minify:--
local kernel=...
kernel.oc={}
kernel.oc.component=kernel.apis.component
kernel.oc.computer=kernel.apis.computer
kernel.log("Installed components:")
for addr, typ in kernel.oc.component.list() do
local dev=kernel.oc.component.proxy(addr)
local tier=""
if dev.getTier then
tier=dev.getTier()
end
kernel.log(" "..addr.." : "..typ..tier)
end
@@ -1,23 +0,0 @@
--:Minify:--
local kernel=...
local component=kernel.oc.component
local function wrap(p)
return function(op, mode)
if op=="type" then
return "device"
elseif op=="open" then
if kernel.uid~=0 then error("EACCES") end
return component.proxy(p)
end
end
end
for addr, typ in kernel.oc.component.list() do
local obj=wrap(addr)
kernel.devfs.data["raw"][addr]=obj
local typefolder=kernel.devfs.data["raw"]["by-type"][typ]
if not typefolder then typefolder={} end
typefolder[tostring(#table.keys(typefolder)+1)] = obj
kernel.devfs.data["raw"]["by-type"][typ]=typefolder
end
@@ -1,177 +0,0 @@
-- OpenComputers TTY driver
local kernel = ...
local component = kernel.oc.component
local computer = kernel.oc.computer
local plt = {
0x000000, 0x000040, 0x000080, 0x0000C0, 0x0000FF,
0x002400, 0x002440, 0x002480, 0x0024C0, 0x0024FF,
0x004900, 0x004940, 0x004980, 0x0049C0, 0x0049FF,
0x006D00, 0x006D40, 0x006D80, 0x006DC0, 0x006DFF,
0x009200, 0x009240, 0x009280, 0x0092C0, 0x0092FF,
0x00B600, 0x00B640, 0x00B680, 0x00B6C0, 0x00B6FF,
0x00DB00, 0x00DB40, 0x00DB80, 0x00DBC0, 0x00DBFF,
0x00FF00, 0x00FF40, 0x00FF80, 0x00FFC0, 0x00FFFF,
0x330000, 0x330040, 0x330080, 0x3300C0, 0x3300FF,
0x332400, 0x332440, 0x332480, 0x3324C0, 0x3324FF,
0x334900, 0x334940, 0x334980, 0x3349C0, 0x3349FF,
0x336D00, 0x336D40, 0x336D80, 0x336DC0, 0x336DFF,
0x339200, 0x339240, 0x339280, 0x3392C0, 0x3392FF,
0x33B600, 0x33B640, 0x33B680, 0x33B6C0, 0x33B6FF,
0x33DB00, 0x33DB40, 0x33DB80, 0x33DBC0, 0x33DBFF,
0x33FF00, 0x33FF40, 0x33FF80, 0x33FFC0, 0x33FFFF,
0x660000, 0x660040, 0x660080, 0x6600C0, 0x6600FF,
0x662400, 0x662440, 0x662480, 0x6624C0, 0x6624FF,
0x664900, 0x664940, 0x664980, 0x6649C0, 0x6649FF,
0x666D00, 0x666D40, 0x666D80, 0x666DC0, 0x666DFF,
0x669200, 0x669240, 0x669280, 0x6692C0, 0x6692FF,
0x66B600, 0x66B640, 0x66B680, 0x66B6C0, 0x66B6FF,
0x66DB00, 0x66DB40, 0x66DB80, 0x66DBC0, 0x66DBFF,
0x66FF00, 0x66FF40, 0x66FF80, 0x66FFC0, 0x66FFFF,
0x990000, 0x990040, 0x990080, 0x9900C0, 0x9900FF,
0x992400, 0x992440, 0x992480, 0x9924C0, 0x9924FF,
0x994900, 0x994940, 0x994980, 0x9949C0, 0x9949FF,
0x996D00, 0x996D40, 0x996D80, 0x996DC0, 0x996DFF,
0x999200, 0x999240, 0x999280, 0x9992C0, 0x9992FF,
0x99B600, 0x99B640, 0x99B680, 0x99B6C0, 0x99B6FF,
0x99DB00, 0x99DB40, 0x99DB80, 0x99DBC0, 0x99DBFF,
0x99FF00, 0x99FF40, 0x99FF80, 0x99FFC0, 0x99FFFF,
0xCC0000, 0xCC0040, 0xCC0080, 0xCC00C0, 0xCC00FF,
0xCC2400, 0xCC2440, 0xCC2480, 0xCC24C0, 0xCC24FF,
0xCC4900, 0xCC4940, 0xCC4980, 0xCC49C0, 0xCC49FF,
0xCC6D00, 0xCC6D40, 0xCC6D80, 0xCC6DC0, 0xCC6DFF,
0xCC9200, 0xCC9240, 0xCC9280, 0xCC92C0, 0xCC92FF,
0xCCB600, 0xCCB640, 0xCCB680, 0xCCB6C0, 0xCCB6FF,
0xCCDB00, 0xCCDB40, 0xCCDB80, 0xCCDBC0, 0xCCDBFF,
0xCCFF00, 0xCCFF40, 0xCCFF80, 0xCCFFC0, 0xCCFFFF,
0xFF0000, 0xFF0040, 0xFF0080, 0xFF00C0, 0xFF00FF,
0xFF2400, 0xFF2440, 0xFF2480, 0xFF24C0, 0xFF24FF,
0xFF4900, 0xFF4940, 0xFF4980, 0xFF49C0, 0xFF49FF,
0xFF6D00, 0xFF6D40, 0xFF6D80, 0xFF6DC0, 0xFF6DFF,
0xFF9200, 0xFF9240, 0xFF9280, 0xFF92C0, 0xFF92FF,
0xFFB600, 0xFFB640, 0xFFB680, 0xFFB6C0, 0xFFB6FF,
0xFFDB00, 0xFFDB40, 0xFFDB80, 0xFFDBC0, 0xFFDBFF,
0xFFFF00, 0xFFFF40, 0xFFFF80, 0xFFFFC0, 0xFFFFFF,
0x000000, 0x0F0F0F, 0x1E1E1E, 0x2D2D2D,
0x3C3C3C, 0x4B4B4B, 0x5A5A5A, 0x696969,
0x787878, 0x878787, 0x969696, 0xA5A5A5,
0xB4B4B4, 0xC3C3C3, 0xD2D2D2, 0xE1E1E1
}
local gpus,screens = {},{}
for addr, typ in component.list("gpu") do
if typ == "gpu" then
gpus[#gpus+1]=component.proxy(addr)
end
end
if #gpus>0 then
for addr, typ in component.list("screen") do
if typ == "screen" then
gpus[1].bind(addr)
local w,h = gpus[1].maxResolution()
gpus[1].setResolution(w,h)
screens[addr]={cx=1,cy=1,w=w,h=h,addr=addr,fg=0,bg=0,gpu=nil}
end
end
end
local scrnum = 0
for i,v in pairs(screens) do
scrnum=scrnum+1
end
kernel.log("initialized "..tostring(#gpus).." gpus and "..tostring(scrnum).." screens")
local binds,newid={},0
local curaddr=""
local function scroll(scr, gpu) gpu.copy(1,2,scr.w,scr.h-1,0,-1);gpu.fill(1,scr.h,scr.w,1," ") end
local function write(text, addr)
local g=gpus[1]
local scr=screens[addr]
if not scr then error("NODEV") end
if curaddr~=addr then g.bind(addr); g.setForeground(scr.fg); g.setBackground(scr.bg) end
for i=1,#text do
local char=text:sub(i,i)
if char=="\n" then scr.cx=1;scr.cy=scr.cy+1
elseif char=="\t" then scr.cx=scr.cx+(4-((scr.cx-1)%4))
elseif char=="\b" then if scr.cx>1 then scr.cx=scr.cx-1;g.set(scr.cx,scr.cy," ") end
else g.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
if scr.cy>scr.h then scroll(scr, g);scr.cy=scr.cy-1 end
end
end
local function newtty(addr)
newid=newid+1
kernel.devfs.data["tty"][tostring(newid)]=function(op, mode)
if op=="type" then
return "Terminal"
elseif op=="open" then
local h = {
read=function(amount) end,
write=function(content)
write(content, addr)
end,
size=function()
return screens[addr].w, screens[addr].h
end,
clear=function()
local g=gpus[1]
local scr=screens[addr]
if addr~=curaddr then g.bind(addr) end
g.fill(1,1,scr.w,scr.h," ");
scr.cx,scr.cy=1,1
end,
gpos=function()
return screens[addr].cx, screens[addr].cy
end,
spos=function(x,y)
if not tonumber(x) or not tonumber(y) then error("Invailid arg") end
screens[addr].cx, screens[addr].cy = x,y
end,
sfgc=function(c)
screens[addr].fg=c
end,
sbgc=function(c)
screens[addr].bg=c
end,
gfgc=function()
return screens[addr].fg
end,
gbgc=function()
return screens[addr].bg
end,
isvirt=function()
return false
end,
gplt=function()
return plt
end
}
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
end
if #gpus>=1 and scrnum>=1 then
for addr,obj in pairs(screens) do
newtty(addr)
end
end
@@ -1,113 +0,0 @@
--:Minify:--
local kernel=...
kernel.oc.keyboards={}
local kbs=kernel.oc.keyboards
local kbidx=0
local keyboard = {}
keyboard.keys = {
back = 0x0E, -- backspace
delete = 0xD3,
down = 0xD0,
enter = 0x1C,
home = 0xC7,
lcontrol = 0x1D,
left = 0xCB,
lmenu = 0x38, -- left Alt
lshift = 0x2A,
pageDown = 0xD1,
rcontrol = 0x9D,
right = 0xCD,
rmenu = 0xB8, -- right Alt
rshift = 0x36,
space = 0x39,
tab = 0x0F,
up = 0xC8,
["end"] = 0xCF,
numpadenter = 0x9C,
}
kernel.oc.keys=keyboard.keys
for i=0, 255 do
kernel.oc.keys[string.char(i)]=i
end
-------------------------------------------------------------------------------
function keyboard.isAltDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lmenu] or kbs[addr].pressedCodes[keyboard.keys.rmenu]
end
function keyboard.isControl(char)
return type(char) == "number" and (char < 0x20 or (char >= 0x7F and char <= 0x9F))
end
function keyboard.isControlDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lcontrol] or kbs[addr].pressedCodes[keyboard.keys.rcontrol]
end
function keyboard.isKeyDown(addr,charOrCode)
if type(charOrCode) == "string" then
return kbs[addr].pressedChars[utf8 and utf8.codepoint(charOrCode) or charOrCode:byte()]
elseif type(charOrCode) == "number" then
return kbs[addr].pressedCodes[charOrCode]
end
end
function keyboard.isShiftDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lshift] or kbs[addr].pressedCodes[keyboard.keys.rshift]
end
kernel.oc.keyboard=keyboard
local function serializeBool(bool)
if bool then
return "T"
else
return "F"
end
end
for addr, typ in kernel.oc.component.list("keyboard") do
if typ=="keyboard" then
kbidx=kbidx+1
kbs[addr]={pressedChars = {}, pressedCodes = {}, events=kernel.newFifo()}
kernel.devfs.data["input"]["keyboard"..tostring(kbidx)]=function(op,mode)
if op=="type" then
return "Keyboard"
elseif op=="open" then
local h = {
read=function(amount)
local rv=""
for i=1, amount or 1 do
local event = {kernel.oc.keyboards[addr].events.pop()}
if event[1] then
rv=rv..event[1]
end
end
if rv=="" then rv=nil end
return rv
end,
write=function(content)
end,
gctrl=function()
return serializeBool(keyboard.isControlDown(addr))..";"..serializeBool(keyboard.isAltDown(addr))
end,
isKeyDown=function(char)
return keyboard.isKeyDown(addr,char)
end
}
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
end
end
@@ -1,99 +0,0 @@
--:Minify:--
local kernel=...
local keys=kernel.oc.keys
kernel.processes.ocdaemon = function()
local timeout = false
kernel.log("OC daemon started")
local ctrlKeyMap = {
[keys.a]=1, [keys.b]=2, [keys.c]=3,
[keys.d]=4, [keys.e]=5, [keys.f]=6,
[keys.g]=7, [keys.h]=8, [keys.i]=9,
[keys.j]=10, [keys.k]=11, [keys.l]=12,
[keys.m]=13, [keys.n]=14, [keys.o]=15,
[keys.p]=16, [keys.q]=17, [keys.r]=18,
[keys.s]=19, [keys.t]=20, [keys.u]=21,
[keys.v]=22, [keys.w]=23, [keys.x]=24,
[keys.y]=25, [keys.z]=26,
}
local specialKeyMap = {
[keys.up] = "\27[A",
[keys.down] = "\27[B",
[keys.right] = "\27[C",
[keys.left] = "\27[D",
[keys.home] = "\27[H",
[keys["end"]] = "\27[F",
--[keys.pageUp] = "\27[5~",
--[keys.pageDown] = "\27[6~",
[keys.delete] = "\27[3~",
[keys.enter] = "\n",
[keys.back] = "\b",
[keys.tab] = "\t",
}
while true do
local event = {kernel.EFI.getMachineEvent()}
if event[1] then
local eventType = event[1]
local addr = event[2]
local char = event[3]
local keyCode = event[4]
if eventType == "key_down" then
local keyboard = kernel.oc.keyboards[addr]
if keyboard.ctrl then
local ctrlByte = ctrlKeyMap[keyCode]
if ctrlByte then
if ctrlByte == 3 then
for _, task in ipairs(syscall.getTasks()) do
syscall.sigsend(task, 1)
end
else
keyboard.events.push(string.char(ctrlByte))
end
end
else
local special = specialKeyMap[keyCode]
if special then
keyboard.events.push(special)
elseif char and char > 0 then
keyboard.events.push(kernel.apis.unicode.char(char))
end
end
elseif eventType == "key_up" then
end
timeout = false
else
timeout = true
end
if timeout then
sleep(0.05)
end
end
end
kernel.log("OC daemon queued for execution")
@@ -1,146 +0,0 @@
--:Minify:--
local kernel=...
local alpha = 0.85
local C_target = 0.01
local Tmin = 0.0005
local Tmax = 0.5
local lambda_budget = 0.08
local lambda_clamp = 0.03
local lambda_var = 0.02
local k_min = 0.5
local k_max = 0.5
local B = 0.01
function kernel.main()
kernel.log("Starting main loop...")
kernel.saveLog()
local stopLog=5
local logTasks=100
while not kernel.exitMain do
if kernel.config.logTasks then
if logTasks<0 then
kernel.log("Active Tasks:")
for i,v in pairs(kernel.tasks) do
kernel.log(v.name.." : "..v.status.." : "..tostring(v.pid).." : "..tostring(v.exit))
end
kernel.log("[END BLOCK]")
logTasks=100
end
logTasks=logTasks-1
end
local N = 0
local Tmin_hit = 0
local Tmax_hit = 0
local totalTaskTime = 0
local taskTimes = {}
for pid, task in pairs(kernel.tasks) do
if kernel.exitMain then break end
for _,list in ipairs(kernel.perTaskHooks) do
for id,hook in ipairs(list) do
local ok,err = xpcall(hook, debug.traceback, task, pid)
if not ok then
kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000)
list[id]=nil
end
end
end
if task.status == "R" then
N = N + 1
task.timeSlice = math.min(Tmax, math.max(Tmin, B / (N ^ alpha)))
if task.status == "R" then
local startTime = kernel.EFI:getEpochMs()
local ret
if stopLog > 0 then
kernel.log("Running task " .. tostring(task.pid) .. " (" .. task.name .. ") with time slice " .. string.format("%.3f", task.timeSlice) .. "s", "DBUG", 0x00FFFF)
end
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
local elapsed = kernel.EFI:getEpochMs() - startTime
task.lastTime = elapsed
task.totalTime = (task.totalTime or 0) + elapsed
task.numRuns = (task.numRuns or 0) + 1
taskTimes[#taskTimes+1] = elapsed
totalTaskTime = totalTaskTime + elapsed
if elapsed <= Tmin then Tmin_hit = Tmin_hit + 1 end
if elapsed >= Tmax then Tmax_hit = Tmax_hit + 1 end
if ret[1] == "error" or ret[1] == false then
kernel.log("processHandlerException: " .. tostring(ret[2]), "ERROR", 0xFF0000)
task.status = "Z"
task.exit = "processHandlerException: " .. tostring(ret[2])
elseif ret[1] == "timeout" then
task.ivs = task.ivs + 1
task.syscallReturn = {}
elseif ret[1] == "success" or ret[1] == true then
task.vs = task.vs + 1
if ret[2] == "syscall" then
local scname = ret[3]
if kernel.syscalls[scname] then
if kernel.config.debugSyscalls then
kernel.log("Task " .. task.pid .. " syscall: " .. scname, "DBUG", 0x00FFFF)
for i = 4, #ret do
kernel.log(" inval[" .. (i-3) .. "] = " .. tostring(ret[i]), "DBUG", 0x00FFFF)
end
end
local sysret = { xpcall(kernel.syscalls[scname], debug.traceback, table.unpack(ret, 4)) }
if kernel.config.debugSyscalls then
if not sysret[1] then
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " failed: " .. tostring(sysret[2]), "ERROR", 0xFF0000)
else
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " ok, " .. (#sysret-1) .. " retvals", "DBUG", 0x00FFFF)
for i = 2, #sysret do
local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i])
kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF)
end
end
end
if not sysret[1] then
task.syscallReturn = { false, sysret[2] }
else
task.syscallReturn = { true, table.unpack(sysret, 2) }
end
else
task.syscallReturn = { false, "Unknown syscall: " .. tostring(scname) }
end
end
end
end
end
kernel.EFI:yield()
end
local T_prev_avg = (N > 0) and (totalTaskTime / N) or 0
local T_prev_var = 0
for _, t in ipairs(taskTimes) do
T_prev_var = T_prev_var + (t - T_prev_avg) ^ 2
end
if N > 0 then T_prev_var = T_prev_var / N end
if N > 0 then
local f_clamp = k_min * (Tmin_hit / N) - k_max * (Tmax_hit / N)
local B_budget = (C_target * (N ^ (alpha - 1))) / math.max(T_prev_avg, 1e-8)
B = B + lambda_budget * (B_budget - B) + lambda_clamp * f_clamp - lambda_var * T_prev_var
end
kernel.hpv.reapDeadTasks()
if stopLog > 0 then
kernel.log("Executed " .. N .. " tasks, avg time: " .. string.format("%.2f", T_prev_avg) .. "ms, var: " .. string.format("%.2f", T_prev_var) .. ", B: " .. string.format("%.5f", B))
stopLog = stopLog - 1
kernel.saveLog()
end
end
end
@@ -1,5 +0,0 @@
--:Minify:--
local kernel=...
if kernel.arch~="cct" then
kernel.deny("cc-tweaked/31_keyboards.kmod")
end
@@ -0,0 +1,387 @@
--: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,
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,
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",
[apis.keys.up]="\17",
[apis.keys.down]="\18",
[apis.keys.left]="\19",
[apis.keys.right]="\20",
}
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
if not apis.fs.exists("/nvram.dat") then
local file = apis.fs.open("/nvram.dat", "w")
file.write("Hello, World!")
file.close()
end
local eeprom
if apis.fs.exists("/startup.lua") then
eeprom="/startup.lua"
elseif apis.fs.exists("/eeprom") then
eeprom="/eeprom"
end
local eventQueue = {}
local function queueEvent(event, ...)
table.insert(eventQueue, {event, ...})
end
local colors = {
[0x000000]=0x0001,
[0xFFFFFF]=0x0002,
[0xFF0000]=0x0004,
[0x00FF00]=0x0008,
[0x0000FF]=0x0010,
[0x00FFFF]=0x0020,
[0xFF00FF]=0x0040,
[0xFFFF00]=0x0080,
[0xFF6D00]=0x0100,
[0x6DFF55]=0x0200,
[0x24FFFF]=0x0400,
[0x924900]=0x0800,
[0x6D6D55]=0x1000,
[0xDBDBAA]=0x2000,
[0x6D00FF]=0x4000,
[0xB6FF00]=0x8000
}
local fg,bg=0x6D6D55,0x000000
local l1f,l1d,l2,ops={},{},{},0
local function findClosest(tbl, target)
local closest = nil
local smallestDiff = math.huge
for k, _ in pairs(tbl) do
local diff = math.abs(k - target)
if diff < smallestDiff then
smallestDiff = diff
closest = k
end
end
return closest
end
local function aprox(c24)
ops = ops + 1
if ops % 1024 == 0 then
l1d = {}
l1f = {}
end
if ops % 8192 == 0 then
l2 = {}
end
if l2[c24] ~= nil then
return l2[c24]
end
if l1d[c24] ~= nil then
l1f[c24] = l1f[c24] + 1
if l1f[c24] >= 16 then
l2[c24] = l1d[c24]
l1d[c24] = nil
l1f[c24] = nil
return l2[c24]
end
return l1d[c24]
end
local closestKey = findClosest(colors, c24)
if not closestKey then return nil end
local value = colors[closestKey]
l1d[c24] = value
l1f[c24] = 1
return value
end
local EFI = {
getEpochMs = function() return apis.os.epoch("utc") end,
getUptime = function() return apis.os.clock() * 1000 end,
date = function() return apis.os.date("!%Y-%m-%dT%H:%M:%SZ", apis.os.epoch("utc") / 1000) end,
getMachineEvent = function()
if #eventQueue > 0 then
return table.unpack(table.remove(eventQueue, 1))
else
return nil
end
end,
getEEPROM = function() return getFile(eeprom) end,
setEEPROM = function(_, text)
local h = apis.fs.open(eeprom, "w")
h.write(text)
h.close()
end,
initfs=fs,
disks=initFs,
screenCtl={
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(aprox(color))
end,
setTextColor = function(_, color)
apis.term.setTextColor(aprox(color))
end,
getBackgroundColor = function()
return bg
end,
getTextColor = function()
return fg
end,
enable=function() end,
disable=function() end
},
architecture="cct",
getNvram = function() return getFile("/nvram.dat") end,
setNvram = function(_, text)
local h = apis.fs.open("/nvram.dat", "w")
h.write(text)
h.close()
end,
firmware=apis,
reboot=false
}
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, EFI)
if not ok and not EFI.reboot then displaySuperBadError(err) end
if err then
apis.os.reboot()
else
apis.os.shutdown()
end
end)
function EFI.resumeWithTimeout(co, timeout, ...)
local startTime = EFI.getEpochMs()
debug.sethook(co, function()
if EFI.getEpochMs() > 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 = EFI.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] == "modem_message" then
queueEvent("modem_message", table.unpack(event, 2))
elseif event[1] == "rednet_message" then
queueEvent("rednet_message", table.unpack(event, 2))
elseif event[1] == "http_success" then
queueEvent("http_success", table.unpack(event, 2))
elseif event[1] == "http_failure" then
queueEvent("http_failure", table.unpack(event, 2))
elseif event[1] == "NoSleep" then
exit = true
end
end
if status == "error" or coroutine.status(kernelCoro) == "dead" then
if EFI.reboot then
apis.os.reboot()
end
displaySuperBadError("Kernel error: " .. tostring(err))
coroutine.yield("key")
end
initFs:refresh()
end
end, debug.traceback)
if not ok then displaySuperBadError("Fatal error during boot: " .. err) end
while true do coroutine.yield("key") end
@@ -0,0 +1,119 @@
--:Minify:--
local BOOT_DRIVE_PATH=({...})[1] or "/$"
-- UnBIOS by JackMacWindows
-- This will undo most of the changes/additions made in the BIOS, but some things may remain wrapped if `debug` is unavailable
-- To use, just place a `bios.lua` in the root of the drive, and run this program
-- Here's a list of things that are irreversibly changed:
-- * both `bit` and `bit32` are kept for compatibility
-- * string metatable blocking (on old versions of CC)
-- In addition, if `debug` is not available these things are also irreversibly changed:
-- * old Lua 5.1 `load` function (for loading from a function)
-- * `loadstring` prefixing (before CC:T 1.96.0)
-- * `http.request`
-- * `os.shutdown` and `os.reboot`
-- * `peripheral`
-- * `turtle.equip[Left|Right]`
-- Licensed under the MIT license
local args = {...}
local keptAPIs = {keys=true, bit32 = true, bit = true, ccemux = true, config = true, coroutine = true, debug = true, fs = true, http = true, mounter = true, os = true, periphemu = true, peripheral = true, redstone = true, rs = true, term = true, utf8 = true, _HOST = true, _CC_DEFAULT_SETTINGS = true, _CC_DISABLE_LUA51_FEATURES = true, _VERSION = true, assert = true, collectgarbage = true, error = true, gcinfo = true, getfenv = true, getmetatable = true, ipairs = true, __inext = true,load = true, loadstring = true, math = true, newproxy = 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, unpack = true, xpcall = true, turtle = true, pocket = true, commands = true, _G = true}
local t = {}
for k in pairs(_G) do if not keptAPIs[k] then table.insert(t, k) end end
for _,k in ipairs(t) do _G[k] = nil end
local native = _G.term.native()
for _, method in ipairs {"nativePaletteColor", "nativePaletteColour", "screenshot"} do native[method] = _G.term[method] end
_G.term = native
if _G.http then
_G.http.checkURL = _G.http.checkURLAsync
_G.http.websocket = _G.http.websocketAsync
end
if _G.commands then _G.commands = _G.commands.native end
if _G.turtle then _G.turtle.native, _G.turtle.craft = nil end
local delete = {os = {"version", "pullEventRaw", "pullEvent", "run", "loadAPI", "unloadAPI", "sleep"}, http = _G.http and {"get", "post", "put", "delete", "patch", "options", "head", "trace", "listen", "checkURLAsync", "websocketAsync"}, fs = {"complete", "isDriveRoot"}}
for k,v in pairs(delete) do for _,a in ipairs(v) do _G[k][a] = nil end end
-- Set up TLCO
-- This functions by crashing `rednet.run` by removing `os.pullEventRaw`. Normally
-- this would cause `parallel` to throw an error, but we replace `error` with an
-- empty placeholder to let it continue and return without throwing. This results
-- in the `pcall` returning successfully, preventing the error-displaying code
-- from running - essentially making it so that `os.shutdown` is called immediately
-- after the new BIOS exits.
--
-- From there, the setup code is placed in `term.native` since it's the first
-- thing called after `parallel` exits. This loads the new BIOS and prepares it
-- for execution. Finally, it overwrites `os.shutdown` with the new function to
-- allow it to be the last function called in the original BIOS, and returns.
-- From there execution continues, calling the `term.redirect` dummy, skipping
-- over the error-handling code (since `pcall` returned ok), and calling
-- `os.shutdown()`. The real `os.shutdown` is re-added, and the new BIOS is tail
-- called, which effectively makes it run as the main chunk.
local olderror = error
_G.error = function() end
_G.term.redirect = function() end
function _G.term.native()
_G.term.native = nil
_G.term.redirect = nil
_G.error = olderror
term.setBackgroundColor(32768)
term.setTextColor(1)
term.setCursorPos(1, 1)
term.setCursorBlink(true)
term.clear()
local file = fs.open(BOOT_DRIVE_PATH.."/boot/cct/boot.lua", "r")
if file == nil then
term.setCursorBlink(false)
term.setTextColor(16384)
term.write("Could not find /boot/cct/boot.lua. UnBIOS cannot continue.")
term.setCursorPos(1, 2)
term.write("Press any key to continue")
coroutine.yield("key")
os.shutdown()
end
local fn, err = loadstring(file.readAll(), "@bootloader")
file.close()
if fn == nil then
term.setCursorBlink(false)
term.setTextColor(16384)
term.write("Could not load /boot/cc/boot.lua. UnBIOS cannot continue.")
term.setCursorPos(1, 2)
term.write(err)
term.setCursorPos(1, 3)
term.write("Press any key to continue")
coroutine.yield("key")
os.shutdown()
end
setfenv(fn, _G)
local oldshutdown = os.shutdown
os.shutdown = function()
os.shutdown = oldshutdown
return fn(BOOT_DRIVE_PATH)
end
end
if debug then
-- Restore functions that were overwritten in the BIOS
-- Apparently this has to be done *after* redefining term.native
local function restoreValue(tab, idx, name, hint)
local i, key, value = 1, debug.getupvalue(tab[idx], hint)
while key ~= name and key ~= nil do
key, value = debug.getupvalue(tab[idx], i)
i=i+1
end
tab[idx] = value or tab[idx]
end
restoreValue(_G, "loadstring", "nativeloadstring", 1)
restoreValue(_G, "load", "nativeload", 5)
if http then restoreValue(http, "request", "nativeHTTPRequest", 3) end
restoreValue(os, "shutdown", "nativeShutdown", 1)
restoreValue(os, "reboot", "nativeReboot", 1)
if turtle then
restoreValue(turtle, "equipLeft", "v", 1)
restoreValue(turtle, "equipRight", "v", 1)
end
do
local i, key, value = 1, debug.getupvalue(peripheral.isPresent, 2)
while key ~= "native" and key ~= nil do
key, value = debug.getupvalue(peripheral.isPresent, i)
i=i+1
end
_G.peripheral = value or peripheral
end
end
@@ -0,0 +1,272 @@
--:Minify:--
local apis = ({...})[1]
local BOOT_DRIVE_PATH = apis.BOOT_DRIVE_PATH
local fs = apis.fs
local native = apis.peripheral
local peripheral = {}
local sides = {"top", "bottom", "left", "right", "front", "back"}
function peripheral.getNames()
local results = {}
for n = 1, #sides do
local side = sides[n]
if native.isPresent(side) then
table.insert(results, side)
if native.hasType(side, "peripheral_hub") then
local remote = native.call(side, "getNamesRemote")
for _, name in ipairs(remote) do
table.insert(results, name)
end
end
end
end
return results
end
function peripheral.isPresent(name)
if native.isPresent(name) then
return true
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return true
end
end
return false
end
function peripheral.getType(peripheral)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.getType(peripheral)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "getTypeRemote", peripheral)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return table.unpack(mt.types)
end
end
function peripheral.hasType(peripheral, peripheral_type)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.hasType(peripheral, peripheral_type)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "hasTypeRemote", peripheral, peripheral_type)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.types[peripheral_type] ~= nil
end
end
function peripheral.getMethods(name)
if native.isPresent(name) then
return native.getMethods(name)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "getMethodsRemote", name)
end
end
return nil
end
function peripheral.getName(peripheral)
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.name
end
function peripheral.call(name, method, ...)
if native.isPresent(name) then
return native.call(name, method, ...)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "callRemote", name, method, ...)
end
end
return nil
end
function peripheral.wrap(name)
local methods = peripheral.getMethods(name)
if not methods then
return nil
end
local types = { peripheral.getType(name) }
for i = 1, #types do types[types[i]] = true end
local result = setmetatable({}, {
__name = "peripheral",
name = name,
type = types[1],
types = types,
})
for _, method in ipairs(methods) do
result[method] = function(...)
return peripheral.call(name, method, ...)
end
end
return result
end
function peripheral.find(ty, filter)
local results = {}
for _, name in ipairs(peripheral.getNames()) do
if peripheral.hasType(name, ty) then
local wrapped = peripheral.wrap(name)
if filter == nil or filter(name, wrapped) then
table.insert(results, wrapped)
end
end
end
return table.unpack(results)
end
local disks = {}
local internal = {}
local function norm(path)
if not path or path == "" then return "/" end
return fs.combine("/", path)
end
local function createDisk(id, basePath, readonly, periph)
basePath = norm(basePath)
local disk = {address = id, isReadOnly = function() return readonly end}
function disk:spaceUsed()
return fs.getCapacity(basePath) - fs.getFreeSpace(basePath)
end
function disk:spaceTotal() return fs.getCapacity(basePath) end
function disk:list(path)
local p = fs.combine(basePath, path)
if not fs.exists(p) or not fs.isDir(p) then
return nil, "not directory"
end
return fs.list(p)
end
function disk:fileExists(path)
local p = fs.combine(basePath, path)
return fs.exists(p) and not fs.isDir(p)
end
function disk:directoryExists(path)
local p = fs.combine(basePath, path)
return fs.exists(p) and fs.isDir(p)
end
function disk:type(path)
local p = fs.combine(basePath, path)
if not fs.exists(p) then
return nil
elseif fs.isDir(p) then
return "directory"
else
return "file"
end
end
function disk:makeDirectory(path)
local p = fs.combine(basePath, path)
fs.makeDir(p)
return true
end
function disk:remove(path)
local p = fs.combine(basePath, path)
if fs.exists(p) then fs.delete(p) end
return true
end
function disk:setLabel(label) periph.setLabel(label) end
function disk:getLabel(label) return periph.getLabel() end
function disk:attributes(path)
local p = fs.combine(basePath, path)
return fs.attributes(p)
end
function disk:open(path, mode)
local p = fs.combine(basePath, path)
return fs.open(p, mode)
end
return disk
end
internal["$"] = createDisk("$", BOOT_DRIVE_PATH, false, {
setLabel = function(label)
local h = fs.open("/.label", "w")
h.write(label)
h.close()
end,
getLabel = function()
local h = fs.open("/.label", "r")
if not h then return "$" end
local label = h.readAll()
h.close()
return label
end
})
internal["rom"] = createDisk("rom", "/rom", true, {
setLabel = function(label)
error("Device is read-only")
end,
getLabel = function()
return "cctrom"
end
})
local function refresh()
disks={}
for _, disk in ipairs({peripheral.find("drive")}) do
if disk.isDiskPresent() then
disks[tostring(disk.getDiskID())]=createDisk("cctdisk"..tostring(disk.getDiskID()), disk.getMountPath(), false, fs)
end
end
end
local function iter()
refresh()
local combined = {}
for id, obj in pairs(internal) do combined[id] = obj end
for id, obj in pairs(disks) do combined[id] = obj end
return pairs(combined)
end
return {refresh = refresh, list = iter}
@@ -0,0 +1,6 @@
--:Minify:--
local kernel=...
if kernel.gfx then
end
@@ -494,7 +494,7 @@ local ok, err = xpcall(function()
h.close()
end,
firmware=apis,
status="running",
reboot=false,
beep=function() end
}
@@ -505,7 +505,7 @@ local ok, err = xpcall(function()
local kernelCoro = coroutine.create(function()
--pf
---@diagnostic disable-next-line: param-type-mismatch
---@diagnostic disable-next-line: param-type-mismatch-
local ok, err = xpcall(Kernel, debug.traceback, EFI)
if not ok then
error(err)
@@ -569,18 +569,14 @@ local ok, err = xpcall(function()
end
end
if status == "error" or coroutine.status(kernelCoro) == "dead" then
if EFI.status=="reboot" then
if EFI.reboot then
apis.os.reboot()
elseif EFI.status=="shutdown" then
apis.os.shutdown()
end
displaySuperBadError("Kernel error: " .. tostring(err))
coroutine.yield("key")
elseif status == "success" then
if EFI.status=="reboot" then
if EFI.reboot then
apis.os.reboot()
elseif EFI.status=="shutdown" then
apis.os.shutdown()
end
displaySuperBadError("Kernel error: Attempted to yield main thread\n"..debug.traceback(kernelCoro, "Attempted to yield main thread"))
coroutine.yield("key")
@@ -163,7 +163,7 @@ local function createDisk(id, basePath, readonly, periph)
local disk = {address = id, isReadOnly = function() return readonly end}
function disk:spaceUsed()
return (fs.getCapacity(basePath) or 0) - (fs.getFreeSpace(basePath) or 0)
return fs.getCapacity(basePath) - fs.getFreeSpace(basePath)
end
function disk:spaceTotal() return fs.getCapacity(basePath) end
@@ -1,12 +0,0 @@
--:Minify:--
local kernel=...
if kernel.arch~="cct" then
kernel.deny("cc-tweaked/01_periph.kmod")
kernel.deny("cc-tweaked/13_devraw.kmod")
kernel.deny("cc-tweaked/22_http.kmod")
kernel.deny("cc-tweaked/25_mouse.kmod")
kernel.deny("cc-tweaked/25_tty.kmod")
kernel.deny("cc-tweaked/30_daemon.kmod")
kernel.deny("cc-tweaked/46_scheduler.kmod")
kernel.deny("cc-tweaked/51_gpio.kmod")
end
@@ -1,25 +0,0 @@
--:Minify:--
local kernel=...
local fifo=kernel.newFifo()
kernel.devfs.data["input"]["mouse1"] = function(op, mode)
if op=="type" then
return "Mouse"
elseif op=="open" then
local h = {
read=function(amount)
local rv=""
for i=1, amount or 1 do
local event = {fifo.pop()}
if event[1] then
rv=rv..event[1]
end
end
---@diagnostic disable-next-line: cast-local-type
if rv=="" then rv=nil end
return rv
end
}
return h
end
end
kernel.cct.mouse={fifo=fifo}
@@ -1,8 +1,6 @@
--:Minify:--
local kernel = ...
local peripheral=kernel.cct.peripheral
kernel.cct.gfx={}
kernel.cct.term={}
local colors = {
[0xFFFFFF]=0x0001,
@@ -157,7 +155,6 @@ local function serializeBool(bool)
end
local function newtty(obj, id, ev)
kernel.cct.term[id]=obj
obj.setPaletteColor(0x1, 0xFFFFFF) -- #000000
obj.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF
obj.setPaletteColor(0x4, 0x00FF00) -- #FF0000
@@ -179,6 +176,17 @@ local function newtty(obj, id, ev)
return "Terminal"
elseif op=="open" then
local h = {
read=function(amount)
local rv=""
for i=1, amount or 1 do
local event = {ev()}
if event[1] then
rv=rv..event[1]
end
end
if rv=="" then rv=nil end
return rv
end,
write=function(content)
write(content, obj)
end,
@@ -213,16 +221,18 @@ local function newtty(obj, id, ev)
return false
end,
gplt=function()
return table.deepcopy(plt)
end,
gfx=function(...)
if kernel.cct.gfx[id] then return kernel.cct.gfx[id] else return false end
end,
id=function()
return id
return plt
end
}
return h
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
end
@@ -249,14 +259,23 @@ kernel.devfs.data["input"]["keyboard1"] = function(op, mode)
rv=rv..event[1]
end
end
---@diagnostic disable-next-line: cast-local-type
if rv=="" then rv=nil end
return rv
end,
write=function(content)
end,
gctrl=function()
return serializeBool(kernel.cct.ctrl)..";"..serializeBool(kernel.cct.alt)
end
}
return h
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
@@ -71,10 +71,8 @@ kernel.processes.cctdaemon = function()
elseif eventType == "mouse_scroll" then
if event[2] == 1 then
kernel.cct.fifo.push("S")
kernel.cct.mouse.fifo.push("S")
else
kernel.cct.fifo.push("T")
kernel.cct.mouse.fifo.push("T")
end
elseif eventType == "http_success" then
if kernel.cct.httpqueue[event[2]] then
@@ -87,16 +85,6 @@ kernel.processes.cctdaemon = function()
kernel.cct.httperror[event[2]]=event[3]
kernel.cct.httpresponse[event[2]]=event[4]
end
elseif eventType == "mouse_click" then
--";X;Y;C"
-- 1 = left
-- 2 = right
-- 3 = middle
kernel.cct.mouse.fifo.push(";"..tostring(event[3])..";"..tostring(event[4])..";"..tostring(event[2]))
elseif eventType == "mouse_drag" then
kernel.cct.mouse.fifo.push(";"..tostring(event[3])..";"..tostring(event[4])..";"..tostring(event[2]))
elseif eventType == "mouse_up" then
kernel.cct.mouse.fifo.push(";"..tostring(event[3])..";"..tostring(event[4])..";"..tostring(event[2]))
else
if kernel.cct.eventhooks[eventType] then
local ok,err = xpcall(kernel.cct.eventhooks[eventType], debug.traceback, table.unpack(event))
@@ -35,14 +35,6 @@ function kernel.main()
local totalTaskTime = 0
local taskTimes = {}
for id,hook in ipairs(kernel.mainHooks) do
local ok,err = xpcall(hook, debug.traceback)
if not ok then
kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000)
kernel.mainHooks[id]=nil
end
end
for pid, task in pairs(kernel.tasks) do
if kernel.exitMain then break end
@@ -50,7 +42,7 @@ function kernel.main()
for id,hook in ipairs(list) do
local ok,err = xpcall(hook, debug.traceback, task, pid)
if not ok then
kernel.log("[TASK HOOK ERR]: "..err, "ERROR", 0xFF0000)
kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000)
list[id]=nil
end
end
@@ -156,6 +148,4 @@ function kernel.main()
kernel.saveLog()
end
end
kernel.log("Exited main")
kernel.saveLog()
end
-3
View File
@@ -1,3 +0,0 @@
Hyperion
Astronand
Xtimhedae
+25 -25
View File
@@ -1,17 +1,13 @@
---@diagnostic disable-next-line: undefined-global
local cp,c=component,computer;local b_addr=c.getBootAddress();local b_fs=cp.proxy(b_addr)
local gpu=cp.list("gpu")() and cp.proxy(cp.list("gpu")())
local e_rom=cp.list("eeprom")() and cp.proxy(cp.list("eeprom")())
local screens={}
for addr in cp.list("screen") do
if gpu then
gpu.bind(addr)
local w,h=gpu.maxResolution()
gpu.setResolution(w,h)
gpu.fill(1,1,w,h," ")
cp.proxy(addr).turnOn()
screens[#screens+1] = {cx=1,cy=1,w=w,h=h,addr=addr}
end
local w,h=gpu and gpu.maxResolution() or 20,10
gpu.setResolution(w,h)
gpu.fill(1,1,w,h," ")
cp.proxy(addr).turnOn()
screens[#screens+1] = {cx=1,cy=1,w=w,h=h,addr=addr}
end
local function scroll(scr) gpu.copy(1,2,scr.w,scr.h-1,0,-1);gpu.fill(1,scr.h,scr.w,1," ") end
local function write(t)
@@ -26,7 +22,7 @@ local function write(t)
elseif char=="\b" then if scr.cx>1 then scr.cx=scr.cx-1;gpu.set(scr.cx,scr.cy," ") end
else gpu.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
if scr.cy>scr.h then scroll(scr);scr.cy=scr.cy-1 end
if scr.cy>scr.h then error("executed")scroll(scr);scr.cy=scr.cy-1 end
end
end
end
@@ -43,9 +39,11 @@ local function throw(err)
while true do c.pullSignal() end
end
local ok,err=xpcall(function()
local apis={}
local apis={os={},fs={},peripheral={},term={}}
local _l={coroutine=1,debug=1,_VERSION=1,assert=1,collectgarbage=1,error=1,getmetatable=1,ipairs=1,load=1,math=1,next=1,pairs=1,pcall=1,rawequal=1,rawget=1,rawlen=1,rawset=1,select=1,setmetatable=1,string=1,table=1,tonumber=1,tostring=1,type=1,xpcall=1,_G=1}
for k,v in pairs(_G) do if not _l[k] then apis[k]=v;_G[k]=nil end end
apis.os.clock=c.uptime;apis.os.epoch=function()return math.floor(c.uptime()*1000) end
apis.os.queueEvent=c.pushSignal
function sleep(t) local s=c.uptime()+t;while c.uptime()<s do c.pullSignal(s-c.uptime()) end end
local function getFile(path)
local h,err=b_fs.open(path,"r")
@@ -55,25 +53,25 @@ local ok,err=xpcall(function()
b_fs.close(h)
return buf
end
local Kernel=load(getFile("/kernel.lua"),"@Kernel")
local initFs=load(getFile("/oc/initdisks"),"@Init_disks")
local fs=load(getFile("/initfs"),"@InitFs")
local Kernel=load(getFile("/boot/kernel.lua"),"@Kernel")
local initFs=load(getFile("/boot/oc/initdisks"),"@Init_disks")
local fs=load(getFile("/boot/initfs"),"@InitFs")
if not Kernel then throw("Kernel load failed.") end
if initFs then initFs=initFs(apis, b_fs, b_addr) end
if fs then fs=fs() end
local n_addr=cp.list("filesystem")()
local eQ={}
local function qEv(e,...) table.insert(eQ,{e,...}) end
apis.peripheral.getNames=function() local res={};for k in cp.list() do table.insert(res,k) end return res end
apis.peripheral.isPresent=function(a) return cp.type(a)~=nil end
apis.peripheral.getType=cp.type
apis.peripheral.getMethods=cp.methods
apis.peripheral.call=cp.invoke
local efi={
getEpochMs=function() return math.floor(c.uptime()*1000) end,
getUptime=function() return c.uptime()*1000 end,
date=function() return tostring(apis.os.date()) end,
getMachineEvent=function()
if #eQ > 0 then
return table.unpack(table.remove(eQ, 1))
else
return nil
end
end,
getMachineEvent=function() return #eQ>0 and table.unpack(table.remove(eQ,1)) or nil end,
getEEPROM=function() return e_rom and e_rom.get() or "" end,
setEEPROM=function(_,t) if e_rom then e_rom.set(t) end end,
getNvram=function() return e_rom and e_rom.getData() or "" end,
@@ -88,8 +86,8 @@ local ok,err=xpcall(function()
screenCtl={
print=function(_,t) write(tostring(t).."\n") end,
printInline=function(_,t) write(tostring(t)) end,
clear=function() if gpu then for i=1, #screens do local scr=screens[i];gpu.bind(scr.addr);gpu.fill(1,1,scr.w,scr.h," ");scr.cx,scr.cy=1,1 end end end,
resetCursor=function() for i=1, #screens do local scr=screens[i];scr.cx,scr.cy=1,1 end end,
clear=function() if gpu then gpu.fill(1,1,w,h," ");cx,cy=1,1 end end,
resetCursor=function() cx,cy=1,1 end,
setBackgroundColor=function(_,cl) if gpu then gpu.setBackground(cl) end end,
setTextColor=function(_,cl) if gpu then gpu.setForeground(cl) end end,
enable=function() end,
@@ -110,8 +108,10 @@ local ok,err=xpcall(function()
local ev={c.pullSignal(0)}
if ev[1]=="key_down" then qEv("keyPressed",1,ev[3]);qEv("keyTyped",1,string.char(ev[3]))
elseif ev[1]=="key_up" then qEv("keyReleased",1,ev[3])
end
if ev[1]=="NoSleep" then ex=true else qEv(table.unpack(ev)) end
elseif ev[1]=="component_added" then qEv("componentAdded",ev[3])
elseif ev[1]=="component_removed" then qEv("componentRemoved",ev[3])
elseif ev[1]=="modem_message" then qEv("modem_message",table.unpack(ev,2))
elseif ev[1]=="NoSleep" then ex=true end
end
if st=="error" or coroutine.status(kCo)=="dead" then
if efi.reboot then c.shutdown(true) end
+1 -1
View File
@@ -27,7 +27,7 @@ do
end
end
local function tryLoadFrom(address)
local handle, reason = boot_invoke(address, "open", "/oc/boot.lua")
local handle, reason = boot_invoke(address, "open", "/boot/oc/boot.lua")
if not handle then
return nil, reason
end
@@ -7,7 +7,7 @@ local internal = {}
local function createDisk(id, hw)
local disk = {
address = id,
address = id,
isReadOnly = function() return hw.isReadOnly() end
}
@@ -18,13 +18,7 @@ local function createDisk(id, hw)
if not hw.exists(path) or not hw.isDirectory(path) then
return nil, "not directory"
end
local ret={}
for i,v in ipairs(hw.list(path)) do
if v:sub(-1)=="/" then
ret[i]=v:sub(1,#v-1)
else ret[i]=v end
end
return ret
return hw.list(path)
end
function disk:fileExists(path)
@@ -1,11 +0,0 @@
--:Minify:--
local kernel=...
if kernel.arch~="oc" then
kernel.deny("opencomputers/01_devices.kmod")
kernel.deny("opencomputers/13_devraw.kmod")
kernel.deny("opencomputers/22_http.kmod")
kernel.deny("opencomputers/25_tty.kmod")
kernel.deny("opencomputers/26_keyboards.kmod")
kernel.deny("opencomputers/30_daemon.kmod")
kernel.deny("opencomputers/36_scheduler.kmod")
end
@@ -67,52 +67,23 @@ local plt = {
local gpus,screens = {},{}
for addr, typ in component.list("gpu") do
for addr, typ in component.list() do
if typ == "gpu" then
gpus[#gpus+1]=component.proxy(addr)
gpus[#gpus]=component.proxy(addr)
elseif typ == "screen" then
screens[addr]={cx=1,cy=1,w=w,h=h}
end
end
if #gpus>0 then
for addr, typ in component.list("screen") do
if typ == "screen" then
gpus[1].bind(addr)
local w,h = gpus[1].maxResolution()
gpus[1].setResolution(w,h)
screens[addr]={cx=1,cy=1,w=w,h=h,addr=addr,fg=0,bg=0,gpu=nil}
end
end
end
local scrnum = 0
for i,v in pairs(screens) do
scrnum=scrnum+1
end
kernel.log("initialized "..tostring(#gpus).." gpus and "..tostring(scrnum).." screens")
local binds,newid={},0
local curaddr=""
local function scroll(scr, gpu) gpu.copy(1,2,scr.w,scr.h-1,0,-1);gpu.fill(1,scr.h,scr.w,1," ") end
local function write(text, addr)
local g=gpus[1]
local scr=screens[addr]
if not scr then error("NODEV") end
if curaddr~=addr then g.bind(addr); g.setForeground(scr.fg); g.setBackground(scr.bg) end
for i=1,#text do
local char=text:sub(i,i)
if char=="\n" then scr.cx=1;scr.cy=scr.cy+1
elseif char=="\t" then scr.cx=scr.cx+(4-((scr.cx-1)%4))
elseif char=="\b" then if scr.cx>1 then scr.cx=scr.cx-1;g.set(scr.cx,scr.cy," ") end
else g.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
if scr.cy>scr.h then scroll(scr, g);scr.cy=scr.cy-1 end
end
end
local function newtty(addr)
newid=newid+1
kernel.devfs.data["tty"][tostring(newid)]=function(op, mode)
kernel.devfs.data["tty"][newid]=function(op, mode)
if op=="type" then
return "Terminal"
elseif op=="open" then
@@ -122,42 +93,39 @@ local function newtty(addr)
write(content, addr)
end,
size=function()
return screens[addr].w, screens[addr].h
local s={obj.getSize()}
return tostring(screens[addr].w)..":"
end,
clear=function()
local g=gpus[1]
local scr=screens[addr]
if addr~=curaddr then g.bind(addr) end
g.fill(1,1,scr.w,scr.h," ");
scr.cx,scr.cy=1,1
obj.clear()
obj.setCursorPos(1,1)
end,
gpos=function()
return screens[addr].cx, screens[addr].cy
local s={obj.getCursorPos()}
return table.concat(s,";")
end,
spos=function(x,y)
if not tonumber(x) or not tonumber(y) then error("Invailid arg") end
screens[addr].cx, screens[addr].cy = x,y
return obj.setCursorPos(x,y)
end,
sfgc=function(c)
screens[addr].fg=c
fg=c
return obj.setTextColor(aprox(c))
end,
sbgc=function(c)
screens[addr].bg=c
bg=c
return obj.setBackgroundColor(aprox(c))
end,
gfgc=function()
return screens[addr].fg
return fg
end,
gbgc=function()
return screens[addr].bg
return bg
end,
isvirt=function()
return false
end,
gplt=function()
return plt
end,
gfx=function()
return false
end
}
if mode=="rw" then
@@ -173,8 +141,6 @@ local function newtty(addr)
end
end
if #gpus>=1 and scrnum>=1 then
for addr,obj in pairs(screens) do
newtty(addr)
end
if #gpus>=1 and #screens>=1 then
end
@@ -1,113 +0,0 @@
--:Minify:--
local kernel=...
kernel.oc.keyboards={}
local kbs=kernel.oc.keyboards
local kbidx=0
local keyboard = {}
keyboard.keys = {
back = 0x0E, -- backspace
delete = 0xD3,
down = 0xD0,
enter = 0x1C,
home = 0xC7,
lcontrol = 0x1D,
left = 0xCB,
lmenu = 0x38, -- left Alt
lshift = 0x2A,
pageDown = 0xD1,
rcontrol = 0x9D,
right = 0xCD,
rmenu = 0xB8, -- right Alt
rshift = 0x36,
space = 0x39,
tab = 0x0F,
up = 0xC8,
["end"] = 0xCF,
numpadenter = 0x9C,
}
kernel.oc.keys=keyboard.keys
for i=0, 255 do
kernel.oc.keys[string.char(i)]=i
end
-------------------------------------------------------------------------------
function keyboard.isAltDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lmenu] or kbs[addr].pressedCodes[keyboard.keys.rmenu]
end
function keyboard.isControl(char)
return type(char) == "number" and (char < 0x20 or (char >= 0x7F and char <= 0x9F))
end
function keyboard.isControlDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lcontrol] or kbs[addr].pressedCodes[keyboard.keys.rcontrol]
end
function keyboard.isKeyDown(addr,charOrCode)
if type(charOrCode) == "string" then
return kbs[addr].pressedChars[utf8 and utf8.codepoint(charOrCode) or charOrCode:byte()]
elseif type(charOrCode) == "number" then
return kbs[addr].pressedCodes[charOrCode]
end
end
function keyboard.isShiftDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lshift] or kbs[addr].pressedCodes[keyboard.keys.rshift]
end
kernel.oc.keyboard=keyboard
local function serializeBool(bool)
if bool then
return "T"
else
return "F"
end
end
for addr, typ in kernel.oc.component.list("keyboard") do
if typ=="keyboard" then
kbidx=kbidx+1
kbs[addr]={pressedChars = {}, pressedCodes = {}, events=kernel.newFifo()}
kernel.devfs.data["input"]["keyboard"..tostring(kbidx)]=function(op,mode)
if op=="type" then
return "Keyboard"
elseif op=="open" then
local h = {
read=function(amount)
local rv=""
for i=1, amount or 1 do
local event = {kernel.oc.keyboards[addr].events.pop()}
if event[1] then
rv=rv..event[1]
end
end
if rv=="" then rv=nil end
return rv
end,
write=function(content)
end,
gctrl=function()
return serializeBool(keyboard.isControlDown(addr))..";"..serializeBool(keyboard.isAltDown(addr))
end,
isKeyDown=function(char)
return keyboard.isKeyDown(addr,char)
end
}
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
end
end
@@ -1,99 +0,0 @@
--:Minify:--
local kernel=...
local keys=kernel.oc.keys
kernel.processes.ocdaemon = function()
local timeout = false
kernel.log("OC daemon started")
local ctrlKeyMap = {
[keys.a]=1, [keys.b]=2, [keys.c]=3,
[keys.d]=4, [keys.e]=5, [keys.f]=6,
[keys.g]=7, [keys.h]=8, [keys.i]=9,
[keys.j]=10, [keys.k]=11, [keys.l]=12,
[keys.m]=13, [keys.n]=14, [keys.o]=15,
[keys.p]=16, [keys.q]=17, [keys.r]=18,
[keys.s]=19, [keys.t]=20, [keys.u]=21,
[keys.v]=22, [keys.w]=23, [keys.x]=24,
[keys.y]=25, [keys.z]=26,
}
local specialKeyMap = {
[keys.up] = "\27[A",
[keys.down] = "\27[B",
[keys.right] = "\27[C",
[keys.left] = "\27[D",
[keys.home] = "\27[H",
[keys["end"]] = "\27[F",
--[keys.pageUp] = "\27[5~",
--[keys.pageDown] = "\27[6~",
[keys.delete] = "\27[3~",
[keys.enter] = "\n",
[keys.back] = "\b",
[keys.tab] = "\t",
}
while true do
local event = {kernel.EFI.getMachineEvent()}
if event[1] then
local eventType = event[1]
local addr = event[2]
local char = event[3]
local keyCode = event[4]
if eventType == "key_down" then
local keyboard = kernel.oc.keyboards[addr]
if keyboard.ctrl then
local ctrlByte = ctrlKeyMap[keyCode]
if ctrlByte then
if ctrlByte == 3 then
for _, task in ipairs(syscall.getTasks()) do
syscall.sigsend(task, 1)
end
else
keyboard.events.push(string.char(ctrlByte))
end
end
else
local special = specialKeyMap[keyCode]
if special then
keyboard.events.push(special)
elseif char and char > 0 then
keyboard.events.push(kernel.apis.unicode.char(char))
end
end
elseif eventType == "key_up" then
end
timeout = false
else
timeout = true
end
if timeout then
sleep(0.05)
end
end
end
kernel.log("OC daemon queued for execution")
@@ -10,7 +10,6 @@ local lambda_var = 0.02
local k_min = 0.5
local k_max = 0.5
local B = 0.01
local nextyield=0
function kernel.main()
kernel.log("Starting main loop...")
-1
View File
@@ -1 +0,0 @@
firmware for Opencomputers mod
@@ -1,593 +0,0 @@
--:Minify:--
local BOOT_DRIVE_PATH = ({...})[1] or "/$"
---@diagnostic disable-next-line: undefined-global
local lterm = term
local function write(text, term)
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, noyield)
lterm.setBackgroundColor(0x1)
lterm.setTextColor(0x4)
lterm.clear()
lterm.setCursorPos(1, 1)
lterm.write("A critical error occurred while loading the system:")
lterm.setCursorPos(1, 3)
write(err, lterm)
coroutine.yield("key")
end
term.setCursorBlink(false)
local ok, err = xpcall(function()
--p
local apis = {BOOT_DRIVE_PATH = BOOT_DRIVE_PATH}
local lua = {
coroutine = true,
debug = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = 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,
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
--p
local acekeys={
[apis.keys.enter]="\n",
[apis.keys.tab]="\t",
[apis.keys.backspace]="\b",
[apis.keys.up]="\17",
[apis.keys.down]="\18",
[apis.keys.left]="\19",
[apis.keys.right]="\20",
}
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 .. "/kernel.lua"),"@Kernel")
local initFs = load(getFile(BOOT_DRIVE_PATH .. "/cct/initdisks"),"@Init_disks")(apis)
local fs = load(getFile(BOOT_DRIVE_PATH .. "/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
if not apis.fs.exists("/nvram.dat") then
local file = apis.fs.open("/nvram.dat", "w")
file.write("Hello, World!")
file.close()
end
local eeprom
if apis.fs.exists("/startup.lua") then
eeprom="/startup.lua"
elseif apis.fs.exists("/eeprom") then
eeprom="/eeprom"
end
local eventQueue = {}
local function queueEvent(event, ...)
table.insert(eventQueue, {event, ...})
end
local colors = {
[0xFFFFFF]=0x0001,
[0xFF0000]=0x0002,
[0x00FF00]=0x0004,
[0x0000FF]=0x0008,
[0x00FFFF]=0x0010,
[0xFF00FF]=0x0020,
[0xFFFF00]=0x0040,
[0xFF6D00]=0x0080,
[0x6DFF55]=0x0100,
[0x24FFFF]=0x0200,
[0x924900]=0x0400,
[0x6D6D55]=0x0800,
[0xDBDBAA]=0x1000,
[0x6D00FF]=0x2000,
[0xB6FF00]=0x4000,
[0x000000]=0x8000
}
local fg,bg=0x6D6D55,0x000000
local l1f,l1d,l2,ops={},{},{},0
local function findClosest(tbl, target)
local closest = nil
local smallestDiff = math.huge
for k, _ in pairs(tbl) do
if k==target then return k end
local diff = math.abs(k - target)
if diff < smallestDiff then
smallestDiff = diff
closest = k
end
end
return closest
end
local function aprox(c24)
ops = ops + 1
if ops % 1024 == 0 then
l1d = {}
l1f = {}
end
if ops % 8192 == 0 then
l2 = {}
end
if l2[c24] ~= nil then
return l2[c24]
end
if l1d[c24] ~= nil then
l1f[c24] = l1f[c24] + 1
if l1f[c24] >= 16 then
l2[c24] = l1d[c24]
l1d[c24] = nil
l1f[c24] = nil
return l2[c24]
end
return l1d[c24]
end
local closestKey = findClosest(colors, c24)
if not closestKey then return nil end
local value = colors[closestKey]
l1d[c24] = value
l1f[c24] = 1
return value
end
--p
local p={}
local native = apis.peripheral
local sides = {"top", "bottom", "left", "right", "front", "back"}
function p.getNames()
local results = {}
for n = 1, #sides do
local side = sides[n]
if native.isPresent(side) then
table.insert(results, side)
if native.hasType(side, "peripheral_hub") then
local remote = native.call(side, "getNamesRemote")
for _, name in ipairs(remote) do
table.insert(results, name)
end
end
end
end
return results
end
function p.isPresent(name)
if native.isPresent(name) then
return true
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return true
end
end
return false
end
function p.getType(peripheral)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.getType(peripheral)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "getTypeRemote", peripheral)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return table.unpack(mt.types)
end
end
function p.hasType(peripheral, peripheral_type)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.hasType(peripheral, peripheral_type)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "hasTypeRemote", peripheral, peripheral_type)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.types[peripheral_type] ~= nil
end
end
function p.getMethods(name)
if native.isPresent(name) then
return native.getMethods(name)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "getMethodsRemote", name)
end
end
return nil
end
function p.getName(peripheral)
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.name
end
function p.call(name, method, ...)
if native.isPresent(name) then
return native.call(name, method, ...)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "callRemote", name, method, ...)
end
end
return nil
end
function p.wrap(name)
local methods = p.getMethods(name)
if not methods then
return nil
end
local types = { p.getType(name) }
for i = 1, #types do types[types[i]] = true end
local result = setmetatable({}, {
__name = "peripheral",
name = name,
type = types[1],
types = types,
})
for _, method in ipairs(methods) do
result[method] = function(...)
return p.call(name, method, ...)
end
end
return result
end
function p.find(ty, filter)
local results = {}
for _, name in ipairs(p.getNames()) do
if p.hasType(name, ty) then
local wrapped = p.wrap(name)
if filter == nil or filter(name, wrapped) then
table.insert(results, wrapped)
end
end
end
return table.unpack(results)
end
--p
local allscreens = {p.find("monitor")}
for i=1, #allscreens do
allscreens[i].setTextScale(.5)
allscreens[i].clear()
allscreens[i].setCursorPos(1,1)
end
allscreens[#allscreens+1] = apis.term
local callAsyncQueue = {}
local callAsyncReturn = {}
apis.callAsyncReturn = callAsyncReturn
local callidx=0
function apis.callAsync(func, ...)
callidx=callidx+1
callAsyncQueue[#callAsyncQueue+1] = {callidx, func, ...}
return callidx
end
local EFI = {
yield=function() end,
getEpochMs = function() return apis.os.epoch("utc") end,
getUptime = function() return apis.os.clock() * 1000 end,
date = function() return apis.os.date("!%Y-%m-%dT%H:%M:%SZ", apis.os.epoch("utc") / 1000) end,
getMachineEvent = function()
if #eventQueue > 0 then
return table.unpack(table.remove(eventQueue, 1))
else
return nil
end
end,
getEEPROM = function() return getFile(eeprom) end,
setEEPROM = function(_, text)
local h = apis.fs.open(eeprom, "w")
h.write(text)
h.close()
end,
initfs=fs,
disks=initFs,
screenCtl={
print = function(_, text)
for i=1, #allscreens do
write(text.."\n", allscreens[i])
end
end,
printInline = function(_, text)
for i=1, #allscreens do
write(text, allscreens[i])
end
end,
clear = function()
for i=1, #allscreens do
allscreens[i].clear()
allscreens[i].setCursorPos(1, 1)
end
end,
resetCursor = function()
for i=1, #allscreens do
allscreens[i].setCursorPos(1, 1)
end
end,
setBackgroundColor = function(_, color)
bg=color
for i=1, #allscreens do
allscreens[i].setBackgroundColor(aprox(color))
end
end,
setTextColor = function(_, color)
fg=color
for i=1, #allscreens do
allscreens[i].setTextColor(aprox(color))
end
end,
getBackgroundColor = function()
return bg
end,
getTextColor = function()
return fg
end,
enable=function()
for i=1, #allscreens do
allscreens[i].clear()
allscreens[i].setCursorPos(1, 1)
end
end,
disable=function() end
},
architecture="cct",
getNvram = function() return getFile("/nvram.dat") end,
setNvram = function(_, text)
local h = apis.fs.open("/nvram.dat", "w")
h.write(text)
h.close()
end,
firmware=apis,
status="running",
beep=function() end
}
apis.term.setBackgroundColor(0x8000)
apis.term.setTextColor(0x1000)
apis.term.clear()
apis.term.setCursorPos(1, 1)
local kernelCoro = coroutine.create(function()
--pf
---@diagnostic disable-next-line: param-type-mismatch
local ok, err = xpcall(Kernel, debug.traceback, EFI)
if not ok then
error(err)
else
apis.os.shutdown()
end
end)
function EFI.resumeWithTimeout(co, timeout, ...)
local startTime = EFI.getEpochMs()
debug.sethook(co, function()
if EFI.getEpochMs() > 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
EFI.screenCtl:print("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n")
--p
while true do
local status, err = EFI.resumeWithTimeout(kernelCoro, 50)
apis.os.queueEvent("NoSleep")
local exit = false
while not exit do
local event = {coroutine.yield()}
if event[1] == "key" then
queueEvent(table.unpack(event))
queueEvent("keyPressed", 1, event[2])
if acekeys[event[2]] then
queueEvent("keyTyped", 1, acekeys[event[2]])
end
elseif event[1] == "char" then
queueEvent(table.unpack(event))
queueEvent("keyTyped", 1, event[2])
elseif event[1] == "key_up" then
queueEvent(table.unpack(event))
queueEvent("keyReleased", 1, event[2])
elseif event[1] == "NoSleep" then
exit = true
else
queueEvent(table.unpack(event))
end
end
while #callAsyncQueue>0 do
local bundle = table.remove(callAsyncQueue, 1)
local ret = {xpcall(bundle[2], debug.traceback, table.unpack(bundle, 3))}
if not ret[1] then
callAsyncReturn[bundle[1]]={false, ret[2]}
else
callAsyncReturn[bundle[1]]={true, table.unpack(ret,2)}
end
end
if status == "error" or coroutine.status(kernelCoro) == "dead" then
if EFI.status=="reboot" then
apis.os.reboot()
elseif EFI.status=="shutdown" then
apis.os.shutdown()
end
displaySuperBadError("Kernel error: " .. tostring(err))
coroutine.yield("key")
elseif status == "success" then
if EFI.status=="reboot" then
apis.os.reboot()
elseif EFI.status=="shutdown" then
apis.os.shutdown()
end
displaySuperBadError("Kernel error: Attempted to yield main thread\n"..debug.traceback(kernelCoro, "Attempted to yield main thread"))
coroutine.yield("key")
end
initFs:refresh()
end
end, debug.traceback)
if not ok then displaySuperBadError("Fatal error during boot: " .. err) end
while true do coroutine.yield("key") end
@@ -1 +0,0 @@
print("Hyperion OS PUC bootloader")
+1 -1
View File
@@ -1,4 +1,4 @@
U $;/boot/
F $;/boot/
V devfs0000;/dev/
V tmpfs0000;/tmp/
V procfs0000;/proc/
+6 -39
View File
@@ -74,7 +74,7 @@ function kernel.PANIC(msg)
break
end
end
EFI.status="reboot"
EFI.reboot=true
error("KERNEL PANIC")
end
kernel.panic=kernel.PANIC
@@ -139,7 +139,6 @@ end
kernel.config = config
local skip=false
local mounted={}
local root=false
for i,v in ipairs(split(fstab,"\n")) do
if v:sub(1,1)=="U" or v:sub(1,1)=="F" then
@@ -153,41 +152,13 @@ for i,v in ipairs(split(fstab,"\n")) do
if not skip then
local path=v:sub(#id+4)
if path=="/" then root=true end
mounted[id]=true
ifs.mount(id,path)
else
skip=false
end
end
end
if not root then
kernel.log("No rootdisk found, prompting user...", "WARN", 0xFF8800)
screen:setTextColor(0xDDDDDD)
screen:print("Disk to mount to /:")
local idx=1
local canadates={}
for i,v in pairs(kernel.disks) do
if not mounted[i] then
screen:print("("..idx..") : "..i)
canadates[idx]=i
idx=idx+1
end
end
while true do
EFI:yield()
local event={EFI:getMachineEvent()}
if event[1]=="keyTyped" then
if tonumber(event[3]) then
if canadates[tonumber(event[3])] then
fstab="U "..canadates[tonumber(event[3])]..";/\n"..fstab
ifs.mount(canadates[tonumber(event[3])], "/")
break
end
end
screen:print(event[1], event[3])
end
end
end
if not root then kernel.panic("No disk mounted to /") end
kernel.log("Disks initialized")
function kernel.saveLog()
@@ -358,7 +329,7 @@ kernel.perTaskHooks={}
kernel.mainHooks={}
kernel.runhooks={}
-- args {taskobj, pid}
-- args {taskobj}
function kernel.execPerTask(func, prior)
if not kernel.perTaskHooks[prior] then kernel.perTaskHooks[prior]={} end
kernel.perTaskHooks[prior][#kernel.perTaskHooks[prior]+1] = func
@@ -459,7 +430,6 @@ kernel.syscalls["saveLog"]=function()
end
end
ifs.writeAllText("/boot/fstab", fstab)
kernel.saveLog()
kernel.log("Running modules")
for _,p in ipairs(modules) do
@@ -471,7 +441,7 @@ for _,p in ipairs(modules) do
if not code then
kernel.panic("Failed to read module "..v)
end
local func,err=load(code,"@"..v,"t",_G)
local func,err=load(code,"@"..v)
if not func then kernel.panic("ModuLoadErr: "..tostring(err)) end
local status, err = xpcall(func,debug.traceback, kernel)
if not status then kernel.panic("ModuRunErr: "..tostring(err)) end
@@ -502,13 +472,10 @@ if kernel.status=="panic" then
kernel.panic(kernel.reason)
end
if kernel.status=="reboot" then
EFI.status="reboot"
EFI.reboot=true
return true
elseif kernel.status=="halt" then
kernel.log("System halted.")
kernel.saveLog()
while true do EFI:yield() end
else
EFI.status="shutdown"
return true
while true do end
end
@@ -2,16 +2,6 @@
--- @diagnostic disable: duplicate-set-field
local kernel = ...
kernel.allowGlobalOverwrites = true
local oldtype = type
local oldgetmetatable = getmetatable
function math.round(x)
if x>=0 then
return math.floor(x+0.5)
else
return math.ceil(x-0.5)
end
end
function string.hasSuffix(str, suffix)
return string.sub(str, #suffix + 1) == suffix
@@ -80,10 +70,6 @@ function table.hasVal(tabl, query)
return false
end
function table.readOnly(tabl, typ)
return setmetatable({},{__index=tabl,__newindex=function()error("Table is read-only")end,__usermeta=false,__type=typ})
end
local function serialize(tbl, seen)
seen = seen or {}
@@ -114,8 +100,6 @@ local function serialize(tbl, seen)
output = output .. "\"" .. tostring(v) .. "\""
elseif type(v) == "thread" then
output = output .. "\"" .. tostring(v) .. "\""
elseif oldgetmetatable(v) and oldgetmetatable(v).__tostring then
output = output .. tostring(v)
else
error("serialization of type \"" .. type(v) .. "\" is not supported")
end
@@ -127,6 +111,8 @@ local function serialize(tbl, seen)
return output
end
local oldtype = type
local oldgetmetatable = getmetatable
function type(object, trueType)
if trueType then return oldtype(object) end
if oldtype(object) ~= "table" then
@@ -145,7 +131,7 @@ end
function getmetatable(object)
if oldtype(object) ~= "table" then return end
if oldtype(oldgetmetatable(object)) == "table" then
if oldgetmetatable(object).__usermeta then
if oldgetmetatable(object).__isuserdata then
if oldtype(oldgetmetatable(object).__usermeta) == "function" then
return oldgetmetatable(object).__usermeta()
else
@@ -265,6 +251,8 @@ local function makeSyscallProxy()
local backing = {}
return setmetatable(backing, {
__index = function(self, name)
local raw = rawget(self, name)
if raw ~= nil then return raw end
return function(...)
local res = table.pack(coroutine.yield("syscall", name, ...))
if res[1] then
@@ -275,7 +263,7 @@ local function makeSyscallProxy()
end
end,
__newindex = function(self, k, v)
error("Table is read-only")
rawset(self, k, v)
end,
__metatable=false
})
@@ -283,5 +271,6 @@ end
syscall = makeSyscallProxy()
table.serialize = serialize
_makeSyscallProxy = makeSyscallProxy
table.serialize = serialize
@@ -299,7 +299,6 @@ local function namei(path, noFollow, symDepth)
if not target or target == "" then
error("ENOENT: empty symlink target")
end
if kernel.config.logSymlinkTraverse then kernel.log(curPath .. " > " .. target) end
local symIsAbs, symTokens = tokenizePath(target)
@@ -694,7 +693,7 @@ function vfs.open(path, mode)
if disk:type(diskPath) ~= "directory" then
handle = disk:open(diskPath, mode)
if type(handle, true) ~= "table" then
error("ENFILE".." KERR="..type(handle,true))
error("ENFILE")
end
end
@@ -1069,9 +1068,8 @@ function vfs.chown(path, uid, gid)
if kernel.unixSockets[namei(path)] then error("EINVAL") end
local disk = resolveMount(path)
if disk:isReadOnly() then error("ERDONLY") end
local meta = getFileMeta(path)
local euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
if euid ~= 0 and euid ~= meta.owner then error("EPERM") end
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
if _euid ~= 0 then error("EPERM") end
updateMeta(path, function(e) e.owner = uid; e.group = gid end)
end
@@ -1159,27 +1157,7 @@ function vfs.devlst(fd)
return table.keys(kernel.currentTask.fd[fd].handle)
end
function vfs.getOpenFds()
local out={}
for i,v in ipairs(kernel.currentTask.fd) do
out[i]=v.path
end
return out
end
function vfs.fsinfo()
local out={mounts={},disks={}}
for i,v in pairs(vfs.mounts) do
out.mounts[i]=v
end
for i,v in pairs(vfs.disks) do
out.disks[i]={size=vfs.disks[i].spaceTotal(),used=vfs.disks[i].spaceUsed(),label=vfs.disks[i].getLabel(),readOnly=vfs.disks[i].isReadOnly(),isVirt=vfs.disks[i].isvirt,address=vfs.disks[i].addressz}
end
return out
end
vfs.resolveMount = resolveMount
vfs.updateMeta = updateMeta
local sys = kernel.syscalls
sys["open"] = vfs.open
@@ -1219,7 +1197,5 @@ sys["fget_suid"] = function(fd)
local fobj = kernel.currentTask and kernel.currentTask.fd[fd]
return fobj and fobj.suid_owner or nil
end
sys["getOpenFds"]= vfs.getOpenFds
sys["fsinfo"] = vfs.fsinfo
kernel.log("VFS module loaded")
@@ -7,12 +7,8 @@ kernel.searchpaths = {
}
kernel.reqcache = cache
local function wrap(lib)
return setmetatable({},{__index=lib,__newindex=function()error("Table is read-only")end,__usermeta=false,__call=function(s,...) return lib.new(...) end})
end
local function require(module, ...)
if cache[module] then return wrap(cache[module].ret) end
if cache[module] then return cache[module].ret end
local args = {...}
for _, path in ipairs(kernel.searchpaths) do
local filepath = path:gsub("?", module)
@@ -40,8 +36,8 @@ local function require(module, ...)
if not ok then
error("Error running module "..module..": "..tostring(ret))
end
cache[module] = {ret = ret}
return wrap(ret)
cache[module] = {ret = ret, expires = kernel.EFI:getEpochMs() + 120000}
return ret
end
coroutine.yield()
end
@@ -103,7 +103,7 @@ local function newtaskproxy(task)
children[tostring(v.pid)]="/proc/"..tostring(v.pid)
end
return {
[".meta"]=strFile(buildMeta({cwd=task.cwd,parent="/proc/"..tostring(task.parent.pid),root=task.root or "/"})),
[".meta"]=strFile(buildMeta({cwd=task.cwd,parent="/proc/"..tostring(task.parent.pid)})),
uid=strFile(task.uid),
comm=strFile(task.name),
fd={
@@ -115,9 +115,7 @@ local function newtaskproxy(task)
children={
[".meta"]=strFile(buildMeta(children))
},
pid=strFile(task.pid),
ivs=strFile(task.ivs),
vs=strFile(task.vs)
pid=strFile(task.pid)
}
end
@@ -1,3 +0,0 @@
--:Minify:--
local kernel = ...
@@ -1,82 +0,0 @@
--:Minify:--
local kernel = ...
local proxy = {}
local data = {}
proxy.address = "devfs0000"
proxy.isvirt = true
proxy.isReadOnly = function() return false end
proxy.spaceUsed = function() return 0 end
proxy.spaceTotal = function() return 0 end
proxy.makeDirectory = function() error("EACCES") end
proxy.remove = function() error("EACCES") end
proxy.setLabel = function() error("EACCES") end
proxy.getLabel = function() return "devfs" end
proxy.attributes = function(path) return {
size = 0,
modified = 0,
created = 0
} end
function proxy:open(path, mode)
local steps = kernel.vfs.splitPath(path)
local step = data
for i=1, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENFILE") end
step=dat
end
if type(step[steps[#steps]]) == "function" then
return step[steps[#steps]]("open", mode)
end
error("ENFILE")
end
function proxy:type(path, mode)
local steps = kernel.vfs.splitPath(path)
local step = data
if #steps == 0 then
return "directory"
end
for i=1, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENFILE") end
step=dat
end
if type(step[steps[#steps]]) == "function" then
return step[steps[#steps]]("type", mode)
end
if type(step[steps[#steps]]) == "table" then
return "directory"
end
error("ENOENT")
end
function proxy:list(path)
local steps = kernel.vfs.splitPath(path)
local step = data
if #steps == 0 then
return table.keys(data)
end
for i=1, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENOENT") end
step=dat
end
if type(step[steps[#steps]]) == "table" then
return table.keys(step[steps[#steps]])
end
error("ENOENT")
end
function proxy:fileExists(path)
local ok = pcall(function()
return self:type(path)
end)
return ok
end
kernel.sysfs={}
kernel.sysfs.proxy=proxy
kernel.disks["sysfs0000"]=proxy
@@ -37,7 +37,7 @@ kernel.execPerTask(function(task)
if task.sigq and #task.sigq ~= 0 and task.sigh then
local coro = coroutine.create(task.sigh)
local status,err=coroutine.resume(coro, table.remove(task.sigq, 1))
kernel.EFI:yield()
EFI:yeild()
if status=="error" or status==false then
task.sigd.error=err or "Unknown"
task.sigd.active=false
@@ -2,5 +2,3 @@
local kernel=...
kernel.unixSockets={}
local socket=kernel.socket
--socket.registerProtocal()
@@ -58,12 +58,10 @@ kernel._U.load = function(a,b,c,d) return origLoad(a,b,c,d or kernel._U) end
function kernel.freshUserEnv()
local locals = {}
locals.syscall = _makeSyscallProxy()
local env = setmetatable(locals, {
__index = kernel._U,
__pairs = function(self)
return pairs(kernel._U)
end,
__newindex = function(_, k, v) rawset(locals, k, v) end,
__metatable=false
})
@@ -33,7 +33,7 @@ local function createVt(id, width, height)
end
end
function vt.obj.write(content)
function vt.obj:write(content)
local x, y = vt.cursorX, vt.cursorY
if x>vt.width then return end
if y>vt.height then return end
@@ -79,36 +79,36 @@ local function createVt(id, width, height)
vt.cursorX, vt.cursorY = x, y
end
function vt.obj.spos(x, y)
function vt.obj:spos(x, y)
vt.cursorX = tonumber(x)
vt.cursorY = tonumber(y)
end
function vt.obj.gpos()
return vt.cursorX, vt.cursorY
function vt.obj:gpos()
return tostring(vt.cursorX)..";"..tostring(vt.cursorY)
end
function vt.obj.sfgc(color)
function vt.obj:sfgc(color)
vt.fgColor = tonumber(color)
end
function vt.obj.sbgc(color)
function vt.obj:sbgc(color)
vt.bgColor = tonumber(color)
end
function vt.obj.gfgc()
function vt.obj:gfgc()
return vt.fgColor
end
function vt.obj.gbgc()
function vt.obj:gbgc()
return vt.bgColor
end
function vt.obj.gplt()
function vt.obj:gplt()
return 24
end
function vt.obj.clear()
function vt.obj:clear()
for y = 1, vt.height do
for x = 1, vt.width do
vt.buffer[y][x] = {char = " ", fgColor = vt.fgColor, bgColor = vt.bgColor}
@@ -117,12 +117,12 @@ local function createVt(id, width, height)
vt.cursorX, vt.cursorY = 1, 1
end
function vt.obj.isvirt()
function vt.obj:isvirt()
return true
end
function vt.obj.gfx()
function vt.obj:gctrl()
return serializeBool(vt.ctrl)..";"..serializeBool(vt.alt)
end
return vt
@@ -108,7 +108,7 @@ function sys.spawn(func, name, envars, args, tgid, clearFds)
end
function sys.execspawn(path, name, envars, args, tgid, keepFds)
local func, euid, suid_active = loadExecutable(path)
local func, euid, suid_active = loadExecutable(path, kernel._U)
local caller = kernel.currentTask
local real_uid = caller and caller.uid or kernel.uid
@@ -124,17 +124,13 @@ function sys.execspawn(path, name, envars, args, tgid, keepFds)
return createTask(func, name or path, envars, args, tgid, real_uid, euid, not keepFds)
end
function sys.exec(path, args, envars, clearFds)
function sys.exec(path, args, envars)
local task = kernel.currentTask
local func, euid, _ = loadExecutable(path)
local func, euid, _ = loadExecutable(path, kernel._U)
-- no idea why this is here?
-- Figured it out it is to close fds on su
if clearFds then
if task.fd then
for fd, _ in pairs(task.fd) do
if fd > 2 then pcall(kernel.vfs.close, fd) end
end
if task.fd then
for fd, _ in pairs(task.fd) do
if fd > 2 then pcall(kernel.vfs.close, fd) end
end
end
@@ -1,7 +1,7 @@
--:Minify:--
local kernel=...
kernel.debug=debug
local debug=debug
kernel._G.debug={
getinfo=kernel.debug.getinfo,
traceback=kernel.debug.traceback
getinfo=debug.getinfo,
traceback=debug.traceback
}
@@ -14,22 +14,11 @@ local data = kernel.vfs.read(handle, 1024 * 1024 * 4)
if not handle then kernel.panic("Failed to read "..kernel.config.initPath) end
kernel.vfs.close(handle)
local initFunc, err = load(data, "@init", "t", kernel._U)
local initFunc, err = load(data, "@sysinit", "t", kernel._U)
if not initFunc then kernel.PANIC("Failed to load init system: " .. err) end
kernel.tasks["1"] = {
coro = coroutine.create(function()
for i,v in pairs(kernel.processes) do
kernel.log("Spawning kernel task "..i)
syscall.spawn(function()
local status, err = pcall(v)
if not status then
kernel.log("Error executing kernel task '" .. i .. "': " .. err, "ERROR", 0xFF0000)
else
kernel.log("Successfully executed kernel task: " .. i)
end
end, i, nil,nil,nil,true)
end
local ok, err = xpcall(initFunc, debug.traceback, kernel)
if not ok then
kernel.panic("Init system crashed: " .. tostring(err))
@@ -39,7 +28,7 @@ kernel.tasks["1"] = {
kernel.saveLog()
end),
name = "init",
name = "sysinit",
status = "R",
pid = 1,
tgid = 1,
@@ -2,11 +2,11 @@
local kernel = ...
kernel.processes.kgc = function()
while true do
--for i,v in pairs(kernel.reqcache) do
-- if v.expires and kernel.EFI:getEpochMs() > v.expires then
-- kernel.reqcache[i] = nil
-- end
--end
for i,v in pairs(kernel.reqcache) do
if v.expires and kernel.EFI:getEpochMs() > v.expires then
kernel.reqcache[i] = nil
end
end
sleep(5)
end
end
@@ -1,12 +1,7 @@
--:Minify:--
local kernel = ...
if kernel.firstBoot or kernel.config.resetPerms then
if kernel.config.resetPerms then
kernel.log("resetPerms is active, disable it in /boot/boot.cfg", "WARN", 0xFFFF00)
end
kernel.log("Seeding filesystem permissions...")
if kernel.firstBoot then
local P = kernel.vfs.P
local PERM = kernel.vfs.PERM
@@ -19,47 +14,107 @@ if kernel.firstBoot or kernel.config.resetPerms then
local RWXRWXRWX = PERM.RWXRWXRWX
local SUID_755 = PERM.SUID_755
local function seed(root, data)
for i=1,#data do
local entry=data[i]
if kernel.vfs.exists(root..entry[1]) then
kernel.vfs.updateMeta(root..entry[1],function(e)
e.perms=entry[4]
e.group=entry[3]
e.owner=entry[2]
end)
end
local META_VERSION = 0x02
local rootDisk = kernel.disks["$"]
local function makeEntry(name, etype, owner, group, perms, cmeta)
cmeta = cmeta or ""
local plo = perms % 256
local phi = math.floor(perms / 256) % 256
local olo = (owner or 0) % 256
local ohi = math.floor((owner or 0) / 256) % 256
local glo = (group or 0) % 256
local ghi = math.floor((group or 0) / 256) % 256
return string.char(#name) .. name
.. string.char(etype, olo, ohi, glo, ghi, plo, phi)
.. string.char(#cmeta) .. cmeta
end
local REG = 0x00
local function mergeMeta(dir, entries)
local diskDir = dir
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
local existing = {}
local rok, rf = pcall(function() return rootDisk:open(metaPath, "r") end)
if rok and rf then
local raw = rf.read(65535)
if rf.close then rf.close() end
existing = (kernel.vfs._parseMetafile and kernel.vfs._parseMetafile(raw)) or {}
end
for _, e in ipairs(entries) do
local name = e[1]
local etype = e[2] or REG
local owner = e[3] or 0
local group = e[4] or 0
local perms = e[5] or RWX_RX_RX
local cmeta = e[6] or ""
existing[name] = {
etype = etype,
owner = owner,
group = group,
perms = perms,
cmeta = cmeta,
}
end
local data = string.char(META_VERSION)
for name, m in pairs(existing) do
data = data .. makeEntry(
name,
m.etype or REG,
m.owner or 0,
m.group or 0,
m.perms or RWX_RX_RX,
m.cmeta or ""
)
end
local ok, err = pcall(function()
local f = rootDisk:open(metaPath, "w")
f.write(data)
f.close()
end)
if not ok then
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 0xFF8800)
end
end
seed("/", {
{"bin", 0, 0, RWX_RX_RX},
{"boot", 0, 0, RWX_RX_RX},
{"etc", 0, 0, RWX_RX_RX},
{"home", 0, 0, RWX_RX_RX},
{"lib", 0, 0, RWX_RX_RX},
{"root", 0, 0, RW____ },
{"sbin", 0, 0, RWX_RX_RX},
{"tmp", 0, 0, RWXRWXRWX},
{"usr", 0, 0, RWX_RX_RX},
{"var", 0, 0, RWXRWXRWX},
{"opt", 0, 0, RWX_RX_RX},
kernel.log("Seeding filesystem permissions...")
mergeMeta("/", {
{"bin", REG, 0, 0, RWX_RX_RX},
{"boot", REG, 0, 0, RWX_RX_RX},
{"dev", REG, 0, 0, RWXRWXRWX},
{"etc", REG, 0, 0, RWX_RX_RX},
{"home", REG, 0, 0, RWX_RX_RX},
{"lib", REG, 0, 0, RWX_RX_RX},
{"proc", REG, 0, 0, RWXRWXRWX},
{"root", REG, 0, 0, RW____ },
{"sbin", REG, 0, 0, RWX_RX_RX},
{"tmp", REG, 0, 0, RWXRWXRWX},
{"usr", REG, 0, 0, RWX_RX_RX},
{"var", REG, 0, 0, RWXRWXRWX},
{"opt", REG, 0, 0, RWX_RX_RX},
})
seed("/bin/", {
{"login", 0, 0, SUID_755 },
{"su", 0, 0, SUID_755 },
{"sudo", 0, 0, SUID_755 },
mergeMeta("/bin", {
{"login", REG, 0, 0, SUID_755 },
{"su", REG, 0, 0, SUID_755 },
{"sudo", REG, 0, 0, SUID_755 },
})
seed("/etc/", {
{"passwd", 0, 0, RW_R_R },
{"shadow", 0, 0, RW____ },
{"pam.d", 0, 0, RW____ },
mergeMeta("/etc", {
{"passwd", REG, 0, 0, RW_R_R },
{"shadow", REG, 0, 0, RW____ },
{"pam.d", REG, 0, 0, RW____ },
})
seed("/etc/pam.d/", {
{"secret", 0, 0, RW____},
mergeMeta("/etc/pam.d", {
{"secret", REG, 0, 0, RW____},
})
kernel.log("Filesystem permissions seeded.")
+1 -1
View File
@@ -1 +1 @@
1.2.4
1.5.0
-1
View File
@@ -1 +0,0 @@
Hyperion
-2
View File
@@ -1,2 +0,0 @@
Hyperion-kernel
Hyperion-core
-1
View File
@@ -1 +0,0 @@
HyperionOS install package-group
-1
View File
@@ -1 +0,0 @@
1.2.4
-1
View File
@@ -1 +0,0 @@
Hyperion
-10
View File
@@ -1,10 +0,0 @@
Hyperion-kernel
Hyperion-core
coreutils
spm
sysinit
hysh
lua
micro
Hypersplash
math
-1
View File
@@ -1 +0,0 @@
HyperionOS install package-group
-1
View File
@@ -1 +0,0 @@
1.2.4
-1
View File
@@ -1 +0,0 @@
Hyperion
-6
View File
@@ -1,6 +0,0 @@
Hyperion-kernel
Hyperion-core
coreutils
hysh
lua
wget
-1
View File
@@ -1 +0,0 @@
HyperionOS install package-group
-1
View File
@@ -1 +0,0 @@
1.2.4
+2 -5
View File
@@ -3,7 +3,6 @@ syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0)
syscall.open("/dev/tty/1", "w") --stdout (fd 1)
syscall.open("/dev/null", "w") --stderr (fd 2)
local fs=require("fs")
local MAX_ATTEMPTS = 3
@@ -101,9 +100,7 @@ local function spawnShell(username, uid, shell, homedir)
pcall(syscall.chdir, "/")
end
local shellfunc, err = load(fs.readAllText(shell))
local ok, err = pcall(syscall.spawn, shellfunc, username .. ":shell", nil,nil,nil,true)
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell")
if not ok then
syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n")
sleep(2)
@@ -148,7 +145,7 @@ local function doLogin()
syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.3)
pcall(spawnShell, username, uid, shell, homedir)
spawnShell(username, uid, shell, homedir)
return -- back to login prompt
else
attempts = attempts + 1
+1 -1
View File
@@ -58,7 +58,7 @@ syscall.setEnviron("HOME", homedir)
syscall.setEnviron("USER", username)
syscall.setEnviron("SHELL", shell)
local ok, err = pcall(syscall.exec, shell, nil, true)
local ok, err = pcall(syscall.exec, shell)
if not ok then
print("su: cannot exec shell '" .. shell .. "': " .. tostring(err))
syscall.exit(1)
+2 -5
View File
@@ -3,7 +3,6 @@ syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0)
syscall.open("/dev/tty/1", "w") --stdout (fd 1)
syscall.open("/dev/null", "w") --stderr (fd 2)
local fs=require("fs")
local MAX_ATTEMPTS = 3
@@ -101,9 +100,7 @@ local function spawnShell(username, uid, shell, homedir)
pcall(syscall.chdir, "/")
end
local shellfunc, err = load(fs.readAllText(shell))
local ok, err = pcall(syscall.spawn, shellfunc, username .. ":shell", nil,nil,nil,true)
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell")
if not ok then
syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n")
sleep(2)
@@ -148,7 +145,7 @@ local function doLogin()
syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.3)
pcall(spawnShell, username, uid, shell, homedir)
spawnShell(username, uid, shell, homedir)
return -- back to login prompt
else
attempts = attempts + 1
-1
View File
@@ -1 +0,0 @@
vector
-19
View File
@@ -1,19 +0,0 @@
function lib.load(fd)
function handle.setPixel(x,y,color24)
function handle.getPixel(x,y)
function handle.setPixels(x,y,w,framebuffer)
function handle.getPixels(x,y,w,h)
function handle.frame(x,y,w,h,writeonly)
integer id
recurse lib.load
function handle.framectl(id)
function frame.move(x,y)
function frame.resize(w,h)
function frame.free()
function handle.sync()
function handle.line(x1,y1,x2,y2)
function handle.box(x,y,w,h,c,fill)
function handle.filledBox(x,y,w,h,c)
function handle.text(x,y,font,text)
function handle.free()
function handle.size()
View File
Whitespace-only changes.
File renamed without changes.
+40
View File
@@ -0,0 +1,40 @@
--:Minify:--
local lib = {}
function lib.frame(frame)
local handle = {}
function handle.setPixel(x,y,color24)
end
function handle.getPixel(x,y)
end
function handle.setPixels(x,y,framebuffer)
end
function handle.getPixels(x,y,w,h)
end
function handle.frame(x,y,w,h,writeonly)
end
function handle.framectl(id,x,y,w,h,writeonly)
end
function handle.drawframe()
end
function handle.line()
end
return handle
end
File renamed without changes.
File renamed without changes.
File renamed without changes.
+350
View File
@@ -0,0 +1,350 @@
term.setGraphicsMode(2)
local w,h = term.getSize(2)
local fb={}
for i=1, h do
fb[i]={}
for x=1, w do
fb[i][x]=0
end
end
local function setPixel(x,y,c)
--local old=fb[y]
--fb[y]=string.sub(old,1,x-1)..string.char(c)..string.sub(old,x+1)
fb[y][x]=c
end
local function setPixels(x,y,frame)
local w,h = #fb[1], #fb
for i=1, #frame do
for j=1, #frame[i] do
fb[y+i-1][x+j-1]=frame[i][j]
end
end
end
local function getPixel(x,y)
return fb[y][x]
end
local function getPixels(x,y,w,h)
local ret={}
for i=y, y+h do
ret[#ret+1] = {table.unpack(fb[i], x, x+w)}
end
return ret
end
local colors = {
[0]=0x000000,
0x0b0b0b,
0x222222,
0x444444,
0x555555,
0x777777,
0x888888,
0xaaaaaa,
0xbbbbbb,
0xdddddd,
0xeeeeee,
0x00000b,
0x000022,
0x000044,
0x000055,
0x000077,
0x000088,
0x0000aa,
0x0000bb,
0x0000dd,
0x0000ee,
0x000b00,
0x002200,
0x004400,
0x005500,
0x007700,
0x008800,
0x00aa00,
0x00bb00,
0x00dd00,
0x00ee00,
0x0b0000,
0x220000,
0x440000,
0x550000,
0x770000,
0x880000,
0xaa0000,
0xbb0000,
0xdd0000,
0xee0000,
0x000033,
0x000066,
0x000099,
0x0000cc,
0x0000ff,
0x003300,
0x003333,
0x003366,
0x003399,
0x0033cc,
0x0033ff,
0x006600,
0x006633,
0x006666,
0x006699,
0x0066cc,
0x0066ff,
0x009900,
0x009933,
0x009966,
0x009999,
0x0099cc,
0x0099ff,
0x00cc00,
0x00cc33,
0x00cc66,
0x00cc99,
0x00cccc,
0x00ccff,
0x00ff00,
0x00ff33,
0x00ff66,
0x00ff99,
0x00ffcc,
0x00ffff,
0x330000,
0x330033,
0x330066,
0x330099,
0x3300cc,
0x3300ff,
0x333300,
0x333333,
0x333366,
0x333399,
0x3333cc,
0x3333ff,
0x336600,
0x336633,
0x336666,
0x336699,
0x3366cc,
0x3366ff,
0x339900,
0x339933,
0x339966,
0x339999,
0x3399cc,
0x3399ff,
0x33cc00,
0x33cc33,
0x33cc66,
0x33cc99,
0x33cccc,
0x33ccff,
0x33ff00,
0x33ff33,
0x33ff66,
0x33ff99,
0x33ffcc,
0x33ffff,
0x660000,
0x660033,
0x660066,
0x660099,
0x6600cc,
0x6600ff,
0x663300,
0x663333,
0x663366,
0x663399,
0x6633cc,
0x6633ff,
0x666600,
0x666633,
0x666666,
0x666699,
0x6666cc,
0x6666ff,
0x669900,
0x669933,
0x669966,
0x669999,
0x6699cc,
0x6699ff,
0x66cc00,
0x66cc33,
0x66cc66,
0x66cc99,
0x66cccc,
0x66ccff,
0x66ff00,
0x66ff33,
0x66ff66,
0x66ff99,
0x66ffcc,
0x66ffff,
0x990000,
0x990033,
0x990066,
0x990099,
0x9900cc,
0x9900ff,
0x993300,
0x993333,
0x993366,
0x993399,
0x9933cc,
0x9933ff,
0x996600,
0x996633,
0x996666,
0x996699,
0x9966cc,
0x9966ff,
0x999900,
0x999933,
0x999966,
0x999999,
0x9999cc,
0x9999ff,
0x99cc00,
0x99cc33,
0x99cc66,
0x99cc99,
0x99cccc,
0x99ccff,
0x99ff00,
0x99ff33,
0x99ff66,
0x99ff99,
0x99ffcc,
0x99ffff,
0xcc0000,
0xcc0033,
0xcc0066,
0xcc0099,
0xcc00cc,
0xcc00ff,
0xcc3300,
0xcc3333,
0xcc3366,
0xcc3399,
0xcc33cc,
0xcc33ff,
0xcc6600,
0xcc6633,
0xcc6666,
0xcc6699,
0xcc66cc,
0xcc66ff,
0xcc9900,
0xcc9933,
0xcc9966,
0xcc9999,
0xcc99cc,
0xcc99ff,
0xcccc00,
0xcccc33,
0xcccc66,
0xcccc99,
0xcccccc,
0xccccff,
0xccff00,
0xccff33,
0xccff66,
0xccff99,
0xccffcc,
0xccffff,
0xff0000,
0xff0033,
0xff0066,
0xff0099,
0xff00cc,
0xff00ff,
0xff3300,
0xff3333,
0xff3366,
0xff3399,
0xff33cc,
0xff33ff,
0xff6600,
0xff6633,
0xff6666,
0xff6699,
0xff66cc,
0xff66ff,
0xff9900,
0xff9933,
0xff9966,
0xff9999,
0xff99cc,
0xff99ff,
0xffcc00,
0xffcc33,
0xffcc66,
0xffcc99,
0xffcccc,
0xffccff,
0xffff00,
0xffff33,
0xffff66,
0xffff99,
0xffffcc,
0xffffff,
}
for i=0,255 do
term.setPaletteColor(i,colors[i])
end
term.drawPixels(0,0,fb)
for i=0,255 do
for y=1+i, h-i do
for x=1+i, w-i do
setPixel(x,y,i)
end
end
term.drawPixels(1,1,fb)
os.queueEvent("nosleep")
os.pullEvent()
end
for i=1, 1000 do
pcall(function()
setPixels(math.random(1,w),math.random(1,h),getPixels(math.random(1,w),math.random(1,h),math.random(1,w),math.random(1,h)))
end)
term.drawPixels(1,1,fb)
os.queueEvent("nosleep")
os.pullEvent()
end
setPixels(1,1,getPixels(w-50,h-50,50,50))
term.drawPixels(0,0,fb)
local i=0
for x=1, 16*4, 4 do
for y=1, 16*4, 4 do
setPixel(x,y,i)
setPixel(x+1,y,i)
setPixel(x+2,y,i)
setPixel(x+3,y,i)
setPixel(x,y+1,i)
setPixel(x+1,y+1,i)
setPixel(x+2,y+1,i)
setPixel(x+3,y+1,i)
setPixel(x,y+2,i)
setPixel(x+1,y+2,i)
setPixel(x+2,y+2,i)
setPixel(x+3,y+2,i)
setPixel(x,y+3,i)
setPixel(x+1,y+3,i)
setPixel(x+2,y+3,i)
setPixel(x+3,y+3,i)
i=i+1
end
end
term.drawPixels(0,0,fb)
sleep(5)
term.setGraphicsMode(false)
File renamed without changes.
+8 -13
View File
@@ -6,7 +6,6 @@ syscall.open("/dev/tty/1","w") --stdout (Device 1)
syscall.open("/dev/null","w") --stderr (device 2)
local fs = require("fs")
local gfx = syscall.devctl(1,"gfx")
syscall.devctl(1,"clear")
syscall.devctl(1,"sfgc",0xFFFFFF)
@@ -243,7 +242,6 @@ builtinCmds.clear = function()
syscall.devctl(1,"clear")
syscall.devctl(1,"sfgc",0xFFFFFF)
syscall.devctl(1,"spos",1,1)
if gfx then local w,h=gfx.size() gfx.box(0,0,w+5,h+5,0,true) end
end
builtinCmds.whoami = function()
@@ -822,11 +820,10 @@ builtinCmds.df = function(...)
end
local function fmt(n) return opts.h and hfmt(n) or tostring(n) end
print(string.format("%-20s %10s %10s %10s %6s %-s","Filesystem","Size","Used","Avail","Use%","Mounted on"))
local fsinfo = syscall.fsinfo()
for id, obj in pairs(fsinfo.disks) do
local use = ((obj.size/obj.used)-1)*100
local avail = obj.size-obj.used
print(string.format("%-20s %10s %10s %10s %6s %-s", id, tostring(obj.size), tostring(obj.used), avail, tostring(use).."%", fsinfo.mounts[id] or ""))
local mounts = {{"$","/"}, {"devfs0000","/dev/"}, {"tmpfs0000","/tmp/"}}
for _, m in ipairs(mounts) do
local id, mp = m[1], m[2]
print(string.format("%-20s %10s %10s %10s %6s %-s", id, "?", "?", "?", "?%", mp))
end
end
@@ -1209,26 +1206,24 @@ local function runCommand(command)
local proc = syscall.spawn(function()
-- Open standard fds so programs that don't do it themselves work correctly.
--syscall.open("/proc/self/parent/fd/0", "r") -- fd 0 stdin
--syscall.open("/proc/self/parent/fd/1", "w") -- fd 1 stdout
--syscall.open("/proc/self/parent/fd/2", "w") -- fd 2 stderr
syscall.open("/proc/self/parent/fd/0", "r") -- fd 0 stdin
syscall.open("/proc/self/parent/fd/1", "w") -- fd 1 stdout
syscall.open("/proc/self/parent/fd/2", "w") -- fd 2 stderr
-- exec replaces this coroutine's code with a fresh isolated environment
-- compiled from disk by the kernel (via loadExecutable -> freshUserEnv),
-- so the child cannot share any upvalue or syscall table state with hysh.
syscall.exec(cmdPath, {table.unpack(args, 2)})
end, progName)
end, progName, nil, nil, nil, true)
while true do
local exited, code = syscall.collect(proc)
if exited then
if gfx then gfx.setMode(false) end
if code then print("\nTask exited with code:\n"..tostring(code)) end
return
end
if terminate then
local ok2 = syscall.kill(proc, true)
if ok2 then
if gfx then gfx.setMode(false) end
syscall.devctl(1,"sbgc",16); syscall.devctl(1,"sfgc",0xFF0000)
print("\nProgram Terminated."); syscall.devctl(1,"sfgc",0xFFFFFF)
end
File renamed without changes.
File renamed without changes.
+1
View File
@@ -0,0 +1 @@
Hyperion os live installer
File renamed without changes.
+4 -6
View File
@@ -173,8 +173,6 @@ end
local luaEnv = setmetatable({}, {__index = _ENV})
luaEnv._G = luaEnv
luaEnv._ENV = _ENV
luaEnv._G = _G
luaEnv.print = function(...)
local n = select("#", ...)
@@ -261,9 +259,9 @@ local function getUserInput(prompt, history)
local key = syscall.read(0)
if key and key ~= "" then
if key == "" then
if cursor > 1 then cursor = cursor + 1; dirty = true end
if cursor > 1 then cursor = cursor - 1; dirty = true end
elseif key == "" then
if cursor <= #input then cursor = cursor - 1; dirty = true end
if cursor <= #input then cursor = cursor + 1; dirty = true end
elseif key == "" then
if history and histIdx < #history then
histIdx = histIdx + 1
@@ -300,9 +298,9 @@ local function getUserInput(prompt, history)
end
c(C_PROMPT); w("HyperionOS " .. _VERSION .. "\n")
w("Interactive Lua REPL. Type \"exit()\" to exit.\n")
w("Type \"exit()\" to exit.")
c(C_NIL)
w("\n\n")
w("Interactive Lua REPL. exit() to quit.\n\n")
c(1)
local history = {}
-217
View File
@@ -1,217 +0,0 @@
--:Minify:--
local lib={}
local function check(a,b,ignoreb)
if type(a)~="vector" then error("vector metatable is on non vector object") end
if not ignoreb and b~=nil then
if type(b)~="vector" then error("b must be vector") end
if #a~=#b then error("vectors must be same size") end
end
end
local vector={
add = function(a,b)
check(a,b)
local ret={}
for i=1, #a do
ret[i]=a[i]+b[i]
end
return lib.convert(ret)
end,
sub = function(a,b)
check(a,b)
if type(b)~="vector" then error("b must be vector") end
local ret={}
for i=1, #a do
ret[i]=a[i]-b[i]
end
return lib.convert(ret)
end,
unm = function(a)
local ret={}
for i=1, #a do
ret[i]=-a[i]
end
return lib.convert(ret)
end,
mul = function(a,b)
if type(a)=="number" and type(b)=="vector" then a,b=b,a end
check(a,b,true)
local ret={}
if type(b)=="vector" then
for i=1, #a do
ret[i]=a[i]*b[i]
end
elseif type(b)=="number" then
for i=1, #a do
ret[i]=a[i]*b
end
else
error("b must be vector or number")
end
return lib.convert(ret)
end,
div = function(a,b)
if type(a)=="number" and type(b)=="vector" then a,b=b,a end
check(a,b,true)
local ret={}
if type(b)=="vector" then
for i=1, #a do
ret[i]=a[i]/b[i]
end
elseif type(b)=="number" then
for i=1, #a do
ret[i]=a[i]/b
end
else
error("b must be vector or number")
end
return lib.convert(ret)
end,
dot = function(a,b)
check(a,b)
local out=a[1]*b[1]
for i=2, #a do
out=out+a[i]*b[i]
end
return out
end,
tostring = function(a)
check(a)
local out = "{"
for i=1, #a do
out=out..tostring(a[i])..", "
end
return out:sub(1,#out-2).."}"
end,
equals = function(a,b)
check(a,b)
for i=1, #a do
if a[i]~=b[i] then
return false
end
end
return true
end,
cross = function(a,b)
check(a,b)
if #a~=3 then error("Vectors must be of type 'vec3'") end
if #b~=3 then error("Vectors must be of type 'vec3'") end
return lib.convert({
a.y*b.z-a.z*b.y,
a.z*b.x-a.x*b.z,
a.x*b.y-a.y*b.x
})
end,
length = function(a)
check(a)
local out=a[1]*a[1]
for i=2, #a do
out=out+a[i]*a[i]
end
if type(out)=="vector" then
return out:sqrt()
else
return math.sqrt(out)
end
end,
len = function(a)
return a:length()
end,
normalize = function(a)
return a*(1/a:len())
end,
round = function(a, t)
check(a)
local ret={}
for i=1, #a do
ret[i]=math.floor((a[i]+t*0.5)/t)*t
end
return lib.convert(ret)
end,
exp = function(a, e)
check(a)
local ret={}
for i=1, #a do
ret[i]=a^e
end
return lib.convert(ret)
end,
sqrt = function(a)
check(a)
local ret={}
for i=1, #a do
if type(a[i])=="vector" then
ret[i]=a[i]:sqrt()
else
ret[i]=math.sqrt(a[i])
end
end
return lib.convert(ret)
end
}
local idxtable={
w=4,
x=1,
y=2,
z=3,
}
local function index(self, k)
if idxtable[k] then
return rawget(self,idxtable[k])
elseif vector[k] then
return vector[k]
else
return rawget(self,k)
end
end
local function newindex(self, k, v)
if idxtable[k] then
rawset(self, idxtable[k], v)
else
rawset(self, k, v)
end
end
local meta={
__name="vector",
__type="vector",
__usermeta=function() error("EACCES") end,
__index=index,
__newindex=newindex,
__unm=vector.unm,
__add=vector.add,
__sub=vector.sub,
__mul=vector.mul,
__div=vector.div,
__tostring=vector.tostring,
__eq=vector.equals
}
function lib.new(...)
local vars={...}
return setmetatable(vars,meta)
end
function lib.convert(vars)
return setmetatable(vars,meta)
end
return lib
-217
View File
@@ -1,217 +0,0 @@
--:Minify:--
local lib={}
local function check(a,b,ignoreb)
if type(a)~="vector" then error("a must be vector") end
if not ignoreb and b~=nil then
if type(b)~="vector" then error("b must be vector") end
if #a~=#b then error("vectors must be same size") end
end
end
local vector={
add = function(a,b)
check(a,b)
local ret={}
for i=1, #a do
ret[i]=a[i]+b[i]
end
return lib.convert(ret)
end,
sub = function(a,b)
check(a,b)
if type(b)~="vector" then error("b must be vector") end
local ret={}
for i=1, #a do
ret[i]=a[i]-b[i]
end
return lib.convert(ret)
end,
unm = function(a)
local ret={}
for i=1, #a do
ret[i]=-a[i]
end
return lib.convert(ret)
end,
mul = function(a,b)
if type(a)=="number" and type(b)=="vector" then a,b=b,a end
check(a,b,true)
local ret={}
if type(b)=="vector" then
for i=1, #a do
ret[i]=a[i]*b[i]
end
elseif type(b)=="number" then
for i=1, #a do
ret[i]=a[i]*b
end
else
error("b must be vector or number")
end
return lib.convert(ret)
end,
div = function(a,b)
if type(a)=="number" and type(b)=="vector" then a,b=b,a end
check(a,b,true)
local ret={}
if type(b)=="vector" then
for i=1, #a do
ret[i]=a[i]/b[i]
end
elseif type(b)=="number" then
for i=1, #a do
ret[i]=a[i]/b
end
else
error("b must be vector or number")
end
return lib.convert(ret)
end,
dot = function(a,b)
check(a,b)
local out=a[1]*b[1]
for i=2, #a do
out=out+a[i]*b[i]
end
return out
end,
tostring = function(a)
check(a)
local out = "{"
for i=1, #a do
out=out..tostring(a[i])..", "
end
return out:sub(1,#out-2).."}"
end,
equals = function(a,b)
check(a,b)
for i=1, #a do
if a[i]~=b[i] then
return false
end
end
return true
end,
cross = function(a,b)
check(a,b)
if #a~=3 then error("Vectors must be of type 'vec3'") end
if #b~=3 then error("Vectors must be of type 'vec3'") end
return lib.convert({
a.y*b.z-a.z*b.y,
a.z*b.x-a.x*b.z,
a.x*b.y-a.y*b.x
})
end,
length = function(a)
check(a)
local out=a[1]*a[1]
for i=2, #a do
out=out+a[i]*a[i]
end
if type(out)=="vector" then
return out:sqrt()
else
return math.sqrt(out)
end
end,
len = function(a)
return a:length()
end,
normalize = function(a)
return a*(1/a:len())
end,
round = function(a, t)
check(a)
local ret={}
for i=1, #a do
ret[i]=math.floor((a[i]+t*0.5)/t)*t
end
return lib.convert(ret)
end,
exp = function(a, e)
check(a)
local ret={}
for i=1, #a do
ret[i]=a^e
end
return lib.convert(ret)
end,
sqrt = function(a)
check(a)
local ret={}
for i=1, #a do
if type(a[i])=="vector" then
ret[i]=a[i]:sqrt()
else
ret[i]=math.sqrt(a[i])
end
end
return lib.convert(ret)
end
}
local idxtable={
w=4,
x=1,
y=2,
z=3,
}
local function index(self, k)
if idxtable[k] then
return rawget(self,idxtable[k])
elseif vector[k] then
return vector[k]
else
return rawget(self,k)
end
end
local function newindex(self, k, v)
if idxtable[k] then
rawset(self, idxtable[k], v)
else
rawset(self, k, v)
end
end
local meta={
__name="vector",
__type="vector",
__usermeta=function() error("EACCES") end,
__index=index,
__newindex=newindex,
__unm=vector.unm,
__add=vector.add,
__sub=vector.sub,
__mul=vector.mul,
__div=vector.div,
__tostring=vector.tostring,
__eq=vector.equals
}
function lib.new(...)
local vars={...}
return setmetatable(vars,meta)
end
function lib.convert(vars)
return setmetatable(vars,meta)
end
return lib
-3
View File
@@ -1,3 +0,0 @@
General advanced math libs
VectorX
Matrix
-1
View File
@@ -1 +0,0 @@
1.0.0
-124
View File
@@ -1,124 +0,0 @@
local args={...}
if #args<1 then print("Usage: render3d [file.obj]") end
local fs=require("fs")
local vec=require("vector")
local gfx=syscall.devctl(1,"gfx")
local file = fs.readAllText(args[1])
local obj={v={},f={}}
local lines=string.split(file, "\n")
for i=1, #lines do
local line=lines[i]
if line:sub(1,2)=="v " then
line=line:sub(3)
local s=string.split(line, " ")
obj.v[#obj.v+1]=vec(tonumber(s[1]),tonumber(s[2]),tonumber(s[3]))
elseif line:sub(1,2)=="f " then
line=line:sub(3)
local s=string.split(line, " ")
local vs={}
for c=1, #s do
local v=string.split(s[c], "/")
vs[#vs+1]=tonumber(v[1])
end
obj.f[#obj.f+1]=vec(table.unpack(vs))
end
end
print("Vertices")
for i=1, #obj.v do
print(obj.v[i])
end
print("Faces")
for i=1, #obj.f do
print(obj.f[i])
end
local function projectPoint(point, cameraPos, cameraRot, fov, width, height)
local p=point-cameraPos
local pitch=cameraRot.x
local yaw=cameraRot.y
local cp=math.cos(pitch)
local sp=math.sin(pitch)
local cy=math.cos(yaw)
local sy=math.sin(yaw)
local right=vec(
cy,
0,
-sy
)
local up=vec(
sy*sp,
cp,
cy*sp
)
local forward=vec(
-sy*cp,
sp,
-cy*cp
)
local x=p:dot(right)
local y=p:dot(up)
local z=p:dot(forward)
if z<=0 then
return nil
end
local aspect=width/height
local f=1/math.tan(fov*0.5)
local sx=(x*f/aspect)/z
local sy=(y*f)/z
return vec(
(sx+1)*0.5*width,
(1-sy)*0.5*height
),z
end
local proj={}
local camera=vec(0,0,3)
local rot=vec(0,0,0)
local w,h=gfx.size()
local fov=math.rad(90)
for i=1, #obj.v do
proj[i]={}
proj[i].p,proj[i].z=projectPoint(obj.v[i],camera,rot,fov,w,h)
end
print("Projected")
for i=1, #proj do
print(proj[i].p)
end
gfx.setMode(true)
for i=#obj.f, 1, -1 do
local f=obj.f[i]
local c=math.random(0,0xffffff)
for p=1, #f do
if p~=#f then
print(tostring(proj[f[p]].p.x)..","..tostring(proj[f[p]].p.y).." > "..tostring(proj[f[p+1]].p.x)..","..tostring(proj[f[p+1]].p.y))
gfx.line(proj[f[p]].p.x,proj[f[p]].p.y,proj[f[p+1]].p.x,proj[f[p+1]].p.y,c)
else
print(tostring(proj[f[p]].p.x)..","..tostring(proj[f[p]].p.y).." > "..tostring(proj[f[1]].p.x)..","..tostring(proj[f[1]].p.y))
gfx.line(proj[f[p]].p.x,proj[f[p]].p.y,proj[f[1]].p.x,proj[f[1]].p.y,c)
end
end
end
while true do
sleep(5)
end
@@ -1,40 +0,0 @@
# Blender 5.2.2 LTS
# www.blender.org
mtllib box.mtl
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
s 0
usemtl Material
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6
+7 -20
View File
@@ -97,7 +97,6 @@ local spm = function(...)
i = i + 1
end
---@diagnostic disable-next-line: cast-local-type
i=nil
if cloptions.help or cloptions.h then
@@ -633,11 +632,9 @@ local spm = function(...)
if pkgdb[i] then
if not cloptions.overwrite then
for f,h in pairs(v.data) do
if fs.exists(f) then
if pkgdb[i].files[f]~=md5(fs.readAllText(f)) then
w(f.." was modified on disk, specify --overwrite to overwrite")
block[f]=true
end
if pkgdb[i].files[f]~=md5(fs.readAllText(f)) then
w(f.." was modified on disk, specify --overwrite to overwrite")
block[f]=true
end
end
end
@@ -658,12 +655,10 @@ local spm = function(...)
if pkgdb[i] then
for f,c in pairs(pkgdb[i].files) do
if not v.data[f] then
if fs.exists(f) then
if c~=md5(fs.readAllText(f)) then
w(f.." was modified on disk, specify --overwrite to overwrite")
else
delete[f]=true
end
if c~=md5(fs.readAllText(f)) then
w(f.." was modified on disk, specify --overwrite to overwrite")
else
delete[f]=true
end
end
end
@@ -722,14 +717,6 @@ local spm = function(...)
w(src.." -> "..dest)
syscall.symlink(dest, src)
end
elseif f=="setup.lua" then
local func, err = load(c, "setupscript", "t", _G)
if not func then
w("Failed to load setup script for package "..i)
else
local ok, err = xpcall(func, debug.traceback)
if not ok then w("Setup script for package "..i.." exited with error: "..err) end
end
end
end
end
+4
View File
@@ -0,0 +1,4 @@
local args={...}
syscall.remove("/sbin/init")
syscall.symlink("/usr/lib/sysinit/sysinit", "/sbin/init")
syscall.exec("/sbin/init", args)
+13 -2
View File
@@ -5,6 +5,18 @@ kernel.saveLog()
local fs=require("fs")
kernel.log("Loaded fs")
for i,v in pairs(kernel.processes) do
kernel.log("Spawning kernel task "..i)
syscall.spawn(function()
local status, err = pcall(v)
if not status then
kernel.log("Error executing kernel task '" .. i .. "': " .. err, "ERROR", 0xFF0000)
else
kernel.log("Successfully executed kernel task: " .. i)
end
end, i, nil,nil,nil,true)
end
-- config file path setup
if not fs.exists("/etc/sysinit/") then
kernel.log("Creating conf path")
@@ -24,7 +36,7 @@ for i,v in ipairs(files) do
kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
else
syscall.spawn(function()
local status, err = xpcall(startupFunc, debug.traceback)
local status, err = pcall(startupFunc)
if not status then
kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
else
@@ -33,7 +45,6 @@ for i,v in ipairs(files) do
end, "startup:" .. v, nil,nil,nil,true)
end
end
kernel.log("sysinit complete")
kernel.saveLog()
while true do
+23
View File
@@ -0,0 +1,23 @@
local fs=require("fs")
local units=fs.list("/usr/lib/hunit/")
fs.mkdir("/tmp/hunit/")
local errors={}
for i,v in ipairs(units) do
print("running unit "..v)
local code=fs.readAllText("/usr/lib/hunit/"..v)
local func, err=load(code, "@"..v)
if not func then
print(" [ERROR]:"..err)
end
---@diagnostic disable-next-line: param-type-mismatch
local ok, err=pcall(func)
if not ok then
print(" [ERROR]:"..err)
table.insert(errors, v)
else
print(" [SUCCESS]")
end
end
print(tostring(#errors).." units failed")
return 0
Loaded 100 of 153 files, more files were not shown because too many files have changed in this diff. Show more