home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-01 | 13.4 KB | 447 lines | [TEXT/CWIE] |
- /* Z80 Emulator: Normal instruction handlers
- Copyright (C) 1995 G.Woigk
-
- This file is part of Mac Spectacle and it is free software
- See application.c for details
-
- 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.
-
- based on fMSX; Copyright (C) Marat Fayzullin 1994,1995
- All opcodes covered, no unsupported opcodes!
- */
-
-
- increment_r;
- COUNT_PC;
- COUNT_INSTR;
-
- switch(n)
- {
-
-
- // ------- JUMPING, BRANCHING etc. ------------------------
-
- case JP: time(10); pc=nn;loop;
- case JP_NZ: time(10); w=nn; if(!(rf&Z_FLAG)) pc=w; loop;
- case JP_NC: time(10); w=nn; if(!(rf&C_FLAG)) pc=w; loop;
- case JP_PO: time(10); w=nn; if(!(rf&P_FLAG)) pc=w; loop;
- case JP_P: time(10); w=nn; if(!(rf&S_FLAG)) pc=w; loop;
- case JP_Z: time(10); w=nn; if( rf&Z_FLAG ) pc=w; loop;
- case JP_C: time(10); w=nn; if( rf&C_FLAG ) pc=w; loop;
- case JP_PE: time(10); w=nn; if( rf&P_FLAG ) pc=w; loop;
- case JP_M: time(10); w=nn; if( rf&S_FLAG ) pc=w; loop;
-
-
- case JR: { pc+=dis; time(12); loop; }
- case JR_NZ: if(rf&Z_FLAG) { pc++; time(7); loop; }
- { pc+=dis; time(12); loop; }
- case JR_NC: if(rf&C_FLAG) { pc++; time(7); loop; }
- { pc+=dis; time(12); loop; }
- case JR_Z: if(rf&Z_FLAG) { pc+=dis; time(12); loop; }
- { pc++; time(7); loop; }
- case JR_C: if(rf&C_FLAG) { pc+=dis; time(12); loop; }
- { pc++; time(7); loop; }
- case DJNZ: if(--RB) { pc+=dis; time(13); loop; }
- { pc++; time(8); loop; }
-
-
-
- case CALL: w=nn; { push(pc); pc=w; time(17); loop; }
- case CALL_NZ: w=nn; if(rf&Z_FLAG) { time(10); loop; }
- { push(pc); pc=w; time(17); loop; }
- case CALL_NC: w=nn; if(rf&C_FLAG) { time(10); loop; }
- { push(pc); pc=w; time(17); loop; }
- case CALL_PO: w=nn; if(rf&P_FLAG) { time(10); loop; }
- { push(pc); pc=w; time(17); loop; }
- case CALL_P: w=nn; if(rf&S_FLAG) { time(10); loop; }
- { push(pc); pc=w; time(17); loop; }
- case CALL_Z: w=nn; if(rf&Z_FLAG) { push(pc); pc=w; time(17); loop; }
- { time(10); loop; }
- case CALL_C: w=nn; if(rf&C_FLAG) { push(pc); pc=w; time(17); loop; }
- { time(10); loop; }
- case CALL_PE: w=nn; if(rf&P_FLAG) { push(pc); pc=w; time(17); loop; }
- { time(10); loop; }
- case CALL_M: w=nn; if(rf&S_FLAG) { push(pc); pc=w; time(17); loop; }
- { time(10); loop; }
-
-
- case RET: { pc=pop(); time(10); loop; }
- case RET_NZ: if(rf&Z_FLAG) { time(5); loop; }
- { pc=pop(); time(11); loop; }
- case RET_NC: if(rf&C_FLAG) { time(5); loop; }
- { pc=pop(); time(11); loop; }
- case RET_PO: if(rf&P_FLAG) { time(5); loop; }
- { pc=pop(); time(11); loop; }
- case RET_P: if(rf&S_FLAG) { time(5); loop; }
- { pc=pop(); time(11); loop; }
- case RET_Z: if(rf&Z_FLAG) { pc=pop(); time(11); loop; }
- { time(5); loop; }
- case RET_C: if(rf&C_FLAG) { pc=pop(); time(11); loop; }
- { time(5); loop; }
- case RET_PE: if(rf&P_FLAG) { pc=pop(); time(11); loop; }
- { time(5); loop; }
- case RET_M: if(rf&S_FLAG) { pc=pop(); time(11); loop; }
- { time(5); loop; }
-
-
- case RST00: info_misc1;time(11); exit(rst0_instr);
- case RST08: info_misc1;time(11); push(pc);pc=0x0008;loop;
- case RST10: info_misc1;time(11); push(pc);pc=0x0010;loop;
- case RST18: info_misc1;time(11); push(pc);pc=0x0018;loop;
- case RST20: info_misc1;time(11); push(pc);pc=0x0020;loop;
- case RST28: info_misc1;time(11); push(pc);pc=0x0028;loop;
- case RST30: info_misc1;time(11); push(pc);pc=0x0030;loop;
- case RST38: info_misc1;time(11); push(pc);pc=0x0038;loop;
-
-
- // ---- LD R,X --------------------------------------------
-
- case LD_B_B: time(4); RB=RB;loop;
- case LD_C_B: time(4); RC=RB;loop;
- case LD_D_B: time(4); RD=RB;loop;
- case LD_E_B: time(4); RE=RB;loop;
- case LD_H_B: time(4); RH=RB;loop;
- case LD_L_B: time(4); RL=RB;loop;
- case LD_A_B: time(4); ra=RB;loop;
- case LD_X_B: time(7); rompoke(HL,RB);loop;
-
- case LD_B_C: time(4); RB=RC;loop;
- case LD_C_C: time(4); RC=RC;loop;
- case LD_D_C: time(4); RD=RC;loop;
- case LD_E_C: time(4); RE=RC;loop;
- case LD_H_C: time(4); RH=RC;loop;
- case LD_L_C: time(4); RL=RC;loop;
- case LD_A_C: time(4); ra=RC;loop;
- case LD_X_C: time(7); rompoke(HL,RC);loop;
-
- case LD_B_D: time(4); RB=RD;loop;
- case LD_C_D: time(4); RC=RD;loop;
- case LD_D_D: time(4); RD=RD;loop;
- case LD_E_D: time(4); RE=RD;loop;
- case LD_H_D: time(4); RH=RD;loop;
- case LD_L_D: time(4); RL=RD;loop;
- case LD_A_D: time(4); ra=RD;loop;
- case LD_X_D: time(7); rompoke(HL,RD);loop;
-
- case LD_B_E: time(4); RB=RE;loop;
- case LD_C_E: time(4); RC=RE;loop;
- case LD_D_E: time(4); RD=RE;loop;
- case LD_E_E: time(4); RE=RE;loop;
- case LD_H_E: time(4); RH=RE;loop;
- case LD_L_E: time(4); RL=RE;loop;
- case LD_A_E: time(4); ra=RE;loop;
- case LD_X_E: time(7); rompoke(HL,RE);loop;
-
- case LD_B_H: time(4); RB=RH;loop;
- case LD_C_H: time(4); RC=RH;loop;
- case LD_D_H: time(4); RD=RH;loop;
- case LD_E_H: time(4); RE=RH;loop;
- case LD_H_H: time(4); RH=RH;loop;
- case LD_L_H: time(4); RL=RH;loop;
- case LD_A_H: time(4); ra=RH;loop;
- case LD_X_H: time(7); rompoke(HL,RH);loop;
-
- case LD_B_L: time(4); RB=RL;loop;
- case LD_C_L: time(4); RC=RL;loop;
- case LD_D_L: time(4); RD=RL;loop;
- case LD_E_L: time(4); RE=RL;loop;
- case LD_H_L: time(4); RH=RL;loop;
- case LD_L_L: time(4); RL=RL;loop;
- case LD_A_L: time(4); ra=RL;loop;
- case LD_X_L: time(7); rompoke(HL,RL);loop;
-
- case LD_B_A: time(4); RB=ra;loop;
- case LD_C_A: time(4); RC=ra;loop;
- case LD_D_A: time(4); RD=ra;loop;
- case LD_E_A: time(4); RE=ra;loop;
- case LD_H_A: time(4); RH=ra;loop;
- case LD_L_A: time(4); RL=ra;loop;
- case LD_A_A: time(4); ra=ra;loop;
- case LD_X_A: time(7); rompoke(HL,ra);loop;
-
- case LD_B_X: time(7); RB=peek(HL); loop;
- case LD_C_X: time(7); RC=peek(HL); loop;
- case LD_D_X: time(7); RD=peek(HL); loop;
- case LD_E_X: time(7); RE=peek(HL); loop;
- case LD_H_X: time(7); RH=peek(HL); loop;
- case LD_L_X: time(7); RL=peek(HL); loop;
- case LD_A_X: time(7); ra=peek(HL); loop;
-
- case LD_B_N: time(7); RB=n; loop;
- case LD_C_N: time(7); RC=n; loop;
- case LD_D_N: time(7); RD=n; loop;
- case LD_E_N: time(7); RE=n; loop;
- case LD_H_N: time(7); RH=n; loop;
- case LD_L_N: time(7); RL=n; loop;
- case LD_A_N: time(7); ra=n; loop;
- case LD_X_N: time(10);rompoke(HL,n); loop;
-
- case LD_xWORD_A:time(13);w=nn;rompoke(w,ra);loop;
- case LD_xBC_A: time(7); rompoke(BC,ra); loop;
- case LD_xDE_A: time(7); rompoke(DE,ra); loop;
- case LD_A_xBC: time(7); ra = peek(BC); loop;
- case LD_A_xDE: time(7); ra = peek(DE); loop;
- case LD_A_xWORD:time(13);ra = peek(nn); loop;
-
-
- // ------- ARITHMETIC + BOOLEAN OPERATIONS ------------------------
-
- case ADD_B: time(4); M_ADD(RB);loop;
- case ADD_C: time(4); M_ADD(RC);loop;
- case ADD_D: time(4); M_ADD(RD);loop;
- case ADD_E: time(4); M_ADD(RE);loop;
- case ADD_H: time(4); M_ADD(RH);loop;
- case ADD_L: time(4); M_ADD(RL);loop;
- case ADD_A: time(4); M_ADD(ra);loop;
- case ADD_X: time(7); c=peek(HL);M_ADD(c);loop;
- case ADD_N: time(7); c=n; M_ADD(c);loop;
-
- case SUB_B: time(4); M_SUB(RB);loop;
- case SUB_C: time(4); M_SUB(RC);loop;
- case SUB_D: time(4); M_SUB(RD);loop;
- case SUB_E: time(4); M_SUB(RE);loop;
- case SUB_H: time(4); M_SUB(RH);loop;
- case SUB_L: time(4); M_SUB(RL);loop;
- case SUB_A: time(4); M_SUB(ra);loop; // ra=0;rf=N_FLAG|Z_FLAG;loop;
- case SUB_X: time(7); c=peek(HL);M_SUB(c);loop;
- case SUB_N: time(7); c=n; M_SUB(c);loop;
-
- case ADC_B: time(4); M_ADC(RB);loop;
- case ADC_C: time(4); M_ADC(RC);loop;
- case ADC_D: time(4); M_ADC(RD);loop;
- case ADC_E: time(4); M_ADC(RE);loop;
- case ADC_H: time(4); M_ADC(RH);loop;
- case ADC_L: time(4); M_ADC(RL);loop;
- case ADC_A: time(4); M_ADC(ra);loop;
- case ADC_X: time(7); c=peek(HL);M_ADC(c);loop;
- case ADC_N: time(7); c=n; M_ADC(c);loop;
-
- case SBC_B: time(4); M_SBC(RB);loop;
- case SBC_C: time(4); M_SBC(RC);loop;
- case SBC_D: time(4); M_SBC(RD);loop;
- case SBC_E: time(4); M_SBC(RE);loop;
- case SBC_H: time(4); M_SBC(RH);loop;
- case SBC_L: time(4); M_SBC(RL);loop;
- case SBC_A: time(4); M_SBC(ra);loop;
- case SBC_X: time(7); c=peek(HL);M_SBC(c);loop;
- case SBC_N: time(7); c=n; M_SBC(c);loop;
-
- case CP_B: time(4); M_CP(RB);loop;
- case CP_C: time(4); M_CP(RC);loop;
- case CP_D: time(4); M_CP(RD);loop;
- case CP_E: time(4); M_CP(RE);loop;
- case CP_H: time(4); M_CP(RH);loop;
- case CP_L: time(4); M_CP(RL);loop;
- case CP_A: time(4); M_CP(ra);loop; // rf=N_FLAG|Z_FLAG;loop;
- case CP_X: time(7); c=peek(HL);M_CP(c);loop;
- case CP_N: time(7); c=n; M_CP(c);loop;
-
- case AND_B: time(4); M_AND(RB);loop;
- case AND_C: time(4); M_AND(RC);loop;
- case AND_D: time(4); M_AND(RD);loop;
- case AND_E: time(4); M_AND(RE);loop;
- case AND_H: time(4); M_AND(RH);loop;
- case AND_L: time(4); M_AND(RL);loop;
- case AND_A: time(4); M_AND(ra);loop;
- case AND_X: time(7); M_AND(peek(HL));loop;
- case AND_N: time(7); M_AND(n); loop;
-
- case OR_B: time(4); M_OR(RB);loop;
- case OR_C: time(4); M_OR(RC);loop;
- case OR_D: time(4); M_OR(RD);loop;
- case OR_E: time(4); M_OR(RE);loop;
- case OR_H: time(4); M_OR(RH);loop;
- case OR_L: time(4); M_OR(RL);loop;
- case OR_A: time(4); M_OR(ra);loop;
- case OR_X: time(7); M_OR(peek(HL));loop;
- case OR_N: time(7); M_OR(n); loop;
-
- case XOR_B: time(4); M_XOR(RB);loop;
- case XOR_C: time(4); M_XOR(RC);loop;
- case XOR_D: time(4); M_XOR(RD);loop;
- case XOR_E: time(4); M_XOR(RE);loop;
- case XOR_H: time(4); M_XOR(RH);loop;
- case XOR_L: time(4); M_XOR(RL);loop;
- case XOR_A: time(4); M_XOR(ra);loop; // ra=0;rf=P_FLAG|Z_FLAG;loop;
- case XOR_X: time(7); M_XOR(peek(HL));loop;
- case XOR_N: time(7); M_XOR(n);loop;
-
- case DEC_B: time(4); M_DEC(RB);loop;
- case DEC_C: time(4); M_DEC(RC);loop;
- case DEC_D: time(4); M_DEC(RD);loop;
- case DEC_E: time(4); M_DEC(RE);loop;
- case DEC_H: time(4); M_DEC(RH);loop;
- case DEC_L: time(4); M_DEC(RL);loop;
- case DEC_A: time(4); M_DEC(ra);loop;
- case DEC_X: time(11);c=peek(HL);M_DEC(c);rompoke(HL,c);loop;
-
- case INC_B: time(4); M_INC(RB);loop;
- case INC_C: time(4); M_INC(RC);loop;
- case INC_D: time(4); M_INC(RD);loop;
- case INC_E: time(4); M_INC(RE);loop;
- case INC_H: time(4); M_INC(RH);loop;
- case INC_L: time(4); M_INC(RL);loop;
- case INC_A: time(4); M_INC(ra);loop;
- case INC_X: time(11);c=peek(HL);M_INC(c);rompoke(HL,c);loop;
-
-
- /* RLCA...RRA set/clr C
- clear H=0, N=0
- pres Z, P, S
- */
- case RLCA:
- time(4);
- ra = (ra<<1) + (ra>>7);
- rf = (rf&~(C_FLAG+N_FLAG+H_FLAG)) + (ra&C_FLAG);
- loop;
- case RRCA:
- time(4);
- ra = (ra>>1) + (ra<<7);
- rf = (rf&~(C_FLAG+N_FLAG+H_FLAG)) + (ra>>7);
- loop;
- case RLA:
- time(4);
- c = ra>>7;
- ra = (ra<<1) + (rf&C_FLAG);
- rf = (rf&~(C_FLAG+N_FLAG+H_FLAG)) + c;
- loop;
- case RRA:
- time(4);
- c = ra&C_FLAG;
- ra = (ra>>1) + (rf<<7);
- rf = (rf&~(C_FLAG+N_FLAG+H_FLAG)) + c;
- loop;
-
-
- // ---- WORD OPERATIONS -----------------------------------------
-
- case LD_BC_WORD: time(10); BC = nn; loop;
- case LD_DE_WORD: time(10); DE = nn; loop;
- case LD_HL_WORD: time(10); HL = nn; loop;
- case LD_SP_WORD: time(10); sp = nn; loop;
-
- case LD_xNN_HL: time(16); w=nn; rompoke2(w,HL); loop;
- case LD_HL_xNN: time(16); w=nn; RL=peek(w); RH=peek(w+1); loop;
-
- case LD_PC_HL: time(4); pc = HL; loop;
- case LD_SP_HL: time(6); sp = HL; loop;
-
- case ADD_HL_BC: time(11); M_ADDW(HL,BC); loop;
- case ADD_HL_DE: time(11); M_ADDW(HL,DE); loop;
- case ADD_HL_HL: time(11); M_ADDW(HL,HL); loop;
- case ADD_HL_SP: time(11); M_ADDW(HL,sp); loop;
-
- case DEC_BC: time(6); BC--; loop;
- case DEC_DE: time(6); DE--; loop;
- case DEC_HL: time(6); HL--; loop;
- case DEC_SP: time(6); sp--; loop;
-
- case INC_BC: time(6); BC++; loop;
- case INC_DE: time(6); DE++; loop;
- case INC_HL: time(6); HL++; loop;
- case INC_SP: time(6); sp++; loop;
-
- case PUSH_BC: time(11); push(BC); loop;
- case PUSH_DE: time(11); push(DE); loop;
- case PUSH_HL: time(11); push(HL); loop;
- case PUSH_AF: time(11); poke(--sp,ra); poke(--sp,rf); loop;
-
- case POP_BC: time(10); BC=pop(); loop;
- case POP_DE: time(10); DE=pop(); loop;
- case POP_HL: time(10); HL=pop(); loop;
- case POP_AF: time(10); rf=peek(sp++); ra = peek(sp++); loop;
-
- case EX_DE_HL:
- time(4);
- w=DE;DE=HL;HL=w;
- loop;
- case EX_AF_AF:
- time(4);
- c=ra;ra=RA2;RA2=c;
- c=rf;rf=RF2;RF2=c;
- loop;
- case EXX:
- time(4);
- w=BC;BC=BC2;BC2=w;
- w=DE;DE=DE2;DE2=w;
- w=HL;HL=HL2;HL2=w;
- loop;
- case EX_HL_xSP:
- time(19);
- w=pop();
- push(HL);
- HL = w;
- loop;
-
-
- // ---- ODDS ----------------------------------------------
-
- case SCF: time(4); rf|=C_FLAG; rf&=~(N_FLAG+H_FLAG); loop;
- case CCF: time(4); rf^=C_FLAG; rf&=~N_FLAG; loop;
- case CPL: time(4); ra=~ra; rf|=N_FLAG+H_FLAG; loop;
- case NOP: time(4); loop;
- case DI: info_misc1; time(4); IFF1=IFF2=disabled; loop;
- case EI: info_misc1; time(4);
- #ifdef EI_WITH_DELAY
- if (WUFF && IFF1==disabled) ccx=cc-4;
- IFF1=IFF2=enabled; loop;
- #else
- IFF1=IFF2=enabled; goto check_wuff;
- #endif
- case HALT: info_misc1; time(4); exit(halt_instr);
-
- case OUTA:
- time(11);
- sto_cc;
- Do_Output ( ((Short)ra<<8) + n,ra );
- loop;
- case INA:
- time(11);
- sto_cc;
- ra = Do_Input ( ((Short)ra<<8) + n);
- loop;
-
-
- // ---- DAA --------------------------------------------------------
-
- case DAA:
- info_misc1;
- time(4);
- if (rf&N_FLAG) // previous instruction was SUB
- { if (rf&H_FLAG) ra -= 0x06;
- if (rf&C_FLAG) ra -= 0x60;
- }
- else // previous instruction was ADD
- { if ((ra&0x0F)>0x09) rf |= H_FLAG;
- if (rf&H_FLAG) ra += 0x06;
- if (ra>0x99) rf |= C_FLAG;
- if (rf&C_FLAG) ra += 0x60;
- };
-
- rf &= C_FLAG+N_FLAG;
- rf |= zlog_flags[ra];
- loop;
-
-
- // ---- PREFIX COMMANDS ---------------------------------------------
-
- case PFX_FD: izp = (dreg*)&IY; goto XY;
- case PFX_DD: izp = (dreg*)&IX; XY:
- #include "CodesXX.c"
-
- case PFX_CB:
- #include "CodesCB.c"
-
- case PFX_ED:
- #include "CodesED.c"
-
- default: // this should never happen
- pc-=1;
- exit(nimp_instr);
-
- };
- loop;
-
-