diff options
Diffstat (limited to 'src/mame/video/combatsc.c')
-rw-r--r-- | src/mame/video/combatsc.c | 640 |
1 files changed, 640 insertions, 0 deletions
diff --git a/src/mame/video/combatsc.c b/src/mame/video/combatsc.c new file mode 100644 index 00000000000..2f7107fe1c1 --- /dev/null +++ b/src/mame/video/combatsc.c @@ -0,0 +1,640 @@ +/*************************************************************************** + + video.c + + Functions to emulate the video hardware of the machine. + +***************************************************************************/ + +#include "driver.h" +#include "video/konamiic.h" + +static tilemap *bg_tilemap[2]; +static tilemap *textlayer; +static UINT8 *private_spriteram[2]; +static int priority; + +static UINT8 *combasc_io_ram; +static int combasc_vreg; + +static int combasc_bank_select; /* 0x00..0x1f */ +static int combasc_video_circuit; /* 0 or 1 */ +static UINT8 *combasc_page[2]; +static UINT8 combasc_scrollram0[0x40]; +static UINT8 combasc_scrollram1[0x40]; +static UINT8 *combasc_scrollram; + + +PALETTE_INIT( combasc ) +{ + int i,pal,clut = 0; + for( pal=0; pal<8; pal++ ) + { + switch( pal ) + { + case 0: /* other sprites */ + case 2: /* other sprites(alt) */ + clut = 1; /* 0 is wrong for Firing Range III targets */ + break; + + case 4: /* player sprites */ + case 6: /* player sprites(alt) */ + clut = 2; + break; + + case 1: /* background */ + case 3: /* background(alt) */ + clut = 1; + break; + + case 5: /* foreground tiles */ + case 7: /* foreground tiles(alt) */ + clut = 3; + break; + } + + for( i=0; i<256; i++ ) + { + if ((pal & 1) == 0) /* sprites */ + { + if (color_prom[256 * clut + i] == 0) + *(colortable++) = 0; + else + *(colortable++) = 16 * pal + color_prom[256 * clut + i]; + } + else /* chars */ + *(colortable++) = 16 * pal + color_prom[256 * clut + i]; + } + } +} + +PALETTE_INIT( combascb ) +{ + int i,pal; + for( pal=0; pal<8; pal++ ) + { + for( i=0; i<256; i++ ) + { + if ((pal & 1) == 0) /* sprites */ + *(colortable++) = 16 * pal + (color_prom[i] ^ 0x0f); + else /* chars */ + *(colortable++) = 16 * pal + (i & 0x0f); /* no lookup? */ + } + } +} + +/*************************************************************************** + + Callbacks for the TileMap code + +***************************************************************************/ + +static TILE_GET_INFO( get_tile_info0 ) +{ + UINT8 attributes = combasc_page[0][tile_index]; + int bank = 4*((combasc_vreg & 0x0f) - 1); + int number,color; + + if (bank < 0) bank = 0; + if ((attributes & 0xb0) == 0) bank = 0; /* text bank */ + + if (attributes & 0x80) bank += 1; + if (attributes & 0x10) bank += 2; + if (attributes & 0x20) bank += 4; + + color = ((K007121_ctrlram[0][6]&0x10)*2+16) + (attributes & 0x0f); + + number = combasc_page[0][tile_index + 0x400] + 256*bank; + + SET_TILE_INFO( + 0, + number, + color, + 0); + tileinfo->category = (attributes & 0x40) >> 6; +} + +static TILE_GET_INFO( get_tile_info1 ) +{ + UINT8 attributes = combasc_page[1][tile_index]; + int bank = 4*((combasc_vreg >> 4) - 1); + int number, color; + + if (bank < 0) bank = 0; + if ((attributes & 0xb0) == 0) bank = 0; /* text bank */ + + if (attributes & 0x80) bank += 1; + if (attributes & 0x10) bank += 2; + if (attributes & 0x20) bank += 4; + + color = ((K007121_ctrlram[1][6]&0x10)*2+16+4*16) + (attributes & 0x0f); + + number = combasc_page[1][tile_index + 0x400] + 256*bank; + + SET_TILE_INFO( + 1, + number, + color, + 0); + tileinfo->category = (attributes & 0x40) >> 6; +} + +static TILE_GET_INFO( get_text_info ) +{ + UINT8 attributes = combasc_page[0][tile_index + 0x800]; + int number = combasc_page[0][tile_index + 0xc00]; + int color = 16 + (attributes & 0x0f); + + SET_TILE_INFO( + 0, + number, + color, + 0); +} + + +static TILE_GET_INFO( get_tile_info0_bootleg ) +{ + UINT8 attributes = combasc_page[0][tile_index]; + int bank = 4*((combasc_vreg & 0x0f) - 1); + int number, pal, color; + + if (bank < 0) bank = 0; + if ((attributes & 0xb0) == 0) bank = 0; /* text bank */ + + if (attributes & 0x80) bank += 1; + if (attributes & 0x10) bank += 2; + if (attributes & 0x20) bank += 4; + + pal = (bank == 0 || bank >= 0x1c || (attributes & 0x40)) ? 1 : 3; + color = pal*16;// + (attributes & 0x0f); + number = combasc_page[0][tile_index + 0x400] + 256*bank; + + SET_TILE_INFO( + 0, + number, + color, + 0); +} + +static TILE_GET_INFO( get_tile_info1_bootleg ) +{ + UINT8 attributes = combasc_page[1][tile_index]; + int bank = 4*((combasc_vreg >> 4) - 1); + int number, pal, color; + + if (bank < 0) bank = 0; + if ((attributes & 0xb0) == 0) bank = 0; /* text bank */ + + if (attributes & 0x80) bank += 1; + if (attributes & 0x10) bank += 2; + if (attributes & 0x20) bank += 4; + + pal = (bank == 0 || bank >= 0x1c || (attributes & 0x40)) ? 5 : 7; + color = pal*16;// + (attributes & 0x0f); + number = combasc_page[1][tile_index + 0x400] + 256*bank; + + SET_TILE_INFO( + 1, + number, + color, + 0); +} + +static TILE_GET_INFO( get_text_info_bootleg ) +{ +// UINT8 attributes = combasc_page[0][tile_index + 0x800]; + int number = combasc_page[0][tile_index + 0xc00]; + int color = 16;// + (attributes & 0x0f); + + SET_TILE_INFO( + 1, + number, + color, + 0); +} + +/*************************************************************************** + + Start the video hardware emulation. + +***************************************************************************/ + +VIDEO_START( combasc ) +{ + combasc_vreg = -1; + + bg_tilemap[0] = tilemap_create(get_tile_info0,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + bg_tilemap[1] = tilemap_create(get_tile_info1,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + textlayer = tilemap_create(get_text_info, tilemap_scan_rows,TILEMAP_TYPE_PEN, 8,8,32,32); + + private_spriteram[0] = auto_malloc(0x800); + private_spriteram[1] = auto_malloc(0x800); + memset(private_spriteram[0],0,0x800); + memset(private_spriteram[1],0,0x800); + + tilemap_set_transparent_pen(bg_tilemap[0],0); + tilemap_set_transparent_pen(bg_tilemap[1],0); + tilemap_set_transparent_pen(textlayer,0); + + tilemap_set_scroll_rows(textlayer,32); +} + +VIDEO_START( combascb ) +{ + combasc_vreg = -1; + + bg_tilemap[0] = tilemap_create(get_tile_info0_bootleg,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + bg_tilemap[1] = tilemap_create(get_tile_info1_bootleg,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + textlayer = tilemap_create(get_text_info_bootleg, tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + + private_spriteram[0] = auto_malloc(0x800); + private_spriteram[1] = auto_malloc(0x800); + memset(private_spriteram[0],0,0x800); + memset(private_spriteram[1],0,0x800); + + tilemap_set_transparent_pen(bg_tilemap[0],0); + tilemap_set_transparent_pen(bg_tilemap[1],0); + + tilemap_set_scroll_rows(bg_tilemap[0],32); + tilemap_set_scroll_rows(bg_tilemap[1],32); +} + +/*************************************************************************** + + Memory handlers + +***************************************************************************/ + +READ8_HANDLER( combasc_video_r ) +{ + return videoram[offset]; +} + +WRITE8_HANDLER( combasc_video_w ) +{ + videoram[offset] = data; + if( offset<0x800 ) + { + if (combasc_video_circuit) + tilemap_mark_tile_dirty(bg_tilemap[1],offset & 0x3ff); + else + tilemap_mark_tile_dirty(bg_tilemap[0],offset & 0x3ff); + } + else if( offset<0x1000 && combasc_video_circuit==0 ) + { + tilemap_mark_tile_dirty( textlayer,offset & 0x3ff); + } +} + + +WRITE8_HANDLER( combasc_vreg_w ) +{ + if (data != combasc_vreg) + { + tilemap_mark_all_tiles_dirty( textlayer ); + if ((data & 0x0f) != (combasc_vreg & 0x0f)) + tilemap_mark_all_tiles_dirty( bg_tilemap[0] ); + if ((data >> 4) != (combasc_vreg >> 4)) + tilemap_mark_all_tiles_dirty( bg_tilemap[1] ); + combasc_vreg = data; + } +} + +static WRITE8_HANDLER( combascb_sh_irqtrigger_w ) +{ + soundlatch_w(offset,data); + cpunum_set_input_line_and_vector(1,0,HOLD_LINE,0xff); +} + +static READ8_HANDLER( combascb_io_r ) +{ + return readinputport(offset); +} + +static WRITE8_HANDLER( combascb_priority_w ) +{ + priority = data & 0x20; +} + +WRITE8_HANDLER( combasc_bankselect_w ) +{ + UINT8 *page = memory_region(REGION_CPU1) + 0x10000; + + if (data & 0x40) + { + combasc_video_circuit = 1; + videoram = combasc_page[1]; + combasc_scrollram = combasc_scrollram1; + } + else + { + combasc_video_circuit = 0; + videoram = combasc_page[0]; + combasc_scrollram = combasc_scrollram0; + } + + priority = data & 0x20; + + if (data & 0x10) + { + memory_set_bankptr(1,page + 0x4000 * ((data & 0x0e) >> 1)); + } + else + { + memory_set_bankptr(1,page + 0x20000 + 0x4000 * (data & 1)); + } +} + +WRITE8_HANDLER( combascb_bankselect_w ) +{ + if (data & 0x40) + { + combasc_video_circuit = 1; + videoram = combasc_page[1]; + } + else + { + combasc_video_circuit = 0; + videoram = combasc_page[0]; + } + + data = data & 0x1f; + if( data != combasc_bank_select ) + { + UINT8 *page = memory_region(REGION_CPU1) + 0x10000; + combasc_bank_select = data; + + if (data & 0x10) + { + memory_set_bankptr(1,page + 0x4000 * ((data & 0x0e) >> 1)); + } + else + { + memory_set_bankptr(1,page + 0x20000 + 0x4000 * (data & 1)); + } + + if (data == 0x1f) + { + memory_set_bankptr(1,page + 0x20000 + 0x4000 * (data & 1)); + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4400, 0x4403, 0, 0, combascb_io_r);/* IO RAM & Video Registers */ + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4400, 0x4400, 0, 0, combascb_priority_w); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4800, 0x4800, 0, 0, combascb_sh_irqtrigger_w); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4c00, 0x4c00, 0, 0, combasc_vreg_w); + } + else + { + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4000, 0x7fff, 0, 0, MRA8_BANK1); /* banked ROM */ + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4000, 0x7fff, 0, 0, MWA8_ROM); + } + } +} + +MACHINE_RESET( combasc ) +{ + UINT8 *MEM = memory_region(REGION_CPU1) + 0x38000; + + + combasc_io_ram = MEM + 0x0000; + combasc_page[0] = MEM + 0x4000; + combasc_page[1] = MEM + 0x6000; + + memset( combasc_io_ram, 0x00, 0x4000 ); + memset( combasc_page[0], 0x00, 0x2000 ); + memset( combasc_page[1], 0x00, 0x2000 ); + + combasc_bank_select = -1; + combasc_bankselect_w( 0,0 ); +} + +WRITE8_HANDLER( combasc_pf_control_w ) +{ + K007121_ctrl_w(combasc_video_circuit,offset,data); + + if (offset == 7) + tilemap_set_flip(bg_tilemap[combasc_video_circuit],(data & 0x08) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); + + if (offset == 3) + { + if (data & 0x08) + memcpy(private_spriteram[combasc_video_circuit],combasc_page[combasc_video_circuit]+0x1000,0x800); + else + memcpy(private_spriteram[combasc_video_circuit],combasc_page[combasc_video_circuit]+0x1800,0x800); + } +} + +READ8_HANDLER( combasc_scrollram_r ) +{ + return combasc_scrollram[offset]; +} + +WRITE8_HANDLER( combasc_scrollram_w ) +{ + combasc_scrollram[offset] = data; +} + + + +/*************************************************************************** + + Display Refresh + +***************************************************************************/ + +static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, const UINT8 *source,int circuit,UINT32 pri_mask) +{ + int base_color = (circuit*4)*16+(K007121_ctrlram[circuit][6]&0x10)*2; + + K007121_sprites_draw(machine,circuit,bitmap,cliprect,source,base_color,0,0,pri_mask); +} + + +VIDEO_UPDATE( combasc ) +{ + int i; + + + if (K007121_ctrlram[0][0x01] & 0x02) + { + tilemap_set_scroll_rows(bg_tilemap[0],32); + for (i = 0;i < 32;i++) + { + tilemap_set_scrollx(bg_tilemap[0],i,combasc_scrollram0[i]); + } + } + else + { + tilemap_set_scroll_rows(bg_tilemap[0],1); + tilemap_set_scrollx(bg_tilemap[0],0,K007121_ctrlram[0][0x00] | ((K007121_ctrlram[0][0x01] & 0x01) << 8)); + } + + if (K007121_ctrlram[1][0x01] & 0x02) + { + tilemap_set_scroll_rows(bg_tilemap[1],32); + for (i = 0;i < 32;i++) + { + tilemap_set_scrollx(bg_tilemap[1],i,combasc_scrollram1[i]); + } + } + else + { + tilemap_set_scroll_rows(bg_tilemap[1],1); + tilemap_set_scrollx(bg_tilemap[1],0,K007121_ctrlram[1][0x00] | ((K007121_ctrlram[1][0x01] & 0x01) << 8)); + } + + tilemap_set_scrolly(bg_tilemap[0],0,K007121_ctrlram[0][0x02]); + tilemap_set_scrolly(bg_tilemap[1],0,K007121_ctrlram[1][0x02]); + + fillbitmap(priority_bitmap,0,cliprect); + + if (priority == 0) + { + tilemap_draw(bitmap,cliprect,bg_tilemap[1],TILEMAP_DRAW_OPAQUE|0,4); + tilemap_draw(bitmap,cliprect,bg_tilemap[1],TILEMAP_DRAW_OPAQUE|1,8); + tilemap_draw(bitmap,cliprect,bg_tilemap[0],0,1); + tilemap_draw(bitmap,cliprect,bg_tilemap[0],1,2); + + /* we use the priority buffer so sprites are drawn front to back */ + draw_sprites(machine,bitmap,cliprect,private_spriteram[1],1,0x0f00); + draw_sprites(machine,bitmap,cliprect,private_spriteram[0],0,0x4444); + } + else + { + tilemap_draw(bitmap,cliprect,bg_tilemap[0],TILEMAP_DRAW_OPAQUE|0,1); + tilemap_draw(bitmap,cliprect,bg_tilemap[0],TILEMAP_DRAW_OPAQUE|1,2); + tilemap_draw(bitmap,cliprect,bg_tilemap[1],1,4); + tilemap_draw(bitmap,cliprect,bg_tilemap[1],0,8); + + /* we use the priority buffer so sprites are drawn front to back */ + draw_sprites(machine,bitmap,cliprect,private_spriteram[1],1,0x0f00); + draw_sprites(machine,bitmap,cliprect,private_spriteram[0],0,0x4444); + } + + if (K007121_ctrlram[0][0x01] & 0x08) + { + for (i = 0;i < 32;i++) + { + tilemap_set_scrollx(textlayer,i,combasc_scrollram0[0x20+i] ? 0 : TILE_LINE_DISABLED); + tilemap_draw(bitmap,cliprect,textlayer,0,0); + } + } + + /* chop the extreme columns if necessary */ + if (K007121_ctrlram[0][0x03] & 0x40) + { + rectangle clip; + + clip = *cliprect; + clip.max_x = clip.min_x + 7; + fillbitmap(bitmap,machine->pens[0],&clip); + + clip = *cliprect; + clip.min_x = clip.max_x - 7; + fillbitmap(bitmap,machine->pens[0],&clip); + } + return 0; +} + + + + + + + + +/*************************************************************************** + + bootleg Combat School sprites. Each sprite has 5 bytes: + +byte #0: sprite number +byte #1: y position +byte #2: x position +byte #3: + bit 0: x position (bit 0) + bits 1..3: ??? + bit 4: flip x + bit 5: unused? + bit 6: sprite bank # (bit 2) + bit 7: ??? +byte #4: + bits 0,1: sprite bank # (bits 0 & 1) + bits 2,3: unused? + bits 4..7: sprite color + +***************************************************************************/ + +static void bootleg_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, const UINT8 *source, int circuit ) +{ + const gfx_element *gfx = machine->gfx[circuit+2]; + + int limit = ( circuit) ? (program_read_byte(0xc2)*256 + program_read_byte(0xc3)) : (program_read_byte(0xc0)*256 + program_read_byte(0xc1)); + const UINT8 *finish; + + source+=0x1000; + finish = source; + source+=0x400; + limit = (0x3400-limit)/8; + if( limit>=0 ) finish = source-limit*8; + source-=8; + + while( source>finish ) + { + UINT8 attributes = source[3]; /* PBxF ?xxX */ + { + int number = source[0]; + int x = source[2] - 71 + (attributes & 0x01)*256; + int y = 242 - source[1]; + UINT8 color = source[4]; /* CCCC xxBB */ + + int bank = (color & 0x03) | ((attributes & 0x40) >> 4); + + number = ((number & 0x02) << 1) | ((number & 0x04) >> 1) | (number & (~6)); + number += 256*bank; + + color = (circuit*4)*16 + (color >> 4); + + /* hacks to select alternate palettes */ +// if(combasc_vreg == 0x40 && (attributes & 0x40)) color += 1*16; +// if(combasc_vreg == 0x23 && (attributes & 0x02)) color += 1*16; +// if(combasc_vreg == 0x66 ) color += 2*16; + + drawgfx( bitmap, gfx, + number, color, + attributes & 0x10,0, /* flip */ + x,y, + cliprect, TRANSPARENCY_PEN, 15 ); + } + source -= 8; + } +} + +VIDEO_UPDATE( combascb ) +{ + int i; + + for( i=0; i<32; i++ ) + { + tilemap_set_scrollx( bg_tilemap[0],i, combasc_io_ram[0x040+i]+5 ); + tilemap_set_scrollx( bg_tilemap[1],i, combasc_io_ram[0x060+i]+3 ); + } + tilemap_set_scrolly( bg_tilemap[0],0, combasc_io_ram[0x000] ); + tilemap_set_scrolly( bg_tilemap[1],0, combasc_io_ram[0x020] ); + + if (priority == 0) + { + tilemap_draw( bitmap,cliprect,bg_tilemap[1],TILEMAP_DRAW_OPAQUE,0); + bootleg_draw_sprites(machine, bitmap,cliprect, combasc_page[0], 0 ); + tilemap_draw( bitmap,cliprect,bg_tilemap[0],0 ,0); + bootleg_draw_sprites(machine, bitmap,cliprect, combasc_page[1], 1 ); + } + else + { + tilemap_draw( bitmap,cliprect,bg_tilemap[0],TILEMAP_DRAW_OPAQUE,0); + bootleg_draw_sprites(machine, bitmap,cliprect, combasc_page[0], 0 ); + tilemap_draw( bitmap,cliprect,bg_tilemap[1],0 ,0); + bootleg_draw_sprites(machine, bitmap,cliprect, combasc_page[1], 1 ); + } + + tilemap_draw( bitmap,cliprect,textlayer,0,0); + return 0; +} |