------------------------------------------------------------------
* New functions for F3DEX(.NoN), F3DLX(.NoN), F3DLX.Rej, 
  F3DLP.Rej, L3DEX ucode release 1.20.


+ gSPVertex (Gfx *pkt, Vtx *v, u32 n, u32 v0)
  gsSPVertex(          Vtx *v, u32 n, u32 v0)

Made the vertex cache larger, so changed the range of parameters 
n and v0. (see below) g*SPVertex accepts less than 33 vertice per 
one load. (n accepts 1-32.) So, you may use it twice or more to 
load more than 32 vertice(*).
	
		    Vertice
		   cache size        Range of n      Range of v0
F3DEX/F3DEX.NoN        32               1-32            0-31
F3DLX/F3DLX.NoN        32               1-32            0-31
F3DLX.Rej              64               1-32(*)         0-63
F3DLP.Rej              80               1-32(*)         0-79
L3DEX                  32               1-32            0-31
	

+ gSP2Triangles (pkt,  v00, v01, v02, flag0,  v10, v11, v12, 
	flag1)
  gsSP2Triangles(      v00, v01, v02, flag0,  v10, v11, v12, 
	flag1)

gSP2Triangles are "double triangle face command." This command 
generates *two* triangles same as

	  gSP1Triangle(pkt++, v00, v01, v02, flag0);
	  gSP1Triangle(pkt++, v10, v11, v12, flag1);

You can replace two g*SP1Triangle to one g*SP2Triangles, so this 
command can make DL size shorter.

	F3DLX.Rej and F3DLP.Rej are very fast because they are
	optimized for executing g*SP2Triangle. So you'd better use
	g*SPTriangle to get more performance.


+ gSP1Quadrangle (pkt,  v0, v1, v2, v3, flag)
  gsSP1Quadrangle(      v0, v1, v2, v3, flag)

	g*SP1Quadrangle generates a quadrangle (v0,v1,v2,v3).
	flag should be either 0,1,2 or 3 for flat shading.

We don't support dynamic divide selection for quadrangle  in this 
and later release. Because SP's overhead is larger than DP's 
increase of performance we had expected.

In release 0.96 and later, g*SP1Quadrangle is emulated by 
g*SP2Triangles, so apps for release 0.95 or before can work with 
re-compiling.


+ gSPSetGeometryMode(Gfx *gdl, unsigned int mode)
  gsSPSetGeometryMode(unsigned int mode)

	G_CLIPPING would be available for mode identify.
	
	If G_CLIPPING has cleared, F3DLX does not clip any 
	triangle (quadrangle) but faster.
	
	If G_CLIPPING has cleared....
	  gSPVertex   :  Does not make pre-calculated vertex data 
			 for clipping.
	  gSP*Triangle:  Does not work any clipping. (Also 
			 gSP1Quadrangle)
	
So, following DL is *not* correct because gsSP1Triangle cannot get
pre-calculated vertex data of clipping from gsSPVertex.  In this 
DL, gsSP1Triangle cannot work.

	gsSPClearGeometryMode(G_CLIPPING),	// Clipping OFF
	gsSPVertex(v, 3, 0),			// Load 3 vertices
	gsSPSetGeometryMode(G_CLIPPING),	// Clipping ON
	gsSP1Triangle(0,1,2,0),			// Draw TRI
	
Also gSPCullDisplayList() cannot work with no pre-calculated 
vertex data made by no G_CLIPPING.
	
	G_CLIPPING is available in F3DLX only. It's ignored in 
	other ucodes.
	
	G_CLIPPING is set when initialized RSP.


+ gSPCullDisplaylist(Gfx *gdl, unsigned int v0, unsigned int vn)
  gsSPCullDisplaylist(unsigned int v0, unsigned int vn)

Change ranges of v0 and vn by increase vertices cache size.
The ranges are same as v0 of gSPVertex parameter. But, must be
v0 <= vn. (man pages are incorrect.)

g*SPClipRatio of F3DEX(.NoN), F3DLX(.NoN) and L3DEX works same
as Fast3D's. But F3DLX.Rej's and F3DLP.Rej's are not same at all.


+ gSPClipRatio(Gfx *gdl, r)
  gsSPClipRatio(r)

Also, g*SPClipRatio of F3DEX(.NoN), F3DLX(.NoN) and L3DEX works
same as Fast3D's. But F3DLX.Rej's and F3DLP.Rej's are not same
at all. In F3DL*.Rej, g*SPClipRatio defines a size of the 
rejecting box. (default rejecting box size: FRUSTRATIO_2)

+ gSPModiftVertex(Gfx *gdl, 
	unsigned int vtx, unsigned int where, unsigned int val)
  gsSPModifyVertex(unsigned int vtx, unsigned int where, unsigned 
  int val)

Change ranges of vtx by increase vertices cache size. The ranges 
are same as v0 of gSPVertex parameter. 


+ gSPBranchLessZ(Gfx *gdl, Gfx *branchdl, unsigned int vtx,
		 float zval, float near, float far, int flag)
  gsSPBranchLessZ(Gfx *branchdl, unsigned int vtx,
		  float zval, float near, float far, int flag)

Branch display list to pointer specified `branchdl' if screen
depth of `vtx' less than or equal `zval'. If greater, do nothing.
It makes supporting model LOD very easier.
	
Here is a sample model with 3 level LOD.

	Gfx model_near[] = {	// Model DL on  32<=depth<=200
		.....
		gsSPEndDisplayList(),
	};

	Gfx model_mid[] = {	// Model DL on 201<=depth<=800
		.....
		gsSPEndDisplayList(),
	};

	Gfx model_far[] = {	// Model DL on 801<=depth<=1600
		.....
		gsSPEndDisplayList(),
	};

    Gfx model[] = {
      gsSPVertex(testvtx, 1, 0),
      gsSPBranchLessZ(model_near, 0,  200, 32, 2000, G_BZ_PERSP),
      gsSPBranchLessZ(model_mid,  0,  800, 32, 2000, G_BZ_PERSP),
      gsSPBranchLessZ(model_far,  0, 1600, 32, 2000, G_BZ_PERSP),
      gsSPEndDisplayList(),	// Don't display if 1601<=depth.
	};

This GBI needs some parameters about viewing frustum as following.
	
	`near'	Distance to the near clipping plane.
		Same value specified in guPerspective()/guOrtho().
	`far'	Distance to the far  clipping plane.
		Same value specified in guPerspective()/guOrtho().
	`flag'	Set `G_BZ_PERSP' for perspective  
		projection(guPerspective).
		Set `G_BZ_ORTHO' for orthographic 
		projection(guOrtho).

To use g*SPBranchLessZ(), the view port parameters
`vp.vscale[2]' and `vp.vtrans[2]' should be set `G_MAXZ/2'.
Normally, it is unnecessary to set other values for vp.vscale[2],
and vp.vtrans[2]. But, when you want other values, you may use
g*SPBranchLessZrg() instead of g*SPBranchLessZ().
	
This GBI's are supported in release 1.02 or later, and available
in F3DEX(.NoN), F3DLX(.NoN), F3DLX.Rej, F3DLP.Rej and L3DEX.


+ gSPBranchLessZrg(Gfx *gdl, Gfx *branchdl, unsigned int vtx,
		   float zval, float near, float far, int flag,
		   int zmin, int zmax)
  gsSPBranchLessZrg(Gfx *branchdl, unsigned int vtx,
		    float zval, float near, float far, int flag,
		    int zmin, int zmax)

Normally, the range of screen depth value should be 0 to G_MAXZ
with g*SPBranchLessZ. However, if you want to use another range
`zmin' to `zmax', you should use g*SPBranchLessZrg instead of
g*SPBranchLessZ. 

g*SPBranchLessZrg needs two more parameters than g*SPBranchLessZ.

	`zmin'	depth value minimum. (= vp.vtrans[2]-vp.vscale[2])
	`zmax'	depth value maximum. (= vp.vtrans[2]+vp.vscale[2])
	
Other paramters (gdl, branchdl, vtx, zval, near, far and flag)
are same as g*SPBranchLessZ's.
	
This GBI's are supported in release 1.02 or later, and available
in F3DEX(.NoN), F3DLX(.NoN), F3DLX.Rej, F3DLP.Rej and L3DEX.


+ gSPLoadUcode(Gfx *gdl, u64 *uc_start, u64 *uc_dstart)
  gsSPLoadUcode(u64 *uc_start, u64 *uc_dstart)

	uc_start : Physical address of the top of the ucode text 
		   section.
	uc_dstart: Physical address of the top of the ucode data 
		   section.
	
Load ucode into IMEM/DMEM and initailize RSP.
Loadable ucodes are F3DEX(.NoN), F3DLX(.NoN), F3DLX_Rej, F3DLP_Rej
and L3DEX. Fast3D and Turbo3D are not loadable.

If you have F3DEX 1.22 (in the N64 Dev 2.0H) and S2DEX ucode for
Sprite drawing, you can use gSPLoadUcode to load S2DEX for drawing
sprite.

You should be careful to `Load ucode'. Because to load ucode would 
often take some processing time. It's overhead. So, you should 
avoid useless ucode loading.

The ucodes would be changed to get best performance in the 
situation, such as...

	o Loading F3DLX ucode to draw game field with clipping 
	  function. (Clipping is necessary to draw game field.)
	o Loading F3DLX.Rej (after draw game field) to draw game 
	  object as a man, a car ... (F3DLX.Rej is faster than 
	  F3DLX.)

And you can load line ucode `L3DEX' to draw line without CPU 
processing.

*** Caution ***
This GBI command g*SPLoadUcode makes RSP initailized.
So, you should set all parameters of RSP status again
(Segment address, Viewport, Geometry-mode, Matrix, Link info.
of display list ... and more). So, when you use g*SPLoadUcode in
Display list (DL1) linked from another Display List (DL2) by 
g*SPDisplayList, the DL1 cannot return back to DL2. It's very
dangerous implemention I think, but we don't have enough code
space to fix it.
	
You should set `OS_TASK_LOADABLE' to member `flag' in `OSTask' to
use this GBI g*SPLoadUcode like as this.

	OSTask *tp;
	tp->t.flag = OS_TASK_LOADABLE | OS_TASK_DP_WAIT;

To make OS_TASK_LOADABLE available, you need some patches for
N64 OS libraries. For more information, see `OS patches:'
in file	`README'. The patched OS libultra*.a have upper
compatiblility with original OS.


+ gSPLoadUcodeL(Gfx *gdl, ucode_name)
  gsSPLoadUcodeL(ucode_name)

g*SPLoadUcodeL is same as g*SPLoadUcode expect an expression.
See following, (a) and (b) works equally.

(a) gsSPLoadUcode(OS_K0_TO_PHYSICAL(&gspF3DEX_fifoTextStart),
    OS_K0_TO_PHYSICAL(&gspF3DEX_fifoDataStart))
(b) gsSPLoadUcodeL(gspF3DEX_fifo)

