ndspy.code
: Code¶
The ndspy.code
module can be used to load and save executable code files:
MainCodeFile
can be used to work with ARM7 or ARM9 main code files.Overlay
can be used to work with ARM7 or ARM9 code overlays.loadOverlayTable()
andsaveOverlayTable()
can be used to load and save ARM7 or ARM9 overlay tables.
- class ndspy.code.MainCodeFile(data, ramAddress[, codeSettingsPointerAddress])¶
Either the main ARM7 code file or the main ARM9 code file. On the console, the entire file is loaded into RAM as one big chunk, decompressed (if needed), and then immediately executed. Usually, the code begins by moving different sections of itself to different addresses. You can access all of these sections via the
sections
attribute.Note
Since this class tries to parse the code data to some degree to give you access to its sections, it automatically decompresses the data (if compressed) upon loading it.
- Parameters:
data (bytes) – The data to be read as a code file. If this is
None
, theMainCodeFile
object will initially be empty.ramAddress – The initial value for the
ramAddress
attribute.codeSettingsPointerAddress – The “code settings pointer address” value corresponding to this code file, from the ROM header. ndspy needs this to correctly determine
codeSettingsOffs
. If 0 or not provided, ndspy will attempt to guesscodeSettingsOffs
for you.
- codeSettingsOffs¶
The offset in the code data of the “code settings” structure present in many code files from retail games. This defines things such as sections and whether the code is compressed or not. This should be
None
if this code file has no code settings structure.- Type:
- ramAddress¶
The address this code file will be automatically loaded to when the software is booted.
- Type:
- sections¶
The list of
Section
s in this code file. ndspy has to populate this list using heuristics, so it may not always be perfectly accurate. Some code files (such as homebrew, mainly) may only have one (implicit) section.
- classmethod fromCompressed(...)¶
Create a main code file from compressed code data.
This function is a bit outdated, since the default constructor can now detect code compression. There is no real reason to use this function anymore, and it may be removed at some point.
Parameters are the same as those of the default constructor.
- Returns:
The main code file object.
- Return type:
- classmethod fromSections(sections, ramAddress)¶
Create a main code file from a list of sections.
- Parameters:
sections (
list
ofSection
) – The list of sections to be included in this main code file.ramAddress – The initial value for the
ramAddress
attribute.
- Returns:
The main code file object.
- Return type:
- classmethod fromFile(filePath, ramAddress)¶
Load a main code file from a filesystem file. This is a convenience function.
- Parameters:
filePath (
str
or other path-like object) – The path to the main code file to open.ramAddress – The initial value for the
ramAddress
attribute.
- Returns:
The main code file object.
- Return type:
- saveToFile(filePath, *[, compress])¶
Generate file data representing this main code file, and save it to a filesystem file. This is a convenience function.
- class MainCodeFile.Section(data, ramAddress, bssSize, *[, implicit=False])¶
A single section within an ARM7 or ARM9 code file. Code not technically contained within a section defined in the sections table in the code settings block is represented as an “implicit” section.
- Parameters:
data – The initial value for the
data
attribute.ramAddress – The initial value for the
ramAddress
attribute.bssSize – The initial value for the
bssSize
attribute.implicit – The initial value for the
implicit
attribute.
- bssSize¶
The size of the .bss section for this code section.
- Type:
- implicit¶
This is
True
if this section is implicitly defined and should be excluded from the sections table;False
otherwise.The first section of every main code file is implicit; this contains the code that parses the sections table and loads (explicit) sections defined there to their appropriate RAM addresses.
- Type:
- Default:
False
- class ndspy.code.Overlay(data, ramAddress, ramSize, bssSize, staticInitStart, staticInitEnd, fileID, compressedSize, flags)¶
An ARM7 or ARM9 code overlay.
Note
If the
flags
parameter indicates the data is compressed (seecompressed
), the class constructor will automatically decompress it. If you need the original compressed data instead, access it directly from your ROM’sfiles
list using thefileID
attribute.- Parameters:
data – The initial value for the
data
attribute.ramAddress – The initial value for the
ramAddress
attribute.ramSize – The initial value for the
ramSize
attribute.bssSize – The initial value for the
bssSize
attribute.staticInitStart – The initial value for the
staticInitStart
attribute.staticInitEnd – The initial value for the
staticInitEnd
attribute.fileID – The initial value for the
fileID
attribute.compressedSize – The initial value for the
compressedSize
attribute.flags – The initial value for the
flags
attribute.
- bssSize¶
The size of the .bss section for this overlay.
- Type:
- compressed¶
Alias property for “
flags
& 1”. This isTrue
if the overlay was most recently saved (save()
) with compression enabled (or – if it hasn’t been saved yet – if the overlay was compressed when it was first loaded), andFalse
otherwise.- Type:
- compressedSize¶
The size of the overlay’s data when compressed. If the overlay is uncompressed, this should be equal to the length of the uncompressed data.
- Type:
- flags¶
A bitfield (8 bits long) representing some flags for the overlay. Values may be game-specific, but known flags have been given named aliases.
- Type:
- ramSize¶
The total size of the overlay once it is loaded into memory. This should be equal to
len(overlay.data)
if the overlay is uncompressed, or smaller than that if it is compressed.- Type:
- staticInitStart¶
The address of the beginning of the static initializers function pointers table for this overlay. I think this is a table of function pointers that (at the C++ level) set static variables in overlay scope to their initial values, which are all run upon loading the overlay; however, I am not sure of this.
- Type:
- staticInitEnd¶
The address of the end of the static initializers function pointers table for this overlay. See the
staticInitStart
attribute for more information.- Type:
- verifyHash¶
Alias property for “
flags
& 2”. This isTrue
if the overlay-loading code should calculate the overlay’s HMAC and compare it to a (hardcoded) expected hash value,False
otherwise.- Type:
- save(*[, compress])¶
Generate a
bytes
object representing this overlay.Note: this function updates several attributes to match the requested output representation. (For example,
compressed
will be set to match the value of thecompress
parameter.)
- ndspy.code.loadOverlayTable(tableData, fileCallback[, idsToLoad])¶
Parse ARM7 or ARM9 overlay table data to create a dictionary of
Overlay
s. This is the inverse ofsaveOverlayTable()
.- Parameters:
tableData (bytes) – The overlay table data.
fileCallback (function with the signature
(overlayID: int, fileID: int) -> bytes
) – A function that takes an overlay ID and a file ID and returns the data for the requested file. This allows you to load overlay data by either of these IDs, whichever suits your needs best.idsToLoad (
set
ofint
) – A specific set of overlay IDs to load. You can use this to avoid loading overlays you don’t actually care about, in order to improve your application’s performance.
- Returns:
A
dict
of overlays.- Return type:
dict
:{overlayID: overlay}
(whereoverlayID
is of typeint
andoverlay
is of typeOverlay
)
- ndspy.code.saveOverlayTable(table)¶
Generate a bytes object representing this dictionary of
Overlay
s, in proper ARM7 or ARM9 overlay table format. This is the inverse ofloadOverlayTable()
.