#!/usr/bin/env lua local usage = [[ lua bin2exe.lua infile outfile Converts a raw binary file to PlayStation 1 (PS-X) executable format. ]] function file_size(filename) local file = io.open(filename, "rb") if not file then return nil end local size = file:seek("end") file:close() return size end function main(args) if #args ~= 2 then io.stderr:write(usage) os.exit(1) end print(string.format("Input file: %s", args[1])) print(string.format("Output file: %s", args[2])) -- PS1 executables have a maximum size limit of 2MB local max_size = 0x200000 print(string.format("\nChecking input file size (max: %d bytes)...", max_size)) local infile_size = file_size(args[1]) if not infile_size then io.stderr:write("Error: Cannot open input file " .. args[1] .. "\n") os.exit(1) end print(string.format("Input file size: %d bytes", infile_size)) if infile_size > max_size then io.stderr:write(string.format("Error: Input file %s longer than %d bytes\n", args[1], max_size)) os.exit(1) end print("\nOpening files...") local ofile = io.open(args[2], "wb") if not ofile then io.stderr:write("Error: Cannot open output file " .. args[2] .. "\n") os.exit(1) end local ifile = io.open(args[1], "rb") if not ifile then io.stderr:write("Error: Cannot open input file " .. args[1] .. "\n") os.exit(1) end print("Writing PS-X executable header...") -- PS1 executables start with "PS-X EXE" magic string ofile:write("PS-X EXE") -- Write entry point address (where the PS1 will jump to start execution) -- 0x80010000 is a standard entry point in PS1 RAM ofile:seek("set", 0x10) ofile:write(string.pack("