1 /******************************************************************************/
2 /* Mednafen Sony PS1 Emulation Module                                         */
3 /******************************************************************************/
4 /* gpu.h:
5 **  Copyright (C) 2011-2017 Mednafen Team
6 **
7 ** This program is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU General Public License
9 ** as published by the Free Software Foundation; either version 2
10 ** of the License, or (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software Foundation, Inc.,
19 ** 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21 
22 // WARNING WARNING WARNING:  ONLY use CanRead() method of BlitterFIFO, and NOT CanWrite(), since the FIFO is larger than the actual PS1 GPU FIFO to accommodate
23 // our lack of fancy superscalarish command sequencer.
24 
25 #ifndef __MDFN_PSX_GPU_H
26 #define __MDFN_PSX_GPU_H
27 
28 #include "FastFIFO.h"
29 
30 namespace MDFN_IEN_PSX
31 {
32 
33 struct CTEntry
34 {
35  void (*func[4][8])(const uint32 *cb);
36  uint8 len;
37  uint8 fifo_fb_len;
38  bool ss_cmd;
39 };
40 
41 struct tri_vertex
42 {
43  int32 x, y;
44  int32 u, v;
45  int32 r, g, b;
46 };
47 
48 struct line_point
49 {
50  int32 x, y;
51  uint8 r, g, b;
52 };
53 
54 struct PS_GPU
55 {
56  uint16 CLUT_Cache[256];
57  uint32 CLUT_Cache_VB;	// Don't try to be clever and reduce it to 16 bits... ~0U is value for invalidated state.
58 
59  struct	// Speedup-cache variables, derived from other variables; shouldn't be saved in save states.
60  {
61   // TW*_* variables derived from tww, twh, twx, twy, TexPageX, TexPageY
62   uint32 TWX_AND;
63   uint32 TWX_ADD;
64 
65   uint32 TWY_AND;
66   uint32 TWY_ADD;
67  } SUCV;
68 
69  struct
70  {
71   uint16 Data[4];
72   uint32 Tag;
73  } TexCache[256];
74 
75  uint32 DMAControl;
76 
77  //
78  // Drawing stuff
79  //
80  //int32 TexPageX;	// 0, 64, 128, 192, etc up to 960
81  //int32 TexPageY;	// 0 or 256
82  //uint32 abr;		// Semi-transparency mode(0~3)
83  //bool dtd;		// Dithering enable
84 
85  int32 ClipX0;
86  int32 ClipY0;
87  int32 ClipX1;
88  int32 ClipY1;
89 
90  int32 OffsX;
91  int32 OffsY;
92 
93  uint32 MaskSetOR;
94  uint32 MaskEvalAND;
95 
96  bool dtd;
97  bool dfe;
98 
99  bool TexDisable;
100  bool TexDisableAllowChange;
101 
102  uint8 tww, twh, twx, twy;
103 
104  uint32 TexPageX;
105  uint32 TexPageY;
106 
107  uint32 SpriteFlip;
108 
109  uint32 abr;
110  uint32 TexMode;
111 
112  FastFIFO<uint32, 0x20> BlitterFIFO; // 0x10 on actual PS1 GPU, 0x20 here(see comment at top of gpu.h)
113  uint32 DataReadBuffer;
114  uint32 DataReadBufferEx;
115 
116  bool IRQPending;
117  //
118  //
119  //
120  // Powers of 2 for faster multiple equality testing(just for multi-testing; InCmd itself will only contain 0, or a power of 2).
121  enum
122  {
123   INCMD_NONE = 0,
124   INCMD_PLINE = (1 << 0),
125   INCMD_QUAD = (1 << 1),
126   INCMD_FBWRITE = (1 << 2),
127   INCMD_FBREAD = (1 << 3)
128  };
129  uint8 InCmd;
130  uint8 InCmd_CC;
131 
132  tri_vertex InQuad_F3Vertices[3];
133 
134  line_point InPLine_PrevPoint;
135 
136  uint32 FBRW_X;
137  uint32 FBRW_Y;
138  uint32 FBRW_W;
139  uint32 FBRW_H;
140  uint32 FBRW_CurY;
141  uint32 FBRW_CurX;
142 
143  //
144  // Display Parameters
145  //
146  uint32 DisplayFB_XStart;
147  uint32 DisplayFB_YStart;
148 
149  uint32 HorizStart;
150  uint32 HorizEnd;
151 
152  uint32 VertStart;
153  uint32 VertEnd;
154  uint32 DisplayMode;
155  bool DisplayOff;
156 
157  //
158  // Display work vars
159  //
160  bool PhaseChange;
161  bool InVBlank;
162  bool sl_zero_reached;
163  bool skip;
164  bool field;
165  bool field_ram_readout;
166  uint32 DisplayFB_CurYOffset;
167  uint32 DisplayFB_CurLineYReadout;
168 
169  //
170  //
171  //
172  uint64 GPUClockCounter;
173  uint32 GPUClockRatio;
174  uint32 LinesPerField;
175  uint32 scanline;
176  uint32 DotClockCounter;
177 
178  int32 LineClockCounter;
179  int32 LinePhase;
180 
181  int32 DrawTimeAvail;
182 
183  pscpu_timestamp_t lastts;
184 
185  uint8 DitherLUT[4][4][512];	// Y, X, 8-bit source value(256 extra for saturation)
186 
187  CTEntry Commands[256];
188  //
189  //
190  //
191  //
192  //
193  //
194  EmulateSpecStruct *espec;
195  MDFN_Surface *surface;
196  MDFN_Rect *DisplayRect;
197  int32 *LineWidths;
198  int LineVisFirst, LineVisLast;
199  bool ShowHOverscan;
200  bool CorrectAspect;
201  int32 HVis;
202  int32 HVisOffs;
203  int32 NCABaseW;
204  int32 hmc_to_visible;
205  /*const*/ bool HardwarePALType;
206  uint32 OutputLUT[384];
207  //
208  //
209  // Y, X
210  uint16 GPURAM[512][1024];
211 };
212 
213  MDFN_HIDE extern PS_GPU GPU;
214 
215  void GPU_Init(bool pal_clock_and_tv) MDFN_COLD;
216  void GPU_Kill(void) MDFN_COLD;
217 
218  void GPU_SetGetVideoParams(MDFNGI* gi, const bool caspect, const int sls, const int sle, const bool show_h_overscan) MDFN_COLD;
219 
220  void GPU_GetGunXTranslation(float* scale, float* offs);
221 
222  void GPU_Power(void) MDFN_COLD;
223 
224  void GPU_StateAction(StateMem *sm, const unsigned load, const bool data_only);
225 
226  void GPU_ResetTS(void);
227 
228  void GPU_StartFrame(EmulateSpecStruct *espec);
229 
230  MDFN_FASTCALL pscpu_timestamp_t GPU_Update(const pscpu_timestamp_t timestamp);
231 
232  MDFN_FASTCALL void GPU_Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V);
233 
GPU_CalcFIFOReadyBit(void)234  static INLINE bool GPU_CalcFIFOReadyBit(void)
235  {
236   if(GPU.InCmd & (PS_GPU::INCMD_PLINE | PS_GPU::INCMD_QUAD))
237    return false;
238 
239   if(GPU.BlitterFIFO.CanRead() == 0)
240    return true;
241 
242   if(GPU.InCmd & (PS_GPU::INCMD_FBREAD | PS_GPU::INCMD_FBWRITE))
243    return false;
244 
245   if(GPU.BlitterFIFO.CanRead() >= GPU.Commands[GPU.BlitterFIFO.Peek() >> 24].fifo_fb_len)
246    return false;
247 
248   return true;
249  }
250 
GPU_DMACanWrite(void)251  static INLINE bool GPU_DMACanWrite(void)
252  {
253   return GPU_CalcFIFOReadyBit();
254  }
255 
256  MDFN_FASTCALL void GPU_WriteDMA(uint32 V);
257  uint32 GPU_ReadDMA(void);
258 
259  MDFN_FASTCALL uint32 GPU_Read(const pscpu_timestamp_t timestamp, uint32 A);
260 
GPU_GetScanlineNum(void)261  static INLINE int32 GPU_GetScanlineNum(void)
262  {
263   return GPU.scanline;
264  }
265 
GPU_PeekRAM(uint32 A)266  static INLINE uint16 GPU_PeekRAM(uint32 A)
267  {
268   return GPU.GPURAM[(A >> 10) & 0x1FF][A & 0x3FF];
269  }
270 
GPU_PokeRAM(uint32 A,uint16 V)271  static INLINE void GPU_PokeRAM(uint32 A, uint16 V)
272  {
273   GPU.GPURAM[(A >> 10) & 0x1FF][A & 0x3FF] = V;
274  }
275 }
276 #endif
277