moved some snes stuff into the driver class. nw.

This commit is contained in:
Fabio Priuli 2013-03-04 12:30:07 +00:00
parent eef0a7fdf2
commit a5aa8f846c
6 changed files with 183 additions and 200 deletions

View File

@ -793,31 +793,6 @@ static INPUT_PORTS_START( snes )
INPUT_PORTS_END
static MACHINE_CONFIG_START( snes, nss_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", _5A22, MCLK_NTSC) /* 2.68Mhz, also 3.58Mhz */
MCFG_CPU_PROGRAM_MAP(snes_map)
MCFG_CPU_ADD("soundcpu", SPC700, 2048000/2) /* 2.048 Mhz, but internal divider */
MCFG_CPU_PROGRAM_MAP(spc_mem)
MCFG_QUANTUM_PERFECT_CPU("maincpu")
/* video hardware */
MCFG_VIDEO_START( snes )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(DOTCLK_NTSC, SNES_HTOTAL, 0, SNES_SCR_WIDTH, SNES_VTOTAL_NTSC, 0, SNES_SCR_HEIGHT_NTSC)
MCFG_SCREEN_UPDATE_DRIVER( snes_state, snes_screen_update )
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("spc700", SNES, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.00)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.00)
MACHINE_CONFIG_END
INTERRUPT_GEN_MEMBER(nss_state::nss_vblank_irq)
{
if(m_nmi_enable)
@ -841,8 +816,18 @@ static M50458_INTERFACE( m50458_intf )
"osd"
};
static MACHINE_CONFIG_DERIVED( nss, snes )
static MACHINE_CONFIG_START( nss, nss_state )
/* base snes hardware */
MCFG_CPU_ADD("maincpu", _5A22, MCLK_NTSC) /* 2.68Mhz, also 3.58Mhz */
MCFG_CPU_PROGRAM_MAP(snes_map)
MCFG_CPU_ADD("soundcpu", SPC700, 2048000/2) /* 2.048 Mhz, but internal divider */
MCFG_CPU_PROGRAM_MAP(spc_mem)
MCFG_QUANTUM_PERFECT_CPU("maincpu")
/* nss hardware */
MCFG_CPU_ADD("bios", Z80, 4000000)
MCFG_CPU_PROGRAM_MAP(bios_map)
MCFG_CPU_IO_MAP(bios_io_map)
@ -853,9 +838,24 @@ static MACHINE_CONFIG_DERIVED( nss, snes )
MCFG_RP5H01_ADD("rp5h01")
MCFG_M6M80011AP_ADD("m6m80011ap")
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("spc700", SNES, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.00)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.00)
/* video hardware */
MCFG_VIDEO_START( snes )
/* TODO: the screen should actually superimpose, but for the time being let's just separate outputs */
MCFG_DEFAULT_LAYOUT(layout_dualhsxs)
// SNES PPU
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(DOTCLK_NTSC, SNES_HTOTAL, 0, SNES_SCR_WIDTH, SNES_VTOTAL_NTSC, 0, SNES_SCR_HEIGHT_NTSC)
MCFG_SCREEN_UPDATE_DRIVER( snes_state, screen_update )
// NSS
MCFG_SCREEN_ADD("osd", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))

View File

@ -148,8 +148,8 @@ public:
DECLARE_WRITE8_MEMBER( port_83_w );
DECLARE_WRITE8_MEMBER( snes_map_0_w );
DECLARE_WRITE8_MEMBER( snes_map_1_w );
DECLARE_MACHINE_START(sfcbox);
DECLARE_MACHINE_RESET(sfcbox);
virtual void machine_start();
virtual void machine_reset();
DECLARE_READ8_MEMBER(spc_ram_100_r);
DECLARE_WRITE8_MEMBER(spc_ram_100_w);
};
@ -438,43 +438,14 @@ static INPUT_PORTS_START( snes )
#endif
INPUT_PORTS_END
static MACHINE_CONFIG_START( snes, sfcbox_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", _5A22, 3580000*6) /* 2.68Mhz, also 3.58Mhz */
MCFG_CPU_PROGRAM_MAP(snes_map)
MCFG_CPU_ADD("soundcpu", SPC700, 2048000/2) /* 2.048 Mhz, but internal divider */
MCFG_CPU_PROGRAM_MAP(spc_mem)
MCFG_QUANTUM_PERFECT_CPU("maincpu")
MCFG_MACHINE_START( snes )
MCFG_MACHINE_RESET( snes )
/* video hardware */
MCFG_VIDEO_START( snes )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(DOTCLK_NTSC, SNES_HTOTAL, 0, SNES_SCR_WIDTH, SNES_VTOTAL_NTSC, 0, SNES_SCR_HEIGHT_NTSC)
MCFG_SCREEN_UPDATE_DRIVER( snes_state, snes_screen_update )
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("spc700", SNES, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.00)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.00)
MACHINE_CONFIG_END
MACHINE_START_MEMBER(sfcbox_state,sfcbox)
void sfcbox_state::machine_start()
{
MACHINE_START_CALL_LEGACY(snes);
m_is_sfcbox = 1;
}
MACHINE_RESET_MEMBER(sfcbox_state,sfcbox)
void sfcbox_state::machine_reset()
{
MACHINE_RESET_CALL_LEGACY( snes );
@ -483,8 +454,18 @@ MACHINE_RESET_MEMBER(sfcbox_state,sfcbox)
m_soundcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
static MACHINE_CONFIG_DERIVED( sfcbox, snes )
static MACHINE_CONFIG_START( sfcbox, sfcbox_state )
/* base snes hardware */
MCFG_CPU_ADD("maincpu", _5A22, 3580000*6) /* 2.68Mhz, also 3.58Mhz */
MCFG_CPU_PROGRAM_MAP(snes_map)
MCFG_CPU_ADD("soundcpu", SPC700, 2048000/2) /* 2.048 Mhz, but internal divider */
MCFG_CPU_PROGRAM_MAP(spc_mem)
MCFG_QUANTUM_PERFECT_CPU("maincpu")
/* sfcbox hardware */
MCFG_CPU_ADD("bios", Z180, XTAL_12MHz / 2) /* HD64180RF6X */
MCFG_CPU_PROGRAM_MAP(sfcbox_map)
MCFG_CPU_IO_MAP(sfcbox_io)
@ -492,12 +473,24 @@ static MACHINE_CONFIG_DERIVED( sfcbox, snes )
MCFG_MB90082_ADD("mb90082",XTAL_12MHz / 2) /* TODO: correct clock */
MCFG_S3520CF_ADD("s3520cf") /* RTC */
MCFG_MACHINE_START_OVERRIDE(sfcbox_state, sfcbox )
MCFG_MACHINE_RESET_OVERRIDE(sfcbox_state, sfcbox )
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("spc700", SNES, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.00)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.00)
/* video hardware */
MCFG_VIDEO_START( snes )
/* TODO: the screen should actually superimpose, but for the time being let's just separate outputs */
MCFG_DEFAULT_LAYOUT(layout_dualhsxs)
// SNES PPU
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(DOTCLK_NTSC, SNES_HTOTAL, 0, SNES_SCR_WIDTH, SNES_VTOTAL_NTSC, 0, SNES_SCR_HEIGHT_NTSC)
MCFG_SCREEN_UPDATE_DRIVER( snes_state, screen_update )
// SFCBOX
MCFG_SCREEN_ADD("osd", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))

View File

@ -646,7 +646,7 @@ static MACHINE_CONFIG_START( kinstb, snesb_state )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(DOTCLK_NTSC, SNES_HTOTAL, 0, SNES_SCR_WIDTH, SNES_VTOTAL_NTSC, 0, SNES_SCR_HEIGHT_NTSC)
MCFG_SCREEN_UPDATE_DRIVER( snes_state, snes_screen_update )
MCFG_SCREEN_UPDATE_DRIVER( snes_state, screen_update )
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")

View File

@ -660,7 +660,7 @@ public:
snes_cart_info m_cart[2]; // the second one is used by MESS for Sufami Turbo and, eventually, BS-X
snes_ppu_class m_ppu;
UINT32 snes_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
/* devices */
_5a22_device *m_maincpu;
@ -677,6 +677,17 @@ public:
DECLARE_DRIVER_INIT(snes_mess);
DECLARE_DRIVER_INIT(snesst);
inline int dma_abus_valid(UINT32 address);
inline UINT8 abus_read(address_space &space, UINT32 abus);
inline void dma_transfer(address_space &space, UINT8 dma, UINT32 abus, UINT16 bbus);
inline int is_last_active_channel(int dma);
inline UINT32 get_hdma_addr(int dma);
inline UINT32 get_hdma_iaddr(int dma);
void dma(address_space &space, UINT8 channels);
void hdma(address_space &space);
void hdma_init(address_space &space);
void hdma_update(address_space &space, int dma);
void hirq_tick();
TIMER_CALLBACK_MEMBER(snes_nmi_tick);
TIMER_CALLBACK_MEMBER(snes_hirq_tick_callback);

View File

@ -31,10 +31,6 @@
/* -- Globals -- */
UINT8 *snes_ram = NULL; /* 65816 ram */
static void snes_dma(address_space &space, UINT8 channels);
static void snes_hdma_init(address_space &space);
static void snes_hdma(address_space &space);
static DECLARE_READ8_HANDLER(snes_io_dma_r);
static DECLARE_WRITE8_HANDLER(snes_io_dma_w);
@ -102,7 +98,7 @@ VIDEO_START( snes )
state->m_ppu.ppu_start(machine);
}
UINT32 snes_state::snes_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
UINT32 snes_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
/* NTSC SNES draw range is 1-225. */
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
@ -127,23 +123,21 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_nmi_tick)
m_nmi_timer->adjust(attotime::never);
}
static void snes_hirq_tick( running_machine &machine )
void snes_state::hirq_tick()
{
snes_state *state = machine.driver_data<snes_state>();
// latch the counters and pull IRQ
// (don't need to switch to the 65816 context, we don't do anything dependant on it)
state->m_ppu.latch_counters(machine);
m_ppu.latch_counters(machine());
snes_ram[TIMEUP] = 0x80; /* Indicate that irq occurred */
state->m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE);
m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE);
// don't happen again
state->m_hirq_timer->adjust(attotime::never);
m_hirq_timer->adjust(attotime::never);
}
TIMER_CALLBACK_MEMBER(snes_state::snes_hirq_tick_callback)
{
snes_hirq_tick(machine());
hirq_tick();
}
TIMER_CALLBACK_MEMBER(snes_state::snes_reset_oam_address)
@ -162,7 +156,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_reset_oam_address)
TIMER_CALLBACK_MEMBER(snes_state::snes_reset_hdma)
{
address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
snes_hdma_init(cpu0space);
hdma_init(cpu0space);
}
TIMER_CALLBACK_MEMBER(snes_state::snes_update_io)
@ -213,7 +207,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick)
// printf("HIRQ @ %d, %d\n", pixel * m_ppu.m_htmult, m_ppu.m_beam.current_vert);
if (pixel == 0)
{
snes_hirq_tick(machine());
hirq_tick();
}
else
{
@ -244,7 +238,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick)
if (m_ppu.m_beam.current_vert == 0)
{
address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
snes_hdma_init(cpu0space);
hdma_init(cpu0space);
}
if (m_ppu.m_beam.current_vert == 0)
@ -281,7 +275,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_hblank_tick)
{
/* Do HDMA */
if (snes_ram[HDMAEN])
snes_hdma(cpu0space);
hdma(cpu0space);
machine().primary_screen->update_partial((m_ppu.m_interlace == 2) ? (m_ppu.m_beam.current_vert * m_ppu.m_interlace) : m_ppu.m_beam.current_vert - 1);
}
@ -727,7 +721,7 @@ WRITE8_HANDLER( snes_w_io )
state->m_vtime &= 0x1ff;
return;
case MDMAEN: /* DMA channel designation and trigger */
snes_dma(space, data);
state->dma(space, data);
data = 0; /* Once DMA is done we need to reset all bits to 0 */
break;
case HDMAEN: /* HDMA channel designation */
@ -1949,7 +1943,7 @@ DRIVER_INIT_MEMBER(snes_state,snes_hirom)
*************************************/
INLINE int dma_abus_valid( UINT32 address )
inline int snes_state::dma_abus_valid( UINT32 address )
{
if((address & 0x40ff00) == 0x2100) return 0; //$[00-3f|80-bf]:[2100-21ff]
if((address & 0x40fe00) == 0x4000) return 0; //$[00-3f|80-bf]:[4000-41ff]
@ -1959,7 +1953,7 @@ INLINE int dma_abus_valid( UINT32 address )
return 1;
}
INLINE UINT8 snes_abus_read( address_space &space, UINT32 abus )
inline UINT8 snes_state::abus_read( address_space &space, UINT32 abus )
{
if (!dma_abus_valid(abus))
return 0;
@ -1967,11 +1961,9 @@ INLINE UINT8 snes_abus_read( address_space &space, UINT32 abus )
return space.read_byte(abus);
}
INLINE void snes_dma_transfer( address_space &space, UINT8 dma, UINT32 abus, UINT16 bbus )
inline void snes_state::dma_transfer( address_space &space, UINT8 dma, UINT32 abus, UINT16 bbus )
{
snes_state *state = space.machine().driver_data<snes_state>();
if (state->m_dma_channel[dma].dmap & 0x80) /* PPU->CPU */
if (m_dma_channel[dma].dmap & 0x80) /* PPU->CPU */
{
if (bbus == 0x2180 && ((abus & 0xfe0000) == 0x7e0000 || (abus & 0x40e000) == 0x0000))
{
@ -2000,7 +1992,7 @@ INLINE void snes_dma_transfer( address_space &space, UINT8 dma, UINT32 abus, UIN
}
else
{
space.write_byte(bbus, snes_abus_read(space, abus));
space.write_byte(bbus, abus_read(space, abus));
return;
}
}
@ -2008,26 +2000,21 @@ INLINE void snes_dma_transfer( address_space &space, UINT8 dma, UINT32 abus, UIN
/* WIP: These have the advantage to automatically update the address, but then we would need to
check again if the transfer is direct/indirect at each step... is it worth? */
INLINE UINT32 snes_get_hdma_addr( running_machine &machine, int dma )
inline UINT32 snes_state::get_hdma_addr( int dma )
{
snes_state *state = machine.driver_data<snes_state>();
return (state->m_dma_channel[dma].bank << 16) | (state->m_dma_channel[dma].hdma_addr++);
return (m_dma_channel[dma].bank << 16) | (m_dma_channel[dma].hdma_addr++);
}
INLINE UINT32 snes_get_hdma_iaddr( running_machine &machine, int dma )
inline UINT32 snes_state::get_hdma_iaddr( int dma )
{
snes_state *state = machine.driver_data<snes_state>();
return (state->m_dma_channel[dma].ibank << 16) | (state->m_dma_channel[dma].trans_size++);
return (m_dma_channel[dma].ibank << 16) | (m_dma_channel[dma].trans_size++);
}
INLINE int is_last_active_channel( running_machine &machine, int dma )
inline int snes_state::is_last_active_channel( int dma )
{
snes_state *state = machine.driver_data<snes_state>();
int i;
for (i = dma + 1; i < 8; i++)
for (int i = dma + 1; i < 8; i++)
{
if (BIT(state->m_hdmaen, i) && state->m_dma_channel[i].hdma_line_counter)
if (BIT(m_hdmaen, i) && m_dma_channel[i].hdma_line_counter)
return 0; // there is still at least another channel with incomplete HDMA
}
@ -2035,141 +2022,133 @@ INLINE int is_last_active_channel( running_machine &machine, int dma )
return 1;
}
static void snes_hdma_update( address_space &space, int dma )
void snes_state::hdma_update( address_space &space, int dma )
{
snes_state *state = space.machine().driver_data<snes_state>();
UINT32 abus = snes_get_hdma_addr(space.machine(), dma);
UINT32 abus = get_hdma_addr(dma);
state->m_dma_channel[dma].hdma_line_counter = snes_abus_read(space, abus);
m_dma_channel[dma].hdma_line_counter = abus_read(space, abus);
if (state->m_dma_channel[dma].dmap & 0x40)
if (m_dma_channel[dma].dmap & 0x40)
{
/* One oddity: if $43xA is 0 and this is the last active HDMA channel for this scanline, only load
one byte for Address, and use the $00 for the low byte. So Address ends up incremented one less than
otherwise expected */
abus = snes_get_hdma_addr(space.machine(), dma);
state->m_dma_channel[dma].trans_size = snes_abus_read(space, abus) << 8;
abus = get_hdma_addr(dma);
m_dma_channel[dma].trans_size = abus_read(space, abus) << 8;
if (state->m_dma_channel[dma].hdma_line_counter || !is_last_active_channel(space.machine(), dma))
if (m_dma_channel[dma].hdma_line_counter || !is_last_active_channel(dma))
{
// we enter here if we have more transfers to be done or if there are other active channels after this one
abus = snes_get_hdma_addr(space.machine(), dma);
state->m_dma_channel[dma].trans_size >>= 8;
state->m_dma_channel[dma].trans_size |= snes_abus_read(space, abus) << 8;
abus = get_hdma_addr(dma);
m_dma_channel[dma].trans_size >>= 8;
m_dma_channel[dma].trans_size |= abus_read(space, abus) << 8;
}
}
if (!state->m_dma_channel[dma].hdma_line_counter)
state->m_hdmaen &= ~(1 << dma);
if (!m_dma_channel[dma].hdma_line_counter)
m_hdmaen &= ~(1 << dma);
state->m_dma_channel[dma].do_transfer = 1;
m_dma_channel[dma].do_transfer = 1;
}
static void snes_hdma_init( address_space &space )
void snes_state::hdma_init( address_space &space )
{
snes_state *state = space.machine().driver_data<snes_state>();
int i;
state->m_hdmaen = snes_ram[HDMAEN];
for (i = 0; i < 8; i++)
m_hdmaen = snes_ram[HDMAEN];
for (int i = 0; i < 8; i++)
{
if (BIT(state->m_hdmaen, i))
if (BIT(m_hdmaen, i))
{
state->m_dma_channel[i].hdma_addr = state->m_dma_channel[i].src_addr;
snes_hdma_update(space, i);
m_dma_channel[i].hdma_addr = m_dma_channel[i].src_addr;
hdma_update(space, i);
}
}
}
static void snes_hdma( address_space &space )
void snes_state::hdma( address_space &space )
{
snes_state *state = space.machine().driver_data<snes_state>();
UINT16 bbus;
UINT32 abus;
int i;
for (i = 0; i < 8; i++)
for (int i = 0; i < 8; i++)
{
if (BIT(state->m_hdmaen, i))
if (BIT(m_hdmaen, i))
{
if (state->m_dma_channel[i].do_transfer)
if (m_dma_channel[i].do_transfer)
{
/* Get transfer addresses */
if (state->m_dma_channel[i].dmap & 0x40) /* Indirect */
abus = (state->m_dma_channel[i].ibank << 16) + state->m_dma_channel[i].trans_size;
if (m_dma_channel[i].dmap & 0x40) /* Indirect */
abus = (m_dma_channel[i].ibank << 16) + m_dma_channel[i].trans_size;
else /* Absolute */
abus = (state->m_dma_channel[i].bank << 16) + state->m_dma_channel[i].hdma_addr;
abus = (m_dma_channel[i].bank << 16) + m_dma_channel[i].hdma_addr;
bbus = state->m_dma_channel[i].dest_addr + 0x2100;
bbus = m_dma_channel[i].dest_addr + 0x2100;
switch (state->m_dma_channel[i].dmap & 0x07)
switch (m_dma_channel[i].dmap & 0x07)
{
case 0: /* 1 register write once (1 byte: p ) */
snes_dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus);
break;
case 5: /* 2 registers write twice alternate (4 bytes: p, p+1, p, p+1) */
snes_dma_transfer(space, i, abus++, bbus);
snes_dma_transfer(space, i, abus++, bbus + 1);
snes_dma_transfer(space, i, abus++, bbus);
snes_dma_transfer(space, i, abus++, bbus + 1);
dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus + 1);
dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus + 1);
break;
case 1: /* 2 registers write once (2 bytes: p, p+1 ) */
snes_dma_transfer(space, i, abus++, bbus);
snes_dma_transfer(space, i, abus++, bbus + 1);
dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus + 1);
break;
case 2: /* 1 register write twice (2 bytes: p, p ) */
case 6:
snes_dma_transfer(space, i, abus++, bbus);
snes_dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus);
break;
case 3: /* 2 registers write twice each (4 bytes: p, p, p+1, p+1) */
case 7:
snes_dma_transfer(space, i, abus++, bbus);
snes_dma_transfer(space, i, abus++, bbus);
snes_dma_transfer(space, i, abus++, bbus + 1);
snes_dma_transfer(space, i, abus++, bbus + 1);
dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus + 1);
dma_transfer(space, i, abus++, bbus + 1);
break;
case 4: /* 4 registers write once (4 bytes: p, p+1, p+2, p+3) */
snes_dma_transfer(space, i, abus++, bbus);
snes_dma_transfer(space, i, abus++, bbus + 1);
snes_dma_transfer(space, i, abus++, bbus + 2);
snes_dma_transfer(space, i, abus++, bbus + 3);
dma_transfer(space, i, abus++, bbus);
dma_transfer(space, i, abus++, bbus + 1);
dma_transfer(space, i, abus++, bbus + 2);
dma_transfer(space, i, abus++, bbus + 3);
break;
default:
#ifdef MAME_DEBUG
mame_printf_debug( " HDMA of unsupported type: %d\n", state->m_dma_channel[i].dmap & 0x07);
mame_printf_debug( " HDMA of unsupported type: %d\n", m_dma_channel[i].dmap & 0x07);
#endif
break;
}
if (state->m_dma_channel[i].dmap & 0x40) /* Indirect */
state->m_dma_channel[i].trans_size = abus;
if (m_dma_channel[i].dmap & 0x40) /* Indirect */
m_dma_channel[i].trans_size = abus;
else /* Absolute */
state->m_dma_channel[i].hdma_addr = abus;
m_dma_channel[i].hdma_addr = abus;
}
}
}
for (i = 0; i < 8; i++)
for (int i = 0; i < 8; i++)
{
if (BIT(state->m_hdmaen, i))
if (BIT(m_hdmaen, i))
{
state->m_dma_channel[i].do_transfer = (--state->m_dma_channel[i].hdma_line_counter) & 0x80;
m_dma_channel[i].do_transfer = (--m_dma_channel[i].hdma_line_counter) & 0x80;
if (!(state->m_dma_channel[i].hdma_line_counter & 0x7f))
snes_hdma_update(space, i);
if (!(m_dma_channel[i].hdma_line_counter & 0x7f))
hdma_update(space, i);
}
}
}
static void snes_dma( address_space &space, UINT8 channels )
void snes_state::dma( address_space &space, UINT8 channels )
{
snes_state *state = space.machine().driver_data<snes_state>();
int i;
INT8 increment;
UINT16 bbus;
UINT32 abus, abus_bank;
@ -2178,113 +2157,113 @@ static void snes_dma( address_space &space, UINT8 channels )
/* FIXME: we also need to round to the nearest 8 master cycles */
/* Assume priority of the 8 DMA channels is 0-7 */
for (i = 0; i < 8; i++)
for (int i = 0; i < 8; i++)
{
if (BIT(channels, i))
{
/* FIXME: the following should be used to stop DMA if the same channel is used by HDMA (being set to 1 in snes_hdma)
However, this cannot be implemented as is atm, because currently DMA transfers always happen as soon as they are enabled... */
state->m_dma_channel[i].dma_disabled = 0;
m_dma_channel[i].dma_disabled = 0;
//printf( "Making a transfer on channel %d\n", i );
/* Find transfer addresses */
abus = state->m_dma_channel[i].src_addr;
abus_bank = state->m_dma_channel[i].bank << 16;
bbus = state->m_dma_channel[i].dest_addr + 0x2100;
abus = m_dma_channel[i].src_addr;
abus_bank = m_dma_channel[i].bank << 16;
bbus = m_dma_channel[i].dest_addr + 0x2100;
//printf("Address: %06x\n", abus | abus_bank);
/* Auto increment */
if (state->m_dma_channel[i].dmap & 0x8)
if (m_dma_channel[i].dmap & 0x8)
increment = 0;
else
{
if (state->m_dma_channel[i].dmap & 0x10)
if (m_dma_channel[i].dmap & 0x10)
increment = -1;
else
increment = 1;
}
/* Number of bytes to transfer */
length = state->m_dma_channel[i].trans_size;
length = m_dma_channel[i].trans_size;
// printf( "DMA-Ch %d: len: %X, abus: %X, bbus: %X, incr: %d, dir: %s, type: %d\n", i, length, abus | abus_bank, bbus, increment, state->m_dma_channel[i].dmap & 0x80 ? "PPU->CPU" : "CPU->PPU", state->m_dma_channel[i].dmap & 0x07);
// printf( "DMA-Ch %d: len: %X, abus: %X, bbus: %X, incr: %d, dir: %s, type: %d\n", i, length, abus | abus_bank, bbus, increment, m_dma_channel[i].dmap & 0x80 ? "PPU->CPU" : "CPU->PPU", m_dma_channel[i].dmap & 0x07);
#ifdef SNES_DBG_DMA
mame_printf_debug( "DMA-Ch %d: len: %X, abus: %X, bbus: %X, incr: %d, dir: %s, type: %d\n", i, length, abus | abus_bank, bbus, increment, state->m_dma_channel[i].dmap & 0x80 ? "PPU->CPU" : "CPU->PPU", state->m_dma_channel[i].dmap & 0x07);
mame_printf_debug( "DMA-Ch %d: len: %X, abus: %X, bbus: %X, incr: %d, dir: %s, type: %d\n", i, length, abus | abus_bank, bbus, increment, m_dma_channel[i].dmap & 0x80 ? "PPU->CPU" : "CPU->PPU", m_dma_channel[i].dmap & 0x07);
#endif
switch (state->m_dma_channel[i].dmap & 0x07)
switch (m_dma_channel[i].dmap & 0x07)
{
case 0: /* 1 register write once */
case 2: /* 1 register write twice */
case 6: /* 1 register write twice */
do
{
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
abus += increment;
} while (--length && !state->m_dma_channel[i].dma_disabled);
} while (--length && !m_dma_channel[i].dma_disabled);
break;
case 1: /* 2 registers write once */
case 5: /* 2 registers write twice alternate */
do
{
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
abus += increment;
if (!(--length) || state->m_dma_channel[i].dma_disabled)
if (!(--length) || m_dma_channel[i].dma_disabled)
break;
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
abus += increment;
} while (--length && !state->m_dma_channel[i].dma_disabled);
} while (--length && !m_dma_channel[i].dma_disabled);
break;
case 3: /* 2 registers write twice each */
case 7: /* 2 registers write twice each */
do
{
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
abus += increment;
if (!(--length) || state->m_dma_channel[i].dma_disabled)
if (!(--length) || m_dma_channel[i].dma_disabled)
break;
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
abus += increment;
if (!(--length) || state->m_dma_channel[i].dma_disabled)
if (!(--length) || m_dma_channel[i].dma_disabled)
break;
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
abus += increment;
if (!(--length) || state->m_dma_channel[i].dma_disabled)
if (!(--length) || m_dma_channel[i].dma_disabled)
break;
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
abus += increment;
} while (--length && !state->m_dma_channel[i].dma_disabled);
} while (--length && !m_dma_channel[i].dma_disabled);
break;
case 4: /* 4 registers write once */
do
{
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
abus += increment;
if (!(--length) || state->m_dma_channel[i].dma_disabled)
if (!(--length) || m_dma_channel[i].dma_disabled)
break;
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
abus += increment;
if (!(--length) || state->m_dma_channel[i].dma_disabled)
if (!(--length) || m_dma_channel[i].dma_disabled)
break;
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 2);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 2);
abus += increment;
if (!(--length) || state->m_dma_channel[i].dma_disabled)
if (!(--length) || m_dma_channel[i].dma_disabled)
break;
snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 3);
dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 3);
abus += increment;
} while (--length && !state->m_dma_channel[i].dma_disabled);
} while (--length && !m_dma_channel[i].dma_disabled);
break;
default:
#ifdef MAME_DEBUG
mame_printf_debug(" DMA of unsupported type: %d\n", state->m_dma_channel[i].dmap & 0x07);
mame_printf_debug(" DMA of unsupported type: %d\n", m_dma_channel[i].dmap & 0x07);
#endif
break;
}
/* We're done, so write the new abus back to the registers */
state->m_dma_channel[i].src_addr = abus;
state->m_dma_channel[i].trans_size = 0;
m_dma_channel[i].src_addr = abus;
m_dma_channel[i].trans_size = 0;
}
}

View File

@ -724,7 +724,7 @@ static MACHINE_CONFIG_START( snes_base, snes_state )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(DOTCLK_NTSC * 2, SNES_HTOTAL * 2, 0, SNES_SCR_WIDTH * 2, SNES_VTOTAL_NTSC, 0, SNES_SCR_HEIGHT_NTSC)
MCFG_SCREEN_UPDATE_DRIVER( snes_state, snes_screen_update )
MCFG_SCREEN_UPDATE_DRIVER( snes_state, screen_update )
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")