1 /*
2  * Simulator of microcontrollers (r2k.cc)
3  *
4  * Derived from ucSim z80.src/z80.cc
5  * Modified for rabbit 2000 by Leland Morrison 2011
6  *
7  * some z80 code base from Karl Bongers karl@turbobit.com
8  *
9  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
10  *
11  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
12  *
13  */
14 
15 /* This file is part of microcontroller simulator: ucsim.
16 
17 UCSIM is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 2 of the License, or
20 (at your option) any later version.
21 
22 UCSIM is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 GNU General Public License for more details.
26 
27 You should have received a copy of the GNU General Public License
28 along with UCSIM; see the file COPYING.  If not, write to the Free
29 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 02111-1307, USA. */
31 /*@1@*/
32 
33 #include "ddconfig.h"
34 
35 #include <stdarg.h> /* for va_list */
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <ctype.h>
39 #include "i_string.h"
40 
41 // prj
42 #include "pobjcl.h"
43 
44 // sim
45 #include "simcl.h"
46 
47 // local
48 #include "z80cl.h"
49 #include "r2kcl.h"
50 #include "glob.h"
51 
52 #define uint32 t_addr
53 #define uint8 unsigned char
54 
55 /*******************************************************************/
56 
57 
58 /*
59  * Rabbit 2000 micro-controller object
60  *  (base for Rabbit 3000/4000/5000)
61  */
62 
cl_r2k(struct cpu_entry * Itype,class cl_sim * asim)63 cl_r2k::cl_r2k(struct cpu_entry *Itype, class cl_sim *asim):
64   cl_z80(Itype, asim), mmu(this)
65 {
66   type= Itype;
67 }
68 
cl_r3ka(struct cpu_entry * Itype,class cl_sim * asim)69 cl_r3ka::cl_r3ka(struct cpu_entry *Itype, class cl_sim *asim):
70   cl_r2k(Itype, asim)
71 {
72   SU = 0;
73 }
74 
75 int
init(void)76 cl_r2k::init(void)
77 {
78   cl_uc::init(); /* Memories now exist */
79 
80   //rom= address_space(MEM_ROM_ID);
81 //  ram= mem(MEM_XRAM);
82   //ram= rom;
83 
84   // zero out ram(this is assumed in regression tests)
85   for (int i=0x8000; i<0x10000; i++) {
86     ram->set((t_addr) i, 0);
87   }
88 
89   return(0);
90 }
91 
92 char *
id_string(void)93 cl_r2k::id_string(void)
94 {
95   return((char*)"rabbit 2000");
96 }
97 
98 char *
id_string(void)99 cl_r3ka::id_string(void)
100 {
101   return((char*)"rabbit 3000A");
102 }
103 
104 /*
105  * Making elements of the controller
106  */
107 /*
108 t_addr
109 cl_r2k::get_mem_size(enum mem_class type)
110 {
111   switch(type)
112     {
113     case MEM_ROM: return(0x10000);
114     case MEM_XRAM: return(0x10000);
115     default: return(0);
116     }
117  return(cl_uc::get_mem_size(type));
118 }
119 */
120 
121 void
mk_hw_elements(void)122 cl_r2k::mk_hw_elements(void)
123 {
124   //class cl_base *o;
125   cl_uc::mk_hw_elements();
126 }
127 
128 void
make_memories(void)129 cl_r2k::make_memories(void)
130 {
131   class cl_address_space *as;
132 
133   rom= ram= as= new cl_address_space("rom", 0, 0x10000, 8);
134   as->init();
135   address_spaces->add(as);
136 
137   class cl_address_decoder *ad;
138   class cl_memory_chip *chip;
139 
140   chip= new cl_memory_chip("rom_chip", 0x10000, 8);
141   chip->init();
142   memchips->add(chip);
143   ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
144   ad->init();
145   as->decoders->add(ad);
146   ad->activate(0);
147 
148   regs8= new cl_address_space("regs8", 0, 18, 8);
149   regs8->init();
150   regs8->get_cell(0)->decode((t_mem*)&regs.raf.A);
151   regs8->get_cell(1)->decode((t_mem*)&regs.raf.F);
152   regs8->get_cell(2)->decode((t_mem*)&regs.bc.h);
153   regs8->get_cell(3)->decode((t_mem*)&regs.bc.l);
154   regs8->get_cell(4)->decode((t_mem*)&regs.de.h);
155   regs8->get_cell(5)->decode((t_mem*)&regs.de.l);
156   regs8->get_cell(6)->decode((t_mem*)&regs.hl.h);
157   regs8->get_cell(7)->decode((t_mem*)&regs.hl.l);
158   regs8->get_cell(8)->decode((t_mem*)&iir);
159   regs8->get_cell(9)->decode((t_mem*)&eir);
160 
161   regs8->get_cell(9)->decode((t_mem*)&regs.ralt_af.aA);
162   regs8->get_cell(10)->decode((t_mem*)&regs.ralt_af.aF);
163   regs8->get_cell(11)->decode((t_mem*)&regs.a_bc.h);
164   regs8->get_cell(12)->decode((t_mem*)&regs.a_bc.l);
165   regs8->get_cell(13)->decode((t_mem*)&regs.a_de.h);
166   regs8->get_cell(14)->decode((t_mem*)&regs.a_de.l);
167   regs8->get_cell(15)->decode((t_mem*)&regs.a_hl.h);
168   regs8->get_cell(16)->decode((t_mem*)&regs.a_hl.l);
169 
170   regs16= new cl_address_space("regs16", 0, 11, 16);
171   regs16->init();
172 
173   regs16->get_cell(0)->decode((t_mem*)&regs.AF);
174   regs16->get_cell(1)->decode((t_mem*)&regs.BC);
175   regs16->get_cell(2)->decode((t_mem*)&regs.DE);
176   regs16->get_cell(3)->decode((t_mem*)&regs.HL);
177   regs16->get_cell(4)->decode((t_mem*)&regs.IX);
178   regs16->get_cell(5)->decode((t_mem*)&regs.IY);
179   regs16->get_cell(6)->decode((t_mem*)&regs.SP);
180   regs16->get_cell(7)->decode((t_mem*)&regs.aAF);
181   regs16->get_cell(8)->decode((t_mem*)&regs.aBC);
182   regs16->get_cell(9)->decode((t_mem*)&regs.aDE);
183   regs16->get_cell(10)->decode((t_mem*)&regs.aHL);
184 
185   address_spaces->add(regs8);
186   address_spaces->add(regs16);
187 
188   class cl_var *v;
189   vars->add(v= new cl_var(cchars("A"), regs8, 0, ""));
190   v->init();
191   vars->add(v= new cl_var(cchars("F"), regs8, 1, ""));
192   v->init();
193   vars->add(v= new cl_var(cchars("B"), regs8, 2, ""));
194   v->init();
195   vars->add(v= new cl_var(cchars("C"), regs8, 3, ""));
196   v->init();
197   vars->add(v= new cl_var(cchars("D"), regs8, 4, ""));
198   v->init();
199   vars->add(v= new cl_var(cchars("E"), regs8, 5, ""));
200   v->init();
201   vars->add(v= new cl_var(cchars("H"), regs8, 6, ""));
202   v->init();
203   vars->add(v= new cl_var(cchars("L"), regs8, 7, ""));
204   v->init();
205   vars->add(v= new cl_var(cchars("IIR"), regs8, 8, ""));
206   v->init();
207   vars->add(v= new cl_var(cchars("EIR"), regs8, 9, ""));
208   v->init();
209 
210   vars->add(v= new cl_var(cchars("ALT_A"), regs8, 10, ""));
211   v->init();
212   vars->add(v= new cl_var(cchars("ALT_F"), regs8, 11, ""));
213   v->init();
214   vars->add(v= new cl_var(cchars("ALT_B"), regs8, 12, ""));
215   v->init();
216   vars->add(v= new cl_var(cchars("ALT_C"), regs8, 13, ""));
217   v->init();
218   vars->add(v= new cl_var(cchars("ALT_D"), regs8, 14, ""));
219   v->init();
220   vars->add(v= new cl_var(cchars("ALT_E"), regs8, 15, ""));
221   v->init();
222   vars->add(v= new cl_var(cchars("ALT_H"), regs8, 16, ""));
223   v->init();
224   vars->add(v= new cl_var(cchars("ALT_L"), regs8, 17, ""));
225   v->init();
226 
227   vars->add(v= new cl_var(cchars("AF"), regs16, 0, ""));
228   v->init();
229   vars->add(v= new cl_var(cchars("BC"), regs16, 1, ""));
230   v->init();
231   vars->add(v= new cl_var(cchars("DE"), regs16, 2, ""));
232   v->init();
233   vars->add(v= new cl_var(cchars("HL"), regs16, 3, ""));
234   v->init();
235   vars->add(v= new cl_var(cchars("IX"), regs16, 4, ""));
236   v->init();
237   vars->add(v= new cl_var(cchars("IY"), regs16, 5, ""));
238   v->init();
239   vars->add(v= new cl_var(cchars("SP"), regs16, 6, ""));
240   v->init();
241   vars->add(v= new cl_var(cchars("ALT_AF"), regs16, 7, ""));
242   v->init();
243   vars->add(v= new cl_var(cchars("ALT_BC"), regs16, 8, ""));
244   v->init();
245   vars->add(v= new cl_var(cchars("ALT_DE"), regs16, 9, ""));
246   v->init();
247   vars->add(v= new cl_var(cchars("ALT_HL"), regs16, 10, ""));
248   v->init();
249 }
250 
251 
252 /*
253  * Help command interpreter
254  */
255 
256 struct dis_entry *
dis_tbl(void)257 cl_r2k::dis_tbl(void)
258 {
259   return(disass_r2k);
260 }
261 
262 /*struct name_entry *
263 cl_r2k::sfr_tbl(void)
264 {
265   return(0);
266 }*/
267 
268 /*struct name_entry *
269 cl_r2k::bit_tbl(void)
270 {
271   //FIXME
272   return(0);
273 }*/
274 
275 int
inst_length(t_addr addr)276 cl_r2k::inst_length(t_addr addr)
277 {
278   int len = 0;
279 
280   get_disasm_info(addr, &len, NULL, NULL);
281 
282   return len;
283 }
284 
285 int
inst_branch(t_addr addr)286 cl_r2k::inst_branch(t_addr addr)
287 {
288   int b;
289 
290   get_disasm_info(addr, NULL, &b, NULL);
291 
292   return b;
293 }
294 
295 int
longest_inst(void)296 cl_r2k::longest_inst(void)
297 {
298   return 4;
299 }
300 
301 
302 const char *
get_disasm_info(t_addr addr,int * ret_len,int * ret_branch,int * immed_offset)303 cl_r2k::get_disasm_info(t_addr addr,
304                         int *ret_len,
305                         int *ret_branch,
306                         int *immed_offset)
307 {
308   const char *b = NULL;
309   uint code;
310   int len = 0;
311   int immed_n = 0;
312   int i;
313   int start_addr = addr;
314   struct dis_entry *dis_e;
315 
316   code= rom->get/*_mem*/(/*MEM_ROM_ID,*/ addr++);
317   dis_e = NULL;
318 
319   switch(code) {
320     case 0xcb:  /* ESC code to lots of op-codes, all 2-byte */
321       code= rom->get/*_mem*/(/*MEM_ROM_ID,*/ addr++);
322       i= 0;
323       while ((code & disass_r2k_cb[i].mask) != disass_r2k_cb[i].code &&
324         disass_r2k_cb[i].mnemonic)
325         i++;
326       dis_e = &disass_r2k_cb[i];
327       b= disass_r2k_cb[i].mnemonic;
328       if (b != NULL)
329         len += (disass_r2k_cb[i].length + 1);
330     break;
331 
332     case 0xed: /* ESC code to about 80 opcodes of various lengths */
333       code= rom->get/*_mem*/(/*MEM_ROM_ID,*/ addr++);
334       i= 0;
335       while ((code & disass_r2k_ed[i].mask) != disass_r2k_ed[i].code &&
336         disass_r2k_ed[i].mnemonic)
337         i++;
338       dis_e = &disass_r2k_ed[i];
339       b= disass_r2k_ed[i].mnemonic;
340       if (b != NULL)
341         len += (disass_r2k_ed[i].length + 1);
342     break;
343 
344     case 0xdd: /* ESC codes,about 284, vary lengths, IX centric */
345       code= rom->get(addr++);
346       if (code == 0xcb) {
347         immed_n = 2;
348         addr++;  // pass up immed data
349         code= rom->get(addr++);
350         i= 0;
351         while ((code & disass_r2k_ddcb[i].mask) != disass_r2k_ddcb[i].code &&
352           disass_r2k_ddcb[i].mnemonic)
353           i++;
354         dis_e = &disass_r2k_ddcb[i];
355         b= disass_r2k_ddcb[i].mnemonic;
356         if (b != NULL)
357           len += (disass_r2k_ddcb[i].length + 2);
358       } else {
359         i= 0;
360         while ((code & disass_r2k_dd[i].mask) != disass_r2k_dd[i].code &&
361           disass_r2k_dd[i].mnemonic)
362           i++;
363         dis_e = &disass_r2k_dd[i];
364         b= disass_r2k_dd[i].mnemonic;
365         if (b != NULL)
366           len += (disass_r2k_dd[i].length + 1);
367       }
368     break;
369 
370     case 0xfd: /* ESC codes,sme as dd but IY centric */
371       code= rom->get(addr++);
372       if (code == 0xcb) {
373         immed_n = 2;
374         addr++;  // pass up immed data
375         code= rom->get(addr++);
376         i= 0;
377         while ((code & disass_r2k_fdcb[i].mask) != disass_r2k_fdcb[i].code &&
378           disass_r2k_fdcb[i].mnemonic)
379           i++;
380         dis_e = &disass_r2k_fdcb[i];
381         b= disass_r2k_fdcb[i].mnemonic;
382         if (b != NULL)
383           len += (disass_r2k_fdcb[i].length + 2);
384       } else {
385         i= 0;
386         while ((code & disass_r2k_fd[i].mask) != disass_r2k_fd[i].code &&
387           disass_r2k_fd[i].mnemonic)
388           i++;
389         dis_e = &disass_r2k_fd[i];
390         b= disass_r2k_fd[i].mnemonic;
391         if (b != NULL)
392           len += (disass_r2k_fd[i].length + 1);
393       }
394     break;
395 
396     default:
397       i= 0;
398       while ((code & disass_r2k[i].mask) != disass_r2k[i].code &&
399              disass_r2k[i].mnemonic)
400         i++;
401       dis_e = &disass_r2k[i];
402       b= disass_r2k[i].mnemonic;
403       if (b != NULL)
404         len += (disass_r2k[i].length);
405     break;
406   }
407 
408 
409   if (ret_branch) {
410     *ret_branch = dis_e->branch;
411   }
412 
413   if (immed_offset) {
414     if (immed_n > 0)
415          *immed_offset = immed_n;
416     else *immed_offset = (addr - start_addr);
417   }
418 
419   if (len == 0)
420     len = 1;
421 
422   if (ret_len)
423     *ret_len = len;
424 
425   return b;
426 }
427 
428 char *
disass(t_addr addr,const char * sep)429 cl_r2k::disass(t_addr addr, const char *sep)
430 {
431   char work[256], temp[20];
432   const char *b;
433   char *buf, *p, *t;
434   int len = 0;
435   int immed_offset = 0;
436 
437   p= work;
438 
439   b = get_disasm_info(addr, &len, NULL, &immed_offset);
440 
441   if (b == NULL) {
442     buf= (char*)malloc(30);
443     strcpy(buf, "UNKNOWN/INVALID");
444     return(buf);
445   }
446 
447   while (*b)
448     {
449       if (*b == '%')
450         {
451           b++;
452           switch (*(b++))
453             {
454             case 'd': // d    jump relative target, signed? byte immediate operand
455               sprintf(temp, "#%d", (char)rom->get(addr+immed_offset));
456               ++immed_offset;
457               break;
458             case 'w': // w    word immediate operand
459               sprintf(temp, "#0x%04x",
460                  (uint)((rom->get(addr+immed_offset)) |
461                         (rom->get(addr+immed_offset+1)<<8)) );
462               ++immed_offset;
463               ++immed_offset;
464               break;
465             case 'b': // b    byte immediate operand
466               sprintf(temp, "#0x%02x", (uint)rom->get(addr+immed_offset));
467               ++immed_offset;
468               break;
469             default:
470               strcpy(temp, "?");
471               break;
472             }
473           t= temp;
474           while (*t)
475             *(p++)= *(t++);
476         }
477       else
478         *(p++)= *(b++);
479     }
480   *p= '\0';
481 
482   p= strchr(work, ' ');
483   if (!p)
484     {
485       buf= strdup(work);
486       return(buf);
487     }
488   if (sep == NULL)
489     buf= (char *)malloc(6+strlen(p)+1);
490   else
491     buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
492   for (p= work, t= buf; *p != ' '; p++, t++)
493     *t= *p;
494   p++;
495   *t= '\0';
496   if (sep == NULL)
497     {
498       while (strlen(buf) < 6)
499         strcat(buf, " ");
500     }
501   else
502     strcat(buf, sep);
503   strcat(buf, p);
504   return(buf);
505 }
506 
507 
508 void
print_regs(class cl_console_base * con)509 cl_r2k::print_regs(class cl_console_base *con)
510 {
511   con->dd_printf("SZ-A-PNC  Flags= 0x%02x %3d %c  ",
512                  regs.raf.F, regs.raf.F, isprint(regs.raf.F)?regs.raf.F:'.');
513   con->dd_printf("A= 0x%02x %3d %c\n",
514                  regs.raf.A, regs.raf.A, isprint(regs.raf.A)?regs.raf.A:'.');
515   con->dd_printf("%c%c-%c-%c%c%c\n",
516                  (regs.raf.F&BIT_S)?'1':'0',
517                  (regs.raf.F&BIT_Z)?'1':'0',
518                  (regs.raf.F&BIT_A)?'1':'0',
519                  (regs.raf.F&BIT_P)?'1':'0',
520                  (regs.raf.F&BIT_N)?'1':'0',
521                  (regs.raf.F&BIT_C)?'1':'0');
522   con->dd_printf("BC= 0x%04x [BC]= %02x %3d %c  ",
523                  regs.BC, ram->get(regs.BC), ram->get(regs.BC),
524                  isprint(ram->get(regs.BC))?ram->get(regs.BC):'.');
525   con->dd_printf("DE= 0x%04x [DE]= %02x %3d %c  ",
526                  regs.DE, ram->get(regs.DE), ram->get(regs.DE),
527                  isprint(ram->get(regs.DE))?ram->get(regs.DE):'.');
528   con->dd_printf("HL= 0x%04x [HL]= %02x %3d %c\n",
529                  regs.HL, ram->get(regs.HL), ram->get(regs.HL),
530                  isprint(ram->get(regs.HL))?ram->get(regs.HL):'.');
531   con->dd_printf("IX= 0x%04x [IX]= %02x %3d %c  ",
532                  regs.IX, ram->get(regs.IX), ram->get(regs.IX),
533                  isprint(ram->get(regs.IX))?ram->get(regs.IX):'.');
534   con->dd_printf("IY= 0x%04x [IY]= %02x %3d %c  ",
535                  regs.IY, ram->get(regs.IY), ram->get(regs.IY),
536                  isprint(ram->get(regs.IY))?ram->get(regs.IY):'.');
537   con->dd_printf("SP= 0x%04x [SP]= %02x %3d %c\n",
538                  regs.SP, ram->get(regs.SP), ram->get(regs.SP),
539                  isprint(ram->get(regs.SP))?ram->get(regs.SP):'.');
540 
541   print_disass(PC, con);
542 }
543 
544 /*
545  * Execution
546  */
547 
548 int
exec_inst(void)549 cl_r2k::exec_inst(void)
550 {
551   t_mem code;
552 
553   ins_start = PC;
554   instPC = PC;
555 
556   if (fetch(&code))
557     return(resBREAKPOINT);
558   tick(1);
559 
560   /* handling for IOI and IOE prefixes */
561   mmu.io_flag = 0;
562   if ((code == 0xd3) || (code == 0xdb)) {
563     mmu.io_flag = (code == 0xd3) ? IOI : IOE;
564 
565     if (fetch(&code))
566       return(resBREAKPOINT);
567     tick(1);
568   }
569 
570   return exec_code( code );
571 }
572 
exec_code(t_mem code)573 int cl_r2k::exec_code(t_mem code)
574 {
575   switch (code)
576     {
577     case 0x00: return(inst_nop(code));
578     case 0x01: case 0x02: case 0x06: return(inst_ld(code));
579     case 0x03: case 0x04: return(inst_inc(code));
580     case 0x05: return(inst_dec(code));
581     case 0x07: return(inst_rlca(code));
582 
583     case 0x08: return(inst_ex(code));
584     case 0x09: return(inst_add(code));
585     case 0x0a: case 0x0e: return(inst_ld(code));
586     case 0x0b: case 0x0d: return(inst_dec(code));
587     case 0x0c: return(inst_inc(code));
588     case 0x0f: return(inst_rrca(code));
589 
590     case 0x10: return(inst_djnz(code));
591     case 0x11: case 0x12: case 0x16: return(inst_ld(code));
592     case 0x13: case 0x14: return(inst_inc(code));
593     case 0x15: return(inst_dec(code));
594     case 0x17: return(inst_rla(code));
595 
596     case 0x18: return(inst_jr(code));
597     case 0x19: return(inst_add(code));
598     case 0x1a: case 0x1e: return(inst_ld(code));
599     case 0x1b: case 0x1d: return(inst_dec(code));
600     case 0x1c: return(inst_inc(code));
601     case 0x1f: return(inst_rra(code));
602 
603 
604     case 0x20: return(inst_jr(code));
605     case 0x21: case 0x22: case 0x26: return(inst_ld(code));
606     case 0x23: case 0x24: return(inst_inc(code));
607     case 0x25: return(inst_dec(code));
608 
609       //case 0x27: return(inst_daa(code));
610     case 0x27: return(inst_add_sp_d(code));
611 
612     case 0x28: return(inst_jr(code));
613     case 0x29: return(inst_add(code));
614     case 0x2a: case 0x2e: return(inst_ld(code));
615     case 0x2b: case 0x2d: return(inst_dec(code));
616     case 0x2c: return(inst_inc(code));
617     case 0x2f: return(inst_cpl(code));
618 
619 
620     case 0x30: return(inst_jr(code));
621     case 0x31: case 0x32: case 0x36: return(inst_ld(code));
622     case 0x33: case 0x34: return(inst_inc(code));
623     case 0x35: return(inst_dec(code));
624     case 0x37: return(inst_scf(code));
625 
626     case 0x38: return(inst_jr(code));
627     case 0x39: return(inst_add(code));
628     case 0x3a: case 0x3e: return(inst_ld(code));
629     case 0x3b: case 0x3d: return(inst_dec(code));
630     case 0x3c: return(inst_inc(code));
631     case 0x3f: return(inst_ccf(code));
632 
633     case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
634     case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
635       return(inst_ld(code));
636 
637     case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
638     case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
639       return(inst_ld(code));
640 
641     case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
642     case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
643       return(inst_ld(code));
644 
645     case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x77:
646     case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
647       return(inst_ld(code));
648     case 0x76:
649       //return(inst_halt(code));
650       return(inst_altd(code));
651 
652     case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
653       return(inst_add(code));
654     case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
655       return(inst_adc(code));
656 
657     case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
658       return(inst_sub(code));
659     case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
660       return(inst_sbc(code));
661 
662     case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
663       return(inst_and(code));
664     case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
665       return(inst_xor(code));
666 
667     case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
668       return(inst_or(code));
669     case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
670       return(inst_cp(code));
671 
672     case 0xc0: return(inst_ret(code));
673     case 0xc1: return(inst_pop(code));
674     case 0xc2: case 0xc3: return(inst_jp(code));
675     case 0xc4: return(inst_r2k_ld(code));
676     case 0xc5: return(inst_push(code));
677     case 0xc6: return(inst_add(code));
678     case 0xc7: return(inst_ljp(code));
679 
680     case 0xc8: case 0xc9: return(inst_ret(code));
681     case 0xca: return(inst_jp(code));
682 
683       /* CB escapes out to 2 byte opcodes(CB include), opcodes
684          to do register bit manipulations */
685     case 0xcb: return(inst_cb());
686     case 0xcc: return(inst_bool(code));
687     case 0xcd: return(inst_call(code));
688     case 0xce: return(inst_adc(code));
689     case 0xcf: return(inst_lcall(code));
690 
691 
692     case 0xd0: return(inst_ret(code));
693     case 0xd1: return(inst_pop(code));
694     case 0xd2: return(inst_jp(code));
695     case 0xd3: /* error (ioi prefix) */ break;
696     case 0xd4: return(inst_r2k_ld(code));
697     case 0xd5: return(inst_push(code));
698     case 0xd6: return(inst_sub(code));
699     case 0xd7: return(inst_rst(code));
700 
701     case 0xd8: return(inst_ret(code));
702     case 0xd9: return(inst_exx(code));
703     case 0xda: return(inst_jp(code));
704     case 0xdb: /* error (ioe prefix) */ break;
705     case 0xdc: return(inst_r2k_and(code));
706       /* DD escapes out to 2 to 4 byte opcodes(DD included)
707         with a variety of uses.  It can precede the CB escape
708         sequence to extend CB codes with IX+immed_byte */
709     case 0xdd: return(inst_xd(code));
710     case 0xde: return(inst_sbc(code));
711     case 0xdf: return(inst_rst(code));
712 
713 
714     case 0xe0: return(inst_ret(code));
715     case 0xe1: return(inst_pop(code));
716     case 0xe2: return(inst_jp(code));
717     case 0xe3: return(inst_r2k_ex(code));
718     case 0xe4: return(inst_r2k_ld(code));
719     case 0xe5: return(inst_push(code));
720     case 0xe6: return(inst_and(code));
721     case 0xe7: return(inst_rst(code));
722 
723     case 0xe8: return(inst_ret(code));
724     case 0xe9: return(inst_jp(code));
725     case 0xea: return(inst_jp(code));
726     case 0xeb: return(inst_ex(code));
727     case 0xec: return(inst_r2k_or (code));
728       /* ED escapes out to other oddball opcodes */
729     case 0xed: return(inst_ed(0xed));
730     case 0xee: return(inst_xor(code));
731     case 0xef: return(inst_rst(code));
732 
733     case 0xf0: return(inst_ret(code));
734     case 0xf1: return(inst_pop(code));
735     case 0xf2: return(inst_jp(code));
736     case 0xf3: return(inst_rl_de(code));
737     case 0xf4: return(inst_r2k_ld(code));
738     case 0xf5: return(inst_push(code));
739     case 0xf6: return(inst_or(code));
740     case 0xf7: return(inst_mul(code));
741 
742     case 0xf8: return(inst_ret(code));
743     case 0xf9: return(inst_ld(code));
744     case 0xfa: return(inst_jp(code));
745     case 0xfb: return(inst_rr_de(code));
746     case 0xfc: return(inst_rr_hl(code));
747       /* FD escapes out to 2 to 4 byte opcodes(DD included)
748         with a variety of uses.  It can precede the CB escape
749         sequence to extend CB codes with IX+immed_byte */
750     case 0xfd: return(inst_xd(code));
751     case 0xfe: return(inst_cp(code));
752     case 0xff: return(inst_rst(code));
753     }
754 
755   /*if (PC)
756     PC--;
757   else
758   PC= get_mem_size(MEM_ROM_ID)-1;*/
759   PC= rom->inc_address(PC, -1);
760 
761   sim->stop(resINV_INST);
762   return(resINV_INST);
763 }
764 
exec_code(t_mem code)765 int cl_r3ka::exec_code(t_mem code)
766 {
767   if (code == 0x5B)
768     {
769       // IDET
770       // if (EDMR && (SU & 0x01))
771       //  system violation interrupt...
772       ;
773     }
774 
775   return cl_r2k::exec_code(code);
776 }
777 
778 /* End of z80.src/z80.cc */
779