It is currently Wed Jan 22, 2020 3:42 am

 All times are UTC

 Page 1 of 1 [ 8 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: ADDX -(A0),-(A0)Posted: Thu Apr 05, 2012 1:20 pm

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1115
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

 Post subject: Posted: Thu Apr 05, 2012 2:00 pm

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

 Post subject: Posted: Thu Apr 05, 2012 7:04 pm

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

 Post subject: Posted: Thu Apr 05, 2012 7:09 pm

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

 Post subject: Posted: Thu Apr 05, 2012 7:14 pm

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

 Post subject: Posted: Thu Apr 05, 2012 7:20 pm

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

 Post subject: Posted: Fri Apr 06, 2012 10:02 pm

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

_________________
Prof. Kelly

Top

 Post subject: Posted: Fri Apr 06, 2012 10:15 pm

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

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 8 posts ]

 All times are UTC

#### Who is online

Users browsing this forum: No registered users and 1 guest

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

Search for:
 Jump to:  Select a forum ------------------ EASy68K Forum    FAQ    Latest Features    EASy68K Questions    68000 Programming Questions    Wish List    Wishes Granted    Undocumented Features    Documented Features    General Discussion    EASy68K Projects
Powered by phpBB® Forum Software © phpBB Group