summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/tia.h
blob: 53c050a6188402803730ffcf3b0ce9e24277f6f2 (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
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol,Stefan Jokisch
#ifndef MAME_VIDEO_VIDEO_TIA_H
#define MAME_VIDEO_VIDEO_TIA_H

#pragma once

//**************************************************************************
//  MACROS / CONSTANTS
//**************************************************************************


#define TIA_PALETTE_LENGTH              128 + 128 * 128
#define TIA_INPUT_PORT_ALWAYS_ON        0
#define TIA_INPUT_PORT_ALWAYS_OFF       0xff
#define TIA_MAX_SCREEN_HEIGHT           342

#define HMOVE_INACTIVE      -200
#define PLAYER_GFX_SLOTS    4
// Per player graphic
// - pixel number to start drawing from (0-7, from GRPx) / number of pixels drawn from GRPx
// - display position to start drawing
// - size to use
struct player_gfx {
	int start_pixel[PLAYER_GFX_SLOTS];
	int start_drawing[PLAYER_GFX_SLOTS];
	int size[PLAYER_GFX_SLOTS];
	int skipclip[PLAYER_GFX_SLOTS];
};

//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_TIA_READ_INPUT_PORT_CB(_devcb) \
	devcb = &tia_video_device::set_read_input_port_callback(*device, DEVCB_##_devcb);

#define MCFG_TIA_DATABUS_CONTENTS_CB(_devcb) \
	devcb = &tia_video_device::set_databus_contents_callback(*device, DEVCB_##_devcb);

#define MCFG_TIA_VSYNC_CB(_devcb) \
	devcb = &tia_video_device::set_vsync_callback(*device, DEVCB_##_devcb);

//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************


// ======================> tia_video_device

class tia_video_device :    public device_t,
							public device_video_interface
{
public:
	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);

	template<class _Object> static devcb_base &set_read_input_port_callback(device_t &device, _Object object) { return downcast<tia_video_device &>(device).m_read_input_port_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_databus_contents_callback(device_t &device, _Object object) { return downcast<tia_video_device &>(device).m_databus_contents_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_vsync_callback(device_t &device, _Object object) { return downcast<tia_video_device &>(device).m_vsync_cb.set_callback(object); }

	DECLARE_READ8_MEMBER( read );
	DECLARE_WRITE8_MEMBER( write );

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

	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;

	void draw_sprite_helper(uint8_t* p, uint8_t *col, struct player_gfx *gfx, uint8_t GRP, uint8_t COLUP, uint8_t REFP);
	void draw_missile_helper(uint8_t* p, uint8_t* col, int horz, int skipdelay, int latch, int start, uint8_t RESMP, uint8_t ENAM, uint8_t NUSIZ, uint8_t COLUM);
	void draw_playfield_helper(uint8_t* p, uint8_t* col, int horz, uint8_t COLU, uint8_t REFPF);
	void draw_ball_helper(uint8_t* p, uint8_t* col, int horz, uint8_t ENAB);
	void drawS0(uint8_t* p, uint8_t* col);
	void drawS1(uint8_t* p, uint8_t* col);
	void drawM0(uint8_t* p, uint8_t* col);
	void drawM1(uint8_t* p, uint8_t* col);
	void drawBL(uint8_t* p, uint8_t* col);
	void drawPF(uint8_t* p, uint8_t *col);
	int collision_check(uint8_t* p1, uint8_t* p2, int x1, int x2);
	int current_x();
	int current_y();
	void setup_pXgfx(void);
	void update_bitmap(int next_x, int next_y);
	DECLARE_WRITE8_MEMBER( WSYNC_w );
	DECLARE_WRITE8_MEMBER( VSYNC_w );
	DECLARE_WRITE8_MEMBER( VBLANK_w );
	DECLARE_WRITE8_MEMBER( CTRLPF_w );
	DECLARE_WRITE8_MEMBER( HMP0_w );
	DECLARE_WRITE8_MEMBER( HMP1_w );
	DECLARE_WRITE8_MEMBER( HMM0_w );
	DECLARE_WRITE8_MEMBER( HMM1_w );
	DECLARE_WRITE8_MEMBER( HMBL_w );
	DECLARE_WRITE8_MEMBER( HMOVE_w );
	DECLARE_WRITE8_MEMBER( RSYNC_w );
	DECLARE_WRITE8_MEMBER( NUSIZ0_w );
	DECLARE_WRITE8_MEMBER( NUSIZ1_w );
	DECLARE_WRITE8_MEMBER( HMCLR_w );
	DECLARE_WRITE8_MEMBER( CXCLR_w );
	DECLARE_WRITE8_MEMBER( RESP0_w );
	DECLARE_WRITE8_MEMBER( RESP1_w );
	DECLARE_WRITE8_MEMBER( RESM0_w );
	DECLARE_WRITE8_MEMBER( RESM1_w );
	DECLARE_WRITE8_MEMBER( RESBL_w );
	DECLARE_WRITE8_MEMBER( RESMP0_w );
	DECLARE_WRITE8_MEMBER( RESMP1_w );
	DECLARE_WRITE8_MEMBER( GRP0_w );
	DECLARE_WRITE8_MEMBER( GRP1_w );
	DECLARE_READ8_MEMBER( INPT_r );


private:
	devcb_read16    m_read_input_port_cb;
	devcb_read8     m_databus_contents_cb;
	devcb_write16   m_vsync_cb;

	struct player_gfx p0gfx;
	struct player_gfx p1gfx;

	uint64_t frame_cycles;
	uint64_t paddle_start;

	int horzP0;
	int horzP1;
	int horzM0;
	int horzM1;
	int horzBL;
	int motclkP0;
	int motclkP1;
	int motclkM0;
	int motclkM1;
	int motclkBL;
	int startP0;
	int startP1;
	int startM0;
	int startM1;
	int skipclipP0;
	int skipclipP1;
	int skipM0delay;
	int skipM1delay;

	int current_bitmap;

	int prev_x;
	int prev_y;

	uint8_t VSYNC;
	uint8_t VBLANK;
	uint8_t COLUP0;
	uint8_t COLUP1;
	uint8_t COLUBK;
	uint8_t COLUPF;
	uint8_t CTRLPF;
	uint8_t GRP0;
	uint8_t GRP1;
	uint8_t REFP0;
	uint8_t REFP1;
	uint8_t HMP0;
	uint8_t HMP1;
	uint8_t HMM0;
	uint8_t HMM1;
	uint8_t HMBL;
	uint8_t VDELP0;
	uint8_t VDELP1;
	uint8_t VDELBL;
	uint8_t NUSIZ0;
	uint8_t NUSIZ1;
	uint8_t ENAM0;
	uint8_t ENAM1;
	uint8_t ENABL;
	uint8_t CXM0P;
	uint8_t CXM1P;
	uint8_t CXP0FB;
	uint8_t CXP1FB;
	uint8_t CXM0FB;
	uint8_t CXM1FB;
	uint8_t CXBLPF;
	uint8_t CXPPMM;
	uint8_t RESMP0;
	uint8_t RESMP1;
	uint8_t PF0;
	uint8_t PF1;
	uint8_t PF2;
	uint8_t INPT4;
	uint8_t INPT5;

	uint8_t prevGRP0;
	uint8_t prevGRP1;
	uint8_t prevENABL;

	int HMOVE_started;
	int HMOVE_started_previous;
	uint8_t HMP0_latch;
	uint8_t HMP1_latch;
	uint8_t HMM0_latch;
	uint8_t HMM1_latch;
	uint8_t HMBL_latch;
	uint8_t REFLECT;      /* Should playfield be reflected or not */
	uint8_t NUSIZx_changed;

	std::unique_ptr<bitmap_ind16> helper[3];

	uint16_t screen_height;

	void register_save_state();
};

class tia_pal_video_device : public tia_video_device
{
public:
	tia_pal_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

protected:
	virtual void device_add_mconfig(machine_config &config) override;

private:
	DECLARE_PALETTE_INIT(tia_pal);
};

class tia_ntsc_video_device : public tia_video_device
{
public:
	tia_ntsc_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

protected:
	virtual void device_add_mconfig(machine_config &config) override;

private:
	DECLARE_PALETTE_INIT(tia_ntsc);
};


// device type definition
DECLARE_DEVICE_TYPE(TIA_PAL_VIDEO, tia_pal_video_device)
DECLARE_DEVICE_TYPE(TIA_NTSC_VIDEO, tia_ntsc_video_device)

#endif // MAME_VIDEO_TIA_H