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