1 // license:BSD-3-Clause
2 // copyright-holders:Luca Elia,David Haywood,Angelo Salese
3 /***************************************************************************
4 
5     Imagetek I4100 / I4220 / I4300 device files
6 
7 ***************************************************************************/
8 
9 #ifndef MAME_VIDEO_I4100_H
10 #define MAME_VIDEO_I4100_H
11 
12 #pragma once
13 
14 #include "emupal.h"
15 #include "screen.h"
16 #include "video/bufsprite.h"
17 
18 
19 //**************************************************************************
20 //  TYPE DEFINITIONS
21 //**************************************************************************
22 
23 // ======================> i4100_device
24 
25 class imagetek_i4100_device : public device_t,
26 							  public device_gfx_interface,
27 							  public device_video_interface
28 {
29 public:
30 	// construction/destruction
31 	imagetek_i4100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
32 
33 	void map(address_map &map);
34 
set_tmap_flip_xoffsets(int x1,int x2,int x3)35 	void set_tmap_flip_xoffsets(int x1, int x2, int x3) { m_tilemap_flip_scrolldx[0] = x1; m_tilemap_flip_scrolldx[1] = x2; m_tilemap_flip_scrolldx[2] = x3; }
set_tmap_flip_yoffsets(int y1,int y2,int y3)36 	void set_tmap_flip_yoffsets(int y1, int y2, int y3) { m_tilemap_flip_scrolldy[0] = y1; m_tilemap_flip_scrolldy[1] = y2; m_tilemap_flip_scrolldy[2] = y3; }
set_tmap_xoffsets(int x1,int x2,int x3)37 	void set_tmap_xoffsets(int x1, int x2, int x3)
38 	{
39 		m_tilemap_scrolldx[0] = x1;
40 		m_tilemap_scrolldx[1] = x2;
41 		m_tilemap_scrolldx[2] = x3;
42 		// default flip xoffset
43 		set_tmap_flip_xoffsets(-x1, -x2, -x3);
44 	}
set_tmap_yoffsets(int y1,int y2,int y3)45 	void set_tmap_yoffsets(int y1, int y2, int y3)
46 	{
47 		m_tilemap_scrolldy[0] = y1;
48 		m_tilemap_scrolldy[1] = y2;
49 		m_tilemap_scrolldy[2] = y3;
50 		// default flip yoffset
51 		set_tmap_flip_yoffsets(-y1, -y2, -y3);
52 	}
53 
blit_irq_cb()54 	auto blit_irq_cb() { return m_blit_irq_cb.bind(); }
set_spriteram_buffered(bool buffer)55 	void set_spriteram_buffered(bool buffer) { m_spriteram_buffered = buffer; }
56 
57 	u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
58 	void draw_foreground(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
59 	DECLARE_WRITE_LINE_MEMBER(screen_eof);
60 
61 protected:
62 	imagetek_i4100_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool has_ext_tiles);
63 
64 	// device-level overrides
65 	//virtual void device_validity_check(validity_checker &valid) const override;
66 	virtual void device_add_mconfig(machine_config &config) override;
67 	virtual void device_start() override;
68 	virtual void device_reset() override;
69 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
70 
71 	required_shared_ptr_array<u16, 3> m_vram;
72 	required_shared_ptr<u16> m_scratchram;
73 	required_shared_ptr<u16> m_blitter_regs;
74 	required_device<buffered_spriteram16_device> m_spriteram;
75 	required_shared_ptr<u16> m_tiletable;
76 	required_shared_ptr<u16> m_window;
77 	required_shared_ptr<u16> m_scroll;
78 
79 	required_device<palette_device> m_palette;
80 	required_region_ptr<u8> m_gfxrom;
81 
82 	std::unique_ptr<u8[]>   m_expanded_gfx1;
83 
84 	devcb_write_line m_blit_irq_cb;
85 
86 	struct sprite_t
87 	{
88 		int x, y;
89 		u32 gfxstart;
90 		int width, height;
91 		int flipx, flipy;
92 		u16 color;
93 		u32 zoom;
94 		int curr_pri;
95 	};
96 
97 	std::unique_ptr<sprite_t []> m_spritelist;
98 	const sprite_t *m_sprite_end;
99 
100 	u16 m_rombank;
101 	size_t m_gfxrom_size;
102 	bool m_crtc_unlock;
103 	u16 m_sprite_count;
104 	u16 m_sprite_priority;
105 	u16 m_sprite_xoffset,m_sprite_yoffset;
106 	u16 m_sprite_color_code;
107 	u8 m_layer_priority[3];
108 	u16 m_background_color;
109 	u16 m_screen_xoffset,m_screen_yoffset;
110 	bool m_layer_tile_select[3];
111 	bool m_screen_blank;
112 	bool m_screen_flip;
113 	const bool m_support_8bpp, m_support_16x16;
114 	int  m_tilemap_scrolldx[3];
115 	int  m_tilemap_scrolldy[3];
116 	int  m_tilemap_flip_scrolldx[3];
117 	int  m_tilemap_flip_scrolldy[3];
118 	bool m_spriteram_buffered;
119 
120 	void blt_write(const int tmap, const offs_t offs, const u16 data, const u16 mask);
121 
122 	enum
123 	{
124 		TIMER_BLIT_END = 1
125 	};
126 
127 	emu_timer *m_blit_done_timer;
128 
129 	// I/O operations
vram_r(offs_t offset,int layer)130 	inline u16 vram_r(offs_t offset, int layer) { return m_vram[layer][offset]; }
vram_w(offs_t offset,u16 data,u16 mem_mask,int layer)131 	inline void vram_w(offs_t offset, u16 data, u16 mem_mask, int layer) { COMBINE_DATA(&m_vram[layer][offset]); }
132 	uint16_t vram_0_r(offs_t offset);
133 	uint16_t vram_1_r(offs_t offset);
134 	uint16_t vram_2_r(offs_t offset);
135 	void vram_0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
136 	void vram_1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
137 	void vram_2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
138 	uint16_t rmw_vram_0_r(offs_t offset);
139 	uint16_t rmw_vram_1_r(offs_t offset);
140 	uint16_t rmw_vram_2_r(offs_t offset);
141 	void rmw_vram_0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
142 	void rmw_vram_1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
143 	void rmw_vram_2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
144 	uint16_t scratchram_r(offs_t offset);
145 	void scratchram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
146 	uint16_t spriteram_r(offs_t offset);
147 	void spriteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
148 	uint16_t tiletable_r(offs_t offset);
149 	void tiletable_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
150 	uint16_t sprite_count_r();
151 	void sprite_count_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
152 	uint16_t sprite_priority_r();
153 	void sprite_priority_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
154 	uint16_t sprite_xoffset_r();
155 	void sprite_xoffset_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
156 	uint16_t sprite_yoffset_r();
157 	void sprite_yoffset_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
158 	uint16_t sprite_color_code_r();
159 	void sprite_color_code_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
160 	uint16_t layer_priority_r();
161 	void layer_priority_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
162 	uint16_t background_color_r();
163 	void background_color_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
164 
165 	uint16_t screen_xoffset_r();
166 	void screen_xoffset_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
167 	uint16_t screen_yoffset_r();
168 	void screen_yoffset_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
169 
170 	uint16_t window_r(offs_t offset);
171 	void window_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
172 	uint16_t scroll_r(offs_t offset);
173 	void scroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
174 
175 
176 	uint16_t gfxrom_r(offs_t offset);
177 	void crtc_vert_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
178 	void crtc_horz_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
179 	void crtc_unlock_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
180 	void blitter_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
181 	void screen_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
182 	void rombank_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
183 
184 	void draw_layers(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri);
185 	inline u8 get_tile_pix(u16 code, u8 x, u8 y, bool const big, u32 &pix);
186 	void draw_tilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 flags, u32 const pcode,
187 					int sx, int sy, int wx, int wy, bool const big, int const layer);
188 	void draw_spritegfx(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &clip,
189 					u32 const gfxstart, u16 const width, u16 const height,
190 					u16 color, int const flipx, int const flipy, int sx, int sy,
191 					u32 const scale, u8 const prival);
192 	void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
193 	void expand_gfx1();
194 
195 // A 2048 x 2048 virtual tilemap
196 	static constexpr u32 BIG_NX = (0x100);
197 	static constexpr u32 BIG_NY = (0x100);
198 
199 // A smaller 512 x 256 window defines the actual tilemap
200 	static constexpr u32 WIN_NX = (0x40);
201 	static constexpr u32 WIN_NY = (0x20);
202 
203 	bool m_inited_hack;
204 	DECLARE_GFXDECODE_MEMBER(gfxinfo);
205 	DECLARE_GFXDECODE_MEMBER(gfxinfo_ext);
206 };
207 
208 class imagetek_i4220_device : public imagetek_i4100_device
209 {
210 public:
211 	// construction/destruction
212 	imagetek_i4220_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
213 
214 	// needed by Blazing Tornado / Grand Striker 2 for mixing with PSAC
215 	// (it's unknown how the chip enables external sync)
get_background_pen()216 	u32 get_background_pen() { return m_palette->pen(m_background_color); };
217 
218 	void v2_map(address_map &map);
219 };
220 
221 class imagetek_i4300_device : public imagetek_i4100_device
222 {
223 public:
224 	// construction/destruction
225 	imagetek_i4300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
226 
227 	void v3_map(address_map &map);
228 };
229 
230 // device type definition
231 DECLARE_DEVICE_TYPE(I4100, imagetek_i4100_device)
232 DECLARE_DEVICE_TYPE(I4220, imagetek_i4220_device)
233 DECLARE_DEVICE_TYPE(I4300, imagetek_i4300_device)
234 
235 
236 
237 //**************************************************************************
238 //  GLOBAL VARIABLES
239 //**************************************************************************
240 
241 
242 #endif // MAME_VIDEO_I4100_H
243