====== Fast3D Display List Commands ======
The Fast3D display list commands are microcode that are passed to the RSP for rendering. They are all 8 bytes long.
===== Fast3D Commands =====
==== 00: G_SPNOOP ====
No operation. This should only be used for debugging purposes.
''00 00 00 00 00 00 00 00''
==== 01: G_MTX ====
Apply transformation matrix. Used in HUD text printing code to translate textures, as well as copious other transformations including animations.
''01 [PP] 00 00 [AA AA AA AA]''
| P | Parameters |
| A | Segmented address of vectors |
Parameters (can be OR'd together):
| 0x01 | projection (default: model view) |
| 0x02 | load (default: multiply) |
| 0x04 | push (default: no push) |
Example: Push matrix and multiply by matrix at 0x00213DF8; Multiply by matrix at 0x00213DB8
01 04 00 40 00 21 3D F8
01 00 00 40 00 21 3D B8
==== 03: G_MOVEMEM ====
Takes a block of memory from an address and puts it in the location pointed to by an index and an offset.
''03 [ii] [nnnn] [aa aa aa aa]''
| i | Index into table of DMEM addresses |
| n | Size in bytes of memory to be moved |
| a | Segmented address of memory |
**i** is an index into a table of addresses of DMEM. Given enumerations for **i** are:
* G_MV_VIEWPORT = 0x80
* G_MV_LOOKATY = 0x82
* G_MV_LOOKATX = 0x84
* G_MV_L0 = 0x86
* G_MV_L1 = 0x88
* G_MV_L2 = 0x8a
* G_MV_L3 = 0x8c
* G_MV_L4 = 0x8e
* G_MV_L5 = 0x90
* G_MV_L6 = 0x92
* G_MV_L7 = 0x94
* G_MV_TXTATT = 0x96
Note: G_MV_TXTATT is not used by any of the macros given to programmers.
In Super Mario 64, this is mainly used to load vector lighting ambient/diffuse RGBA values.
The ambient light is loaded using G_MV_L1 (0x88), and the segment address points to 8 bytes defining the ambient color RGB value.
03 88 00 10 0E 00 00 00 // This loads the ambient light from segment address 0x0E000000.
At address 0x0E000000:
FF FF FF 00 FF FF FF 00 // Sets the ambient color to be white. The zeroes here don't matter.
Note 1: The last 4 bytes should match the first 4 since it is a copy of the RGB color.
Note 2: The 4th and 8th bytes are just padding; they don't represent the alpha value.
The diffuse light is loaded using G_MV_L0 (0x86), and the segment address points to 16 bytes defining the color RGB value and normalized direction that the light is coming from.
03 86 00 10 0E 00 00 08 // This loads the diffuse light from segment address 0x0E000008.
At address 0x0E000008:
7F 7F 7F 00 7F 7F 7F 00 // Sets the diffuse light color to be gray.
28 28 28 00 00 00 00 00 // SM64 usually sets the normalized direction as (0x28, 0x28, 0x28)
Note: All the zeroes here are for padding, since diffuse lights are 16-byte aligned.
The normalized direction is calculated using the following formula:
First calculate variable 'd' as: d = 127/square_root(x*x + y*y + z*z)
Then the normalized direction is: Xn = x*d; Yn = y*d; Zn = z*d
Note: Xn, Yn, and Zn should be signed bytes.
----
==== 04: G_VTX ====
Fills the vertex buffer with vertex information (ex. coordinates, color values). Max amount of bytes to load in F3D is 0x100 (16 vertices).
''04 [N][I] [LL LL] [SS SS SS SS]''
| N | Number of vertices - 1 |
| I | Where to start writing vertices inside the vertex buffer |
| L | Length of vertex data to write in bytes((N+1)*0x10) |
| S | Segmented address to load vertices from |
Example: Load 15 (0xF0 / 0x10) vertices from 0x0E000780 (current map data) - and put them into the vertex buffer, starting at position 0.
04 E0 00 F0 0E 00 07 80
----
==== 06: G_DL ====
Signifies the start of a Display List. May be used to link data and branch the current DL.
''06 [AA] 00 00 [BB BB BB BB]''
| AA | 00 = store return address, 01 = don't store (end DL after branch) |
| B | Segmented Address to branch to |
Example: Loads a display list from 0xA50 in segment 0x07.
06 00 00 00 07 00 0A 50
----
==== B2: G_RDPHALF_CONT ====
Acts as an indicator that the command continues with the given lower word. This is used only when operators longer than 64bits are in use.
Note: When this command gets executed, it will immediately send all the previous data (from RDPHALF_1 and/or RDPHALF_2) to the RDP.
''B2 00 00 00 [CC CC CC CC]''
| C | Continued value of lower word. |
----
==== B3: G_RDPHALF_2 ====
This opcode sets the low half of the generic RDP word.
''B3 00 00 00 [LL LL LL LL]''
| L | New value of low word |
Note: the referenced function also generates opcode B4. See the section on B4 for info on that.
----
==== B4: G_RDPHALF_1 ====
This opcode sets the higher half of the generic RDP word.
''B4 00 00 00 [hh hh hh hh]''
| h | New value of high word |
**Note:** the referenced function also generates opcode B3. See the section on B3 for info on that.
----
==== B6: G_CLEARGEOMETRYMODE ====
Disables certain geometry parameters (ex. lighting, front-/backface culling, Z-buffer).
''B6 00 00 00 [AA AA AA AA]''
| A | Various parameters |
Parameters:\\
See [[https://hack64.net/wiki/doku.php?id=rcpstructs#rsp_geometry_mode|RSP Geometry Mode]] under RCP Structs.
Examples:
B6 00 00 00 00 02 10 00 : Disable G_LIGHTING and G_CULL_FRONT
B6 00 00 00 00 02 00 00 : Disable G_LIGHTING
B6 00 00 00 00 00 00 00 : Disable nothing
B6 00 00 00 00 00 22 00 : Disable G_CULL_BACK and G_SHADING_SMOOTH
----
==== B7: G_SETGEOMETRYMODE ====
Enables certain geometry parameters (ex. lighting, front-/backface culling, Z-buffer).
''B7 00 00 00 [AA AA AA AA]''
| A | Various parameters |
Parameters:\\
See [[https://hack64.net/wiki/doku.php?id=rcpstructs#rsp_geometry_mode|RSP Geometry Mode]] under RCP structs.
Examples:
B7 00 00 00 00 02 10 00 : Enable G_LIGHTING and G_CULL_FRONT
B7 00 00 00 00 02 00 00 : Enable G_LIGHTING
B7 00 00 00 00 00 00 00 : Enable nothing
B7 00 00 00 00 00 22 00 : Enable G_CULL_BACK and G_SHADING_SMOOTH
----
==== B8: G_ENDDL ====
Terminates the current Display List
''B8 00 00 00 00 00 00 00''
----
==== B9: G_SetOtherMode_L ====
Modifies various bits of the lower half of the RDP Other Modes word.
''B9 00 [ss] [nn] [dd dd dd dd]''
| s | Amount mode-bits are shifted by, or number of LSb of mode bits to be changed |
| n | Number of mode-bits affected (-1) |
| d | Mode-bits |
The operation performed by the opcode can be expressed as such, assuming LO to stand for the lower word of the RDP other modes:
LO = LO & ~(((1 << n) - 1) << s) | d
Or, in English, it clears all the bits designated to be modified (determined by s and n), and then sets those bits according to data. Important to note that mode-bits //are **preshifted**//. That is, it is up to the caller to shift data appropriately. The enumerations provided for data are pre-shifted to match this requirement.\\ The enumerations provided for s are:
* G_MDSFT_ALPHACOMPARE = 0
* G_MDSFT_ZSRCSEL = 2
* G_MDSFT_RENDERMODE = 3
The structure of the lower modes is provided [[https://hack64.net/wiki/doku.php?id=rcpstructs#lower-half_bits|in the RCP structs page]].
----
==== BA: G_SetOtherMode_H ====
Modifies various bits of the lower half of the RDP Other Modes word.
''BA 00 [ss] [nn] [dd dd dd dd]''
| s | Amount mode-bits are shifted by, or number of LSb of mode bits to be changed |
| n | Number of mode-bits affected (-1) |
| d | Mode-bits |
Like with B9, data is preshifted, and the opcode's procedure can be formulised in the same way (where OH stands for the high word of the other modes):
OH = OH & ~(((1 << n) - 1) << s) | d
The enumerations provided for s are:
* G_MDSFT_BLENDMASK = 0
* G_MDSFT_ALPHADITHER = 4
* G_MDSFT_RGBDITHER = 6
* G_MDSFT_COMBKEY = 8
* G_MDSFT_TEXTCONV = 9
* G_MDSFT_TEXTFILT = 0x0C
* G_MDSFT_TEXTLUT = 0x0E
* G_MDSFT_TEXTLOD = 0x10
* G_MDSFT_TEXTDETAIL = 0x11
* G_MDSFT_TEXTPERSP = 0x13
* G_MDSFT_CYCLETYPE = 0x14
* G_MDSFT_COLORDITHER = 0x16
* G_MDSFT_PIPELINE = 0x17
The structure of the higher modes is provided [[https://hack64.net/wiki/doku.php?id=rcpstructs#lower-half_bits|in the RCP structs page]].
----
==== BB: G_TEXTURE ====
Sets the texture scaling factor.
''BB 00 [xx] [nn] [ss ss] [tt tt]''
''xx = 00LL Lddd''
| n | Enable/Disable Tile Descriptor (1=enable, 0=disable) |
| s | Scaling factor for S axis (horizontal) |
| t | Scaling factor for T axis (vertical) |
| L | Maximum number of mipmap levels aside from the first |
| d | Tile descriptor to enable/disable |
Note that scaling factors are binary fractional values with an implied 0.; for example, a scaleS of 0x8000 means 0b0.1000_0000_0000_0000, or 0d0.5.
Examples:
BB 00 00 01 FF FF FF FF : Standard - at start for extremely close to 1 scaling enabled on tile desc 0.
BB 00 00 01 80 00 80 00 : Standard - at start for 0.5 scaling enabled on tile desc 0.
BB 00 00 01 0F 80 07 C0 : Scale for environment mapping 64x32 (Metal mario) and enable tile desc 0.
BB 00 00 00 FF FF FF FF : Disable tile descriptor 0 (end of DL).
----
==== BC: G_MOVEWORD ====
Loads a new 32-bit value data to the location specified by index and offset.
''BC oo oo ii dd dd dd dd''
| o | Offset from the indexed base address |
| i | Index into DMEM pointer table |
| d | New 32-bit value |
**i** is an index into a table of DMEM addresses. The enumerations given for this are:
| G_MW_MATRIX | 0x00 | 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. |
| G_MW_NUMLIGHT | 0x02 | Specifies the number of directional/diffuse lights. (The lighting system always has an ambient light.) |
| G_MW_CLIP | 0x04 | Specifies the ratio between the clipping and scissoring boxes. |
| G_MW_SEGMENT | 0x06 | Sets up the physical address of a segment. |
| G_MW_FOG | 0x08 | Specifies the multiplier and offset for fog effects. |
| G_MW_LIGHTCOL | 0x0A | Changes the color of a light without changing the direction |
| G_MW_FORCEMTX | 0x0C | Tells the RCP if the MP matrix has been forcibly changed(?) |
| G_MW_PERSPNORM | 0x0E | Sets amount by which to scale the W axis value before dividing X, Y, and Z by it. |
The offset is, as the name suggests, an offset from the address that index resolves to. Enumerations are also provided for this value, for each of the enumerated index values. (XXX where to put them? It's a bit of a list.)
----
==== BD: G_POPMTX ====
Pops a matrix from the stack.
''BD000000 00 00 00 00''
Removes the top matrix from the matrix stack in dmem
----
==== BE: G_CULLDL ====
''BE 00 vv vv 00 00 ww ww''
| v | Vertex buffer index of first vertex for bounding volume (*0x0A) |
| w | Vertex buffer index of last vertex for bounding volume (*0x0A) |
This command takes the vertices in the vertex buffer from vfirst through vlast as describing the volume of the object being rendered (called the "bounding value"). If the bounding volume does not intersect with the current viewing volume (aka if the bounding volume is entirely offscreen), then the display list ends, equivalent to a B8 opcode. Otherwise, the display list continues as though nothing happened (equivalent to 00, then).
For F3D 1.0, Each of vfirst and vlast must be in the range 0 ≤ x ≤ 15. Additionally, vfirst < vlast must be true (thus a minimum of two vertices must be specified, and range of vertices cannot be reversed). It's not specified what the behavior is when all the vertices are coplanar.
----
==== BF: G_TRI1 ====
Renders one triangle according to the vertices inside the vertex buffer
''BF 00 00 00 00 [AA] [BB] [CC]''
| A | First vertex to use for the triangle (* 0x0A) |
| B | Second vertex to use for the triangle (* 0x0A) |
| C | Third vertex to use for the triangle (* 0x0A) |
Example: Render a triangle using the vertex data specified at the vertex buffer positions 0, 1 (0x0A / 0x0A) and 2 (0x14 / 0x0A).
BF 00 00 00 00 00 0A 14
----
==== C0: G_NOOP ====
Does nothing. Seemingly different from 00; this opcode may stall the RDP instead of the RSP, or the other way around, though nothing has been really confirmed. (Judging by gbi.h from F3DEX)
''C0 00 00 00 00 00 00 00''
----
==== E4: G_TEXRECT ====
Draws a textured 2D rectangle on the screen
''E4 [xx x][y yy] 0[I] [XX X][Y YY]''\\
''B3 00 00 00 [SS SS] [TT TT]'' (RDPHalf_2)\\
''B2 00 00 00 [DD DD] [EE EE]'' (RDPHalf_Cont)
| xxx | Lower-right corner X coordinate |
| yyy | Lower-right corner Y coordinate |
| I | Tile descriptor to use for rectangle |
| XXX | Upper-left corner X coordinate |
| YYY | Upper-left corner Y coordinate |
| SSSS | Texture S coordinate at upper-left corner |
| TTTT | Texture T coordinate at upper-left corner |
| DDDD | Change in S coordinate over change in X coordinate |
| EEEE | Change in T coordinate over change in Y coordinate |
----
==== E5: G_TEXRECTFLIP ====
Draws a textured 2D rectangle on the screen
''E5 [xx x][y yy] 0[I] [XX X][Y YY]''\\
''B3 00 00 00 [SS SS] [TT TT]'' (RDPHalf_2)\\
''B2 00 00 00 [DD DD] [EE EE]'' (RDPHalf_Cont)
| xxx | Lower-right corner X coordinate |
| yyy | Lower-right corner Y coordinate |
| I | Tile descriptor to use for rectangle |
| XXX | Upper-left corner X coordinate |
| YYY | Upper-left corner Y coordinate |
| SSSS | Texture S coordinate at upper-left corner |
| TTTT | Texture T coordinate at upper-left corner |
| DDDD | Change in T coordinate over change in X coordinate |
| EEEE | Change in S coordinate over change in Y coordinate |
This is similar to opcode E4, with the only difference being that the S and T coordinates of a texture are flipped in rendering, so that S coordinates are along the Y axis and T along the X axis. This essentially flips the texture about the diagonal line (XXX,YYY),(xxx,yyy).
----
==== E6: G_RDPLOADSYNC ====
This forces a wait for a texture to load, in order to synchronize with pixel rendering. This ensures that loading a new texture won't disrupt the rendering of primitives mid-render.
''E6 00 00 00 00 00 00 00''
----
==== E7: G_RDPPIPESYNC ====
**This is not the "start of display list" command. //There is no such thing.//**
Waits for the RDP to finish rendering its currently-rendering primitive, before updating RDP attributes. This avoids altering the rendering of a primitive in the middle of its render.
''E7 00 00 00 00 00 00 00''
Historically, several model viewers have interpreted this command as somehow starting a display list. **This is not true.** Display lists have no command that starts a display list. To find display lists, the most accurate way would be to find the end display list command (B8) and work backwards, until an invalid display list command is encountered, or to parse byte-code that points to display lists.
----
==== E8: G_RDPTILESYNC ====
Forces a wait for rendering to finish before updating tile descriptor attributes, so as to not disrupt rendering of primitives mid-render.
''E8 00 00 00 00 00 00 00''
----
==== E9: G_RDPFULLSYNC ====
Generates an interrupt for the main CPU when the RDP has finished doing everything. This is typically the last opcode before the "end display list" opcode (B8).
''E9 00 00 00 00 00 00 00''
----
==== EA: G_SETKEYGB ====
Sets the center, scale, and width parameters for the green and blue components for chroma key (see EB for red).
''EA [ww w][x xx] [cc] [ss] [dd] [tt]''
| w | Scaled width of half the key window for green |
| x | Scaled width of half the key window for blue |
| c | Intensity of active key for green |
| s | Reciprocal of size of soft edge, normalized to 0..0xFF, for green |
| d | Intensity of active key for blue |
| t | Reciprocal of size of soft edge, normalized to 0..0xFF, for blue |
w and x are in an unsigned fixed-point 4.8 format. The other parameters are normal 8-bit unsigned integers.
----
==== EB: G_SETKEYR ====
Sets the scale, center, and width parameters for the red component for chroma key (see EA for blue and green).
''EB 00 00 00 0[w ww] [cc] [ss]''
| w | Scaled with of half the key window for red |
| c | Intensity of active key for red |
| s | Reciprocal of size of soft edge, normalized to 0..0xFF, for blue |
Sets the scale, center, and width parameters for the red component for chroma key (see EA for blue and green).
w is an unsigned fixed-point 4.8 number. c and s are 8-bit unsigned integers.
----
==== EC: G_SETCONVERT ====
Sets the terms need to perform conversion from YUV to RGB.
'' E C 00aa aaaa aaab bbbb bbbb cccc\\
cccc cddd dddd ddee eeee eeef ffff ffff''
| a | **K0** term of conversion matrix |
| b | **K1** term of conversion matrix |
| c | **K2** term of conversion matrix |
| d | **K3** term of conversion matrix |
| e | **K4** term of conversion matrix |
| f | **K5** term of conversion matrix |
All of the parameters are signed 9-bit numbers, with range -256 ≤ k ≤ 255.
----
Conceptually the equations for converting from YUV to RGB are:
| R | C0 * (Y - 16) + C1 * V |
| G | C0 * (Y - 16) - C2 * U - C3 * V |
| B | C0 * (Y - 16) + C4 * U |
The K terms in G_SETCONVERT come from these C terms.
| **K0** | C1 / C0 |
| **K1** | C2 / C0 |
| **K2** | C3 / C0 |
| **K3** | C4 / C0 |
| **K4** | 16 + 16 / (C0 - 1.0) |
| **K5** | C0 - 1.0 |
In the hardware, the color conversion is done in two stages. In the texture filter (TF), the following equation is performed:
| R’ | Y + **K0** * V |
| G’ | Y + **K1** * U + **K2** * V |
| B’ | Y + **K3** * U |
In the color combiner, the following equations are performed to get the RGB color:
| R | (R’ - **K4**) * **K5** + R’ |
| G | (G’ - **K4**) * **K5** + G’ |
| B | (B’ - **K4**) * **K5** + B’ |
Typical Values for YUV to RGB conversion:
K0 = 175
K1 = -43
K2 = -89
K3 = 222
K4 = 114
K5 = 42
----
==== ED: G_SETSCISSOR ====
Sets the scissoring rectangle.
''ED [xx x][y yy] 0[m] [vv v][w ww]''
| x | Upper-left X coordinate of rectangle |
| y | Upper-left Y coordinate of rectangle |
| m | Interpolation mode setting |
| v | Lower-right X coordinate of rectangle |
| w | Lower-right Y coordinate of rectangle |
Valid values for m are:
* G_SC_NON_INTERLACE = 0
* G_SC_EVEN_INTERLACE = 2
* G_SC_ODD_INTERLACE = 3
NON_INTERLACE draws all scanlines, while EVEN and ODD draw only even or odd scanlines, respectively.
----
==== EE: G_SETPRIMDEPTH ====
This sets the Z value for the entire primitive to be rendered, when the source for its depth component is set to be taken from this value. (This could be thought of as the depth version of "flat shading".)
''EE 00 00 00 zz zz dd dd''
| z | Z value for primitive |
| d | Delta Z value for primitive |
z and d are signed 16-bit values. z sets the actual depth for the primitive, while d helps rendering of anti-aliased and decal objects (this is usually 0).
----
==== EF: G_RDPSetOtherMode ====
Sets the other mode bits of the RDP.
''EF [HH HH HH] [LL LL LL LL]''
| H | Settings for other mode higher word bits |
| L | Settings for other mode lower word bits |
H is similar to using BA, and L is similar to using B9.
The difference from either BA or B9 is that this command sets all the bits in both halves of the RDP word (that is, this opcode has no way of limiting what bits are actually affected).
The RSP Geometry Mode word bits' parameters can be found [[https://hack64.net/wiki/doku.php?id=rcpstructs#setothermode|under the RCP structs page.]]
----
==== F0: G_LOADTLUT ====
Tells the RDP to load a number of colors from the texture loaded to a given tile descriptor. The tile descriptor's attributes and other state related to textures inform the RDP how to load the palette, and where to load it to.
''F0 00 00 00 0[t] [cc c]0 00''
| t | Tile descriptor to load from |
| c | ((colour count-1) & 0x3FF) << 2 |
(Note: the count is quadrupled likely due to how palettes are stored in TMEM. Not sure where details on that would be appropriate, though.)
----
==== F2: G_SETTILESIZE ====
Sets the texture coordinates and size
''F2 [SS S][T TT] 0[I] [WW W][H HH]''
| SSS | Upper-left corner of texture to load, S-axis |
| TTT | Upper-left corner of texture to load, T-axis |
| I | Tile descriptor to load into |
| W | (width - 1) << 2 |
| H | (height - 1) << 2 |
Examples:
F2 00 00 00 00 07 C0 7C : 32x32 textures
F2 00 00 00 00 0F C0 7C : 64x32
F2 00 00 00 00 07 C0 FC : 32x64
----
==== F3: G_LOADBLOCK ====
Determines how much data to load after SETTIMG
''F3 [SS S][T TT] 0[I] [XX X][D DD]''
| SSS | Upper-left corner of texture to load, S-axis |
| TTT | Upper-left corner of texture to load, T-axis |
| I | Tile descriptor to load into |
| XXX | Number of texels to load to TMEM, minus one |
| DDD | dxt |
Some notes on dxt:
dxt is an unsigned fixed-point 1.11 number, meaning a range of 0 ≤ n ≤ 1.999512. This number has units, namely lines•words-1, where a "word" is 64 bits in length, and a line is one row of the texture. (It may be more easily understood when inverted to get its reciprocal: words/lines. dxt is the reciprocal of the number of 64-bit chunks it takes to get a row of texture.)
When loading an image through this opcode, an internal counter is incremented by dxt for every 64 bits of texture read. When this counter is high enough to turn over to the next integer value (e.g. 0.9 + 0.15 -> 1.05), the current line number is incremented. This is important as odd-numbered rows have their values swapped for interleaved access (the first line read in is line 0, and thus isn't swapped).
Note that if dxt is not a power of two (i.e. only one bit in the value is 'on'), then an error in the counter will accumulate over time, and eventually cause errors in determining where next lines are (when exactly this happens depends on the value and the type of texture being read in).
Examples:
F3 00 00 00 07 7F F1 00 : 32x64 16-bit Textures
F3 00 00 00 07 7F F0 80 : 64x32 16-bit Textures
F3 00 00 00 07 3F F1 00 : 32x32 16-bit Textures
F3 00 00 00 07 FF F1 00 : 64x64 8-bit Textures
----
==== F4: G_LOADTILE ====
Loads a rectangular portion of the texture being pointed to in DRAM for given tile descriptor into TMEM.
''F4 [ss s][t tt] 0[i] [uu u][v vv]''
| s | Upper-left corner of tile, S-axis |
| t | Upper-left corner of tile, T-axis |
| i | Tile descriptor being loaded to |
| u | Lower-right corner of tile, S-axis |
| v | Lower-right corner of tile, T-axis |
(s, t) specifies the upper-left corner of the texture in RAM, offset from its earlier-specified origin, and (u, v) specifies the lower-right corner of the texture to load.
All coordinate values are in unsigned fixed-point 10.2 format (range 0 ≤ n ≤ 1023.75).
----
==== F5: G_SETTILE ====
Sets the texture properties (ex. mirroring)
''F5 [XX XX XX XX XX XX XX]''
| X | Bit-wise parameters |
Bit-wise parameters:
'' [F 5] fffi i0nn nnnn nnnm mmmm mmmm ''
''0000 0ttt pppp ccaa aass ssdd bbbb uuuu''
| fff | Sets color format |
| ii | Sets bit size of pixel |
| nnnnnnnnn | Number of 64-bit values per row |
| mmmmmmmmm | Offset of texture in TMEM |
| ttt | Tile descriptor being modified |
| pppp | Which palette to use for colors (if relevant) |
| cc | Clamp and Mirror flags for the T axis |
| aaaa | T mask (Sets how much of T axis is shown before clamping) |
| ssss | Sets the amount to shift T axis values after perspective division |
| dd | Clamp and Mirror flags for the S axis |
| bbbb | S mask (Sets how much of S axis is shown before clamping) |
| uuuu | Sets the amount to shift S axis values after perspective division |
|Color formats|||
| 0 | RGBA | Color and alpha |
| 1 | YUV | Luminance and Chrominance |
| 2 | CI | Index and look-up palette |
| 3 | IA | Grayscale and alpha |
| 4 | I | Grayscale |
|Bit sizes|||
| 0 | 4-bit | I, IA, and CI |
| 1 | 8-bit | I, IA, and CI |
| 2 | 16-bit | RGBA, IA, and YUV |
| 3 | 32-bit | RGBA |
|wraps/wrapt modes||
| 0 | Wrap/No mirror |
| 1 | Mirror |
| 2 | Clamp |
|shifts/shiftt modes||
| 0-10 | >> shift |
| 11-15 | << (shift-10) |
Or simply
''Bitsize = 4*2^(i)''
Examples:
F5 10 00 00 07 00 00 00 : Settile for RGBA16, followed by another F5 command (rendertile)
F5 70 00 00 07 00 00 00 : Settile for IA16, followed by another F5 command (rendertile)
F5 10 10 00 07 01 40 50 : Rendertile for RGBA16 32x32 textures
F5 10 20 00 07 01 40 60 : Rendertile for RGBA16 64x32 textures
F5 70 10 00 00 01 40 50 : Rendertile for IA16 32x32 textures
F5 00 01 00 01 00 00 00 : Settile for palettes loading into TLUT0 in tile descriptor 1
F5 40 08 00 00 09 80 60 : Rendertile for CI4 64x64 textures with clamping on the T (vertical) axis
----
==== F6: G_FILLRECT ====
Draws a colored rectangle on the screen. Use command 0xF7 to set the color of the rectangle.
''F6 [VV V][W WW] 00 [XX X][Y YY]''
| VVV | Lower-right corner of rectangle, X-axis |
| WWW | Lower-right corner of rectangle, Y-axis |
| XXX | Upper-left corner of rectangle, X-axis |
| YYY | Upper-left corner of rectangle, Y-axis |
----
==== F7: G_SETFILLCOLOR ====
Sets the fill color for use in fill mode.
''F7 00 00 00 [CC CC CC CC]''
| CCCCCCCC | Fill value for use in fill mode |
----
==== F8: G_SETFOGCOLOR ====
Sets the fog color
''F8 00 00 00 [RR] [GG] [BB] [AA]''
| R | red value |
| G | green value |
| B | blue value |
| A | alpha: Set to FF unless combiner uses 2-cycle mode |
Example: set the fog for the following polygons to pure green
F8 00 00 00 00 FF 00 FF
----
==== F9: G_SETBLENDCOLOR ====
Sets the RDP blender's blend color, a general purpose color register available for various purposes in the blender.
''F9 00 00 00 [RR] [GG] [BB] [AA]''
| R | red value |
| G | green value |
| B | blue value |
| A | alpha value |
Example: make blend colour green and opaque
FB 00 00 00 00 FF 00 FF
----
==== FA: G_SETPRIMCOLOR ====
Sets the primitive color register of the RDP's color combiner. Also sets two additional values available to the color combiner, the minimum LOD level and an LOD fraction.
''FA 00 [mm] [ff] [RR] [GG] [BB] [AA]''
| m | Minimum possible LOD value (clamped to this at minimum) |
| f | Primitive LOD fraction for mipmap filtering |
| R | red value |
| G | green value |
| B | blue value |
| A | alpha value |
m and f are both fixed-point unsigned 0.8 numbers, meaning a range of 0 ≤ n ≤ 0.99609375. m defines the minimum possible value for LOD to have, when the LOD calculated for a particular part of the primitive is less than 1.0. In other words, the LOD of any part of the primitive is clamped at the lower end to max(m, LOD).
f specifies a fraction that the programmer can specify for use in the color combiner of the RDP. It's meant to offer a further refinement (XXX verify that, not 100% sure on it) on the linear filtering of two mipmaps.
----
==== FB: G_SETENVCOLOR ====
Sets the environment color for combiner
''FB 00 00 00 [RR] [GG] [BB] [AA]''
| R | red value |
| G | green value |
| B | blue value |
| A | alpha value |
Example: make everything loaded underneath the command red, and semi-transparent
FB 00 00 00 FF 00 00 8C
----
==== FC: G_SETCOMBINE ====
Performs combining operations (ex. multi-texturing). The N64's Color Combiner calculates the output color by combining the various source colors and source alphas using the following equation: outputcolor = ( A - B ) * C + D.
''FC [XX XX XX XX XX XX XX]''
| X | Equation for blending. Mask is bitwise. |
Bitwise mask for X:
''[**aaaa**] [**ccccc**] [**eee**] [**ggg**] [**iiii**] [**kkkkk**] [**bbbb**] [**jjjj**] [**mmm**] [**ooo**] [**ddd**] [**fff**] [**hhh**] [**lll**] [**nnn**] [**ppp**]''
| **a** | variable 'a' for mode 1 (color) |
| **b** | variable 'b' for mode 1 (color) |
| **c** | variable 'c' for mode 1 (color) |
| **d** | variable 'd' for mode 1 (color) |
| **e** | variable 'e' for mode 1 (alpha) |
| **f** | variable 'f' for mode 1 (alpha) |
| **g** | variable 'g' for mode 1 (alpha) |
| **h** | variable 'h' for mode 1 (alpha) |
| **i** | variable 'a' for mode 2 (color) |
| **j** | variable 'b' for mode 2 (color) |
| **k** | variable 'c' for mode 2 (color) |
| **l** | variable 'd' for mode 2 (color) |
| **m** | variable 'e' for mode 2 (alpha) |
| **n** | variable 'f' for mode 2 (alpha) |
| **o** | variable 'g' for mode 2 (alpha) |
| **p** | variable 'h' for mode 2 (alpha) |
More information here:
[[http://n64devkit.square7.ch/pro-man/pro12/12-06.htm|N64's Color Combiner]]
Examples:
FC 12 7F FF FF FF F8 38 : Standard usage for solid RGBA textures
FC 12 18 24 FF 33 FF FF : Standard usage for alpha RGBA textures
----
==== FD: G_SETTIMG ====
Sets the texture image offset
''FD [xx] 00 00 [bb bb bb bb]''
''[xx] = fffi i000''
| b | Segmented address of texture |
| f | Texture format |
| i | Texture bit-size |
|Color formats|||
| 0 | RGBA | Color and alpha |
| 1 | YUV | Luminance and Chrominance |
| 2 | CI | Index and look-up palette |
| 3 | IA | Grayscale and alpha |
| 4 | I | Grayscale |
|Bit sizes|||
| 0 | 4-bit | I, IA, and CI |
| 1 | 8-bit | I, IA, and CI |
| 2 | 16-bit | RGBA, IA, and YUV |
| 3 | 32-bit | RGBA |
Or simply
''Bitsize = 4*2^(i)''
Example: Load texture position from 0x90 in RAM bank 0x04 for RGBA16
FD 10 00 00 04 00 00 90
----
==== FE: G_SETZIMG ====
Sets the location of the depth buffer
''FE 00 00 00 [ii ii ii ii]''
| i | Segmented address of the depth buffer |
Since the format of the depth buffer is fixed (14-bit Z value and 2-bit dZ value), those parameters are not here, unlike for FD and FF. The width of the depth buffer is shared with the color buffer (see FF), and thus isn't set here.
----
==== FF: G_SETCIMG ====
Sets the location of the color framebuffer, usually a framebuffer that's displayed to the screen.
''FF [xx] 0[w ww] [ii ii ii ii]''
''xx = fffs s000 (binary)''
| w | Width of the color buffer (-1) |
| i | RAM address of color buffer |
| f | Format of color buffer to be pointed to |
| s | Bit size of pixels in color buffer to be pointed to |
The color buffer is set to RAM location i, with a width of w. f and s are the typical image format enumerations, described in G_Settile.
The location is usually some place set as the framebuffer to show (which is not handled by display lists), but oftentimes will be set to a depth buffer. This is usually done to fill (aka clear) the depth buffer in fill mode.
===== Fast3D DMEM Map =====
|0x000|Program data from compiler |0x110 bytes|
|0x110|RSP GFX State |0x050 bytes|
|0x160|RSP Memory segment table |0x040 bytes|
|0x1A0|Lights |0x180 bytes|
|0x320|Viewport |0x010 bytes|
|0x330|Fog factors |0x006 bytes|
|0x336|padding |0x002 bytes|
|0x338|Display list stack |0x028 bytes|
|0x360|Modelview matrix top of stack |0x040 bytes|
|0x3A0|Projection Matrix top of stack |0x040 bytes|
|0x3E0|MP Matrix (Modelview * Projection) |0x040 bytes|
|0x420|Points buffer |0x280 bytes|
|0x6A0|Input (display list) |0x140 bytes|
|0x7E0|Input (data) |0x100 bytes|
|0x8E0|setup tmp |0x060 bytes|
|0x940|clip tmp |0x0A0 bytes|
|0x9E0|Output to RDP |0x400 bytes|
|0xDE0|Scratch space |0x1E0 bytes|
|0xFC0|Task |0x040 bytes|
===== Fast3D RSP Register Assignment =====
|return |$31||
|return_save|$30||
|rsp_state |$29||
|dlcount |$28||
|dinp |$27|Pointer to current display list command in the input buffer in DMEM|
|inp |$26|Pointer to the current command block in RDRAM|
|gfx0 |$25|Display list command high word|
|gfx1 |$24|Display list command low word|
|outp |$23||
|in_bufp |$22||
|zero |$0 ||
----
===== References =====
* http://www.smwcentral.net/?p=viewthread&t=74389
* http://origami64.net/showthread.php?tid=114
* http://n64.icequake.net/doc/n64intro/kantan/step2/4-3.html
* http://jul.rustedlogic.net/thread.php?id=1234
* http://level42.ca/projects/ultra64/Documentation/man/pro-man/pro25/25-01.html
* http://wiki.spinout182.com/w/F3DEX2
* http://wiki.cloudmodding.com/oot/F3DZEX/Opcode_Details
* http://ultra64.ca/files/documentation/silicon-graphics/SGI_RDP_Command_Summary.pdf
* https://www.docdroid.net/NXMlF3s/grucode.pdf