os.execute("mkdir -p build") os.execute("rm -rf build/*") local actions = {} -- VELX builder --[[---------------------------------------------------------------------------- LZSS - encoder / decoder This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to --]]---------------------------------------------------------------------------- -------------------------------------------------------------------------------- local M = {} local string, table = string, table -------------------------------------------------------------------------------- local POS_BITS = 12 local LEN_BITS = 16 - POS_BITS local POS_SIZE = 1 << POS_BITS local LEN_SIZE = 1 << LEN_BITS local LEN_MIN = 3 -------------------------------------------------------------------------------- function M.compress(input) local offset, output = 1, {} local window = '' local function search() for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do local str = string.sub(input, offset, offset + i - 1) local pos = string.find(window, str, 1, true) if pos then return pos, str end end end while offset <= #input do local flags, buffer = 0, {} for i = 0, 7 do if offset <= #input then local pos, str = search() if pos and #str >= LEN_MIN then local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN) buffer[#buffer + 1] = string.pack('>I2', tmp) else flags = flags | (1 << i) str = string.sub(input, offset, offset) buffer[#buffer + 1] = str end window = string.sub(window .. str, -POS_SIZE) offset = offset + #str else break end end if #buffer > 0 then output[#output + 1] = string.char(flags) output[#output + 1] = table.concat(buffer) end end return table.concat(output) end -------------------------------------------------------------------------------- function M.decompress(input) local offset, output = 1, {} local window = '' while offset <= #input do local flags = string.byte(input, offset) offset = offset + 1 for i = 1, 8 do local str = nil if (flags & 1) ~= 0 then if offset <= #input then str = string.sub(input, offset, offset) offset = offset + 1 end else if offset + 1 <= #input then local tmp = string.unpack('>I2', input, offset) offset = offset + 2 local pos = (tmp >> LEN_BITS) + 1 local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN str = string.sub(window, pos, pos + len - 1) end end flags = flags >> 1 if str then output[#output + 1] = str window = string.sub(window .. str, -POS_SIZE) end end end return table.concat(output) end local function struct(tbl) local pat = tbl.endian or "=" local args = {} for i=1, #tbl do local a, b = pairs(tbl[i]) local k, v = a(b) args[i] = k pat = pat .. v end return setmetatable({}, {__call=function(_, arg) --checkArg(1, arg, "string", "table") if (type(arg) == "string") then local sval = {string.unpack(pat, arg)} local rtn = {} for i=1, #args do rtn[args[i]] = sval[i] end return rtn, sval[#sval] elseif (type(arg) == "table") then local sval = {} for i=1, #args do sval[i] = arg[args[i]] end return string.pack(pat, unpack(sval)) end end, __len=function() return string.packsize(pat) end}) end local velx_spec = struct { endian = "<", {magic="c5"}, {fver="B"}, {compression="B"}, {lver="B"}, {os="B"}, {arctype="c4"}, {psize="I3"}, {lsize="I3"}, {ssize="I3"}, {rsize="I4"} } local function velx_multistep(path, arcpath, args, steps) local shell_args = "" for k, v in pairs(args) do shell_args = shell_args .. k .. "=".. v .." " end steps.precomp() local h = io.popen(shell_args.."luacomp "..path, "r") local prog = h:read("*a") h:close() prog = steps.postcomp(prog) steps.prearc() h = io.popen("find .docs -depth | tsar -o", "r") local arc = h:read("*a") h:close() steps.postarc() if (not args.noz) then steps.prez() prog = M.compress(prog) steps.postz() end local header = velx_spec({ magic = "\27VelX", compression = (args.noz and 0 or) 1, lver = 0x53, fver = 1, os = 0x7F, psize = #prog, lsize=0, ssize=0, rsize=#arc, arctype="tsar" }) return header .. prog .. arc end local function velx(path, arcpath, args) return velx_multistep(path, arcpath, args, { precomp = function()end postcomp = function(prog) return prog end prearc = function()end postarc = function()end prez = function()end postz = function()end }) end local TSUKI_RELEASE = "0.0.1" local tz = os.date("%z") tz = tz:sub(1, 3)..":"..tz:sub(4) local TSUKI_VERSION = "Lua 5.3 "..os.date("%Y-%m-%dT%H:%M:%S")..tz local TSUKI_TARGET = os.getenv("TSUKI_TARGET") or "OC" function actions.kernel(dbg) os.execute("mkdir -p build/kernel") print("Compiling kernel...") local h = io.open("build/kernel/tkrnl.velx", "wb") h:write(velx_multistep("ksrc/init.lua", ".docs", { TSUKI_RELEASE = TSUKI_RELEASE, TSUKI_VERSION = TSUKI_VERSION, TSUKI_TARGET = TSUKI_TARGET, PRINT_DMESG_LEVEL = ((dbg and 0) or 1) }, { precomp = function() print("Compiling kernel...") end, postcomp = function(krnl) os.execute("mkdir .docs") local h = io.open("build/kernel/debug.lua") h:write(krnl) h:close() print("Generating docs and stripping comments...") h = io.popen("lua utils/gendocs.lua .docs 2>.ktmp", "w") h:write(krnl) h:close() h = io.open(".ktmp", "rb") local data = h:read("*a") h:close() os.execute("rm -rf .ktmp") return data end, prearc = function() print("Storing docs...") end, postarc = function() os.execute("rm -rf .docs") end, precomp = function() print("Compressing kernel...") end, postcomp = function() print("Writing kernel out...") end })) end actions[#actions+1] = "kernel" function actions.crescent() os.execute("mkdir -p build/crescent") os.execute("cd extras; lua ../utils/mkvelx.lua crescent/init.lua ../build/crescent/boot.velx") os.execute("cp extras/crescent/bootvelxloader.lua build/crescent/init.lua") end actions[#actions+1] = "crescent" function actions.velxboot() os.execute("mkdir -p build/velxboot") os.execute("cd extras; luacomp velxboot/init.lua -O ../build/velxboot/bios.lua") os.execute("cd extras; luacomp velxboot/flashvelxboot.lua -O ../build/velxboot/flashvelxboot.lua") end actions[#actions+1] = "velxboot" function actions.clean() print("Cleaning up...") os.execute("rm -rf .docs") os.execute("rm -rf .ktmp") end --[[function actions.debug() actions.kernel(true) actions.crescent() actions.velxboot() actions.clean() end]] function actions.all() for i=1, #actions do actions[actions[i]]() end end if not arg[1] then arg[1] = "all" end actions[arg[1]]() print("Build complete.")