PlayStation2 Linux vO~OЂƂ߂ () 

 v


  {eł́APS2 Linuxŉʂhɂ邱ƂڕWɁAʂ̃vO
~OƂ̉s܂B
  O҂łPS2 Linux3DOtBbNXs߂̃vO~OɕKv
ȋZpe[}Ƃ܂B
  ́AVPU1PlayStation2̃ptH[}X`[jOe[}Ƃ
܂B
  PS2A3DOtBbNAǂƂĂɉ[AƂĂ̂悤
y[W̌eňƂ͍lĂ܂񂪁A{eł̕З؂ɏłG
΂ƍlĂ܂B


 3DXvCg

  ́A3DXvCgƌĂ΂ZpgpāAp[eBN\s
܂B
  O҂ňA3DOtBbN\͊eOp`̒_𓧎ϊ
邱ƂɂāA3DW2DW֓ϊ܂Bʂ̃f\A
̑ł͒ʏ킱̂悤Ȏ菇ӂ݂܂B
  {ełf\ƁAO҂̑ɂȂǂ̂łAf\
ʂƂȂƁA낢ȗvf݂܂̂ŁAƂĂ܂B
  ́A3DXvCge[}ƂĈ܂B
  3DXvCǵAXvCg̈ʒû݂𓧎ϊđΉ2DW
߁AXvCg̃TCY߂Ă͌ŕʌvZɂčs@łB
  ̓Iɂ̓XvCg`߂ɂ́AWnł̃XvCgW
(x,y,z,w)wgAXN[W(Sx,Sy)A߂XvCg̃TCY
cꂼh,vƂāA}1̂悤ɕ\Ƃł܂B


		      Sx-h      Sx       Sx+h
			|--------|--------|
			-------------------
		Sy-v ---|        |        |
		      |	|        |        |
		      |	|        |        |
		      |	|        |        |
		 Sy  ---| ------ .        |
		      |	|     (Sx,Sy)     |
		      |	|                 |
		      |	|                 |
		Sy+v ---|                 |
			-------------------

			  h = (1/w) * m
			  v = (1/w) * n

			AAm, n͒萔

			}1 3DXvCg


  m,ńAIȃTCYɂČvZŋ߂܂Aꂪ
łA\镨̂̃XP[茈߂ĂȂ΂܂ӖȂ
AOtBbN\͐\ł͂ȂhłA\
ȂYɌ悤ɒǂʂ܂ł傤B


 EEł̎Ƃ̃ptH[}X

  EEŋLqāAȒPȃp[eBÑf쐬Ă݂܂B{e
ł͑O҂ƓlɃTvvO쐬܂ARpCIvV
ŏύXłāÃIveB}CY菇iKIɎƂł
悤ɂȂĂ܂B
B
  EEł̎śAȉ̏ŃRpC܂B

	#undef USE_VU1
	#define USE_FAKERANDOM
	#undef USE_NOVPU1_POINT
	#define FIRE_SPRITE_SIZE	30000.0f

  s̃ptH[}X́ASELECTă|[Y܂܌ƁA\
OCPU͏ȗ邱Ƃł܂̂ŁA̖ړIɂ͓s悢
vsƂł܂B
  1t[̃XvCgptH[}XłA摜̏Ԃɂ
Ēl͑Oサ܂̂ŐmȒl͓ɂ̂łAftHg̃Jʒu
ł5500܂1t[ŏł悤łBāAb33
̃XvCg\Ă܂B
  EÊ݂gpĂ܂̂ŁAPS2łEEōsKv̂ȂWIgv
ZCPUԂ̑gĂ܂B
  PS2ɂ̓WIgvZsړIɓKVPU1܂̂ŁA
𗘗pĕ\VPU1֕܂B


 \VPU1ւ̕Ƃ̃ptH[}X

  PS2ɂVPUƌĂ΂WIgZɗLpȋ@\݂܂AVPU
VPU0VPU1̓݂܂B
  āAO҂ŃWIgϊ̘boꂵ܂ŕKvɂȂ܂B
  PS2̕\ƂẮAsTpers(OPDFt@C̎AXg15)EE
VPU0gpČvZAȌ̎(O҂̎AXg13AX
g17)ʊOɃXvCgo\鎞ɂ͕Kvɉă|S
Nbv(O҂̃Xg)s_̌vZVPU1ōŝf
Ō̗ǂ@ł傤B
  {eł̕WIȃf܂AΏ۔͈͂VPU1/GS̍œK
݂̂ɂڂ肽̂ŁAVPU1݂̂Ǝv܂B(VPU0VPU1Ɠl
̌vZ}Nōsł)
  VPU1gOtBbN_OpCvCO҂̐}11
(}2)ɂĂ܂߂ƁA}3̂悤ɂȂ܂B


-----------------------     ------------------------
|                     |     | IuWFNgzu   |
|  IuWFNg쐬 |     | AJ肵 |
|                     |	--> | ŃV[܂Ƃ߂   | -->
|([JWԏ|     |([hWԏ |
| ʂ)     |     |  ʂ)     |
-----------------------     ------------------------
         (A)                          (B)

(Ȇ)

------------------------     ----------------------
| 3DW̃IuWFN |     |GSŉBʏ      |
|gɑΉfBXv| --> |       s` |
|C̈ʒu߂      |     |			  |
|(2XN[ԏ|     |(fBXvC   |
|̌ʂ)     |     |   ۂɕ`悳)|
------------------------     ----------------------
         (C)                          (D)

   }2 OtBbN_OpCvC (O҂̐}11Ɠ)


-----------------------     ------------------------
|                     |     |(A)ō쐬XvC |
|X̃XvCgʒu |     |g̔zuJ|
|       쐬        |	--> | ăV[܂Ƃ߂ | -->
|([JWԏ|     |([hWԏ |
| ʂ)     |     |  ʂ)     |
-----------------------     ------------------------
         (A)                          (B)

(Ȇ)

------------------------    
| EE3DWɑΉ |     ------------------------
| fBXv[ |     | VPU1ŃXN[ |     ------------------
| ʒu߂邪ATpers|     | \܂łׂĂ߂ |     |                |
| ܂łvZA   | --> | GSŃX^CY | --> | GSŎۂɕ` |
| VPU1փf[^] |     | ߂̃pPbgf[^ |     |                |
| 邽߂̃ZbgAbv |     |                |     ------------------
| s               |     ------------------------
------------------------
        (C-1)                         (C-2)                       (D)

	   }3 3DXvCg̃OtBbN_OpCvC


  EEŏ镔́A(A),(B),(C-1),VPU1ŏ镔(C-2),GS
镔(D)ƂȂ܂B
  āAVPU̐ɓ܂BłVPU1ɂĂ̂ݐG܂A
VPU0{\͂قƂǓŁAvłEFUȂȂ_
قȂ邾łB
  VPU1͐}4̂悤ȍ\ƂȂĂ܂B


			(ʃt@C)

			}4 VPU1̍\


  VPU1gvZbTƂȂĂA64bitLIW(Long Instruction
Word)̃}CN߂VPU1̃ɃXgAĎs邱Ƃł܂B
VPU1͖ߗp̃Ƃ16KBAf[^p̃Ƃ16KBpӂĂ
܂B
  VPU1ł32{128rbg_WX^(VF00`VF31)A16{̐
WX^(VI00`VI15)gpĎRɃvO~O\łBVFxxWX^
128rbgłA432rbg̕_XYZW̑gƂĎgp܂B
  ꂼ̃WX^1A炩ߒlŒ肳ꂽWX^
(VI00,VF00)萔Ƃėpł܂B
  VPU1ɂ́A32rbg_ϘaZ@(FMAC)4A_Z/J
Z@(FDIV)1AVUƂ̃[h/XgARg[
LSUA16rbgZsIALUAWv𐧌䂷BRUA
RANDUAw֐Eΐ֐AOp֐̉Zs֐jb
g(EFU)܂BāA4ɑ΂ϘaZɏł
B
  VPU1߂̊{\́AUpper߂Lower߂̑gݍ킹ƂȂĂA
Upper߂FMAC𐧌䂵ALower߂͂̑̃jbgFDIV,LSU,IALU
𐧌䂵܂BUpper߂4FMAC𓯎ɓ삳Kv܂A
ꂼsɓ삵܂Alʂ̃XgAɃ}XNAl
ŜŋL(u[hLXg)ƂɂāAxU𐧌
ł悤ɂȂĂ܂B
  VPU1̍\ƃ}CN߂́AL̂悤ɂȂĂ܂Aۂ̓
Ă̓pCvCɂ1NbN1߂ŕɎsĂ܂B
AnCvCɂČ1NbNɌ邾ŁAۂɕKv
ȌvZ݂܂B̎ԂCeVƌĂт܂B
  閽߂s鎞ɁA󂢂Ă郊\[XɊւĂ11NbN
ŎsĂ܂AAZű󂫂ȂA邢͎s̉Z
ʂߎsɕKvȏꍇAnU[h̔ƂȂAߎsɕKvȃ\[
X܂Ŗ߂̎s̓Xg[(҂)ƂɂȂ܂B
  nU[hꍇ́Â悤ȏꍇłB

1. FDIV, EFUgp閽߂̏ɁAjbggp閽߂
   sꍇ

2. VIxx, VFxxWX^fBXeBl[VƂĎgp閽߂̎s
   VIxx,VFxxWX^̒lgp閽߂𔭍sꍇ

3. WX^̃[h/XgA߂sɂ̐WX^gp
   ߂sꍇB
   (Z̏ꍇ̓CeV=1Ȃ̂ŃnU[h͔܂)

  VPU1ǂgp邽߂ɂ́AnU[h𔭐Ȃ悤ɖ߂
Kv܂B
  ܂Aӂ_ƂẮA򖽗߂̎s͒xXbg܂̂ŁA
̖߂Ks邱Ƃ܂B̏ꍇ́AɎg
p鐮WX^𒼑OɕύXĂ͂܂B
  āAVPU1(VPU0)EE core,GSƐ}̂悤ɐڑĂ܂B


		(ʃt@C)

		}5 EEcore, GS, VPU̐ڑ


  VPU0,1͂قƂǓ悤ȍ\Ă܂Aڑ@̈Ⴂɂ
قȂĂ܂BVPU1DMAVIFĐ䂳܂B
VU璼GIFGSփf[^]邱Ƃł܂B
āAVPU1ł́A炩߃}CNvO]ĂAKvȃf[^
ݒ肵VPU1}CNvONƂ̂WIȎgɂȂ
BVPU1[e]rbg߂Ɠ~܂BVPU1̃}CN
vOŁAN閈ɗ^ꂽf[^(_f[^)(
ϊsAGIFf[^쐬)AGIF͏o͂悤ɂĂ΁ADMA
VPU1AGSEE܂邱ƂȂ邱Ƃł܂B
  VPU0̏ꍇ́AGIF֏o͂ł܂񂪁Al̓sƂł
܂B}CN[hƌĂт܂BAVPU0̓RvZbTƂ
EE coreɐڑĂ܂̂ŁA}N߂ƂCPU̕⏕@\̂悤Ɉ
Ƃ\ŁAɃ}N[hŎg܂B
  {eł́AVIF1̃}CN[he[}ƂĂ܂̂ŁA𒆐S
ɘbi߂܂BVPU1ւVIF1ăf[^DMA]܂Af[^
ӖVIF^OɂĎw܂BVIF1^O߂\1Ɏ܂B


		        \1 VIF^O̎
|--------------------------------------------------------------------------|
	NOP		삵Ȃ
	STCYCL		CYCLEWX^̐ݒ
	OFFSET		OFFSETWX^̐ݒ
	BASE		BASEWX^̐ݒ
	ITOP		ITOPSWX^̐ݒ
	STMOD		MODEWX^̐ݒ
	MSKPATH3	GIFPATH3]}XN
	MARK		MARKWX^̐ݒ
	FLUSHE		}CNvO̎sI҂
	FLUSH		}CNvO̎sI҂
			GIF(PATH1/PATH2)̓]I҂
	FLUSHA		}CNvO̎sI҂
			GIF(PATH1-PATH3)̓]I҂
	MSCAL		}CNvO̎s
	MSCALF		}CNvO̎s
	MSCNT		}CNvǑps
	STMASK		MASKWX^̐ݒ
	STROW		ROWWX^̐ݒ
	STCOL		COLWX^̐ݒ
	MPG		}CNvO[h
	DIRECT		GIFւ̃f[^] (PATH2)
	DIRECTHL	GIFւ̃f[^] (PATH2)
	UNPACK		f[^̓WJVPUւ̏
|--------------------------------------------------------------------------|


  VIF1VPU1̎sJn𐧌ł閽߂́AMSCALAMSCALFAMSCNT
BMSCALAMSCALFŃAhXw肵VPU1sJnAVPU1erb
gw肳ꂽ߂ɂ~̌AMSCNT𑗂邱ƂɂČps܂B
  VPU̎s𑗂OɁA}CNvO̓]ƁAKvȃf[^VPU1
ւ̃ZbgAbvKvłB
  }CNvO̓]́AMPG^Oɑă}CNR[h]
łBVPU1̃}CNvOi[̈16KBłB̃_
O@ɑΉAGȉZsꍇ͓ȂȂĂ܂܂B
āAVPU1̃}CNR[h1t[ԂɉxꊷKv
łĂ܂ÅVPU1/GS~܂܂܂ɂȂĂ܂܂̂ŁAKv
Œɗ}Kv܂B
  āAf[^]łA̓CVPU1ւ̃f[^]A
VPU1̃vOsAVPU1GSւ̃f[^]ƕ`𓯎ɍsKv
邽߁AC-VPU1ԁAVPU1-GSԂꂼ_uobt@ɂ
̂Ƃ̗ǂ]@ƂȂ܂B
  CVPU1Ԃ̃_uobt@́ABASE/OFFSET^OŐݒ肵܂B
  āAVIF̃f[^]ɂ͎ɑʂȋ@\܂B
  rbgkf[^WJȂ]AAłĂȂVU
֓]蓙łB
  @\͖Lxɂ܂AňƂ肠Ă}jA
ł邾ŁAӖ܂̂ŁAۂɃvO~O
݂܂B


 VPU1̃vO~OƂ̃ptH[}X  

  ۂɁÃTvvOVPU1ɕĎ܂B
  vO͑O҂̃}Nx[XɏĂ܂BVPU1@
܂̂ŁAɎgp}NĂ܂BB
  \̃vOR[h̍\EÊ݂̂̂}6AVPU1̂̂}7
Ɏ܂B(TvvOfire_sub.c, prim3d.c)
  rƁAVPU1̕킩₷ł傤B̃Tv
vOłEETperseNX`֘AA_ʒuAVPU1̊Jn߂
ꂽDMApPbg쐬Đݒ肵Ă܂B
  ǂĐĂ܂ÃTvvOł́Axɓ
VPU1ŕ̃Tu[`̑gtLVuɎsł悤ɂȂ
Ă܂B


void grd_3d_vsprite( GRVector4 *posvec_p, GRVector4 *colvec_p,
	GRVector4 *stqvec1_p, GRVector4 *stqvec2_p,
	GRVector4 *multvec_p, int opt )
{
	int wclip;
	float q;
	GRVector4 tvec1, tvec2, mvec;

	// WNbv
	grg_rotperstrans_hm_wclip_q( &tvec1, posvec_p, &grg_screen, wclip, q );
	if (!wclip) {
		// h(mvec.x) = m(multvec_p->x) * (q=1/w)
		// v(mvec.y) = n(multvec_p->y) * (q=1/w)
		mvec.x = multvec_p->x * q;
		mvec.y = multvec_p->y * q;
		mvec.z = 0.0f;
		mvec.w = 0.0f;

		// tvec2 = tvec1 + mvec
		// tvec1 = tvec1 - mvec
		grm_vector4_a_vector4( &tvec2, &tvec1, &mvec );
		grm_vector4_s_vector4( &tvec1, &tvec1, &mvec );

		// ۂGSփXvCgpPbgς݂܂
		// tvec1->tvec2̃TCYŕ`悵܂B
		grd_draw_vtsprite( &tvec2, &tvec1, colvec_p, stqvec1_p, stqvec2_p, opt );
	}
	return;
}

static void fire1_draw( FIRE_COMMON_STRUCT *fcp )
{
	fp = fcp -> mem_p;

	// TpersуXN[Wϊs߂Đݒ肵܂
	grg_setpos_hm( &fcp->pos, &rotzero );

	// texturew肵AV-RAMɂȂV-RAM֓]A
	// GS֓nTEX0/TEX1pPbgDMAobt@֐ς݂܂
	grd_tex_use( &texinfo[fcp->tex], GRTEX_OPT_LINEAR, GRD_TEX_MIPMAP_DEFAULT, 0 );

	// XvCg`悵܂
	for (i = 0; i < fcp -> max; i++) {
		if (fp -> resttime <= 0)
			continue;
		grd_3d_vsprite(
			&((GRVector4 *)(fcp -> dmem_p))[i*2],
			&((GRVector4 *)(fcp -> dmem_p))[i*2+1],
			&fire1_vectors[1], &fire1_vectors[2], &fire1_vectors[0],
			GRDRAW_OPT_ALPHABLEND );
	}
}

		}6 VPU1gpȂXvCg\[`


	fp = fcp -> mem_p;

	// TpersуXN[Wϊs߂Đݒ肵܂
	grg_setpos_hm( &fcp->pos, &rotzero );

	// texturew肵AV-RAMɂȂV-RAM֓]܂B
	// AAGS֓nTEX0/TEX1pPbg͊m܂B
	_gps2_tex_use_trans( &texinfo[fcp->tex], 0 );

	// ̃AhX128rbg11̃f[^VIF1AhX0
	//֓]܂B
	// _r_Ă̂ŁA_uobt@ŏ܂B
	_gps2_setdma_vpudata_r_tag( 0, DMAsizeof(GRVector4)*(7+4) );

	// VPU1vOTu[` VPU1_ENTRY_MATRIXI܂
	_gps2_setdma_32323232( VPU1_ENTRY_MATRIX, 0, 0, 0 );

	// TpersƃXN[Wϊpsݒ肵܂
	_gps2_setdma_vpudata_body( &grg_screen,    DMAsizeof(GRMatrix44) );
	_gps2_setdma_vpudata_body( &grg_hm_scale,  DMAsizeof(GRVector4) );
	_gps2_setdma_vpudata_body( &grg_hm_offset, DMAsizeof(GRVector4) );

	// VPU1vOTu[` VPU1_ENTRY_DIRECTI܂
	_gps2_setdma_32323232( VPU1_ENTRY_DIRECT, 0, 0, 0 );
	// gif^Otex0/tex1n܂BVPU1vOgif^O܂A
	// f[^̌gif^On_loopǂݎ܂
	// PATH1,PATH2̓悭邽߂ɂׂPATH1܂
	_gps2_setdma_gif( 2, 1, GIF_FLG_PACKED, GIF_REGS(GIF_REGS_A_D, 0) );
	_gps2_tex_use_notag( &texinfo[fcp->tex], GRTEX_OPT_LINEAR, GRD_TEX_MIPMAP_DEFAULT, 0 );
	next_adr = 7+4;

	// xVPU1̃R[hsĎ~߂܂B́AŐœK
	// VPUR[ĥ߂̏łBȊOł͂̍ƂsK
	// v͂܂B
	// ̃TvvOłVPU1_ENTRY_STOPuVPU1͎~
	// ܂
	// 
	_gps2_setdma_vpudata_r_tag( next_adr, DMAsizeof(GRVector4) );
	_gps2_setdma_32323232( VPU1_ENTRY_STOP, 0, 0, 0 );
	next_adr++;
	grd_ps2_vpu1_cont();
	next_adr = 0;
	// ܂

	// XvCg`悵܂AUSE_VPU1_PACKNUM̐
	// VPU1փpPbg𑗂܂
	for (i = 0; i < fcp -> max; i+=USE_VPU1_PACK1NUM) {
		n_data = USE_VPU1_PACK1NUM;
		if (i+n_data > fcp -> max)
			n_data = fcp->max - i;
		if (i)
			next_adr = 0;

		// ̃AhX128rbg5̃f[^VIF1AhX
		//next_adr֓]܂B
		// _r_Ă̂ŁA_uobt@ŏ܂B
		_gps2_setdma_vpudata_r_tag( next_adr, DMAsizeof(GRVector4)*5 );

		// VPU1vOTu[` VPU1_ENTRY_SPRITEI܂
		_gps2_setdma_32323232( VPU1_ENTRY_SPRITE, 0, 0, 0 );
		// gif^On܂BVPU1vOgif^O܂A
		// f[^̌n_loopǂݎ܂
		_gps2_setdma_6464( GIF_NLOOP(n_data) | GIF_NREG(6) | GIF_PRE | GIF_FLG_PACKED |
			GIF_PRIM(GS_PRIM_SPRITE |
				GS_PRIM_TME |
				GS_PRIM_ABE |
				GS_PRIM_CTXT_1),
			GIF_REGS(GIF_REGS_ST,    0) |
			GIF_REGS(GIF_REGS_RGBAQ, 1) |
			GIF_REGS(GIF_REGS_XYZ2,  2) |
			GIF_REGS(GIF_REGS_ST,    3) |
			GIF_REGS(GIF_REGS_RGBAQ, 4) |
			GIF_REGS(GIF_REGS_XYZ2,  5) );
		// fire1xNg x 3]܂
		_gps2_setdma_vpudata_body( fire1_vectors, DMAsizeof(GRVector4)*3 );
		next_adr += 5;

		// _ʒuƒ_FXvCǧn܂
		_gps2_setdma_vpudata_r( next_adr,
			&((GRVector4 *)(fcp -> dmem_p))[i*2],
			(n_data << 1) );
		next_adr += n_data << 1;

		// VPŨvO~邽߂̍Ԃ[`s܂
		_gps2_setdma_vpudata_r_tag( next_adr, DMAsizeof(GRVector4) );
		_gps2_setdma_32323232( VPU1_ENTRY_STOP, 0, 0, 0 );
		next_adr++;

		// f[^̂ŎۂVPU1MSCNTŋN܂
		grd_ps2_vpu1_cont();
	}

		}7 VPU1gpXvCg\[`


VPU1̃vÓAׂĂ\Ȍɓ삳邽߂ɁA̓f[
^Əo̓f[^Ƀ_uobt@ɂ܂BāAVPU1̍\
͎̂悤ɂȂ܂B


   (lsprite.hŒ`)
     VPU1_BASE     +0 ----------------------
                      |                    |
                      |    ̓f[^ 1    |
                      |                    |
                      |                    |
     VPU1_OFFSET +256 ----------------------  ̓f[^_uobt@
                      |                    |     _uobt@
                      |    ̓f[^ 2    |     VIF
                      |                    |    (MSCNT/XTOPɐؑ)
                      |                    |
    VPU1_GSBASE1 +512 ----------------------
                      |                    |
                      |    o̓f[^ 1    |
                      |                    |
                      |                    |
    VPU1_GSBASE2 +768 ----------------------  o̓f[^_uobt@
                      |                    |     _uobt@
                      |    o̓f[^ 2    |     VPU1vO
                      |                    |     
                      |                    |     (XGKICKɐؑ)
                +1024 ----------------------

		}8 }bv


_uobt@邽߂VIF^Oł炩߁A̓f[^
BASE/OFFSETw肵Ă܂Bf[^]UNPACK^Ogpăf[
^̓WJ`w肵ĊJn܂AUNPACK^ÕAhXw莞ɍŏ
rbg1ɂƃ_uobt@LɂȂ܂BVPU1vO
XTOP߂ɂăf[^i[ꂽAhX𖈉񓾂܂̂ŁA̓f[
^̃_uobt@\tgEGAŊǗKv͂܂B
  _uobt@֘ȀݒĂяoу}N`́A}9̂悤
Ȃ܂B


           grd_ps2_vpu1_setdma( VPU1_BASE, VPU1_OFFSET );

		VPU1AhXݒ (fire.c, fire_draw())

#define grd_ps2_vpu1_setdma( _BASE, _OFFSET ) { \
        _gps2_setdma_vif1( PS2_VIF_SET_CODE( (_BASE),   0, PS2_VIF_BASE,   0 ) )
; \
        _gps2_setdma_vif1( PS2_VIF_SET_CODE( (_OFFSET), 0, PS2_VIF_OFFSET, 0 ) )
; }

			}N` (vpu1.h)

		}9 VPU1_uobt@֘Ȁݒ


  f[^]Ɏgp}N͐}10̂悤ɂȂ܂B


#ifdef USE_VIF1DMA_TTE1 /* J[lɂTTE=1p */
#define _gps2_setdma_vif1_2( _LEN, _VIFDATA1, _VIFDATA2 ) \
        _gps2_setdma_32323232( (_LEN) | 0x10000000, \
                0, (_VIFDATA1), (_VIFDATA2) );
#else /* TTE=0, PS2 Linux W */
#define _gps2_setdma_vif1_2( _LEN, _VIFDATA1, _VIFDATA2 ) \
        if (!__grl_ps2gdma_path) { \
                _gps2_set_reducedma_cnt( 1+(_LEN), 0 ); \
                _gps2_setdma_32323232( 0, 0, (_VIFDATA1), (_VIFDATA2) ); \
        }
#endif

#define _gps2_setdma_vpudata_r_tag( _ADR, _LEN ) { \
                _gps2_setdma_vif1_2( (_LEN), \
                        PS2_VIF_SET_CODE( 0x0404, 0, PS2_VIF_STCYCL, 0 ), \
                        PS2_VIF_SET_CODE( (_ADR) | 0x8000U, (_LEN), VIF_UNPACK_V
4_32, 0 ) ); \
        }

#define _gps2_setdma_vpudata_body( _P, _LEN ) { \
                memcpy( __grl_ps2gdma_buf_p, (_P), (_LEN) << DMA_UNIT_BITS ); \
                _gps2_setdma_skip_16(_LEN); \
        }

#define _gps2_setdma_vpudata_r( _ADR, _P, _LEN ) { \
                _gps2_setdma_vpudata_r_tag( (_ADR), (_LEN) ); \
                _gps2_setdma_vpudata_body( (_P), (_LEN) ); \
        }

		}10 VPU1ւ̃f[^]p}N


  _gps2_setdma_vpudata_r()œ]f[^𒊏ۉĐݒ肷邱Ƃ
܂Aۂɂ͕\vOŎgpĂ悤ɕĎg
łB̂悤ȕ^O̐ݒ@낢l
AO҂ŐGꂽʂA}NWJꂽʂ\ȌœKȃR[h
Ȃ邱ƂڎwĂ܂̂ŁA͈̔͂ł̒ۉڎw܂B}N
Kw}}11Ɏ܂B


_gps2_setdma_32323232 --- _gps2_setdma_vif1_2 --- _gsp2_setdma_vpudata_r_tag ---
									       |--- _gps2_setdma_vpudata_r
									       |
  ۂ̃f[^        --------------------------- _gps2_setdma_vpudata_body ----

		}11 VPU1ւ̃f[^]p}N̊Kw}


  āAVIF1VPU1ւ̃f[^]͑ʂȕ@邱ƂɂłɐG
܂B̃TvvOł͐G܂񂵁A]f[^32rb
ĝ܂ܓ]郂[hgp܂񂪁A֗ȗƐ}
12̂悤ɂȂ܂BCYCLEWX^̒lݒ肵AUNPACKɂ]2
邾ŁÂ悤ȏ@\łBʒuf[^ƐFf[^̓
ʂɎĂ_ɏłꍇ̂ŕ֗łB̃T
vvÕp[eBN͒Pȓ܂񂪁AƋÂ
̂ɂȂYƂ͌܂񂩂Â߂ɂ͈₷f[^\
Kv܂B
  DMAchain[h^OƑgݍ킹āA̋@\p΂낢
ȉpł傤B


	_ʒuf[^1		->	_ʒuf[^1
	_Ff[^1		->	_Ff[^1
	_ʒuf[^2		->	_ʒuf[^2
	_Ff[^2		->	_Ff[^2
	_ʒuf[^3		->	_ʒuf[^3
	_Ff[^3		->	_Ff[^3
	_ʒuf[^4		->	_ʒuf[^4
	_Ff[^4		->	_Ff[^4

	   C			   VPU

		(A) ʏDMA]

	_ʒuf[^1
	_ʒuf[^2		->	_ʒuf[^1
	_ʒuf[^3		->	_Ff[^1
	_ʒuf[^4		->	_ʒuf[^2
	  (̈ A)		->	_Ff[^2	
					_ʒuf[^3
	_Ff[^1		->	_Ff[^3
	_Ff[^2		->	_ʒuf[^4
	_Ff[^3		->	_Ff[^4
	_Ff[^4		->
	  (̈ B)

	C			   VPU

		(B) CYCLEWX^̒lݒ肵āA
		    1Ƃ΂2DMA]s
		    VUݒ

		}12 VPU1ւ̃f[^]p}N̊Kw}


  VPU1Jn邽߂̃}N͐}13̂悤ɂȂĂ܂B


#define grd_ps2_vpu1_exec( _ADDR ) \
        _gps2_setdma_vif1( PS2_VIF_SET_CODE( (_ADDR), 0, PS2_VIF_MSCAL, 0 ) );

#define grd_ps2_vpu1_cont() \
        _gps2_setdma_vif1( PS2_VIF_SET_CODE( 0, 0, PS2_VIF_MSCNT, 0 ) );

		}13 VPU1̊Jn}N (vpu1.h)


  MSCALōŏVPU1vOAhXwŋNAMSCNTő
Ă̂ʏ̍łB
  ŌɁA}CNvO쐬ē]Kv܂A
PS2 LinuxVPU1̈Ɩڂɗł܂B
  VPU1}CNvOvOŐƂƂ邩܂
񂪁AʂVPUAZuŋLq邱ƂɂȂł傤BPS2 Linuxł́A
ee-dvp-asƂVPUp̃AZugp܂B
  PS2 Linuxł́AVPU1vO͒P̂elft@C𐶐AAvP[
VvO̓_Ci~bNɓǂݍŘA邱Ƃł܂B
ee-dvp-asVPU1}CNR[hł͂ȂADMÃpPbg܂߂ċLq
܂̂ŁÂ܂DMA]邾ŗpłVPU1R[h𐶐ł
ÃTvvOł1DMAobt@փ}CNR[h
肵āADMApb`ς̉J[lƋp̃R[hŎRɎgƂ
ƖړI܂̂ŁA܂Ył͂܂񂪁AVPU1R[h_C
i~bNNÄ̗VPU1R[ĥ݂Rs[Ă܂B
(vpu1.c grd_ps2_vpu1_load())
  쐬\[Xt@C͓ŁA}14Ɏ܂B


    1. sprite.dsx (cppʂsprite.dsm𐶐)
	        .data
	        .DmaPackVif 0
	        .align 0

	        VIFNOP
	        VIFNOP
	        VIFNOP
	        MPG *,*
	#include "sprite.vsm"	(sprite.vsm͂include܂)
	        .EndMPG
	        DMAend

    2. sprite.vsm
		ۂVPU}CNvO


	}14 VPU1}CNR[h̃\[Xt@C\


  ̃TvvOł́Asprite.dsx(sprite.dsm)̓e̓_~[
쐬AύXȂ̂Ɖ肵VPU}CNR[h̃AhXvZ
܂B(vpu1.c, grd_ps2_vpu1_trans())
  āAee-dvp-aśAGNUAZu(gas)Ȃ̂ŃvvZbTƂgasp
gp܂ǍlIȍD݂ŐC̃vvZbT(cpp)ʂĖ{
̃^[Qbgł.dsmgq̃t@C𐶐悤ɂĂ܂B
  AZu̗}15Ɏ܂B


		sprite.dsx
		sprite.vsm
		     |
		     |  cppɂ܂Ƃ߂
                     |
		     V
		sprite.dsm
                     |
                     |  ee-dvp-asɂAZu
                     |
                     V
                  sprite.vo
		     |
		     |  ldɂ胊N
		     |
		     V
		  sprite.elf

    }15 VPU1}CNR[h̃AZu菇Ɛt@C̊֌W


  ȏŁAVPU1}CNvO𓮍삳܂BāA
ۂɃ}CNAZuLq܂B
  T^IVPU1}CNvO̍\}ɕ\ƁA}16̂悤ɂȂ
B


                    Jn
                      |
                      |
                      V
    Kvȏ (GIF_uobt@̏)
                      |
                      |
                      |<------------------------ (*)
                      |
		      V
		XTOP߂ɂ
  	 f[^ǂ݂Jnʒu̎擾
		      |
		      V
 Kvȏ (GSo̓f[^A_ǂ݂ʒuݒ蓙)   ... (A)
		      |
		      |<------------------------
		      |                        |
		      V                        |
	      e_̌vZ               |
		      |                        |
		      V                  no    |
	  ׂĂ̒_vZ -------------
                      |
                      |yes
                      |
                      V
         ㏈ (GIFf[^̏I)                      ... (B)
                      |
                      |
         XGKICKɂGSւ̃f[^]Jn
         o̓f[^_uobt@̐ؑւ
                      |
          Upper߂ւErbgwɂVPU1~
            (MSCNTɂps)
                      |
                      ---------------------------> (*)փWv

	  }16 T^IVPU1̃vO\


  ̍\ŋLq΂̂łA{iIȃQ[ɂ邱Ƃl
ďHvĂ݂ƍl܂B܂AVPU1̃vOɕKvȓ
ڍׂɍlĂ݂܂B
  ̃XvCgTvVPU1֓]f[^́Â悤ɂȂ܂B

	E}gNXTpers
	EXN[WϊpZxNg
		(xs,ys,zsSx,Sy,Sz߂鎞Ɏgp)
	EXN[WϊpZxNg
		(xs,ys,zsSx,Sy,Sz߂鎞Ɏgp)
	EGS֒ړ]pPbgA
		giftag, tex0, tex1
	EXvCgf[^pPbg
		giftag
		TCY({)xNg
		eNX`stq()
		eNX`stq(E)
		e_ʒuf[^
		e_Ff[^

  E܂AGS֒ړ]pPbgɂĐ܂B
eNX`wpTEX0ATEX1Ƃ̂߂giftagłAPS2̍\l
PATH2fɎg悤Ɍ܂B
  AۂɎƂ܂܂B߂VIF^O
FLUSH܂ȂꍇAVPU1̏ԂɂāAVPU1܂
͐ɃeNX`]Ă܂܂B(Ă̏ꍇAVPU1N
PATH2փf[^]ƐPATH2]Ă܂܂A
ē͕ω܂)BFLUSH^OƁAVIF̓삪~܂܂ő
킯łÂ͔łB
  ŁAPATH2̓eNX`]݂̎̂Ɏgp邱ƂɂāAVPU1
̌oRăpPbg]Ă܂B
  {ɖ߂܂B
  VPU1]f[^łAŕ̃f\ƓVPU1
삷邱ƂlĂ݂܂B}gNXTpersXN[W̓[h
W̃IuWFNg̈ʒuꍇύXKv܂񂩂AVPU1v
OԂŋʉł邱Ƃł傤B܂AGS֒ړ]pPb
g̃vOpłłBXvCgf[^̃pPbg͓Ɨ
gpȂĂ͂ȂȂł傤AVPU1̋Nɑ̃}gNXƓ
ݒ肷邱Ƃ΁Ȁ͈ؕύXKvȂƂ܂B
  ŁAvOTu[`Ǝv܂B
  MSCAL^OgpāAAhXw肵ă}gNXݒ肾̃v
Os܂A̎ɂ́AGSփf[^]
sȂVPUsIɓꂽɂ́A2,3%GS/VPU1ԂʂɂȂ
܂̂ŁA悭܂B
  VPŨvOs͐}16Ɏ܂Â(A)`(B)̋Ԃ
IłA܂Ƃ߂KGKICKł悤ɂΏL̖肪ł܂B
(A)̑OɕKvO̊JnAhXe悤ɂ܂BVPU1vO
͏ɊJnAhXǂ݂ĕ򂵂܂B
  vOύXɃAhXςĂ܂̂ł͕sւł̂ŁAT
vvO0ԒnWv߂ׂĂAVPU1_ENTRY_*Ƃ
OŃxt܂B(`t@Csprite.h)
  VPU1}CNvÓAǈȉ̂悤ɂ킩܂B

	E (ŏ1xĂ΂܂)
		VPU1_ENTRY_INIT

	E~XGKICK߂̎s
		VPU1_ENTRY_STOP

	ETpersƃXN[WϊxNg̐ݒ
		VPU1_ENTRY_MATRIX

	EGSւ̃_CNg]
		VPU1_ENTRY_DIRECT

	E3DXvCg
		VPU1_ENTRY_SPRITE

  ʂƂĂłvOEE͐}7łBef[^̓]
ɃTu[`IĂ܂B
  VPU1vO3DXvCgȊÓ̕A}17̂悤ɂȂ܂B


	/* WvxNg */
main:	nop			b	init	; 0  init
	nop			nop
	nop			b	stop	; 2  stop
	nop			nop
	nop			b	matrix	; 4  matrix Tpers, vector
	nop			nop
	nop			b	direct	; 6  GS direct data
	nop			nop
	nop			b	sprite	; 8  3D sprite
	nop			nop

	/* BGIFp_uobt@AhX̐ݒA
	   ʃWX^̒lݒ蓙 */
init:	nop			iaddiu	vi01,vi00,VPU1_GSBASE1
	nop			iaddiu	vi02,vi00,VPU1_GSBASE2
	nop			mfir.x	vf31,vi01
	nop			mfir.z	vf31,vi01
	nop			mfir.y	vf31,vi02
	nop			mfir.w	vf31,vi02
	nop			iaddiu	vi12,vi00,VPU1_EOPMASK
	nop			b	stopn
	nop			iaddiu	vi11,vi12,1	; (delay slot)

stop:	nop			ibltz	vi13,stopn	; vi13 < 0ƃf[^Ȃ
	nop			mtir	vi14,vf31x	; ŌGIF^OEOP
	nop			ilw/x	vi01,0(vi13)    ; ZbgXGKICK
	nop			ior	vi01,vi01,vi11	; set eop
	nop			isw/x	vi01,0(vi13)
	nop			xgkick	vi14
	nop			mr32	vf31,vf31	; _uobt@ؑւ

stopn:	nop[e]			isubiu	vi13,vi00,1	; vi13 = -1
	nop			nop

	/* xtopāAf[^ǂ݂AsAhXdispatch */
	nop			mtir	vi14,vf31x
	nop			xtop	vi15
nextop:	nop			ilw/x   vi01,0(vi15)
	nop			iaddiu	vi15,vi15,1
	nop			jr	vi01
	nop			nop

	/* Tpersݒ肷 */
matrix:	nop			lqi	vf25,(vi15++)	; Tpers
	nop			lqi	vf26,(vi15++)
	nop			lqi	vf27,(vi15++)
	nop			lqi	vf28,(vi15++)
	nop			lqi	vf29,(vi15++)	; screen scale
	nop			b	nextop
	nop			lqi	vf30,(vi15++)	; screen offset

	/* giftagnloop̐pPbgdirect] */
direct:	nop			iaddiu	vi13,vi14,0	; vi13(eop) = vi14
	nop			ilw/x	vi01,0(vi15)
	nop			iand	vi01,vi01,vi12	; count = gif nloop
	nop			iaddiu	vi01,vi01,1
dirloop:nop			isubiu	vi01,vi01,1
	nop			lqi	vf01,(vi15++)
	nop			ibne	vi01,vi00,dirloop
	nop			sqi	vf01,(vi14++)	; (delay slot)
	nop			b	nextop
	nop			nop

	}17 VPU1}CNR[h (3DXvCgȊO)


  āA3DXvCg̃vO}18Ɏ܂B


	; [v̂߂̃XvCgf[^ݒ
sprite:	nop			ilw/x	vi05,0(vi15)
	nop			iand	vi05,vi05,vi12	; vi05 = giftag & 0x7fff = count

	nop			lqi	vf10,(vi15++)	; giftag
	nop			lqi	vf11,(vi15++)	; vec1 (multiply)
	nop			lqi	vf12,(vi15++)	; vec2 (stq 1)
	nop			lqi	vf13,(vi15++)	; vec3 (stq 2)

	nop			iadd	vi13,vi14,vi00	; vi13 = vi14 (for eop)
	nop			sq	vf10,0(vi13)	; set giftag
	nop			iaddiu	vi14,vi14,1	; inc vi14

sploop:
	; Wϊ
	nop			lq	vf01,0(vi15)	; pos
	mulax   acc,vf25,vf01x	nop
	madday  acc,vf26,vf01y	nop
	maddaz  acc,vf27,vf01z	nop
	maddw   vf01,vf28,vf01w	nop
	nop			div	Q,vf00w,vf01w	; Q = 1 / vf01.w
	nop			waitQ
	mulq	vf01,vf01,Q	nop

	; NbvŴ߂ɓWۑ
	mulw	vf03,vf01,vf00w	nop

	; WnXN[Wn֕ϊ
	mul	vf01,vf01,vf29	nop
	add	vf01,vf01,vf30	nop

	; H/V1/wvZ
	mulq.xyz vf04,vf11,Q	nop
	add.xyz	vf06,vf01,vf04	nop
	sub.xyz	vf05,vf01,vf04	nop

	; W4rbgŒ菬_Ȃ̂ŕϊ
	ftoi4	vf06,vf06	nop
	ftoi4	vf05,vf05	nop

	; NbvWs
	clipw.xyz vf03xyz,vf03w	nop
	nop			nop
	nop			nop
	nop			nop
	nop			fcand	vi01,0x3f
	nop			ibeq	vi01,vi00,spncl
	nop			nop
	nop			mtir	vi02,vf05w
	nop			ior	vi02,vi02,vi11
	nop			mfir.w	vf05w,vi02
spncl:
	; RGBlɕϊ
	nop			lq	vf08,1(vi15)	; ld rgba
	ftoi0 vf09,vf08		nop

	; vZʂXgA
	nop			sq	vf12,0(vi14)	; stq1
	nop			sq	vf13,3(vi14)	; stq2
	nop			sq	vf09,1(vi14)	; rgba1
	nop			sq	vf09,4(vi14)	; rgba2
	nop			sq	vf06,2(vi14)	; xyz1
	nop			sq	vf05,5(vi14)	; xyz2

	; 1_̏ÎŃJE^ύX
	nop			isubiu	vi05,vi05,1
	nop			iaddiu	vi15,vi15,2
	nop			iaddiu	vi14,vi14,6

	; ȉnop͕KvȂAibne̒OisubiuĂ͂Ȃ
	nop			nop

	nop			ibne	vi05,vi00,sploop
	nop			nop
	nop			b	nextop
	nop			nop

	}18 VPU1}CNR[h (3DXvCĝ/œKȂ)


  ȏVPU1gp3DXvCgvO܂B
  VPU1̃vOgpTvvÕRpĆA
ȉ̂悤ɂȂ܂B

	#define USE_VPU1
	#define USE_FAKERANDOM
	#define FIRE_SPRITE_SIZE	30000.0f
	#define USE_VPU1_PACK1NUM	35
	#define USE_VPU1_SPRITE		1

  ̐S̎sʂłA1t[̃XvCg͖18000łB
āAb108̃|S\Ă܂B
  XvCg2.2{łA܂܂̌ʂꂽƌł
B
  āAŃXvCg̑傫
	#define FIRE_SPRITE_SIZE	5000.0f
ƂďĂ݂܂B̏ꍇA1t[ς܂Ńf[^\
悤ɂ邽߂ɂ́ATvvỎKvƂȂ܂
ŒӂĂB
  1t[̃XvCg͖56000łBāAb336
̃XvCg\Ă܂B
  XvCgTCYύXƁA\x3{ɂȂ܂B
  ̓̑茋ʂ̈Ӗ͌Ő܂A̒lx[XɎ̃Iv
eB}CYƂɓ܂B


 VPU1}CNR[h̃IveB}CY

  VPU1}CNR[h́AȂɂlɋLqꍇAnU[h̎RɂȂ
Ă܂܂BL̃vÓAT^IVPU1̒PȃvOłA
nU[h܂lĂ܂̂ŁAPS2̗͂ƂĂ͂܂
ĂȂ\܂B
  āAVPU1̃}CNvOIveB}CY܂AIveB
}CY͂ӖĂ̂ł傤B
 VPU1̃vÓAnU[hȂApCvĈ
11NbNœł܂B̃vÕnU[hNOP
ɒuăvOƐ}19ɂȂ܂B(TvvO
̏ꍇ́A#define USE_VPU1_SPRITE 2ŃRpC܂)
  [v1_̏́A66߁A܂66NbNƂȂ܂B


sprite: nop                     ilw/x   vi05,0(vi15)
        nop                     iand    vi05,vi05,vi12  ; vi05 = giftag & 0x7fff
 = count

        nop                     lqi     vf10,(vi15++)   ; giftag
        nop                     lqi     vf11,(vi15++)   ; vec1 (multiply)
        nop                     lqi     vf12,(vi15++)   ; vec2 (stq 1)
        nop                     lqi     vf13,(vi15++)   ; vec3 (stq 2)
        nop                     iadd    vi13,vi14,vi00  ; vi13 = vi14 (for eop)
        nop                     sq      vf10,0(vi13)    ; set giftag
        nop                     iaddiu  vi14,vi14,1     ; inc vi14

; ------------ [vJn --------------------------------
sploop:
        ; rotpers
        nop                     lq      vf01,0(vi15)    ; pos
        nop                     nop
        nop                     nop
        nop                     nop
        mulax   acc,vf25,vf01x  nop
        madday  acc,vf26,vf01y  nop
        maddaz  acc,vf27,vf01z  nop
        maddw   vf01,vf28,vf01w nop
        nop                     div     Q,vf00w,vf01w   ; Q = 1 / vf01.w
        nop                     nop
        nop                     nop
        nop                     nop
        nop                     nop
        nop                     nop
        nop                     nop
        mulq    vf01,vf01,Q     nop
        nop                     nop
        nop                     nop
        nop                     nop

        ; copy for clipw
        mulw    vf03,vf01,vf00w nop

        ; screen coodinates
        mul     vf01,vf01,vf29  nop
        nop                     nop
        nop                     nop
        nop                     nop
        add     vf01,vf01,vf30  nop

        ; calc and add sprite w/h
        mulq.xyz vf04,vf11,Q    nop
        nop                     nop
        nop                     nop
        nop                     nop
        add.xyz vf06,vf01,vf04  nop
        sub.xyz vf05,vf01,vf04  nop
        nop                     nop
        nop                     nop

        ; convert
        ftoi4   vf06,vf06       nop
        ftoi4   vf05,vf05       nop

        ; clip W
        clipw.xyz vf03xyz,vf03w nop
        nop                     nop
        nop                     nop
        nop                     nop
        nop                     fcand   vi01,0x3f
        nop                     ibeq    vi01,vi00,spncl
        nop                     nop
        nop                     mtir    vi02,vf05w
        nop                     nop
        nop                     nop
        nop                     nop
        nop                     ior     vi02,vi02,vi11
        nop                     mfir.w  vf05w,vi02
spncl:
        ; rgba
        nop                     lq      vf08,1(vi15)    ; ld rgba
        nop                     nop
        nop                     nop
        nop                     nop
        ftoi0 vf09,vf08         nop
        nop                     nop

        ; store data
        nop                     sq      vf12,0(vi14)    ; stq1
        nop                     sq      vf13,3(vi14)    ; stq2
        nop                     sq      vf09,1(vi14)    ; rgba1
        nop                     sq      vf09,4(vi14)    ; rgba2
        nop                     sq      vf06,2(vi14)    ; xyz1
        nop                     sq      vf05,5(vi14)    ; xyz2

        ; counter update
        nop                     isubiu  vi05,vi05,1
        nop                     iaddiu  vi15,vi15,2
        nop                     iaddiu  vi14,vi14,6

        nop                     nop

        nop                     ibne    vi05,vi00,sploop
        nop                     nop
; ------------ [vI --------------------------------

        nop                     b       nextop		; I
        nop                     nop

  }19 VPU1}CNR[h (3DXvCĝ/œKȂNOP\)


EE͖294MHzł̂ŁA1bԂɎsł閽߂̐294000000łB

		294000000/66  4454545

܂AVPU1SGSƕ񓮍삵ĖʂȂ삵ꍇ̗_lƂ
͕b4454̃XvCg\ł܂BNTSC, VGAŃtbV[
g60HzƂƁA

		4454545/60  74242

ƂƂŁA1t[74242̃XvCgł܂B
̒ĺA̎ʂ̗ǂlƔrĂAƗǂlƂȂĂ
AGSVPU1SɗzIɕ񓮍삷邱Ƃ͂肦܂̂ŁAvZ
̒l͂܂ŖڈƂƂɂȂ܂BƂẮAf[^̃Zbg
AbvGS/VPU1̃_uobt@ؑւ҂ԓ낢ȃI[o[wb
hl܂Aǂȃn[hEGAł͂낢Ȏɂ҂
낢ȂƂŔĂ܂܂B
  ƂŁǍvZɂĕʂ̌ƁAVPU1̃IveB}CYɂ
čő含\܂Ă܂Ƃƌ܂BVPU1̃IveB}CY1N
bN邲ƂɃWIgϊɂvZ邱ƂɂȂ
BAGS̕`摬xȏɍĂӖȂ̂łB
  낢돔͂܂APS2VPU1|S\\͂́Ax
`}[NIɃs[N\oƂĕb1500`1700̃|S`\
͂łB̃XvCg\ł́A1[vŃXvCg12_̌vZ
s܂B(ʏ̃|S\ŎgXgbvOp`łXgbv
Ȃ1_1|SɂȂ܂̂ŁAvZ@g܂)
IȎgpprƂĂ͌؂Ă܂ƁA

	294000000/15000000 = 19.6

܂AVPU1ƂĂ͂20NbNڈɃIveB}CYΏ\
ƂƂɂȂ܂B

  ڕW܂܂̂ŁA͓s悤ɖ߂בւ邾łB
  VPU1vOœK̊{ȍl̓[ṽvO
Ƃɂ܂BWX^ł邾gpAnU[h𔭐
EE̎𖳑ʂȂs삳܂Bn[hEGÃpCvCv
ׂĂB\tgEGAŎČ̃[v̏
Ԃ܂BvO~OƂƂĂ̓[ṽR[hXL
[邱ƂɂȂ܂BꂪVPU1̎蓮œKƂłB(}20)



			(ʎ)


		}20 VPU1œK̊{ƒӓ_

  XL[ɂ͊JnƏIɈKv̂Ȃf[^XL[
vZĂ܂AXgAĂ܂܂B̓vOȒPɂ邽
߂ɍœKɂ́AVPU1_ENTRY_STOPxsGSɂ͏o͎̓XvC
g̈ȊÕf[^uȂ悤ɂāAɍ쐬f[^󂳂邱
hɂĂ܂B(}7Q)
  ́Ae߂̃CeVɒӂāA߂zuĂ킯łA
VPU͒Pł̂ŁAO͑̂́A{Iɂ͕_Z̃
CeV4AWX^̃[h/XgÃCeV2AZ
CeV1Ȃ̂œɋCɂȂAɂ͒xXbgA
̏ɎgWX^͒OɎgpȂADIV͂߂ƂO
߂ɂċC邱Ƃ𓪂ɓĂ΂̖ł
BVPU1œKłARc߂Αςł͂܂B
  āAƂ͒PȂpY̖łÃTvvOł͈
ʓ|ȗvf܂BWNbv̕򖽗߂łB͋ZŊ撣
Ă悢̂łA͏HvĂ݂ĕ򖽗߂yɈ@l
݂܂B

  1) 2[vpӂĂ݂ɕ򂷂 (}21)

  2) CLIP̏򂻂̂̂ (}22)



			(ʎ)


	  }21 2̃[vpӂčœK


        nop                     fcand   vi01,0x3f
        nop                     mtir    vi02,vf05w
        nop                     ibeq    vi01,vi00,next
        nop                     ior     vi02,vi02,vi11
        nop                     mfir.w  vf05w,vi02
next:

			|
			V

        nop                     fcand   vi01,0x3f
	nop			mtir    vi02,vf05w
	nop			iadd    vi01,vi01,vi12(0x7fff)
	nop			iand    vi01,vi01,vi11(0x8000)
	nop			ior     vi02,vi02,vi01
	nop			mfir.w  vf05w,vi02

	  }22  (߂̒u)


  1)̕@́A/񕪊򎞂̗̍œK[vʂɗpӂČ݂
CLIPʂɂă[v𕪊򂷂邾łAꂾōœK͔
ɊȒPɂȂ܂B
  2)̕@́Aߐ1Ă܂܂A򂻂̂̂Ƃ
ł܂̂ŁA肻̂̂ȂȂœKȒPɂȂ܂B
  ́Ały2)̕@ōœK܂BœKꂽvO}23
Ɏ܂B


        ftoi0   vf09,vf08       div     Q,vf00w,vf14w   ; Q = 1 / vf14(vf01).w
        mulax   acc,vf25,vf02x  isubiu  vi05,vi05,1
        madday  acc,vf26,vf02y  iaddiu  vi15,vi15,2
        maddaz  acc,vf27,vf02z  iaddiu  vi14,vi14,6
        maddw   vf02,vf28,vf02w mtir    vi02,vf16w
        nop                     fcand   vi01,0x3f000
        nop                     iadd    vi01,vi01,vi12
        mulq    vf01,vf14,Q     iand    vi01,vi01,vi11
        mulq.xyz vf04,vf11,Q    ior     vi02,vi02,vi01
        mulw    vf14,vf02,vf00w mfir.w  vf16w,vi02
        nop                     sq      vf09,1-6(vi14)  ; rgba1
        mulw    vf03,vf01,vf00  sq      vf09,4-6(vi14)  ; rgba2
        mul     vf01,vf01,vf29  lq      vf08,1-2(vi15)  ; ld rgba
        sub.xyz vf05,vf07,vf04  sq      vf15,2-18-6(vi14) ; xyz1
        add.xyz vf06,vf07,vf04  sq      vf16,5-18-6(vi14) ; xyz2
        clipw.xyz vf03xyz,vf03w lq      vf02,0-2(vi15)  ; ld pos
        add     vf07,vf01,vf30  sq      vf12,0-6(vi14)  ; stq1
        ftoi4   vf15,vf05       ibne    vi05,vi00,sploop
        ftoi4   vf16,vf06       sq      vf13,3-6(vi14)  ; stq2

	 }23 œKꂽXvCg\vO ([v̂)


  ʂƂẮA1XvCg̃[v19NbÑvO
邱Ƃł܂B
  VPU1̏ԂƂẮA19NbNł̂ŁA

		294000000/19  15472684

܂Ab5547̃XvCg\ł܂B
NTSC, VGAŃtbV[g60HzƂƁA

		15473684/60  257894

ƂȂ܂̂ŁAWIgZƂĂ1t[257894(b
1500)̃XvCgł܂B
  VPU1̃vOgpTvvÕRpĆA
ȉ̂悤ɂȂ܂B

	#define USE_VPU1
	#define USE_FAKERANDOM
	#define FIRE_SPRITE_SIZE	30000.0f
	#define USE_VPU1_PACK1NUM	35
	#define USE_VPU1_SPRITE		3

ۂɎsɕ\ꂽ1t[̃XvCg18000łB
́AVPU1̍œK܂ӖȂĂ܂BœKȂ̃v
Oł`TCY̕ύXőx傫ςƂƉ킹čl
ǂVPU1ł͂ȂGS̕`摬x{glbN悤łB
  āAŃXvCg̑傫
	#define FIRE_SPRITE_SIZE	5000.0f
ƂďrĂ݂܂Bۂɕ\ꂽ1t[
XvCg150000łBāAb900̃XvCg\
Ă܂B
  ́AVPU1̍œǨʂAVPU1̗_l͒̂łA
IȗRlƂ܂܂ǂʂꂽƂł傤B
  Ƃ]Ȃ΁AœKVPU1̃vO
_~[nopĂAɉsԂ̕ωOtɂ΂킩
₷ł傤B
  {eł3DXvCge[}ƂĈĂ܂Aʂ̌ł|S
fł̘b͂̂܂ܓKpł܂BAgCAOXg
bv̂ȂAfɂđ傫ʂς܂̂ŁAœK
̑P]̂̓XvCgƓȂĂ܂B


 VCLɂ

  {eł͏ڍׂ͐G܂񂪁APS2 LinuxɂVCLƂœKc[t
Ă܂BgVPU}CNvO̍œKłĂ
܂BœKPS2̃n[hEGǍEڎŵ͍̂Ƃ떳
Ȃ悤łAړIőVPU1}CNR[hꍇA
ƍœKĂ̂ł̓vO}̐_͂̕EɒBĂ܂܂
炱̂悤ȃc[płłB
  ܂AO߂̂悤VPU1œKĂӖ̂Ȃ`܂A
\OtBbNɂĂ͂̂悤Ȏc[݂̂ŏ\Ȏ
邩܂B
  AʓIȃfł̓Jʒuɂă|STCYω
ÃXvCĝ悤ɖ̐؂蕪ł킯ł͂܂
̂ŁAvO~OɂĂu\Ȍw͂vƂʂƎv
܂B
  āA啔PS2OtBbNvO}VPU1vO~O
œKƂėǂ̂邱Ƃ͓Ǝ͎v܂B


 VPU/GSƂ̃oX

  VPU1vO̍œKɂāAȂ悢lo悤ɂ͂Ȃ܂
AVPU1̗_l͒lƂȂĂ܂B
  ̌𐄑Ă݂܂B
  EE DMAAVPU1AGS̃pCvC͐}24̂悤ɂȂĂ܂B



			(ʎ)



	    }24 EE DMAAVPU1AGS̃pCvC

  ̒ŁAEẼf[^͑Ot[łׂčĂƂƁA
ʂȑ҂錴́An[hEGA̒჌xȕāA
\tgEGAIɂ͂ȂƂĂł傤B
  AVPU1GSփf[^]悤Ƃ鎞AGS̕`悪܂I
ĂȂVPU1͑҂ԂɂȂ܂BGSɂĂlŁAGS̕`悪
ɏIĂAVPU1̃f[^܂ő҂ԂɂȂĂ܂܂B
(̖邽߂PATH3Ƃ̕sf[^]gpłłA
ۂɕs`sƒxȂĂ܂܂)
  ܂A

  VPU CNT1̎s =
		Max(VPU1̎s, GS̎s)

ƂȂĂ܂܂BɁAVPU1/GSԂ̃f[^]A/VPU1Ԃ
DMAAɂoX̃A[rg[Vɂ҂AlXȗv
ł܂܂BۂɃ_uobt@̐\傫̂
͐mɂ͂킩܂񂪁Aȏ̗RlƁAO߂̌vʂ͂
̂ł傤B
  ł_lɋ߂ÂȂ΁AVPU1̏ = GS̏ԂƂȂ
悤Ƀf[^𒲐΂悢̂łAGS̏Ԃ̓|S̃TCY
đ傫ω܂B܂Aʏ3DOtBbÑJʒuɂ
ĕ`掞Ԃω邱ƂӖAɉăTCŸႤ|S
ׂȂĂ͂ȂȂƂӖĂ邽߁Aǂ󋵂^[QbgƂ
邩߂̂ȂĂ܂܂Bǂ̂ƂA͂܂茻
Ił͂ȂƂƂɂȂĂ܂܂B
  AȂ͂܂łA3DXvCg̏ꍇ́Aʂ
߂ȂAȂʒuŎgƉ肷ƁAGSɕ\傫̕
̂Řb͈Ă܂B
  GS̕`悷e܂Ă΁AGSԂ܂܂Bxɑ
ׂVPU1̒_ߌvAx̒l߂邱Ƃł
܂B
  ۂɃvOŐł̂́Axɑ钸_炢łA
̃TvvȌꍇAقVPU1̎s < GS̕`掞ԂƂȂ
邽߂cOȂقƂǕω܂B
  ȑOAQ[JĂɂ͍܂̂ŎQlxɋLq
܂ƁAVPU1vOł͒_20`35x̎ɍōxo
ƂłAȊO̒_20ȉA35ȏ̎ɂ͑xxȂ
B̃TvƂDMAf[^]̃f[^܂قȂ
Ă邱Ɠ⑼̗v肻łA񎞊Ԃ̕ωȂR͎
ɂȂĂ܂B

  ȏA܂ł̘b𑍍PS2̃ptH[}X`[jOōłw
͂ɂEɒB镔GS̕`揈Ǝ͍lĂ܂BɌ
݂GPUƂĂ͍GSłAcOȂL]p[Ƃ킯ł
܂񂵁AvO~Oœw͂ł邱Ɠeɂ͌E܂B
  GŜ̂̕`摬xɂẮAV-RAM̃y[WEAeNX`Lb
VAeNX`̐FAl邱Ƃ͂낢날܂AvO
w͂tɕ\e̕GS̓𐶂̂ɂKv
܂B
  ̃Tv́A32x3232biteNX`gpăXvCg`悵
Ă܂̂ŁAeNX`ƂāA܂ʂ̕`@ƂĂ͍łɂ
悤ɂȂĂ܂B


 EEGS/VPU1̃oX

  ̌eł́AVPU1/GŜ݂̃vO~OΏۂƂĂ̂ŁA
ȏ̂Ƃ͍s܂񂪁Aۂ̃vO~OłEEVPU1/GS
̃oXKvłBEȄ́AVPU1/GS
ԂŏIĂKvł傤B
  ͒PȃTvVPU1/GŜ݂^[QbgƂĂ邽߁Aق
ǉĂ܂񂪁APɓ삳VPU1/GSƔrĔ
x߁Arand()֐ȒPȊ֐ɒuĂ܂B
  LlĂÃTvvO͏ɂĂEE̕
ȂĂ܂BEE̍œKIȃvOł͕KKvȍƂłB
  ̃TvvȌꍇAXNb`pbh̗pAVPU0}N
߂̗pACCAZu̗pALbṼvtFb`ALb
VTCYll܂B
  Aۂ̃Q[̏ꍇAOtBbNɂ邽߂ɂ́A
ÂKvɂȂ܂̂ŁAEȄ͍̃TvƂ͑S
Ⴄ̂ɂ܂Ă܂ł傤Ałf𓯎ɕ\肷ƁA
f\EEVPU1/GS̕SɂȂ܂Aȏ
̍œKKvȂ܂B
  ȏ́AۂɎ̂Ɉˑł傤B肽
̂AƂ̂YłAPS2̓sɍ킹Ď𒲐
ƂƂ邽߂̔錍Ǝ͍lĂ܂B


 TvvO

  쐬TvvOufireworksvɂĐ܂B
  ̃vO͈ȉāAPS2 LinuxłƂfXg[
V(ԉ΂ǂ̃p[eBNf)s܂B(ʐ^1`4, BMP`)

        EeNX`/VPU1păp[eBNf
        EpbhpăJRg[
        EtHg\
        Et[obt@_v
        EptH[}Xvp_Ot\

  O҂cubedemox[XVPU1ΉgvOłAptH[
}XvƂGS/VPU1̎Ԃ悤ɂȂÄႢ
܂B
  @͎̂悤ɂȂ܂B

        EẼAiOƍ4{^ŃJړ܂
        EƁ~ŉԉ(ǂ)̐𑝌܂
        ESELECTĂԈꎞ~ASELECTĂԂSTART
          ƁAt[obt@̂܂܃t@CɃZ[u܂B

  vO\͎̂悤ɂȂĂ܂B

  E Aݒt@C
	Makefile
	MCONFIG
	config.h
	config_fire.h
	config_ps2linux.h
	common.h
	init.c

  E p[eBNf̃[`
	main.[hc]
	fire.[hc]
	fire_sub.[hc]

  E DMAAReLXgAGSݒ蓙
	def_dma.h
	def_gs.h
	context.h
	draw.[hc]

  E PS22DOtBbN
	prim.h
	prim2d.h
	bmp.h
	tex.[hc]
	font.[hc]

  E PS23DOtBbN
	matrix.[hc]
	geometry.[hc]
	prim3d.[hc]

  E VPU1֘A
	vpu1.[hc]
	sprite.h
	sprite.dsx
	sprite.vsm

  E vt@CAt[obt@Z[u
	debug.[hc]

  E ̑̃Tu[`
	fileio.[hc]
	memory.[hc]
	input.[hc]

  fireworks̎sɂ́ARpCƂKvłB

        cd fireworks
        make depend
        make
        make run

  RpCɈȉ̃IvVIł܂B

1. MCONFIGGDEFINES
2. config.h
3. config_ps2linux.h

  ȏAO҂cubedemoƓł̂ŁAcubedemo̐䗗B

4. config_fire.h

  #define USE_VPU1
        VPU1gpăWIgZs܂B

  #define USE_FAKERAND
        rand()֐glibĉ̂玩O̊ȒPȂ̂ɕύX܂B

  #undef USE_NOVPU1_POINT
        #undef USE_VPU1݂̎̂Ɍʂ܂B
        XvCgł͂ȂA|Cg\s܂B

  #define FIRE_SPRITE_SIZE      30000.0f
        p[eBÑXvCgTCYw肵܂B
        
  #define USE_VPU1_PACK1NUM       30
        VPU1ֈxɑ钸_ݒ肵܂B
        
  #define USE_VPU1_SPRITE         3
        VPU1}CNvOI܂B

        1 ... œKȂ
        2 ... œKȂ (nopŃnU[hu)
        3 ... œK


 Ō

  ́AVPU1gpPS2 Linux̃vO~OƃptH[}X`[
jO܂B
  Ŗ{ẽe[}łPlayStation2vO~OЂƂ߂͏I
APS2͉[A{eňptH[}XɊւĂł
VPU1/GS̊{ɐGꂽł܂B
  ŌɁA{Lō쐬vOłAׂ͂GNU Public
License Ver.2ɏƂ܂B


ȏ
