Velx fixes, velxdump.
This commit is contained in:
parent
7bd0c23ee9
commit
9059749a6a
@ -147,9 +147,9 @@ end
|
||||
local velx_spec = struct {
|
||||
endian = "<",
|
||||
{magic="c5"},
|
||||
{fver="B"},
|
||||
{compression="B"},
|
||||
{lver="B"},
|
||||
{fver="B"},
|
||||
{os="B"},
|
||||
{psize="I3"},
|
||||
{lsize="I3"},
|
||||
|
BIN
tkrnl.velx
BIN
tkrnl.velx
Binary file not shown.
195
utils/velxdump.lua
Normal file
195
utils/velxdump.lua
Normal file
@ -0,0 +1,195 @@
|
||||
--[[----------------------------------------------------------------------------
|
||||
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 <http://unlicense.org/>
|
||||
--]]----------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
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"},
|
||||
{psize="I3"},
|
||||
{lsize="I3"},
|
||||
{ssize="I3"},
|
||||
{rsize="I4"}
|
||||
}
|
||||
|
||||
local compression = {
|
||||
[0] = "None",
|
||||
[1] = "LZSS"
|
||||
}
|
||||
|
||||
local os = {
|
||||
[0] = "Tsuki",
|
||||
[0x7F] = "BIOS",
|
||||
}
|
||||
|
||||
local f = io.open(arg[1], "rb")
|
||||
local header = velx_spec(f:read(#velx_spec))
|
||||
local program = f:read(header.psize)
|
||||
local linker = f:read(header.lsize)
|
||||
local sigs = f:read(header.ssize)
|
||||
local archive = f:read(header.rsize)
|
||||
local lver = string.format("%x", header.lver)
|
||||
lver = lver:sub(1,1).."."..lver:sub(2,2)
|
||||
io.stdout:write(string.format([[File Version: %d
|
||||
Compression: %s
|
||||
Type: %s
|
||||
OS: %s
|
||||
Lua Version: %s]],
|
||||
header.fver,
|
||||
compression[header.compression] or "Unknown",
|
||||
(((header.os & 0x80) > 0) and "Library") or "Executable",
|
||||
os[header.os & 0x7F] or "Unknown",
|
||||
lver),"\n")
|
||||
local h = io.popen("tsar -t", "w")
|
||||
h:write(archive)
|
||||
h:close()
|
||||
if (header.compression == 1) then
|
||||
io.stderr:write(M.decompress(program))
|
||||
elseif (header.compression == 0) then
|
||||
io.stderr:write(program)
|
||||
end
|
Loading…
Reference in New Issue
Block a user