Using NSF Players one can determine NSF compatibility without hardware verification.
Although the TNS-HFC4, TNS-HFC3, TNS-HFP1, and TNS-HFC2 are designed based on NSF format Ver. 1.61,
a very small difference between this Family Computer and the emulator may interfere with the NSF data
performance on the TNS-HFC4, TNS-HFC3, TNS-HFP1, and TNS-HFC2.
HFC2 may interfere with playing NSF data on TNS-HFC4, TNS-HFC3, TNS-HFP1, and TNS-HFC2.
In the CPU used in the Family Computer (hereafter referred to as NES), the following addresses have special meanings.
Address | Meaning |
‚e‚e‚e‚` | NMI Vector |
‚e‚e‚e‚b | RESET Vector |
‚e‚e‚e‚d | IRQ Vector |
The contents written to this address are read into the CPU in the instruction cycle following the ƒÓ2 cycle in which the interrupt request is input to the CPU.
Here is an example of operation failure when accessing the NSF standard specification bank switching register.
CPU Address | Corresponding Bank Register | Bank Number |
‚W‚O‚O‚O`‚W‚e‚e‚e | ‚T‚e‚e‚W | ‚O‚O |
‚X‚O‚O‚O`‚X‚e‚e‚e | ‚T‚e‚e‚X | ‚O‚P |
‚`‚O‚O‚O`‚`‚e‚e‚e | ‚T‚e‚e‚` | ‚O‚Q |
‚a‚O‚O‚O`‚a‚e‚e‚e | ‚T‚e‚e‚a | ‚O‚R |
‚b‚O‚O‚O`‚b‚e‚e‚e | ‚T‚e‚e‚b | ‚O‚S |
‚c‚O‚O‚O`‚c‚e‚e‚e | ‚T‚e‚e‚c | ‚O‚T |
‚d‚O‚O‚O`‚d‚e‚e‚e | ‚T‚e‚e‚d | ‚O‚U |
‚e‚O‚O‚O`‚e‚e‚e‚e | ‚T‚e‚e‚e | ‚O‚V |
In this state, the three interrupt vectors mentioned above are written to addresses $0FFA to $0FFF in bank number $07.
Therefore, the bank registers are manipulated from the CPU-side application.
CPU Address | Corresponding Bank Register | Bank Number |
‚W‚O‚O‚O`‚W‚e‚e‚e | ‚T‚e‚e‚W | ‚O‚O |
‚X‚O‚O‚O`‚X‚e‚e‚e | ‚T‚e‚e‚X | ‚O‚P |
‚`‚O‚O‚O`‚`‚e‚e‚e | ‚T‚e‚e‚` | ‚O‚Q |
‚a‚O‚O‚O`‚a‚e‚e‚e | ‚T‚e‚e‚a | ‚O‚R |
‚b‚O‚O‚O`‚b‚e‚e‚e | ‚T‚e‚e‚b | ‚O‚S¨‚OA |
‚c‚O‚O‚O`‚c‚e‚e‚e | ‚T‚e‚e‚c | ‚O‚T¨‚OB |
‚d‚O‚O‚O`‚d‚e‚e‚e | ‚T‚e‚e‚d | ‚O‚U¨‚O0 |
‚e‚O‚O‚O`‚e‚e‚e‚e | ‚T‚e‚e‚e | ‚O‚V¨‚O‚O |
In the address seen from the CPU, the data read from $F000 to $FFFFF is the same as the data written to $8000 to $8FFF.
In other words, the vector address that the CPU reads when an interrupt occurs is $8FFA-8FFF, and if a valid address for this address is
not written, the application will run out of control because the interrupt jump destination is incorrect.
There are two methods of bank switching that do not cause the application to run out of control.
CPU Address | Corresponding Bank Register | TNS-HFC4 Bank Number |
TNS-HFC3 (1024KB Version) Bank Number |
TNS-HFC2 Bank Number |
TNS-HFP1 Bank Number |
‚W‚O‚O‚O`‚W‚e‚e‚e | ‚T‚e‚e‚W | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚X‚O‚O‚O`‚X‚e‚e‚e | ‚T‚e‚e‚X | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚`‚O‚O‚O`‚`‚e‚e‚e | ‚T‚e‚e‚` | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚a‚O‚O‚O`‚a‚e‚e‚e | ‚T‚e‚e‚a | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚b‚O‚O‚O`‚b‚e‚e‚e | ‚T‚e‚e‚b | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚c‚O‚O‚O`‚c‚e‚e‚e | ‚T‚e‚e‚c | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚d‚O‚O‚O`‚d‚e‚e‚e | ‚T‚e‚e‚d | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚e‚O‚O‚O`‚e‚e‚e‚e | ‚T‚e‚e‚e | ‚O‚V (Fixed) | ‚O‚V (Fixed) | ‚O‚V (Fixed) | ‚O‚V (Fixed) |
CPU Address | Corresponding Bank Register | TNS-HFC4 Bank Number |
TNS-HFC3 (1024KB Version) Bank Number |
TNS-HFC2 Bank Number |
TNS-HFP1 Bank Number |
‚W‚O‚O‚O`‚W‚e‚e‚e | ‚T‚e‚e‚W | ‚O‚O | ‚O‚O | ‚O‚O | ‚O‚O |
‚X‚O‚O‚O`‚X‚e‚e‚e | ‚T‚e‚e‚X | ‚O1 | ‚O1 | ‚O1 | ‚O1 |
‚`‚O‚O‚O`‚`‚e‚e‚e | ‚T‚e‚e‚` | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚a‚O‚O‚O`‚a‚e‚e‚e | ‚T‚e‚e‚a | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚b‚O‚O‚O`‚b‚e‚e‚e | ‚T‚e‚e‚b | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚c‚O‚O‚O`‚c‚e‚e‚e | ‚T‚e‚e‚c | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚d‚O‚O‚O`‚d‚e‚e‚e | ‚T‚e‚e‚d | ‚O‚O`‚e‚d (Variable) | ‚O‚O`‚e‚e (Variable) | ‚O‚O`‚V‚e (Variable) | ‚O‚O`‚P‚d (Variable) |
‚e‚O‚O‚O`‚e‚e‚e‚e | ‚T‚e‚e‚e | ‚O‚O | ‚O‚O | ‚O‚O | ‚O‚O |
In TNS-HFC4, the main memory and bank memory are shared.
The maximum usable NSF file size is limited to 1040512 bytes due to the shared bank memory with the main memory.
CPU Address | Bank Number | NSF Data Domain | Comment |
‚T‚O‚O‚O`‚T‚d‚e‚e | ‚e‚e | Cannot be allocated. | No memory allocation for extended sound source I/O addresses. |
‚U‚O‚O‚O`‚U‚e‚e‚e | ‚e‚d | Available | Always read/write available (no write protection) |
‚V‚O‚O‚O`‚V‚e‚e‚e | ‚e‚c | Available | Always read/write available (no write protection) |
TNS-HFC4 has 8KB of built in Character Memory.
PPU Address | Mirroring Control Address | Comment |
‚O‚O‚O‚O`‚R‚e‚e‚e | Available | Horizontal Mirroring on RESET (bit 3=0) |
Address mirror (horizontal and vertical) control uses the register (bit 3) located at $4025.
Memory transfer from the CPU to the PPU must be handled by the user application.
Memory is not cleared when writing to $8000 to DFFF, which usually occurs when enabling RP2C33 sound, does not occur with the TNS-HFC4.
All the written data is passed to the optional expansion sound source slot or TNS-HFX4.
In TNS-HFP1, the main memory and bank memory are shared.
The maximum usable NSF file size is limited to 126720 bytes due to the shared bank memory with the main memory.
CPU Address | Bank Number | NSF Data Domain | Comment |
‚O‚O‚O‚O`‚O‚e‚e‚e | ‚R‚P | Not Assignable | NES standard is up to 2KB i‚O‚O‚O‚O`‚O‚V‚e‚ej |
‚P‚O‚O‚O`‚P‚e‚e‚e | ‚R‚O | Conditional Available |
Interprocessor communication port space i‚P‚e‚O‚O`‚P‚e‚e‚ej is prohibited. |
‚Q‚O‚O‚O`‚R‚e‚e‚e | | | | | Image mapping of PPU registers ‚Q‚O‚O‚O`‚Q‚O‚O‚V |
‚S‚O‚O‚O`‚T‚d‚e‚e | | | | | 2A03 CPU built-in I/O registers |
‚U‚O‚O‚O`‚U‚e‚e‚e | ‚Q‚X | Available | Always read/write available (no write protection) |
‚V‚O‚O‚O`‚V‚e‚e‚e | ‚Q‚W | Available | Always read/write available (no write protection) |
TNS-HFP1 has 2KB Nametable Memory and 8KB CHR ROM.
PPU Address | Address Mirroring Control | Comment |
‚O‚O‚O‚O`‚R‚e‚e‚e | OK | Horizontal mirroring on RESET (bit 7 = 0) |
Address mirror (horizontal and vertical) control uses the register (bit 7) placed in $5FED.
Memory transfer from CPU to PPU must be handled by the user application side.
Memory is not cleared when writing to $8000 to DFFF, which usually occurs when enabling RP2C33 sound, does not occur with the TNS-HFP1.
All writes are blocked.
The TNS-HFC3 and TNS-HFC2 implement the memory shown in the table below, in addition to the 2KBx2 that the NES comes standard with.
CPU Address | Address Availability | Comment |
‚S‚W‚O‚O`‚S‚e‚e‚e | OK | Disabled when using Namco 163 expansion sound |
‚T‚O‚O‚O`‚T‚d‚e‚e | OK | Disabled when using MMC5 expansion sound |
‚U‚O‚O‚O`‚V‚e‚e‚e | Always Available | Always read/write available (no write protection) |
Address availability uses registers placed in $5FEC.
PPU Address | Address Mirroring Control | Comment |
‚O‚O‚O‚O`‚R‚e‚e‚e | OK | Horizontal on RESET (bit 7 = 0) |
Address mirror (horizontal and vertical) control uses the register (bit 7) placed in $5FED.
Memory transfer from CPU to PPU must be handled by the user application side.
The memory occupying CPU address $6000-7FFF is often used in NSF players.
It is treated the same as when enabling RP2C33 sound.
Unlike the state in which the disk system sound source is enabled by NSF playing on emulators such as Windows,
TNS-HFC3 and TNS-HFC2 cannot use $5FFF6 and $5FFF7 to switch banks $6000-$6FFF and $7000-$7FFF.
The $6000-$7FFF range is treated as SRAM.
(Pointed out by "h7")
This memory can be used to move the sound driver data itself into this memory space,
place the processing routines for the aforementioned interrupt vectors, etc.
Memory is not cleared when writing to $8000 to DFFF, which usually occurs when enabling RP2C33 sound,
does not occur with the TNS-HFC3 and TNS-HFC2.
Writes are passed to the (optional) expansion sound slot or TNS-HFX4 on TNS-HFC3,
and to the TNS-HFE4 expansion unit for TNS-HFC2.
In the expansion slot unit, the real address is remapped to prevent bus conflicts.
For SUNSOFT 5B expansion sound, the software remaps writes to the YMZ294 SSG (ƒÓ?1.78MHz).
VRC7's address is not remapped to the on-board YM2413 chip (ƒÓ?3.58MHz).
Expansion Sound Chip | Expansion Sound Original Address |
Address on TNS-HFX4 |
Address on TNS-HFE4 |
‚r‚t‚m‚r‚n‚e‚s‚T‚a | ‚b‚O‚O‚O | ‚T‚e‚d‚O | ‚T‚e‚d‚O |
V | ‚d‚O‚O‚O | ‚T‚e‚d‚P | ‚T‚e‚d‚P |
‚u‚q‚b‚V | ‚X‚O‚P‚O | ‚X‚O‚P‚O When DIPSW is ON |
Non-functional |
V | V | ‚T‚e‚X‚O When DIPSW is OFF |
Non-functional |
V | ‚X‚O‚R‚O | ‚X‚O‚R‚O When DIPSW is ON |
Non-functional |
V | V | ‚T‚e‚a‚O When DIPSW is OFF |
Non-functional |
All devices on the expansion sound slots are read-only.
Attempting to read from these registers will return undefined values,
so please treat expansion sound slots as write-only when programming.
April 1, 2006: First Edition
April 16, 2006: Corrected functionality in the $6000-$7FFF area
April 20, 2006: Addition of notation with/without backup
September 11, 2007: Added TNS-HFP1 bank specifications
September 11, 2009: Added TNS-HFC3 bank specifications
February 11, 2013: Added TNS-HFC4 bank specifications
August 1, 2013: Added specification for Expansion Sound Slot Unit
February 8, 2023: Page (unofficially) translated into English