This commit is contained in:
Michaël Banaan Ananas 2014-06-16 20:36:37 +00:00
parent 85937f897d
commit 0d333b29c5
4 changed files with 31 additions and 28 deletions

View File

@ -78,7 +78,7 @@ lr35902_cpu_device::lr35902_cpu_device(const machine_config &mconfig, const char
, m_IF(0) , m_IF(0)
, m_timer_func(*this) , m_timer_func(*this)
, m_enable(0) , m_enable(0)
, m_features(0) , m_has_halt_bug(false)
{ {
} }
@ -144,13 +144,13 @@ void lr35902_cpu_device::device_start()
save_item(NAME(m_IE)); save_item(NAME(m_IE));
save_item(NAME(m_IF)); save_item(NAME(m_IF));
save_item(NAME(m_irq_state)); save_item(NAME(m_irq_state));
save_item(NAME(m_ei_delay)); save_item(NAME(m_handle_ei_delay));
save_item(NAME(m_execution_state)); save_item(NAME(m_execution_state));
save_item(NAME(m_op)); save_item(NAME(m_op));
save_item(NAME(m_gb_speed)); save_item(NAME(m_gb_speed));
save_item(NAME(m_gb_speed_change_pending)); save_item(NAME(m_gb_speed_change_pending));
save_item(NAME(m_enable)); save_item(NAME(m_enable));
save_item(NAME(m_doHALTbug)); save_item(NAME(m_handle_halt_bug));
// Register state for debugger // Register state for debugger
state_add( LR35902_PC, "PC", m_PC ).callimport().callexport().formatstr("%04X"); state_add( LR35902_PC, "PC", m_PC ).callimport().callexport().formatstr("%04X");
@ -211,8 +211,8 @@ void lr35902_cpu_device::device_reset()
m_IF = 0; m_IF = 0;
m_execution_state = 0; m_execution_state = 0;
m_doHALTbug = 0; m_handle_halt_bug = false;
m_ei_delay = 0; m_handle_ei_delay = false;
m_gb_speed_change_pending = 0; m_gb_speed_change_pending = 0;
m_gb_speed = 1; m_gb_speed = 1;
} }
@ -230,8 +230,8 @@ void lr35902_cpu_device::check_interrupts()
UINT8 irq = m_IE & m_IF; UINT8 irq = m_IE & m_IF;
/* Interrupts should be taken after the first instruction after an EI instruction */ /* Interrupts should be taken after the first instruction after an EI instruction */
if (m_ei_delay) { if (m_handle_ei_delay) {
m_ei_delay = 0; m_handle_ei_delay = false;
return; return;
} }
@ -255,10 +255,10 @@ void lr35902_cpu_device::check_interrupts()
{ {
m_enable &= ~HALTED; m_enable &= ~HALTED;
m_PC++; m_PC++;
if ( m_features & LR35902_FEATURE_HALT_BUG ) { if ( m_has_halt_bug ) {
if ( ! ( m_enable & IME ) ) { if ( ! ( m_enable & IME ) ) {
/* Old cpu core (dmg/mgb/sgb) */ /* Old cpu core (dmg/mgb/sgb) */
m_doHALTbug = 1; m_handle_halt_bug = true;
} }
} else { } else {
/* New cpu core (cgb/agb/ags) */ /* New cpu core (cgb/agb/ags) */
@ -311,9 +311,9 @@ void lr35902_cpu_device::execute_run()
m_execution_state = 1; m_execution_state = 1;
} else { } else {
m_op = mem_read_byte( m_PC++ ); m_op = mem_read_byte( m_PC++ );
if ( m_doHALTbug ) { if ( m_handle_halt_bug ) {
m_PC--; m_PC--;
m_doHALTbug = 0; m_handle_halt_bug = false;
} }
} }
} }

View File

@ -6,6 +6,10 @@
#define MCFG_LR35902_TIMER_CB(_devcb) \ #define MCFG_LR35902_TIMER_CB(_devcb) \
lr35902_cpu_device::set_timer_cb(*device, DEVCB_##_devcb); lr35902_cpu_device::set_timer_cb(*device, DEVCB_##_devcb);
// The first release of this CPU has a bug where the programcounter
// is not incremented properly after an interrupt after the halt opcode.
// This was fixed in a newer revision.
#define MCFG_LR35902_HALT_BUG \ #define MCFG_LR35902_HALT_BUG \
lr35902_cpu_device::set_halt_bug(*device); lr35902_cpu_device::set_halt_bug(*device);
@ -28,7 +32,7 @@ public:
// static configuration helpers // static configuration helpers
template<class _Object> static devcb_base &set_timer_cb(device_t &device, _Object object) { return downcast<lr35902_cpu_device &>(device).m_timer_func.set_callback(object); } template<class _Object> static devcb_base &set_timer_cb(device_t &device, _Object object) { return downcast<lr35902_cpu_device &>(device).m_timer_func.set_callback(object); }
static void set_halt_bug(device_t &device) { downcast<lr35902_cpu_device &>(device).m_features |= LR35902_FEATURE_HALT_BUG; } static void set_halt_bug(device_t &device) { downcast<lr35902_cpu_device &>(device).m_has_halt_bug = true; }
UINT8 get_speed(); UINT8 get_speed();
void set_speed( UINT8 speed_request ); void set_speed( UINT8 speed_request );
@ -40,7 +44,6 @@ public:
void set_if( UINT8 data ) { m_IF = data; } void set_if( UINT8 data ) { m_IF = data; }
protected: protected:
static const UINT8 LR35902_FEATURE_HALT_BUG = 0x01;
// device-level overrides // device-level overrides
virtual void device_start(); virtual void device_start();
@ -71,7 +74,6 @@ protected:
inline void mem_write_word(UINT16 addr, UINT16 data); inline void mem_write_word(UINT16 addr, UINT16 data);
inline void check_interrupts(); inline void check_interrupts();
protected:
address_space_config m_program_config; address_space_config m_program_config;
UINT8 m_A; UINT8 m_A;
@ -89,7 +91,7 @@ protected:
UINT8 m_IE; UINT8 m_IE;
UINT8 m_IF; UINT8 m_IF;
int m_irq_state; int m_irq_state;
int m_ei_delay; bool m_handle_ei_delay;
lr35902_cpu_device *m_device; lr35902_cpu_device *m_device;
address_space *m_program; address_space *m_program;
int m_icount; int m_icount;
@ -102,8 +104,8 @@ protected:
int m_gb_speed; int m_gb_speed;
int m_gb_speed_change_pending; int m_gb_speed_change_pending;
int m_enable; int m_enable;
int m_doHALTbug; bool m_handle_halt_bug;
UINT8 m_features; bool m_has_halt_bug;
}; };
extern const device_type LR35902; extern const device_type LR35902;

View File

@ -1439,7 +1439,7 @@ case 0xF2: /* LD A,($FF00+C) */
m_A = mem_read_byte( 0xFF00 + m_C ); m_A = mem_read_byte( 0xFF00 + m_C );
break; break;
case 0xF3: /* DI */ case 0xF3: /* DI */
m_ei_delay = 0; m_handle_ei_delay = false;
m_enable &= ~IME; m_enable &= ~IME;
break; break;
case 0xF5: /* PUSH AF */ case 0xF5: /* PUSH AF */
@ -1505,7 +1505,7 @@ case 0xFA: /* LD A,(n16) */
break; break;
case 0xFB: /* EI */ case 0xFB: /* EI */
m_enable |= IME; m_enable |= IME;
m_ei_delay = 1; m_handle_ei_delay = true;
break; break;
case 0xFE: /* CP A,n8 */ case 0xFE: /* CP A,n8 */
x = mem_read_byte( m_PC++ ); x = mem_read_byte( m_PC++ );

View File

@ -12,6 +12,7 @@
TODO list: TODO list:
- Do correct lcd stat timing - Do correct lcd stat timing
- Add Game Boy Light (Japan, 1997) - does it differ from gbpocket? - Add Game Boy Light (Japan, 1997) - does it differ from gbpocket?
- SGB should be moved to SNES driver
Timers Timers
@ -753,11 +754,11 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( supergb, gameboy ) static MACHINE_CONFIG_DERIVED( supergb, gameboy )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_REPLACE("maincpu", LR35902, 4295454) /* 4.295454 MHz */ MCFG_CPU_REPLACE("maincpu", LR35902, 4295454) /* 4.295454 MHz, derived from SNES xtal */
MCFG_CPU_PROGRAM_MAP(sgb_map) MCFG_CPU_PROGRAM_MAP(sgb_map)
MCFG_CPU_MODIFY("maincpu") MCFG_CPU_MODIFY("maincpu")
MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) ) MCFG_LR35902_TIMER_CB( WRITE8(gb_state, gb_timer_callback ) )
MCFG_LR35902_HALT_BUG MCFG_LR35902_HALT_BUG
MCFG_MACHINE_START_OVERRIDE(gb_state, sgb) MCFG_MACHINE_START_OVERRIDE(gb_state, sgb)
@ -792,8 +793,8 @@ static MACHINE_CONFIG_DERIVED( gbcolor, gameboy )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_MODIFY("maincpu") // todo XTAL_8_388MHz MCFG_CPU_MODIFY("maincpu") // todo XTAL_8_388MHz
MCFG_CPU_PROGRAM_MAP( gbc_map) MCFG_CPU_PROGRAM_MAP(gbc_map)
MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) ) MCFG_LR35902_TIMER_CB( WRITE8(gb_state, gb_timer_callback ) )
MCFG_MACHINE_START_OVERRIDE(gb_state,gbc) MCFG_MACHINE_START_OVERRIDE(gb_state,gbc)
MCFG_MACHINE_RESET_OVERRIDE(gb_state,gbc) MCFG_MACHINE_RESET_OVERRIDE(gb_state,gbc)
@ -820,8 +821,8 @@ static MACHINE_CONFIG_START( megaduck, megaduck_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD("maincpu", LR35902, 4194304) /* 4.194304 MHz */ MCFG_CPU_ADD("maincpu", LR35902, 4194304) /* 4.194304 MHz */
MCFG_CPU_PROGRAM_MAP( megaduck_map) MCFG_CPU_PROGRAM_MAP(megaduck_map)
MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) ) MCFG_LR35902_TIMER_CB( WRITE8(gb_state, gb_timer_callback ) )
MCFG_LR35902_HALT_BUG MCFG_LR35902_HALT_BUG
/* video hardware */ /* video hardware */