1 /***************************************************************************
2 
3   vidhrdw.c
4 
5   Functions to emulate the video hardware of the machine.
6 
7 ***************************************************************************/
8 
9 #include "driver.h"
10 #include "vidhrdw/generic.h"
11 
12 
13 
14 unsigned char *rallyx_videoram2,*rallyx_colorram2;
15 unsigned char *rallyx_radarx,*rallyx_radary,*rallyx_radarattr;
16 size_t rallyx_radarram_size;
17 unsigned char *rallyx_scrollx,*rallyx_scrolly;
18 static unsigned char *dirtybuffer2;	/* keep track of modified portions of the screen */
19 											/* to speed up video refresh */
20 static struct mame_bitmap *tmpbitmap1;
21 
22 
23 
24 static struct rectangle radarvisiblearea =
25 {
26 	28*8, 36*8-1,
27 	0*8, 28*8-1
28 };
29 
30 static struct rectangle radarvisibleareaflip =
31 {
32 	0*8, 8*8-1,
33 	0*8, 28*8-1
34 };
35 
36 
37 
38 /***************************************************************************
39 
40   Convert the color PROMs into a more useable format.
41 
42   Rally X has one 32x8 palette PROM and one 256x4 color lookup table PROM.
43   The palette PROM is connected to the RGB output this way:
44 
45   bit 7 -- 220 ohm resistor  -- BLUE
46         -- 470 ohm resistor  -- BLUE
47         -- 220 ohm resistor  -- GREEN
48         -- 470 ohm resistor  -- GREEN
49         -- 1  kohm resistor  -- GREEN
50         -- 220 ohm resistor  -- RED
51         -- 470 ohm resistor  -- RED
52   bit 0 -- 1  kohm resistor  -- RED
53 
54   In Rally-X there is a 1 kohm pull-down on B only, in Locomotion the
55   1 kohm pull-down is an all three RGB outputs.
56 
57 ***************************************************************************/
PALETTE_INIT(rallyx)58 PALETTE_INIT( rallyx )
59 {
60 	int i;
61 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
62 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
63 
64 
65 	for (i = 0;i < Machine->drv->total_colors;i++)
66 	{
67 		int bit0,bit1,bit2,r,g,b;
68 
69 
70 		/* red component */
71 		bit0 = (*color_prom >> 0) & 0x01;
72 		bit1 = (*color_prom >> 1) & 0x01;
73 		bit2 = (*color_prom >> 2) & 0x01;
74 		r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
75 		/* green component */
76 		bit0 = (*color_prom >> 3) & 0x01;
77 		bit1 = (*color_prom >> 4) & 0x01;
78 		bit2 = (*color_prom >> 5) & 0x01;
79 		g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
80 		/* blue component */
81 		bit0 = 0;
82 		bit1 = (*color_prom >> 6) & 0x01;
83 		bit2 = (*color_prom >> 7) & 0x01;
84 		b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
85 
86 		palette_set_color(i,r,g,b);
87 
88 		color_prom++;
89 	}
90 
91 	/* color_prom now points to the beginning of the lookup table */
92 
93 	/* character lookup table */
94 	/* sprites use the same color lookup table as characters */
95 	/* characters use colors 0-15 */
96 	for (i = 0;i < TOTAL_COLORS(0);i++)
97 		COLOR(0,i) = *(color_prom++) & 0x0f;
98 
99 	/* radar dots lookup table */
100 	/* they use colors 16-19 */
101 	for (i = 0;i < 4;i++)
102 		COLOR(2,i) = 16 + i;
103 }
104 
PALETTE_INIT(locomotn)105 PALETTE_INIT( locomotn )
106 {
107 	int i;
108 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
109 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
110 
111 
112 	for (i = 0;i < Machine->drv->total_colors;i++)
113 	{
114 		int bit0,bit1,bit2,r,g,b;
115 
116 
117 		/* red component */
118 		bit0 = (*color_prom >> 0) & 0x01;
119 		bit1 = (*color_prom >> 1) & 0x01;
120 		bit2 = (*color_prom >> 2) & 0x01;
121 		r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
122 		/* green component */
123 		bit0 = (*color_prom >> 3) & 0x01;
124 		bit1 = (*color_prom >> 4) & 0x01;
125 		bit2 = (*color_prom >> 5) & 0x01;
126 		g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
127 		/* blue component */
128 		bit0 = (*color_prom >> 6) & 0x01;
129 		bit1 = (*color_prom >> 7) & 0x01;
130 		b = 0x50 * bit0 + 0xab * bit1;
131 
132 		palette_set_color(i,r,g,b);
133 
134 		color_prom++;
135 	}
136 
137 	/* color_prom now points to the beginning of the lookup table */
138 
139 	/* character lookup table */
140 	/* sprites use the same color lookup table as characters */
141 	/* characters use colors 0-15 */
142 	for (i = 0;i < TOTAL_COLORS(0);i++)
143 		COLOR(0,i) = *(color_prom++) & 0x0f;
144 
145 	/* radar dots lookup table */
146 	/* they use colors 16-19 */
147 	for (i = 0;i < 4;i++)
148 		COLOR(2,i) = 16 + i;
149 }
150 
151 
152 /***************************************************************************
153 
154   Start the video hardware emulation.
155 
156 ***************************************************************************/
VIDEO_START(rallyx)157 VIDEO_START( rallyx )
158 {
159 	if (video_start_generic() != 0)
160 		return 1;
161 
162 	if ((dirtybuffer2 = auto_malloc(videoram_size)) == 0)
163 		return 1;
164 	memset(dirtybuffer2,1,videoram_size);
165 
166 	if ((tmpbitmap1 = auto_bitmap_alloc(32*8,32*8)) == 0)
167 		return 1;
168 
169 	return 0;
170 }
171 
172 
173 
WRITE_HANDLER(rallyx_videoram2_w)174 WRITE_HANDLER( rallyx_videoram2_w )
175 {
176 	if (rallyx_videoram2[offset] != data)
177 	{
178 		dirtybuffer2[offset] = 1;
179 
180 		rallyx_videoram2[offset] = data;
181 	}
182 }
183 
184 
WRITE_HANDLER(rallyx_colorram2_w)185 WRITE_HANDLER( rallyx_colorram2_w )
186 {
187 	if (rallyx_colorram2[offset] != data)
188 	{
189 		dirtybuffer2[offset] = 1;
190 
191 		rallyx_colorram2[offset] = data;
192 	}
193 }
194 
195 
196 
WRITE_HANDLER(rallyx_flipscreen_w)197 WRITE_HANDLER( rallyx_flipscreen_w )
198 {
199 	if (flip_screen != (data & 1))
200 	{
201 		flip_screen_set(data & 1);
202 		memset(dirtybuffer,1,videoram_size);
203 		memset(dirtybuffer2,1,videoram_size);
204 	}
205 }
206 
207 
208 
209 /***************************************************************************
210 
211   Draw the game screen in the given mame_bitmap.
212   Do NOT call osd_update_display() from this function, it will be called by
213   the main emulation engine.
214 
215 ***************************************************************************/
216 
VIDEO_UPDATE(rallyx)217 VIDEO_UPDATE( rallyx )
218 {
219 	int offs,sx,sy;
220 	int scrollx,scrolly;
221 const int displacement = 1;
222 
223 
224 	if (flip_screen)
225 	{
226 		scrollx = (*rallyx_scrollx - displacement) + 32;
227 		scrolly = (*rallyx_scrolly + 16) - 32;
228 	}
229 	else
230 	{
231 		scrollx = -(*rallyx_scrollx - 3*displacement);
232 		scrolly = -(*rallyx_scrolly + 16);
233 	}
234 
235 
236 	/* draw the below sprite priority characters */
237 	for (offs = videoram_size - 1;offs >= 0;offs--)
238 	{
239 		if (rallyx_colorram2[offs] & 0x20)  continue;
240 
241 		if (dirtybuffer2[offs])
242 		{
243 			int flipx,flipy;
244 
245 
246 			dirtybuffer2[offs] = 0;
247 
248 			sx = offs % 32;
249 			sy = offs / 32;
250 			flipx = ~rallyx_colorram2[offs] & 0x40;
251 			flipy = rallyx_colorram2[offs] & 0x80;
252 			if (flip_screen)
253 			{
254 				sx = 31 - sx;
255 				sy = 31 - sy;
256 				flipx = !flipx;
257 				flipy = !flipy;
258 			}
259 
260 			drawgfx(tmpbitmap1,Machine->gfx[0],
261 					rallyx_videoram2[offs],
262 					rallyx_colorram2[offs] & 0x3f,
263 					flipx,flipy,
264 					8*sx,8*sy,
265 					0,TRANSPARENCY_NONE,0);
266 		}
267 	}
268 
269 	/* update radar */
270 	for (offs = videoram_size - 1;offs >= 0;offs--)
271 	{
272 		if (dirtybuffer[offs])
273 		{
274 			int flipx,flipy;
275 
276 
277 			dirtybuffer[offs] = 0;
278 
279 			sx = (offs % 32) ^ 4;
280 			sy = offs / 32 - 2;
281 			flipx = ~colorram[offs] & 0x40;
282 			flipy = colorram[offs] & 0x80;
283 			if (flip_screen)
284 			{
285 				sx = 7 - sx;
286 				sy = 27 - sy;
287 				flipx = !flipx;
288 				flipy = !flipy;
289 			}
290 
291 			drawgfx(tmpbitmap,Machine->gfx[0],
292 					videoram[offs],
293 					colorram[offs] & 0x3f,
294 					flipx,flipy,
295 					8*sx,8*sy,
296 					&radarvisibleareaflip,TRANSPARENCY_NONE,0);
297 		}
298 	}
299 
300 
301 	/* copy the temporary bitmap to the screen */
302 	copyscrollbitmap(bitmap,tmpbitmap1,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
303 
304 
305 	/* draw the sprites */
306 	for (offs = 0;offs < spriteram_size;offs += 2)
307 	{
308 		sx = spriteram[offs + 1] + ((spriteram_2[offs + 1] & 0x80) << 1) - displacement;
309 		sy = 225 - spriteram_2[offs] - displacement;
310 
311 		drawgfx(bitmap,Machine->gfx[1],
312 				(spriteram[offs] & 0xfc) >> 2,
313 				spriteram_2[offs + 1] & 0x3f,
314 				spriteram[offs] & 1,spriteram[offs] & 2,
315 				sx,sy,
316 				&Machine->visible_area,TRANSPARENCY_COLOR,0);
317 	}
318 
319 
320 	/* draw the above sprite priority characters */
321 	for (offs = videoram_size - 1;offs >= 0;offs--)
322 	{
323 		int flipx,flipy;
324 
325 
326 		if (!(rallyx_colorram2[offs] & 0x20))  continue;
327 
328 		sx = offs % 32;
329 		sy = offs / 32;
330 		flipx = ~rallyx_colorram2[offs] & 0x40;
331 		flipy = rallyx_colorram2[offs] & 0x80;
332 		if (flip_screen)
333 		{
334 			sx = 31 - sx;
335 			sy = 31 - sy;
336 			flipx = !flipx;
337 			flipy = !flipy;
338 		}
339 
340 		drawgfx(bitmap,Machine->gfx[0],
341 				rallyx_videoram2[offs],
342 				rallyx_colorram2[offs] & 0x3f,
343 				flipx,flipy,
344 				(8*sx + scrollx) & 0xff,(8*sy + scrolly) & 0xff,
345 				0,TRANSPARENCY_NONE,0);
346 		drawgfx(bitmap,Machine->gfx[0],
347 				rallyx_videoram2[offs],
348 				rallyx_colorram2[offs] & 0x3f,
349 				flipx,flipy,
350 				((8*sx + scrollx) & 0xff) - 256,(8*sy + scrolly) & 0xff,
351 				0,TRANSPARENCY_NONE,0);
352 	}
353 
354 
355 	/* radar */
356 	if (flip_screen)
357 		copybitmap(bitmap,tmpbitmap,0,0,0,0,&radarvisibleareaflip,TRANSPARENCY_NONE,0);
358 	else
359 		copybitmap(bitmap,tmpbitmap,0,0,28*8,0,&radarvisiblearea,TRANSPARENCY_NONE,0);
360 
361 
362 	/* draw the cars on the radar */
363 	for (offs = 0; offs < rallyx_radarram_size;offs++)
364 	{
365 		int x,y;
366 
367 		x = rallyx_radarx[offs] + ((~rallyx_radarattr[offs] & 0x01) << 8);
368 		y = 237 - rallyx_radary[offs];
369 		if (flip_screen) x -= 3;
370 
371 		drawgfx(bitmap,Machine->gfx[2],
372 				((rallyx_radarattr[offs] & 0x0e) >> 1) ^ 0x07,
373 				0,
374 				0,0,
375 				x,y,
376 				&Machine->visible_area,TRANSPARENCY_PEN,3);
377 	}
378 }
379 
380 
381 
VIDEO_UPDATE(jungler)382 VIDEO_UPDATE( jungler )
383 {
384 	int offs,sx,sy;
385 	int scrollx,scrolly;
386 const int displacement = 0;
387 
388 
389 	if (flip_screen)
390 	{
391 		scrollx = (*rallyx_scrollx - displacement) + 32;
392 		scrolly = (*rallyx_scrolly + 16) - 32;
393 	}
394 	else
395 	{
396 		scrollx = -(*rallyx_scrollx - 3*displacement);
397 		scrolly = -(*rallyx_scrolly + 16);
398 	}
399 
400 
401 	for (offs = videoram_size - 1;offs >= 0;offs--)
402 	{
403 		if (dirtybuffer2[offs])
404 		{
405 			int flipx,flipy;
406 
407 
408 			dirtybuffer2[offs] = 0;
409 
410 			sx = offs % 32;
411 			sy = offs / 32;
412 			flipx = ~rallyx_colorram2[offs] & 0x40;
413 			flipy = rallyx_colorram2[offs] & 0x80;
414 			if (flip_screen)
415 			{
416 				sx = 31 - sx;
417 				sy = 31 - sy;
418 				flipx = !flipx;
419 				flipy = !flipy;
420 			}
421 
422 			drawgfx(tmpbitmap1,Machine->gfx[0],
423 					rallyx_videoram2[offs],
424 					rallyx_colorram2[offs] & 0x3f,
425 					flipx,flipy,
426 					8*sx,8*sy,
427 					0,TRANSPARENCY_NONE,0);
428 		}
429 	}
430 
431 	/* update radar */
432 	for (offs = videoram_size - 1;offs >= 0;offs--)
433 	{
434 		if (dirtybuffer[offs])
435 		{
436 			int flipx,flipy;
437 
438 
439 			dirtybuffer[offs] = 0;
440 
441 			sx = (offs % 32) ^ 4;
442 			sy = offs / 32 - 2;
443 			flipx = ~colorram[offs] & 0x40;
444 			flipy = colorram[offs] & 0x80;
445 			if (flip_screen)
446 			{
447 				sx = 7 - sx;
448 				sy = 27 - sy;
449 				flipx = !flipx;
450 				flipy = !flipy;
451 			}
452 
453 			drawgfx(tmpbitmap,Machine->gfx[0],
454 					videoram[offs],
455 					colorram[offs] & 0x3f,
456 					flipx,flipy,
457 					8*sx,8*sy,
458 					&radarvisibleareaflip,TRANSPARENCY_NONE,0);
459 		}
460 	}
461 
462 
463 	/* copy the temporary bitmap to the screen */
464 	copyscrollbitmap(bitmap,tmpbitmap1,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
465 
466 
467 	/* draw the sprites */
468 	for (offs = 0;offs < spriteram_size;offs += 2)
469 	{
470 		sx = spriteram[offs + 1] + ((spriteram_2[offs + 1] & 0x80) << 1) - displacement;
471 		sy = 225 - spriteram_2[offs] - displacement;
472 
473 		drawgfx(bitmap,Machine->gfx[1],
474 				(spriteram[offs] & 0xfc) >> 2,
475 				spriteram_2[offs + 1] & 0x3f,
476 				spriteram[offs] & 1,spriteram[offs] & 2,
477 				sx,sy,
478 				&Machine->visible_area,TRANSPARENCY_COLOR,0);
479 	}
480 
481 
482 	/* radar */
483 	if (flip_screen)
484 		copybitmap(bitmap,tmpbitmap,0,0,0,0,&radarvisibleareaflip,TRANSPARENCY_NONE,0);
485 	else
486 		copybitmap(bitmap,tmpbitmap,0,0,28*8,0,&radarvisiblearea,TRANSPARENCY_NONE,0);
487 
488 
489 	/* draw the cars on the radar */
490 	for (offs = 0; offs < rallyx_radarram_size;offs++)
491 	{
492 		int x,y;
493 
494 		x = rallyx_radarx[offs] + ((~rallyx_radarattr[offs] & 0x08) << 5);
495 		y = 237 - rallyx_radary[offs];
496 
497 		drawgfx(bitmap,Machine->gfx[2],
498 				(rallyx_radarattr[offs] & 0x07) ^ 0x07,
499 				0,
500 				0,0,
501 				x,y,
502 				&Machine->visible_area,TRANSPARENCY_PEN,0);
503 	}
504 }
505 
506 
507 
VIDEO_UPDATE(locomotn)508 VIDEO_UPDATE( locomotn )
509 {
510 	int offs,sx,sy;
511 const int displacement = 0;
512 
513 
514 	/* for every character in the Video RAM, check if it has been modified */
515 	/* since last time and update it accordingly. */
516 	for (offs = videoram_size - 1;offs >= 0;offs--)
517 	{
518 		if (dirtybuffer2[offs])
519 		{
520 			int flipx,flipy;
521 
522 
523 			dirtybuffer2[offs] = 0;
524 
525 			sx = offs % 32;
526 			sy = offs / 32;
527 			/* not a mistake, one bit selects both  flips */
528 			flipx = rallyx_colorram2[offs] & 0x80;
529 			flipy = rallyx_colorram2[offs] & 0x80;
530 			if (flip_screen)
531 			{
532 				sx = 31 - sx;
533 				sy = 31 - sy;
534 				flipx = !flipx;
535 				flipy = !flipy;
536 			}
537 
538 			drawgfx(tmpbitmap1,Machine->gfx[0],
539 					(rallyx_videoram2[offs]&0x7f) + 2*(rallyx_colorram2[offs]&0x40) + 2*(rallyx_videoram2[offs]&0x80),
540 					rallyx_colorram2[offs] & 0x3f,
541 					flipx,flipy,
542 					8*sx,8*sy,
543 					0,TRANSPARENCY_NONE,0);
544 		}
545 	}
546 
547 	/* update radar */
548 	for (offs = videoram_size - 1;offs >= 0;offs--)
549 	{
550 		if (dirtybuffer[offs])
551 		{
552 			int flipx,flipy;
553 
554 
555 			dirtybuffer[offs] = 0;
556 
557 			sx = (offs % 32) ^ 4;
558 			sy = offs / 32 - 2;
559 			/* not a mistake, one bit selects both  flips */
560 			flipx = colorram[offs] & 0x80;
561 			flipy = colorram[offs] & 0x80;
562 			if (flip_screen)
563 			{
564 				sx = 7 - sx;
565 				sy = 27 - sy;
566 				flipx = !flipx;
567 				flipy = !flipy;
568 			}
569 
570 			drawgfx(tmpbitmap,Machine->gfx[0],
571 					(videoram[offs]&0x7f) + 2*(colorram[offs]&0x40) + 2*(videoram[offs]&0x80),
572 					colorram[offs] & 0x3f,
573 					flipx,flipy,
574 					8*sx,8*sy,
575 					&radarvisibleareaflip,TRANSPARENCY_NONE,0);
576 		}
577 	}
578 
579 
580 	/* copy the temporary bitmap to the screen */
581 	{
582 		int scrollx,scrolly;
583 
584 
585 		if (flip_screen)
586 		{
587 			scrollx = (*rallyx_scrollx) + 32;
588 			scrolly = (*rallyx_scrolly + 16) - 32;
589 		}
590 		else
591 		{
592 			scrollx = -(*rallyx_scrollx);
593 			scrolly = -(*rallyx_scrolly + 16);
594 		}
595 
596 		copyscrollbitmap(bitmap,tmpbitmap1,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
597 	}
598 
599 
600 	/* radar */
601 	if (flip_screen)
602 		copybitmap(bitmap,tmpbitmap,0,0,0,0,&radarvisibleareaflip,TRANSPARENCY_NONE,0);
603 	else
604 		copybitmap(bitmap,tmpbitmap,0,0,28*8,0,&radarvisiblearea,TRANSPARENCY_NONE,0);
605 
606 
607 	/* draw the sprites */
608 	for (offs = 0;offs < spriteram_size;offs += 2)
609 	{
610 		sx = spriteram[offs + 1] + ((spriteram_2[offs + 1] & 0x80) << 1) - displacement;
611 		sy = 225 - spriteram_2[offs] - displacement;
612 
613 		/* handle reduced visible area in some games */
614 		if (flip_screen && Machine->drv->default_visible_area.max_x == 32*8-1) sx += 32;
615 
616 		drawgfx(bitmap,Machine->gfx[1],
617 				((spriteram[offs] & 0x7c) >> 2) + 0x20*(spriteram[offs] & 0x01) + ((spriteram[offs] & 0x80) >> 1),
618 				spriteram_2[offs + 1] & 0x3f,
619 				spriteram[offs] & 2,spriteram[offs] & 2,
620 				sx,sy,
621 				&Machine->visible_area,TRANSPARENCY_COLOR,0);
622 	}
623 
624 
625 	/* draw the cars on the radar */
626 	for (offs = 0; offs < rallyx_radarram_size;offs++)
627 	{
628 		int x,y;
629 
630 		x = rallyx_radarx[offs] + ((~rallyx_radarattr[offs] & 0x08) << 5);
631 		y = 237 - rallyx_radary[offs];
632 		if (flip_screen) x -= 3;
633 
634 		/* handle reduced visible area in some games */
635 		if (flip_screen && Machine->drv->default_visible_area.max_x == 32*8-1) x += 32;
636 
637 		drawgfx(bitmap,Machine->gfx[2],
638 				(rallyx_radarattr[offs & 0x0f] & 0x07) ^ 0x07,
639 				0,
640 				0,0,
641 				x,y,
642 				&Machine->visible_area,TRANSPARENCY_PEN,3);
643 	}
644 }
645 
646 
647 
VIDEO_UPDATE(commsega)648 VIDEO_UPDATE( commsega )
649 {
650 	int offs,sx,sy;
651 
652 
653 	/* for every character in the Video RAM, check if it has been modified */
654 	/* since last time and update it accordingly. */
655 	for (offs = videoram_size - 1;offs >= 0;offs--)
656 	{
657 		if (dirtybuffer2[offs])
658 		{
659 			int flipx,flipy;
660 
661 
662 			dirtybuffer2[offs] = 0;
663 
664 			sx = offs % 32;
665 			sy = offs / 32;
666 			/* not a mistake, one bit selects both  flips */
667 			flipx = rallyx_colorram2[offs] & 0x80;
668 			flipy = rallyx_colorram2[offs] & 0x80;
669 			if (flip_screen)
670 			{
671 				sx = 31 - sx;
672 				sy = 31 - sy;
673 				flipx = !flipx;
674 				flipy = !flipy;
675 			}
676 
677 			drawgfx(tmpbitmap1,Machine->gfx[0],
678 					(rallyx_videoram2[offs]&0x7f) + 2*(rallyx_colorram2[offs]&0x40) + 2*(rallyx_videoram2[offs]&0x80),
679 					rallyx_colorram2[offs] & 0x3f,
680 					flipx,flipy,
681 					8*sx,8*sy,
682 					0,TRANSPARENCY_NONE,0);
683 		}
684 	}
685 
686 	/* update radar */
687 	for (offs = videoram_size - 1;offs >= 0;offs--)
688 	{
689 		if (dirtybuffer[offs])
690 		{
691 			int flipx,flipy;
692 
693 
694 			dirtybuffer[offs] = 0;
695 
696 			sx = (offs % 32) ^ 4;
697 			sy = offs / 32 - 2;
698 			/* not a mistake, one bit selects both  flips */
699 			flipx = colorram[offs] & 0x80;
700 			flipy = colorram[offs] & 0x80;
701 			if (flip_screen)
702 			{
703 				sx = 7 - sx;
704 				sy = 27 - sy;
705 				flipx = !flipx;
706 				flipy = !flipy;
707 			}
708 
709 			drawgfx(tmpbitmap,Machine->gfx[0],
710 					(videoram[offs]&0x7f) + 2*(colorram[offs]&0x40) + 2*(videoram[offs]&0x80),
711 					colorram[offs] & 0x3f,
712 					flipx,flipy,
713 					8*sx,8*sy,
714 					&radarvisibleareaflip,TRANSPARENCY_NONE,0);
715 		}
716 	}
717 
718 
719 	/* copy the temporary bitmap to the screen */
720 	{
721 		int scrollx,scrolly;
722 
723 
724 		if (flip_screen)
725 		{
726 			scrollx = (*rallyx_scrollx) + 32;
727 			scrolly = (*rallyx_scrolly + 16) - 32;
728 		}
729 		else
730 		{
731 			scrollx = -(*rallyx_scrollx);
732 			scrolly = -(*rallyx_scrolly + 16);
733 		}
734 
735 		copyscrollbitmap(bitmap,tmpbitmap1,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
736 	}
737 
738 
739 	/* radar */
740 	if (flip_screen)
741 		copybitmap(bitmap,tmpbitmap,0,0,0,0,&radarvisibleareaflip,TRANSPARENCY_NONE,0);
742 	else
743 		copybitmap(bitmap,tmpbitmap,0,0,28*8,0,&radarvisiblearea,TRANSPARENCY_NONE,0);
744 
745 
746 	/* draw the sprites */
747 	for (offs = 0;offs < spriteram_size;offs += 2)
748 	{
749 		int flipx,flipy;
750 
751 
752 		sx = spriteram[offs + 1] - 1;
753 		sy = 224 - spriteram_2[offs];
754 if (flip_screen) sx += 32;
755 		flipx = ~spriteram[offs] & 1;
756 		flipy = ~spriteram[offs] & 2;
757 		if (flip_screen)
758 		{
759 			flipx = !flipx;
760 			flipy = !flipy;
761 		}
762 
763 		if (spriteram[offs] & 0x01)	/* ??? */
764 			drawgfx(bitmap,Machine->gfx[1],
765 					((spriteram[offs] & 0x7c) >> 2) + 0x20*(spriteram[offs] & 0x01) + ((spriteram[offs] & 0x80) >> 1),
766 					spriteram_2[offs + 1] & 0x3f,
767 					flipx,flipy,
768 					sx,sy,
769 					&Machine->visible_area,TRANSPARENCY_COLOR,0);
770 	}
771 
772 
773 	/* draw the cars on the radar */
774 	for (offs = 0; offs < rallyx_radarram_size;offs++)
775 	{
776 		int x,y;
777 
778 
779 		/* it looks like the addresses used are
780 		   a000-a003  a004-a00f
781 		   8020-8023  8034-803f
782 		   8820-8823  8834-883f
783 		   so 8024-8033 and 8824-8833 are not used
784 		*/
785 
786 		x = rallyx_radarx[offs] + ((~rallyx_radarattr[offs & 0x0f] & 0x08) << 5);
787 		if (flip_screen) x += 32;
788 		y = 237 - rallyx_radary[offs];
789 
790 
791 		drawgfx(bitmap,Machine->gfx[2],
792 				(rallyx_radarattr[offs & 0x0f] & 0x07) ^ 0x07,
793 				0,
794 				0,0,
795 				x,y,
796 				&Machine->visible_area,TRANSPARENCY_PEN,3);
797 	}
798 }
799