The split, the symbols, the disassembly and the viewers, without the programs
Split an N64 cartridge by the ranges its game declares, name the functions in its code by signature, disassemble any address and read its bytes — in a browser tab, over the same library as the other two tools.
Split an N64 cartridge by the ranges its game declares, name the functions in its code by signature, disassemble any address and read its bytes — in a browser tab, over the same library as the other two tools.
Work
Cartridge
What the file is: the header's title, product code and revision, its checksum, its byte order, and which game module claims it.
Split
Every range the declarations describe — the boot code, the code regions the segment table describes, the tables and the numbered files — with the status of each boundary.
Signatures
Every function start a walk reaches, with the entries of a signature library that match it, named as the shape they are and not as a name nobody has.
Hex
The bytes themselves, at an offset or an address, paged and searchable.
Disassembly
Any address in any code region, listed a page at a time, with the flow of control marked.
Rebuild
A Klartext program read against the cartridge in hand and written into a copy of it, statement by statement, with the reason for every one that could not be written.
Read this before you open a cartridge
Drop a cartridge image into the panel above, or into the explorer, and the tool reads it where it is. Nothing is uploaded: the file is read by the page, in the tab, and it never leaves your computer.
This is the third tool and the widest. The field does these steps with local programs: a splitter that takes a configuration file of ranges and labels, a symbol matcher that names functions by signature, a disassembler, the SDK's own viewers, and a script that rebuilds the cartridge. Every one of those steps is a declaration about a cartridge rather than a program about one — a range is an offset and a length, a label is a name and an address, a signature is a run of instructions — so all of it belongs in the same place the other two tools keep their declarations: the game module and the address book.
What it answers
Four questions, which are four views: Cartridge is what the file is; Split is where each declared range begins and ends; Signatures is what the functions in the code look like; and the Bytes and Code views are the bytes and the instructions at any address in them.
A range whose extent is a hypothesis says so. The code a cartridge runs is the one part of it no table states: the segment declarations describe the overlays, and the code between the boot code and the first overlay is a bound this build infers and measures rather than reads.
A signature says which bits are the function and which are its operands, so one entry can name many functions and none of them exactly. That is why every entry carries a status — confirmed, likely or hypothesis — and why the shapes are named as shapes: open a stack frame is a reading, and a function name nobody has would not be.
The rebuild
The last step of that workflow is a rebuild, and it is here as the Rebuild view. A program written in the patch language the other pages speak is read against the cartridge in hand, statement by statement, and written into a copy of it. Every statement answers: the rows it selected, the bytes it would write and where, or the sentence saying why it cannot be written.
Where a byte is comes from the declarations rather than from arithmetic in the writer. A table's place is the game module's address book or its file table; a field's place inside a row is the layout's own sum of the widths in front of it; a row's place is its index times the entry size the game states. And a row of a numbered file lives in the decoded stream rather than at a cartridge offset — No Mercy's damage table is twelve thousand bytes of LZSS that expand to seventy-six thousand — so an edited file is packed again with the codec it came in and written whole into its slot. A file that no longer fits is refused with the number of bytes it needs.
Nothing is written but the copy you ask for, and a program whose every row already holds what it asks for writes nothing and says so. A hook — the part of the language that installs code and calls it — is read and reported and not written, because this build has nowhere to put the code it would call.
What it does not do yet
- The symbol library is five entries. A real one is thousands, and each has to carry where it came from — a cartridge this build read, a public symbol list, or a guess about a shape.
- A hook is not lowered. The language's hooks need code this build cannot assemble, so a program that uses one is read, measured and reported, and the statement says that rather than failing quietly.