From CloudModding OoT Wiki
(Redirected from F3DZEX)

F3DZEX2 is the primary 3D graphics microcode for the N64's Reality Signal Processor (RSP), used exclusively by both Ocarina of Time and Majora's Mask. It is a variant of the F3DEX2 (Fast 3D, Extended 2) microcode, containing a very similar (if not identical) binary interface.

Differences from F3DEX2

The SDK given to all N64 developers includes several microcodes to load onto the RSP, one of which is the F3DEX2 3D graphics microcode (the latest iteration of Nintendo's 3D microcode offerings). The microcode used in N64 Zelda titles appears to be a variation of this microcode, though how exactly is unknown.

The only known difference between the two is that the F3DZEX2 readme encourages the use of the g*SPBranchLessZraw macros over the g*SPBranchLessZ macros (note that the Zraw form is available to developers using F3DEX2, but it's undocumented in the SDK). This doesn't explain the need for a separate compiled microcode, however, since these macros only differ in how a programmer specifies the Z value for the G_BRANCH_Z command.

The readme for F3DZEX2 (as part of the iQue leak) reveals that this microcode required F3DEX2 to be installed first, with the Z-specific microcode object files and a ucode_z.h file installed on top of the F3DEX2 installation afterwards. This header file does not define any new macros or other new features over the standard F3DEX2 microcode, so the need for a Z-specific microcode object is not currently known. It's also not known why the Zraw macro is part of the standard SDK if it was only mentioned to programmers using F3DZEX2, or why the readme doesn't bring up g*SPBranchLessZrg in its discussion of how to branch on the Z value.

Versions Used

The variation used in both OoT and MM is F3DZEX2.NoN.fifo, with "NoN" standing for No Near clipping (objects between the viewer and the near clipping plane are not clipped, and objects in this area aren't subject to Z buffer calculations), and "fifo" simply being a method of transferring commands to the RSP.

Below is the version/copyright strings for F3DZEX2 present in Ocarina of Time and Majora's Mask. Note that the version strings claim the microcode as being "F3DZEX" microcode (which apparently did exist as the counterpart to F3DEX), but the iQue leak shows that the 2 was left out of the version string in F3DZEX2 object files. The Japanese Nintendo 64 versions of Majora's Mask also contain an alternate string that lacks the credit to Kawasedo.

Version String
OoT Nintendo 64 RSP Gfx ucode F3DZEX.NoN fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.
Majora's Mask JP N64 (Alt) RSP Gfx ucode F3DZEX.NoN fifo 2.08I Yoshitaka Yasumoto Nintendo 1999.
Majora's Mask RSP Gfx ucode F3DZEX.NoN fifo 2.08I Yoshitaka Yasumoto/Kawasedo 1999.
OoT GameCube/iQue RSP Gfx ucode F3DZEX.NoN fifo 2.08J Yoshitaka Yasumoto/Kawasedo 1999.

Graphics Binary Interface

This GBI instruction list is currently based on SDK documentation of F3DEX2. Slight variations may be present in F3DZEX.

The below table will link to the right part of the opcode details subpage. Rows highlighted blue are common between different microcodes, at least F3DEX and F3DEX2.

No. Name Description
00 G_NOOP Stalls RDP for a few cycles
01 G_VTX Loads vertices to RSP
02 G_MODIFYVTX Modifies a portion of vertex attributes in RSP
03 G_CULLDL End display list if object is offscreen
04 G_BRANCH_Z Branch to another display list if vertex is close enough to screen
05 G_TRI1 Draw a triangle
06 G_TRI2 Draw two triangles
07 G_QUAD Draw quadrilateral (deprecated in favor of G_TRI2)
08

BF
Unspecified; these commands mean nothing for F3DEX2
C0

C7
Potentially internal triangle commands (see below), but not documented in SDK.
C8

CF
Internal triangle commands. These are generated by the RSP; none of the macros available to the programmer would generate them. Details in the below section
D0

D2
Unspecified; these commands mean nothing for F3DEX2
D3 G_SPECIAL_3 Explicitly reserved opcode... or is it?
D4 G_SPECIAL_2 Explicitly reserved opcode... or is it?
D5 G_SPECIAL_1 Explicitly reserved opcode... or is it?
D6 G_DMA_IO DMA transfer between main RAM and RCP DMEM (or IMEM)
D7 G_TEXTURE Enables tile descriptor, sets its scaling factor and mipmap levels
D8 G_POPMTX Pops n modelview matrices from stack
D9 G_GEOMETRYMODE Configures RSP Geometry Mode
DA G_MTX Push new modelview or projection matrix
DB G_MOVEWORD Change "word" (32 bits) of data in DMEM
DC G_MOVEMEM Change block of memory in DMEM
DD G_LOAD_UCODE Load new microcode for RSP
DE G_DL Jump or "call" another display list
DF G_ENDDL End current display list
E0 G_SPNOOP Stall RSP for a few cycles
E1 G_RDPHALF_1 Set value in high half of generic RDP "word"
E2 G_SETOTHERMODE_L Configure lower half of RDP Other Modes
E3 G_SETOTHERMODE_H Configure higher half of RDP Other Modes
E4 G_TEXRECT Draw textured rectangle onto screen
E5 G_TEXRECTFLIP Draw textured rectangle onto screen, with flipped texture axes
E6 G_RDPLOADSYNC Synchronize with rendering to safely load texture
E7 G_RDPPIPESYNC Synchronize with rendering to safely update RDP attributes. Does not indicate start of display list!
E8 G_RDPTILESYNC Synchronize with rendering to safely update tile descriptor attributes
E9 G_RDPFULLSYNC Indicates end of RDP processing; interrupts CPU when RDP has nothing more to do
EA G_SETKEYGB Set green and blue components of chroma key
EB G_SETKEYR Set red component of chroma key
EC G_SETCONVERT Set conversion factors for YUV to RGB conversion
ED G_SETSCISSOR Set scissoring rectangle
EE G_SETPRIMDEPTH Set depth value of whole primitive (used when enabled)
EF G_RDPSETOTHERMODE Set state of the RDP Other Modes bits, both halves (combined E2 and E3).
F0 G_LOADTLUT Load palette into TMEM.
F1 G_RDPHALF_2 Set value in low half of generic RDP "word"
F2 G_SETTILESIZE Set dimensions of texture
F3 G_LOADBLOCK Load texture into TMEM as a continuous stream
F4 G_LOADTILE Load texture into TMEM as a rectangular region of in-RAM texture.
F5 G_SETTILE Set various parameters of a tile descriptor
F6 G_FILLRECT Draw solid color rectangle to screen
F7 G_SETFILLCOLOR Set fill color register
F8 G_SETFOGCOLOR Set fog color register
F9 G_SETBLENDCOLOR Set blend color register
FA G_SETPRIMCOLOR Set primitive color register
FB G_SETENVCOLOR Set environment color register
FC G_SETCOMBINE Set color combiner parameters
FD G_SETTIMG Set location of texture image in RAM
FE G_SETZIMG Set location of depth buffer
FF G_SETCIMG Set location of color buffer

Triangle Opcodes

Several opcodes are named in the SDK source code, but don't get used by any opcode-generating macros. The comments with these opcodes say that they're generated by the microcode itself, and that the programmer will never use (or need) them. The list of named opcodes are:

No. Name
C8 G_TRI_FILL
C9 G_TRI_FILL_ZBUFF
CA G_TRI_TXTR
CB G_TRI_TXTR_ZBUFF
CC G_TRI_SHADE
CD G_TRI_SHADE_ZBUFF
CE G_TRI_SHADE_TXTR
CF G_TRI_SHADE_TXTR_ZBUFF

The source also gives a set of bitmasks to use to construct these opcodes, which as listed are:

  • G_RDP_TRI_ZBUFF_MASK = 0x01
  • G_RDP_TRI_TXTR_MASK = 0x02
  • G_RDP_TRI_SHADE_MASK = 0x04
  • G_RDP_TRI_FILL_MASK = 0x08

E.g. to get G_TRI_TXTR_ZBUFF, you could do 0xC0 +| G_RDP_TRI_FILL_MASK +| G_RDP_TRI_TXTR_MASK +| G_RDP_TRI_ZBUFF_MASK. Note that the bitmasks would suggest that the range 0xC0..0xC7 could possibly be considered triangle commands as well, however those values are not named. Not even a display list dumper provided by the SDK accounts for those potential opcodes, only accounting for 0xC8..0xCF. So either 0xC0..0xC7 do nothing, or are otherwise not useful without a fill bit set.

Vertex Structure

In RAM/ROM

Outside of the RCP, vertices are stored in the format presented below, depending on whether they're expecting a lighting system or not.

This layout is used for vertices that supply their own color, instead of asking the lighting system to calculate one:

Struct Memory Layout
struct Vertex_Color {
    int16_t position[3]; // (X, Y, and Z) coordinate
    uint16_t reserved;   // unused
    int16_t texcoord[2]; // S and T texture coordinate
    uint8_t color[4];    // R, G, B, A color components
}
xx xx  yy yy  zz zz  00 00
ss ss  tt tt  rr gg  bb aa

While this is the layout for vertices that wish to use lighting:

Struct Memory Layout
struct Vertex_Normal {
    int16_t position[3]; // (X, Y, and Z) coordinate
    uint16_t reserved;   // unused
    int16_t texcoord[2]; // S and T texture coordinate
    int8_t normal[3];    // X, Y, and Z of vertex normal
    uint8_t alpha;       // Alpha component of vertex
}
xx xx  yy yy  zz zz  00 00
ss ss  tt tt  nn pp  qq aa

In this case, the red, green, and blue components are instead the vertex normal used in lighting calculations. The memory layout looks the same, the decision between which layout belongs to is made by whether or not the RSP is currently set to perform lighting calculations when vertices are being loaded.

The texture coordinates are in a signed fixed-point 10.5 format, in a range of -1024 ≤ n ≤ 1023.96875

In RCP

The following vertex structure documentation is unconfirmed, and is based on documentation for Fast3D.

struct Vertex_RCP {
/* 0x00 */ int16_t  xyzw_int[4];
/* 0x08 */ uint16_t xyzw_frac[4];
/* 0x10 */ u8 rgba[4]; // always a color. If lighting is enabled, this is the result of color calculations
/* 0x14 */ s16 s;
/* 0x16 */ s16 t;
/* 0x18 */ s16 xscr;
/* 0x1A */ s16 yscr;
/* 0x1C */ s16 zscr_int;
/* 0x1E */ u16 zscr_frac;
/* 0x20 */ s16 i/w_int;  // 1/w
/* 0x22 */ u16 i/w_frac; // 1/w
/* 0x24 */ ? OcOc
           ? Flags (e.g clip test results)
           ? OO
}; //size 0x28

Matrix Structure

The matrices used by the RSP are 4x4 matrices in a fixed-point s16.u16 format. The structure is a bit unusual, as shown here:

Struct Memory Layout
struct Matrix {
    int16_t intpart[4][4];
    uint16_t fracpart[4][4];
}
0000 0001 0002 0003
0100 0101 0102 0103
0200 0201 0202 0203
0300 0301 0302 0303
0000 0001 0002 0003
0100 0101 0102 0103
0200 0201 0202 0203
0300 0301 0302 0303

That is, each matrix element has its integer part at Matrix.intpart[n][m], and its fractional part at Matrix.fracpart[n][m].

The RSP does matrix multiplication with 32-bit numbers (that is, effectively combining the integer and fractional parts of an element), which leads to a 64-bit number. To fit inside a matrix, only the inner 32 bits (lower 16 integer bits, higher 16 fractional bits) are kept. An example of this:

    0123.4567
*   89AB.CDEF
-----------------
009CA39D.C94E4629
    vvvv vvvv
    A39D.C94E  (final result stored in resulting matrix)

Note that the SDK sets up access to the Matrix structure in a different way, as a simple typedef:

typedef int32_t Mtx[4][4];

That is, the integer parts are accesible as Mtx[0..1], and the fractional parts Mtx[2..3], with each matrix element as one half of the int32_t type. All parts are signed here, however it appears the fractional parts are all treated as unsigned. The other structure chosen above was done so that referencing integer and fraction parts will match the "real" index of matrix elements.

RCP Bit Fields

Various opcodes in the microcode configure bitfields that tell the RSP and RDP how to operate on what ultimately will be rendered.

RSP Geometry Mode

This 32-bit value configures how the RSP will process geometry. They are all 1-bit flags. All of these flags are disabled by default except for G_CLIPPING

Affects Bit Name Description
0000 0000 0000 0000 0000 0000 0000 0001 G_ZBUFFER Enables depth (Z buffer) calculations in the RSP
0000 0000 0000 0000 0000 0000 0000 0100 G_SHADE Enables calculating vertex color for triangle. Uses flat shading without G_SHADING_SMOOTH.
0000 0000 0000 0000 0000 0010 0000 0000 G_CULL_FRONT Front-face culling
0000 0000 0000 0000 0000 0100 0000 0000 G_CULL_BACK Back-face culling
0000 0000 0000 0001 0000 0000 0000 0000 G_FOG Calculates alpha value of primitives for fog effects
0000 0000 0000 0010 0000 0000 0000 0000 G_LIGHTING Enables lighting calculations to determine vertex color (determines how the color/normal part of loaded vertices are interpreted)
0000 0000 0000 0100 0000 0000 0000 0000 G_TEXTURE_GEN Generates spherical texture coordinates, based on X and Y components of the projected version of the normal
0000 0000 0000 1000 0000 0000 0000 0000 G_TEXTURE_GEN_LINEAR Generates linear texture coordinates, based on acos() of X and Y components of the normal, after projection transformation
0000 0000 0010 0000 0000 0000 0000 0000 G_SHADING_SMOOTH Enables smooth (Gouraud) shading of primitives. Needs G_SHADE enabled to work.
0000 0000 1000 0000 0000 0000 0000 0000 G_CLIPPING In F3DLX2, can disable clipping calculations, and is on by default. Ignored by F3DEX2, clipping is always on.
Other Meanings
0000 0000 0000 0000 0000 0000 1111 1111 The lowest byte of the geometry mode can be OR'd with G_TRI_FILL to generate an appropriate internal triangle opcode, apparently.
1111 1111 0000 0000 0000 0000 0000 0000 The highest byte of the geometry mode is OR'd with 0x703 to generate a "clip code mask". All that's known about this value is that when set to 0x04 (after ORing, 0x707), "near clipping will occur".

RDP Other Modes, Lower Half

The lower half of the RDP Other Modes control various aspects of the RDP blender, which mixes new primitives with the framebuffer. The majority of this 32-bit value sets up the render mode for the blender.

Affects Bits Name of Option Description
0000 0000 0000 0000 0000 0000 0000 0011 G_MDSFT_ALPHACOMPARE Decides how to compare the input (new) pixel's alpha value, valid choices are:
  • 00 — No comparisons are made, so doesn't affect the process
  • 01 — Compare to the alpha value of the blend color register. Draw only if input alpha is larger than the blend color alpha.
  • 11 — Compare to a random dither value in the range 0.0 < x < 1.0[note 1]. Creates stippling transparency effects, among other uses.
0000 0000 0000 0000 0000 0000 0000 0100 G_MDSFT_ZSRCSEL Selects the source of depth information for pixels. If enabled, it uses the depth value from the primitive depth value for the entire primitive. If disabled, the depth value is calculated per-pixel and used instead.
0000 0000 0000 0000 1111 1111 1111 1000 G_MDSFT_RENDERMODE (cycle-independent) Sets the cycle-independent render mode options for the RDP blender. See below for details.
1111 1111 1111 1111 0000 0000 0000 0000 G_MDSFT_RENDERMODE (cycle-dependent) Sets the cycle-dependent render mode options for the RDP blender. See below for details.

Cycle-Independent Blender Settings

The thirteen bits described here are settings for the blender that apply across both cycles in 2-cycle mode. The table in the section above shows where these cycle-independent settings fit into the lower Other Mode settings. The bit values are as follows:

Affects Bits Name of Option Description
0000 0000 0000 1 AA_EN Judging by the name, enables antialiasing. The only description in the SDK is a cryptic "if no FORCE_BL set, allow blend enable - use cvgbit."
0000 0000 0001 0 Z_CMP Enables use of the Z buffer to check if an input pixel should be written to the framebuffer.
0000 0000 0010 0 Z_UPD Updates the depth buffer when writing a new pixel. If disabled, the depth buffer value for a pixel will stay the same even after writing a closer pixel to the framebuffer.
0000 0000 0100 0 IM_RD According to description, enables read/write memory access for color and coverage values. The true meaning of this flag is unclear, though, since it's apparently not needed by all of the pre-assembled rendering modes. It seems to be the deciding factor between the two different kinds of antialiasing provided (with this option disabled leading to the faster but uglier version), but that's not the sole pattern in pre-assembled modes.
0000 0000 1000 0 CLR_ON_CVG Prevents updating the color of a pixel unless its coverage value overflows, at which point the color is set and the coverage value is set to the lower four bits of the overflowing summed coverage value. Note that coverage value is always updated, this mode doesn't prevent it.
0000 0011 0000 0 CVG_DST_* Configures out to handle the coverage value in the framebuffer (CVG_DST presumably means "coverage [value] destination"). The options available are:
  • 00CVG_DST_CLAMP — clamps the value if FORCE_BL, otherwise "new" (perhaps "new coverage value"?)
  • 01CVG_DST_WRAP — Always wraps the coverage value on overflow
  • 10CVG_DST_FULL — Force coverage value to fully-on (hence "full")
  • 11CVG_DST_SAVE — Don't overwrite buffer coverage value
0000 1100 0000 0 ZMODE_* This mode is unfortunately completely unexplained. Judging by the name, it controls the usage of the depth buffer, depending on the type of surface being rendered. Values are:
  • 00ZMODE_OPA — Opaque surfaces
  • 01ZMODE_INTER — Interpenetrating surfaces
  • 10ZMODE_XLU — Translucent surfaces
  • 11ZMODE_DEC — Decal surfaces
0001 0000 0000 0 CVG_X_ALPHA Multiplies coverage and alpha values and uses the result as both the coverage and the alpha.
0010 0000 0000 0 ALPHA_CVG_SEL Use the coverage value for alpha instead (does nothing different if CVG_X_ALPHA is enabled)
0100 0000 0000 0 FORCE_BL "Forces blending" if enabled. What this means is not explained.

Note that the highest bit of this group no longer means anything.

Cycle-Dependent Blender Settings

The 16 bits that make up the cycle-dependent settings for the RDP blender specify what and how to actually blend things together. The blender runs on the formula

   (P * A + M * B) / (A + B)

to blend primitives into the framebuffer. The 16 bits specify the values of these variables for both cycles in the following layout:

Bit Layout
Parameter PPPP AAAA MMMM BBBB
Cycle No. 1122 1122 1122 1122

Or in other words, each nybble specifies one of the formula parameters, with each nybble half specifying that parameter for one of the two cycles. In 1-cycle mode, both halves must be equal.

The P and M values can be any of the following values:

  • 00G_BL_CLR_IN — In the first cycle, parameter is color from input pixel. In the second cycle, parameter is the numerator of the formula as computed for the first cycle.
  • 01G_BL_CLR_MEM — Takes color from the framebuffer
  • 10G_BL_CLR_BL — Takes color from the blend color register
  • 11G_BL_CLR_FOG — Takes color from the fog color register

The A parameter can be set to any of these things:

  • 00G_BL_A_IN — Parameter is alpha value of input pixel
  • 01G_BL_A_FOG — Alpha value from the fog color register
  • 10G_BL_A_SHADE — Calculated alpha value for the pixel, presumably
  • 11G_BL_0 — Constant 0.0 value

And the B parameter can be set to any of these:

  • 00G_BL_1MA1.0 - source alpha
  • 01G_BL_A_MEM — Framebuffer alpha value
  • 10G_BL_1 — Constant 1.0 value
  • 11G_BL_0 — Constant 0.0 value

RDP Other Modes, Higher Half

The higher half of the RDP Other Modes bits controls various aspects of the RDP (whereas the lower half deals more with just the blender). Some of these options differ between two hardware versions; since it's currently not known which version OoT was programmed for, both versions will be accounted for below where there are differences.

Bits Affected Option Name Description
0000 0000 0000 0000 0000 0000 0011 0000 G_MDSFT_ALPHADITHER Only a hardware v2.0 option. Sets up the dithering of the alpha value for when the blender drops from 8-bit to 5-bit precision (this always happens, even for a 32-bit color buffer). Some of the settings are dependent on the color dither setting (see G_MDSFT_RGBDITHER and/or G_MDSFT_COLORDITHER below). Possible values are:
  • 00G_AD_PATTERN — Alpha dithering uses the same pattern as that for the color components. If the color dither is disabled, alpha dithering uses the "standard" Bayer pattern (so G_CD_BAYER). If the color dither is set to G_CD_NOISE, alpha dither is instead like G_CD_MAGICSQ.
  • 01G_AD_NOTPATTERN — the inverse of whatever G_AD_PATTERN would be using.
  • 10G_AD_NOISE — Random dithering pattern.
  • 11G_AD_DISABLE — No dithering for alpha values.
0000 0000 0000 0000 0000 0000 1100 0000 G_MDSFT_RGBDITHER Only a hardware v2.0 option. Sets up the dithering for the color components. Possible options are:
  • 00G_CD_MAGICSQ — Uses magic square ordered dithering (presumably a matrix of values which is a magic square, though it's not further specified)
  • 01G_CD_BAYER — Uses standard Bayer matrix (of unknown size) for ordered dithering
  • 10G_CD_NOISE — Random dithering pattern

These names for the G_MDSFT_COLORDITHER option are defined as aliases for this option in hardware version 2.0:

  • 11G_CD_DISABLE — Disable dithering for color.
  • 10G_CD_ENABLE — Backwards-compatible name, for code previously expecting hardware version 1.0. Equivalent to G_CD_NOISE.

The above two options are defined differently for hardware version 1.0, see G_MDSFT_COLORDITHER below.

0000 0000 0000 0000 0000 0001 0000 0000 G_MDSFT_COMBKEY This option enables/disables chroma key, with the bit enabled specifying chroma key is enabled.
0000 0000 0000 0000 0000 1110 0000 0000 G_MDSFT_TEXTCONV Specifies what the Texture Filter unit of the RDP should do with the texels it receives. Valid options are:
  • 000G_TC_CONV — Does the first step of converting texels from YUV to RGB (second step done in color combiner)
  • 101G_TC_FILTCONV — Does both G_TC_CONV and G_TC_FILT.
  • 110G_TC_FILT — Does linear filtering between the four texels it received into one texel. (Typically referred to as "bilinear" filtering in this context.)

Note that even though G_TC_CONV is the default state, most programs will make sure to set this value differently. If you're making a new display list, for example, and the textures happen to be messed up, making sure you set this option is one place to look (assuming a real N64 or perfect emulator).

0000 0000 0000 0000 0011 0000 0000 0000 G_MDSFT_TEXTFILT Chooses how the Texture Filter unit filters the texels it received (if doing filtering, see G_MDSFT_TEXTCONV). Available choices are:
  • 00G_TF_POINT — Just takes the texel closest to the destination pixel as-is.
  • 10G_TF_BILERP — Does linear filtering between the four texels ("bilinear filtering")
  • 11G_TF_AVERAGE — Averages values of the four texels
0000 0000 0000 0000 1100 0000 0000 0000 G_MDSFT_TEXTLUT Sets the storage type of the pixels in the TLUT, for color-indexed textures. Possible values are:
  • 00G_TT_NONE — No TLUT is being used
  • 10G_TT_RGBA16 — Colors are stored in RGBA16 format
  • 11G_TT_IA16 — Colors are stored in IA16 format
0000 0000 0000 0001 0000 0000 0000 0000 G_MDSFT_TEXTLOD Sets whether to use LOD calculations in selecting texture tiles. Possible values are:
  • 0G_TL_TILE — No LOD performed. Display list specifies the tile to use directly. In 2-cycle mode the second tile selected is the next one after the specified tile, that is selected_tile + 1.
  • 1G_TL_LOD — LOD is performed. Calculations are done to select the closer (i.e. larger) tile for a given LOD. In 2-cycle mode the second-closest mipmap level is chosen as the second tile.
0000 0000 0000 0110 0000 0000 0000 0000 G_MDSFT_TEXTDETAIL Decides how to handle texturing when the LOD is less than 1.0, if LOD is enabled (see G_MDSFT_TEXTLOD above). Available choices are:
  • 00G_TD_CLAMP — Just uses the tile for the highest LOD.
  • 01G_TD_SHARPEN — Generates a sharper texture from the highest two mipmap levels.
  • 10G_TD_DETAIL — Uses a special detail texture to add detail to the highest mipmap level.

It's not known what would happen if you set both bits, that is specify both sharpening and detail texture.

0000 0000 0000 1000 0000 0000 0000 0000 G_MDSFT_TEXTPERSP Enables perspective correction on texture coordinates when set.
0000 0000 0011 0000 0000 0000 0000 0000 G_MDSFT_CYCLETYPE Sets the cycle type of RDP, and thus what it does in rendering.
  • 00G_CYC_1CYCLE — 1-cycle mode. Renders a pixel per clock cycle.
  • 01G_CYC_2CYCLE — 2-cycle mode. Renders a pixel per two clock cycles. Used when more advanced operations are needed, e.g. fog effects or mipmapping.
  • 10G_CYC_COPY — Texture copy mode. Copies a texture direct to the framebuffer at 64 bits per clock cycle. Can apparently still do alpha comparison, but otherwise is just direct copying.
  • 11G_CYC_FILL — Buffer fill mode. Fills the chosen color buffer (which may really be the depth buffer) with the color in the fill color register at a rate of 64 bits per clock cycle.

Note that only 1-cycle and 2-cycle mode make use of the whole RDP pipeline; fill and copy mode skip past most (if not all) of it for greater speeds.

0000 0000 0100 0000 0000 0000 0000 0000 G_MDSFT_COLORDITHER Only for hardware version 1.0. Enables dithering in the color components of pixels, with the set bit enabling it. Note that the names G_CD_ENABLE and G_CD_DISABLE are defined for G_MDSFT_RGBDITHER instead in hardware version 2.0.
0000 0000 1000 0000 0000 0000 0000 0000 G_MDSFT_PIPELINE This option controls whether span buffer coherency will be used in the RDP. Options are:
  • 0G_PM_NPRIMITIVE — No coherency is guaranteed. Several span buffers may load the same area of the framebuffer into memory, causing problems in rendering.
  • 1G_PM_1PRIMITIVE — Coherency is acheived via adding around 30 to 40 null cycles after the last span of a primitive is rendered. This ensures that each span buffer will always have the latest-computed version of pixels. This reduces speed (due to the empty cycles) at the cost of correctness. The SDK notes that this shouldn't be used unless necessary.

Color Combiner Settings

The color combiner mixes colors together with the general formula

   (a - b) * c + d

The choice of what a, b, c, and d mean is configured by the programmer, separately for color and alpha. In 2-cycle mode, these calculations can be set differently for the second cycle (1-cycle mode needs the settings to match). In essence, four calculations can be performed:

   First/only cycle color = (ca1 - cb1) * cc1 + cd1
   First/only cycle alpha = (aa1 - ab1) * ac1 + ad1
   Second cycle color     = (ca2 - cb2) * cc2 + cd2
   Second cycle alpha     = (aa2 - ab2) * ac2 + ad2

The configuration of this is done by opcode FC, and the values they take vary based on which parameter you're configuring for. A chart of valid configuration values is below:

Parameter Color A Color B Color C Color D Alpha A Alpha B Alpha C Alpha D
00 G_CCMUX_COMBINED G_ACMUX_COMBINED G_ACMUX_LOD_FRACTION G_ACMUX_COMBINED
01 G_CCMUX_TEXEL0 G_ACMUX_TEXEL0
02 G_CCMUX_TEXEL1 G_ACMUX_TEXEL1
03 G_CCMUX_PRIMITIVE G_ACMUX_PRIMITIVE
04 G_CCMUX_SHADE G_ACMUX_SHADE
05 G_CCMUX_ENVIRONMENT G_ACMUX_ENVIRONMENT
06 G_CCMUX_1 G_CCMUX_CENTER G_CCMUX_SCALE G_CCMUX_1 G_ACMUX_1 G_ACMUX_PRIM_LOD_FRAC G_ACMUX_1
07 G_CCMUX_NOISE G_CCMUX_K4 G_CCMUX_COMBINED_ALPHA G_CCMUX_0 G_ACMUX_0
08 G_CCMUX_0 G_CCMUX_0 G_CCMUX_TEXEL0_ALPHA
09 G_CCMUX_TEXEL1_ALPHA
0A G_CCMUX_PRIMITIVE_ALPHA
0B G_CCMUX_SHADE_ALPHA
0C G_CCMUX_ENV_ALPHA
0D G_CCMUX_LOD_FRACTION
0E G_CCMUX_PRIM_LOD_FRAC
0F G_CCMUX_K5
10

1F
G_CCMUX_0


Note that, in SDK code, G_CCMUX_0 is actually defined as 0x1F, with the value ANDed to the right number of bits for the particular parameter. The other values the various G_CCMUX_0 options occupy in each parameter are specified in other parts of SDK documentation.

Parameter Description

Here is a list detailing what all the color options above do:

  • G_CCMUX_COMBINED — Uses the color value calculated in the first cycle. Presumably only for the second cycle of 2-cycle mode, behavior unknown in the first/only cycle.
  • G_CCMUX_TEXEL0 — Uses the texel colors from the currently-selected tile; either the directly selected tile or the closest tile as chosen by LOD, depending on LOD calculations.
  • G_CCMUX_TEXEL1 — Uses the texel colors from the next (farther) tile after TEXEL0.
  • G_CCMUX_PRIMITIVE — Takes color from the primitive color register.
  • G_CCMUX_SHADE — Uses the color for the current pixel of the primitive, as calculated from vertex colors. That is, flat shading would effectively return the color for the first vertex, and non-flat shading would calculate the color from all the vertices as per Gouraud shading.
  • G_CCMUX_ENVIRONMENT — Uses color from the environment color register.
  • G_CCMUX_1 — Uses a constant 1.0 for all color components (red, green, and blue).
  • G_CCMUX_NOISE — Uses random values for color components.
  • G_CCMUX_0 — Uses a constant 0.0 for all color components (red, green, and blue).
  • G_CCMUX_CENTER — Uses the center values set for chroma keying.
  • G_CCMUX_K4 — Uses constant K4 from the set values for the YUV to RGB conversion process.
  • G_CCMUX_SCALE — Uses scale values set for chroma keying.
  • G_CCMUX_COMBINED_ALPHA — Uses alpha value calculated in the first cycle in all color components. Presumably only for the second cycle of 2-cycle mode, behavior unknown in the first/only cycle.
  • G_CCMUX_TEXEL0_ALPHA — Uses alpha value from the texel of the currently-selected tile in all color components.
  • G_CCMUX_TEXEL1_ALPHA — Uses alpha value from the texel of the next tile in all color components.
  • G_CCMUX_PRIMITIVE_ALPHA — Uses alpha value from the primitive color register in all color components.
  • G_CCMUX_SHADE_ALPHA — Uses alpha value from current pixel of the primitive in all color components.
  • G_CCMUX_ENV_ALPHA — Uses the alpha value from the environment color register in all color components.
  • G_CCMUX_LOD_FRACTION — Uses the LOD fraction value specified in the primitive color register for all color components.
  • G_CCMUX_PRIM_LOD_FRAC — Unclear, used in only one (undocumented) Color Combiner configuration. Possibly the calculated LOD value for the current pixel of the primitive.
  • G_CCMUX_K5 — Uses constant K5 from the set values for YUV to RGB conversion.

And for alpha options:

  • G_ACMUX_COMBINED — Uses alpha value calculated in the first cycle. Presumably only for the second cycle of 2-cycle mode, behavior unknown in the first/only cycle.
  • G_ACMUX_TEXEL0 — Uses alpha value in the texel from the currently-selected tile.
  • G_ACMUX_TEXEL1 — Uses alpha value in the texel from the next tile after TEXEL0.
  • G_ACMUX_PRIMITIVE — Uses alpha value from the primitive color register.
  • G_ACMUX_SHADE — Uses alpha value from the current primitive pixel's calculated RGBA value.
  • G_ACMUX_ENVIRONMENT — Uses alpha value from the environment color register.
  • G_ACMUX_1 — Uses a constant 1.0 for the alpha component.
  • G_ACMUX_0 — Uses a constant 0.0 for the alpha component.
  • G_ACMUX_LOD_FRACTION — Uses the LOD fraction value from the primitive color register.
  • G_ACMUX_PRIM_LOD_FRAC — Unclear, used in only one (undocumented) Color Combiner configuration. Possibly the calculated LOD value for the current pixel of the primitive.

DMEM Memory Access

This section describes the parts of the RCP's DMEM that G_MOVEWORD and G_MOVEMEM handle. These commands access memory via a pointer table, so their locations are currently only known via these table indices.

Following is a description of what the table indices for each of those two opcodes mean:

Name Index Description
G_MOVEWORD Indices
G_MW_MATRIX 00 Allows direct modification of part of the current MP (modelview * projection) matrix (which is calculated upon loading of either kind of matrix), modifying two elements' integer or fractional parts. Supposedly not supported by F3DEX2.
G_MW_NUMLIGHT 02 Specifies the number of directional/diffuse lights. (The lighting system always has an ambient light.)
G_MW_CLIP 04 Specifies the ratio between the clipping and scissoring boxes.
G_MW_SEGMENT 06 Sets up the physical address of a segment.
G_MW_FOG 08 Specifies the multiplier and offset for fog effects.
G_MW_LIGHTCOL 0A Changes the color of a light without changing the direction
G_MW_FORCEMTX 0C Tells the RCP if the MP matrix has been forcibly changed(?)
G_MW_PERSPNORM 0E Sets amount by which to scale the W axis value before dividing X, Y, and Z by it.
G_MOVEMEM Indices
G_MV_VIEWPORT 08 Specifies the scale and translation of the viewport.
G_MV_LIGHT 0A Location of appropriate light structures.
G_MV_MATRIX 0E The location of the multiplied MP matrix.

Note that there are more indices defined for G_MOVEMEM, but only the ones listed above are used by any macros.


Notes

  1. Not sure if the range is (0.0, 1.0), [0.0, 1.0), (0.0, 1.0], or [0.0, 1.0]