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