1 #define NEW_DRAWSPRITE 1
2 /* System 32 Video Hardware */
3 
4 /* todo:
5 
6 add linezoom, clipping window effects on bg tilemaps
7 fix sprite clipping effect? (outside area clip)
8 fix / improve alphablending
9 fix alphablending enable, amount etc. (sonic almost certainly shouldn't have it enabled ?)
10 fix / add row-select, linescroll
11 fix priorities properly (will need vmixer)
12 find rad rally title screen background
13 remaining colour problems (sonic?)
14 solid flag on tiles? (rad rally..)
15 background colour
16 any remaining glitches
17 
18 */
19 
20 #include "driver.h"
21 #define MAX_COLOURS (16384)
22 
23 /* Debugging flags and kludges*/
24 extern int system32_temp_kludge;
25 int priloop;
26 
27 extern int multi32;
28 
29 extern data16_t *sys32_spriteram16;
30 data8_t  *sys32_spriteram8; /* I maintain this to make drawing ram based sprites easier */
31 extern data16_t *system32_mixerregs[2];		/* mixer registers*/
32 data16_t *sys32_videoram;
33 data32_t *multi32_videoram;
34 data8_t sys32_ramtile_dirty[0x1000];
35 extern data16_t sys32_displayenable;
36 extern data16_t sys32_tilebank_external;
37 data16_t sys32_old_tilebank_external;
38 
39 int sys32_tilebank_internal;
40 int sys32_old_tilebank_internal;
41 
42 int sys32_paletteshift[4];
43 int sys32_palettebank[4];
44 int sys32_old_paletteshift[4];
45 int sys32_old_palettebank[4];
46 
47 extern int system32_mixerShift;
48 int system32_screen_mode;
49 int system32_screen_old_mode;
50 int system32_allow_high_resolution;
51 static int sys32_old_brightness[2][3];
52 int sys32_brightness[2][3];
53 
54 data8_t system32_dirty_window[0x100];
55 data8_t system32_windows[4][4];
56 data8_t system32_old_windows[4][4];
57 
58 /* these are the various attributes a sprite can have, will decide which need to be global later, maybe put them in a struct */
59 
60 static int sys32sprite_indirect_palette;
61 static int sys32sprite_indirect_interleave;
62 static int sys32sprite_is_shadow;
63 static int sys32sprite_rambasedgfx;
64 static int sys32sprite_8bpp;
65 static int sys32sprite_draw_colour_f;
66 static int sys32sprite_yflip;
67 static int sys32sprite_xflip;
68 static int sys32sprite_use_yoffset;
69 static int sys32sprite_use_xoffset;
70 static int sys32sprite_yalign;
71 static int sys32sprite_xalign;
72 static int sys32sprite_rom_height;
73 static int sys32sprite_rom_width;
74 static int sys32sprite_rom_bank_low;
75 static int sys32sprite_unknown_1;
76 static int sys32sprite_unknown_2;
77 /*static int sys32sprite_solid;*/
78 static int sys32sprite_screen_height;
79 static int sys32sprite_unknown_3;
80 static int sys32sprite_rom_bank_high;
81 static int sys32sprite_unknown_4;
82 static int sys32sprite_unknown_5;
83 static int sys32sprite_rom_bank_mid;
84 static int sys32sprite_screen_width;
85 static int sys32sprite_ypos;
86 static int sys32sprite_xpos;
87 static int sys32sprite_rom_offset;
88 static int sys32sprite_palette;
89 static int sys32sprite_monitor_select; /* multi32*/
90 static int sys32sprite_priority;
91 
92 static data16_t *sys32sprite_table;
93 
94 static int spritenum; /* used to go through the sprite list */
95 static int jump_x, jump_y; /* these are set during a jump command and sometimes used by the sprites afterwards */
96 static data16_t *spritedata_source; /* a pointer into spriteram */
97 
98 #if !NEW_DRAWSPRITE
99 static UINT32 sys32sprite_x_zoom;
100 static UINT32 sys32sprite_y_zoom;
101 #else
102 static int sys32mon_old4, sys32mon_old8;
103 #endif
104 
105 /*
106 
107 this actually draws the sprite, and could probably be optimized quite a bit ;-)
108 currently zooming isn't supported etc.
109 
110 */
111 #if NEW_DRAWSPRITE
112 
113 /** AT050703 new drawsprite (unproven, general testing required)*/
system32_draw_sprite(struct mame_bitmap * bitmap,const struct rectangle * cliprect)114 static INLINE void system32_draw_sprite ( struct mame_bitmap *bitmap, const struct rectangle *cliprect )
115 {
116 #define FP     20
117 #define FPONE  (1<<FP)
118 #define FPHALF (1<<(FP-1))
119 
120 /* FP entry vaule(FPENT) should normally be 0.5(FPHALF) but it causes sprite gaps occationally.*/
121 #define FPENT  0
122 
123 	static UINT32 idp_cache8[256];
124 	static UINT32 idp_cache4[16];
125 	static data16_t *idp_base, *idb_old=0;
126 	static int idi_old=-1;
127 
128 	/* one-time*/
129 	int src_fw, src_fh;
130 	int dst_minx, dst_maxx, dst_miny, dst_maxy;
131 	int dst_skipx, dst_skipy, dst_x, dst_y, dst_lastx, dst_lasty; /* Buy Warren Spector's Deus Ex2. It's cool.*/
132 	int flipx, flipy;
133 
134 	/* inner loop*/
135 	UINT8 *src_ptr;
136 	register int edx, eax, ecx;
137 	int src_fx, src_fdx, transparent_pen;
138 	UINT32 *pal_base;
139 	UINT32 *dst_ptr;
140 
141 	/* outter loop*/
142 	int src_fby, src_fdy;
143 	int dst_pitch;
144 	int src_pitch, src_fbx;
145 	UINT8 *src_base;
146 	int dst_w, dst_h;
147 
148 
149 	/* fill internal data structure with default values*/
150 	src_base  = memory_region(REGION_GFX2);
151 	src_pitch = sys32sprite_rom_width;
152 	src_fw    = sys32sprite_rom_width;
153 	src_fh    = sys32sprite_rom_height;
154 
155 	idp_base  = sys32sprite_table;
156 	pal_base  = Machine->gfx[0]->colortable;
157 
158 	dst_ptr   = bitmap->base;
159 	dst_pitch = bitmap->rowpixels;
160 	dst_minx  = cliprect->min_x;
161 	dst_maxx  = cliprect->max_x;
162 	dst_miny  = cliprect->min_y;
163 	dst_maxy  = cliprect->max_y;
164 	dst_x     = sys32sprite_xpos;
165 	dst_y     = sys32sprite_ypos;
166 	dst_w     = sys32sprite_screen_width;
167 	dst_h     = sys32sprite_screen_height;
168 
169 	flipx     = sys32sprite_xflip;
170 	flipy     = sys32sprite_yflip;
171 	transparent_pen   = 0;
172 
173 	/* cull zero dimension and off-screen objects*/
174 	if (!src_fw || !src_fh || !dst_w || !dst_h) return;
175 	if (dst_x > dst_maxx || dst_y > dst_maxy) return;
176 	dst_lastx = dst_x + dst_w - 1;
177 	if (dst_lastx < dst_minx) return;
178 	dst_lasty = dst_y + dst_h - 1;
179 	if (dst_lasty < dst_miny) return;
180 
181 	/* calculate zoom factors*/
182 	src_fw <<= FP;
183 	src_fh <<= FP;
184 	src_fdx = src_fw / dst_w;
185 	src_fdy = src_fh / dst_h;
186 
187 	/* clip destination*/
188 	dst_skipx = 0;
189 	eax = dst_minx;  if ((eax -= dst_x) > 0) { dst_skipx = eax;  dst_w -= eax;  dst_x = dst_minx; }
190 	eax = dst_lastx; if ((eax -= dst_maxx) > 0) dst_w -= eax;
191 	dst_skipy = 0;
192 	eax = dst_miny;  if ((eax -= dst_y) > 0) { dst_skipy = eax;  dst_h -= eax;  dst_y = dst_miny; }
193 	eax = dst_lasty; if ((eax -= dst_maxy) > 0) dst_h -= eax;
194 
195 	/* clip source (precision loss from MUL after DIV is intentional to maintain pixel consistency)*/
196 	if (flipx)
197 	{
198 		src_fbx = src_fw - FPENT - 1;
199 		src_fdx = -src_fdx;
200 	}
201 	else src_fbx = FPENT;
202 	src_fbx += dst_skipx * src_fdx;
203 	if (flipy)
204 	{
205 		src_fby = src_fh - FPENT - 1;
206 		src_fdy = -src_fdy;
207 	}
208 	else src_fby = FPENT;
209 	src_fby += dst_skipy * src_fdy;
210 
211 
212 	/* modify oddities*/
213 	/* if the gfx data is coming from RAM instead of ROM change the pointer*/
214 	if (sys32sprite_rambasedgfx)
215 	{
216 		src_base = sys32_spriteram8;
217 		sys32sprite_rom_offset &= 0x1ffff; /* right mask?*/
218 	}
219 
220 	if (sys32sprite_monitor_select)
221 	{
222 		pal_base += MAX_COLOURS;
223 		dst_x += system32_screen_mode ? 52*8 : 40*8;
224 	}
225 
226 	if (!sys32sprite_8bpp)
227 	{
228 		src_pitch >>= 1;
229 		if (!sys32sprite_draw_colour_f) transparent_pen = 0x0f;
230 	}
231 	else
232 		if (!sys32sprite_draw_colour_f) transparent_pen = 0xff;
233 
234 	if (!sys32sprite_is_shadow)
235 	{
236 		if (sys32sprite_indirect_palette)
237 		{
238 			/* update indirect palette cache if necessary*/
239 			if (!sys32sprite_8bpp)
240 			{
241 				if (idb_old != idp_base || sys32mon_old4 != sys32sprite_monitor_select)
242 				{
243 					idb_old = idp_base;
244 					sys32mon_old4 = sys32sprite_monitor_select;
245 
246 					for (ecx=0; ecx<0x10; ecx+=2)
247 					{
248 						eax = idp_base[ecx];   edx = idp_base[ecx+1];
249 						eax &= 0x0fff;         edx &= 0x0fff; /* no apparent side-effect observed*/
250 						eax = pal_base[eax];   edx = pal_base[edx];
251 						idp_cache4[ecx] = eax; idp_cache4[ecx+1] = edx;
252 					}
253 				}
254 			}
255 			else
256 			{
257 				edx = *idp_base & 0xfff;
258 				if (idi_old != edx || sys32mon_old8 != sys32sprite_monitor_select)
259 				{
260 					idi_old = edx;
261 					sys32mon_old8 = sys32sprite_monitor_select;
262 					pal_base += edx;
263 
264 					for (ecx=0; ecx<0x100; ecx+=2)
265 					{
266 						eax = pal_base[ecx];   edx = pal_base[ecx+1];
267 						idp_cache8[ecx] = eax; idp_cache8[ecx+1] = edx;
268 					}
269 				}
270 			}
271 		}
272 		else
273 			pal_base += sys32sprite_palette<<4;
274 	}
275 	else
276 		sys32sprite_indirect_palette = 0; /* make sure full-shadows and IDP's are mutually exclusive*/
277 
278 
279 	/* adjust insertion points and pre-entry constants*/
280 	src_base += sys32sprite_rom_offset;
281 	dst_ptr += dst_y * dst_pitch + dst_x + dst_w;
282 	dst_w = -dst_w;
283 
284 	ecx = src_fby;
285 	src_fby += src_fdy;
286 	ecx >>= FP;
287 	src_ptr = src_base;
288 	ecx *= src_pitch;
289 	src_fx = src_fbx;
290 	edx    = src_fbx;
291 	src_ptr += ecx;
292 	ecx = dst_w;
293 
294 	if (!sys32sprite_8bpp)
295 	{
296 		/* 4bpp*/
297 		edx >>= FP+1;
298 
299 		if (sys32sprite_indirect_palette)
300 		{
301 			do {
302 				do {
303 					eax = src_ptr[edx];
304 					edx = src_fx;
305 					if (src_fx & FPONE) eax &= 0xf; else eax >>= 4;
306 					edx += src_fdx;
307 					src_fx += src_fdx;
308 					edx >>= FP+1;
309 
310 					if (!eax || eax == transparent_pen) continue;
311 					if (eax != 0x0e)
312 						dst_ptr[ecx] = idp_cache4[eax];
313 					else
314 					{
315 						eax = dst_ptr[ecx];
316 						eax = (eax>>9&0x7c00) | (eax>>6&0x03e0) | (eax>>3&0x001f);
317 						dst_ptr[ecx] = ((UINT32*)palette_shadow_table)[eax];
318 					}
319 
320 				} while (++ecx);
321 
322 				ecx = src_fby;      src_fby += src_fdy;
323 				ecx >>= FP;         dst_ptr += dst_pitch;
324 				ecx *= src_pitch;   src_fx = src_fbx;
325 				edx = src_fbx;
326 				src_ptr = src_base; edx >>= FP+1;
327 				src_ptr += ecx;     ecx = dst_w;
328 
329 			} while (--dst_h);
330 		}
331 		else if (!sys32sprite_is_shadow)
332 		{
333 			do {
334 				do {
335 					eax = src_ptr[edx];
336 					edx = src_fx;
337 					if (src_fx & FPONE) eax &= 0xf; else eax >>= 4;
338 					edx += src_fdx;
339 					src_fx += src_fdx;
340 					edx >>= (FP+1);
341 
342 					if (!eax || eax == transparent_pen) continue;
343 					dst_ptr[ecx] = pal_base[eax];
344 
345 				} while (++ecx);
346 
347 				ecx = src_fby;      src_fby += src_fdy;
348 				ecx >>= FP;         dst_ptr += dst_pitch;
349 				ecx *= src_pitch;   src_fx = src_fbx;
350 				edx = src_fbx;
351 				src_ptr = src_base; edx >>= FP+1;
352 				src_ptr += ecx;     ecx = dst_w;
353 
354 			} while (--dst_h);
355 		}
356 		else
357 		{
358 			do {
359 				do {
360 					eax = src_ptr[edx];
361 					edx = src_fx;
362 					if (src_fx & FPONE) eax &= 0xf; else eax >>= 4;
363 					edx += src_fdx;
364 					src_fx += src_fdx;
365 					edx >>= (FP+1);
366 
367 					if (!eax || eax == transparent_pen) continue;
368 					eax = dst_ptr[ecx];
369 					eax = (eax>>9&0x7c00) | (eax>>6&0x03e0) | (eax>>3&0x001f);
370 					dst_ptr[ecx] = ((UINT32*)palette_shadow_table)[eax];
371 
372 				} while (++ecx);
373 
374 				ecx = src_fby;      src_fby += src_fdy;
375 				ecx >>= FP;         dst_ptr += dst_pitch;
376 				ecx *= src_pitch;   src_fx = src_fbx;
377 				edx = src_fbx;
378 				src_ptr = src_base; edx >>= FP+1;
379 				src_ptr += ecx;     ecx = dst_w;
380 
381 			} while (--dst_h);
382 		}
383 	}
384 	else
385 	{
386 		/* 8bpp*/
387 		edx >>= FP;
388 		src_fx += src_fdx;
389 
390 		if (sys32sprite_indirect_palette)
391 		{
392 			do {
393 				do {
394 					eax = src_ptr[edx];
395 					edx = src_fx;
396 					src_fx += src_fdx;
397 					edx >>= FP;
398 
399 					if (!eax || eax == 0xe0 || eax == transparent_pen) continue;
400 					if (eax != 0xf0)
401 						dst_ptr[ecx] = idp_cache8[eax];
402 					else
403 					{
404 						eax = dst_ptr[ecx];
405 						eax = (eax>>9&0x7c00) | (eax>>6&0x03e0) | (eax>>3&0x001f);
406 						dst_ptr[ecx] = ((UINT32*)palette_shadow_table)[eax];
407 					}
408 
409 				} while (++ecx);
410 
411 				ecx = src_fby;      src_fby += src_fdy;
412 				ecx >>= FP;         dst_ptr += dst_pitch;
413 				ecx *= src_pitch;   src_fx = src_fbx;
414 				edx = src_fbx;      src_fx += src_fdx;
415 				src_ptr = src_base; edx >>= FP;
416 				src_ptr += ecx;     ecx = dst_w;
417 
418 			} while (--dst_h);
419 		}
420 		else if (!sys32sprite_is_shadow)
421 		{
422 			do {
423 				do {
424 					eax = src_ptr[edx];
425 					edx = src_fx;
426 					src_fx += src_fdx;
427 					edx >>= FP;
428 
429 					if (!eax || eax == transparent_pen) continue;
430 					dst_ptr[ecx] = pal_base[eax];
431 
432 				} while (++ecx);
433 
434 				ecx = src_fby;      src_fby += src_fdy;
435 				ecx >>= FP;         dst_ptr += dst_pitch;
436 				ecx *= src_pitch;   src_fx = src_fbx;
437 				edx = src_fbx;      src_fx += src_fdx;
438 				src_ptr = src_base; edx >>= FP;
439 				src_ptr += ecx;     ecx = dst_w;
440 
441 			} while (--dst_h);
442 		}
443 		else
444 		{
445 			do {
446 				do {
447 					eax = src_ptr[edx];
448 					edx = src_fx;
449 					src_fx += src_fdx;
450 					edx >>= FP;
451 
452 					if (!eax || eax == transparent_pen) continue;
453 					eax = dst_ptr[ecx];
454 					eax = (eax>>9&0x7c00) | (eax>>6&0x03e0) | (eax>>3&0x001f);
455 					dst_ptr[ecx] = ((UINT32*)palette_shadow_table)[eax];
456 
457 				} while (++ecx);
458 
459 				ecx = src_fby;      src_fby += src_fdy;
460 				ecx >>= FP;         dst_ptr += dst_pitch;
461 				ecx *= src_pitch;   src_fx = src_fbx;
462 				edx = src_fbx;      src_fx += src_fdx;
463 				src_ptr = src_base; edx >>= FP;
464 				src_ptr += ecx;     ecx = dst_w;
465 
466 			} while (--dst_h);
467 		}
468 	}
469 #undef FP
470 #undef FPONE
471 #undef FPHALF
472 #undef FPENT
473 }
474 
475 #else
476 
477 /* old drawsprite (working and proven)*/
system32_draw_sprite(struct mame_bitmap * bitmap,const struct rectangle * cliprect)478 void system32_draw_sprite ( struct mame_bitmap *bitmap, const struct rectangle *cliprect ) {
479 	data8_t *sprite_gfxdata = memory_region ( REGION_GFX2 );
480 	UINT32 xsrc,ysrc;
481 	UINT32 xdst,ydst;
482 	/* um .. probably a better way to do this */
483 	struct GfxElement *gfx=Machine->gfx[0];
484 	const pen_t *paldata = &gfx->colortable[0];
485 
486 	/* if the gfx data is coming from RAM instead of ROM change the pointer */
487 	if ( sys32sprite_rambasedgfx ) {
488 		sprite_gfxdata = sys32_spriteram8;
489 		sys32sprite_rom_offset &= 0x1ffff; /* right mask? */
490 	}
491 
492 	ysrc = 0;
493 	ydst = 0;
494 
495 	while ( ysrc < (sys32sprite_rom_height<<16) ) {
496 		int drawypos;
497 		xsrc = 0;
498 		xdst = 0;
499 
500 		if (!sys32sprite_yflip) {
501 			drawypos = sys32sprite_ypos+ydst; /* no flip*/
502 			if (drawypos > cliprect->max_y) ysrc = sys32sprite_rom_height<<16; /* quit drawing if we've gone off the right*/
503 		}
504 		else {
505 			drawypos = sys32sprite_ypos+((sys32sprite_screen_height-1)-ydst); /* y flip*/
506 			if (drawypos < cliprect->min_y) ysrc = sys32sprite_rom_height<<16; /* quit drawing if we've gone off the left on a flipped sprite*/
507 		}
508 
509 		if ((drawypos >= cliprect->min_y) && (drawypos <= cliprect->max_y)) {
510 			UINT32 *destline = (bitmap->line[drawypos]);
511 
512 			while ( xsrc < (sys32sprite_rom_width<<16) ) {
513 
514 				int drawxpos;
515 
516 				if (!sys32sprite_xflip) {
517 					drawxpos = sys32sprite_xpos+xdst; /* no flip*/
518 					if (drawxpos > cliprect->max_x) xsrc = sys32sprite_rom_width<<16; /* quit drawing if we've gone off the right*/
519 				}
520 				else {
521 					drawxpos = sys32sprite_xpos+((sys32sprite_screen_width-1)-xdst); /* x flip*/
522 					if (drawxpos < cliprect->min_x) xsrc = sys32sprite_rom_width<<16; /* quit drawing if we've gone off the left on a flipped sprite*/
523 				}
524 
525 				if ((drawxpos >= cliprect->min_x) && (drawxpos <= cliprect->max_x)) {
526 					int gfxdata;
527 					int data;
528 					int r,g,b;
529 
530 					if (sys32sprite_monitor_select) drawxpos+=system32_screen_mode?52*8:40*8;
531 					if (!sys32sprite_8bpp) { /* 4bpp*/
532 						gfxdata = (sprite_gfxdata[sys32sprite_rom_offset+((xsrc>>16)/2)+(ysrc>>16)*(sys32sprite_rom_width/2)]);
533 
534 						if (xsrc & 0x10000) gfxdata = gfxdata & 0x0f;
535 						else gfxdata = (gfxdata & 0xf0) >> 4;
536 
537 						if ( (!sys32sprite_draw_colour_f && gfxdata == 0x0f) ) gfxdata = 0;
538 						if (sys32sprite_indirect_palette) {
539 							switch (gfxdata) {
540 							case 0x00:
541 								break;
542 
543 							case 0x0f: /* Transparent*/
544 								break;
545 
546 							case 0x0e: /* Shadow*/
547 								data=destline[drawxpos];
548 
549 								r = ((data >> 16) & 0xff)*0.5;
550 								g = ((data >> 8) & 0xff)*0.5;
551 								b = ((data >> 0) & 0xff)*0.5;
552 
553 								destline[drawxpos] =  MAKE_RGB(r,g,b);
554 								break;
555 
556 							default:
557 								destline[drawxpos] =  paldata[(sys32sprite_table[gfxdata] & 0xfff)+(sys32sprite_monitor_select*MAX_COLOURS)];
558 								break;
559 							}
560 						}
561 						else {
562 							if (sys32sprite_is_shadow) {
563 								data=destline[drawxpos];
564 
565 								r = ((data >> 16) & 0xff)*0.5;
566 								g = ((data >> 8) & 0xff)*0.5;
567 								b = ((data >> 0) & 0xff)*0.5;
568 
569 								if (gfxdata) destline[drawxpos] =  MAKE_RGB(r,g,b);
570 							}
571 							else {
572 
573 								switch (gfxdata) {
574 								case 0x00:
575 									break;
576 								default:
577 									destline[drawxpos] =  paldata[gfxdata + (sys32sprite_palette * 16)+(sys32sprite_monitor_select*MAX_COLOURS)];
578 									break;
579 								}
580 
581 							}
582 						}
583 					}
584 					else { /* 8bpp*/
585 						gfxdata = (sprite_gfxdata[sys32sprite_rom_offset+(xsrc>>16)+(ysrc>>16)*(sys32sprite_rom_width)]);
586 
587 						if ( (!sys32sprite_draw_colour_f) && (gfxdata == 0xff) ) gfxdata = 0;
588 
589 						if (sys32sprite_indirect_palette) {
590 							switch (gfxdata) {
591 							case 0x00:
592 								break;
593 							case 0xe0: /* Transparent*/
594 								break;
595 							case 0xf0: /* Shadow*/
596 								data=destline[drawxpos];
597 
598 								r = ((data >> 16) & 0xff)*0.5;
599 								g = ((data >> 8) & 0xff)*0.5;
600 								b = ((data >> 0) & 0xff)*0.5;
601 
602 								destline[drawxpos] =  MAKE_RGB(r,g,b);
603 								break;
604 							default:
605 								destline[drawxpos] =  paldata[gfxdata+(sys32sprite_table[0] & 0xfff)+sys32sprite_monitor_select*MAX_COLOURS];
606 								break;
607 							}
608 						}
609 						else {
610 							if (sys32sprite_is_shadow) {
611 								data=destline[drawxpos];
612 
613 								r = ((data >> 16) & 0xff)*0.5;
614 								g = ((data >> 8) & 0xff)*0.5;
615 								b = ((data >> 0) & 0xff)*0.5;
616 
617 								if (gfxdata) destline[drawxpos] =  MAKE_RGB(r,g,b);
618 							}
619 							else {
620 								if (gfxdata) destline[drawxpos] =  paldata[gfxdata + (sys32sprite_palette * 16)+sys32sprite_monitor_select*MAX_COLOURS];
621 							}
622 						}
623 					} /* bpp */
624 				} /* xclipping */
625 				xsrc+=sys32sprite_x_zoom;
626 				xdst++;
627 			}
628 		}
629 		ysrc+=sys32sprite_y_zoom;
630 		ydst++;
631 	}
632 }
633 
634 #endif
635 
636 /* system32_get_sprite_info
637 
638 this function is used to get information on the sprite from spriteram and call the
639 drawing functions
640 
641 	spriteram Sprite Entry layout
642 
643 	0:  ffffffff ffffffff  1:  HHHHHHHH WWWWWWWW  2:  hhhhhhhh hhhhhhhh  3:  wwwwwwww wwwwwwww
644 	4:  yyyyyyyy yyyyyyyy  5:  xxxxxxxx xxxxxxxx  6:  rrrrrrrr rrrrrrrr  7:  pppppppp pppppppp
645 
646 	f = various flags
647 		xx------ -------- (0xc000) :  Command (00 for a sprite, other values would mean this isn't a sprite)
648 		--x----- -------- (0x2000) :  Sprite uses Indirect Palette (TRUSTED)
649 		---x---- -------- (0x1000) :  Sprite uses Indirect Palette which is Interleaved in Spritelist (GA2?)
650 		----x--- -------- (0x0800) :  Sprite is a shadow.  Uses upper 16 values of the sprite priority table
651 		-----x-- -------- (0x0400) :  Sprite GFX data comes from Spriteram, not ROM (TRUSTED)
652 		------x- -------- (0x0200) :  Sprite is 8bpp not 4bpp (TRUSTED)
653 		-------x -------- (0x0100) :  If NOT set colour in palette 0x0f is transparent (TRUSTED)
654 		-------- x------- (0x0080) :  Sprite Y-Flip (TRUSTED)
655 		-------- -x------ (0x0040) :  Sprite X-Flip (TRUSTED)
656 		-------- --x----- (0x0020) :  Use Y offset (offset set in last jump) (not trusted)
657 		-------- ---x---- (0x0010) :  Use X offset (offset set in last jump) (TRUSTED)
658 		-------- ----xx-- (0x000c) :  Y alignment. 00=Center, 10=Start, 01=End (TRUSTED)
659 		-------- ------xx (0x0003) :  X alignment. 00=Center, 10=Start, 01=End (TRUSTED)
660 
661 	H = height of sprite in ROM
662 	W = width  of sprite in ROM (multiply by 4 to get screen width)
663 
664 	System32:
665 	w = width to draw on SCREEN + extra attributes
666 		x------- -------- (0x8000) :  unknown
667 		-x------ -------- (0x4000) :  Bit 5 of Sprite ROM Bank (TRUSTED)
668 		--x----- -------- (0x2000) :  unknown
669 		---x---- -------- (0x1000) :  unknown
670 		----x--- -------- (0x0800) :  Bit 4 of Sprite ROM Bank (TRUSTED)
671 		-----xxx xxxxxxxx (0x07ff) :  Width to draw on screen (TRUSTED)
672 
673 	Multi32:
674 	w = width to draw on SCREEN + extra attributes
675 		x------- -------- (0x8000) :  bit 5 of the sprite bank (TRUSTED)
676 		-x------ -------- (0x4000) :  unknown
677 		--x----- -------- (0x2000) :  Bit 4 of the sprite bank (TRUSTED)
678 		---x---- -------- (0x1000) :  unknown
679 		----x--- -------- (0x0800) :  Monitor selection for this sprite (TRUSTED)
680 		-----xxx xxxxxxxx (0x07ff) :  Width to draw on screen (TRUSTED)
681 	y = y-position (12-bit?, high bit = sign bit?)
682 
683 	x = x-position (12-bit, high bit = sign bit)
684 
685 	r = ROM Offset of GFX data (multiply by 4 to get real offset)
686 
687 	p = Palette & Priority bits, I think these change depending on the mode (Direct or Indirect)
688 		DIRECT MODE *probably wrong, holoseum needed a kludge to work
689 		xxxxx--- -------- (0xf800) :  unknown
690 		-----xxx xxxx---- (0x07f0) :  palette #
691 		-------- ----xxxx (0x000f) :  unknown
692 
693 */
694 
695 /** AT050703: minor clean-up's*/
system32_get_sprite_info(struct mame_bitmap * bitmap,const struct rectangle * cliprect)696 static INLINE void system32_get_sprite_info ( struct mame_bitmap *bitmap, const struct rectangle *cliprect ) {
697 	/* get attributes */
698 	int mixerinput, sprite_palette_mask, sprite_priority_levels, sys32sprite_priority_lookup;
699 
700 	sys32sprite_indirect_palette		= (spritedata_source[0]&0x2000) >> 13;
701 	sys32sprite_indirect_interleave		= (spritedata_source[0]&0x1000) >> 12;
702 	sys32sprite_is_shadow				= (spritedata_source[0]&0x0800) >> 11;
703 	sys32sprite_rambasedgfx				= (spritedata_source[0]&0x0400) >> 10;
704 	sys32sprite_8bpp					= (spritedata_source[0]&0x0200) >> 9;
705 	sys32sprite_draw_colour_f			= (spritedata_source[0]&0x0100) >> 8;
706 	sys32sprite_yflip					= (spritedata_source[0]&0x0080) >> 7;
707 	sys32sprite_xflip					= (spritedata_source[0]&0x0040) >> 6;
708 	sys32sprite_use_yoffset				= (spritedata_source[0]&0x0020) >> 5;
709 	sys32sprite_use_xoffset				= (spritedata_source[0]&0x0010) >> 4;
710 	sys32sprite_yalign					= (spritedata_source[0]&0x000c) >> 2;
711 	sys32sprite_xalign					= (spritedata_source[0]&0x0003) >> 0;
712 
713 	sys32sprite_rom_height				= (spritedata_source[1]&0xff00) >> 8;
714 	sys32sprite_rom_width				= (spritedata_source[1]&0x00ff) >> 0;
715 
716 	sys32sprite_rom_bank_low			= (spritedata_source[2]&0xf000) >> 12;
717 	sys32sprite_unknown_1				= (spritedata_source[2]&0x0800) >> 11;
718 	sys32sprite_unknown_2				= (spritedata_source[2]&0x0400) >> 10;
719 	sys32sprite_screen_height			= (spritedata_source[2]&0x03ff) >> 0;
720 
721 	if (multi32) {
722 		sys32sprite_rom_bank_high			= (spritedata_source[3]&0x8000) >> 15;
723 		sys32sprite_unknown_3				= (spritedata_source[3]&0x4000) >> 14;
724 		sys32sprite_rom_bank_mid			= (spritedata_source[3]&0x2000) >> 13;
725 		sys32sprite_unknown_4				= (spritedata_source[3]&0x1000) >> 12;
726 		sys32sprite_monitor_select			= (spritedata_source[3]&0x0800) >> 11;
727 	}
728 	else {
729 		sys32sprite_unknown_3				= (spritedata_source[3]&0x8000) >> 15;
730 		sys32sprite_rom_bank_high			= (spritedata_source[3]&0x4000) >> 14;
731 		sys32sprite_unknown_4				= (spritedata_source[3]&0x2000) >> 13;
732 		sys32sprite_unknown_5				= (spritedata_source[3]&0x1000) >> 12;
733 		sys32sprite_rom_bank_mid			= (spritedata_source[3]&0x0800) >> 11;
734 		sys32sprite_monitor_select			= 0;
735 	}
736 	sys32sprite_screen_width			= (spritedata_source[3]&0x07ff) >> 0;
737 
738 	sys32sprite_ypos					= (spritedata_source[4]&0xffff) >> 0;
739 
740 	sys32sprite_xpos					= (spritedata_source[5]&0xffff) >> 0;
741 
742 	sys32sprite_rom_offset				= (spritedata_source[6]&0xffff) >> 0;
743 
744 	sprite_palette_mask=(1<<(system32_mixerShift+4))-1;
745 	sprite_priority_levels=system32_mixerregs[sys32sprite_monitor_select][0x4d/2]&2?15:3;
746 	mixerinput = (spritedata_source[7] >> (system32_mixerShift + 8)) & 0xf;
747 	sys32sprite_palette = (spritedata_source[7] >> 4) & sprite_palette_mask;
748 	sys32sprite_palette += (system32_mixerregs[sys32sprite_monitor_select][mixerinput] & 0x30)<<2;
749 
750 	/* process attributes */
751 
752 	sys32sprite_rom_width = sys32sprite_rom_width << 2;
753 	sys32sprite_rom_offset = sys32sprite_rom_offset | (sys32sprite_rom_bank_low << 16) | (sys32sprite_rom_bank_mid << 20) | (sys32sprite_rom_bank_high << 21);
754 	sys32sprite_rom_offset = sys32sprite_rom_offset << 2;
755 
756 	/* Determine the sprites palette and priority.  The actual priority of the sprite is found by looking up
757 	   the sprite priority table in the mixer registers.  The lookup value is found by reading the first colour
758 	   in the sprites palette in the case of indirect sprites.  For direct sprites, the lookup value is found by
759 	   reading the sprite priority data.
760 	*/
761 	if (sys32sprite_indirect_palette) {
762 		if (sys32sprite_indirect_interleave) /* indirect mode where the table is included in the display list */
763 		{
764 			sys32sprite_table = spritedata_source+8;
765 			spritenum+=2;
766 		}
767 		else /* indirect mode where the display list contains an offset to the table */
768 		{
769 			sys32sprite_table = sys32_spriteram16 + ((spritedata_source[7] & ((1<<(8+system32_mixerShift))-1))*8);
770 		}
771 		if (sys32sprite_table[0]==0xffff) sys32sprite_priority_lookup=1;
772 		else sys32sprite_priority_lookup = (sys32sprite_table[0]>>(8+system32_mixerShift))&0xf;
773 	}
774 	else {
775 		/* If all of the palette bits are set, the sprite is a shadow.  This is a secondary
776 		   method to define sprite shadows alongside the sys32sprite_is_shadow bit.
777 		   Direct palette shadow sprites use the upper 16 values in the sprite priority lookup table. */
778 		if (sprite_palette_mask==((spritedata_source[7]>>4)&sprite_palette_mask)) sys32sprite_is_shadow=1;
779 		sys32sprite_priority_lookup = (spritedata_source[7]>>(system32_mixerShift+8))&0xf;
780 	}
781 
782 	sys32sprite_priority = system32_mixerregs[sys32sprite_monitor_select][sys32sprite_priority_lookup&sprite_priority_levels]&0xf;
783 	if (sys32sprite_is_shadow && ((!strcmp(Machine->gamedrv->name,"f1en")) || (!strcmp(Machine->gamedrv->name,"f1lap")))) sys32sprite_is_shadow=0;  /* f1en turns this flag on the car sprites?*/
784 
785 	if (sys32sprite_use_yoffset) sys32sprite_ypos += jump_y;
786 	if (sys32sprite_use_xoffset) sys32sprite_xpos += jump_x;
787 
788 	/* adjust positions according to offsets if used (radm, radr, alien3, darkedge etc.) */
789 
790 	/* adjust sprite positions based on alignment, pretty much straight from modeler */
791 	switch (sys32sprite_xalign) {
792 	case 0: /* centerX*/
793 	case 3:
794 		sys32sprite_xpos -= (sys32sprite_screen_width-1) / 2; /* this is trusted again spiderman truck door*/
795 		break;
796 	case 1: /* rightX*/
797 		sys32sprite_xpos -= sys32sprite_screen_width - 1;
798 		break;
799 	case 2: /* leftX*/
800 		break;
801 	}
802 
803 	switch (sys32sprite_yalign) {
804 	case 0: /* centerY*/
805 	case 3:
806 		sys32sprite_ypos -= (sys32sprite_screen_height-1) / 2; /* this is trusted against alien3 energy bars*/
807 		break;
808 	case 1: /* bottomY*/
809 		sys32sprite_ypos -= sys32sprite_screen_height - 1;
810 		break;
811 	case 2: /* topY*/
812 		break;
813 	}
814 
815 	sys32sprite_xpos &= 0x0fff;
816 	sys32sprite_ypos &= 0x0fff;
817 
818 	/* sprite positions are signed */
819 	if (sys32sprite_ypos & 0x0800) sys32sprite_ypos -= 0x1000;
820 	if (sys32sprite_xpos & 0x0800) sys32sprite_xpos -= 0x1000;
821 
822 	/* Inefficient sprite priority hack to get things working for now.  Will change to arrays later.
823 		Currently, draw_sprite is a lot more processor intensive and has a greater need for optimisation. */
824 	if (priloop==sys32sprite_priority)
825 		if (!multi32 || (multi32 && (readinputport(0xf)&(sys32sprite_monitor_select+1))>>sys32sprite_monitor_select))
826 			system32_draw_sprite ( bitmap, cliprect );
827 }
828 
829 /* Sprite RAM
830 
831 each entry in the sprite list is 16 bytes (8 words)
832 the sprite list itself consists of 4 main different types of entry
833  a normal sprite
834 
835 	0:  00------ --------  1:  -------- --------  2:  -------- --------  3:  -------- --------
836 	4:  -------- --------  5:  -------- --------  6:  -------- --------  7:  -------- --------
837 
838 		(See Above for bit usage)
839 
840  a command to set the clipping area
841 
842 	0:  01------ --------  1:  -------- --------  2:  -------- --------  3:  -------- --------
843 	4:  -------- --------  5:  -------- --------  6:  -------- --------  7:  -------- --------
844 
845 		(to be filled in later)
846 
847  a jump command
848 
849 	0:  10ujjjjj jjjjjjjj  1:  yyyyyyyy yyyyyyyy  2:  xxxxxxxx xxxxxxxx  3:  -------- --------
850 	4:  -------- --------  5:  -------- --------  6:  -------- --------  7:  -------- --------
851 
852 		u = set sprite offset positions with this jump (alien3 proves this test is needed)
853 		j = sprite number to jump to
854 		y = sprite y offset to use (? bits) (only set if u = 1)
855 		x = sprite x offset to use (? bits) (only set if u = 1)
856 
857 		other bits unused / unknown
858 
859  a terminate list command
860 
861 	0:  11------ --------  1:  -------- --------  2:  -------- --------  3:  -------- --------
862 	4:  -------- --------  5:  -------- --------  6:  -------- --------  7:  -------- --------
863 
864 		(other bits unused, list is terminated)
865 
866 sprite ram can also contain palette look up data for the special indirect
867 palette modes, as well as sprite gfx data which is used instead of the gfx
868 in the roms if a bit in the sprite entry is set.
869 
870 */
871 
system32_process_spritelist(struct mame_bitmap * bitmap,const struct rectangle * cliprect)872 void system32_process_spritelist ( struct mame_bitmap *bitmap, const struct rectangle *cliprect ) {
873 	int processed;
874 	int command;
875 	struct rectangle clip;
876 
877 	/* set clipping defaults */
878 	clip.min_x = Machine->visible_area.min_x;
879 	clip.max_x = Machine->visible_area.max_x;
880 	clip.min_y = Machine->visible_area.min_y;
881 	clip.max_y = Machine->visible_area.max_y;
882 
883 	processed = 0;
884 	spritenum = 0;
885 
886 	while (spritenum < 0x20000/16) {
887 		spritedata_source = sys32_spriteram16 + 8 * spritenum;
888 
889 		command = (spritedata_source[0] & 0xc000) >> 14;
890 
891 		switch (command) {
892 		case 0x3: /* end of sprite list */
893 			/*				logerror ("SPRITELIST: terminated at sprite %06x\n", spritenum*16);*/
894 			spritenum = 60000; /* just set a high sprite number so we stop processing */
895 			break;
896 		case 0x2: /* jump to position in sprite list*/
897 			/*				logerror ("SPRITELIST: jump at sprite %06x to %06x extra data 0 %04x 1 %04x, 2 %04x 3 %04x 4 %04x 5 %04x 6 %04x 7 %04x\n", spritenum*16, (spritedata_source[0] & 0x1fff)*16, spritedata_source[0] & 0x2000, spritedata_source[1], spritedata_source[2], spritedata_source[3] , spritedata_source[4] , spritedata_source[5] ,spritedata_source[6] , spritedata_source[7] );*/
898 			spritenum = spritedata_source[0] & 0x1fff;
899 			if (spritedata_source[0] & 0x2000) {
900 				jump_y = spritedata_source[1];
901 				jump_x = spritedata_source[2];
902 			}
903 			break;
904 		case 0x1: /* set clipping registers */
905 			/*				logerror ("SPRITELIST: set clip regs at %06x extra data 0 %04x 1 %04x 2 %04x 3 %04x 4 %04x 5 %04x 6 %04x 7 %04x\n", spritenum*16, spritedata_source[0], spritedata_source[1],spritedata_source[2],spritedata_source[3],spritedata_source[4],spritedata_source[5],spritedata_source[6],spritedata_source[7]  );*/
906 			{
907 
908 				if (spritedata_source[0] & 0x3000) /* alien 3 needs something like this ... */
909 				{
910 					clip.min_y = spritedata_source[0]& 0x0fff;
911 					clip.max_y = spritedata_source[1]& 0x0fff;
912 					clip.min_x = spritedata_source[2]& 0x0fff;
913 					clip.max_x = spritedata_source[3]& 0x0fff;
914 
915 					if  (clip.max_y > Machine->visible_area.max_y) clip.max_y = Machine->visible_area.max_y;
916 					if  (clip.max_x > Machine->visible_area.max_x) clip.max_x = Machine->visible_area.max_x;
917 				}
918 				else {
919 					clip.min_x = Machine->visible_area.min_x;
920 					clip.max_x = Machine->visible_area.max_x;
921 					clip.min_y = Machine->visible_area.min_y;
922 					clip.max_y = Machine->visible_area.max_y;
923 				}
924 
925 			}
926 
927 			spritenum ++;
928 			break;
929 		case 0x0: /* draw sprite */
930 			/*				logerror ("SPRITELIST: draw sprite at %06x\n", spritenum*16 );*/
931 			system32_get_sprite_info (bitmap, &clip);
932 			spritenum ++;
933 			break;
934 		}
935 
936 		processed++;
937 		if (processed > 0x20000/16) /* its dead ;-) */
938 		{
939 			/*			logerror ("SPRITELIST: terminated due to infinite loop\n");*/
940 			spritenum = 16384;
941 		};
942 	}
943 }
944 
945 /* 0x31ff00 - 0x31ffff are video registers
946 
947 tile banking is controlled by a register in here as well as a register external to the tilemap chip
948 which is mapped at 0xc0000e
949 
950 	00 | rR-- -b--  ---- ----    |  b = tile bank low bit ( | 0x2000 ), not multi-32  r = screen resolution R also resolution?
951 	02 | ---- ----  ---- dddd    |  d = tilemap disable registers
952 	04 | bbbb bbbb  ???? SsRr       S = layer 3 rowselect enable
953 									s = layer 2 rowselect enable
954 									R = layer 3 rowscroll enable
955 									r = layer 2 rowscroll enable
956 									b = table bases
957 									jpark sets one of the ?
958 	06 |
959 	08 |
960 	0a |
961 	0c |
962 	0e |
963 	10 |
964 	12 | scroll x for tilemap 0
965 	14 |
966 	16 | scroll y for tilemap 0
967 	18 |
968 	1a | scroll x for tilemap 1
969 	1c |
970 	1e | scroll y for tilemap 1
971 	20 |
972 	22 | scroll x for tilemap 2
973 	24 |
974 	26 | scroll y for tilemap 2
975 	28 |
976 	2a | scroll x for tilemap 3
977 	2c |
978 	2e | scroll y for tilemap 3
979 	30 | scroll x offset tilemap 0
980 	32 | scroll y offset tilemap 0
981 	34 | scroll x offset tilemap 1
982 	36 | scroll y offset tilemap 1
983 	38 | scroll x offset tilemap 2
984 	3a | scroll y offset tilemap 2
985 	3c | scroll x offset tilemap 3
986 	3e | scroll y offset tilemap 3
987 	40 | pages 0 + 1 of tilemap 0
988 	42 | pages 2 + 3 of tilemap 0
989 	44 | pages 0 + 1 of tilemap 1
990 	46 | pages 2 + 3 of tilemap 1
991 	48 | pages 0 + 1 of tilemap 2
992 	4a | pages 2 + 3 of tilemap 2
993 	4c | pages 0 + 1 of tilemap 3
994 	4e | pages 2 + 3 of tilemap 4
995 	50 |
996 	52 |
997 	54 |
998 	56 |
999 	58 |
1000 	5a |
1001 	5c |
1002 	5e |
1003 	60 |
1004 	62 |
1005 	64 |
1006 	66 |
1007 	.... etc.. fill the rest in later
1008 
1009 */
1010 
1011 
1012 /* Mixer Registers
1013 
1014 00 ---- ---- ---- pppp  p = Sprite Priority Table
1015 02 ---- ---- ---- pppp  p = Sprite Priority Table
1016 04 ---- ---- ---- pppp  p = Sprite Priority Table
1017 06 ---- ---- ---- pppp  p = Sprite Priority Table
1018 08 ---- ---- ---- pppp  p = Sprite Priority Table
1019 0a ---- ---- ---- pppp  p = Sprite Priority Table
1020 0c ---- ---- ---- pppp  p = Sprite Priority Table
1021 0e ---- ---- ---- pppp  p = Sprite Priority Table
1022 10 ---- ---- ---- pppp  p = Sprite shadow? Priority Table
1023 12 ---- ---- ---- pppp  p = Sprite shadow? Priority Table
1024 14 ---- ---- ---- pppp  p = Sprite shadow? Priority Table
1025 16 ---- ---- ---- pppp  p = Sprite shadow? Priority Table
1026 18 ---- ---- ---- pppp  p = Sprite shadow? Priority Table
1027 1a ---- ---- ---- pppp  p = Sprite shadow? Priority Table
1028 1c ---- ---- ---- pppp  p = Sprite shadow? Priority Table
1029 1e ---- ---- ---- pppp  p = Sprite shadow? Priority Table
1030 20 ---- ---- ssss ssss  s = Mixershift?
1031 22 ---- ssss bbbb pppp  Tilemap Palette Base + Shifting, b = bank, s = shift p = priority 0
1032 24 ---- ssss bbbb pppp  p = priority 1
1033 26 ---- ssss bbbb pppp  p = priority 2
1034 28 ---- ssss bbbb pppp  p = priority 3
1035 2a ---- ---- ---- f---  f = tilemap flip x 0
1036 2c ---- ---- ---- f---  f = tilemap flip x 1
1037 2e ---- ---- ---- f---  f = tilemap flip x 2
1038 30 ---- ---- ---- f---  f = tilemap flip x 3
1039 32 ---e ---- ---e ----  e = alpha enable 0
1040 34 ---e ---- ---e ----  e = alpha enable 1
1041 36 ---e ---- ---e ----  e = alpha enable 2
1042 38 ---e ---- ---e ----  e = alpha enable 3
1043 3a
1044 3c
1045 3e ---- ---- ---- ---w  w = tilemap wrap disable?
1046 40 bbbb bbbb bbbb bbbb  b = brightness (red)
1047 42 bbbb bbbb bbbb bbbb  b = brightness (green)
1048 44 bbbb bbbb bbbb bbbb  b = brightness (blue)
1049 46 bbbb bbbb bbbb bbbb  b = brightness? (layer?) 2?     or r ? (jpark)
1050 48 bbbb bbbb bbbb bbbb  b = brightness? (layer?) 3?     or g ? (jpark)
1051 4a bbbb bbbb bbbb bbbb  b = brightness? (layer?)        or b ? (jpark)
1052 4c ---- ---- ---- --l-   l = number of sprite layers?16:4
1053 4e bbbb bbbb ---- ----   b = alpha blend amount?
1054 
1055 */
1056 
1057 /** AT050703: minor code shufflings*/
system32_draw_text_layer(struct mame_bitmap * bitmap,const struct rectangle * cliprect)1058 void system32_draw_text_layer ( struct mame_bitmap *bitmap, const struct rectangle *cliprect ) /* using this for now to save me tilemap system related headaches */
1059 {
1060 	int x,y;
1061 	int textbank = sys32_videoram[0x01ff5c/2] & 0x0007;
1062 	int tmaddress = (sys32_videoram[0x01ff5c/2] & 0x00f0) >> 4;
1063 
1064 	int monitor_select, monitor_offset;
1065 	struct GfxElement *gfx = Machine->gfx[1];
1066 	struct GfxLayout *gfxlayout = Machine->drv->gfxdecodeinfo[1].gfxlayout;
1067 	data8_t *txtile_gfxregion = memory_region(REGION_GFX3);
1068 	data16_t* tx_tilemapbase = sys32_videoram + ((0x10000+tmaddress*0x1000) /2);
1069 
1070 	if (multi32)
1071 	{
1072 		monitor_select = readinputport(0xf) & 3;
1073 		monitor_offset = system32_screen_mode ? 52*8 : 40*8;
1074 	}
1075 	else
1076 	{
1077 		monitor_select = 1;
1078 		monitor_offset = 0;
1079 	}
1080 
1081 	/* this register is like this
1082 
1083 	 ---- ----  tttt -bbb
1084 
1085 	 t = address of tilemap data (used by dbzvrvs)
1086 	 b = address of tile gfx data (used by radmobile / radrally ingame, jpark)
1087 
1088 	 */
1089 
1090 	for (y = 0; y < 32 ; y++) {
1091 		for (x = 0; x < 64 ; x++) {
1092 			int data=tx_tilemapbase[x+y*64];
1093 			int code = data & 0x01ff;
1094 			int pal = (data>>9) & 0x7f;
1095 			int drawypos, flip;
1096 
1097 			pal += (((system32_mixerregs[0][0x10] & 0xf0) >> 4) * 0x40);
1098 
1099 			code += textbank * 0x200;
1100 
1101 			if (sys32_ramtile_dirty[code]) {
1102 				decodechar(gfx, code, (data8_t*)txtile_gfxregion, gfxlayout);
1103 				sys32_ramtile_dirty[code] = 0;
1104 			}
1105 
1106 			if (system32_temp_kludge != 1) {
1107 				drawypos = y*8;
1108 				flip = 0;
1109 			}
1110 			else /* holoseum, actually probably requires the sprites to be globally flipped + game ROT180 not the tilemap */
1111 			{
1112 				drawypos = 215-y*8;
1113 				flip = 1;
1114 			}
1115 
1116 			if (monitor_select & 1)
1117 				drawgfx(bitmap,gfx,code,pal,0,flip,(x<<3),drawypos,cliprect,TRANSPARENCY_PEN,0);
1118 
1119 			/* Multi32: Draw the same text on Monitor B*/
1120 			if (monitor_select & 2)
1121 				drawgfx(bitmap,gfx,code,pal,0,flip,(x<<3)+monitor_offset,drawypos,cliprect,TRANSPARENCY_PEN,0);
1122 		}
1123 	}
1124 }
1125 
READ16_HANDLER(sys32_videoram_r)1126 READ16_HANDLER ( sys32_videoram_r ) {
1127 	return sys32_videoram[offset];
1128 }
1129 
WRITE16_HANDLER(sys32_videoram_w)1130 WRITE16_HANDLER ( sys32_videoram_w ) {
1131 	data8_t *txtile_gfxregion = memory_region(REGION_GFX3);
1132 
1133 	COMBINE_DATA(&sys32_videoram[offset]);
1134 
1135 
1136 	/* also write it to another region so its easier (imo) to work with the ram based tiles */
1137 	if (ACCESSING_MSB)
1138 		txtile_gfxregion[offset*2+1] = (data & 0xff00) >> 8;
1139 
1140 	if (ACCESSING_LSB)
1141 		txtile_gfxregion[offset*2] = (data & 0x00ff );
1142 
1143 	/* each tile is 0x10 words */
1144 	sys32_ramtile_dirty[offset / 0x10] = 1;
1145 
1146 	system32_dirty_window[offset>>9]=1;
1147 
1148 }
1149 
WRITE16_HANDLER(sys32_spriteram_w)1150 WRITE16_HANDLER ( sys32_spriteram_w ) {
1151 
1152 	COMBINE_DATA(&sys32_spriteram16[offset]);
1153 
1154 	/* also write it to another region so its easier to work with when drawing sprites with RAM based gfx */
1155 	if (ACCESSING_MSB)
1156 		sys32_spriteram8[offset*2+1] = (data & 0xff00) >> 8;
1157 
1158 	if (ACCESSING_LSB)
1159 		sys32_spriteram8[offset*2] = (data & 0x00ff );
1160 }
1161 
1162 /*
1163 
1164 Tilemaps are made of 4 windows
1165 
1166 each window is 32x16 in size
1167 
1168 */
1169 
sys32_bg_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)1170 UINT32 sys32_bg_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ) {
1171 	int page = 0;
1172 	if( row<16 ) { /* top */
1173 		if( col<32 ) page = 0; else page = 1;
1174 	}
1175 	else { /* bottom */
1176 		if( col<32 ) page = 2; else page = 3;
1177 	}
1178 
1179 	return ((col & 31) + (row & 15) * 32) + page * 0x200;
1180 
1181 }
1182 
1183 
1184 static struct tilemap *system32_layer_tilemap[4];
1185 
get_system32_tile_info(int tile_index,int layer)1186 static void get_system32_tile_info ( int tile_index, int layer ) {
1187 	int tileno, s32palette;
1188 	int page;
1189 	int yxflip;
1190 	int monitor=multi32?layer%2:0;
1191 
1192 	page = tile_index >> 9;
1193 
1194 	tileno = sys32_videoram[(tile_index&0x1ff)+system32_windows[layer][page]*0x200];
1195 	s32palette = ((tileno & 0x1ff0) >> (sys32_paletteshift[layer]+4));
1196 	yxflip = (tileno & 0xc000)>>14;
1197 
1198 	tileno &= 0x1fff;
1199 
1200 	if (multi32) {
1201 
1202 		/*
1203 		External tilebank register (0xc0000e)
1204 
1205 		-------- x-------  Tilemap Layer 3 bank += 0x4000
1206 		-------- -x------  Tilemap Layer 3 bank += 0x2000
1207 		-------- --x-----  Tilemap Layer 2 bank += 0x4000
1208 		-------- ---x----  Tilemap Layer 2 bank += 0x2000
1209 		-------- ----x---  Tilemap Layer 1 bank += 0x4000
1210 		-------- -----x--  Tilemap Layer 1 bank += 0x2000
1211 		-------- ------x-  Tilemap Layer 0 bank += 0x4000
1212 		-------- -------x  Tilemap Layer 0 bank += 0x2000
1213 		*/
1214 
1215 		tileno|=(sys32_tilebank_external>>(layer*2)&3)*0x2000;
1216 	}
1217 	else {
1218 		if (sys32_tilebank_internal) tileno |= 0x2000;
1219 		if (sys32_tilebank_external&1) tileno |= 0x4000;
1220 	}
1221 
1222 	/* Multi32: use palette_b for monitor 2*/
1223 	SET_TILE_INFO(0,tileno,sys32_palettebank[layer]+s32palette+(monitor*MAX_COLOURS/0x10),TILE_FLIPYX(yxflip))
1224 }
1225 
get_system32_layer0_tile_info(int tile_index)1226 static void get_system32_layer0_tile_info(int tile_index) {
1227 	get_system32_tile_info(tile_index,0);
1228 }
get_system32_layer1_tile_info(int tile_index)1229 static void get_system32_layer1_tile_info(int tile_index) {
1230 	get_system32_tile_info(tile_index,1);
1231 }
get_system32_layer2_tile_info(int tile_index)1232 static void get_system32_layer2_tile_info(int tile_index) {
1233 	get_system32_tile_info(tile_index,2);
1234 }
get_system32_layer3_tile_info(int tile_index)1235 static void get_system32_layer3_tile_info(int tile_index) {
1236 	get_system32_tile_info(tile_index,3);
1237 }
1238 
VIDEO_START(system32)1239 VIDEO_START( system32 ) {
1240 	int i;
1241 
1242 	system32_layer_tilemap[0] = tilemap_create(get_system32_layer0_tile_info,sys32_bg_map,TILEMAP_TRANSPARENT, 16, 16,64,32);
1243 	tilemap_set_transparent_pen(system32_layer_tilemap[0],0);
1244 	system32_layer_tilemap[1] = tilemap_create(get_system32_layer1_tile_info,sys32_bg_map,TILEMAP_TRANSPARENT, 16, 16,64,32);
1245 	tilemap_set_transparent_pen(system32_layer_tilemap[1],0);
1246 	system32_layer_tilemap[2] = tilemap_create(get_system32_layer2_tile_info,sys32_bg_map,TILEMAP_TRANSPARENT, 16, 16,64,32);
1247 	tilemap_set_transparent_pen(system32_layer_tilemap[2],0);
1248 	system32_layer_tilemap[3] = tilemap_create(get_system32_layer3_tile_info,sys32_bg_map,TILEMAP_TRANSPARENT, 16, 16,64,32);
1249 	tilemap_set_transparent_pen(system32_layer_tilemap[3],0);
1250 
1251 	sys32_spriteram8 = auto_malloc ( 0x20000 ); /* for ram sprites*/
1252 	sys32_videoram = auto_malloc ( 0x20000 );
1253 
1254 	for (i=0; i <= multi32; i++) {
1255 		sys32_old_brightness[i][0] = 0;
1256 		sys32_old_brightness[i][1] = 0;
1257 		sys32_old_brightness[i][2] = 0;
1258 		sys32_brightness[i][0] = 0xff;
1259 		sys32_brightness[i][1] = 0xff;
1260 		sys32_brightness[i][2] = 0xff;
1261 	}
1262 
1263 	for (i = 0; i < 0x100; i++)
1264 		system32_dirty_window[i] = 1;
1265 
1266 	return 0;
1267 }
1268 
1269 void system32_set_colour (int offset);
1270 void multi32_set_colour (int offset, int monitor);
1271 
system32_recalc_palette(int monitor)1272 static void system32_recalc_palette( int monitor ) {
1273 	int i;
1274 	for (i = 0; i < MAX_COLOURS; i++) {
1275 		if (multi32) multi32_set_colour (i,monitor);
1276 		else system32_set_colour(i);
1277 	}
1278 }
1279 
system32_draw_bg_layer(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int layer)1280 void system32_draw_bg_layer ( struct mame_bitmap *bitmap, const struct rectangle *cliprect, int layer ) {
1281 	int trans = 0;
1282 	int alphaamount = 0;
1283 	int rowscroll=0, rowselect=0;
1284 	int monitor = multi32?layer%2:0;
1285 	int monitor_res = 0;
1286 	struct rectangle clip;
1287 
1288 	if ((system32_mixerregs[monitor][(0x32+2*layer)/2] & 0x1010) == 0x1010) {
1289 		trans = TILEMAP_ALPHA;
1290 		alphaamount = 255-((((system32_mixerregs[monitor][0x4e/2])>>8) & 7) <<5); /*umm this is almost certainly wrong*/
1291 		alpha_set_level(alphaamount);
1292 	}
1293 
1294 	/* rowselect / rowscroll
1295 
1296 	outrunners road - works ok
1297 	svf pitch - works ok with tilemap flip / clipping hack
1298 	brival floor - seems ok
1299 	arabfgt floor - seems ok, bit shakey
1300 	rad rally mirror - reasonable but doesn't scroll smoothly
1301 	rad mobile backgrounds - wrong?
1302 	sonic title screen background - ok
1303 
1304 	what effect does alien3 use? zooming instead?
1305 	jurassic park enables rowscroll on one of the levels in the attract but its hard to see what for
1306 
1307 	*/
1308 
1309 	if (layer == 2) {
1310 		rowscroll = (sys32_videoram[0x01FF04/2] & 0x0001);
1311 		rowselect = (sys32_videoram[0x01FF04/2] & 0x0004)>>2;
1312 	}
1313 
1314 	if (layer == 3) {
1315 		rowscroll = (sys32_videoram[0x01FF04/2] & 0x0002)>>1;
1316 		rowselect = (sys32_videoram[0x01FF04/2] & 0x0008)>>3;
1317 	}
1318 
1319 	/* Switch to Machine->visible_area.max_x later*/
1320 	monitor_res=system32_screen_mode?52*8:40*8;
1321 
1322 	if (multi32) {
1323 		/*			clip.min_x = Machine->visible_area.min_x;*/
1324 		/*			clip.max_x = Machine->visible_area.max_x;*/
1325 		clip.min_x = (layer%2)*monitor_res;
1326 		clip.max_x = (layer%2+1)*monitor_res;
1327 		clip.min_y = 0;
1328 		clip.max_y = 28*8;
1329 	}
1330 	else {
1331 		clip.min_x = Machine->visible_area.min_x;
1332 		clip.max_x = Machine->visible_area.max_x;
1333 		clip.min_y = Machine->visible_area.min_y;
1334 		clip.max_y = Machine->visible_area.max_y;
1335 	}
1336 
1337 	if (rowscroll || rowselect) {
1338 		int line;
1339 
1340 		int tableaddress = sys32_videoram[0x01FF04/2]>>8;
1341 
1342 		tableaddress = (tableaddress * 0x200);
1343 
1344 		if ((system32_mixerregs[monitor][(0x32+layer*2)/2]&8)>>3) {
1345 			if (layer==2) tilemap_set_flip(system32_layer_tilemap[layer], TILEMAP_FLIPX);
1346 		}
1347 
1348 		for (line = 0; line < 224;line++) {
1349 			int xscroll = (sys32_videoram[(0x01FF12+8*layer)/2]);
1350 			int yscroll = (sys32_videoram[(0x01FF16+8*layer)/2]);
1351 
1352 			clip.min_y = clip.max_y = line;
1353 
1354 			if (rowscroll) xscroll+=(sys32_videoram[((tableaddress+(layer-2)*0x200)/2)+line]);
1355 			if (rowselect) yscroll+=(sys32_videoram[((tableaddress+0x400+(layer-2)*0x200)/2)+line])-line;
1356 
1357 
1358 			if ((system32_mixerregs[monitor][(0x32+layer*2)/2]&8)>>3) {
1359 				/* disable wrap on this tilemap, should be done on the other too but its less important
1360 				   this is a bit messy because mame has no core functionality for this without resorting
1361 				   to tilemap_draw_roz which I can't do because of RGB_DIRECT, it might be wrong anyway,
1362 				   maybe its using the system32 clipping windows somehow */
1363 				if (layer == 3) {
1364 					int x2;
1365 					x2 =xscroll&0x7ff;
1366 					x2 = 0x7ff-x2;
1367 					if (x2 > 0x3ff) clip.min_x = 0;
1368 					else clip.min_x = x2;
1369 					clip.max_x = 320-1;
1370 				}
1371 			}
1372 			/* Multi32: Shift layer 3's rowscroll left one screen so that it lines up*/
1373 			tilemap_set_scrollx(system32_layer_tilemap[layer],0, (xscroll & 0x3ff));
1374 			tilemap_set_scrolly(system32_layer_tilemap[layer],0, (yscroll & 0x1ff));
1375 			tilemap_set_scrolldx(system32_layer_tilemap[layer], (sys32_videoram[(0x01FF30+layer*4)/2]&0x00ff)+monitor*monitor_res, -(sys32_videoram[(0x01FF30+layer*4)/2]&0x00ff)-monitor*monitor_res);
1376 			tilemap_set_scrolldy(system32_layer_tilemap[layer], sys32_videoram[(0x01FF32+layer*4)/2]&0x00ff, -sys32_videoram[(0x01FF32+layer*4)/2]&0x00ff);
1377 			tilemap_draw(bitmap,&clip,system32_layer_tilemap[layer],trans,0);
1378 		}
1379 	}
1380 	else {
1381 		/* Multi32: Shift layer 3's rowscroll left one screen so that it lines up*/
1382 		tilemap_set_scrollx(system32_layer_tilemap[layer],0,((sys32_videoram[(0x01FF12+8*layer)/2]) & 0x3ff));
1383 		tilemap_set_scrolly(system32_layer_tilemap[layer],0,((sys32_videoram[(0x01FF16+8*layer)/2]) & 0x1ff));
1384 		tilemap_set_scrolldx(system32_layer_tilemap[layer], (sys32_videoram[(0x01FF30+layer*4)/2]&0x00ff)+monitor*monitor_res, -(sys32_videoram[(0x01FF30+layer*4)/2]&0x00ff)-monitor*monitor_res);
1385 		tilemap_set_scrolldy(system32_layer_tilemap[layer], sys32_videoram[(0x01FF32+layer*4)/2]&0x00ff, -sys32_videoram[(0x01FF32+layer*4)/2]&0x00ff);
1386 		tilemap_draw(bitmap,&clip,system32_layer_tilemap[layer],trans,0);
1387 	}
1388 }
1389 
VIDEO_UPDATE(system32)1390 VIDEO_UPDATE( system32 ) {
1391 	int i;
1392 
1393 	int monitor_setting;
1394 	int monitor_display_start;
1395 	int monitor_display_width;
1396 	int monitor_vertical_offset;
1397 
1398 	int sys32_tmap_disabled = sys32_videoram[0x1FF02/2] & 0x000f;
1399 
1400 	int priority0 = (system32_mixerregs[0][0x22/2] & 0x000f);
1401 	int priority1 = (system32_mixerregs[multi32][0x24/2] & 0x000f);
1402 	int priority2 = (system32_mixerregs[0][0x26/2] & 0x000f);
1403 	int priority3 = (system32_mixerregs[multi32][0x28/2] & 0x000f);
1404 	int sys32_palette_dirty[2] = {0, 0};
1405 
1406 	/* -------------------------------------- experimental wip code --------------------------------*/
1407 	int tm,ii;
1408 
1409 	#if NEW_DRAWSPRITE
1410 		/** force IDP recache*/
1411 		sys32mon_old8 = sys32mon_old4 = -1;
1412 	#endif
1413 
1414 	/* if the windows number used by a tilemap use change then that window of the tilemap needs to be considered dirty*/
1415 	for (tm = 0; tm < 4; tm++) {
1416 		system32_windows[tm][0] = (sys32_videoram[(0x01FF40+4*tm)/2] & 0x007f);
1417 		system32_windows[tm][1] = (sys32_videoram[(0x01FF40+4*tm)/2] & 0x7f00)>>8;
1418 		system32_windows[tm][2] = (sys32_videoram[(0x01FF42+4*tm)/2] & 0x007f);
1419 		system32_windows[tm][3] = (sys32_videoram[(0x01FF42+4*tm)/2] & 0x7f00)>>8;
1420 
1421 		if (system32_windows[tm][0] != system32_old_windows[tm][0]) {
1422 			for (ii = 0x000 ; ii < 0x200 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1423 		}
1424 		if (system32_windows[tm][1] != system32_old_windows[tm][1]) {
1425 			for (ii = 0x200 ; ii < 0x400 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1426 		}
1427 		if (system32_windows[tm][2] != system32_old_windows[tm][2]) {
1428 			for (ii = 0x400 ; ii < 0x600 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1429 		}
1430 		if (system32_windows[tm][3] != system32_old_windows[tm][3]) {
1431 			for (ii = 0x600 ; ii < 0x800 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1432 		}
1433 
1434 		/* if the actual windows are dirty we also need to mark them dirty in the tilemap*/
1435 		if (system32_dirty_window [ system32_windows[tm][0] ]) {
1436 			for (ii = 0x000 ; ii < 0x200 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1437 		}
1438 		if (system32_dirty_window [ system32_windows[tm][1] ]) {
1439 			for (ii = 0x200 ; ii < 0x400 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1440 		}
1441 		if (system32_dirty_window [ system32_windows[tm][2] ]) {
1442 			for (ii = 0x400 ; ii < 0x600 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1443 		}
1444 		if (system32_dirty_window [ system32_windows[tm][3] ]) {
1445 			for (ii = 0x600 ; ii < 0x800 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1446 		}
1447 
1448 		system32_old_windows[tm][0] = system32_windows[tm][0];
1449 		system32_old_windows[tm][1] = system32_windows[tm][1];
1450 		system32_old_windows[tm][2] = system32_windows[tm][2];
1451 		system32_old_windows[tm][3] = system32_windows[tm][3];
1452 	}
1453 
1454 	/* we can clean the dirty window markers now*/
1455 	for (ii = 0; ii < 0x100; ii++)
1456 		system32_dirty_window[ii] = 0;
1457 
1458 	/* if the internal tilebank changed everything is dirty*/
1459 	sys32_tilebank_internal = sys32_videoram[0x01FF00/2] & 0x0400;
1460 	if (sys32_tilebank_internal != sys32_old_tilebank_internal) {
1461 		tilemap_mark_all_tiles_dirty(system32_layer_tilemap[0]);
1462 		tilemap_mark_all_tiles_dirty(system32_layer_tilemap[1]);
1463 		tilemap_mark_all_tiles_dirty(system32_layer_tilemap[2]);
1464 		tilemap_mark_all_tiles_dirty(system32_layer_tilemap[3]);
1465 	}
1466 	sys32_old_tilebank_internal = sys32_tilebank_internal;
1467 
1468 	/* if the external tilebank changed everything is dirty*/
1469 
1470 	if  ( (sys32_tilebank_external) != sys32_old_tilebank_external ) {
1471 		tilemap_mark_all_tiles_dirty(system32_layer_tilemap[0]);
1472 		tilemap_mark_all_tiles_dirty(system32_layer_tilemap[1]);
1473 		tilemap_mark_all_tiles_dirty(system32_layer_tilemap[2]);
1474 		tilemap_mark_all_tiles_dirty(system32_layer_tilemap[3]);
1475 	}
1476 	sys32_old_tilebank_external = sys32_tilebank_external;
1477 
1478 	/* if the palette shift /bank registers changed the tilemap is dirty, not sure these are regs 100% correct some odd colours in sonic / jpark*/
1479 	for (tm = 0; tm < 4; tm++) {
1480 		int monitor=multi32?tm%2:0;
1481 		sys32_paletteshift[tm] = (system32_mixerregs[monitor][(0x22+tm*2)/2] & 0x0f00)>>8;
1482 		if (sys32_paletteshift[tm] != sys32_old_paletteshift[tm]) {
1483 			tilemap_mark_all_tiles_dirty(system32_layer_tilemap[tm]);
1484 			sys32_old_paletteshift[tm] = sys32_paletteshift[tm];
1485 		}
1486 
1487 		sys32_palettebank[tm] = ((system32_mixerregs[monitor][(0x22+tm*2)/2] & 0x00f0)>>4)*0x40;
1488 		if (sys32_palettebank[tm] != sys32_old_palettebank[tm]) {
1489 			tilemap_mark_all_tiles_dirty(system32_layer_tilemap[tm]);
1490 			sys32_old_palettebank[tm] = sys32_palettebank[tm];
1491 		}
1492 	}
1493 	/*---------------------------------------- end wip code -----------------------------------------------*/
1494 
1495 	/* palette dirty check */
1496 
1497 	for (i=0; i <= multi32; i++) {
1498 		sys32_brightness[i][0] = (system32_mixerregs[i][0x40/2]);
1499 		sys32_brightness[i][1] = (system32_mixerregs[i][0x42/2]);
1500 		sys32_brightness[i][2] = (system32_mixerregs[i][0x44/2]);
1501 
1502 		if (sys32_brightness[i][0] != sys32_old_brightness[i][0]) {
1503 			sys32_old_brightness[i][0] = sys32_brightness[i][0]; sys32_palette_dirty[i] = 1;
1504 		}
1505 		if (sys32_brightness[i][1] != sys32_old_brightness[i][1]) {
1506 			sys32_old_brightness[i][1] = sys32_brightness[i][1]; sys32_palette_dirty[i] = 1;
1507 		}
1508 		if (sys32_brightness[i][2] != sys32_old_brightness[i][2]) {
1509 			sys32_old_brightness[i][2] = sys32_brightness[i][2]; sys32_palette_dirty[i] = 1;
1510 		}
1511 
1512 		if (sys32_palette_dirty[i]) {
1513 			sys32_palette_dirty[i] = 0;
1514 			system32_recalc_palette(i);
1515 		}
1516 	}
1517 
1518 	/* end palette dirty*/
1519 
1520 	system32_screen_mode = sys32_videoram[0x01FF00/2] & 0xc000;  /* this should be 0x8000 according to modeler but then brival is broken?  this way alien3 and arabfgt try to change when they shouldn't .. wrong register?*/
1521 
1522 	if (multi32) {
1523 		monitor_setting=readinputport(0xf);
1524 		monitor_vertical_offset=1;
1525 		monitor_display_start=0;
1526 		if (monitor_setting==2) monitor_display_start=1;
1527 		if (monitor_setting==3) {
1528 			monitor_vertical_offset=2;
1529 			monitor_display_width=2;
1530 		}
1531 		else
1532 			monitor_display_width=1+monitor_display_start;
1533 	}
1534 	else {
1535 		monitor_display_start=0;
1536 		monitor_display_width=1;
1537 		monitor_vertical_offset=1;
1538 	}
1539 
1540 	fillbitmap(bitmap, 0, 0);
1541 
1542 	if (system32_screen_mode && system32_allow_high_resolution) {
1543 		set_visible_area(52*monitor_display_start*8, 52*8*monitor_display_width-1, 0, 28*8*monitor_vertical_offset-1);
1544 	}
1545 	else {
1546 		set_visible_area(40*monitor_display_start*8, 40*8*monitor_display_width-1, 0, 28*8*monitor_vertical_offset-1);
1547 	}
1548 
1549 	fillbitmap(bitmap, 0, 0);
1550 
1551 	/* Priority loop.  Draw layers 1 and 3 on Multi32's Monitor B*/
1552 	if (sys32_displayenable & 0x0002) {
1553 		for (priloop=0; priloop < 0x10; priloop++) {
1554 			if (priloop == priority0 && (!multi32 || (multi32 && (readinputport(0xf)&1)))) {
1555 				if (!(sys32_tmap_disabled & 0x1)) system32_draw_bg_layer (bitmap,cliprect,0);
1556 			}
1557 			if (priloop == priority1 && (!multi32 || (multi32 && (readinputport(0xf)&2)>>1))) {
1558 				if (!(sys32_tmap_disabled & 0x2)) system32_draw_bg_layer (bitmap,cliprect,1);
1559 			}
1560 			if (priloop == priority2 && (!multi32 || (multi32 && (readinputport(0xf)&1)))) {
1561 				if (!(sys32_tmap_disabled & 0x4)) system32_draw_bg_layer (bitmap,cliprect,2);
1562 			}
1563 			if (priloop == priority3 && (!multi32 || (multi32 && (readinputport(0xf)&2)>>1))) {
1564 				if (!(sys32_tmap_disabled & 0x8)) system32_draw_bg_layer (bitmap,cliprect,3);
1565 			}
1566 			system32_process_spritelist (bitmap, cliprect);
1567 		}
1568 	}
1569 	system32_draw_text_layer (bitmap, cliprect);
1570 }
1571