diff options
Diffstat (limited to 'src/mame/video/battlera.c')
-rw-r--r-- | src/mame/video/battlera.c | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/src/mame/video/battlera.c b/src/mame/video/battlera.c new file mode 100644 index 00000000000..99d3f132d4d --- /dev/null +++ b/src/mame/video/battlera.c @@ -0,0 +1,413 @@ +/******************************************************************************* + + Battle Rangers - Bryan McPhail, mish@tendril.co.uk + + This file only implements necessary features - not all PC-Engine video + features are used in this game (no DMA for one). + +*******************************************************************************/ + +#include "driver.h" +#include "cpu/h6280/h6280.h" + +static int HuC6270_registers[20]; +static int VDC_register,vram_ptr; +static UINT8 *HuC6270_vram,*tile_dirty,*sprite_dirty,*vram_dirty; +static mame_bitmap *tile_bitmap,*front_bitmap; + +static int current_scanline,inc_value; +static int irq_enable,rcr_enable,sb_enable,bb_enable,bldwolf_vblank; + + + +/******************************************************************************/ + +VIDEO_START( battlera ) +{ + HuC6270_vram=auto_malloc(0x20000); + tile_dirty=auto_malloc(0x1000); + sprite_dirty=auto_malloc(0x400); + vram_dirty=auto_malloc(0x1000); + + memset(HuC6270_vram,0,0x20000); + memset(tile_dirty,1,0x1000); + memset(sprite_dirty,1,0x400); + memset(vram_dirty,1,0x1000); + + tile_bitmap=auto_bitmap_alloc(512,512,machine->screen[0].format); + front_bitmap=auto_bitmap_alloc(512,512,machine->screen[0].format); + + vram_ptr=0; + inc_value=1; + current_scanline=0; + irq_enable=rcr_enable=sb_enable=bb_enable=0; +} + +/******************************************************************************/ + +WRITE8_HANDLER( battlera_palette_w ) +{ + int pal_word; + + paletteram[offset]=data; + if (offset%2) offset-=1; + + pal_word=paletteram[offset] | (paletteram[offset+1]<<8); + palette_set_color_rgb(Machine, offset/2, pal3bit(pal_word >> 3), pal3bit(pal_word >> 6), pal3bit(pal_word >> 0)); +} + +/******************************************************************************/ + +READ8_HANDLER( HuC6270_debug_r ) +{ + return HuC6270_vram[offset]; +} + +WRITE8_HANDLER( HuC6270_debug_w ) +{ + HuC6270_vram[offset]=data; +} +READ8_HANDLER( HuC6270_register_r ) +{ + int rr; + + if ((current_scanline+56)==HuC6270_registers[6]) rr=1; else rr=0; + + return 0 /* CR flag */ + | (0 << 1) /* OR flag */ + | (rr << 2) /* RR flag */ + | (0 << 3) /* DS flag */ + | (0 << 4) /* DV flag */ + | (bldwolf_vblank << 5) /* VD flag (1 when vblank else 0) */ + | (0 << 6) /* BSY flag (1 when dma active, else 0) */ + | (0 << 7); /* Always zero */ +} + +WRITE8_HANDLER( HuC6270_register_w ) +{ + switch (offset) { + case 0: /* Select data region */ + VDC_register=data; + break; + case 1: /* Unused */ + break; + } +} + +/******************************************************************************/ + +#ifdef UNUSED_FUNCTION +READ8_HANDLER( HuC6270_data_r ) +{ + int result; + + switch (offset) { + case 0: /* LSB */ + return HuC6270_vram[(HuC6270_registers[1]<<1)|1]; + + case 1:/* MSB */ + result=HuC6270_vram[(HuC6270_registers[1]<<1)|0]; + HuC6270_registers[1]=(HuC6270_registers[1]+inc_value)&0xffff; + return result; + } + + return 0; +} +#endif + +WRITE8_HANDLER( HuC6270_data_w ) +{ + switch (offset) { + case 0: /* LSB */ + switch (VDC_register) { + + case 0: /* MAWR */ + HuC6270_registers[0]=(HuC6270_registers[0]&0xff00) | (data); + return; + + case 1: /* MARR */ + HuC6270_registers[0]=(HuC6270_registers[1]&0xff00) | (data); + return; + + case 2: /* VRAM */ + if (HuC6270_vram[(HuC6270_registers[0]<<1)|1]!=data) { + HuC6270_vram[(HuC6270_registers[0]<<1)|1]=data; + tile_dirty[HuC6270_registers[0]>>4]=1; + sprite_dirty[HuC6270_registers[0]>>6]=1; + } + if (HuC6270_registers[0]<0x1000) vram_dirty[HuC6270_registers[0]]=1; + return; + + case 3: break; /* Unused */ + case 4: break; /* Unused */ + + case 5: /* CR - Control register */ + /* Bits 0,1 unknown */ + rcr_enable=data&0x4; /* Raster interrupt enable */ + irq_enable=data&0x8; /* VBL interrupt enable */ + /* Bits 4,5 unknown (EX) */ + sb_enable=data&0x40; /* Sprites enable */ + bb_enable=data&0x80; /* Background enable */ + return; + + case 6: /* RCR - Raster counter register */ + HuC6270_registers[6]=(HuC6270_registers[6]&0xff00) | (data); + return; + + case 7: /* BXR - X scroll */ + HuC6270_registers[7]=(HuC6270_registers[7]&0xff00) | (data); + return; + + case 8: /* BYR - Y scroll */ + HuC6270_registers[8]=(HuC6270_registers[8]&0xff00) | (data); + return; + + case 15: /* DMA */ + case 16: + case 17: + case 18: + logerror("%04x: dma 2 %02x\n",activecpu_get_pc(),data); + break; + + case 19: /* SATB */ + HuC6270_registers[19]=(HuC6270_registers[19]&0xff00) | (data); + return; + + } + break; + + /*********************************************/ + + case 1: /* MSB (Autoincrement on this write) */ + switch (VDC_register) { + + case 0: /* MAWR - Memory Address Write Register */ + HuC6270_registers[0]=(HuC6270_registers[0]&0xff) | (data<<8); + return; + + case 1: /* MARR */ + HuC6270_registers[1]=(HuC6270_registers[1]&0xff) | (data<<8); + return; + + case 2: /* VWR - VRAM */ + if (HuC6270_vram[(HuC6270_registers[0]<<1)|0]!=data) { + HuC6270_vram[(HuC6270_registers[0]<<1)|0]=data; + tile_dirty[HuC6270_registers[0]>>4]=1; + sprite_dirty[HuC6270_registers[0]>>6]=1; + if (HuC6270_registers[0]<0x1000) vram_dirty[HuC6270_registers[0]]=1; + } + HuC6270_registers[0]+=inc_value; + HuC6270_registers[0]=HuC6270_registers[0]&0xffff; + return; + + case 5: /* CR */ + /* IW - Auto-increment values */ + switch ((data>>3)&3) { + case 0: inc_value=1; break; + case 1: inc_value=32;break; + case 2: inc_value=64; break; + case 3: inc_value=128; break; + } + + /* DR, TE unknown */ + return; + + case 6: /* RCR - Raster counter register */ + HuC6270_registers[6]=(HuC6270_registers[6]&0xff) | (data<<8); + return; + + case 7: /* BXR - X scroll */ + HuC6270_registers[7]=(HuC6270_registers[7]&0xff) | (data<<8); + return; + + case 8: /* BYR - Y scroll */ + HuC6270_registers[8]=(HuC6270_registers[8]&0xff) | (data<<8); + return; + + case 15: /* DMA */ + case 16: + case 17: + case 18: + logerror("%04x: dma 2 %02x\n",activecpu_get_pc(),data); + break; + + case 19: /* SATB - Sprites */ + HuC6270_registers[19]=(HuC6270_registers[19]&0xff) | (data<<8); + return; + } + break; + } + logerror("%04x: unknown write to VDC_register %02x (%02x) at %02x\n",activecpu_get_pc(),VDC_register,data,offset); +} + +/******************************************************************************/ + +static void draw_sprites(running_machine *machine, mame_bitmap *bitmap,const rectangle *clip,int pri) +{ + int offs,my,mx,code,code2,fx,fy,cgy=0,cgx,colour,i,yinc; + + /* Draw sprites, starting at SATB, draw in _reverse_ order */ + for (offs=(HuC6270_registers[19]<<1)+0x200-8; offs>=(HuC6270_registers[19]<<1); offs-=8) + { + if ((HuC6270_vram[offs+7]&0x80) && !pri) continue; + if (!(HuC6270_vram[offs+7]&0x80) && pri) continue; + + code=HuC6270_vram[offs+5] + (HuC6270_vram[offs+4]<<8); + code=code>>1; + + my=HuC6270_vram[offs+1] + (HuC6270_vram[offs+0]<<8); + mx=HuC6270_vram[offs+3] + (HuC6270_vram[offs+2]<<8); + + mx-=32; + my-=57; + + fx=HuC6270_vram[offs+6]&0x8; + fy=HuC6270_vram[offs+6]&0x80; + cgx=HuC6270_vram[offs+6]&1; + colour=HuC6270_vram[offs+7]&0xf; + + switch ((HuC6270_vram[offs+6]>>4)&3) { + case 0: cgy=1; break; + case 1: cgy=2; break; + case 2: cgy=0; break; /* Illegal */ + case 3: cgy=4; break; + } + + if (cgx && cgy==2) code=code&0x3fc; /* Title screen */ + + if (fx && cgx) {code2=code; code++;} /* Swap tile order on X flips */ + else code2=code+1; + + yinc = 16; + if (fy) { my += 16*(cgy-1); yinc = -16; } /* Swap tile order on Y flips */ + + for (i=0; i<cgy; i++) { + drawgfx(bitmap,machine->gfx[1], + code, + colour, + fx,fy, + mx,my, + clip,TRANSPARENCY_PEN,0); + + if (cgx) + drawgfx(bitmap,machine->gfx[1], + code2, + colour, + fx,fy, + mx+16,my, + clip,TRANSPARENCY_PEN,0); + my += yinc; + /* if (cgx) */ /* Different from console? */ + code += 2; + code2 += 2; + /*else code += 1; */ /* Different from console? */ + } + } + +} + +static void screenrefresh(running_machine *machine, mame_bitmap *bitmap,const rectangle *clip) +{ + int offs,code,scrollx,scrolly,mx,my; + + /* Dynamically decode chars if dirty */ + for (code = 0x0000;code < 0x1000;code++) + if (tile_dirty[code]) + decodechar(machine->gfx[0],code,HuC6270_vram,machine->drv->gfxdecodeinfo[0].gfxlayout); + + /* Dynamically decode sprites if dirty */ + for (code = 0x0000;code < 0x400;code++) + if (sprite_dirty[code]) + decodechar(machine->gfx[1],code,HuC6270_vram,machine->drv->gfxdecodeinfo[1].gfxlayout); + + /* NB: If first 0x1000 byte is always tilemap, no need to decode the first batch of tiles/sprites */ + + mx=-1; + my=0; + for (offs = 0x0000;offs < 0x2000;offs += 2) + { + mx++; + if (mx==64) {mx=0; my++;} + code=HuC6270_vram[offs+1] + ((HuC6270_vram[offs] & 0x0f) << 8); + + /* If this tile was changed OR tilemap was changed, redraw */ + if (tile_dirty[code] || vram_dirty[offs/2]) { + vram_dirty[offs/2]=0; + drawgfx(tile_bitmap,machine->gfx[0], + code, + HuC6270_vram[offs] >> 4, + 0,0, + 8*mx,8*my, + 0,TRANSPARENCY_NONE,0); + drawgfx(front_bitmap,machine->gfx[2], + 0, + 0, /* fill the spot with pen 256 */ + 0,0, + 8*mx,8*my, + 0,TRANSPARENCY_NONE,0); + drawgfx(front_bitmap,machine->gfx[0], + code, + HuC6270_vram[offs] >> 4, + 0,0, + 8*mx,8*my, + 0,TRANSPARENCY_PENS,0x1); + } + } + + /* Nothing dirty after a screen refresh */ + for (code = 0x0000;code < 0x1000;code++) + tile_dirty[code]=0; + for (code = 0x0000;code < 0x400;code++) + sprite_dirty[code]=0; + + /* Render bitmap */ + scrollx=-HuC6270_registers[7]; + scrolly=-HuC6270_registers[8]+clip->min_y-1; + + copyscrollbitmap(bitmap,tile_bitmap,1,&scrollx,1,&scrolly,clip,TRANSPARENCY_NONE,0); + + /* Todo: Background enable (not used anyway) */ + + /* Render low priority sprites, if enabled */ + if (sb_enable) draw_sprites(machine,bitmap,clip,0); + + /* Render background over sprites */ + copyscrollbitmap(bitmap,front_bitmap,1,&scrollx,1,&scrolly,clip,TRANSPARENCY_COLOR,256); + + /* Render high priority sprites, if enabled */ + if (sb_enable) draw_sprites(machine,bitmap,clip,1); +} + +/******************************************************************************/ + +VIDEO_UPDATE( battlera ) +{ + screenrefresh(machine,bitmap,cliprect); + return 0; +} + +/******************************************************************************/ + +INTERRUPT_GEN( battlera_interrupt ) +{ + current_scanline=255-cpu_getiloops(); /* 8 lines clipped at top */ + + /* If raster interrupt occurs, refresh screen _up_ to this point */ + if (rcr_enable && (current_scanline+56)==HuC6270_registers[6]) { + video_screen_update_partial(0, current_scanline); + cpunum_set_input_line(0, 0, HOLD_LINE); /* RCR interrupt */ + } + + /* Start of vblank */ + else if (current_scanline==240) { + bldwolf_vblank=1; + video_screen_update_partial(0, 240); + if (irq_enable) + cpunum_set_input_line(0, 0, HOLD_LINE); /* VBL */ + } + + /* End of vblank */ + if (current_scanline==254) { + bldwolf_vblank=0; + } +} |