version 0.5.2
[fw/sdcc] / sim / ucsim / xa.src / xa.cc
index 9e65740fa816b1a85b3959a7c45b8a6f03a6fa91..35be697abb7abb3572b0d9a66ac5b0227ac9fe89 100644 (file)
@@ -6,7 +6,7 @@
  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
  * Other contributors include:
  *   Karl Bongers karl@turbobit.com,
- *   Johan Knol 
+ *   Johan Knol johan.knol@iduna.nl
  */
 
 /* This file is part of microcontroller simulator: ucsim.
@@ -45,7 +45,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "glob.h"
 #include "regsxa.h"
 
-
 /*
  * Base type of xa controllers
  */
@@ -60,19 +59,36 @@ int
 cl_xa::init(void)
 {
   cl_uc::init(); /* Memories now exist */
-  ram= mem(MEM_XRAM);
-  rom= mem(MEM_ROM);
-
-  wmem_direct = (TYPE_UWORD *) &mem_direct[0];
+  ram= address_space(MEM_XRAM_ID);
+  rom= address_space(MEM_ROM_ID);
 
+  /* set SCR to osc/4, native XA mode, flat 24 */
+  set_scr(0);
   /* initialize SP to 100H */
-  set_reg2(7*2, 0x100);
+  set_reg2(7, 0x100);
+  /* set PSW from reset vector */
+  set_psw(getcode2(0));
+  /* set PC from reset vector */
+  PC = getcode2(2);
 
   printf("The XA Simulator is in development, UNSTABLE, DEVELOPERS ONLY!\n");
 
   return(0);
 }
 
+/*
+class cl_m *
+cl_xa::mk_mem(enum mem_class type, char *class_name)
+{
+  class cl_m *m= cl_uc::mk_mem(type, class_name);
+  if (type == MEM_SFR)
+    sfr= m;
+  if (type == MEM_IRAM)
+    iram= m;
+  return(m);
+}
+*/
+
 char *
 cl_xa::id_string(void)
 {
@@ -83,18 +99,21 @@ cl_xa::id_string(void)
 /*
  * Making elements of the controller
  */
-
+/*
 t_addr
 cl_xa::get_mem_size(enum mem_class type)
 {
   switch(type)
     {
-    case MEM_ROM: return(0x10000);
+    case MEM_IRAM: return(0x2000);
+    case MEM_SFR:  return(0x2000);
+    case MEM_ROM:  return(0x10000);
     case MEM_XRAM: return(0x10000);
     default: return(0);
     }
  return(cl_uc::get_mem_size(type));
 }
+*/
 
 void
 cl_xa::mk_hw_elements(void)
@@ -103,6 +122,60 @@ cl_xa::mk_hw_elements(void)
   /* t_uc::mk_hw() does nothing */
 }
 
+void
+cl_xa::make_memories(void)
+{
+  class cl_address_space *as;
+
+  as= rom= new cl_address_space("rom", 0, 0x10000, 8);
+  as->init();
+  address_spaces->add(as);
+  as= iram= new cl_address_space("iram", 0, 0x2000, 8);
+  as->init();
+  address_spaces->add(as);
+  as= sfr= new cl_address_space("sfr", 0x0, 0x2000, 8);
+  as->init();
+  address_spaces->add(as);
+  as= ram= new cl_address_space("xram", 0, 0x10000, 8);
+  as->init();
+  address_spaces->add(as);
+
+  class cl_address_decoder *ad;
+  class cl_memory_chip *chip;
+
+  chip= new cl_memory_chip("rom_chip", 0x10000, 8);
+  chip->init();
+  memchips->add(chip);
+  ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
+  ad->init();
+  as->decoders->add(ad);
+  ad->activate(0);
+
+  chip= new cl_memory_chip("iram_chip", 0x2000, 8);
+  chip->init();
+  memchips->add(chip);
+  ad= new cl_address_decoder(as= address_space("iram"), chip, 0, 0x1fff, 0);
+  ad->init();
+  as->decoders->add(ad);
+  ad->activate(0);
+
+  chip= new cl_memory_chip("xram_chip", 0x10000, 8);
+  chip->init();
+  memchips->add(chip);
+  ad= new cl_address_decoder(as= address_space("xram"), chip, 0, 0xffff, 0);
+  ad->init();
+  as->decoders->add(ad);
+  ad->activate(0);
+
+  chip= new cl_memory_chip("sfr_chip", 0x2000, 8);
+  chip->init();
+  memchips->add(chip);
+  ad= new cl_address_decoder(as= address_space("sfr"), chip, 0x0, 0x1fff, 0);
+  ad->init();
+  as->decoders->add(ad);
+  ad->activate(0);
+}
+
 
 /*
  * Help command interpreter
@@ -117,18 +190,15 @@ cl_xa::dis_tbl(void)
   return(glob_disass_xa);
 }
 
-/*struct name_entry *
-cl_xa::sfr_tbl(void)
+struct name_entry *cl_xa::sfr_tbl(void)
 {
-  return(0);
-}*/
+  return(sfr_tabXA51);
+}
 
-/*struct name_entry *
-cl_xa::bit_tbl(void)
+struct name_entry *cl_xa::bit_tbl(void)
 {
-  //FIXME
-  return(0);
-}*/
+  return(bit_tabXA51);
+}
 
 int
 cl_xa::inst_length(t_addr addr)
@@ -156,8 +226,42 @@ cl_xa::longest_inst(void)
   return 6;
 }
 
+static char dir_name[64];
+char *cl_xa::get_dir_name(short addr) {
+  if (!get_name(addr, sfr_tbl(), dir_name)) {
+    sprintf (dir_name, "0x%03x", addr);
+  }
+  return dir_name;
+}
+
+static char bit_name[64];
+char *cl_xa::get_bit_name(short addr) {
+  if (!get_name(addr, bit_tbl(), bit_name)) {
+    sprintf (bit_name, "0x%03x", addr);
+  }
+  return bit_name;
+}
+
 /*--------------------------------------------------------------------
-get_disasm_info -
+get_disasm_info - Given an address, return information about the opcode
+  which resides there.
+  addr - address of opcode we want information on.
+  ret_len - return length of opcode.
+  ret_branch - return a character which indicates if we are
+    a branching opcode.  Used by main app to implement "Next"
+    function which steps over functions.
+  immed_offset - return a number which represents the number of bytes
+    offset to where any immediate data is(tail end of opcode).  Used
+    for printing disassembly.
+  operands - return a key indicating the form of the operands,
+    used for printing the disassembly.
+  mnemonic - return a key indicating the mnemonic of the instruction.
+
+  Return value: Return the operand code formed by either the single
+  byte opcode or 2 bytes of the opcode for multi-byte opcodes.
+
+  Note: Any of the return pointer parameters can be set to NULL to
+    indicate the caller does not want the information.
 |--------------------------------------------------------------------*/
 int
 cl_xa::get_disasm_info(t_addr addr,
@@ -173,14 +277,14 @@ cl_xa::get_disasm_info(t_addr addr,
   int i;
   int start_addr = addr;
 
-  code= get_mem(MEM_ROM, addr++);
+  code= get_mem(MEM_ROM_ID, addr++);
   if (code == 0x00) {
     i= 0;
     while (disass_xa[i].mnemonic != NOP)
       i++;
   } else {
     len = 2;
-    code = (code << 8) | get_mem(MEM_ROM, addr++);
+    code = (code << 8) | get_mem(MEM_ROM_ID, addr++);
     i= 0;
     while ((code & disass_xa[i].mask) != disass_xa[i].code &&
            disass_xa[i].mnemonic != BAD_OPCODE)
@@ -227,7 +331,9 @@ static char *b_reg_strs[] = {
  "R7l", "R7h"};
 
 /*--------------------------------------------------------------------
-disass -
+disass - Disassemble an opcode.
+    addr - address of opcode to disassemble/print.
+    sep - optionally points to string(tab) to use as separator.
 |--------------------------------------------------------------------*/
 char *
 cl_xa::disass(t_addr addr, char *sep)
@@ -274,33 +380,33 @@ cl_xa::disass(t_addr addr, char *sep)
               reg_strs[((code >> 4) & 0xf)] );
     break;
     case REG_IREGOFF8 :
-      sprintf(parm_str, "%s,[%s+%02d]",
+      sprintf(parm_str, "%s,[%s+%02x]",
               reg_strs[((code >> 4) & 0xf)],
               w_reg_strs[(code & 0x7)],
-              get_mem(MEM_ROM, addr+immed_offset));
+              get_mem(MEM_ROM_ID, addr+immed_offset));
       ++immed_offset;
     break;
     case IREGOFF8_REG :
-      sprintf(parm_str, "[%s+%02d],%s",
+      sprintf(parm_str, "[%s+%02x],%s",
               w_reg_strs[(code & 0x7)],
-              get_mem(MEM_ROM, addr+immed_offset),
+              get_mem(MEM_ROM_ID, addr+immed_offset),
               reg_strs[((code >> 4) & 0xf)] );
       ++immed_offset;
     break;
     case REG_IREGOFF16 :
-      sprintf(parm_str, "%s,[%s+%04d]",
+      sprintf(parm_str, "%s,[%s+%04x]",
               reg_strs[((code >> 4) & 0xf)],
               w_reg_strs[(code & 0x7)],
-              (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
-                     (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)) );
       ++immed_offset;
       ++immed_offset;
     break;
     case IREGOFF16_REG :
-      sprintf(parm_str, "[%s+%04d],%s",
+      sprintf(parm_str, "[%s+%04x],%s",
               w_reg_strs[(code & 0x7)],
-              (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
-                     (get_mem(MEM_ROM, addr+immed_offset)<<8)),
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)),
               reg_strs[((code >> 4) & 0xf)] );
       ++immed_offset;
       ++immed_offset;
@@ -316,102 +422,106 @@ cl_xa::disass(t_addr addr, char *sep)
               reg_strs[((code >> 4) & 0xf)] );
     break;
     case DIRECT_REG :
-      sprintf(parm_str, "0x%03x,%s",
-              ((code & 0x7) << 8) | get_mem(MEM_ROM, addr+immed_offset),
+      sprintf(parm_str, "%s,%s",
+              get_dir_name(((code & 0x7) << 8) | 
+                          get_mem(MEM_ROM_ID, addr+immed_offset)),
               reg_strs[((code >> 4) & 0xf)] );
       ++immed_offset;
     break;
     case REG_DIRECT :
-      sprintf(parm_str, "%s,0x%03x",
-              reg_strs[((code >> 4) & 0xf)],
-              ((code & 0x7) << 8) + get_mem(MEM_ROM, addr+immed_offset) );
+      sprintf(parm_str, "%s,%s",
+             reg_strs[((code >> 4) & 0xf)], 
+              get_dir_name(((code & 0x7) << 8) | 
+                          get_mem(MEM_ROM_ID, addr+immed_offset)));
       ++immed_offset;
     break;
     case REG_DATA8 :
       sprintf(parm_str, "%s,#0x%02x",
               b_reg_strs[((code >> 4) & 0xf)],
-              get_mem(MEM_ROM, addr+immed_offset) );
+              get_mem(MEM_ROM_ID, addr+immed_offset) );
       ++immed_offset;
     break;
     case REG_DATA16 :
       sprintf(parm_str, "%s,#0x%04x",
               reg_strs[((code >> 4) & 0xf)],
-              (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
-                     (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)) );
       ++immed_offset;
       ++immed_offset;
     break;
     case IREG_DATA8 :
       sprintf(parm_str, "[%s], 0x%02x",
               w_reg_strs[((code >> 4) & 0x7)],
-              get_mem(MEM_ROM, addr+immed_offset) );
+              get_mem(MEM_ROM_ID, addr+immed_offset) );
       ++immed_offset;
     break;
     case IREG_DATA16 :
       sprintf(parm_str, "[%s], 0x%04x",
               w_reg_strs[((code >> 4) & 0x7)],
-              (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
-                     (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)) );
       ++immed_offset;
       ++immed_offset;
     break;
     case IREGINC_DATA8 :
       sprintf(parm_str, "[%s+], 0x%02x",
               w_reg_strs[((code >> 4) & 0x7)],
-              get_mem(MEM_ROM, addr+immed_offset) );
+              get_mem(MEM_ROM_ID, addr+immed_offset) );
       ++immed_offset;
     break;
     case IREGINC_DATA16 :
       sprintf(parm_str, "[%s+], 0x%04x",
               w_reg_strs[((code >> 4) & 0x7)],
-              (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
-                     (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)) );
       ++immed_offset;
       ++immed_offset;
     break;
     case IREGOFF8_DATA8 :
-      sprintf(parm_str, "[%s+%02d], 0x%02x",
+      sprintf(parm_str, "[%s+%02x], 0x%02x",
               w_reg_strs[((code >> 4) & 0x7)],
-              get_mem(MEM_ROM, addr+immed_offset),
-              get_mem(MEM_ROM, addr+immed_offset+1) );
+              get_mem(MEM_ROM_ID, addr+immed_offset),
+              get_mem(MEM_ROM_ID, addr+immed_offset+1) );
       immed_offset += 2;
     break;
     case IREGOFF8_DATA16 :
-      sprintf(parm_str, "[%s+%02d], 0x%04x",
+      sprintf(parm_str, "[%s+%02x], 0x%04x",
               w_reg_strs[((code >> 4) & 0x7)],
-              get_mem(MEM_ROM, addr+immed_offset),
-              (short)((get_mem(MEM_ROM, addr+immed_offset+2)) |
-                     (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) );
+              get_mem(MEM_ROM_ID, addr+immed_offset),
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+2)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset+1)<<8)) );
       immed_offset += 3;
     break;
     case IREGOFF16_DATA8 :
-      sprintf(parm_str, "[%s+%04d], 0x%02x",
+      sprintf(parm_str, "[%s+%04x], 0x%02x",
               w_reg_strs[((code >> 4) & 0x7)],
-              (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
-                     (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
-              get_mem(MEM_ROM, addr+immed_offset+2) );
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset+0)<<8)),
+              get_mem(MEM_ROM_ID, addr+immed_offset+2) );
       immed_offset += 3;
     break;
     case IREGOFF16_DATA16 :
-      sprintf(parm_str, "[%s+%04d], 0x%04x",
+      sprintf(parm_str, "[%s+%04x], 0x%04x",
               w_reg_strs[((code >> 4) & 0x7)],
-              (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
-                     (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
-              (short)((get_mem(MEM_ROM, addr+immed_offset+3)) |
-                     (get_mem(MEM_ROM, addr+immed_offset+2)<<8)) );
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset+0)<<8)),
+              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+3)) |
+                     (get_mem(MEM_ROM_ID, addr+immed_offset+2)<<8)) );
       immed_offset += 4;
     break;
     case DIRECT_DATA8 :
-      sprintf(parm_str, "0x%03x,#0x%02x",
-              ((code & 0x0070) << 4) | get_mem(MEM_ROM, addr+immed_offset),
-              get_mem(MEM_ROM, addr+immed_offset+1));
+      sprintf(parm_str, "%s,#0x%02x",
+              get_dir_name(((code & 0x0070) << 4) | 
+                          get_mem(MEM_ROM_ID, addr+immed_offset)),
+              get_mem(MEM_ROM_ID, addr+immed_offset+1));
       immed_offset += 3;
     break;
     case DIRECT_DATA16 :
-      sprintf(parm_str, "%0x03x,#0x%04x",
-              ((code & 0x0070) << 4) | get_mem(MEM_ROM, addr+immed_offset),
-              get_mem(MEM_ROM, addr+immed_offset+2) +
-             (get_mem(MEM_ROM, addr+immed_offset+1)<<8));
+      sprintf(parm_str, "%s,#0x%04x",
+              get_dir_name(((code & 0x0070) << 4) | 
+                          get_mem(MEM_ROM_ID, addr+immed_offset)),
+              get_mem(MEM_ROM_ID, addr+immed_offset+2) +
+             (get_mem(MEM_ROM_ID, addr+immed_offset+1)<<8));
       immed_offset += 3;
     break;
 
@@ -419,12 +529,20 @@ cl_xa::disass(t_addr addr, char *sep)
     case NO_OPERANDS :  // for NOP
       strcpy(parm_str, "");
     break;
-    case C_BIT :
-      strcpy(parm_str, "C_BIT");
+    case CY_BIT :
+      sprintf(parm_str, "C,%s", 
+            get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM_ID, addr+2)));
+    break;
+    case BIT_CY :
+      sprintf(parm_str, "%s,C", 
+             get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM_ID, addr+2)));
     break;
     case REG_DATA4 :
       strcpy(parm_str, "REG_DATA4");
     break;
+    case REG_DATA5 :
+      strcpy(parm_str, "REG_DATA5");
+    break;
     case IREG_DATA4 :
       strcpy(parm_str, "IREG_DATA4");
     break;
@@ -438,90 +556,184 @@ cl_xa::disass(t_addr addr, char *sep)
       strcpy(parm_str, "IREGOFF16_DATA4");
     break;
     case DIRECT_DATA4 :
-      strcpy(parm_str, "DIRECT_DATA4");
+      sprintf(parm_str, "%s,#0x%x",
+             get_dir_name(((code & 0x70)<<4) |
+                          get_mem(MEM_ROM_ID, addr+2)),
+             code&0x0f);
     break;
-    case DIRECT_ALONE :
-      sprintf(parm_str, "0x%03x",
-             ((code & 0x007) << 4) + get_mem(MEM_ROM, addr+2));
+    case DIRECT :
+      sprintf(parm_str, "%s",
+             get_dir_name(((code & 0x007) << 4) + 
+                          get_mem(MEM_ROM_ID, addr+2)));
     break;
-    case REG_ALONE :
+    case REG :
       sprintf(parm_str, "%s",
               reg_strs[((code >> 4) & 0xf)] );
     break;
-    case IREG_ALONE :
+    case IREG :
       sprintf(parm_str, "[%s]",
               reg_strs[((code >> 4) & 0xf)] );
     break;
     case BIT_ALONE :
-      sprintf(parm_str, "0x%03x",
-             ((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2));
+      sprintf(parm_str, "%s",
+             get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM_ID, addr+2)));
     break;
     case BIT_REL8 :
-      sprintf(parm_str, "0x%03x,0x%04x",
-             ((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2),
-             ((signed char)get_mem(MEM_ROM, addr+3)*2+addr+len)&0xfffe);
+      sprintf(parm_str, "%s,0x%04x",
+             get_bit_name((code&0x0003)<<8) + get_mem(MEM_ROM_ID, addr+2),
+             ((signed char)get_mem(MEM_ROM_ID, addr+3)*2+addr+len)&0xfffe);
     break;
+    case DATA4:
+      sprintf(parm_str, "#0x%02x", code&0x0f);
+      break;
     case ADDR24 :
-      strcpy(parm_str, "ADDR24");
+      sprintf(parm_str, "0x%06x", 
+            (get_mem(MEM_ROM_ID, addr+3)<<16) + 
+            (get_mem(MEM_ROM_ID, addr+1)<<8) + 
+            get_mem(MEM_ROM_ID, addr+2));
+      break;
     break;
     case REG_REL8 :
-      //strcpy(parm_str, "REG_REL8");
       sprintf(parm_str, "%s,0x%04x",
              reg_strs[(code>>4) & 0xf],
-             ((signed char)get_mem(MEM_ROM, addr+2)*2+addr+len)&0xfffe);
+             ((signed char)get_mem(MEM_ROM_ID, addr+2)*2+addr+len)&0xfffe);
     break;
     case DIRECT_REL8 :
-      strcpy(parm_str, "DIRECT_REL8");
+      sprintf(parm_str, "%s,0x%04x",
+             get_dir_name(((code&0x07)<<8) +
+                          get_mem(MEM_ROM_ID, addr+2)),
+             ((signed char)get_mem(MEM_ROM_ID, addr+2)*2+addr+len)&0xfffe);
+    break;
+    case REG_USP:
+      sprintf(parm_str, "REG_USP");
+    break;
+    case USP_REG:
+      sprintf(parm_str, "USP_REG");
     break;
-
     case REL8 :
-      //strcpy(parm_str, "REL8");
       sprintf(parm_str, "0x%04x",
-             ((signed char)get_mem(MEM_ROM, addr+1)*2+addr+len)&0xfffe);
+             ((signed char)get_mem(MEM_ROM_ID, addr+1)*2+addr+len)&0xfffe);
     break;
     case REL16 :
-      //strcpy(parm_str, "REL16");
       sprintf(parm_str, "0x%04x",
-             ((signed short)((get_mem(MEM_ROM, addr+1)<<8) + get_mem(MEM_ROM, addr+2))*2+addr+len)&0xfffe);
-    break;
-
-    case RLIST :
-      strcpy(parm_str, "RLIST");
+             ((signed short)((get_mem(MEM_ROM_ID, addr+1)<<8) + get_mem(MEM_ROM_ID, addr+2))*2+addr+len)&0xfffe);
+    break;
+
+    case RLIST : {
+      /* TODO: the list should be comma reperated
+        and maybe for POP the list should be reversed */
+      unsigned char rlist=code&0xff;
+      parm_str[0]='\0';
+      if (code&0x0800) { // word list
+       if (code&0x4000) { // R8-R15
+         if (rlist&0x80) strcat (parm_str, "R15 ");
+         if (rlist&0x40) strcat (parm_str, "R14");
+         if (rlist&0x20) strcat (parm_str, "R13 ");
+         if (rlist&0x10) strcat (parm_str, "R12 ");
+         if (rlist&0x08) strcat (parm_str, "R11 ");
+         if (rlist&0x04) strcat (parm_str, "R10 ");
+         if (rlist&0x02) strcat (parm_str, "R9 ");
+         if (rlist&0x01) strcat (parm_str, "R8 ");
+       } else { // R7-R0
+         if (rlist&0x80) strcat (parm_str, "R7 ");
+         if (rlist&0x40) strcat (parm_str, "R6 ");
+         if (rlist&0x20) strcat (parm_str, "R5 ");
+         if (rlist&0x10) strcat (parm_str, "R4 ");
+         if (rlist&0x08) strcat (parm_str, "R3 ");
+         if (rlist&0x04) strcat (parm_str, "R2 ");
+         if (rlist&0x02) strcat (parm_str, "R1 ");
+         if (rlist&0x01) strcat (parm_str, "R0 ");
+       }
+      } else { // byte list
+       if (code&0x4000) { //R7h-R4l
+         if (rlist&0x80) strcat (parm_str, "R7h ");
+         if (rlist&0x40) strcat (parm_str, "R7l ");
+         if (rlist&0x20) strcat (parm_str, "R6h ");
+         if (rlist&0x10) strcat (parm_str, "R6l ");
+         if (rlist&0x08) strcat (parm_str, "R5h ");
+         if (rlist&0x04) strcat (parm_str, "R5l ");
+         if (rlist&0x02) strcat (parm_str, "R4h ");
+         if (rlist&0x01) strcat (parm_str, "R4l ");
+       } else { // R3h-R0l
+         if (rlist&0x80) strcat (parm_str, "R3h ");
+         if (rlist&0x40) strcat (parm_str, "R3l ");
+         if (rlist&0x20) strcat (parm_str, "R2h ");
+         if (rlist&0x10) strcat (parm_str, "R2l ");
+         if (rlist&0x08) strcat (parm_str, "R1h ");
+         if (rlist&0x04) strcat (parm_str, "R1l ");
+         if (rlist&0x02) strcat (parm_str, "R0h ");
+         if (rlist&0x01) strcat (parm_str, "R0l ");
+       }
+      }
+    }
     break;
 
     case REG_DIRECT_REL8 :
-      sprintf(parm_str, "%s,0x%02x,0x%02x",
+      sprintf(parm_str, "%s,%s,0x%02x",
               reg_strs[((code >> 4) & 0xf)],
-              ((code & 0x7) << 8) + get_mem(MEM_ROM, addr+immed_offset),
-              (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
+              get_dir_name(((code & 0x7) << 8) + 
+                          get_mem(MEM_ROM_ID, addr+immed_offset)),
+              ((signed char) get_mem(MEM_ROM_ID, addr+immed_offset+1) * 2) & 0xfffe );
     break;
     case REG_DATA8_REL8 :
-      sprintf(parm_str, "%s,#0x%04x,0x%02x",
+      sprintf(parm_str, "%s,#0x%02x,0x%02x",
               reg_strs[((code >> 4) & 0xf)],
-              get_mem(MEM_ROM, addr+immed_offset),
-              (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
+              get_mem(MEM_ROM_ID, addr+immed_offset+1),
+              ((signed char)get_mem(MEM_ROM_ID, addr+immed_offset) * 2) & 0xfffe );
     break;
     case REG_DATA16_REL8 :
-      sprintf(parm_str, "%s,#0x%02x,0x%02x",
-              w_reg_strs[((code >> 4) & 0x7)*2],
-              get_mem(MEM_ROM, addr+immed_offset+1) +
-                 (get_mem(MEM_ROM, addr+immed_offset+0)<<8),
-              (get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe );
+      sprintf(parm_str, "%s,#0x%04x,0x%02x",
+              w_reg_strs[(code >> 4) & 0xf],
+              get_mem(MEM_ROM_ID, addr+immed_offset+2) +
+                 (get_mem(MEM_ROM_ID, addr+immed_offset+1)<<8),
+              ((signed char)get_mem(MEM_ROM_ID, addr+immed_offset) * 2) & 0xfffe );
     break;
     case IREG_DATA8_REL8 :
-      sprintf(parm_str, "[%s],#0x%04x,0x%02x",
+      sprintf(parm_str, "[%s],#0x%02x,0x%02x",
               reg_strs[((code >> 4) & 0x7)],
-              get_mem(MEM_ROM, addr+immed_offset),
-              (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe );
+              get_mem(MEM_ROM_ID, addr+immed_offset+1),
+              ((signed char)get_mem(MEM_ROM_ID, addr+immed_offset) * 2) & 0xfffe );
     break;
     case IREG_DATA16_REL8 :
-      sprintf(parm_str, "[%s],#0x%02x,0x%02x",
-              w_reg_strs[((code >> 4) & 0x7)*2],
-              get_mem(MEM_ROM, addr+immed_offset+1) +
-                 (get_mem(MEM_ROM, addr+immed_offset+0)<<8),
-              (get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe );
+      sprintf(parm_str, "[%s],#0x%04x,0x%02x",
+              w_reg_strs[(code >> 4) & 0x7],
+              get_mem(MEM_ROM_ID, addr+immed_offset+2) +
+               (get_mem(MEM_ROM_ID, addr+immed_offset+1)<<8),
+              ((signed char)get_mem(MEM_ROM_ID, addr+immed_offset) * 2) & 0xfffe );
     break;
 
+    case A_APLUSDPTR :
+      strcpy(parm_str, "A, [A+DPTR]");
+    break;
+
+    case A_APLUSPC :
+      strcpy(parm_str, "A, [A+PC]");
+    break;
+
+    case REG_REGOFF8 :
+      sprintf(parm_str, "%s,%s+0x%02x", 
+             w_reg_strs[(code >> 4) & 0x7],
+             w_reg_strs[code & 0x7],
+             get_mem(MEM_ROM_ID, addr+immed_offset));
+      break;
+
+    case REG_REGOFF16 :
+      sprintf(parm_str, "%s,%s+0x%02x", 
+             w_reg_strs[(code >> 4) & 0x7],
+             w_reg_strs[code & 0x7],
+             get_mem(MEM_ROM_ID, addr+immed_offset+1) +
+               (get_mem(MEM_ROM_ID, addr+immed_offset+0)<<8));
+      break;
+
+    case A_PLUSDPTR :
+      strcpy(parm_str, "[A+DPTR]");
+      break;
+
+    case IIREG :
+      sprintf(parm_str, "[[%s]]",
+              w_reg_strs[(code & 0x7)]);
+      break;
+
     default:
       strcpy(parm_str, "???");
     break;
@@ -541,6 +753,7 @@ cl_xa::disass(t_addr addr, char *sep)
     buf= (char *)malloc(6+strlen(p)+1);
   else
     buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
+
   for (p= work, b= buf; *p != ' '; p++, b++)
     *b= *p;
   p++;
@@ -557,7 +770,8 @@ cl_xa::disass(t_addr addr, char *sep)
 }
 
 /*--------------------------------------------------------------------
- print_regs -
+ print_regs - Print the registers, flags and other useful information.
+   Used to print a status line while stepping through the code.
 |--------------------------------------------------------------------*/
 void
 cl_xa::print_regs(class cl_console *con)
@@ -565,30 +779,29 @@ cl_xa::print_regs(class cl_console *con)
   unsigned char flags;
 
   flags = get_psw();
-  con->dd_printf("CA---VNZ  Flags: %02x ", flags);
+  con->dd_printf("CA---VNZ | ", flags);
   con->dd_printf("R0:%04x R1:%04x R2:%04x R3:%04x\n",
-                 get_reg(1,0), get_reg(1,2), get_reg(1,4), get_reg(1,6));
+                 reg2(0), reg2(1), reg2(2), reg2(3));
 
-  con->dd_printf("%c%c---%c%c%c            ",
+  con->dd_printf("%c%c---%c%c%c | ",
          (flags & BIT_C)?'1':'0',
          (flags & BIT_AC)?'1':'0',
          (flags & BIT_V)?'1':'0',
          (flags & BIT_N)?'1':'0',
          (flags & BIT_Z)?'1':'0');
 
-  con->dd_printf("R4:%04x R5:%04x R6:%04x R7(SP):%04x ES:%04x  DS:%04x\n",
-            get_reg(1,8), get_reg(1,10), get_reg(1,12), get_reg(1,14), 0, 0);
+  con->dd_printf("R4:%04x R5:%04x R6:%04x SP:%04x ES:%04x  DS:%04x\n",
+                 reg2(4), reg2(5), reg2(6), reg2(7), 0, 0);
 
   print_disass(PC, con);
 }
 
 
-/*
- * Execution
- */
-
-int
-cl_xa::exec_inst(void)
+/*--------------------------------------------------------------------
+ exec_inst - Called to implement simulator execution of 1 instruction
+   at the current PC(program counter) address.
+|--------------------------------------------------------------------*/
+int cl_xa::exec_inst(void)
 {
   t_mem code1;
   uint code;
@@ -606,7 +819,7 @@ cl_xa::exec_inst(void)
   code = (code1 << 8);
   i= 0;
   while ( ((code & disass_xa[i].mask) != disass_xa[i].code ||
-           ((disass_xa[i].mask & 0x00ff) != 0)) /* one byte op code */
+          (!disass_xa[i].is1byte)) /* not a one byte op code */
                     &&
          disass_xa[i].mnemonic != BAD_OPCODE)
     i++;
@@ -632,46 +845,122 @@ cl_xa::exec_inst(void)
     return inst_ADD(code, operands);
     case ADDC:
     return inst_ADDC(code, operands);
-    case SUB:
-    return inst_SUB(code, operands);
-    case SUBB:
-    return inst_SUBB(code, operands);
-    case CMP:
-    return inst_CMP(code, operands);
-    case AND:
-    return inst_AND(code, operands);
-    case OR:
-    return inst_OR(code, operands);
-    case XOR:
-    return inst_XOR(code, operands);
     case ADDS:
     return inst_ADDS(code, operands);
-    case NEG:
-    return inst_NEG(code, operands);
-    case SEXT:
-    return inst_SEXT(code, operands);
-    case MUL:
-    return inst_MUL(code, operands);
+    case AND:
+    return inst_AND(code, operands);
+    case ANL:
+    return inst_ANL(code, operands);
+    case ASL:
+    return inst_ASL(code, operands);
+    case ASR:
+    return inst_ASR(code, operands);
+    case BCC:
+    return inst_BCC(code, operands);
+    case BCS:
+    return inst_BCS(code, operands);
+    case BEQ:
+    return inst_BEQ(code, operands);
+    case BG:
+    return inst_BG(code, operands);
+    case BGE:
+    return inst_BGE(code, operands);
+    case BGT:
+    return inst_BGT(code, operands);
+    case BKPT:
+    return inst_BKPT(code, operands);
+    case BL:
+    return inst_BL(code, operands);
+    case BLE:
+    return inst_BLE(code, operands);
+    case BLT:
+    return inst_BLT(code, operands);
+    case BMI:
+    return inst_BMI(code, operands);
+    case BNE:
+    return inst_BNE(code, operands);
+    case BNV:
+    return inst_BNV(code, operands);
+    case BOV:
+    return inst_BOV(code, operands);
+    case BPL:
+    return inst_BPL(code, operands);
+    case BR:
+    return inst_BR(code, operands);
+    case CALL:
+    return inst_CALL(code, operands);
+    case CJNE:
+    return inst_CJNE(code, operands);
+    case CLR:
+    return inst_CLR(code, operands);
+    case CMP:
+    return inst_CMP(code, operands);
+    case CPL:
+    return inst_CPL(code, operands);
+    case DA:
+    return inst_DA(code, operands);
     case DIV_w :
     case DIV_d :
     case DIVU_b:
     case DIVU_w:
     case DIVU_d:
     return inst_DIV(code, operands);
-    case DA:
-    return inst_DA(code, operands);
-    case ASL:
-    return inst_ASL(code, operands);
-    case ASR:
-    return inst_ASR(code, operands);
+    case DJNZ:
+    return inst_DJNZ(code, operands);
+    case FCALL:
+    return inst_FCALL(code, operands);
+    case FJMP:
+    return inst_FJMP(code, operands);
+    case JB:
+    return inst_JB(code, operands);
+    case JBC:
+    return inst_JBC(code, operands);
+    case JMP:
+    return inst_JMP(code, operands);
+    case JNB:
+    return inst_JNB(code, operands);
+    case JNZ:
+    return inst_JNZ(code, operands);
+    case JZ:
+    return inst_JZ(code, operands);
     case LEA:
     return inst_LEA(code, operands);
-    case CPL:
-    return inst_CPL(code, operands);
     case LSR:
     return inst_LSR(code, operands);
+    case MOV:
+    return inst_MOV(code, operands);
+    case MOVC:
+    return inst_MOVC(code, operands);
+    case MOVS:
+    return inst_MOVS(code, operands);
+    case MOVX:
+    return inst_MOVX(code, operands);
+    case MUL_w:
+    case MULU_b:
+    case MULU_w:
+    return inst_MUL(code, operands);
+    case NEG:
+    return inst_NEG(code, operands);
+    case NOP:
+    return inst_NOP(code, operands);
     case NORM:
     return inst_NORM(code, operands);
+    case OR:
+    return inst_OR(code, operands);
+    case ORL:
+    return inst_ORL(code, operands);
+    case POP:
+    case POPU:
+    return inst_POP(code, operands);
+    case PUSH:
+    case PUSHU:
+    return inst_PUSH(code, operands);
+    case RESET:
+    return inst_RESET(code, operands);
+    case RET:
+    return inst_RET(code, operands);
+    case RETI:
+    return inst_RETI(code, operands);
     case RL:
     return inst_RL(code, operands);
     case RLC:
@@ -680,69 +969,31 @@ cl_xa::exec_inst(void)
     return inst_RR(code, operands);
     case RRC:
     return inst_RRC(code, operands);
-    case MOVS:
-    return inst_MOVS(code, operands);
-    case MOVC:
-    return inst_MOVC(code, operands);
-    case MOVX:
-    return inst_MOVX(code, operands);
-    case PUSH:
-    return inst_PUSH(code, operands);
-    case POP:
-    return inst_POP(code, operands);
-    case XCH:
-    return inst_XCH(code, operands);
     case SETB:
     return inst_SETB(code, operands);
-    case CLR:
-    return inst_CLR(code, operands);
-    case MOV:
-    return inst_MOV(code, operands);
-    case ANL:
-    return inst_ANL(code, operands);
-    case ORL:
-    return inst_ORL(code, operands);
-    case BEQ:
-    return inst_BEQ(code, operands);
-    case BR:
-    return inst_BR(code, operands);
-    case JMP:
-    return inst_JMP(code, operands);
-    case CALL:
-    return inst_CALL(code, operands);
-    case RET:
-    return inst_RET(code, operands);
-    case BCC:
-    return inst_Bcc(code, operands);
-    case JB:
-    return inst_JB(code, operands);
-    case JNB:
-    return inst_JNB(code, operands);
-    case CJNE:
-    return inst_CJNE(code, operands);
-    case DJNZ:
-    return inst_DJNZ(code, operands);
-    case JZ:
-    return inst_JZ(code, operands);
-    case JNZ:
-    return inst_JNZ(code, operands);
-    case NOP:
-    return inst_NOP(code, operands);
-    case BKPT:
-    return inst_BKPT(code, operands);
+    case SEXT:
+    return inst_SEXT(code, operands);
+    case SUB:
+    return inst_SUB(code, operands);
+    case SUBB:
+    return inst_SUBB(code, operands);
     case TRAP:
     return inst_TRAP(code, operands);
-    case RESET:
-    return inst_RESET(code, operands);
+    case XCH:
+    return inst_XCH(code, operands);
+    case XOR:
+    return inst_XOR(code, operands);
+
     case BAD_OPCODE:
     default:
     break;
   }
 
-  if (PC)
+  /*if (PC)
     PC--;
   else
-    PC= get_mem_size(MEM_ROM)-1;
+  PC= get_mem_size(MEM_ROM_ID)-1;*/
+  PC= rom->inc_address(PC, -1);
   //tick(-clock_per_cycle());
   sim->stop(resINV_INST);
   return(resINV_INST);