1 // license:BSD-3-Clause
2 // copyright-holders:Peter Trauner
3 /*****************************************************************************
4  *
5  * video/vic4567.h
6  *
7  ****************************************************************************/
8 
9 #ifndef MAME_VIDEO_VIC4567_H
10 #define MAME_VIDEO_VIC4567_H
11 
12 #pragma once
13 
14 
15 /***************************************************************************
16     TYPE DEFINITIONS
17 ***************************************************************************/
18 
19 
20 /***************************************************************************
21     CONSTANTS
22 ***************************************************************************/
23 
24 #define VIC6567_CLOCK       (1022700 /* = 8181600 / 8) */ )
25 #define VIC6569_CLOCK       ( 985248 /* = 7881984 / 8) */ )
26 
27 #define VIC6567_CYCLESPERLINE   65
28 #define VIC6569_CYCLESPERLINE   63
29 
30 #define VIC6567_LINES       263
31 #define VIC6569_LINES       312
32 
33 #define VIC6567_VRETRACERATE    (59.8245100906698 /* = 1022700 / (65 * 263) */ )
34 #define VIC6569_VRETRACERATE    (50.1245421245421 /* =  985248 / (63 * 312) */ )
35 
36 #define VIC6567_HRETRACERATE    (VIC6567_CLOCK / VIC6567_CYCLESPERLINE)
37 #define VIC6569_HRETRACERATE    (VIC6569_CLOCK / VIC6569_CYCLESPERLINE)
38 
39 #define VIC2_HSIZE      320
40 #define VIC2_VSIZE      200
41 
42 #define VIC6567_VISIBLELINES    235
43 #define VIC6569_VISIBLELINES    284
44 
45 #define VIC6567_FIRST_DMA_LINE  0x30
46 #define VIC6569_FIRST_DMA_LINE  0x30
47 
48 #define VIC6567_LAST_DMA_LINE   0xf7
49 #define VIC6569_LAST_DMA_LINE   0xf7
50 
51 #define VIC6567_FIRST_DISP_LINE 0x29
52 #define VIC6569_FIRST_DISP_LINE 0x10
53 
54 #define VIC6567_LAST_DISP_LINE  (VIC6567_FIRST_DISP_LINE + VIC6567_VISIBLELINES - 1)
55 #define VIC6569_LAST_DISP_LINE  (VIC6569_FIRST_DISP_LINE + VIC6569_VISIBLELINES - 1)
56 
57 #define VIC6567_RASTER_2_EMU(a) ((a >= VIC6567_FIRST_DISP_LINE) ? (a - VIC6567_FIRST_DISP_LINE) : (a + 222))
58 #define VIC6569_RASTER_2_EMU(a) (a - VIC6569_FIRST_DISP_LINE)
59 
60 #define VIC6567_FIRSTCOLUMN 50
61 #define VIC6569_FIRSTCOLUMN 50
62 
63 #define VIC6567_VISIBLECOLUMNS  418
64 #define VIC6569_VISIBLECOLUMNS  403
65 
66 #define VIC6567_X_2_EMU(a)  (a)
67 #define VIC6569_X_2_EMU(a)  (a)
68 
69 #define VIC6567_STARTVISIBLELINES ((VIC6567_LINES - VIC6567_VISIBLELINES)/2)
70 #define VIC6569_STARTVISIBLELINES 16 /* ((VIC6569_LINES - VIC6569_VISIBLELINES)/2) */
71 
72 #define VIC6567_FIRSTRASTERLINE 34
73 #define VIC6569_FIRSTRASTERLINE 0
74 
75 #define VIC6567_COLUMNS 512
76 #define VIC6569_COLUMNS 504
77 
78 
79 #define VIC6567_STARTVISIBLECOLUMNS ((VIC6567_COLUMNS - VIC6567_VISIBLECOLUMNS)/2)
80 #define VIC6569_STARTVISIBLECOLUMNS ((VIC6569_COLUMNS - VIC6569_VISIBLECOLUMNS)/2)
81 
82 #define VIC6567_FIRSTRASTERCOLUMNS 412
83 #define VIC6569_FIRSTRASTERCOLUMNS 404
84 
85 #define VIC6569_FIRST_X 0x194
86 #define VIC6567_FIRST_X 0x19c
87 
88 #define VIC6569_FIRST_VISIBLE_X 0x1e0
89 #define VIC6567_FIRST_VISIBLE_X 0x1e8
90 
91 #define VIC6569_MAX_X 0x1f7
92 #define VIC6567_MAX_X 0x1ff
93 
94 #define VIC6569_LAST_VISIBLE_X 0x17c
95 #define VIC6567_LAST_VISIBLE_X 0x184
96 
97 #define VIC6569_LAST_X 0x193
98 #define VIC6567_LAST_X 0x19b
99 
100 /***************************************************************************
101     DEVICE CONFIGURATION MACROS
102 ***************************************************************************/
103 
104 class vic3_device : public device_t,
105 					public device_palette_interface,
106 					public device_video_interface
107 {
108 public:
109 	enum class vic3_type { NTSC, PAL };
110 
111 	vic3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
112 
set_cpu_tag(T && tag)113 	template <typename T> void set_cpu_tag(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); }
set_vic3_type(vic3_type type)114 	void set_vic3_type(vic3_type type) { m_type = type; }
dma_read_callback()115 	auto dma_read_callback() { return m_dma_read_cb.bind(); }
dma_read_color_callback()116 	auto dma_read_color_callback() { return m_dma_read_color_cb.bind(); }
interrupt_callback()117 	auto interrupt_callback() { return m_interrupt_cb.bind(); }
port_changed_callback()118 	auto port_changed_callback() { return m_port_changed_cb.bind(); }
lightpen_button_callback()119 	auto lightpen_button_callback() { return m_lightpen_button_cb.bind(); }
lightpen_x_callback()120 	auto lightpen_x_callback() { return m_lightpen_x_cb.bind(); }
lightpen_y_callback()121 	auto lightpen_y_callback() { return m_lightpen_y_cb.bind(); }
c64_mem_r_callback()122 	auto c64_mem_r_callback() { return m_c64_mem_r_cb.bind(); }
123 
124 	void port_w(offs_t offset, uint8_t data);
125 	void palette_w(offs_t offset, uint8_t data);
126 	uint8_t port_r(offs_t offset);
127 
128 	void raster_interrupt_gen();
129 	uint32_t video_update(bitmap_ind16 &bitmap, const rectangle &cliprect);
130 
131 protected:
132 	// device-level overrides
133 	virtual void device_start() override;
134 	virtual void device_reset() override;
135 
136 	// device_palette_interface override
palette_entries()137 	virtual uint32_t palette_entries() const override { return 0x100; }
138 
139 private:
140 	static constexpr unsigned SPRITE_BASE_X_SIZE = 24;
141 	static constexpr unsigned SPRITE_BASE_Y_SIZE = 21;
142 
143 	struct vic3_sprite
144 	{
145 		int x, y;
146 
147 		int repeat;                         /* expand, line once drawn */
148 		int line;                           /* 0 not painting, else painting */
149 
150 		/* buffer for currently painted line */
151 		int paintedline[8];
152 		uint8_t bitmap[8][SPRITE_BASE_X_SIZE * 2 / 8 + 1  /*for simpler sprite collision detection*/];
153 	};
154 
155 	// internal state
156 	inline int getforeground(int y, int x);
157 	inline int getforeground16(int y, int x);
158 	void set_interrupt(int mask);
159 	void clear_interrupt(int mask);
160 	void draw_character(int ybegin, int yend, int ch, int yoff, int xoff, uint16_t *color, int start_x, int end_x);
161 	void draw_character_multi(int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x);
162 	void draw_bitmap(int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x);
163 	void draw_bitmap_multi(int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x);
164 	void draw_sprite_code(int y, int xbegin, int code, int color, int start_x, int end_x);
165 	void draw_sprite_code_multi(int y, int xbegin, int code, int prior, int start_x, int end_x);
166 	void sprite_collision(int nr, int y, int x, int mask);
167 	void draw_sprite(int nr, int yoff, int ybegin, int yend, int start_x, int end_x);
168 	void draw_sprite_multi(int nr, int yoff, int ybegin, int yend, int start_x, int end_x);
169 	void drawlines(int first, int last, int start_x, int end_x);
170 	void vic2_drawlines(int first, int last, int start_x, int end_x);
171 	void interlace_draw_block(int x, int y, int offset);
172 	void draw_block(int x, int y, int offset);
173 	void draw_bitplanes();
174 
175 	TIMER_CALLBACK_MEMBER(timer_timeout);
176 
177 	vic3_type  m_type;
178 
179 	required_device<cpu_device> m_cpu;
180 
181 	uint8_t m_reg[0x80];
182 	int m_on;                             /* rastering of the screen */
183 
184 	int m_lines;
185 
186 	uint16_t m_chargenaddr, m_videoaddr, m_bitmapaddr;
187 
188 	std::unique_ptr<bitmap_ind16> m_bitmap;
189 	int m_x_begin, m_x_end;
190 	int m_y_begin, m_y_end;
191 
192 	uint16_t m_c64_bitmap[2], m_bitmapmulti[4], m_mono[2], m_multi[4], m_ecmcolor[2], m_colors[4], m_spritemulti[4];
193 
194 	int m_lastline, m_rasterline;
195 
196 	int m_interlace;
197 	int m_columns, m_rows;
198 
199 	/* background/foreground for sprite collision */
200 	uint8_t *m_screenptr[216], m_shift[216];
201 
202 	/* convert multicolor byte to background/foreground for sprite collision */
203 	uint8_t m_foreground[256];
204 	uint16_t m_expandx[256];
205 	uint16_t m_expandx_multi[256];
206 
207 	/* converts sprite multicolor info to info for background collision checking */
208 	uint8_t m_multi_collision[256];
209 
210 	vic3_sprite m_sprites[8];
211 
212 	/* DMA */
213 	devcb_read8    m_dma_read_cb;
214 	devcb_read8    m_dma_read_color_cb;
215 
216 	/* IRQ */
217 	devcb_write_line m_interrupt_cb;
218 
219 	/* Port Changed */
220 	devcb_write8   m_port_changed_cb;
221 
222 	/* lightpen */
223 	devcb_read8 m_lightpen_button_cb;
224 	devcb_read8 m_lightpen_x_cb;
225 	devcb_read8 m_lightpen_y_cb;
226 
227 	/* C64 memory access */
228 	devcb_read8      m_c64_mem_r_cb;
229 
230 	/* palette - vic3 specific items (the ones above are used for VIC II as well) */
231 	uint8_t m_palette_red[0x100];
232 	uint8_t m_palette_green[0x100];
233 	uint8_t m_palette_blue[0x100];
234 	int m_palette_dirty;
235 };
236 
237 DECLARE_DEVICE_TYPE(VIC3, vic3_device)
238 
239 #endif // MAME_VIDEO_VIC4567_H
240