Sync with MESS

This commit is contained in:
Wilbert Pol 2012-02-25 11:48:35 +00:00
parent 84422fd1ca
commit 9add8b78c0
2 changed files with 310 additions and 378 deletions

View File

@ -129,12 +129,13 @@ typedef int (*OpcodeEmulator) (lr35902_state *cpustate);
/* Memory functions */ /* Memory functions */
/****************************************************************************/ /****************************************************************************/
#define mem_ReadByte(cs,A) ((UINT8)(cs)->w.program->read_byte(A)) #define mem_ReadByte(cs,A) ((UINT8)(cs)->w.program->read_byte(A)); CYCLES_PASSED(4);
#define mem_WriteByte(cs,A,V) ((cs)->w.program->write_byte(A,V)) #define mem_WriteByte(cs,A,V) ((cs)->w.program->write_byte(A,V)); CYCLES_PASSED(4);
INLINE UINT16 mem_ReadWord (lr35902_state *cpustate, UINT32 address) INLINE UINT16 mem_ReadWord (lr35902_state *cpustate, UINT32 address)
{ {
UINT16 value = (UINT16) mem_ReadByte (cpustate, (address + 1) & 0xffff) << 8; UINT16 value = mem_ReadByte (cpustate, (address + 1) & 0xffff);
value <<= 8;
value |= mem_ReadByte (cpustate, address); value |= mem_ReadByte (cpustate, address);
return value; return value;
} }
@ -145,46 +146,6 @@ INLINE void mem_WriteWord (lr35902_state *cpustate, UINT32 address, UINT16 value
mem_WriteByte (cpustate, (address + 1) & 0xffff, value >> 8); mem_WriteByte (cpustate, (address + 1) & 0xffff, value >> 8);
} }
static const int Cycles[256] =
{
4,12, 8, 8, 4, 4, 8, 4,20, 8, 8, 8, 4, 4, 8, 4,
4,12, 8, 8, 4, 4, 8, 4,12, 8, 8, 8, 4, 4, 8, 4,
8,12, 8, 8, 4, 4, 8, 4, 8, 8, 8, 8, 4, 4, 8, 4,
8,12, 8, 8,12,12,12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 8, 8, 8, 8, 8, 4, 8, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8,12,12,16,12,16, 8,16, 8,16,12, 0,12,24, 8,16,
8,12,12, 4,12,16, 8,16, 8,16,12, 4,12, 4, 8,16,
12,12, 8, 4, 4,16, 8,16,16, 4,16, 4, 4, 4, 8,16,
12,12, 8, 4, 4,16, 8,16,12, 8,16, 4, 4, 4, 8,16
};
static const int CyclesCB[256] =
{
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8
};
static CPU_INIT( lr35902 ) static CPU_INIT( lr35902 )
{ {
lr35902_state *cpustate = get_safe_token(device); lr35902_state *cpustate = get_safe_token(device);
@ -285,7 +246,7 @@ INLINE void lr35902_ProcessInterrupts (lr35902_state *cpustate)
(*cpustate->w.irq_callback)(cpustate->w.device, irqline); (*cpustate->w.irq_callback)(cpustate->w.device, irqline);
cpustate->w.enable &= ~IME; cpustate->w.enable &= ~IME;
cpustate->w.IF &= ~(1 << irqline); cpustate->w.IF &= ~(1 << irqline);
CYCLES_PASSED( 20 ); CYCLES_PASSED( 12 );
cpustate->w.SP -= 2; cpustate->w.SP -= 2;
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
cpustate->w.PC = 0x40 + irqline * 8; cpustate->w.PC = 0x40 + irqline * 8;
@ -318,7 +279,7 @@ static CPU_EXECUTE( lr35902 )
lr35902_ProcessInterrupts (cpustate); lr35902_ProcessInterrupts (cpustate);
debugger_instruction_hook(device, cpustate->w.PC); debugger_instruction_hook(device, cpustate->w.PC);
if ( cpustate->w.enable & HALTED ) { if ( cpustate->w.enable & HALTED ) {
CYCLES_PASSED( Cycles[0x76] ); CYCLES_PASSED( 4 );
cpustate->w.execution_state = 1; cpustate->w.execution_state = 1;
} else { } else {
cpustate->w.op = mem_ReadByte (cpustate, cpustate->w.PC++); cpustate->w.op = mem_ReadByte (cpustate, cpustate->w.PC++);
@ -326,7 +287,6 @@ static CPU_EXECUTE( lr35902 )
cpustate->w.PC--; cpustate->w.PC--;
cpustate->w.doHALTbug = 0; cpustate->w.doHALTbug = 0;
} }
CYCLES_PASSED( Cycles[cpustate->w.op] );
} }
} }
cpustate->w.execution_state ^= 1; cpustate->w.execution_state ^= 1;

View File

@ -147,15 +147,15 @@ case 0x02: /* LD (BC),A */
mem_WriteByte (cpustate, cpustate->w.BC, cpustate->b.A); mem_WriteByte (cpustate, cpustate->w.BC, cpustate->b.A);
break; break;
case 0x03: /* INC BC */ case 0x03: /* INC BC */
#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ #if 0 /* FIXME ?? do we want to support this? (bug emulation) */
if (cpustate->b.B == 0xFE) if (cpustate->b.B == 0xFE)
{ {
trash_sprites (state); trash_sprites (state);
} }
#endif #endif
cpustate->w.BC += 1; cpustate->w.BC += 1;
break; CYCLES_PASSED( 4 );
break;
case 0x04: /* INC B */ case 0x04: /* INC B */
INC_8BIT (cpustate->b.B) INC_8BIT (cpustate->b.B)
@ -186,9 +186,9 @@ case 0x08: /* LD (n16),SP */
cpustate->w.PC += 2; cpustate->w.PC += 2;
break; break;
case 0x09: /* ADD HL,BC */ case 0x09: /* ADD HL,BC */
ADD_HL_RR (cpustate->w.BC)
ADD_HL_RR (cpustate->w.BC) CYCLES_PASSED( 4 );
break; break;
case 0x0A: /* LD A,(BC) */ case 0x0A: /* LD A,(BC) */
cpustate->b.A = mem_ReadByte (cpustate, cpustate->w.BC); cpustate->b.A = mem_ReadByte (cpustate, cpustate->w.BC);
@ -201,9 +201,9 @@ case 0x0B: /* DEC BC */
trash_sprites (state); trash_sprites (state);
} }
#endif #endif
cpustate->w.BC -= 1;
cpustate->w.BC -= 1; CYCLES_PASSED( 4 );
break; break;
case 0x0C: /* INC C */ case 0x0C: /* INC C */
INC_8BIT (cpustate->b.C) INC_8BIT (cpustate->b.C)
@ -248,8 +248,9 @@ case 0x13: /* INC DE */
} }
#endif #endif
cpustate->w.DE += 1; cpustate->w.DE += 1;
break; CYCLES_PASSED( 4 );
break;
case 0x14: /* INC D */ case 0x14: /* INC D */
INC_8BIT (cpustate->b.D) INC_8BIT (cpustate->b.D)
@ -275,12 +276,13 @@ case 0x18: /* JR n8 */
offset = mem_ReadByte (cpustate, cpustate->w.PC++); offset = mem_ReadByte (cpustate, cpustate->w.PC++);
cpustate->w.PC += offset; cpustate->w.PC += offset;
CYCLES_PASSED( 4 );
} }
break; break;
case 0x19: /* ADD HL,DE */ case 0x19: /* ADD HL,DE */
ADD_HL_RR (cpustate->w.DE)
ADD_HL_RR (cpustate->w.DE) CYCLES_PASSED( 4 );
break; break;
case 0x1A: /* LD A,(DE) */ case 0x1A: /* LD A,(DE) */
cpustate->b.A = mem_ReadByte (cpustate, cpustate->w.DE); cpustate->b.A = mem_ReadByte (cpustate, cpustate->w.DE);
@ -293,9 +295,9 @@ case 0x1B: /* DEC DE */
trash_sprites (state); trash_sprites (state);
} }
#endif #endif
cpustate->w.DE -= 1;
cpustate->w.DE -= 1; CYCLES_PASSED( 4 );
break; break;
case 0x1C: /* INC E */ case 0x1C: /* INC E */
INC_8BIT (cpustate->b.E) INC_8BIT (cpustate->b.E)
@ -316,20 +318,15 @@ case 0x1F: /* RRA */
cpustate->b.F = x; cpustate->b.F = x;
break; break;
case 0x20: /* JR NZ,n8 */ case 0x20: /* JR NZ,n8 */
{
if (cpustate->b.F & FLAG_Z) INT8 offset = mem_ReadByte (cpustate, cpustate->w.PC++);
{ if (! (cpustate->b.F & FLAG_Z) )
cpustate->w.PC++; {
} cpustate->w.PC += offset;
else CYCLES_PASSED( 4 );
{ }
INT8 offset; }
break;
offset = mem_ReadByte (cpustate, cpustate->w.PC++);
cpustate->w.PC += offset;
CYCLES_PASSED( 4 );
}
break;
case 0x21: /* LD HL,n16 */ case 0x21: /* LD HL,n16 */
cpustate->w.HL = mem_ReadWord (cpustate, cpustate->w.PC); cpustate->w.HL = mem_ReadWord (cpustate, cpustate->w.PC);
@ -356,8 +353,9 @@ case 0x23: /* INC HL */
} }
#endif #endif
cpustate->w.HL += 1; cpustate->w.HL += 1;
break; CYCLES_PASSED( 4 );
break;
case 0x24: /* INC H */ case 0x24: /* INC H */
INC_8BIT (cpustate->b.H); INC_8BIT (cpustate->b.H);
@ -397,25 +395,20 @@ case 0x27: /* DAA */
} }
break; break;
case 0x28: /* JR Z,n8 */ case 0x28: /* JR Z,n8 */
{
INT8 offset = mem_ReadByte (cpustate, cpustate->w.PC++);;
if (cpustate->b.F & FLAG_Z) if (cpustate->b.F & FLAG_Z)
{ {
INT8 offset; cpustate->w.PC += offset;
CYCLES_PASSED( 4 );
offset = mem_ReadByte (cpustate, cpustate->w.PC++); }
cpustate->w.PC += offset; }
break;
CYCLES_PASSED( 4 );
}
else
{
cpustate->w.PC += 1;
}
break;
case 0x29: /* ADD HL,HL */ case 0x29: /* ADD HL,HL */
ADD_HL_RR (cpustate->w.HL)
ADD_HL_RR (cpustate->w.HL) CYCLES_PASSED( 4 );
break; break;
case 0x2A: /* LD A,(HL+) */ case 0x2A: /* LD A,(HL+) */
#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ #if 0 /* FIXME ?? do we want to support this? (bug emulation) */
if (cpustate->b.H == 0xFE) if (cpustate->b.H == 0xFE)
@ -435,9 +428,9 @@ case 0x2B: /* DEC HL */
trash_sprites (state); trash_sprites (state);
} }
#endif #endif
cpustate->w.HL -= 1;
cpustate->w.HL -= 1; CYCLES_PASSED( 4 );
break; break;
case 0x2C: /* INC L */ case 0x2C: /* INC L */
INC_8BIT (cpustate->b.L); INC_8BIT (cpustate->b.L);
@ -456,20 +449,16 @@ case 0x2F: /* CPL */
cpustate->b.F |= FLAG_N | FLAG_H; cpustate->b.F |= FLAG_N | FLAG_H;
break; break;
case 0x30: /* JR NC,n8 */ case 0x30: /* JR NC,n8 */
{
INT8 offset = mem_ReadByte (cpustate, cpustate->w.PC++);
if (cpustate->b.F & FLAG_C) if ( ! (cpustate->b.F & FLAG_C) )
{ {
cpustate->w.PC += 1; cpustate->w.PC += offset;
} CYCLES_PASSED( 4 );
else }
{ }
INT8 offset; break;
offset = mem_ReadByte (cpustate, cpustate->w.PC++);
cpustate->w.PC += offset;
CYCLES_PASSED( 4 );
}
break;
case 0x31: /* LD SP,n16 */ case 0x31: /* LD SP,n16 */
cpustate->w.SP = mem_ReadWord (cpustate, cpustate->w.PC); cpustate->w.SP = mem_ReadWord (cpustate, cpustate->w.PC);
@ -488,16 +477,17 @@ case 0x32: /* LD (HL-),A */
cpustate->w.HL -= 1; cpustate->w.HL -= 1;
break; break;
case 0x33: /* INC SP */ case 0x33: /* INC SP */
cpustate->w.SP += 1;
cpustate->w.SP += 1; CYCLES_PASSED( 4 );
break; break;
case 0x34: /* INC (HL) */ case 0x34: /* INC (HL) */
{ {
register UINT8 r, f; register UINT8 r, f;
f = (UINT8) (cpustate->b.F & FLAG_C); f = (UINT8) (cpustate->b.F & FLAG_C);
r = (UINT8) (mem_ReadByte (cpustate, cpustate->w.HL) + 1); r = mem_ReadByte (cpustate, cpustate->w.HL);
r += 1;
mem_WriteByte (cpustate, cpustate->w.HL, r); mem_WriteByte (cpustate, cpustate->w.HL, r);
if (r == 0) if (r == 0)
@ -515,7 +505,8 @@ case 0x35: /* DEC (HL) */
register UINT8 r, f; register UINT8 r, f;
f = (UINT8) ((cpustate->b.F & FLAG_C) | FLAG_N); f = (UINT8) ((cpustate->b.F & FLAG_C) | FLAG_N);
r = (UINT8) (mem_ReadByte (cpustate, cpustate->w.HL) - 1); r = mem_ReadByte (cpustate, cpustate->w.HL);
r -= 1;
mem_WriteByte (cpustate, cpustate->w.HL, r); mem_WriteByte (cpustate, cpustate->w.HL, r);
if (r == 0) if (r == 0)
@ -529,31 +520,30 @@ case 0x35: /* DEC (HL) */
break; break;
case 0x36: /* LD (HL),n8 */ case 0x36: /* LD (HL),n8 */
/* FIXED / broken ? */ /* FIXED / broken ? */
mem_WriteByte (cpustate, cpustate->w.HL, mem_ReadByte (cpustate, cpustate->w.PC++)); {
UINT8 v = mem_ReadByte (cpustate, cpustate->w.PC++);
mem_WriteByte (cpustate, cpustate->w.HL, v);
}
break; break;
case 0x37: /* SCF */ case 0x37: /* SCF */
cpustate->b.F = (UINT8) ((cpustate->b.F & FLAG_Z) | FLAG_C); cpustate->b.F = (UINT8) ((cpustate->b.F & FLAG_Z) | FLAG_C);
break; break;
case 0x38: /* JR C,n8 */ case 0x38: /* JR C,n8 */
{
INT8 offset = mem_ReadByte (cpustate, cpustate->w.PC++);
if (cpustate->b.F & FLAG_C) if (cpustate->b.F & FLAG_C)
{ {
INT8 offset; cpustate->w.PC += offset;
CYCLES_PASSED( 4 );
offset = mem_ReadByte (cpustate, cpustate->w.PC++); }
cpustate->w.PC += offset; }
break;
CYCLES_PASSED( 4 );
}
else
{
cpustate->w.PC += 1;
}
break;
case 0x39: /* ADD HL,SP */ case 0x39: /* ADD HL,SP */
ADD_HL_RR (cpustate->w.SP) ADD_HL_RR (cpustate->w.SP)
break; CYCLES_PASSED( 4 );
break;
case 0x3A: /* LD A,(HL-) */ case 0x3A: /* LD A,(HL-) */
#if 0 /* FIXME ?? do we want to support this? (bug emulation) */ #if 0 /* FIXME ?? do we want to support this? (bug emulation) */
if (cpustate->b.H == 0xFE) if (cpustate->b.H == 0xFE)
@ -566,9 +556,9 @@ case 0x3A: /* LD A,(HL-) */
cpustate->w.HL -= 1; cpustate->w.HL -= 1;
break; break;
case 0x3B: /* DEC SP */ case 0x3B: /* DEC SP */
cpustate->w.SP -= 1;
cpustate->w.SP -= 1; CYCLES_PASSED( 4 );
break; break;
case 0x3C: /* INC A */ case 0x3C: /* INC A */
INC_8BIT (cpustate->b.A); INC_8BIT (cpustate->b.A);
@ -1100,257 +1090,235 @@ case 0xBF: /* CP A,A */
CP_A_X (cpustate->b.A) CP_A_X (cpustate->b.A)
break; break;
case 0xC0: /* RET NZ */ case 0xC0: /* RET NZ */
CYCLES_PASSED( 4 );
if (!(cpustate->b.F & FLAG_Z)) if (!(cpustate->b.F & FLAG_Z))
{ {
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP); cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP);
cpustate->w.SP += 2; cpustate->w.SP += 2;
CYCLES_PASSED( 12 ); CYCLES_PASSED( 4 );
} }
break; break;
case 0xC1: /* POP BC */ case 0xC1: /* POP BC */
cpustate->w.BC = mem_ReadWord (cpustate, cpustate->w.SP); cpustate->w.BC = mem_ReadWord (cpustate, cpustate->w.SP);
cpustate->w.SP += 2; cpustate->w.SP += 2;
break; break;
case 0xC2: /* JP NZ,n16 */ case 0xC2: /* JP NZ,n16 */
{
UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC += 2;
if (cpustate->b.F & FLAG_Z) if ( ! (cpustate->b.F & FLAG_Z) )
{ {
cpustate->w.PC += 2; cpustate->w.PC = addr;
} CYCLES_PASSED( 4 );
else }
{ }
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.PC); break;
CYCLES_PASSED( 4 );
}
break;
case 0xC3: /* JP n16 */ case 0xC3: /* JP n16 */
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.PC); CYCLES_PASSED( 4 );
break; break;
case 0xC4: /* CALL NZ,n16 */ case 0xC4: /* CALL NZ,n16 */
{
UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC += 2;
if (cpustate->b.F & FLAG_Z) if ( ! (cpustate->b.F & FLAG_Z) )
{ {
cpustate->w.PC += 2; cpustate->w.SP -= 2;
} mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
else cpustate->w.PC = addr;
{ CYCLES_PASSED( 4 );
register UINT16 PC; }
PC = mem_ReadWord (cpustate, cpustate->w.PC); }
cpustate->w.PC += 2; break;
cpustate->w.SP -= 2;
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
cpustate->w.PC = PC;
CYCLES_PASSED( 12 );
}
break;
case 0xC5: /* PUSH BC */ case 0xC5: /* PUSH BC */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.BC);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.BC); CYCLES_PASSED( 4 );
break; break;
case 0xC6: /* ADD A,n8 */ case 0xC6: /* ADD A,n8 */
x = mem_ReadByte (cpustate, cpustate->w.PC++); x = mem_ReadByte (cpustate, cpustate->w.PC++);
ADD_A_X (x) ADD_A_X (x)
break; break;
case 0xC7: /* RST 0 */ case 0xC7: /* RST 0 */
cpustate->w.SP -= 2;
{ mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
register UINT16 PC; cpustate->w.PC = 0;
PC = cpustate->w.PC; CYCLES_PASSED( 4 );
cpustate->w.PC = 0; break;
cpustate->w.SP -= 2;
mem_WriteWord (cpustate, cpustate->w.SP, PC);
}
break;
case 0xC8: /* RET Z */ case 0xC8: /* RET Z */
CYCLES_PASSED( 4 );
if (cpustate->b.F & FLAG_Z) if (cpustate->b.F & FLAG_Z)
{ {
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP); cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP);
cpustate->w.SP += 2; cpustate->w.SP += 2;
CYCLES_PASSED( 12 ); CYCLES_PASSED( 4 );
} }
break; break;
case 0xC9: /* RET */ case 0xC9: /* RET */
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP);
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP); cpustate->w.SP += 2;
cpustate->w.SP += 2; CYCLES_PASSED( 4 );
break; break;
case 0xCA: /* JP Z,n16 */ case 0xCA: /* JP Z,n16 */
{
UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC += 2;
if (cpustate->b.F & FLAG_Z) if (cpustate->b.F & FLAG_Z)
{ {
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.PC); cpustate->w.PC = addr;
CYCLES_PASSED( 4 ); CYCLES_PASSED( 4 );
} }
else }
{ break;
cpustate->w.PC += 2;
}
break;
case 0xCB: /* PREFIX! */ case 0xCB: /* PREFIX! */
x = mem_ReadByte (cpustate, cpustate->w.PC++); x = mem_ReadByte (cpustate, cpustate->w.PC++);
CYCLES_PASSED( CyclesCB[x] );
switch (x) switch (x)
{ {
#include "opc_cb.h" #include "opc_cb.h"
} }
break; break;
case 0xCC: /* CALL Z,n16 */ case 0xCC: /* CALL Z,n16 */
{
UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC += 2;
if (cpustate->b.F & FLAG_Z) if (cpustate->b.F & FLAG_Z)
{ {
register UINT16 PC; cpustate->w.SP -= 2;
PC = mem_ReadWord (cpustate, cpustate->w.PC); mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
cpustate->w.PC += 2; cpustate->w.PC = addr;
CYCLES_PASSED( 4 );
cpustate->w.SP -= 2; }
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); }
cpustate->w.PC = PC; break;
CYCLES_PASSED( 12 );
}
else
{
cpustate->w.PC += 2;
}
break;
case 0xCD: /* CALL n16 */ case 0xCD: /* CALL n16 */
{ {
register UINT16 PC; UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
PC = mem_ReadWord (cpustate, cpustate->w.PC); cpustate->w.PC += 2;
cpustate->w.PC += 2;
cpustate->w.SP -= 2; cpustate->w.SP -= 2;
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
cpustate->w.PC = PC; cpustate->w.PC = addr;
} CYCLES_PASSED( 4 );
break; }
break;
case 0xCE: /* ADC A,n8 */ case 0xCE: /* ADC A,n8 */
x = mem_ReadByte (cpustate, cpustate->w.PC++); x = mem_ReadByte (cpustate, cpustate->w.PC++);
ADC_A_X (x) ADC_A_X (x)
break; break;
case 0xCF: /* RST 8 */ case 0xCF: /* RST 8 */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); cpustate->w.PC = 8;
cpustate->w.PC = 8; CYCLES_PASSED( 4 );
break; break;
case 0xD0: /* RET NC */ case 0xD0: /* RET NC */
CYCLES_PASSED( 4 );
if (!(cpustate->b.F & FLAG_C)) if (!(cpustate->b.F & FLAG_C))
{ {
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP); cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP);
cpustate->w.SP += 2; cpustate->w.SP += 2;
CYCLES_PASSED( 12 ); CYCLES_PASSED( 4 );
} }
break; break;
case 0xD1: /* POP DE */ case 0xD1: /* POP DE */
cpustate->w.DE = mem_ReadWord (cpustate, cpustate->w.SP); cpustate->w.DE = mem_ReadWord (cpustate, cpustate->w.SP);
cpustate->w.SP += 2; cpustate->w.SP += 2;
break; break;
case 0xD2: /* JP NC,n16 */ case 0xD2: /* JP NC,n16 */
{
UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC += 2;
if (cpustate->b.F & FLAG_C) if ( ! (cpustate->b.F & FLAG_C) )
{ {
cpustate->w.PC += 2; cpustate->w.PC = addr;
} CYCLES_PASSED( 4 );
else }
{ }
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.PC); break;
CYCLES_PASSED( 4 );
}
break;
case 0xD3: /* EH? */ case 0xD3: /* EH? */
break; break;
case 0xD4: /* CALL NC,n16 */ case 0xD4: /* CALL NC,n16 */
{
UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC += 2;
if (cpustate->b.F & FLAG_C) if ( ! (cpustate->b.F & FLAG_C) )
{ {
cpustate->w.PC += 2; cpustate->w.SP -= 2;
} mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
else cpustate->w.PC = addr;
{ CYCLES_PASSED( 4 );
register UINT16 PC; }
PC = mem_ReadWord (cpustate, cpustate->w.PC); }
cpustate->w.PC += 2; break;
cpustate->w.SP -= 2;
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
cpustate->w.PC = PC;
CYCLES_PASSED( 12 );
}
break;
case 0xD5: /* PUSH DE */ case 0xD5: /* PUSH DE */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.DE);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.DE); CYCLES_PASSED( 4 );
break; break;
case 0xD6: /* SUB A,n8 */ case 0xD6: /* SUB A,n8 */
x = mem_ReadByte (cpustate, cpustate->w.PC++); x = mem_ReadByte (cpustate, cpustate->w.PC++);
SUB_A_X (x) SUB_A_X (x)
break; break;
case 0xD7: /* RST $10 */ case 0xD7: /* RST $10 */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); cpustate->w.PC = 0x10;
cpustate->w.PC = 0x10; CYCLES_PASSED( 4 );
break; break;
case 0xD8: /* RET C */ case 0xD8: /* RET C */
CYCLES_PASSED( 4 );
if (cpustate->b.F & FLAG_C) if (cpustate->b.F & FLAG_C)
{ {
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP); cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP);
cpustate->w.SP += 2; cpustate->w.SP += 2;
CYCLES_PASSED( 12 ); CYCLES_PASSED( 4 );
} }
break; break;
case 0xD9: /* RETI */ case 0xD9: /* RETI */
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP);
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.SP); cpustate->w.SP += 2;
cpustate->w.SP += 2; cpustate->w.enable |= IME;
cpustate->w.enable |= IME; CYCLES_PASSED( 4 );
break; break;
case 0xDA: /* JP C,n16 */ case 0xDA: /* JP C,n16 */
{
UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC += 2;
if (cpustate->b.F & FLAG_C) if (cpustate->b.F & FLAG_C)
{ {
cpustate->w.PC = mem_ReadWord (cpustate, cpustate->w.PC); cpustate->w.PC = addr;
CYCLES_PASSED( 4 ); CYCLES_PASSED( 4 );
} }
else }
{ break;
cpustate->w.PC += 2;
}
break;
case 0xDB: /* EH? */ case 0xDB: /* EH? */
break; break;
case 0xDC: /* CALL C,n16 */ case 0xDC: /* CALL C,n16 */
{
UINT16 addr = mem_ReadWord (cpustate, cpustate->w.PC);
cpustate->w.PC += 2;
if (cpustate->b.F & FLAG_C) if (cpustate->b.F & FLAG_C)
{ {
register UINT16 PC; cpustate->w.SP -= 2;
PC = mem_ReadWord (cpustate, cpustate->w.PC); mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
cpustate->w.PC += 2; cpustate->w.PC = addr;
CYCLES_PASSED( 4 );
cpustate->w.SP -= 2; }
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); }
cpustate->w.PC = PC; break;
CYCLES_PASSED( 12 );
}
else
{
cpustate->w.PC += 2;
}
break;
case 0xDD: /* EH? */ case 0xDD: /* EH? */
break; break;
case 0xDE: /* SBC A,n8 */ case 0xDE: /* SBC A,n8 */
@ -1359,13 +1327,16 @@ case 0xDE: /* SBC A,n8 */
SBC_A_X (x) SBC_A_X (x)
break; break;
case 0xDF: /* RST $18 */ case 0xDF: /* RST $18 */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); cpustate->w.PC = 0x18;
cpustate->w.PC = 0x18; CYCLES_PASSED( 4 );
break; break;
case 0xE0: /* LD ($FF00+n8),A */ case 0xE0: /* LD ($FF00+n8),A */
mem_WriteByte (cpustate, mem_ReadByte (cpustate, cpustate->w.PC++) + 0xFF00, cpustate->b.A); {
UINT8 v = mem_ReadByte (cpustate, cpustate->w.PC++);
mem_WriteByte (cpustate, 0xFF00 + v, cpustate->b.A);
}
break; break;
case 0xE1: /* POP HL */ case 0xE1: /* POP HL */
@ -1381,21 +1352,21 @@ case 0xE3: /* EH? */
case 0xE4: /* EH? */ case 0xE4: /* EH? */
break; break;
case 0xE5: /* PUSH HL */ case 0xE5: /* PUSH HL */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.HL);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.HL); CYCLES_PASSED( 4 );
break; break;
case 0xE6: /* AND A,n8 */ case 0xE6: /* AND A,n8 */
x = mem_ReadByte (cpustate, cpustate->w.PC++); x = mem_ReadByte (cpustate, cpustate->w.PC++);
AND_A_X (x) AND_A_X (x)
break; break;
case 0xE7: /* RST $20 */ case 0xE7: /* RST $20 */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); cpustate->w.PC = 0x20;
cpustate->w.PC = 0x20; CYCLES_PASSED( 4 );
break; break;
case 0xE8: /* ADD SP,n8 */ case 0xE8: /* ADD SP,n8 */
/* /*
* Z - Reset. * Z - Reset.
@ -1407,7 +1378,7 @@ case 0xE8: /* ADD SP,n8 */
{ {
register INT32 n; register INT32 n;
n = (INT32) ((INT8) mem_ReadByte (cpustate, cpustate->w.PC++)); n = (INT8) mem_ReadByte (cpustate, cpustate->w.PC++);
if ( ( cpustate->w.SP & 0xFF ) + (UINT8)(n & 0xFF) > 0xFF ) if ( ( cpustate->w.SP & 0xFF ) + (UINT8)(n & 0xFF) > 0xFF )
{ {
@ -1425,6 +1396,7 @@ case 0xE8: /* ADD SP,n8 */
cpustate->w.SP = (UINT16) ( cpustate->w.SP + n ); cpustate->w.SP = (UINT16) ( cpustate->w.SP + n );
} }
CYCLES_PASSED( 8 );
break; break;
case 0xE9: /* JP (HL) */ case 0xE9: /* JP (HL) */
@ -1447,14 +1419,16 @@ case 0xEE: /* XOR A,n8 */
XOR_A_X (x) XOR_A_X (x)
break; break;
case 0xEF: /* RST $28 */ case 0xEF: /* RST $28 */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); cpustate->w.PC = 0x28;
cpustate->w.PC = 0x28; CYCLES_PASSED( 4 );
break; break;
case 0xF0: /* LD A,($FF00+n8) */ case 0xF0: /* LD A,($FF00+n8) */
{
cpustate->b.A = mem_ReadByte (cpustate, 0xFF00 + mem_ReadByte (cpustate, cpustate->w.PC++)); UINT8 v = mem_ReadByte (cpustate, cpustate->w.PC++);
cpustate->b.A = mem_ReadByte (cpustate, 0xFF00 + v);
}
break; break;
case 0xF1: /* POP AF */ case 0xF1: /* POP AF */
@ -1472,21 +1446,21 @@ case 0xF3: /* DI */
case 0xF4: /* EH? */ case 0xF4: /* EH? */
break; break;
case 0xF5: /* PUSH AF */ case 0xF5: /* PUSH AF */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, (UINT16) (cpustate->w.AF & 0xFFF0));
mem_WriteWord (cpustate, cpustate->w.SP, (UINT16) (cpustate->w.AF & 0xFFF0)); CYCLES_PASSED( 4 );
break; break;
case 0xF6: /* OR A,n8 */ case 0xF6: /* OR A,n8 */
x = mem_ReadByte (cpustate, cpustate->w.PC++); x = mem_ReadByte (cpustate, cpustate->w.PC++);
OR_A_X (x) OR_A_X (x)
break; break;
case 0xF7: /* RST $30 */ case 0xF7: /* RST $30 */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); cpustate->w.PC = 0x30;
cpustate->w.PC = 0x30; CYCLES_PASSED( 4 );
break; break;
case 0xF8: /* LD HL,SP+n8 */ case 0xF8: /* LD HL,SP+n8 */
/* /*
* n = one UINT8 signed immediate value. * n = one UINT8 signed immediate value.
@ -1501,7 +1475,7 @@ case 0xF8: /* LD HL,SP+n8 */
{ {
register INT32 n; register INT32 n;
n = (INT32) ((INT8) mem_ReadByte (cpustate, cpustate->w.PC++)); n = (INT8) mem_ReadByte (cpustate, cpustate->w.PC++);
if ( ( cpustate->w.SP & 0xFF ) + (UINT8)(n & 0xFF) > 0xFF ) if ( ( cpustate->w.SP & 0xFF ) + (UINT8)(n & 0xFF) > 0xFF )
{ {
@ -1519,33 +1493,31 @@ case 0xF8: /* LD HL,SP+n8 */
cpustate->w.HL = (UINT16) ( cpustate->w.SP + n ); cpustate->w.HL = (UINT16) ( cpustate->w.SP + n );
} }
CYCLES_PASSED( 4 );
break; break;
case 0xF9: /* LD SP,HL */ case 0xF9: /* LD SP,HL */
cpustate->w.SP = cpustate->w.HL;
cpustate->w.SP = cpustate->w.HL; CYCLES_PASSED( 4 );
break; break;
case 0xFA: /* LD A,(n16) */ case 0xFA: /* LD A,(n16) */
cpustate->b.A = mem_ReadByte (cpustate, mem_ReadWord (cpustate, cpustate->w.PC));
cpustate->b.A = mem_ReadByte (cpustate, mem_ReadWord (cpustate, cpustate->w.PC)); cpustate->w.PC += 2;
cpustate->w.PC += 2; break;
break;
case 0xFB: /* EI */ case 0xFB: /* EI */
cpustate->w.enable |= IME;
cpustate->w.enable |= IME; cpustate->w.ei_delay = 1;
cpustate->w.ei_delay = 1; break;
break;
case 0xFC: /* EH? */ case 0xFC: /* EH? */
break; break;
case 0xFD: /* EH? */ case 0xFD: /* EH? */
break; break;
case 0xFE: /* CP A,n8 */ case 0xFE: /* CP A,n8 */
x = mem_ReadByte (cpustate, cpustate->w.PC++);
x = mem_ReadByte (cpustate, cpustate->w.PC++); CP_A_X (x)
CP_A_X (x) break;
break;
case 0xFF: /* RST $38 */ case 0xFF: /* RST $38 */
cpustate->w.SP -= 2;
cpustate->w.SP -= 2; mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC);
mem_WriteWord (cpustate, cpustate->w.SP, cpustate->w.PC); cpustate->w.PC = 0x38;
cpustate->w.PC = 0x38; CYCLES_PASSED( 4 );
break; break;