summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-01-25 02:59:21 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-01-25 02:59:21 +0000
commit2b0c13696868f8c9d8ecb29cf577159913f55733 (patch)
tree42199e34b5c648484ee0db3f5641bd605b3afeee
parent9249191b8b2923cd3874c6d75aaefb1a5ab2f243 (diff)
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.
-rw-r--r--src/emu/cpu/z80gb/z80gb.c58
1 files 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;