[ucsim] Update email and file info, fix stm8 flash controller
[sdcc.git] / sdcc / sim / ucsim / src / sims / z80.src / inst_ed.cc
blob2310ff371b5b6a408e65b93f3126fc1dd6f9f8e1
1 /*
2 * Simulator of microcontrollers (inst_ed.cc)
3 * ED escaped multi-byte opcodes for Z80.
5 * Copyright (C) 1999 Drotos Daniel
7 * To contact author send email to dr.dkdb@gmail.com
9 */
11 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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@*/
29 //#include "ddconfig.h"
31 // local
32 #include "z80cl.h"
33 //#include "regsz80.h"
34 #include "z80mac.h"
37 #define tst_A_bytereg(br) { \
38 ubtmp = regs.raf.A & (br); \
39 regs.raf.F &= ~(BIT_ALL); /* clear these */ \
40 regs.raf.F |= BIT_A; \
41 if (ubtmp == 0) regs.raf.F |= BIT_Z; \
42 if (ubtmp & 0x80) regs.raf.F |= BIT_S; \
43 if (parity(ubtmp)) regs.raf.F |= BIT_P; \
47 int cl_z80::inst_ed_(t_mem code)
49 unsigned short tw;
50 u8_t ubtmp;
52 if (type->type == CPU_Z80N)
54 int ret;
55 if (inst_z80n(code, &ret))
56 return ret;
59 if (code < 0x40)
61 if (!(type->type & (CPU_Z180 | CPU_EZ80)))
62 return resINV_INST;
64 switch ( code & 0x07 )
66 case 0: // IN0
67 ubtmp = fetch1( );
68 reg_g_store( (code >> 3) & 0x07, in_byte( ubtmp ) );
69 return resGO;
71 case 1: // OUT0
72 ubtmp = fetch1( );
73 out_byte( ubtmp, reg_g_read( (code >> 3) & 0x07 ) );
74 return resGO;
76 case 4: // TST
77 tst_A_bytereg(reg_g_read( (code >> 3) & 0x07 ));
78 return resGO;
80 default:
81 return resINV_INST;
85 switch(code)
87 case 0x40: // IN B,(C)
88 regs.bc.h= inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l);
89 regs.raf.F &= ~(BIT_N | BIT_P);
90 if (parity(regs.bc.h)) regs.raf.F |= BIT_P;
91 vc.rd++;
92 //tick(11);
93 return(resGO);
95 case 0x41: // OUT (C),B
96 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, regs.bc.h);
97 vc.wr++;
98 //tick(11);
99 return(resGO);
101 case 0x42: // SBC HL,BC
102 sbc_HL_wordreg(regs.BC);
103 //tick(14);
104 return(resGO);
106 case 0x43: // LD (nnnn),BC
107 tw = fetch2();
108 store2(tw, regs.BC);
109 vc.wr+= 2;
110 //tick(19);
111 return(resGO);
113 case 0x44: // NEG
114 regs.raf.F &= ~(BIT_ALL); /* clear these */
115 if (regs.raf.A != 0) regs.raf.F |= BIT_C;
116 if (regs.raf.A == 0x80) regs.raf.F |= BIT_P;
117 if ((regs.raf.A & 0x0F) != 0) regs.raf.F |= BIT_A;
118 regs.raf.A = 0 - regs.raf.A;
119 regs.raf.F |= BIT_N; /* not addition */
120 if (regs.raf.A == 0) regs.raf.F |= BIT_Z;
121 if (regs.raf.A & 0x80) regs.raf.F |= BIT_S;
122 //tick(7);
123 return(resGO);
125 case 0x45: // RETN (return from non-maskable interrupt)
126 pop2(PC);
127 IFF1= IFF2;
128 IFF2= false;
129 vc.rd+= 2;
130 //tick(13);
131 return(resGO);
133 case 0x46: // IM 0
134 /* interrupt device puts opcode on data bus */
135 imode= 0;
136 //tick(7);
137 return(resGO);
139 case 0x47: // LD IV,A
140 regs.iv = regs.raf.A;
141 //tick(8);
142 return(resGO);
144 case 0x48: // IN C,(C)
145 regs.bc.l= inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l);
146 regs.raf.F &= ~(BIT_N | BIT_P);
147 if (parity(regs.bc.l)) regs.raf.F |= BIT_P;
148 vc.rd++;
149 //tick(11);
150 return(resGO);
152 case 0x49: // OUT (C),C
153 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, regs.bc.l);
154 vc.wr++;
155 //tick(11);
156 return(resGO);
158 case 0x4A: // ADC HL,BC
159 adc_HL_wordreg(regs.BC);
160 //tick(14);
161 return(resGO);
163 case 0x4B: // LD BC,(nnnn)
164 tw = fetch2();
165 regs.BC = get2(tw);
166 vc.rd+= 2;
167 //tick(14);
168 return(resGO);
170 case 0x4C: // MLT BC
171 if (!(type->type & (CPU_Z180 | CPU_EZ80)))
172 return(resINV_INST);
173 regs.BC = (unsigned long)(regs.bc.h) * (unsigned long)(regs.bc.l);
174 return(resGO);
176 case 0x4D: // RETI (return from interrupt)
177 pop2(PC);
178 IFF1= IFF2;
179 IFF2= false;
180 vc.rd+= 2;
181 //tick(13);
182 return(resGO);
184 case 0x4F: // LD R,A
185 regs.R= regs.raf.A;
186 //tick(8);
187 return(resGO);
189 case 0x50: // IN D,(C)
190 regs.de.h= inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l);
191 regs.raf.F &= ~(BIT_N | BIT_P);
192 if (parity(regs.de.h)) regs.raf.F |= BIT_P;
193 vc.rd++;
194 //tick(11);
195 return(resGO);
197 case 0x51: // OUT (C),D
198 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, regs.de.h);
199 vc.wr++;
200 //tick(11);
201 return(resGO);
203 case 0x52: // SBC HL,DE
204 sbc_HL_wordreg(regs.DE);
205 //tick(14);
206 return(resGO);
208 case 0x53: // LD (nnnn),DE
209 tw = fetch2();
210 store2(tw, regs.DE);
211 vc.wr+= 2;
212 //tick(19);
213 return(resGO);
215 case 0x56: // IM 1
216 imode= 1;
217 //tick(7);
218 return(resGO);
220 case 0x57: // LD A,IV
221 regs.raf.A = regs.iv;
222 SET_S(regs.iv);
223 SET_Z(regs.iv);
224 regs.raf.F &= ~(BIT_A | BIT_N | BIT_P);
225 if (IFF2) regs.raf.F |= BIT_P;
226 //tick(8);
227 return(resGO);
229 case 0x58: // IN E,(C)
230 regs.de.l= inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l);
231 regs.raf.F &= ~(BIT_N | BIT_P);
232 if (parity(regs.de.l)) regs.raf.F |= BIT_P;
233 vc.rd++;
234 //tick(11);
235 return(resGO);
237 case 0x59: // OUT (C),E
238 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, regs.de.l);
239 vc.wr++;
240 //tick(11);
241 return(resGO);
243 case 0x5A: // ADC HL,DE
244 adc_HL_wordreg(regs.DE);
245 //tick(14);
246 return(resGO);
248 case 0x5B: // LD DE,(nnnn)
249 tw = fetch2();
250 regs.DE = get2(tw);
251 vc.rd+= 2;
252 //tick(19);
253 return(resGO);
255 case 0x5C: // MLT DE
256 if (!(type->type & (CPU_Z180 | CPU_EZ80)))
257 return(resINV_INST);
258 regs.DE = (unsigned long)(regs.de.h) * (unsigned long)(regs.de.l);
259 return(resGO);
261 case 0x5E: // IM 2
262 imode= 2;
263 //tick(7);
264 return(resGO);
266 case 0x5F: // LD A,R
267 regs.raf.A= regs.R;
268 SET_S(regs.R);
269 SET_Z(regs.R);
270 regs.raf.F &= ~(BIT_A | BIT_N | BIT_P);
271 if (IFF2) regs.raf.F |= BIT_P;
272 //tick(7);
273 return(resGO);
275 case 0x60: // IN H,(C)
276 regs.hl.h= inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l);
277 regs.raf.F &= ~(BIT_N | BIT_P);
278 if (parity(regs.hl.h)) regs.raf.F |= BIT_P;
279 vc.rd++;
280 //tick(11);
281 return(resGO);
283 case 0x61: // OUT (C),H
284 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, regs.hl.h);
285 vc.wr++;
286 //tick(11);
287 return(resGO);
289 case 0x62: // SBC HL,HL
290 sbc_HL_wordreg(regs.HL);
291 //tick(14);
292 return(resGO);
294 case 0x63: // LD (nnnn),HL opcode 22 does the same faster
295 tw = fetch2();
296 store2(tw, regs.HL);
297 vc.wr+= 2;
298 //tick(19);
299 return(resGO);
301 case 0x64:
302 if (!(type->type & (CPU_Z180 | CPU_EZ80)))
303 return(resINV_INST);
304 ubtmp = fetch(); // TST A,n
305 tst_A_bytereg(ubtmp);
306 return(resGO);
308 case 0x67: // RRD
309 ubtmp = get1(regs.HL);
310 store1(regs.HL, (ubtmp >> 4) | (regs.raf.A << 4));
311 regs.raf.A = (regs.raf.A & 0xf0) | (ubtmp & 0x0f);
312 //tick(17);
313 return(resGO);
315 case 0x68: // IN L,(C)
316 regs.hl.l= inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l);
317 regs.raf.F &= ~(BIT_N | BIT_P);
318 if (parity(regs.hl.l)) regs.raf.F |= BIT_P;
319 vc.rd++;
320 //tick(11);
321 return(resGO);
323 case 0x69: // OUT (C),L
324 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, regs.hl.l);
325 vc.wr++;
326 //tick(11);
327 return(resGO);
329 case 0x6A: // ADC HL,HL
330 adc_HL_wordreg(regs.HL);
331 //tick(14);
332 return(resGO);
334 case 0x6B: // LD HL,(nnnn) opcode 2A does the same faster
335 tw = fetch2();
336 regs.HL = get2(tw);
337 vc.rd+= 2;
338 //tick(19);
339 return(resGO);
341 case 0x6C: // MLT HL
342 if (!(type->type & (CPU_Z180 | CPU_EZ80)))
343 return(resINV_INST);
344 regs.HL = (unsigned long)(regs.hl.h) * (unsigned long)(regs.hl.l);
345 return(resGO);
347 case 0x6F: // RLD
348 ubtmp = get1(regs.HL);
349 store1(regs.HL, (ubtmp << 4) | (regs.raf.A & 0x0f));
350 regs.raf.A = (regs.raf.A & 0xf0) | (ubtmp >> 4);
351 //tick(17);
352 return(resGO);
354 case 0x70: // IN (C) set flags only (TSTI)
356 u8_t x= inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l);
357 regs.raf.F &= ~(BIT_N | BIT_P);
358 if (parity(x)) regs.raf.F |= BIT_P;
359 vc.rd++;
360 //tick(11);
361 return(resGO);
364 case 0x71: // OUT (C),0
365 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, 0);
366 vc.wr++;
367 //tick(11);
368 return(resGO);
370 case 0x72: // SBC HL,SP
371 sbc_HL_wordreg(regs.SP);
372 //tick(14);
373 return(resGO);
375 case 0x73: // LD (nnnn),SP
376 tw = fetch2();
377 store2(tw, regs.SP);
378 vc.wr+= 2;
379 //tick(19);
380 return(resGO);
382 case 0x78: // IN A,(C)
383 regs.raf.A= inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l);
384 regs.raf.F &= ~(BIT_N | BIT_P);
385 if (parity(regs.raf.A)) regs.raf.F |= BIT_P;
386 vc.rd++;
387 //tick(11);
388 return(resGO);
390 case 0x79: // OUT (C),A
391 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, regs.raf.A);
392 vc.wr++;
393 //tick(11);
394 return(resGO);
396 case 0x7A: // ADC HL,SP
397 adc_HL_wordreg(regs.SP);
398 //tick(14);
399 return(resGO);
401 case 0x7B: // LD SP,(nnnn)
402 tw = fetch2();
403 regs.SP = get2(tw);
404 vc.rd+= 2;
405 //tick(19);
406 return(resGO);
408 case 0x7C: // MLT SP
409 //if(type != CPU_Z180)
410 return(resINV_INST);
411 //regs.SP = (unsigned long)(regs.sp.h) * (unsigned long)(regs.sp.l);
412 return(resGO);
414 case 0xA0: // LDI
415 // BC - count, source=HL, dest=DE. *DE++ = *HL++, --BC until zero
416 regs.raf.F &= ~(BIT_P | BIT_N | BIT_A); /* clear these */
417 store1(regs.DE, get1(regs.HL));
418 ++regs.HL;
419 ++regs.DE;
420 --regs.BC;
421 if (regs.BC != 0) regs.raf.F |= BIT_P;
422 //tick(15);
423 return(resGO);
425 case 0xA1: // CPI
426 // compare acc with mem(HL), if ACC=0 set Z flag. Incr HL, decr BC.
428 unsigned char tmp;
429 tmp = get1(regs.HL);
430 cp_bytereg(tmp);
431 ++regs.HL;
432 --regs.BC;
433 if (regs.BC != 0) regs.raf.F |= BIT_P;
434 //tick(15);
436 return(resGO);
438 case 0xA2: // INI
439 this->store1(regs.HL, inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l));
440 vc.rd++;
441 vc.wr++;
442 if (type->type==CPU_Z80N)
443 regs.raf.F |= BIT_N;
444 else
445 regs.raf.F &= ~(BIT_N);
446 regs.HL++;
447 regs.bc.h--;
448 SET_Z(regs.bc.h);
449 //tick(16);
450 return(resGO);
452 case 0xA3: // OUTI
453 regs.bc.h--;
454 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.h, this->get1(regs.HL));
455 vc.wr++;
456 vc.rd++;
457 SET_Z(regs.bc.h);
458 if (type->type==CPU_Z80N)
459 regs.raf.F |= BIT_N;
460 else
461 regs.raf.F &= ~(BIT_N);
462 regs.HL++;
463 //tick(16);
464 return(resGO);
466 case 0xA8: // LDD
467 // BC - count, source=HL, dest=DE. *DE-- = *HL--, --BC until zero
468 regs.raf.F &= ~(BIT_P | BIT_N | BIT_A); /* clear these */
469 store1(regs.DE, get1(regs.HL));
470 --regs.HL;
471 --regs.DE;
472 --regs.BC;
473 if (regs.BC != 0) regs.raf.F |= BIT_P;
474 vc.rd++;
475 vc.wr++;
476 //tick(15);
477 return(resGO);
479 case 0xA9: // CPD
480 /* fixme: checkme, compare to other emul. */
482 regs.raf.F &= ~(BIT_ALL); /* clear these */
483 if ((regs.raf.A - get1(regs.HL)) == 0) {
484 regs.raf.F |= (BIT_Z | BIT_P);
486 ++regs.HL;
487 --regs.BC;
488 if (regs.BC != 0) regs.raf.F |= BIT_P;
489 vc.rd++;
490 //tick(15);
491 return(resGO);
493 case 0xAA: // IND
494 this->store1(regs.HL, inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l));
495 vc.rd++;
496 vc.wr++;
497 if (type->type==CPU_Z80N)
498 regs.raf.F |= BIT_N;
499 else
500 regs.raf.F &= ~(BIT_N);
501 regs.HL--;
502 regs.bc.h--;
503 SET_Z(regs.bc.h);
504 //tick(15);
505 return(resGO);
506 case 0xAB: // OUTD
507 regs.bc.h--;
508 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, this->get1(regs.HL));
509 vc.rd++;
510 vc.wr++;
511 if (type->type==CPU_Z80N)
512 regs.raf.F |= BIT_N;
513 else
514 regs.raf.F &= ~(BIT_N);
515 regs.HL--;
516 SET_Z(regs.bc.h);
517 //tick(15);
518 return(resGO);
520 case 0xB0: // LDIR
521 // BC - count, source=HL, dest=DE. *DE++ = *HL++, --BC until zero
522 regs.raf.F &= ~(BIT_P | BIT_N | BIT_A); /* clear these */
523 //do {
524 store1(regs.DE, get1(regs.HL));
525 ++regs.HL;
526 ++regs.DE;
527 --regs.BC;
528 vc.rd++;
529 vc.wr++;
530 //tick(15);
531 //if (regs.BC) //tick(5);
532 //} while (regs.BC != 0);
533 if (regs.BC)
535 repeating= true;
536 cond_true= true;
537 PC= instPC;
538 regs.raf.F|= BIT_P;
540 return(resGO);
542 case 0xB1: // CPIR
543 // compare acc with mem(HL), if ACC=0 set Z flag. Incr HL, decr BC.
544 regs.raf.F &= ~(BIT_P | BIT_A | BIT_Z | BIT_S); /* clear these */
545 regs.raf.F |= BIT_N;
546 //do {
547 if((regs.raf.A - get1(regs.HL)) == 0)
548 regs.raf.F |= BIT_Z;
549 else
550 regs.raf.F &= ~(BIT_Z);
551 if((regs.raf.A - get1(regs.HL)) & 0x80)
552 regs.raf.F |= BIT_S;
553 else
554 regs.raf.F &= ~(BIT_S);
555 /* fixme: set BIT_A correctly. */
556 ++regs.HL;
557 --regs.BC;
558 vc.rd++;
559 //tick(15);
560 //if (regs.BC) //tick(5);
561 //} while (regs.BC != 0 && (regs.raf.F & BIT_Z) == 0);
562 if(regs.BC)
564 regs.raf.F |= BIT_P;
565 if (!(regs.raf.F & BIT_Z))
567 cond_true= true;
568 repeating= true;
569 PC= instPC;
572 return(resGO);
574 case 0xB2: // INIR
575 //do {
576 this->store1(regs.HL, inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l));
577 vc.rd++;
578 vc.wr++;
579 if (type->type==CPU_Z80N)
580 regs.raf.F |= BIT_N;
581 else
582 regs.raf.F &= ~(BIT_N);
583 regs.HL++;
584 regs.bc.h--;
585 SET_Z(regs.bc.h);
586 //tick(15);
587 //if (regs.BC) //tick(5);
588 if (regs.bc.h)
590 repeating= true;
591 cond_true= true;
592 PC= instPC;
594 //} while (regs.BC);
595 return(resGO);
597 case 0xB3: // OTIR
598 //do {
599 regs.bc.h--;
600 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.h, this->get1(regs.HL));
601 vc.wr++;
602 vc.rd++;
603 SET_Z(regs.bc.h);
604 if (type->type==CPU_Z80N)
605 regs.raf.F |= BIT_N;
606 else
607 regs.raf.F &= ~(BIT_N);
608 regs.HL++;
609 //tick(15);
610 //if (regs.BC) //tick(5);
611 if (regs.bc.h)
613 repeating= true;
614 cond_true= true;
615 PC= instPC;
617 //} while (regs.BC);
618 return(resGO);
620 case 0xB8: // LDDR
621 // BC - count, source=HL, dest=DE. *DE-- = *HL--, --BC until zero
622 regs.raf.F &= ~(BIT_P | BIT_N | BIT_A); /* clear these */
623 //do {
624 store1(regs.DE, get1(regs.HL));
625 --regs.HL;
626 --regs.DE;
627 --regs.BC;
628 vc.rd++;
629 vc.wr++;
630 //tick(15);
631 //if (regs.BC) //tick(5);
632 //} while (regs.BC != 0);
633 if (regs.BC)
635 repeating= true;
636 cond_true= true;
637 PC= instPC;
639 return(resGO);
640 case 0xB9: // CPDR
642 bool gotit= false;
643 // compare acc with mem(HL), if ACC=0 set Z flag. Incr HL, decr BC.
644 regs.raf.F &= ~(BIT_ALL); /* clear these */
645 //do {
646 if ((regs.raf.A - get1(regs.HL)) == 0) {
647 regs.raf.F |= (BIT_Z | BIT_P);
648 gotit= true;
650 else
652 --regs.HL;
653 --regs.BC;
654 vc.rd++;
656 //tick(15);
657 //if (regs.BC) //tick(5);
658 //} while (regs.BC != 0);
659 if (regs.BC)
661 if (!gotit)
663 repeating= true;
664 cond_true= true;
665 PC= instPC;
668 return(resGO);
670 case 0xBA: // INDR
671 //do {
672 this->store1(regs.HL, inputs->read((type->type==CPU_Z80N)?regs.BC:regs.bc.l));
673 vc.rd++;
674 vc.wr++;
675 if (type->type==CPU_Z80N)
676 regs.raf.F |= BIT_N;
677 else
678 regs.raf.F &= ~(BIT_N);
679 regs.HL--;
680 regs.bc.h--;
681 SET_Z(regs.bc.h);
682 //tick(15);
683 //if (regs.BC) //tick(5);
684 //} while (regs.BC);
685 if (regs.bc.h)
687 repeating= true;
688 cond_true= true;
689 PC= instPC;
691 return(resGO);
693 case 0xBB: // OTDR
694 //do {
695 regs.bc.h--;
696 outputs->write((type->type==CPU_Z80N)?regs.BC:regs.bc.l, this->get1(regs.HL));
697 vc.rd++;
698 vc.wr++;
699 if (type->type==CPU_Z80N)
700 regs.raf.F |= BIT_N;
701 else
702 regs.raf.F &= ~(BIT_N);
703 regs.HL--;
704 SET_Z(regs.bc.h);
705 //tick(15);
706 //if (regs.BC) //tick(5);
707 //} while (regs.BC);
708 if (regs.bc.h)
710 repeating= true;
711 cond_true= true;
712 PC= instPC;
714 return(resGO);
716 case 0xc1:
717 case 0xc9:
718 case 0xd1:
719 case 0xd9:
720 return(resINV_INST);
722 case 0xc3:
723 return(resINV_INST);
724 case 0xf3:
725 return(resINV_INST);
727 default:
728 return(resINV_INST);
731 return(resGO);
734 /******** start ED codes *****************/
735 int cl_z80::inst_ed(t_mem prefix)
737 t_mem code;
739 if (fetch(&code))
740 return(resBREAKPOINT);
742 return inst_ed_(code);
745 /* End of z80.src/inst_ed.cc */