/** VGB: portable GameBoy emulator ***************************/ /** **/ /** Codes.h **/ /** **/ /** This file contains implementation for the main table of **/ /** Z80 commands. It is included from Z80.c. **/ /** **/ /** Copyright (C) Marat Fayzullin 1994,1995 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ /*************************************************************/ case 0x08: J.B.l=M_RDMEM(R.PC.W++);J.B.h=M_RDMEM(R.PC.W++); M_WRMEM(J.W++,R.SP.B.l);M_WRMEM(J.W,R.SP.B.h); break; case 0x22: M_WRMEM(R.HL.W++,R.AF.B.h);break; case 0x2A: R.AF.B.h=M_RDMEM(R.HL.W++);break; case 0x32: M_WRMEM(R.HL.W--,R.AF.B.h);break; case 0x3A: R.AF.B.h=M_RDMEM(R.HL.W--);break; case 0xD9: R.IFF|=0x01;M_RET;break; case 0xE0: M_WRMEM(0xFF00+M_RDMEM(R.PC.W++),R.AF.B.h);break; case 0xE2: M_WRMEM(0xFF00+R.BC.B.l,R.AF.B.h);break; case 0xE8: R.SP.W+=(offset)M_RDMEM(R.PC.W++);break; case 0xEA: J.B.l=M_RDMEM(R.PC.W++); J.B.h=M_RDMEM(R.PC.W++); M_WRMEM(J.W,R.AF.B.h); break; case 0xF0: R.AF.B.h=M_RDMEM(0xFF00+M_RDMEM(R.PC.W++));break; case 0xF2: R.AF.B.h=M_RDMEM(0xFF00+R.BC.B.l);break; case 0xF8: R.HL.W=R.SP.W+(offset)M_RDMEM(R.PC.W++);break; case 0xFA: J.B.l=M_RDMEM(R.PC.W++); J.B.h=M_RDMEM(R.PC.W++); R.AF.B.h=M_RDMEM(J.W); break; case JR_NZ: if(R.AF.B.l&Z_FLAG) R.PC.W++; else { M_JR; } break; case JR_NC: if(R.AF.B.l&C_FLAG) R.PC.W++; else { M_JR; } break; case JR_Z: if(R.AF.B.l&Z_FLAG) { M_JR; } else R.PC.W++; break; case JR_C: if(R.AF.B.l&C_FLAG) { M_JR; } else R.PC.W++; break; case JP_NZ: if(R.AF.B.l&Z_FLAG) R.PC.W+=2; else { M_JP; } break; case JP_NC: if(R.AF.B.l&C_FLAG) R.PC.W+=2; else { M_JP; } break; case JP_Z: if(R.AF.B.l&Z_FLAG) { M_JP; } else R.PC.W+=2; break; case JP_C: if(R.AF.B.l&C_FLAG) { M_JP; } else R.PC.W+=2; break; case RET_NZ: if(!(R.AF.B.l&Z_FLAG)) { M_RET; } break; case RET_NC: if(!(R.AF.B.l&C_FLAG)) { M_RET; } break; case RET_Z: if(R.AF.B.l&Z_FLAG) { M_RET; } break; case RET_C: if(R.AF.B.l&C_FLAG) { M_RET; } break; case CALL_NZ: if(R.AF.B.l&Z_FLAG) R.PC.W+=2; else { M_CALL; } break; case CALL_NC: if(R.AF.B.l&C_FLAG) R.PC.W+=2; else { M_CALL; } break; case CALL_Z: if(R.AF.B.l&Z_FLAG) { M_CALL; } else R.PC.W+=2; break; case CALL_C: if(R.AF.B.l&C_FLAG) { M_CALL; } else R.PC.W+=2; break; case ADD_B: M_ADD(R.BC.B.h);break; case ADD_C: M_ADD(R.BC.B.l);break; case ADD_D: M_ADD(R.DE.B.h);break; case ADD_E: M_ADD(R.DE.B.l);break; case ADD_H: M_ADD(R.HL.B.h);break; case ADD_L: M_ADD(R.HL.B.l);break; case ADD_A: M_ADD(R.AF.B.h);break; case ADD_xHL: I=M_RDMEM(R.HL.W);M_ADD(I);break; case ADD_BYTE: I=M_RDMEM(R.PC.W++);M_ADD(I);break; case SUB_B: M_SUB(R.BC.B.h);break; case SUB_C: M_SUB(R.BC.B.l);break; case SUB_D: M_SUB(R.DE.B.h);break; case SUB_E: M_SUB(R.DE.B.l);break; case SUB_H: M_SUB(R.HL.B.h);break; case SUB_L: M_SUB(R.HL.B.l);break; case SUB_A: R.AF.B.h=0;R.AF.B.l=N_FLAG|Z_FLAG;break; case SUB_xHL: I=M_RDMEM(R.HL.W);M_SUB(I);break; case SUB_BYTE: I=M_RDMEM(R.PC.W++);M_SUB(I);break; case AND_B: M_AND(R.BC.B.h);break; case AND_C: M_AND(R.BC.B.l);break; case AND_D: M_AND(R.DE.B.h);break; case AND_E: M_AND(R.DE.B.l);break; case AND_H: M_AND(R.HL.B.h);break; case AND_L: M_AND(R.HL.B.l);break; case AND_A: M_AND(R.AF.B.h);break; case AND_xHL: I=M_RDMEM(R.HL.W);M_AND(I);break; case AND_BYTE: I=M_RDMEM(R.PC.W++);M_AND(I);break; case OR_B: M_OR(R.BC.B.h);break; case OR_C: M_OR(R.BC.B.l);break; case OR_D: M_OR(R.DE.B.h);break; case OR_E: M_OR(R.DE.B.l);break; case OR_H: M_OR(R.HL.B.h);break; case OR_L: M_OR(R.HL.B.l);break; case OR_A: M_OR(R.AF.B.h);break; case OR_xHL: I=M_RDMEM(R.HL.W);M_OR(I);break; case OR_BYTE: I=M_RDMEM(R.PC.W++);M_OR(I);break; case ADC_B: M_ADC(R.BC.B.h);break; case ADC_C: M_ADC(R.BC.B.l);break; case ADC_D: M_ADC(R.DE.B.h);break; case ADC_E: M_ADC(R.DE.B.l);break; case ADC_H: M_ADC(R.HL.B.h);break; case ADC_L: M_ADC(R.HL.B.l);break; case ADC_A: M_ADC(R.AF.B.h);break; case ADC_xHL: I=M_RDMEM(R.HL.W);M_ADC(I);break; case ADC_BYTE: I=M_RDMEM(R.PC.W++);M_ADC(I);break; case SBC_B: M_SBC(R.BC.B.h);break; case SBC_C: M_SBC(R.BC.B.l);break; case SBC_D: M_SBC(R.DE.B.h);break; case SBC_E: M_SBC(R.DE.B.l);break; case SBC_H: M_SBC(R.HL.B.h);break; case SBC_L: M_SBC(R.HL.B.l);break; case SBC_A: M_SBC(R.AF.B.h);break; case SBC_xHL: I=M_RDMEM(R.HL.W);M_SBC(I);break; case SBC_BYTE: I=M_RDMEM(R.PC.W++);M_SBC(I);break; case XOR_B: M_XOR(R.BC.B.h);break; case XOR_C: M_XOR(R.BC.B.l);break; case XOR_D: M_XOR(R.DE.B.h);break; case XOR_E: M_XOR(R.DE.B.l);break; case XOR_H: M_XOR(R.HL.B.h);break; case XOR_L: M_XOR(R.HL.B.l);break; case XOR_A: R.AF.B.h=0;R.AF.B.l=Z_FLAG;break; case XOR_xHL: I=M_RDMEM(R.HL.W);M_XOR(I);break; case XOR_BYTE: I=M_RDMEM(R.PC.W++);M_XOR(I);break; case CP_B: M_CP(R.BC.B.h);break; case CP_C: M_CP(R.BC.B.l);break; case CP_D: M_CP(R.DE.B.h);break; case CP_E: M_CP(R.DE.B.l);break; case CP_H: M_CP(R.HL.B.h);break; case CP_L: M_CP(R.HL.B.l);break; case CP_A: R.AF.B.l=N_FLAG|Z_FLAG;break; case CP_xHL: I=M_RDMEM(R.HL.W);M_CP(I);break; case CP_BYTE: I=M_RDMEM(R.PC.W++);M_CP(I);break; case LD_BC_WORD: M_LDWORD(BC);break; case LD_DE_WORD: M_LDWORD(DE);break; case LD_HL_WORD: M_LDWORD(HL);break; case LD_SP_WORD: M_LDWORD(SP);break; case LD_PC_HL: R.PC.W=R.HL.W;break; case LD_SP_HL: R.SP.W=R.HL.W;break; case LD_A_xBC: R.AF.B.h=M_RDMEM(R.BC.W);break; case LD_A_xDE: R.AF.B.h=M_RDMEM(R.DE.W);break; case ADD_HL_BC: M_ADDW(HL,BC);break; case ADD_HL_DE: M_ADDW(HL,DE);break; case ADD_HL_HL: M_ADDW(HL,HL);break; case ADD_HL_SP: M_ADDW(HL,SP);break; case DEC_BC: R.BC.W--;break; case DEC_DE: R.DE.W--;break; case DEC_HL: R.HL.W--;break; case DEC_SP: R.SP.W--;break; case INC_BC: R.BC.W++;break; case INC_DE: R.DE.W++;break; case INC_HL: R.HL.W++;break; case INC_SP: R.SP.W++;break; case DEC_B: M_DEC(R.BC.B.h);break; case DEC_C: M_DEC(R.BC.B.l);break; case DEC_D: M_DEC(R.DE.B.h);break; case DEC_E: M_DEC(R.DE.B.l);break; case DEC_H: M_DEC(R.HL.B.h);break; case DEC_L: M_DEC(R.HL.B.l);break; case DEC_A: M_DEC(R.AF.B.h);break; case DEC_xHL: I=M_RDMEM(R.HL.W);M_DEC(I);M_WRMEM(R.HL.W,I);break; case INC_B: M_INC(R.BC.B.h);break; case INC_C: M_INC(R.BC.B.l);break; case INC_D: M_INC(R.DE.B.h);break; case INC_E: M_INC(R.DE.B.l);break; case INC_H: M_INC(R.HL.B.h);break; case INC_L: M_INC(R.HL.B.l);break; case INC_A: M_INC(R.AF.B.h);break; case INC_xHL: I=M_RDMEM(R.HL.W);M_INC(I);M_WRMEM(R.HL.W,I);break; case RLCA: I=R.AF.B.h&0x80? C_FLAG:0; R.AF.B.h=(R.AF.B.h<<1)|I; R.AF.B.l=(R.AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I; break; case RLA: I=R.AF.B.h&0x80? C_FLAG:0; R.AF.B.h=(R.AF.B.h<<1)|(R.AF.B.l&C_FLAG); R.AF.B.l=(R.AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I; break; case RRCA: I=R.AF.B.h&0x01; R.AF.B.h=(R.AF.B.h>>1)|(I? 0x80:0); R.AF.B.l=(R.AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I; break; case RRA: I=R.AF.B.h&0x01; R.AF.B.h=(R.AF.B.h>>1)|(R.AF.B.l&C_FLAG? 0x80:0); R.AF.B.l=(R.AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I; break; case RST00: M_RST(0x0000);break; case RST08: M_RST(0x0008);break; case RST10: M_RST(0x0010);break; case RST18: M_RST(0x0018);break; case RST20: M_RST(0x0020);break; case RST28: M_RST(0x0028);break; case RST30: M_RST(0x0030);break; case RST38: M_RST(0x0038);break; case PUSH_BC: M_PUSH(BC);break; case PUSH_DE: M_PUSH(DE);break; case PUSH_HL: M_PUSH(HL);break; case PUSH_AF: M_PUSH(AF);break; case POP_BC: M_POP(BC);break; case POP_DE: M_POP(DE);break; case POP_HL: M_POP(HL);break; case POP_AF: M_POP(AF);break; case JP: M_JP;break; case JR: M_JR;break; case CALL: M_CALL;break; case RET: M_RET;break; case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break; case CPL: R.AF.B.h=~R.AF.B.h;S(N_FLAG|H_FLAG);break; case NOP: break; case EI: R.IFF|=0x01;break; case DI: R.IFF&=0xFE;break; case CCF: R.AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG); R.AF.B.l|=R.AF.B.l&C_FLAG? 0:H_FLAG; break; case LD_B_B: R.BC.B.h=R.BC.B.h;break; case LD_C_B: R.BC.B.l=R.BC.B.h;break; case LD_D_B: R.DE.B.h=R.BC.B.h;break; case LD_E_B: R.DE.B.l=R.BC.B.h;break; case LD_H_B: R.HL.B.h=R.BC.B.h;break; case LD_L_B: R.HL.B.l=R.BC.B.h;break; case LD_A_B: R.AF.B.h=R.BC.B.h;break; case LD_xHL_B: M_WRMEM(R.HL.W,R.BC.B.h);break; case LD_B_C: R.BC.B.h=R.BC.B.l;break; case LD_C_C: R.BC.B.l=R.BC.B.l;break; case LD_D_C: R.DE.B.h=R.BC.B.l;break; case LD_E_C: R.DE.B.l=R.BC.B.l;break; case LD_H_C: R.HL.B.h=R.BC.B.l;break; case LD_L_C: R.HL.B.l=R.BC.B.l;break; case LD_A_C: R.AF.B.h=R.BC.B.l;break; case LD_xHL_C: M_WRMEM(R.HL.W,R.BC.B.l);break; case LD_B_D: R.BC.B.h=R.DE.B.h;break; case LD_C_D: R.BC.B.l=R.DE.B.h;break; case LD_D_D: R.DE.B.h=R.DE.B.h;break; case LD_E_D: R.DE.B.l=R.DE.B.h;break; case LD_H_D: R.HL.B.h=R.DE.B.h;break; case LD_L_D: R.HL.B.l=R.DE.B.h;break; case LD_A_D: R.AF.B.h=R.DE.B.h;break; case LD_xHL_D: M_WRMEM(R.HL.W,R.DE.B.h);break; case LD_B_E: R.BC.B.h=R.DE.B.l;break; case LD_C_E: R.BC.B.l=R.DE.B.l;break; case LD_D_E: R.DE.B.h=R.DE.B.l;break; case LD_E_E: R.DE.B.l=R.DE.B.l;break; case LD_H_E: R.HL.B.h=R.DE.B.l;break; case LD_L_E: R.HL.B.l=R.DE.B.l;break; case LD_A_E: R.AF.B.h=R.DE.B.l;break; case LD_xHL_E: M_WRMEM(R.HL.W,R.DE.B.l);break; case LD_B_H: R.BC.B.h=R.HL.B.h;break; case LD_C_H: R.BC.B.l=R.HL.B.h;break; case LD_D_H: R.DE.B.h=R.HL.B.h;break; case LD_E_H: R.DE.B.l=R.HL.B.h;break; case LD_H_H: R.HL.B.h=R.HL.B.h;break; case LD_L_H: R.HL.B.l=R.HL.B.h;break; case LD_A_H: R.AF.B.h=R.HL.B.h;break; case LD_xHL_H: M_WRMEM(R.HL.W,R.HL.B.h);break; case LD_B_L: R.BC.B.h=R.HL.B.l;break; case LD_C_L: R.BC.B.l=R.HL.B.l;break; case LD_D_L: R.DE.B.h=R.HL.B.l;break; case LD_E_L: R.DE.B.l=R.HL.B.l;break; case LD_H_L: R.HL.B.h=R.HL.B.l;break; case LD_L_L: R.HL.B.l=R.HL.B.l;break; case LD_A_L: R.AF.B.h=R.HL.B.l;break; case LD_xHL_L: M_WRMEM(R.HL.W,R.HL.B.l);break; case LD_B_A: R.BC.B.h=R.AF.B.h;break; case LD_C_A: R.BC.B.l=R.AF.B.h;break; case LD_D_A: R.DE.B.h=R.AF.B.h;break; case LD_E_A: R.DE.B.l=R.AF.B.h;break; case LD_H_A: R.HL.B.h=R.AF.B.h;break; case LD_L_A: R.HL.B.l=R.AF.B.h;break; case LD_A_A: R.AF.B.h=R.AF.B.h;break; case LD_xHL_A: M_WRMEM(R.HL.W,R.AF.B.h);break; case LD_xBC_A: M_WRMEM(R.BC.W,R.AF.B.h);break; case LD_xDE_A: M_WRMEM(R.DE.W,R.AF.B.h);break; case LD_B_xHL: R.BC.B.h=M_RDMEM(R.HL.W);break; case LD_C_xHL: R.BC.B.l=M_RDMEM(R.HL.W);break; case LD_D_xHL: R.DE.B.h=M_RDMEM(R.HL.W);break; case LD_E_xHL: R.DE.B.l=M_RDMEM(R.HL.W);break; case LD_H_xHL: R.HL.B.h=M_RDMEM(R.HL.W);break; case LD_L_xHL: R.HL.B.l=M_RDMEM(R.HL.W);break; case LD_A_xHL: R.AF.B.h=M_RDMEM(R.HL.W);break; case LD_B_BYTE: R.BC.B.h=M_RDMEM(R.PC.W++);break; case LD_C_BYTE: R.BC.B.l=M_RDMEM(R.PC.W++);break; case LD_D_BYTE: R.DE.B.h=M_RDMEM(R.PC.W++);break; case LD_E_BYTE: R.DE.B.l=M_RDMEM(R.PC.W++);break; case LD_H_BYTE: R.HL.B.h=M_RDMEM(R.PC.W++);break; case LD_L_BYTE: R.HL.B.l=M_RDMEM(R.PC.W++);break; case LD_A_BYTE: R.AF.B.h=M_RDMEM(R.PC.W++);break; case LD_xHL_BYTE: M_WRMEM(R.HL.W,M_RDMEM(R.PC.W++));break; case EX_HL_xSP: J.B.l=M_RDMEM(R.SP.W);M_WRMEM(R.SP.W++,R.HL.B.l); J.B.h=M_RDMEM(R.SP.W);M_WRMEM(R.SP.W--,R.HL.B.h); R.HL.W=J.W; break; case DAA: J.B.h=R.AF.B.h&0x0F; J.W=(R.AF.B.l&N_FLAG)? ( (R.AF.B.l&C_FLAG)? (((R.AF.B.l&H_FLAG)? 0x9A00:0xA000)+C_FLAG): ((R.AF.B.l&H_FLAG)? 0xFA00:0x0000) ) : ( (R.AF.B.l&C_FLAG)? (((R.AF.B.l&H_FLAG)? 0x6600:((J.B.h<0x0A)? 0x6000:0x6600))+C_FLAG): ( (R.AF.B.l&H_FLAG)? ((R.AF.B.h<0xA0)? 0x0600:(0x6600+C_FLAG)): ( (J.B.h<0x0A)? ((R.AF.B.h<0xA0)? 0x0000:(0x6000+C_FLAG)): ((R.AF.B.h<0x90)? 0x0600:(0x6600+C_FLAG)) ) ) ); R.AF.B.h+=J.B.h; FLAGS(R.AF.B.h,J.B.l|(R.AF.B.l&N_FLAG)); break;