From df4d3f693dbaba27c898d1063dc172e00d3d3b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Banaan=20Ananas?= Date: Mon, 16 Jun 2014 21:19:56 +0000 Subject: [PATCH] added macro and callback for 16bit inc/dec --- src/emu/cpu/lr35902/lr35902.c | 3 +- src/emu/cpu/lr35902/lr35902.h | 19 +++- src/emu/cpu/lr35902/opc_main.inc | 146 ++++++------------------------- src/mess/drivers/gb.c | 1 + 4 files changed, 47 insertions(+), 122 deletions(-) diff --git a/src/emu/cpu/lr35902/lr35902.c b/src/emu/cpu/lr35902/lr35902.c index e26eeead393..2fea7e7b163 100644 --- a/src/emu/cpu/lr35902/lr35902.c +++ b/src/emu/cpu/lr35902/lr35902.c @@ -76,9 +76,10 @@ lr35902_cpu_device::lr35902_cpu_device(const machine_config &mconfig, const char , m_PC(0) , m_IE(0) , m_IF(0) - , m_timer_func(*this) , m_enable(0) , m_has_halt_bug(false) + , m_timer_func(*this) + , m_incdec16_func(*this) { } diff --git a/src/emu/cpu/lr35902/lr35902.h b/src/emu/cpu/lr35902/lr35902.h index a5df2bf2eeb..aba1e83293b 100644 --- a/src/emu/cpu/lr35902/lr35902.h +++ b/src/emu/cpu/lr35902/lr35902.h @@ -13,6 +13,13 @@ #define MCFG_LR35902_HALT_BUG \ lr35902_cpu_device::set_halt_bug(*device); +// The GameBoy has a bug where OAM data gets corrupted if you inc/dec +// a 16-bit register in the $fe** region. +// note: oldval is in hiword, newval is in loword +#define MCFG_LR35902_INCDEC16_CB(_devcb) \ + lr35902_cpu_device::set_incdec16_cb(*device, DEVCB_##_devcb); + + enum { LR35902_PC=1, LR35902_SP, LR35902_A, LR35902_F, LR35902_B, LR35902_C, LR35902_D, LR35902_E, LR35902_H, LR35902_L, @@ -32,6 +39,7 @@ public: // static configuration helpers template static devcb_base &set_timer_cb(device_t &device, _Object object) { return downcast(device).m_timer_func.set_callback(object); } + template static devcb_base &set_incdec16_cb(device_t &device, _Object object) { return downcast(device).m_incdec16_func.set_callback(object); } static void set_halt_bug(device_t &device) { downcast(device).m_has_halt_bug = true; } UINT8 get_speed(); @@ -87,6 +95,7 @@ protected: UINT16 m_SP; UINT16 m_PC; + /* Interrupt related */ UINT8 m_IE; UINT8 m_IF; @@ -95,17 +104,21 @@ protected: 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; - UINT8 m_op; + UINT8 m_op; + /* Others */ int m_gb_speed; int m_gb_speed_change_pending; int m_enable; bool m_handle_halt_bug; bool m_has_halt_bug; + + /* Callbacks */ + devcb_write8 m_timer_func; + devcb_write32 m_incdec16_func; }; extern const device_type LR35902; diff --git a/src/emu/cpu/lr35902/opc_main.inc b/src/emu/cpu/lr35902/opc_main.inc index 258a7b29aef..dda008559bd 100644 --- a/src/emu/cpu/lr35902/opc_main.inc +++ b/src/emu/cpu/lr35902/opc_main.inc @@ -20,6 +20,22 @@ m_F=f; \ } +#define INC_16BIT(x,y) \ +{ \ + register UINT16 r = x << 8 | y; \ + if (++y == 0) x++; \ + if (!m_incdec16_func.isnull()) \ + m_incdec16_func(r << 16 | x << 8 | y); \ +} + +#define DEC_16BIT(x,y) \ +{ \ + register UINT16 r = x << 8 | y; \ + if (--y == 0xff) x--; \ + if (!m_incdec16_func.isnull()) \ + m_incdec16_func(r << 16 | x << 8 | y); \ +} + #define ADD_HL_RR(x) \ { \ register UINT32 r1,r2; \ @@ -145,24 +161,15 @@ case 0x02: /* LD (BC),A */ break; case 0x03: /* INC BC */ -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_B == 0xFE) - { - trash_sprites (state); - } -#endif - m_C++; - if ( m_C == 0 ) - { - m_B++; - } + INC_16BIT(m_B, m_C); cycles_passed( 4 ); break; + case 0x04: /* INC B */ INC_8BIT (m_B) break; -case 0x05: /* DEC B */ +case 0x05: /* DEC B */ DEC_8BIT (m_B) break; @@ -197,18 +204,7 @@ case 0x0A: /* LD A,(BC) */ m_A = mem_read_byte ( (m_B<<8)|m_C ); break; case 0x0B: /* DEC BC */ - -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_B == 0xFE) - { - trash_sprites (state); - } -#endif - m_C--; - if ( m_C == 0xFF ) - { - m_B--; - } + DEC_16BIT(m_B, m_C); cycles_passed( 4 ); break; case 0x0C: /* INC C */ @@ -246,18 +242,7 @@ case 0x12: /* LD (DE),A */ mem_write_byte( ( m_D << 8 ) | m_E, m_A ); break; case 0x13: /* INC DE */ - -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_D == 0xFE) - { - trash_sprites (state); - } -#endif - m_E++; - if ( m_E == 0 ) - { - m_D++; - } + INC_16BIT(m_D, m_E); cycles_passed( 4 ); break; case 0x14: /* INC D */ @@ -297,18 +282,7 @@ case 0x1A: /* LD A,(DE) */ m_A = mem_read_byte( ( m_D << 8 ) | m_E ); break; case 0x1B: /* DEC DE */ - -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_D == 0xFE) - { - trash_sprites (state); - } -#endif - m_E--; - if ( m_E == 0xFF ) - { - m_D--; - } + DEC_16BIT(m_D, m_E); cycles_passed( 4 ); break; case 0x1C: /* INC E */ @@ -345,33 +319,11 @@ case 0x21: /* LD HL,n16 */ m_H = mem_read_byte( m_PC++ ); break; case 0x22: /* LD (HL+),A */ - -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_H == 0xFE) - { - trash_sprites (state); - } -#endif mem_write_byte( (m_H << 8 ) | m_L, m_A ); - m_L++; - if ( m_L == 0 ) - { - m_H++; - } + INC_16BIT(m_H, m_L); break; case 0x23: /* INC HL */ - -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_H == 0xFE) - { - trash_sprites (state); - } -#endif - m_L++; - if ( m_L == 0 ) - { - m_H++; - } + INC_16BIT(m_H, m_L); cycles_passed( 4 ); break; case 0x24: /* INC H */ @@ -428,32 +380,11 @@ case 0x29: /* ADD HL,HL */ cycles_passed( 4 ); break; case 0x2A: /* LD A,(HL+) */ -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_H == 0xFE) - { - trash_sprites (state); - } -#endif m_A = mem_read_byte( ( m_H << 8 ) | m_L ); - m_L++; - if ( m_L == 0 ) - { - m_H++; - } + INC_16BIT(m_H, m_L); break; case 0x2B: /* DEC HL */ - -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_H == 0xFE) - { - trash_sprites (state); - } -#endif - m_L--; - if ( m_L == 0xFF ) - { - m_H--; - } + DEC_16BIT(m_H, m_L); cycles_passed( 4 ); break; case 0x2C: /* INC L */ @@ -490,19 +421,8 @@ case 0x31: /* LD SP,n16 */ m_PC += 2; break; case 0x32: /* LD (HL-),A */ - -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_H == 0xFE) - { - trash_sprites (state); - } -#endif mem_write_byte( ( m_H << 8 ) | m_L, m_A ); - m_L--; - if ( m_L == 0xFF ) - { - m_H--; - } + DEC_16BIT(m_H, m_L); break; case 0x33: /* INC SP */ m_SP += 1; @@ -572,18 +492,8 @@ case 0x39: /* ADD HL,SP */ cycles_passed( 4 ); break; case 0x3A: /* LD A,(HL-) */ -#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ - if (m_H == 0xFE) - { - trash_sprites (state); - } -#endif m_A = mem_read_byte( ( m_H << 8 ) | m_L ); - m_L--; - if ( m_L == 0xFF ) - { - m_H--; - } + DEC_16BIT(m_H, m_L); break; case 0x3B: /* DEC SP */ m_SP -= 1; diff --git a/src/mess/drivers/gb.c b/src/mess/drivers/gb.c index e093a8388cb..ae6a7003c65 100644 --- a/src/mess/drivers/gb.c +++ b/src/mess/drivers/gb.c @@ -13,6 +13,7 @@ - Do correct lcd stat timing - Add Game Boy Light (Japan, 1997) - does it differ from gbpocket? - SGB should be moved to SNES driver + - Emulate OAM corruption bug on 16bit inc/dec in $fe** region Timers