1 #include <stdint.h>
2 #include <string.h>
3 
4 #include <retro_inline.h>
5 
6 #include "N64.h"
7 #include "RSP.h"
8 #include "GBI.h"
9 #include "gDP.h"
10 #include "Debug.h"
11 #include "Common.h"
12 #include "gSP.h"
13 #include "RDP.h"
14 
15 #include "../../Graphics/RSP/gSP_state.h"
16 #include "../../Graphics/RDP/RDP_state.h"
17 
18 enum
19 {
20    gspTexRect = 0,
21    gdpTexRect,
22    halfTexRect
23 };
24 
RDP_Unknown(uint32_t w0,uint32_t w1)25 void RDP_Unknown( uint32_t w0, uint32_t w1 )
26 {
27 }
28 
RDP_NoOp(uint32_t w0,uint32_t w1)29 void RDP_NoOp( uint32_t w0, uint32_t w1 )
30 {
31     gln64gSPNoOp();
32 }
33 
RDP_SetCImg(uint32_t w0,uint32_t w1)34 void RDP_SetCImg( uint32_t w0, uint32_t w1 )
35 {
36     gln64gDPSetColorImage( _SHIFTR( w0, 21,  3 ),        // fmt
37                       _SHIFTR( w0, 19,  2 ),        // siz
38                       _SHIFTR( w0,  0, 12 ) + 1,    // width
39                       w1 );                         // img
40 }
41 
RDP_SetZImg(uint32_t w0,uint32_t w1)42 void RDP_SetZImg( uint32_t w0, uint32_t w1 )
43 {
44     gln64gDPSetDepthImage( w1 ); // img
45 }
46 
RDP_SetTImg(uint32_t w0,uint32_t w1)47 void RDP_SetTImg( uint32_t w0, uint32_t w1 )
48 {
49     gln64gDPSetTextureImage( _SHIFTR( w0, 21,  3),       // fmt
50                         _SHIFTR( w0, 19,  2 ),      // siz
51                         _SHIFTR( w0,  0, 12 ) + 1,  // width
52                         w1 );                       // img
53 }
54 
RDP_SetCombine(uint32_t w0,uint32_t w1)55 void RDP_SetCombine( uint32_t w0, uint32_t w1 )
56 {
57     gln64gDPSetCombine( _SHIFTR( w0, 0, 24 ),    // muxs0
58                    w1 );                    // muxs1
59 }
60 
RDP_SetEnvColor(uint32_t w0,uint32_t w1)61 void RDP_SetEnvColor( uint32_t w0, uint32_t w1 )
62 {
63     gln64gDPSetEnvColor( _SHIFTR( w1, 24, 8 ),       // r
64                     _SHIFTR( w1, 16, 8 ),       // g
65                     _SHIFTR( w1,  8, 8 ),       // b
66                     _SHIFTR( w1,  0, 8 ) );     // a
67 }
68 
RDP_SetPrimColor(uint32_t w0,uint32_t w1)69 void RDP_SetPrimColor( uint32_t w0, uint32_t w1 )
70 {
71     gln64gDPSetPrimColor( _SHIFTL( w0,  8, 5 ),      // m
72                      _SHIFTL( w0,  0, 8 ),      // l
73                      _SHIFTR( w1, 24, 8 ),      // r
74                      _SHIFTR( w1, 16, 8 ),      // g
75                      _SHIFTR( w1,  8, 8 ),      // b
76                      _SHIFTR( w1,  0, 8 ) );    // a
77 
78 }
79 
RDP_SetBlendColor(uint32_t w0,uint32_t w1)80 void RDP_SetBlendColor( uint32_t w0, uint32_t w1 )
81 {
82     gln64gDPSetBlendColor( _SHIFTR( w1, 24, 8 ),     // r
83                       _SHIFTR( w1, 16, 8 ),     // g
84                       _SHIFTR( w1,  8, 8 ),     // b
85                       _SHIFTR( w1,  0, 8 ) );   // a
86 }
87 
RDP_SetFogColor(uint32_t w0,uint32_t w1)88 void RDP_SetFogColor( uint32_t w0, uint32_t w1 )
89 {
90     gln64gDPSetFogColor( _SHIFTR( w1, 24, 8 ),       // r
91                     _SHIFTR( w1, 16, 8 ),       // g
92                     _SHIFTR( w1,  8, 8 ),       // b
93                     _SHIFTR( w1,  0, 8 ) );     // a
94 }
95 
RDP_SetFillColor(uint32_t w0,uint32_t w1)96 void RDP_SetFillColor( uint32_t w0, uint32_t w1 )
97 {
98     gln64gDPSetFillColor( w1 );
99 }
100 
RDP_FillRect(uint32_t w0,uint32_t w1)101 void RDP_FillRect( uint32_t w0, uint32_t w1 )
102 {
103 	const uint32_t ulx = _SHIFTR(w1, 14, 10);
104 	const uint32_t uly = _SHIFTR(w1, 2, 10);
105 	const uint32_t lrx = _SHIFTR(w0, 14, 10);
106 	const uint32_t lry = _SHIFTR(w0, 2, 10);
107 	if (lrx < ulx || lry < uly)
108 		return;
109 	gln64gDPFillRectangle(ulx, uly, lrx, lry);
110 }
111 
RDP_SetTile(uint32_t w0,uint32_t w1)112 void RDP_SetTile( uint32_t w0, uint32_t w1 )
113 {
114 
115     gln64gDPSetTile( _SHIFTR( w0, 21, 3 ),   // fmt
116                 _SHIFTR( w0, 19, 2 ),   // siz
117                 _SHIFTR( w0,  9, 9 ),   // line
118                 _SHIFTR( w0,  0, 9 ),   // tmem
119                 _SHIFTR( w1, 24, 3 ),   // tile
120                 _SHIFTR( w1, 20, 4 ),   // palette
121                 _SHIFTR( w1, 18, 2 ),   // cmt
122                 _SHIFTR( w1,  8, 2 ),   // cms
123                 _SHIFTR( w1, 14, 4 ),   // maskt
124                 _SHIFTR( w1,  4, 4 ),   // masks
125                 _SHIFTR( w1, 10, 4 ),   // shiftt
126                 _SHIFTR( w1,  0, 4 ) ); // shifts
127 }
128 
RDP_LoadTile(uint32_t w0,uint32_t w1)129 void RDP_LoadTile( uint32_t w0, uint32_t w1 )
130 {
131     gln64gDPLoadTile( _SHIFTR( w1, 24,  3 ),     // tile
132                  _SHIFTR( w0, 12, 12 ),     // uls
133                  _SHIFTR( w0,  0, 12 ),     // ult
134                  _SHIFTR( w1, 12, 12 ),     // lrs
135                  _SHIFTR( w1,  0, 12 ) );   // lrt
136 }
137 
138 static uint32_t lbw0, lbw1;
RDP_LoadBlock(uint32_t w0,uint32_t w1)139 void RDP_LoadBlock( uint32_t w0, uint32_t w1 )
140 {
141 	lbw0 = w0;
142 	lbw1 = w1;
143 
144    gln64gDPLoadBlock( _SHIFTR( w1, 24,  3 ),    // tile
145                   _SHIFTR( w0, 12, 12 ),    // uls
146                   _SHIFTR( w0,  0, 12 ),    // ult
147                   _SHIFTR( w1, 12, 12 ),    // lrs
148                   _SHIFTR( w1,  0, 12 ) );  // dxt
149 }
150 
RDP_RepeatLastLoadBlock()151 void RDP_RepeatLastLoadBlock()
152 {
153 	RDP_LoadBlock(lbw0, lbw1);
154 }
155 
RDP_SetTileSize(uint32_t w0,uint32_t w1)156 void RDP_SetTileSize( uint32_t w0, uint32_t w1 )
157 {
158    gln64gDPSetTileSize( _SHIFTR( w1, 24,  3 ),      // tile
159                     _SHIFTR( w0, 12, 12 ),      // uls
160                     _SHIFTR( w0,  0, 12 ),      // ult
161                     _SHIFTR( w1, 12, 12 ),      // lrs
162                     _SHIFTR( w1,  0, 12 ) );    // lrt
163 }
164 
RDP_LoadTLUT(uint32_t w0,uint32_t w1)165 void RDP_LoadTLUT( uint32_t w0, uint32_t w1 )
166 {
167     gln64gDPLoadTLUT(  _SHIFTR( w1, 24,  3 ),    // tile
168                   _SHIFTR( w0, 12, 12 ),    // uls
169                   _SHIFTR( w0,  0, 12 ),    // ult
170                   _SHIFTR( w1, 12, 12 ),    // lrs
171                   _SHIFTR( w1,  0, 12 ) );  // lrt
172 }
173 
RDP_SetOtherMode(uint32_t w0,uint32_t w1)174 void RDP_SetOtherMode( uint32_t w0, uint32_t w1 )
175 {
176     gln64gDPSetOtherMode( _SHIFTR( w0, 0, 24 ),  // mode0
177                      w1 );                  // mode1
178 }
179 
RDP_SetPrimDepth(uint32_t w0,uint32_t w1)180 void RDP_SetPrimDepth( uint32_t w0, uint32_t w1 )
181 {
182     gln64gDPSetPrimDepth( _SHIFTR( w1, 16, 16 ),     // z
183                      _SHIFTR( w1,  0, 16 ) );   // dz
184 }
185 
RDP_SetScissor(uint32_t w0,uint32_t w1)186 void RDP_SetScissor( uint32_t w0, uint32_t w1 )
187 {
188     gln64gDPSetScissor( _SHIFTR( w1, 24, 2 ),                        // mode
189                    _FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ),    // ulx
190                    _FIXED2FLOAT( _SHIFTR( w0,  0, 12 ), 2 ),    // uly
191                    _FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ),    // lrx
192                    _FIXED2FLOAT( _SHIFTR( w1,  0, 12 ), 2 ) );  // lry
193 }
194 
RDP_SetConvert(uint32_t w0,uint32_t w1)195 void RDP_SetConvert( uint32_t w0, uint32_t w1 )
196 {
197     gln64gDPSetConvert( _SHIFTR( w0, 13, 9 ),    // k0
198                    _SHIFTR( w0,  4, 9 ),    // k1
199                    _SHIFTL( w0,  5, 4 ) | _SHIFTR( w1, 27, 5 ), // k2
200                    _SHIFTR( w1, 18, 9 ),    // k3
201                    _SHIFTR( w1,  9, 9 ),    // k4
202                    _SHIFTR( w1,  0, 9 ) );  // k5
203 }
204 
RDP_SetKeyR(uint32_t w0,uint32_t w1)205 void RDP_SetKeyR( uint32_t w0, uint32_t w1 )
206 {
207     gln64gDPSetKeyR( _SHIFTR( w1,  8,  8 ),      // cR
208                 _SHIFTR( w1,  0,  8 ),      // sR
209                 _SHIFTR( w1, 16, 12 ) );    // wR
210 }
211 
RDP_SetKeyGB(uint32_t w0,uint32_t w1)212 void RDP_SetKeyGB( uint32_t w0, uint32_t w1 )
213 {
214     gln64gDPSetKeyGB( _SHIFTR( w1, 24,  8 ),     // cG
215                  _SHIFTR( w1, 16,  8 ),     // sG
216                  _SHIFTR( w0, 12, 12 ),     // wG
217                  _SHIFTR( w1,  8,  8 ),     // cB
218                  _SHIFTR( w1,  0,  8 ),     // SB
219                  _SHIFTR( w0,  0, 12 ) );   // wB
220 }
221 
RDP_FullSync(uint32_t w0,uint32_t w1)222 void RDP_FullSync( uint32_t w0, uint32_t w1 )
223 {
224    gln64gDPFullSync();
225 }
226 
RDP_TileSync(uint32_t w0,uint32_t w1)227 void RDP_TileSync( uint32_t w0, uint32_t w1 )
228 {
229    gln64gDPTileSync();
230 }
231 
RDP_PipeSync(uint32_t w0,uint32_t w1)232 void RDP_PipeSync( uint32_t w0, uint32_t w1 )
233 {
234    gln64gDPPipeSync();
235 }
236 
RDP_LoadSync(uint32_t w0,uint32_t w1)237 void RDP_LoadSync( uint32_t w0, uint32_t w1 )
238 {
239    gln64gDPLoadSync();
240 }
241 
242 
_getTexRectParams(uint32_t * w2,uint32_t * w3)243 static void _getTexRectParams(uint32_t *w2, uint32_t *w3)
244 {
245    unsigned texRectMode;
246    uint32_t cmd1, cmd2;
247 
248    if (__RSP.bLLE)
249    {
250       *w2 = __RDP.w2;
251       *w3 = __RDP.w3;
252       return;
253    }
254 
255    texRectMode = gdpTexRect;
256    cmd1        = (*(uint32_t*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 0]) >> 24;
257    cmd2        = (*(uint32_t*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 8]) >> 24;
258 
259    if (cmd1 == G_RDPHALF_1)
260    {
261       if (cmd2 == G_RDPHALF_2)
262          texRectMode = gspTexRect;
263    }
264    else if (cmd1 == 0xB3)
265    {
266       if (cmd2 == 0xB2)
267          texRectMode = gspTexRect;
268       else
269          texRectMode = halfTexRect;
270    }
271    else if (cmd1 == 0xF1)
272       texRectMode = halfTexRect;
273 
274    switch (texRectMode)
275    {
276       case gspTexRect:
277          *w2 = *(uint32_t*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4];
278          __RSP.PC[__RSP.PCi] += 8;
279 
280          *w3 = *(uint32_t*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4];
281          __RSP.PC[__RSP.PCi] += 8;
282          break;
283       case gdpTexRect:
284          *w2 = *(uint32_t*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 0];
285          *w3 = *(uint32_t*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4];
286          __RSP.PC[__RSP.PCi] += 8;
287          break;
288       case halfTexRect:
289          *w2 = 0;
290          *w3 = *(uint32_t*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4];
291          __RSP.PC[__RSP.PCi] += 8;
292          break;
293       default:
294 #if 0
295          assert(false && "Unknown texrect mode");
296 #endif
297 	break;
298    }
299 }
300 
RDP_TexRectFlip(uint32_t w0,uint32_t w1)301 void RDP_TexRectFlip( uint32_t w0, uint32_t w1 )
302 {
303    uint32_t ulx, uly, lrx, lry;
304 	uint32_t w2, w3;
305 	_getTexRectParams(&w2, &w3);
306 	ulx = _SHIFTR(w1, 12, 12);
307 	uly = _SHIFTR(w1, 0, 12);
308 	lrx = _SHIFTR(w0, 12, 12);
309 	lry = _SHIFTR(w0, 0, 12);
310 	if ((lrx >> 2) < (ulx >> 2) || (lry >> 2) < (uly >> 2))
311 		return;
312 
313 	gln64gDPTextureRectangleFlip(
314 		_FIXED2FLOAT(ulx, 2),
315 		_FIXED2FLOAT(uly, 2),
316 		_FIXED2FLOAT(lrx, 2),
317 		_FIXED2FLOAT(lry, 2),
318 		_SHIFTR(w1, 24, 3),							// tile
319 		_FIXED2FLOAT((int16_t)_SHIFTR(w2, 16, 16), 5),	// s
320 		_FIXED2FLOAT((int16_t)_SHIFTR(w2, 0, 16), 5),	// t
321 		_FIXED2FLOAT((int16_t)_SHIFTR(w3, 16, 16), 10),	// dsdx
322 		_FIXED2FLOAT((int16_t)_SHIFTR(w3, 0, 16), 10));	// dsdy
323 }
324 
RDP_TexRect(uint32_t w0,uint32_t w1)325 void RDP_TexRect( uint32_t w0, uint32_t w1 )
326 {
327    uint32_t ulx, uly, lrx, lry;
328 	uint32_t w2, w3;
329 	_getTexRectParams(&w2, &w3);
330 	ulx = _SHIFTR(w1, 12, 12);
331 	uly = _SHIFTR(w1,  0, 12);
332 	lrx = _SHIFTR(w0, 12, 12);
333 	lry = _SHIFTR(w0,  0, 12);
334 	if ((lrx >> 2) < (ulx >> 2) || (lry >> 2) < (uly >> 2))
335 		return;
336 
337 	gln64gDPTextureRectangle(
338 		_FIXED2FLOAT(ulx, 2),
339 		_FIXED2FLOAT(uly, 2),
340 		_FIXED2FLOAT(lrx, 2),
341 		_FIXED2FLOAT(lry, 2),
342 		_SHIFTR(w1, 24, 3),							// tile
343 		_FIXED2FLOAT((int16_t)_SHIFTR(w2, 16, 16), 5),	// s
344 		_FIXED2FLOAT((int16_t)_SHIFTR(w2, 0, 16), 5),	// t
345 		_FIXED2FLOAT((int16_t)_SHIFTR(w3, 16, 16), 10),	// dsdx
346 		_FIXED2FLOAT((int16_t)_SHIFTR(w3, 0, 16), 10));	// dsdy
347 }
348 
349 
350 //Low Level RDP Drawing Commands:
RDP_TriFill(uint32_t _w0,uint32_t _w1)351 void RDP_TriFill(uint32_t _w0, uint32_t _w1)
352 {
353 	gln64gDPTriFill(_w0, _w1);
354 }
355 
RDP_TriTxtr(uint32_t _w0,uint32_t _w1)356 void RDP_TriTxtr(uint32_t _w0, uint32_t _w1)
357 {
358 	gln64gDPTriTxtr(_w0, _w1);
359 }
360 
RDP_TriTxtrZBuff(uint32_t w0,uint32_t w1)361 void RDP_TriTxtrZBuff(uint32_t w0, uint32_t w1)
362 {
363     LOG(LOG_VERBOSE, "RSP_TRI_TXTR_ZBUFF Command\n");
364 }
365 
RDP_TriShade(uint32_t _w0,uint32_t _w1)366 void RDP_TriShade(uint32_t _w0, uint32_t _w1)
367 {
368 	gln64gDPTriShadeZ(_w0, _w1);
369 }
370 
RDP_TriShadeZBuff(uint32_t w0,uint32_t w1)371 void RDP_TriShadeZBuff(uint32_t w0, uint32_t w1)
372 {
373     LOG(LOG_VERBOSE, "RSP_TRI_SHADE_ZBUFF Command\n");
374 }
375 
RDP_TriShadeTxtr(uint32_t _w0,uint32_t _w1)376 void RDP_TriShadeTxtr(uint32_t _w0, uint32_t _w1)
377 {
378 	gln64gDPTriShadeTxtr(_w0, _w1);
379 }
380 
RDP_TriFillZ(uint32_t _w0,uint32_t _w1)381 void RDP_TriFillZ( uint32_t _w0, uint32_t _w1 )
382 {
383 	gln64gDPTriFillZ(_w0, _w1);
384 }
385 
RDP_TriShadeTxtrZBuff(uint32_t _w0,uint32_t _w1)386 void RDP_TriShadeTxtrZBuff(uint32_t _w0, uint32_t _w1)
387 {
388 	gln64gDPTriShadeTxtrZ(_w0, _w1);
389 }
390 
RDP_TriShadeZ(uint32_t _w0,uint32_t _w1)391 void RDP_TriShadeZ( uint32_t _w0, uint32_t _w1 )
392 {
393 	gln64gDPTriShadeZ(_w0, _w1);
394 }
395 
RDP_TriTxtrZ(uint32_t _w0,uint32_t _w1)396 void RDP_TriTxtrZ( uint32_t _w0, uint32_t _w1 )
397 {
398 	gln64gDPTriTxtrZ(_w0, _w1);
399 }
400 
RDP_TriShadeTxtrZ(uint32_t _w0,uint32_t _w1)401 void RDP_TriShadeTxtrZ( uint32_t _w0, uint32_t _w1 )
402 {
403 	gln64gDPTriShadeTxtrZ(_w0, _w1);
404 }
405 
RDP_Init(void)406 void RDP_Init(void)
407 {
408    int i;
409    // Initialize RDP commands to RDP_UNKNOWN
410    for (i = 0xC8; i <= 0xCF; i++)
411       GBI.cmd[i] = RDP_Unknown;
412 
413    // Initialize RDP commands to RDP_UNKNOWN
414    for (i = 0xE4; i <= 0xFF; i++)
415       GBI.cmd[i] = RDP_Unknown;
416 
417    // Set known GBI commands
418    GBI.cmd[G_NOOP]             = RDP_NoOp;
419    GBI.cmd[G_SETCIMG]          = RDP_SetCImg;
420    GBI.cmd[G_SETZIMG]          = RDP_SetZImg;
421    GBI.cmd[G_SETTIMG]          = RDP_SetTImg;
422    GBI.cmd[G_SETCOMBINE]       = RDP_SetCombine;
423    GBI.cmd[G_SETENVCOLOR]      = RDP_SetEnvColor;
424    GBI.cmd[G_SETPRIMCOLOR]     = RDP_SetPrimColor;
425    GBI.cmd[G_SETBLENDCOLOR]    = RDP_SetBlendColor;
426    GBI.cmd[G_SETFOGCOLOR]      = RDP_SetFogColor;
427    GBI.cmd[G_SETFILLCOLOR]     = RDP_SetFillColor;
428    GBI.cmd[G_FILLRECT]         = RDP_FillRect;
429    GBI.cmd[G_SETTILE]          = RDP_SetTile;
430    GBI.cmd[G_LOADTILE]         = RDP_LoadTile;
431    GBI.cmd[G_LOADBLOCK]        = RDP_LoadBlock;
432    GBI.cmd[G_SETTILESIZE]      = RDP_SetTileSize;
433    GBI.cmd[G_LOADTLUT]         = RDP_LoadTLUT;
434    GBI.cmd[G_RDPSETOTHERMODE]  = RDP_SetOtherMode;
435    GBI.cmd[G_SETPRIMDEPTH]     = RDP_SetPrimDepth;
436    GBI.cmd[G_SETSCISSOR]       = RDP_SetScissor;
437    GBI.cmd[G_SETCONVERT]       = RDP_SetConvert;
438    GBI.cmd[G_SETKEYR]          = RDP_SetKeyR;
439    GBI.cmd[G_SETKEYGB]         = RDP_SetKeyGB;
440    GBI.cmd[G_RDPFULLSYNC]      = RDP_FullSync;
441    GBI.cmd[G_RDPTILESYNC]      = RDP_TileSync;
442    GBI.cmd[G_RDPPIPESYNC]      = RDP_PipeSync;
443    GBI.cmd[G_RDPLOADSYNC]      = RDP_LoadSync;
444    GBI.cmd[G_TEXRECTFLIP]      = RDP_TexRectFlip;
445    GBI.cmd[G_TEXRECT]          = RDP_TexRect;
446 
447    __RDP.w2 = __RDP.w3 = 0;
448    __RDP.cmd_ptr = __RDP.cmd_cur = 0;
449 }
450 
451 static
452 GBIFunc LLEcmd[64] = {
453 	/* 0x00 */
454 	RDP_NoOp,			RDP_Unknown,		RDP_Unknown,		RDP_Unknown,
455 	RDP_Unknown,		RDP_Unknown,		RDP_Unknown,		RDP_Unknown,
456 	RDP_TriFill,		RDP_TriFillZ,		RDP_TriTxtr,		RDP_TriTxtrZ,
457 	RDP_TriShade,		RDP_TriShadeZ,		RDP_TriShadeTxtr,	RDP_TriShadeTxtrZ,
458 	/* 0x10 */
459 	RDP_Unknown,		RDP_Unknown,		RDP_Unknown,		RDP_Unknown,
460 	RDP_Unknown,		RDP_Unknown,		RDP_Unknown,		RDP_Unknown,
461 	RDP_Unknown,		RDP_Unknown,		RDP_Unknown,		RDP_Unknown,
462 	RDP_Unknown,		RDP_Unknown,		RDP_Unknown,		RDP_Unknown,
463 	/* 0x20 */
464 	RDP_Unknown,		RDP_Unknown,		RDP_Unknown,		RDP_Unknown,
465 	RDP_TexRect,		RDP_TexRectFlip,	RDP_LoadSync,		RDP_PipeSync,
466 	RDP_TileSync,		RDP_FullSync,		RDP_SetKeyGB,		RDP_SetKeyR,
467 	RDP_SetConvert,		RDP_SetScissor,		RDP_SetPrimDepth,	RDP_SetOtherMode,
468 	/* 0x30 */
469 	RDP_LoadTLUT,		RDP_Unknown,		RDP_SetTileSize,	RDP_LoadBlock,
470 	RDP_LoadTile,		RDP_SetTile,		RDP_FillRect,		RDP_SetFillColor,
471 	RDP_SetFogColor,	RDP_SetBlendColor,	RDP_SetPrimColor,	RDP_SetEnvColor,
472 	RDP_SetCombine,		RDP_SetTImg,		RDP_SetZImg,		RDP_SetCImg
473 };
474 
475 static
476 const uint32_t CmdLength[64] =
477 {
478 	8,                      // 0x00, No Op
479 	8,                      // 0x01, ???
480 	8,                      // 0x02, ???
481 	8,                      // 0x03, ???
482 	8,                      // 0x04, ???
483 	8,                      // 0x05, ???
484 	8,                      // 0x06, ???
485 	8,                      // 0x07, ???
486 	32,                     // 0x08, Non-Shaded Triangle
487 	32+16,          // 0x09, Non-Shaded, Z-Buffered Triangle
488 	32+64,          // 0x0a, Textured Triangle
489 	32+64+16,       // 0x0b, Textured, Z-Buffered Triangle
490 	32+64,          // 0x0c, Shaded Triangle
491 	32+64+16,       // 0x0d, Shaded, Z-Buffered Triangle
492 	32+64+64,       // 0x0e, Shaded+Textured Triangle
493 	32+64+64+16,// 0x0f, Shaded+Textured, Z-Buffered Triangle
494 	8,                      // 0x10, ???
495 	8,                      // 0x11, ???
496 	8,                      // 0x12, ???
497 	8,                      // 0x13, ???
498 	8,                      // 0x14, ???
499 	8,                      // 0x15, ???
500 	8,                      // 0x16, ???
501 	8,                      // 0x17, ???
502 	8,                      // 0x18, ???
503 	8,                      // 0x19, ???
504 	8,                      // 0x1a, ???
505 	8,                      // 0x1b, ???
506 	8,                      // 0x1c, ???
507 	8,                      // 0x1d, ???
508 	8,                      // 0x1e, ???
509 	8,                      // 0x1f, ???
510 	8,                      // 0x20, ???
511 	8,                      // 0x21, ???
512 	8,                      // 0x22, ???
513 	8,                      // 0x23, ???
514 	16,                     // 0x24, Texture_Rectangle
515 	16,                     // 0x25, Texture_Rectangle_Flip
516 	8,                      // 0x26, Sync_Load
517 	8,                      // 0x27, Sync_Pipe
518 	8,                      // 0x28, Sync_Tile
519 	8,                      // 0x29, Sync_Full
520 	8,                      // 0x2a, Set_Key_GB
521 	8,                      // 0x2b, Set_Key_R
522 	8,                      // 0x2c, Set_Convert
523 	8,                      // 0x2d, Set_Scissor
524 	8,                      // 0x2e, Set_Prim_Depth
525 	8,                      // 0x2f, Set_Other_Modes
526 	8,                      // 0x30, Load_TLUT
527 	8,                      // 0x31, ???
528 	8,                      // 0x32, Set_Tile_Size
529 	8,                      // 0x33, Load_Block
530 	8,                      // 0x34, Load_Tile
531 	8,                      // 0x35, Set_Tile
532 	8,                      // 0x36, Fill_Rectangle
533 	8,                      // 0x37, Set_Fill_Color
534 	8,                      // 0x38, Set_Fog_Color
535 	8,                      // 0x39, Set_Blend_Color
536 	8,                      // 0x3a, Set_Prim_Color
537 	8,                      // 0x3b, Set_Env_Color
538 	8,                      // 0x3c, Set_Combine
539 	8,                      // 0x3d, Set_Texture_Image
540 	8,                      // 0x3e, Set_Mask_Image
541 	8                       // 0x3f, Set_Color_Image
542 };
543 
RDP_Half_1(uint32_t _c)544 void RDP_Half_1( uint32_t _c )
545 {
546    if (RDP_Half1(_c))
547       LLEcmd[__RSP.cmd](__RSP.w0, __RSP.w1);
548 }
549 
GLN64_READ_RDP_DATA(uint32_t address)550 static INLINE uint32_t GLN64_READ_RDP_DATA(uint32_t address)
551 {
552 	if ((*(uint32_t*)gfx_info.DPC_STATUS_REG) & 0x1)          // XBUS_DMEM_DMA enabled
553 		return gfx_info.DMEM[(address & 0xfff)>>2];
554    return gfx_info.RDRAM[address>>2];
555 }
556 
gln64ProcessRDPList(void)557 void gln64ProcessRDPList(void)
558 {
559    uint32_t i;
560    bool set_zero = true;
561    const uint32_t length = gfx_info.DPC_END_REG - gfx_info.DPC_CURRENT_REG;
562 
563    (*(uint32_t*)gfx_info.DPC_STATUS_REG) &= ~0x0002;
564 
565    if (gfx_info.DPC_END_REG <= gfx_info.DPC_CURRENT_REG)
566       return;
567 
568    __RSP.bLLE = true;
569 
570    /* load command data */
571    for (i = 0; i < length; i += 4)
572    {
573       __RDP.cmd_data[__RDP.cmd_ptr] = rdp_read_data(*gfx_info.DPC_CURRENT_REG + i);
574       __RDP.cmd_ptr = (__RDP.cmd_ptr + 1) & maxCMDMask;
575    }
576 
577    while (__RDP.cmd_cur != __RDP.cmd_ptr)
578    {
579       uint32_t w0, w1;
580       uint32_t cmd = (__RDP.cmd_data[__RDP.cmd_cur] >> 24) & 0x3f;
581 
582       if ((((__RDP.cmd_ptr - __RDP.cmd_cur)&maxCMDMask) * 4) < CmdLength[cmd])
583       {
584          set_zero = false;
585          break;
586       }
587 
588       if (__RDP.cmd_cur + CmdLength[cmd] / 4 > MAXCMD)
589          memcpy(__RDP.cmd_data + MAXCMD, __RDP.cmd_data, CmdLength[cmd] - (MAXCMD - __RDP.cmd_cur) * 4);
590 
591       // execute the command
592       w0 = __RDP.cmd_data[__RDP.cmd_cur+0];
593       w1 = __RDP.cmd_data[__RDP.cmd_cur+1];
594       __RDP.w2 = __RDP.cmd_data[__RDP.cmd_cur+2];
595       __RDP.w3 = __RDP.cmd_data[__RDP.cmd_cur + 3];
596       __RSP.cmd = cmd;
597       LLEcmd[cmd](w0, w1);
598 
599       __RDP.cmd_cur = (__RDP.cmd_cur + CmdLength[cmd] / 4) & maxCMDMask;
600    }
601 
602    if (set_zero)
603    {
604       __RDP.cmd_ptr = 0;
605       __RDP.cmd_cur = 0;
606    }
607 
608    __RSP.bLLE = false;
609    gSP.changed |= CHANGED_COLORBUFFER;
610 
611    gfx_info.DPC_START_REG = gfx_info.DPC_CURRENT_REG = gfx_info.DPC_END_REG;
612 }
613