diff options
Diffstat (limited to 'src/mame/video/alpha68k.c')
-rw-r--r-- | src/mame/video/alpha68k.c | 560 |
1 files changed, 560 insertions, 0 deletions
diff --git a/src/mame/video/alpha68k.c b/src/mame/video/alpha68k.c new file mode 100644 index 00000000000..7c013e80cc1 --- /dev/null +++ b/src/mame/video/alpha68k.c @@ -0,0 +1,560 @@ +/*************************************************************************** + + Alpha 68k video emulation - Bryan McPhail, mish@tendril.co.uk + +****************************************************************************/ + +#include "driver.h" + +static tilemap *fix_tilemap; +static int bank_base,flipscreen; + +extern void (*alpha68k_video_banking)(int *bank, int data); + +extern int alpha68k_microcontroller_id; + +/******************************************************************************/ + +void alpha68k_flipscreen_w(int flip) +{ + flipscreen = flip; +} + +void alpha68k_V_video_bank_w(int bank) +{ + bank_base = bank&0xf; +} + +WRITE16_HANDLER( alpha68k_paletteram_w ) +{ + int newword; + int r,g,b; + + COMBINE_DATA(paletteram16 + offset); + newword = paletteram16[offset]; + + r = ((newword >> 7) & 0x1e) | ((newword >> 14) & 0x01); + g = ((newword >> 3) & 0x1e) | ((newword >> 13) & 0x01); + b = ((newword << 1) & 0x1e) | ((newword >> 12) & 0x01); + + palette_set_color_rgb(Machine,offset,pal5bit(r),pal5bit(g),pal5bit(b)); +} + +/******************************************************************************/ + +static TILE_GET_INFO( get_tile_info ) +{ + int tile = videoram16[2*tile_index] &0xff; + int color = videoram16[2*tile_index+1] &0x0f; + + tile=tile | (bank_base<<8); + + SET_TILE_INFO(0, tile, color, 0); +} + +WRITE16_HANDLER( alpha68k_videoram_w ) +{ + /* Doh. */ + if(ACCESSING_LSB) + if(ACCESSING_MSB) + videoram16[offset] = data; + else + videoram16[offset] = data & 0xff; + else + videoram16[offset] = (data >> 8) & 0xff; + + tilemap_mark_tile_dirty(fix_tilemap,offset/2); +} + +VIDEO_START( alpha68k ) +{ + fix_tilemap = tilemap_create(get_tile_info,tilemap_scan_cols,TILEMAP_TYPE_PEN,8,8,32,32); + + tilemap_set_transparent_pen(fix_tilemap,0); +} + +/******************************************************************************/ +//AT +static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int j, int s, int e) +{ + int offs,mx,my,color,tile,fx,fy,i; + + for (offs = s; offs < e; offs += 0x40 ) + { + my = spriteram16[offs+3+(j<<1)]; + mx = spriteram16[offs+2+(j<<1)]<<1 | my>>15; + my = -my & 0x1ff; + mx = ((mx + 0x100) & 0x1ff) - 0x100; + if (j==0 && s==0x7c0) my++; +//ZT + if (flipscreen) { + mx=240-mx; + my=240-my; + } + + for (i=0; i<0x40; i+=2) { + tile = spriteram16[offs+1+i+(0x800*j)+0x800]; + color = spriteram16[offs +i+(0x800*j)+0x800]&0x7f; + + fy=tile&0x8000; + fx=tile&0x4000; + tile&=0x3fff; + + if (flipscreen) { + if (fx) fx=0; else fx=1; + if (fy) fy=0; else fy=1; + } + + if (color) + drawgfx(bitmap,machine->gfx[1], + tile, + color, + fx,fy, + mx,my, + cliprect,TRANSPARENCY_PEN,0); + + if (flipscreen) + my=(my-16)&0x1ff; + else + my=(my+16)&0x1ff; + } + } +} + +/******************************************************************************/ + +VIDEO_UPDATE( alpha68k_II ) +{ + static int last_bank=0; + + if (last_bank!=bank_base) + tilemap_mark_all_tiles_dirty(ALL_TILEMAPS); + last_bank=bank_base; + tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); + + fillbitmap(bitmap,machine->pens[2047],cliprect); +//AT + draw_sprites(machine, bitmap,cliprect,0,0x07c0,0x0800); + draw_sprites(machine, bitmap,cliprect,1,0x0000,0x0800); + draw_sprites(machine, bitmap,cliprect,2,0x0000,0x0800); + draw_sprites(machine, bitmap,cliprect,0,0x0000,0x07c0); +//ZT + tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); + return 0; +} + +/******************************************************************************/ + +/* + Video banking: + + Write to these locations in this order for correct bank: + + 20 28 30 for Bank 0 + 60 28 30 for Bank 1 + 20 68 30 etc + 60 68 30 + 20 28 70 + 60 28 70 + 20 68 70 + 60 68 70 for Bank 7 + + Actual data values written don't matter! + +*/ + +WRITE16_HANDLER( alpha68k_II_video_bank_w ) +{ + static int buffer_28,buffer_60,buffer_68; + + switch (offset) { + case 0x10: /* Reset */ + bank_base=buffer_28=buffer_60=buffer_68=0; + return; + case 0x14: + if (buffer_60) bank_base=1; else bank_base=0; + buffer_28=1; + return; + case 0x18: + if (buffer_68) {if (buffer_60) bank_base=3; else bank_base=2; } + if (buffer_28) {if (buffer_60) bank_base=1; else bank_base=0; } + return; + case 0x30: + buffer_28=buffer_68=0; bank_base=1; + buffer_60=1; + return; + case 0x34: + if (buffer_60) bank_base=3; else bank_base=2; + buffer_68=1; + return; + case 0x38: + if (buffer_68) {if (buffer_60) bank_base=7; else bank_base=6; } + if (buffer_28) {if (buffer_60) bank_base=5; else bank_base=4; } + return; + case 0x08: /* Graphics flags? Not related to fix chars anyway */ + case 0x0c: + case 0x28: + case 0x2c: + return; + } + + logerror("%04x \n",offset); +} + +/******************************************************************************/ + +WRITE16_HANDLER( alpha68k_V_video_control_w ) +{ + switch (offset) { + case 0x08: /* Graphics flags? Not related to fix chars anyway */ + case 0x0c: + case 0x28: + case 0x2c: + return; + } +} + +static void draw_sprites_V(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int j, int s, int e, int fx_mask, int fy_mask, int sprite_mask) +{ + int offs,mx,my,color,tile,fx,fy,i; + + for (offs = s; offs < e; offs += 0x40 ) + { +//AT + my = spriteram16[offs+3+(j<<1)]; + mx = spriteram16[offs+2+(j<<1)]<<1 | my>>15; + my = -my & 0x1ff; + mx = ((mx + 0x100) & 0x1ff) - 0x100; + if (j==0 && s==0x7c0) my++; +//ZT + if (flipscreen) { + mx=240-mx; + my=240-my; + } + + for (i=0; i<0x40; i+=2) { + tile = spriteram16[offs+1+i+(0x800*j)+0x800]; + color = spriteram16[offs +i+(0x800*j)+0x800]&0xff; + + fx=tile&fx_mask; + fy=tile&fy_mask; + tile=tile&sprite_mask; + if (tile>0x4fff) continue; + + if (flipscreen) { + if (fx) fx=0; else fx=1; + if (fy) fy=0; else fy=1; + } + + if (color) + drawgfx(bitmap,machine->gfx[1], + tile, + color, + fx,fy, + mx,my, + cliprect,TRANSPARENCY_PEN,0); + + if (flipscreen) + my=(my-16)&0x1ff; + else + my=(my+16)&0x1ff; + } + } +} + +VIDEO_UPDATE( alpha68k_V ) +{ + static int last_bank=0; + + if (last_bank!=bank_base) + tilemap_mark_all_tiles_dirty(ALL_TILEMAPS); + last_bank=bank_base; + tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); + + fillbitmap(bitmap,machine->pens[4095],cliprect); + + /* This appears to be correct priority */ + if (alpha68k_microcontroller_id == 0x8814) /* Sky Adventure */ + { + draw_sprites_V(machine, bitmap,cliprect,0,0x07c0,0x0800,0,0x8000,0x7fff); + draw_sprites_V(machine, bitmap,cliprect,1,0x0000,0x0800,0,0x8000,0x7fff); + //AT: *KLUDGE* fixes priest priority in level 1(could be a game bug) + if (spriteram16[0x1bde]==0x24 && (spriteram16[0x1bdf]>>8)==0x3b) { + draw_sprites_V(machine, bitmap,cliprect,2,0x03c0,0x0800,0,0x8000,0x7fff); + draw_sprites_V(machine, bitmap,cliprect,2,0x0000,0x03c0,0,0x8000,0x7fff); + } else + draw_sprites_V(machine, bitmap,cliprect,2,0x0000,0x0800,0,0x8000,0x7fff); + draw_sprites_V(machine, bitmap,cliprect,0,0x0000,0x07c0,0,0x8000,0x7fff); + } + else /* gangwars */ + { + draw_sprites_V(machine, bitmap,cliprect,0,0x07c0,0x0800,0x8000,0,0x7fff); + draw_sprites_V(machine, bitmap,cliprect,1,0x0000,0x0800,0x8000,0,0x7fff); + draw_sprites_V(machine, bitmap,cliprect,2,0x0000,0x0800,0x8000,0,0x7fff); + draw_sprites_V(machine, bitmap,cliprect,0,0x0000,0x07c0,0x8000,0,0x7fff); + } + + tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); + return 0; +} + +VIDEO_UPDATE( alpha68k_V_sb ) +{ + static int last_bank=0; + + if (last_bank!=bank_base) + tilemap_mark_all_tiles_dirty(ALL_TILEMAPS); + last_bank=bank_base; + tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); + + fillbitmap(bitmap,machine->pens[4095],cliprect); + + /* This appears to be correct priority */ + draw_sprites_V(machine,bitmap,cliprect,0,0x07c0,0x0800,0x4000,0x8000,0x3fff); + draw_sprites_V(machine,bitmap,cliprect,1,0x0000,0x0800,0x4000,0x8000,0x3fff); + draw_sprites_V(machine,bitmap,cliprect,2,0x0000,0x0800,0x4000,0x8000,0x3fff); + draw_sprites_V(machine,bitmap,cliprect,0,0x0000,0x07c0,0x4000,0x8000,0x3fff); + + tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); + return 0; +} + +/******************************************************************************/ +//AT +static void draw_sprites_I(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int c, int d, int yshift) +{ + int data, offs, mx, my, tile, color, fy, i; + UINT8 *color_prom = memory_region(REGION_USER1); + gfx_element *gfx = machine->gfx[0]; + + for (offs=0; offs<0x400; offs+=0x20) + { + mx = spriteram16[offs+c]; + my = (yshift-(mx>>8)) & 0xff; + mx &= 0xff; + + for (i=0; i<0x20; i++) + { + data = spriteram16[offs+d+i]; + tile = data & 0x3fff; + fy = data & 0x4000; + color = color_prom[tile<<1|data>>15]; + + drawgfx(bitmap, gfx, tile, color, 0, fy, mx, my, + cliprect, TRANSPARENCY_PEN, 0); + + my = (my + 8) & 0xff; + } + } +} + +VIDEO_UPDATE( alpha68k_I ) +{ + int yshift = (alpha68k_microcontroller_id == 0x890a) ? 1 : 0; // The Next Space is 1 pixel off + + fillbitmap(bitmap,machine->pens[0],cliprect); + + /* This appears to be correct priority */ + draw_sprites_I(machine, bitmap,cliprect,2,0x0800,yshift); + draw_sprites_I(machine, bitmap,cliprect,3,0x0c00,yshift); + draw_sprites_I(machine, bitmap,cliprect,1,0x0400,yshift); + return 0; +} +//ZT +/******************************************************************************/ + +PALETTE_INIT( kyros ) +{ + int i,bit0,bit1,bit2,bit3,r,g,b; + + for (i = 0;i < 256;i++) + { + bit0 = (color_prom[0] >> 0) & 0x01; + bit1 = (color_prom[0] >> 1) & 0x01; + bit2 = (color_prom[0] >> 2) & 0x01; + bit3 = (color_prom[0] >> 3) & 0x01; + r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (color_prom[0x100] >> 0) & 0x01; + bit1 = (color_prom[0x100] >> 1) & 0x01; + bit2 = (color_prom[0x100] >> 2) & 0x01; + bit3 = (color_prom[0x100] >> 3) & 0x01; + g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (color_prom[0x200] >> 0) & 0x01; + bit1 = (color_prom[0x200] >> 1) & 0x01; + bit2 = (color_prom[0x200] >> 2) & 0x01; + bit3 = (color_prom[0x200] >> 3) & 0x01; + b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + palette_set_color(machine,i,MAKE_RGB(r,g,b)); + color_prom++; + } + + color_prom += 0x200; + + for (i = 0;i < 256;i++) + { + *colortable++ = ((color_prom[0] & 0x0f) << 4) | (color_prom[0x100] & 0x0f); + color_prom++; + } +} + +PALETTE_INIT( paddlem ) +{ + int i,bit0,bit1,bit2,bit3,r,g,b; + + for (i = 0;i < 256;i++) + { + bit0 = (color_prom[0] >> 0) & 0x01; + bit1 = (color_prom[0] >> 1) & 0x01; + bit2 = (color_prom[0] >> 2) & 0x01; + bit3 = (color_prom[0] >> 3) & 0x01; + r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (color_prom[0x100] >> 0) & 0x01; + bit1 = (color_prom[0x100] >> 1) & 0x01; + bit2 = (color_prom[0x100] >> 2) & 0x01; + bit3 = (color_prom[0x100] >> 3) & 0x01; + g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (color_prom[0x200] >> 0) & 0x01; + bit1 = (color_prom[0x200] >> 1) & 0x01; + bit2 = (color_prom[0x200] >> 2) & 0x01; + bit3 = (color_prom[0x200] >> 3) & 0x01; + b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + palette_set_color(machine,i,MAKE_RGB(r,g,b)); + color_prom++; + } + + /* Fill in clut */ + color_prom += 0x200; + for (i=0; i<1024; i++) colortable[i] = color_prom[i]|(color_prom[i+0x400]<<4); +} + +void kyros_video_banking(int *bank, int data) +{ + *bank = (data>>13 & 4) | (data>>10 & 3); +} + +void jongbou_video_banking(int *bank, int data) +{ + *bank = (data>>11 & 4) | (data>>10 & 3); +} + +static void kyros_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int c,int d) +{ + int offs,mx,my,color,tile,i,bank,fy,fx; + int data; + UINT8 *color_prom = memory_region(REGION_USER1); + +//AT + for (offs=0; offs<0x400; offs+=0x20) + { + mx = spriteram16[offs+c]; + my = -(mx>>8) & 0xff; + mx &= 0xff; + + if (flipscreen) { + my=249-my; + } + + for (i=0; i<0x20; i++) + { + data = spriteram16[offs+d+i]; + if (data!=0x20) + { + color = color_prom[(data>>1&0x1000)|(data&0xffc)|(data>>14&3)]; + if (color!=0xff) + { + fy = data & 0x1000; + fx = 0; + + if(flipscreen) + { + if (fy) fy=0; else fy=1; + fx = 1; + } + + tile = (data>>3 & 0x400) | (data & 0x3ff); + alpha68k_video_banking(&bank, data); + drawgfx(bitmap, machine->gfx[bank], tile, color, fx, fy, mx, my, + cliprect, TRANSPARENCY_PEN, 0); + } + } +//ZT + if(flipscreen) + my=(my-8)&0xff; + else + my=(my+8)&0xff; + } + } +} + +VIDEO_UPDATE( kyros ) +{ + fillbitmap(bitmap,*videoram16 & 0xff,cliprect); //AT + + kyros_draw_sprites(machine, bitmap,cliprect,2,0x0800); + kyros_draw_sprites(machine, bitmap,cliprect,3,0x0c00); + kyros_draw_sprites(machine, bitmap,cliprect,1,0x0400); + return 0; +} + +/******************************************************************************/ + +static void sstingry_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int c,int d) +{ +//AT + int data,offs,mx,my,color,tile,i,bank,fy,fx; + + for (offs=0; offs<0x400; offs+=0x20) + { + mx = spriteram16[offs+c]; + my = -(mx>>8) & 0xff; + mx &= 0xff; + if (mx > 0xf8) mx -= 0x100; + + if (flipscreen) { + my=249-my; + } + + for (i=0; i<0x20; i++) + { + data = spriteram16[offs+d+i]; + if (data!=0x40) + { + fy = data & 0x1000; + fx = 0; + + if(flipscreen) + { + if (fy) fy=0; else fy=1; + fx = 1; + } + + color = (data>>7 & 0x18) | (data>>13 & 7); + tile = data & 0x3ff; + bank = data>>10 & 3; + drawgfx(bitmap, machine->gfx[bank], tile, color, fx, fy, mx, my, + cliprect, TRANSPARENCY_PEN, 0); + } +//ZT + if(flipscreen) + my=(my-8)&0xff; + else + my=(my+8)&0xff; + } + } +} + +VIDEO_UPDATE( sstingry ) +{ + fillbitmap(bitmap,*videoram16 & 0xff,cliprect); //AT + + sstingry_draw_sprites(machine, bitmap,cliprect,2,0x0800); + sstingry_draw_sprites(machine, bitmap,cliprect,3,0x0c00); + sstingry_draw_sprites(machine, bitmap,cliprect,1,0x0400); + return 0; +} |