gpu: rework dma vs busy timing
[pcsx_rearmed.git] / plugins / gpu_unai_old / gpulib_if.cpp
CommitLineData
6f2ee2be 1/***************************************************************************
2* Copyright (C) 2010 PCSX4ALL Team *
3* Copyright (C) 2010 Unai *
4* Copyright (C) 2011 notaz *
5* *
6* This program is free software; you can redistribute it and/or modify *
7* it under the terms of the GNU General Public License as published by *
8* the Free Software Foundation; either version 2 of the License, or *
9* (at your option) any later version. *
10* *
11* This program is distributed in the hope that it will be useful, *
12* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14* GNU General Public License for more details. *
15* *
16* You should have received a copy of the GNU General Public License *
17* along with this program; if not, write to the *
18* Free Software Foundation, Inc., *
19* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
20***************************************************************************/
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
62d7fa95 25#include "../gpulib/gpu.h"
8f2bb0cb 26#include "arm_features.h"
6f2ee2be 27
28#define u8 uint8_t
29#define s8 int8_t
30#define u16 uint16_t
31#define s16 int16_t
32#define u32 uint32_t
33#define s32 int32_t
34#define s64 int64_t
35
8aea5f5a 36#define INLINE static
6f2ee2be 37
38#define FRAME_BUFFER_SIZE (1024*512*2)
39#define FRAME_WIDTH 1024
40#define FRAME_HEIGHT 512
41#define FRAME_OFFSET(x,y) (((y)<<10)+(x))
42
89c0de42 43#define isSkip 0 /* skip frame (info coming from GPU) */
6f2ee2be 44#define alt_fps 0
89c0de42 45static int linesInterlace; /* internal lines interlace */
46static int force_interlace;
6f2ee2be 47
48static bool light = true; /* lighting */
49static bool blend = true; /* blending */
50static bool FrameToRead = false; /* load image in progress */
51static bool FrameToWrite = false; /* store image in progress */
52
53static bool enableAbbeyHack = false; /* Abe's Odyssey hack */
54
55static u8 BLEND_MODE;
56static u8 TEXT_MODE;
57static u8 Masking;
58
59static u16 PixelMSB;
60static u16 PixelData;
61
62///////////////////////////////////////////////////////////////////////////////
63// GPU Global data
64///////////////////////////////////////////////////////////////////////////////
65
66// Dma Transfers info
67static s32 px,py;
68static s32 x_end,y_end;
69static u16* pvram;
70
71static s32 PacketCount;
72static s32 PacketIndex;
73
74// Rasterizer status
75static u32 TextureWindow [4];
76static u32 DrawingArea [4];
77static u32 DrawingOffset [2];
78
79static u16* TBA;
80static u16* CBA;
81
82// Inner Loops
83static s32 u4, du4;
84static s32 v4, dv4;
85static s32 r4, dr4;
86static s32 g4, dg4;
87static s32 b4, db4;
88static u32 lInc;
89static u32 tInc, tMsk;
90
91union GPUPacket
92{
8aea5f5a 93 u32 U4[16];
94 s32 S4[16];
95 u16 U2[32];
96 s16 S2[32];
97 u8 U1[64];
98 s8 S1[64];
6f2ee2be 99};
100
101static GPUPacket PacketBuffer;
102static u16 *GPU_FrameBuffer;
103static u32 GPU_GP1;
104
105///////////////////////////////////////////////////////////////////////////////
106
5a920d32 107#include "gpu_fixedpoint.h"
6f2ee2be 108
109// Inner loop driver instanciation file
5a920d32 110#include "gpu_inner.h"
6f2ee2be 111
112// GPU Raster Macros
113#define GPU_RGB16(rgb) ((((rgb)&0xF80000)>>9)|(((rgb)&0xF800)>>6)|(((rgb)&0xF8)>>3))
114
9ed4ca47 115#define GPU_EXPANDSIGN(x) (((s32)(x)<<21)>>21)
6f2ee2be 116
9ed4ca47 117#define CHKMAX_X 1024
118#define CHKMAX_Y 512
6f2ee2be 119
120#define GPU_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
121
122// GPU internal image drawing functions
5a920d32 123#include "gpu_raster_image.h"
6f2ee2be 124
125// GPU internal line drawing functions
5a920d32 126#include "gpu_raster_line.h"
6f2ee2be 127
128// GPU internal polygon drawing functions
5a920d32 129#include "gpu_raster_polygon.h"
6f2ee2be 130
131// GPU internal sprite drawing functions
5a920d32 132#include "gpu_raster_sprite.h"
6f2ee2be 133
134// GPU command buffer execution/store
5a920d32 135#include "gpu_command.h"
6f2ee2be 136
6f2ee2be 137/////////////////////////////////////////////////////////////////////////////
138
139int renderer_init(void)
140{
141 GPU_FrameBuffer = (u16 *)gpu.vram;
142
143 // s_invTable
144 for(int i=1;i<=(1<<TABLE_BITS);++i)
145 {
146 double v = 1.0 / double(i);
147 #ifdef GPU_TABLE_10_BITS
148 v *= double(0xffffffff>>1);
149 #else
150 v *= double(0x80000000);
151 #endif
152 s_invTable[i-1]=s32(v);
153 }
154
155 return 0;
156}
157
e929dec5 158void renderer_finish(void)
159{
160}
161
162void renderer_notify_res_change(void)
163{
164}
165
2da2fc76 166void renderer_notify_scanout_change(int x, int y)
0b4038f8 167{
168}
169
6f2ee2be 170extern const unsigned char cmd_lengths[256];
171
8412166f 172int do_cmd_list(uint32_t *list, int list_len,
173 int *cycles_sum_out, int *cycles_last, int *last_cmd)
6f2ee2be 174{
42a261f1 175 unsigned int cmd = 0, len, i;
b243416b 176 unsigned int *list_start = list;
6f2ee2be 177 unsigned int *list_end = list + list_len;
178
89c0de42 179 linesInterlace = force_interlace;
8f2bb0cb 180#ifdef HAVE_PRE_ARMV7 /* XXX */
3499746e 181 linesInterlace |= !!(gpu.status & PSX_GPU_STATUS_INTERLACE);
89c0de42 182#endif
183
6f2ee2be 184 for (; list < list_end; list += 1 + len)
185 {
6f2ee2be 186 cmd = *list >> 24;
187 len = cmd_lengths[cmd];
b243416b 188 if (list + 1 + len > list_end) {
189 cmd = -1;
190 break;
191 }
192
42a261f1 193 #define PRIM cmd
194 PacketBuffer.U4[0] = list[0];
195 for (i = 1; i <= len; i++)
196 PacketBuffer.U4[i] = list[i];
6f2ee2be 197
42a261f1 198 switch (cmd)
6f2ee2be 199 {
42a261f1 200 case 0x02:
201 gpuClearImage();
202 break;
203
204 case 0x20:
205 case 0x21:
206 case 0x22:
207 case 0x23:
208 gpuDrawF3(gpuPolySpanDrivers [Blending_Mode | Masking | Blending | PixelMSB]);
209 break;
210
211 case 0x24:
212 case 0x25:
213 case 0x26:
214 case 0x27:
215 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
216 gpuSetTexture(PacketBuffer.U4[4] >> 16);
217 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
218 gpuDrawFT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | PixelMSB]);
219 else
220 gpuDrawFT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | PixelMSB]);
221 break;
222
223 case 0x28:
224 case 0x29:
225 case 0x2A:
226 case 0x2B: {
227 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | Masking | Blending | PixelMSB];
228 gpuDrawF3(gpuPolySpanDriver);
229 PacketBuffer.U4[1] = PacketBuffer.U4[4];
230 gpuDrawF3(gpuPolySpanDriver);
231 break;
232 }
233
234 case 0x2C:
235 case 0x2D:
236 case 0x2E:
237 case 0x2F: {
238 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
239 gpuSetTexture(PacketBuffer.U4[4] >> 16);
240 PP gpuPolySpanDriver;
241 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
242 gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | PixelMSB];
243 else
244 gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | PixelMSB];
245 gpuDrawFT3(gpuPolySpanDriver);
246 PacketBuffer.U4[1] = PacketBuffer.U4[7];
247 PacketBuffer.U4[2] = PacketBuffer.U4[8];
248 gpuDrawFT3(gpuPolySpanDriver);
249 break;
250 }
251
252 case 0x30:
253 case 0x31:
254 case 0x32:
255 case 0x33:
256 gpuDrawG3(gpuPolySpanDrivers [Blending_Mode | Masking | Blending | 129 | PixelMSB]);
257 break;
258
259 case 0x34:
260 case 0x35:
261 case 0x36:
262 case 0x37:
263 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
264 gpuSetTexture (PacketBuffer.U4[5] >> 16);
265 gpuDrawGT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | ((Lighting)?129:0) | PixelMSB]);
266 break;
267
268 case 0x38:
269 case 0x39:
270 case 0x3A:
271 case 0x3B: {
272 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | Masking | Blending | 129 | PixelMSB];
273 gpuDrawG3(gpuPolySpanDriver);
274 PacketBuffer.U4[0] = PacketBuffer.U4[6];
275 PacketBuffer.U4[1] = PacketBuffer.U4[7];
276 gpuDrawG3(gpuPolySpanDriver);
277 break;
278 }
279
280 case 0x3C:
281 case 0x3D:
282 case 0x3E:
283 case 0x3F: {
284 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
285 gpuSetTexture (PacketBuffer.U4[5] >> 16);
286 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | ((Lighting)?129:0) | PixelMSB];
287 gpuDrawGT3(gpuPolySpanDriver);
288 PacketBuffer.U4[0] = PacketBuffer.U4[9];
289 PacketBuffer.U4[1] = PacketBuffer.U4[10];
290 PacketBuffer.U4[2] = PacketBuffer.U4[11];
291 gpuDrawGT3(gpuPolySpanDriver);
292 break;
293 }
294
295 case 0x40:
296 case 0x41:
297 case 0x42:
298 case 0x43:
299 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
300 break;
301
6f2ee2be 302 case 0x48 ... 0x4F:
303 {
304 u32 num_vertexes = 1;
305 u32 *list_position = &(list[2]);
8aea5f5a 306
8aea5f5a 307 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
6f2ee2be 308
309 while(1)
310 {
8aea5f5a 311 PacketBuffer.U4[1] = PacketBuffer.U4[2];
312 PacketBuffer.U4[2] = *list_position++;
313 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
314
6f2ee2be 315 num_vertexes++;
804789d7 316 if(list_position >= list_end) {
317 cmd = -1;
318 goto breakloop;
319 }
320 if((*list_position & 0xf000f000) == 0x50005000)
b243416b 321 break;
6f2ee2be 322 }
323
b243416b 324 len += (num_vertexes - 2);
6f2ee2be 325 break;
326 }
327
42a261f1 328 case 0x50:
329 case 0x51:
330 case 0x52:
331 case 0x53:
332 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
333 break;
334
6f2ee2be 335 case 0x58 ... 0x5F:
336 {
337 u32 num_vertexes = 1;
338 u32 *list_position = &(list[2]);
8aea5f5a 339
8aea5f5a 340 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
6f2ee2be 341
342 while(1)
343 {
8aea5f5a 344 PacketBuffer.U4[0] = PacketBuffer.U4[2];
345 PacketBuffer.U4[1] = PacketBuffer.U4[3];
346 PacketBuffer.U4[2] = *list_position++;
347 PacketBuffer.U4[3] = *list_position++;
348 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
349
6f2ee2be 350 num_vertexes++;
804789d7 351 if(list_position >= list_end) {
352 cmd = -1;
353 goto breakloop;
354 }
355 if((*list_position & 0xf000f000) == 0x50005000)
b243416b 356 break;
6f2ee2be 357 }
358
b243416b 359 len += (num_vertexes - 2) * 2;
6f2ee2be 360 break;
361 }
362
42a261f1 363 case 0x60:
364 case 0x61:
365 case 0x62:
366 case 0x63:
367 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
368 break;
369
370 case 0x64:
371 case 0x65:
372 case 0x66:
373 case 0x67:
374 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
375 gpuSetTexture (GPU_GP1);
376 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
377 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
378 else
379 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
380 break;
381
382 case 0x68:
383 case 0x69:
384 case 0x6A:
385 case 0x6B:
386 PacketBuffer.U4[2] = 0x00010001;
387 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
388 break;
389
390 case 0x70:
391 case 0x71:
392 case 0x72:
393 case 0x73:
394 PacketBuffer.U4[2] = 0x00080008;
395 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
396 break;
397
398 case 0x74:
399 case 0x75:
400 case 0x76:
401 case 0x77:
402 PacketBuffer.U4[3] = 0x00080008;
403 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
404 gpuSetTexture (GPU_GP1);
405 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
406 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
407 else
408 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
409 break;
410
411 case 0x78:
412 case 0x79:
413 case 0x7A:
414 case 0x7B:
415 PacketBuffer.U4[2] = 0x00100010;
416 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
417 break;
418
419 case 0x7C:
420 case 0x7D:
421#ifdef __arm__
422 if ((GPU_GP1 & 0x180) == 0 && (Masking | PixelMSB) == 0)
423 {
424 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
425 gpuSetTexture (GPU_GP1);
426 gpuDrawS16();
427 break;
428 }
429 // fallthrough
430#endif
431 case 0x7E:
432 case 0x7F:
433 PacketBuffer.U4[3] = 0x00100010;
434 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
435 gpuSetTexture (GPU_GP1);
436 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
437 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
438 else
439 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
440 break;
441
72583812 442#ifdef TEST
42a261f1 443 case 0x80: // vid -> vid
444 gpuMoveImage(); // prim handles updateLace && skip
445 break;
9a6e7816 446 case 0xA0: // sys -> vid
447 {
448 u32 load_width = list[2] & 0xffff;
449 u32 load_height = list[2] >> 16;
450 u32 load_size = load_width * load_height;
451
452 len += load_size / 2;
453 break;
454 }
42a261f1 455 case 0xC0:
456 break;
457#else
72583812 458 case 0x80 ... 0x9F: // vid -> vid
459 case 0xA0 ... 0xBF: // sys -> vid
460 case 0xC0 ... 0xDF: // vid -> sys
461 // Handled by gpulib
42a261f1 462 goto breakloop;
9a6e7816 463#endif
42a261f1 464 case 0xE1: {
465 const u32 temp = PacketBuffer.U4[0];
466 GPU_GP1 = (GPU_GP1 & ~0x000007FF) | (temp & 0x000007FF);
467 gpuSetTexture(temp);
468 gpu.ex_regs[1] = temp;
469 break;
470 }
471 case 0xE2: {
472 static const u8 TextureMask[32] = {
473 255, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7,
474 127, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7
475 };
476 const u32 temp = PacketBuffer.U4[0];
477 TextureWindow[0] = ((temp >> 10) & 0x1F) << 3;
478 TextureWindow[1] = ((temp >> 15) & 0x1F) << 3;
479 TextureWindow[2] = TextureMask[(temp >> 0) & 0x1F];
480 TextureWindow[3] = TextureMask[(temp >> 5) & 0x1F];
481 gpuSetTexture(GPU_GP1);
482 gpu.ex_regs[2] = temp;
483 break;
484 }
485 case 0xE3: {
486 const u32 temp = PacketBuffer.U4[0];
487 DrawingArea[0] = temp & 0x3FF;
488 DrawingArea[1] = (temp >> 10) & 0x3FF;
489 gpu.ex_regs[3] = temp;
6f2ee2be 490 break;
42a261f1 491 }
492 case 0xE4: {
493 const u32 temp = PacketBuffer.U4[0];
494 DrawingArea[2] = (temp & 0x3FF) + 1;
495 DrawingArea[3] = ((temp >> 10) & 0x3FF) + 1;
496 gpu.ex_regs[4] = temp;
497 break;
498 }
499 case 0xE5: {
500 const u32 temp = PacketBuffer.U4[0];
4144e9ab 501 DrawingOffset[0] = ((s32)temp<<(32-11))>>(32-11);
502 DrawingOffset[1] = ((s32)temp<<(32-22))>>(32-11);
42a261f1 503 gpu.ex_regs[5] = temp;
504 break;
505 }
506 case 0xE6: {
507 const u32 temp = PacketBuffer.U4[0];
508 Masking = (temp & 0x2) << 1;
509 PixelMSB =(temp & 0x1) << 8;
510 gpu.ex_regs[6] = temp;
511 break;
512 }
6f2ee2be 513 }
514 }
b243416b 515
42a261f1 516breakloop:
b243416b 517 gpu.ex_regs[1] &= ~0x1ff;
518 gpu.ex_regs[1] |= GPU_GP1 & 0x1ff;
519
520 *last_cmd = cmd;
521 return list - list_start;
6f2ee2be 522}
523
524void renderer_sync_ecmds(uint32_t *ecmds)
525{
42a261f1 526 int dummy;
8412166f 527 do_cmd_list(&ecmds[1], 6, &dummy, &dummy, &dummy);
6f2ee2be 528}
529
0b4038f8 530void renderer_update_caches(int x, int y, int w, int h, int state_changed)
6f2ee2be 531{
532}
533
534void renderer_flush_queues(void)
535{
536}
914455e6 537
5440b88e 538void renderer_set_interlace(int enable, int is_odd)
539{
540}
541
9a6e7816 542#ifndef TEST
543
914455e6 544#include "../../frontend/plugin_lib.h"
545
546void renderer_set_config(const struct rearmed_cbs *cbs)
547{
5a920d32 548 force_interlace = cbs->gpu_unai_old.lineskip;
549 enableAbbeyHack = cbs->gpu_unai_old.abe_hack;
550 light = !cbs->gpu_unai_old.no_light;
551 blend = !cbs->gpu_unai_old.no_blend;
9ee0fd5b 552
553 GPU_FrameBuffer = (u16 *)gpu.vram;
914455e6 554}
9a6e7816 555
556#endif
42a261f1 557
558// vim:shiftwidth=2:expandtab