9e65740fa816b1a85b3959a7c45b8a6f03a6fa91
[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*2, 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 -
161 |--------------------------------------------------------------------*/
162 int
163 cl_xa::get_disasm_info(t_addr addr,
164                        int *ret_len,
165                        int *ret_branch,
166                        int *immed_offset,
167                        int *parms,
168                        int *mnemonic)
169 {
170   uint code;
171   int len = 0;
172   int immed_n = 0;
173   int i;
174   int start_addr = addr;
175
176   code= get_mem(MEM_ROM, addr++);
177   if (code == 0x00) {
178     i= 0;
179     while (disass_xa[i].mnemonic != NOP)
180       i++;
181   } else {
182     len = 2;
183     code = (code << 8) | get_mem(MEM_ROM, addr++);
184     i= 0;
185     while ((code & disass_xa[i].mask) != disass_xa[i].code &&
186            disass_xa[i].mnemonic != BAD_OPCODE)
187       i++;
188   }
189
190   if (ret_len)
191     *ret_len = disass_xa[i].length;
192   if (ret_branch)
193    *ret_branch = disass_xa[i].branch;
194   if (immed_offset) {
195     if (immed_n > 0)
196          *immed_offset = immed_n;
197     else *immed_offset = (addr - start_addr);
198   }
199   if (parms) {
200     *parms = disass_xa[i].operands;
201   }
202   if (mnemonic) {
203     *mnemonic = disass_xa[i].mnemonic;
204   }
205
206   return code;
207 }
208
209 static char *w_reg_strs[] = {
210  "R0", "R1",
211  "R2", "R3",
212  "R4", "R5",
213  "R6", "R7",
214  "R8", "R9",
215  "R10", "R11",
216  "R12", "R13",
217  "R14", "R15"};
218
219 static char *b_reg_strs[] = {
220  "R0l", "R0h",
221  "R1l", "R1h",
222  "R2l", "R2h",
223  "R3l", "R3h",
224  "R4l", "R4h",
225  "R5l", "R5h",
226  "R6l", "R6h",
227  "R7l", "R7h"};
228
229 /*--------------------------------------------------------------------
230 disass -
231 |--------------------------------------------------------------------*/
232 char *
233 cl_xa::disass(t_addr addr, char *sep)
234 {
235   char work[256], parm_str[40];
236   char *buf, *p, *b;
237   int code;
238   int len = 0;
239   int immed_offset = 0;
240   int operands;
241   int mnemonic;
242   char **reg_strs;
243
244   p= work;
245
246   code = get_disasm_info(addr, &len, NULL, &immed_offset, &operands, &mnemonic);
247
248   if (mnemonic == BAD_OPCODE) {
249     buf= (char*)malloc(30);
250     strcpy(buf, "UNKNOWN/INVALID");
251     return(buf);
252   }
253
254   if (code & 0x0800)
255     reg_strs = w_reg_strs;
256   else
257     reg_strs = b_reg_strs;
258
259   switch(operands) {
260      // the repeating common parameter encoding for ADD, ADDC, SUB, AND...
261     case REG_REG :
262       sprintf(parm_str, "%s,%s",
263               reg_strs[((code >> 4) & 0xf)],
264               reg_strs[(code & 0xf)]);
265     break;
266     case REG_IREG :
267       sprintf(parm_str, "%s,[%s]",
268               reg_strs[((code >> 4) & 0xf)],
269               w_reg_strs[(code & 0xf)]);
270     break;
271     case IREG_REG :
272       sprintf(parm_str, "[%s],%s",
273               w_reg_strs[(code & 0x7)],
274               reg_strs[((code >> 4) & 0xf)] );
275     break;
276     case REG_IREGOFF8 :
277       sprintf(parm_str, "%s,[%s+%02d]",
278               reg_strs[((code >> 4) & 0xf)],
279               w_reg_strs[(code & 0x7)],
280               get_mem(MEM_ROM, addr+immed_offset));
281       ++immed_offset;
282     break;
283     case IREGOFF8_REG :
284       sprintf(parm_str, "[%s+%02d],%s",
285               w_reg_strs[(code & 0x7)],
286               get_mem(MEM_ROM, addr+immed_offset),
287               reg_strs[((code >> 4) & 0xf)] );
288       ++immed_offset;
289     break;
290     case REG_IREGOFF16 :
291       sprintf(parm_str, "%s,[%s+%04d]",
292               reg_strs[((code >> 4) & 0xf)],
293               w_reg_strs[(code & 0x7)],
294               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
295                      (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
296       ++immed_offset;
297       ++immed_offset;
298     break;
299     case IREGOFF16_REG :
300       sprintf(parm_str, "[%s+%04d],%s",
301               w_reg_strs[(code & 0x7)],
302               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
303                      (get_mem(MEM_ROM, addr+immed_offset)<<8)),
304               reg_strs[((code >> 4) & 0xf)] );
305       ++immed_offset;
306       ++immed_offset;
307     break;
308     case REG_IREGINC :
309       sprintf(parm_str, "%s,[%s+]",
310               reg_strs[((code >> 4) & 0xf)],
311               w_reg_strs[(code & 0xf)]);
312     break;
313     case IREGINC_REG :
314       sprintf(parm_str, "[%s+],%s",
315               w_reg_strs[(code & 0x7)],
316               reg_strs[((code >> 4) & 0xf)] );
317     break;
318     case DIRECT_REG :
319       sprintf(parm_str, "0x%03x,%s",
320               ((code & 0x7) << 8) | get_mem(MEM_ROM, addr+immed_offset),
321               reg_strs[((code >> 4) & 0xf)] );
322       ++immed_offset;
323     break;
324     case REG_DIRECT :
325       sprintf(parm_str, "%s,0x%03x",
326               reg_strs[((code >> 4) & 0xf)],
327               ((code & 0x7) << 8) + get_mem(MEM_ROM, addr+immed_offset) );
328       ++immed_offset;
329     break;
330     case REG_DATA8 :
331       sprintf(parm_str, "%s,#0x%02x",
332               b_reg_strs[((code >> 4) & 0xf)],
333               get_mem(MEM_ROM, addr+immed_offset) );
334       ++immed_offset;
335     break;
336     case REG_DATA16 :
337       sprintf(parm_str, "%s,#0x%04x",
338               reg_strs[((code >> 4) & 0xf)],
339               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
340                      (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
341       ++immed_offset;
342       ++immed_offset;
343     break;
344     case IREG_DATA8 :
345       sprintf(parm_str, "[%s], 0x%02x",
346               w_reg_strs[((code >> 4) & 0x7)],
347               get_mem(MEM_ROM, addr+immed_offset) );
348       ++immed_offset;
349     break;
350     case IREG_DATA16 :
351       sprintf(parm_str, "[%s], 0x%04x",
352               w_reg_strs[((code >> 4) & 0x7)],
353               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
354                      (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
355       ++immed_offset;
356       ++immed_offset;
357     break;
358     case IREGINC_DATA8 :
359       sprintf(parm_str, "[%s+], 0x%02x",
360               w_reg_strs[((code >> 4) & 0x7)],
361               get_mem(MEM_ROM, addr+immed_offset) );
362       ++immed_offset;
363     break;
364     case IREGINC_DATA16 :
365       sprintf(parm_str, "[%s+], 0x%04x",
366               w_reg_strs[((code >> 4) & 0x7)],
367               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
368                      (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
369       ++immed_offset;
370       ++immed_offset;
371     break;
372     case IREGOFF8_DATA8 :
373       sprintf(parm_str, "[%s+%02d], 0x%02x",
374               w_reg_strs[((code >> 4) & 0x7)],
375               get_mem(MEM_ROM, addr+immed_offset),
376               get_mem(MEM_ROM, addr+immed_offset+1) );
377       immed_offset += 2;
378     break;
379     case IREGOFF8_DATA16 :
380       sprintf(parm_str, "[%s+%02d], 0x%04x",
381               w_reg_strs[((code >> 4) & 0x7)],
382               get_mem(MEM_ROM, addr+immed_offset),
383               (short)((get_mem(MEM_ROM, addr+immed_offset+2)) |
384                      (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) );
385       immed_offset += 3;
386     break;
387     case IREGOFF16_DATA8 :
388       sprintf(parm_str, "[%s+%04d], 0x%02x",
389               w_reg_strs[((code >> 4) & 0x7)],
390               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
391                      (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
392               get_mem(MEM_ROM, addr+immed_offset+2) );
393       immed_offset += 3;
394     break;
395     case IREGOFF16_DATA16 :
396       sprintf(parm_str, "[%s+%04d], 0x%04x",
397               w_reg_strs[((code >> 4) & 0x7)],
398               (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
399                      (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
400               (short)((get_mem(MEM_ROM, addr+immed_offset+3)) |
401                      (get_mem(MEM_ROM, addr+immed_offset+2)<<8)) );
402       immed_offset += 4;
403     break;
404     case DIRECT_DATA8 :
405       sprintf(parm_str, "0x%03x,#0x%02x",
406               ((code & 0x0070) << 4) | get_mem(MEM_ROM, addr+immed_offset),
407               get_mem(MEM_ROM, addr+immed_offset+1));
408       immed_offset += 3;
409     break;
410     case DIRECT_DATA16 :
411       sprintf(parm_str, "%0x03x,#0x%04x",
412               ((code & 0x0070) << 4) | get_mem(MEM_ROM, addr+immed_offset),
413               get_mem(MEM_ROM, addr+immed_offset+2) +
414               (get_mem(MEM_ROM, addr+immed_offset+1)<<8));
415       immed_offset += 3;
416     break;
417
418 // odd-ball ones
419     case NO_OPERANDS :  // for NOP
420       strcpy(parm_str, "");
421     break;
422     case C_BIT :
423       strcpy(parm_str, "C_BIT");
424     break;
425     case REG_DATA4 :
426       strcpy(parm_str, "REG_DATA4");
427     break;
428     case IREG_DATA4 :
429       strcpy(parm_str, "IREG_DATA4");
430     break;
431     case IREGINC_DATA4 :
432       strcpy(parm_str, "IREGINC_DATA4");
433     break;
434     case IREGOFF8_DATA4 :
435       strcpy(parm_str, "IREGOFF8_DATA4");
436     break;
437     case IREGOFF16_DATA4 :
438       strcpy(parm_str, "IREGOFF16_DATA4");
439     break;
440     case DIRECT_DATA4 :
441       strcpy(parm_str, "DIRECT_DATA4");
442     break;
443     case DIRECT_ALONE :
444       sprintf(parm_str, "0x%03x",
445               ((code & 0x007) << 4) + get_mem(MEM_ROM, addr+2));
446     break;
447     case REG_ALONE :
448       sprintf(parm_str, "%s",
449               reg_strs[((code >> 4) & 0xf)] );
450     break;
451     case IREG_ALONE :
452       sprintf(parm_str, "[%s]",
453               reg_strs[((code >> 4) & 0xf)] );
454     break;
455     case BIT_ALONE :
456       sprintf(parm_str, "0x%03x",
457               ((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2));
458     break;
459     case BIT_REL8 :
460       sprintf(parm_str, "0x%03x,0x%04x",
461               ((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2),
462               ((signed char)get_mem(MEM_ROM, addr+3)*2+addr+len)&0xfffe);
463     break;
464     case ADDR24 :
465       strcpy(parm_str, "ADDR24");
466     break;
467     case REG_REL8 :
468       //strcpy(parm_str, "REG_REL8");
469       sprintf(parm_str, "%s,0x%04x",
470               reg_strs[(code>>4) & 0xf],
471               ((signed char)get_mem(MEM_ROM, addr+2)*2+addr+len)&0xfffe);
472     break;
473     case DIRECT_REL8 :
474       strcpy(parm_str, "DIRECT_REL8");
475     break;
476
477     case REL8 :
478       //strcpy(parm_str, "REL8");
479       sprintf(parm_str, "0x%04x",
480               ((signed char)get_mem(MEM_ROM, addr+1)*2+addr+len)&0xfffe);
481     break;
482     case REL16 :
483       //strcpy(parm_str, "REL16");
484       sprintf(parm_str, "0x%04x",
485               ((signed short)((get_mem(MEM_ROM, addr+1)<<8) + get_mem(MEM_ROM, addr+2))*2+addr+len)&0xfffe);
486     break;
487
488     case RLIST :
489       strcpy(parm_str, "RLIST");
490     break;
491
492     case REG_DIRECT_REL8 :
493       sprintf(parm_str, "%s,0x%02x,0x%02x",
494               reg_strs[((code >> 4) & 0xf)],
495               ((code & 0x7) << 8) + get_mem(MEM_ROM, addr+immed_offset),
496               (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
497     break;
498     case REG_DATA8_REL8 :
499       sprintf(parm_str, "%s,#0x%04x,0x%02x",
500               reg_strs[((code >> 4) & 0xf)],
501               get_mem(MEM_ROM, addr+immed_offset),
502               (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
503     break;
504     case REG_DATA16_REL8 :
505       sprintf(parm_str, "%s,#0x%02x,0x%02x",
506               w_reg_strs[((code >> 4) & 0x7)*2],
507               get_mem(MEM_ROM, addr+immed_offset+1) +
508                  (get_mem(MEM_ROM, addr+immed_offset+0)<<8),
509               (get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe );
510     break;
511     case IREG_DATA8_REL8 :
512       sprintf(parm_str, "[%s],#0x%04x,0x%02x",
513               reg_strs[((code >> 4) & 0x7)],
514               get_mem(MEM_ROM, addr+immed_offset),
515               (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
516     break;
517     case IREG_DATA16_REL8 :
518       sprintf(parm_str, "[%s],#0x%02x,0x%02x",
519               w_reg_strs[((code >> 4) & 0x7)*2],
520               get_mem(MEM_ROM, addr+immed_offset+1) +
521                  (get_mem(MEM_ROM, addr+immed_offset+0)<<8),
522               (get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe );
523     break;
524
525     default:
526       strcpy(parm_str, "???");
527     break;
528   }
529
530   sprintf(work, "%s %s",
531           op_mnemonic_str[ mnemonic ],
532           parm_str);
533
534   p= strchr(work, ' ');
535   if (!p)
536     {
537       buf= strdup(work);
538       return(buf);
539     }
540   if (sep == NULL)
541     buf= (char *)malloc(6+strlen(p)+1);
542   else
543     buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
544   for (p= work, b= buf; *p != ' '; p++, b++)
545     *b= *p;
546   p++;
547   *b= '\0';
548   if (sep == NULL)
549     {
550       while (strlen(buf) < 6)
551         strcat(buf, " ");
552     }
553   else
554     strcat(buf, sep);
555   strcat(buf, p);
556   return(buf);
557 }
558
559 /*--------------------------------------------------------------------
560  print_regs -
561 |--------------------------------------------------------------------*/
562 void
563 cl_xa::print_regs(class cl_console *con)
564 {
565   unsigned char flags;
566
567   flags = get_psw();
568   con->dd_printf("CA---VNZ  Flags: %02x ", flags);
569   con->dd_printf("R0:%04x R1:%04x R2:%04x R3:%04x\n",
570                  get_reg(1,0), get_reg(1,2), get_reg(1,4), get_reg(1,6));
571
572   con->dd_printf("%c%c---%c%c%c            ",
573          (flags & BIT_C)?'1':'0',
574          (flags & BIT_AC)?'1':'0',
575          (flags & BIT_V)?'1':'0',
576          (flags & BIT_N)?'1':'0',
577          (flags & BIT_Z)?'1':'0');
578
579   con->dd_printf("R4:%04x R5:%04x R6:%04x R7(SP):%04x ES:%04x  DS:%04x\n",
580             get_reg(1,8), get_reg(1,10), get_reg(1,12), get_reg(1,14), 0, 0);
581
582   print_disass(PC, con);
583 }
584
585
586 /*
587  * Execution
588  */
589
590 int
591 cl_xa::exec_inst(void)
592 {
593   t_mem code1;
594   uint code;
595   int i;
596   int operands;
597
598   if (fetch(&code1))
599     return(resBREAKPOINT);
600   tick(1);
601
602 /* the following lookups make for a slow simulation, we will
603   figure out how to make it fast later... */
604
605   /* scan to see if its a 1 byte-opcode */
606   code = (code1 << 8);
607   i= 0;
608   while ( ((code & disass_xa[i].mask) != disass_xa[i].code ||
609            ((disass_xa[i].mask & 0x00ff) != 0)) /* one byte op code */
610                     &&
611          disass_xa[i].mnemonic != BAD_OPCODE)
612     i++;
613
614   if (disass_xa[i].mnemonic == BAD_OPCODE) {
615     /* hit the end of the list, must be a 2 or more byte opcode */
616     /* fetch another code byte and search the list again */
617       //if (fetch(&code2))  ?not sure if break allowed in middle of opcode?
618       //  return(resBREAKPOINT);
619     code |= fetch();  /* add 2nd opcode */
620
621     i= 0;
622     while ((code & disass_xa[i].mask) != disass_xa[i].code &&
623            disass_xa[i].mnemonic != BAD_OPCODE)
624       i++;
625     /* we should have found the opcode by now, if not invalid entry at eol */
626   }
627
628   operands = (int)(disass_xa[i].operands);
629   switch (disass_xa[i].mnemonic)
630   {
631     case ADD:
632     return inst_ADD(code, operands);
633     case ADDC:
634     return inst_ADDC(code, operands);
635     case SUB:
636     return inst_SUB(code, operands);
637     case SUBB:
638     return inst_SUBB(code, operands);
639     case CMP:
640     return inst_CMP(code, operands);
641     case AND:
642     return inst_AND(code, operands);
643     case OR:
644     return inst_OR(code, operands);
645     case XOR:
646     return inst_XOR(code, operands);
647     case ADDS:
648     return inst_ADDS(code, operands);
649     case NEG:
650     return inst_NEG(code, operands);
651     case SEXT:
652     return inst_SEXT(code, operands);
653     case MUL:
654     return inst_MUL(code, operands);
655     case DIV_w :
656     case DIV_d :
657     case DIVU_b:
658     case DIVU_w:
659     case DIVU_d:
660     return inst_DIV(code, operands);
661     case DA:
662     return inst_DA(code, operands);
663     case ASL:
664     return inst_ASL(code, operands);
665     case ASR:
666     return inst_ASR(code, operands);
667     case LEA:
668     return inst_LEA(code, operands);
669     case CPL:
670     return inst_CPL(code, operands);
671     case LSR:
672     return inst_LSR(code, operands);
673     case NORM:
674     return inst_NORM(code, operands);
675     case RL:
676     return inst_RL(code, operands);
677     case RLC:
678     return inst_RLC(code, operands);
679     case RR:
680     return inst_RR(code, operands);
681     case RRC:
682     return inst_RRC(code, operands);
683     case MOVS:
684     return inst_MOVS(code, operands);
685     case MOVC:
686     return inst_MOVC(code, operands);
687     case MOVX:
688     return inst_MOVX(code, operands);
689     case PUSH:
690     return inst_PUSH(code, operands);
691     case POP:
692     return inst_POP(code, operands);
693     case XCH:
694     return inst_XCH(code, operands);
695     case SETB:
696     return inst_SETB(code, operands);
697     case CLR:
698     return inst_CLR(code, operands);
699     case MOV:
700     return inst_MOV(code, operands);
701     case ANL:
702     return inst_ANL(code, operands);
703     case ORL:
704     return inst_ORL(code, operands);
705     case BEQ:
706     return inst_BEQ(code, operands);
707     case BR:
708     return inst_BR(code, operands);
709     case JMP:
710     return inst_JMP(code, operands);
711     case CALL:
712     return inst_CALL(code, operands);
713     case RET:
714     return inst_RET(code, operands);
715     case BCC:
716     return inst_Bcc(code, operands);
717     case JB:
718     return inst_JB(code, operands);
719     case JNB:
720     return inst_JNB(code, operands);
721     case CJNE:
722     return inst_CJNE(code, operands);
723     case DJNZ:
724     return inst_DJNZ(code, operands);
725     case JZ:
726     return inst_JZ(code, operands);
727     case JNZ:
728     return inst_JNZ(code, operands);
729     case NOP:
730     return inst_NOP(code, operands);
731     case BKPT:
732     return inst_BKPT(code, operands);
733     case TRAP:
734     return inst_TRAP(code, operands);
735     case RESET:
736     return inst_RESET(code, operands);
737     case BAD_OPCODE:
738     default:
739     break;
740   }
741
742   if (PC)
743     PC--;
744   else
745     PC= get_mem_size(MEM_ROM)-1;
746   //tick(-clock_per_cycle());
747   sim->stop(resINV_INST);
748   return(resINV_INST);
749 }
750
751
752 /* End of xa.src/xa.cc */