SuperFX
Talk0this wiki
This is an attempt to document the SuperFX, a processor inside the cartridges of some SNES games. This knowledge comes from the source diving into BSNES and Snes9x.
This wiki page is not complete and might contain mistakes.
Contents |
Requirements
Edit
SuperFX seems to require the LoROM layout and to limit the ROM to 2 megabytes (equal to 64 LoROM banks).
SNES header
Edit
Emulators use the SNES header to decide whether to emulate SuperFX. (The real SNES ignores this part of the SNES header and uses the actual hardware in the cartridge.) If you want to add SuperFX to a game, then you edit the SNES header.
BSNES and Snes9x each require that
- the value at $ffd5 is exactly $20.
- the value at $ffd6 is $13, $14, $15 or $1a.
- $13 => SuperFX with no battery
- $14 => SuperFX with no battery
- $15 => SuperFX with save-RAM
- $1a => SuperFX with save-RAM
The value at $ffbd is a RAM size byte, like $ffd8. I am not sure how this works.
- The value at $ffbd supersedes the value at $ffd8?
- One value controls the total size of RAM, while the other value the amount that acts as save-RAM?
Address $ffdb is within the extended header, so the licensee code at $ffda must be $33. Snes9x ignores the value at $ffdb unless the licensee code is $33, but BSNES checks not the licensee code.
Address space
Edit
The cartridge contains ROM and RAM. SuperFX in the cartridge shares them with 5A22, the central processor in the SNES. One flag controls whether SuperFX or 5A22 has access to the ROM. Another flag controls access to the RAM. The 5A22 uses SNES addresses, but the SuperFX uses SuperFX addresses.
Central address space
Edit
Each SuperFX register appears in the central access space, so that 5A22 can access each SuperFX register. This allows the 65816 code at 5A22 to communicate with SuperFX.
Each register has 2 bytes. The easy way is to bring the 5A22 to 16-bit mode (through the 65816 processor flags) when you access these registers.
|
Size |
Description | |
|
REG $3000 |
2 bytes |
SuperFX r0 |
|
REG $3002 |
2 bytes |
SuperFX r1 |
|
REG $3004 |
2 bytes |
SuperFX r2 |
|
REG $3006 |
2 bytes |
SuperFX r3 |
|
REG $3008 |
2 bytes |
SuperFX r4 |
|
REG $300a |
2 bytes |
SuperFX r5 |
|
REG $300c |
2 bytes |
SuperFX r6 |
|
REG $300e |
2 bytes |
SuperFX r7 |
|
REG $3010 |
2 bytes |
SuperFX r8 |
|
REG $3012 |
2 bytes |
SuperFX r9 |
|
REG $3014 |
2 bytes |
SuperFX r10 |
|
REG $3016 |
2 bytes |
SuperFX r11 |
|
REG $3018 |
2 bytes |
SuperFX r12 |
|
REG $301a |
2 bytes |
SuperFX r13 |
|
REG $301c |
2 bytes |
SuperFX r14 |
|
REG $301e |
2 bytes |
SuperFX r15. If you write $301f, then SuperFX starts to run. |
|
REG $3030 |
2 bytes |
SuperFX processor status register. If you set the "go" flag, then SuperFX starts to run. If you read $3031, then you clear some IRQ. |
|
REG $3034 |
2 bytes? |
Program bank register |
|
REG $3036 |
2 bytes? |
ROM bank register |
|
REG $303c |
2 bytes? |
RAM bank register |
SuperFX address space
Edit
SuperFX divides its address space into banks. SuperFX has three current banks; these are the current ROM bank, the current RAM bank and the current program bank.
- SuperFX can access a maximum of $20 ROM banks, each $10000 bytes.
- This limits a SuperFX cartridge to 2 MB of ROM.
- The address space has four RAM banks. The banks $70..$73 hold RAM. However, the typical SuperFX has only one or two banks of RAM.
- SuperFX never uses banks $60 through $6f, nor banks >= $74.
Registers
Edit
SuperFX boasts 16 general purpose registers named r0 through r15. Some of these registers also have a special purpose. These registers also appear as $3000..$301f, but in which address space?
- $3000 => r0
- $3002 => r1
- ...
- $301e => r15
r15 is the program counter, and points to an instruction in the current program bank. SuperFX uses a pipe to fetch instructions. When SuperFX executes the instruction in the pipe, it also uses r15 to fetch the next instruction to the pipe. The order is to
- grab the first instruction from the pipe,
- use r15 to fetch the second instruction to the pipe,
- execute the first instruction.
SuperFX also has other special purpose registers.
Processor flags
Edit
i00bhlaa0rgvscz0 | ||||| |||||| | ||||| |||||\--$0002 zero | ||||| ||||\--$0004 carry | ||||| |||\--$0008 sign | ||||| ||\--$0010 overflow | ||||| |\--$0020 go | ||||| \--$0040 read ROM r14 | ||||| | ||||\--$0100 alternate 1 | |||\--$0200 alternate 2 | ||\--$0400 lower immediate | |\--$0800 higher immediate | \--$1000 with (why letter b?) | | \--$8000 IRQ
Opcodes
Edit
SuperFX uses 256 opcodes, numbered $00..$ff. SuperFX has four alternate modes. The current alternate mode determines the meaning of the opcode. Its two flags control the current alternate mode.
i00bhlaa0rgvscz0
||
00 => alternate 0
01 => alternate 1
10 => alternate 2
11 => alternate 3
Many opcodes perform the small reset, which is to
- clear the "with" flag,
- clear the alternate mode to alternate 0,
- set the source and destination registers to r0.
Opcode $01 is the nop instruction. This instruction performs the small reset and increments r15.