1 #pragma once 2 3 #include "Types.h" 4 #include "Convertible.h" 5 #include "../uint128.h" 6 #include "../Profiler.h" 7 #include "zip/ZipArchiveWriter.h" 8 #include "zip/ZipArchiveReader.h" 9 10 class CVpu; 11 class CINTC; 12 13 class CVif 14 { 15 public: 16 enum 17 { 18 REGS0_START = 0x10003800, 19 VIF0_STAT = 0x10003800, 20 VIF0_FBRST = 0x10003810, 21 VIF0_ERR = 0x10003820, 22 VIF0_MARK = 0x10003830, 23 VIF0_CYCLE = 0x10003840, 24 VIF0_MODE = 0x10003850, 25 VIF0_NUM = 0x10003860, 26 VIF0_MASK = 0x10003870, 27 VIF0_CODE = 0x10003880, 28 VIF0_R0 = 0x10003900, 29 VIF0_R1 = 0x10003910, 30 VIF0_R2 = 0x10003920, 31 VIF0_R3 = 0x10003930, 32 REGS0_END = 0x10003A00, 33 34 REGS1_START = 0x10003C00, 35 VIF1_STAT = 0x10003C00, 36 VIF1_FBRST = 0x10003C10, 37 VIF1_ERR = 0x10003C20, 38 VIF1_MARK = 0x10003C30, 39 VIF1_CYCLE = 0x10003C40, 40 VIF1_MODE = 0x10003C50, 41 VIF1_NUM = 0x10003C60, 42 VIF1_MASK = 0x10003C70, 43 VIF1_CODE = 0x10003C80, 44 VIF1_R0 = 0x10003D00, 45 VIF1_R1 = 0x10003D10, 46 VIF1_R2 = 0x10003D20, 47 VIF1_R3 = 0x10003D30, 48 REGS1_END = 0x10003E00, 49 50 VIF0_FIFO_START = 0x10004000, 51 VIF0_FIFO_END = 0x10004FFF, 52 VIF1_FIFO_START = 0x10005000, 53 VIF1_FIFO_END = 0x10005FFF, 54 }; 55 56 CVif(unsigned int, CVpu&, CINTC&, uint8*, uint8*); 57 virtual ~CVif() = default; 58 59 virtual void Reset(); 60 uint32 GetRegister(uint32); 61 void SetRegister(uint32, uint32); 62 virtual void SaveState(Framework::CZipArchiveWriter&); 63 virtual void LoadState(Framework::CZipArchiveReader&); 64 65 virtual uint32 GetTOP() const; 66 virtual uint32 GetITOP() const; 67 68 virtual uint32 ReceiveDMA(uint32, uint32, uint32, bool); 69 70 bool IsWaitingForProgramEnd() const; 71 72 protected: 73 enum 74 { 75 CODE_CMD_MARK = 0x07, 76 }; 77 78 enum 79 { 80 FBRST_RST = 0x01, 81 FBRST_FBK = 0x02, 82 FBRST_STP = 0x04, 83 FBRST_STC = 0x08 84 }; 85 86 enum 87 { 88 STAT_FDR = 0x00800000, 89 }; 90 91 enum 92 { 93 FIFO_SIZE = 0x100 94 }; 95 96 class CFifoStream 97 { 98 public: 99 CFifoStream(uint8*, uint8*); 100 virtual ~CFifoStream() = default; 101 102 void Reset(); 103 104 uint32 GetAvailableReadBytes() const; 105 uint32 GetRemainingDmaTransferSize() const; 106 void Read(void*, uint32); 107 void Flush(); 108 void Align32(); 109 void SetDmaParams(uint32, uint32, bool); 110 void SetFifoParams(uint8*, uint32); 111 112 uint8* GetDirectPointer() const; 113 void Advance(uint32); 114 115 private: 116 void SyncBuffer(); 117 118 enum 119 { 120 BUFFERSIZE = 0x10 121 }; 122 123 uint8* m_ram = nullptr; 124 uint8* m_spr = nullptr; 125 126 uint128 m_buffer; 127 uint32 m_bufferPosition = BUFFERSIZE; 128 uint32 m_startAddress = 0; 129 uint32 m_nextAddress = 0; 130 uint32 m_endAddress = 0; 131 bool m_tagIncluded = false; 132 uint8* m_source = nullptr; 133 }; 134 135 typedef CFifoStream StreamType; 136 137 struct STAT : public convertible<uint32> 138 { 139 unsigned int nVPS : 2; 140 unsigned int nVEW : 1; 141 unsigned int nReserved0 : 3; 142 unsigned int nMRK : 1; 143 unsigned int nDBF : 1; 144 unsigned int nVSS : 1; 145 unsigned int nVFS : 1; 146 unsigned int nVIS : 1; 147 unsigned int nINT : 1; 148 unsigned int nER0 : 1; 149 unsigned int nER1 : 1; 150 unsigned int nReserved2 : 9; 151 unsigned int nFDR : 1; //VIF1 only 152 unsigned int nFQC : 4; 153 unsigned int nReserved3 : 4; 154 }; 155 static_assert(sizeof(STAT) == sizeof(uint32), "Size of STAT struct must be 4 bytes."); 156 157 struct ERR : public convertible<uint32> 158 { 159 unsigned int nMII : 1; 160 unsigned int nME0 : 1; 161 unsigned int nME1 : 1; 162 unsigned int nReserved : 29; 163 }; 164 static_assert(sizeof(ERR) == sizeof(uint32), "Size of ERR struct must be 4 bytes."); 165 166 struct CYCLE : public convertible<uint32> 167 { 168 unsigned int nCL : 8; 169 unsigned int nWL : 8; 170 unsigned int reserved : 16; 171 }; 172 static_assert(sizeof(CYCLE) == sizeof(uint32), "Size of CYCLE struct must be 4 bytes."); 173 174 struct CODE : public convertible<uint32> 175 { 176 unsigned int nIMM : 16; 177 unsigned int nNUM : 8; 178 unsigned int nCMD : 7; 179 unsigned int nI : 1; 180 }; 181 static_assert(sizeof(CODE) == sizeof(uint32), "Size of CODE struct must be 4 bytes."); 182 183 enum ADDMODE 184 { 185 MODE_NORMAL = 0, 186 MODE_OFFSET = 1, 187 MODE_DIFFERENCE = 2 188 }; 189 190 enum MASKOP 191 { 192 MASK_DATA = 0, 193 MASK_ROW = 1, 194 MASK_COL = 2, 195 MASK_MASK = 3 196 }; 197 198 void ProcessFifoWrite(uint32, uint32); 199 200 void ProcessPacket(StreamType&); 201 virtual void ExecuteCommand(StreamType&, CODE); 202 virtual void Cmd_UNPACK(StreamType&, CODE, uint32); 203 204 void Cmd_MPG(StreamType&, CODE); 205 void Cmd_STROW(StreamType&, CODE); 206 void Cmd_STCOL(StreamType&, CODE); 207 void Cmd_STMASK(StreamType&, CODE); 208 209 bool Unpack_ReadValue(const CODE&, StreamType&, uint128&, bool); 210 bool Unpack_S32(StreamType&, uint128&); 211 bool Unpack_S16(StreamType&, uint128&, bool); 212 bool Unpack_S8(StreamType&, uint128&, bool); 213 bool Unpack_V16(StreamType&, uint128&, unsigned int, bool); 214 bool Unpack_V8(StreamType&, uint128&, unsigned int, bool); 215 bool Unpack_V32(StreamType&, uint128&, unsigned int); 216 bool Unpack_V45(StreamType&, uint128&); 217 218 uint32 GetMaskOp(unsigned int, unsigned int) const; 219 220 virtual void PrepareMicroProgram(); 221 void StartMicroProgram(uint32); 222 void StartDelayedMicroProgram(uint32); 223 bool ResumeDelayedMicroProgram(); 224 225 void DisassembleCommand(CODE); 226 void DisassembleGet(uint32); 227 void DisassembleSet(uint32, uint32); 228 229 unsigned int m_number = 0; 230 CVpu& m_vpu; 231 CINTC& m_intc; 232 uint8* m_ram = nullptr; 233 uint8* m_spr = nullptr; 234 CFifoStream m_stream; 235 236 uint8 m_fifoBuffer[FIFO_SIZE]; 237 uint32 m_fifoIndex = 0; 238 239 STAT m_STAT; 240 ERR m_ERR; 241 CYCLE m_CYCLE; 242 CODE m_CODE; 243 uint8 m_NUM; 244 uint32 m_MODE; 245 uint32 m_R[4]; 246 uint32 m_C[4]; 247 uint32 m_MASK; 248 uint32 m_MARK; 249 uint32 m_ITOP; 250 uint32 m_ITOPS; 251 uint32 m_readTick; 252 uint32 m_writeTick; 253 uint32 m_pendingMicroProgram; 254 uint32 m_incomingFifoDelay; 255 256 CProfiler::ZoneHandle m_vifProfilerZone = 0; 257 }; 258