summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/vic4567.h
blob: e680a3ff0cff14ba5a7843ddf018fc91a687d7c7 (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
// license:BSD-3-Clause
// copyright-holders:Peter Trauner
/*****************************************************************************
 *
 * video/vic4567.h
 *
 ****************************************************************************/

#ifndef MAME_VIDEO_VIC4567_H
#define MAME_VIDEO_VIC4567_H

#pragma once


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


/***************************************************************************
    CONSTANTS
***************************************************************************/

#define VIC6567_CLOCK       (1022700 /* = 8181600 / 8) */ )
#define VIC6569_CLOCK       ( 985248 /* = 7881984 / 8) */ )

#define VIC6567_CYCLESPERLINE   65
#define VIC6569_CYCLESPERLINE   63

#define VIC6567_LINES       263
#define VIC6569_LINES       312

#define VIC6567_VRETRACERATE    (59.8245100906698 /* = 1022700 / (65 * 263) */ )
#define VIC6569_VRETRACERATE    (50.1245421245421 /* =  985248 / (63 * 312) */ )

#define VIC6567_HRETRACERATE    (VIC6567_CLOCK / VIC6567_CYCLESPERLINE)
#define VIC6569_HRETRACERATE    (VIC6569_CLOCK / VIC6569_CYCLESPERLINE)

#define VIC2_HSIZE      320
#define VIC2_VSIZE      200

#define VIC6567_VISIBLELINES    235
#define VIC6569_VISIBLELINES    284

#define VIC6567_FIRST_DMA_LINE  0x30
#define VIC6569_FIRST_DMA_LINE  0x30

#define VIC6567_LAST_DMA_LINE   0xf7
#define VIC6569_LAST_DMA_LINE   0xf7

#define VIC6567_FIRST_DISP_LINE 0x29
#define VIC6569_FIRST_DISP_LINE 0x10

#define VIC6567_LAST_DISP_LINE  (VIC6567_FIRST_DISP_LINE + VIC6567_VISIBLELINES - 1)
#define VIC6569_LAST_DISP_LINE  (VIC6569_FIRST_DISP_LINE + VIC6569_VISIBLELINES - 1)

#define VIC6567_RASTER_2_EMU(a) ((a >= VIC6567_FIRST_DISP_LINE) ? (a - VIC6567_FIRST_DISP_LINE) : (a + 222))
#define VIC6569_RASTER_2_EMU(a) (a - VIC6569_FIRST_DISP_LINE)

#define VIC6567_FIRSTCOLUMN 50
#define VIC6569_FIRSTCOLUMN 50

#define VIC6567_VISIBLECOLUMNS  418
#define VIC6569_VISIBLECOLUMNS  403

#define VIC6567_X_2_EMU(a)  (a)
#define VIC6569_X_2_EMU(a)  (a)

#define VIC6567_STARTVISIBLELINES ((VIC6567_LINES - VIC6567_VISIBLELINES)/2)
#define VIC6569_STARTVISIBLELINES 16 /* ((VIC6569_LINES - VIC6569_VISIBLELINES)/2) */

#define VIC6567_FIRSTRASTERLINE 34
#define VIC6569_FIRSTRASTERLINE 0

#define VIC6567_COLUMNS 512
#define VIC6569_COLUMNS 504


#define VIC6567_STARTVISIBLECOLUMNS ((VIC6567_COLUMNS - VIC6567_VISIBLECOLUMNS)/2)
#define VIC6569_STARTVISIBLECOLUMNS ((VIC6569_COLUMNS - VIC6569_VISIBLECOLUMNS)/2)

#define VIC6567_FIRSTRASTERCOLUMNS 412
#define VIC6569_FIRSTRASTERCOLUMNS 404

#define VIC6569_FIRST_X 0x194
#define VIC6567_FIRST_X 0x19c

#define VIC6569_FIRST_VISIBLE_X 0x1e0
#define VIC6567_FIRST_VISIBLE_X 0x1e8

#define VIC6569_MAX_X 0x1f7
#define VIC6567_MAX_X 0x1ff

#define VIC6569_LAST_VISIBLE_X 0x17c
#define VIC6567_LAST_VISIBLE_X 0x184

#define VIC6569_LAST_X 0x193
#define VIC6567_LAST_X 0x19b

/***************************************************************************
    DEVICE CONFIGURATION MACROS
***************************************************************************/

class vic3_device : public device_t,
					public device_palette_interface,
					public device_video_interface
{
public:
	enum class vic3_type { NTSC, PAL };

	vic3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void set_cpu_tag(const char *tag) { m_cpu.set_tag(tag); }
	void set_vic3_type(vic3_type type) { m_type = type; }
	template <class Object> devcb_base &set_dma_read_callback(Object &&cb) { return m_dma_read_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_dma_read_color_callback(Object &&cb) { return m_dma_read_color_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_interrupt_callback(Object &&cb) { return m_interrupt_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_port_changed_callback(Object &&cb) { return m_port_changed_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_lightpen_button_callback(Object &&cb) { return m_lightpen_button_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_lightpen_x_callback(Object &&cb) { return m_lightpen_x_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_lightpen_y_callback(Object &&cb) { return m_lightpen_y_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_c64_mem_r_callback(Object &&cb) { return m_c64_mem_r_cb.set_callback(std::forward<Object>(cb)); }

	DECLARE_WRITE8_MEMBER(port_w);
	DECLARE_WRITE8_MEMBER(palette_w);
	DECLARE_READ8_MEMBER(port_r);

	void raster_interrupt_gen();
	uint32_t video_update(bitmap_ind16 &bitmap, const rectangle &cliprect);

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

	// device_palette_interface override
	virtual uint32_t palette_entries() const override { return 0x100; }

private:
	static constexpr unsigned SPRITE_BASE_X_SIZE = 24;
	static constexpr unsigned SPRITE_BASE_Y_SIZE = 21;

	struct vic3_sprite
	{
		int x, y;

		int repeat;                         /* expand, line once drawn */
		int line;                           /* 0 not painting, else painting */

		/* buffer for currently painted line */
		int paintedline[8];
		uint8_t bitmap[8][SPRITE_BASE_X_SIZE * 2 / 8 + 1  /*for simpler sprite collision detection*/];
	};

	// internal state
	inline int getforeground(int y, int x);
	inline int getforeground16(int y, int x);
	void set_interrupt(int mask);
	void clear_interrupt(int mask);
	void draw_character(int ybegin, int yend, int ch, int yoff, int xoff, uint16_t *color, int start_x, int end_x);
	void draw_character_multi(int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x);
	void draw_bitmap(int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x);
	void draw_bitmap_multi(int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x);
	void draw_sprite_code(int y, int xbegin, int code, int color, int start_x, int end_x);
	void draw_sprite_code_multi(int y, int xbegin, int code, int prior, int start_x, int end_x);
	void sprite_collision(int nr, int y, int x, int mask);
	void draw_sprite(int nr, int yoff, int ybegin, int yend, int start_x, int end_x);
	void draw_sprite_multi(int nr, int yoff, int ybegin, int yend, int start_x, int end_x);
	void drawlines(int first, int last, int start_x, int end_x);
	void vic2_drawlines(int first, int last, int start_x, int end_x);
	void interlace_draw_block(int x, int y, int offset);
	void draw_block(int x, int y, int offset);
	void draw_bitplanes();

	TIMER_CALLBACK_MEMBER(timer_timeout);

	vic3_type  m_type;

	required_device<cpu_device> m_cpu;

	uint8_t m_reg[0x80];
	int m_on;                             /* rastering of the screen */

	int m_lines;

	uint16_t m_chargenaddr, m_videoaddr, m_bitmapaddr;

	std::unique_ptr<bitmap_ind16> m_bitmap;
	int m_x_begin, m_x_end;
	int m_y_begin, m_y_end;

	uint16_t m_c64_bitmap[2], m_bitmapmulti[4], m_mono[2], m_multi[4], m_ecmcolor[2], m_colors[4], m_spritemulti[4];

	int m_lastline, m_rasterline;

	int m_interlace;
	int m_columns, m_rows;

	/* background/foreground for sprite collision */
	uint8_t *m_screenptr[216], m_shift[216];

	/* convert multicolor byte to background/foreground for sprite collision */
	uint8_t m_foreground[256];
	uint16_t m_expandx[256];
	uint16_t m_expandx_multi[256];

	/* converts sprite multicolor info to info for background collision checking */
	uint8_t m_multi_collision[256];

	vic3_sprite m_sprites[8];

	/* DMA */
	devcb_read8    m_dma_read_cb;
	devcb_read8    m_dma_read_color_cb;

	/* IRQ */
	devcb_write_line m_interrupt_cb;

	/* Port Changed */
	devcb_write8   m_port_changed_cb;

	/* lightpen */
	devcb_read8 m_lightpen_button_cb;
	devcb_read8 m_lightpen_x_cb;
	devcb_read8 m_lightpen_y_cb;

	/* C64 memory access */
	devcb_read8      m_c64_mem_r_cb;

	/* palette - vic3 specific items (the ones above are used for VIC II as well) */
	uint8_t m_palette_red[0x100];
	uint8_t m_palette_green[0x100];
	uint8_t m_palette_blue[0x100];
	int m_palette_dirty;
};

DECLARE_DEVICE_TYPE(VIC3, vic3_device)


#define MCFG_VIC3_CPU(tag) \
	downcast<vic3_device &>(*device).set_cpu_tag(tag);

#define MCFG_VIC3_TYPE(type) \
	downcast<vic3_device &>(*device).set_vic3_type((vic3_device::vic3_type::type));

#define MCFG_VIC3_DMA_READ_CB(cb) \
	downcast<vic3_device &>(*device).set_dma_read_callback((DEVCB_##cb));

#define MCFG_VIC3_DMA_READ_COLOR_CB(cb) \
	downcast<vic3_device &>(*device).set_dma_read_color_callback((DEVCB_##cb));

#define MCFG_VIC3_INTERRUPT_CB(cb) \
	downcast<vic3_device &>(*device).set_interrupt_callback((DEVCB_##cb));

#define MCFG_VIC3_PORT_CHANGED_CB(cb) \
	downcast<vic3_device &>(*device).set_port_changed_callback((DEVCB_##cb));

#define MCFG_VIC3_LIGHTPEN_BUTTON_CB(cb) \
	downcast<vic3_device &>(*device).set_lightpen_button_callback((DEVCB_##cb));

#define MCFG_VIC3_LIGHTPEN_X_CB(cb) \
	downcast<vic3_device &>(*device).set_lightpen_x_callback((DEVCB_##cb));

#define MCFG_VIC3_LIGHTPEN_Y_CB(cb) \
	downcast<vic3_device &>(*device).set_lightpen_y_callback((DEVCB_##cb));

#define MCFG_VIC3_C64_MEM_R_CB(cb) \
	downcast<vic3_device &>(*device).set_c64_mem_r_callback((DEVCB_##cb));

#endif // MAME_VIDEO_VIC4567_H