work in progress
[fw/sdcc] / sim / ucsim / xa.src / xa.cc
index e189643ff1e2dec16d1ab2de0ed876b599856542..0f5ed45498c77f9f6fd3834c79d0cebfbcbb8614 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
  */
@@ -63,8 +62,6 @@ cl_xa::init(void)
   ram= mem(MEM_XRAM);
   rom= mem(MEM_ROM);
 
-  wmem_direct = (TYPE_UWORD *) &mem_direct[0];
-
   /* set SCR to osc/4, native XA mode, flat 24 */
   set_scr(0);
   /* initialize SP to 100H */
@@ -79,6 +76,17 @@ cl_xa::init(void)
   return(0);
 }
 
+class cl_mem *
+cl_xa::mk_mem(enum mem_class type, char *class_name)
+{
+  class cl_mem *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)
 {
@@ -95,6 +103,8 @@ cl_xa::get_mem_size(enum mem_class type)
 {
   switch(type)
     {
+    case MEM_IRAM: return(0x2000);
+    case MEM_SFR: return(0x2000);
     case MEM_ROM: return(0x10000);
     case MEM_XRAM: return(0x10000);
     default: return(0);
@@ -313,21 +323,21 @@ 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));
       ++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),
               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)) |
@@ -336,7 +346,7 @@ cl_xa::disass(t_addr addr, char *sep)
       ++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)),
@@ -411,14 +421,14 @@ cl_xa::disass(t_addr addr, char *sep)
       ++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) );
       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)) |
@@ -426,7 +436,7 @@ cl_xa::disass(t_addr addr, char *sep)
       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)),
@@ -434,7 +444,7 @@ cl_xa::disass(t_addr addr, char *sep)
       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)),
@@ -462,12 +472,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, addr+2)));
+    break;
+    case BIT_CY :
+      sprintf(parm_str, "%s,C", 
+             get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM, 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;
@@ -508,8 +526,15 @@ cl_xa::disass(t_addr addr, char *sep)
              get_bit_name((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2),
              ((signed char)get_mem(MEM_ROM, 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, addr+3)<<16) + 
+            (get_mem(MEM_ROM, addr+1)<<8) + 
+            get_mem(MEM_ROM, addr+2));
+      break;
     break;
     case REG_REL8 :
       sprintf(parm_str, "%s,0x%04x",
@@ -522,7 +547,12 @@ cl_xa::disass(t_addr addr, char *sep)
                           get_mem(MEM_ROM, addr+2)),
              ((signed char)get_mem(MEM_ROM, 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 :
       sprintf(parm_str, "0x%04x",
              ((signed char)get_mem(MEM_ROM, addr+1)*2+addr+len)&0xfffe);
@@ -532,8 +562,53 @@ cl_xa::disass(t_addr addr, char *sep)
              ((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");
+    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 :
@@ -570,6 +645,14 @@ cl_xa::disass(t_addr addr, char *sep)
               ((signed char)get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe );
     break;
 
+    case A_APLUSDPTR :
+      strcpy(parm_str, "A, [A+DPTR]");
+    break;
+
+    case A_APLUSPC :
+      strcpy(parm_str, "A, [A+PC]");
+    break;
+
     default:
       strcpy(parm_str, "???");
     break;
@@ -589,6 +672,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++;
@@ -614,18 +698,18 @@ 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",
                  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",
+  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);
@@ -654,7 +738,7 @@ int 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++;