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