mirror of
https://github.com/holub/mame
synced 2025-07-07 19:03:29 +03:00
ygv608.cpp: added CRTC function, moved irqs in handler callbacks [Angelo Salese]
This commit is contained in:
parent
d0aba57fba
commit
12dc9f81a6
@ -202,9 +202,6 @@ static ADDRESS_MAP_START( namcond1_map, AS_PROGRAM, 16, namcond1_state )
|
||||
AM_RANGE(0x400000, 0x40ffff) AM_RAM AM_SHARE("shared_ram")
|
||||
AM_RANGE(0x800000, 0x80000f) AM_DEVICE8("ygv608", ygv608_device, port_map, 0xff00)
|
||||
AM_RANGE(0xa00000, 0xa00fff) AM_DEVREADWRITE8("at28c16", at28c16_device, read, write, 0xff00)
|
||||
#ifdef MAME_DEBUG
|
||||
AM_RANGE(0xb00000, 0xb00001) AM_DEVREAD("ygv608", ygv608_device, debug_trigger_r)
|
||||
#endif
|
||||
AM_RANGE(0xc3ff00, 0xc3ffff) AM_READWRITE(cuskey_r,cuskey_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -216,9 +213,6 @@ static ADDRESS_MAP_START( abcheck_map, AS_PROGRAM, 16, namcond1_state )
|
||||
AM_RANGE(0x780000, 0x780001) AM_READ(printer_r)
|
||||
AM_RANGE(0x800000, 0x80000f) AM_DEVICE8("ygv608", ygv608_device, port_map, 0xff00)
|
||||
AM_RANGE(0xa00000, 0xa00fff) AM_DEVREADWRITE8("at28c16", at28c16_device, read, write, 0xff00)
|
||||
#ifdef MAME_DEBUG
|
||||
AM_RANGE(0xb00000, 0xb00001) AM_DEVREAD("ygv608", ygv608_device, debug_trigger_r)
|
||||
#endif
|
||||
AM_RANGE(0xc3ff00, 0xc3ffff) AM_READWRITE(cuskey_r,cuskey_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -335,19 +329,22 @@ INTERRUPT_GEN_MEMBER(namcond1_state::mcu_interrupt)
|
||||
- The level 1 interrupt to the 68k has been measured at 60Hz.
|
||||
*******************************************/
|
||||
|
||||
WRITE_LINE_MEMBER( namcond1_state::vblank_irq_w )
|
||||
{
|
||||
m_maincpu->set_input_line(1, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( namcond1_state::raster_irq_w )
|
||||
{
|
||||
m_maincpu->set_input_line(2, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( namcond1 )
|
||||
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", M68000, XTAL_49_152MHz/4)
|
||||
MCFG_CPU_PROGRAM_MAP(namcond1_map)
|
||||
MCFG_CPU_VBLANK_INT_DRIVER("screen", namcond1_state, irq1_line_hold)
|
||||
|
||||
// I've disabled this for now, I don't think it's correct, it breaks ncv2 'game options' in test
|
||||
// mode (and could also be responsible for the random resets?)
|
||||
// also, if you log the timing of it and the scanlines on which the interrupt fires, it doesn't
|
||||
// seem correct for the intended purpose?
|
||||
//MCFG_DEVICE_PERIODIC_INT_DEVICE("ygv608", ygv608_device, timed_interrupt, 1000)
|
||||
|
||||
// MCFG_CPU_VBLANK_INT_DRIVER("screen", namcond1_state, irq1_line_hold)
|
||||
|
||||
MCFG_CPU_ADD("mcu", H83002, XTAL_49_152MHz/3 )
|
||||
MCFG_CPU_PROGRAM_MAP( nd1h8rwmap)
|
||||
@ -357,12 +354,18 @@ static MACHINE_CONFIG_START( namcond1 )
|
||||
MCFG_QUANTUM_TIME(attotime::from_hz(6000))
|
||||
|
||||
|
||||
MCFG_YGV608_ADD("ygv608")
|
||||
MCFG_YGV608_PALETTE("palette")
|
||||
MCFG_YGV608_VBLANK_HANDLER(WRITELINE(namcond1_state, vblank_irq_w))
|
||||
MCFG_YGV608_RASTER_HANDLER(WRITELINE(namcond1_state, raster_irq_w))
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60.0)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
|
||||
MCFG_SCREEN_SIZE(288, 224) // maximum display resolution (512x512 in theory)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 287, 0, 223) // default visible area
|
||||
/*
|
||||
H 804 108 576 48 32
|
||||
V 261 26 224 3 0
|
||||
*/
|
||||
MCFG_SCREEN_RAW_PARAMS( XTAL_49_152MHz/8, 804/2, 108/2, (108+576)/2, 261, 26, 26+224)
|
||||
MCFG_SCREEN_UPDATE_DEVICE("ygv608", ygv608_device, update_screen)
|
||||
MCFG_SCREEN_PALETTE("palette")
|
||||
|
||||
@ -379,14 +382,13 @@ static MACHINE_CONFIG_START( namcond1 )
|
||||
|
||||
MCFG_AT28C16_ADD( "at28c16", nullptr )
|
||||
|
||||
MCFG_YGV608_ADD("ygv608")
|
||||
MCFG_YGV608_PALETTE("palette")
|
||||
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( abcheck, namcond1 )
|
||||
MCFG_CPU_REPLACE("maincpu", M68000, XTAL_49_152MHz/4)
|
||||
MCFG_CPU_PROGRAM_MAP(abcheck_map)
|
||||
MCFG_CPU_VBLANK_INT_DRIVER("screen", namcond1_state, irq1_line_hold)
|
||||
// MCFG_CPU_VBLANK_INT_DRIVER("screen", namcond1_state, irq1_line_hold)
|
||||
|
||||
MCFG_NVRAM_ADD_0FILL("zpr1")
|
||||
MCFG_NVRAM_ADD_0FILL("zpr2")
|
||||
|
@ -43,5 +43,7 @@ public:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
INTERRUPT_GEN_MEMBER(mcu_interrupt);
|
||||
DECLARE_WRITE_LINE_MEMBER( vblank_irq_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( raster_irq_w );
|
||||
INTERRUPT_GEN_MEMBER(mcu_interrupt);
|
||||
};
|
||||
|
@ -361,7 +361,12 @@ GFXDECODE_END
|
||||
*
|
||||
***************************************/
|
||||
|
||||
// we use decimals here to match documentation
|
||||
static ADDRESS_MAP_START( regs_map, AS_IO, 8, ygv608_device )
|
||||
AM_RANGE(14, 14) AM_READWRITE(irq_mask_r,irq_mask_w)
|
||||
AM_RANGE(15, 16) AM_READWRITE(irq_ctrl_r,irq_ctrl_w)
|
||||
|
||||
AM_RANGE(39, 46) AM_WRITE(crtc_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/***************************************
|
||||
@ -390,7 +395,9 @@ ygv608_device::ygv608_device( const machine_config &mconfig, const char *tag, de
|
||||
: device_t(mconfig, YGV608, tag, owner, clock),
|
||||
device_gfx_interface(mconfig, *this, GFXDECODE_NAME(ygv608)),
|
||||
device_memory_interface(mconfig, *this),
|
||||
m_io_space_config("io", ENDIANNESS_BIG, 8, 6, 0, *ADDRESS_MAP_NAME(regs_map))
|
||||
m_io_space_config("io", ENDIANNESS_BIG, 8, 6, 0, *ADDRESS_MAP_NAME(regs_map)),
|
||||
m_vblank_handler(*this),
|
||||
m_raster_handler(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -446,7 +453,14 @@ void ygv608_device::device_start()
|
||||
m_tilemap_B = nullptr;
|
||||
|
||||
m_iospace = &space(AS_IO);
|
||||
|
||||
|
||||
// TODO: tagging configuration
|
||||
m_screen = downcast<screen_device *>(machine().device("screen"));
|
||||
m_vblank_handler.resolve();
|
||||
m_raster_handler.resolve();
|
||||
m_vblank_timer = timer_alloc(VBLANK_TIMER);
|
||||
m_raster_timer = timer_alloc(RASTER_TIMER);
|
||||
|
||||
register_state_save();
|
||||
}
|
||||
|
||||
@ -460,42 +474,32 @@ const address_space_config *ygv608_device::memory_space_config(address_spacenum
|
||||
return (spacenum == AS_IO) ? &m_io_space_config : nullptr;
|
||||
}
|
||||
|
||||
void ygv608_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case VBLANK_TIMER:
|
||||
{
|
||||
m_screen_status |= 8; // FV
|
||||
if(m_vblank_irq_mask == true)
|
||||
m_vblank_handler(ASSERT_LINE);
|
||||
break;
|
||||
}
|
||||
case RASTER_TIMER:
|
||||
{
|
||||
m_screen_status |= 0x10; // FP
|
||||
if(m_raster_irq_mask == true)
|
||||
m_raster_handler(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ygv608_device::set_gfxbank(uint8_t gfxbank)
|
||||
{
|
||||
m_namcond1_gfxbank = gfxbank;
|
||||
}
|
||||
|
||||
/* interrupt generated every 1ms second */
|
||||
INTERRUPT_GEN_MEMBER(ygv608_device::timed_interrupt )
|
||||
{
|
||||
/*
|
||||
this is not quite generic, because we trigger a 68k interrupt
|
||||
- if this chip is ever used by another driver, we should make
|
||||
this more generic - or move it into the machine driver
|
||||
*/
|
||||
|
||||
static int timer = 0;
|
||||
|
||||
if( ++timer == 1000 )
|
||||
timer = 0;
|
||||
|
||||
/* once every 60Hz, set the vertical border interval start flag */
|
||||
if( ( timer % (1000/60) ) == 0 )
|
||||
{
|
||||
m_ports.s.p6 |= p6_fv;
|
||||
if (m_regs.s.r14 & r14_iev)
|
||||
device.execute().set_input_line(2, HOLD_LINE);
|
||||
}
|
||||
|
||||
/* once every 60Hz, set the position detection flag (somewhere) */
|
||||
else if( ( timer % (1000/60) ) == 7 )
|
||||
{
|
||||
m_ports.s.p6 |= p6_fp;
|
||||
if (m_regs.s.r14 & r14_iep)
|
||||
device.execute().set_input_line(2, HOLD_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TILEMAP_MAPPER_MEMBER( ygv608_device::get_tile_offset )
|
||||
@ -1138,13 +1142,6 @@ uint32_t ygv608_device::update_screen(screen_device &screen, bitmap_ind16 &bitma
|
||||
|
||||
if( m_screen_resize )
|
||||
{
|
||||
#ifdef _ENABLE_SCREEN_RESIZE
|
||||
// hdw should be scaled by 16, not 8
|
||||
// - is it something to do with double dot-clocks???
|
||||
screen.set_visible_area(0, ((int)(m_regs.s.hdw)<<3/*4*/)-1,
|
||||
0, ((int)(m_regs.s.vdw)<<3)-1 );
|
||||
#endif
|
||||
|
||||
m_work_bitmap.resize(screen.width(), screen.height());
|
||||
|
||||
// reset resize flag
|
||||
@ -1455,7 +1452,7 @@ READ8_MEMBER(ygv608_device::register_data_r)
|
||||
***/
|
||||
READ8_MEMBER( ygv608_device::status_port_r )
|
||||
{
|
||||
return (uint8_t)(m_ports.b[6]);
|
||||
return m_screen_status;
|
||||
}
|
||||
|
||||
// P#7R - system control port
|
||||
@ -1628,7 +1625,11 @@ WRITE8_MEMBER( ygv608_device::register_select_w )
|
||||
WRITE8_MEMBER( ygv608_device::status_port_w )
|
||||
{
|
||||
/* writing a '1' resets that bit */
|
||||
m_ports.b[6] &= ~data;
|
||||
m_screen_status &= ~data;
|
||||
if(data & 8)
|
||||
m_vblank_handler(0);
|
||||
if(data & 0x10)
|
||||
m_raster_handler(0);
|
||||
}
|
||||
|
||||
// P#7W - system control port
|
||||
@ -1729,30 +1730,166 @@ void ygv608_device::HandleRomTransfers(uint8_t type)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
void nvsram( offs_t offset, uint16_t data )
|
||||
/***************************************
|
||||
*
|
||||
* Register Interface routines
|
||||
*
|
||||
****************************************/
|
||||
|
||||
// R#14R interrupt mask control
|
||||
READ8_MEMBER( ygv608_device::irq_mask_r )
|
||||
{
|
||||
static int i = 0;
|
||||
|
||||
data = ( data >> 8 ) & 0xff;
|
||||
|
||||
if( 1 ) {
|
||||
static char ascii[16];
|
||||
if( i%16 == 0 )
|
||||
logerror( "%04X: ", offset );
|
||||
logerror( "%02X ", data );
|
||||
ascii[i%16] = (data > 0x20) ? data : '.';
|
||||
if( i%16 == 15 )
|
||||
logerror( "| %-16.16s\n", ascii );
|
||||
}
|
||||
|
||||
i++;
|
||||
return (m_raster_irq_mask << 1) | (m_vblank_irq_mask << 0);
|
||||
}
|
||||
|
||||
// R#14W interrupt mask control
|
||||
WRITE8_MEMBER( ygv608_device::irq_mask_w )
|
||||
{
|
||||
m_vblank_irq_mask = BIT(data, 0);
|
||||
m_raster_irq_mask = BIT(data, 1);
|
||||
}
|
||||
|
||||
// R#15R / R#16R raster interrupt control
|
||||
READ8_MEMBER( ygv608_device::irq_ctrl_r )
|
||||
{
|
||||
uint8_t res;
|
||||
|
||||
if(offset == 0) // R#15
|
||||
res = m_raster_irq_vpos & 0xff;
|
||||
else // R#16
|
||||
{
|
||||
res = (m_raster_irq_mode << 7);
|
||||
|
||||
res|= (BIT(m_raster_irq_vpos, 8) << 6);
|
||||
|
||||
res|= (m_raster_irq_hpos / 32) & 0x1f;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// R#15W / R#16W raster interrupt control
|
||||
WRITE8_MEMBER( ygv608_device::irq_ctrl_w )
|
||||
{
|
||||
if(offset == 0) // R#15
|
||||
{
|
||||
m_raster_irq_vpos &= ~0xff;
|
||||
m_raster_irq_vpos |= data & 0xff;
|
||||
}
|
||||
else // R#16
|
||||
{
|
||||
m_raster_irq_mode = BIT(data,7);
|
||||
|
||||
m_raster_irq_vpos &= ~0x100;
|
||||
m_raster_irq_vpos |= BIT(data,6) << 8;
|
||||
|
||||
m_raster_irq_hpos = (data & 0x1f) * 32;
|
||||
}
|
||||
}
|
||||
|
||||
// R#39W - R#46W display scan control write
|
||||
WRITE8_MEMBER( ygv608_device::crtc_w )
|
||||
{
|
||||
//printf("[%d] <- %02x\n",offset+39,data);
|
||||
|
||||
switch(offset+39)
|
||||
{
|
||||
case 39:
|
||||
{
|
||||
m_crtc.display_hsync = ((data >> 5) & 7) * 16;
|
||||
m_crtc.border_width = (data & 0x1f) * 16;
|
||||
break;
|
||||
}
|
||||
|
||||
case 40:
|
||||
{
|
||||
m_crtc.htotal &= ~0x600;
|
||||
m_crtc.htotal |= (data & 0xc0) << 3;
|
||||
|
||||
m_crtc.display_width = (data & 0x3f) * 16;
|
||||
break;
|
||||
}
|
||||
|
||||
case 41:
|
||||
{
|
||||
m_crtc.display_hstart &= ~0x1fe;
|
||||
m_crtc.display_hstart |= (data & 0xff) << 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 42:
|
||||
{
|
||||
m_crtc.htotal &= ~0x1fe;
|
||||
m_crtc.htotal |= (data & 0xff) << 1;
|
||||
|
||||
printf("H %d %d %d %d %d\n",m_crtc.htotal,m_crtc.display_hstart,m_crtc.display_width,m_crtc.display_hsync,m_crtc.border_width);
|
||||
break;
|
||||
}
|
||||
|
||||
case 43:
|
||||
{
|
||||
m_crtc.display_vsync = (data >> 5) & 7;
|
||||
m_crtc.border_height = (data & 0x1f) * 8;
|
||||
break;
|
||||
}
|
||||
|
||||
case 44:
|
||||
{
|
||||
// TODO: VSLS, bit 6
|
||||
|
||||
m_crtc.display_height = (data & 0x3f) * 8;
|
||||
break;
|
||||
}
|
||||
|
||||
case 45:
|
||||
{
|
||||
m_crtc.vtotal &= ~0x100;
|
||||
m_crtc.vtotal |= BIT(data,7) << 8;
|
||||
|
||||
// TODO: TRES, bit 6
|
||||
|
||||
m_crtc.display_vstart = data & 0x3f;
|
||||
break;
|
||||
}
|
||||
|
||||
case 46:
|
||||
{
|
||||
m_crtc.vtotal &= ~0xff;
|
||||
m_crtc.vtotal |= data & 0xff;
|
||||
|
||||
// TODO: call it for all mods in the CRTC
|
||||
screen_configure();
|
||||
|
||||
//printf("V %d %d %d %d %d\n",m_crtc.vtotal,m_crtc.display_vstart,m_crtc.display_height,m_crtc.display_vsync,m_crtc.border_height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: all horizontal values needs to be divided by 2, presumably some other register?
|
||||
// TODO: h/vstart not taken into account (needs video mods)
|
||||
void ygv608_device::screen_configure()
|
||||
{
|
||||
// int display_hend = (m_crtc.display_hstart + (m_crtc.display_width / 2)) - 1;
|
||||
int display_hend = (m_crtc.display_width / 2) - 1;
|
||||
// int display_vend = (m_crtc.display_vstart + m_crtc.display_height) - 1;
|
||||
int display_vend = (m_crtc.display_height) - 1;
|
||||
|
||||
//rectangle visarea(m_crtc.display_hstart, display_hend, m_crtc.display_vstart, display_vend);
|
||||
rectangle visarea(0, display_hend, 0, display_vend);
|
||||
|
||||
attoseconds_t period = HZ_TO_ATTOSECONDS(m_screen->clock()) * m_crtc.vtotal * (m_crtc.htotal / 2);
|
||||
|
||||
m_screen->configure(m_crtc.htotal / 2, m_crtc.vtotal, visarea, period );
|
||||
|
||||
// reset vblank timer
|
||||
m_vblank_timer->reset();
|
||||
//m_vblank_timer->adjust(m_screen->time_until_pos(m_crtc.display_vstart+m_crtc.display_height,0), 0, m_screen->frame_period());
|
||||
m_vblank_timer->adjust(m_screen->time_until_pos(m_crtc.display_height,0), 0, m_screen->frame_period());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set any "short-cut" variables before we update the YGV608 registers
|
||||
// - these are used only in optimisation of the emulation
|
||||
|
||||
void ygv608_device::SetPreShortcuts( int reg, int data )
|
||||
{
|
||||
switch( reg ) {
|
||||
@ -1937,106 +2074,10 @@ void ygv608_device::SetPostShortcuts(int reg )
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* The rest of this stuff is for debugging only!
|
||||
*/
|
||||
|
||||
|
||||
//#define SHOW_SOURCE_MODE
|
||||
|
||||
#if 0
|
||||
void dump_block( char *name, uint8_t *block, int len )
|
||||
{
|
||||
int i;
|
||||
|
||||
logerror( "uint8_t %s[] = {\n", name );
|
||||
for( i=0; i<len; i++ ) {
|
||||
if( i%8 == 0 )
|
||||
logerror( " " );
|
||||
logerror( "0x%02X, ", block[i] );
|
||||
if( i%8 == 7 )
|
||||
logerror( "\n" );
|
||||
}
|
||||
logerror( "};\n" );
|
||||
}
|
||||
#endif
|
||||
READ16_MEMBER( ygv608_device::debug_trigger_r )
|
||||
{
|
||||
static int oneshot = 0;
|
||||
|
||||
#ifndef SHOW_SOURCE_MODE
|
||||
int i;
|
||||
#endif
|
||||
char ascii[16];
|
||||
|
||||
if( oneshot )
|
||||
return( 0 );
|
||||
oneshot = 1;
|
||||
|
||||
ShowYGV608Registers();
|
||||
|
||||
#ifdef SHOW_SOURCE_MODE
|
||||
#if 0
|
||||
dump_block( "ygv608_regs",
|
||||
(uint8_t *)m_regs.b,
|
||||
64 );
|
||||
dump_block( "ygv608_pnt",
|
||||
(uint8_t *)m_pattern_name_table,
|
||||
4096 );
|
||||
dump_block( "ygv608_sat",
|
||||
(uint8_t *)m_sprite_attribute_table.b,
|
||||
256 );
|
||||
dump_block( "ygv608_sdt",
|
||||
(uint8_t *)m_scroll_data_table,
|
||||
512 );
|
||||
dump_block( "ygv608_cp",
|
||||
(uint8_t *)m_colour_palette,
|
||||
768 );
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Dump pattern name table ram
|
||||
*/
|
||||
#if 1
|
||||
logerror( "Pattern Name Table\n" );
|
||||
for( i=0; i<4096; i++ ) {
|
||||
if( i % 16 == 0 )
|
||||
logerror( "$%04X : ", i );
|
||||
logerror( "%02X ", m_pattern_name_table[i] );
|
||||
if( m_pattern_name_table[i] >= 0x20)
|
||||
ascii[i%16] = m_pattern_name_table[i];
|
||||
else
|
||||
ascii[i%16] = '.';
|
||||
if( i % 16 == 15 )
|
||||
logerror( " | %-16.16s\n", ascii );
|
||||
}
|
||||
logerror( "\n" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dump scroll table ram
|
||||
*/
|
||||
|
||||
logerror( "Scroll Table\n" );
|
||||
for( i=0; i<256; i++ ) {
|
||||
if( i % 16 == 0 )
|
||||
logerror( "$%04X : ", i );
|
||||
logerror( "%02X ", m_scroll_data_table[0][i] );
|
||||
if( m_scroll_data_table[0][i] >= 0x20 )
|
||||
ascii[i%16] = m_scroll_data_table[0][i];
|
||||
else
|
||||
ascii[i%16] = '.';
|
||||
if( i % 16 == 15 )
|
||||
logerror( " | %-16.16s\n", ascii );
|
||||
}
|
||||
logerror( "\n" );
|
||||
|
||||
#endif
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void ygv608_device::ShowYGV608Registers()
|
||||
{
|
||||
|
@ -1,15 +1,17 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark McDougall
|
||||
/*
|
||||
* Yamaha YGV608 - PVDC2 Pattern mode Video Display Controller 2
|
||||
* - Mark McDougall
|
||||
*/
|
||||
|
||||
#ifndef MAME_VIDEO_YGV608_H
|
||||
#define MAME_VIDEO_YGV608_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tilemap.h"
|
||||
/*
|
||||
* Yamaha YGV608 - PVDC2 Pattern mode Video Display Controller 2
|
||||
* - Mark McDougall
|
||||
*/
|
||||
#include "screen.h"
|
||||
|
||||
class ygv608_device : public device_t,
|
||||
public device_gfx_interface,
|
||||
@ -21,6 +23,7 @@ public:
|
||||
|
||||
DECLARE_ADDRESS_MAP(port_map, 8);
|
||||
|
||||
// ports section
|
||||
DECLARE_READ8_MEMBER(pattern_name_table_r);
|
||||
DECLARE_READ8_MEMBER(sprite_data_r);
|
||||
DECLARE_READ8_MEMBER(scroll_data_r);
|
||||
@ -38,21 +41,35 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(status_port_w);
|
||||
DECLARE_WRITE8_MEMBER(system_control_w);
|
||||
|
||||
// register section
|
||||
DECLARE_READ8_MEMBER(irq_mask_r);
|
||||
DECLARE_WRITE8_MEMBER(irq_mask_w);
|
||||
DECLARE_READ8_MEMBER(irq_ctrl_r);
|
||||
DECLARE_WRITE8_MEMBER(irq_ctrl_w);
|
||||
DECLARE_WRITE8_MEMBER(crtc_w);
|
||||
|
||||
// TODO: is this even a real connection?
|
||||
void set_gfxbank(uint8_t gfxbank);
|
||||
|
||||
uint32_t update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
INTERRUPT_GEN_MEMBER( timed_interrupt );
|
||||
|
||||
// to be removed
|
||||
DECLARE_READ16_MEMBER( debug_trigger_r );
|
||||
template <class Object> static devcb_base &static_set_vblank_callback(device_t &device, Object &&cb)
|
||||
{
|
||||
return downcast<ygv608_device &>(device).m_vblank_handler.set_callback(std::forward<Object>(cb));
|
||||
}
|
||||
template <class Object> static devcb_base &static_set_raster_callback(device_t &device, Object &&cb)
|
||||
{
|
||||
return downcast<ygv608_device &>(device).m_raster_handler.set_callback(std::forward<Object>(cb));
|
||||
}
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_IO) const override;
|
||||
|
||||
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
address_space *m_iospace;
|
||||
private:
|
||||
const address_space_config m_io_space_config;
|
||||
@ -226,7 +243,42 @@ private:
|
||||
// new variable handling starts here
|
||||
uint8_t m_register_address; /**< RN: Register address select */
|
||||
bool m_register_autoinc_r; /**< RRAI: Register address auto-increment on read */
|
||||
bool m_register_autoinc_w; /**< RWAI: Register address auto-increment on write */
|
||||
bool m_register_autoinc_w; /**< RWAI: Register address auto-increment on write */
|
||||
uint8_t m_screen_status; /**< CD: status port r/w */
|
||||
|
||||
bool m_raster_irq_mask; /**< IEP: raster irq mask (INT1 occurs if 1) */
|
||||
bool m_vblank_irq_mask; /**< IEV: vblank irq mask (INT0 occurs if 1) */
|
||||
int m_raster_irq_hpos; /**< IH: horizontal position where raster irq occurs x 32 */
|
||||
int m_raster_irq_vpos; /**< IV: vertical position where raster irq occurs */
|
||||
bool m_raster_irq_mode; /**< FPM: if 1 vertical position becomes invalid for raster irqs (irqs occur for every line) */
|
||||
|
||||
// screen section
|
||||
devcb_write_line m_vblank_handler;
|
||||
devcb_write_line m_raster_handler;
|
||||
screen_device *m_screen;
|
||||
emu_timer *m_vblank_timer;
|
||||
emu_timer *m_raster_timer;
|
||||
|
||||
enum
|
||||
{
|
||||
VBLANK_TIMER,
|
||||
RASTER_TIMER
|
||||
};
|
||||
|
||||
struct {
|
||||
int htotal; /**< HTL: horizontal total number of dots x 2 */
|
||||
int vtotal; /**< VTL: vertical total number of lines x 1 */
|
||||
int display_hstart; /**< HDS: horizontal display starting position x 2*/
|
||||
int display_vstart; /**< VDS: vertical display starting position x 1 */
|
||||
int display_width; /**< HDW: horizontal display size x 16 */
|
||||
int display_height; /**< VDW: vertical display size x 8 */
|
||||
int display_hsync; /**< HSW: horizontal sync signal x 16 */
|
||||
int display_vsync; /**< VSW: vertical sync signal x 1 */
|
||||
int border_width; /**< HBW: horizontal border size x 16 */
|
||||
int border_height; /**< VBW: vertical border size x 8 */
|
||||
}m_crtc;
|
||||
|
||||
void screen_configure();
|
||||
};
|
||||
|
||||
// device type definition
|
||||
@ -243,4 +295,11 @@ DECLARE_DEVICE_TYPE(YGV608, ygv608_device)
|
||||
#define MCFG_YGV608_PALETTE(_palette_tag) \
|
||||
MCFG_GFX_PALETTE(_palette_tag)
|
||||
|
||||
#define MCFG_YGV608_VBLANK_HANDLER( _intcallb ) \
|
||||
devcb = &ygv608_device::static_set_vblank_callback( *device, DEVCB_##_intcallb );
|
||||
|
||||
#define MCFG_YGV608_RASTER_HANDLER( _intcallb ) \
|
||||
devcb = &ygv608_device::static_set_raster_callback( *device, DEVCB_##_intcallb );
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user