NES targets

From llvm-mos
(Redirected from NES overview)
Jump to navigation Jump to search

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 nes target contains only functionality that is generically applicable across mapper chips. Individual mappers each have their own derived target:

Supported Mappers
Number Name Target
000 NROM nes-nrom
001 MMC1 nes-mmc1

Sections[edit | edit source]

PRG-ROM[edit | edit source]

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

CHR-ROM[edit | edit source]

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

PRG-RAM[edit | edit source]

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

Symbol Configuration[edit | edit source]

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, __prg_nvram_size_raw corresponds to the high nibble of header field 10. This means that the lowest nibble of __prg_nvram_size_raw is mapped to the high nibble of header field 10.

Configuration Symbols
Symbol Description
__prg_rom_size KiB of PRG-ROM
__chr_rom_size KiB of CHR-ROM
__prg_ram_size KiB of PRG-RAM
__prg_nvram_size KiB of PRG-NVRAM
__chr_ram_size KiB of CHR-RAM
__chr_nvram_size KiB of CHR-NVRAM
__mirroring Bit 0 of field 6
__battery Bit 1 of field 6
__trainer Bit 2 of field 6
__four_screen Bit 3 of field 6
__mapper Mapper number.
__console_type Low two bits of field 7
__timing Low two bits of field 12
__ppu_type Low nibble of byte 13 when Vs. System
__hw_type High nibble of byte 13 when Vs. System
__extended_console_type Low nibble of byte 13 when Extended Console Type
__misc_roms Low 2 bytes of byte 14
__default_expansion_device Low 6 bytes of byte 15
__prg_rom_size_raw The most significant nibble is the lower nibble of field 9, and the least significant byte is field 4. Overrides __prg_rom_size.
__chr_rom_size_raw The most significant nibble is the upper nibble of field 9, and the least significant byte is field 5. Overrides __chr_rom_size.
__prg_ram_size_raw Raw value of low 4 bits of header field 10. Overrides __prg_ram_size.
__prg_nvram_size_raw Raw value of high 4 bits of header field 10. Overrides __prg_nvram_size.
__chr_ram_size_raw Raw value of low 4 bits of header field 11. Overrides __chr_ram_size.
__chr_nvram_size_raw Raw value of high 4 bits of header field 11. Overrides __chr_nvram_size.

INCLUDE Configuration[edit | edit source]

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.

INCLUDE Files
Name Description
common.ld Functionality common to all linker scripts for a given target. Must be included. Included in default linker script.
c-in-ram.ld Place the writable C sections into NES RAM. Exactly one c-in- script must be included. Included in default linker script.

NROM[edit | edit source]

INCLUDE Configuration[edit | edit source]

INCLUDE Files
Name Description
c-in-prg-ram.ld Place the writable C sections into PRG-RAM.

MMC1[edit | edit source]

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 __prg_rom_size 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.

INCLUDE Configuration[edit | edit source]

INCLUDE Files
Name Description
c-in-prg-ram-0.ld Place the writable C sections into PRG-RAM bank 0.
prg-ram-16.ld 16 KiB of PRG-ROM without banking.
prg-ram-32.ld 32 KiB of PRG-ROM without banking.
prg-ram-32-banked.ld 32 KiB of PRG-ROM with banking. Initializes to PRG-ROM bank mode 3, bank 0.
prg-ram-64.ld 64 KiB of PRG-ROM with banking. Initializes to PRG-ROM bank mode 3.
prg-ram-128.ld 128 KiB of PRG-ROM with banking. Initializes to PRG-ROM bank mode 3.
prg-ram-256.ld 256 KiB of PRG-ROM with banking. Initializes to PRG-ROM bank mode 3. Included in default linker script.