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