fix MT385, and maybe 386 by making battlera use the proper PCE video code

note: there is a significant performance cost to this as the real PCE code is slow, also some graphics will now flicker a bit because the real PCE emulation respects sprite chip limits / masking (which is why the submarine boss now works)
This commit is contained in:
David Haywood 2014-10-04 16:33:18 +00:00
parent 4ef1aa7884
commit c815b46cd0
6 changed files with 63 additions and 457 deletions

View File

@ -181,6 +181,19 @@ void huc6260_device::video_update( bitmap_ind16 &bitmap, const rectangle &clipre
}
// the battlera arcade board reads/writes the palette directly
READ8_MEMBER(huc6260_device::palette_direct_read)
{
if (!(offset&1)) return m_palette[offset>>1];
else return m_palette[offset >> 1] >> 8;
}
WRITE8_MEMBER(huc6260_device::palette_direct_write)
{
if (!(offset&1)) m_palette[offset>>1] = (m_palette[offset>>1] & 0xff00) | data;
else m_palette[offset>>1] = (m_palette[offset>>1] & 0x00ff) | (data<<8);
}
READ8_MEMBER( huc6260_device::read )
{
UINT8 data = 0xFF;

View File

@ -48,6 +48,9 @@ public:
DECLARE_WRITE8_MEMBER( write );
DECLARE_PALETTE_INIT(huc6260);
READ8_MEMBER(palette_direct_read);
WRITE8_MEMBER(palette_direct_write);
protected:
// device-level overrides
virtual void device_start();

View File

@ -13,8 +13,6 @@
Twice as much VRAM.
Todo:
- Convert this driver to use proper PC-Engine video.
- Priority is wrong for the submarine at the end of level 1.
- There seems to be a bug with a stuck note from the YM2203 FM channel
at the start of scene 3 and near the ending when your characters are
flying over a forest in a helicopter.
@ -65,19 +63,20 @@ READ8_MEMBER(battlera_state::control_data_r)
static ADDRESS_MAP_START( battlera_map, AS_PROGRAM, 8, battlera_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_READWRITE(HuC6270_debug_r, HuC6270_debug_w) /* Cheat to edit vram data */
AM_RANGE(0x1e0800, 0x1e0801) AM_WRITE(battlera_sound_w)
AM_RANGE(0x1e1000, 0x1e13ff) AM_WRITE(battlera_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x1e1000, 0x1e13ff) AM_DEVREADWRITE( "huc6260", huc6260_device, palette_direct_read, palette_direct_write) AM_SHARE("paletteram")
AM_RANGE(0x1f0000, 0x1f1fff) AM_RAMBANK("bank8") /* Main ram */
AM_RANGE(0x1fe000, 0x1fe001) AM_READWRITE(HuC6270_register_r, HuC6270_register_w)
AM_RANGE(0x1fe002, 0x1fe003) AM_WRITE(HuC6270_data_w)
AM_RANGE(0x1ff000, 0x1ff001) AM_READWRITE(control_data_r, control_data_w)
AM_RANGE(0x1ff400, 0x1ff403) AM_DEVWRITE("maincpu", h6280_device, irq_status_w)
AM_RANGE( 0x1FE000, 0x1FE3FF) AM_DEVREADWRITE( "huc6270", huc6270_device, read, write )
AM_RANGE( 0x1FE400, 0x1FE7FF) AM_DEVREADWRITE( "huc6260", huc6260_device, read, write )
AM_RANGE( 0x1FEC00, 0x1FEFFF) AM_DEVREADWRITE( "maincpu", h6280_device, timer_r, timer_w )
AM_RANGE( 0x1FF400, 0x1FF7FF) AM_DEVREADWRITE( "maincpu", h6280_device, irq_status_r, irq_status_w )
ADDRESS_MAP_END
static ADDRESS_MAP_START( battlera_portmap, AS_IO, 8, battlera_state )
AM_RANGE(0x00, 0x01) AM_WRITE(HuC6270_register_w)
AM_RANGE(0x02, 0x03) AM_WRITE(HuC6270_data_w)
AM_RANGE( 0x00, 0x03) AM_DEVREADWRITE( "huc6270", huc6270_device, read, write )
ADDRESS_MAP_END
/******************************************************************************/
@ -179,61 +178,46 @@ static INPUT_PORTS_START( battlera )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:8" ) /* Listed as "Unused" */
INPUT_PORTS_END
/******************************************************************************/
static const gfx_layout tiles =
{
8,8,
4096,
4,
{ 16*8, 16*8+8, 0, 8 },
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 },
32*8
};
static const gfx_layout sprites =
{
16,16,
1024,
4,
{ 96*8, 64*8, 32*8, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16,
8*16, 9*16, 10*16, 11*16, 12*16, 13*16, 14*16, 15*16 },
128*8
};
static GFXDECODE_START( battlera )
GFXDECODE_ENTRY( NULL, 0, tiles, 0, 16 ) /* Dynamically modified */
GFXDECODE_ENTRY( NULL, 0, sprites, 256, 16 ) /* Dynamically modified */
GFXDECODE_ENTRY( NULL, 0, tiles , 256, 16 ) /* Blank tile */
GFXDECODE_END
/******************************************************************************/
WRITE_LINE_MEMBER(battlera_state::pce_irq_changed)
{
m_maincpu->set_input_line(0, state);
}
UINT32 battlera_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_huc6260->video_update( bitmap, cliprect );
return 0;
}
static MACHINE_CONFIG_START( battlera, battlera_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", H6280,21477200/3)
MCFG_CPU_PROGRAM_MAP(battlera_map)
MCFG_CPU_IO_MAP(battlera_portmap)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", battlera_state, battlera_irq, "screen", 0, 1) /* 8 prelines, 232 lines, 16 vblank? */
MCFG_CPU_ADD("audiocpu", H6280,21477200/3)
MCFG_CPU_PROGRAM_MAP(sound_map)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
MCFG_SCREEN_SIZE(32*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 30*8-1)
MCFG_SCREEN_UPDATE_DRIVER(battlera_state, screen_update_battlera)
MCFG_SCREEN_PALETTE("palette")
MCFG_SCREEN_RAW_PARAMS(MAIN_CLOCK, HUC6260_WPF, 64, 64 + 1024 + 64, HUC6260_LPF, 18, 18 + 242)
MCFG_SCREEN_UPDATE_DRIVER( battlera_state, screen_update )
MCFG_SCREEN_PALETTE("huc6260:palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", battlera)
MCFG_PALETTE_ADD("palette", 512)
MCFG_DEVICE_ADD( "huc6260", HUC6260, MAIN_CLOCK )
MCFG_HUC6260_NEXT_PIXEL_DATA_CB(DEVREAD16("huc6270", huc6270_device, next_pixel))
MCFG_HUC6260_TIME_TIL_NEXT_EVENT_CB(DEVREAD16("huc6270", huc6270_device, time_until_next_event))
MCFG_HUC6260_VSYNC_CHANGED_CB(DEVWRITELINE("huc6270", huc6270_device, vsync_changed))
MCFG_HUC6260_HSYNC_CHANGED_CB(DEVWRITELINE("huc6270", huc6270_device, hsync_changed))
MCFG_DEVICE_ADD( "huc6270", HUC6270, 0 )
MCFG_HUC6270_VRAM_SIZE(0x20000)
MCFG_HUC6270_IRQ_CHANGED_CB(WRITELINE(battlera_state, pce_irq_changed))
/* sound hardware */

View File

@ -1,4 +1,9 @@
#include "sound/msm5205.h"
#include "video/huc6260.h"
#include "video/huc6270.h"
#include "video/huc6202.h"
#define MAIN_CLOCK 21477270
class battlera_state : public driver_device
{
@ -8,53 +13,34 @@ public:
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_msm(*this, "msm"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_generic_paletteram_8(*this, "paletteram") { }
m_huc6260(*this, "huc6260")
{ }
int m_control_port_select;
int m_msm5205next;
int m_toggle;
int m_HuC6270_registers[20];
int m_VDC_register;
int m_vram_ptr;
UINT8 *m_HuC6270_vram;
UINT8 *m_vram_dirty;
bitmap_ind16 *m_tile_bitmap;
bitmap_ind16 *m_front_bitmap;
UINT32 m_tile_dirtyseq;
int m_current_scanline;
int m_inc_value;
int m_irq_enable;
int m_rcr_enable;
int m_sb_enable;
int m_bb_enable;
int m_bldwolf_vblank;
UINT8 m_blank_tile[32];
required_device<cpu_device> m_maincpu;
DECLARE_WRITE8_MEMBER(battlera_sound_w);
DECLARE_WRITE8_MEMBER(control_data_w);
DECLARE_READ8_MEMBER(control_data_r);
DECLARE_WRITE8_MEMBER(battlera_adpcm_data_w);
DECLARE_WRITE8_MEMBER(battlera_palette_w);
DECLARE_READ8_MEMBER(HuC6270_debug_r);
DECLARE_WRITE8_MEMBER(HuC6270_debug_w);
DECLARE_READ8_MEMBER(HuC6270_register_r);
DECLARE_WRITE8_MEMBER(HuC6270_register_w);
DECLARE_READ8_MEMBER(HuC6270_data_r);
DECLARE_WRITE8_MEMBER(HuC6270_data_w);
DECLARE_WRITE8_MEMBER(battlera_adpcm_reset_w);
virtual void video_start();
UINT32 screen_update_battlera(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_DEVICE_CALLBACK_MEMBER(battlera_irq);
void draw_sprites(bitmap_ind16 &bitmap,const rectangle &clip,int pri);
DECLARE_WRITE_LINE_MEMBER(battlera_adpcm_int);
required_device<cpu_device> m_audiocpu;
required_device<msm5205_device> m_msm;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_shared_ptr<UINT8> m_generic_paletteram_8;
optional_device<huc6260_device> m_huc6260;
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(pce_irq_changed);
};

View File

@ -1,383 +1,2 @@
/*******************************************************************************
// delete me
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 "emu.h"
#include "cpu/h6280/h6280.h"
#include "includes/battlera.h"
/******************************************************************************/
void battlera_state::video_start()
{
m_HuC6270_vram=auto_alloc_array(machine(), UINT8, 0x20000);
m_vram_dirty=auto_alloc_array(machine(), UINT8, 0x1000);
memset(m_HuC6270_vram,0,0x20000);
memset(m_vram_dirty,1,0x1000);
m_tile_bitmap=auto_bitmap_ind16_alloc(machine(),512,512);
m_front_bitmap=auto_bitmap_ind16_alloc(machine(),512,512);
m_vram_ptr=0;
m_inc_value=1;
m_current_scanline=0;
m_irq_enable=m_rcr_enable=m_sb_enable=m_bb_enable=0;
m_gfxdecode->gfx(0)->set_source(m_HuC6270_vram);
m_gfxdecode->gfx(1)->set_source(m_HuC6270_vram);
m_gfxdecode->gfx(2)->set_source(m_blank_tile);
}
/******************************************************************************/
WRITE8_MEMBER(battlera_state::battlera_palette_w)
{
int pal_word;
m_generic_paletteram_8[offset]=data;
if (offset%2) offset-=1;
pal_word=m_generic_paletteram_8[offset] | (m_generic_paletteram_8[offset+1]<<8);
m_palette->set_pen_color(offset/2, pal3bit(pal_word >> 3), pal3bit(pal_word >> 6), pal3bit(pal_word >> 0));
}
/******************************************************************************/
READ8_MEMBER(battlera_state::HuC6270_debug_r)
{
return m_HuC6270_vram[offset];
}
WRITE8_MEMBER(battlera_state::HuC6270_debug_w)
{
m_HuC6270_vram[offset]=data;
}
READ8_MEMBER(battlera_state::HuC6270_register_r)
{
int rr;
if ((m_current_scanline+56)==m_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 */
| (m_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_MEMBER(battlera_state::HuC6270_register_w)
{
switch (offset) {
case 0: /* Select data region */
m_VDC_register=data;
break;
case 1: /* Unused */
break;
}
}
/******************************************************************************/
#ifdef UNUSED_FUNCTION
READ8_MEMBER(battlera_state::HuC6270_data_r)
{
int result;
switch (offset) {
case 0: /* LSB */
return m_HuC6270_vram[(m_HuC6270_registers[1]<<1)|1];
case 1:/* MSB */
result=m_HuC6270_vram[(m_HuC6270_registers[1]<<1)|0];
m_HuC6270_registers[1]=(m_HuC6270_registers[1]+m_inc_value)&0xffff;
return result;
}
return 0;
}
#endif
WRITE8_MEMBER(battlera_state::HuC6270_data_w)
{
switch (offset) {
case 0: /* LSB */
switch (m_VDC_register) {
case 0: /* MAWR */
m_HuC6270_registers[0]=(m_HuC6270_registers[0]&0xff00) | (data);
return;
case 1: /* MARR */
m_HuC6270_registers[0]=(m_HuC6270_registers[1]&0xff00) | (data);
return;
case 2: /* VRAM */
if (m_HuC6270_vram[(m_HuC6270_registers[0]<<1)|1]!=data) {
m_HuC6270_vram[(m_HuC6270_registers[0]<<1)|1]=data;
m_gfxdecode->gfx(0)->mark_dirty(m_HuC6270_registers[0]>>4);
m_gfxdecode->gfx(1)->mark_dirty(m_HuC6270_registers[0]>>6);
}
if (m_HuC6270_registers[0]<0x1000) m_vram_dirty[m_HuC6270_registers[0]]=1;
return;
case 3: break; /* Unused */
case 4: break; /* Unused */
case 5: /* CR - Control register */
/* Bits 0,1 unknown */
m_rcr_enable=data&0x4; /* Raster interrupt enable */
m_irq_enable=data&0x8; /* VBL interrupt enable */
/* Bits 4,5 unknown (EX) */
m_sb_enable=data&0x40; /* Sprites enable */
m_bb_enable=data&0x80; /* Background enable */
return;
case 6: /* RCR - Raster counter register */
m_HuC6270_registers[6]=(m_HuC6270_registers[6]&0xff00) | (data);
return;
case 7: /* BXR - X scroll */
m_HuC6270_registers[7]=(m_HuC6270_registers[7]&0xff00) | (data);
return;
case 8: /* BYR - Y scroll */
m_HuC6270_registers[8]=(m_HuC6270_registers[8]&0xff00) | (data);
return;
case 15: /* DMA */
case 16:
case 17:
case 18:
logerror("%04x: dma 2 %02x\n",space.device().safe_pc(),data);
break;
case 19: /* SATB */
m_HuC6270_registers[19]=(m_HuC6270_registers[19]&0xff00) | (data);
return;
}
break;
/*********************************************/
case 1: /* MSB (Autoincrement on this write) */
switch (m_VDC_register) {
case 0: /* MAWR - Memory Address Write Register */
m_HuC6270_registers[0]=(m_HuC6270_registers[0]&0xff) | (data<<8);
return;
case 1: /* MARR */
m_HuC6270_registers[1]=(m_HuC6270_registers[1]&0xff) | (data<<8);
return;
case 2: /* VWR - VRAM */
if (m_HuC6270_vram[(m_HuC6270_registers[0]<<1)|0]!=data) {
m_HuC6270_vram[(m_HuC6270_registers[0]<<1)|0]=data;
m_gfxdecode->gfx(0)->mark_dirty(m_HuC6270_registers[0]>>4);
m_gfxdecode->gfx(1)->mark_dirty(m_HuC6270_registers[0]>>6);
if (m_HuC6270_registers[0]<0x1000) m_vram_dirty[m_HuC6270_registers[0]]=1;
}
m_HuC6270_registers[0]+=m_inc_value;
m_HuC6270_registers[0]=m_HuC6270_registers[0]&0xffff;
return;
case 5: /* CR */
/* IW - Auto-increment values */
switch ((data>>3)&3) {
case 0: m_inc_value=1; break;
case 1: m_inc_value=32;break;
case 2: m_inc_value=64; break;
case 3: m_inc_value=128; break;
}
/* DR, TE unknown */
return;
case 6: /* RCR - Raster counter register */
m_HuC6270_registers[6]=(m_HuC6270_registers[6]&0xff) | (data<<8);
return;
case 7: /* BXR - X scroll */
m_HuC6270_registers[7]=(m_HuC6270_registers[7]&0xff) | (data<<8);
return;
case 8: /* BYR - Y scroll */
m_HuC6270_registers[8]=(m_HuC6270_registers[8]&0xff) | (data<<8);
return;
case 15: /* DMA */
case 16:
case 17:
case 18:
logerror("%04x: dma 2 %02x\n",space.device().safe_pc(),data);
break;
case 19: /* SATB - Sprites */
m_HuC6270_registers[19]=(m_HuC6270_registers[19]&0xff) | (data<<8);
return;
}
break;
}
logerror("%04x: unknown write to VDC_register %02x (%02x) at %02x\n",space.device().safe_pc(),m_VDC_register,data,offset);
}
/******************************************************************************/
void battlera_state::draw_sprites(bitmap_ind16 &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=(m_HuC6270_registers[19]<<1)+0x200-8; offs>=(m_HuC6270_registers[19]<<1); offs-=8)
{
if ((m_HuC6270_vram[offs+7]&0x80) && !pri) continue;
if (!(m_HuC6270_vram[offs+7]&0x80) && pri) continue;
code=m_HuC6270_vram[offs+5] + (m_HuC6270_vram[offs+4]<<8);
code=code>>1;
my=m_HuC6270_vram[offs+1] + (m_HuC6270_vram[offs+0]<<8);
mx=m_HuC6270_vram[offs+3] + (m_HuC6270_vram[offs+2]<<8);
mx-=32;
my-=57;
fx=m_HuC6270_vram[offs+6]&0x8;
fy=m_HuC6270_vram[offs+6]&0x80;
cgx=m_HuC6270_vram[offs+6]&1;
colour=m_HuC6270_vram[offs+7]&0xf;
switch ((m_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++) {
m_gfxdecode->gfx(1)->transpen(bitmap,clip,
code,
colour,
fx,fy,
mx,my,0);
if (cgx)
m_gfxdecode->gfx(1)->transpen(bitmap,clip,
code2,
colour,
fx,fy,
mx+16,my,0);
my += yinc;
/* if (cgx) */ /* Different from console? */
code += 2;
code2 += 2;
/*else code += 1; */ /* Different from console? */
}
}
}
/******************************************************************************/
UINT32 battlera_state::screen_update_battlera(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int offs,code,scrollx,scrolly,mx,my;
/* if any tiles changed, redraw the VRAM */
if (m_gfxdecode->gfx(0)->dirtyseq() != m_tile_dirtyseq)
{
m_tile_dirtyseq = m_gfxdecode->gfx(0)->dirtyseq();
memset(m_vram_dirty, 1, 0x1000);
}
mx=-1;
my=0;
for (offs = 0x0000;offs < 0x2000;offs += 2)
{
mx++;
if (mx==64) {mx=0; my++;}
code=m_HuC6270_vram[offs+1] + ((m_HuC6270_vram[offs] & 0x0f) << 8);
/* If this tile was changed OR tilemap was changed, redraw */
if (m_vram_dirty[offs/2]) {
m_vram_dirty[offs/2]=0;
m_gfxdecode->gfx(0)->opaque(*m_tile_bitmap,m_tile_bitmap->cliprect(),
code,
m_HuC6270_vram[offs] >> 4,
0,0,
8*mx,8*my);
m_gfxdecode->gfx(2)->opaque(*m_front_bitmap,m_tile_bitmap->cliprect(),
0,
0, /* fill the spot with pen 256 */
0,0,
8*mx,8*my);
m_gfxdecode->gfx(0)->transmask(*m_front_bitmap,m_tile_bitmap->cliprect(),
code,
m_HuC6270_vram[offs] >> 4,
0,0,
8*mx,8*my,0x1);
}
}
/* Render bitmap */
scrollx=-m_HuC6270_registers[7];
scrolly=-m_HuC6270_registers[8]+cliprect.min_y-1;
copyscrollbitmap(bitmap,*m_tile_bitmap,1,&scrollx,1,&scrolly,cliprect);
/* Todo: Background enable (not used anyway) */
/* Render low priority sprites, if enabled */
if (m_sb_enable) draw_sprites(bitmap,cliprect,0);
/* Render background over sprites */
copyscrollbitmap_trans(bitmap,*m_front_bitmap,1,&scrollx,1,&scrolly,cliprect,256);
/* Render high priority sprites, if enabled */
if (m_sb_enable) draw_sprites(bitmap,cliprect,1);
return 0;
}
/******************************************************************************/
TIMER_DEVICE_CALLBACK_MEMBER(battlera_state::battlera_irq)
{
m_current_scanline = param; /* 8 lines clipped at top */
/* If raster interrupt occurs, refresh screen _up_ to this point */
if (m_rcr_enable && (m_current_scanline+56)==m_HuC6270_registers[6]) {
m_screen->update_partial(m_current_scanline);
m_maincpu->set_input_line(0, HOLD_LINE); /* RCR interrupt */
}
/* Start of vblank */
else if (m_current_scanline==240) {
m_bldwolf_vblank=1;
m_screen->update_partial(240);
if (m_irq_enable)
m_maincpu->set_input_line(0, HOLD_LINE); /* VBL */
}
/* End of vblank */
if (m_current_scanline==254) {
m_bldwolf_vblank=0;
}
}

View File

@ -326,6 +326,7 @@ static MACHINE_CONFIG_START( pce_common, pce_state )
MCFG_HUC6260_TIME_TIL_NEXT_EVENT_CB(DEVREAD16("huc6270", huc6270_device, time_until_next_event))
MCFG_HUC6260_VSYNC_CHANGED_CB(DEVWRITELINE("huc6270", huc6270_device, vsync_changed))
MCFG_HUC6260_HSYNC_CHANGED_CB(DEVWRITELINE("huc6270", huc6270_device, hsync_changed))
MCFG_DEVICE_ADD( "huc6270", HUC6270, 0 )
MCFG_HUC6270_VRAM_SIZE(0x10000)
MCFG_HUC6270_IRQ_CHANGED_CB(WRITELINE(pce_state, pce_irq_changed))