1 /***************************************************************************
2 
3 Sega System 16 Video Hardware
4 
5 Known issues:
6 - better abstraction of tilemap hardware is needed; a lot of this mess could and should
7 	be consolidated further
8 - many games have ROM patches - why?  let's emulate protection when possible
9 - several games fail their RAM self-test because of hacks in the drivers
10 - many registers are suspiciously plucked from working RAM
11 - several games have nvram according to the self test, but we aren't yet saving it
12 - many games suffer from sys16_refreshenable register not being mapped
13 - road-rendering routines need to be cleaned up or at least better described
14 - logical sprite height computation isn't quite right - garbage pixels are drawn
15 - screen orientation support for sprite drawing
16 - sprite drawing is unoptimized
17 - end-of-sprite marker support will fix some glitches
18 - shadow and partial shadow sprite support
19 - to achieve sprite-tilemap orthogonality we must draw sprites from front to back;
20 	this will also allow us to avoid processing the same shadowed pixel twice.
21 
22 The System16 video hardware consists of:
23 
24 - Road Layer (present only for certain games)
25 
26 - Two scrolling tilemap layers
27 
28 - Two alternate scrolling tilemap layers, normally invisible.
29 
30 - A fixed tilemap layer, normally used for score, lives display
31 
32 Each scrolling layer (foreground, background) is an arrangement
33 of 4 pages selected from 16 available pages, laid out as follows:
34 
35 	Page0  Page1
36 	Page2  Page3
37 
38 Each page is an arrangement of 8x8 tiles, 64 tiles wide, and 32 tiles high.
39 
40 Layers normally scroll as a whole, with xscroll and yscroll.
41 
42 However, layers can also be configured with screenwise rowscroll, if the most significant
43 bit of xscroll is set.  When a layer is in this mode, the splittable is used.
44 
45 When rowscroll is in effect, the most significant bit of rowscroll selects between the
46 default layer and an alternate layer associated with it.
47 
48 The foreground layer's tiles may be flagged as high-priority; this is used to mask
49 sprites, i.e. the grass in Altered Beast.
50 
51 The background layer's tiles may also be flagged as high-priority.  In this case,
52 it's really a transparency_pen effect rather.  Aurail uses this.
53 
54 Most games map Video Registers in textram as follows:
55 
56 type0:
57 most games
58 
59 type1:
60 alexkidd,fantzone,shinobl,hangon
61 mjleague
62 
63 others:
64 	shangon, shdancbl,
65 	dduxbl,eswat,
66 	passsht,passht4b
67 	quartet,quartet2,
68 	tetris,tturfbl,wb3bl
69 
70 sys16_textram:
71 type1		type0			function
72 ---------------------------------------
73 0x74f		0x740			sys16_fg_page
74 0x74e		0x741			sys16_bg_page
75 			0x742			sys16_fg2_page
76 			0x743			sys16_bg2_page
77 
78 0x792		0x748			sys16_fg_scrolly
79 0x793		0x749			sys16_bg_scrolly
80 			0x74a			sys16_fg2_scrolly
81 			0x74b			sys16_bg2_scrolly
82 
83 0x7fc		0x74c			sys16_fg_scrollx
84 0x7fd		0x74d			sys16_bg_scrollx
85 			0x74e			sys16_fg2_scrollx
86 			0x74f			sys16_bg2_scrollx
87 
88 			0x7c0..0x7df	sys18_splittab_fg_x
89 			0x7e0..0x7ff	sys18_splittab_bg_x
90 
91 ***************************************************************************/
92 #include "driver.h"
93 #include "system16.h"
94 #include "vidhrdw/res_net.h"
95 
96 /*
97 static void debug_draw( struct mame_bitmap *bitmap, int x, int y, unsigned int data ){
98 	int digit;
99 	for( digit=0; digit<4; digit++ ){
100 		drawgfx( bitmap, Machine->uifont,
101 			"0123456789abcdef"[data>>12],
102 			0,
103 			0,0,
104 			x+digit*6,y,
105 			&Machine->visible_area,TRANSPARENCY_NONE,0);
106 		data = (data<<4)&0xffff;
107 	}
108 }
109 
110 static void debug_vreg( struct mame_bitmap *bitmap ){
111 	int g = 0x740;
112 	int i;
113 
114 	if( keyboard_pressed( KEYCODE_Q ) ) g+=0x10;
115 	if( keyboard_pressed( KEYCODE_W ) ) g+=0x20;
116 	if( keyboard_pressed( KEYCODE_E ) ) g+=0x40;
117 	if( keyboard_pressed( KEYCODE_R ) ) g+=0x80;
118 
119 	for( i=0; i<16; i++ ){
120 		debug_draw( bitmap, 8,8*i,sys16_textram[g+i] );
121 	}
122 }
123 */
124 
125 /* callback to poll video registers */
126 void (* sys16_update_proc)( void );
127 
128 data16_t *sys16_tileram;
129 data16_t *sys16_textram;
130 data16_t *sys16_spriteram;
131 data16_t *sys16_roadram;
132 
133 static int num_sprites;
134 
135 #define MAXCOLOURS 0x2000 /* 8192 */
136 
137 int sys16_sh_shadowpal;
138 int sys16_MaxShadowColors;
139 
140 /* video driver constants (potentially different for each game) */
141 int sys16_gr_bitmap_width;
142 int (*sys16_spritesystem)( struct sys16_sprite_attributes *sprite, const UINT16 *source, int bJustGetColor );
143 int *sys16_obj_bank;
144 int sys16_sprxoffset;
145 int sys16_bgxoffset;
146 int sys16_fgxoffset;
147 int sys16_textmode;
148 int sys16_textlayer_lo_min;
149 int sys16_textlayer_lo_max;
150 int sys16_textlayer_hi_min;
151 int sys16_textlayer_hi_max;
152 int sys16_bg1_trans; // alien syn + sys18
153 int sys16_bg_priority_mode;
154 int sys16_fg_priority_mode;
155 int sys16_bg_priority_value;
156 int sys16_fg_priority_value;
157 int sys16_18_mode;
158 int sys16_tilebank_switch;
159 int sys16_rowscroll_scroll;
160 int sys16_quartet_title_kludge;
161 
162 /* video registers */
163 int sys16_tile_bank1;
164 int sys16_tile_bank0;
165 int sys16_refreshenable;
166 
167 int sys16_bg_scrollx, sys16_bg_scrolly;
168 int sys16_bg2_scrollx, sys16_bg2_scrolly;
169 int sys16_fg_scrollx, sys16_fg_scrolly;
170 int sys16_fg2_scrollx, sys16_fg2_scrolly;
171 
172 int sys16_bg_page[4];
173 int sys16_bg2_page[4];
174 int sys16_fg_page[4];
175 int sys16_fg2_page[4];
176 
177 int sys18_bg2_active;
178 int sys18_fg2_active;
179 data16_t *sys18_splittab_bg_x;
180 data16_t *sys18_splittab_bg_y;
181 data16_t *sys18_splittab_fg_x;
182 data16_t *sys18_splittab_fg_y;
183 
184 data16_t *sys16_gr_ver;
185 data16_t *sys16_gr_hor;
186 data16_t *sys16_gr_pal;
187 data16_t *sys16_gr_flip;
188 int sys16_gr_palette;
189 int sys16_gr_palette_default;
190 unsigned char sys16_gr_colorflip[2][4];
191 data16_t *sys16_gr_second_road;
192 
193 static struct tilemap *background, *foreground, *text_layer;
194 static struct tilemap *background2, *foreground2;
195 static int old_bg_page[4],old_fg_page[4], old_tile_bank1, old_tile_bank0;
196 static int old_bg2_page[4],old_fg2_page[4];
197 
198 /***************************************************************************/
199 
READ16_HANDLER(sys16_textram_r)200 READ16_HANDLER( sys16_textram_r ){
201 	return sys16_textram[offset];
202 }
203 
READ16_HANDLER(sys16_tileram_r)204 READ16_HANDLER( sys16_tileram_r ){
205 	return sys16_tileram[offset];
206 }
207 
208 /***************************************************************************/
209 
210 /*
211 	We mark the priority buffer as follows:
212 		text	(0xf)
213 		fg (hi) (0x7)
214 		fg (lo) (0x3)
215 		bg (hi) (0x1)
216 		bg (lo) (0x0)
217 
218 	Each sprite has 4 levels of priority, specifying where they are placed between bg(lo) and text.
219 */
220 
draw_sprite(struct mame_bitmap * bitmap,const struct rectangle * cliprect,const unsigned char * addr,int pitch,const pen_t * paldata,int x0,int y0,int screen_width,int screen_height,int width,int height,int flipx,int flipy,int priority,int shadow,int shadow_pen,int eos)221 static void draw_sprite( //*
222 	struct mame_bitmap *bitmap,
223 	const struct rectangle *cliprect,
224 	const unsigned char *addr, int pitch,
225 	const pen_t *paldata,
226 	int x0, int y0, int screen_width, int screen_height,
227 	int width, int height,
228 	int flipx, int flipy,
229 	int priority,
230 	int shadow,
231 	int shadow_pen, int eos )
232 {
233 	const pen_t *shadow_base = Machine->gfx[0]->colortable + (Machine->drv->total_colors/2);
234 	const UINT8 *source;
235 	int full_shadow=shadow&SYS16_SPR_SHADOW;
236 	int partial_shadow=shadow&SYS16_SPR_PARTIAL_SHADOW;
237 	int shadow_mask=(Machine->drv->total_colors/2)-1;
238 	int sx, x, xcount;
239 	int sy, y, ycount = 0;
240 	int dx,dy;
241 	UINT16 *dest;
242 	UINT8 *pri;
243 	unsigned pen, data;
244 
245 	priority = 1<<priority;
246 	if (!strcmp(Machine->gamedrv->name,"sonicbom")) flipy^=0x80; // temp hack until we fix drawing
247 
248 	if( flipy ){
249 		dy = -1;
250 		y0 += screen_height-1;
251 	}
252 	else {
253 		dy = 1;
254 	}
255 
256 	if( flipx ){
257 		dx = -1;
258 		x0 += screen_width-1;
259 	}
260 	else {
261 		dx = 1;
262 	}
263 
264 	if (!eos)
265 	{
266 		sy = y0;
267 		for( y=height; y; y-- ){
268 			ycount += screen_height;
269 			while( ycount>=height ){
270 				if( sy>=cliprect->min_y && sy<=cliprect->max_y ){
271 					source = addr;
272 					dest = (UINT16 *)bitmap->line[sy];
273 					pri = priority_bitmap->line[sy];
274 					sx = x0;
275 					xcount = 0;
276 					for( x=width; x; x-=2 ){
277 						data = (unsigned)*source++; /* next 2 pixels */
278 						pen = data>>4;
279 						xcount += screen_width;
280 						while( xcount>=width )
281 						{
282 							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x ){
283 								if(!(pri[sx]&priority)){
284 									if (full_shadow)
285 										dest[sx] = shadow_base[dest[sx]&shadow_mask];
286 									else if (partial_shadow && pen==shadow_pen)
287 										dest[sx] = shadow_base[dest[sx]&shadow_mask];
288 									else
289 										dest[sx] = paldata[pen];
290 								}
291 							}
292 							xcount -= width;
293 							sx+=dx;
294 						}
295 						pen = data&0xf;
296 						xcount += screen_width;
297 						while( xcount>=width )
298 						{
299 							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x ){
300 								if(!(pri[sx]&priority)){
301 									if (full_shadow)
302 										dest[sx] = shadow_base[dest[sx]&shadow_mask];
303 									else if (partial_shadow && pen==shadow_pen)
304 										dest[sx] = shadow_base[dest[sx]&shadow_mask];
305 									else
306 										dest[sx] = paldata[pen];
307 								}
308 							}
309 							xcount -= width;
310 							sx+=dx;
311 						}
312 					}
313 				}
314 				ycount -= height;
315 				sy+=dy;
316 			}
317 			addr += pitch;
318 		}
319 	}
320 	else
321 	{
322 		sy = y0;
323 		for( y=height; y; y-- ){
324 			ycount += screen_height;
325 			while( ycount>=height ){
326 				if( sy>=cliprect->min_y && sy<=cliprect->max_y ){
327 					source = addr;
328 					dest = (UINT16 *)bitmap->line[sy];
329 					pri = priority_bitmap->line[sy];
330 					sx = x0;
331 					xcount = 0;
332 					for( x=width; x; x-=2 ){
333 						data = (unsigned)*source++; /* next 2 pixels */
334 						pen = data>>4;
335 						if (pen==0xf) break;
336 						xcount += screen_width;
337 						while( xcount>=width )
338 						{
339 							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x )
340 								if(!(pri[sx]&priority)) dest[sx] = paldata[pen];
341 							xcount -= width;
342 							sx+=dx;
343 						}
344 						pen = data&0xf;
345 						xcount += screen_width;
346 						while( xcount>=width )
347 						{
348 							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x )
349 								if(!(pri[sx]&priority)) dest[sx] = paldata[pen];
350 							xcount -= width;
351 							sx+=dx;
352 						}
353 					}
354 				}
355 				ycount -= height;
356 				sy+=dy;
357 			}
358 			addr += pitch;
359 		}
360 	}
361 }
362 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int b3d)363 static void draw_sprites( struct mame_bitmap *bitmap, const struct rectangle *cliprect, int b3d ) //*
364 {
365 	const pen_t *base_pal = Machine->gfx[0]->colortable;
366 	const unsigned char *base_gfx = memory_region(REGION_GFX2);
367 	const int gfx_rom_size = memory_region_length(REGION_GFX2);
368 	const data16_t *source = sys16_spriteram;
369 	struct sys16_sprite_attributes sprite;
370 	int xpos, ypos, screen_width, width, logical_height, pitch, flipy, flipx;
371 	int i, mod_h, mod_x, eos;
372 	unsigned gfx;
373 
374 	memset(&sprite, 0x00, sizeof(sprite));
375 
376 	for(i=0; i<num_sprites; i++)
377 	{
378 		sprite.flags = 0;
379 		if (sys16_spritesystem(&sprite, source, 0)) return; /* end-of-spritelist */
380 		source += 8;
381 
382 		if( sprite.flags & SYS16_SPR_VISIBLE )
383 		{
384 			xpos = sprite.x;
385 			flipx = sprite.flags & SYS16_SPR_FLIPX;
386 			ypos = sprite.y;
387 			pitch = sprite.pitch;
388 			flipy = pitch & 0x80;
389 			width = pitch & 0x7f;
390 			if (pitch & 0x80) width = 0x80 - width;
391 			pitch = width << 1;
392 			width <<= 2;
393 			eos = 0;
394 
395 			if( b3d ) // outrun/aburner
396 			{
397 				if (b3d == 2) eos = 1;
398 				if (xpos < 0 && flipx) continue;
399 				if (ypos >= 240) ypos -= 256;
400 				sprite.screen_height++;
401 				logical_height = (sprite.screen_height<<4)*sprite.zoomy/0x2000;
402 				screen_width = width*0x200/sprite.zoomx;
403 
404 				if (flipx && flipy) { mod_h = -logical_height;   mod_x = 4; }
405 				else if     (flipx) { mod_h = -1; xpos++;        mod_x = 4; }
406 				else if     (flipy) { mod_h = -logical_height;   mod_x = 0; }
407 				else                { mod_h = 0;                 mod_x = 0; }
408 
409 				if( sprite.flags & SYS16_SPR_DRAW_TO_TOP )
410 				{
411 					ypos -= sprite.screen_height;
412 					flipy = !flipy;
413 				}
414 
415 				if( sprite.flags & SYS16_SPR_DRAW_TO_LEFT )
416 				{
417 					xpos -= screen_width;
418 					flipx = !flipx;
419 				}
420 			}
421 			else if( sys16_spritesystem==sys16_sprite_sharrier )
422 			{
423 				logical_height = (sprite.screen_height<<4)*(0x400+sprite.zoomy)/0x4000;
424 				screen_width = width*(0x800-sprite.zoomx)/0x800;
425 
426 				if (flipx && flipy) { mod_h = -logical_height-1; mod_x = 4; }
427 				else if     (flipx) { mod_h = 0;                 mod_x = 4; }
428 				else if     (flipy) { mod_h = -logical_height;   mod_x = 0; }
429 				else                { mod_h = 1;                 mod_x = 0; }
430 			}
431 			else
432 			{
433 				if (!width) { width = 512; eos = 1; } // used by fantasy zone for laser
434 				screen_width = width;
435 				logical_height = sprite.screen_height;
436 
437 				if (sprite.zoomy) logical_height = logical_height*(0x400 + sprite.zoomy)/0x400 - 1;
438 				if (sprite.zoomx) screen_width = screen_width*(0x800 - sprite.zoomx)/0x800 + 2;
439 
440 // fix, 5-bit zoom field
441 //				if (sprite.zoomy) logical_height = logical_height*(0x20 + sprite.zoomy)/0x20 - 1;
442 //				if (sprite.zoomx) screen_width = screen_width*(0x40 - sprite.zoomx)/0x40 + 2;
443 
444 				if (flipx && flipy) { mod_h = -logical_height-1; mod_x = 2; }
445 				else if     (flipx) { mod_h = 0;                 mod_x = 2; }
446 				else if     (flipy) { mod_h = -logical_height;   mod_x = 0; }
447 				else                { mod_h = 1;                 mod_x = 0; }
448 			}
449 
450 			gfx = sprite.gfx + pitch * mod_h + mod_x;
451 			if (gfx >= gfx_rom_size) gfx %= gfx_rom_size;
452 
453 			draw_sprite(
454 				bitmap,cliprect,
455 				base_gfx + gfx, pitch,
456 				base_pal + (sprite.color<<4),
457 				xpos, ypos, screen_width, sprite.screen_height,
458 				width, logical_height,
459 				flipx, flipy,
460 				sprite.priority,
461 				sprite.flags,
462 				sprite.shadow_pen, eos);
463 		}
464 	}
465 }
466 
467 /***************************************************************************/
468 
sys16_bg_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)469 UINT32 sys16_bg_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
470 	int page = 0;
471 	if( row<32 ){ /* top */
472 		if( col<64 ) page = 0; else page = 1;
473 	}
474 	else { /* bottom */
475 		if( col<64 ) page = 2; else page = 3;
476 	}
477 	row = row%32;
478 	col = col%64;
479 	return page*64*32+row*64+col;
480 }
481 
sys16_text_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)482 UINT32 sys16_text_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
483 	return row*64+col+(64-40);
484 }
485 
486 /***************************************************************************/
487 
488 /*
489 	Color generation details
490 
491 	Each color is made up of 5 bits, connected through one or more resistors like so:
492 
493 	Bit 0 = 1 x 3.9K ohm
494 	Bit 1 = 1 x 2.0K ohm
495 	Bit 2 = 1 x 1.0K ohm
496 	Bit 3 = 2 x 1.0K ohm
497 	Bit 4 = 4 x 1.0K ohm
498 
499 	Another data bit is connected by a tristate buffer to the color output through a 470 ohm resistor.
500 	The buffer allows the resistor to have no effect (tristate), halve brightness (pull-down) or double brightness (pull-up).
501 	The data bit source is a PPI pin in some of the earlier hardware (Hang-On, Pre-System 16) or bit 15 of each
502 	color RAM entry (Space Harrier, System 16B and most later boards).
503 */
504 
505 const int resistances_normal[6] = {3900, 2000, 1000, 1000/2, 1000/4, 0};
506 const int resistances_sh[6] = {3900, 2000, 1000, 1000/2, 1000/4, 470};
507 static double weights[2][3][6];
508 
WRITE16_HANDLER(sys16_paletteram_w)509 WRITE16_HANDLER( sys16_paletteram_w )
510 {
511 	data16_t oldword = paletteram16[offset];
512 	data16_t newword;
513 	COMBINE_DATA( &paletteram16[offset] );
514 	newword = paletteram16[offset];
515 
516 	if( oldword!=newword )
517 	{
518 		/* we can do this, because we initialize palette RAM to all black in vh_start */
519 		/*	   byte 0    byte 1 */
520 		/*	sBGR BBBB GGGG RRRR */
521 		/*	x000 4321 4321 4321 */
522 
523 		int r, g, b, rs, gs, bs, rh, gh, bh;
524 		int r0 = (newword >> 12) & 1;
525 		int r1 = (newword >>  0) & 1;
526 		int r2 = (newword >>  1) & 1;
527 		int r3 = (newword >>  2) & 1;
528 		int r4 = (newword >>  3) & 1;
529 		int g0 = (newword >> 13) & 1;
530 		int g1 = (newword >>  4) & 1;
531 		int g2 = (newword >>  5) & 1;
532 		int g3 = (newword >>  6) & 1;
533 		int g4 = (newword >>  7) & 1;
534 		int b0 = (newword >> 14) & 1;
535 		int b1 = (newword >>  8) & 1;
536 		int b2 = (newword >>  9) & 1;
537 		int b3 = (newword >> 10) & 1;
538 		int b4 = (newword >> 11) & 1;
539 
540 		/* Normal colors */
541 		r = combine_6_weights(weights[0][0], r0, r1, r2, r3, r4, 0);
542 		g = combine_6_weights(weights[0][1], g0, g1, g2, g3, g4, 0);
543 		b = combine_6_weights(weights[0][2], b0, b1, b2, b3, b4, 0);
544 
545 		/* Shadow colors */
546 		rs = combine_6_weights(weights[1][0], r0, r1, r2, r3, r4, 0);
547 		gs = combine_6_weights(weights[1][1], g0, g1, g2, g3, g4, 0);
548 		bs = combine_6_weights(weights[1][2], b0, b1, b2, b3, b4, 0);
549 
550 		/* Highlight colors */
551 		rh = combine_6_weights(weights[1][0], r0, r1, r2, r3, r4, 1);
552 		gh = combine_6_weights(weights[1][1], g0, g1, g2, g3, g4, 1);
553 		bh = combine_6_weights(weights[1][2], b0, b1, b2, b3, b4, 1);
554 
555 		palette_set_color( offset, r, g, b );
556 
557 #ifdef TRANSPARENT_SHADOWS
558 		palette_set_color( offset+Machine->drv->total_colors/2,rs,gs,bs);
559 #endif
560 
561 	}
562 }
563 
564 
update_page(void)565 static void update_page( void ){
566 	int all_dirty = 0;
567 	int i,offset;
568 	if( old_tile_bank1 != sys16_tile_bank1 ){
569 		all_dirty = 1;
570 		old_tile_bank1 = sys16_tile_bank1;
571 	}
572 	if( old_tile_bank0 != sys16_tile_bank0 ){
573 		all_dirty = 1;
574 		old_tile_bank0 = sys16_tile_bank0;
575 		tilemap_mark_all_tiles_dirty( text_layer );
576 	}
577 	if( all_dirty ){
578 		tilemap_mark_all_tiles_dirty( background );
579 		tilemap_mark_all_tiles_dirty( foreground );
580 		if( sys16_18_mode ){
581 			tilemap_mark_all_tiles_dirty( background2 );
582 			tilemap_mark_all_tiles_dirty( foreground2 );
583 		}
584 	}
585 	else {
586 		for(i=0;i<4;i++){
587 			int page0 = 64*32*i;
588 			if( old_bg_page[i]!=sys16_bg_page[i] ){
589 				old_bg_page[i] = sys16_bg_page[i];
590 				for( offset = page0; offset<page0+64*32; offset++ ){
591 					tilemap_mark_tile_dirty( background, offset );
592 				}
593 			}
594 			if( old_fg_page[i]!=sys16_fg_page[i] ){
595 				old_fg_page[i] = sys16_fg_page[i];
596 				for( offset = page0; offset<page0+64*32; offset++ ){
597 					tilemap_mark_tile_dirty( foreground, offset );
598 				}
599 			}
600 			if( sys16_18_mode ){
601 				if( old_bg2_page[i]!=sys16_bg2_page[i] ){
602 					old_bg2_page[i] = sys16_bg2_page[i];
603 					for( offset = page0; offset<page0+64*32; offset++ ){
604 						tilemap_mark_tile_dirty( background2, offset );
605 					}
606 				}
607 				if( old_fg2_page[i]!=sys16_fg2_page[i] ){
608 					old_fg2_page[i] = sys16_fg2_page[i];
609 					for( offset = page0; offset<page0+64*32; offset++ ){
610 						tilemap_mark_tile_dirty( foreground2, offset );
611 					}
612 				}
613 			}
614 		}
615 	}
616 }
617 
get_bg_tile_info(int offset)618 static void get_bg_tile_info( int offset ){
619 	const UINT16 *source = 64*32*sys16_bg_page[offset/(64*32)] + sys16_tileram;
620 	int data = source[offset%(64*32)];
621 	int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
622 
623 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
624 		SET_TILE_INFO(
625 				0,
626 				tile_number,
627 				512+384+((data>>6)&0x7f),
628 				0)
629 	}
630 	else if(sys16_textmode==0){
631 		SET_TILE_INFO(
632 				0,
633 				tile_number,
634 				(data>>6)&0x7f,
635 				0)
636 	}
637 	else{
638 		SET_TILE_INFO(
639 				0,
640 				tile_number,
641 				(data>>5)&0x7f,
642 				0)
643 	}
644 
645 	switch(sys16_bg_priority_mode) {
646 	case 1: // Alien Syndrome
647 		tile_info.priority = (data&0x8000)?1:0;
648 		break;
649 	case 2: // Body Slam / wrestwar
650 		tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
651 		break;
652 	case 3: // sys18 games
653 		if( data&0x8000 ){
654 			tile_info.priority = 2;
655 		}
656 		else {
657 			tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
658 		}
659 		break;
660 	}
661 }
662 
get_fg_tile_info(int offset)663 static void get_fg_tile_info( int offset ){
664 	const UINT16 *source = 64*32*sys16_fg_page[offset/(64*32)] + sys16_tileram;
665 	int data = source[offset%(64*32)];
666 	int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
667 
668 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
669 		SET_TILE_INFO(
670 				0,
671 				tile_number,
672 				512+384+((data>>6)&0x7f),
673 				0)
674 	}
675 	else if(sys16_textmode==0){
676 		SET_TILE_INFO(
677 				0,
678 				tile_number,
679 				(data>>6)&0x7f,
680 				0)
681 	}
682 	else{
683 		SET_TILE_INFO(
684 				0,
685 				tile_number,
686 				(data>>5)&0x7f,
687 				0)
688 	}
689 	switch(sys16_fg_priority_mode){
690 	case 1: // alien syndrome
691 		tile_info.priority = (data&0x8000)?1:0;
692 		break;
693 
694 	case 3:
695 		tile_info.priority = ((data&0xff00) >= sys16_fg_priority_value)?1:0;
696 		break;
697 
698 	default:
699 		if( sys16_fg_priority_mode>=0 ){
700 			tile_info.priority = (data&0x8000)?1:0;
701 		}
702 		break;
703 	}
704 }
705 
get_bg2_tile_info(int offset)706 static void get_bg2_tile_info( int offset ){
707 	const UINT16 *source = 64*32*sys16_bg2_page[offset/(64*32)] + sys16_tileram;
708 	int data = source[offset%(64*32)];
709 	int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
710 
711 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
712 		SET_TILE_INFO(
713 				0,
714 				tile_number,
715 				512+384+((data>>6)&0x7f),
716 				0)
717 	}
718 	else if(sys16_textmode==0){
719 		SET_TILE_INFO(
720 				0,
721 				tile_number,
722 				(data>>6)&0x7f,
723 				0)
724 	}
725 	else{
726 		SET_TILE_INFO(
727 				0,
728 				tile_number,
729 				(data>>5)&0x7f,
730 				0)
731 	}
732 	tile_info.priority = 0;
733 }
734 
get_fg2_tile_info(int offset)735 static void get_fg2_tile_info( int offset ){
736 	const UINT16 *source = 64*32*sys16_fg2_page[offset/(64*32)] + sys16_tileram;
737 	int data = source[offset%(64*32)];
738 	int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
739 
740 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
741 		SET_TILE_INFO(
742 				0,
743 				tile_number,
744 				512+384+((data>>6)&0x7f),
745 				0)
746 	}
747 	else if(sys16_textmode==0){
748 		SET_TILE_INFO(
749 				0,
750 				tile_number,
751 				(data>>6)&0x7f,
752 				0)
753 	}
754 	else{
755 		SET_TILE_INFO(
756 				0,
757 				tile_number,
758 				(data>>5)&0x7f,
759 				0)
760 	}
761 	if((data&0xff00) >= sys16_fg_priority_value) tile_info.priority = 1;
762 	else tile_info.priority = 0;
763 }
764 
WRITE16_HANDLER(sys16_tileram_w)765 WRITE16_HANDLER( sys16_tileram_w ){
766 	data16_t oldword = sys16_tileram[offset];
767 	COMBINE_DATA( &sys16_tileram[offset] );
768 	if( oldword != sys16_tileram[offset] ){
769 		int page = offset/(64*32);
770 		offset = offset%(64*32);
771 
772 		if( sys16_bg_page[0]==page ) tilemap_mark_tile_dirty( background, offset+64*32*0 );
773 		if( sys16_bg_page[1]==page ) tilemap_mark_tile_dirty( background, offset+64*32*1 );
774 		if( sys16_bg_page[2]==page ) tilemap_mark_tile_dirty( background, offset+64*32*2 );
775 		if( sys16_bg_page[3]==page ) tilemap_mark_tile_dirty( background, offset+64*32*3 );
776 
777 		if( sys16_fg_page[0]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*0 );
778 		if( sys16_fg_page[1]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*1 );
779 		if( sys16_fg_page[2]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*2 );
780 		if( sys16_fg_page[3]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*3 );
781 
782 		if( sys16_18_mode ){
783 			if( sys16_bg2_page[0]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*0 );
784 			if( sys16_bg2_page[1]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*1 );
785 			if( sys16_bg2_page[2]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*2 );
786 			if( sys16_bg2_page[3]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*3 );
787 
788 			if( sys16_fg2_page[0]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*0 );
789 			if( sys16_fg2_page[1]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*1 );
790 			if( sys16_fg2_page[2]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*2 );
791 			if( sys16_fg2_page[3]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*3 );
792 		}
793 	}
794 }
795 
796 /***************************************************************************/
797 
get_text_tile_info(int offset)798 static void get_text_tile_info( int offset ){
799 	const data16_t *source = sys16_textram;
800 	int tile_number = source[offset];
801 	int pri = tile_number >> 8;
802 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
803 		SET_TILE_INFO(
804 				0,
805 				(tile_number&0x1ff) + sys16_tile_bank0 * 0x1000,
806 				512+384+((tile_number>>9)&0x7),
807 				0)
808 	}
809 	else if(sys16_textmode==0){
810 		SET_TILE_INFO(
811 				0,
812 				(tile_number&0x1ff) + sys16_tile_bank0 * 0x1000,
813 				(tile_number>>9)%8,
814 				0)
815 	}
816 	else{
817 		SET_TILE_INFO(
818 				0,
819 				(tile_number&0xff)  + sys16_tile_bank0 * 0x1000,
820 				(tile_number>>8)%8,
821 				0)
822 	}
823 	if(pri>=sys16_textlayer_lo_min && pri<=sys16_textlayer_lo_max)
824 		tile_info.priority = 1;
825 	if(pri>=sys16_textlayer_hi_min && pri<=sys16_textlayer_hi_max)
826 		tile_info.priority = 0;
827 }
828 
WRITE16_HANDLER(sys16_textram_w)829 WRITE16_HANDLER( sys16_textram_w ){
830 	int oldword = sys16_textram[offset];
831 	COMBINE_DATA( &sys16_textram[offset] );
832 	if( oldword!=sys16_textram[offset] ){
833 		tilemap_mark_tile_dirty( text_layer, offset );
834 	}
835 }
836 
837 /***************************************************************************/
838 
VIDEO_START(system16)839 VIDEO_START( system16 ){
840 	static int bank_default[16] = {
841 		0x0,0x1,0x2,0x3,
842 		0x4,0x5,0x6,0x7,
843 		0x8,0x9,0xa,0xb,
844 		0xc,0xd,0xe,0xf
845 	};
846 	sys16_obj_bank = bank_default;
847 
848 	/* Normal colors */
849 	compute_resistor_weights(0, 255, -1.0,
850 		6, resistances_normal, weights[0][0], 0, 0,
851 		6, resistances_normal, weights[0][1], 0, 0,
852 		6, resistances_normal, weights[0][2], 0, 0
853 		);
854 
855 	/* Shadow/Highlight colors */
856 	compute_resistor_weights(0, 255, -1.0,
857 		6, resistances_sh, weights[1][0], 0, 0,
858 		6, resistances_sh, weights[1][1], 0, 0,
859 		6, resistances_sh, weights[1][2], 0, 0
860 		);
861 
862 	if( !sys16_bg1_trans )
863 		background = tilemap_create(
864 			get_bg_tile_info,
865 			sys16_bg_map,
866 			TILEMAP_OPAQUE,
867 			8,8,
868 			64*2,32*2 );
869 	else
870 		background = tilemap_create(
871 			get_bg_tile_info,
872 			sys16_bg_map,
873 			TILEMAP_TRANSPARENT,
874 			8,8,
875 			64*2,32*2 );
876 
877 	foreground = tilemap_create(
878 		get_fg_tile_info,
879 		sys16_bg_map,
880 		TILEMAP_TRANSPARENT,
881 		8,8,
882 		64*2,32*2 );
883 
884 	text_layer = tilemap_create(
885 		get_text_tile_info,
886 		sys16_text_map,
887 		TILEMAP_TRANSPARENT,
888 		8,8,
889 		40,28 );
890 
891 	num_sprites = 128*2; /* only 128 for most games; aburner uses 256 */
892 
893 	if(!strcmp(Machine->gamedrv->name, "hangon"))
894 		num_sprites = 128;
895 
896 	if( background && foreground && text_layer ){
897 		/* initialize all entries to black - needed for Golden Axe*/
898 		int i;
899 		for( i=0; i<Machine->drv->total_colors; i++ ){
900 			palette_set_color( i, 0,0,0 );
901 		}
902 
903 		if(sys16_bg1_trans) tilemap_set_transparent_pen( background, 0 );
904 		tilemap_set_transparent_pen( foreground, 0 );
905 		tilemap_set_transparent_pen( text_layer, 0 );
906 
907 		sys16_tile_bank0 = 0;
908 		sys16_tile_bank1 = 1;
909 
910 		sys16_fg_scrollx = 0;
911 		sys16_fg_scrolly = 0;
912 
913 		sys16_bg_scrollx = 0;
914 		sys16_bg_scrolly = 0;
915 
916 		sys16_refreshenable = 1;
917 
918 		/* common defaults */
919 		sys16_update_proc = 0;
920 		sys16_spritesystem = sys16_sprite_shinobi;
921 		sys16_sprxoffset = -0xb8;
922 		sys16_textmode = 0;
923 		sys16_bgxoffset = 0;
924 		sys16_bg_priority_mode=0;
925 		sys16_fg_priority_mode=0;
926 		sys16_tilebank_switch=0x1000;
927 
928 		// Defaults for sys16 games
929 		sys16_textlayer_lo_min=0;
930 		sys16_textlayer_lo_max=0x7f;
931 		sys16_textlayer_hi_min=0x80;
932 		sys16_textlayer_hi_max=0xff;
933 
934 		sys16_18_mode=0;
935 
936 #ifdef GAMMA_ADJUST
937 		{
938 			static float sys16_orig_gamma=0;
939 			static float sys16_set_gamma=0;
940 			float cur_gamma=osd_get_gamma();
941 
942 			if(sys16_orig_gamma == 0)
943 			{
944 				sys16_orig_gamma = cur_gamma;
945 				sys16_set_gamma = cur_gamma - 0.35;
946 				if (sys16_set_gamma < 0.5) sys16_set_gamma = 0.5;
947 				if (sys16_set_gamma > 2.0) sys16_set_gamma = 2.0;
948 				osd_set_gamma(sys16_set_gamma);
949 			}
950 			else
951 			{
952 				if(sys16_orig_gamma == cur_gamma)
953 				{
954 					osd_set_gamma(sys16_set_gamma);
955 				}
956 			}
957 		}
958 #endif
959 		return 0;
960 	}
961 	return 1;
962 }
963 
VIDEO_START(hangon)964 VIDEO_START( hangon ){
965 	int ret;
966 	sys16_bg1_trans=1;
967 	ret = video_start_system16();
968 	if(ret) return 1;
969 
970 	sys16_textlayer_lo_min=0;
971 	sys16_textlayer_lo_max=0;
972 	sys16_textlayer_hi_min=0;
973 	sys16_textlayer_hi_max=0xff;
974 
975 	sys16_bg_priority_mode=-1;
976 	sys16_bg_priority_value=0x1800;
977 	sys16_fg_priority_value=0x2000;
978 	return 0;
979 }
980 
VIDEO_START(system18)981 VIDEO_START( system18 ){
982 	sys16_bg1_trans=1;
983 
984 	background2 = tilemap_create(
985 		get_bg2_tile_info,
986 		sys16_bg_map,
987 		TILEMAP_OPAQUE,
988 		8,8,
989 		64*2,32*2 );
990 
991 	foreground2 = tilemap_create(
992 		get_fg2_tile_info,
993 		sys16_bg_map,
994 		TILEMAP_TRANSPARENT,
995 		8,8,
996 		64*2,32*2 );
997 
998 	if( background2 && foreground2 ){
999 		if( video_start_system16()==0 ){
1000 			tilemap_set_transparent_pen( foreground2, 0 );
1001 
1002 			if(sys18_splittab_fg_x){
1003 				tilemap_set_scroll_rows( foreground , 64 );
1004 				tilemap_set_scroll_rows( foreground2 , 64 );
1005 			}
1006 			if(sys18_splittab_bg_x){
1007 				tilemap_set_scroll_rows( background , 64 );
1008 				tilemap_set_scroll_rows( background2 , 64 );
1009 			}
1010 
1011 			sys16_textlayer_lo_min=0;
1012 			sys16_textlayer_lo_max=0x1f;
1013 			sys16_textlayer_hi_min=0x20;
1014 			sys16_textlayer_hi_max=0xff;
1015 
1016 			sys16_18_mode=1;
1017 			sys16_bg_priority_mode=3;
1018 			sys16_fg_priority_mode=3;
1019 			sys16_bg_priority_value=0x1800;
1020 			sys16_fg_priority_value=0x2000;
1021 
1022 			return 0;
1023 		}
1024 	}
1025 	return 1;
1026 }
1027 
1028 /***************************************************************************/
1029 
sys16_vh_refresh_helper(void)1030 static void sys16_vh_refresh_helper( void ){
1031 	if( sys18_splittab_bg_x ){
1032 		if( (sys16_bg_scrollx&0xff00)  != sys16_rowscroll_scroll ){
1033 			tilemap_set_scroll_rows( background , 1 );
1034 			tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1035 		}
1036 		else {
1037 			int offset, scroll,i;
1038 
1039 			tilemap_set_scroll_rows( background , 64 );
1040 			offset = 32+((sys16_bg_scrolly&0x1f8) >> 3);
1041 
1042 			for( i=0; i<29; i++ ){
1043 				scroll = sys18_splittab_bg_x[i];
1044 				tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1045 			}
1046 		}
1047 	}
1048 	else {
1049 		tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1050 	}
1051 
1052 	if( sys18_splittab_bg_y ){
1053 		if( (sys16_bg_scrolly&0xff00)  != sys16_rowscroll_scroll ){
1054 			tilemap_set_scroll_cols( background , 1 );
1055 			tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1056 		}
1057 		else {
1058 			int offset, scroll,i;
1059 
1060 			tilemap_set_scroll_cols( background , 128 );
1061 			offset = 127-((sys16_bg_scrollx&0x3f8) >> 3)-40+2;
1062 
1063 			for( i=0;i<41;i++ ){
1064 				scroll = sys18_splittab_bg_y[(i+24)>>1];
1065 				tilemap_set_scrolly( background , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1066 			}
1067 		}
1068 	}
1069 	else {
1070 		tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1071 	}
1072 
1073 	if( sys18_splittab_fg_x ){
1074 		if( (sys16_fg_scrollx&0xff00)  != sys16_rowscroll_scroll ){
1075 			tilemap_set_scroll_rows( foreground , 1 );
1076 			tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1077 		}
1078 		else {
1079 			int offset, scroll,i;
1080 
1081 			tilemap_set_scroll_rows( foreground , 64 );
1082 			offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
1083 
1084 			for(i=0;i<29;i++){
1085 				scroll = sys18_splittab_fg_x[i];
1086 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1087 			}
1088 		}
1089 	}
1090 	else {
1091 		tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1092 	}
1093 
1094 	if( sys18_splittab_fg_y ){
1095 		if( (sys16_fg_scrolly&0xff00)  != sys16_rowscroll_scroll ){
1096 			tilemap_set_scroll_cols( foreground , 1 );
1097 			tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1098 		}
1099 		else {
1100 			int offset, scroll,i;
1101 
1102 			tilemap_set_scroll_cols( foreground , 128 );
1103 			offset = 127-((sys16_fg_scrollx&0x3f8) >> 3)-40+2;
1104 
1105 			for( i=0; i<41; i++ ){
1106 				scroll = sys18_splittab_fg_y[(i+24)>>1];
1107 				tilemap_set_scrolly( foreground , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1108 			}
1109 		}
1110 	}
1111 	else {
1112 		tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1113 	}
1114 }
1115 
sys18_vh_screenrefresh_helper(void)1116 static void sys18_vh_screenrefresh_helper( void ){
1117 	int i;
1118 	if( sys18_splittab_bg_x ){ // screenwise rowscroll?
1119 		int offset,offset2, scroll,scroll2,orig_scroll;
1120 
1121 		offset = 32+((sys16_bg_scrolly&0x1f8) >> 3); // 0x00..0x3f
1122 		offset2 = 32+((sys16_bg2_scrolly&0x1f8) >> 3); // 0x00..0x3f
1123 
1124 		for( i=0;i<29;i++ ){
1125 			orig_scroll = scroll2 = scroll = sys18_splittab_bg_x[i];
1126 			if((sys16_bg_scrollx  &0xff00) != 0x8000) scroll = sys16_bg_scrollx;
1127 			if((sys16_bg2_scrollx &0xff00) != 0x8000) scroll2 = sys16_bg2_scrollx;
1128 
1129 			if(orig_scroll&0x8000){ // background2
1130 				tilemap_set_scrollx( background , (i+offset)&0x3f, TILE_LINE_DISABLED );
1131 				tilemap_set_scrollx( background2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_bgxoffset );
1132 			}
1133 			else{ // background
1134 				tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1135 				tilemap_set_scrollx( background2, (i+offset2)&0x3f, TILE_LINE_DISABLED );
1136 			}
1137 		}
1138 	}
1139 	else {
1140 		tilemap_set_scrollx( background , 0, -320-(sys16_bg_scrollx&0x3ff)+sys16_bgxoffset );
1141 		tilemap_set_scrollx( background2, 0, -320-(sys16_bg2_scrollx&0x3ff)+sys16_bgxoffset );
1142 	}
1143 
1144 	tilemap_set_scrolly( background , 0, -256+sys16_bg_scrolly );
1145 	tilemap_set_scrolly( background2, 0, -256+sys16_bg2_scrolly );
1146 
1147 	if( sys18_splittab_fg_x ){
1148 		int offset,offset2, scroll,scroll2,orig_scroll;
1149 
1150 		offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
1151 		offset2 = 32+((sys16_fg2_scrolly&0x1f8) >> 3);
1152 
1153 		for( i=0;i<29;i++ ){
1154 			orig_scroll = scroll2 = scroll = sys18_splittab_fg_x[i];
1155 			if( (sys16_fg_scrollx &0xff00) != 0x8000 ) scroll = sys16_fg_scrollx;
1156 
1157 			if( (sys16_fg2_scrollx &0xff00) != 0x8000 ) scroll2 = sys16_fg2_scrollx;
1158 
1159 			if( orig_scroll&0x8000 ){
1160 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, TILE_LINE_DISABLED );
1161 				tilemap_set_scrollx( foreground2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_fgxoffset );
1162 			}
1163 			else {
1164 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1165 				tilemap_set_scrollx( foreground2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
1166 			}
1167 		}
1168 	}
1169 	else {
1170 		tilemap_set_scrollx( foreground , 0, -320-(sys16_fg_scrollx&0x3ff)+sys16_fgxoffset );
1171 		tilemap_set_scrollx( foreground2, 0, -320-(sys16_fg2_scrollx&0x3ff)+sys16_fgxoffset );
1172 	}
1173 
1174 
1175 	tilemap_set_scrolly( foreground , 0, -256+sys16_fg_scrolly );
1176 	tilemap_set_scrolly( foreground2, 0, -256+sys16_fg2_scrolly );
1177 
1178 	tilemap_set_enable( background2, sys18_bg2_active );
1179 	tilemap_set_enable( foreground2, sys18_fg2_active );
1180 }
1181 
VIDEO_UPDATE(system16)1182 VIDEO_UPDATE( system16 ){
1183 	if (!sys16_refreshenable) return;
1184 
1185 	if( sys16_update_proc ) sys16_update_proc();
1186 	update_page();
1187 	sys16_vh_refresh_helper(); /* set scroll registers */
1188 
1189 	fillbitmap(priority_bitmap,0,cliprect);
1190 
1191 	tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY, 0x00 );
1192 	if(sys16_bg_priority_mode) tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 1, 0x00 );
1193 //	sprite_draw(sprite_list,3); // needed for Aurail
1194 	if( sys16_bg_priority_mode==2 ) tilemap_draw( bitmap,cliprect, background, 1, 0x01 );// body slam (& wrestwar??)
1195 //	sprite_draw(sprite_list,2);
1196 	else if( sys16_bg_priority_mode==1 ) tilemap_draw( bitmap,cliprect, background, 1, 0x03 );// alien syndrome / aurail
1197 	tilemap_draw( bitmap,cliprect, foreground, 0, 0x03 );
1198 //	sprite_draw(sprite_list,1);
1199 	tilemap_draw( bitmap,cliprect, foreground, 1, 0x07 );
1200 	if( sys16_textlayer_lo_max!=0 ) tilemap_draw( bitmap,cliprect, text_layer, 1, 7 );// needed for Body Slam
1201 //	sprite_draw(sprite_list,0);
1202 	tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1203 
1204 	draw_sprites( bitmap,cliprect,0 );
1205 }
1206 
VIDEO_UPDATE(system18)1207 VIDEO_UPDATE( system18 ){
1208 	if (!sys16_refreshenable) return;
1209 	if( sys16_update_proc ) sys16_update_proc();
1210 	update_page();
1211 	sys18_vh_screenrefresh_helper(); /* set scroll registers */
1212 
1213 	fillbitmap(priority_bitmap,0,NULL);
1214 	if(sys18_bg2_active)
1215 		tilemap_draw( bitmap,cliprect, background2, 0, 0 );
1216 	else
1217 		fillbitmap(bitmap,Machine->pens[0],cliprect);
1218 
1219 	tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY, 0 );
1220 	tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 1, 0 );	//??
1221 	tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 2, 0 );	//??
1222 
1223 //	sprite_draw(sprite_list,3);
1224 	tilemap_draw( bitmap,cliprect, background, 1, 0x1 );
1225 //	sprite_draw(sprite_list,2);
1226 	tilemap_draw( bitmap,cliprect, background, 2, 0x3 );
1227 
1228 	if(sys18_fg2_active) tilemap_draw( bitmap,cliprect, foreground2, 0, 0x3 );
1229 	tilemap_draw( bitmap,cliprect, foreground, 0, 0x3 );
1230 //	sprite_draw(sprite_list,1);
1231 	if(sys18_fg2_active) tilemap_draw( bitmap,cliprect, foreground2, 1, 0x7 );
1232 	tilemap_draw( bitmap,cliprect, foreground, 1, 0x7 );
1233 
1234 	tilemap_draw( bitmap,cliprect, text_layer, 1, 0x7 );
1235 //	sprite_draw(sprite_list,0);
1236 	tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1237 
1238 	draw_sprites( bitmap,cliprect, 0 );
1239 }
1240 
1241 
render_gr(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)1242 static void render_gr(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority){
1243 	/* the road is a 4 color bitmap */
1244 	int i,j;
1245 	UINT8 *data = memory_region(REGION_GFX3);
1246 	UINT8 *source;
1247 	UINT16 *line16;
1248 	UINT16 *data_ver=sys16_gr_ver;
1249 	UINT32 ver_data,hor_pos;
1250 	UINT16 colors[5];
1251 	int colorflip;
1252 	int yflip=0, ypos;
1253 	int dx=1,xoff=0;
1254 
1255 	pen_t *paldata1 = Machine->gfx[0]->colortable + sys16_gr_palette;
1256 	pen_t *paldata2 = Machine->gfx[0]->colortable + sys16_gr_palette_default;
1257 
1258 #if 0
1259 if( keyboard_pressed( KEYCODE_S ) ){
1260 	FILE *f;
1261 	int i;
1262 	char fname[64];
1263 	static int fcount = 0;
1264 	while( keyboard_pressed( KEYCODE_S ) ){}
1265 	sprintf( fname, "road%d.txt",fcount );
1266 	fcount++;
1267 	f = fopen( fname,"w" );
1268 	if( f ){
1269 		const UINT16 *source = sys16_gr_ver;
1270 		for( i=0; i<0x1000; i++ ){
1271 			if( (i&0x1f)==0 ) fprintf( f, "\n %04x: ", i );
1272 			fprintf( f, "%04x ", source[i] );
1273 		}
1274 		fclose( f );
1275 	}
1276 }
1277 #endif
1278 
1279 	priority=priority << 10;
1280 
1281 	if (Machine->scrbitmap->depth == 16) /* 16 bit */
1282 	{
1283 		if( Machine->orientation & ORIENTATION_SWAP_XY ){
1284 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
1285 				dx=-1;
1286 				xoff=319;
1287 			}
1288 			if( Machine->orientation & ORIENTATION_FLIP_X ){
1289 				yflip=1;
1290 			}
1291 
1292 			for(i=cliprect->min_y;i<=cliprect->max_y;i++){
1293 				if(yflip) ypos=223-i;
1294 				else ypos=i;
1295 				ver_data=*data_ver;
1296 				if((ver_data & 0x400) == priority)
1297 				{
1298 					colors[0] = paldata1[ sys16_gr_pal[(ver_data)&0xff]&0xff ];
1299 
1300 					if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
1301 					{
1302 						// fill line
1303 						for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1304 						{
1305 							line16=(UINT16 *)bitmap->line[j]+ypos;
1306 							*line16=colors[0];
1307 						}
1308 					}
1309 					else
1310 					{
1311 						// copy line
1312 						ver_data=ver_data & 0x00ff;
1313 						colorflip = (sys16_gr_flip[ver_data] >> 3) & 1;
1314 
1315 						colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1316 						colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1317 						colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1318 						colors[4] = paldata2[ sys16_gr_colorflip[colorflip][3] ];
1319 
1320 						hor_pos = sys16_gr_hor[ver_data];
1321 						ver_data = ver_data << sys16_gr_bitmap_width;
1322 
1323 						if(hor_pos & 0xf000)
1324 						{
1325 							// reverse
1326 							hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
1327 						}
1328 						else
1329 						{
1330 							// normal
1331 							hor_pos=(hor_pos+0x200) & 0x3ff;
1332 						}
1333 
1334 						source = data + hor_pos + ver_data + 18 + 8;
1335 
1336 						for(j=cliprect->min_x;j<cliprect->max_x;j++)
1337 						{
1338 							line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
1339 							*line16 = colors[*source++];
1340 						}
1341 					}
1342 				}
1343 				data_ver++;
1344 			}
1345 		}
1346 		else
1347 		{ /* 16 bpp, normal screen orientation */
1348 			if( Machine->orientation & ORIENTATION_FLIP_X ){
1349 				dx=-1;
1350 				xoff=319;
1351 			}
1352 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
1353 				yflip=1;
1354 			}
1355 
1356 			for(i=cliprect->min_y;i<=cliprect->max_y;i++){ /* with each scanline */
1357 				if( yflip ) ypos=223-i; else ypos=i;
1358 				ver_data= *data_ver; /* scanline parameters */
1359 				/*
1360 					gr_ver:
1361 						---- -x-- ---- ----	priority
1362 						---- --x- ---- ---- ?
1363 						---- ---x ---- ---- ?
1364 						---- ---- xxxx xxxx ypos (source bitmap)
1365 
1366 					gr_flip:
1367 						---- ---- ---- x--- flip colors
1368 
1369 					gr_hor:
1370 						xxxx xxxx xxxx xxxx	xscroll
1371 
1372 					gr_pal:
1373 						---- ---- xxxx xxxx palette
1374 				*/
1375 				if( (ver_data & 0x400) == priority ){
1376 					colors[0] = paldata1[ sys16_gr_pal[ver_data&0xff]&0xff ];
1377 
1378 					if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200){
1379 						line16 = (UINT16 *)bitmap->line[ypos]; /* dest for drawing */
1380 						for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1381 							*line16++=colors[0]; /* opaque fill with background color */
1382 						}
1383 					}
1384 					else {
1385 						// copy line
1386 						line16 = (UINT16 *)bitmap->line[ypos]+xoff; /* dest for drawing */
1387 						ver_data &= 0xff;
1388 
1389 						colorflip = (sys16_gr_flip[ver_data] >> 3) & 1;
1390 						colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1391 						colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1392 						colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1393 						colors[4] = paldata2[ sys16_gr_colorflip[colorflip][3] ];
1394 
1395 						hor_pos = sys16_gr_hor[ver_data];
1396 						if( hor_pos & 0xf000 ){ // reverse (precalculated)
1397 							hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
1398 						}
1399 						else { // normal
1400 							hor_pos=(hor_pos+0x200) & 0x3ff;
1401 						}
1402 
1403 						ver_data <<= sys16_gr_bitmap_width;
1404 						source = data + hor_pos + ver_data + 18 + 8;
1405 
1406 						for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1407 							*line16 = colors[*source++];
1408 							line16+=dx;
1409 						}
1410 					}
1411 				}
1412 				data_ver++;
1413 			}
1414 		}
1415 	}
1416 }
1417 
VIDEO_UPDATE(hangon)1418 VIDEO_UPDATE( hangon ){
1419 	if (!sys16_refreshenable) return;
1420 	if( sys16_update_proc ) sys16_update_proc();
1421 	update_page();
1422 
1423 	tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1424 	tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1425 	tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1426 	tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1427 
1428 	fillbitmap(priority_bitmap,0,cliprect);
1429 
1430 	render_gr(bitmap,cliprect,0); /* sky */
1431 	tilemap_draw( bitmap,cliprect, background, 0, 0 );
1432 	tilemap_draw( bitmap,cliprect, foreground, 0, 0 );
1433 	render_gr(bitmap,cliprect,1); /* floor */
1434 	tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1435 
1436 	draw_sprites( bitmap,cliprect, 0 );
1437 }
1438 
render_grv2(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)1439 static void render_grv2(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority)
1440 {
1441 	int i,j;
1442 	UINT8 *data = memory_region(REGION_GFX3);
1443 	UINT8 *source,*source2,*temp;
1444 	UINT16 *line16;
1445 	UINT16 *data_ver=sys16_gr_ver;
1446 	UINT32 ver_data,hor_pos,hor_pos2;
1447 	UINT16 colors[5];
1448 	int colorflip,colorflip_info;
1449 	int yflip=0,ypos;
1450 	int dx=1,xoff=0;
1451 
1452 	int second_road = sys16_gr_second_road[0];
1453 
1454 	pen_t *paldata1 = Machine->gfx[0]->colortable + sys16_gr_palette;
1455 	pen_t *paldata2 = Machine->gfx[0]->colortable + sys16_gr_palette_default;
1456 
1457 	priority=priority << 11;
1458 
1459 	if (Machine->scrbitmap->depth == 16) /* 16 bit */
1460 	{
1461 		if( Machine->orientation & ORIENTATION_SWAP_XY )
1462 		{
1463 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
1464 				dx=-1;
1465 				xoff=319;
1466 			}
1467 			if( Machine->orientation & ORIENTATION_FLIP_X ){
1468 				yflip=1;
1469 			}
1470 
1471 			for(i=cliprect->min_y;i<=cliprect->max_y;i++)
1472 			{
1473 				if(yflip) ypos=223-i;
1474 				else ypos=i;
1475 				ver_data = *data_ver;
1476 				if((ver_data & 0x800) == priority)
1477 				{
1478 
1479 					if(ver_data & 0x800) /* disable */
1480 					{
1481 						colors[0] = paldata1[ ver_data&0x3f ];
1482 						// fill line
1483 						for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1484 						{
1485 							line16=(UINT16 *)bitmap->line[j]+ypos;
1486 							*line16=colors[0];
1487 						}
1488 					}
1489 					else
1490 					{
1491 						// copy line
1492 						ver_data=ver_data & 0x01ff;		//???
1493 						colorflip_info = sys16_gr_flip[ver_data];
1494 
1495 						colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ];		//??
1496 
1497 						colorflip = (colorflip_info >> 3) & 1;
1498 
1499 						colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1500 						colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1501 						colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1502 
1503 						hor_pos = sys16_gr_hor[ver_data];
1504 						hor_pos2= sys16_gr_hor[ver_data+0x200];
1505 
1506 						ver_data=ver_data>>1;
1507 						if( ver_data != 0 )
1508 						{
1509 							ver_data = (ver_data-1) << sys16_gr_bitmap_width;
1510 						}
1511 						source  = data + ((hor_pos +0x200) & 0x7ff) + 0x300 + ver_data + 8;
1512 						source2 = data + ((hor_pos2+0x200) & 0x7ff) + 0x300 + ver_data + 8;
1513 
1514 						switch(second_road)
1515 						{
1516 							case 0:	source2=source;	break;
1517 							case 2:	temp=source;source=source2;source2=temp; break;
1518 							case 3:	source=source2;	break;
1519 						}
1520 
1521 						source2++;
1522 
1523 						for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1524 						{
1525 							line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
1526 							if(*source2 <= *source)
1527 								*line16 = colors[*source];
1528 							else
1529 								*line16 = colors[*source2];
1530 							source++;
1531 							source2++;
1532 						}
1533 					}
1534 				}
1535 				data_ver++;
1536 			}
1537 		}
1538 		else
1539 		{
1540 			if( Machine->orientation & ORIENTATION_FLIP_X ){
1541 				dx=-1;
1542 				xoff=319;
1543 			}
1544 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
1545 				yflip=1;
1546 			}
1547 
1548 			for(i=cliprect->min_y;i<=cliprect->max_y;i++){
1549 				if(yflip) ypos=223-i;
1550 				else ypos=i;
1551 				ver_data= *data_ver;
1552 				if((ver_data & 0x800) == priority){
1553 					if(ver_data & 0x800){
1554 						colors[0] = paldata1[ ver_data&0x3f ];
1555 						// fill line
1556 						line16 = (UINT16 *)bitmap->line[ypos];
1557 						for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1558 							*line16++ = colors[0];
1559 						}
1560 					}
1561 					else {
1562 						// copy line
1563 						line16 = (UINT16 *)bitmap->line[ypos]+xoff;
1564 						ver_data &= 0x01ff;		//???
1565 						colorflip_info = sys16_gr_flip[ver_data];
1566 						colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ];		//??
1567 						colorflip = (colorflip_info >> 3) & 1;
1568 						colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1569 						colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1570 						colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1571 						hor_pos = sys16_gr_hor[ver_data];
1572 						hor_pos2= sys16_gr_hor[ver_data+0x200];
1573 						ver_data=ver_data>>1;
1574 						if( ver_data != 0 ){
1575 							ver_data = (ver_data-1) << sys16_gr_bitmap_width;
1576 						}
1577 						source  = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
1578 						source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
1579 						switch(second_road){
1580 							case 0:	source2=source;	break;
1581 							case 2:	temp=source;source=source2;source2=temp; break;
1582 							case 3:	source=source2;	break;
1583 						}
1584 						source2++;
1585 						for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1586 							if(*source2 <= *source) *line16 = colors[*source]; else *line16 = colors[*source2];
1587 							source++;
1588 							source2++;
1589 							line16+=dx;
1590 						}
1591 					}
1592 				}
1593 				data_ver++;
1594 			}
1595 		}
1596 	}
1597 }
1598 
1599 
VIDEO_START(outrun)1600 VIDEO_START( outrun ){
1601 	int ret;
1602 	sys16_bg1_trans=1;
1603 	ret = video_start_system16();
1604 	if(ret) return 1;
1605 
1606 	sys16_textlayer_lo_min=0;
1607 	sys16_textlayer_lo_max=0;
1608 	sys16_textlayer_hi_min=0;
1609 	sys16_textlayer_hi_max=0xff;
1610 
1611 	sys16_bg_priority_mode=-1;
1612 	sys16_bg_priority_value=0x1800;
1613 	sys16_fg_priority_value=0x2000;
1614 	return 0;
1615 }
1616 
VIDEO_UPDATE(outrun)1617 VIDEO_UPDATE( outrun ){
1618 	if( sys16_refreshenable ){
1619 		if( sys16_update_proc ) sys16_update_proc();
1620 		update_page();
1621 
1622 		tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1623 		tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1624 
1625 		tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1626 		tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1627 
1628 		render_grv2(bitmap,cliprect,1);
1629 		tilemap_draw( bitmap,cliprect, background, 0, 0 );
1630 		tilemap_draw( bitmap,cliprect, foreground, 0, 0 );
1631 		render_grv2(bitmap,cliprect,0);
1632 
1633 		draw_sprites( bitmap,cliprect, 1 );
1634 
1635 		tilemap_draw( bitmap,cliprect, text_layer, 0, 0 );
1636 	}
1637 }
1638 
1639 /***************************************************************************/
1640 
1641 static UINT8 *aburner_backdrop;
1642 
aburner_unpack_backdrop(const UINT8 * baseaddr)1643 UINT8 *aburner_unpack_backdrop( const UINT8 *baseaddr ){
1644 	UINT8 *result = auto_malloc(512*256*2);
1645 	if( result ){
1646 		int page;
1647 		for( page=0; page<2; page++ ){
1648 			UINT8 *dest = result + 512*256*page;
1649 			const UINT8 *source = baseaddr + 0x8000*page;
1650 			int y;
1651 			for( y=0; y<256; y++ ){
1652 				int x;
1653 				for( x=0; x<512; x++ ){
1654 					int data0 = source[x/8];
1655 					int data1 = source[x/8 + 0x4000];
1656 					int bit = 0x80>>(x&7);
1657 					int pen = 0;
1658 					if( data0 & bit ) pen+=1;
1659 					if( data1 & bit ) pen+=2;
1660 					dest[x] = pen;
1661 				}
1662 
1663 				{
1664 					int edge_color = dest[0];
1665 					for( x=0; x<512; x++ ){
1666 						if( dest[x]==edge_color ) dest[x] = 4; else break;
1667 					}
1668 					edge_color = dest[511];
1669 					for( x=511; x>=0; x-- ){
1670 						if( dest[x]==edge_color ) dest[x] = 4; else break;
1671 					}
1672 				}
1673 
1674 				source += 0x40;
1675 				dest += 512;
1676 			}
1677 		}
1678 	}
1679 	return result;
1680 }
1681 
VIDEO_START(aburner)1682 VIDEO_START( aburner ){
1683 	int ret;
1684 
1685 	aburner_backdrop = aburner_unpack_backdrop( memory_region(REGION_GFX3) );
1686 
1687 	sys16_bg1_trans=1;
1688 	ret = video_start_system16();
1689 	if(ret) return 1;
1690 
1691 	foreground2 = tilemap_create(
1692 		get_fg2_tile_info,
1693 		sys16_bg_map,
1694 		TILEMAP_TRANSPARENT,
1695 		8,8,
1696 		64*2,32*2 );
1697 
1698 	background2 = tilemap_create(
1699 		get_bg2_tile_info,
1700 		sys16_bg_map,
1701 		TILEMAP_TRANSPARENT,
1702 		8,8,
1703 		64*2,32*2 );
1704 
1705 	if( foreground2 && background2 ){
1706 		ret = video_start_system16();
1707 		if(ret) return 1;
1708 		tilemap_set_transparent_pen( foreground2, 0 );
1709 		sys16_18_mode = 1;
1710 
1711 		tilemap_set_scroll_rows( foreground , 64 );
1712 		tilemap_set_scroll_rows( foreground2 , 64 );
1713 		tilemap_set_scroll_rows( background , 64 );
1714 		tilemap_set_scroll_rows( background2 , 64 );
1715 
1716 		return 0;
1717 	}
1718 	return 1;
1719 }
1720 
aburner_draw_road(struct mame_bitmap * bitmap,const struct rectangle * cliprect)1721 static void aburner_draw_road( struct mame_bitmap *bitmap, const struct rectangle *cliprect ){
1722 	/*
1723 		sys16_roadram[0x1000]:
1724 			0x04: flying (sky/horizon)
1725 			0x43: (flying->landing)
1726 			0xc3: runway landing
1727 			0xe3: (landing -> flying)
1728 			0x03: rocky canyon
1729 
1730 			Thunderblade: 0x04, 0xfe
1731 	*/
1732 
1733 	/*	Palette:
1734 	**		0x1700	ground(8), road(4), road(4)
1735 	**		0x1720	sky(16)
1736 	**		0x1730	road edge(2)
1737 	**		0x1780	background color(16)
1738 	*/
1739 
1740 	const UINT16 *vreg = sys16_roadram;
1741 	/*	0x000..0x0ff: 0x800: disable; 0x100: enable
1742 		0x100..0x1ff: color/line_select
1743 		0x200..0x2ff: xscroll
1744 		0x400..0x4ff: 0x5b0?
1745 		0x600..0x6ff: flip colors
1746 	*/
1747 	int page = sys16_roadram[0x1000];
1748 	int sy;
1749 
1750 	for( sy=cliprect->min_y; sy<=cliprect->max_y; sy++ ){
1751 		UINT16 *dest = (UINT16 *)bitmap->line[sy] + cliprect->min_x; /* assume 16bpp */
1752 		int sx;
1753 		UINT16 line = vreg[0x100+sy];
1754 
1755 		if( page&4 ){ /* flying */
1756 			int xscroll = vreg[0x200+sy] - 0x552;
1757 			UINT16 sky = Machine->pens[0x1720];
1758 			UINT16 ground = Machine->pens[0x1700];
1759 			for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1760 				int temp = xscroll+sx;
1761 				if( temp<0 ){
1762 					*dest++ = sky;
1763 				}
1764 				else if( temp < 0x200 ){
1765 					*dest++ = ground;
1766 				}
1767 				else {
1768 					*dest++ = sky;
1769 				}
1770 			}
1771 		}
1772 		else if( line&0x800 ){
1773 			/* opaque fill; the least significant nibble selects color */
1774 			unsigned short color = Machine->pens[0x1780+(line&0xf)];
1775 			for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1776 				*dest++ = color;
1777 			}
1778 		}
1779 		else if( page&0xc0 ){ /* road */
1780 			const UINT8 *source = aburner_backdrop+(line&0xff)*512 + 512*256*(page&1);
1781 			UINT16 xscroll = (512-320)/2;
1782 			// 040d 04b0 0552: normal: sky,horizon,sea
1783 
1784 			UINT16 flip = vreg[0x600+sy];
1785 			int clut[5];
1786 			{
1787 				int road_color = 0x1708+(flip&0x1);
1788 				clut[0] = Machine->pens[road_color];
1789 				clut[1] = Machine->pens[road_color+2];
1790 				clut[2] = Machine->pens[road_color+4];
1791 				clut[3] = Machine->pens[road_color+6];
1792 				clut[4] = Machine->pens[(flip&0x100)?0x1730:0x1731]; /* edge of road */
1793 			}
1794 			for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1795 				int xpos = (sx + xscroll)&0x1ff;
1796 				*dest++ = clut[source[xpos]];
1797 			}
1798 		}
1799 		else { /* rocky canyon */
1800 			UINT16 flip = vreg[0x600+sy];
1801 			unsigned short color = Machine->pens[(flip&0x100)?0x1730:0x1731];
1802 			for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1803 				*dest++ = color;
1804 			}
1805 		}
1806 	}
1807 #if 0
1808 	if( keyboard_pressed( KEYCODE_S ) ){ /* debug */
1809 		FILE *f;
1810 		int i;
1811 		char fname[64];
1812 		static int fcount = 0;
1813 		while( keyboard_pressed( KEYCODE_S ) ){}
1814 		sprintf( fname, "road%d.txt",fcount );
1815 		fcount++;
1816 		f = fopen( fname,"w" );
1817 		if( f ){
1818 			const UINT16 *source = sys16_roadram;
1819 			for( i=0; i<0x1000; i++ ){
1820 				if( (i&0x1f)==0 ) fprintf( f, "\n %04x: ", i );
1821 				fprintf( f, "%04x ", source[i] );
1822 			}
1823 			fclose( f );
1824 		}
1825 	}
1826 #endif
1827 }
1828 
sys16_aburner_vh_screenrefresh_helper(void)1829 static void sys16_aburner_vh_screenrefresh_helper( void ){
1830 	const data16_t *vreg = &sys16_textram[0x740];
1831 	int i;
1832 
1833 	{
1834 		UINT16 data = vreg[0];
1835 		sys16_fg_page[0] = data>>12;
1836 		sys16_fg_page[1] = (data>>8)&0xf;
1837 		sys16_fg_page[2] = (data>>4)&0xf;
1838 		sys16_fg_page[3] = data&0xf;
1839 		sys16_fg_scrolly = vreg[8];
1840 		sys16_fg_scrollx = vreg[12];
1841 	}
1842 
1843 	{
1844 		UINT16 data = vreg[0+1];
1845 		sys16_bg_page[0] = data>>12;
1846 		sys16_bg_page[1] = (data>>8)&0xf;
1847 		sys16_bg_page[2] = (data>>4)&0xf;
1848 		sys16_bg_page[3] = data&0xf;
1849 		sys16_bg_scrolly = vreg[8+1];
1850 		sys16_bg_scrollx = vreg[12+1];
1851 	}
1852 
1853 	{
1854 		UINT16 data = vreg[0+2];
1855 		sys16_fg2_page[0] = data>>12;
1856 		sys16_fg2_page[1] = (data>>8)&0xf;
1857 		sys16_fg2_page[2] = (data>>4)&0xf;
1858 		sys16_fg2_page[3] = data&0xf;
1859 		sys16_fg2_scrolly = vreg[8+2];
1860 		sys16_fg2_scrollx = vreg[12+2];
1861 	}
1862 
1863 	{
1864 		UINT16 data = vreg[0+3];
1865 		sys16_bg2_page[0] = data>>12;
1866 		sys16_bg2_page[1] = (data>>8)&0xf;
1867 		sys16_bg2_page[2] = (data>>4)&0xf;
1868 		sys16_bg2_page[3] = data&0xf;
1869 		sys16_bg2_scrolly = vreg[8+3];
1870 		sys16_bg2_scrollx = vreg[12+3];
1871 	}
1872 
1873 	sys18_splittab_fg_x = &sys16_textram[0x7c0];
1874 	sys18_splittab_bg_x = &sys16_textram[0x7e0];
1875 
1876 	{
1877 		int offset,offset2, scroll,scroll2,orig_scroll;
1878 		offset  = 32+((sys16_bg_scrolly >>3)&0x3f ); // screenwise rowscroll
1879 		offset2 = 32+((sys16_bg2_scrolly>>3)&0x3f ); // screenwise rowscroll
1880 
1881 		for( i=0;i<29;i++ ){
1882 			orig_scroll = scroll2 = scroll = sys18_splittab_bg_x[i];
1883 			if((sys16_bg_scrollx  &0xff00) != 0x8000) scroll = sys16_bg_scrollx;
1884 			if((sys16_bg2_scrollx &0xff00) != 0x8000) scroll2 = sys16_bg2_scrollx;
1885 
1886 			if( orig_scroll&0x8000 ){ // background2
1887 				tilemap_set_scrollx( background , (i+offset)&0x3f, TILE_LINE_DISABLED );
1888 				tilemap_set_scrollx( background2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_bgxoffset );
1889 			}
1890 			else{ // background1
1891 				tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1892 				tilemap_set_scrollx( background2, (i+offset2)&0x3f, TILE_LINE_DISABLED );
1893 			}
1894 		}
1895 	}
1896 
1897 	tilemap_set_scrolly( background , 0, -256+sys16_bg_scrolly );
1898 	tilemap_set_scrolly( background2, 0, -256+sys16_bg2_scrolly );
1899 
1900 	{
1901 		int offset,offset2, scroll,scroll2,orig_scroll;
1902 		offset  = 32+((sys16_fg_scrolly >>3)&0x3f ); // screenwise rowscroll
1903 		offset2 = 32+((sys16_fg2_scrolly>>3)&0x3f ); // screenwise rowscroll
1904 
1905 		for( i=0;i<29;i++ ){
1906 			orig_scroll = scroll2 = scroll = sys18_splittab_fg_x[i];
1907 			if( (sys16_fg_scrollx &0xff00) != 0x8000 ) scroll = sys16_fg_scrollx;
1908 
1909 			if( (sys16_fg2_scrollx &0xff00) != 0x8000 ) scroll2 = sys16_fg2_scrollx;
1910 
1911 			if( orig_scroll&0x8000 ){ // foreground2
1912 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, TILE_LINE_DISABLED );
1913 				tilemap_set_scrollx( foreground2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_fgxoffset );
1914 			}
1915 			else { // foreground
1916 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1917 				tilemap_set_scrollx( foreground2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
1918 			}
1919 		}
1920 	}
1921 
1922 	tilemap_set_scrolly( foreground , 0, -256+sys16_fg_scrolly );
1923 	tilemap_set_scrolly( foreground2, 0, -256+sys16_fg2_scrolly );
1924 }
1925 
VIDEO_UPDATE(aburner)1926 VIDEO_UPDATE( aburner ){
1927 	sys16_aburner_vh_screenrefresh_helper();
1928 	update_page();
1929 
1930 	fillbitmap(priority_bitmap,0,cliprect);
1931 
1932 	aburner_draw_road( bitmap,cliprect );
1933 
1934 //	tilemap_draw( bitmap,cliprect, background2, 0, 7 );
1935 //	tilemap_draw( bitmap,cliprect, background2, 1, 7 );
1936 
1937 	/* speed indicator, high score header */
1938 	tilemap_draw( bitmap,cliprect, background, 0, 7 );
1939 	tilemap_draw( bitmap,cliprect, background, 1, 7 );
1940 
1941 	/* radar view */
1942 	tilemap_draw( bitmap,cliprect, foreground2, 0, 7 );
1943 	tilemap_draw( bitmap,cliprect, foreground2, 1, 7 );
1944 
1945 	/* hand, scores */
1946 	tilemap_draw( bitmap,cliprect, foreground, 0, 7 );
1947 	tilemap_draw( bitmap,cliprect, foreground, 1, 7 );
1948 
1949 	tilemap_draw( bitmap,cliprect, text_layer, 0, 7 );
1950 	draw_sprites( bitmap,cliprect, 2 );
1951 
1952 //	debug_draw( bitmap,cliprect, 8,8,sys16_roadram[0x1000] );
1953 }
1954