]> git.gag.com Git - fw/sdcc/blobdiff - sim/ucsim/hc08.src/inst.cc
* sim/ucsim/hc08.src/inst.cc (inst_condbranch): fixed simulation of
[fw/sdcc] / sim / ucsim / hc08.src / inst.cc
index 6c491a14b0a77c85356d53eebd7b40b1edc38efc..08f786fb6290a1de2effc065d887b85dce65219a 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);
 }
 
@@ -684,6 +673,7 @@ cl_hc08::inst_clr(t_mem code, bool prefix)
   else if ((code & 0xf0) == 0x50)
     regs.X = operand;
   else {
+    ea = fetchea(code,prefix);
     store1(ea, operand);
   }
   return(resGO);
@@ -852,11 +842,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;
@@ -877,6 +867,7 @@ cl_hc08::inst_condbranch(t_mem code, bool prefix)
 {
   bool taken;
   signed char ofs;
+  unsigned char maskedP;
   
   if ((code & 0xf0)==0x20) {
     switch ((code>>1) & 7) {
@@ -884,7 +875,7 @@ cl_hc08::inst_condbranch(t_mem code, bool prefix)
         taken = 1;
         break;
       case 1: // BHI
-        taken = (regs.P & BIT_C) || !(regs.P & BIT_Z);
+        taken = !(regs.P & (BIT_C | BIT_Z));
         break;
       case 2: // BCC
         taken = !(regs.P & BIT_C);
@@ -910,11 +901,12 @@ cl_hc08::inst_condbranch(t_mem code, bool prefix)
   else if ((code & 0xf0)==0x90) {
     switch ((code>>1) & 7) {
       case 0: // BGE
-        taken = !(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0));
+        maskedP = regs.P & (BIT_N | BIT_V);
+        taken = !maskedP || (maskedP == (BIT_N | BIT_V));
         break;
-      case 1: // BLT
-        taken = (!(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0)))
-                || (regs.P & BIT_Z);
+      case 1: // BGT
+        maskedP = regs.P & (BIT_N | BIT_V | BIT_Z);
+        taken = !maskedP || (maskedP == (BIT_N | BIT_V));
         break;
       default:
         return(resHALT);
@@ -1028,25 +1020,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 +1067,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 +1090,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 +1115,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);
 }