EASy68K  
It is currently Wed Nov 22, 2017 8:22 pm

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: ADDX -(A0),-(A0)
PostPosted: Thu Apr 05, 2012 1:20 pm 
Offline
User avatar

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1049
The addressing mode is not behaving correctly. The pre-decrement should be progressive.

Pre: A0 is $1002
$1000: 01 02 00

Post: A0 should be $1000
$1000: 03 02 00

_________________
Prof. Kelly


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2012 2:00 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
Seems to impact ADDX.W and ADDX.L also, but not a similar MOVE.W

ADDX is one of the few logic operations that permits EA, EA addressing.

I guess CMPM, ABCD, SBCD, SUBX would be worth a look also.

..

SUBX fails
ABCD fails
SBCD fails

CMPM only has (Ax)+, (Ax)+ behaviour, need to check if (A0)+,(A0)+ operates as expected

CMPM.B (A0)+,(A0)+ advances A0 by two, but seems to set Z when the subsequent values are not the same, using A0 and A1 to point to A0+1 does not set Z. Need to check on real silicon, but this appears to be wrong.

CMPM fails


Last edited by clive on Thu Apr 05, 2012 7:12 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2012 7:04 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
Here's a fix for CMPM
Code:
int   CMPM()
{
long   size;
int   Rx, Ry;

if (decode_size(&size))
  return (BAD_INST);

Rx = a_reg((inst >> 9) & 0x07);

Ry = a_reg(inst & 0x07);

mem_req ( (int) A[Ry], size, &source);

if (size == BYTE_MASK)
   A[Ry]++;
else if (size == WORD_MASK)
   A[Ry] += 2;
else if (size == LONG_MASK)
   A[Ry] += 4;

mem_req ( (int) A[Rx], size, &dest);

if (size == BYTE_MASK)
   A[Rx]++;
else if (size == WORD_MASK)
   A[Rx] += 2;
else if (size == LONG_MASK)
   A[Rx] += 4;

put (&result, dest - source, size);

/* now set the condition codes according to the result */
cc_update (N_A, GEN, GEN, CASE_2, CASE_6, source, dest, result, size, 0);

inc_cyc ( (size == LONG_MASK) ? 20 : 12);

return SUCCESS;
}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2012 7:09 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
For ADDX

Code:
int   ADDX()
{
  long   size;
  int   Rx, Ry;

  if (decode_size(&size)) return (BAD_INST);

  Rx = (inst >> 9) & 0x0007;
  Ry = inst & 0x0007;

  /* perform the ADDX operation */
  if (inst & 0x0008)
          {
          Rx = a_reg (Rx);
          Ry = a_reg (Ry);

          if (size == BYTE_MASK)
             A[Ry]--;
          else if (size == WORD_MASK)
             A[Ry] -= 2;
          else if (size == LONG_MASK)
             A[Ry] -= 4;

          mem_req ((int) A[Ry], size, &source);

          if (size == BYTE_MASK)
            A[Rx]--;
          else if (size == WORD_MASK)
            A[Rx] -= 2;
          else if (size == LONG_MASK)
            A[Rx] -= 4;

          mem_req ((int) A[Rx], size, &dest);

          put ((long *)&memory[A[a_reg(Rx)]], source + dest + ((SR & xbit) >> 4), size);
          mem_req ((int) A[Rx], size, &result);
          }
  else
          {
          source = D[Ry] & size;
          dest = D[Rx] & size;
          put (&D[Rx], source + dest + ((SR & xbit) >> 4), size);
          result = D[Rx] & size;
          }

  cc_update (GEN, GEN, CASE_1, CASE_1, CASE_5, source, dest, result, size, 0);

  if (size == LONG_MASK)
     inc_cyc ( (inst & 0x0008) ? 30 : 8);
  else
     inc_cyc ( (inst & 0x0008) ? 18 : 4);

  return SUCCESS;

}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2012 7:14 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
ABCD, SBCD
Code:
//-------------------------------------------------------
// perform the ABCD operation
int   ABCD()
{
  int   Rx, Ry, carry, temp_result;

  Rx = (inst >> 9) & 0x0007;
  Ry = inst & 0x0007;

  if (inst & 0x0008) // Rx & Ry are address registers used in predecrement mode
  {
    Rx = a_reg(Rx);
    Ry = a_reg(Ry);

    A[Ry]--;

    //source = memory[A[Ry]];     //ck 4-2006 replace with below
    mem_req ((int)A[Ry], BYTE_MASK, &source); // cause bus error on bad access

    A[Rx]--;

    //dest = memory[A[Rx]];      //ck 4-2006 replace with below
    mem_req ((int)A[Rx], BYTE_MASK, &dest);

  }
  else      // Rx & Ry are data registers
  {
    source = D[Ry] & BYTE_MASK;
    dest = D[Rx] & BYTE_MASK;
  }

  // perform the ABCD operation
  result = ((SR & xbit) >> 4) + (source & 0xf) + (dest & 0xf);
  if (result > 9)
  {
    result = result - 10;
    carry = 1;
  }
  else
    carry = 0;
  temp_result = ((source >> 4) & 0xf) + ((dest >> 4) & 0xf) + carry;
  if (temp_result > 9)
  {
    temp_result = temp_result - 10;
    carry = 1;
  }
  else
    carry = 0;

  result = result + (temp_result << 4);

  if (inst & 0x0008)
    put ((long *)&memory[A[Rx]], result, (long) BYTE_MASK);
  else
    put (&D[Rx], result, (long) BYTE_MASK);
  if (carry)
    SR = SR | cbit;
  else
    SR = SR & ~cbit;

  cc_update (GEN, UND, CASE_1, UND, N_A, source, dest, result, (long) BYTE_MASK, 0);

  inc_cyc ( (inst & 0x0008) ? 18 : 6);

  return SUCCESS;
}



//-------------------------------------------------------
// perform the SUB operation
int   SBCD()
{
  int   Rx, Ry, borrow, temp_result;

  Rx = (inst >> 9) & 0x0007;
  Ry = inst & 0x0007;

  if (inst & 0x0008) //Rx & Ry are address registers used in predecrement mode
  {
    Rx = a_reg(Rx);
    Ry = a_reg(Ry);

    A[Ry]--;

    //source = memory[A[Ry]];     //ck 4-2006 replace with below
    mem_req ((int)A[Ry], BYTE_MASK, &source); // cause bus error on bad access

    A[Rx]--;

    //dest = memory[A[Rx]];      //ck 4-2006 replace with below
    mem_req ((int)A[Rx], BYTE_MASK, &dest);
  }
  else
  {              // Rx & Ry are data registers
    source = D[Ry];
    dest = D[Rx];
  }

  // perform the SBCD operation
  result = (dest & 0xf) - (source & 0xf) - ((SR & xbit) >> 4);
  if (result < 0)
  {
    result = result + 10;
    borrow = 1;
  }
  else
    borrow = 0;
  temp_result = ((dest >> 4) & 0xf) - ((source >> 4) & 0xf) - borrow;
  if (temp_result < 0)
  {
    temp_result = temp_result + 10;
    borrow = 1;
  }
  else
    borrow = 0;
  result = result + (temp_result << 4);

  if (inst & 0x0008)
    put ((long *)&memory[A[Rx]], result, (long) BYTE_MASK);
  else
    put (&D[Rx], result, (long) BYTE_MASK);

  if (borrow)
    SR = SR | cbit;
  else
    SR = SR & ~cbit;

  cc_update (GEN, UND, CASE_1, UND, N_A, source, dest, result, (long) BYTE_MASK, 0);

  inc_cyc ( (inst & 0x0008) ? 18 : 6);

  return SUCCESS;
}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2012 7:20 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
SUBX
Code:
int   SUBX()
{
  long   size;
  int   Rx, Ry;

  if (decode_size(&size))
    return (BAD_INST);

  Ry = (inst >> 9) & 0x0007;
  Rx = inst & 0x0007;

  /* perform the SUBX operation */
  if (inst & 0x0008)
          {
          Rx = a_reg(Rx);
          Ry = a_reg(Ry);

  /* Handle pre-decrements in a linear fashion to permit correct function
      of -(A0),-(A0) type examples */

          if (size == LONG_MASK)
                  A[Rx] -= 4;
          else if (size == WORD_MASK)
                  A[Rx] -= 2;
          else
                  A[Rx]--;

          mem_req ( (int) A[Rx], size, &source);

          if (size == LONG_MASK)
                  A[Ry] -= 4;
          else if (size == WORD_MASK)
                  A[Ry] -= 2;
          else
                  A[Ry]--;

          mem_req ( (int) A[Ry], size, &dest);
          put ((long *)&memory[A[Ry]], dest - source - ((SR & xbit)>> 4), size);
          mem_req ( (int) A[Ry], size, &result);
          }
  else
          {
          source = D[Rx] & size;
          dest = D[Ry] & size;
          put (&D[Ry], dest - source - ((SR & xbit) >> 4), size);
          result = D[Ry] & size;
          }

  cc_update (GEN, GEN, CASE_1, CASE_2, CASE_6, source, dest, result, size, 0);

  if (size == LONG_MASK)
     inc_cyc ( (inst & 0x0008) ? 30 : 8);
  else
     inc_cyc ( (inst & 0x0008) ? 18 : 4);

  return SUCCESS;
}


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 06, 2012 10:02 pm 
Offline
User avatar

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1049
Corrected in EASy68K v5.12.0

_________________
Prof. Kelly


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 06, 2012 10:15 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
Super, will download the new build.

Later:
CMPM, ABCD, ADDX, SBCD, SUBX appear happier now.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google Adsense [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group