1 #include "driver.h"
2 
3 
4 extern unsigned char *taitol_rambanks;
5 
6 static struct tilemap *bg18_tilemap;
7 static struct tilemap *bg19_tilemap;
8 static struct tilemap *ch1a_tilemap;
9 
10 static int cur_ctrl = 0;
11 static int horshoes_gfxbank = 0;
12 static int bankc[4];
13 static int flipscreen;
14 #define SPRITERAM_SIZE 0x400
15 static unsigned char buffered_spriteram[SPRITERAM_SIZE];
16 
17 
18 /***************************************************************************
19 
20   Callbacks for the TileMap code
21 
22 ***************************************************************************/
23 
get_bg18_tile_info(int tile_index)24 static void get_bg18_tile_info(int tile_index)
25 {
26 	int attr = taitol_rambanks[2*tile_index+0x4000+1];
27 	int code = taitol_rambanks[2*tile_index+0x4000]
28 			| ((attr & 0x03) << 8)
29 			| ((bankc[(attr & 0xc) >> 2]) << 10)
30 			| (horshoes_gfxbank << 12);
31 
32 	SET_TILE_INFO(
33 			0,
34 			code,
35 			(attr & 0xf0) >> 4)
36 }
37 
get_bg19_tile_info(int tile_index)38 static void get_bg19_tile_info(int tile_index)
39 {
40 	int attr = taitol_rambanks[2*tile_index+0x5000+1];
41 	int code = taitol_rambanks[2*tile_index+0x5000]
42 			| ((attr & 0x03) << 8)
43 			| ((bankc[(attr & 0xc) >> 2]) << 10)
44 			| (horshoes_gfxbank << 12);
45 
46 	SET_TILE_INFO(
47 			0,
48 			code,
49 			(attr & 0xf0) >> 4)
50 }
51 
get_ch1a_tile_info(int tile_index)52 static void get_ch1a_tile_info(int tile_index)
53 {
54 	int attr = taitol_rambanks[2*tile_index+0x6000+1];
55 	int code = taitol_rambanks[2*tile_index+0x6000]|((attr&0x01)<<8)|((attr&0x04)<<7);
56 
57 	SET_TILE_INFO(
58 			2,
59 			code,
60 			(attr & 0xf0) >> 4)
61 }
62 
63 
64 
65 /***************************************************************************
66 
67   Start the video hardware emulation.
68 
69 ***************************************************************************/
70 
taitol_vh_start(void)71 int taitol_vh_start(void)
72 {
73 	int i;
74 
75 	bg18_tilemap = tilemap_create(get_bg18_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
76 	bg19_tilemap = tilemap_create(get_bg19_tile_info,tilemap_scan_rows,TILEMAP_OPAQUE,     8,8,64,32);
77 	ch1a_tilemap = tilemap_create(get_ch1a_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
78 
79 	if (!ch1a_tilemap || !bg18_tilemap || !bg19_tilemap)
80 		return 1;
81 
82 	bankc[0] = bankc[1] = bankc[2] = bankc[3] = 0;
83 	horshoes_gfxbank = 0;
84 	cur_ctrl = 0;
85 
86 	tilemap_set_transparent_pen(bg18_tilemap,0);
87 	tilemap_set_transparent_pen(ch1a_tilemap,0);
88 
89 	for (i=0;i<256;i++)
90 		palette_change_color(i, 0, 0, 0);
91 
92 	tilemap_set_scrolldx(ch1a_tilemap,-8,-8);
93 	tilemap_set_scrolldx(bg18_tilemap,28,-11);
94 	tilemap_set_scrolldx(bg19_tilemap,38,-21);
95 
96 	return 0;
97 }
98 
99 
100 
101 /***************************************************************************
102 
103   Memory handlers
104 
105 ***************************************************************************/
106 
WRITE_HANDLER(horshoes_bankg_w)107 WRITE_HANDLER( horshoes_bankg_w )
108 {
109 	if (horshoes_gfxbank != data)
110 	{
111 		horshoes_gfxbank = data;
112 
113 		tilemap_mark_all_tiles_dirty(bg18_tilemap);
114 		tilemap_mark_all_tiles_dirty(bg19_tilemap);
115 	}
116 }
117 
WRITE_HANDLER(taitol_bankc_w)118 WRITE_HANDLER( taitol_bankc_w )
119 {
120 	if (bankc[offset] != data)
121 	{
122 		bankc[offset] = data;
123 //		logerror("Bankc %d, %02x (%04x)\n", offset, data, cpu_get_pc());
124 
125 		tilemap_mark_all_tiles_dirty(bg18_tilemap);
126 		tilemap_mark_all_tiles_dirty(bg19_tilemap);
127 	}
128 }
129 
READ_HANDLER(taitol_bankc_r)130 READ_HANDLER( taitol_bankc_r )
131 {
132 	return bankc[offset];
133 }
134 
135 
WRITE_HANDLER(taitol_control_w)136 WRITE_HANDLER( taitol_control_w )
137 {
138 //	logerror("Control Write %02x (%04x)\n", data, cpu_get_pc());
139 
140 	cur_ctrl = data;
141 //usrintf_showmessage("%02x",data);
142 
143 	/* bit 0 unknown */
144 
145 	/* bit 1 unknown */
146 
147 	/* bit 3 controls sprite/tile priority - handled in vh_screenrefresh() */
148 
149 	/* bit 4 flip screen */
150 	flipscreen = data & 0x10;
151 	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
152 
153 	/* bit 5 display enable - handled in vh_screenrefresh() */
154 }
155 
READ_HANDLER(taitol_control_r)156 READ_HANDLER( taitol_control_r )
157 {
158 //	logerror("Control Read %02x (%04x)\n", cur_ctrl, cpu_get_pc());
159 	return cur_ctrl;
160 }
161 
taitol_chardef14_m(int offset)162 void taitol_chardef14_m(int offset)
163 {
164 	decodechar(Machine->gfx[2], offset/32,     taitol_rambanks,
165 			   Machine->drv->gfxdecodeinfo[2].gfxlayout);
166 	tilemap_mark_all_tiles_dirty(ch1a_tilemap);
167 }
168 
taitol_chardef15_m(int offset)169 void taitol_chardef15_m(int offset)
170 {
171 	decodechar(Machine->gfx[2], offset/32+128, taitol_rambanks,
172 			   Machine->drv->gfxdecodeinfo[2].gfxlayout);
173 	tilemap_mark_all_tiles_dirty(ch1a_tilemap);
174 }
175 
taitol_chardef16_m(int offset)176 void taitol_chardef16_m(int offset)
177 {
178 	decodechar(Machine->gfx[2], offset/32+256, taitol_rambanks,
179 			   Machine->drv->gfxdecodeinfo[2].gfxlayout);
180 	tilemap_mark_all_tiles_dirty(ch1a_tilemap);
181 }
182 
taitol_chardef17_m(int offset)183 void taitol_chardef17_m(int offset)
184 {
185 	decodechar(Machine->gfx[2], offset/32+384, taitol_rambanks,
186 			   Machine->drv->gfxdecodeinfo[2].gfxlayout);
187 	tilemap_mark_all_tiles_dirty(ch1a_tilemap);
188 }
189 
taitol_chardef1c_m(int offset)190 void taitol_chardef1c_m(int offset)
191 {
192 	decodechar(Machine->gfx[2], offset/32+512, taitol_rambanks + 0x4000,
193 			   Machine->drv->gfxdecodeinfo[2].gfxlayout);
194 	tilemap_mark_all_tiles_dirty(ch1a_tilemap);
195 }
196 
taitol_chardef1d_m(int offset)197 void taitol_chardef1d_m(int offset)
198 {
199 	decodechar(Machine->gfx[2], offset/32+640, taitol_rambanks + 0x4000,
200 			   Machine->drv->gfxdecodeinfo[2].gfxlayout);
201 	tilemap_mark_all_tiles_dirty(ch1a_tilemap);
202 }
203 
taitol_chardef1e_m(int offset)204 void taitol_chardef1e_m(int offset)
205 {
206 	decodechar(Machine->gfx[2], offset/32+768, taitol_rambanks + 0x4000,
207 			   Machine->drv->gfxdecodeinfo[2].gfxlayout);
208 	tilemap_mark_all_tiles_dirty(ch1a_tilemap);
209 }
210 
taitol_chardef1f_m(int offset)211 void taitol_chardef1f_m(int offset)
212 {
213 	decodechar(Machine->gfx[2], offset/32+896, taitol_rambanks + 0x4000,
214 			   Machine->drv->gfxdecodeinfo[2].gfxlayout);
215 	tilemap_mark_all_tiles_dirty(ch1a_tilemap);
216 }
217 
taitol_bg18_m(int offset)218 void taitol_bg18_m(int offset)
219 {
220 	tilemap_mark_tile_dirty(bg18_tilemap,offset/2);
221 }
222 
taitol_bg19_m(int offset)223 void taitol_bg19_m(int offset)
224 {
225 	tilemap_mark_tile_dirty(bg19_tilemap,offset/2);
226 }
227 
taitol_char1a_m(int offset)228 void taitol_char1a_m(int offset)
229 {
230 	tilemap_mark_tile_dirty(ch1a_tilemap,offset/2);
231 }
232 
taitol_obj1b_m(int offset)233 void taitol_obj1b_m(int offset)
234 {
235 #if 0
236 	if (offset>=0x3f0 && offset<=0x3ff)
237 	{
238 		/* scroll, handled in vh-screenrefresh */
239 	}
240 #endif
241 }
242 
243 
244 
245 /***************************************************************************
246 
247   Display refresh
248 
249 ***************************************************************************/
250 
251 /*
252 	Sprite format:
253 	00: xxxxxxxx tile number (low)
254 	01: xxxxxxxx tile number (high)
255 	02: ----xxxx color
256 	    ----x--- priority
257 	03: -------x flip x
258 	    ------x- flip y
259 	04: xxxxxxxx x position (low)
260 	05: -------x x position (high)
261 	06: xxxxxxxx y position
262 	07: xxxxxxxx unknown / ignored? Seems just garbage in many cases, e.g
263 	             plgirs2 bullets and raimais big bosses.
264 */
265 
draw_sprites(struct osd_bitmap * bitmap)266 static void draw_sprites(struct osd_bitmap *bitmap)
267 {
268 	int offs;
269 
270 
271 	/* at spriteram + 0x3f0 and 03f8 are the tilemap control registers;
272 		spriteram + 0x3e8 seems to be unused
273 	*/
274 	for (offs = 0;offs < SPRITERAM_SIZE-3*8;offs += 8)
275 	{
276 		int code,color,sx,sy,flipx,flipy;
277 
278 		color = buffered_spriteram[offs + 2] & 0x0f;
279 		code = buffered_spriteram[offs] | (buffered_spriteram[offs + 1] << 8);
280 
281 		code |= (horshoes_gfxbank & 0x03) << 10;
282 
283 		sx = buffered_spriteram[offs + 4] | ((buffered_spriteram[offs + 5] & 1) << 8);
284 		sy = buffered_spriteram[offs + 6];
285 		if (sx >= 320) sx -= 512;
286 		flipx = buffered_spriteram[offs + 3] & 0x01;
287 		flipy = buffered_spriteram[offs + 3] & 0x02;
288 
289 		if (flipscreen)
290 		{
291 			sx = 304 - sx;
292 			sy = 240 - sy;
293 			flipx = !flipx;
294 			flipy = !flipy;
295 		}
296 
297 		pdrawgfx(bitmap,Machine->gfx[1],
298 				code,
299 				color,
300 				flipx,flipy,
301 				sx,sy,
302 				&Machine->visible_area,TRANSPARENCY_PEN,0,
303 				(color & 0x08) ? 0xaa : 0x00);
304 	}
305 }
306 
307 
taitol_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)308 void taitol_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
309 {
310 	int dx,dy;
311 
312 
313 	/* tilemap bug? If I do this just in vh_start(), it won't work */
314 	tilemap_set_scrollx(ch1a_tilemap,0,0);	/* won't change at run time */
315 
316 	dx = taitol_rambanks[0x73f4]|(taitol_rambanks[0x73f5]<<8);
317 	if (flipscreen)
318 		dx = ((dx & 0xfffc) | ((dx - 3) & 0x0003)) ^ 0xf;
319 	dy = taitol_rambanks[0x73f6];
320 	tilemap_set_scrollx(bg18_tilemap,0,-dx);
321 	tilemap_set_scrolly(bg18_tilemap,0,-dy);
322 
323 	dx = taitol_rambanks[0x73fc]|(taitol_rambanks[0x73fd]<<8);
324 	if (flipscreen)
325 		dx = ((dx & 0xfffc) | ((dx - 3) & 0x0003)) ^ 0xf;
326 	dy = taitol_rambanks[0x73fe];
327 	tilemap_set_scrollx(bg19_tilemap,0,-dx);
328 	tilemap_set_scrolly(bg19_tilemap,0,-dy);
329 
330 
331 	tilemap_update(ALL_TILEMAPS);
332 
333 	if (palette_recalc())
334 	        tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
335 
336 	tilemap_render(ALL_TILEMAPS);
337 
338 	if (cur_ctrl & 0x20)	/* display enable */
339 	{
340 		fillbitmap(priority_bitmap,0,NULL);
341 
342 		tilemap_draw(bitmap,bg19_tilemap,0);
343 
344 		if (cur_ctrl & 0x08)	/* sprites always over BG1 */
345 			tilemap_draw(bitmap,bg18_tilemap,0);
346 		else					/* split priority */
347 			tilemap_draw(bitmap,bg18_tilemap,1);
348 		draw_sprites(bitmap);
349 
350 		tilemap_draw(bitmap,ch1a_tilemap,0);
351 	}
352 	else
353 		fillbitmap(bitmap,Machine->pens[0],&Machine->visible_area);
354 }
355 
356 
357 
taitol_eof_callback(void)358 void taitol_eof_callback(void)
359 {
360 	unsigned char *spriteram = taitol_rambanks + 0x7000;
361 
362 	memcpy(buffered_spriteram,spriteram,SPRITERAM_SIZE);
363 }
364