summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/psx.h
blob: 9693f3902236f29f02c9c17da184fd791e9d3994 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
// license:BSD-3-Clause
// copyright-holders:smf
/*
 * PlayStation GPU emulator
 *
 * Copyright 2003-2014 smf
 *
 */

#ifndef MAME_VIDEO_PSX_H
#define MAME_VIDEO_PSX_H

#pragma once

#include "emupal.h"

#define PSXGPU_DEBUG_VIEWER ( 0 )


#define MCFG_PSX_GPU_VBLANK_HANDLER(_devcb) \
	downcast<psxgpu_device &>(*device).set_vblank_handler(DEVCB_##_devcb);

#define MCFG_PSXGPU_ADD( cputag, tag, type, _vramSize, clock ) \
	MCFG_DEVICE_MODIFY( cputag ) \
	MCFG_PSX_GPU_READ_HANDLER(READ32(tag, psxgpu_device, read)) \
	MCFG_PSX_GPU_WRITE_HANDLER(WRITE32(tag, psxgpu_device, write)) \
	MCFG_DEVICE_ADD( tag, type, clock ) \
	downcast<psxgpu_device &>(*device).set_vram_size(_vramSize); \
	MCFG_PSX_GPU_VBLANK_HANDLER(WRITELINE(cputag ":irq", psxirq_device, intin0)) \
	MCFG_PSX_DMA_CHANNEL_READ( cputag, 2, psxdma_device::write_delegate(&psxgpu_device::dma_read, (psxgpu_device *) device ) ) \
	MCFG_PSX_DMA_CHANNEL_WRITE( cputag, 2, psxdma_device::read_delegate(&psxgpu_device::dma_write, (psxgpu_device *) device ) )

#define MCFG_PSXGPU_REPLACE( cputag, tag, type, _vramSize, clock ) \
	MCFG_DEVICE_MODIFY( cputag ) \
	MCFG_PSX_GPU_READ_HANDLER(READ32(tag, psxgpu_device, read)) \
	MCFG_PSX_GPU_WRITE_HANDLER(WRITE32(tag, psxgpu_device, write)) \
	MCFG_DEVICE_REPLACE( tag, type, clock ) \
	downcast<psxgpu_device &>(*device).set_vram_size(_vramSize); \
	MCFG_PSX_GPU_VBLANK_HANDLER(WRITELINE(cputag ":irq", psxirq_device, intin0)) \
	MCFG_PSX_DMA_CHANNEL_READ( cputag, 2, psxdma_device::write_delegate(&psxgpu_device::dma_read, (psxgpu_device *) device ) ) \
	MCFG_PSX_DMA_CHANNEL_WRITE( cputag, 2, psxdma_device::read_delegate(&psxgpu_device::dma_write, (psxgpu_device *) device ) )

#define MCFG_PSXGPU_VBLANK_CALLBACK( _delegate ) \
	((screen_device *) config.device_find( device, "screen" ))->register_vblank_callback( _delegate );

DECLARE_DEVICE_TYPE(CXD8514Q,  cxd8514q_device)
DECLARE_DEVICE_TYPE(CXD8538Q,  cxd8538q_device)
DECLARE_DEVICE_TYPE(CXD8561Q,  cxd8561q_device)
DECLARE_DEVICE_TYPE(CXD8561BQ, cxd8561bq_device)
DECLARE_DEVICE_TYPE(CXD8561CQ, cxd8561cq_device)
DECLARE_DEVICE_TYPE(CXD8654Q,  cxd8654q_device)

class psxgpu_device : public device_t, public device_video_interface
{
public:
	// configuration helpers
	template <class Object> devcb_base &set_vblank_handler(Object &&cb) { return m_vblank_handler.set_callback(std::forward<Object>(cb)); }
	void set_vram_size(int size) { vramSize = size; }

	DECLARE_WRITE32_MEMBER( write );
	DECLARE_READ32_MEMBER( read );
	void dma_read( uint32_t *ram, uint32_t n_address, int32_t n_size );
	void dma_write( uint32_t *ram, uint32_t n_address, int32_t n_size );
	void lightgun_set( int, int );

protected:
	static constexpr unsigned MAX_LEVEL = 32;
	static constexpr unsigned MID_LEVEL = (MAX_LEVEL / 2) << 8;
	static constexpr unsigned MAX_SHADE = 0x100;
	static constexpr unsigned MID_SHADE = 0x80;

	// construction/destruction
	psxgpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_add_mconfig(machine_config &config) override;

	int vramSize;

private:
	static constexpr unsigned DEBUG_COORDS = 10;

	struct psx_gpu_debug
	{
		std::unique_ptr<bitmap_ind16> mesh;
		int b_clear;
		int b_mesh;
		int n_skip;
		int b_texture;
		int n_interleave;
		int n_coord;
		int n_coordx[ DEBUG_COORDS ];
		int n_coordy[ DEBUG_COORDS ];
	};

	struct FLATVERTEX
	{
		PAIR n_coord;
	};

	struct GOURAUDVERTEX
	{
		PAIR n_bgr;
		PAIR n_coord;
	};

	struct FLATTEXTUREDVERTEX
	{
		PAIR n_coord;
		PAIR n_texture;
	};

	struct GOURAUDTEXTUREDVERTEX
	{
		PAIR n_bgr;
		PAIR n_coord;
		PAIR n_texture;
	};

	union PACKET
	{
		uint32_t n_entry[ 16 ];

		struct
		{
			PAIR n_cmd;
			struct FLATVERTEX vertex[ 2 ];
			PAIR n_size;
		} MoveImage;

		struct
		{
			PAIR n_bgr;
			PAIR n_coord;
			PAIR n_size;
		} FlatRectangle;

		struct
		{
			PAIR n_bgr;
			PAIR n_coord;
		} FlatRectangle8x8;

		struct
		{
			PAIR n_bgr;
			PAIR n_coord;
		} FlatRectangle16x16;

		struct
		{
			PAIR n_bgr;
			PAIR n_coord;
			PAIR n_texture;
		} Sprite8x8;

		struct
		{
			PAIR n_bgr;
			PAIR n_coord;
			PAIR n_texture;
		} Sprite16x16;

		struct
		{
			PAIR n_bgr;
			PAIR n_coord;
			PAIR n_texture;
			PAIR n_size;
		} FlatTexturedRectangle;

		struct
		{
			PAIR n_bgr;
			struct FLATVERTEX vertex[ 4 ];
		} FlatPolygon;

		struct
		{
			struct GOURAUDVERTEX vertex[ 4 ];
		} GouraudPolygon;

		struct
		{
			PAIR n_bgr;
			struct FLATVERTEX vertex[ 2 ];
		} MonochromeLine;

		struct
		{
			struct GOURAUDVERTEX vertex[ 2 ];
		} GouraudLine;

		struct
		{
			PAIR n_bgr;
			struct FLATTEXTUREDVERTEX vertex[ 4 ];
		} FlatTexturedPolygon;

		struct
		{
			struct GOURAUDTEXTUREDVERTEX vertex[ 4 ];
		} GouraudTexturedPolygon;

		struct
		{
			PAIR n_bgr;
			struct FLATVERTEX vertex;
		} Dot;
	};

	void updatevisiblearea();
	void decode_tpage( uint32_t tpage );
	void FlatPolygon( int n_points );
	void FlatTexturedPolygon( int n_points );
	void GouraudPolygon( int n_points );
	void GouraudTexturedPolygon( int n_points );
	void MonochromeLine();
	void GouraudLine();
	void FrameBufferRectangleDraw();
	void FlatRectangle();
	void FlatRectangle8x8();
	void FlatRectangle16x16();
	void FlatTexturedRectangle();
	void Sprite8x8();
	void Sprite16x16();
	void Dot();
	void MoveImage();
	void psx_gpu_init( int n_gputype );
	void gpu_reset();
	void gpu_read( uint32_t *p_ram, int32_t n_size );
	void gpu_write( uint32_t *p_ram, int32_t n_size );

	int32_t m_n_tx;
	int32_t m_n_ty;
	int32_t n_abr;
	int32_t n_tp;
	int32_t n_ix;
	int32_t n_iy;
	int32_t n_ti;

	std::unique_ptr<uint16_t[]> p_vram;
	uint32_t n_vramx;
	uint32_t n_vramy;
	uint32_t n_twy;
	uint32_t n_twx;
	uint32_t n_twh;
	uint32_t n_tww;
	uint32_t n_drawarea_x1;
	uint32_t n_drawarea_y1;
	uint32_t n_drawarea_x2;
	uint32_t n_drawarea_y2;
	uint32_t n_horiz_disstart;
	uint32_t n_horiz_disend;
	uint32_t n_vert_disstart;
	uint32_t n_vert_disend;
	uint32_t b_reverseflag;
	int32_t n_drawoffset_x;
	int32_t n_drawoffset_y;
	uint32_t m_n_displaystartx;
	uint32_t n_displaystarty;
	int m_n_gputype;
	uint32_t n_gpustatus;
	uint32_t n_gpuinfo;
	uint32_t n_gpu_buffer_offset;
	uint32_t n_lightgun_x;
	uint32_t n_lightgun_y;
	uint32_t n_screenwidth;
	uint32_t n_screenheight;

	PACKET m_packet;

	uint16_t *p_p_vram[ 1024 ];

	uint16_t p_n_redshade[ MAX_LEVEL * MAX_SHADE ];
	uint16_t p_n_greenshade[ MAX_LEVEL * MAX_SHADE ];
	uint16_t p_n_blueshade[ MAX_LEVEL * MAX_SHADE ];
	uint16_t p_n_redlevel[ 0x10000 ];
	uint16_t p_n_greenlevel[ 0x10000 ];
	uint16_t p_n_bluelevel[ 0x10000 ];

	uint16_t p_n_f025[ MAX_LEVEL * MAX_SHADE ];
	uint16_t p_n_f05[ MAX_LEVEL * MAX_SHADE ];
	uint16_t p_n_f1[ MAX_LEVEL * MAX_SHADE ];
	uint16_t p_n_redb05[ 0x10000 ];
	uint16_t p_n_greenb05[ 0x10000 ];
	uint16_t p_n_blueb05[ 0x10000 ];
	uint16_t p_n_redb1[ 0x10000 ];
	uint16_t p_n_greenb1[ 0x10000 ];
	uint16_t p_n_blueb1[ 0x10000 ];
	uint16_t p_n_redaddtrans[ MAX_LEVEL * MAX_LEVEL ];
	uint16_t p_n_greenaddtrans[ MAX_LEVEL * MAX_LEVEL ];
	uint16_t p_n_blueaddtrans[ MAX_LEVEL * MAX_LEVEL ];
	uint16_t p_n_redsubtrans[ MAX_LEVEL * MAX_LEVEL ];
	uint16_t p_n_greensubtrans[ MAX_LEVEL * MAX_LEVEL ];
	uint16_t p_n_bluesubtrans[ MAX_LEVEL * MAX_LEVEL ];

	uint16_t p_n_g0r0[ 0x10000 ];
	uint16_t p_n_b0[ 0x10000 ];
	uint16_t p_n_r1[ 0x10000 ];
	uint16_t p_n_b1g1[ 0x10000 ];

	devcb_write_line m_vblank_handler;

	void vblank(screen_device &screen, bool vblank_state);
	DECLARE_PALETTE_INIT( psx );
	uint32_t update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);

#if defined(PSXGPU_DEBUG_VIEWER) && PSXGPU_DEBUG_VIEWER
	void DebugMeshInit();
	void DebugMesh( int n_coordx, int n_coordy );
	void DebugMeshEnd();
	void DebugCheckKeys();
	int DebugMeshDisplay( bitmap_ind16 &bitmap, const rectangle &cliprect );
	int DebugTextureDisplay( bitmap_ind16 &bitmap );

	psx_gpu_debug m_debug;
#endif
};

class cxd8514q_device : public psxgpu_device
{
public:
	// construction/destruction
	cxd8514q_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

class cxd8538q_device : public psxgpu_device
{
public:
	// construction/destruction
	cxd8538q_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

class cxd8561q_device : public psxgpu_device
{
public:
	// construction/destruction
	cxd8561q_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

class cxd8561bq_device : public psxgpu_device
{
public:
	// construction/destruction
	cxd8561bq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

class cxd8561cq_device : public psxgpu_device
{
public:
	// construction/destruction
	cxd8561cq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

class cxd8654q_device : public psxgpu_device
{
public:
	// construction/destruction
	cxd8654q_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

#endif // MAME_VIDEO_PSX_H