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_timer_func(*this)
, 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_IF));
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_op));
save_item(NAME(m_gb_speed));
save_item(NAME(m_gb_speed_change_pending));
save_item(NAME(m_enable));
save_item(NAME(m_doHALTbug));
save_item(NAME(m_handle_halt_bug));
// Register state for debugger
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_execution_state = 0;
m_doHALTbug = 0;
m_ei_delay = 0;
m_handle_halt_bug = false;
m_handle_ei_delay = false;
m_gb_speed_change_pending = 0;
m_gb_speed = 1;
}
@ -230,8 +230,8 @@ void lr35902_cpu_device::check_interrupts()
UINT8 irq = m_IE & m_IF;
/* Interrupts should be taken after the first instruction after an EI instruction */
if (m_ei_delay) {
m_ei_delay = 0;
if (m_handle_ei_delay) {
m_handle_ei_delay = false;
return;
}
@ -255,10 +255,10 @@ void lr35902_cpu_device::check_interrupts()
{
m_enable &= ~HALTED;
m_PC++;
if ( m_features & LR35902_FEATURE_HALT_BUG ) {
if ( m_has_halt_bug ) {
if ( ! ( m_enable & IME ) ) {
/* Old cpu core (dmg/mgb/sgb) */
m_doHALTbug = 1;
m_handle_halt_bug = true;
}
} else {
/* New cpu core (cgb/agb/ags) */
@ -311,9 +311,9 @@ void lr35902_cpu_device::execute_run()
m_execution_state = 1;
} else {
m_op = mem_read_byte( m_PC++ );
if ( m_doHALTbug ) {
if ( m_handle_halt_bug ) {
m_PC--;
m_doHALTbug = 0;
m_handle_halt_bug = false;
}
}
}

View File

@ -6,6 +6,10 @@
#define MCFG_LR35902_TIMER_CB(_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 \
lr35902_cpu_device::set_halt_bug(*device);
@ -28,7 +32,7 @@ public:
// 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); }
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();
void set_speed( UINT8 speed_request );
@ -40,7 +44,6 @@ public:
void set_if( UINT8 data ) { m_IF = data; }
protected:
static const UINT8 LR35902_FEATURE_HALT_BUG = 0x01;
// device-level overrides
virtual void device_start();
@ -71,7 +74,6 @@ protected:
inline void mem_write_word(UINT16 addr, UINT16 data);
inline void check_interrupts();
protected:
address_space_config m_program_config;
UINT8 m_A;
@ -86,24 +88,24 @@ protected:
UINT16 m_SP;
UINT16 m_PC;
/* Interrupt related */
UINT8 m_IE;
UINT8 m_IF;
UINT8 m_IE;
UINT8 m_IF;
int m_irq_state;
int m_ei_delay;
bool m_handle_ei_delay;
lr35902_cpu_device *m_device;
address_space *m_program;
int m_icount;
/* Timer callback */
devcb_write8 m_timer_func;
/* Fetch & execute related */
int m_execution_state;
int m_execution_state;
UINT8 m_op;
/* Others */
int m_gb_speed;
int m_gb_speed_change_pending;
int m_enable;
int m_doHALTbug;
UINT8 m_features;
bool m_handle_halt_bug;
bool m_has_halt_bug;
};
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 );
break;
case 0xF3: /* DI */
m_ei_delay = 0;
m_handle_ei_delay = false;
m_enable &= ~IME;
break;
case 0xF5: /* PUSH AF */
@ -1505,7 +1505,7 @@ case 0xFA: /* LD A,(n16) */
break;
case 0xFB: /* EI */
m_enable |= IME;
m_ei_delay = 1;
m_handle_ei_delay = true;
break;
case 0xFE: /* CP A,n8 */
x = mem_read_byte( m_PC++ );

View File

@ -12,6 +12,7 @@
TODO list:
- Do correct lcd stat timing
- Add Game Boy Light (Japan, 1997) - does it differ from gbpocket?
- SGB should be moved to SNES driver
Timers
@ -753,11 +754,11 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( supergb, gameboy )
/* 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_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_MACHINE_START_OVERRIDE(gb_state, sgb)
@ -792,8 +793,8 @@ static MACHINE_CONFIG_DERIVED( gbcolor, gameboy )
/* basic machine hardware */
MCFG_CPU_MODIFY("maincpu") // todo XTAL_8_388MHz
MCFG_CPU_PROGRAM_MAP( gbc_map)
MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) )
MCFG_CPU_PROGRAM_MAP(gbc_map)
MCFG_LR35902_TIMER_CB( WRITE8(gb_state, gb_timer_callback ) )
MCFG_MACHINE_START_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 */
MCFG_CPU_ADD("maincpu", LR35902, 4194304) /* 4.194304 MHz */
MCFG_CPU_PROGRAM_MAP( megaduck_map)
MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) )
MCFG_CPU_PROGRAM_MAP(megaduck_map)
MCFG_LR35902_TIMER_CB( WRITE8(gb_state, gb_timer_callback ) )
MCFG_LR35902_HALT_BUG
/* video hardware */