1 /* Mednafen - Multi-system Emulator
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17 
18 #ifndef __MDFN_PCE_VCE_H
19 #define __MDFN_PCE_VCE_H
20 
21 #include "huc6280.h"
22 #include <mednafen/hw_video/huc6270/vdc.h>
23 
24 namespace MDFN_IEN_PCE
25 {
26 
27 class VCE final
28 {
29 	public:
30 
31 	VCE(const bool want_sgfx, const uint32 vram_size = 32768) MDFN_COLD;
32 	~VCE() MDFN_COLD;
33 
34 	void SetVDCUnlimitedSprites(const bool nospritelimit);
35 	void SetShowHorizOS(bool show);
36 	void SetLayerEnableMask(uint64 mask);
37 
38 	void StateAction(StateMem *sm, const unsigned load, const bool data_only);
39 
40 	void SetPixelFormat(const MDFN_PixelFormat &format, const uint8* CustomColorMap, const uint32 CustomColorMapLen);
41 
42 	void StartFrame(MDFN_Surface *surface, MDFN_Rect *DisplayRect, int32 *LineWidths, int skip);
43 	bool RunPartial(void);
44 
45         void Update(const int32 timestamp);
46 
ResetTS(int ts_base)47 	INLINE void ResetTS(int ts_base)
48 	{
49 	 last_ts = ts_base;
50 	}
51 
GetScanlineNo(void)52 	inline int GetScanlineNo(void)
53 	{
54 	 return(scanline);
55 	}
56 
57 	void Reset(const int32 timestamp);
58 
59 	void Write(uint32 A, uint8 V);
60 	uint8 Read(uint32 A);
61 
62         uint8 ReadVDC(uint32 A);
63         void WriteVDC(uint32 A, uint8 V);
64         void WriteVDC_ST(uint32 A, uint8 V);
65 
66 	#ifdef WANT_DEBUGGER
67 
PeekPRAM(const uint16 Address)68 	INLINE uint16 PeekPRAM(const uint16 Address)
69 	{
70 	 return color_table[Address & 0x1FF];
71 	}
72 
PokePRAM(const uint16 Address,const uint16 Data)73 	INLINE void PokePRAM(const uint16 Address, const uint16 Data)
74 	{
75 	 color_table[Address & 0x1FF] = Data & 0x1FF;
76 	 FixPCache(Address);
77 	}
78 
79         // Peek(VRAM/SAT) and Poke(VRAM/SAT) work in 16-bit VRAM word units(Address and Length, both).
PeekVDCVRAM(unsigned int which,uint16 Address)80         INLINE uint16 PeekVDCVRAM(unsigned int which, uint16 Address)
81         {
82 	 assert(which < (unsigned int)chip_count);
83 
84 	 return(vdc[which].PeekVRAM(Address));
85         }
86 
PeekVDCSAT(unsigned int which,uint8 Address)87         INLINE uint16 PeekVDCSAT(unsigned int which, uint8 Address)
88         {
89 	 assert(which < (unsigned int)chip_count);
90 
91 	 return(vdc[which].PeekSAT(Address));
92         }
93 
PokeVDCVRAM(const unsigned int which,const uint16 Address,const uint16 Data)94         INLINE void PokeVDCVRAM(const unsigned int which, const uint16 Address, const uint16 Data)
95 	{
96 	 assert(which < (unsigned int)chip_count);
97 
98 	 vdc[which].PokeVRAM(Address, Data);
99 	}
100 
PokeVDCSAT(const unsigned int which,const uint8 Address,const uint16 Data)101         INLINE void PokeVDCSAT(const unsigned int which, const uint8 Address, const uint16 Data)
102 	{
103 	 assert(which < (unsigned int)chip_count);
104 
105 	 vdc[which].PokeSAT(Address, Data);
106 	}
107 
108 	void SetGraphicsDecode(MDFN_Surface *surface, int line, int which, int xscroll, int yscroll, int pbn);
109 
110         enum
111         {
112          GSREG_CR = 0,
113          GSREG_CTA,
114          GSREG_SCANLINE,
115 
116 	 // VPC:
117 	 GSREG_PRIORITY_0,
118 	 GSREG_PRIORITY_1,
119 	 GSREG_WINDOW_WIDTH_0,
120 	 GSREG_WINDOW_WIDTH_1,
121 	 GSREG_ST_MODE
122 	};
123 
124         uint32 GetRegister(const unsigned int id, char *special, const uint32 special_len);
125         void SetRegister(const unsigned int id, const uint32 value);
126 
GetRegisterVDC(const unsigned int which_vdc,const unsigned int id,char * special,const uint32 special_len)127 	INLINE uint32 GetRegisterVDC(const unsigned int which_vdc, const unsigned int id, char *special, const uint32 special_len)
128 	{
129 	 assert(which_vdc < chip_count);
130 	 return vdc[which_vdc].GetRegister(id, special, special_len);
131 	}
132 
SetRegisterVDC(const unsigned int which_vdc,const unsigned int id,const uint32 value)133 	INLINE void SetRegisterVDC(const unsigned int which_vdc, const unsigned int id, const uint32 value)
134 	{
135 	 assert(which_vdc < chip_count);
136 	 vdc[which_vdc].SetRegister(id, value);
137 	}
138 
ResetSimulateVDC(void)139 	INLINE void ResetSimulateVDC(void)
140 	{
141 	 for(unsigned chip = 0; chip < chip_count; chip++)
142 	  vdc[chip].ResetSimulate();
143 	}
144 
SimulateReadVDC(uint32 A,VDC_SimulateResult * result)145 	INLINE int SimulateReadVDC(uint32 A, VDC_SimulateResult *result)
146 	{
147 	 if(!sgfx)
148 	 {
149 	  vdc[0].SimulateRead(A, result);
150 	  return(0);
151 	 }
152 	 else
153 	 {
154 	  int chip = 0;
155 
156 	  A &= 0x1F;
157 
158 	  if(!(A & 0x8))
159 	  {
160 	   chip = (A & 0x10) >> 4;
161 	   vdc[chip].SimulateRead(A & 0x3, result);
162 	   return(chip);
163 	  }
164 	 }
165 
166          result->ReadCount = result->WriteCount = 0;
167          return(0);
168 	}
169 
170 	// If the simulated write is due to a ST0, ST1, or ST2 instruction, set the high bit of the passed address to 1.
SimulateWriteVDC(uint32 A,uint8 V,VDC_SimulateResult * result)171 	INLINE int SimulateWriteVDC(uint32 A, uint8 V, VDC_SimulateResult *result)
172 	{
173 	 if(!sgfx)
174 	 {
175 	  vdc[0].SimulateWrite(A, V, result);
176 	  return(0);
177 	 }
178 	 else
179 	 {
180 	  // For ST0/ST1/ST2
181 	  A |= ((A >> 31) & st_mode) << 4;
182 
183 	  A &= 0x1F;
184 
185 	  if(!(A & 0x8))
186 	  {
187 	   int chip = (A & 0x10) >> 4;
188 	   vdc[chip].SimulateWrite(A & 0x3, V, result);
189 	   return(chip);
190 	  }
191 	 }
192 
193 	 result->ReadCount = result->WriteCount = 0;
194 	 result->ReadStart = result->WriteStart = 0;
195 	 return(0);
196 	}
197 	#endif
198 
199         void IRQChangeCheck(void);
200 
201         bool WS_Hook(int32 vdc_cycles);
202 
203 	void SetCDEvent(const int32 cycles);
204 
205 	//
206 	//
207 	//
208 	//
209 	//
210 	//
211         int32 SyncReal(const int32 timestamp);
212 	private:
213 
214 	template<bool TA_SuperGrafx, bool TA_AwesomeMode>
215 	void SyncSub(int32 clocks);
216 
217         void FixPCache(int entry);
218         void SetVCECR(uint8 V);
219 
220 	#ifdef WANT_DEBUGGER
221 	void DoGfxDecode(void);
222 	#endif
223 
224 	int32 CalcNextEvent(void);
225 	int32 child_event[2];
226 
227         int32 cd_event;
228 
229 	uint32 *fb;	// Pointer to the framebuffer.
230 	uint32 pitch32;	// Pitch(in 32-bit pixels)
231 	bool FrameDone;
232 	bool ShowHorizOS;
233 	bool sgfx;
234 
235 	bool skipframe;
236 	int32 *LW;
237 	unsigned chip_count;	// = 1 when sgfx is false, = 2 when sgfx is true
238 
239 	int32 clock_divider;
240 
241 	int32 scanline;
242 	uint32 *scanline_out_ptr;	// Pointer into fb
243 	int32 pixel_offset;
244 
245 	int32 hblank_counter;
246 	int32 vblank_counter;
247 
248 	bool hblank;	// true if in HBLANK, false if not.
249 	bool vblank;	// true if in vblank, false if not
250 
251 	bool NeedSLReset;
252 
253         uint8 CR;		// Control Register
254         bool lc263;     	// CR->263 line count if set, 262 if not
255         bool bw;        	// CR->Black and White
256         uint8 dot_clock;	// CR->Dot Clock(5, 7, or 10 MHz = 0, 1, 2/3)
257 	int32 dot_clock_ratio;	// CR->Dot Clock ratio cache
258 
259 	int32 ws_counter;
260 
261 	int32 last_ts;
262 
263 	//
264 	// SuperGrafx HuC6202 VPC state
265 	//
266 	int32 window_counter[2];
267         uint16 winwidths[2];
268         uint8 priority[2];
269         uint8 st_mode;
270 	//
271 	//
272 	//
273         uint16 ctaddress;
274         uint32 color_table_cache[0x200 * 2];	// * 2 for user layer disabling stuff.
275 	uint16 pixel_buffer[2][2048];	// Internal temporary pixel buffers.
276         uint16 color_table[0x200];
277 	uint32 surf_clut[2][512];
278 
279 	VDC vdc[2];
280 
281 	#ifdef WANT_DEBUGGER
282 	MDFN_Surface *GfxDecode_Buf;// = NULL;
283 	int GfxDecode_Line;// = -1;
284 	int GfxDecode_Layer;// = 0;
285 	int GfxDecode_Scroll;// = 0;
286 	int GfxDecode_Pbn;// = 0;
287 	#endif
288 };
289 
290 
291 };
292 
293 #endif
294