Imported Upstream version 2.9.0
[debian/cc1111] / sim / ucsim / z80.src / inst_ed.cc
1 /*
2  * Simulator of microcontrollers (inst_ed.cc)
3  *   ED escaped multi-byte opcodes for Z80.
4  *
5  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6  * 
7  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
8  *
9  */
10
11 /* This file is part of microcontroller simulator: ucsim.
12
13 UCSIM is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 UCSIM is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with UCSIM; see the file COPYING.  If not, write to the Free
25 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 02111-1307, USA. */
27 /*@1@*/
28
29 #include "ddconfig.h"
30
31 // local
32 #include "z80cl.h"
33 #include "regsz80.h"
34 #include "z80mac.h"
35
36
37 int
38 cl_z80::inst_ed_(t_mem code)
39 {
40   switch(code) {
41   }
42   return(resGO);
43 }
44
45 /******** start CB codes *****************/
46 int
47 cl_z80::inst_ed(void)
48 {
49   t_mem code;
50   unsigned short tw;
51
52   if (fetch(&code))
53     return(resBREAKPOINT);
54
55   switch (code)
56   {
57 #if 0
58     case 0x40: // IN B,(C)
59     return(resGO);
60     case 0x41: // OUT (C),B
61     return(resGO);
62 #endif
63     case 0x42: // SBC HL,BC
64       sbc_HL_wordreg(regs.BC);
65     return(resGO);
66     case 0x43: // LD (nnnn),BC
67       tw = fetch2();
68       store2(tw, regs.BC);
69     return(resGO);
70     case 0x44: // NEG
71       regs.F &= ~(BIT_ALL);  /* clear these */
72       regs.A -= regs.A;
73       regs.F |= BIT_N; /* not addition */
74       if (regs.A == 0) regs.F |= BIT_Z;
75       if (regs.A & 0x80) regs.F |= BIT_S;
76       /* Skip BIT_A for now */
77     return(resGO);
78     case 0x45: // RETN (return from non-maskable interrupt)
79       pop2(PC);
80     return(resGO);
81 #if 0
82     case 0x46: // IM 0
83       /* interrupt device puts opcode on data bus */
84     return(resGO);
85 #endif
86     case 0x47: // LD IV,A
87       regs.iv = regs.A;
88     return(resGO);
89
90     case 0x48: // IN C,(C)
91     return(resGO);
92     case 0x49: // OUT (C),C
93     return(resGO);
94
95     case 0x4A: // ADC HL,BC
96       adc_HL_wordreg(regs.BC);
97     return(resGO);
98     case 0x4B: // LD BC,(nnnn)
99       tw = fetch2();
100       regs.BC = get2(tw);
101     return(resGO);
102     case 0x4D: // RETI (return from interrupt)
103       pop2(PC);
104     return(resGO);
105     case 0x4F: // LD R,A
106       /* Load "refresh" register(whats that?) */
107     return(resGO);
108
109     case 0x50: // IN D,(C)
110     return(resGO);
111     case 0x51: // OUT (C),D
112     return(resGO);
113
114     case 0x52: // SBC HL,DE
115       sbc_HL_wordreg(regs.DE);
116     return(resGO);
117     case 0x53: // LD (nnnn),DE
118       tw = fetch2();
119       store2(tw, regs.DE);
120     return(resGO);
121 #if 0
122     case 0x56: // IM 1
123     return(resGO);
124 #endif
125     case 0x57: // LD A,IV
126       regs.A = regs.iv;
127     return(resGO);
128
129     case 0x58: // IN E,(C)
130     return(resGO);
131     case 0x59: // OUT (C),E
132     return(resGO);
133
134     case 0x5A: // ADC HL,DE
135       adc_HL_wordreg(regs.DE);
136     return(resGO);
137     case 0x5B: // LD DE,(nnnn)
138       tw = fetch2();
139       regs.DE = get2(tw);
140     return(resGO);
141
142 #if 0
143     case 0x5E: // IM 2
144     return(resGO);
145     case 0x5F: // LD A,R
146     return(resGO);
147     case 0x60: // IN H,(C)
148     return(resGO);
149     case 0x61: // OUT (C),H
150     return(resGO);
151 #endif
152     case 0x62: // SBC HL,HL
153       sbc_HL_wordreg(regs.HL);
154     return(resGO);
155     case 0x63: // LD (nnnn),HL opcode 22 does the same faster
156       tw = fetch2();
157       store2(tw, regs.HL);
158     return(resGO);
159
160 #if 0
161     case 0x67: // RRD
162     return(resGO);
163 #endif
164     case 0x68: // IN L,(C)
165     return(resGO);
166     case 0x69: // OUT (C),L
167     return(resGO);
168
169     case 0x6A: // ADC HL,HL
170       adc_HL_wordreg(regs.HL);
171     return(resGO);
172     case 0x6B: // LD HL,(nnnn) opcode 2A does the same faster
173       tw = fetch2();
174       regs.HL = get2(tw);
175     return(resGO);
176
177 #if 0
178     case 0x6F: // RLD
179       /* rotate 1 bcd digit left between ACC and memory location */
180     return(resGO);
181 #endif
182
183     case 0x70: // IN (C)  set flags only (TSTI)
184     return(resGO);
185     case 0x71: //  OUT (C),0
186     return(resGO);
187
188     case 0x72: // SBC HL,SP
189       sbc_HL_wordreg(regs.SP);
190     return(resGO);
191     case 0x73: // LD (nnnn),SP
192       tw = fetch2();
193       store2(tw, regs.SP);
194     return(resGO);
195
196     case 0x78: // IN A,(C)
197     return(resGO);
198     case 0x79: // OUT (C),A
199     return(resGO);
200
201     case 0x7A: // ADC HL,SP
202       adc_HL_wordreg(regs.SP);
203     return(resGO);
204     case 0x7B: // LD SP,(nnnn)
205       tw = fetch2();
206       regs.SP = get2(tw);
207     return(resGO);
208
209     case 0xA0: // LDI
210       // BC - count, sourc=HL, dest=DE.  *DE++ = *HL++, --BC until zero
211       regs.F &= ~(BIT_P | BIT_N | BIT_A);  /* clear these */
212       store1(regs.DE, get1(regs.HL));
213       ++regs.HL;
214       ++regs.DE;
215       --regs.BC;
216       if (regs.BC != 0) regs.F |= BIT_P;
217     return(resGO);
218     case 0xA1: // CPI
219       // compare acc with mem(HL), if ACC=0 set Z flag.  Incr HL, decr BC.
220       {
221         unsigned char tmp;
222         tmp = get1(regs.HL);
223         cp_bytereg(tmp);
224         ++regs.HL;
225         --regs.BC;
226         if (regs.BC != 0) regs.F |= BIT_P;
227       }
228     return(resGO);
229
230     case 0xA2: // INI
231     return(resGO);
232     case 0xA3: // OUTI
233     return(resGO);
234
235     case 0xA8: // LDD
236       // BC - count, source=HL, dest=DE.  *DE-- = *HL--, --BC until zero
237       regs.F &= ~(BIT_P | BIT_N | BIT_A);  /* clear these */
238       store1(regs.DE, get1(regs.HL));
239       --regs.HL;
240       --regs.DE;
241       --regs.BC;
242       if (regs.BC != 0) regs.F |= BIT_P;
243     return(resGO);
244     case 0xA9: // CPD
245 /* fixme: checkme, compare to other emul. */
246
247       regs.F &= ~(BIT_ALL);  /* clear these */
248       if ((regs.A - get1(regs.HL)) == 0) {
249         regs.F |= (BIT_Z | BIT_P);
250       }
251       ++regs.HL;
252       --regs.BC;
253       if (regs.BC != 0) regs.F |= BIT_P;
254
255     return(resGO);
256
257     case 0xAA: // IND
258     return(resGO);
259     case 0xAB: // OUTD
260     return(resGO);
261
262     case 0xB0: // LDIR
263       // BC - count, sourc=HL, dest=DE.  *DE++ = *HL++, --BC until zero
264       regs.F &= ~(BIT_P | BIT_N | BIT_A);  /* clear these */
265       do {
266         store1(regs.DE, get1(regs.HL));
267         ++regs.HL;
268         ++regs.DE;
269         --regs.BC;
270       } while (regs.BC != 0);
271     return(resGO);
272
273     case 0xB1: // CPIR
274       // compare acc with mem(HL), if ACC=0 set Z flag.  Incr HL, decr BC.
275       regs.F &= ~(BIT_P | BIT_A | BIT_Z | BIT_S);  /* clear these */
276       regs.F |= BIT_N;
277       do {
278         if((regs.A - get1(regs.HL)) == 0)
279           regs.F |= BIT_Z;
280         else
281           regs.F &= ~BIT_Z;
282         if((regs.A - get1(regs.HL)) & 0x80)
283           regs.F |= BIT_S;
284         else
285           regs.F &= ~BIT_S;
286 /* fixme: set BIT_A correctly. */
287         ++regs.HL;
288         --regs.BC;
289       } while (regs.BC != 0 && (regs.F & BIT_Z) == 0);
290       if(regs.BC != 0)
291         regs.F |= BIT_P;
292
293     return(resGO);
294 #if 0
295     case 0xB2: // INIR
296     return(resGO);
297     case 0xB3: // OTIR
298     return(resGO);
299 #endif
300     case 0xB8: // LDDR
301       // BC - count, source=HL, dest=DE.  *DE-- = *HL--, --BC until zero
302       regs.F &= ~(BIT_P | BIT_N | BIT_A);  /* clear these */
303       do {
304         store1(regs.DE, get1(regs.HL));
305         --regs.HL;
306         --regs.DE;
307         --regs.BC;
308       } while (regs.BC != 0);
309     return(resGO);
310     case 0xB9: // CPDR
311       // compare acc with mem(HL), if ACC=0 set Z flag.  Incr HL, decr BC.
312       regs.F &= ~(BIT_ALL);  /* clear these */
313       do {
314         if ((regs.A - get1(regs.HL)) == 0) {
315           regs.F |= (BIT_Z | BIT_P);
316           break;
317         }
318         --regs.HL;
319         --regs.BC;
320       } while (regs.BC != 0);
321     return(resGO);
322 #if 0
323     case 0xBA: // INDR
324     return(resGO);
325     case 0xBB: // OTDR
326     return(resGO);
327 #endif
328
329     default:
330     return(resINV_INST);
331   }
332
333   return(resINV_INST);
334 }
335
336 /* End of z80.src/inst_ed.cc */