e189643ff1e2dec16d1ab2de0ed876b599856542
[fw/sdcc] / sim / ucsim / xa.src / xa.cc
1 /*
2  * Simulator of microcontrollers (xa.cc)
3  *
4  * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
5  *
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  * Other contributors include:
8  *   Karl Bongers karl@turbobit.com,
9  *   Johan Knol 
10  */
11
12 /* This file is part of microcontroller simulator: ucsim.
13
14 UCSIM is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 UCSIM is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with UCSIM; see the file COPYING.  If not, write to the Free
26 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 02111-1307, USA. */
28 /*@1@*/
29
30 #include "ddconfig.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <ctype.h>
35 #include "i_string.h"
36
37 // prj
38 #include "pobjcl.h"
39
40 // sim
41 #include "simcl.h"
42
43 // local
44 #include "xacl.h"
45 #include "glob.h"
46 #include "regsxa.h"
47
48
49 /*
50  * Base type of xa controllers
51  */
52
53 cl_xa::cl_xa(class cl_sim *asim):
54   cl_uc(asim)
55 {
56   type= CPU_XA;
57 }
58
59 int
60 cl_xa::init(void)
61 {
62   cl_uc::init(); /* Memories now exist */
63   ram= mem(MEM_XRAM);
64   rom= mem(MEM_ROM);
65
66   wmem_direct = (TYPE_UWORD *) &mem_direct[0];
67
68   /* set SCR to osc/4, native XA mode, flat 24 */
69   set_scr(0);
70   /* initialize SP to 100H */
71   set_reg2(7, 0x100);
72   /* set PSW from reset vector */
73   set_psw(getcode2(0));
74   /* set PC from reset vector */
75   PC = getcode2(2);
76
77   printf("The XA Simulator is in development, UNSTABLE, DEVELOPERS ONLY!\n");
78
79   return(0);
80 }
81
82 char *
83 cl_xa::id_string(void)
84 {
85   return("unspecified XA");
86 }
87
88
89 /*
90  * Making elements of the controller
91  */
92
93 t_addr
94 cl_xa::get_mem_size(enum mem_class type)
95 {
96   switch(type)
97     {
98     case MEM_ROM: return(0x10000);
99     case MEM_XRAM: return(0x10000);
100     default: return(0);
101     }
102  return(cl_uc::get_mem_size(type));
103 }
104
105 void
106 cl_xa::mk_hw_elements(void)
107 {
108   //class cl_base *o;
109   /* t_uc::mk_hw() does nothing */
110 }
111
112
113 /*
114  * Help command interpreter
115  */
116
117 struct dis_entry *
118 cl_xa::dis_tbl(void)
119 {
120   // this should be unused, we need to make main prog code
121   // independent of any array thing.
122   printf("ERROR - Using disass[] table in XA sim code!\n");
123   return(glob_disass_xa);
124 }
125
126 struct name_entry *cl_xa::sfr_tbl(void)
127 {
128   return(sfr_tabXA51);
129 }
130
131 struct name_entry *cl_xa::bit_tbl(void)
132 {
133   return(bit_tabXA51);
134 }
135
136 int
137 cl_xa::inst_length(t_addr addr)
138 {
139   int len = 0;
140
141   get_disasm_info(addr, &len, NULL, NULL, NULL, NULL);
142
143   return len;
144 }
145
146 int
147 cl_xa::inst_branch(t_addr addr)
148 {
149   int b;
150
151   get_disasm_info(addr, NULL, &b, NULL, NULL, NULL);
152
153   return b;
154 }
155
156 int
157 cl_xa::longest_inst(void)
158 {
159   return 6;
160 }
161
162 static char dir_name[64];
163 char *cl_xa::get_dir_name(short addr) {
164   if (!get_name(addr, sfr_tbl(), dir_name)) {
165     sprintf (dir_name, "0x%03x", addr);
166   }
167   return dir_name;
168 }
169
170 static char bit_name[64];
171 char *cl_xa::get_bit_name(short addr) {
172   if (!get_name(addr, bit_tbl(), bit_name)) {
173     sprintf (bit_name, "0x%03x", addr);
174   }
175   return bit_name;
176 }
177
178 /*--------------------------------------------------------------------
179 get_disasm_info - Given an address, return information about the opcode
180   which resides there.
181   addr - address of opcode we want information on.
182   ret_len - return length of opcode.
183   ret_branch - return a character which indicates if we are
184     a branching opcode.  Used by main app to implement "Next"
185     function which steps over functions.
186   immed_offset - return a number which represents the number of bytes
187     offset to where any immediate data is(tail end of opcode).  Used
188     for printing disassembly.
189   operands - return a key indicating the form of the operands,
190     used for printing the disassembly.
191   mnemonic - return a key indicating the mnemonic of the instruction.
192
193   Return value: Return the operand code formed by either the single
194   byte opcode or 2 bytes of the opcode for multi-byte opcodes.
195
196   Note: Any of the return pointer parameters can be set to NULL to
197     indicate the caller does not want the information.
198 |--------------------------------------------------------------------*/
199 int
200 cl_xa::get_disasm_info(t_addr addr,
201                        int *ret_len,
202                        int *ret_branch,
203                        int *immed_offset,
204                        int *parms,
205                        int *mnemonic)
206 {
207   uint code;
208   int len = 0;
209   int immed_n = 0;
210   int i;
211   int start_addr = addr;
212
213   code= get_mem(MEM_ROM, addr++);
214   if (code == 0x00) {
215     i= 0;
216     while (disass_xa[i].mnemonic != NOP)
217       i++;
218   } else {
219     len = 2;
220     code = (code << 8) | get_mem(MEM_ROM, addr++);
221     i= 0;
222     while ((code & disass_xa[i].mask) != disass_xa[i].code &&
223            disass_xa[i].mnemonic != BAD_OPCODE)
224       i++;
225   }
226
227   if (ret_len)
228     *ret_len = disass_xa[i].length;
229   if (ret_branch)
230    *ret_branch = disass_xa[i].branch;
231   if (immed_offset) {
232     if (immed_n > 0)
233          *immed_offset = immed_n;
234     else *immed_offset = (addr - start_addr);
235   }
236   if (parms) {
237     *parms = disass_xa[i].operands;
238   }
239   if (mnemonic) {
240     *mnemonic = disass_xa[i].mnemonic;
241   }
242
243   return code;
244 }
245
246 static char *w_reg_strs[] = {
247  "R0", "R1",
248  "R2", "R3",
249  "R4", "R5",
250  "R6", "R7",
251  "R8", "R9",
252  "R10", "R11",
253  "R12", "R13",
254  "R14", "R15"};
255
256 static char *b_reg_strs[] = {
257  "R0l", "R0h",
258  "R1l", "R1h",
259  "R2l", "R2h",
260  "R3l", "R3h",
261  "R4l", "R4h",
262  "R5l", "R5h",
263  "R6l", "R6h",
264  "R7l", "R7h"};
265
266 /*--------------------------------------------------------------------
267 disass - Disassemble an opcode.
268     addr - address of opcode to disassemble/print.
269     sep - optionally points to string(tab) to use as separator.
270 |--------------------------------------------------------------------*/
271 char *
272 cl_xa::disass(t_addr addr, char *sep)
273 {
274   char work[256], parm_str[40];
275   char *buf, *p, *b;
276   int code;
277   int len = 0;
278   int immed_offset = 0;
279   int operands;
280   int mnemonic;
281   char **reg_strs;
282
283   p= work;
284
285   code = get_disasm_info(addr, &len, NULL, &immed_offset, &operands, &mnemonic);
286
287   if (mnemonic == BAD_OPCODE) {
288     buf= (char*)malloc(30);
289     strcpy(buf, "UNKNOWN/INVALID");
290     return(buf);
291   }
292
293   if (code & 0x0800)
294     reg_strs = w_reg_strs;
295   else
296     reg_strs = b_reg_strs;
297
298   switch(operands) {
299      // the repeating common parameter encoding for ADD, ADDC, SUB, AND...
300     case REG_REG :
301       sprintf(parm_str, "%s,%s",
302               reg_strs[((code >> 4) & 0xf)],
303               reg_strs[(code & 0xf)]);
304     break;
305     case REG_IREG :
306       sprintf(parm_str, "%s,[%s]",
307               reg_strs[((code >> 4) & 0xf)],
308               w_reg_strs[(code & 0xf)]);
309     break;
310     case IREG_REG :
311       sprintf(parm_str, "[%s],%s",
312               w_reg_strs[(code & 0x7)],
313               reg_strs[((code >> 4) & 0xf)] );
314     break;
315     case REG_IREGOFF8 :
316       sprintf(parm_str, "%s,[%s+%02d]",
317               reg_strs[((code >> 4) & 0xf)],
318               w_reg_strs[(code & 0x7)],
319               get_mem(MEM_ROM, addr+immed_offset));
320       ++immed_offset;
321     break;
322     case IREGOFF8_REG :
323       sprintf(parm_str, "[%s+%02d],%s",
324               w_reg_strs[(code & 0x7)],
325               get_mem(MEM_ROM, addr+immed_offset),
326               reg_strs[((code >> 4) & 0xf)] );
327       ++immed_offset;
328     break;
329     case REG_IREGOFF16 :
330       sprintf(parm_str, "%s,[%s+%04d]",
331               reg_strs[((code >> 4) & 0xf)],
332               w_reg_strs[(code & 0x7)],
333               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
334                      (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
335       ++immed_offset;
336       ++immed_offset;
337     break;
338     case IREGOFF16_REG :
339       sprintf(parm_str, "[%s+%04d],%s",
340               w_reg_strs[(code & 0x7)],
341               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
342                      (get_mem(MEM_ROM, addr+immed_offset)<<8)),
343               reg_strs[((code >> 4) & 0xf)] );
344       ++immed_offset;
345       ++immed_offset;
346     break;
347     case REG_IREGINC :
348       sprintf(parm_str, "%s,[%s+]",
349               reg_strs[((code >> 4) & 0xf)],
350               w_reg_strs[(code & 0xf)]);
351     break;
352     case IREGINC_REG :
353       sprintf(parm_str, "[%s+],%s",
354               w_reg_strs[(code & 0x7)],
355               reg_strs[((code >> 4) & 0xf)] );
356     break;
357     case DIRECT_REG :
358       sprintf(parm_str, "%s,%s",
359               get_dir_name(((code & 0x7) << 8) | 
360                            get_mem(MEM_ROM, addr+immed_offset)),
361               reg_strs[((code >> 4) & 0xf)] );
362       ++immed_offset;
363     break;
364     case REG_DIRECT :
365       sprintf(parm_str, "%s,%s",
366               reg_strs[((code >> 4) & 0xf)], 
367               get_dir_name(((code & 0x7) << 8) | 
368                            get_mem(MEM_ROM, addr+immed_offset)));
369       ++immed_offset;
370     break;
371     case REG_DATA8 :
372       sprintf(parm_str, "%s,#0x%02x",
373               b_reg_strs[((code >> 4) & 0xf)],
374               get_mem(MEM_ROM, addr+immed_offset) );
375       ++immed_offset;
376     break;
377     case REG_DATA16 :
378       sprintf(parm_str, "%s,#0x%04x",
379               reg_strs[((code >> 4) & 0xf)],
380               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
381                      (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
382       ++immed_offset;
383       ++immed_offset;
384     break;
385     case IREG_DATA8 :
386       sprintf(parm_str, "[%s], 0x%02x",
387               w_reg_strs[((code >> 4) & 0x7)],
388               get_mem(MEM_ROM, addr+immed_offset) );
389       ++immed_offset;
390     break;
391     case IREG_DATA16 :
392       sprintf(parm_str, "[%s], 0x%04x",
393               w_reg_strs[((code >> 4) & 0x7)],
394               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
395                      (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
396       ++immed_offset;
397       ++immed_offset;
398     break;
399     case IREGINC_DATA8 :
400       sprintf(parm_str, "[%s+], 0x%02x",
401               w_reg_strs[((code >> 4) & 0x7)],
402               get_mem(MEM_ROM, addr+immed_offset) );
403       ++immed_offset;
404     break;
405     case IREGINC_DATA16 :
406       sprintf(parm_str, "[%s+], 0x%04x",
407               w_reg_strs[((code >> 4) & 0x7)],
408               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
409                      (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
410       ++immed_offset;
411       ++immed_offset;
412     break;
413     case IREGOFF8_DATA8 :
414       sprintf(parm_str, "[%s+%02d], 0x%02x",
415               w_reg_strs[((code >> 4) & 0x7)],
416               get_mem(MEM_ROM, addr+immed_offset),
417               get_mem(MEM_ROM, addr+immed_offset+1) );
418       immed_offset += 2;
419     break;
420     case IREGOFF8_DATA16 :
421       sprintf(parm_str, "[%s+%02d], 0x%04x",
422               w_reg_strs[((code >> 4) & 0x7)],
423               get_mem(MEM_ROM, addr+immed_offset),
424               (short)((get_mem(MEM_ROM, addr+immed_offset+2)) |
425                      (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) );
426       immed_offset += 3;
427     break;
428     case IREGOFF16_DATA8 :
429       sprintf(parm_str, "[%s+%04d], 0x%02x",
430               w_reg_strs[((code >> 4) & 0x7)],
431               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
432                      (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
433               get_mem(MEM_ROM, addr+immed_offset+2) );
434       immed_offset += 3;
435     break;
436     case IREGOFF16_DATA16 :
437       sprintf(parm_str, "[%s+%04d], 0x%04x",
438               w_reg_strs[((code >> 4) & 0x7)],
439               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
440                      (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
441               (short)((get_mem(MEM_ROM, addr+immed_offset+3)) |
442                      (get_mem(MEM_ROM, addr+immed_offset+2)<<8)) );
443       immed_offset += 4;
444     break;
445     case DIRECT_DATA8 :
446       sprintf(parm_str, "%s,#0x%02x",
447               get_dir_name(((code & 0x0070) << 4) | 
448                            get_mem(MEM_ROM, addr+immed_offset)),
449               get_mem(MEM_ROM, addr+immed_offset+1));
450       immed_offset += 3;
451     break;
452     case DIRECT_DATA16 :
453       sprintf(parm_str, "%s,#0x%04x",
454               get_dir_name(((code & 0x0070) << 4) | 
455                            get_mem(MEM_ROM, addr+immed_offset)),
456               get_mem(MEM_ROM, addr+immed_offset+2) +
457               (get_mem(MEM_ROM, addr+immed_offset+1)<<8));
458       immed_offset += 3;
459     break;
460
461 // odd-ball ones
462     case NO_OPERANDS :  // for NOP
463       strcpy(parm_str, "");
464     break;
465     case C_BIT :
466       strcpy(parm_str, "C_BIT");
467     break;
468     case REG_DATA4 :
469       strcpy(parm_str, "REG_DATA4");
470     break;
471     case IREG_DATA4 :
472       strcpy(parm_str, "IREG_DATA4");
473     break;
474     case IREGINC_DATA4 :
475       strcpy(parm_str, "IREGINC_DATA4");
476     break;
477     case IREGOFF8_DATA4 :
478       strcpy(parm_str, "IREGOFF8_DATA4");
479     break;
480     case IREGOFF16_DATA4 :
481       strcpy(parm_str, "IREGOFF16_DATA4");
482     break;
483     case DIRECT_DATA4 :
484       sprintf(parm_str, "%s,#0x%x",
485               get_dir_name(((code & 0x70)<<4) |
486                            get_mem(MEM_ROM, addr+2)),
487               code&0x0f);
488     break;
489     case DIRECT :
490       sprintf(parm_str, "%s",
491               get_dir_name(((code & 0x007) << 4) + 
492                            get_mem(MEM_ROM, addr+2)));
493     break;
494     case REG :
495       sprintf(parm_str, "%s",
496               reg_strs[((code >> 4) & 0xf)] );
497     break;
498     case IREG :
499       sprintf(parm_str, "[%s]",
500               reg_strs[((code >> 4) & 0xf)] );
501     break;
502     case BIT_ALONE :
503       sprintf(parm_str, "%s",
504               get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2)));
505     break;
506     case BIT_REL8 :
507       sprintf(parm_str, "%s,0x%04x",
508               get_bit_name((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2),
509               ((signed char)get_mem(MEM_ROM, addr+3)*2+addr+len)&0xfffe);
510     break;
511     case ADDR24 :
512       strcpy(parm_str, "ADDR24");
513     break;
514     case REG_REL8 :
515       sprintf(parm_str, "%s,0x%04x",
516               reg_strs[(code>>4) & 0xf],
517               ((signed char)get_mem(MEM_ROM, addr+2)*2+addr+len)&0xfffe);
518     break;
519     case DIRECT_REL8 :
520       sprintf(parm_str, "%s,0x%04x",
521               get_dir_name(((code&0x07)<<8) +
522                            get_mem(MEM_ROM, addr+2)),
523               ((signed char)get_mem(MEM_ROM, addr+2)*2+addr+len)&0xfffe);
524     break;
525
526     case REL8 :
527       sprintf(parm_str, "0x%04x",
528               ((signed char)get_mem(MEM_ROM, addr+1)*2+addr+len)&0xfffe);
529     break;
530     case REL16 :
531       sprintf(parm_str, "0x%04x",
532               ((signed short)((get_mem(MEM_ROM, addr+1)<<8) + get_mem(MEM_ROM, addr+2))*2+addr+len)&0xfffe);
533     break;
534
535     case RLIST :
536       strcpy(parm_str, "RLIST");
537     break;
538
539     case REG_DIRECT_REL8 :
540       sprintf(parm_str, "%s,%s,0x%02x",
541               reg_strs[((code >> 4) & 0xf)],
542               get_dir_name(((code & 0x7) << 8) + 
543                            get_mem(MEM_ROM, addr+immed_offset)),
544               ((signed char) get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
545     break;
546     case REG_DATA8_REL8 :
547       sprintf(parm_str, "%s,#0x%04x,0x%02x",
548               reg_strs[((code >> 4) & 0xf)],
549               get_mem(MEM_ROM, addr+immed_offset),
550               ((signed char)get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
551     break;
552     case REG_DATA16_REL8 :
553       sprintf(parm_str, "%s,#0x%02x,0x%02x",
554               w_reg_strs[((code >> 4) & 0x7)*2],
555               get_mem(MEM_ROM, addr+immed_offset+1) +
556                  (get_mem(MEM_ROM, addr+immed_offset+0)<<8),
557               ((signed char)get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe );
558     break;
559     case IREG_DATA8_REL8 :
560       sprintf(parm_str, "[%s],#0x%04x,0x%02x",
561               reg_strs[((code >> 4) & 0x7)],
562               get_mem(MEM_ROM, addr+immed_offset),
563               ((signed char)get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
564     break;
565     case IREG_DATA16_REL8 :
566       sprintf(parm_str, "[%s],#0x%02x,0x%02x",
567               w_reg_strs[((code >> 4) & 0x7)*2],
568               get_mem(MEM_ROM, addr+immed_offset+1) +
569                  (get_mem(MEM_ROM, addr+immed_offset+0)<<8),
570               ((signed char)get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe );
571     break;
572
573     default:
574       strcpy(parm_str, "???");
575     break;
576   }
577
578   sprintf(work, "%s %s",
579           op_mnemonic_str[ mnemonic ],
580           parm_str);
581
582   p= strchr(work, ' ');
583   if (!p)
584     {
585       buf= strdup(work);
586       return(buf);
587     }
588   if (sep == NULL)
589     buf= (char *)malloc(6+strlen(p)+1);
590   else
591     buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
592   for (p= work, b= buf; *p != ' '; p++, b++)
593     *b= *p;
594   p++;
595   *b= '\0';
596   if (sep == NULL)
597     {
598       while (strlen(buf) < 6)
599         strcat(buf, " ");
600     }
601   else
602     strcat(buf, sep);
603   strcat(buf, p);
604   return(buf);
605 }
606
607 /*--------------------------------------------------------------------
608  print_regs - Print the registers, flags and other useful information.
609    Used to print a status line while stepping through the code.
610 |--------------------------------------------------------------------*/
611 void
612 cl_xa::print_regs(class cl_console *con)
613 {
614   unsigned char flags;
615
616   flags = get_psw();
617   con->dd_printf("CA---VNZ  Flags: %02x ", flags);
618   con->dd_printf("R0:%04x R1:%04x R2:%04x R3:%04x\n",
619                  reg2(0), reg2(1), reg2(2), reg2(3));
620
621   con->dd_printf("%c%c---%c%c%c            ",
622          (flags & BIT_C)?'1':'0',
623          (flags & BIT_AC)?'1':'0',
624          (flags & BIT_V)?'1':'0',
625          (flags & BIT_N)?'1':'0',
626          (flags & BIT_Z)?'1':'0');
627
628   con->dd_printf("R4:%04x R5:%04x R6:%04x R7(SP):%04x ES:%04x  DS:%04x\n",
629                  reg2(4), reg2(5), reg2(6), reg2(7), 0, 0);
630
631   print_disass(PC, con);
632 }
633
634
635 /*--------------------------------------------------------------------
636  exec_inst - Called to implement simulator execution of 1 instruction
637    at the current PC(program counter) address.
638 |--------------------------------------------------------------------*/
639 int cl_xa::exec_inst(void)
640 {
641   t_mem code1;
642   uint code;
643   int i;
644   int operands;
645
646   if (fetch(&code1))
647     return(resBREAKPOINT);
648   tick(1);
649
650 /* the following lookups make for a slow simulation, we will
651   figure out how to make it fast later... */
652
653   /* scan to see if its a 1 byte-opcode */
654   code = (code1 << 8);
655   i= 0;
656   while ( ((code & disass_xa[i].mask) != disass_xa[i].code ||
657            ((disass_xa[i].mask & 0x00ff) != 0)) /* one byte op code */
658                     &&
659          disass_xa[i].mnemonic != BAD_OPCODE)
660     i++;
661
662   if (disass_xa[i].mnemonic == BAD_OPCODE) {
663     /* hit the end of the list, must be a 2 or more byte opcode */
664     /* fetch another code byte and search the list again */
665       //if (fetch(&code2))  ?not sure if break allowed in middle of opcode?
666       //  return(resBREAKPOINT);
667     code |= fetch();  /* add 2nd opcode */
668
669     i= 0;
670     while ((code & disass_xa[i].mask) != disass_xa[i].code &&
671            disass_xa[i].mnemonic != BAD_OPCODE)
672       i++;
673     /* we should have found the opcode by now, if not invalid entry at eol */
674   }
675
676   operands = (int)(disass_xa[i].operands);
677   switch (disass_xa[i].mnemonic)
678   {
679     case ADD:
680     return inst_ADD(code, operands);
681     case ADDC:
682     return inst_ADDC(code, operands);
683     case ADDS:
684     return inst_ADDS(code, operands);
685     case AND:
686     return inst_AND(code, operands);
687     case ANL:
688     return inst_ANL(code, operands);
689     case ASL:
690     return inst_ASL(code, operands);
691     case ASR:
692     return inst_ASR(code, operands);
693     case BCC:
694     return inst_BCC(code, operands);
695     case BCS:
696     return inst_BCS(code, operands);
697     case BEQ:
698     return inst_BEQ(code, operands);
699     case BG:
700     return inst_BG(code, operands);
701     case BGE:
702     return inst_BGE(code, operands);
703     case BGT:
704     return inst_BGT(code, operands);
705     case BKPT:
706     return inst_BKPT(code, operands);
707     case BL:
708     return inst_BL(code, operands);
709     case BLE:
710     return inst_BLE(code, operands);
711     case BLT:
712     return inst_BLT(code, operands);
713     case BMI:
714     return inst_BMI(code, operands);
715     case BNE:
716     return inst_BNE(code, operands);
717     case BNV:
718     return inst_BNV(code, operands);
719     case BOV:
720     return inst_BOV(code, operands);
721     case BPL:
722     return inst_BPL(code, operands);
723     case BR:
724     return inst_BR(code, operands);
725     case CALL:
726     return inst_CALL(code, operands);
727     case CJNE:
728     return inst_CJNE(code, operands);
729     case CLR:
730     return inst_CLR(code, operands);
731     case CMP:
732     return inst_CMP(code, operands);
733     case CPL:
734     return inst_CPL(code, operands);
735     case DA:
736     return inst_DA(code, operands);
737     case DIV_w :
738     case DIV_d :
739     case DIVU_b:
740     case DIVU_w:
741     case DIVU_d:
742     return inst_DIV(code, operands);
743     case DJNZ:
744     return inst_DJNZ(code, operands);
745     case FCALL:
746     return inst_FCALL(code, operands);
747     case FJMP:
748     return inst_FJMP(code, operands);
749     case JB:
750     return inst_JB(code, operands);
751     case JBC:
752     return inst_JBC(code, operands);
753     case JMP:
754     return inst_JMP(code, operands);
755     case JNB:
756     return inst_JNB(code, operands);
757     case JNZ:
758     return inst_JNZ(code, operands);
759     case JZ:
760     return inst_JZ(code, operands);
761     case LEA:
762     return inst_LEA(code, operands);
763     case LSR:
764     return inst_LSR(code, operands);
765     case MOV:
766     return inst_MOV(code, operands);
767     case MOVC:
768     return inst_MOVC(code, operands);
769     case MOVS:
770     return inst_MOVS(code, operands);
771     case MOVX:
772     return inst_MOVX(code, operands);
773     case MUL_w:
774     case MULU_b:
775     case MULU_w:
776     return inst_MUL(code, operands);
777     case NEG:
778     return inst_NEG(code, operands);
779     case NOP:
780     return inst_NOP(code, operands);
781     case NORM:
782     return inst_NORM(code, operands);
783     case OR:
784     return inst_OR(code, operands);
785     case ORL:
786     return inst_ORL(code, operands);
787     case POP:
788     case POPU:
789     return inst_POP(code, operands);
790     case PUSH:
791     case PUSHU:
792     return inst_PUSH(code, operands);
793     case RESET:
794     return inst_RESET(code, operands);
795     case RET:
796     return inst_RET(code, operands);
797     case RETI:
798     return inst_RETI(code, operands);
799     case RL:
800     return inst_RL(code, operands);
801     case RLC:
802     return inst_RLC(code, operands);
803     case RR:
804     return inst_RR(code, operands);
805     case RRC:
806     return inst_RRC(code, operands);
807     case SETB:
808     return inst_SETB(code, operands);
809     case SEXT:
810     return inst_SEXT(code, operands);
811     case SUB:
812     return inst_SUB(code, operands);
813     case SUBB:
814     return inst_SUBB(code, operands);
815     case TRAP:
816     return inst_TRAP(code, operands);
817     case XCH:
818     return inst_XCH(code, operands);
819     case XOR:
820     return inst_XOR(code, operands);
821
822     case BAD_OPCODE:
823     default:
824     break;
825   }
826
827   if (PC)
828     PC--;
829   else
830     PC= get_mem_size(MEM_ROM)-1;
831   //tick(-clock_per_cycle());
832   sim->stop(resINV_INST);
833   return(resINV_INST);
834 }
835
836
837 /* End of xa.src/xa.cc */