Handling of PSX binaries
There is some support for handling PSX binaries in the Lua API. The PCSX.Binary
module has the following functions:
PCSX.Binary.load(input, output)
: loads an inputFile
object into an outputFile
object. The input file must be a valid PSX binary, which can be in the formats CPE, PS-EXE, PSF, or ELF, and the output file must be at least 4GB large, which means it's really only suitable with themem4g
object, or the object returned bygetMemoryAsFile()
. The output file will be modified in-place. The output file will be loaded at the address specified in the binary header. If successful, the function will return an info structure with the following optional fields:pc
: the entry point of the binarygp
: the global pointer of the binarysp
: the stack pointer of the binaryregion
: the region of the binary, which can be one of the following:'NTSC'
: NTSC region'PAL'
: PAL region
PCSX.Binary.pack(src, dest, addr, pc, gp, sp, options)
: compresses the input binary stream into a self-decompressing stream. The input must be aFile
object, and the output must be aFile
object. Theaddr
is the address that the binary will be loaded at. Thepc
,gp
, andsp
are the entry point, global pointer, and stack pointer of the binary. Theoptions
is an optional table with the following optional fields:tload
: the address that the compressed binary will be loaded at. If not specified, it will be set to a suitable address. Not specifying this will generate an in-place decompression binary, which doesn't require much extra memory. When specifying this, the whole output stream will be loaded at this specific address, and the decompression code will be located at its beginning, meaning both the entry point and the loading addresses will be the same.nopad
: the generated PS-EXE will not be padded to 2048 bytes. It will not be suitable to boot from cd-rom, as the BIOS requires binaries to be aligned to sector sizes, but many other tools like unirom+nops or caetla+catflap will be able to handle it properly.booty
: a boolean specifying that the output stream will be suitable to boot as a PIO bytestream. Incompatible withtload
orraw
.nokernel
: a boolean specifying that the produced binary will not try to call into the kernel, in case the kernel has been wiped out. Results in a slightly bigger binary, but is necessary when the retail kernel is not present.shell
: a boolean specifying that the output stream will attempt to reboot the machine and load the binary, which can be useful when resetting the kernel.raw
: a boolean specifying that the output stream will be a raw binary, without a PS-EXE header. The generated binary will be completely position independent, and will not require any special loading address. It is up to the user to ensure no overlap can happen by loading the file to a high enough address. This option can be used to generate embedded binaries within others, or to be loaded by other means, and executed by jumping to it. Thetload
option will be ignored when this is specified.rom
: a boolean specifying that the output stream will be a ROM file suitable to be flashed on a cheat cartridge, as long as the cartridge itself has linear addressing, which is not necessarily the case for all cartridges. Thetload
option will be ignored when this is specified.cpe
: a boolean specifying that the output stream will be a CPE file, which is the file format used by the ancient toolchain by Sony. This can be useful when trying to load binaries with these ancient tools.
PCSX.Binary.createExe(src, dest, addr, pc, gp, sp)
: creates a PS-EXE binary from the input binary stream. The input must be aFile
object, and the output must be aFile
object. Theaddr
is the address that the binary will be loaded at. Thepc
,gp
, andsp
are the entry point, global pointer, and stack pointer of the binary.
The above methods can be used for example the following way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Additionally, the PCSX.Misc
module has the following functions:
PCSX.Misc.uclPack(src, dest)
: compresses the input binary stream into a ucl-compressed stream. Both the input and output arguments must beFile
objects. The output stream will be written at its current write pointer, and will be compressed using the UCL-NRV2E compression algorithm, which is a variant of the UCL compression algorithm. The output stream can be decompressed in-place with very little memory overhead. Simply place the compressed data at the end of the decompression buffer + 16 bytes. The stream doesn't require to be aligned in any particular way.PCSX.Misc.writeUclDecomp(dest)
: writes a MIPS UCL-NRV2E decompression routine to the outputFile
object, at its current write pointer. The function returns the number of bytes written, which at the moment is 340 bytes. The code is position independent, and has the following function signature:void decompress(const uint8_t* src, uint8_t* dest);