1 /***************************************************************************
2 
3   Dec0 Video emulation - Bryan McPhail, mish@tendril.co.uk
4 
5 *********************************************************************
6 
7 	Each game uses the MXC-06 chip to produce sprites.
8 
9 	Sprite data:  The unknown bits seem to be unused.
10 
11 	Byte 0:
12 		Bit 0 : Y co-ord hi bit
13 		Bit 1,2: ?
14 		Bit 3,4 : Sprite height (1x, 2x, 4x, 8x)
15 		Bit 5  - X flip
16 		Bit 6  - Y flip
17 		Bit 7  - Only display Sprite if set
18 	Byte 1: Y-coords
19 	Byte 2:
20 		Bit 0,1,2,3: Hi bits of sprite number
21 		Bit 4,5,6,7: (Probably unused MSB's of sprite)
22 	Byte 3: Low bits of sprite number
23 	Byte 4:
24 		Bit 0 : X co-ords hi bit
25 		Bit 1,2: ??
26 		Bit 3: Sprite flash (sprite is displayed every other frame)
27 		Bit 4,5,6,7:  - Colour
28 	Byte 5: X-coords
29 
30 **********************************************************************
31 
32   Palette data
33 
34     0x000 - character palettes (Sprites on Midnight R)
35     0x200 - sprite palettes (Characters on Midnight R)
36     0x400 - tiles 1
37   	0x600 - tiles 2
38 
39 	Bad Dudes, Robocop, Heavy Barrel, Hippodrome - 24 bit rgb
40 	Sly Spy, Midnight Resistance - 12 bit rgb
41 
42   Tile data
43 
44   	4 bit palette select, 12 bit tile select
45 
46 **********************************************************************
47 
48  All games contain three BAC06 background generator chips, usual (software)
49 configuration is 2 chips of 16*16 tiles, 1 of 8*8.
50 
51  Playfield control registers:
52    bank 0:
53    0:
54 		bit 0 (0x1) set = 8*8 tiles, else 16*16 tiles
55 		Bit 1 (0x2) unknown
56 		bit 2 (0x4) set enables rowscroll
57 		bit 3 (0x8) set enables colscroll
58 		bit 7 (0x80) set in playfield 1 is reverse screen (set via dip-switch)
59 		bit 7 (0x80) in other playfields unknown
60    2: unknown (00 in bg, 03 in fg+text - maybe controls pf transparency?)
61    4: unknown (always 00)
62    6: playfield shape: 00 = 4x1, 01 = 2x2, 02 = 1x4 (low 4 bits only)
63 
64    bank 1:
65    0: horizontal scroll
66    2: vertical scroll
67    4: Style of colscroll (low 4 bits, top 4 bits do nothing)
68    6: Style of rowscroll (low 4 bits, top 4 bits do nothing)
69 
70 Rowscroll/Colscroll styles:
71 	0: 256 scroll registers (Robocop)
72 	1: 128 scroll registers
73 	2:  64 scroll registers
74 	3:  32 scroll registers (Heavy Barrel, Midres)
75 	4:  16 scroll registers (Bad Dudes, Sly Spy)
76 	5:   8 scroll registers (Hippodrome)
77 	6:   4 scroll registers (Heavy Barrel)
78 	7:   2 scroll registers (Heavy Barrel, used on other games but registers kept at 0)
79 	8:   1 scroll register (ie, none)
80 
81 	Values above are *multiplied* by playfield shape.
82 
83 Playfield priority (Bad Dudes, etc):
84 	In the bottommost playfield, pens 8-15 can have priority over the next playfield.
85 	In that next playfield, pens 8-15 can have priority over sprites.
86 
87 Bit 0:  Playfield inversion
88 Bit 1:  Enable playfield mixing (for palettes 8-15 only)
89 Bit 2:  Enable playfield/sprite mixing (for palettes 8-15 only)
90 
91 Priority word (Midres):
92 	Bit 0 set = Playfield 3 drawn over Playfield 2
93 			~ = Playfield 2 drawn over Playfield 3
94 	Bit 1 set = Sprites are drawn inbetween playfields
95 			~ = Sprites are on top of playfields
96 	Bit 2
97 	Bit 3 set = ...
98 
99 ***************************************************************************/
100 
101 #include "driver.h"
102 #include "vidhrdw/generic.h"
103 
104 #define TEXTRAM_SIZE	0x2000	/* Size of text layer */
105 #define TILERAM_SIZE	0x800	/* Size of background and foreground */
106 
107 /* Video */
108 unsigned char *dec0_pf1_data,*dec0_pf2_data,*dec0_pf3_data;
109 static unsigned char *dec0_pf1_dirty,*dec0_pf3_dirty,*dec0_pf2_dirty;
110 static struct osd_bitmap *dec0_pf1_bitmap;
111 static int dec0_pf1_current_shape;
112 static struct osd_bitmap *dec0_pf2_bitmap;
113 static int dec0_pf2_current_shape;
114 static struct osd_bitmap *dec0_pf3_bitmap;
115 static int dec0_pf3_current_shape;
116 static struct osd_bitmap *dec0_tf2_bitmap;
117 static struct osd_bitmap *dec0_tf3_bitmap;
118 
119 unsigned char *dec0_pf1_rowscroll,*dec0_pf2_rowscroll,*dec0_pf3_rowscroll;
120 unsigned char *dec0_pf1_colscroll,*dec0_pf2_colscroll,*dec0_pf3_colscroll;
121 static unsigned char dec0_pf1_control_0[8];
122 static unsigned char dec0_pf1_control_1[8];
123 static unsigned char dec0_pf2_control_0[8];
124 static unsigned char dec0_pf2_control_1[8];
125 static unsigned char dec0_pf3_control_0[8];
126 static unsigned char dec0_pf3_control_1[8];
127 static unsigned char *dec0_spriteram;
128 
129 static int dec0_pri;
130 
131 /******************************************************************************/
132 
WRITE_HANDLER(dec0_update_sprites_w)133 WRITE_HANDLER( dec0_update_sprites_w )
134 {
135 	memcpy(dec0_spriteram,spriteram,0x800);
136 }
137 
138 /******************************************************************************/
139 
update_24bitcol(int offset)140 static void update_24bitcol(int offset)
141 {
142 	int r,g,b;
143 
144 	r = (READ_WORD(&paletteram[offset]) >> 0) & 0xff;
145 	g = (READ_WORD(&paletteram[offset]) >> 8) & 0xff;
146 	b = (READ_WORD(&paletteram_2[offset]) >> 0) & 0xff;
147 
148 	palette_change_color(offset / 2,r,g,b);
149 }
150 
WRITE_HANDLER(dec0_paletteram_rg_w)151 WRITE_HANDLER( dec0_paletteram_rg_w )
152 {
153 	COMBINE_WORD_MEM(&paletteram[offset],data);
154 	update_24bitcol(offset);
155 }
156 
WRITE_HANDLER(dec0_paletteram_b_w)157 WRITE_HANDLER( dec0_paletteram_b_w )
158 {
159 	COMBINE_WORD_MEM(&paletteram_2[offset],data);
160 	update_24bitcol(offset);
161 }
162 
163 /******************************************************************************/
164 
165 /* pf23priority: 1 -> pf2 transparent, pf3 not transparent */
166 /*               0 -> pf2 not transparent, pf3 transparent */
dec0_update_palette(int pf23priority)167 static void dec0_update_palette(int pf23priority)
168 {
169 	int offs;
170 	int color,code,i;
171 	int colmask[16];
172 	int pal_base;
173 
174 
175 	palette_init_used_colors();
176 
177 	pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
178 	for (color = 0;color < 16;color++) colmask[color] = 0;
179 	for (offs = 0; offs < TEXTRAM_SIZE;offs += 2)
180 	{
181 		code = READ_WORD(&dec0_pf1_data[offs]);
182 		color = (code & 0xf000) >> 12;
183 		code &= 0x0fff;
184 		colmask[color] |= Machine->gfx[0]->pen_usage[code];
185 	}
186 
187 	for (color = 0;color < 16;color++)
188 	{
189 		if (colmask[color] & (1 << 0))
190 			palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
191 		for (i = 1;i < 16;i++)
192 		{
193 			if (colmask[color] & (1 << i))
194 				palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
195 		}
196 	}
197 
198 	pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
199 	for (color = 0;color < 16;color++) colmask[color] = 0;
200 	for (offs = 0; offs < TILERAM_SIZE;offs += 2)
201 	{
202 		code = READ_WORD(&dec0_pf2_data[offs]);
203 		color = (code & 0xf000) >> 12;
204 		code &= 0x0fff;
205 		colmask[color] |= Machine->gfx[1]->pen_usage[code];
206 	}
207 
208 	for (color = 0;color < 16;color++)
209 	{
210 		if (colmask[color] & (1 << 0))
211 			palette_used_colors[pal_base + 16 * color] = pf23priority ? PALETTE_COLOR_USED : PALETTE_COLOR_TRANSPARENT;
212 		for (i = 1;i < 16;i++)
213 		{
214 			if (colmask[color] & (1 << i))
215 				palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
216 		}
217 	}
218 
219 	pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
220 	for (color = 0;color < 16;color++) colmask[color] = 0;
221 	for (offs = 0; offs < TILERAM_SIZE;offs += 2)
222 	{
223 		code = READ_WORD(&dec0_pf3_data[offs]);
224 		color = (code & 0xf000) >> 12;
225 		code &= 0x0fff;
226 		colmask[color] |= Machine->gfx[2]->pen_usage[code];
227 	}
228 
229 	for (color = 0;color < 16;color++)
230 	{
231 		if (colmask[color] & (1 << 0))
232 			palette_used_colors[pal_base + 16 * color] = pf23priority ? PALETTE_COLOR_TRANSPARENT : PALETTE_COLOR_USED;
233 		for (i = 1;i < 16;i++)
234 		{
235 			if (colmask[color] & (1 << i))
236 				palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
237 		}
238 	}
239 
240 	pal_base = Machine->drv->gfxdecodeinfo[3].color_codes_start;
241 	palette_used_colors[pal_base] = PALETTE_COLOR_TRANSPARENT; /* Always set this, for priorities to work */
242 	for (color = 0;color < 16;color++) colmask[color] = 0;
243 	for (offs = 0;offs < 0x800;offs += 8)
244 	{
245 		int x,y,sprite,multi;
246 
247 		y = READ_WORD(&dec0_spriteram[offs]);
248 		if ((y&0x8000) == 0) continue;
249 
250 		x = READ_WORD(&dec0_spriteram[offs+4]);
251 		color = (x & 0xf000) >> 12;
252 
253 		multi = (1 << ((y & 0x1800) >> 11)) - 1;	/* 1x, 2x, 4x, 8x height */
254 											/* multi = 0   1   3   7 */
255 
256 		x = x & 0x01ff;
257 		if (x >= 256) x -= 512;
258 		x = 240 - x;
259 		if (x>256) continue; /* Speedup + save colours */
260 
261 		sprite = READ_WORD (&dec0_spriteram[offs+2]) & 0x0fff;
262 
263 		sprite &= ~multi;
264 
265 		while (multi >= 0)
266 		{
267 			colmask[color] |= Machine->gfx[3]->pen_usage[sprite + multi];
268 
269 			multi--;
270 		}
271 	}
272 
273 	for (color = 0;color < 16;color++)
274 	{
275 		for (i = 1;i < 16;i++)
276 		{
277 			if (colmask[color] & (1 << i))
278 				palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
279 		}
280 	}
281 
282 
283 	if (palette_recalc())
284 	{
285 		memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
286 		memset(dec0_pf2_dirty,1,TILERAM_SIZE);
287 		memset(dec0_pf3_dirty,1,TILERAM_SIZE);
288 	}
289 }
290 
291 /******************************************************************************/
292 
dec0_drawsprites(struct osd_bitmap * bitmap,int pri_mask,int pri_val)293 static void dec0_drawsprites(struct osd_bitmap *bitmap,int pri_mask,int pri_val)
294 {
295 	int offs;
296 
297 	for (offs = 0;offs < 0x800;offs += 8)
298 	{
299 		int x,y,sprite,colour,multi,fx,fy,inc,flash;
300 
301 		y = READ_WORD(&dec0_spriteram[offs]);
302 		if ((y&0x8000) == 0) continue;
303 
304 		x = READ_WORD(&dec0_spriteram[offs+4]);
305 		colour = x >> 12;
306 		if ((colour & pri_mask) != pri_val) continue;
307 
308 		flash=x&0x800;
309 		if (flash && (cpu_getcurrentframe() & 1)) continue;
310 
311 		fx = y & 0x2000;
312 		fy = y & 0x4000;
313 		multi = (1 << ((y & 0x1800) >> 11)) - 1;	/* 1x, 2x, 4x, 8x height */
314 											/* multi = 0   1   3   7 */
315 
316 		sprite = READ_WORD (&dec0_spriteram[offs+2]) & 0x0fff;
317 
318 		x = x & 0x01ff;
319 		y = y & 0x01ff;
320 		if (x >= 256) x -= 512;
321 		if (y >= 256) y -= 512;
322 		x = 240 - x;
323 		y = 240 - y;
324 
325 		if (x>256) continue; /* Speedup */
326 
327 		sprite &= ~multi;
328 		if (fy)
329 			inc = -1;
330 		else
331 		{
332 			sprite += multi;
333 			inc = 1;
334 		}
335 
336 		while (multi >= 0)
337 		{
338 			drawgfx(bitmap,Machine->gfx[3],
339 					sprite - multi * inc,
340 					colour,
341 					fx,fy,
342 					x,y - 16 * multi,
343 					&Machine->visible_area,TRANSPARENCY_PEN,0);
344 
345 			multi--;
346 		}
347 	}
348 }
349 
350 /******************************************************************************/
351 
dec0_pf1_update(void)352 static void dec0_pf1_update(void)
353 {
354 	int offs,mx,my,color,tile,quarter;
355 	int offsetx[4],offsety[4];
356 
357 	switch (READ_WORD(&dec0_pf1_control_0[6])&0xf)
358 	{
359 		case 0:	/* 4x1 */
360 			offsetx[0] = 0;
361 			offsetx[1] = 256;
362 			offsetx[2] = 512;
363 			offsetx[3] = 768;
364 			offsety[0] = 0;
365 			offsety[1] = 0;
366 			offsety[2] = 0;
367 			offsety[3] = 0;
368 			if (dec0_pf1_current_shape != 0)
369 			{
370 				bitmap_free(dec0_pf1_bitmap);
371 				dec0_pf1_bitmap = bitmap_alloc(1024,256);
372 				dec0_pf1_current_shape = 0;
373 				memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
374 			}
375 			break;
376 		case 1:	/* 2x2 */
377 			offsetx[0] = 0;
378 			offsetx[1] = 0;
379 			offsetx[2] = 256;
380 			offsetx[3] = 256;
381 			offsety[0] = 0;
382 			offsety[1] = 256;
383 			offsety[2] = 0;
384 			offsety[3] = 256;
385 			if (dec0_pf1_current_shape != 1)
386 			{
387 				bitmap_free(dec0_pf1_bitmap);
388 				dec0_pf1_bitmap = bitmap_alloc(512,512);
389 				dec0_pf1_current_shape = 1;
390 				memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
391 			}
392 			break;
393 		case 2:	/* 1x4 */
394 			offsetx[0] = 0;
395 			offsetx[1] = 0;
396 			offsetx[2] = 0;
397 			offsetx[3] = 0;
398 			offsety[0] = 0;
399 			offsety[1] = 256;
400 			offsety[2] = 512;
401 			offsety[3] = 768;
402 			if (dec0_pf1_current_shape != 2)
403 			{
404 				bitmap_free(dec0_pf1_bitmap);
405 				dec0_pf1_bitmap = bitmap_alloc(256,1024);
406 				dec0_pf1_current_shape = 2;
407 				memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
408 			}
409 			break;
410 		default:
411 			//logerror("error: pf1_update with unknown shape %04x\n",READ_WORD(&dec0_pf1_control_0[6]));
412 			return;
413 	}
414 
415 	for (quarter = 0;quarter < 4;quarter++)
416 	{
417 		mx = -1;
418 		my = 0;
419 
420 		for (offs = 0x800 * quarter; offs < 0x800 * quarter + 0x800;offs += 2)
421 		{
422 			mx++;
423 			if (mx == 32)
424 			{
425 				mx = 0;
426 				my++;
427 			}
428 
429 			if (dec0_pf1_dirty[offs])
430 			{
431 				dec0_pf1_dirty[offs] = 0;
432 				tile = READ_WORD(&dec0_pf1_data[offs]);
433 				color = (tile & 0xf000) >> 12;
434 
435 				drawgfx(dec0_pf1_bitmap,Machine->gfx[0],
436 						tile & 0x0fff,
437 						color,
438 						0,0,
439 						8*mx + offsetx[quarter],8*my + offsety[quarter],
440 						0,TRANSPARENCY_NONE,0);
441 			}
442 		}
443 	}
444 }
445 
dec0_pf2_update(int transparent,int special)446 static void dec0_pf2_update(int transparent, int special)
447 {
448 	int offs,mx,my,color,tile,quarter;
449 	int offsetx[4],offsety[4];
450 	static int last_transparent;
451 
452 	if (transparent != last_transparent)
453 	{
454 		last_transparent = transparent;
455 		memset(dec0_pf2_dirty,1,TILERAM_SIZE);
456 	}
457 
458 	switch (READ_WORD(&dec0_pf2_control_0[6])&0xf)
459 	{
460 		case 0:	/* 4x1 */
461 			offsetx[0] = 0;
462 			offsetx[1] = 256;
463 			offsetx[2] = 512;
464 			offsetx[3] = 768;
465 			offsety[0] = 0;
466 			offsety[1] = 0;
467 			offsety[2] = 0;
468 			offsety[3] = 0;
469 			if (dec0_pf2_current_shape != 0)
470 			{
471 				bitmap_free(dec0_pf2_bitmap);
472 				dec0_pf2_bitmap = bitmap_alloc(1024,256);
473 				bitmap_free(dec0_tf2_bitmap);
474 				dec0_tf2_bitmap = bitmap_alloc(1024,256);
475 				dec0_pf2_current_shape = 0;
476 				memset(dec0_pf2_dirty,1,TILERAM_SIZE);
477 			}
478 			break;
479 		case 1:	/* 2x2 */
480 			offsetx[0] = 0;
481 			offsetx[1] = 0;
482 			offsetx[2] = 256;
483 			offsetx[3] = 256;
484 			offsety[0] = 0;
485 			offsety[1] = 256;
486 			offsety[2] = 0;
487 			offsety[3] = 256;
488 			if (dec0_pf2_current_shape != 1)
489 			{
490 				bitmap_free(dec0_pf2_bitmap);
491 				dec0_pf2_bitmap = bitmap_alloc(512,512);
492 				bitmap_free(dec0_tf2_bitmap);
493 				dec0_tf2_bitmap = bitmap_alloc(512,512);
494 				dec0_pf2_current_shape = 1;
495 				memset(dec0_pf2_dirty,1,TILERAM_SIZE);
496 			}
497 			break;
498 		case 2:	/* 1x4 */
499 			offsetx[0] = 0;
500 			offsetx[1] = 0;
501 			offsetx[2] = 0;
502 			offsetx[3] = 0;
503 			offsety[0] = 0;
504 			offsety[1] = 256;
505 			offsety[2] = 512;
506 			offsety[3] = 768;
507 			if (dec0_pf2_current_shape != 2)
508 			{
509 				bitmap_free(dec0_pf2_bitmap);
510 				dec0_pf2_bitmap = bitmap_alloc(256,1024);
511 				bitmap_free(dec0_tf2_bitmap);
512 				dec0_tf2_bitmap = bitmap_alloc(256,1024);
513 				dec0_pf2_current_shape = 2;
514 				memset(dec0_pf2_dirty,1,TILERAM_SIZE);
515 			}
516 			break;
517 		default:
518 			//logerror("error: pf2_update with unknown shape %04x\n",READ_WORD(&dec0_pf2_control_0[6]));
519 			return;
520 	}
521 
522 	for (quarter = 0;quarter < 4;quarter++)
523 	{
524 		mx = -1;
525 		my = 0;
526 
527 		for (offs = 0x200 * quarter; offs < 0x200 * quarter + 0x200;offs += 2)
528 		{
529 			mx++;
530 			if (mx == 16)
531 			{
532 				mx = 0;
533 				my++;
534 			}
535 
536 			if (dec0_pf2_dirty[offs])
537 			{
538 				tile = READ_WORD(&dec0_pf2_data[offs]);
539 				color = (tile & 0xf000) >> 12;
540 
541 				/* 'Special' - Render foreground pens (8-15) to a seperate bitmap */
542 				if (special) {
543 					/* Blank tile */
544 					drawgfx(dec0_tf2_bitmap,Machine->gfx[3],
545 							0,
546 							0,
547 							0,0,
548 							16*mx + offsetx[quarter],16*my + offsety[quarter],
549 							0,TRANSPARENCY_NONE,0);
550 
551 					if (color>7)
552 						drawgfx(dec0_tf2_bitmap,Machine->gfx[1],
553 								tile & 0x0fff,
554 								color,
555 								0,0,
556 								16*mx + offsetx[quarter],16*my + offsety[quarter],
557 								0,TRANSPARENCY_PENS,0xff);
558 				} else { /* Else, business as usual */
559 					dec0_pf2_dirty[offs] = 0;
560 					drawgfx(dec0_pf2_bitmap,Machine->gfx[1],
561 							tile & 0x0fff,
562 							color,
563 							0,0,
564 							16*mx + offsetx[quarter],16*my + offsety[quarter],
565 							0,TRANSPARENCY_NONE,0);
566 				}
567 			}
568 		}
569 	}
570 }
571 
dec0_pf3_update(int transparent,int special)572 static void dec0_pf3_update(int transparent, int special)
573 {
574 	int offs,mx,my,color,tile,quarter;
575 	int offsetx[4],offsety[4];
576 	static int last_transparent;
577 
578 	if (transparent != last_transparent)
579 	{
580 		last_transparent = transparent;
581 		memset(dec0_pf3_dirty,1,TILERAM_SIZE);
582 	}
583 
584 	switch (READ_WORD(&dec0_pf3_control_0[6])&0xf)
585 	{
586 		case 0:	/* 4x1 */
587 			offsetx[0] = 0;
588 			offsetx[1] = 256;
589 			offsetx[2] = 512;
590 			offsetx[3] = 768;
591 			offsety[0] = 0;
592 			offsety[1] = 0;
593 			offsety[2] = 0;
594 			offsety[3] = 0;
595 			if (dec0_pf3_current_shape != 0)
596 			{
597 				bitmap_free(dec0_pf3_bitmap);
598 				dec0_pf3_bitmap = bitmap_alloc(1024,256);
599 				bitmap_free(dec0_tf3_bitmap);
600 				dec0_tf3_bitmap = bitmap_alloc(1024,256);
601 				dec0_pf3_current_shape = 0;
602 				memset(dec0_pf3_dirty,1,TILERAM_SIZE);
603 			}
604 			break;
605 		case 1:	/* 2x2 */
606 			offsetx[0] = 0;
607 			offsetx[1] = 0;
608 			offsetx[2] = 256;
609 			offsetx[3] = 256;
610 			offsety[0] = 0;
611 			offsety[1] = 256;
612 			offsety[2] = 0;
613 			offsety[3] = 256;
614 			if (dec0_pf3_current_shape != 1)
615 			{
616 				bitmap_free(dec0_pf3_bitmap);
617 				dec0_pf3_bitmap = bitmap_alloc(512,512);
618 				bitmap_free(dec0_tf3_bitmap);
619 				dec0_tf3_bitmap = bitmap_alloc(512,512);
620 				dec0_pf3_current_shape = 1;
621 				memset(dec0_pf3_dirty,1,TILERAM_SIZE);
622 			}
623 			break;
624 		case 2:	/* 1x4 */
625 			offsetx[0] = 0;
626 			offsetx[1] = 0;
627 			offsetx[2] = 0;
628 			offsetx[3] = 0;
629 			offsety[0] = 0;
630 			offsety[1] = 256;
631 			offsety[2] = 512;
632 			offsety[3] = 768;
633 			if (dec0_pf3_current_shape != 2)
634 			{
635 				bitmap_free(dec0_pf3_bitmap);
636 				dec0_pf3_bitmap = bitmap_alloc(256,1024);
637 				bitmap_free(dec0_tf3_bitmap);
638 				dec0_tf3_bitmap = bitmap_alloc(256,1024);
639 				dec0_pf3_current_shape = 2;
640 				memset(dec0_pf3_dirty,1,TILERAM_SIZE);
641 			}
642 			break;
643 		default:
644 			//logerror("error: pf3_update with unknown shape %04x\n",READ_WORD(&dec0_pf3_control_0[6]));
645 			return;
646 	}
647 
648 	for (quarter = 0;quarter < 4;quarter++)
649 	{
650 		mx = -1;
651 		my = 0;
652 
653 		for (offs = 0x200 * quarter; offs < 0x200 * quarter + 0x200;offs += 2)
654 		{
655 			mx++;
656 			if (mx == 16)
657 			{
658 				mx = 0;
659 				my++;
660 			}
661 
662 			if (dec0_pf3_dirty[offs])
663 			{
664 				tile = READ_WORD(&dec0_pf3_data[offs]);
665 				color = (tile & 0xf000) >> 12;
666 
667 				/* 'Special' - Render foreground pens (8-15) to a seperate bitmap */
668 				if (special) {
669 					/* Blank tile */
670 					drawgfx(dec0_tf3_bitmap,Machine->gfx[3],
671 							0,
672 							0,
673 							0,0,
674 							16*mx + offsetx[quarter],16*my + offsety[quarter],
675 							0,TRANSPARENCY_NONE,0);
676 
677 					if (color>7)
678 						drawgfx(dec0_tf3_bitmap,Machine->gfx[2],
679 							tile & 0x0fff,
680 							color,
681 							0,0,
682 							16*mx + offsetx[quarter],16*my + offsety[quarter],
683 							0,TRANSPARENCY_PENS,0xff);
684 				} else { /* Else, business as usual */
685 					dec0_pf3_dirty[offs] = 0;
686 					drawgfx(dec0_pf3_bitmap,Machine->gfx[2],
687 							tile & 0x0fff,
688 							color,
689 							0,0,
690 							16*mx + offsetx[quarter],16*my + offsety[quarter],
691 							0,TRANSPARENCY_NONE,0);
692 				}
693 			}
694 		}
695 	}
696 }
697 
698 /******************************************************************************/
699 
dec0_pf1_draw(struct osd_bitmap * bitmap)700 void dec0_pf1_draw(struct osd_bitmap *bitmap)
701 {
702 	int offs,lines,height,scrolly,scrollx;
703 
704 	scrollx = - READ_WORD(&dec0_pf1_control_1[0]);
705 	scrolly = - READ_WORD(&dec0_pf1_control_1[2]);
706 
707 	/* We check for column scroll and use that if needed, otherwise use row scroll,
708 	   I am 99% sure they are never needed at same time ;) */
709 	if (READ_WORD(&dec0_pf1_colscroll[0])) /* This is NOT a good check for col scroll, I can't find real bit */
710 	{
711 		int cscrolly[64];
712 
713 		for (offs = 0;offs < 32;offs++)
714 		cscrolly[offs] = -READ_WORD(&dec0_pf1_control_1[2]) - READ_WORD(&dec0_pf1_colscroll[2*offs]);
715 
716 		copyscrollbitmap(bitmap,dec0_pf1_bitmap,1,&scrollx,32,cscrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
717 	}
718 
719 	/* Row scroll enable bit (unsure if this enables/disables col scroll too) */
720 	else if (READ_WORD(&dec0_pf1_control_0[0])&0x4)
721 	{
722 		int rscrollx[1024];
723 
724 		/* Playfield shape */
725 		switch (READ_WORD(&dec0_pf1_control_0[6])&0xf)
726 		{
727 			case 0:	height=1; break; /* 4x1, 256 rows */
728 			case 1:	height=2; break; /* 2x2, 512 rows */
729 			case 2:	height=4; break; /* 1x4, 1024 rows */
730 			default: height=2; break; /* Never happens (I hope) */
731 		}
732 
733 		/* Rowscroll style */
734 		switch (READ_WORD(&dec0_pf1_control_1[6])&0xf)
735 		{
736 			case 0: lines=256; break; /* 256 horizontal scroll registers (Robocop) */
737 			case 1: lines=128; break; /* 128 horizontal scroll registers (Not used?) */
738 			case 2: lines=64; break; /* 128 horizontal scroll registers (Not used?) */
739 			case 3: lines=32; break; /* 32 horizontal scroll registers (Heavy Barrel title screen) */
740 			case 4: lines=16; break; /* 16 horizontal scroll registers (Bad Dudes, Sly Spy) */
741 			case 5: lines=8; break; /* 8 horizontal scroll registers (Not used?) */
742 			case 6: lines=4; break; /* 4 horizontal scroll registers (Not used?) */
743 			case 7: lines=2; break; /* 2 horizontal scroll registers (Not used?) */
744 			case 8: lines=1; break; /* Appears to be no row-scroll - so maybe only bottom 3 bits are style */
745 			default: lines=1; break; /* Just in case */
746 		}
747 
748 		for (offs = 0; offs < lines*height; offs++)
749 			rscrollx[offs] = scrollx - READ_WORD(&dec0_pf1_rowscroll[offs<<1]);
750 		copyscrollbitmap(bitmap,dec0_pf1_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
751 	}
752 	else /* Scroll registers not enabled */
753 		copyscrollbitmap(bitmap,dec0_pf1_bitmap,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
754 }
755 
756 /* trans=0 - bottom playfield, trans=1 - top playfield, trans=2 - special foreground section */
dec0_pf2_draw(struct osd_bitmap * bitmap,int trans)757 void dec0_pf2_draw(struct osd_bitmap *bitmap, int trans)
758 {
759 	int offs,lines,height,width,scrolly,scrollx;
760 
761 	scrollx = - READ_WORD(&dec0_pf2_control_1[0]);
762 	scrolly = - READ_WORD(&dec0_pf2_control_1[2]);
763 
764 	/* Row scroll enable bit */
765 	if (READ_WORD(&dec0_pf2_control_0[0])&0x4)
766 	{
767 		int rscrollx[1024];
768 
769 		/* Playfield shape */
770 		switch (READ_WORD(&dec0_pf2_control_0[6])&0xf)
771 		{
772 			case 0:	height=1; break; /* 4x1, 256 rows */
773 			case 1:	height=2; break; /* 2x2, 512 rows */
774 			case 2:	height=4; break; /* 1x4, 1024 rows */
775 			default: height=2; break; /* Never happens (I hope) */
776 		}
777 
778 		/* Rowscroll style */
779 		switch (READ_WORD(&dec0_pf2_control_1[6])&0xf)
780 		{
781 			case 0: lines=256; break; /* 256 horizontal scroll registers (Robocop) */
782 			case 1: lines=128; break; /* 128 horizontal scroll registers (Not used?) */
783 			case 2: lines=64; break; /* 128 horizontal scroll registers (Not used?) */
784 			case 3: lines=32; break; /* 32 horizontal scroll registers (Heavy Barrel title screen) */
785 			case 4: lines=16; break; /* 16 horizontal scroll registers (Bad Dudes, Sly Spy) */
786 			case 5: lines=8; break; /* 8 horizontal scroll registers (Not used?) */
787 			case 6: lines=4; break; /* 4 horizontal scroll registers (Not used?) */
788 			case 7: lines=2; break; /* 2 horizontal scroll registers (Not used?) */
789 			case 8: lines=1; break; /* Appears to be no row-scroll */
790 			default: lines=1; break; /* Just in case */
791 		}
792 
793 		for (offs = 0; offs < lines*height; offs++)
794 			rscrollx[offs] = scrollx - READ_WORD(&dec0_pf2_rowscroll[offs<<1]);
795 
796 		if (trans==2)
797 			copyscrollbitmap(bitmap,dec0_tf2_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
798 		else if (trans==1)
799 			copyscrollbitmap(bitmap,dec0_pf2_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
800 		else
801 			copyscrollbitmap(bitmap,dec0_pf2_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
802 	}
803 	else /* Column scroll enable bit */
804 	if (READ_WORD(&dec0_pf2_control_0[0])&0x8)
805 	{
806 		int rscrollx[1024];
807 
808 		/* Playfield shape */
809 		switch (READ_WORD(&dec0_pf2_control_0[6])&0xf)
810 		{
811 			case 0:	width=1; break; /* 4x1, 256 rows */
812 			case 1:	width=2; break; /* 2x2, 512 rows */
813 			case 2:	width=4; break; /* 1x4, 1024 rows */
814 			default: width=2; break; /* Never happens (I hope) */
815 		}
816 
817 		/* Rowscroll style */
818 		switch (READ_WORD(&dec0_pf2_control_1[4])&0xf)
819 		{
820 			case 0: lines=64; break; /* 256 horizontal scroll registers (Robocop) */
821 			case 1: lines=32; break; /* 128 horizontal scroll registers (Not used?) */
822 			case 2: lines=16; break; /* 128 horizontal scroll registers (Not used?) */
823 			case 3: lines=8; break; /* 32 horizontal scroll registers (Heavy Barrel title screen) */
824 			case 4: lines=4; break; /* 16 horizontal scroll registers (Bad Dudes, Sly Spy) */
825 			case 5: lines=2; break; /* 8 horizontal scroll registers (Not used?) */
826 			case 6: lines=1; break; /* 4 horizontal scroll registers (Not used?) */
827 			case 7: lines=2; break; /* 2 horizontal scroll registers (Not used?) */
828 			case 8: lines=1; break; /* Appears to be no row-scroll */
829 			default: lines=1; break; /* Just in case */
830 		}
831 
832 		for (offs = 0; offs < lines; offs++)
833 			rscrollx[offs] = scrolly - READ_WORD(&dec0_pf2_colscroll[offs<<1]);
834 
835 		if (trans==2)
836 			copyscrollbitmap(bitmap,dec0_tf2_bitmap,1,&scrollx,lines,rscrollx,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
837 		else if (trans==1)
838 			copyscrollbitmap(bitmap,dec0_pf2_bitmap,1,&scrollx,lines,rscrollx,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
839 		else
840 			copyscrollbitmap(bitmap,dec0_pf2_bitmap,1,&scrollx,lines,rscrollx,&Machine->visible_area,TRANSPARENCY_NONE,0);
841 	}
842 	else { /* Scroll registers not enabled */
843 		if (trans==2)
844 			copyscrollbitmap(bitmap,dec0_tf2_bitmap,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
845 		else if (trans==1)
846 			copyscrollbitmap(bitmap,dec0_pf2_bitmap,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
847 		else
848 			copyscrollbitmap(bitmap,dec0_pf2_bitmap,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
849 	}
850 }
851 
dec0_pf3_draw(struct osd_bitmap * bitmap,int trans)852 void dec0_pf3_draw(struct osd_bitmap *bitmap, int trans)
853 {
854 	int offs,lines,height,scrolly,scrollx;
855 
856 	scrollx = - READ_WORD(&dec0_pf3_control_1[0]);
857 	scrolly = - READ_WORD(&dec0_pf3_control_1[2]);
858 
859 	/* Colscroll not supported for this playfield (does anything use it?) */
860 
861 	/* Row scroll enable bit (unsure if this enables/disables col scroll too) */
862 	if (READ_WORD(&dec0_pf3_control_0[0])&0x4)
863 	{
864 		int rscrollx[1024];
865 
866 		/* Playfield shape */
867 		switch (READ_WORD(&dec0_pf3_control_0[6])&0xf)
868 		{
869 			case 0:	height=1; break; /* 4x1, 256 rows */
870 			case 1:	height=2; break; /* 2x2, 512 rows */
871 			case 2:	height=4; break; /* 1x4, 1024 rows */
872 			default: height=2; break; /* Never happens (I hope) */
873 		}
874 
875 		/* Rowscroll style */
876 		switch (READ_WORD(&dec0_pf3_control_1[6])&0xf)
877 		{
878 			case 0: lines=256; break; /* 256 horizontal scroll registers (Robocop) */
879 			case 1: lines=128; break; /* 128 horizontal scroll registers (Not used?) */
880 			case 2: lines=64; break; /* 128 horizontal scroll registers (Not used?) */
881 			case 3: lines=32; break; /* 32 horizontal scroll registers (Heavy Barrel title screen) */
882 			case 4: lines=16; break; /* 16 horizontal scroll registers (Bad Dudes, Sly Spy) */
883 			case 5: lines=8; break; /* 8 horizontal scroll registers (Not used?) */
884 			case 6: lines=4; break; /* 4 horizontal scroll registers (Not used?) */
885 			case 7: lines=2; break; /* 2 horizontal scroll registers (Not used?) */
886 			case 8: lines=1; break; /* Appears to be no row-scroll - so maybe only bottom 3 bits are style */
887 			default: lines=1; break; /* Just in case */
888 		}
889 
890 		for (offs = 0; offs < lines*height; offs++)
891 			rscrollx[offs] = scrollx - READ_WORD(&dec0_pf3_rowscroll[offs<<1]);
892 
893 		if (trans==2)
894 			copyscrollbitmap(bitmap,dec0_tf3_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
895 		else if (trans==1)
896 			copyscrollbitmap(bitmap,dec0_pf3_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
897 		else
898 			copyscrollbitmap(bitmap,dec0_pf3_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
899 	}
900 	else { /* Scroll registers not enabled */
901 		if (trans==2)
902 			copyscrollbitmap(bitmap,dec0_tf3_bitmap,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
903 		else if (trans==1)
904 			copyscrollbitmap(bitmap,dec0_pf3_bitmap,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
905 		else
906 			copyscrollbitmap(bitmap,dec0_pf3_bitmap,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
907 	}
908 }
909 
910 /******************************************************************************/
911 
hbarrel_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)912 void hbarrel_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
913 {
914 	dec0_update_palette(dec0_pri & 0x01);
915 
916 	dec0_pf1_update();
917 	dec0_pf3_update(0,0);
918 	dec0_pf2_update(1,0);
919 	dec0_pf3_draw(bitmap,0);
920 	dec0_drawsprites(bitmap,0x08,0x08);
921 	dec0_pf2_draw(bitmap,1);
922 
923 	/* HB always keeps pf2 on top of pf3, no need explicitly support priority register */
924 
925 	dec0_drawsprites(bitmap,0x08,0x00);
926 	dec0_pf1_draw(bitmap);
927 }
928 
929 /******************************************************************************/
930 
baddudes_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)931 void baddudes_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
932 {
933 	/* WARNING: priority inverted wrt all the other games */
934 	dec0_update_palette(~dec0_pri & 0x01);
935 	dec0_pf1_update();
936 
937 	/* WARNING: inverted wrt Midnight Resistance */
938 	if ((dec0_pri & 0x01) == 0)
939 	{
940 		dec0_pf2_update(0,1); /* Foreground pens of pf2 only */
941 		dec0_pf2_update(0,0);
942 		dec0_pf3_update(1,1);
943 		dec0_pf3_update(1,0);
944 
945 		dec0_pf2_draw(bitmap,0);
946 		dec0_pf3_draw(bitmap,1);
947 
948 		if (dec0_pri & 2)
949 			dec0_pf2_draw(bitmap,2); /* Foreground pens only */
950 
951 		dec0_drawsprites(bitmap,0x00,0x00);
952 
953 		if (dec0_pri & 4)
954 			dec0_pf3_draw(bitmap,2); /* Foreground pens only */
955 	}
956 	else
957 	{
958 		dec0_pf3_update(0,1);
959 		dec0_pf3_update(0,0);
960 		dec0_pf2_update(1,1);
961 		dec0_pf2_update(1,0);
962 
963 		dec0_pf3_draw(bitmap,0);
964 		dec0_pf2_draw(bitmap,1);
965 
966 		if (dec0_pri & 2)
967 			dec0_pf3_draw(bitmap,2);
968 
969 		dec0_drawsprites(bitmap,0x00,0x00);
970 
971 		if (dec0_pri & 4)
972 			dec0_pf2_draw(bitmap,2);
973 	}
974 
975 	dec0_pf1_draw(bitmap);
976 }
977 
978 /******************************************************************************/
979 
robocop_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)980 void robocop_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
981 {
982 	dec0_update_palette(dec0_pri & 0x01);
983 	dec0_pf1_update();
984 
985 	if (dec0_pri & 0x01)
986 	{
987 		int trans;
988 
989 		dec0_pf2_update(0,0);
990 		dec0_pf3_update(1,0);
991 
992 		/* WARNING: inverted wrt Midnight Resistance */
993 		/* Robocop uses it only for the title screen, so this might be just */
994 		/* completely wrong. The top 8 bits of the register might mean */
995 		/* something (they are 0x80 in midres, 0x00 here) */
996 		if (dec0_pri & 0x04)
997 			trans = 0x08;
998 		else trans = 0x00;
999 
1000 		dec0_pf2_draw(bitmap,0);
1001 
1002 		if (dec0_pri & 0x02)
1003 			dec0_drawsprites(bitmap,0x08,trans);
1004 
1005 		dec0_pf3_draw(bitmap,1);
1006 
1007 		if (dec0_pri & 0x02)
1008 			dec0_drawsprites(bitmap,0x08,trans ^ 0x08);
1009 		else
1010 			dec0_drawsprites(bitmap,0x00,0x00);
1011 	}
1012 	else
1013 	{
1014 		int trans;
1015 
1016 		dec0_pf3_update(0,0);
1017 		dec0_pf2_update(1,0);
1018 
1019 		/* WARNING: inverted wrt Midnight Resistance */
1020 		/* Robocop uses it only for the title screen, so this might be just */
1021 		/* completely wrong. The top 8 bits of the register might mean */
1022 		/* something (they are 0x80 in midres, 0x00 here) */
1023 		if (dec0_pri & 0x04)
1024 			trans = 0x08;
1025 		else trans = 0x00;
1026 
1027 		dec0_pf3_draw(bitmap,0);
1028 
1029 		if (dec0_pri & 0x02)
1030 			dec0_drawsprites(bitmap,0x08,trans);
1031 
1032 		dec0_pf2_draw(bitmap,1);
1033 
1034 		if (dec0_pri & 0x02)
1035 			dec0_drawsprites(bitmap,0x08,trans ^ 0x08);
1036 		else
1037 			dec0_drawsprites(bitmap,0x00,0x00);
1038 	}
1039 
1040 	dec0_pf1_draw(bitmap);
1041 
1042 }
1043 
1044 /******************************************************************************/
1045 
birdtry_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1046 void birdtry_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1047 {
1048 	dec0_update_palette(dec0_pri & 0x01);
1049 
1050 	/* This game doesn't have the extra playfield chip on the game board */
1051 	dec0_pf1_update();
1052 	dec0_pf2_update(0,0);
1053 	dec0_pf2_draw(bitmap,0);
1054 	dec0_drawsprites(bitmap,0x00,0x00);
1055 	dec0_pf1_draw(bitmap);
1056 }
1057 
1058 /******************************************************************************/
1059 
hippodrm_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1060 void hippodrm_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1061 {
1062 	dec0_update_palette(dec0_pri & 0x01);
1063 	dec0_pf1_update();
1064 
1065 	if (dec0_pri & 0x01)
1066 	{
1067 		dec0_pf2_update(0,0);
1068 		dec0_pf3_update(1,0);
1069 
1070 		dec0_pf2_draw(bitmap,0);
1071 		dec0_pf3_draw(bitmap,1);
1072 	}
1073 	else
1074 	{
1075 		dec0_pf3_update(0,0);
1076 		dec0_pf2_update(1,0);
1077 
1078 		dec0_pf3_draw(bitmap,0);
1079 		dec0_pf2_draw(bitmap,1);
1080 	}
1081 
1082 	dec0_drawsprites(bitmap,0x00,0x00);
1083 	dec0_pf1_draw(bitmap);
1084 }
1085 
1086 /******************************************************************************/
1087 
slyspy_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1088 void slyspy_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1089 {
1090 	dec0_update_palette(0);
1091 
1092 	dec0_pf1_update();
1093 	dec0_pf3_update(0,0);
1094 	dec0_pf2_update(1,1);
1095 	dec0_pf2_update(1,0);
1096 
1097 	dec0_pf3_draw(bitmap,0);
1098 	dec0_pf2_draw(bitmap,1);
1099 
1100 	dec0_drawsprites(bitmap,0x00,0x00);
1101 
1102 	if (dec0_pri&0x80)
1103 		dec0_pf2_draw(bitmap,2);
1104 
1105 	dec0_pf1_draw(bitmap);
1106 }
1107 
1108 /******************************************************************************/
1109 
midres_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1110 void midres_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1111 {
1112 	dec0_update_palette(dec0_pri & 0x01);
1113 	dec0_pf1_update();
1114 
1115 if (dec0_pri & 0x01)
1116 {
1117 	int trans;
1118 
1119 	dec0_pf2_update(0,0);
1120 	dec0_pf3_update(1,0);
1121 
1122 	if (dec0_pri & 0x04)
1123 		trans = 0x00;
1124 	else trans = 0x08;
1125 
1126 	dec0_pf2_draw(bitmap,0);
1127 
1128 	if (dec0_pri & 0x02)
1129 		dec0_drawsprites(bitmap,0x08,trans);
1130 
1131 	dec0_pf3_draw(bitmap,1);
1132 
1133 	if (dec0_pri & 0x02)
1134 		dec0_drawsprites(bitmap,0x08,trans ^ 0x08);
1135 	else
1136 		dec0_drawsprites(bitmap,0x00,0x00);
1137 }
1138 else
1139 {
1140 	int trans;
1141 
1142 	dec0_pf3_update(0,0);
1143 	dec0_pf2_update(1,0);
1144 
1145 	if (dec0_pri & 0x04)
1146 		trans = 0x00;
1147 	else trans = 0x08;
1148 
1149 	dec0_pf3_draw(bitmap,0);
1150 
1151 	if (dec0_pri & 0x02)
1152 		dec0_drawsprites(bitmap,0x08,trans);
1153 
1154 	dec0_pf2_draw(bitmap,1);
1155 
1156 	if (dec0_pri & 0x02)
1157 		dec0_drawsprites(bitmap,0x08,trans ^ 0x08);
1158 	else
1159 		dec0_drawsprites(bitmap,0x00,0x00);
1160 	}
1161 
1162 	dec0_pf1_draw(bitmap);
1163 }
1164 
1165 /******************************************************************************/
1166 
WRITE_HANDLER(dec0_pf1_control_0_w)1167 WRITE_HANDLER( dec0_pf1_control_0_w )
1168 {
1169 	COMBINE_WORD_MEM(&dec0_pf1_control_0[offset],data);
1170 }
1171 
WRITE_HANDLER(dec0_pf1_control_1_w)1172 WRITE_HANDLER( dec0_pf1_control_1_w )
1173 {
1174 	COMBINE_WORD_MEM(&dec0_pf1_control_1[offset],data);
1175 }
1176 
WRITE_HANDLER(dec0_pf1_rowscroll_w)1177 WRITE_HANDLER( dec0_pf1_rowscroll_w )
1178 {
1179 	COMBINE_WORD_MEM(&dec0_pf1_rowscroll[offset],data);
1180 }
1181 
WRITE_HANDLER(dec0_pf1_colscroll_w)1182 WRITE_HANDLER( dec0_pf1_colscroll_w )
1183 {
1184 	COMBINE_WORD_MEM(&dec0_pf1_colscroll[offset],data);
1185 }
1186 
WRITE_HANDLER(dec0_pf1_data_w)1187 WRITE_HANDLER( dec0_pf1_data_w )
1188 {
1189 	int oldword = READ_WORD(&dec0_pf1_data[offset]);
1190 	int newword = COMBINE_WORD(oldword,data);
1191 
1192 	if (oldword != newword)
1193 	{
1194 		WRITE_WORD(&dec0_pf1_data[offset],newword);
1195 		dec0_pf1_dirty[offset] = 1;
1196 	}
1197 }
1198 
READ_HANDLER(dec0_pf1_data_r)1199 READ_HANDLER( dec0_pf1_data_r )
1200 {
1201 	return READ_WORD(&dec0_pf1_data[offset]);
1202 }
1203 
WRITE_HANDLER(dec0_pf2_control_0_w)1204 WRITE_HANDLER( dec0_pf2_control_0_w )
1205 {
1206 	COMBINE_WORD_MEM(&dec0_pf2_control_0[offset],data);
1207 }
1208 
WRITE_HANDLER(dec0_pf2_control_1_w)1209 WRITE_HANDLER( dec0_pf2_control_1_w )
1210 {
1211 	COMBINE_WORD_MEM(&dec0_pf2_control_1[offset],data);
1212 }
1213 
WRITE_HANDLER(dec0_pf2_rowscroll_w)1214 WRITE_HANDLER( dec0_pf2_rowscroll_w )
1215 {
1216 	COMBINE_WORD_MEM(&dec0_pf2_rowscroll[offset],data);
1217 }
1218 
WRITE_HANDLER(dec0_pf2_colscroll_w)1219 WRITE_HANDLER( dec0_pf2_colscroll_w )
1220 {
1221 	COMBINE_WORD_MEM(&dec0_pf2_colscroll[offset],data);
1222 }
1223 
WRITE_HANDLER(dec0_pf2_data_w)1224 WRITE_HANDLER( dec0_pf2_data_w )
1225 {
1226 	int oldword = READ_WORD(&dec0_pf2_data[offset]);
1227 	int newword = COMBINE_WORD(oldword,data);
1228 
1229 	if (oldword != newword)
1230 	{
1231 		WRITE_WORD(&dec0_pf2_data[offset],newword);
1232 		dec0_pf2_dirty[offset] = 1;
1233 	}
1234 }
1235 
READ_HANDLER(dec0_pf2_data_r)1236 READ_HANDLER( dec0_pf2_data_r )
1237 {
1238 	return READ_WORD(&dec0_pf2_data[offset]);
1239 }
1240 
WRITE_HANDLER(dec0_pf3_control_0_w)1241 WRITE_HANDLER( dec0_pf3_control_0_w )
1242 {
1243 	COMBINE_WORD_MEM(&dec0_pf3_control_0[offset],data);
1244 }
1245 
WRITE_HANDLER(dec0_pf3_control_1_w)1246 WRITE_HANDLER( dec0_pf3_control_1_w )
1247 {
1248 	COMBINE_WORD_MEM(&dec0_pf3_control_1[offset],data);
1249 }
1250 
WRITE_HANDLER(dec0_pf3_rowscroll_w)1251 WRITE_HANDLER( dec0_pf3_rowscroll_w )
1252 {
1253 	COMBINE_WORD_MEM(&dec0_pf3_rowscroll[offset],data);
1254 }
1255 
WRITE_HANDLER(dec0_pf3_colscroll_w)1256 WRITE_HANDLER( dec0_pf3_colscroll_w )
1257 {
1258 	COMBINE_WORD_MEM(&dec0_pf3_colscroll[offset],data);
1259 }
1260 
READ_HANDLER(dec0_pf3_colscroll_r)1261 READ_HANDLER( dec0_pf3_colscroll_r )
1262 {
1263 	return READ_WORD(&dec0_pf3_colscroll[offset]);
1264 }
1265 
WRITE_HANDLER(dec0_pf3_data_w)1266 WRITE_HANDLER( dec0_pf3_data_w )
1267 {
1268 	int oldword = READ_WORD(&dec0_pf3_data[offset]);
1269 	int newword = COMBINE_WORD(oldword,data);
1270 
1271 	if (oldword != newword)
1272 	{
1273 		WRITE_WORD(&dec0_pf3_data[offset],newword);
1274 		dec0_pf3_dirty[offset] = 1;
1275 	}
1276 }
1277 
READ_HANDLER(dec0_pf3_data_r)1278 READ_HANDLER( dec0_pf3_data_r )
1279 {
1280 	return READ_WORD(&dec0_pf3_data[offset]);
1281 }
1282 
WRITE_HANDLER(dec0_priority_w)1283 WRITE_HANDLER( dec0_priority_w )
1284 {
1285   	dec0_pri = COMBINE_WORD(dec0_pri,data);
1286 }
1287 
WRITE_HANDLER(dec0_pf3_control_8bit_w)1288 WRITE_HANDLER( dec0_pf3_control_8bit_w )
1289 {
1290 	static int buffer[0x20];
1291 	int myword;
1292 
1293 	buffer[offset]=data;
1294 
1295 	/* Rearrange little endian bytes from H6280 into big endian words for 68k */
1296 	offset&=0xffe;
1297 	myword=buffer[offset] + (buffer[offset+1]<<8);
1298 
1299 	if (offset<0x10) dec0_pf3_control_0_w(offset,myword);
1300 	else dec0_pf3_control_1_w(offset-0x10,myword);
1301 }
1302 
WRITE_HANDLER(dec0_pf3_data_8bit_w)1303 WRITE_HANDLER( dec0_pf3_data_8bit_w )
1304 {
1305 	if (offset&1) { /* MSB has changed */
1306 		int lsb=READ_WORD(&dec0_pf3_data[offset&0x7fe]);
1307 		int newword=(lsb&0xff) | (data<<8);
1308 		WRITE_WORD(&dec0_pf3_data[offset&0x7fe],newword);
1309 		dec0_pf3_dirty[offset&0x7fe] = 1;
1310 	}
1311 	else { /* LSB has changed */
1312 		int msb=READ_WORD(&dec0_pf3_data[offset&0x7fe]);
1313 		int newword=(msb&0xff00) | data;
1314 		WRITE_WORD(&dec0_pf3_data[offset&0x7fe],newword);
1315 		dec0_pf3_dirty[offset&0x7fe] = 1;
1316 	}
1317 }
1318 
READ_HANDLER(dec0_pf3_data_8bit_r)1319 READ_HANDLER( dec0_pf3_data_8bit_r )
1320 {
1321 	if (offset&1) /* MSB */
1322 		return READ_WORD(&dec0_pf3_data[offset&0x7fe])>>8;
1323 
1324 	return READ_WORD(&dec0_pf3_data[offset&0x7fe])&0xff;;
1325 }
1326 
1327 /******************************************************************************/
1328 
dec0_nodma_vh_stop(void)1329 void dec0_nodma_vh_stop (void)
1330 {
1331 	bitmap_free(dec0_pf3_bitmap);
1332 	bitmap_free(dec0_pf2_bitmap);
1333 	bitmap_free(dec0_pf1_bitmap);
1334 	bitmap_free(dec0_tf2_bitmap);
1335 	bitmap_free(dec0_tf3_bitmap);
1336 	free(dec0_pf3_dirty);
1337 	free(dec0_pf2_dirty);
1338 	free(dec0_pf1_dirty);
1339 }
1340 
dec0_vh_stop(void)1341 void dec0_vh_stop (void)
1342 {
1343 	free(dec0_spriteram);
1344 	dec0_nodma_vh_stop();
1345 }
1346 
dec0_nodma_vh_start(void)1347 int dec0_nodma_vh_start (void)
1348 {
1349 	/* Allocate bitmaps */
1350 	if ((dec0_pf1_bitmap = bitmap_alloc(512,512)) == 0) {
1351 		dec0_vh_stop ();
1352 		return 1;
1353 	}
1354 	dec0_pf1_current_shape = 1;
1355 
1356 	if ((dec0_pf2_bitmap = bitmap_alloc(512,512)) == 0) {
1357 		dec0_vh_stop ();
1358 		return 1;
1359 	}
1360 	dec0_pf2_current_shape = 1;
1361 
1362 	if ((dec0_pf3_bitmap = bitmap_alloc(512,512)) == 0) {
1363 		dec0_vh_stop ();
1364 		return 1;
1365 	}
1366 	dec0_pf3_current_shape = 1;
1367 
1368 	if ((dec0_tf2_bitmap = bitmap_alloc(512,512)) == 0) {
1369 		dec0_vh_stop ();
1370 		return 1;
1371 	}
1372 
1373 	if ((dec0_tf3_bitmap = bitmap_alloc(512,512)) == 0) {
1374 		dec0_vh_stop ();
1375 		return 1;
1376 	}
1377 
1378 	dec0_pf1_dirty = (unsigned char*)malloc(TEXTRAM_SIZE);
1379 	dec0_pf3_dirty = (unsigned char*)malloc(TILERAM_SIZE);
1380 	dec0_pf2_dirty = (unsigned char*)malloc(TILERAM_SIZE);
1381 
1382 	memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
1383 	memset(dec0_pf2_dirty,1,TILERAM_SIZE);
1384 	memset(dec0_pf3_dirty,1,TILERAM_SIZE);
1385 
1386 	dec0_spriteram=spriteram;
1387 
1388 	return 0;
1389 }
1390 
dec0_vh_start(void)1391 int dec0_vh_start (void)
1392 {
1393 	dec0_nodma_vh_start();
1394 	dec0_spriteram=(unsigned char*)malloc(0x800);
1395 
1396 	return 0;
1397 }
1398 
1399 /******************************************************************************/
1400 
1401