From 2b0c13696868f8c9d8ecb29cf577159913f55733 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Fri, 25 Jan 2008 02:59:21 +0000 Subject: [PATCH] From: Wilbert Pol [mailto:w.pol@tiscali.nl] Subject: z80gb cpu core patch Changes: - Small timing fixes when leaving HALT state. - Fixed bug in retrieving Z80GB_SPEED pseudo register. -- From: Wilbert Pol [mailto:wilbert@jdg.info] Subject: Re: timer_set_global_time patch This patch for the z80gb cpu core also fixes my problems without the need to recode a lot of things: - Split the execution of an instruction into separate fetch and execute phase. --- src/emu/cpu/z80gb/z80gb.c | 58 +++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/emu/cpu/z80gb/z80gb.c b/src/emu/cpu/z80gb/z80gb.c index 3e51ed1b44a..4d7b8984ca8 100644 --- a/src/emu/cpu/z80gb/z80gb.c +++ b/src/emu/cpu/z80gb/z80gb.c @@ -32,6 +32,9 @@ /** Added 4 cycle penalty when leaving HALT state for **/ /** newer versions of the cpu core **/ /** **/ +/** 1.4: **/ +/** Split fetch and execute cycles. **/ +/** **/ /*************************************************************/ #include "z80gb.h" #include "debugger.h" @@ -62,6 +65,9 @@ typedef struct { int (*irq_callback)(int irqline); /* Timer stuff */ void (*timer_callback)(int cycles); + /* Fetch & execute related */ + int execution_state; + UINT8 op; /* Others */ int gb_speed; int gb_speed_change_pending; @@ -209,6 +215,7 @@ static void z80gb_reset(void) Regs.w.IE = 0; Regs.w.IF = 0; + Regs.w.execution_state = 0; Regs.w.doHALTbug = 0; Regs.w.ei_delay = 0; Regs.w.gb_speed_change_pending = 0; @@ -246,15 +253,19 @@ INLINE void z80gb_ProcessInterrupts (void) Regs.w.enable &= ~HALTED; Regs.w.IF &= ~(1 << irqline); Regs.w.PC++; - if ( ! Regs.w.enable & IME ) { - if ( Regs.w.features & Z80GB_FEATURE_HALT_BUG ) { + if ( Regs.w.features & Z80GB_FEATURE_HALT_BUG ) { + if ( ! Regs.w.enable & IME ) { /* Old cpu core (dmg/mgb/sgb) */ /* check if the HALT bug should be performed */ if ( Regs.w.haltIFstatus ) { Regs.w.doHALTbug = 1; } - } else { - /* New cpu core (cgb/agb/ags) */ + } + } else { + /* New cpu core (cgb/agb/ags) */ + /* Adjust for internal syncing with video core */ + /* This feature needs more investigation */ + if ( irqline < 2 ) { CYCLES_PASSED( 4 ); } } @@ -282,28 +293,33 @@ INLINE void z80gb_ProcessInterrupts (void) /**********************************************************/ static int z80gb_execute (int cycles) { - UINT8 x; - z80gb_ICount = cycles; do { - z80gb_ProcessInterrupts (); - CALL_MAME_DEBUG; - if ( Regs.w.enable & HALTED ) { - CYCLES_PASSED( Cycles[0x76] ); - } else { - x = mem_ReadByte (Regs.w.PC++); - if ( Regs.w.doHALTbug ) { - Regs.w.PC--; - Regs.w.doHALTbug = 0; - } - CYCLES_PASSED( Cycles[x] ); - switch (x) - { + if ( Regs.w.execution_state ) { + UINT8 x; + /* Execute instruction */ + switch( Regs.w.op ) { #include "opc_main.h" } + } else { + /* Fetch and count cycles */ + z80gb_ProcessInterrupts (); + CALL_MAME_DEBUG; + if ( Regs.w.enable & HALTED ) { + CYCLES_PASSED( Cycles[0x76] ); + Regs.w.execution_state = 1; + } else { + Regs.w.op = mem_ReadByte (Regs.w.PC++); + if ( Regs.w.doHALTbug ) { + Regs.w.PC--; + Regs.w.doHALTbug = 0; + } + CYCLES_PASSED( Cycles[Regs.w.op] ); + } } + Regs.w.execution_state ^= 1; } while (z80gb_ICount > 0); return cycles - z80gb_ICount; @@ -438,7 +454,7 @@ void z80gb_get_info(UINT32 state, cpuinfo *info) case CPUINFO_INT_REGISTER + Z80GB_HL: info->i = Regs.w.HL; break; case CPUINFO_INT_REGISTER + Z80GB_IE: info->i = Regs.w.IE; break; case CPUINFO_INT_REGISTER + Z80GB_IF: info->i = Regs.w.IF; break; - case CPUINFO_INT_REGISTER + Z80GB_SPEED: info->i = 0x7E | ( ( Regs.w.gb_speed - 1 ) << 7 ) | Regs.w.gb_speed_change_pending; + case CPUINFO_INT_REGISTER + Z80GB_SPEED: info->i = 0x7E | ( ( Regs.w.gb_speed - 1 ) << 7 ) | Regs.w.gb_speed_change_pending; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_SET_INFO: info->setinfo = z80gb_set_info; break; @@ -457,7 +473,7 @@ void z80gb_get_info(UINT32 state, cpuinfo *info) /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "Z80GB"); break; case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Nintendo Z80"); break; - case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.3"); break; + case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.4"); break; case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright The MESS Team."); break;