ndspy.code: Code

The ndspy.code module can be used to load and save executable code files:

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, the MainCodeFile 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 guess codeSettingsOffs 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:

int

ramAddress

The address this code file will be automatically loaded to when the software is booted.

Type:

int

sections

The list of Sections 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.

Type:

list of 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:

MainCodeFile

classmethod fromSections(sections, ramAddress)

Create a main code file from a list of sections.

Parameters:
  • sections (list of Section) – 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:

MainCodeFile

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:

MainCodeFile

save(*[, compress])

Generate a bytes object representing this code file.

Parameters:

compress (bool) –

Whether to compress the code or not. Compression is optional for ARM9 code, but ARM7 code should never be compressed.

default:

False

Returns:

The code file data.

Return type:

bytes

saveToFile(filePath, *[, compress])

Generate file data representing this main code file, and save it to a filesystem file. This is a convenience function.

Parameters:
  • filePath (str or other path-like object) – The path to the main code file to save to.

  • compress (bool) –

    Whether to compress the code or not. Compression is optional for ARM9 code, but ARM7 code should never be compressed.

    default:

    False

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:

int

data

The code data for this section.

Type:

bytes

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:

bool

Default:

False

ramAddress

The address where this code section will be placed in memory when loaded.

Type:

int

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 (see compressed), the class constructor will automatically decompress it. If you need the original compressed data instead, access it directly from your ROM’s files list using the fileID 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:

int

data

The bytes object containing the decompressed code for this overlay.

compressed

Alias property for “flags & 1”. This is True 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), and False otherwise.

Type:

bool

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:

int

fileID

The file ID for the file containing the code data for this overlay.

Type:

int

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:

int

ramAddress

The address where this overlay will be placed in memory when loaded.

Type:

int

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:

int

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:

int

staticInitEnd

The address of the end of the static initializers function pointers table for this overlay. See the staticInitStart attribute for more information.

Type:

int

verifyHash

Alias property for “flags & 2”. This is True if the overlay-loading code should calculate the overlay’s HMAC and compare it to a (hardcoded) expected hash value, False otherwise.

Type:

bool

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 the compress parameter.)

Parameters:

compress (bool) –

Whether to compress the overlay or not.

default:

False

Returns:

The overlay file data.

Return type:

bytes

ndspy.code.loadOverlayTable(tableData, fileCallback[, idsToLoad])

Parse ARM7 or ARM9 overlay table data to create a dictionary of Overlays. This is the inverse of saveOverlayTable().

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 of int) – 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} (where overlayID is of type int and overlay is of type Overlay)

ndspy.code.saveOverlayTable(table)

Generate a bytes object representing this dictionary of Overlays, in proper ARM7 or ARM9 overlay table format. This is the inverse of loadOverlayTable().

Parameters:

table (dict: {overlayID: overlay}, where overlayID is of type int and overlay is of type Overlay) – A dict of overlays.

Returns:

The overlay table data.

Return type:

bytes