1 /***************************************************************************
2 
3   vidhrdw.c
4 
5 ***************************************************************************/
6 
7 #include "driver.h"
8 #include "vidhrdw/generic.h"
9 #include <math.h>
10 
11 data16_t *nemesis_videoram1b;
12 data16_t *nemesis_videoram2b;
13 data16_t *nemesis_videoram1f;
14 data16_t *nemesis_videoram2f;
15 
16 data16_t *nemesis_characterram;
17 size_t nemesis_characterram_size;
18 data16_t *nemesis_xscroll1,*nemesis_xscroll2,*nemesis_yscroll;
19 data16_t *nemesis_yscroll1,*nemesis_yscroll2;
20 
21 static int spriteram_words;
22 static int tilemap_flip;
23 static int flipscreen;
24 
25 static struct tilemap *background, *foreground;
26 
27 static unsigned char *blank_characterdata; /* pseudo character */
28 
29 /* gfxram dirty flags */
30 static unsigned char *char_dirty;	/* 2048 chars */
31 
32 /* we should be able to draw sprite gfx directly without caching to GfxElements */
33 static unsigned char *sprite_dirty;	/* 512 sprites */
34 static unsigned char *sprite3216_dirty;	/* 256 sprites */
35 static unsigned char *sprite816_dirty;	/* 1024 sprites */
36 static unsigned char *sprite1632_dirty;	/* 256 sprites */
37 static unsigned char *sprite3232_dirty;	/* 128 sprites */
38 static unsigned char *sprite168_dirty;	/* 1024 sprites */
39 static unsigned char *sprite6464_dirty;	/* 32 sprites */
40 
get_bg_tile_info(int offs)41 static void get_bg_tile_info( int offs )
42 {
43 	int code,color,flags;
44 	code = nemesis_videoram1f[offs];
45 	color = nemesis_videoram2f[offs];
46 	flags = 0;
47 	if ( color & 0x80)  flags |= TILE_FLIPX;
48 	if ( code & 0x0800) flags |= TILE_FLIPY;
49 	if ((~code & 0x2000) || ((code & 0xc000) == 0x4000))
50 		 flags |= TILE_IGNORE_TRANSPARENCY;
51 	if (code & 0xf800) {
52 		SET_TILE_INFO( 0, code&0x7ff, color&0x7f, flags );
53 	} else {
54 		SET_TILE_INFO( 0, 0x800, 0x00, 0 );
55 	}
56 	tile_info.priority = (code & 0x1000)>>12;
57 }
58 
get_fg_tile_info(int offs)59 static void get_fg_tile_info( int offs )
60 {
61 	int code,color,flags;
62 	code = nemesis_videoram1b[offs];
63 	color = nemesis_videoram2b[offs];
64 	flags = 0;
65 	if ( color & 0x80)  flags |= TILE_FLIPX;
66 	if ( code & 0x0800) flags |= TILE_FLIPY;
67 	if ((~code & 0x2000) || ((code & 0xc000) == 0x4000))
68 		 flags |= TILE_IGNORE_TRANSPARENCY;
69 	if (code & 0xf800) {
70 		SET_TILE_INFO( 0, code&0x7ff, color&0x7f, flags );
71 	} else {
72 		SET_TILE_INFO( 0, 0x800, 0x00, 0 );
73 	}
74 	tile_info.priority = (code & 0x1000)>>12;
75 }
76 
WRITE16_HANDLER(nemesis_gfx_flipx_w)77 WRITE16_HANDLER( nemesis_gfx_flipx_w )
78 {
79 	if (ACCESSING_LSB)
80 	{
81 		flipscreen = data & 0x01;
82 		if (flipscreen)
83 			tilemap_flip |= TILEMAP_FLIPX;
84 		else
85 			tilemap_flip &= ~TILEMAP_FLIPX;
86 
87 		tilemap_set_flip(ALL_TILEMAPS, tilemap_flip);
88 	}
89 }
90 
WRITE16_HANDLER(nemesis_gfx_flipy_w)91 WRITE16_HANDLER( nemesis_gfx_flipy_w )
92 {
93 	if (ACCESSING_LSB)
94 	{
95 		if (data & 0x01)
96 			tilemap_flip |= TILEMAP_FLIPY;
97 		else
98 			tilemap_flip &= ~TILEMAP_FLIPY;
99 
100 		tilemap_set_flip(ALL_TILEMAPS, tilemap_flip);
101 	}
102 }
103 
WRITE16_HANDLER(nemesis_palette_word_w)104 WRITE16_HANDLER( nemesis_palette_word_w )
105 {
106 	int r,g,b,bit1,bit2,bit3,bit4,bit5;
107 
108 	COMBINE_DATA(paletteram16 + offset);
109 	data = paletteram16[offset];
110 
111 	/* Mish, 30/11/99 - Schematics show the resistor values are:
112 		300 Ohms
113 		620 Ohms
114 		1200 Ohms
115 		2400 Ohms
116 		4700 Ohms
117 
118 		So the correct weights per bit are 8, 17, 33, 67, 130
119 	*/
120 
121 	#define MULTIPLIER 8 * bit1 + 17 * bit2 + 33 * bit3 + 67 * bit4 + 130 * bit5
122 
123 	bit1=(data >>  0)&1;
124 	bit2=(data >>  1)&1;
125 	bit3=(data >>  2)&1;
126 	bit4=(data >>  3)&1;
127 	bit5=(data >>  4)&1;
128 	r = MULTIPLIER;
129 	r = pow (r/255.0, 2)*255;
130 	bit1=(data >>  5)&1;
131 	bit2=(data >>  6)&1;
132 	bit3=(data >>  7)&1;
133 	bit4=(data >>  8)&1;
134 	bit5=(data >>  9)&1;
135 	g = MULTIPLIER;
136 	g = pow (g/255.0, 2)*255;
137 	bit1=(data >>  10)&1;
138 	bit2=(data >>  11)&1;
139 	bit3=(data >>  12)&1;
140 	bit4=(data >>  13)&1;
141 	bit5=(data >>  14)&1;
142 	b = MULTIPLIER;
143 	b = pow (b/255.0, 2)*255;
144 
145 	palette_set_color(offset,r,g,b);
146 }
147 
WRITE16_HANDLER(salamander_palette_word_w)148 WRITE16_HANDLER( salamander_palette_word_w )
149 {
150 	int r,g,b;
151 
152 	COMBINE_DATA(paletteram16 + offset);
153 	offset &= ~1;
154 
155 	data = ((paletteram16[offset] << 8) & 0xff00) | (paletteram16[offset+1] & 0xff);
156 
157 	r = (data >>  0) & 0x1f;
158 	g = (data >>  5) & 0x1f;
159 	b = (data >> 10) & 0x1f;
160 
161 	r = (r << 3) | (r >> 2);
162 	g = (g << 3) | (g >> 2);
163 	b = (b << 3) | (b >> 2);
164 
165 	palette_set_color(offset / 2,r,g,b);
166 }
167 
READ16_HANDLER(nemesis_videoram1b_word_r)168 READ16_HANDLER( nemesis_videoram1b_word_r )
169 {
170 	return nemesis_videoram1b[offset];
171 }
READ16_HANDLER(nemesis_videoram1f_word_r)172 READ16_HANDLER( nemesis_videoram1f_word_r )
173 {
174 	return nemesis_videoram1f[offset];
175 }
176 
WRITE16_HANDLER(nemesis_videoram1b_word_w)177 WRITE16_HANDLER( nemesis_videoram1b_word_w )
178 {
179 	COMBINE_DATA(nemesis_videoram1b + offset);
180 	tilemap_mark_tile_dirty( foreground,offset );
181 }
WRITE16_HANDLER(nemesis_videoram1f_word_w)182 WRITE16_HANDLER( nemesis_videoram1f_word_w )
183 {
184 	COMBINE_DATA(nemesis_videoram1f + offset);
185 	tilemap_mark_tile_dirty( background,offset );
186 }
187 
READ16_HANDLER(nemesis_videoram2b_word_r)188 READ16_HANDLER( nemesis_videoram2b_word_r )
189 {
190 	return nemesis_videoram2b[offset];
191 }
READ16_HANDLER(nemesis_videoram2f_word_r)192 READ16_HANDLER( nemesis_videoram2f_word_r )
193 {
194 	return nemesis_videoram2f[offset];
195 }
196 
WRITE16_HANDLER(nemesis_videoram2b_word_w)197 WRITE16_HANDLER( nemesis_videoram2b_word_w )
198 {
199 	COMBINE_DATA(nemesis_videoram2b + offset);
200 	tilemap_mark_tile_dirty( foreground,offset );
201 }
WRITE16_HANDLER(nemesis_videoram2f_word_w)202 WRITE16_HANDLER( nemesis_videoram2f_word_w )
203 {
204 	COMBINE_DATA(nemesis_videoram2f + offset);
205 	tilemap_mark_tile_dirty( background,offset );
206 }
207 
208 
READ16_HANDLER(gx400_xscroll1_word_r)209 READ16_HANDLER( gx400_xscroll1_word_r ) { return nemesis_xscroll1[offset];}
READ16_HANDLER(gx400_xscroll2_word_r)210 READ16_HANDLER( gx400_xscroll2_word_r ) { return nemesis_xscroll2[offset];}
READ16_HANDLER(gx400_yscroll_word_r)211 READ16_HANDLER( gx400_yscroll_word_r ) { return nemesis_yscroll[offset];}
READ16_HANDLER(gx400_yscroll1_word_r)212 READ16_HANDLER( gx400_yscroll1_word_r ) { return nemesis_yscroll1[offset];}
READ16_HANDLER(gx400_yscroll2_word_r)213 READ16_HANDLER( gx400_yscroll2_word_r ) { return nemesis_yscroll2[offset];}
214 
WRITE16_HANDLER(gx400_xscroll1_word_w)215 WRITE16_HANDLER( gx400_xscroll1_word_w ) { COMBINE_DATA(nemesis_xscroll1 + offset);}
WRITE16_HANDLER(gx400_xscroll2_word_w)216 WRITE16_HANDLER( gx400_xscroll2_word_w ) { COMBINE_DATA(nemesis_xscroll2 + offset);}
WRITE16_HANDLER(gx400_yscroll_word_w)217 WRITE16_HANDLER( gx400_yscroll_word_w ) { COMBINE_DATA(nemesis_yscroll + offset);}
WRITE16_HANDLER(gx400_yscroll1_word_w)218 WRITE16_HANDLER( gx400_yscroll1_word_w ) { COMBINE_DATA(nemesis_yscroll1 + offset);}
WRITE16_HANDLER(gx400_yscroll2_word_w)219 WRITE16_HANDLER( gx400_yscroll2_word_w ) { COMBINE_DATA(nemesis_yscroll2 + offset);}
220 
221 
222 /* we have to straighten out the 16-bit word into bytes for gfxdecode() to work */
READ16_HANDLER(nemesis_characterram_word_r)223 READ16_HANDLER( nemesis_characterram_word_r )
224 {
225 	return nemesis_characterram[offset];
226 }
227 
WRITE16_HANDLER(nemesis_characterram_word_w)228 WRITE16_HANDLER( nemesis_characterram_word_w )
229 {
230 	data16_t oldword = nemesis_characterram[offset];
231 	COMBINE_DATA(nemesis_characterram + offset);
232 	data = nemesis_characterram[offset];
233 
234 	if (oldword != data)
235 	{
236 		char_dirty[offset / 16] = 1;
237 		sprite_dirty[offset / 64] = 1;
238 		sprite3216_dirty[offset / 128] = 1;
239 		sprite1632_dirty[offset / 128] = 1;
240 		sprite3232_dirty[offset / 256] = 1;
241 		sprite168_dirty[offset / 32] = 1;
242 		sprite816_dirty[offset / 32] = 1;
243 		sprite6464_dirty[offset / 1024] = 1;
244 	}
245 }
246 
247 
248 /* Fix the gdx decode info for lsb first systems */
nemesis_lsbify_gfx(void)249 static void nemesis_lsbify_gfx(void)
250 {
251 	int i, j;
252 	for(i=0; i<8; i++)
253 		for(j=0; j<Machine->drv->gfxdecodeinfo[i].gfxlayout->width; j++)
254 			Machine->drv->gfxdecodeinfo[i].gfxlayout->xoffset[j] ^= 8;
255 }
256 
257 
258 /* claim a palette dirty array */
VIDEO_START(nemesis)259 VIDEO_START( nemesis )
260 {
261 #ifndef MSB_FIRST
262 	nemesis_lsbify_gfx();
263 #endif
264 
265 	spriteram_words = spriteram_size / 2;
266 
267 	background = tilemap_create(
268 		get_bg_tile_info, tilemap_scan_rows, TILEMAP_TRANSPARENT, 8,8, 64,32 );
269 
270 	foreground = tilemap_create(
271 		get_fg_tile_info, tilemap_scan_rows, TILEMAP_TRANSPARENT, 8,8, 64,32 );
272 
273 	if( !(background && foreground) )
274 		return 1;
275 
276 	tilemap_set_transparent_pen( background, 0 );
277 	tilemap_set_transparent_pen( foreground, 0 );
278 	tilemap_set_scroll_rows( background, 256 );
279 	tilemap_set_scroll_rows( foreground, 256 );
280 
281 	char_dirty = auto_malloc(2048);
282 	if (!char_dirty)
283 		return 1;
284 	memset(char_dirty,1,2048);
285 
286 	sprite_dirty = auto_malloc(512);
287 	if (!sprite_dirty)
288 		return 1;
289 	memset(sprite_dirty,1,512);
290 
291 	sprite3216_dirty = auto_malloc(256);
292 	if (!sprite3216_dirty)
293 		return 1;
294 	memset(sprite3216_dirty,1,256);
295 
296 	sprite1632_dirty = auto_malloc(256);
297 	if (!sprite1632_dirty)
298 		return 1;
299 	memset(sprite1632_dirty,1,256);
300 
301 	sprite3232_dirty = auto_malloc(128);
302 	if (!sprite3232_dirty)
303 		return 1;
304 	memset(sprite3232_dirty,1,128);
305 
306 	sprite168_dirty = auto_malloc(1024);
307 	if (!sprite168_dirty)
308 		return 1;
309 	memset(sprite168_dirty,1,1024);
310 
311 	sprite816_dirty = auto_malloc(1024);
312 	if (!sprite816_dirty)
313 		return 1;
314 	memset(sprite816_dirty,1,32);
315 
316 	sprite6464_dirty = auto_malloc(32);
317 	if (!sprite6464_dirty)
318 		return 1;
319 	memset(sprite6464_dirty,1,32);
320 
321 	memset(nemesis_characterram,0,nemesis_characterram_size);
322 
323 
324 	blank_characterdata = auto_malloc(32*8/8*(2048+1));
325 	if (!blank_characterdata)
326 		return 1;
327 	memset(blank_characterdata,0x00,32*8/8*(2048+1));
328 	decodechar(Machine->gfx[0],0x800,(unsigned char *)blank_characterdata,
329 					Machine->drv->gfxdecodeinfo[0].gfxlayout);
330 
331 	flipscreen = 0;
332 	tilemap_flip = 0;
333 
334 	return 0;
335 }
336 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)337 static void draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cliprect)
338 {
339 	/*
340 	 *	16 bytes per sprite, in memory from 56000-56fff
341 	 *
342 	 *	byte	0 :	relative priority.
343 	 *	byte	2 :	size (?) value #E0 means not used., bit 0x01 is flipx
344 	                0xc0 is upper 2 bits of zoom.
345 					0x38 is size.
346 	 * 	byte	4 :	zoom = 0xff
347 	 *	byte	6 :	low bits sprite code.
348 	 *	byte	8 :	color + hi bits sprite code., bit 0x20 is flipy bit. bit 0x01 is high bit of X pos.
349 	 *	byte	A :	X position.
350 	 *	byte	C :	Y position.
351 	 * 	byte	E :	not used.
352 	 */
353 
354 	int adress;	/* start of sprite in spriteram */
355 	int sx;	/* sprite X-pos */
356 	int sy;	/* sprite Y-pos */
357 	int code;	/* start of sprite in obj RAM */
358 	int color;	/* color of the sprite */
359 	int flipx,flipy;
360 	int zoom;
361 	int char_type;
362 	int priority;
363 	int size;
364 	int w,h;
365 
366 	for (priority=256-1; priority>=0; priority--)
367 	{
368 		for (adress = spriteram_words-8; adress >= 0; adress -= 8)
369 		{
370 			if((spriteram16[adress] & 0xff)!=priority) continue;
371 
372 			zoom = spriteram16[adress+2] & 0xff;
373 			if (!(spriteram16[adress+2] & 0xff00) && ((spriteram16[adress+3] & 0xff00) != 0xff00))
374 				code = spriteram16[adress+3] + ((spriteram16[adress+4] & 0xc0) << 2);
375 			else
376 				code = (spriteram16[adress+3] & 0xff) + ((spriteram16[adress+4] & 0xc0) << 2);
377 
378 			if (zoom != 0xFF || code!=0)
379 			{
380 				size=spriteram16[adress+1];
381 				zoom+=(size&0xc0)<<2;
382 
383 				sx = spriteram16[adress+5]&0xff;
384 				sy = spriteram16[adress+6]&0xff;
385 				if(spriteram16[adress+4]&1)
386 					sx-=0x100;	/* fixes left side clip */
387 				color = (spriteram16[adress+4] & 0x1e) >> 1;
388 				flipx = spriteram16[adress+1] & 0x01;
389 				flipy = spriteram16[adress+4] & 0x20;
390 
391 				switch(size&0x38)
392 				{
393 					case 0x00:	/* sprite 32x32*/
394 						char_type=4;
395 						code/=8;
396 						w=32;
397 						h=32;
398 						break;
399 					case 0x08:	/* sprite 16x32 */
400 						char_type=5;
401 						code/=4;
402 						w=16;
403 						h=32;
404 						break;
405 					case 0x10:	/* sprite 32x16 */
406 						char_type=2;
407 						code/=4;
408 						w=32;
409 						h=16;
410 						break;
411 					case 0x18:		/* sprite 64x64 */
412 						char_type=7;
413 						code/=32;
414 						w=64;
415 						h=64;
416 						break;
417 					case 0x20:	/* char 8x8 */
418 						char_type=0;
419 						code*=2;
420 						w=8;
421 						h=8;
422 						break;
423 					case 0x28:		/* sprite 16x8 */
424 						char_type=6;
425 						w=16;
426 						h=8;
427 						break;
428 					case 0x30:	/* sprite 8x16 */
429 						char_type=3;
430 						w=8;
431 						h=16;
432 						break;
433 					case 0x38:
434 					default:	/* sprite 16x16 */
435 						char_type=1;
436 						code/=2;
437 						w=16;
438 						h=16;
439 						break;
440 				}
441 
442 				if( zoom )
443 				{
444 					zoom = ((1<<16)*0x80/zoom) + 0x0200;
445 					if (flipscreen)
446 					{
447 						sx = 256 - ((zoom * w) >> 16) - sx;
448 						sy = 256 - ((zoom * h) >> 16) - sy;
449 						flipx = !flipx;
450 						flipy = !flipy;
451 					}
452 					pdrawgfxzoom(bitmap,Machine->gfx[char_type],
453 						code,
454 						color,
455 						flipx,flipy,
456 						sx,sy,
457 						cliprect,TRANSPARENCY_PEN,0,
458 						zoom,zoom,
459 						0xfff0 );
460 				}
461 			} /* if sprite */
462 		} /* for loop */
463 	} /* priority */
464 }
465 
466 /******************************************************************************/
467 
update_gfx(void)468 static void update_gfx(void)
469 {
470 	int offs,code;
471 	int bAnyDirty;
472 
473 	bAnyDirty = 0;
474 	for (offs = 0x800 - 1;offs >= 0;offs --)
475 	{
476 		if (char_dirty[offs] )
477 		{
478 			decodechar(Machine->gfx[0],offs,(unsigned char *)nemesis_characterram,
479 					Machine->drv->gfxdecodeinfo[0].gfxlayout);
480 			bAnyDirty = 1;
481 			char_dirty[offs] = 0;
482 		}
483 	}
484 	if( bAnyDirty )
485 	{
486 		tilemap_mark_all_tiles_dirty( background );
487 		tilemap_mark_all_tiles_dirty( foreground );
488 	}
489 
490 	for (offs = 0;offs < spriteram_words;offs += 8)
491 	{
492 		int char_type;
493 		int zoom;
494 
495 		zoom = spriteram16[offs+2] & 0xff;
496 		if (!(spriteram16[offs+2] & 0xff00) && ((spriteram16[offs+3] & 0xff00) != 0xff00))
497 			code = spriteram16[offs+3] + ((spriteram16[offs+4] & 0xc0) << 2);
498 		else
499 			code = (spriteram16[offs+3] & 0xff) + ((spriteram16[offs+4] & 0xc0) << 2);
500 
501 		if (zoom != 0xFF || code!=0)
502 		{
503 			int size = spriteram16[offs+1];
504 			switch(size&0x38)
505 			{
506 				case 0x00:
507 					/* sprite 32x32*/
508 					char_type=4;
509 					code/=8;
510 					if (sprite3232_dirty[code] == 1)
511 					{
512 						decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
513 								Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
514 						sprite3232_dirty[code] = 0;
515 					}
516 					break;
517 				case 0x08:
518 					/* sprite 16x32 */
519 					char_type=5;
520 					code/=4;
521 					if (sprite1632_dirty[code] == 1)
522 					{
523 						decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
524 								Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
525 						sprite1632_dirty[code] = 0;
526 
527 					}
528 					break;
529 				case 0x10:
530 					/* sprite 32x16 */
531 					char_type=2;
532 					code/=4;
533 					if (sprite3216_dirty[code] == 1)
534 					{
535 						decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
536 								Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
537 						sprite3216_dirty[code] = 0;
538 					}
539 					break;
540 				case 0x18:
541 					/* sprite 64x64 */
542 					char_type=7;
543 					code/=32;
544 					if (sprite6464_dirty[code] == 1)
545 					{
546 						decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
547 								Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
548 						sprite6464_dirty[code] = 0;
549 					}
550 					break;
551 				case 0x20:
552 					/* char 8x8 */
553 					char_type=0;
554 					code*=2;
555 					if (char_dirty[code] == 1)
556 					{
557 						decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
558 						Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
559 						char_dirty[code] = 0;
560 					}
561 					break;
562 				case 0x28:
563 					/* sprite 16x8 */
564 					char_type=6;
565 					if (sprite168_dirty[code] == 1)
566 					{
567 						decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
568 								Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
569 						sprite168_dirty[code] = 0;
570 					}
571 					break;
572 				case 0x30:
573 					/* sprite 8x16 */
574 					char_type=3;
575 					if (sprite816_dirty[code] == 1)
576 					{
577 						decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
578 								Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
579 						sprite816_dirty[code] = 0;
580 					}
581 					break;
582 				default:
583 					logerror("UN-SUPPORTED SPRITE SIZE %-4x\n",size&0x38);
584 				case 0x38:
585 					/* sprite 16x16 */
586 					char_type=1;
587 					code/=2;
588 					if (sprite_dirty[code] == 1)
589 					{
590 						decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
591 								Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
592 						sprite_dirty[code] = 2;
593 
594 					}
595 					break;
596 			}
597 		}
598 	}
599 }
600 
601 /******************************************************************************/
602 
VIDEO_UPDATE(nemesis)603 VIDEO_UPDATE( nemesis )
604 {
605 	int offs;
606 
607 	update_gfx();
608 
609 	fillbitmap(priority_bitmap,0,cliprect);
610 	fillbitmap(bitmap,Machine->pens[0],cliprect);
611 
612 	tilemap_set_scrolly( background, 0, (nemesis_yscroll[0x180] & 0xff) );
613 
614 	for (offs = 0;offs < 256;offs++)
615 	{
616 		tilemap_set_scrollx( background, offs,
617 			(nemesis_xscroll2[offs] & 0xff) + ((nemesis_xscroll2[0x100 + offs] & 0x01) << 8) - (flipscreen ? 0x107 : 0) );
618 		tilemap_set_scrollx( foreground, offs,
619 			(nemesis_xscroll1[offs] & 0xff) + ((nemesis_xscroll1[0x100 + offs] & 0x01) << 8) - (flipscreen ? 0x107 : 0) );
620 	}
621 
622 	tilemap_draw(bitmap,cliprect,background,0,1);
623 	tilemap_draw(bitmap,cliprect,foreground,0,2);
624 	tilemap_draw(bitmap,cliprect,background,1,4);
625 	tilemap_draw(bitmap,cliprect,foreground,1,8);
626 
627 	draw_sprites(bitmap,cliprect);
628 }
629 
VIDEO_UPDATE(salamand)630 VIDEO_UPDATE( salamand )
631 {
632 	int offs;
633 	struct rectangle clip;
634 
635 	update_gfx();
636 
637 	fillbitmap(priority_bitmap,0,cliprect);
638 	fillbitmap(bitmap,Machine->pens[0],cliprect);
639 
640 	clip.min_x = 0;
641 	clip.max_x = 255;
642 
643 	tilemap_set_scroll_cols( background, 64 );
644 	tilemap_set_scroll_cols( foreground, 64 );
645 	tilemap_set_scroll_rows( background, 1 );
646 	tilemap_set_scroll_rows( foreground, 1 );
647 
648 	for (offs = 0; offs < 64; offs++)
649 	{
650 		tilemap_set_scrolly( background, offs, nemesis_yscroll1[offs] );
651 		tilemap_set_scrolly( foreground, offs, nemesis_yscroll2[offs] );
652 	}
653 
654 	for (offs = cliprect->min_y; offs <= cliprect->max_y; offs++)
655 	{
656 		clip.min_y = offs;
657 		clip.max_y = offs;
658 
659 		tilemap_set_scrollx( background, 0,
660 			((nemesis_xscroll2[offs] & 0xff) + ((nemesis_xscroll2[0x100 + offs] & 1) << 8)) );
661 		tilemap_set_scrollx( foreground, 0,
662 			((nemesis_xscroll1[offs] & 0xff) + ((nemesis_xscroll1[0x100 + offs] & 1) << 8)) );
663 
664 		tilemap_draw(bitmap,&clip,foreground,0,1);
665 		tilemap_draw(bitmap,&clip,background,0,2);
666 		tilemap_draw(bitmap,&clip,foreground,1,4);
667 		tilemap_draw(bitmap,&clip,background,1,8);
668 	}
669 
670 	draw_sprites(bitmap,cliprect);
671 }
672