1 // Based on MAME sources by Nicola Salmoria
2 
3 #include "tiles_generic.h"
4 #include "taito_ic.h"
5 #include "taito.h"
6 
7 UINT8 *TC0180VCURAM;
8 UINT8 *TC0180VCUScrollRAM;
9 UINT8 *TC0180VCUFbRAM; // framebuffer ram
10 
11 static UINT16 *TC0180VCUFramebuffer[2];
12 
13 static INT32 TC0180VCU_y_offset;
14 static INT32 TC0180VCU_x_offset;
15 
16 static UINT8 TC0180VCUControl[0x10];
17 
18 static UINT8 *tiledata[2];
19 static UINT32 tilemask[2];
20 static UINT8 *transtiletab[2];
21 
22 static UINT8 *dummy_tile = NULL;
23 
24 static INT32 *TC0180VCU_scrollx[2];
25 static INT32 *TC0180VCU_scrolly[2];
26 
27 static INT32 flipscreen;
28 static INT32 framebuffer_page;
29 
TC0180VCUFramebufferWrite(INT32 offset)30 void TC0180VCUFramebufferWrite(INT32 offset)
31 {
32 	offset &= 0x3fffe;
33 	INT32 data = *((UINT16*)(TC0180VCUFbRAM + offset));
34 
35 	INT32 fb = (offset >> 17) & 1;
36 
37 	offset &= 0x1fffe;
38 
39 	TC0180VCUFramebuffer[fb][offset + 0] = data >> 8;
40 	TC0180VCUFramebuffer[fb][offset + 1] = data & 0xff;
41 }
42 
TC0180VCUFramebufferRead(INT32 offset)43 UINT16 TC0180VCUFramebufferRead(INT32 offset)
44 {
45 	offset &= 0x3fffe;
46 
47 	INT32 fb = (offset >> 17) & 1;
48 
49 	offset &= 0x1fffe;
50 
51 	return (TC0180VCUFramebuffer[fb][offset + 0] << 8) | (TC0180VCUFramebuffer[fb][offset + 1] & 0xff);
52 }
53 
TC0180VCUReadControl()54 UINT8 TC0180VCUReadControl()
55 {
56 	return TC0180VCUControl[7];
57 }
58 
TC0180VCUReadRegs(INT32 offset)59 UINT8 TC0180VCUReadRegs(INT32 offset)
60 {
61 	offset >>= 1;
62 	offset &= 0x0f;
63 
64 	return TC0180VCUControl[offset];
65 }
66 
TC0180VCUWriteRegs(INT32 offset,INT32 data)67 void TC0180VCUWriteRegs(INT32 offset, INT32 data)
68 {
69 	offset >>= 1;
70 	offset &= 0x0f;
71 
72 	TC0180VCUControl[offset] = data;
73 
74 	if (offset == 7) {
75 		if (data & 0x80) {
76 			framebuffer_page = (data & 0x40) ? 0 : 1;
77 		}
78 	}
79 }
80 
TC0180VCUReset()81 void TC0180VCUReset()
82 {
83 	for (INT32 i = 0; i < 2; i++) {
84 
85 		memset (TC0180VCUFramebuffer[i], 0, 512 * 256 * sizeof(UINT16));
86 		memset (TC0180VCU_scrollx[i], 0, 256 * sizeof(INT32));
87 		memset (TC0180VCU_scrolly[i], 0, 256 * sizeof(INT32));
88 	}
89 
90 	memset (TC0180VCUControl, 	0, 16);
91 	memset (TC0180VCURAM,		0, 0x010000);
92 	memset (TC0180VCUScrollRAM,	0, 0x000800);
93 	memset (TC0180VCUFbRAM,		0, 0x040000);
94 
95 	flipscreen = 0;
96 	framebuffer_page = 0;
97 }
98 
create_transtile_table(INT32 tile)99 static void create_transtile_table(INT32 tile)
100 {
101 	INT32 size = (tile) ? (16 * 16) : (8 * 8);
102 
103 	if (tilemask[tile]) {
104 		INT32 len = (tilemask[tile] + 1);
105 
106 		transtiletab[tile] = (UINT8*)BurnMalloc(len);
107 
108 		memset (transtiletab[tile], 1, len);
109 
110 		for (INT32 i = 0; i < len * size; i++)
111 		{
112 			if (tiledata[tile][i]) {
113 				transtiletab[tile][i / size] = 0;
114 				i|=(size-1);
115 			}
116 		}
117 	}
118 }
119 
TC0180VCUInit(UINT8 * gfx0,INT32 mask0,UINT8 * gfx1,INT32 mask1,INT32 global_x,INT32 global_y)120 void TC0180VCUInit(UINT8 *gfx0, INT32 mask0, UINT8 *gfx1, INT32 mask1, INT32 global_x, INT32 global_y)
121 {
122 	TaitoIC_TC0180VCUInUse = 1;
123 
124 	for (INT32 i = 0; i < 2; i++)
125 	{
126 		TC0180VCUFramebuffer[i] = (UINT16*)BurnMalloc(512 * 256 * sizeof(UINT16));
127 		TC0180VCU_scrollx[i] = (INT32*)BurnMalloc(257 * sizeof(INT32));
128 		TC0180VCU_scrolly[i] = (INT32*)BurnMalloc(257 * sizeof(INT32));
129 	}
130 
131 	TC0180VCURAM		= (UINT8*)BurnMalloc(0x010000);
132 	TC0180VCUScrollRAM	= (UINT8*)BurnMalloc(0x000800);
133 	TC0180VCUFbRAM		= (UINT8*)BurnMalloc(0x040000);
134 
135 	tilemask[0] = mask0;
136 	tilemask[1] = mask1;
137 	tiledata[0] = gfx0;
138 	tiledata[1] = gfx1;
139 
140 	if (mask0) create_transtile_table(0);
141 	if (mask1) create_transtile_table(1);
142 
143 	if (mask0 == 0) {
144 		dummy_tile = (UINT8*)BurnMalloc(0x100);
145 		transtiletab[1] = (UINT8*)BurnMalloc(1);
146 		tiledata[1] = dummy_tile;
147 	}
148 
149 	TC0180VCU_y_offset = global_y;
150 	TC0180VCU_x_offset = global_x;
151 
152 	TC0180VCUReset();
153 }
154 
TC0180VCUExit()155 void TC0180VCUExit()
156 {
157 	for (INT32 i = 0; i < 2; i++)
158 	{
159 		BurnFree (TC0180VCU_scrollx[i]);
160 		BurnFree (TC0180VCU_scrolly[i]);
161 
162 		tilemask[i] = ~0;
163 		tiledata[i] = NULL;
164 
165 		BurnFree (TC0180VCUFramebuffer[i]);
166 		BurnFree (transtiletab[i]);
167 	}
168 
169 	BurnFree (dummy_tile);
170 	BurnFree (TC0180VCURAM);
171 	BurnFree (TC0180VCUScrollRAM);
172 	BurnFree (TC0180VCUFbRAM);
173 
174 	TC0180VCU_y_offset = 0;
175 	TC0180VCU_x_offset = 0;
176 }
177 
update_scroll(INT32 plane)178 static void update_scroll(INT32 plane)
179 {
180 	flipscreen = TC0180VCUReadControl() & 0x10;
181 
182 	UINT16 *scrollram = (UINT16*)TC0180VCUScrollRAM;
183 
184 	INT32 lines_per_block = 256 - TC0180VCUControl[2 + plane];
185 	INT32 number_of_blocks = 256 / lines_per_block;
186 
187 	for (INT32 i = 0; i < number_of_blocks; i++)
188 	{
189 		INT32 scrollx = BURN_ENDIAN_SWAP_INT16(scrollram[plane * 0x200 + i * 2 * lines_per_block + 0]);
190 		INT32 scrolly = BURN_ENDIAN_SWAP_INT16(scrollram[plane * 0x200 + i * 2 * lines_per_block + 1]);
191 
192 		INT32 min_y = (i + 0) * lines_per_block - 0;
193 		INT32 max_y = (i + 1) * lines_per_block - 1;
194 
195 		if (min_y <= max_y)
196 		{
197 			for (INT32 y = min_y; y <= max_y; y++) {
198 				TC0180VCU_scrollx[plane][y] = -(scrollx & 0x3ff);
199 				TC0180VCU_scrolly[plane][y] = -(scrolly & 0x3ff);
200 			}
201 		}
202 	}
203 }
204 
TC0180VCUDrawLayer(INT32 colorbase,INT32 ctrl_offset,INT32 transparent)205 void TC0180VCUDrawLayer(INT32 colorbase, INT32 ctrl_offset, INT32 transparent) // 0, -1
206 {
207 	update_scroll(ctrl_offset);
208 
209 	UINT16 *ram = (UINT16*)TC0180VCURAM;
210 
211 	INT32 bank0 = (TC0180VCUControl[ctrl_offset] << 12) & 0xf000; // tile bank
212 	INT32 bank1 = (TC0180VCUControl[ctrl_offset] <<  8) & 0xf000; // color bank
213 
214 	INT32 *scroll_x = TC0180VCU_scrollx[ctrl_offset];
215 	INT32 *scroll_y = TC0180VCU_scrolly[ctrl_offset];
216 
217 	INT32 lines = TC0180VCUControl[2 + ctrl_offset];
218 
219 	if (lines)
220 	{
221 		INT32 screen_width = nScreenWidth - 1;
222 		INT32 screen_height = nScreenHeight - 1;
223 
224 		UINT16 *dest;
225 
226 		for (INT32 sy = 0; sy < nScreenHeight; sy++)
227 		{
228 			if (flipscreen) {
229 				dest = pTransDraw + (screen_height - sy) * nScreenWidth;
230 			} else {
231 				dest = pTransDraw + sy * nScreenWidth;
232 			}
233 
234 			INT32 scly = (sy + scroll_y[(sy + TC0180VCU_y_offset) & 0xff] + TC0180VCU_y_offset) & 0x3ff;
235 
236 			INT32 scly_off = (scly >> 4) << 6;
237 			INT32 scly_ts  = (scly & 0x0f) << 4;
238 
239 			INT32 sclx_base = scroll_x[(sy + TC0180VCU_y_offset) & 0xff] + TC0180VCU_x_offset;
240 
241 			for (INT32 sx = 0; sx < nScreenWidth + 16; sx+=16)
242 			{
243 				INT32 sclx = (sx + sclx_base) & 0x3ff;
244 
245 				INT32 offs = scly_off | (sclx >> 4);
246 
247 				INT32 attr = BURN_ENDIAN_SWAP_INT16(ram[offs + bank1]);
248 				INT32 code = BURN_ENDIAN_SWAP_INT16(ram[offs + bank0]);
249 				INT32 color = (attr & 0x003f) + colorbase;
250 				code &= tilemask[1];
251 
252 				if (!transparent) {
253 					if (transtiletab[1][code]) continue;
254 				}
255 
256 				{
257 					INT32 sx4 = sx - (sclx & 0x0f);
258 
259 					color <<= 4;
260 					UINT8 *src = tiledata[1] + code * 256;
261 
262 					if (attr & 0x80) {			// flipy
263 						src += (scly_ts ^ 0xf0);
264 					} else {
265 						src += (scly_ts);
266 					}
267 
268 					INT32 flipx = ((attr & 0x40) >> 6) * 0x0f;
269 
270 					if (flipscreen) {
271 						if (!transparent) { // transparency
272 							for (INT32 sxx = 0; sxx < 16; sxx++, sx4++) {
273 								if (sx4 >= nScreenWidth || sx4 < 0) continue;
274 
275 								INT32 pxl = src[sxx ^ flipx];
276 
277 								if (pxl != transparent) {
278 									dest[(screen_width - sx4)] = pxl | color;
279 								}
280 							}
281 						} else {
282 							for (INT32 sxx = 0; sxx < 16; sxx++, sx4++) {
283 								if (sx4 >= nScreenWidth || sx4 < 0) continue;
284 
285 								dest[(screen_width - sx4)] = src[sxx ^ flipx] | color;
286 							}
287 						}
288 					} else {
289 						if (!transparent) { // transparency
290 							for (INT32 sxx = 0; sxx < 16; sxx++, sx4++) {
291 								if (sx4 >= nScreenWidth || sx4 < 0) continue;
292 
293 								INT32 pxl = src[sxx ^ flipx];
294 
295 								if (pxl != transparent) {
296 									dest[sx4] = pxl | color;
297 								}
298 							}
299 						} else {
300 							for (INT32 sxx = 0; sxx < 16; sxx++, sx4++) {
301 								if (sx4 >= nScreenWidth || sx4 < 0) continue;
302 
303 								dest[sx4] = src[sxx ^ flipx] | color;
304 							}
305 						}
306 					}
307 				}
308 			}
309 		}
310 	}
311 	else
312 	{
313 		for (INT32 offs = 0; offs < 64 * 64; offs++)
314 		{
315 			INT32 sx = (offs & 0x3f) << 4;
316 			INT32 sy = (offs >> 6) << 4;
317 
318 			sy -= scroll_y[(sy + TC0180VCU_y_offset) & 0xff];
319 			if (sy >= 0x400-15) sy -= 0x400;
320 
321 			sx -= scroll_x[(sy + TC0180VCU_y_offset) & 0xff];
322 			if (sx >= 0x400-15) sx -= 0x400;
323 
324 			INT32 attr  = BURN_ENDIAN_SWAP_INT16(ram[offs + bank1]);
325 			INT32 code  = BURN_ENDIAN_SWAP_INT16(ram[offs + bank0]);
326 
327 			INT32 color = (attr & 0x003f) + colorbase;
328 			INT32 flipx = (attr & 0x0040);
329 			INT32 flipy = (attr & 0x0080);
330 
331 			code &= tilemask[1];
332 
333 			if (flipscreen) {
334 				sx = (nScreenWidth - 16) - sx;
335 				sy = 240 - sy;
336 				flipx ^= 0x40;
337 				flipy ^= 0x80;
338 			}
339 
340 			sx -= TC0180VCU_x_offset;
341 			sy -= TC0180VCU_y_offset;
342 
343 			if (!transparent) {
344 				if (transtiletab[1][code]) continue;
345 
346 				if (sy >= 0 && sy < (nScreenHeight - 15) && sx >= 0 && sx < (nScreenWidth - 15)) {
347 					if (flipy) {
348 						if (flipx) {
349 							Render16x16Tile_Mask_FlipXY(pTransDraw, code, sx, sy, color, 4, 0, 0, tiledata[1]);
350 						} else {
351 							Render16x16Tile_Mask_FlipY(pTransDraw, code, sx, sy, color, 4, 0, 0, tiledata[1]);
352 						}
353 					} else {
354 						if (flipx) {
355 							Render16x16Tile_Mask_FlipX(pTransDraw, code, sx, sy, color, 4, 0, 0, tiledata[1]);
356 						} else {
357 							Render16x16Tile_Mask(pTransDraw, code, sx, sy, color, 4, 0, 0, tiledata[1]);
358 						}
359 					}
360 				} else {
361 					if (flipy) {
362 						if (flipx) {
363 							Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, tiledata[1]);
364 						} else {
365 							Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, tiledata[1]);
366 						}
367 					} else {
368 						if (flipx) {
369 							Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, tiledata[1]);
370 						} else {
371 							Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, tiledata[1]);
372 						}
373 					}
374 				}
375 			} else {
376 				if (sy >= 0 && sy < (nScreenHeight - 15) && sx >= 0 && sx < (nScreenWidth - 15)) {
377 					if (flipy) {
378 						if (flipx) {
379 							Render16x16Tile_FlipXY(pTransDraw, code, sx, sy, color, 4, 0, tiledata[1]);
380 						} else {
381 							Render16x16Tile_FlipY(pTransDraw, code, sx, sy, color, 4, 0, tiledata[1]);
382 						}
383 					} else {
384 						if (flipx) {
385 							Render16x16Tile_FlipX(pTransDraw, code, sx, sy, color, 4, 0, tiledata[1]);
386 						} else {
387 							Render16x16Tile(pTransDraw, code, sx, sy, color, 4, 0, tiledata[1]);
388 						}
389 					}
390 				} else {
391 					if (flipy) {
392 						if (flipx) {
393 							Render16x16Tile_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, tiledata[1]);
394 						} else {
395 							Render16x16Tile_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, tiledata[1]);
396 						}
397 					} else {
398 						if (flipx) {
399 							Render16x16Tile_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, tiledata[1]);
400 						} else {
401 							Render16x16Tile_Clip(pTransDraw, code, sx, sy, color, 4, 0, tiledata[1]);
402 						}
403 					}
404 				}
405 			}
406 		}
407 	}
408 }
409 
TC0180VCUDrawCharLayer(INT32 colorbase)410 void TC0180VCUDrawCharLayer(INT32 colorbase)
411 {
412 	if (tilemask[0] == 0) return;
413 
414 	UINT16 *ram = (UINT16*)TC0180VCURAM;
415 
416 	INT32 bank0 = (TC0180VCUControl[6] & 0x0f) << 11; // tile bank
417 
418 	for (INT32 offs = 0; offs < 64 * 32; offs++)
419 	{
420 		INT32 sx = (offs & 0x3f) << 3;
421 		INT32 sy = (offs >> 6) << 3;
422 
423 		INT32 code  = BURN_ENDIAN_SWAP_INT16(ram[offs + bank0]);
424 		INT32 color = (code >> 12) + colorbase;
425 
426 		code = (code & 0x07ff) | (TC0180VCUControl[4 + ((code & 0x800) >> 11)] << 11);
427 
428 		code &= tilemask[0];
429 
430 		if (transtiletab[0][code]) continue;
431 
432 		if (flipscreen) {
433 			sx = (nScreenWidth - 8) - sx;
434 			sy = 248 - sy;
435 
436 			Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code, sx - TC0180VCU_x_offset, sy - TC0180VCU_y_offset, color, 4, 0, 0, tiledata[0]);
437 		} else {
438 			Render8x8Tile_Mask_Clip(pTransDraw, code, sx - TC0180VCU_x_offset, sy - TC0180VCU_y_offset, color, 4, 0, 0, tiledata[0]);
439 		}
440 	}
441 }
442 
TC0180VCUFramebufferDraw(INT32 priority,INT32 color_base)443 void TC0180VCUFramebufferDraw(INT32 priority, INT32 color_base)
444 {
445 	priority <<= 4;
446 
447 	INT32 ctrl = TC0180VCUReadControl();
448 
449 	if (ctrl & 0x08)
450 	{
451 		if (ctrl & 0x10)	// flip screen
452 		{
453 			for (INT32 y = 0; y < nScreenHeight; y++)
454 			{
455 				UINT16 *src = TC0180VCUFramebuffer[framebuffer_page & 1] + (y + TC0180VCU_y_offset) * 512 + TC0180VCU_x_offset;
456 				UINT16 *dst = pTransDraw + ((nScreenHeight - 1) - y) * nScreenWidth + (nScreenWidth - 1);
457 
458 				for (INT32 x = 0; x < nScreenWidth; x++)
459 				{
460 					INT32 c = *src++;
461 
462 					if (c != 0) *dst = color_base + c;
463 					dst--;
464 				}
465 			}
466 		}
467 		else
468 		{
469 			for (INT32 y = 0; y < nScreenHeight; y++)
470 			{
471 				UINT16 *src = TC0180VCUFramebuffer[framebuffer_page & 1] + (y + TC0180VCU_y_offset) * 512 + TC0180VCU_x_offset;
472 				UINT16 *dst = pTransDraw + y * nScreenWidth;
473 
474 				for (INT32 x = 0; x < nScreenWidth; x++)
475 				{
476 					INT32 c = *src++;
477 
478 					if (c != 0) *dst = color_base + c;
479 					dst++;
480 				}
481 			}
482 		}
483 	}
484 	else
485 	{
486 		if (ctrl & 0x10)   // flip screen
487 		{
488 			for (INT32 y = 0; y < nScreenHeight; y++)
489 			{
490 				UINT16 *src = TC0180VCUFramebuffer[framebuffer_page & 1] + (y + TC0180VCU_y_offset) * 512 + TC0180VCU_x_offset;
491 				UINT16 *dst = pTransDraw + ((nScreenHeight - 1) - y) * nScreenWidth + (nScreenWidth - 1);
492 
493 				for (INT32 x = 0; x < nScreenWidth; x++)
494 				{
495 					INT32 c = *src++;
496 
497 					if (c != 0 && (c & 0x10) == priority)
498 						*dst = color_base + c;
499 					dst--;
500 				}
501 			}
502 		}
503     		else
504 		{
505 			for (INT32 y = 0; y < nScreenHeight; y++)
506 			{
507 				UINT16 *src = TC0180VCUFramebuffer[framebuffer_page & 1] + (y + TC0180VCU_y_offset) * 512 + TC0180VCU_x_offset;
508 				UINT16 *dst = pTransDraw + y * nScreenWidth;
509 
510 				for (INT32 x = 0; x < nScreenWidth; x++)
511 				{
512 					INT32 c = *src++;
513 
514 					if (c != 0 && (c & 0x10) == priority)
515 						*dst = color_base + c;
516 					dst++;
517 				}
518 			}
519 		}
520 	}
521 }
522 
TC0180VCUDrawSprite(UINT16 * dest)523 void TC0180VCUDrawSprite(UINT16 *dest)
524 {
525 	//INT32 t_swide = nScreenWidth;  nScreenWidth = 512; // hack to allow use of generic tile routines
526 	//INT32 t_shigh = nScreenHeight; nScreenHeight = 256;
527 	// The above method can no longer be used, instead, use this below:  (Keep for reference!)
528 
529 	GenericTilesSetClipRaw(0, 512, 0, 256);
530 
531 	INT32 xlatch = 0;
532 	INT32 ylatch = 0;
533 	INT32 x_no = 0;
534 	INT32 y_no = 0;
535 	INT32 x_num = 0;
536 	INT32 y_num = 0;
537 	INT32 big_sprite = 0;
538 	UINT32 zoomx;
539 	UINT32 zoomy;
540 	UINT32 zx;
541 	UINT32 zy;
542 	UINT32 zoomxlatch = 0;
543 	UINT32 zoomylatch = 0;
544 
545 	UINT16 *ram = (UINT16*)TaitoSpriteRam;
546 
547 	for (INT32 offs = (0x1980 - 16) / 2; offs >=0; offs -= 8)
548 	{
549 		INT32 code  = BURN_ENDIAN_SWAP_INT16(ram[offs + 0]) & tilemask[1];
550 		INT32 color = BURN_ENDIAN_SWAP_INT16(ram[offs + 1]);
551 		INT32 x     = BURN_ENDIAN_SWAP_INT16(ram[offs + 2]) & 0x03ff;
552 		INT32 y     = BURN_ENDIAN_SWAP_INT16(ram[offs + 3]) & 0x03ff;
553 
554 		INT32 data  = BURN_ENDIAN_SWAP_INT16(ram[offs + 5]);
555 
556 		INT32 flipx = color & 0x4000;
557 		INT32 flipy = color & 0x8000;
558 
559 		if (x >= 0x200) x -= 0x400;
560 		if (y >= 0x200) y -= 0x400;
561 
562 		if (data)
563 		{
564 			if (!big_sprite)
565 			{
566 				x_num  = (data >> 8) & 0xff;
567 				y_num  = (data >> 0) & 0xff;
568 				x_no   = 0;
569 				y_no   = 0;
570 				xlatch = x;
571 				ylatch = y;
572 				data   = BURN_ENDIAN_SWAP_INT16(ram[offs + 4]);
573 				zoomxlatch = (data >> 8) & 0xff;
574 				zoomylatch = (data >> 0) & 0xff;
575 				big_sprite = 1;
576 			}
577 		}
578 
579 		data = BURN_ENDIAN_SWAP_INT16(ram[offs + 4]);
580 		zoomx = (data >> 8) & 0xff;
581 		zoomy = (data >> 0) & 0xff;
582 		zx = (0x100 - zoomx) / 16;
583 		zy = (0x100 - zoomy) / 16;
584 
585 		if (big_sprite)
586 		{
587 			zoomx = zoomxlatch;
588 			zoomy = zoomylatch;
589 
590 			x = xlatch + x_no * (0x100 - zoomx) / 16;
591 			y = ylatch + y_no * (0x100 - zoomy) / 16;
592 			zx = xlatch + (x_no + 1) * (0x100 - zoomx) / 16 - x;
593 			zy = ylatch + (y_no + 1) * (0x100 - zoomy) / 16 - y;
594 			y_no++;
595 
596 			if (y_no > y_num)
597 			{
598 				y_no = 0;
599 				x_no++;
600 
601 				if (x_no > x_num) big_sprite = 0;
602 			}
603 		}
604 
605 		if (zoomx || zoomy )
606 		{
607 			RenderZoomedTile(dest, tiledata[1], code, (color & 0x3f) << 4, 0, x, y, flipx, flipy, 16, 16, zx << 12, zy << 12);
608 		}
609 		else
610 		{
611 			if (flipy) {
612 				if (flipx) {
613 					Render16x16Tile_Mask_FlipXY_Clip(dest, code, x, y, color & 0x3f, 4, 0, 0, tiledata[1]);
614 				} else {
615 					Render16x16Tile_Mask_FlipY_Clip(dest, code, x, y, color & 0x3f, 4, 0, 0, tiledata[1]);
616 				}
617 			} else {
618 				if (flipx) {
619 					Render16x16Tile_Mask_FlipX_Clip(dest, code, x, y, color & 0x3f, 4, 0,0, tiledata[1]);
620 				} else {
621 					Render16x16Tile_Mask_Clip(dest, code, x, y, color & 0x3f, 4, 0, 0, tiledata[1]);
622 				}
623 			}
624 		}
625 	}
626 
627 	//nScreenWidth = t_swide;
628 	//nScreenHeight = t_shigh;
629 	// Like above, use this to revert the ClipRaw() changes, instead of setting the nScreenWidth/Height directly.
630 	GenericTilesClearClipRaw();
631 }
632 
TC0180VCUBufferSprites()633 void TC0180VCUBufferSprites()
634 {
635 	INT32 ctrl = TC0180VCUReadControl();
636 
637 	if (~ctrl & 0x01) {
638 		memset (TC0180VCUFbRAM + framebuffer_page * 0x20000, 0, 512 * 256);
639 		memset (TC0180VCUFramebuffer[framebuffer_page], 0, 512 * 256 * sizeof(UINT16));
640 	}
641 
642 	if (~ctrl & 0x80) {
643 		framebuffer_page ^= 1;
644 	}
645 
646 	if (tilemask[1]) {
647 		TC0180VCUDrawSprite(TC0180VCUFramebuffer[framebuffer_page]);
648 	}
649 }
650 
TC0180VCUScan(INT32 nAction)651 void TC0180VCUScan(INT32 nAction)
652 {
653 	struct BurnArea ba;
654 
655 	if (nAction & ACB_VOLATILE)
656 	{
657 		ba.Data	  = (UINT8*)TC0180VCUFramebuffer[0];
658 		ba.nLen	  = 512 * 256 * sizeof(UINT16);
659 		ba.szName = "Framebuffer 0";
660 		BurnAcb(&ba);
661 
662 		ba.Data	  = (UINT8*)TC0180VCUFramebuffer[1];
663 		ba.nLen	  = 512 * 256 * sizeof(UINT16);
664 		ba.szName = "Framebuffer 1";
665 		BurnAcb(&ba);
666 
667 		ba.Data	  = TC0180VCURAM;
668 		ba.nLen	  = 0x10000;
669 		ba.szName = "Tilemap RAM";
670 		BurnAcb(&ba);
671 
672 		ba.Data	  = TC0180VCUScrollRAM;
673 		ba.nLen	  = 0x00800;
674 		ba.szName = "Scroll RAM";
675 		BurnAcb(&ba);
676 
677 		ba.Data	  = TC0180VCUFbRAM;
678 		ba.nLen	  = 0x00800;
679 		ba.szName = "Framebuffer RAM";
680 		BurnAcb(&ba);
681 
682 		ba.Data	  = TC0180VCUControl;
683 		ba.nLen	  = 0x00010;
684 		ba.szName = "Control RAM";
685 		BurnAcb(&ba);
686 
687 		SCAN_VAR(framebuffer_page);
688 	}
689 }
690