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