]> git.gag.com Git - fw/sdcc/blobdiff - sim/ucsim/xa.src/inst.cc
*** empty log message ***
[fw/sdcc] / sim / ucsim / xa.src / inst.cc
index 47920fdf4a64bbd829632327f55de8ab5cfa4e03..ec737aa83bd2d38e10cd059eed8574e881502c4f 100644 (file)
@@ -35,19 +35,87 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "xacl.h"
 #include "regsxa.h"
 
+
+void cl_xa::store1(t_addr addr, unsigned char val)
+{
+  if (addr < 0x2000) {
+    set_idata1(addr, val);
+  } else {
+    set_xdata1(addr, val);
+  }
+}
+
+void cl_xa::store2(t_addr addr, unsigned char val)
+{
+  if (addr < 0x2000) {
+    set_idata2(addr, val);
+  } else {
+    set_xdata2(addr, val);
+  }
+}
+
+unsigned char cl_xa::get1(t_addr addr)
+{
+  if (addr < 0x2000) {
+    return get_idata1(addr);
+  } else {
+    return get_xdata1(addr);
+  }
+}
+
+unsigned short cl_xa::get2(t_addr addr)
+{
+  if (addr < 0x2000) {
+    return get_idata2(addr);
+  } else {
+    return get_xdata2(addr);
+  }
+}
+
 int cl_xa::get_reg(int word_flag, unsigned int index)
 {
-  //if (index < 3) { /* banked */
-  //  if (word_flag)
-  //    return get_word_direct(0x400+index);
-  //  else
-  //    return mem_direct[0x400+index];
-  //} else { /* non-banked */
-    if (word_flag)
-      return get_word_direct(0x400+index);
-    else
-      return mem_direct[0x400+index];
-  //}
+  int result;
+
+  if (word_flag) {
+    result = get_word_direct(index);
+  }
+  else {
+    result = get_byte_direct(index);
+  }
+  return result;
+}
+
+bool cl_xa::get_bit(int bit) {
+  short offset=0;
+  unsigned char result;
+
+  if (bit>=0x200) {
+    // in sfr space
+    bit-=0x200;
+    offset=0x400;
+  }
+  result = get_byte_direct(offset + (bit/8)) & (1 << (bit%8));
+  return result;
+  //return mem_direct[offset + (bit/8)] & (1 << (bit%8));
+}
+
+void cl_xa::set_bit(int bit, int value) {
+  int i;
+  short offset=0;
+  if (bit>=0x200) {
+    // in sfr space
+    bit-=0x200;
+    offset=0x400;
+  }
+
+  i = get_byte_direct(offset + (bit/8));
+  if (value) {
+    set_byte_direct(offset + (bit/8), i | (1 << (bit%8)) );
+    //mem_direct[offset + (bit/8)] |= (1 << (bit%8));
+  } else {
+    set_byte_direct(offset + (bit/8), i & ~(1 << (bit%8)) );
+    //mem_direct[offset + (bit/8)] &= ~(1 << (bit%8));
+  }
 }
 
 #define RI_F0 ((code >> 4) & 0xf)
@@ -178,7 +246,7 @@ int cl_xa::inst_BPL(uint code, int operands)
 int cl_xa::inst_BR(uint code, int operands)
 {
   short jmpAddr = fetch1()*2;
-  PC=(PC+jmpAddr)&0xfffffffe;
+  PC=(PC+jmpAddr)&0xfffffe;
   return(resGO);
 }
 
@@ -186,33 +254,35 @@ int cl_xa::inst_CALL(uint code, int operands)
 {
   int jmpaddr;
   unsigned int sp;
+  bool pageZero=get_scr()&1;
 
   switch(operands) {
     case REL16:
     {
       jmpaddr = (signed short)fetch2();
-      sp = get_sp() - 4;
+      sp = get_sp() - (pageZero ? 2 : 4);
       set_sp(sp);
-      store2(sp, PC);
-      store2(sp+2, 0);  /* segment(not sure about ordering...) */
+      store2(sp, PC&0xffff);
+      if (!pageZero) {
+       store2(sp+2, (PC>>16)&0xff);
+      }
       jmpaddr *= 2;
-      PC = (PC + jmpaddr) & 0xfffffffe;
+      PC = (PC + jmpaddr) & 0xfffffe;
     }
     break;
     case IREG:
     {
-      sp = get_sp() - 2;
+      sp = get_sp() - (pageZero ? 2 : 4);
       set_sp(sp);
-      store2(sp, PC);
-#if 0 // only in huge model
-      store2(sp+2, ...
-#endif
+      store2(sp, PC&0xffff);
+      if (!pageZero) {
+       store2(sp+2, (PC>>16)&0xff);
+      }
       jmpaddr = reg2(RI_07);
       jmpaddr *= 2;
-      PC = (PC + jmpaddr) & 0xfffffffe;
+      PC = (PC + jmpaddr) & 0xfffffe;
     }
     break;
-    /* fixme 2 more... */ /* johan: which ones? */
   }
   return(resGO);
 }
@@ -320,12 +390,12 @@ int cl_xa::inst_DJNZ(uint code, int operands)
          unsigned short tmp = mov2(0, reg2(RI_F0)-1);
          set_reg2(RI_F0, tmp);
          if (tmp != 0)
-           PC = (PC + addr) & 0xfffffffe;
+           PC = (PC + addr) & 0xfffffe;
        } else {
          unsigned char tmp = mov1(0, reg1(RI_F0)-1);
          set_reg1(RI_F0, tmp);
          if (tmp != 0)
-           PC = (PC + addr) & 0xfffffffe;
+           PC = (PC + addr) & 0xfffffe;
        }
     }
     break;
@@ -394,7 +464,7 @@ int cl_xa::inst_JMP(uint code, int operands)
     case REL16:
     {
       jmpAddr = (signed short)fetch2()*2;
-      PC = (PC + jmpAddr) & 0xfffffffe;
+      PC = (PC + jmpAddr) & 0xfffffe;
     }
     break;
     case IREG:
@@ -464,7 +534,36 @@ int cl_xa::inst_MOVC(uint code, int operands)
       }
     }
     break;
-    // fixme, 2 more
+    case A_APLUSDPTR:
+    {  /* R4l=ACC, R6=DPTR */
+      unsigned int addr = (PC & 0xff0000) | (reg1(4) + reg2(6));
+      unsigned short result;
+      unsigned char flags;
+      flags = get_psw();
+
+      flags &= ~(BIT_Z | BIT_N); /* clear these bits */
+      result = getcode1(addr);
+      set_reg1( 4, result);
+      if (result == 0) flags |= BIT_Z;
+      if (result & 0x80) flags |= BIT_N;
+      set_psw(flags);
+    }
+    break;
+    case A_APLUSPC:
+    {  /* R4l=ACC, R6=DPTR */
+      unsigned int addr = (PC + reg1(4));
+      unsigned short result;
+      unsigned char flags;
+      flags = get_psw();
+
+      flags &= ~(BIT_Z | BIT_N); /* clear these bits */
+      result = getcode1(addr);
+      set_reg1( 4, result);
+      if (result == 0) flags |= BIT_Z;
+      if (result & 0x80) flags |= BIT_N;
+      set_psw(flags);
+    }
+    break;
   }
   return(resGO);
 }
@@ -569,17 +668,35 @@ int cl_xa::inst_RET(uint code, int operands)
 {
   unsigned int retaddr;
   unsigned short sp;
+  bool pageZero=get_scr()&1;
+
   sp = get_sp();
   retaddr = get2(sp);
-#if 0 // only in huge model
-  retaddr |= get2(sp+2) << 16;
-#endif
-  set_sp(sp+2);
+  if (!pageZero) {
+    retaddr |= get2(sp+2) << 16;
+    set_sp(sp+4);
+  } else {
+    set_sp(sp+2);
+  }
   PC = retaddr;
   return(resGO);
 }
 int cl_xa::inst_RETI(uint code, int operands)
 {
+  unsigned int retaddr;
+  unsigned short sp;
+  bool pageZero=get_scr()&1;
+
+  sp = get_sp();
+  set_psw(get2(sp));
+  retaddr = get2(sp+2);
+  if (!pageZero) {
+    retaddr |= get2(sp+4) << 16;
+    set_sp(sp+6);
+  } else {
+    set_sp(sp+4);
+  }
+  PC = retaddr;
   return(resGO);
 }
 int cl_xa::inst_RL(uint code, int operands)