1 /***************************************************************************
2 
3    Alpha 68k video emulation - Bryan McPhail, mish@tendril.co.uk
4 
5 ****************************************************************************/
6 
7 #include "driver.h"
8 #include "vidhrdw/generic.h"
9 
10 static struct tilemap *fix_tilemap;
11 static int bank_base,flipscreen;
12 
13 extern void (*alpha68k_video_banking)(int *bank, int data);
14 
15 extern int microcontroller_id;
16 
17 /******************************************************************************/
18 
alpha68k_flipscreen_w(int flip)19 void alpha68k_flipscreen_w(int flip)
20 {
21 	flipscreen = flip;
22 }
23 
alpha68k_V_video_bank_w(int bank)24 void alpha68k_V_video_bank_w(int bank)
25 {
26 	bank_base = bank&0xf;
27 }
28 
WRITE16_HANDLER(alpha68k_paletteram_w)29 WRITE16_HANDLER( alpha68k_paletteram_w )
30 {
31 	int newword;
32 	int r,g,b;
33 
34 	COMBINE_DATA(paletteram16 + offset);
35 	newword = paletteram16[offset];
36 
37 	r = ((newword >> 7) & 0x1e) | ((newword >> 14) & 0x01);
38 	g = ((newword >> 3) & 0x1e) | ((newword >> 13) & 0x01);
39 	b = ((newword << 1) & 0x1e) | ((newword >> 12) & 0x01);
40 
41 	palette_set_color(offset, pal5bit(r), pal5bit(g), pal5bit(b));
42 }
43 
44 /******************************************************************************/
45 
get_tile_info(int tile_index)46 static void get_tile_info(int tile_index)
47 {
48 	int tile  = videoram16[2*tile_index]   &0xff;
49 	int color = videoram16[2*tile_index+1] &0x0f;
50 
51 	tile=tile | (bank_base<<8);
52 
53 	SET_TILE_INFO(
54 			0,
55 			tile,
56 			color,
57 			0)
58 }
59 
WRITE16_HANDLER(alpha68k_videoram_w)60 WRITE16_HANDLER( alpha68k_videoram_w )
61 {
62 	/* Doh. */
63 	if(ACCESSING_LSB)
64 		if(ACCESSING_MSB)
65 			videoram16[offset] = data;
66 		else
67 			videoram16[offset] = data & 0xff;
68 	else
69 		videoram16[offset] = (data >> 8) & 0xff;
70 
71 	tilemap_mark_tile_dirty(fix_tilemap,offset/2);
72 }
73 
VIDEO_START(alpha68k)74 VIDEO_START( alpha68k )
75 {
76 	fix_tilemap = tilemap_create(get_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,32,32);
77 
78 	if (!fix_tilemap)
79 		return 1;
80 
81 	tilemap_set_transparent_pen(fix_tilemap,0);
82 
83 	return 0;
84 }
85 
86 /******************************************************************************/
87 /*AT*/
88 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int j,int s,int e)89 static void draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int j, int s, int e)
90 {
91 	int offs,mx,my,color,tile,fx,fy,i;
92 
93 	for (offs = s; offs < e; offs += 0x40 )
94 	{
95 		my = spriteram16[offs+3+(j<<1)];
96 		mx = spriteram16[offs+2+(j<<1)]<<1 | my>>15;
97 		my = -my & 0x1ff;
98 		mx = ((mx + 0x100) & 0x1ff) - 0x100;
99 		if (j==0 && s==0x7c0) my++;
100 /*ZT*/
101 		if (flipscreen) {
102 			mx=240-mx;
103 			my=240-my;
104 		}
105 
106 		for (i=0; i<0x40; i+=2) {
107 			tile  = spriteram16[offs+1+i+(0x800*j)+0x800];
108 			color = spriteram16[offs  +i+(0x800*j)+0x800]&0x7f;
109 
110 			fy=tile&0x8000;
111 			fx=tile&0x4000;
112 			tile&=0x3fff;
113 
114 			if (flipscreen) {
115 				if (fx) fx=0; else fx=1;
116 				if (fy) fy=0; else fy=1;
117 			}
118 
119 			if (color)
120 				drawgfx(bitmap,Machine->gfx[1],
121 					tile,
122 					color,
123 					fx,fy,
124 					mx,my,
125 					cliprect,TRANSPARENCY_PEN,0);
126 
127 			if (flipscreen)
128 				my=(my-16)&0x1ff;
129 			else
130 				my=(my+16)&0x1ff;
131 		}
132 	}
133 }
134 
135 /******************************************************************************/
136 
VIDEO_UPDATE(alpha68k_II)137 VIDEO_UPDATE( alpha68k_II )
138 {
139 	static int last_bank=0;
140 
141 	if (last_bank!=bank_base)
142 		tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
143 	last_bank=bank_base;
144 	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
145 
146 	fillbitmap(bitmap,Machine->pens[2047],cliprect);
147 /*AT*/
148 
149 	draw_sprites(bitmap,cliprect,0,0x07c0,0x0800);
150 	draw_sprites(bitmap,cliprect,1,0x0000,0x0800);
151 	draw_sprites(bitmap,cliprect,2,0x0000,0x0800);
152 	draw_sprites(bitmap,cliprect,0,0x0000,0x07c0);
153 /*ZT*/
154 	tilemap_draw(bitmap,cliprect,fix_tilemap,0,0);
155 }
156 
157 /******************************************************************************/
158 
159 /*
160 	Video banking:
161 
162 	Write to these locations in this order for correct bank:
163 
164 	20 28 30 for Bank 0
165 	60 28 30 for Bank 1
166 	20 68 30 etc
167 	60 68 30
168 	20 28 70
169 	60 28 70
170 	20 68 70
171 	60 68 70 for Bank 7
172 
173 	Actual data values written don't matter!
174 
175 */
176 
WRITE16_HANDLER(alpha68k_II_video_bank_w)177 WRITE16_HANDLER( alpha68k_II_video_bank_w )
178 {
179 	static int buffer_28,buffer_60,buffer_68;
180 
181 	switch (offset) {
182 		case 0x10: /* Reset */
183 			bank_base=buffer_28=buffer_60=buffer_68=0;
184 			return;
185 		case 0x14:
186 			buffer_28=1;
187 			return;
188 		case 0x18:
189 			if (buffer_68) {if (buffer_60) bank_base=3; else bank_base=2; }
190 			if (buffer_28) {if (buffer_60) bank_base=1; else bank_base=0; }
191 			return;
192 		case 0x30:
193 			bank_base=buffer_28=buffer_68=0;
194 			buffer_60=1;
195 			return;
196 		case 0x34:
197 			buffer_68=1;
198 			return;
199 		case 0x38:
200 			if (buffer_68) {if (buffer_60) bank_base=7; else bank_base=6; }
201 			if (buffer_28) {if (buffer_60) bank_base=5; else bank_base=4; }
202 			return;
203 		case 0x08: /* Graphics flags?  Not related to fix chars anyway */
204 		case 0x0c:
205 		case 0x28:
206 		case 0x2c:
207 			return;
208 	}
209 
210 	log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x \n",offset);
211 }
212 
213 /******************************************************************************/
214 
WRITE16_HANDLER(alpha68k_V_video_control_w)215 WRITE16_HANDLER( alpha68k_V_video_control_w )
216 {
217 	switch (offset) {
218 		case 0x08: /* Graphics flags?  Not related to fix chars anyway */
219 		case 0x0c:
220 		case 0x28:
221 		case 0x2c:
222 			return;
223 	}
224 }
225 
draw_sprites_V(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int j,int s,int e,int fx_mask,int fy_mask,int sprite_mask)226 static void draw_sprites_V(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int j, int s, int e, int fx_mask, int fy_mask, int sprite_mask)
227 {
228 	int offs,mx,my,color,tile,fx,fy,i;
229 
230 	for (offs = s; offs < e; offs += 0x40 )
231 	{
232 /*AT*/
233 
234 		my = spriteram16[offs+3+(j<<1)];
235 		mx = spriteram16[offs+2+(j<<1)]<<1 | my>>15;
236 		my = -my & 0x1ff;
237 		mx = ((mx + 0x100) & 0x1ff) - 0x100;
238 		if (j==0 && s==0x7c0) my++;
239 /*ZT*/
240 		if (flipscreen) {
241 			mx=240-mx;
242 			my=240-my;
243 		}
244 
245 		for (i=0; i<0x40; i+=2) {
246 			tile  = spriteram16[offs+1+i+(0x800*j)+0x800];
247 			color = spriteram16[offs  +i+(0x800*j)+0x800]&0xff;
248 
249 			fx=tile&fx_mask;
250 			fy=tile&fy_mask;
251 			tile=tile&sprite_mask;
252 			if (tile>0x4fff) continue;
253 
254 			if (flipscreen) {
255 				if (fx) fx=0; else fx=1;
256 				if (fy) fy=0; else fy=1;
257 			}
258 
259 			if (color)
260 				drawgfx(bitmap,Machine->gfx[1],
261 					tile,
262 					color,
263 					fx,fy,
264 					mx,my,
265 					cliprect,TRANSPARENCY_PEN,0);
266 
267 			if (flipscreen)
268 				my=(my-16)&0x1ff;
269 			else
270 				my=(my+16)&0x1ff;
271 		}
272 	}
273 }
274 
VIDEO_UPDATE(alpha68k_V)275 VIDEO_UPDATE( alpha68k_V )
276 {
277 	static int last_bank=0;
278 
279 	if (last_bank!=bank_base)
280 		tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
281 	last_bank=bank_base;
282 	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
283 
284 	fillbitmap(bitmap,Machine->pens[4095],cliprect);
285 
286 	/* This appears to be correct priority */
287 	if (microcontroller_id == 0x8814) /* Sky Adventure */
288 	{
289 		draw_sprites_V(bitmap,cliprect,0,0x07c0,0x0800,0,0x8000,0x7fff);
290 		draw_sprites_V(bitmap,cliprect,1,0x0000,0x0800,0,0x8000,0x7fff);
291 		/*AT: *KLUDGE* fixes priest priority in level 1(could be a game bug)*/
292 		if (spriteram16[0x1bde]==0x24 && (spriteram16[0x1bdf]>>8)==0x3b) {
293 			draw_sprites_V(bitmap,cliprect,2,0x03c0,0x0800,0,0x8000,0x7fff);
294 			draw_sprites_V(bitmap,cliprect,2,0x0000,0x03c0,0,0x8000,0x7fff);
295 		} else
296 		draw_sprites_V(bitmap,cliprect,2,0x0000,0x0800,0,0x8000,0x7fff);
297 		draw_sprites_V(bitmap,cliprect,0,0x0000,0x07c0,0,0x8000,0x7fff);
298 	}
299 	else	/* gangwars */
300 	{
301 		draw_sprites_V(bitmap,cliprect,0,0x07c0,0x0800,0x8000,0,0x7fff);
302 		draw_sprites_V(bitmap,cliprect,1,0x0000,0x0800,0x8000,0,0x7fff);
303 		draw_sprites_V(bitmap,cliprect,2,0x0000,0x0800,0x8000,0,0x7fff);
304 		draw_sprites_V(bitmap,cliprect,0,0x0000,0x07c0,0x8000,0,0x7fff);
305 	}
306 
307 	tilemap_draw(bitmap,cliprect,fix_tilemap,0,0);
308 }
309 
VIDEO_UPDATE(alpha68k_V_sb)310 VIDEO_UPDATE( alpha68k_V_sb )
311 {
312 	static int last_bank=0;
313 
314 	if (last_bank!=bank_base)
315 		tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
316 	last_bank=bank_base;
317 	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
318 
319 	fillbitmap(bitmap,Machine->pens[4095],cliprect);
320 
321 	/* This appears to be correct priority */
322 	draw_sprites_V(bitmap,cliprect,0,0x07c0,0x0800,0x4000,0x8000,0x3fff);
323 	draw_sprites_V(bitmap,cliprect,1,0x0000,0x0800,0x4000,0x8000,0x3fff);
324 	draw_sprites_V(bitmap,cliprect,2,0x0000,0x0800,0x4000,0x8000,0x3fff);
325 	draw_sprites_V(bitmap,cliprect,0,0x0000,0x07c0,0x4000,0x8000,0x3fff);
326 
327 	tilemap_draw(bitmap,cliprect,fix_tilemap,0,0);
328 }
329 
330 /******************************************************************************/
331 /*AT*/
332 
draw_sprites2(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int c,int d,int yshift)333 static void draw_sprites2(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int c, int d, int yshift)
334 {
335 	int data, offs, mx, my, tile, color, fy, i;
336 	UINT8 *color_prom = memory_region(REGION_USER1);
337 	struct GfxElement *gfx = Machine->gfx[0];
338 
339 	for (offs=0; offs<0x400; offs+=0x20)
340 	{
341 		mx = spriteram16[offs+c];
342 		my = (yshift-(mx>>8)) & 0xff;
343 		mx &= 0xff;
344 
345 		for (i=0; i<0x20; i++)
346 		{
347 			data = spriteram16[offs+d+i];
348 			tile = data & 0x3fff;
349 			fy = data & 0x4000;
350 			color = color_prom[tile<<1|data>>15];
351 
352 			drawgfx(bitmap, gfx, tile, color, 0, fy, mx, my,
353 					cliprect, TRANSPARENCY_PEN, 0);
354 
355 			my = (my + 8) & 0xff;
356 		}
357 	}
358 }
359 
VIDEO_UPDATE(alpha68k_I)360 VIDEO_UPDATE( alpha68k_I )
361 {
362 	int yshift = (microcontroller_id == 0x890a) ? 1 : 0; /* The Next Space is 1 pixel off*/
363 
364 	fillbitmap(bitmap,Machine->pens[0],cliprect);
365 
366 	/* This appears to be correct priority */
367 	draw_sprites2(bitmap,cliprect,2,0x0800,yshift);
368 	draw_sprites2(bitmap,cliprect,3,0x0c00,yshift);
369 	draw_sprites2(bitmap,cliprect,1,0x0400,yshift);
370 }
371 /*ZT*/
372 /******************************************************************************/
373 
PALETTE_INIT(kyros)374 PALETTE_INIT( kyros )
375 {
376 	int i,bit0,bit1,bit2,bit3,r,g,b;
377 
378 	for (i = 0;i < 256;i++)
379 	{
380 		bit0 = (color_prom[0] >> 0) & 0x01;
381 		bit1 = (color_prom[0] >> 1) & 0x01;
382 		bit2 = (color_prom[0] >> 2) & 0x01;
383 		bit3 = (color_prom[0] >> 3) & 0x01;
384 		r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
385 
386 		bit0 = (color_prom[0x100] >> 0) & 0x01;
387 		bit1 = (color_prom[0x100] >> 1) & 0x01;
388 		bit2 = (color_prom[0x100] >> 2) & 0x01;
389 		bit3 = (color_prom[0x100] >> 3) & 0x01;
390 		g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
391 
392 		bit0 = (color_prom[0x200] >> 0) & 0x01;
393 		bit1 = (color_prom[0x200] >> 1) & 0x01;
394 		bit2 = (color_prom[0x200] >> 2) & 0x01;
395 		bit3 = (color_prom[0x200] >> 3) & 0x01;
396 		b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
397 
398 		palette_set_color(i,r,g,b);
399 		color_prom++;
400 	}
401 
402 	color_prom += 0x200;
403 
404 	for (i = 0;i < 256;i++)
405 	{
406 		*colortable++ = ((color_prom[0] & 0x0f) << 4) | (color_prom[0x100] & 0x0f);
407 		color_prom++;
408 	}
409 }
410 
PALETTE_INIT(paddlem)411 PALETTE_INIT( paddlem )
412 {
413 	int i,bit0,bit1,bit2,bit3,r,g,b;
414 
415 	for (i = 0;i < 256;i++)
416 	{
417 		bit0 = (color_prom[0] >> 0) & 0x01;
418 		bit1 = (color_prom[0] >> 1) & 0x01;
419 		bit2 = (color_prom[0] >> 2) & 0x01;
420 		bit3 = (color_prom[0] >> 3) & 0x01;
421 		r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
422 
423 		bit0 = (color_prom[0x100] >> 0) & 0x01;
424 		bit1 = (color_prom[0x100] >> 1) & 0x01;
425 		bit2 = (color_prom[0x100] >> 2) & 0x01;
426 		bit3 = (color_prom[0x100] >> 3) & 0x01;
427 		g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
428 
429 		bit0 = (color_prom[0x200] >> 0) & 0x01;
430 		bit1 = (color_prom[0x200] >> 1) & 0x01;
431 		bit2 = (color_prom[0x200] >> 2) & 0x01;
432 		bit3 = (color_prom[0x200] >> 3) & 0x01;
433 		b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
434 
435 		palette_set_color(i,r,g,b);
436 		color_prom++;
437 	}
438 
439 	/* Fill in clut */
440 	color_prom += 0x200;
441 	for (i=0; i<1024; i++) colortable[i] = color_prom[i]|(color_prom[i+0x400]<<4);
442 }
443 
kyros_video_banking(int * bank,int data)444 void kyros_video_banking(int *bank, int data)
445 {
446 	*bank = (data>>13 & 4) | (data>>10 & 3);
447 }
448 
kyros_draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int c,int d)449 static void kyros_draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int c,int d)
450 {
451 	int offs,mx,my,color,tile,i,bank,fy,fx;
452 	int data;
453 	UINT8 *color_prom = memory_region(REGION_USER1);
454 
455 /* AT */
456 	for (offs=0; offs<0x400; offs+=0x20)
457 	{
458 		mx = spriteram16[offs+c];
459 		my = -(mx>>8) & 0xff;
460 		mx &= 0xff;
461 
462 		if (flipscreen) {
463 			my=249-my;
464 		}
465 
466 		for (i=0; i<0x20; i++)
467 		{
468 			data = spriteram16[offs+d+i];
469 			if (data!=0x20)
470 			{
471 				color = color_prom[(data>>1&0x1000)|(data&0xffc)|(data>>14&3)];
472 				if (color!=0xff)
473 				{
474 					fy = data & 0x1000;
475 					fx = 0;
476 
477 					if(flipscreen)
478 					{
479 						if (fy) fy=0; else fy=1;
480 						fx = 1;
481 					}
482 
483 					tile = (data>>3 & 0x400) | (data & 0x3ff);
484 					alpha68k_video_banking(&bank, data);
485 					drawgfx(bitmap, Machine->gfx[bank], tile, color, fx, fy, mx, my,
486 							cliprect, TRANSPARENCY_PEN, 0);
487 				}
488 			}
489 /* ZT */
490 			if(flipscreen)
491 				my=(my-8)&0xff;
492 			else
493 				my=(my+8)&0xff;
494 		}
495 	}
496 }
497 
VIDEO_UPDATE(kyros)498 VIDEO_UPDATE( kyros )
499 {
500 	fillbitmap(bitmap,*videoram16&0xff,cliprect); /*AT*/
501 
502 	kyros_draw_sprites(bitmap,cliprect,2,0x0800);
503 	kyros_draw_sprites(bitmap,cliprect,3,0x0c00);
504 	kyros_draw_sprites(bitmap,cliprect,1,0x0400);
505 }
506 
507 /******************************************************************************/
508 
sstingry_draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int c,int d)509 static void sstingry_draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int c,int d)
510 {
511 /* AT */
512 	int data,offs,mx,my,color,tile,i,bank,fy,fx;
513 
514 	for (offs=0; offs<0x400; offs+=0x20)
515 	{
516 		mx = spriteram16[offs+c];
517 		my = -(mx>>8) & 0xff;
518 		mx &= 0xff;
519 		if (mx > 0xf8) mx -= 0x100;
520 
521 		if (flipscreen) {
522 			my=249-my;
523 		}
524 
525 		for (i=0; i<0x20; i++)
526 		{
527 			data = spriteram16[offs+d+i];
528 			if (data!=0x40)
529 			{
530 				fy = data & 0x1000;
531 				fx = 0;
532 
533 				if(flipscreen)
534 				{
535 					if (fy) fy=0; else fy=1;
536 					fx = 1;
537 				}
538 
539 				color = (data>>7 & 0x18) | (data>>13 & 7);
540 				tile = data & 0x3ff;
541 				bank = data>>10 & 3;
542 				drawgfx(bitmap, Machine->gfx[bank], tile, color, fx, fy, mx, my,
543 						cliprect, TRANSPARENCY_PEN, 0);
544 			}
545 /* ZT */
546 			if(flipscreen)
547 				my=(my-8)&0xff;
548 			else
549 				my=(my+8)&0xff;
550 		}
551 	}
552 }
553 
VIDEO_UPDATE(sstingry)554 VIDEO_UPDATE( sstingry )
555 {
556 	fillbitmap(bitmap,*videoram16 & 0xff,cliprect); /* AT */
557 
558 	sstingry_draw_sprites(bitmap,cliprect,2,0x0800);
559 	sstingry_draw_sprites(bitmap,cliprect,3,0x0c00);
560 	sstingry_draw_sprites(bitmap,cliprect,1,0x0400);
561 }
562