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