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*)®s.raf.A);
151 regs8->get_cell(1)->decode((t_mem*)®s.raf.F);
152 regs8->get_cell(2)->decode((t_mem*)®s.bc.h);
153 regs8->get_cell(3)->decode((t_mem*)®s.bc.l);
154 regs8->get_cell(4)->decode((t_mem*)®s.de.h);
155 regs8->get_cell(5)->decode((t_mem*)®s.de.l);
156 regs8->get_cell(6)->decode((t_mem*)®s.hl.h);
157 regs8->get_cell(7)->decode((t_mem*)®s.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*)®s.ralt_af.aA);
162 regs8->get_cell(10)->decode((t_mem*)®s.ralt_af.aF);
163 regs8->get_cell(11)->decode((t_mem*)®s.a_bc.h);
164 regs8->get_cell(12)->decode((t_mem*)®s.a_bc.l);
165 regs8->get_cell(13)->decode((t_mem*)®s.a_de.h);
166 regs8->get_cell(14)->decode((t_mem*)®s.a_de.l);
167 regs8->get_cell(15)->decode((t_mem*)®s.a_hl.h);
168 regs8->get_cell(16)->decode((t_mem*)®s.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*)®s.AF);
174 regs16->get_cell(1)->decode((t_mem*)®s.BC);
175 regs16->get_cell(2)->decode((t_mem*)®s.DE);
176 regs16->get_cell(3)->decode((t_mem*)®s.HL);
177 regs16->get_cell(4)->decode((t_mem*)®s.IX);
178 regs16->get_cell(5)->decode((t_mem*)®s.IY);
179 regs16->get_cell(6)->decode((t_mem*)®s.SP);
180 regs16->get_cell(7)->decode((t_mem*)®s.aAF);
181 regs16->get_cell(8)->decode((t_mem*)®s.aBC);
182 regs16->get_cell(9)->decode((t_mem*)®s.aDE);
183 regs16->get_cell(10)->decode((t_mem*)®s.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