d696d30275c3f4c794b47a78a5a7341a6aa0cbba
[fw/sdcc] / sim / ucsim / z80.src / inst_xxcb.cc
1 /*
2  * Simulator of microcontrollers (inst_xxcb.cc)
3  *   DD CB or FD CB escaped multi-byte opcodes for Z80.
4  *
5  *   This module gets pulled in and pre-processed to create
6  *   two modules.  DD CB prefixed opcodes reference
7  *   IX register, while FD CB prefixes reference IY register.
8  *   See inst_ddcb.cc and inst_fdcb.cc
9  *
10  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
11  * 
12  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
13  *
14  */
15
16 /* This file is part of microcontroller simulator: ucsim.
17
18 UCSIM is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or
21 (at your option) any later version.
22
23 UCSIM is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 GNU General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with UCSIM; see the file COPYING.  If not, write to the Free
30 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31 02111-1307, USA. */
32 /*@1@*/
33
34 static unsigned char n_offset;
35
36 int
37 cl_z80::inst_XXcb_rlc(t_mem code)
38 {
39   unsigned char tmp;
40   unsigned short addr;
41
42   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
43   tmp = get1(addr);
44   rlc_byte(tmp);
45
46   switch(code) {
47     case 0x00: // RLC B
48       regs.bc.h = tmp;
49     break;
50     case 0x01: // RLC C
51       regs.bc.l = tmp;
52     break;
53     case 0x02: // RLC D
54       regs.de.h = tmp;
55     break;
56     case 0x03: // RLC E
57       regs.de.l = tmp;
58     break;
59     case 0x04: // RLC H
60       regs.hl.h = tmp;
61     break;
62     case 0x05: // RLC L
63       regs.hl.l = tmp;
64     break;
65     case 0x06: // RLC (HL)
66     break;
67     case 0x07: // RLC A
68       regs.A = tmp;
69     break;
70     default:
71       return(resINV_INST);
72     break;
73   }
74   store1(addr, tmp);
75
76   return(resGO);
77 }
78
79 int
80 cl_z80::inst_XXcb_rrc(t_mem code)
81 {
82   unsigned char tmp;
83   unsigned short addr;
84   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
85   tmp = get1(addr);
86   rrc_byte(tmp);
87
88   switch(code) {
89     case 0x08: // RRC B
90       regs.bc.h = tmp;
91     break;
92     case 0x09: // RRC C
93       regs.bc.l = tmp;
94     break;
95     case 0x0A: // RRC D
96       regs.de.h = tmp;
97     break;
98     case 0x0B: // RRC E
99       regs.de.l = tmp;
100     break;
101     case 0x0C: // RRC H
102       regs.hl.h = tmp;
103     break;
104     case 0x0D: // RRC L
105       regs.hl.l = tmp;
106     break;
107     case 0x0E: // RRC (HL)
108     break;
109     case 0x0F: // RRC A
110       regs.A = tmp;
111     break;
112     default:
113       return(resINV_INST);
114     break;
115   }
116   store1(addr, tmp);
117
118   return(resGO);
119 }
120
121 int
122 cl_z80::inst_XXcb_rl(t_mem code)
123 {
124   unsigned char tmp;
125   unsigned short addr;
126   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
127   tmp = get1(addr);
128   rl_byte(tmp);
129
130   switch(code) {
131     case 0x10: // RL B
132       regs.bc.h = tmp;
133     break;
134     case 0x11: // RL C
135       regs.bc.l = tmp;
136     break;
137     case 0x12: // RL D
138       regs.de.h = tmp;
139     break;
140     case 0x13: // RL E
141       regs.de.l = tmp;
142     break;
143     case 0x14: // RL H
144       regs.hl.h = tmp;
145     break;
146     case 0x15: // RL L
147       regs.hl.l = tmp;
148     break;
149     case 0x16: // RL (HL)
150     break;
151     case 0x17: // RL A
152       regs.A = tmp;
153     break;
154     default:
155       return(resINV_INST);
156     break;
157   }
158   store1(addr, tmp);
159
160   return(resGO);
161 }
162
163 int
164 cl_z80::inst_XXcb_rr(t_mem code)
165 {
166   unsigned char tmp;
167   unsigned short addr;
168   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
169   tmp = get1(addr);
170   rr_byte(tmp);
171
172   switch(code) {
173     case 0x18: // RR B
174       regs.bc.h = tmp;
175     break;
176     case 0x19: // RR C
177       regs.bc.l = tmp;
178     break;
179     case 0x1A: // RR D
180       regs.de.h = tmp;
181     break;
182     case 0x1B: // RR E
183       regs.de.l = tmp;
184     break;
185     case 0x1C: // RR H
186       regs.hl.h = tmp;
187     break;
188     case 0x1D: // RR L
189       regs.hl.l = tmp;
190     break;
191     case 0x1E: // RR (HL)
192     break;
193     case 0x1F: // RR A
194       regs.A = tmp;
195     break;
196     default:
197       return(resINV_INST);
198     break;
199   }
200   store1(addr, tmp);
201
202   return(resGO);
203 }
204
205 int
206 cl_z80::inst_XXcb_sla(t_mem code)
207 {
208   unsigned char tmp;
209   unsigned short addr;
210   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
211   tmp = get1(addr);
212   sla_byte(tmp);
213
214   switch(code) {
215     case 0x20: // SLA B
216       regs.bc.h = tmp;
217     break;
218     case 0x21: // SLA C
219       regs.bc.l = tmp;
220     break;
221     case 0x22: // SLA D
222       regs.de.h = tmp;
223     break;
224     case 0x23: // SLA E
225       regs.de.l = tmp;
226     break;
227     case 0x24: // SLA H
228       regs.hl.h = tmp;
229     break;
230     case 0x25: // SLA L
231       regs.hl.l = tmp;
232     break;
233     case 0x26: // SLA (HL)
234     break;
235     case 0x27: // SLA A
236       regs.A = tmp;
237     break;
238     default:
239       return(resINV_INST);
240     break;
241   }
242   store1(addr, tmp);
243   return(resGO);
244 }
245
246 int
247 cl_z80::inst_XXcb_sra(t_mem code)
248 {
249   unsigned char tmp;
250   unsigned short addr;
251   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
252   tmp = get1(addr);
253   sra_byte(tmp);
254
255   switch(code) {
256     case 0x28: // SRA B
257       regs.bc.h = tmp;
258     break;
259     case 0x29: // SRA C
260       regs.bc.l = tmp;
261     break;
262     case 0x2A: // SRA D
263       regs.de.h = tmp;
264     break;
265     case 0x2B: // SRA E
266       regs.de.l = tmp;
267     break;
268     case 0x2C: // SRA H
269       regs.hl.h = tmp;
270     break;
271     case 0x2D: // SRA L
272       regs.hl.l = tmp;
273     break;
274     case 0x2E: // SRA (HL)
275     break;
276     case 0x2F: // SRA A
277       regs.A = tmp;
278     break;
279     default:
280       return(resINV_INST);
281     break;
282   }
283   store1(addr, tmp);
284   return(resGO);
285 }
286
287 int
288 cl_z80::inst_XXcb_slia(t_mem code)
289 {
290   unsigned char tmp;
291   unsigned short addr;
292   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
293   tmp = get1(addr);
294   slia_byte(tmp);
295
296   switch(code) {
297     case 0x30: // SLIA B        (Shift Left Inverted Arithmetic)
298       regs.bc.h = tmp;
299     break;
300     case 0x31: // SLIA C        like SLA, but shifts in a 1 bit
301       regs.bc.l = tmp;
302     break;
303     case 0x32: // SLIA D
304       regs.de.h = tmp;
305     break;
306     case 0x33: // SLIA E
307       regs.de.l = tmp;
308     break;
309     case 0x34: // SLIA H
310       regs.hl.h = tmp;
311     break;
312     case 0x35: // SLIA L
313       regs.hl.l = tmp;
314     break;
315     case 0x36: // SLIA (HL)
316     break;
317     case 0x37: // SLIA A
318       regs.A = tmp;
319     break;
320     default:
321       return(resINV_INST);
322     break;
323   }
324   store1(addr, tmp);
325   return(resGO);
326 }
327
328 int
329 cl_z80::inst_XXcb_srl(t_mem code)
330 {
331   unsigned char tmp;
332   unsigned short addr;
333   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
334   tmp = get1(addr);
335   srl_byte(tmp);
336
337   switch(code) {
338     case 0x38: // SRL B
339       regs.bc.h = tmp;
340     break;
341     case 0x39: // SRL C
342       regs.bc.l = tmp;
343     break;
344     case 0x3A: // SRL D
345       regs.de.h = tmp;
346     break;
347     case 0x3B: // SRL E
348       regs.de.l = tmp;
349     break;
350     case 0x3C: // SRL H
351       regs.hl.h = tmp;
352     break;
353     case 0x3D: // SRL L
354       regs.hl.l = tmp;
355     break;
356     case 0x3E: // SRL (HL)
357     break;
358     case 0x3F: // SRL A
359       regs.A = tmp;
360     break;
361     default:
362       return(resINV_INST);
363     break;
364   }
365   store1(addr, tmp);
366   return(resGO);
367 }
368
369
370 int
371 cl_z80::inst_XXcb_bit(t_mem code)
372 {
373   unsigned char tmp;
374   unsigned short addr;
375
376 #define bit_bitnum ((code >> 3) & 7)
377
378   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
379   tmp = get1(addr);
380   bit_byte(tmp, bit_bitnum);
381
382   store1(addr, tmp);
383
384   return(resGO);
385 }
386
387 int
388 cl_z80::inst_XXcb_res(t_mem code)
389 {
390   unsigned char tmp;
391   unsigned short addr;
392
393 #define bit_bitnum ((code >> 3) & 7)
394
395   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
396   tmp = get1(addr);
397   tmp &= ~(1 << bit_bitnum);
398
399   switch(code & 0x7) {
400     case 0x0: // RES x,B
401       regs.bc.h = tmp; break;
402     case 0x1: // RES x,C
403       regs.bc.l = tmp; break;
404     case 0x2: // RES x,D
405       regs.de.h = tmp; break;
406     case 0x3: // RES x,E
407       regs.de.l = tmp; break;
408     case 0x4: // RES x,H
409       regs.hl.h = tmp; break;
410     case 0x5: // RES x,L
411       regs.hl.l = tmp; break;
412     case 0x6: // RES x,(HL)
413     break;
414     case 0x7: // RES x,A
415       regs.A = tmp;
416     break;
417   }
418   store1(addr, tmp);
419   return(resGO);
420 }
421
422 int
423 cl_z80::inst_XXcb_set(t_mem code)
424 {
425   unsigned char tmp;
426   unsigned short addr;
427
428 #define bit_bitnum ((code >> 3) & 7)
429
430   addr = add_u16_disp(regs_IX_OR_IY, n_offset);
431   tmp = get1(addr);
432   tmp |= (1 << bit_bitnum);
433
434   switch(code) {
435     case 0x0: // SET x,B
436       regs.bc.h = tmp; break;
437     case 0x1: // SET x,C
438       regs.bc.l = tmp; break;
439     case 0x2: // SET x,D
440       regs.de.h = tmp; break;
441     case 0x3: // SET x,E
442       regs.de.l = tmp; break;
443     case 0x4: // SET x,H
444       regs.de.h = tmp; break;
445     case 0x5: // SET x,L
446       regs.de.h = tmp; break;
447     case 0x6: // SET x,(IX+dd)
448     break;
449     case 0x7: // SET x,A
450       regs.de.h = tmp; break;
451     break;
452     default:
453       return(resINV_INST);
454     break;
455   }
456   store1(addr, tmp);
457   return(resGO);
458 }
459
460 /******** start CB codes *****************/
461 int
462 cl_z80::inst_XXcb(void)
463 {
464   t_mem code;
465
466   // all DD CB escaped opcodes have a 3rd byte which is a displacement,
467   // 4th byte is opcode extension.
468   n_offset = fetch();
469
470   if (fetch(&code))
471     return(resBREAKPOINT);
472   tick(1);
473   switch (code)
474     {
475     case 0x00: // RLC B
476     case 0x01: // RLC C
477     case 0x02: // RLC D
478     case 0x03: // RLC E
479     case 0x04: // RLC H
480     case 0x05: // RLC L
481     case 0x06: // RLC (HL)
482     case 0x07: // RLC A
483       return (inst_XXcb_rlc(code));
484     case 0x08: // RRC B
485     case 0x09: // RRC C
486     case 0x0A: // RRC D
487     case 0x0B: // RRC E
488     case 0x0C: // RRC H
489     case 0x0D: // RRC L
490     case 0x0E: // RRC (HL)
491     case 0x0F: // RRC A
492       return (inst_XXcb_rrc(code));
493     case 0x10: // RL B
494     case 0x11: // RL C
495     case 0x12: // RL D
496     case 0x13: // RL E
497     case 0x14: // RL H
498     case 0x15: // RL L
499     case 0x16: // RL (HL)
500     case 0x17: // RL A
501       return (inst_XXcb_rl(code));
502     case 0x18: // RR B
503     case 0x19: // RR C
504     case 0x1A: // RR D
505     case 0x1B: // RR E
506     case 0x1C: // RR H
507     case 0x1D: // RR L
508     case 0x1E: // RR (HL)
509     case 0x1F: // RR A
510       return (inst_XXcb_rr(code));
511     case 0x20: // SLA B
512     case 0x21: // SLA C
513     case 0x22: // SLA D
514     case 0x23: // SLA E
515     case 0x24: // SLA H
516     case 0x25: // SLA L
517     case 0x26: // SLA (HL)
518     case 0x27: // SLA A
519       return (inst_XXcb_sla(code));
520     case 0x28: // SRA B
521     case 0x29: // SRA C
522     case 0x2A: // SRA D
523     case 0x2B: // SRA E
524     case 0x2C: // SRA H
525     case 0x2D: // SRA L
526     case 0x2E: // SRA (HL)
527     case 0x2F: // SRA A
528       return (inst_XXcb_sra(code));
529     case 0x30: // SLIA B        (Shift Left Inverted Arithmetic)
530     case 0x31: // SLIA C        like SLA, but shifts in a 1 bit
531     case 0x32: // SLIA D
532     case 0x33: // SLIA E
533     case 0x34: // SLIA H
534     case 0x35: // SLIA L
535     case 0x36: // SLIA (HL)
536     case 0x37: // SLIA A
537       return (inst_XXcb_slia(code));
538     case 0x38: // SRL B
539     case 0x39: // SRL C
540     case 0x3A: // SRL D
541     case 0x3B: // SRL E
542     case 0x3C: // SRL H
543     case 0x3D: // SRL L
544     case 0x3E: // SRL (HL)
545     case 0x3F: // SRL A
546       return (inst_XXcb_srl(code));
547     case 0x46: // BIT 0,(HL)
548     case 0x4E: // BIT 1,(HL)
549     case 0x56: // BIT 2,(HL)
550     case 0x5E: // BIT 3,(HL)
551     case 0x66: // BIT 4,(HL)
552     case 0x6E: // BIT 5,(HL)
553     case 0x76: // BIT 6,(HL)
554     case 0x7E: // BIT 7,(HL)
555       return (inst_XXcb_bit(code));
556     case 0x80: // RES 0,B
557     case 0x81: // RES 0,C
558     case 0x82: // RES 0,D
559     case 0x83: // RES 0,E
560     case 0x84: // RES 0,H
561     case 0x85: // RES 0,L
562     case 0x86: // RES 0,(HL)
563     case 0x87: // RES 0,A
564     case 0x88: // RES 1,B
565     case 0x89: // RES 1,C
566     case 0x8A: // RES 1,D
567     case 0x8B: // RES 1,E
568     case 0x8C: // RES 1,H
569     case 0x8D: // RES 1,L
570     case 0x8E: // RES 1,(HL)
571     case 0x8F: // RES 1,A
572     case 0x90: // RES 2,B
573     case 0x91: // RES 2,C
574     case 0x92: // RES 2,D
575     case 0x93: // RES 2,E
576     case 0x94: // RES 2,H
577     case 0x95: // RES 2,L
578     case 0x96: // RES 2,(HL)
579     case 0x97: // RES 2,A
580     case 0x98: // RES 3,B
581     case 0x99: // RES 3,C
582     case 0x9A: // RES 3,D
583     case 0x9B: // RES 3,E
584     case 0x9C: // RES 3,H
585     case 0x9D: // RES 3,L
586     case 0x9E: // RES 3,(HL)
587     case 0x9F: // RES 3,A
588     case 0xA0: // RES 4,B
589     case 0xA1: // RES 4,C
590     case 0xA2: // RES 4,D
591     case 0xA3: // RES 4,E
592     case 0xA4: // RES 4,H
593     case 0xA5: // RES 4,L
594     case 0xA6: // RES 4,(HL)
595     case 0xA7: // RES 4,A
596     case 0xA8: // RES 5,B
597     case 0xA9: // RES 5,C
598     case 0xAA: // RES 5,D
599     case 0xAB: // RES 5,E
600     case 0xAC: // RES 5,H
601     case 0xAD: // RES 5,L
602     case 0xAE: // RES 5,(HL)
603     case 0xAF: // RES 5,A
604     case 0xB0: // RES 6,B
605     case 0xB1: // RES 6,C
606     case 0xB2: // RES 6,D
607     case 0xB3: // RES 6,E
608     case 0xB4: // RES 6,H
609     case 0xB5: // RES 6,L
610     case 0xB6: // RES 6,(HL)
611     case 0xB7: // RES 6,A
612     case 0xB8: // RES 7,B
613     case 0xB9: // RES 7,C
614     case 0xBA: // RES 7,D
615     case 0xBB: // RES 7,E
616     case 0xBC: // RES 7,H
617     case 0xBD: // RES 7,L
618     case 0xBE: // RES 7,(HL)
619     case 0xBF: // RES 7,A
620       return (inst_XXcb_res(code));
621     case 0xC0: // SET 0,B
622     case 0xC1: // SET 0,C
623     case 0xC2: // SET 0,D
624     case 0xC3: // SET 0,E
625     case 0xC4: // SET 0,H
626     case 0xC5: // SET 0,L
627     case 0xC6: // SET 0,(HL)
628     case 0xC7: // SET 0,A
629     case 0xC8: // SET 1,B
630     case 0xC9: // SET 1,C
631     case 0xCA: // SET 1,D
632     case 0xCB: // SET 1,E
633     case 0xCC: // SET 1,H
634     case 0xCD: // SET 1,L
635     case 0xCE: // SET 1,(HL)
636     case 0xCF: // SET 1,A
637     case 0xD0: // SET 2,B
638     case 0xD1: // SET 2,C
639     case 0xD2: // SET 2,D
640     case 0xD3: // SET 2,E
641     case 0xD4: // SET 2,H
642     case 0xD5: // SET 2,L
643     case 0xD6: // SET 2,(HL)
644     case 0xD7: // SET 2,A
645     case 0xD8: // SET 3,B
646     case 0xD9: // SET 3,C
647     case 0xDA: // SET 3,D
648     case 0xDB: // SET 3,E
649     case 0xDC: // SET 3,H
650     case 0xDD: // SET 3,L
651     case 0xDE: // SET 3,(HL)
652     case 0xDF: // SET 3,A
653     case 0xE0: // SET 4,B
654     case 0xE1: // SET 4,C
655     case 0xE2: // SET 4,D
656     case 0xE3: // SET 4,E
657     case 0xE4: // SET 4,H
658     case 0xE5: // SET 4,L
659     case 0xE6: // SET 4,(HL)
660     case 0xE7: // SET 4,A
661     case 0xE8: // SET 5,B
662     case 0xE9: // SET 5,C
663     case 0xEA: // SET 5,D
664     case 0xEB: // SET 5,E
665     case 0xEC: // SET 5,H
666     case 0xED: // SET 5,L
667     case 0xEE: // SET 5,(HL)
668     case 0xEF: // SET 5,A
669     case 0xF0: // SET 6,B
670     case 0xF1: // SET 6,C
671     case 0xF2: // SET 6,D
672     case 0xF3: // SET 6,E
673     case 0xF4: // SET 6,H
674     case 0xF5: // SET 6,L
675     case 0xF6: // SET 6,(HL)
676     case 0xF7: // SET 6,A
677     case 0xF8: // SET 7,B
678     case 0xF9: // SET 7,C
679     case 0xFA: // SET 7,D
680     case 0xFB: // SET 7,E
681     case 0xFC: // SET 7,H
682     case 0xFD: // SET 7,L
683     case 0xFE: // SET 7,(HL)
684     case 0xFF: // SET 7,A
685       return (inst_XXcb_set(code));
686     }
687   if (PC)
688     PC--;
689   else
690     PC= get_mem_size(MEM_ROM)-1;
691   return(resINV_INST);
692 }
693
694 /* End of z80.src/inst_xxcb.cc */