1 /***************************************************************************
2 
3   vidhrdw/toaplan1.c
4 
5   Functions to emulate the video hardware of the machine.
6 
7   There are 4 scrolling layers of graphics, stored in planes of 64x64 tiles.
8   Each tile in each plane is assigned a priority between 1 and 15, higher
9   numbers have greater priority.
10 
11   Each tile takes up 32 bits, the format is:
12 
13   0         1         2         3
14   ---- ---- ---- ---- -xxx xxxx xxxx xxxx = tile number (0 - $7fff)
15   ---- ---- ---- ---- ?--- ---- ---- ---- = unknown / unused
16   ---- ---- --xx xxxx ---- ---- ---- ---- = color (0 - $3f)
17   ---- ???? ??-- ---- ---- ---- ---- ---- = unknown / unused
18   xxxx ---- ---- ---- ---- ---- ---- ---- = priority (0-$f)
19 
20   BG Scroll Reg
21 
22   0         1         2         3
23   xxxx xxxx x--- ---- ---- ---- ---- ---- = x
24   ---- ---- ---- ---- yyyy yyyy ---- ---- = y
25 
26 
27  Sprite RAM format  (except Rally Bike)
28 
29   0         1         2         3
30   ---- ---- ---- ---- -xxx xxxx xxxx xxxx = tile number (0 - $7fff)
31   ---- ---- ---- ---- x--- ---- ---- ---- = hidden
32   ---- ---- --xx xxxx ---- ---- ---- ---- = color (0 - $3f)
33   ---- xxxx xx-- ---- ---- ---- ---- ---- = sprite number
34   xxxx ---- ---- ---- ---- ---- ---- ---- = priority (0-$f)
35 
36   4         5         6         7
37   ---- ---- ---- ---- xxxx xxxx x--- ---- = x
38   yyyy yyyy y--- ---- ---- ---- ---- ---- = y
39 
40   The tiles use a palette of 1024 colors, the sprites use a different palette
41   of 1024 colors.
42 
43 ***************************************************************************/
44 
45 #include "driver.h"
46 #include "palette.h"
47 #include "vidhrdw/generic.h"
48 #include "cpu/m68000/m68000.h"
49 
50 #define VIDEORAM1_SIZE	0x1000		/* size in bytes - sprite ram */
51 #define VIDEORAM2_SIZE	0x100		/* size in bytes - sprite size ram */
52 #define VIDEORAM3_SIZE	0x4000		/* size in bytes - tile ram */
53 
54 unsigned char *toaplan1_videoram1;
55 unsigned char *toaplan1_videoram2;
56 unsigned char *toaplan1_videoram3;
57 unsigned char *toaplan1_buffered_videoram1;
58 unsigned char *toaplan1_buffered_videoram2;
59 
60 unsigned char *toaplan1_colorram1;
61 unsigned char *toaplan1_colorram2;
62 
63 size_t colorram1_size;
64 size_t colorram2_size;
65 
66 unsigned int scrollregs[8];
67 unsigned int vblank;
68 unsigned int num_tiles;
69 
70 unsigned int video_ofs;
71 unsigned int video_ofs3;
72 
73 int toaplan1_flipscreen;
74 int tiles_offsetx;
75 int tiles_offsety;
76 int layers_offset[4];
77 
78 
79 typedef struct
80 	{
81 	UINT16 tile_num;
82 	UINT16 color;
83 	char priority;
84 	int xpos;
85 	int ypos;
86 	} tile_struct;
87 
88 tile_struct *bg_list[4];
89 
90 tile_struct *tile_list[32];
91 tile_struct *temp_list;
92 static int max_list_size[32];
93 static int tile_count[32];
94 
95 struct osd_bitmap *tmpbitmap1;
96 static struct osd_bitmap *tmpbitmap2;
97 static struct osd_bitmap *tmpbitmap3;
98 
99 
rallybik_vh_start(void)100 int rallybik_vh_start(void)
101 {
102 	int i;
103 
104 	if ((toaplan1_videoram3 = (unsigned char*)calloc(VIDEORAM3_SIZE * 4, 1)) == 0) /* 4 layers */
105 	{
106 		return 1;
107 	}
108 
109 	//logerror("colorram_size: %08x\n", colorram1_size + colorram2_size);
110 	if ((paletteram = (unsigned char*)calloc(colorram1_size + colorram2_size, 1)) == 0)
111 	{
112 		free(toaplan1_videoram3);
113 		return 1;
114 	}
115 
116 	for (i=0; i<4; i++)
117 	{
118 		if ((bg_list[i]=(tile_struct *)malloc( 33 * 44 * sizeof(tile_struct))) == 0)
119 		{
120 			free(paletteram);
121 			free(toaplan1_videoram3);
122 			return 1;
123 		}
124 		memset(bg_list[i], 0, 33 * 44 * sizeof(tile_struct));
125 	}
126 
127 	for (i=0; i<16; i++)
128 	{
129 		max_list_size[i] = 8192;
130 		if ((tile_list[i]=(tile_struct *)malloc(max_list_size[i]*sizeof(tile_struct))) == 0)
131 		{
132 			for (i=3; i>=0; i--)
133 				free(bg_list[i]);
134 			free(paletteram);
135 			free(toaplan1_videoram3);
136 			return 1;
137 		}
138 		memset(tile_list[i],0,max_list_size[i]*sizeof(tile_struct));
139 	}
140 
141 	max_list_size[16] = 65536;
142 	if ((tile_list[16]=(tile_struct *)malloc(max_list_size[16]*sizeof(tile_struct))) == 0)
143 	{
144 		for (i=15; i>=0; i--)
145 			free(tile_list[i]);
146 		for (i=3; i>=0; i--)
147 			free(bg_list[i]);
148 		free(paletteram);
149 		free(toaplan1_videoram3);
150 		return 1;
151 	}
152 	memset(tile_list[16],0,max_list_size[16]*sizeof(tile_struct));
153 
154 	num_tiles = (Machine->drv->screen_width/8+1)*(Machine->drv->screen_height/8) ;
155 
156 	video_ofs = video_ofs3 = 0;
157 
158 	return 0;
159 }
160 
rallybik_vh_stop(void)161 void rallybik_vh_stop(void)
162 {
163 	int i ;
164 
165 	for (i=16; i>=0; i--)
166 	{
167 		free(tile_list[i]);
168 		//logerror("max_list_size[%d]=%08x\n",i,max_list_size[i]);
169 	}
170 
171 	for (i=3; i>=0; i--)
172 		free(bg_list[i]);
173 
174 	free(paletteram);
175 	free(toaplan1_videoram3);
176 }
177 
toaplan1_vh_start(void)178 int toaplan1_vh_start(void)
179 {
180 	tmpbitmap1 = bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height);
181 	tmpbitmap2 = bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height);
182 	tmpbitmap3 = bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height);
183 
184 
185 	if ((toaplan1_videoram1 = (unsigned char*)calloc(VIDEORAM1_SIZE, 1)) == 0)
186 	{
187 		return 1;
188 	}
189 	if ((toaplan1_buffered_videoram1 = (unsigned char*)calloc(VIDEORAM1_SIZE, 1)) == 0)
190 	{
191 		free(toaplan1_videoram1);
192 		return 1;
193 	}
194 	if ((toaplan1_videoram2 = (unsigned char*)calloc(VIDEORAM2_SIZE, 1)) == 0)
195 	{
196 		free(toaplan1_buffered_videoram1);
197 		free(toaplan1_videoram1);
198 		return 1;
199 	}
200 	if ((toaplan1_buffered_videoram2 = (unsigned char*)calloc(VIDEORAM2_SIZE, 1)) == 0)
201 	{
202 		free(toaplan1_videoram2);
203 		free(toaplan1_buffered_videoram1);
204 		free(toaplan1_videoram1);
205 		return 1;
206 	}
207 
208 	/* Also include all allocated stuff in Rally Bike startup */
209 	return rallybik_vh_start();
210 }
211 
toaplan1_vh_stop(void)212 void toaplan1_vh_stop(void)
213 {
214 	rallybik_vh_stop();
215 
216 	free(toaplan1_buffered_videoram2);
217 	free(toaplan1_videoram2);
218 	free(toaplan1_buffered_videoram1);
219 	free(toaplan1_videoram1);
220 	bitmap_free(tmpbitmap3);
221 	bitmap_free(tmpbitmap2);
222 	bitmap_free(tmpbitmap1);
223 }
224 
225 
226 
227 
READ_HANDLER(toaplan1_vblank_r)228 READ_HANDLER( toaplan1_vblank_r )
229 {
230 	return vblank ^= 1;
231 }
232 
WRITE_HANDLER(toaplan1_flipscreen_w)233 WRITE_HANDLER( toaplan1_flipscreen_w )
234 {
235 	toaplan1_flipscreen = data; /* 8000 flip, 0000 dont */
236 }
237 
READ_HANDLER(video_ofs_r)238 READ_HANDLER( video_ofs_r )
239 {
240 	return video_ofs ;
241 }
242 
WRITE_HANDLER(video_ofs_w)243 WRITE_HANDLER( video_ofs_w )
244 {
245 	video_ofs = data ;
246 }
247 
248 /* tile palette */
READ_HANDLER(toaplan1_colorram1_r)249 READ_HANDLER( toaplan1_colorram1_r )
250 {
251 	return READ_WORD (&toaplan1_colorram1[offset]);
252 }
253 
WRITE_HANDLER(toaplan1_colorram1_w)254 WRITE_HANDLER( toaplan1_colorram1_w )
255 {
256 	WRITE_WORD (&toaplan1_colorram1[offset], data);
257 	paletteram_xBBBBBGGGGGRRRRR_word_w(offset,data);
258 }
259 
260 /* sprite palette */
READ_HANDLER(toaplan1_colorram2_r)261 READ_HANDLER( toaplan1_colorram2_r )
262 {
263 	return READ_WORD (&toaplan1_colorram2[offset]);
264 }
265 
WRITE_HANDLER(toaplan1_colorram2_w)266 WRITE_HANDLER( toaplan1_colorram2_w )
267 {
268 	WRITE_WORD (&toaplan1_colorram2[offset], data);
269 	paletteram_xBBBBBGGGGGRRRRR_word_w(offset+colorram1_size,data);
270 }
271 
READ_HANDLER(toaplan1_videoram1_r)272 READ_HANDLER( toaplan1_videoram1_r )
273 {
274 	return READ_WORD (&toaplan1_videoram1[2*(video_ofs & (VIDEORAM1_SIZE-1))]);
275 }
276 
WRITE_HANDLER(toaplan1_videoram1_w)277 WRITE_HANDLER( toaplan1_videoram1_w )
278 {
279 	int oldword = READ_WORD (&toaplan1_videoram1[2*video_ofs & (VIDEORAM1_SIZE-1)]);
280 	int newword = COMBINE_WORD (oldword, data);
281 
282 #ifdef DEBUG
283 	if (2*video_ofs >= VIDEORAM1_SIZE)
284 	{
285 		logerror("videoram1_w, %08x\n", 2*video_ofs);
286 		return;
287 	}
288 #endif
289 
290 	WRITE_WORD (&toaplan1_videoram1[2*video_ofs & (VIDEORAM1_SIZE-1)],newword);
291 	video_ofs++;
292 }
293 
READ_HANDLER(toaplan1_videoram2_r)294 READ_HANDLER( toaplan1_videoram2_r )
295 {
296 	return READ_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)]);
297 }
298 
WRITE_HANDLER(toaplan1_videoram2_w)299 WRITE_HANDLER( toaplan1_videoram2_w )
300 {
301 	int oldword = READ_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)]);
302 	int newword = COMBINE_WORD (oldword, data);
303 
304 #ifdef DEBUG
305 	if (2*video_ofs >= VIDEORAM2_SIZE)
306 	{
307 		logerror("videoram2_w, %08x\n", 2*video_ofs);
308 		return;
309 	}
310 #endif
311 
312 	WRITE_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)],newword);
313 	video_ofs++;
314 }
315 
READ_HANDLER(video_ofs3_r)316 READ_HANDLER( video_ofs3_r )
317 {
318 	return video_ofs3;
319 }
320 
WRITE_HANDLER(video_ofs3_w)321 WRITE_HANDLER( video_ofs3_w )
322 {
323 	video_ofs3 = data ;
324 }
325 
READ_HANDLER(rallybik_videoram3_r)326 READ_HANDLER( rallybik_videoram3_r )
327 {
328 	int rb_tmp_vid;
329 
330 	rb_tmp_vid = READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
331 
332 	if (offset == 0)
333 	{
334 		rb_tmp_vid |= ((rb_tmp_vid & 0xf000) >> 4);
335 		rb_tmp_vid |= ((rb_tmp_vid & 0x0030) << 2);
336 	}
337 	return rb_tmp_vid;
338 }
339 
READ_HANDLER(toaplan1_videoram3_r)340 READ_HANDLER( toaplan1_videoram3_r )
341 {
342 	return READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
343 }
344 
WRITE_HANDLER(toaplan1_videoram3_w)345 WRITE_HANDLER( toaplan1_videoram3_w )
346 {
347 	int oldword = READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
348 	int newword = COMBINE_WORD (oldword, data);
349 
350 #ifdef DEBUG
351 	if ((video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset >= VIDEORAM3_SIZE*4)
352 	{
353 		logerror("videoram3_w, %08x\n", 2*video_ofs3);
354 		return;
355 	}
356 #endif
357 
358 	WRITE_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset],newword);
359 	if ( offset == 2 ) video_ofs3++;
360 }
361 
READ_HANDLER(scrollregs_r)362 READ_HANDLER( scrollregs_r )
363 {
364 	return scrollregs[offset>>1];
365 }
366 
WRITE_HANDLER(scrollregs_w)367 WRITE_HANDLER( scrollregs_w )
368 {
369 	scrollregs[offset>>1] = data ;
370 }
371 
WRITE_HANDLER(offsetregs_w)372 WRITE_HANDLER( offsetregs_w )
373 {
374 	if ( offset == 0 )
375 		tiles_offsetx = data ;
376 	else
377 		tiles_offsety = data ;
378 }
379 
WRITE_HANDLER(layers_offset_w)380 WRITE_HANDLER( layers_offset_w )
381 {
382 	switch (offset)
383 	{
384 /*		case 0:
385 			layers_offset[0] = (data&0xff) - 0xdb ;
386 			break ;
387 		case 2:
388 			layers_offset[1] = (data&0xff) - 0x14 ;
389 			break ;
390 		case 4:
391 			layers_offset[2] = (data&0xff) - 0x85 ;
392 			break ;
393 		case 6:
394 			layers_offset[3] = (data&0xff) - 0x07 ;
395 			break ;
396 */
397 		case 0:
398 			layers_offset[0] = data;
399 			break ;
400 		case 2:
401 			layers_offset[1] = data;
402 			break ;
403 		case 4:
404 			layers_offset[2] = data;
405 			break ;
406 		case 6:
407 			layers_offset[3] = data;
408 			break ;
409 	}
410 
411 	/*
412 	logerror("layers_offset[0]:%08x\n",layers_offset[0]);
413 	logerror("layers_offset[1]:%08x\n",layers_offset[1]);
414 	logerror("layers_offset[2]:%08x\n",layers_offset[2]);
415 	logerror("layers_offset[3]:%08x\n",layers_offset[3]);
416 	*/
417 
418 }
419 
420 /***************************************************************************
421 
422   Draw the game screen in the given osd_bitmap.
423 
424 ***************************************************************************/
425 
426 
toaplan1_update_palette(void)427 static void toaplan1_update_palette (void)
428 {
429 	int i;
430 	int priority;
431 	int color;
432 	unsigned short palette_map[64*2];
433 
434 	memset (palette_map, 0, sizeof (palette_map));
435 
436 	/* extract color info from priority layers in order */
437 	for (priority = 0; priority < 17; priority++ )
438 	{
439 		tile_struct *tinfo;
440 
441 		tinfo = (tile_struct *)&(tile_list[priority][0]);
442 		/* draw only tiles in list */
443 		for ( i = 0; i < tile_count[priority]; i++ )
444 		{
445 			int bank;
446 
447 			bank  = (tinfo->color >> 7) & 1;
448 			color = (tinfo->color & 0x3f);
449 			palette_map[color + bank*64] |= Machine->gfx[bank]->pen_usage[tinfo->tile_num & (Machine->gfx[bank]->total_elements-1)];
450 
451 			tinfo++;
452 		}
453 	}
454 
455 	/* Tell MAME about the color usage */
456 	for (i = 0; i < 64*2; i++)
457 	{
458 		int usage = palette_map[i];
459 		int j;
460 
461 		if (usage)
462 		{
463 			palette_used_colors[i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
464 			for (j = 0; j < 16; j++)
465 			{
466 				if (usage & (1 << j))
467 					palette_used_colors[i * 16 + j] = PALETTE_COLOR_USED;
468 				else
469 					palette_used_colors[i * 16 + j] = PALETTE_COLOR_UNUSED;
470 			}
471 		}
472 		else
473 			memset(&palette_used_colors[i * 16],PALETTE_COLOR_UNUSED,16);
474 	}
475 
476 	palette_recalc ();
477 }
478 
479 
480 
481 static int 	layer_scrollx[4];
482 static int 	layer_scrolly[4];
483 
toaplan1_find_tiles(int xoffs,int yoffs)484 static void toaplan1_find_tiles(int xoffs,int yoffs)
485 {
486 	int priority;
487 	int layer;
488 	tile_struct *tinfo;
489 	unsigned char *t_info;
490 
491 	if(toaplan1_flipscreen){
492 		layer_scrollx[0] = ((scrollregs[0]) >> 7) + (523 - xoffs);
493 		layer_scrollx[1] = ((scrollregs[2]) >> 7) + (525 - xoffs);
494 		layer_scrollx[2] = ((scrollregs[4]) >> 7) + (527 - xoffs);
495 		layer_scrollx[3] = ((scrollregs[6]) >> 7) + (529 - xoffs);
496 
497 		layer_scrolly[0] = ((scrollregs[1]) >> 7) +	(256 - yoffs);
498 		layer_scrolly[1] = ((scrollregs[3]) >> 7) + (256 - yoffs);
499 		layer_scrolly[2] = ((scrollregs[5]) >> 7) + (256 - yoffs);
500 		layer_scrolly[3] = ((scrollregs[7]) >> 7) + (256 - yoffs);
501 	}else{
502 		layer_scrollx[0] = ((scrollregs[0]) >> 7) +(495 - xoffs + 6);
503 		layer_scrollx[1] = ((scrollregs[2]) >> 7) +(495 - xoffs + 4);
504 		layer_scrollx[2] = ((scrollregs[4]) >> 7) +(495 - xoffs + 2);
505 		layer_scrollx[3] = ((scrollregs[6]) >> 7) +(495 - xoffs);
506 
507 		layer_scrolly[0] = ((scrollregs[1]) >> 7) +	(0x101 - yoffs);
508 		layer_scrolly[1] = ((scrollregs[3]) >> 7) + (0x101 - yoffs);
509 		layer_scrolly[2] = ((scrollregs[5]) >> 7) + (0x101 - yoffs);
510 		layer_scrolly[3] = ((scrollregs[7]) >> 7) + (0x101 - yoffs);
511 	}
512 
513 	for ( layer = 3 ; layer >= 0 ; layer-- )
514 	{
515 		int scrolly,scrollx,offsetx,offsety;
516 		int sx,sy,tattr;
517 		int i;
518 
519 		t_info = (toaplan1_videoram3+layer * VIDEORAM3_SIZE);
520 		scrollx = layer_scrollx[layer];
521 		offsetx = scrollx / 8 ;
522 		scrolly = layer_scrolly[layer];
523 		offsety = scrolly / 8 ;
524 
525 		for ( sy = 0 ; sy < 32 ; sy++ )
526 		{
527 			for ( sx = 0 ; sx <= 40 ; sx++ )
528 			{
529 				i = ((sy+offsety)&0x3f)*256 + ((sx+offsetx)&0x3f)*4 ;
530 				tattr = READ_WORD(&t_info[i]);
531 				priority = (tattr >> 12);
532 
533 				tinfo = (tile_struct *)&(bg_list[layer][sy*41+sx]) ;
534 				tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
535 				tinfo->priority = priority ;
536 				tinfo->color = tattr & 0x3f ;
537 				tinfo->xpos = (sx*8)-(scrollx&0x7) ;
538 				tinfo->ypos = (sy*8)-(scrolly&0x7) ;
539 
540 				if ( (priority) || (layer == 0) )	/* if priority 0 draw layer 0 only */
541 				{
542 
543 					tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
544 					tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
545 					if ( (tinfo->tile_num & 0x8000) == 0 )
546 					{
547 						tinfo->priority = priority ;
548 						tinfo->color = tattr & 0x3f ;
549 						tinfo->color |= layer<<8;
550 						tinfo->xpos = (sx*8)-(scrollx&0x7) ;
551 						tinfo->ypos = (sy*8)-(scrolly&0x7) ;
552 						tile_count[priority]++ ;
553 						if(tile_count[priority]==max_list_size[priority])
554 						{
555 							/*reallocate tile_list[priority] to larger size */
556 							temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
557 							memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
558 							max_list_size[priority]+=512;
559 							free(tile_list[priority]);
560 							tile_list[priority] = temp_list ;
561 						}
562 					}
563 				}
564 			}
565 		}
566 	}
567 	for ( layer = 3 ; layer >= 0 ; layer-- )
568 	{
569 		layer_scrollx[layer] &= 0x7;
570 		layer_scrolly[layer] &= 0x7;
571 	}
572 }
573 
rallybik_find_tiles(void)574 static void rallybik_find_tiles(void)
575 {
576 	int priority;
577 	int layer;
578 	tile_struct *tinfo;
579 	unsigned char *t_info;
580 
581 	for ( priority = 0 ; priority < 16 ; priority++ )
582 	{
583 		tile_count[priority]=0;
584 	}
585 
586 	for ( layer = 3 ; layer >= 0 ; layer-- )
587 	{
588 		int scrolly,scrollx,offsetx,offsety;
589 		int sx,sy,tattr;
590 		int i;
591 
592 		t_info = (toaplan1_videoram3+layer * VIDEORAM3_SIZE);
593 		scrollx = scrollregs[layer*2];
594 		scrolly = scrollregs[(layer*2)+1];
595 
596 		scrollx >>= 7 ;
597 		scrollx += 43 ;
598 		if ( layer == 0 ) scrollx += 2 ;
599 		if ( layer == 2 ) scrollx -= 2 ;
600 		if ( layer == 3 ) scrollx -= 4 ;
601 		offsetx = scrollx / 8 ;
602 
603 		scrolly >>= 7 ;
604 		scrolly += 21 ;
605 		offsety = scrolly / 8 ;
606 
607 		for ( sy = 0 ; sy < 32 ; sy++ )
608 		{
609 			for ( sx = 0 ; sx <= 40 ; sx++ )
610 			{
611 				i = ((sy+offsety)&0x3f)*256 + ((sx+offsetx)&0x3f)*4 ;
612 				tattr = READ_WORD(&t_info[i]);
613 				priority = tattr >> 12 ;
614 				if ( (priority) || (layer == 0) )	/* if priority 0 draw layer 0 only */
615 				{
616 					tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
617 					tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
618 
619 					if ( !((priority) && (tinfo->tile_num & 0x8000)) )
620 					{
621 						tinfo->tile_num &= 0x3fff ;
622 						tinfo->color = tattr & 0x3f ;
623 						tinfo->xpos = (sx*8)-(scrollx&0x7) ;
624 						tinfo->ypos = (sy*8)-(scrolly&0x7) ;
625 						tile_count[priority]++ ;
626 						if(tile_count[priority]==max_list_size[priority])
627 						{
628 							/*reallocate tile_list[priority] to larger size */
629 							temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
630 							memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
631 							max_list_size[priority]+=512;
632 							free(tile_list[priority]);
633 							tile_list[priority] = temp_list ;
634 						}
635 					}
636 				}
637 			}
638 		}
639 	}
640 }
641 
642 unsigned long toaplan_sp_ram_dump = 0;
643 
toaplan1_find_sprites(void)644 static void toaplan1_find_sprites (void)
645 {
646 	int priority;
647 	int sprite;
648 	unsigned char *s_info,*s_size;
649 
650 
651 	for ( priority = 0 ; priority < 17 ; priority++ )
652 	{
653 		tile_count[priority]=0;
654 	}
655 
656 
657 #if 0		// sp ram dump start
658 	s_size = (toaplan1_buffered_videoram2);		/* sprite block size */
659 	s_info = (toaplan1_buffered_videoram1);		/* start of sprite ram */
660 	if( (toaplan_sp_ram_dump == 0)
661 	 && (keyboard_pressed(KEYCODE_N)) )
662 	{
663 		toaplan_sp_ram_dump = 1;
664 		for ( sprite = 0 ; sprite < 256 ; sprite++ )
665 		{
666 			int tattr,tchar;
667 			tchar = READ_WORD (&s_info[0]) & 0xffff;
668 			tattr = READ_WORD (&s_info[2]);
669 			logerror("%08x: %04x %04x\n", sprite, tattr, tchar);
670 			s_info += 8 ;
671 		}
672 	}
673 #endif		// end
674 
675 	s_size = (toaplan1_buffered_videoram2);		/* sprite block size */
676 	s_info = (toaplan1_buffered_videoram1);		/* start of sprite ram */
677 
678 	for ( sprite = 0 ; sprite < 256 ; sprite++ )
679 	{
680 		int tattr,tchar;
681 
682 		tchar = READ_WORD (&s_info[0]) & 0xffff;
683 		tattr = READ_WORD (&s_info[2]);
684 
685 		if ( (tattr & 0xf000) && ((tchar & 0x8000) == 0) )
686 		{
687 			int sx,sy,dx,dy,s_sizex,s_sizey;
688 			int sprite_size_ptr;
689 
690 			sx=READ_WORD(&s_info[4]);
691 			sx >>= 7 ;
692 			if ( sx > 416 ) sx -= 512 ;
693 
694 			sy=READ_WORD(&s_info[6]);
695 			sy >>= 7 ;
696 			if ( sy > 416 ) sy -= 512 ;
697 
698 			priority = (tattr >> 12);
699 
700 			sprite_size_ptr = (tattr>>6)&0x3f ;
701 			s_sizey = (READ_WORD(&s_size[2*sprite_size_ptr])>>4)&0xf ;
702 			s_sizex = (READ_WORD(&s_size[2*sprite_size_ptr]))&0xf ;
703 
704 			for ( dy = s_sizey ; dy > 0 ; dy-- )
705 			for ( dx = s_sizex; dx > 0 ; dx-- )
706 			{
707 				tile_struct *tinfo;
708 
709 				tinfo = (tile_struct *)&(tile_list[16][tile_count[16]]) ;
710 				tinfo->priority = priority;
711 				tinfo->tile_num = tchar;
712 				tinfo->color = 0x80 | (tattr & 0x3f) ;
713 				tinfo->xpos = sx-dx*8+s_sizex*8 ;
714 				tinfo->ypos = sy-dy*8+s_sizey*8 ;
715 				tile_count[16]++ ;
716 				if(tile_count[16]==max_list_size[16])
717 				{
718 					/*reallocate tile_list[priority] to larger size */
719 					temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[16]+512)) ;
720 					memcpy(temp_list,tile_list[16],sizeof(tile_struct)*max_list_size[16]);
721 					max_list_size[16]+=512;
722 					free(tile_list[16]);
723 					tile_list[16] = temp_list ;
724 				}
725 				tchar++;
726 			}
727 		}
728 		s_info += 8 ;
729 	}
730 }
731 
rallybik_find_sprites(void)732 static void rallybik_find_sprites (void)
733 {
734 	int offs;
735 	int tattr;
736 	int sx,sy,tchar;
737 	int priority;
738 	tile_struct *tinfo;
739 
740 	for (offs = 0;offs < spriteram_size;offs += 8)
741 	{
742 		tattr = READ_WORD(&buffered_spriteram[offs+2]);
743 		if ( tattr )	/* no need to render hidden sprites */
744 		{
745 			sx=READ_WORD(&buffered_spriteram[offs+4]);
746 			sx >>= 7 ;
747 			sx &= 0x1ff ;
748 			if ( sx > 416 ) sx -= 512 ;
749 
750 			sy=READ_WORD(&buffered_spriteram[offs+6]);
751 			sy >>= 7 ;
752 			sy &= 0x1ff ;
753 			if ( sy > 416 ) sy -= 512 ;
754 
755 			priority = (tattr>>8) & 0xc ;
756 			tchar = READ_WORD(&buffered_spriteram[offs+0]);
757 			tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
758 			tinfo->tile_num = tchar & 0x7ff ;
759 			tinfo->color = 0x80 | (tattr&0x3f) ;
760 			tinfo->color |= (tattr & 0x0100) ;
761 			tinfo->color |= (tattr & 0x0200) ;
762 			if (tinfo->color & 0x0100) sx -= 15;
763 
764 			tinfo->xpos = sx-31 ;
765 			tinfo->ypos = sy-16 ;
766 			tile_count[priority]++ ;
767 			if(tile_count[priority]==max_list_size[priority])
768 			{
769 				/*reallocate tile_list[priority] to larger size */
770 				temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
771 				memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
772 				max_list_size[priority]+=512;
773 				free(tile_list[priority]);
774 				tile_list[priority] = temp_list ;
775 			}
776 		}  // if tattr
777 	} // for sprite
778 }
779 
780 
toaplan1_fillbgmask(struct osd_bitmap * dest_bmp,struct osd_bitmap * source_bmp,const struct rectangle * clip,int transparent_color)781 void toaplan1_fillbgmask(struct osd_bitmap *dest_bmp, struct osd_bitmap *source_bmp,
782  const struct rectangle *clip,int transparent_color)
783 {
784 	struct rectangle myclip;
785 	int sx=0;
786 	int sy=0;
787 
788 	if (Machine->orientation & ORIENTATION_SWAP_XY)
789 	{
790 		int temp;
791 
792 		/* clip and myclip might be the same, so we need a temporary storage */
793 		temp = clip->min_x;
794 		myclip.min_x = clip->min_y;
795 		myclip.min_y = temp;
796 		temp = clip->max_x;
797 		myclip.max_x = clip->max_y;
798 		myclip.max_y = temp;
799 		clip = &myclip;
800 	}
801 	if (Machine->orientation & ORIENTATION_FLIP_X)
802 	{
803 		int temp;
804 
805 		sx = -sx;
806 
807 		/* clip and myclip might be the same, so we need a temporary storage */
808 		temp = clip->min_x;
809 		myclip.min_x = dest_bmp->width-1 - clip->max_x;
810 		myclip.max_x = dest_bmp->width-1 - temp;
811 		myclip.min_y = clip->min_y;
812 		myclip.max_y = clip->max_y;
813 		clip = &myclip;
814 	}
815 	if (Machine->orientation & ORIENTATION_FLIP_Y)
816 	{
817 		int temp;
818 
819 		sy = -sy;
820 
821 		myclip.min_x = clip->min_x;
822 		myclip.max_x = clip->max_x;
823 		/* clip and myclip might be the same, so we need a temporary storage */
824 		temp = clip->min_y;
825 		myclip.min_y = dest_bmp->height-1 - clip->max_y;
826 		myclip.max_y = dest_bmp->height-1 - temp;
827 		clip = &myclip;
828 	}
829 
830 	if (dest_bmp->depth != 16)
831 	{
832 		int ex = sx+source_bmp->width;
833 		int ey = sy+source_bmp->height;
834 
835 		if( sx < clip->min_x)
836 		{ /* clip left */
837 			sx = clip->min_x;
838 		}
839 		if( sy < clip->min_y )
840 		{ /* clip top */
841 			sy = clip->min_y;
842 		}
843 		if( ex > clip->max_x+1 )
844 		{ /* clip right */
845 			ex = clip->max_x + 1;
846 		}
847 		if( ey > clip->max_y+1 )
848 		{ /* clip bottom */
849 			ey = clip->max_y + 1;
850 		}
851 
852 		if( ex>sx )
853 		{ /* skip if inner loop doesn't draw anything */
854 			int y;
855 			for( y=sy; y<ey; y++ )
856 			{
857 				unsigned char *dest = dest_bmp->line[y];
858 				unsigned char *source = source_bmp->line[y];
859 				int x;
860 
861 				for( x=sx; x<ex; x++ )
862 				{
863 					int c = source[x];
864 					if( c != transparent_color )
865 						dest[x] = transparent_color;
866 				}
867 			}
868 		}
869 	}
870 
871 	else
872 	{
873 		int ex = sx+source_bmp->width;
874 		int ey = sy+source_bmp->height;
875 
876 		if( sx < clip->min_x)
877 		{ /* clip left */
878 			sx = clip->min_x;
879 		}
880 		if( sy < clip->min_y )
881 		{ /* clip top */
882 			sy = clip->min_y;
883 		}
884 		if( ex > clip->max_x+1 )
885 		{ /* clip right */
886 			ex = clip->max_x + 1;
887 		}
888 		if( ey > clip->max_y+1 )
889 		{ /* clip bottom */
890 			ey = clip->max_y + 1;
891 		}
892 
893 		if( ex>sx )
894 		{ /* skip if inner loop doesn't draw anything */
895 			int y;
896 
897 			for( y=sy; y<ey; y++ )
898 			{
899 				unsigned short *dest = (unsigned short *)dest_bmp->line[y];
900 				unsigned char *source = source_bmp->line[y];
901 				int x;
902 
903 				for( x=sx; x<ex; x++ )
904 				{
905 					int c = source[x];
906 					if( c != transparent_color )
907 						dest[x] = transparent_color;
908 				}
909 			}
910 		}
911 	}
912 }
913 
914 
915 //#define BGDBG
916 #ifdef BGDBG
917 int	toaplan_dbg_priority = 0;
918 #endif
919 
920 
toaplan1_render(struct osd_bitmap * bitmap)921 static void toaplan1_render (struct osd_bitmap *bitmap)
922 {
923 	int i,j;
924 	int priority,pen;
925 	int	flip;
926 	tile_struct *tinfo;
927 	tile_struct *tinfo2;
928 	struct rectangle sp_rect;
929 
930 	fillbitmap (bitmap, palette_transparent_pen, &Machine->visible_area);
931 
932 #ifdef BGDBG
933 
934 if (keyboard_pressed(KEYCODE_Q)) { toaplan_dbg_priority = 0; }
935 if (keyboard_pressed(KEYCODE_W)) { toaplan_dbg_priority = 1; }
936 if (keyboard_pressed(KEYCODE_E)) { toaplan_dbg_priority = 2; }
937 if (keyboard_pressed(KEYCODE_R)) { toaplan_dbg_priority = 3; }
938 if (keyboard_pressed(KEYCODE_T)) { toaplan_dbg_priority = 4; }
939 if (keyboard_pressed(KEYCODE_Y)) { toaplan_dbg_priority = 5; }
940 if (keyboard_pressed(KEYCODE_U)) { toaplan_dbg_priority = 6; }
941 if (keyboard_pressed(KEYCODE_I)) { toaplan_dbg_priority = 7; }
942 if (keyboard_pressed(KEYCODE_A)) { toaplan_dbg_priority = 8; }
943 if (keyboard_pressed(KEYCODE_S)) { toaplan_dbg_priority = 9; }
944 if (keyboard_pressed(KEYCODE_D)) { toaplan_dbg_priority = 10; }
945 if (keyboard_pressed(KEYCODE_F)) { toaplan_dbg_priority = 11; }
946 if (keyboard_pressed(KEYCODE_G)) { toaplan_dbg_priority = 12; }
947 if (keyboard_pressed(KEYCODE_H)) { toaplan_dbg_priority = 13; }
948 if (keyboard_pressed(KEYCODE_J)) { toaplan_dbg_priority = 14; }
949 if (keyboard_pressed(KEYCODE_K)) { toaplan_dbg_priority = 15; }
950 
951 if( toaplan_dbg_priority != 0 ){
952 
953 	priority = toaplan_dbg_priority;
954 	{
955 		tinfo = (tile_struct *)&(tile_list[priority][0]) ;
956 		/* hack to fix black blobs in Demon's World sky */
957 		pen = TRANSPARENCY_NONE ;
958 		for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
959 		{
960 			/* hack to fix blue blobs in Zero Wing attract mode */
961 //			if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
962 //				pen = TRANSPARENCY_PEN ;
963 			drawgfx(bitmap,Machine->gfx[0],
964 				tinfo->tile_num,
965 				(tinfo->color&0x3f),
966 				0,0,						/* flipx,flipy */
967 				tinfo->xpos,tinfo->ypos,
968 				&Machine->visible_area,pen,0);
969 			tinfo++ ;
970 		}
971 	}
972 
973 }else{
974 
975 #endif
976 
977 //	if(toaplan1_flipscreen)
978 //		flip = 1;
979 //	else
980 		flip = 0;
981 //
982 	priority = 0;
983 	while ( priority < 16 )			/* draw priority layers in order */
984 	{
985 		int	layer;
986 
987 		tinfo = (tile_struct *)&(tile_list[priority][0]) ;
988 		layer = (tinfo->color >> 8);
989 		if ( (layer < 3) && (priority < 2))
990 			pen = TRANSPARENCY_NONE ;
991 		else
992 			pen = TRANSPARENCY_PEN ;
993 
994 		for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
995 		{
996 			int	xpos,ypos;
997 
998 			/* hack to fix blue blobs in Zero Wing attract mode */
999 //			if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
1000 //				pen = TRANSPARENCY_PEN ;
1001 
1002 //			if ( flip ){
1003 //				xpos = tinfo->xpos;
1004 //				ypos = tinfo->ypos;
1005 //			}
1006 //			else{
1007 				xpos = tinfo->xpos;
1008 				ypos = tinfo->ypos;
1009 //			}
1010 
1011 			drawgfx(bitmap,Machine->gfx[0],
1012 				tinfo->tile_num,
1013 				(tinfo->color&0x3f),
1014 				flip,flip,							/* flipx,flipy */
1015 				tinfo->xpos,tinfo->ypos,
1016 				&Machine->visible_area,pen,0);
1017 			tinfo++ ;
1018 		}
1019 		priority++;
1020 	}
1021 
1022 	tinfo2 = (tile_struct *)&(tile_list[16][0]) ;
1023 	for ( i = 0; i < tile_count[16]; i++ )	/* draw sprite No. in order */
1024 	{
1025 		int	flipx,flipy;
1026 
1027 		sp_rect.min_x = tinfo2->xpos;
1028 		sp_rect.min_y = tinfo2->ypos;
1029 		sp_rect.max_x = tinfo2->xpos + 7;
1030 		sp_rect.max_y = tinfo2->ypos + 7;
1031 
1032 		fillbitmap (tmpbitmap2, palette_transparent_pen, &sp_rect);
1033 
1034 		flipx = (tinfo2->color & 0x0100);
1035 		flipy = (tinfo2->color & 0x0200);
1036 //		if(toaplan1_flipscreen){
1037 //			flipx = !flipx;
1038 //			flipy = !flipy;
1039 //		}
1040 		drawgfx(tmpbitmap2,Machine->gfx[1],
1041 			tinfo2->tile_num,
1042 			(tinfo2->color&0x3f), 			/* bit 7 not for colour */
1043 			flipx,flipy,					/* flipx,flipy */
1044 			tinfo2->xpos,tinfo2->ypos,
1045 			&Machine->visible_area,TRANSPARENCY_PEN,0);
1046 
1047 		priority = tinfo2->priority;
1048 		{
1049 		int ix0,ix1,ix2,ix3;
1050 		int dirty;
1051 
1052 		dirty = 0;
1053 		fillbitmap (tmpbitmap3, palette_transparent_pen, &sp_rect);
1054 		for ( j = 0 ; j < 4 ; j++ )
1055 		{
1056 			int x,y;
1057 
1058 			y = tinfo2->ypos+layer_scrolly[j];
1059 			x = tinfo2->xpos+layer_scrollx[j];
1060 			ix0 = ( y   /8) * 41 +  x   /8;
1061 			ix1 = ( y   /8) * 41 + (x+7)/8;
1062 			ix2 = ((y+7)/8) * 41 +  x   /8;
1063 			ix3 = ((y+7)/8) * 41 + (x+7)/8;
1064 
1065 			if(	(ix0 >= 0) && (ix0 < 32*41) ){
1066 				tinfo = (tile_struct *)&(bg_list[j][ix0]) ;
1067 				if( (tinfo->priority >= tinfo2->priority) ){
1068 					drawgfx(tmpbitmap3,Machine->gfx[0],
1069 //					drawgfx(tmpbitmap2,Machine->gfx[0],
1070 						tinfo->tile_num,
1071 						(tinfo->color&0x3f),
1072 						flip,flip,
1073 						tinfo->xpos,tinfo->ypos,
1074 						&sp_rect,TRANSPARENCY_PEN,0);
1075 					dirty=1;
1076 				}
1077 			}
1078 			if(	(ix1 >= 0) && (ix1 < 32*41) ){
1079 				tinfo = (tile_struct *)&(bg_list[j][ix1]) ;
1080 //				tinfo++;
1081 				if( (ix0 != ix1)
1082 				 && (tinfo->priority >= tinfo2->priority) ){
1083 					drawgfx(tmpbitmap3,Machine->gfx[0],
1084 //					drawgfx(tmpbitmap2,Machine->gfx[0],
1085 						tinfo->tile_num,
1086 						(tinfo->color&0x3f),
1087 						flip,flip,
1088 						tinfo->xpos,tinfo->ypos,
1089 						&sp_rect,TRANSPARENCY_PEN,0);
1090 					dirty=1;
1091 				}
1092 			}
1093 			if(	(ix2 >= 0) && (ix2 < 32*41) ){
1094 				tinfo = (tile_struct *)&(bg_list[j][ix2]) ;
1095 //				tinfo += 40;
1096 				if( (ix0 != ix2)
1097 				 && (tinfo->priority >= tinfo2->priority) ){
1098 					drawgfx(tmpbitmap3,Machine->gfx[0],
1099 //					drawgfx(tmpbitmap2,Machine->gfx[0],
1100 						tinfo->tile_num,
1101 						(tinfo->color&0x3f),
1102 						flip,flip,
1103 						tinfo->xpos,tinfo->ypos,
1104 						&sp_rect,TRANSPARENCY_PEN,0);
1105 					dirty=1;
1106 				}
1107 			}
1108 			if(	(ix3 >= 0) && (ix3 < 32*41) ){
1109 				tinfo = (tile_struct *)&(bg_list[j][ix3]) ;
1110 //				tinfo++;
1111 				if( (ix0 != ix3) && (ix1 != ix3) && (ix2 != ix3)
1112 				 && (tinfo->priority >= tinfo2->priority) ){
1113 					drawgfx(tmpbitmap3,Machine->gfx[0],
1114 //					drawgfx(tmpbitmap2,Machine->gfx[0],
1115 						tinfo->tile_num,
1116 						(tinfo->color&0x3f),
1117 						flip,flip,
1118 						tinfo->xpos,tinfo->ypos,
1119 						&sp_rect,TRANSPARENCY_PEN,0);
1120 					dirty=1;
1121 				}
1122 			}
1123 		}
1124 		if(	dirty != 0 )
1125 		{
1126 			toaplan1_fillbgmask(
1127 				tmpbitmap2,				// dist
1128 				tmpbitmap3,				// mask
1129 				&sp_rect,
1130 				palette_transparent_pen
1131 			);
1132 		}
1133 		copybitmap(bitmap, tmpbitmap2, 0, 0, 0, 0, &sp_rect, TRANSPARENCY_PEN, palette_transparent_pen);
1134 		tinfo2++;
1135 		}
1136 	}
1137 
1138 #ifdef BGDBG
1139 }
1140 #endif
1141 
1142 }
1143 
1144 
rallybik_render(struct osd_bitmap * bitmap)1145 static void rallybik_render (struct osd_bitmap *bitmap)
1146 {
1147 	int i;
1148 	int priority,pen;
1149 	tile_struct *tinfo;
1150 
1151 	fillbitmap (bitmap, palette_transparent_pen, &Machine->visible_area);
1152 
1153 	for ( priority = 0 ; priority < 16 ; priority++ )	/* draw priority layers in order */
1154 	{
1155 		tinfo = (tile_struct *)&(tile_list[priority][0]) ;
1156 		/* hack to fix black blobs in Demon's World sky */
1157 		if ( priority == 1 )
1158 			pen = TRANSPARENCY_NONE ;
1159 		else
1160 			pen = TRANSPARENCY_PEN ;
1161 		for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
1162 		{
1163 			/* hack to fix blue blobs in Zero Wing attract mode */
1164 			if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
1165 				pen = TRANSPARENCY_PEN ;
1166 
1167 			drawgfx(bitmap,Machine->gfx[(tinfo->color>>7)&1],	/* bit 7 set for sprites */
1168 				tinfo->tile_num,
1169 				(tinfo->color&0x3f), 			/* bit 7 not for colour */
1170 				(tinfo->color & 0x0100),(tinfo->color & 0x0200),	/* flipx,flipy */
1171 				tinfo->xpos,tinfo->ypos,
1172 				&Machine->visible_area,pen,0);
1173 			tinfo++ ;
1174 		}
1175 	}
1176 }
1177 
1178 
toaplan1_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1179 void toaplan1_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1180 {
1181 	/* discover what data will be drawn */
1182 	toaplan1_find_sprites();
1183 	toaplan1_find_tiles(tiles_offsetx,tiles_offsety);
1184 
1185 	toaplan1_update_palette();
1186 	toaplan1_render(bitmap);
1187 }
1188 
rallybik_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1189 void rallybik_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1190 {
1191 	/* discover what data will be drawn */
1192 	rallybik_find_tiles();
1193 	rallybik_find_sprites();
1194 
1195 	toaplan1_update_palette();
1196 	rallybik_render(bitmap);
1197 }
1198 
1199 
1200 
1201 /****************************************************************************
1202 	Spriteram is always 1 frame ahead, suggesting spriteram buffering.
1203 	There are no CPU output registers that control this so we
1204 	assume it happens automatically every frame, at the end of vblank
1205 ****************************************************************************/
1206 
toaplan1_eof_callback(void)1207 void toaplan1_eof_callback(void)
1208 {
1209 	memcpy(toaplan1_buffered_videoram1,toaplan1_videoram1,VIDEORAM1_SIZE);
1210 	memcpy(toaplan1_buffered_videoram2,toaplan1_videoram2,VIDEORAM2_SIZE);
1211 }
1212 
rallybik_eof_callback(void)1213 void rallybik_eof_callback(void)
1214 {
1215 	buffer_spriteram_w(0,0);
1216 }
1217 
samesame_eof_callback(void)1218 void samesame_eof_callback(void)
1219 {
1220 	memcpy(toaplan1_buffered_videoram1,toaplan1_videoram1,VIDEORAM1_SIZE);
1221 	memcpy(toaplan1_buffered_videoram2,toaplan1_videoram2,VIDEORAM2_SIZE);
1222 	cpu_set_irq_line(0, MC68000_IRQ_2, HOLD_LINE);  /* Frame done */
1223 }
1224 
1225