2 * Simulator of microcontrollers (inst_xd.cc)
3 * dd or fd escaped multi-byte opcodes.
5 * This module gets pulled in and pre-processed to create
6 * two modules. DD prefixed opcodes reference
7 * IX register, while FD prefixes reference IY register.
8 * See inst_ddcb.cc and inst_fdcb.cc
10 * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
11 * some z80 coding from Karl Bongers karl@turbobit.com
13 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
17 /* This file is part of microcontroller simulator: ucsim.
19 UCSIM is free software; you can redistribute it and/or modify
20 it under the terms of the GNU General Public License as published by
21 the Free Software Foundation; either version 2 of the License, or
22 (at your option) any later version.
24 UCSIM is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License for more details.
29 You should have received a copy of the GNU General Public License
30 along with UCSIM; see the file COPYING. If not, write to the Free
31 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
36 cl_z80::inst_Xd_ld(t_mem code)
41 case 0x21: // LD IX,nnnn
42 regs_IX_OR_IY = fetch2();
44 case 0x22: // LD (nnnn),IX
46 store2(tw, regs_IX_OR_IY);
48 case 0x26: // LD HX,nn
51 case 0x2A: // LD IX,(nnnn)
53 regs_IX_OR_IY = get2(tw);
55 case 0x2E: // LD LX,nn
58 case 0x36: // LD (IX+dd),nn
59 tw = add_u16_disp(regs_IX_OR_IY, fetch());
63 regs.bc.h = regs_iX_h;
66 regs.bc.h = regs_iX_l;
68 case 0x46: // LD B,(IX+dd)
69 regs.bc.h = get1(add_u16_disp(regs_IX_OR_IY,fetch()));
72 regs.bc.l = regs_iX_h;
75 regs.bc.l = regs_iX_l;
77 case 0x4E: // LD C,(IX+dd)
78 regs.bc.l = get1(add_u16_disp(regs_IX_OR_IY,fetch()));
81 regs.de.h = regs_iX_h;
84 regs.de.h = regs_iX_l;
86 case 0x56: // LD D,(IX+dd)
87 regs.de.h = get1(add_u16_disp(regs_IX_OR_IY,fetch()));
90 regs.de.l = regs.hl.h;
93 regs.de.l = regs.hl.l;
95 case 0x5E: // LD E,(IX+dd)
96 regs.de.l = get1(add_u16_disp(regs_IX_OR_IY,fetch()));
99 regs_iX_h = regs.bc.h;
101 case 0x61: // LD HX,C
102 regs_iX_h = regs.bc.l;
104 case 0x62: // LD HX,D
105 regs_iX_h = regs.de.h;
107 case 0x63: // LD HX,E
108 regs_iX_h = regs.de.l;
110 case 0x64: // LD HX,HX
112 case 0x65: // LD HX,LX
113 regs_iX_h = regs_iX_l;
115 case 0x66: // LD H,(IX+dd)
116 regs.hl.h = get1(add_u16_disp(regs_IX_OR_IY,fetch()));
118 case 0x67: // LD HX,A
121 case 0x68: // LD LX,B
122 regs_iX_l = regs.bc.h;
124 case 0x69: // LD LX,C
125 regs_iX_l = regs.bc.l;
127 case 0x6A: // LD LX,D
128 regs_iX_l = regs.de.h;
130 case 0x6B: // LD LX,E
131 regs_iX_l = regs.de.l;
133 case 0x6C: // LD LX,HX
134 regs_iX_l = regs.hl.h;
136 case 0x6D: // LD LX,LX
138 case 0x6E: // LD L,(IX+dd)
139 regs.hl.l = get1(add_u16_disp(regs_IX_OR_IY,fetch()));
141 case 0x6F: // LD LX,A
144 case 0x70: // LD (IX+dd),B
145 store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.bc.h);
147 case 0x71: // LD (IX+dd),C
148 store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.bc.l);
150 case 0x72: // LD (IX+dd),D
151 store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.de.h);
153 case 0x73: // LD (IX+dd),E
154 store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.de.l);
156 case 0x74: // LD (IX+dd),H
157 store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.hl.h);
159 case 0x75: // LD (IX+dd),L
160 store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.hl.l);
162 case 0x77: // LD (IX+dd),A
163 store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.A);
165 case 0x7C: // LD A,HX
168 case 0x7D: // LD A,LX
171 case 0x7E: // LD A,(IX+dd)
172 regs.A = get1(add_u16_disp(regs_IX_OR_IY,fetch()));
174 case 0xF9: // LD SP,IX
175 regs.SP = regs_IX_OR_IY;
182 cl_z80::inst_Xd_add(t_mem code)
184 #define add_IX_Word(wr) { \
186 regs.F &= ~(BIT_A | BIT_N | BIT_C); /* clear these */ \
187 tmp = (unsigned int)regs_IX_OR_IY + (unsigned int)(wr); \
188 if (tmp > 0xffff) regs.F |= BIT_C; \
189 regs_IX_OR_IY = (unsigned short) tmp; }
192 case 0x09: // ADD IX,BC
193 add_IX_Word(regs.BC);
195 case 0x19: // ADD IX,DE
196 add_IX_Word(regs.DE);
198 case 0x29: // ADD IX,IX
199 add_IX_Word(regs_IX_OR_IY);
201 case 0x39: // ADD IX,SP
202 add_IX_Word(regs.SP);
204 case 0x84: // ADD A,HX
205 add_A_bytereg(regs_iX_h);
207 case 0x85: // ADD A,LX
208 add_A_bytereg(regs_iX_l);
210 case 0x86: // ADD A,(IX+dd)
211 { unsigned char ourtmp;
213 addr = add_u16_disp(regs_IX_OR_IY, fetch());
215 add_A_bytereg(ourtmp);
223 cl_z80::inst_Xd_push(t_mem code)
226 case 0xe5: // PUSH IX
227 push2(regs_IX_OR_IY);
234 cl_z80::inst_Xd_inc(t_mem code)
246 case 0x34: // INC (IX+dd)
250 addr = add_u16_disp(regs_IX_OR_IY,fetch());
264 cl_z80::inst_Xd_dec(t_mem code)
276 case 0x35: // DEC (IX+dd)
280 addr = add_u16_disp(regs_IX_OR_IY,fetch());
294 /* need ADC, SUB, SBC, AND, XOR, OR, CP */
296 cl_z80::inst_Xd_misc(t_mem code)
299 case 0x8C: // ADC A,HX
300 adc_A_bytereg(regs_iX_h);
302 case 0x8D: // ADC A,LX
303 adc_A_bytereg(regs_iX_l);
305 case 0x8E: // ADC A,(IX+dd)
306 { unsigned char utmp;
308 addr = add_u16_disp(regs_IX_OR_IY, fetch());
315 sub_A_bytereg(regs_iX_h);
318 sub_A_bytereg(regs_iX_l);
320 case 0x96: // SUB (IX+dd)
321 { unsigned char tmp1;
322 tmp1 = get1(add_u16_disp(regs_IX_OR_IY, fetch()));
327 case 0x9C: // SBC A,HX
328 sbc_A_bytereg(regs_iX_h);
330 case 0x9D: // SBC A,LX
331 sbc_A_bytereg(regs_iX_l);
333 case 0x9E: // SBC A,(IX+dd)
334 { unsigned char utmp;
335 utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch()));
341 and_A_bytereg(regs_iX_h);
344 and_A_bytereg(regs_iX_l);
346 case 0xA6: // AND (IX+dd)
347 { unsigned char utmp;
348 utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch()));
354 xor_A_bytereg(regs_iX_h);
357 xor_A_bytereg(regs_iX_l);
359 case 0xAE: // XOR (IX+dd)
360 { unsigned char utmp;
361 utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch()));
367 or_A_bytereg(regs_iX_h);
370 or_A_bytereg(regs_iX_l);
372 case 0xB6: // OR (IX+dd)
373 { unsigned char utmp;
374 utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch()));
380 cp_bytereg(regs_iX_h);
383 cp_bytereg(regs_iX_l);
385 case 0xBE: // CP (IX+dd)
386 { unsigned char utmp;
387 utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch()));
396 cl_z80::inst_Xd(void)
401 return(resBREAKPOINT);
405 case 0x21: // LD IX,nnnn
406 case 0x22: // LD (nnnn),IX
407 case 0x26: // LD HX,nn
408 case 0x2A: // LD IX,(nnnn)
409 case 0x2E: // LD LX,nn
410 case 0x36: // LD (IX+dd),nn
411 case 0x44: // LD B,HX
412 case 0x45: // LD B,LX
413 case 0x46: // LD B,(IX+dd)
414 case 0x4C: // LD C,HX
415 case 0x4D: // LD C,LX
416 case 0x4E: // LD C,(IX+dd)
417 case 0x54: // LD D,HX
418 case 0x55: // LD D,LX
419 case 0x56: // LD D,(IX+dd)
422 case 0x5E: // LD E,(IX+dd)
423 case 0x60: // LD HX,B
424 case 0x61: // LD HX,C
425 case 0x62: // LD HX,D
426 case 0x63: // LD HX,E
427 case 0x64: // LD HX,HX
428 case 0x66: // LD H,(IX+dd)
429 case 0x67: // LD HX,A
430 case 0x68: // LD LX,B
431 case 0x69: // LD LX,C
432 case 0x6A: // LD LX,D
433 case 0x6B: // LD LX,E
434 case 0x6C: // LD LX,HX
435 case 0x6D: // LD LX,LX
436 case 0x6E: // LD L,(IX+dd)
437 case 0x6F: // LD LX,A
438 case 0x70: // LD (IX+dd),B
439 case 0x71: // LD (IX+dd),C
440 case 0x72: // LD (IX+dd),D
441 case 0x73: // LD (IX+dd),E
442 case 0x74: // LD (IX+dd),H
443 case 0x75: // LD (IX+dd),L
444 case 0x77: // LD (IX+dd),A
445 case 0x7C: // LD A,HX
446 case 0x7D: // LD A,LX
447 case 0x7E: // LD A,(IX+dd)
448 case 0xF9: // LD SP,IX
449 return(inst_Xd_ld(code));
454 case 0x34: // INC (IX+dd)
455 return(inst_Xd_inc(code));
458 addr = add_u16_disp(regs_IX_OR_IY,fetch());
459 store1(addr, get1(addr)+1);
462 case 0x09: // ADD IX,BC
463 case 0x19: // ADD IX,DE
464 case 0x29: // ADD IX,IX
465 case 0x39: // ADD IX,SP
466 case 0x84: // ADD A,HX
467 case 0x85: // ADD A,LX
468 case 0x86: // ADD A,(IX)
469 return(inst_Xd_add(code));
474 case 0x35: // DEC (IX+dd)
475 return(inst_Xd_dec(code));
477 case 0x8C: // ADC A,HX
478 case 0x8D: // ADC A,LX
479 case 0x8E: // ADC A,(IX)
482 case 0x96: // SUB (IX+dd)
483 case 0x9C: // SBC A,HX
484 case 0x9D: // SBC A,LX
485 case 0x9E: // SBC A,(IX+dd)
488 case 0xA6: // AND (IX+dd)
491 case 0xAE: // XOR (IX+dd)
494 case 0xB6: // OR (IX+dd)
497 case 0xBE: // CP (IX+dd)
498 return(inst_Xd_misc(code));
501 case 0xCB: // escape, IX prefix to CB commands
502 return(inst_Xdcb()); /* see inst_ddcb.cc */
506 regs_IX_OR_IY = get2(regs.SP);
510 case 0xE3: // EX (SP),IX
514 tempw = regs_IX_OR_IY;
515 regs_IX_OR_IY = get2(regs.SP);
516 store2(regs.SP, tempw);
520 case 0xE5: // PUSH IX
521 push2(regs_IX_OR_IY);
524 case 0xE9: // JP (IX)
534 /* End of z80.src/inst_xd.cc */