1 /***************************************************************************
2 
3     vidhrdw.c
4 
5     Functions to emulate the video hardware of the machine.
6 
7 This file is also used by scregg.c
8 
9 ***************************************************************************/
10 
11 #include "driver.h"
12 #include "vidhrdw/generic.h"
13 
14 
15 unsigned char *lnc_charbank;
16 unsigned char *bnj_backgroundram;
17 unsigned char *zoar_scrollram;
18 unsigned char *deco_charram;
19 size_t bnj_backgroundram_size;
20 
21 static int sprite_dirty[256];
22 static int char_dirty[1024];
23 
24 static int btime_palette = 0;
25 static unsigned char bnj_scroll1 = 0;
26 static unsigned char bnj_scroll2 = 0;
27 static unsigned char *dirtybuffer2 = 0;
28 static struct mame_bitmap *background_bitmap;
29 static int lnc_sound_interrupt_enabled = 0;
30 
31 /***************************************************************************
32 
33     Burger Time doesn't have a color PROM. It uses RAM to dynamically
34     create the palette.
35     The palette RAM is connected to the RGB output this way:
36 
37     bit 7 -- 15 kohm resistor  -- BLUE (inverted)
38           -- 33 kohm resistor  -- BLUE (inverted)
39           -- 15 kohm resistor  -- GREEN (inverted)
40           -- 33 kohm resistor  -- GREEN (inverted)
41           -- 47 kohm resistor  -- GREEN (inverted)
42           -- 15 kohm resistor  -- RED (inverted)
43           -- 33 kohm resistor  -- RED (inverted)
44     bit 0 -- 47 kohm resistor  -- RED (inverted)
45 
46 ***************************************************************************/
PALETTE_INIT(btime)47 PALETTE_INIT( btime )
48 {
49 	int i;
50 
51 
52 	/* Burger Time doesn't have a color PROM, but Hamburge has. */
53 	/* This function is also used by Eggs. */
54 	if (color_prom == 0) return;
55 
56 	for (i = 0;i < Machine->drv->total_colors;i++)
57 	{
58 		int bit0,bit1,bit2,r,g,b;
59 
60 		/* red component */
61 		bit0 = (color_prom[i] >> 0) & 0x01;
62 		bit1 = (color_prom[i] >> 1) & 0x01;
63 		bit2 = (color_prom[i] >> 2) & 0x01;
64 		r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
65 		/* green component */
66 		bit0 = (color_prom[i] >> 3) & 0x01;
67 		bit1 = (color_prom[i] >> 4) & 0x01;
68 		bit2 = (color_prom[i] >> 5) & 0x01;
69 		g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
70 		/* blue component */
71 		bit0 = 0;
72 		bit1 = (color_prom[i] >> 6) & 0x01;
73 		bit2 = (color_prom[i] >> 7) & 0x01;
74 		b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
75 
76 		palette_set_color(i,r,g,b);
77 	}
78 }
79 
80 /***************************************************************************
81 
82     Convert the color PROMs into a more useable format.
83 
84     The PROM is connected to the RGB output this way:
85 
86     bit 7 -- 47 kohm resistor  -- RED
87           -- 33 kohm resistor  -- RED
88           -- 15 kohm resistor  -- RED
89           -- 47 kohm resistor  -- GREEN
90           -- 33 kohm resistor  -- GREEN
91           -- 15 kohm resistor  -- GREEN
92           -- 33 kohm resistor  -- BLUE
93     bit 0 -- 15 kohm resistor  -- BLUE
94 
95 ***************************************************************************/
PALETTE_INIT(lnc)96 PALETTE_INIT( lnc )
97 {
98 	int i;
99 
100 
101 	for (i = 0;i < Machine->drv->total_colors;i++)
102 	{
103 		int bit0,bit1,bit2,r,g,b;
104 
105 		/* red component */
106 		bit0 = (color_prom[i] >> 7) & 0x01;
107 		bit1 = (color_prom[i] >> 6) & 0x01;
108 		bit2 = (color_prom[i] >> 5) & 0x01;
109 		r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
110 		/* green component */
111 		bit0 = (color_prom[i] >> 4) & 0x01;
112 		bit1 = (color_prom[i] >> 3) & 0x01;
113 		bit2 = (color_prom[i] >> 2) & 0x01;
114 		g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
115 		/* blue component */
116 		bit0 = 0;
117 		bit1 = (color_prom[i] >> 1) & 0x01;
118 		bit2 = (color_prom[i] >> 0) & 0x01;
119 		b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
120 
121 		palette_set_color(i,r,g,b);
122 	}
123 }
124 
125 
MACHINE_INIT(lnc)126 MACHINE_INIT( lnc )
127 {
128     *lnc_charbank = 1;
129 }
130 
131 
132 /***************************************************************************
133 
134 Start the video hardware emulation.
135 
136 ***************************************************************************/
VIDEO_START(bnj)137 VIDEO_START( bnj )
138 {
139     if (video_start_generic() != 0)
140         return 1;
141 
142     if ((dirtybuffer2 = auto_malloc(bnj_backgroundram_size)) == 0)
143         return 1;
144     memset(dirtybuffer2,1,bnj_backgroundram_size);
145 
146     /* the background area is twice as wide as the screen */
147     if ((background_bitmap = auto_bitmap_alloc(2*Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
148         return 1;
149 
150     bnj_scroll1 = 0;
151     bnj_scroll2 = 0;
152 
153     return 0;
154 }
155 
VIDEO_START(btime)156 VIDEO_START( btime )
157 {
158     bnj_scroll1 = 0;
159     bnj_scroll2 = 0;
160 
161     return video_start_generic();
162 }
163 
164 
165 
WRITE_HANDLER(btime_paletteram_w)166 WRITE_HANDLER( btime_paletteram_w )
167 {
168     /* RGB output is inverted */
169     paletteram_BBGGGRRR_w(offset,~data);
170 }
171 
WRITE_HANDLER(lnc_videoram_w)172 WRITE_HANDLER( lnc_videoram_w )
173 {
174     if (videoram[offset] != data || colorram[offset] != *lnc_charbank)
175     {
176         videoram[offset] = data;
177         colorram[offset] = *lnc_charbank;
178 
179         dirtybuffer[offset] = 1;
180     }
181 }
182 
READ_HANDLER(btime_mirrorvideoram_r)183 READ_HANDLER( btime_mirrorvideoram_r )
184 {
185     int x,y;
186 
187     /* swap x and y coordinates */
188     x = offset / 32;
189     y = offset % 32;
190     offset = 32 * y + x;
191 
192     return videoram_r(offset);
193 }
194 
READ_HANDLER(btime_mirrorcolorram_r)195 READ_HANDLER( btime_mirrorcolorram_r )
196 {
197     int x,y;
198 
199     /* swap x and y coordinates */
200     x = offset / 32;
201     y = offset % 32;
202     offset = 32 * y + x;
203 
204     return colorram_r(offset);
205 }
206 
WRITE_HANDLER(btime_mirrorvideoram_w)207 WRITE_HANDLER( btime_mirrorvideoram_w )
208 {
209     int x,y;
210 
211     /* swap x and y coordinates */
212     x = offset / 32;
213     y = offset % 32;
214     offset = 32 * y + x;
215 
216     videoram_w(offset,data);
217 }
218 
WRITE_HANDLER(lnc_mirrorvideoram_w)219 WRITE_HANDLER( lnc_mirrorvideoram_w )
220 {
221     int x,y;
222 
223     /* swap x and y coordinates */
224     x = offset / 32;
225     y = offset % 32;
226     offset = 32 * y + x;
227 
228     lnc_videoram_w(offset,data);
229 }
230 
WRITE_HANDLER(btime_mirrorcolorram_w)231 WRITE_HANDLER( btime_mirrorcolorram_w )
232 {
233     int x,y;
234 
235     /* swap x and y coordinates */
236     x = offset / 32;
237     y = offset % 32;
238     offset = 32 * y + x;
239 
240     colorram_w(offset,data);
241 }
242 
WRITE_HANDLER(deco_charram_w)243 WRITE_HANDLER( deco_charram_w )
244 {
245     if (deco_charram[offset] == data)  return;
246 
247     deco_charram[offset] = data;
248 
249     offset &= 0x1fff;
250 
251     /* dirty sprite */
252     sprite_dirty[offset >> 5] = 1;
253 
254     /* diry char */
255     char_dirty  [offset >> 3] = 1;
256 }
257 
WRITE_HANDLER(bnj_background_w)258 WRITE_HANDLER( bnj_background_w )
259 {
260     if (bnj_backgroundram[offset] != data)
261     {
262         dirtybuffer2[offset] = 1;
263 
264         bnj_backgroundram[offset] = data;
265     }
266 }
267 
WRITE_HANDLER(bnj_scroll1_w)268 WRITE_HANDLER( bnj_scroll1_w )
269 {
270     /* Dirty screen if background is being turned off*/
271     if (bnj_scroll1 && !data)
272     {
273 		set_vh_global_attribute(NULL,0);
274     }
275 
276     bnj_scroll1 = data;
277 }
278 
WRITE_HANDLER(bnj_scroll2_w)279 WRITE_HANDLER( bnj_scroll2_w )
280 {
281     bnj_scroll2 = data;
282 }
283 
WRITE_HANDLER(zoar_video_control_w)284 WRITE_HANDLER( zoar_video_control_w )
285 {
286     /* Zoar video control*/
287     /**/
288     /* Bit 0-2 = Unknown (always 0). Marked as MCOL on schematics*/
289     /* Bit 3-4 = Palette*/
290     /* Bit 7   = Flip Screen*/
291 
292 	set_vh_global_attribute(&btime_palette, (data & 0x30) >> 3);
293 	flip_screen_set(data & 0x80);
294 }
295 
WRITE_HANDLER(btime_video_control_w)296 WRITE_HANDLER( btime_video_control_w )
297 {
298     /* Btime video control*/
299     /**/
300     /* Bit 0   = Flip screen*/
301     /* Bit 1-7 = Unknown*/
302 
303 	flip_screen_set(data & 0x01);
304 }
305 
WRITE_HANDLER(bnj_video_control_w)306 WRITE_HANDLER( bnj_video_control_w )
307 {
308     /* Bnj/Lnc works a little differently than the btime/eggs (apparently). */
309     /* According to the information at: */
310     /* http://www.davesclassics.com/arcade/Switch_Settings/BumpNJump.sw */
311     /* SW8 is used for cocktail video selection (as opposed to controls), */
312     /* but bit 7 of the input port is used for vblank input. */
313     /* My guess is that this switch open circuits some connection to */
314     /* the monitor hardware. */
315     /* For now we just check 0x40 in DSW1, and ignore the write if we */
316     /* are in upright controls mode. */
317 
318     if (input_port_3_r(0) & 0x40) /* cocktail mode */
319         btime_video_control_w(offset, data);
320 }
321 
WRITE_HANDLER(lnc_video_control_w)322 WRITE_HANDLER( lnc_video_control_w )
323 {
324     /* I have a feeling that this only works by coincidence. I couldn't*/
325     /* figure out how NMI's are disabled by the sound processor*/
326     lnc_sound_interrupt_enabled = data & 0x08;
327 
328     bnj_video_control_w(offset, data & 0x01);
329 }
330 
WRITE_HANDLER(disco_video_control_w)331 WRITE_HANDLER( disco_video_control_w )
332 {
333 	set_vh_global_attribute(&btime_palette, (data >> 2) & 0x03);
334 
335 	if (!(input_port_3_r(0) & 0x40)) /* cocktail mode */
336 	{
337 		flip_screen_set(data & 0x01);
338 	}
339 }
340 
341 
INTERRUPT_GEN(lnc_sound_interrupt)342 INTERRUPT_GEN( lnc_sound_interrupt )
343 {
344     if (lnc_sound_interrupt_enabled)
345     	cpu_set_irq_line(1, IRQ_LINE_NMI, PULSE_LINE);
346 }
347 
348 
349 /***************************************************************************
350 
351 Draw the game screen in the given mame_bitmap.
352 Do NOT call osd_update_display() from this function, it will be called by
353 the main emulation engine.
354 
355 ***************************************************************************/
drawchars(struct mame_bitmap * bitmap,int transparency,int color,int priority)356 static void drawchars(struct mame_bitmap *bitmap, int transparency, int color, int priority)
357 {
358     int offs;
359 
360     /* for every character in the Video RAM, check if it has been modified */
361     /* since last time and update it accordingly. If the background is on, */
362     /* draw characters as sprites */
363 
364     for (offs = videoram_size - 1;offs >= 0;offs--)
365     {
366         int sx,sy,code;
367 
368         if (!dirtybuffer[offs] && (bitmap == tmpbitmap)) continue;
369 
370         dirtybuffer[offs] = 0;
371 
372         code = videoram[offs] + 256 * (colorram[offs] & 3);
373 
374         /* check priority */
375         if ((priority != -1) && (priority != ((code >> 7) & 0x01)))  continue;
376 
377         sx = 31 - (offs / 32);
378         sy = offs % 32;
379 
380         if (flip_screen)
381         {
382             sx = 31 - sx;
383             sy = 31 - sy;
384         }
385 
386         drawgfx(bitmap,Machine->gfx[0],
387                 code,
388                 color,
389                 flip_screen,flip_screen,
390                 8*sx,8*sy,
391                 &Machine->visible_area,transparency,0);
392     }
393 }
394 
drawsprites(struct mame_bitmap * bitmap,int color,int sprite_y_adjust,int sprite_y_adjust_flip_screen,unsigned char * sprite_ram,int interleave)395 static void drawsprites(struct mame_bitmap *bitmap, int color,
396                         int sprite_y_adjust, int sprite_y_adjust_flip_screen,
397                         unsigned char *sprite_ram, int interleave)
398 {
399     int i,offs;
400 
401     /* Draw the sprites */
402     for (i = 0, offs = 0;i < 8; i++, offs += 4*interleave)
403     {
404         int sx,sy,flipx,flipy;
405 
406         if (!(sprite_ram[offs + 0] & 0x01)) continue;
407 
408         sx = 240 - sprite_ram[offs + 3*interleave];
409         sy = 240 - sprite_ram[offs + 2*interleave];
410 
411         flipx = sprite_ram[offs + 0] & 0x04;
412         flipy = sprite_ram[offs + 0] & 0x02;
413 
414         if (flip_screen)
415         {
416             sx = 240 - sx;
417             sy = 240 - sy + sprite_y_adjust_flip_screen;
418 
419             flipx = !flipx;
420             flipy = !flipy;
421         }
422 
423         sy -= sprite_y_adjust;
424 
425         drawgfx(bitmap,Machine->gfx[1],
426                 sprite_ram[offs + interleave],
427                 color,
428                 flipx,flipy,
429                 sx,sy,
430                 &Machine->visible_area,TRANSPARENCY_PEN,0);
431 
432         sy += (flip_screen ? -256 : 256);
433 
434         /* Wrap around*/
435         drawgfx(bitmap,Machine->gfx[1],
436                 sprite_ram[offs + interleave],
437                 color,
438                 flipx,flipy,
439                 sx,sy,
440                 &Machine->visible_area,TRANSPARENCY_PEN,0);
441     }
442 }
443 
444 
drawbackground(struct mame_bitmap * bitmap,unsigned char * tilemap)445 static void drawbackground(struct mame_bitmap *bitmap, unsigned char* tilemap)
446 {
447     int i, offs;
448 
449     int scroll = -(bnj_scroll2 | ((bnj_scroll1 & 0x03) << 8));
450 
451     /* One extra iteration for wrap around*/
452     for (i = 0; i < 5; i++, scroll += 256)
453     {
454         int tileoffset = tilemap[i & 3] * 0x100;
455 
456         /* Skip if this title is completely off the screen*/
457         if (scroll > 256)  break;
458         if (scroll < -256) continue;
459 
460         for (offs = 0; offs < 0x100; offs++)
461         {
462             int sx,sy;
463 
464             sx = 240 - (16 * (offs / 16) + scroll);
465             sy = 16 * (offs % 16);
466 
467             if (flip_screen)
468             {
469                 sx = 240 - sx;
470                 sy = 240 - sy;
471             }
472 
473             drawgfx(bitmap, Machine->gfx[2],
474                     memory_region(REGION_GFX3)[tileoffset + offs],
475                     btime_palette,
476                     flip_screen,flip_screen,
477                     sx,sy,
478                     0,TRANSPARENCY_NONE,0);
479         }
480     }
481 }
482 
483 
decode_modified(unsigned char * sprite_ram,int interleave)484 static void decode_modified(unsigned char *sprite_ram, int interleave)
485 {
486     int i,offs;
487 
488 
489     /* decode dirty characters */
490     for (offs = videoram_size - 1;offs >= 0;offs--)
491     {
492         int code;
493 
494         code = videoram[offs] + 256 * (colorram[offs] & 3);
495 
496         switch (char_dirty[code])
497         {
498         case 1:
499             decodechar(Machine->gfx[0],code,deco_charram,Machine->drv->gfxdecodeinfo[0].gfxlayout);
500             char_dirty[code] = 2;
501             /* fall through */
502         case 2:
503             dirtybuffer[offs] = 1;
504             break;
505         default:
506             break;
507         }
508     }
509 
510     for (i = 0; i < sizeof(char_dirty)/sizeof(char_dirty[0]); i++)
511     {
512         if (char_dirty[i] == 2)  char_dirty[i] = 0;
513     }
514 
515     /* decode dirty sprites */
516     for (i = 0, offs = 0;i < 8; i++, offs += 4*interleave)
517     {
518         int code;
519 
520         code  = sprite_ram[offs + interleave];
521         if (sprite_dirty[code])
522         {
523             sprite_dirty[code] = 0;
524 
525             decodechar(Machine->gfx[1],code,deco_charram,Machine->drv->gfxdecodeinfo[1].gfxlayout);
526         }
527     }
528 }
529 
530 
VIDEO_UPDATE(btime)531 VIDEO_UPDATE( btime )
532 {
533     if (get_vh_global_attribute_changed())
534         memset(dirtybuffer,1,videoram_size);
535 
536     if (bnj_scroll1 & 0x10)
537     {
538         int i, start;
539 
540         /* Generate tile map*/
541         static unsigned char btime_tilemap[4];
542 
543         if (flip_screen)
544             start = 0;
545         else
546             start = 1;
547 
548         for (i = 0; i < 4; i++)
549         {
550             btime_tilemap[i] = start | (bnj_scroll1 & 0x04);
551             start = (start+1) & 0x03;
552         }
553 
554         drawbackground(bitmap, btime_tilemap);
555 
556         drawchars(bitmap, TRANSPARENCY_PEN, 0, -1);
557     }
558     else
559     {
560         drawchars(tmpbitmap, TRANSPARENCY_NONE, 0, -1);
561 
562         /* copy the temporary bitmap to the screen */
563         copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
564     }
565 
566     drawsprites(bitmap, 0, 1, 0, videoram, 0x20);
567 }
568 
569 
VIDEO_UPDATE(eggs)570 VIDEO_UPDATE( eggs )
571 {
572     if (get_vh_global_attribute_changed())
573         memset(dirtybuffer,1,videoram_size);
574 
575     drawchars(tmpbitmap, TRANSPARENCY_NONE, 0, -1);
576 
577     /* copy the temporary bitmap to the screen */
578     copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
579 
580     drawsprites(bitmap, 0, 0, 0, videoram, 0x20);
581 }
582 
583 
VIDEO_UPDATE(lnc)584 VIDEO_UPDATE( lnc )
585 {
586     if (get_vh_global_attribute_changed())
587         memset(dirtybuffer,1,videoram_size);
588 
589     drawchars(tmpbitmap, TRANSPARENCY_NONE, 0, -1);
590 
591     /* copy the temporary bitmap to the screen */
592     copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
593 
594     drawsprites(bitmap, 0, 1, 2, videoram, 0x20);
595 }
596 
597 
VIDEO_UPDATE(zoar)598 VIDEO_UPDATE( zoar )
599 {
600     if (get_vh_global_attribute_changed())
601         memset(dirtybuffer,1,videoram_size);
602 
603     if (bnj_scroll1 & 0x04)
604     {
605         drawbackground(bitmap, zoar_scrollram);
606 
607         drawchars(bitmap, TRANSPARENCY_PEN, btime_palette + 1, -1);
608     }
609     else
610     {
611         drawchars(tmpbitmap, TRANSPARENCY_NONE, btime_palette + 1, -1);
612 
613         /* copy the temporary bitmap to the screen */
614         copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
615     }
616 
617     /* The order is important for correct priorities */
618     drawsprites(bitmap, btime_palette + 1, 1, 2, videoram + 0x1f, 0x20);
619     drawsprites(bitmap, btime_palette + 1, 1, 2, videoram,        0x20);
620 }
621 
622 
VIDEO_UPDATE(bnj)623 VIDEO_UPDATE( bnj )
624 {
625     if (get_vh_global_attribute_changed())
626     {
627         memset(dirtybuffer,1,videoram_size);
628         memset(dirtybuffer2,1,bnj_backgroundram_size);
629     }
630 
631     /*
632      *  For each character in the background RAM, check if it has been
633      *  modified since last time and update it accordingly.
634      */
635     if (bnj_scroll1)
636     {
637         int scroll, offs;
638 
639         for (offs = bnj_backgroundram_size-1; offs >=0; offs--)
640         {
641             int sx,sy;
642 
643             if (!dirtybuffer2[offs]) continue;
644 
645             dirtybuffer2[offs] = 0;
646 
647             sx = 16 * ((offs < 0x100) ? ((offs % 0x80) / 8) : ((offs % 0x80) / 8) + 16);
648             sy = 16 * (((offs % 0x100) < 0x80) ? offs % 8 : (offs % 8) + 8);
649             sx = 496 - sx;
650 
651             if (flip_screen)
652             {
653                 sx = 496 - sx;
654                 sy = 240 - sy;
655             }
656 
657             drawgfx(background_bitmap, Machine->gfx[2],
658                     (bnj_backgroundram[offs] >> 4) + ((offs & 0x80) >> 3) + 32,
659                     0,
660                     flip_screen, flip_screen,
661                     sx, sy,
662                     0, TRANSPARENCY_NONE, 0);
663         }
664 
665         /* copy the background bitmap to the screen */
666         scroll = (bnj_scroll1 & 0x02) * 128 + 511 - bnj_scroll2;
667         if (!flip_screen)
668             scroll = 767-scroll;
669         copyscrollbitmap (bitmap, background_bitmap, 1, &scroll, 0, 0, &Machine->visible_area,TRANSPARENCY_NONE, 0);
670 
671         /* copy the low priority characters followed by the sprites
672            then the high priority characters */
673         drawchars(bitmap, TRANSPARENCY_PEN, 0, 1);
674         drawsprites(bitmap, 0, 0, 0, videoram, 0x20);
675         drawchars(bitmap, TRANSPARENCY_PEN, 0, 0);
676     }
677     else
678     {
679         drawchars(tmpbitmap, TRANSPARENCY_NONE, 0, -1);
680 
681         /* copy the temporary bitmap to the screen */
682         copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
683 
684         drawsprites(bitmap, 0, 0, 0, videoram, 0x20);
685     }
686 }
687 
688 
VIDEO_UPDATE(cookrace)689 VIDEO_UPDATE( cookrace )
690 {
691     int offs;
692 
693 
694     if (get_vh_global_attribute_changed())
695         memset(dirtybuffer,1,videoram_size);
696 
697     /*
698      *  For each character in the background RAM, check if it has been
699      *  modified since last time and update it accordingly.
700      */
701     for (offs = bnj_backgroundram_size-1; offs >=0; offs--)
702     {
703         int sx,sy;
704 
705         sx = 31 - (offs / 32);
706         sy = offs % 32;
707 
708         if (flip_screen)
709         {
710             sx = 31 - sx;
711             sy = 31 - sy;
712         }
713 
714         drawgfx(bitmap, Machine->gfx[2],
715                 bnj_backgroundram[offs],
716                 0,
717                 flip_screen, flip_screen,
718                 8*sx,8*sy,
719                 0, TRANSPARENCY_NONE, 0);
720     }
721 
722     drawchars(bitmap, TRANSPARENCY_PEN, 0, -1);
723 
724     drawsprites(bitmap, 0, 1, 0, videoram, 0x20);
725 }
726 
727 
VIDEO_UPDATE(disco)728 VIDEO_UPDATE( disco )
729 {
730     if (get_vh_global_attribute_changed())
731         memset(dirtybuffer,1,videoram_size);
732 
733     decode_modified(spriteram, 1);
734 
735     drawchars(tmpbitmap, TRANSPARENCY_NONE, btime_palette, -1);
736 
737     /* copy the temporary bitmap to the screen */
738     copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
739 
740     drawsprites(bitmap, btime_palette, 0, 0, spriteram, 1);
741 }
742