2 * Simulator of microcontrollers (xa.cc)
4 * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
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 johan.knol@iduna.nl
12 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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
49 * Base type of xa controllers
52 cl_xa::cl_xa(class cl_sim *asim):
61 cl_uc::init(); /* Memories now exist */
65 /* set SCR to osc/4, native XA mode, flat 24 */
67 /* initialize SP to 100H */
69 /* set PSW from reset vector */
71 /* set PC from reset vector */
74 printf("The XA Simulator is in development, UNSTABLE, DEVELOPERS ONLY!\n");
80 cl_xa::mk_mem(enum mem_class type, char *class_name)
82 class cl_mem *m= cl_uc::mk_mem(type, class_name);
91 cl_xa::id_string(void)
93 return("unspecified XA");
98 * Making elements of the controller
102 cl_xa::get_mem_size(enum mem_class type)
106 case MEM_IRAM: return(0x2000);
107 case MEM_SFR: return(0x2000);
108 case MEM_ROM: return(0x10000);
109 case MEM_XRAM: return(0x10000);
112 return(cl_uc::get_mem_size(type));
116 cl_xa::mk_hw_elements(void)
119 /* t_uc::mk_hw() does nothing */
124 * Help command interpreter
130 // this should be unused, we need to make main prog code
131 // independent of any array thing.
132 printf("ERROR - Using disass[] table in XA sim code!\n");
133 return(glob_disass_xa);
136 struct name_entry *cl_xa::sfr_tbl(void)
141 struct name_entry *cl_xa::bit_tbl(void)
147 cl_xa::inst_length(t_addr addr)
151 get_disasm_info(addr, &len, NULL, NULL, NULL, NULL);
157 cl_xa::inst_branch(t_addr addr)
161 get_disasm_info(addr, NULL, &b, NULL, NULL, NULL);
167 cl_xa::longest_inst(void)
172 static char dir_name[64];
173 char *cl_xa::get_dir_name(short addr) {
174 if (!get_name(addr, sfr_tbl(), dir_name)) {
175 sprintf (dir_name, "0x%03x", addr);
180 static char bit_name[64];
181 char *cl_xa::get_bit_name(short addr) {
182 if (!get_name(addr, bit_tbl(), bit_name)) {
183 sprintf (bit_name, "0x%03x", addr);
188 /*--------------------------------------------------------------------
189 get_disasm_info - Given an address, return information about the opcode
191 addr - address of opcode we want information on.
192 ret_len - return length of opcode.
193 ret_branch - return a character which indicates if we are
194 a branching opcode. Used by main app to implement "Next"
195 function which steps over functions.
196 immed_offset - return a number which represents the number of bytes
197 offset to where any immediate data is(tail end of opcode). Used
198 for printing disassembly.
199 operands - return a key indicating the form of the operands,
200 used for printing the disassembly.
201 mnemonic - return a key indicating the mnemonic of the instruction.
203 Return value: Return the operand code formed by either the single
204 byte opcode or 2 bytes of the opcode for multi-byte opcodes.
206 Note: Any of the return pointer parameters can be set to NULL to
207 indicate the caller does not want the information.
208 |--------------------------------------------------------------------*/
210 cl_xa::get_disasm_info(t_addr addr,
221 int start_addr = addr;
223 code= get_mem(MEM_ROM, addr++);
226 while (disass_xa[i].mnemonic != NOP)
230 code = (code << 8) | get_mem(MEM_ROM, addr++);
232 while ((code & disass_xa[i].mask) != disass_xa[i].code &&
233 disass_xa[i].mnemonic != BAD_OPCODE)
238 *ret_len = disass_xa[i].length;
240 *ret_branch = disass_xa[i].branch;
243 *immed_offset = immed_n;
244 else *immed_offset = (addr - start_addr);
247 *parms = disass_xa[i].operands;
250 *mnemonic = disass_xa[i].mnemonic;
256 static char *w_reg_strs[] = {
266 static char *b_reg_strs[] = {
276 /*--------------------------------------------------------------------
277 disass - Disassemble an opcode.
278 addr - address of opcode to disassemble/print.
279 sep - optionally points to string(tab) to use as separator.
280 |--------------------------------------------------------------------*/
282 cl_xa::disass(t_addr addr, char *sep)
284 char work[256], parm_str[40];
288 int immed_offset = 0;
295 code = get_disasm_info(addr, &len, NULL, &immed_offset, &operands, &mnemonic);
297 if (mnemonic == BAD_OPCODE) {
298 buf= (char*)malloc(30);
299 strcpy(buf, "UNKNOWN/INVALID");
304 reg_strs = w_reg_strs;
306 reg_strs = b_reg_strs;
309 // the repeating common parameter encoding for ADD, ADDC, SUB, AND...
311 sprintf(parm_str, "%s,%s",
312 reg_strs[((code >> 4) & 0xf)],
313 reg_strs[(code & 0xf)]);
316 sprintf(parm_str, "%s,[%s]",
317 reg_strs[((code >> 4) & 0xf)],
318 w_reg_strs[(code & 0xf)]);
321 sprintf(parm_str, "[%s],%s",
322 w_reg_strs[(code & 0x7)],
323 reg_strs[((code >> 4) & 0xf)] );
326 sprintf(parm_str, "%s,[%s+%02x]",
327 reg_strs[((code >> 4) & 0xf)],
328 w_reg_strs[(code & 0x7)],
329 get_mem(MEM_ROM, addr+immed_offset));
333 sprintf(parm_str, "[%s+%02x],%s",
334 w_reg_strs[(code & 0x7)],
335 get_mem(MEM_ROM, addr+immed_offset),
336 reg_strs[((code >> 4) & 0xf)] );
340 sprintf(parm_str, "%s,[%s+%04x]",
341 reg_strs[((code >> 4) & 0xf)],
342 w_reg_strs[(code & 0x7)],
343 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
344 (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
349 sprintf(parm_str, "[%s+%04x],%s",
350 w_reg_strs[(code & 0x7)],
351 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
352 (get_mem(MEM_ROM, addr+immed_offset)<<8)),
353 reg_strs[((code >> 4) & 0xf)] );
358 sprintf(parm_str, "%s,[%s+]",
359 reg_strs[((code >> 4) & 0xf)],
360 w_reg_strs[(code & 0xf)]);
363 sprintf(parm_str, "[%s+],%s",
364 w_reg_strs[(code & 0x7)],
365 reg_strs[((code >> 4) & 0xf)] );
368 sprintf(parm_str, "%s,%s",
369 get_dir_name(((code & 0x7) << 8) |
370 get_mem(MEM_ROM, addr+immed_offset)),
371 reg_strs[((code >> 4) & 0xf)] );
375 sprintf(parm_str, "%s,%s",
376 reg_strs[((code >> 4) & 0xf)],
377 get_dir_name(((code & 0x7) << 8) |
378 get_mem(MEM_ROM, addr+immed_offset)));
382 sprintf(parm_str, "%s,#0x%02x",
383 b_reg_strs[((code >> 4) & 0xf)],
384 get_mem(MEM_ROM, addr+immed_offset) );
388 sprintf(parm_str, "%s,#0x%04x",
389 reg_strs[((code >> 4) & 0xf)],
390 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
391 (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
396 sprintf(parm_str, "[%s], 0x%02x",
397 w_reg_strs[((code >> 4) & 0x7)],
398 get_mem(MEM_ROM, addr+immed_offset) );
402 sprintf(parm_str, "[%s], 0x%04x",
403 w_reg_strs[((code >> 4) & 0x7)],
404 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
405 (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
410 sprintf(parm_str, "[%s+], 0x%02x",
411 w_reg_strs[((code >> 4) & 0x7)],
412 get_mem(MEM_ROM, addr+immed_offset) );
415 case IREGINC_DATA16 :
416 sprintf(parm_str, "[%s+], 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)<<8)) );
423 case IREGOFF8_DATA8 :
424 sprintf(parm_str, "[%s+%02x], 0x%02x",
425 w_reg_strs[((code >> 4) & 0x7)],
426 get_mem(MEM_ROM, addr+immed_offset),
427 get_mem(MEM_ROM, addr+immed_offset+1) );
430 case IREGOFF8_DATA16 :
431 sprintf(parm_str, "[%s+%02x], 0x%04x",
432 w_reg_strs[((code >> 4) & 0x7)],
433 get_mem(MEM_ROM, addr+immed_offset),
434 (short)((get_mem(MEM_ROM, addr+immed_offset+2)) |
435 (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) );
438 case IREGOFF16_DATA8 :
439 sprintf(parm_str, "[%s+%04x], 0x%02x",
440 w_reg_strs[((code >> 4) & 0x7)],
441 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
442 (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
443 get_mem(MEM_ROM, addr+immed_offset+2) );
446 case IREGOFF16_DATA16 :
447 sprintf(parm_str, "[%s+%04x], 0x%04x",
448 w_reg_strs[((code >> 4) & 0x7)],
449 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
450 (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
451 (short)((get_mem(MEM_ROM, addr+immed_offset+3)) |
452 (get_mem(MEM_ROM, addr+immed_offset+2)<<8)) );
456 sprintf(parm_str, "%s,#0x%02x",
457 get_dir_name(((code & 0x0070) << 4) |
458 get_mem(MEM_ROM, addr+immed_offset)),
459 get_mem(MEM_ROM, addr+immed_offset+1));
463 sprintf(parm_str, "%s,#0x%04x",
464 get_dir_name(((code & 0x0070) << 4) |
465 get_mem(MEM_ROM, addr+immed_offset)),
466 get_mem(MEM_ROM, addr+immed_offset+2) +
467 (get_mem(MEM_ROM, addr+immed_offset+1)<<8));
472 case NO_OPERANDS : // for NOP
473 strcpy(parm_str, "");
476 sprintf(parm_str, "C,%s",
477 get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2)));
480 sprintf(parm_str, "%s,C",
481 get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2)));
484 strcpy(parm_str, "REG_DATA4");
487 strcpy(parm_str, "REG_DATA5");
490 strcpy(parm_str, "IREG_DATA4");
493 strcpy(parm_str, "IREGINC_DATA4");
495 case IREGOFF8_DATA4 :
496 strcpy(parm_str, "IREGOFF8_DATA4");
498 case IREGOFF16_DATA4 :
499 strcpy(parm_str, "IREGOFF16_DATA4");
502 sprintf(parm_str, "%s,#0x%x",
503 get_dir_name(((code & 0x70)<<4) |
504 get_mem(MEM_ROM, addr+2)),
508 sprintf(parm_str, "%s",
509 get_dir_name(((code & 0x007) << 4) +
510 get_mem(MEM_ROM, addr+2)));
513 sprintf(parm_str, "%s",
514 reg_strs[((code >> 4) & 0xf)] );
517 sprintf(parm_str, "[%s]",
518 reg_strs[((code >> 4) & 0xf)] );
521 sprintf(parm_str, "%s",
522 get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2)));
525 sprintf(parm_str, "%s,0x%04x",
526 get_bit_name((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2),
527 ((signed char)get_mem(MEM_ROM, addr+3)*2+addr+len)&0xfffe);
530 sprintf(parm_str, "#0x%02x", code&0x0f);
533 sprintf(parm_str, "0x%06x",
534 (get_mem(MEM_ROM, addr+3)<<16) +
535 (get_mem(MEM_ROM, addr+1)<<8) +
536 get_mem(MEM_ROM, addr+2));
540 sprintf(parm_str, "%s,0x%04x",
541 reg_strs[(code>>4) & 0xf],
542 ((signed char)get_mem(MEM_ROM, addr+2)*2+addr+len)&0xfffe);
545 sprintf(parm_str, "%s,0x%04x",
546 get_dir_name(((code&0x07)<<8) +
547 get_mem(MEM_ROM, addr+2)),
548 ((signed char)get_mem(MEM_ROM, addr+2)*2+addr+len)&0xfffe);
551 sprintf(parm_str, "REG_USP");
554 sprintf(parm_str, "USP_REG");
557 sprintf(parm_str, "0x%04x",
558 ((signed char)get_mem(MEM_ROM, addr+1)*2+addr+len)&0xfffe);
561 sprintf(parm_str, "0x%04x",
562 ((signed short)((get_mem(MEM_ROM, addr+1)<<8) + get_mem(MEM_ROM, addr+2))*2+addr+len)&0xfffe);
566 /* TODO: the list should be comma reperated
567 and maybe for POP the list should be reversed */
568 unsigned char rlist=code&0xff;
570 if (code&0x0800) { // word list
571 if (code&0x4000) { // R8-R15
572 if (rlist&0x80) strcat (parm_str, "R15 ");
573 if (rlist&0x40) strcat (parm_str, "R14");
574 if (rlist&0x20) strcat (parm_str, "R13 ");
575 if (rlist&0x10) strcat (parm_str, "R12 ");
576 if (rlist&0x08) strcat (parm_str, "R11 ");
577 if (rlist&0x04) strcat (parm_str, "R10 ");
578 if (rlist&0x02) strcat (parm_str, "R9 ");
579 if (rlist&0x01) strcat (parm_str, "R8 ");
581 if (rlist&0x80) strcat (parm_str, "R7 ");
582 if (rlist&0x40) strcat (parm_str, "R6 ");
583 if (rlist&0x20) strcat (parm_str, "R5 ");
584 if (rlist&0x10) strcat (parm_str, "R4 ");
585 if (rlist&0x08) strcat (parm_str, "R3 ");
586 if (rlist&0x04) strcat (parm_str, "R2 ");
587 if (rlist&0x02) strcat (parm_str, "R1 ");
588 if (rlist&0x01) strcat (parm_str, "R0 ");
590 } else { // byte list
591 if (code&0x4000) { //R7h-R4l
592 if (rlist&0x80) strcat (parm_str, "R7h ");
593 if (rlist&0x40) strcat (parm_str, "R7l ");
594 if (rlist&0x20) strcat (parm_str, "R6h ");
595 if (rlist&0x10) strcat (parm_str, "R6l ");
596 if (rlist&0x08) strcat (parm_str, "R5h ");
597 if (rlist&0x04) strcat (parm_str, "R5l ");
598 if (rlist&0x02) strcat (parm_str, "R4h ");
599 if (rlist&0x01) strcat (parm_str, "R4l ");
601 if (rlist&0x80) strcat (parm_str, "R3h ");
602 if (rlist&0x40) strcat (parm_str, "R3l ");
603 if (rlist&0x20) strcat (parm_str, "R2h ");
604 if (rlist&0x10) strcat (parm_str, "R2l ");
605 if (rlist&0x08) strcat (parm_str, "R1h ");
606 if (rlist&0x04) strcat (parm_str, "R1l ");
607 if (rlist&0x02) strcat (parm_str, "R0h ");
608 if (rlist&0x01) strcat (parm_str, "R0l ");
614 case REG_DIRECT_REL8 :
615 sprintf(parm_str, "%s,%s,0x%02x",
616 reg_strs[((code >> 4) & 0xf)],
617 get_dir_name(((code & 0x7) << 8) +
618 get_mem(MEM_ROM, addr+immed_offset)),
619 ((signed char) get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
621 case REG_DATA8_REL8 :
622 sprintf(parm_str, "%s,#0x%02x,0x%02x",
623 reg_strs[((code >> 4) & 0xf)],
624 get_mem(MEM_ROM, addr+immed_offset+1),
625 ((signed char)get_mem(MEM_ROM, addr+immed_offset) * 2) & 0xfffe );
627 case REG_DATA16_REL8 :
628 sprintf(parm_str, "%s,#0x%04x,0x%02x",
629 w_reg_strs[(code >> 4) & 0xf],
630 get_mem(MEM_ROM, addr+immed_offset+2) +
631 (get_mem(MEM_ROM, addr+immed_offset+1)<<8),
632 ((signed char)get_mem(MEM_ROM, addr+immed_offset) * 2) & 0xfffe );
634 case IREG_DATA8_REL8 :
635 sprintf(parm_str, "[%s],#0x%02x,0x%02x",
636 reg_strs[((code >> 4) & 0x7)],
637 get_mem(MEM_ROM, addr+immed_offset+1),
638 ((signed char)get_mem(MEM_ROM, addr+immed_offset) * 2) & 0xfffe );
640 case IREG_DATA16_REL8 :
641 sprintf(parm_str, "[%s],#0x%04x,0x%02x",
642 w_reg_strs[(code >> 4) & 0x7],
643 get_mem(MEM_ROM, addr+immed_offset+2) +
644 (get_mem(MEM_ROM, addr+immed_offset+1)<<8),
645 ((signed char)get_mem(MEM_ROM, addr+immed_offset) * 2) & 0xfffe );
649 strcpy(parm_str, "A, [A+DPTR]");
653 strcpy(parm_str, "A, [A+PC]");
657 sprintf(parm_str, "%s,%s+0x%02x",
658 w_reg_strs[(code >> 4) & 0x7],
659 w_reg_strs[code & 0x7],
660 get_mem(MEM_ROM, addr+immed_offset));
664 sprintf(parm_str, "%s,%s+0x%02x",
665 w_reg_strs[(code >> 4) & 0x7],
666 w_reg_strs[code & 0x7],
667 get_mem(MEM_ROM, addr+immed_offset+1) +
668 (get_mem(MEM_ROM, addr+immed_offset+0)<<8));
672 strcpy(parm_str, "[A+DPTR]");
676 sprintf(parm_str, "[[%s]]",
677 w_reg_strs[(code & 0x7)]);
681 strcpy(parm_str, "???");
685 sprintf(work, "%s %s",
686 op_mnemonic_str[ mnemonic ],
689 p= strchr(work, ' ');
696 buf= (char *)malloc(6+strlen(p)+1);
698 buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
700 for (p= work, b= buf; *p != ' '; p++, b++)
706 while (strlen(buf) < 6)
715 /*--------------------------------------------------------------------
716 print_regs - Print the registers, flags and other useful information.
717 Used to print a status line while stepping through the code.
718 |--------------------------------------------------------------------*/
720 cl_xa::print_regs(class cl_console *con)
725 con->dd_printf("CA---VNZ | ", flags);
726 con->dd_printf("R0:%04x R1:%04x R2:%04x R3:%04x\n",
727 reg2(0), reg2(1), reg2(2), reg2(3));
729 con->dd_printf("%c%c---%c%c%c | ",
730 (flags & BIT_C)?'1':'0',
731 (flags & BIT_AC)?'1':'0',
732 (flags & BIT_V)?'1':'0',
733 (flags & BIT_N)?'1':'0',
734 (flags & BIT_Z)?'1':'0');
736 con->dd_printf("R4:%04x R5:%04x R6:%04x SP:%04x ES:%04x DS:%04x\n",
737 reg2(4), reg2(5), reg2(6), reg2(7), 0, 0);
739 print_disass(PC, con);
743 /*--------------------------------------------------------------------
744 exec_inst - Called to implement simulator execution of 1 instruction
745 at the current PC(program counter) address.
746 |--------------------------------------------------------------------*/
747 int cl_xa::exec_inst(void)
755 return(resBREAKPOINT);
758 /* the following lookups make for a slow simulation, we will
759 figure out how to make it fast later... */
761 /* scan to see if its a 1 byte-opcode */
764 while ( ((code & disass_xa[i].mask) != disass_xa[i].code ||
765 (!disass_xa[i].is1byte)) /* not a one byte op code */
767 disass_xa[i].mnemonic != BAD_OPCODE)
770 if (disass_xa[i].mnemonic == BAD_OPCODE) {
771 /* hit the end of the list, must be a 2 or more byte opcode */
772 /* fetch another code byte and search the list again */
773 //if (fetch(&code2)) ?not sure if break allowed in middle of opcode?
774 // return(resBREAKPOINT);
775 code |= fetch(); /* add 2nd opcode */
778 while ((code & disass_xa[i].mask) != disass_xa[i].code &&
779 disass_xa[i].mnemonic != BAD_OPCODE)
781 /* we should have found the opcode by now, if not invalid entry at eol */
784 operands = (int)(disass_xa[i].operands);
785 switch (disass_xa[i].mnemonic)
788 return inst_ADD(code, operands);
790 return inst_ADDC(code, operands);
792 return inst_ADDS(code, operands);
794 return inst_AND(code, operands);
796 return inst_ANL(code, operands);
798 return inst_ASL(code, operands);
800 return inst_ASR(code, operands);
802 return inst_BCC(code, operands);
804 return inst_BCS(code, operands);
806 return inst_BEQ(code, operands);
808 return inst_BG(code, operands);
810 return inst_BGE(code, operands);
812 return inst_BGT(code, operands);
814 return inst_BKPT(code, operands);
816 return inst_BL(code, operands);
818 return inst_BLE(code, operands);
820 return inst_BLT(code, operands);
822 return inst_BMI(code, operands);
824 return inst_BNE(code, operands);
826 return inst_BNV(code, operands);
828 return inst_BOV(code, operands);
830 return inst_BPL(code, operands);
832 return inst_BR(code, operands);
834 return inst_CALL(code, operands);
836 return inst_CJNE(code, operands);
838 return inst_CLR(code, operands);
840 return inst_CMP(code, operands);
842 return inst_CPL(code, operands);
844 return inst_DA(code, operands);
850 return inst_DIV(code, operands);
852 return inst_DJNZ(code, operands);
854 return inst_FCALL(code, operands);
856 return inst_FJMP(code, operands);
858 return inst_JB(code, operands);
860 return inst_JBC(code, operands);
862 return inst_JMP(code, operands);
864 return inst_JNB(code, operands);
866 return inst_JNZ(code, operands);
868 return inst_JZ(code, operands);
870 return inst_LEA(code, operands);
872 return inst_LSR(code, operands);
874 return inst_MOV(code, operands);
876 return inst_MOVC(code, operands);
878 return inst_MOVS(code, operands);
880 return inst_MOVX(code, operands);
884 return inst_MUL(code, operands);
886 return inst_NEG(code, operands);
888 return inst_NOP(code, operands);
890 return inst_NORM(code, operands);
892 return inst_OR(code, operands);
894 return inst_ORL(code, operands);
897 return inst_POP(code, operands);
900 return inst_PUSH(code, operands);
902 return inst_RESET(code, operands);
904 return inst_RET(code, operands);
906 return inst_RETI(code, operands);
908 return inst_RL(code, operands);
910 return inst_RLC(code, operands);
912 return inst_RR(code, operands);
914 return inst_RRC(code, operands);
916 return inst_SETB(code, operands);
918 return inst_SEXT(code, operands);
920 return inst_SUB(code, operands);
922 return inst_SUBB(code, operands);
924 return inst_TRAP(code, operands);
926 return inst_XCH(code, operands);
928 return inst_XOR(code, operands);
938 PC= get_mem_size(MEM_ROM)-1;
939 //tick(-clock_per_cycle());
940 sim->stop(resINV_INST);
945 /* End of xa.src/xa.cc */