cdrom: change pause timing again
[pcsx_rearmed.git] / plugins / dfxvideo / gpulib_if.c
CommitLineData
b094071f 1/***************************************************************************
2 copyright : (C) 2001 by Pete Bernert, 2011 notaz
3
4 ***************************************************************************/
5/***************************************************************************
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. See also the license.txt file for *
11 * additional informations. *
12 * *
13 ***************************************************************************/
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
62d7fa95 18#include "../gpulib/gpu.h"
0a371c2c 19#include "../../include/arm_features.h"
b094071f 20
415213c9 21#if defined(__GNUC__) && (__GNUC__ >= 6 || (defined(__clang_major__) && __clang_major__ >= 10))
22#pragma GCC diagnostic ignored "-Wmisleading-indentation"
23#endif
24
b094071f 25#define u32 uint32_t
26
27#define INFO_TW 0
28#define INFO_DRAWSTART 1
29#define INFO_DRAWEND 2
30#define INFO_DRAWOFF 3
31
32#define SHADETEXBIT(x) ((x>>24) & 0x1)
33#define SEMITRANSBIT(x) ((x>>25) & 0x1)
34#define PSXRGB(r,g,b) ((g<<10)|(b<<5)|r)
35
36#define DATAREGISTERMODES unsigned short
37
38#define DR_NORMAL 0
39#define DR_VRAMTRANSFER 1
40
41#define GPUSTATUS_READYFORVRAM 0x08000000
42
43// byteswappings
44
ae097dfb
PC
45#define SWAP16(x) __builtin_bswap16(x)
46#define SWAP32(x) __builtin_bswap32(x)
b094071f 47
04bd10b1 48#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
b094071f 49
50// big endian config
51#define HOST2LE32(x) SWAP32(x)
52#define HOST2BE32(x) (x)
53#define LE2HOST32(x) SWAP32(x)
54#define BE2HOST32(x) (x)
55
56#define HOST2LE16(x) SWAP16(x)
57#define HOST2BE16(x) (x)
58#define LE2HOST16(x) SWAP16(x)
59#define BE2HOST16(x) (x)
60
61#else
62
63// little endian config
64#define HOST2LE32(x) (x)
65#define HOST2BE32(x) SWAP32(x)
66#define LE2HOST32(x) (x)
67#define BE2HOST32(x) SWAP32(x)
68
69#define HOST2LE16(x) (x)
70#define HOST2BE16(x) SWAP16(x)
71#define LE2HOST16(x) (x)
72#define BE2HOST16(x) SWAP16(x)
73
74#endif
75
0a371c2c 76#define GETLEs16(X) ((int16_t)GETLE16((uint16_t *)(X)))
b094071f 77
0a371c2c 78#define GETLE16(X) LE2HOST16(*(uint16_t *)(X))
79#define GETLE32_(X) LE2HOST32(*(uint32_t *)(X))
80#define PUTLE16(X, Y) do{*((uint16_t *)(X))=HOST2LE16((uint16_t)(Y));}while(0)
81#define PUTLE32_(X, Y) do{*((uint32_t *)(X))=HOST2LE32((uint32_t)(Y));}while(0)
82#if defined(__arm__) && !defined(HAVE_ARMV6)
83// for (very) old ARMs with no unaligned loads?
84#define GETLE32(X) (*(uint16_t *)(X)|((uint32_t)((uint16_t *)(X))[1]<<16))
b094071f 85#define PUTLE32(X, Y) do{uint16_t *p_=(uint16_t *)(X);uint32_t y_=Y;p_[0]=y_;p_[1]=y_>>16;}while(0)
86#else
87#define GETLE32 GETLE32_
88#define PUTLE32 PUTLE32_
89#endif
90
91/////////////////////////////////////////////////////////////////////////////
92
93typedef struct VRAMLOADTTAG
94{
95 short x;
96 short y;
97 short Width;
98 short Height;
99 short RowsRemaining;
100 short ColsRemaining;
101 unsigned short *ImagePtr;
102} VRAMLoad_t;
103
104/////////////////////////////////////////////////////////////////////////////
105
106typedef struct PSXPOINTTAG
107{
108 int32_t x;
109 int32_t y;
110} PSXPoint_t;
111
112typedef struct PSXSPOINTTAG
113{
114 short x;
115 short y;
116} PSXSPoint_t;
117
118typedef struct PSXRECTTAG
119{
120 short x0;
121 short x1;
122 short y0;
123 short y1;
124} PSXRect_t;
125
126// linux defines for some windows stuff
127
128#define FALSE 0
129#define TRUE 1
130#define BOOL unsigned short
131#define LOWORD(l) ((unsigned short)(l))
132#define HIWORD(l) ((unsigned short)(((uint32_t)(l) >> 16) & 0xFFFF))
133#define max(a,b) (((a) > (b)) ? (a) : (b))
134#define min(a,b) (((a) < (b)) ? (a) : (b))
135#define DWORD uint32_t
136#ifndef __int64
137#define __int64 long long int
138#endif
139
140typedef struct RECTTAG
141{
142 int left;
143 int top;
144 int right;
145 int bottom;
146}RECT;
147
148/////////////////////////////////////////////////////////////////////////////
149
150typedef struct TWINTAG
151{
152 PSXRect_t Position;
153 int xmask, ymask;
154} TWin_t;
155
156/////////////////////////////////////////////////////////////////////////////
157
158typedef struct PSXDISPLAYTAG
159{
160 PSXPoint_t DisplayModeNew;
161 PSXPoint_t DisplayMode;
162 PSXPoint_t DisplayPosition;
163 PSXPoint_t DisplayEnd;
164
165 int32_t Double;
166 int32_t Height;
167 int32_t PAL;
168 int32_t InterlacedNew;
169 int32_t Interlaced;
170 int32_t RGB24New;
171 int32_t RGB24;
172 PSXSPoint_t DrawOffset;
173 int32_t Disabled;
174 PSXRect_t Range;
175
176} PSXDisplay_t;
177
178/////////////////////////////////////////////////////////////////////////////
179
180// draw.c
181
182extern int32_t GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;
183extern int32_t GlobalTextABR,GlobalTextPAGE;
184extern short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;
185extern long lLowerpart;
186extern BOOL bCheckMask;
187extern unsigned short sSetMask;
188extern unsigned long lSetMask;
189extern short g_m1;
190extern short g_m2;
191extern short g_m3;
192extern short DrawSemiTrans;
193
194// prim.c
195
196extern BOOL bUsingTWin;
197extern TWin_t TWin;
198extern void (*primTableJ[256])(unsigned char *);
199extern void (*primTableSkip[256])(unsigned char *);
200extern unsigned short usMirror;
201extern int iDither;
202extern uint32_t dwCfgFixes;
203extern uint32_t dwActFixes;
204extern int iUseFixes;
205extern int iUseDither;
206extern BOOL bDoVSyncUpdate;
207extern int32_t drawX;
208extern int32_t drawY;
209extern int32_t drawW;
210extern int32_t drawH;
211
212// gpu.h
213
214#define OPAQUEON 10
215#define OPAQUEOFF 11
216
217#define KEY_RESETTEXSTORE 1
218#define KEY_SHOWFPS 2
219#define KEY_RESETOPAQUE 4
220#define KEY_RESETDITHER 8
221#define KEY_RESETFILTER 16
222#define KEY_RESETADVBLEND 32
223#define KEY_BADTEXTURES 128
224#define KEY_CHECKTHISOUT 256
225
04bd10b1 226#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
b094071f 227#define RED(x) (x & 0xff)
228#define BLUE(x) ((x>>16) & 0xff)
229#define GREEN(x) ((x>>8) & 0xff)
230#define COLOR(x) (x & 0xffffff)
04bd10b1 231#else
b094071f 232#define RED(x) ((x>>24) & 0xff)
233#define BLUE(x) ((x>>8) & 0xff)
234#define GREEN(x) ((x>>16) & 0xff)
235#define COLOR(x) SWAP32(x & 0xffffff)
236#endif
237
238PSXDisplay_t PSXDisplay;
239unsigned char *psxVub;
b094071f 240unsigned short *psxVuw;
241unsigned short *psxVuw_eom;
b094071f 242
243long lGPUstatusRet;
244uint32_t lGPUInfoVals[16];
245
246VRAMLoad_t VRAMWrite;
247VRAMLoad_t VRAMRead;
248
249DATAREGISTERMODES DataWriteMode;
250DATAREGISTERMODES DataReadMode;
251
252BOOL bCheckMask = FALSE;
253unsigned short sSetMask = 0;
254unsigned long lSetMask = 0;
255long lLowerpart;
256
857275a9 257#if defined(__GNUC__) && __GNUC__ >= 6
258#pragma GCC diagnostic ignored "-Wmisleading-indentation"
259#endif
260
62d7fa95 261#include "soft.c"
262#include "prim.c"
b094071f 263
264/////////////////////////////////////////////////////////////////////////////
265
9ee0fd5b 266static void set_vram(void *vram)
b094071f 267{
9ee0fd5b 268 psxVub=vram;
b094071f 269 psxVuw=(unsigned short *)psxVub;
b094071f 270 psxVuw_eom=psxVuw+1024*512; // pre-calc of end of vram
9ee0fd5b 271}
272
273int renderer_init(void)
274{
275 set_vram(gpu.vram);
b094071f 276
277 PSXDisplay.RGB24 = FALSE; // init some stuff
278 PSXDisplay.Interlaced = FALSE;
279 PSXDisplay.DrawOffset.x = 0;
280 PSXDisplay.DrawOffset.y = 0;
281 PSXDisplay.DisplayMode.x= 320;
282 PSXDisplay.DisplayMode.y= 240;
283 PSXDisplay.Disabled = FALSE;
284 PSXDisplay.Range.x0=0;
285 PSXDisplay.Range.x1=0;
286 PSXDisplay.Double = 1;
287
288 DataWriteMode = DR_NORMAL;
289 lGPUstatusRet = 0x14802000;
290
291 return 0;
292}
293
e929dec5 294void renderer_finish(void)
295{
296}
297
298void renderer_notify_res_change(void)
299{
300}
301
2da2fc76 302void renderer_notify_scanout_change(int x, int y)
0b4038f8 303{
304}
305
90ac6fed 306#include "../gpulib/gpu_timing.h"
b094071f 307extern const unsigned char cmd_lengths[256];
308
8412166f 309int do_cmd_list(uint32_t *list, int list_len,
310 int *cycles_sum_out, int *cycles_last, int *last_cmd)
b094071f 311{
8412166f 312 int cpu_cycles_sum = 0, cpu_cycles = *cycles_last;
b243416b 313 unsigned int cmd = 0, len;
7a8d521f 314 uint32_t *list_start = list;
315 uint32_t *list_end = list + list_len;
b094071f 316
317 for (; list < list_end; list += 1 + len)
318 {
90ac6fed 319 short *slist = (void *)list;
ae097dfb 320 cmd = GETLE32(list) >> 24;
b094071f 321 len = cmd_lengths[cmd];
b243416b 322 if (list + 1 + len > list_end) {
323 cmd = -1;
324 break;
325 }
326
327#ifndef TEST
72583812 328 if (0x80 <= cmd && cmd < 0xe0)
b243416b 329 break; // image i/o, forward to upper layer
330 else if ((cmd & 0xf8) == 0xe0)
ae097dfb 331 gpu.ex_regs[cmd & 7] = GETLE32(list);
b243416b 332#endif
b094071f 333
334 primTableJ[cmd]((void *)list);
335
336 switch(cmd)
337 {
338 case 0x48 ... 0x4F:
339 {
b243416b 340 u32 num_vertexes = 2;
341 u32 *list_position = &(list[3]);
b094071f 342
343 while(1)
344 {
8412166f 345 gput_sum(cpu_cycles_sum, cpu_cycles, gput_line(0));
90ac6fed 346
804789d7 347 if(list_position >= list_end) {
348 cmd = -1;
349 goto breakloop;
350 }
351
ae097dfb 352 if((*list_position & HOST2LE32(0xf000f000)) == HOST2LE32(0x50005000))
b094071f 353 break;
354
355 list_position++;
356 num_vertexes++;
357 }
358
b243416b 359 len += (num_vertexes - 2);
b094071f 360 break;
361 }
362
363 case 0x58 ... 0x5F:
364 {
b243416b 365 u32 num_vertexes = 2;
366 u32 *list_position = &(list[4]);
b094071f 367
368 while(1)
369 {
8412166f 370 gput_sum(cpu_cycles_sum, cpu_cycles, gput_line(0));
90ac6fed 371
804789d7 372 if(list_position >= list_end) {
373 cmd = -1;
374 goto breakloop;
375 }
376
ae097dfb 377 if((*list_position & HOST2LE32(0xf000f000)) == HOST2LE32(0x50005000))
b094071f 378 break;
379
380 list_position += 2;
381 num_vertexes++;
382 }
383
b243416b 384 len += (num_vertexes - 2) * 2;
b094071f 385 break;
386 }
387
9a6e7816 388#ifdef TEST
b094071f 389 case 0xA0: // sys -> vid
390 {
8412166f 391 u32 load_width = LE2HOST16(slist[4]);
392 u32 load_height = LE2HOST16(slist[5]);
b094071f 393 u32 load_size = load_width * load_height;
394
395 len += load_size / 2;
396 break;
397 }
9a6e7816 398#endif
90ac6fed 399
400 // timing
401 case 0x02:
8412166f 402 gput_sum(cpu_cycles_sum, cpu_cycles,
403 gput_fill(LE2HOST16(slist[4]) & 0x3ff, LE2HOST16(slist[5]) & 0x1ff));
90ac6fed 404 break;
8412166f 405 case 0x20 ... 0x23: gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base()); break;
406 case 0x24 ... 0x27: gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_t()); break;
407 case 0x28 ... 0x2B: gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base()); break;
408 case 0x2C ... 0x2F: gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_t()); break;
409 case 0x30 ... 0x33: gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_g()); break;
410 case 0x34 ... 0x37: gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_gt()); break;
411 case 0x38 ... 0x3B: gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_g()); break;
412 case 0x3C ... 0x3F: gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_gt()); break;
413 case 0x40 ... 0x47: gput_sum(cpu_cycles_sum, cpu_cycles, gput_line(0)); break;
414 case 0x50 ... 0x57: gput_sum(cpu_cycles_sum, cpu_cycles, gput_line(0)); break;
90ac6fed 415 case 0x60 ... 0x63:
8412166f 416 gput_sum(cpu_cycles_sum, cpu_cycles,
417 gput_sprite(LE2HOST16(slist[4]) & 0x3ff, LE2HOST16(slist[5]) & 0x1ff));
90ac6fed 418 break;
419 case 0x64 ... 0x67:
8412166f 420 gput_sum(cpu_cycles_sum, cpu_cycles,
421 gput_sprite(LE2HOST16(slist[6]) & 0x3ff, LE2HOST16(slist[7]) & 0x1ff));
90ac6fed 422 break;
8412166f 423 case 0x68 ... 0x6B: gput_sum(cpu_cycles_sum, cpu_cycles, gput_sprite(1, 1)); break;
90ac6fed 424 case 0x70 ... 0x73:
8412166f 425 case 0x74 ... 0x77: gput_sum(cpu_cycles_sum, cpu_cycles, gput_sprite(8, 8)); break;
90ac6fed 426 case 0x78 ... 0x7B:
8412166f 427 case 0x7C ... 0x7F: gput_sum(cpu_cycles_sum, cpu_cycles, gput_sprite(16, 16)); break;
b094071f 428 }
429 }
b243416b 430
804789d7 431breakloop:
b243416b 432 gpu.ex_regs[1] &= ~0x1ff;
433 gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff;
434
8412166f 435 *cycles_sum_out += cpu_cycles_sum;
436 *cycles_last = cpu_cycles;
b243416b 437 *last_cmd = cmd;
438 return list - list_start;
b094071f 439}
440
4ad17db3 441void renderer_sync_ecmds(uint32_t *ecmds_)
5b745e5b 442{
4ad17db3 443#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
444 // the funcs below expect LE
445 uint32_t i, ecmds[8];
446 for (i = 1; i <= 6; i++)
447 ecmds[i] = HTOLE32(ecmds_[i]);
448#else
449 uint32_t *ecmds = ecmds_;
450#endif
5b745e5b 451 cmdTexturePage((unsigned char *)&ecmds[1]);
452 cmdTextureWindow((unsigned char *)&ecmds[2]);
453 cmdDrawAreaStart((unsigned char *)&ecmds[3]);
454 cmdDrawAreaEnd((unsigned char *)&ecmds[4]);
455 cmdDrawOffset((unsigned char *)&ecmds[5]);
456 cmdSTP((unsigned char *)&ecmds[6]);
457}
458
0b4038f8 459void renderer_update_caches(int x, int y, int w, int h, int state_changed)
b094071f 460{
461}
462
463void renderer_flush_queues(void)
464{
465}
914455e6 466
5440b88e 467void renderer_set_interlace(int enable, int is_odd)
468{
469}
470
914455e6 471#include "../../frontend/plugin_lib.h"
472
473void renderer_set_config(const struct rearmed_cbs *cbs)
474{
475 iUseDither = cbs->gpu_peops.iUseDither;
476 dwActFixes = cbs->gpu_peops.dwActFixes;
fa56d360 477 if (cbs->pl_set_gpu_caps)
478 cbs->pl_set_gpu_caps(0);
9ee0fd5b 479 set_vram(gpu.vram);
914455e6 480}
90ac6fed 481
482// vim:ts=2:shiftwidth=2:expandtab