1 /** Z80: portable Z80 emulator *******************************/ 2 /** **/ 3 /** CodesED.h **/ 4 /** **/ 5 /** This file contains implementation for the ED table of **/ 6 /** Z80 commands. It is included from Z80.c. **/ 7 /** **/ 8 /** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/ 9 /** You are not allowed to distribute this software **/ 10 /** commercially. Please, notify me, if you make any **/ 11 /** changes to this file. **/ 12 /*************************************************************/ 13 14 /* $Id: mz80opc4.h,v 1.2 1999/11/08 01:33:53 nyef Exp $ */ 15 16 /** This is a special patch for emulating BIOS calls: ********/ 17 /* case DB_FE: PatchZ80(R);break; */ 18 /*************************************************************/ 19 20 case ADC_HL_BC: M_ADCW(BC);break; 21 case ADC_HL_DE: M_ADCW(DE);break; 22 case ADC_HL_HL: M_ADCW(HL);break; 23 case ADC_HL_SP: M_ADCW(SP);break; 24 25 case SBC_HL_BC: M_SBCW(BC);break; 26 case SBC_HL_DE: M_SBCW(DE);break; 27 case SBC_HL_HL: M_SBCW(HL);break; 28 case SBC_HL_SP: M_SBCW(SP);break; 29 30 case LD_xWORDe_HL: 31 J.B.l=OpZ80(R); 32 J.B.h=OpZ80(R); 33 WrZ80(J.W++,R->HL.B.l); 34 WrZ80(J.W,R->HL.B.h); 35 break; 36 case LD_xWORDe_DE: 37 J.B.l=OpZ80(R); 38 J.B.h=OpZ80(R); 39 WrZ80(J.W++,R->DE.B.l); 40 WrZ80(J.W,R->DE.B.h); 41 break; 42 case LD_xWORDe_BC: 43 J.B.l=OpZ80(R); 44 J.B.h=OpZ80(R); 45 WrZ80(J.W++,R->BC.B.l); 46 WrZ80(J.W,R->BC.B.h); 47 break; 48 case LD_xWORDe_SP: 49 J.B.l=OpZ80(R); 50 J.B.h=OpZ80(R); 51 WrZ80(J.W++,R->SP.B.l); 52 WrZ80(J.W,R->SP.B.h); 53 break; 54 55 case LD_HL_xWORDe: 56 J.B.l=OpZ80(R); 57 J.B.h=OpZ80(R); 58 R->HL.B.l=RdZ80(J.W++); 59 R->HL.B.h=RdZ80(J.W); 60 break; 61 case LD_DE_xWORDe: 62 J.B.l=OpZ80(R); 63 J.B.h=OpZ80(R); 64 R->DE.B.l=RdZ80(J.W++); 65 R->DE.B.h=RdZ80(J.W); 66 break; 67 case LD_BC_xWORDe: 68 J.B.l=OpZ80(R); 69 J.B.h=OpZ80(R); 70 R->BC.B.l=RdZ80(J.W++); 71 R->BC.B.h=RdZ80(J.W); 72 break; 73 case LD_SP_xWORDe: 74 J.B.l=OpZ80(R); 75 J.B.h=OpZ80(R); 76 R->SP.B.l=RdZ80(J.W++); 77 R->SP.B.h=RdZ80(J.W); 78 break; 79 80 case RRD: 81 I=RdZ80(R->HL.W); 82 J.B.l=(I>>4)|(R->AF.B.h<<4); 83 WrZ80(R->HL.W,J.B.l); 84 R->AF.B.h=(I&0x0F)|(R->AF.B.h&0xF0); 85 R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG); 86 break; 87 case RLD: 88 I=RdZ80(R->HL.W); 89 J.B.l=(I<<4)|(R->AF.B.h&0x0F); 90 WrZ80(R->HL.W,J.B.l); 91 R->AF.B.h=(I>>4)|(R->AF.B.h&0xF0); 92 R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG); 93 break; 94 95 case LD_A_I: 96 R->AF.B.h=R->I; 97 R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&1? P_FLAG:0)|ZSTable[R->AF.B.h]; 98 break; 99 100 case LD_A_R: 101 R->AF.B.h=(byte)(-R->ICount&0xFF); 102 R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&1? P_FLAG:0)|ZSTable[R->AF.B.h]; 103 break; 104 105 case LD_I_A: R->I=R->AF.B.h;break; 106 case LD_R_A: break; 107 108 case IM_0: R->IFF&=0xF9;break; 109 case IM_1: R->IFF=(R->IFF&0xF9)|2;break; 110 case IM_2: R->IFF=(R->IFF&0xF9)|4;break; 111 112 case RETI: M_RET;break; 113 case RETN: if(R->IFF&0x40) R->IFF|=0x01; else R->IFF&=0xFE; 114 M_RET;break; 115 116 case NEG: I=R->AF.B.h;R->AF.B.h=0;M_SUB(I);break; 117 118 case IN_B_xC: M_IN(R->BC.B.h);break; 119 case IN_C_xC: M_IN(R->BC.B.l);break; 120 case IN_D_xC: M_IN(R->DE.B.h);break; 121 case IN_E_xC: M_IN(R->DE.B.l);break; 122 case IN_H_xC: M_IN(R->HL.B.h);break; 123 case IN_L_xC: M_IN(R->HL.B.l);break; 124 case IN_A_xC: M_IN(R->AF.B.h);break; 125 case IN_F_xC: M_IN(J.B.l);break; 126 127 case OUT_xC_B: OutZ80(R->BC.B.l,R->BC.B.h);break; 128 case OUT_xC_C: OutZ80(R->BC.B.l,R->BC.B.l);break; 129 case OUT_xC_D: OutZ80(R->BC.B.l,R->DE.B.h);break; 130 case OUT_xC_E: OutZ80(R->BC.B.l,R->DE.B.l);break; 131 case OUT_xC_H: OutZ80(R->BC.B.l,R->HL.B.h);break; 132 case OUT_xC_L: OutZ80(R->BC.B.l,R->HL.B.l);break; 133 case OUT_xC_A: OutZ80(R->BC.B.l,R->AF.B.h);break; 134 135 case INI: 136 WrZ80(R->HL.W++,InZ80(R->BC.B.l)); 137 R->BC.B.h--; 138 R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG); 139 break; 140 141 case INIR: 142 do 143 { 144 WrZ80(R->HL.W++,InZ80(R->BC.B.l)); 145 R->BC.B.h--;R->ICount-=21; 146 } 147 while(R->BC.B.h&&(R->ICount>0)); 148 if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2;mz80_cache_ip(R); } 149 else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; } 150 break; 151 152 case IND: 153 WrZ80(R->HL.W--,InZ80(R->BC.B.l)); 154 R->BC.B.h--; 155 R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG); 156 break; 157 158 case INDR: 159 do 160 { 161 WrZ80(R->HL.W--,InZ80(R->BC.B.l)); 162 R->BC.B.h--;R->ICount-=21; 163 } 164 while(R->BC.B.h&&(R->ICount>0)); 165 if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2;mz80_cache_ip(R); } 166 else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; } 167 break; 168 169 case OUTI: 170 OutZ80(R->BC.B.l,RdZ80(R->HL.W++)); 171 R->BC.B.h--; 172 R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG); 173 break; 174 175 case OTIR: 176 do 177 { 178 OutZ80(R->BC.B.l,RdZ80(R->HL.W++)); 179 R->BC.B.h--;R->ICount-=21; 180 } 181 while(R->BC.B.h&&(R->ICount>0)); 182 if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2;mz80_cache_ip(R); } 183 else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; } 184 break; 185 186 case OUTD: 187 OutZ80(R->BC.B.l,RdZ80(R->HL.W--)); 188 R->BC.B.h--; 189 R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG); 190 break; 191 192 case OTDR: 193 do 194 { 195 OutZ80(R->BC.B.l,RdZ80(R->HL.W--)); 196 R->BC.B.h--;R->ICount-=21; 197 } 198 while(R->BC.B.h&&(R->ICount>0)); 199 if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2;mz80_cache_ip(R); } 200 else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; } 201 break; 202 203 case LDI: 204 WrZ80(R->DE.W++,RdZ80(R->HL.W++)); 205 R->BC.W--; 206 R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0); 207 break; 208 209 case LDIR: 210 do 211 { 212 WrZ80(R->DE.W++,RdZ80(R->HL.W++)); 213 R->BC.W--;R->ICount-=21; 214 } 215 while(R->BC.W&&(R->ICount>0)); 216 R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG); 217 if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2;mz80_cache_ip(R); } 218 else R->ICount+=5; 219 break; 220 221 case LDD: 222 WrZ80(R->DE.W--,RdZ80(R->HL.W--)); 223 R->BC.W--; 224 R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0); 225 break; 226 227 case LDDR: 228 do 229 { 230 WrZ80(R->DE.W--,RdZ80(R->HL.W--)); 231 R->BC.W--;R->ICount-=21; 232 } 233 while(R->BC.W&&(R->ICount>0)); 234 R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG); 235 if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2;mz80_cache_ip(R); } 236 else R->ICount+=5; 237 break; 238 239 case CPI: 240 I=RdZ80(R->HL.W++); 241 J.B.l=R->AF.B.h-I; 242 R->BC.W--; 243 R->AF.B.l = 244 N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]| 245 ((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0); 246 break; 247 248 case CPIR: 249 do 250 { 251 I=RdZ80(R->HL.W++); 252 J.B.l=R->AF.B.h-I; 253 R->BC.W--;R->ICount-=21; 254 } 255 while(R->BC.W&&J.B.l&&(R->ICount>0)); 256 R->AF.B.l = 257 N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]| 258 ((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0); 259 if(R->BC.W&&J.B.l) { R->PC.W-=2;mz80_cache_ip(R); } else R->ICount+=5; 260 break; 261 262 case CPD: 263 I=RdZ80(R->HL.W--); 264 J.B.l=R->AF.B.h-I; 265 R->BC.W--; 266 R->AF.B.l = 267 N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]| 268 ((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0); 269 break; 270 271 case CPDR: 272 do 273 { 274 I=RdZ80(R->HL.W--); 275 J.B.l=R->AF.B.h-I; 276 R->BC.W--;R->ICount-=21; 277 } 278 while(R->BC.W&&J.B.l); 279 R->AF.B.l = 280 N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]| 281 ((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0); 282 if(R->BC.W&&J.B.l) { R->PC.W-=2;mz80_cache_ip(R); } else R->ICount+=5; 283 break; 284 285 /* 286 * $Log: mz80opc4.h,v $ 287 * Revision 1.2 1999/11/08 01:33:53 nyef 288 * added preliminary implementation of ranged mmu 289 * 290 * Revision 1.1 1999/01/03 02:27:45 nyef 291 * Initial revision 292 * 293 */ 294