From 24e2de5cc413b320b0f3849ec3e0a02b38aee510 Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Sun, 26 Sep 2010 23:53:49 +0000 Subject: [PATCH] Give an option of how to handle the DMA timing... with or without the MAME timers (without is a lot faster..) (not worth) --- src/emu/cpu/sh2/sh2.c | 12 ++++++++++++ src/emu/cpu/sh2/sh2comn.c | 25 ++++++++++++++++++------- src/emu/cpu/sh2/sh2comn.h | 4 ++++ src/emu/cpu/sh2/sh2drc.c | 12 ++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/emu/cpu/sh2/sh2.c b/src/emu/cpu/sh2/sh2.c index 56241aaa1d7..9ae8d9e2626 100644 --- a/src/emu/cpu/sh2/sh2.c +++ b/src/emu/cpu/sh2/sh2.c @@ -2219,6 +2219,18 @@ static CPU_EXECUTE( sh2 ) return; } + // run any active DMAs now +#ifndef USE_TIMER_FOR_DMA + for ( int i = 0; i < sh2->icount ; i++) + { + for( int dma=0;dma<1;dma++) + { + if (sh2->dma_timer_active[dma]) + sh2_do_dma(sh2, dma); + } + } +#endif + do { UINT32 opcode; diff --git a/src/emu/cpu/sh2/sh2comn.c b/src/emu/cpu/sh2/sh2comn.c index c590249d056..d65432ec2b4 100644 --- a/src/emu/cpu/sh2/sh2comn.c +++ b/src/emu/cpu/sh2/sh2comn.c @@ -134,7 +134,6 @@ static TIMER_CALLBACK( sh2_timer_callback ) } - /* We have to do DMA on a timer (or at least, in chunks) due to the way some systems use it. The 32x is a difficult case, they set the SOURCE of the DMA to a FIFO buffer, which at most @@ -142,11 +141,21 @@ static TIMER_CALLBACK( sh2_timer_callback ) because the game is expecting the 68k of the system to feed data into the FIFO at the same time as the SH2 is transfering it out via DMA - It might be possible to avoid the timer (which causes a performance hit) by calling this - from the CPU_EXECUTE loop instead when there is active DMA + There are two ways we can do this + + a) with a high frequency timer (more accurate, but a large performance hit) + + or + + b) in the CPU_EXECUTE loop + + + we're currently doing b) + */ -static void sh2_do_dma(sh2_state *sh2, int dma) + +void sh2_do_dma(sh2_state *sh2, int dma) { UINT32 dmadata; @@ -154,8 +163,10 @@ static void sh2_do_dma(sh2_state *sh2, int dma) if (sh2->active_dma_count[dma] > 0) { - // schedule next DMA callback +#ifdef USE_TIMER_FOR_DMA + //schedule next DMA callback timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); +#endif // process current DMA switch(sh2->active_dma_size[dma]) @@ -393,10 +404,10 @@ static void sh2_dmac_check(sh2_state *sh2, int dma) sh2->active_dma_count[dma] &= ~3; break; } - +#ifdef USE_TIMER_FOR_DMA // start DMA timer timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); - +#endif } } diff --git a/src/emu/cpu/sh2/sh2comn.h b/src/emu/cpu/sh2/sh2comn.h index de891b5c480..df03f70b084 100644 --- a/src/emu/cpu/sh2/sh2comn.h +++ b/src/emu/cpu/sh2/sh2comn.h @@ -14,6 +14,9 @@ #define USE_SH2DRC +// do we use a timer for the DMA, or have it in CPU_EXECUTE +//#define USE_TIMER_FOR_DMA + #ifdef USE_SH2DRC #include "cpu/drcfe.h" #include "cpu/drcuml.h" @@ -184,5 +187,6 @@ void sh2_common_init(sh2_state *sh2, legacy_cpu_device *device, device_irq_callb void sh2_recalc_irq(sh2_state *sh2); void sh2_set_irq_line(sh2_state *sh2, int irqline, int state); void sh2_exception(sh2_state *sh2, const char *message, int irqline); +void sh2_do_dma(sh2_state *sh2, int dma); #endif /* __SH2COMN_H__ */ diff --git a/src/emu/cpu/sh2/sh2drc.c b/src/emu/cpu/sh2/sh2drc.c index 4b8d2a96864..d618b35e368 100644 --- a/src/emu/cpu/sh2/sh2drc.c +++ b/src/emu/cpu/sh2/sh2drc.c @@ -884,6 +884,18 @@ static CPU_EXECUTE( sh2 ) drcuml_state *drcuml = sh2->drcuml; int execute_result; + // run any active DMAs now +#ifndef USE_TIMER_FOR_DMA + for ( int i = 0; i < sh2->icount ; i++) + { + for( int dma=0;dma<1;dma++) + { + if (sh2->dma_timer_active[dma]) + sh2_do_dma(sh2, dma); + } + } +#endif + /* reset the cache if dirty */ if (sh2->cache_dirty) code_flush_cache(sh2);