1 /***************************************************************************
2 copyright : (C) 2001 by Pete Bernert, 2011 notaz
4 ***************************************************************************/
5 /***************************************************************************
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. *
13 ***************************************************************************/
18 #include "../gpulib/gpu.h"
19 #include "../../include/arm_features.h"
21 #if defined(__GNUC__) && (__GNUC__ >= 6 || (defined(__clang_major__) && __clang_major__ >= 10))
22 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
28 #define INFO_DRAWSTART 1
29 #define INFO_DRAWEND 2
30 #define INFO_DRAWOFF 3
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)
36 #define DATAREGISTERMODES unsigned short
39 #define DR_VRAMTRANSFER 1
41 #define GPUSTATUS_READYFORVRAM 0x08000000
45 #define SWAP16(x) __builtin_bswap16(x)
46 #define SWAP32(x) __builtin_bswap32(x)
48 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
51 #define HOST2LE32(x) SWAP32(x)
52 #define HOST2BE32(x) (x)
53 #define LE2HOST32(x) SWAP32(x)
54 #define BE2HOST32(x) (x)
56 #define HOST2LE16(x) SWAP16(x)
57 #define HOST2BE16(x) (x)
58 #define LE2HOST16(x) SWAP16(x)
59 #define BE2HOST16(x) (x)
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)
69 #define HOST2LE16(x) (x)
70 #define HOST2BE16(x) SWAP16(x)
71 #define LE2HOST16(x) (x)
72 #define BE2HOST16(x) SWAP16(x)
76 #define GETLEs16(X) ((int16_t)GETLE16((uint16_t *)(X)))
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))
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)
87 #define GETLE32 GETLE32_
88 #define PUTLE32 PUTLE32_
91 /////////////////////////////////////////////////////////////////////////////
93 typedef struct VRAMLOADTTAG
101 unsigned short *ImagePtr;
104 /////////////////////////////////////////////////////////////////////////////
106 typedef struct PSXPOINTTAG
112 typedef struct PSXSPOINTTAG
118 typedef struct PSXRECTTAG
126 // linux defines for some windows stuff
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
137 #define __int64 long long int
140 typedef struct RECTTAG
148 /////////////////////////////////////////////////////////////////////////////
150 typedef struct TWINTAG
156 /////////////////////////////////////////////////////////////////////////////
158 typedef struct PSXDISPLAYTAG
160 PSXPoint_t DisplayModeNew;
161 PSXPoint_t DisplayMode;
162 PSXPoint_t DisplayPosition;
163 PSXPoint_t DisplayEnd;
168 int32_t InterlacedNew;
172 PSXSPoint_t DrawOffset;
178 /////////////////////////////////////////////////////////////////////////////
182 extern int32_t GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;
183 extern int32_t GlobalTextABR,GlobalTextPAGE;
184 extern short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;
185 extern long lLowerpart;
186 extern BOOL bCheckMask;
187 extern unsigned short sSetMask;
188 extern unsigned long lSetMask;
192 extern short DrawSemiTrans;
196 extern BOOL bUsingTWin;
198 extern void (*primTableJ[256])(unsigned char *);
199 extern void (*primTableSkip[256])(unsigned char *);
200 extern unsigned short usMirror;
202 extern uint32_t dwCfgFixes;
203 extern uint32_t dwActFixes;
204 extern int iUseFixes;
205 extern int iUseDither;
206 extern BOOL bDoVSyncUpdate;
207 extern int32_t drawX;
208 extern int32_t drawY;
209 extern int32_t drawW;
210 extern int32_t drawH;
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
226 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
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)
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)
238 PSXDisplay_t PSXDisplay;
239 unsigned char *psxVub;
240 unsigned short *psxVuw;
241 unsigned short *psxVuw_eom;
244 uint32_t lGPUInfoVals[16];
246 VRAMLoad_t VRAMWrite;
249 DATAREGISTERMODES DataWriteMode;
250 DATAREGISTERMODES DataReadMode;
252 BOOL bCheckMask = FALSE;
253 unsigned short sSetMask = 0;
254 unsigned long lSetMask = 0;
257 #if defined(__GNUC__) && __GNUC__ >= 6
258 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
264 /////////////////////////////////////////////////////////////////////////////
266 static void set_vram(void *vram)
269 psxVuw=(unsigned short *)psxVub;
270 psxVuw_eom=psxVuw+1024*512; // pre-calc of end of vram
273 int renderer_init(void)
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;
288 DataWriteMode = DR_NORMAL;
289 lGPUstatusRet = 0x14802000;
294 void renderer_finish(void)
298 void renderer_notify_res_change(void)
302 extern const unsigned char cmd_lengths[256];
304 int do_cmd_list(uint32_t *list, int list_len, int *last_cmd)
306 unsigned int cmd = 0, len;
307 uint32_t *list_start = list;
308 uint32_t *list_end = list + list_len;
310 for (; list < list_end; list += 1 + len)
312 cmd = GETLE32(list) >> 24;
313 len = cmd_lengths[cmd];
314 if (list + 1 + len > list_end) {
320 if (cmd == 0xa0 || cmd == 0xc0)
321 break; // image i/o, forward to upper layer
322 else if ((cmd & 0xf8) == 0xe0)
323 gpu.ex_regs[cmd & 7] = GETLE32(list);
326 primTableJ[cmd]((void *)list);
332 u32 num_vertexes = 2;
333 u32 *list_position = &(list[3]);
337 if(list_position >= list_end) {
342 if((*list_position & HOST2LE32(0xf000f000)) == HOST2LE32(0x50005000))
349 len += (num_vertexes - 2);
355 u32 num_vertexes = 2;
356 u32 *list_position = &(list[4]);
360 if(list_position >= list_end) {
365 if((*list_position & HOST2LE32(0xf000f000)) == HOST2LE32(0x50005000))
372 len += (num_vertexes - 2) * 2;
377 case 0xA0: // sys -> vid
379 short *slist = (void *)list;
380 u32 load_width = LE2HOST32(slist[4]);
381 u32 load_height = LE2HOST32(slist[5]);
382 u32 load_size = load_width * load_height;
384 len += load_size / 2;
392 gpu.ex_regs[1] &= ~0x1ff;
393 gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff;
396 return list - list_start;
399 void renderer_sync_ecmds(uint32_t *ecmds_)
401 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
402 // the funcs below expect LE
403 uint32_t i, ecmds[8];
404 for (i = 1; i <= 6; i++)
405 ecmds[i] = HTOLE32(ecmds_[i]);
407 uint32_t *ecmds = ecmds_;
409 cmdTexturePage((unsigned char *)&ecmds[1]);
410 cmdTextureWindow((unsigned char *)&ecmds[2]);
411 cmdDrawAreaStart((unsigned char *)&ecmds[3]);
412 cmdDrawAreaEnd((unsigned char *)&ecmds[4]);
413 cmdDrawOffset((unsigned char *)&ecmds[5]);
414 cmdSTP((unsigned char *)&ecmds[6]);
417 void renderer_update_caches(int x, int y, int w, int h)
421 void renderer_flush_queues(void)
425 void renderer_set_interlace(int enable, int is_odd)
429 #include "../../frontend/plugin_lib.h"
431 void renderer_set_config(const struct rearmed_cbs *cbs)
433 iUseDither = cbs->gpu_peops.iUseDither;
434 dwActFixes = cbs->gpu_peops.dwActFixes;
435 if (cbs->pl_set_gpu_caps)
436 cbs->pl_set_gpu_caps(0);