* sim/ucsim/hc08.src/inst.cc,
[fw/sdcc] / sim / ucsim / hc08.src / inst.cc
index 6c491a14b0a77c85356d53eebd7b40b1edc38efc..bdd8312d2b18c8b014f659874baa65718e15696a 100644 (file)
@@ -204,112 +204,98 @@ cl_hc08::inst_stx(t_mem code, bool prefix)
 int
 cl_hc08::inst_add(t_mem code, bool prefix)
 {
-  int result;
-  uchar operand;
+  int result, operand1, operand2;
 
-  operand = OPERAND(code, prefix);
-  result = (regs.A + operand) & 0xff;
+  operand1 = regs.A;
+  operand2 = OPERAND(code, prefix);
+  result = operand1 + operand2;
   FLAG_NZ (result);
-  FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result)
-                              | (~regs.A & ~operand & result)));
-  FLAG_ASSIGN (BIT_H, 0x10 & ((regs.A & operand)
-                              | (operand & ~result)
-                              | (~result & regs.A)));
-  FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand)
-                              | (operand & ~result)
-                              | (~result & regs.A)));
-  regs.A = result;
+  FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+  FLAG_ASSIGN (BIT_C, 0x100 & result);
+  FLAG_ASSIGN (BIT_H, 0x10 & (operand1 ^ operand2 ^ result));
+  
+  regs.A = result & 0xff;
   return(resGO);
 }
 
 int
 cl_hc08::inst_adc(t_mem code, bool prefix)
 {
-  int result;
-  uchar operand;
+  int result, operand1, operand2;
+  int carryin = (regs.P & BIT_C)!=0;
 
-  operand = OPERAND(code, prefix);
-  result = (regs.A + operand + ((regs.P & BIT_C)!=0)) & 0xff;
+  operand1 = regs.A;
+  operand2 = OPERAND(code, prefix);
+  result = operand1 + operand2 + carryin;
   FLAG_NZ (result);
-  FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result)
-                              | (~regs.A & ~operand & result)));
-  FLAG_ASSIGN (BIT_H, 0x10 & ((regs.A & operand)
-                              | (operand & ~result)
-                              | (~result & regs.A)));
-  FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand)
-                              | (operand & ~result)
-                              | (~result & regs.A)));
-  regs.A = result;
+  FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+  FLAG_ASSIGN (BIT_C, 0x100 & result);
+  FLAG_ASSIGN (BIT_H, 0x10 & (operand1 ^ operand2 ^ result));
+
+  regs.A = result & 0xff;
   return(resGO);
 }
 
 int
 cl_hc08::inst_sub(t_mem code, bool prefix)
 {
-  int result;
-  uchar operand;
+  int result, operand1, operand2;
 
-  operand = OPERAND(code, prefix);
-  result = (regs.A - operand) & 0xff;
+  operand1 = regs.A;
+  operand2 = OPERAND(code, prefix);
+  result = operand1 - operand2;
   FLAG_NZ (result);
-  FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
-                              | (~regs.A & operand & result)));
-  FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
-                              | (operand & result)
-                              | (result & ~regs.A)));
-  regs.A = result;
+  FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+  FLAG_ASSIGN (BIT_C, 0x100 & result);
+
+  regs.A = result & 0xff;
   return(resGO);
 }
 
 int
 cl_hc08::inst_sbc(t_mem code, bool prefix)
 {
-  int result;
-  uchar operand;
+  int result, operand1, operand2;
+  int carryin = (regs.P & BIT_C)!=0;
 
-  operand = OPERAND(code, prefix);
-  result = (regs.A - operand - ((regs.P & BIT_C)!=0) ) & 0xff;
+  operand1 = regs.A;
+  operand2 = OPERAND(code, prefix);
+  result = operand1 - operand2 - carryin;
   FLAG_NZ (result);
-  FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
-                              | (~regs.A & operand & result)));
-  FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
-                              | (operand & result)
-                              | (result & ~regs.A)));
-  regs.A = result;
+  FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+  FLAG_ASSIGN (BIT_C, 0x100 & result);
+
+  regs.A = result & 0xff;
   return(resGO);
 }
 
 int
 cl_hc08::inst_cmp(t_mem code, bool prefix)
 {
-  int result;
-  uchar operand;
+  int result, operand1, operand2;
 
-  operand = OPERAND(code, prefix);
-  result = (regs.A - operand) & 0xff;
+  operand1 = regs.A;
+  operand2 = OPERAND(code, prefix);
+  result = operand1 - operand2;
   FLAG_NZ (result);
-  FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
-                              | (~regs.A & operand & result)));
-  FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
-                              | (operand & result)
-                              | (result & ~regs.A)));
+  FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+  FLAG_ASSIGN (BIT_C, 0x100 & result);
+
   return(resGO);
 }
 
 int
 cl_hc08::inst_cpx(t_mem code, bool prefix)
 {
-  int result;
-  uchar operand;
+  int result, operand1, operand2;
 
-  operand = OPERAND(code, prefix);
-  result = (regs.X - operand) & 0xff;
+  operand1 = regs.X;
+  operand2 = OPERAND(code, prefix);
+  result = operand1 - operand2;
   FLAG_NZ (result);
-  FLAG_ASSIGN (BIT_V, 0x80 & ((regs.X & ~operand & ~result)
-                              | (~regs.X & operand & result)));
-  FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.X & operand)
-                              | (operand & result)
-                              | (result & ~regs.X)));
+  FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+  FLAG_ASSIGN (BIT_C, 0x100 & result);
+
   return(resGO);
 }
 
@@ -353,7 +339,10 @@ cl_hc08::inst_ais(t_mem code, bool prefix)
 int
 cl_hc08::inst_aix(t_mem code, bool prefix)
 {
-  regs.X = regs.X + (signed char)fetch();
+  int hx = (regs.H << 8) | (regs.X);
+  hx += (signed char)fetch();
+  regs.H = (hx >> 8) & 0xff;
+  regs.X = hx & 0xff;
   return(resGO);
 }
 
@@ -852,11 +841,11 @@ cl_hc08::inst_mul(t_mem code, bool prefix)
 int
 cl_hc08::inst_div(t_mem code, bool prefix)
 {
-  int dividend = (regs.H << 8) | regs.A;
-  int quotient;
+  unsigned int dividend = (regs.H << 8) | regs.A;
+  unsigned int quotient;
 
   if (regs.X) {
-    quotient = dividend / regs.X;
+    quotient = dividend / (unsigned int)regs.X;
     if (quotient<=0xff) {
       regs.A = quotient;
       regs.H = dividend % regs.X;
@@ -1028,25 +1017,26 @@ cl_hc08::inst_mov(t_mem code, bool prefix)
   int ea;
   uchar operand;
   bool aix;
+  int hx = (regs.H << 8) | (regs.X);
   
   switch (code) {
-    case 0x4e:
+    case 0x4e: //mov opr8a,opr8a
       operand = get1(fetch());
       ea = fetch();
       aix = 0;
       break;
-    case 0x5e:
+    case 0x5e: //mov opr8a,x+
       operand = get1(fetch());
-      ea = regs.X;
+      ea = hx;
       aix = 1;
       break;
-    case 0x6e:
+    case 0x6e: //mov #opr8i,opr8a
       operand = fetch();
       ea = fetch();
       aix = 0;
       break;
-    case 0x7e:
-      operand = get1(regs.X);
+    case 0x7e: //mov x+,opr8a
+      operand = get1(hx);
       ea = fetch();
       aix = 1;
       break;
@@ -1074,8 +1064,8 @@ cl_hc08::inst_sthx(t_mem code, bool prefix)
   store1((ea+1) & 0xffff, regs.X);
 
   FLAG_CLEAR(BIT_V);
-  FLAG_ASSIGN(BIT_N, regs.X & 0x80);
-  FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A);
+  FLAG_ASSIGN(BIT_N, regs.H & 0x80);
+  FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
   return(resGO);
 }
 
@@ -1097,8 +1087,8 @@ cl_hc08::inst_ldhx(t_mem code, bool prefix)
     return(resHALT);
   
   FLAG_CLEAR(BIT_V);
-  FLAG_ASSIGN(BIT_N, regs.X & 0x80);
-  FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A);
+  FLAG_ASSIGN(BIT_N, regs.H & 0x80);
+  FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
   return(resGO);
 }
 
@@ -1122,16 +1112,12 @@ cl_hc08::inst_cphx(t_mem code, bool prefix)
     return(resHALT);
 
   hx = (regs.H << 8) | regs.X;
+  result = hx-operand;
 
-  result = (hx-operand) & 0xffff;
-
-  FLAG_ASSIGN (BIT_V, 0x8000 & ((hx & ~operand & ~result)
-                              | (~hx & operand & result)));
-  FLAG_ASSIGN (BIT_C, 0x8000 & ((~hx & operand)
-                              | (operand & result)
-                              | (result & ~hx)));
+  FLAG_ASSIGN (BIT_V, 0x8000 & (hx ^ operand ^ result ^ (result>>1)));
+  FLAG_ASSIGN (BIT_C, 0x10000 & result);
   FLAG_ASSIGN(BIT_N, result & 0x8000);
-  FLAG_ASSIGN(BIT_Z, !result);
+  FLAG_ASSIGN(BIT_Z, !(result & 0xffff));
                               
   return(resGO);
 }