Super NES Programming/Super FX tutorial

Introduction

The Super FX is a custom 16-bit RISC processor with a special bitmap emulation function designed for the SNES. It was designed to bring rudimentary 3D capabilities to the SNES. Programming for it is done with special Super FX assembly language. Each Super FX title uses a combination of standard SNES assembly code with specially compiled Super FX assembly routines coded as binary data in the cartridge. It can run in parallel with the SNES under certain conditions. Each Super FX cartridge has on-board RAM which the Super FX chip uses as a frame buffer and for general purpose operations which it can share with the SNES.

Existing Titles

The Super FX chip was used in 8 released SNES games, in Star Fox 2 (unreleased) and in multiple tech demos; 2 of which binaries are available.

TitleSuper FX VersionROM SizeGame Pak RAM Size Save RAM Size
Star Fox (PAL: Starwing)Mario Chip8 MBit256 KBitNone
Dirt RacerGSU-14 MBit256 KBitNone
Dirt Trax FXGSU-14 MBit512 KBitNone
Stunt Race FX (JP: Wild Trax)GSU-18 MBit512 KBit64KBit
Star Fox 2GSU-18 MBit512 KBit64KBit
VortexGSU-14 MBit256 KBitNone
SNES Voxel Landscape DemoGSU-13 MBit512 KBitNone
Powerslide (demo)GSU-13 MBit512 KBitNone
DOOMGSU-216 MBit512 KBitNone
Yoshi's IslandGSU-2-SP116 MBit256 KBit64KBit
Winter GoldGSU-216 MBit512 KBit64KBit

Theory of Operation

A Super FX co-processor.

The Super FX is a co-processor for the SNES CPU. The Super FX's task is to execute complex mathematical calculations much faster than the SNES and to generate bitmap pictures for simple 3D rendering of Super FX games. The Super FX and SNES processors share access to a common Game Pak RAM and ROM bus. Only one processor, the Super FX or SNES CPU, may access the Game Pak RAM and/or ROM at any time, controlled by special registers. The flow of the SNES and Super FX accessing the data busses is an art in optimizing the program's efficiency.

The Game Pak RAM is mainly used for storing results of calculations, a Super FX program, bulk data, or a PLOT picture the Super FX is generating. There can be 256 Kib (32KiB) or 512 Kib (64 KiB) of RAM. Some Super FX games have also used this RAM to store save data.

The Super FX can process instructions in 3 ways: reading them from Game Pak RAM, from the Game Pak ROM (reading straight out of the ROM chip), or via a special 512 byte instruction cache.

It is possible for the Super FX to run in parallel with the SNES CPU when using the 512 byte instruction Cache. It involves loading a program in, and then setting the Super FX to start its work. The 512 byte cache is in general 3x faster compared to running the program in the Game Pak RAM or ROM. The Super FX can interrupt the SNES CPU after it finishes processing.

When using the Super FX's special bitmap functions, it's possible to quickly load the bitmap out of Game Pak RAM into the SNES Video RAM and display it on the screen. The SNES by default is a tile and sprite based console - pixel based scene construction used in 3D rendered games is very inefficient with stock SNES hardware. In Super FX games such as DOOM, Star Fox/Starwing and the like, the Super FX is rapidly painting pixel based scene bitmaps onto the Game Pak RAM and then throwing it into the SNES VRAM for graphics display many times per second.

Hardware Revisions

There are 3 different hardware revisions of the Super FX. All revisions are functionally compatible in terms of instruction set but support different ROM sizes.

  • MARIO Chip - which stands for Mathematical Argonaut Rotation Input Output. The first release of the Super FX chip and was only used with Star Fox/Starwing. There are two versions of the chip - one with a direct PCB die bonded/epoxied setup and one with a standard chip carrier package.
  • GSU-1 - the release used on most Super FX games in a standard chip carrier package. Functionally identical to MARIO Chip. Supports a maximum 8 Megabit (1 Megabyte) ROM size.
  • GSU-2 - used on the final 3 Super FX games, supports the full 16 Megabit (2 Megabyte) ROM size.

Registers

The Super FX chip has 16 general-purpose 16-bit registers labeled R0 to R15 plus 11 control registers. Additionally, a memory space from $3100-$32FF forms the instruction cache.

General-Purpose Registers

RegisterAddressDescriptionAccess from SNES
R0$3000default source/destination registerR/W
R1$3002pixel plot X position registerR/W
R2$3004pixel plot Y position registerR/W
R3$3006for general useR/W
R4$3008lower 16 bit result of lmultR/W
R5$300Afor general useR/W
R6$300Cmultiplier for fmult and lmultR/W
R7$300Efixed point texel X position for mergeR/W
R8$3010fixed point texel Y position for mergeR/W
R9$3012for general useR/W
R10$3014for general useR/W
R11$3016return address set by linkR/W
R12$3018loop counterR/W
R13$301Aloop point addressR/W
R14$301Crom address for GETB, GETBH, GETBL, GETBSR/W
R15$301Eprogram counterR/W

Control Registers

NameAddressDescriptionSizeAccess from SNES
SFR$3030status flag register16 bitsR/W
$3032unused
BRAMR$3033Backup RAM register8 bitsW
PBR$3034program bank register8 bitsR/W
$3035unused
ROMBR$3036rom bank register8 bitsR
CFGR$3037control flags register8 bitsW
SCBR$3038screen base register8 bitsW
CLSR$3039clock speed register8 bitsW
SCMR$303Ascreen mode register8 bitsW
VCR$303Bversion code register (read only)8 bitsR
RAMBR$303CRAM bank register8 bitsR
$303Dunused
CBR$303Ecache base register16 bitsR

Instruction Cache

NameAddressDescriptionSizeAccess from SNES
1$3100First byte of instruction cache8 bitsR/W
2$3101Second byte of instruction cache8 bitsR/W
.........8 bitsR/W
.........8 bitsR/W
512$32FFFive hundred and twelfth byte of instruction cache8 bitsR/W

SFR Status Flag Register

The SFR is a very important register. It controls branching within the Super FX after evaluating a calculation and can determine the status of the Super FX when accessed from the SNES CPU.

BitDescription
0-
1Z Zero flag
2CY Carry flag
3S Sign flag
4OV Overflow flag
5G Go flag (set to 1 when the GSU is running)
6R Set to 1 when reading ROM using R14 address
7-
8ALT1 Mode set-up flag for the next instruction
9ALT2 Mode set-up flag for the next instruction
10IL Immediate lower 8-bit flag
11IH Immediate higher 8-bit flag
12B Set to 1 when the WITH instruction is executed
13-
14-
15IRQ Set to 1 when GSU caused an interrupt. Set to 0 when read by 658c16

BRAMBR Backup RAM Register

Used to allow protection of the Back-up RAM (not to be confused with Game Pak RAM) inside the Game Pak. Bit 0 can be set to 0 to disable writing to Back-up RAM, and 1 to enable writing.

BitDescription
0BRAM Flag (0 = write disable, 1=write enable)
1Not Used
2Not Used
3Not Used
4Not Used
5Not Used
6Not Used
7Not Used

PBR Program Bank Register

When the Super FX is loading code it references the PBR register to specify the bank being used. The LJMP instruction is the general method used to change this register.

BitDescription
0A16 Address Select
1A17 Address Select
2A18 Address Select
3A19 Address Select
4A20 Address Select
5A21 Address Select
6A22 Address Select
7A23 Address Select

ROMBR Game Pak ROM Bank Register

When using the ROM buffering system, this register specifies the bank of the Game Pak ROM being copied into the buffer. The ROMB instruction is the general method used to change this register.

BitDescription
0A16 ROM Address Select
1A17 ROM Address Select
2A18 ROM Address Select
3A19 ROM Address Select
4A20 ROM Address Select
5A21 ROM Address Select
6A22 ROM Address Select
7A23 ROM Address Select

CFGR Config Register

Controls the clock multiplier and interrupt mask.

BitDescription
0Not used
1Not Used
2Not Used
3Not Used
4Not Used
5MS0 (0=standard,1=high speed)
6Not Used
7IRQ (0=normal, 1=masked)

Note: If set to run at 21.477 MHz through the CLSR flag(1), MS0 flag should be set to 0.

SCBR Screen Base Register

This register sets the starting address of the graphics storage area. It is written to directly, rather than through a specific instruction.

BitDescription
0A10 Screen Base Select
1A11 Screen Base Select
2A12 Screen Base Select
3A13 Screen Base Select
4A14 Screen Base Select
5A15 Screen Base Select
6A16 Screen Base Select
7A17 Screen Base Select

CLSR Clock Register

Controls the clock frequency of the Super FX chip.

BitDescription
0CLSR, 0=10.738 MHz, 1=21.477 MHz
1Not Used
2Not Used
3Not Used
4Not Used
5Not used
6Not Used
7Not used

SCMR Screen Mode Register

This register sets the number of colors and screen height for the PLOT graphics acceleration routine and additionally controls whether the Super FX or SNES has control of the Game Pak RAM and ROM.

BitDescription
0Color Mode MD0
1Color Mode MD1
2Screen Height HT0
3Game Pak RAM Access - RAN (0=SNES,1=Super FX)
4Game Pak ROM Access - RON (0=SNES,1=Super FX)
5Screen Height HT1
6Not used
7Not used

Screen Height Truth Table

HT1HT0Mode
00128 pixels
01160 pixels
10192 pixels
11OBJ Mode

Color Mode Truth Table

MD1MD0Mode
004 colors
0116 colors
10Not used
11256 colors

VCR Version Register

Can read out the version of the Super FX chip in use with this register

BitDescription
0VC0
1VC1
2VC2
3VC3
4VC4
5VC5
6VC6
7VC7

RAMBR Game Pak RAM Bank Register

When writing between the Game Pak RAM and the Super FX registers, this register specifies the bank of the Game Pak RAM being used. The RAMB instruction is the general method used to change this register. Bit 0 is used to set the RAM bank to $70 or $71

BitDescription
0A16 ($70 when 0, $71 when 1)
1Not Used
2Not Used
3Not Used
4Not Used
5Not Used
6Not Used
7Not Used

CBR Cache Base Register

This register specifies the address of either the Game Pak RAM or ROM where data will be loaded from into the cache. Both the LJMP and CACHE instructions are accepted ways to change this register.

BitDescription
0- (0 when read always)
1- (0 when read always)
2- (0 when read always)
3- (0 when read always)
4A4
5A5
6A6
7A7
8A8
9A9
10A10
11A11
12A12
13A13
14A14
15A15

Memory Map

From SNES CPU Point of View

Super FX Interface: Mapped to $3000-$32FF, in banks $00-$3F and $80-$BF
Game ROM: Mapped to 2MiB in banks $00-$3F from $8000-$FFFF. 2MiB mirror mapped from banks $40-$5F.
Game Pak RAM: Mapped to 128KiB starting from bank $70:$0000. First 8KiB mirrored to $6000 in each of banks $00-$3F and $80-$BF.
Game Back-up RAM: Mapped to 128KiB from bank $78:$0000
SNES CPU ROM: An additional 6MiB ROM only accessible to the SNES CPU could be used, but no Super FX games went above 2MiB. The additional ROM would've been mapped in banks $80-$BF from $8000-$FFFF and in banks $C0-$FF from $0000-$FFFF

From Super FX Point of View

Game ROM: Mapped to 2MiB in banks $00-$3F from $8000-$FFFF. 2MiB mirror mapped from banks $40-$5F.
Game Pak RAM: Mapped to 128KiB starting from Bank $70:$0000. Other memory locations viewable from the SNES should not be addressed.
Note: The Super FX accesses memory through three bank control registers: Program Bank Register(PBR), ROM Bank Register (ROMBR) and RAM Bank Register (RAMBR)

Instruction Set

The Super FX instruction set is different from the Super Nintendo's native instruction set. It allows faster, more sophisticated 16-bit mathematical functions and includes some specific graphics manipulation functions.

Some instructions can be assembled as a single byte. This is where both the instruction(nibble) and argument(nibble) are co-joined into the same storage byte. This allows for faster execution and also greater instruction density. These are important objectives when designing a co-processor. One such instruction is ADC, which starts as $5 and takes an argument of one of the 16 general purpose Super FX registers($0-$F).

Quite a few instructions require an ALT instruction to be executed before the opcode. This modifies the behavior of the same opcode to perform a slightly different operation. There are 3 possible ALT codes - ALT1($3D), ALT2($3E), and ALT1+ALT2($3F). In the table below, the specific ALT code is listed for each instruction.

Most instructions rely on pre-defined pointers for the locations of calculation variables. These are the FROM, TO and WITH instructions. The TO and FROM commands specify the general purpose register that is the variable, and the calculation result respectively. WITH defines both of the variable/result in the same command. The variable and result are known as the source and destination registers respectfully.

Instruction Set Table

InstructionDescriptionALT(Hex)CODE(HEX)ARGLength(B)BATL1ALT2O/VSCYZROMRAMCacheClassificationNote
ADCAdd with carry3D0x5Rn2000****662Arithmetic Operation Instructions
ADCAdd with carry3F0x5#n2000****662Arithmetic Operation Instructions
ADDAddNone0x5Rn1000****331Arithmetic Operation Instructions
ADDAdd3E0x5#n2000****662Arithmetic Operation Instructions
ALT1Set ALT1 modeNone0x3D/1/1/////331Prefix Flag Instructions
ALT2Set ALT2 modeNone0x3E/1//1////331Prefix Flag Instructions
ALT3Set ALT3 modeNone0x3F/1/11////331Prefix Flag Instructions
ANDLogical ANDNone0x7Rn1000/*/*331Logical Operation Instructions
ANDLogical AND3E0x7#n2000/*/*662Logical Operation Instructions
ASRArithmetric Shift RightNone0x96/1000/***331Shift Instructions
BCCBranch on carry clearNone0x0Ce2///////662"Jump, Branch and Loop Instructions"
BCSBranch on carry setNone0x0De2///////662"Jump, Branch and Loop Instructions"
BEQBranch on equalNone0x09e2///////662"Jump, Branch and Loop Instructions"
BGEBranch on greater than or equal to zeroNone0x06e2///////662"Jump, Branch and Loop Instructions"
BICBit clear mask3D0x7Rn2000/*/*662Logical Operation Instructions
BICBit clear mask3F0x7#n2000/*/*662Logical Operation Instructions
BLTBranch on less than zeroNone0x07e2///////662"Jump, Branch and Loop Instructions"
BMIBranch on minusNone0x0Be2///////662"Jump, Branch and Loop Instructions"
BNEBranch on not equalNone0x08e2///////662"Jump, Branch and Loop Instructions"
BPLBranch on plusNone0x0Ae2///////662"Jump, Branch and Loop Instructions"
BRABranch alwaysNone0x05e2///////662"Jump, Branch and Loop Instructions"
BVCBranch on overflow clearNone0x0Ee2///////662"Jump, Branch and Loop Instructions"
BVSBranch on overflow setNone0x0Fe2///////662"Jump, Branch and Loop Instructions"
CACHESet cache base registerNone0x02/1000////3-43-41GSU Control Instructions
CMODESet Plot mode3D0x4E/2000////662Plot/related instructions
CMPCompare3F0x6Rn2000****662Arithmetic Operation Instructions
COLORSet plot colorNone0x4E/1000////331Plot/related instructions
DECDecrementNone0xERn1000/*/*331Arithmetic Operation Instructions
DIV2Divide by 23D0x96/2000/***662Arithmetic Operation Instructions
FMULTFractional signed multiplyNone0x9F/1000/***11 or 711 or 78 or 4Arithmetic Operation InstructionsCycles Depends onCFGR Register
FROMSet SregNone0xBRn1///////331Prefix Register Instructions
GETBGet byte from ROM bufferNone0xEF/1000////3-83-81-6Data Transfer From Game Pak ROM to registerCycles varies due to ROM buffer
GETBHGet high byte from ROM buffer3D0xEF/2000////6-106-92-6Data Transfer From Game Pak ROM to registerCycles varies due to ROM buffer
GETBLGet low byte from ROM buffer3E0xEF/2000////6-106-92-6Data Transfer From Game Pak ROM to registerCycles varies due to ROM buffer
GETBSGet signed byte from ROM buffer3F0xEF/2000////6-106-92-6Data Transfer From Game Pak ROM to registerCycles varies due to ROM buffer
GETCGet byte from ROM to color registerNone0xDF/1000////3-103-91-6Data Transfer From Game Pak ROM to registerCycles varies due to ROM buffer
HIBValue of high byte of registerNone0xC0/1000/*/*331Byte transfer Instructions
IBTLoad immediate byte dataNone0xA"Rn, #pp"2000////662Data Transfer / Immediate data to register
INCIncrementNone0xDRn1000/*/*331Arithmetic Operation Instructions
IWTLoad immediate word dataNone0xF"Rn, #xx"3000////993Data Transfer / Immediate data to register
JMPJumpNone0x9Rn1000////331"Jump, Branch and Loop Instructions"
LDBLoad byte data from RAM3D0x4Rm1000////11136Data Transfer From Game Pak RAM to register
LDWLoad word data from RAMNone0x4Rm1000////10127Data Transfer From Game Pak RAM to register
LEALoad effective addressNone0xF"Rn, xx"3000////993Macro Instructions
LINKLink Return AddressNone0x9#n1000////331"Jump, Branch and Loop Instructions"
LJMPLong jump3D0x9Rn2000////662"Jump, Branch and Loop Instructions"
LM"Load word data from RAM, using 16 bits"3D0xF"Rn, (xx)"2000////202111Data Transfer From Game Pak RAM to register
LMS"Load word data from RAM, short address"3D0xA"Rn, (yy)"2000////171710Data Transfer From Game Pak RAM to register
LMULT16x16 signed multiply3D0x9F/2000/***10 or 1410 or 145 or 9Arithmetic Operation InstructionsCycles Depends on CFGR Register
LOBValue of low byte of registerNone0x9E/1000/*/*331Byte transfer Instructions
LOOPLoopNone0x3C/1000/*/*331"Jump, Branch and Loop Instructions"
LSRLogical shift rightNone0x03/1000/0**331Shift Instructions
MERGEMerge high byte of R8 and R7None0x70/1000////662Byte transfer Instructions
MOVEMove word data from Rn' to RnNone0x2n1n'"Rn, Rn'"2000////662Data transfer register to register
MOVESMove word data from Rn' to Rn and set flagsNone0x2nBn'"Rn, Rn'"2000////662Data transfer register to register
MULTSigned multiplyNone0x8Rn1000/*/*3 or 53 or 51 or 2Arithmetic Operation InstructionsCycles Depends on CFGR Register
MULTSigned multiply3E0x8#n2000/*/*6 or 86 or 82 or 3Arithmetic Operation InstructionsCycles Depends on CFGR Register
NOPNo operationNone0x01/1000////331GSU Control Instructions
NOTInvert all bitsNone0x4F/1000////331Bitwise Operation Instructions
ORBitwise ORNone0xCRn1000////331Bitwise Operation Instructions
ORBitwise OR3E0xC#n2000////662Bitwise Operation Instructions
PLOTPlot pixelNone0x4C/1000////3-483-511-48Plot/related instructionsCycles varies due to RAM buffer and program
RAMBSet RAM data bank3E0xDF/2000////662Bank Set/up Instructions
ROLRotate left through carryNone0x04/1000/***331Shift Instructions
ROMBSet ROM Data bank3F0xDF/2000////662Bank Set/up Instructions
RORRotate right through carryNone0x97/1000/***331Shift Instructions
RPIXRead pixel color3D0x4C/2000/*/*24-8024-7820-74Plot/related instructions
SBCSubtract with carry3D0x6Rn2000****662Arithmetic Operation Instructions
SBK"Store word data, last RAM address used"None0x9/1000////3-87-111-6Data Transfer From register to Game Pak RAM
SEXSign extend registerNone0x95/1000/*/*331Byte transfer Instructions
SMStore word data to RAM using 16 bits3E0xF"Rn, (xx)"3000////12-1716-204-9Data Transfer From register to Game Pak RAMCycles varies due to RAM buffer and program
SMS"Store word data to RAM, short address"3E0xA"Rn, (yy)"3000////9-1413-173-8Data Transfer From register to Game Pak RAMCycles varies due to RAM buffer and program
STBStore byte data to RAM3D0x3Rm2000////6-98-142-5Data Transfer From register to Game Pak RAMCycles varies due to RAM buffer and program
STOPStop processorNone0x00/1000////331GSU Control Instructions
STWStore word data to RAMNone0x3Rm1000////3-87-111-6Data Transfer From register to Game Pak RAMCycles varies due to RAM buffer and program
SUBSubtractNone0x6Rn1000****331Arithmetic Operation Instructions
SUBSubtract3E0x6#n2000****662Arithmetic Operation Instructions
SWAPSwap low and high byteNone0x4D/1000/*/*331Byte transfer Instructions
TOSet DregNone0x1Rn1///////331Prefix Register Instructions
UMULTUnsigned multiply3D0x8Rn2000/*/*6 or 86 or 82 or 3Arithmetic Operation InstructionsNumber of cycles depends on CONFIG register
UMULTUnsigned multiply3F0x8#n2000/*/*6 or 86 or 82 or 3Arithmetic Operation Instructions?
WITHSet Sreg and DregNone0x2"Rn, ?"?1?????????Prefix Register Instructions?
XORBitwise Exclusive Or3D0xCRn2??????????Bitwise Operation Instructions?
XORBitwise Exclusive Or3F0xC#n2??????????Bitwise Operation Instructions?

Sreg and Dreg

For certain instructions, the Sreg and Dreg must be specified before the instruction is run. The Sreg is the "Source Register" and the Dreg is the "Destination Register" - each specified as one of the 16 general purpose registers. Use of the TO, FROM, and WITH instructions specifies the Sreg and Dreg.

Bitmap Emulation

The Bitmap Emulation function is one of the major acceleration functions of the Super FX. It allows a pixel based shading approach within frame buffer as opposed to a tile based approach in the SNES VRAM. For 3D rendering operations, a fast pixel by pixel shader is necessary. The Super FX provides the framework to plot individual pixels to the frame buffer fast, and then transfer the plotted picture to the SNES VRAM.

Fast Multiply

The Super FX has 4 multiplication instructions.

  • MULT - Signed 8 bit x Signed 8 bit, with Signed 16 bit result in Dreg.
  • UMULT - Unsigned 8 bit x Unsigned 8 bit, with Unsigned 16 bit result in Dreg.
  • LMULT - Signed 16 bit x Signed 16 bit, with Signed 32 bit result - MSB in Dreg, LSB in R4
  • FMULT - Signed 16 bit x Signed 16 bit, with Signed 32 bit result.

The MULT/UMULT instructions are faster than the LMULT/FMULT instructions.

Compiling Super FX Routines

Whilst SNES assembly language programs can be compiled using a regular 65c816 compiler, the Super FX assembly language requires a custom compiler. The original compiler used on existing Super FX games has not been released outside the closed development community.

An open source compiler called sfxasm is available for compiling Super FX programs.

Once compiled, Super FX programs are included in the SNES assembly language program as a binary library. The SNES program then directs the Super FX to use the precompiled program packed into the ROM.

Using the Super FX in a SNES Program

When the SNES boots up with a Super FX game, the Super FX chip is idle and you don't need to do anything to start the normal SNES routine of loading the ROM and executing code. When the SNES has booted, performed some startup routines and generally is ready, then the Super FX can be activated in your program. Note, for emulators to support Super FX instructions, the $FFD6 byte in the header must be $13, $14, $15, or $1A. The $FFD5 byte should be $20.

Initializing

The Super FX chip should be initialized before running code. This includes setting the basic config registers.

  • SCBR
  • SCMR
  • CFGR
  • CLSR

Choosing the Execution Mode

As mentioned before, code can be loaded into the Super FX in 3 different ways - from Game Pak ROM, RAM, and also the 512 byte cache. Depending which way you want to go, there is a slightly different procedure.

  • The advantage of the ROM mode is simplicity at the cost of stopping the SNES CPU while Super FX is processing.
  • The advantage of the RAM mode is to be able to run a large Super FX program whilst the SNES CPU is already busy, but at the cost of having to write the program into Game Pak RAM before running.
  • The advantage of the Cache mode is to run a small program 3 times faster than ROM or RAM modes and additionally while the SNES is busy with both the Game Pak ROM and RAM, but at the cost of loading the program into cache memory before the execution process.

Setup - ROM Mode

1. Setup the Program Bank Register (PBR) for where the SFX program starts.
2. Program the program counter (R15) in the Super FX.
3. Give the Super FX exclusive access to the ROM by setting the RON flag in the SFR register.

Setup - RAM Mode

1. Transfer the program from ROM into Game Pak RAM using copy routines.
2. Setup the Program Base Register (PBR) for where the SFX program starts.
3. Write to the Super FX program counter (R15).

Setup - Cache Mode

1. Transfer the program from ROM into Cache RAM ($3100-$31FF) onwards using copy routines. The programs need to be in blocks of 16 bytes each otherwise the Super FX will not execute the instructions surplus to a 16 byte segment. This also applies for tiny programs under 16 bytes - to get around this, write something into the 16th byte ($310F)
2. Write to the Super FX program counter (R15), this is usually 0.
3. The Super FX program will execute independently of the SNES until it hits a STOP instruction. When it finished, depending if the SFR config interrupt is set, it will generate an interrupt(RTI instruction) on the SNES. If the interrupt is masked then the Super FX will go to idle mode and wait for the next command from the SNES to start execution.

Starting Processing

Processing starts when the Super FX notices that the SNES has written to its program counter register (R15).

Stopping Processing

The Super FX can be stopped in one of two ways - by executing a STOP instruction in the Super FX's program, or from the SNES by writing a "0" to the GO flag in the Super FX's SFR register.

Interrupt on Stop

The Super FX calls an RTI instruction when it reads a Super FX STOP instruction. It is possible to mask the interrupt by setting the IRQ bit in the SFR register. If interrupt is not masked, to figure out if it is a screen blanking interrupt or the Super FX, check the IRQ flag bit in the SFR register.

Category:Book:Super NES Programming#Super%20FX%20tutorial%20
Category:Book:Super NES Programming