NES targets

The NES is a particularly challenging compiler target, due to the extremely large number of configurations supported by the various "mapper" ASICs on its cartridges.

The generic  target contains only functionality that is generically applicable across mapper chips. Individual mappers each have their own derived target:

PRG-ROM
If PRG-ROM banking is disabled, then data can be placed in PRG-ROM using the regular  C sections. Otherwise, data can be placed into a specific PRG-ROM bank using section  or any section that begins with. The load addresses of PRG-ROM banks begin at. This allows the bottom 24-bits to represent a logical PRG-ROM address space, while the high byte being  indicates that the address is PRG-ROM.

CHR-ROM
If CHR-ROM banking is disabled, then data can be placed in CHR-ROM using the  section or any section that begins with. Otherwise, data can be placed into a specific CHR-ROM bank using section  or any section that begins with. The logical addresses of CHR-ROM banks begins at. This allows the bottom 24-bits to represent a logical CHR-ROM address space, while the highest byte being  indicates that the address is CHR-ROM.

PRG-RAM
If PRG-RAM banking is disabled, then data can be placed in PRG-RAM using the  section or any section that begins with. Otherwise, variables can be placed into a specific PRG-RAM bank using section  or any section that begins with. The PRG-RAM is not initialized at program start, so any initializers given in C or data provided in assembly are ignored.

Symbol Configuration
As far as is possible, mappers are configured by assigning symbol values. These control the contents of the iNES 2.0 header in the resulting binary, as well as the addresses assigned to program sections. Some of the following values have logical sizes less than the full 32-bits available for symbol values. In such cases, only the lowest order bits are considered. For example,  corresponds to the high nibble of header field 10. This means that the lowest nibble of  is mapped to the high nibble of header field 10.

INCLUDE Configuration
In some cases, the linker script semantics are insufficiently powerful to configure the linker alone. In this case, linker scripts can be composed by `INCLUDE`-ing script files to build up a custom linker script (rather than using the default). The following script files are common to all targets.

MMC1
Different PRG-ROM sizes of the MMC1 require different numbers of reset stubs to be available, so the PRG-ROM size must be set by INCLUDE, not by symbol. The below INCLUDE files automatically set the  header field to the corresponding value. The 512KiB PRG-ROM mode and PRG-ROM bank modes other than 3 are not yet supported, since the C runtime model currently used by the compiler is only really practical if a fixed bank is present where e.g. libcalls can be placed.

MMC3
By default, the mapper is configured such that 24KiB of PRG-ROM is fixed, while a 8KiB bank is available at 0x8000. This can be altered by INCLUDEing alternative linker scripts.

In banking mode 0, the even banks are available at 0x8000, and the odd banks are available at 0xa000. In banking mode 1, the even banks are available at 0xc000, and the odd banks at 0xa000. This assignment can be changed on a per-bank basis by defining the symbol, where   is the bank number.