kolibrios/programs/emulator/e80/trunk/z80/opcodes.c
Yogev Ezra b2ba8d7766 Add emulators: 'DosBox' (binary only), 'e80', 'fceu' (binary only).
git-svn-id: svn://kolibrios.org@1814 a494cfbc-eb01-0410-851d-a64ba20cac60
2011-01-30 14:48:24 +00:00

902 lines
28 KiB
C

/*====================================================================/*
opcodes.c -> This file executes the single-byte Z80 opcodes.
The CPU fetchs the byte pointed by the PC register (Program Counter)
into de IR (Instruction Register) and decodes it. The value of this
fetched byte (opcode) determines what operation the CPU must do.
On Z80 (which uses 8 bit for the IW register) this means that we
can have 256 (2^8) different opcodes. The z80 uses a simple trick
called PREFIXES to obtain more opcodes by using more than one byte
in the decoding (see opcodes_cb.c to know how it does it).
This file executes the whole list of single-byte opcodes.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Copyright (c) 2000 Santiago Romero Iglesias.
Email: sromero@escomposlinux.org
=====================================================================*/
/* About the AddCycles(4) -> Remember that reading from memory
takes 3 cycles plus 1 of the decoding.
Add 3 cycles for each operand fetch, and
3 more for each memory write/read. */
case NOP : AddCycles( 4 ); break;
case LD_BC_NN : LD_rr_nn(r_BC); AddCycles( 4+3+3 ); break;
case LD_xBC_A : STORE_r(r_BC, r_A); AddCycles( 4+3 ); break;
case INC_BC : r_BC++; AddCycles( 4+2 ); break;
case INC_B : INC(r_B); AddCycles( 4 ); break;
case DEC_B : DEC(r_B); AddCycles( 4 ); break;
case LD_B_N : LD_r_n(r_B);
AddCycles( 4+3 );
break;
case EX_AF_AF : EX_WORD(r_AF, r_AFs);
AddCycles( 4 );
break;
case LD_A_xBC : LOAD_r(r_A, r_BC);
AddCycles( 4+3 );
break;
case DEC_BC : r_BC--;
AddCycles( 4+2 );
break;
case INC_C : INC(r_C);
AddCycles( 4 );
break;
case DEC_C : DEC(r_C);
AddCycles( 4 );
break;
case LD_C_N : LD_r_n(r_C);
AddCycles( 4+3 );
break;
case LD_DE_NN : LD_rr_nn(r_DE);
AddCycles( 4+3+3 );
break;
case LD_xDE_A : STORE_r(r_DE, r_A);
AddCycles( 4+3 );
break;
case INC_DE : r_DE++;
AddCycles( 4+2 );
break;
case INC_D : INC(r_D);
AddCycles( 4 );
break;
case DEC_D : DEC(r_D);
AddCycles( 4 );
break;
case LD_D_N : LD_r_n(r_D);
AddCycles( 4+3 );
break;
case ADD_HL_BC : ADD_WORD(r_HL, r_BC); AddCycles( 4+3+3+1 ); break;
case ADD_HL_DE : ADD_WORD(r_HL, r_DE); AddCycles( 4+3+3+1 ); break;
case ADD_HL_HL : ADD_WORD(r_HL, r_HL); AddCycles( 4+3+3+1 ); break;
case ADD_HL_SP : ADD_WORD(r_HL, r_SP); AddCycles( 4+3+3+1 ); break;
case LD_A_xDE : LOAD_r(r_A, r_DE);
AddCycles( 4+3 );
break;
case DEC_DE : r_DE--;
AddCycles( 4+2 );
break;
case INC_E : INC(r_E);
AddCycles( 4 );
break;
case DEC_E : DEC(r_E);
AddCycles( 4 );
break;
case LD_E_N : LD_r_n(r_E);
AddCycles( 4+3 );
break;
case LD_HL_NN : LD_rr_nn(r_HL);
AddCycles( 4+3+3 );
break;
case LD_xNN_HL : STORE_nn_rr(r_HL);
AddCycles( 4+3+3+3+3 );
break;
case INC_HL : r_HL++;
AddCycles( 4+2 );
break;
case INC_H : INC(r_H);
AddCycles( 4 );
break;
case DEC_H : DEC(r_H);
AddCycles( 4 );
break;
case LD_H_N : LD_r_n(r_H);
AddCycles( 4+3 );
break;
case LD_HL_xNN : LOAD_rr_nn(r_HL);
AddCycles( 4+3+3+3+3 );
break;
case DEC_HL : r_HL--;
AddCycles( 4+2 );
break;
case INC_L : INC(r_L);
AddCycles( 4 );
break;
case DEC_L : DEC(r_L);
AddCycles( 4 );
break;
case LD_L_N : LD_r_n(r_L);
AddCycles( 4+3 );
break;
case LD_SP_NN : LD_rr_nn(r_SP);
AddCycles( 10 );
break;
case LD_xNN_A : STORE_nn_r(r_A);
AddCycles( 13 );
break;
case INC_SP : r_SP++;
AddCycles( 6 );
break;
case LD_xHL_N : r_meml = Z80ReadMem(r_PC); r_PC++;
STORE_r( r_HL, r_meml );
AddCycles( 10 );
break;
case LD_A_xNN : LOAD_r_nn( r_A );
AddCycles( 13 );
break;
case DEC_SP : r_SP--;
AddCycles( 6 );
break;
case INC_A : INC(r_A);
AddCycles( 4 );
break;
case DEC_A : DEC(r_A);
AddCycles( 4 );
break;
case LD_A_N : LD_r_n(r_A);
AddCycles( 4+3 );
break;
case LD_B_B : LD_r_r( r_B, r_B );
AddCycles( 4 );
break;
case LD_B_C : LD_r_r( r_B, r_C );
AddCycles( 4 );
break;
case LD_B_D : LD_r_r( r_B, r_D );
AddCycles( 4 );
break;
case LD_B_E : LD_r_r( r_B, r_E );
AddCycles( 4 );
break;
case LD_B_H : LD_r_r( r_B, r_H );
AddCycles( 4 );
break;
case LD_B_L : LD_r_r( r_B, r_L );
AddCycles( 4 );
break;
case LD_B_xHL : LOAD_r(r_B, r_HL);
AddCycles( 4+3 );
break;
case LD_B_A : LD_r_r( r_B, r_A );
AddCycles( 4 );
break;
case LD_C_B : LD_r_r( r_C, r_B );
AddCycles( 4 );
break;
case LD_C_C : LD_r_r( r_C, r_C );
AddCycles( 4 );
break;
case LD_C_D : LD_r_r( r_C, r_D );
AddCycles( 4 );
break;
case LD_C_E : LD_r_r( r_C, r_E );
AddCycles( 4 );
break;
case LD_C_H : LD_r_r( r_C, r_H );
AddCycles( 4 );
break;
case LD_C_L : LD_r_r( r_C, r_L );
AddCycles( 4 );
break;
case LD_C_xHL : LOAD_r(r_C, r_HL);
AddCycles( 4+3 );
break;
case LD_C_A : LD_r_r( r_C, r_A );
AddCycles( 4 );
break;
case LD_D_B : LD_r_r( r_D, r_B );
AddCycles( 4 );
break;
case LD_D_C : LD_r_r( r_D, r_C );
AddCycles( 4 );
break;
case LD_D_D : LD_r_r( r_D, r_D );
AddCycles( 4 );
break;
case LD_D_E : LD_r_r( r_D, r_E );
AddCycles( 4 );
break;
case LD_D_H : LD_r_r( r_D, r_H );
AddCycles( 4 );
break;
case LD_D_L : LD_r_r( r_D, r_L );
AddCycles( 4 );
break;
case LD_D_xHL : LOAD_r(r_D, r_HL);
AddCycles( 4+3 );
break;
case LD_D_A : LD_r_r( r_D, r_A );
AddCycles( 4 );
break;
case LD_E_B : LD_r_r( r_E, r_B );
AddCycles( 4 );
break;
case LD_E_C : LD_r_r( r_E, r_C );
AddCycles( 4 );
break;
case LD_E_D : LD_r_r( r_E, r_D );
AddCycles( 4 );
break;
case LD_E_E : LD_r_r( r_E, r_E );
AddCycles( 4 );
break;
case LD_E_H : LD_r_r( r_E, r_H );
AddCycles( 4 );
break;
case LD_E_L : LD_r_r( r_E, r_L );
AddCycles( 4 );
break;
case LD_E_xHL : LOAD_r(r_E, r_HL);
AddCycles( 4+3 );
break;
case LD_E_A : LD_r_r( r_E, r_A );
AddCycles( 4 );
break;
case LD_H_B : LD_r_r( r_H, r_B );
AddCycles( 4 );
break;
case LD_H_C : LD_r_r( r_H, r_C );
AddCycles( 4 );
break;
case LD_H_D : LD_r_r( r_H, r_D );
AddCycles( 4 );
break;
case LD_H_E : LD_r_r( r_H, r_E );
AddCycles( 4 );
break;
case LD_H_H : LD_r_r( r_H, r_H );
AddCycles( 4 );
break;
case LD_H_L : LD_r_r( r_H, r_L );
AddCycles( 4 );
break;
case LD_H_xHL : LOAD_r(r_H, r_HL);
AddCycles( 4+3 );
break;
case LD_H_A : LD_r_r( r_H, r_A );
AddCycles( 4 );
break;
case LD_L_B : LD_r_r( r_L, r_B );
AddCycles( 4 );
break;
case LD_L_C : LD_r_r( r_L, r_C );
AddCycles( 4 );
break;
case LD_L_D : LD_r_r( r_L, r_D );
AddCycles( 4 );
break;
case LD_L_E : LD_r_r( r_L, r_E );
AddCycles( 4 );
break;
case LD_L_H : LD_r_r( r_L, r_H );
AddCycles( 4 );
break;
case LD_L_L : LD_r_r( r_L, r_L );
AddCycles( 4 );
break;
case LD_L_xHL : LOAD_r(r_L, r_HL);
AddCycles( 7 );
break;
case LD_L_A : LD_r_r( r_L, r_A );
AddCycles( 4 );
break;
case LD_xHL_B : STORE_r( r_HL, r_B );
AddCycles( 4+3 );
break;
case LD_xHL_C : STORE_r( r_HL, r_C );
AddCycles( 4+3 );
break;
case LD_xHL_D : STORE_r( r_HL, r_D );
AddCycles( 4+3 );
break;
case LD_xHL_E : STORE_r( r_HL, r_E );
AddCycles( 4+3 );
break;
case LD_xHL_H : STORE_r( r_HL, r_H );
AddCycles( 4+3 );
break;
case LD_xHL_L : STORE_r( r_HL, r_L );
AddCycles( 4+3 );
break;
case LD_xHL_A : STORE_r(r_HL, r_A );
AddCycles( 4+3 );
break;
case LD_A_B : LD_r_r( r_A, r_B );
AddCycles( 4 );
break;
case LD_A_C : LD_r_r( r_A, r_C );
AddCycles( 4 );
break;
case LD_A_D : LD_r_r( r_A, r_D );
AddCycles( 4 );
break;
case LD_A_E : LD_r_r( r_A, r_E );
AddCycles( 4 );
break;
case LD_A_H : LD_r_r( r_A, r_H );
AddCycles( 4 );
break;
case LD_A_L : LD_r_r( r_A, r_L );
AddCycles( 4 );
break;
case LD_A_xHL : LOAD_r( r_A, r_HL);
AddCycles( 4+3 );
break;
case LD_A_A : LD_r_r( r_A, r_A );
AddCycles( 4 );
break;
case LD_SP_HL : LD_r_r( r_SP, r_HL );
AddCycles( 6 ); break;
case ADD_B : ADD(r_B); AddCycles( 4 ); break;
case ADD_C : ADD(r_C); AddCycles( 4 ); break;
case ADD_D : ADD(r_D); AddCycles( 4 ); break;
case ADD_E : ADD(r_E); AddCycles( 4 ); break;
case ADD_H : ADD(r_H); AddCycles( 4 ); break;
case ADD_L : ADD(r_L); AddCycles( 4 ); break;
case ADD_xHL : r_meml = Z80ReadMem(r_HL);
ADD(r_meml);
AddCycles( 4+3 );
break;
case ADD_A : ADD(r_A); AddCycles( 4 ); break;
case ADC_B : ADC(r_B); AddCycles( 4 ); break;
case ADC_C : ADC(r_C); AddCycles( 4 ); break;
case ADC_D : ADC(r_D); AddCycles( 4 ); break;
case ADC_E : ADC(r_E); AddCycles( 4 ); break;
case ADC_H : ADC(r_H); AddCycles( 4 ); break;
case ADC_L : ADC(r_L); AddCycles( 4 ); break;
case ADC_xHL : r_meml = Z80ReadMem(r_HL);
ADC(r_meml);
AddCycles( 4+3 );
break;
case ADC_A : ADC(r_A); AddCycles( 4 ); break;
case ADC_N : r_meml = Z80ReadMem(r_PC); r_PC++;
ADC(r_meml);
AddCycles( 4+3 );
break;
case SUB_A : SUB(r_A); AddCycles( 4 ); break;
case SUB_B : SUB(r_B); AddCycles( 4 ); break;
case SUB_C : SUB(r_C); AddCycles( 4 ); break;
case SUB_D : SUB(r_D); AddCycles( 4 ); break;
case SUB_E : SUB(r_E); AddCycles( 4 ); break;
case SUB_H : SUB(r_H); AddCycles( 4 ); break;
case SUB_L : SUB(r_L); AddCycles( 4 ); break;
case SUB_xHL : r_meml = Z80ReadMem(r_HL);
SUB(r_meml);
AddCycles( 4+3 );
break;
case SUB_N : r_meml = Z80ReadMem(r_PC); r_PC++;
SUB(r_meml);
AddCycles( 4+3 );
break;
case SBC_A : SBC(r_A); AddCycles( 4 ); break;
case SBC_B : SBC(r_B); AddCycles( 4 ); break;
case SBC_C : SBC(r_C); AddCycles( 4 ); break;
case SBC_D : SBC(r_D); AddCycles( 4 ); break;
case SBC_E : SBC(r_E); AddCycles( 4 ); break;
case SBC_H : SBC(r_H); AddCycles( 4 ); break;
case SBC_L : SBC(r_L); AddCycles( 4 ); break;
case SBC_xHL : r_meml = Z80ReadMem(r_HL);
SBC(r_meml);
AddCycles( 4+3 );
break;
case SBC_N : r_meml = Z80ReadMem(r_PC); r_PC++;
SBC(r_meml);
AddCycles( 4 );
break;
case AND_B : AND( r_B ); AddCycles( 4 ); break;
case AND_C : AND( r_C ); AddCycles( 4 ); break;
case AND_D : AND( r_D ); AddCycles( 4 ); break;
case AND_E : AND( r_E ); AddCycles( 4 ); break;
case AND_H : AND( r_H ); AddCycles( 4 ); break;
case AND_L : AND( r_L ); AddCycles( 4 ); break;
case AND_xHL : AND_mem( r_HL ); AddCycles( 4+3 ); break;
case AND_A : AND( r_A ); AddCycles( 4 ); break;
case XOR_B : XOR( r_B ); AddCycles( 4 ); break;
case XOR_C : XOR( r_C ); AddCycles( 4 ); break;
case XOR_D : XOR( r_D ); AddCycles( 4 ); break;
case XOR_E : XOR( r_E ); AddCycles( 4 ); break;
case XOR_H : XOR( r_H ); AddCycles( 4 ); break;
case XOR_L : XOR( r_L ); AddCycles( 4 ); break;
case XOR_xHL : XOR_mem( r_HL ); AddCycles( 4+3 ); break;
case XOR_A : XOR( r_A ); AddCycles( 4 ); break;
case OR_B : OR( r_B ); AddCycles( 4 ); break;
case OR_C : OR( r_C ); AddCycles( 4 ); break;
case OR_D : OR( r_D ); AddCycles( 4 ); break;
case OR_E : OR( r_E ); AddCycles( 4 ); break;
case OR_H : OR( r_H ); AddCycles( 4 ); break;
case OR_L : OR( r_L ); AddCycles( 4 ); break;
case OR_xHL : OR_mem( r_HL ); AddCycles( 4+3 ); break;
case OR_A : OR( r_A ); AddCycles( 4 ); break;
case CP_A : CP(r_A); AddCycles( 4 ); break;
case CP_B : CP(r_B); AddCycles( 4 ); break;
case CP_C : CP(r_C); AddCycles( 4 ); break;
case CP_D : CP(r_D); AddCycles( 4 ); break;
case CP_E : CP(r_E); AddCycles( 4 ); break;
case CP_H : CP(r_H); AddCycles( 4 ); break;
case CP_L : CP(r_L); AddCycles( 4 ); break;
case CP_xHL : r_meml = Z80ReadMem( r_HL );
CP(r_meml); AddCycles( 4+3 ); break;
case CP_N : r_meml = Z80ReadMem(r_PC); r_PC++;
CP(r_meml);
AddCycles( 4+3);
break;
case RET_Z : if( TEST_FLAG(Z_FLAG) )
{ RET_nn(); AddCycles( 4+1+3+3 ); }
else { AddCycles( 4+1 ); }
break;
case RET_C : if( TEST_FLAG(C_FLAG) )
{ RET_nn(); AddCycles( 4+1+3+3 ); }
else { AddCycles( 4+1 ); }
break;
case RET_M : if( TEST_FLAG(S_FLAG) )
{ RET_nn(); AddCycles( 4+1+3+3 ); }
else { AddCycles( 4+1 ); }
break;
case RET_PE : if( TEST_FLAG(P_FLAG) )
{ RET_nn(); AddCycles( 4+1+3+3 ); }
else { AddCycles( 4+1 ); }
break;
case RET_PO : if( TEST_FLAG(P_FLAG) )
{ AddCycles( 4+1 ); }
else { RET_nn(); AddCycles( 4+1+3+3 ); }
break;
case RET_P : if( TEST_FLAG(S_FLAG) )
{ AddCycles( 4+1 ); }
else { RET_nn(); AddCycles( 4+1+3+3 ); }
break;
case RET : RET_nn();
AddCycles( 4+3+3 );
break;
case RET_NZ : if( TEST_FLAG(Z_FLAG) )
{ AddCycles( 4+1 ); }
else { RET_nn(); AddCycles( 4+1+3+3 ); }
break;
case RET_NC : if( TEST_FLAG(C_FLAG) )
{ AddCycles( 4+1 ); }
else { RET_nn(); AddCycles( 4+1+3+3 ); }
break;
case ADD_N : r_meml = Z80ReadMem(r_PC); r_PC++;
ADD(r_meml);
AddCycles( 4+3 );
break;
case JR : JR_n();
AddCycles( 4+3+3+2 );
break;
case JR_NZ : if( TEST_FLAG(Z_FLAG) )
{ r_PC++; AddCycles( 4+3 ); }
else
{ JR_n(); AddCycles( 4+8 ); }
break;
case JR_Z : if( TEST_FLAG(Z_FLAG) )
{ JR_n(); AddCycles( 4+8 ); }
else
{ r_PC++; AddCycles( 4+3 ); }
break;
case JR_NC : if( TEST_FLAG(C_FLAG) )
{ r_PC++; AddCycles( 4+3 ); }
else
{ JR_n(); AddCycles( 4+8 ); }
break;
case JR_C : if( TEST_FLAG(C_FLAG) )
{ JR_n(); AddCycles( 4+8 ); }
else
{ r_PC++; AddCycles( 4+3 ); }
break;
case JP_NZ : if( TEST_FLAG(Z_FLAG) ) { r_PC += 2; }
else { JP_nn(); }
AddCycles( 4+3+3 );
break;
case JP : JP_nn();
AddCycles( 4+3+3 );
break;
case JP_Z : if( TEST_FLAG(Z_FLAG) ) { JP_nn(); }
else { r_PC += 2; }
AddCycles( 4+3+3 );
break;
case JP_NC : if( TEST_FLAG(C_FLAG) ) { r_PC += 2; }
else { JP_nn(); }
AddCycles( 4+3+3 );
break;
case JP_C : if( TEST_FLAG(C_FLAG) ) { JP_nn(); }
else { r_PC += 2; }
AddCycles( 4+3+3 );
break;
case JP_PO : if( TEST_FLAG(P_FLAG) ) { r_PC += 2; }
else { JP_nn(); }
AddCycles( 4+3+3 );
break;
case JP_PE : if( TEST_FLAG(P_FLAG) ) { JP_nn(); }
else { r_PC += 2; }
AddCycles( 4+3+3 );
break;
case JP_P : if( TEST_FLAG(S_FLAG) ) { r_PC += 2; }
else { JP_nn(); }
AddCycles( 4+3+3 );
break;
case JP_M : if( TEST_FLAG(S_FLAG) ) { JP_nn(); }
else { r_PC += 2; }
AddCycles( 4+3+3 );
break;
case JP_xHL : r_PC = r_HL; AddCycles( 4 ); break;
case CPL : r_A ^= 0xFF;
r_F = ( r_F & (FLAG_C|FLAG_P|FLAG_Z|FLAG_S)) |
( r_A & (FLAG_3|FLAG_5))|(FLAG_N|FLAG_H);
AddCycles( 4 ); break;
case INC_xHL : r_meml = Z80ReadMem( r_HL );
INC(r_meml);
Z80WriteMem( r_HL, r_meml, regs );
AddCycles( 4+3+3+1 ); break;
case DEC_xHL : r_meml = Z80ReadMem( r_HL );
DEC(r_meml);
Z80WriteMem( r_HL, r_meml, regs );
AddCycles( 4+3+3+1 ); break;
case SCF : r_F = r_F | FLAG_C;
r_F &= FLAG_Z | FLAG_S | FLAG_P;
if(r_F & FLAG_H) r_F ^= FLAG_H;
r_F |= FLAG_C;
AddCycles( 4 ); break;
case CCF : r_F = (r_F & (FLAG_P|FLAG_Z|FLAG_S) ) |
((r_F & FLAG_C) ? FLAG_H : FLAG_C) |
( r_A & (FLAG_3 | FLAG_5) );
AddCycles( 4 ); break;
case HALT : regs->halted = 1;
AddCycles(4);
break;
case POP_BC : POP(BC); AddCycles( 10 ); break;
case PUSH_BC : PUSH(BC); AddCycles( 11 ); break;
case POP_HL : POP(HL); AddCycles( 10 ); break;
case PUSH_HL : PUSH(HL); AddCycles( 11 ); break;
case POP_AF : POP(AF); AddCycles( 10 ); break;
case PUSH_AF : PUSH(AF); AddCycles( 11 ); break;
case POP_DE : POP(DE); AddCycles( 10 ); break;
case PUSH_DE : PUSH(DE); AddCycles( 11 ); break;
case RLCA : r_A = (r_A << 1) | (r_A >> 7);
r_F = ( r_F & (FLAG_P|FLAG_Z|FLAG_S)) |
( r_A & (FLAG_C|FLAG_3|FLAG_5) );
AddCycles( 4 ); break;
case RRCA : r_F = ( r_F & (FLAG_P|FLAG_Z|FLAG_S)) |
( r_A & FLAG_C );
r_A = ( r_A >> 1) | ( r_A << 7 );
r_F |= ( r_A & ( FLAG_3 | FLAG_5 ) );
AddCycles( 4 ); break;
case DJNZ : r_B--;
if( r_B ) { JR_n(); AddCycles(13); }
else { r_PC++ ; AddCycles(8); }
break;
case RLA : r_meml = r_A;
r_A = ( r_A << 1 ) | ( r_F & FLAG_C );
r_F = ( r_F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |
(r_A & ( FLAG_3 | FLAG_5 ) ) | ( r_meml >> 7);
AddCycles( 4 ); break;
case RRA : r_meml = r_A;
r_A = ( r_A >> 1 ) | ( r_F << 7 );
r_F = ( r_F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |
( r_A & ( FLAG_3 | FLAG_5 ) ) | ( r_meml & FLAG_C );
AddCycles( 4 ); break;
case DAA : r_meml = 0;
r_memh = ( r_F & FLAG_C );
if( ( r_F & FLAG_H ) || ( (r_A & 0x0f)>9 ) ) r_meml=6;
if( r_memh || (r_A > 0x9f ) ) r_meml |= 0x60;
if( r_A > 0x99 ) r_memh=1;
if ( r_F & FLAG_N ) { SUB(r_meml); }
else
{
if( (r_A>0x90) && ( (r_A & 0x0f)>9) ) r_meml|=0x60;
ADD(r_meml);
}
r_F = ( r_F & ~( FLAG_C | FLAG_P) ) | r_memh |
parity_table[r_A];
AddCycles( 4 ); break;
case OUT_N_A : Z80OutPort( regs, Z80ReadMem( r_PC ), r_A ); r_PC++;
AddCycles( 11 ); break;
case IN_A_N : r_A = Z80InPort( Z80ReadMem( r_PC ) + (r_A << 8));
r_PC++; AddCycles( 11 ); break;
case EX_HL_xSP : r_meml = Z80ReadMem(r_SP);
r_memh = Z80ReadMem(r_SP+1);
Z80WriteMem(r_SP, r_L, regs);
Z80WriteMem(r_SP+1, r_H, regs);
r_L = r_meml;
r_H = r_memh;
AddCycles( 19 ); break;
case EXX : EX_WORD(r_BC, r_BCs); EX_WORD(r_DE, r_DEs);
EX_WORD(r_HL, r_HLs);
AddCycles( 4 ); break;
case EX_DE_HL : EX_WORD( r_DE, r_HL );
AddCycles( 4 );
break;
case AND_N : AND_mem( r_PC );
r_PC++;
AddCycles( 4+3 );
break;
case XOR_N : XOR_mem( r_PC );
r_PC++;
AddCycles( 4+3 );
break;
case OR_N : OR_mem( r_PC );
r_PC++;
AddCycles( 4+3 );
break;
case DI : r_IFF1 = r_IFF2 = 0;
AddCycles( 4 );
break;
case CALL :
CALL_nn();
AddCycles( 4+3+3+3+3+1 );
break;
case CALL_NZ : if( TEST_FLAG(Z_FLAG) )
{ r_PC += 2; AddCycles( 4+3+3 ); }
else
{
CALL_nn();
AddCycles( 4+3+3+3+3+1 );
}
break;
case CALL_NC : if( TEST_FLAG(C_FLAG) )
{ r_PC += 2; AddCycles( 4+3+3 ); }
else
{ CALL_nn();
AddCycles( 4+3+3+3+3+1 );
}
break;
case CALL_PO : if( TEST_FLAG(P_FLAG) )
{ r_PC += 2; AddCycles( 4+3+3 ); }
else
{ CALL_nn();
AddCycles( 4+3+3+ 3+3+1 );
}
break;
case CALL_P : if( TEST_FLAG(S_FLAG) )
{ r_PC += 2; AddCycles( 4+3+3 ); }
else
{ CALL_nn();
AddCycles( 4+3+3+3+3+1 );
}
break;
case CALL_Z : if( TEST_FLAG(Z_FLAG) )
{ CALL_nn();
AddCycles( 4+3+3+3+3+1 );
}
else
{ r_PC += 2; AddCycles( 4+3+3 ); }
break;
case CALL_C : if( TEST_FLAG(C_FLAG) )
{ CALL_nn();
AddCycles( 4+3+3+ 3+3+4 );
}
else
{ r_PC += 2; AddCycles( 4+3+3 ); }
break;
case CALL_PE : if( TEST_FLAG(P_FLAG) )
{ CALL_nn();
AddCycles( 4+3+3+3+3+1 );
}
else
{ r_PC += 2; AddCycles( 4+3+3 ); }
break;
case CALL_M : if( TEST_FLAG(S_FLAG) )
{ CALL_nn();
AddCycles( 4+3+3+3+3+1 );
}
else
{ r_PC += 2; AddCycles( 4+3+3 ); }
break;
case EI : r_IFF1 = r_IFF2 = 1;
/*
Why Marat Fayzullin does this? ->
regs->IFF2 |= 0x01;
if( regs->IRequest != INT_NOINT )
{
regs->IBackup = regs->ICount;
regs->ICount = 0x1;
r_IFF |= 0x20;
}*/
AddCycles( 4 );
break;
case RST_00 : RST(0x00); AddCycles( 11 ); break;
case RST_08 : RST(0x08); AddCycles( 11 ); break;
case RST_10 : RST(0x10); AddCycles( 11 ); break;
case RST_18 : RST(0x18); AddCycles( 11 ); break;
case RST_20 : RST(0x20); AddCycles( 11 ); break;
case RST_28 : RST(0x28); AddCycles( 11 ); break;
case RST_30 : RST(0x30); AddCycles( 11 ); break;
case RST_38 : RST(0x38); AddCycles( 11 ); break;
default:
// exit(1);
///!!! if( regs->DecodingErrors )
///!!! printf("z80 core: Unknown instruction: %02Xh at PC=%04Xh.\n",
///!!! Z80ReadMem(r_PC-1), r_PC-1 );
break;