Previous 199869 Revisions Next

r33423 Monday 17th November, 2014 at 16:23:18 UTC by Ryan Holtz
rsp: Made the RSP interpreter core functional again. [MooglyGuy]
[src/emu/cpu/rsp]rsp.c rsp.h rspdrc.c

trunk/src/emu/cpu/rsp/rsp.c
r241934r241935
6262#define ACCUM_H(x)      m_accum[((x))].w[3]
6363#define ACCUM_M(x)      m_accum[((x))].w[2]
6464#define ACCUM_L(x)      m_accum[((x))].w[1]
65#define ACCUM_LL(x)     m_accum[((x))].w[0]
6566
6667#define CARRY       0
6768#define COMPARE     1
r241934r241935
7576#define ZERO_FLAG(x)            (m_vflag[ZERO][x & 7] != 0 ? 0xffff : 0)
7677#define CLIP2_FLAG(x)           (m_vflag[CLIP2][x & 7] != 0 ? 0xffff : 0)
7778
78#define CLEAR_CARRY_FLAGS()     { memset(m_vflag[0], 0, 16); }
79#define CLEAR_COMPARE_FLAGS()   { memset(m_vflag[1], 0, 16); }
80#define CLEAR_CLIP1_FLAGS()     { memset(m_vflag[2], 0, 16); }
81#define CLEAR_ZERO_FLAGS()      { memset(m_vflag[3], 0, 16); }
82#define CLEAR_CLIP2_FLAGS()     { memset(m_vflag[4], 0, 16); }
79#define CLEAR_CARRY_FLAGS()     { memset(m_vflag[CARRY], 0, 16); }
80#define CLEAR_COMPARE_FLAGS()   { memset(m_vflag[COMPARE], 0, 16); }
81#define CLEAR_CLIP1_FLAGS()     { memset(m_vflag[CLIP1], 0, 16); }
82#define CLEAR_ZERO_FLAGS()      { memset(m_vflag[ZERO], 0, 16); }
83#define CLEAR_CLIP2_FLAGS()     { memset(m_vflag[CLIP2], 0, 16); }
8384
84#define SET_CARRY_FLAG(x)       { m_vflag[0][x & 7] = 0xffff; }
85#define SET_COMPARE_FLAG(x)     { m_vflag[1][x & 7] = 0xffff; }
86#define SET_CLIP1_FLAG(x)       { m_vflag[2][x & 7] = 0xffff; }
87#define SET_ZERO_FLAG(x)        { m_vflag[3][x & 7] = 0xffff; }
88#define SET_CLIP2_FLAG(x)       { m_vflag[4][x & 7] = 0xffff; }
85#define SET_CARRY_FLAG(x)       { m_vflag[CARRY][x & 7] = 0xffff; }
86#define SET_COMPARE_FLAG(x)     { m_vflag[COMPARE][x & 7] = 0xffff; }
87#define SET_CLIP1_FLAG(x)       { m_vflag[CLIP1][x & 7] = 0xffff; }
88#define SET_ZERO_FLAG(x)        { m_vflag[ZERO][x & 7] = 0xffff; }
89#define SET_CLIP2_FLAG(x)       { m_vflag[CLIP2][x & 7] = 0xffff; }
8990
90#define CLEAR_CARRY_FLAG(x)     { m_vflag[0][x & 7] = 0; }
91#define CLEAR_COMPARE_FLAG(x)   { m_vflag[1][x & 7] = 0; }
92#define CLEAR_CLIP1_FLAG(x)     { m_vflag[2][x & 7] = 0; }
93#define CLEAR_ZERO_FLAG(x)      { m_vflag[3][x & 7] = 0; }
94#define CLEAR_CLIP2_FLAG(x)     { m_vflag[4][x & 7] = 0; }
91#define CLEAR_CARRY_FLAG(x)     { m_vflag[CARRY][x & 7] = 0; }
92#define CLEAR_COMPARE_FLAG(x)   { m_vflag[COMPARE][x & 7] = 0; }
93#define CLEAR_CLIP1_FLAG(x)     { m_vflag[CLIP1][x & 7] = 0; }
94#define CLEAR_ZERO_FLAG(x)      { m_vflag[ZERO][x & 7] = 0; }
95#define CLEAR_CLIP2_FLAG(x)     { m_vflag[CLIP2][x & 7] = 0; }
9596
9697#define ROPCODE(pc)     m_program->read_dword(pc)
9798
r241934r241935
203204inline UINT8 rsp_device::READ8(UINT32 address)
204205{
205206   UINT8 ret;
206   address = 0x04000000 | (address & 0xfff);
207   address &= 0xfff;
207208   ret = m_program->read_byte(address);
208   //printf("%04xr%02x\n", address & 0x0000ffff, ret);
209209   return ret;
210210}
211211
212212inline UINT16 rsp_device::READ16(UINT32 address)
213213{
214214   UINT16 ret;
215   address = 0x04000000 | (address & 0xfff);
215   address &= 0xfff;
216216
217   if(address & 1)
218   {
219      ret = ((m_program->read_byte(address + 0) & 0xff) << 8) | (m_program->read_byte(address + 1) & 0xff);
220   }
221   else
222   {
223      ret = m_program->read_word(address);
224   }
217   ret = (m_program->read_byte(address) << 8) | (m_program->read_byte(address + 1) & 0xff);
225218
226   //printf("%04xr%04x\n", address & 0x0000ffff, ret);
227
228219   return ret;
229220}
230221
231222inline UINT32 rsp_device::READ32(UINT32 address)
232223{
233224   UINT32 ret;
234   address = 0x04000000 | (address & 0xfff);
225   address &= 0xfff;
235226
236   if(address & 3)
237   {
238      ret =  ((m_program->read_byte(address + 0) & 0xff) << 24) |
239            ((m_program->read_byte(address + 1) & 0xff) << 16) |
240            ((m_program->read_byte(address + 2) & 0xff) << 8) |
241            ((m_program->read_byte(address + 3) & 0xff) << 0);
242   }
243   else
244   {
245      ret = m_program->read_dword(address);
246   }
227   ret =   (m_program->read_byte(address) << 24) |
228         (m_program->read_byte(address + 1) << 16) |
229         (m_program->read_byte(address + 2) << 8) |
230         (m_program->read_byte(address + 3) << 0);
247231
248   //printf("%04xr%08x\n", address & 0x0000ffff, ret);
249232   return ret;
250233}
251234
252235void rsp_device::WRITE8(UINT32 address, UINT8 data)
253236{
254   address = 0x04000000 | (address & 0xfff);
255   //printf("%04x:%02x\n", address & 0x0000ffff, data);
237   address &= 0xfff;
256238   m_program->write_byte(address, data);
257239}
258240
259241void rsp_device::WRITE16(UINT32 address, UINT16 data)
260242{
261   address = 0x04000000 | (address & 0xfff);
262   //printf("%04x:%04x\n", address & 0x0000ffff, data);
243   address &= 0xfff;
263244
264   if(address & 1)
265   {
266      m_program->write_byte(address + 0, (data >> 8) & 0xff);
267      m_program->write_byte(address + 1, (data >> 0) & 0xff);
268      return;
269   }
270
271   m_program->write_word(address, data);
245   m_program->write_byte(address, data >> 8);
246   m_program->write_byte(address + 1, data & 0xff);
272247}
273248
274249void rsp_device::WRITE32(UINT32 address, UINT32 data)
275250{
276   address = 0x04000000 | (address & 0xfff);
277   //printf("%04x:%08x\n", address & 0x0000ffff, data);
251   address &= 0xfff;
278252
279   if(address & 3)
280   {
281      m_program->write_byte(address + 0, (data >> 24) & 0xff);
282      m_program->write_byte(address + 1, (data >> 16) & 0xff);
283      m_program->write_byte(address + 2, (data >> 8) & 0xff);
284      m_program->write_byte(address + 3, (data >> 0) & 0xff);
285      return;
286   }
287
288   m_program->write_dword(address, data);
253   m_program->write_byte(address, data >> 24);
254   m_program->write_byte(address + 1, (data >> 16) & 0xff);
255   m_program->write_byte(address + 2, (data >> 8) & 0xff);
256   m_program->write_byte(address + 3, data & 0xff);
289257}
290258
291259/*****************************************************************************/
r241934r241935
402370   m_direct = &m_program->direct();
403371   resolve_cb();
404372
405   // Inaccurate.  RSP registers power on to a random state...
373   // RSP registers should power on to a random state
406374   for(int regIdx = 0; regIdx < 32; regIdx++ )
407375   {
408376      m_rsp_state->r[regIdx] = 0;
r241934r241935
414382   CLEAR_CLIP1_FLAGS();
415383   CLEAR_ZERO_FLAGS();
416384   CLEAR_CLIP2_FLAGS();
417   //m_square_root_res = 0;
418   //m_square_root_high = 0;
419385   m_reciprocal_res = 0;
420386   m_reciprocal_high = 0;
421387
422   // ...except for the accumulators.
423   // We're not calling machine.rand() because initializing something with machine.rand()
424   //   makes me retch uncontrollably.
388   // Accumulators do not power on to a random state
425389   for(int accumIdx = 0; accumIdx < 8; accumIdx++ )
426390   {
427391      m_accum[accumIdx].q = 0;
r241934r241935
458422      m_regmap[regnum] = (regnum == 0) ? uml::parameter(0) : uml::parameter::make_memory(&m_rsp_state->r[regnum]);
459423   }
460424
461   /*
462   drcbe_info beinfo;
463   m_drcuml->get_backend_info(beinfo);
464   if (beinfo.direct_iregs > 2)
465   {
466       m_regmap[30] = I2;
467   }
468   if (beinfo.direct_iregs > 3)
469   {
470       m_regmap[31] = I3;
471   }
472   if (beinfo.direct_iregs > 4)
473   {
474       m_regmap[2] = I4;
475   }
476   if (beinfo.direct_iregs > 5)
477   {
478       m_regmap[3] = I5;
479   }
480   if (beinfo.direct_iregs > 6)
481   {
482       m_regmap[4] = I6;
483   }
484   */
485
486425   /* mark the cache dirty so it is updated on next execute */
487426   m_cache_dirty = TRUE;
488427
r241934r241935
15271466         }
15281467      }
15291468   }
1530
1531   // never executed
1532   //return 0;
15331469}
15341470
15351471#define WRITEBACK_RESULT() {memcpy(&m_v[VDREG].s[0], &vres[0], 16);}
15361472
1537#if 0
1538static float float_round(float input)
1539{
1540   INT32 integer = (INT32)input;
1541   float fraction = input - (float)integer;
1542   float output = 0.0f;
1543   if( fraction >= 0.5f )
1544   {
1545      output = (float)( integer + 1 );
1546   }
1547   else
1548   {
1549      output = (float)integer;
1550   }
1551   return output;
1552}
1553#endif
1554
15551473void rsp_device::handle_vector_ops(UINT32 op)
15561474{
15571475   int i;
r241934r241935
15781496         //
15791497         // Multiplies signed integer by signed integer * 2
15801498
1581         int sel;
1582         INT32 s1, s2;
1583         INT64 r;
15841499         for (i=0; i < 8; i++)
15851500         {
1586            sel = VEC_EL_2(EL, i);
1587            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1588            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
1501            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1502            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1503
15891504            if (s1 == -32768 && s2 == -32768)
15901505            {
15911506               // overflow
r241934r241935
15961511            }
15971512            else
15981513            {
1599               r =  s1 * s2 * 2;
1514               INT64 r =  s1 * s2 * 2;
16001515               r += 0x8000;    // rounding ?
16011516               ACCUM_H(i) = (r < 0) ? 0xffff : 0;      // sign-extend to 48-bit
16021517               ACCUM_M(i) = (INT16)(r >> 16);
r241934r241935
16171532         // ------------------------------------------------------
16181533         //
16191534
1620         int sel;
1621         INT32 s1, s2;
1622         INT64 r;
16231535         for (i=0; i < 8; i++)
16241536         {
1625            sel = VEC_EL_2(EL, i);
1626            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1627            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
1628            r = s1 * s2 * 2;
1537            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1538            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1539
1540            INT64 r = s1 * s2 * 2;
16291541            r += 0x8000;    // rounding ?
16301542
16311543            ACCUM_H(i) = (UINT16)(r >> 32);
r241934r241935
16601572         // Stores the higher 16 bits of the 32-bit result to accumulator
16611573         // The low slice of accumulator is stored into destination element
16621574
1663         int sel;
1664         UINT32 s1, s2;
1665         UINT32 r;
16661575         for (i=0; i < 8; i++)
16671576         {
1668            sel = VEC_EL_2(EL, i);
1669            s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
1670            s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
1671            r = s1 * s2;
1577            UINT32 s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
1578            UINT32 s2 = (UINT32)(UINT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1579            UINT32 r = s1 * s2;
16721580
16731581            ACCUM_H(i) = 0;
16741582            ACCUM_M(i) = 0;
r241934r241935
16911599         // The result is stored into accumulator
16921600         // The middle slice of accumulator is stored into destination element
16931601
1694         int sel;
1695         INT32 s1, s2;
1696         INT32 r;
16971602         for (i=0; i < 8; i++)
16981603         {
1699            sel = VEC_EL_2(EL, i);
1700            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1701            s2 = (UINT16)VREG_S(VS2REG, sel);   // not sign-extended
1702            r =  s1 * s2;
1604            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1605            INT32 s2 = (UINT16)VREG_S(VS2REG, VEC_EL_2(EL, i));   // not sign-extended
1606            INT32 r =  s1 * s2;
17031607
17041608            ACCUM_H(i) = (r < 0) ? 0xffff : 0;      // sign-extend to 48-bit
17051609            ACCUM_M(i) = (INT16)(r >> 16);
r241934r241935
17231627         // The result is stored into accumulator
17241628         // The low slice of accumulator is stored into destination element
17251629
1726         int sel;
1727         INT32 s1, s2;
1728         INT32 r;
17291630         for (i=0; i < 8; i++)
17301631         {
1731            sel = VEC_EL_2(EL, i);
1732            s1 = (UINT16)VREG_S(VS1REG, i);     // not sign-extended
1733            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
1734            r = s1 * s2;
1632            INT32 s1 = (UINT16)VREG_S(VS1REG, i);     // not sign-extended
1633            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1634            INT32 r = s1 * s2;
17351635
17361636            ACCUM_H(i) = (r < 0) ? 0xffff : 0;      // sign-extend to 48-bit
17371637            ACCUM_M(i) = (INT16)(r >> 16);
r241934r241935
17541654         // The result is stored into highest 32 bits of accumulator, the low slice is zero
17551655         // The highest 32 bits of accumulator is saturated into destination element
17561656
1757         int sel;
1758         INT32 s1, s2;
1759         INT32 r;
17601657         for (i=0; i < 8; i++)
17611658         {
1762            sel = VEC_EL_2(EL, i);
1763            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1764            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
1765            r = s1 * s2;
1659            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1660            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1661            INT32 r = s1 * s2;
17661662
17671663            ACCUM_H(i) = (INT16)(r >> 16);
17681664            ACCUM_M(i) = (UINT16)(r);
r241934r241935
17861682         // Multiplies signed integer by signed integer * 2
17871683         // The result is added to accumulator
17881684
1789         int sel;
1790         INT32 s1, s2;
1791         INT32 r;
1792         UINT16 res;
17931685         for (i=0; i < 8; i++)
17941686         {
1795            sel = VEC_EL_2(EL, i);
1796            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1797            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
1798            r = s1 * s2;
1687            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1688            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1689            INT32 r = s1 * s2;
17991690
1800            ACCUM(i) += (INT64)(r) << 17;
1801            res = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff);
1691            UINT64 q = (UINT64)(UINT16)ACCUM_LL(i);
1692            q |= (((UINT64)(UINT16)ACCUM_L(i)) << 16);
1693            q |= (((UINT64)(UINT16)ACCUM_M(i)) << 32);
1694            q |= (((UINT64)(UINT16)ACCUM_H(i)) << 48);
18021695
1803            vres[i] = res;
1696            q += (INT64)(r) << 17;
1697
1698            ACCUM_LL(i) = (UINT16)q;
1699            ACCUM_L(i) = (UINT16)(q >> 16);
1700            ACCUM_M(i) = (UINT16)(q >> 32);
1701            ACCUM_H(i) = (UINT16)(q >> 48);
1702
1703            vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff);
18041704         }
18051705         WRITEBACK_RESULT();
18061706         break;
r241934r241935
18141714         // ------------------------------------------------------
18151715         //
18161716
1817         UINT16 res;
1818         int sel;
1819         INT32 s1, s2, r1;
1820         UINT32 r2, r3;
18211717         for (i = 0; i < 8; i++)
18221718         {
1823            sel = VEC_EL_2(EL, i);
1824            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1825            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
1826            r1 = s1 * s2;
1827            r2 = (UINT16)ACCUM_L(i) + ((UINT16)(r1) * 2);
1828            r3 = (UINT16)ACCUM_M(i) + (UINT16)((r1 >> 16) * 2) + (UINT16)(r2 >> 16);
1719            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1720            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1721            INT32 r1 = s1 * s2;
1722            UINT32 r2 = (UINT16)ACCUM_L(i) + ((UINT16)(r1) * 2);
1723            UINT32 r3 = (UINT16)ACCUM_M(i) + (UINT16)((r1 >> 16) * 2) + (UINT16)(r2 >> 16);
18291724
18301725            ACCUM_L(i) = (UINT16)(r2);
18311726            ACCUM_M(i) = (UINT16)(r3);
18321727            ACCUM_H(i) += (UINT16)(r3 >> 16) + (UINT16)(r1 >> 31);
18331728
1834            //res = SATURATE_ACCUM(i, 1, 0x0000, 0xffff);
18351729            if ((INT16)ACCUM_H(i) < 0)
18361730            {
1837               res = 0;
1731               vres[i] = 0;
18381732            }
18391733            else
18401734            {
18411735               if (ACCUM_H(i) != 0)
18421736               {
1843                  res = 0xffff;
1737                  vres[i] = 0xffff;
18441738               }
18451739               else
18461740               {
18471741                  if ((INT16)ACCUM_M(i) < 0)
18481742                  {
1849                     res = 0xffff;
1743                     vres[i] = 0xffff;
18501744                  }
18511745                  else
18521746                  {
1853                     res = ACCUM_M(i);
1747                     vres[i] = ACCUM_M(i);
18541748                  }
18551749               }
18561750            }
1857
1858            vres[i] = res;
18591751         }
18601752         WRITEBACK_RESULT();
18611753         break;
r241934r241935
18721764         // Adds the higher 16 bits of the 32-bit result to accumulator
18731765         // The low slice of accumulator is stored into destination element
18741766
1875         UINT16 res;
1876         int sel;
1877         UINT32 s1, s2, r1;
1878         UINT32 r2, r3;
18791767         for (i = 0; i < 8; i++)
18801768         {
1881            sel = VEC_EL_2(EL, i);
1882            s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
1883            s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
1884            r1 = s1 * s2;
1885            r2 = (UINT16)ACCUM_L(i) + (r1 >> 16);
1886            r3 = (UINT16)ACCUM_M(i) + (r2 >> 16);
1769            UINT32 s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
1770            UINT32 s2 = (UINT32)(UINT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1771            UINT32 r1 = s1 * s2;
1772            UINT32 r2 = (UINT16)ACCUM_L(i) + (r1 >> 16);
1773            UINT32 r3 = (UINT16)ACCUM_M(i) + (r2 >> 16);
18871774
18881775            ACCUM_L(i) = (UINT16)(r2);
18891776            ACCUM_M(i) = (UINT16)(r3);
18901777            ACCUM_H(i) += (INT16)(r3 >> 16);
18911778
1892            res = SATURATE_ACCUM(i, 0, 0x0000, 0xffff);
1893
1894            vres[i] = res;
1779            vres[i] = SATURATE_ACCUM(i, 0, 0x0000, 0xffff);
18951780         }
18961781         WRITEBACK_RESULT();
18971782         break;
r241934r241935
19081793         // The result is added into accumulator
19091794         // The middle slice of accumulator is stored into destination element
19101795
1911         UINT16 res;
1912         int sel;
1913         UINT32 s1, s2, r1;
1914         UINT32 r2, r3;
19151796         for (i=0; i < 8; i++)
19161797         {
1917            sel = VEC_EL_2(EL, i);
1918            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1919            s2 = (UINT16)VREG_S(VS2REG, sel);   // not sign-extended
1920            r1 = s1 * s2;
1921            r2 = (UINT16)ACCUM_L(i) + (UINT16)(r1);
1922            r3 = (UINT16)ACCUM_M(i) + (r1 >> 16) + (r2 >> 16);
1798            UINT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1799            UINT32 s2 = (UINT16)VREG_S(VS2REG, VEC_EL_2(EL, i));   // not sign-extended
1800            UINT32 r1 = s1 * s2;
1801            UINT32 r2 = (UINT16)ACCUM_L(i) + (UINT16)(r1);
1802            UINT32 r3 = (UINT16)ACCUM_M(i) + (r1 >> 16) + (r2 >> 16);
19231803
19241804            ACCUM_L(i) = (UINT16)(r2);
19251805            ACCUM_M(i) = (UINT16)(r3);
r241934r241935
19271807            if ((INT32)(r1) < 0)
19281808               ACCUM_H(i) -= 1;
19291809
1930            res = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff);
1931
1932            vres[i] = res;
1810            vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff);
19331811         }
19341812         WRITEBACK_RESULT();
19351813         break;
r241934r241935
19461824         // The result is added into accumulator
19471825         // The low slice of accumulator is stored into destination element
19481826
1949         INT32 s1, s2;
1950         UINT16 res;
1951         int sel;
19521827         for (i=0; i < 8; i++)
19531828         {
1954            sel = VEC_EL_2(EL, i);
1955            s1 = (UINT16)VREG_S(VS1REG, i);     // not sign-extended
1956            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
1829            INT32 s1 = (UINT16)VREG_S(VS1REG, i);     // not sign-extended
1830            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
19571831
1958            ACCUM(i) += (INT64)(s1*s2)<<16;
1832            UINT64 q = (UINT64)ACCUM_LL(i);
1833            q |= (((UINT64)ACCUM_L(i)) << 16);
1834            q |= (((UINT64)ACCUM_M(i)) << 32);
1835            q |= (((UINT64)ACCUM_H(i)) << 48);
1836            q += (INT64)(s1*s2) << 16;
19591837
1960            res = SATURATE_ACCUM(i, 0, 0x0000, 0xffff);
1961            vres[i] = res;
1838            ACCUM_LL(i) = (UINT16)q;
1839            ACCUM_L(i) = (UINT16)(q >> 16);
1840            ACCUM_M(i) = (UINT16)(q >> 32);
1841            ACCUM_H(i) = (UINT16)(q >> 48);
1842
1843            vres[i] = SATURATE_ACCUM(i, 0, 0x0000, 0xffff);
19621844         }
19631845         WRITEBACK_RESULT();
19641846
r241934r241935
19761858         // The result is added into highest 32 bits of accumulator, the low slice is zero
19771859         // The highest 32 bits of accumulator is saturated into destination element
19781860
1979         UINT16 res;
1980         int sel;
1981         INT32 s1, s2;
19821861         for (i = 0; i < 8; i++)
19831862         {
1984            sel = VEC_EL_2(EL, i);
1985            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1986            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
1863            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1864            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
19871865
1988            m_accum[i].l[1] += s1*s2;
1866            INT32 accum = (UINT32)(UINT16)ACCUM_M(i);
1867            accum |= ((UINT32)((UINT16)ACCUM_H(i))) << 16;
1868            accum += s1 * s2;
19891869
1990            res = SATURATE_ACCUM1(i, 0x8000, 0x7fff);
1870            ACCUM_H(i) = (UINT16)(accum >> 16);
1871            ACCUM_M(i) = (UINT16)accum;
19911872
1992            vres[i] = res;
1873            vres[i] = SATURATE_ACCUM1(i, 0x8000, 0x7fff);
19931874         }
19941875         WRITEBACK_RESULT();
19951876
r241934r241935
20071888
20081889         // TODO: check VS2REG == VDREG
20091890
2010         int sel;
2011         INT32 s1, s2, r;
20121891         for (i=0; i < 8; i++)
20131892         {
2014            sel = VEC_EL_2(EL, i);
2015            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
2016            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
2017            r = s1 + s2 + CARRY_FLAG(i);
1893            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1894            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1895            INT32 r = s1 + s2 + (CARRY_FLAG(i) != 0 ? 1 : 0);
20181896
20191897            ACCUM_L(i) = (INT16)(r);
20201898
r241934r241935
20391917
20401918         // TODO: check VS2REG == VDREG
20411919
2042         int sel;
2043         INT32 s1, s2, r;
20441920         for (i = 0; i < 8; i++)
20451921         {
2046            sel = VEC_EL_2(EL, i);
2047            s1 = (INT32)(INT16)VREG_S(VS1REG, i);
2048            s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
2049            r = s1 - s2 - CARRY_FLAG(i);
1922            INT32 s1 = (INT32)(INT16)VREG_S(VS1REG, i);
1923            INT32 s2 = (INT32)(INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1924            INT32 r = s1 - s2 - (CARRY_FLAG(i) != 0 ? 1 : 0);
20501925
20511926            ACCUM_L(i) = (INT16)(r);
20521927
r241934r241935
20711946         // Changes the sign of source register 2 if source register 1 is negative and stores
20721947         // the result to destination register
20731948
2074         int sel;
2075         INT16 s1, s2;
20761949         for (i=0; i < 8; i++)
20771950         {
2078            sel = VEC_EL_2(EL, i);
2079            s1 = (INT16)VREG_S(VS1REG, i);
2080            s2 = (INT16)VREG_S(VS2REG, sel);
1951            INT16 s1 = (INT16)VREG_S(VS1REG, i);
1952            INT16 s2 = (INT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
20811953
20821954            if (s1 < 0)
20831955            {
r241934r241935
21161988
21171989         // TODO: check VS2REG = VDREG
21181990
2119         int sel;
2120         INT32 s1, s2, r;
21211991         CLEAR_ZERO_FLAGS();
21221992         CLEAR_CARRY_FLAGS();
21231993
21241994         for (i=0; i < 8; i++)
21251995         {
2126            sel = VEC_EL_2(EL, i);
2127            s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
2128            s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
2129            r = s1 + s2;
1996            INT32 s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
1997            INT32 s2 = (UINT32)(UINT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
1998            INT32 r = s1 + s2;
21301999
21312000            vres[i] = (INT16)(r);
21322001            ACCUM_L(i) = (INT16)(r);
r241934r241935
21512020
21522021         // TODO: check VS2REG = VDREG
21532022
2154         int sel;
2155         INT32 s1, s2, r;
21562023         CLEAR_ZERO_FLAGS();
21572024         CLEAR_CARRY_FLAGS();
21582025
21592026         for (i=0; i < 8; i++)
21602027         {
2161            sel = VEC_EL_2(EL, i);
2162            s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
2163            s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
2164            r = s1 - s2;
2028            INT32 s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
2029            INT32 s2 = (UINT32)(UINT16)VREG_S(VS2REG, VEC_EL_2(EL, i));
2030            INT32 r = s1 - s2;
21652031
21662032            vres[i] = (INT16)(r);
21672033            ACCUM_L(i) = (UINT16)(r);
r241934r241935
22312097         // Sets compare flags if elements in VS1 are less than VS2
22322098         // Moves the element in VS2 to destination vector
22332099
2234         int sel;
22352100         CLEAR_COMPARE_FLAGS();
22362101         CLEAR_CLIP2_FLAGS();
22372102
22382103         for (i=0; i < 8; i++)
22392104         {
2240            sel = VEC_EL_2(EL, i);
2241
2242            if (VREG_S(VS1REG, i) < VREG_S(VS2REG, sel))
2105            INT16 s1, s2;
2106            s1 = VREG_S(VS1REG, i);
2107            s2 = VREG_S(VS2REG, VEC_EL_2(EL, i));
2108            if (s1 < s2)
22432109            {
22442110               SET_COMPARE_FLAG(i);
22452111            }
2246            else if (VREG_S(VS1REG, i) == VREG_S(VS2REG, sel))
2112            else if (s1 == s2)
22472113            {
2248               if (ZERO_FLAG(i) == 1 && CARRY_FLAG(i) != 0)
2114               if (ZERO_FLAG(i) != 0 && CARRY_FLAG(i) != 0)
22492115               {
22502116                  SET_COMPARE_FLAG(i);
22512117               }
22522118            }
22532119
2254            if (COMPARE_FLAG(i))
2120            if (COMPARE_FLAG(i) != 0)
22552121            {
2256               vres[i] = VREG_S(VS1REG, i);
2122               vres[i] = s1;
22572123            }
22582124            else
22592125            {
2260               vres[i] = VREG_S(VS2REG, sel);
2126               vres[i] = s2;
22612127            }
22622128
22632129            ACCUM_L(i) = vres[i];
r241934r241935
22792145         // Sets compare flags if elements in VS1 are equal with VS2
22802146         // Moves the element in VS2 to destination vector
22812147
2282         int sel;
22832148         CLEAR_COMPARE_FLAGS();
22842149         CLEAR_CLIP2_FLAGS();
22852150
22862151         for (i = 0; i < 8; i++)
22872152         {
2288            sel = VEC_EL_2(EL, i);
2153            INT16 s1 = VREG_S(VS1REG, i);
2154            INT16 s2 = VREG_S(VS2REG, VEC_EL_2(EL, i));
22892155
2290            if ((VREG_S(VS1REG, i) == VREG_S(VS2REG, sel)) && ZERO_FLAG(i) == 0)
2156            if ((s1 == s2) && ZERO_FLAG(i) == 0)
22912157            {
22922158               SET_COMPARE_FLAG(i);
2293               vres[i] = VREG_S(VS1REG, i);
2159               vres[i] = s1;
22942160            }
22952161            else
22962162            {
2297               vres[i] = VREG_S(VS2REG, sel);
2163               vres[i] = s2;
22982164            }
22992165            ACCUM_L(i) = vres[i];
23002166         }
r241934r241935
23152181         // Sets compare flags if elements in VS1 are not equal with VS2
23162182         // Moves the element in VS2 to destination vector
23172183
2318         int sel;
23192184         CLEAR_COMPARE_FLAGS();
23202185         CLEAR_CLIP2_FLAGS();
23212186
2322         for (i=0; i < 8; i++)//?????????? ????
2187         for (i = 0; i < 8; i++)
23232188         {
2324            sel = VEC_EL_2(EL, i);
2189            INT16 s1 = VREG_S(VS1REG, i);
2190            INT16 s2 = VREG_S(VS2REG, VEC_EL_2(EL, i));
23252191
2326            if (VREG_S(VS1REG, i) != VREG_S(VS2REG, sel))
2192            if (s1 != s2 || ZERO_FLAG(i) != 0)
23272193            {
23282194               SET_COMPARE_FLAG(i);
2195               vres[i] = s1;
23292196            }
23302197            else
23312198            {
2332               if (ZERO_FLAG(i) == 1)
2333               {
2334                  SET_COMPARE_FLAG(i);
2335               }
2199               vres[i] = s2;
23362200            }
2337            if (COMPARE_FLAG(i))
2338            {
2339               vres[i] = VREG_S(VS1REG, i);
2340            }
2341            else
2342            {
2343               vres[i] = VREG_S(VS2REG, sel);
2344            }
23452201            ACCUM_L(i) = vres[i];
23462202         }
23472203
r241934r241935
23612217         // Sets compare flags if elements in VS1 are greater or equal with VS2
23622218         // Moves the element in VS2 to destination vector
23632219
2364         int sel;
23652220         CLEAR_COMPARE_FLAGS();
23662221         CLEAR_CLIP2_FLAGS();
23672222
23682223         for (i=0; i < 8; i++)
23692224         {
2370            sel = VEC_EL_2(EL, i);
2225            INT16 s1 = VREG_S(VS1REG, i);
2226            INT16 s2 = VREG_S(VS2REG, VEC_EL_2(EL, i));
23712227
2372            if (VREG_S(VS1REG, i) == VREG_S(VS2REG, sel))
2228            if ((s1 == s2 && (ZERO_FLAG(i) == 0 || CARRY_FLAG(i) == 0)) || s1 > s2)
23732229            {
2374               if (ZERO_FLAG(i) == 0 || CARRY_FLAG(i) == 0)
2375               {
2376                  SET_COMPARE_FLAG(i);
2377               }
2378            }
2379            else if (VREG_S(VS1REG, i) > VREG_S(VS2REG, sel))
2380            {
23812230               SET_COMPARE_FLAG(i);
2231               vres[i] = s1;
23822232            }
2383
2384            if (COMPARE_FLAG(i) != 0)
2385            {
2386               vres[i] = VREG_S(VS1REG, i);
2387            }
23882233            else
23892234            {
2390               vres[i] = VREG_S(VS2REG, sel);
2235               vres[i] = s2;
23912236            }
23922237
23932238            ACCUM_L(i) = vres[i];
r241934r241935
24082253         //
24092254         // Vector clip low
24102255
2411         int sel;
2412         INT16 s1, s2;
24132256         for (i = 0; i < 8; i++)
24142257         {
2415            sel = VEC_EL_2(EL, i);
2416            s1 = VREG_S(VS1REG, i);
2417            s2 = VREG_S(VS2REG, sel);
2258            INT16 s1 = VREG_S(VS1REG, i);
2259            INT16 s2 = VREG_S(VS2REG, VEC_EL_2(EL, i));
24182260
24192261            if (CARRY_FLAG(i) != 0)
24202262            {
r241934r241935
24292271                     ACCUM_L(i) = s1;
24302272                  }
24312273               }
2432               else//ZERO_FLAG(i)==0
2274               else
24332275               {
24342276                  if (CLIP1_FLAG(i) != 0)
24352277                  {
24362278                     if (((UINT32)(UINT16)(s1) + (UINT32)(UINT16)(s2)) > 0x10000)
2437                     {//proper fix for Harvest Moon 64, r4
2279                     {
24382280
24392281                        ACCUM_L(i) = s1;
24402282                        CLEAR_COMPARE_FLAG(i);
r241934r241935
24592301                     }
24602302                  }
24612303               }
2462            }//
2463            else//CARRY_FLAG(i)==0
2304            }
2305            else
24642306            {
24652307               if (ZERO_FLAG(i) != 0)
24662308               {
r241934r241935
25062348         //
25072349         // Vector clip high
25082350
2509         int sel;
2510         INT16 s1, s2;
25112351         CLEAR_CARRY_FLAGS();
25122352         CLEAR_COMPARE_FLAGS();
25132353         CLEAR_CLIP1_FLAGS();
r241934r241935
25172357
25182358         for (i=0; i < 8; i++)
25192359         {
2520            sel = VEC_EL_2(EL, i);
2521            s1 = VREG_S(VS1REG, i);
2522            s2 = VREG_S(VS2REG, sel);
2360            INT16 s1 = VREG_S(VS1REG, i);
2361            INT16 s2 = VREG_S(VS2REG, VEC_EL_2(EL, i));
25232362
25242363            if ((s1 ^ s2) < 0)
25252364            {
r241934r241935
25472386                     SET_ZERO_FLAG(i);
25482387                  }
25492388               }
2550            }//sign
2389            }
25512390            else
25522391            {
25532392               vce = 0;
r241934r241935
25922431         //
25932432         // Vector clip reverse
25942433
2595         int sel;
2596         INT16 s1, s2;
25972434         CLEAR_CARRY_FLAGS();
25982435         CLEAR_COMPARE_FLAGS();
25992436         CLEAR_CLIP1_FLAGS();
r241934r241935
26022439
26032440         for (i=0; i < 8; i++)
26042441         {
2605            sel = VEC_EL_2(EL, i);
2606            s1 = VREG_S(VS1REG, i);
2607            s2 = VREG_S(VS2REG, sel);
2442            INT16 s1 = VREG_S(VS1REG, i);
2443            INT16 s2 = VREG_S(VS2REG, VEC_EL_2(EL, i));
26082444
26092445            if ((INT16)(s1 ^ s2) < 0)
26102446            {
r241934r241935
26542490         //
26552491         // Merges two vectors according to compare flags
26562492
2657         int sel;
26582493         for (i = 0; i < 8; i++)
26592494         {
2660            sel = VEC_EL_2(EL, i);
26612495            if (COMPARE_FLAG(i) != 0)
26622496            {
26632497               vres[i] = VREG_S(VS1REG, i);
26642498            }
26652499            else
26662500            {
2667               vres[i] = VREG_S(VS2REG, sel);//??? ???????????
2501               vres[i] = VREG_S(VS2REG, VEC_EL_2(EL, i));
26682502            }
26692503
26702504            ACCUM_L(i) = vres[i];
r241934r241935
26812515         //
26822516         // Bitwise AND of two vector registers
26832517
2684         int sel;
26852518         for (i = 0; i < 8; i++)
26862519         {
2687            sel = VEC_EL_2(EL, i);
2688            vres[i] = VREG_S(VS1REG, i) & VREG_S(VS2REG, sel);
2520            vres[i] = VREG_S(VS1REG, i) & VREG_S(VS2REG, VEC_EL_2(EL, i));
26892521            ACCUM_L(i) = vres[i];
26902522         }
26912523         WRITEBACK_RESULT();
r241934r241935
27002532         //
27012533         // Bitwise NOT AND of two vector registers
27022534
2703         int sel;
27042535         for (i = 0; i < 8; i++)
27052536         {
2706            sel = VEC_EL_2(EL, i);
2707            vres[i] = ~((VREG_S(VS1REG, i) & VREG_S(VS2REG, sel)));
2537            vres[i] = ~((VREG_S(VS1REG, i) & VREG_S(VS2REG, VEC_EL_2(EL, i))));
27082538            ACCUM_L(i) = vres[i];
27092539         }
27102540         WRITEBACK_RESULT();
r241934r241935
27192549         //
27202550         // Bitwise OR of two vector registers
27212551
2722         int sel;
27232552         for (i = 0; i < 8; i++)
27242553         {
2725            sel = VEC_EL_2(EL, i);
2726            vres[i] = VREG_S(VS1REG, i) | VREG_S(VS2REG, sel);
2554            vres[i] = VREG_S(VS1REG, i) | VREG_S(VS2REG, VEC_EL_2(EL, i));
27272555            ACCUM_L(i) = vres[i];
27282556         }
27292557         WRITEBACK_RESULT();
r241934r241935
27382566         //
27392567         // Bitwise NOT OR of two vector registers
27402568
2741         int sel;
27422569         for (i=0; i < 8; i++)
27432570         {
2744            sel = VEC_EL_2(EL, i);
2745            vres[i] = ~((VREG_S(VS1REG, i) | VREG_S(VS2REG, sel)));
2571            vres[i] = ~((VREG_S(VS1REG, i) | VREG_S(VS2REG, VEC_EL_2(EL, i))));
27462572            ACCUM_L(i) = vres[i];
27472573         }
27482574         WRITEBACK_RESULT();
r241934r241935
27572583         //
27582584         // Bitwise XOR of two vector registers
27592585
2760         int sel;
27612586         for (i=0; i < 8; i++)
27622587         {
2763            sel = VEC_EL_2(EL, i);
2764            vres[i] = VREG_S(VS1REG, i) ^ VREG_S(VS2REG, sel);
2588            vres[i] = VREG_S(VS1REG, i) ^ VREG_S(VS2REG, VEC_EL_2(EL, i));
27652589            ACCUM_L(i) = vres[i];
27662590         }
27672591         WRITEBACK_RESULT();
r241934r241935
27762600         //
27772601         // Bitwise NOT XOR of two vector registers
27782602
2779         int sel;
27802603         for (i=0; i < 8; i++)
27812604         {
2782            sel = VEC_EL_2(EL, i);
2783            vres[i] = ~((VREG_S(VS1REG, i) ^ VREG_S(VS2REG, sel)));
2605            vres[i] = ~((VREG_S(VS1REG, i) ^ VREG_S(VS2REG, VEC_EL_2(EL, i))));
27842606            ACCUM_L(i) = vres[i];
27852607         }
27862608         WRITEBACK_RESULT();
r241934r241935
27952617         // ------------------------------------------------------
27962618         //
27972619         // Calculates reciprocal
2798         int del = VS1REG & 7;
2799         int sel = EL & 7;
28002620         INT32 shifter = 0;
28012621
2802         INT32 rec = (INT16)(VREG_S(VS2REG, sel));
2622         INT32 rec = (INT16)(VREG_S(VS2REG, EL & 7));
28032623         INT32 datainput = (rec < 0) ? (-rec) : rec;
28042624         if (datainput)
28052625         {
28062626            for (i = 0; i < 32; i++)
28072627            {
2808               if (datainput & (1 << ((~i) & 0x1f)))//?.?.??? 31 - i
2628               if (datainput & (1 << ((~i) & 0x1f)))
28092629               {
28102630                  shifter = i;
28112631                  break;
r241934r241935
28372657         m_reciprocal_res = rec;
28382658         m_dp_allowed = 0;
28392659
2840         VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
2660         VREG_S(VDREG, VS1REG & 7) = (UINT16)(rec & 0xffff);
28412661
28422662         for (i = 0; i < 8; i++)
28432663         {
2844            sel = VEC_EL_2(EL, i);
2845            ACCUM_L(i) = VREG_S(VS2REG, sel);
2664            ACCUM_L(i) = VREG_S(VS2REG, VEC_EL_2(EL, i));
28462665         }
28472666
28482667
r241934r241935
28582677         //
28592678         // Calculates reciprocal low part
28602679
2861         int del = VS1REG & 7;
2862         int sel = EL & 7;
28632680         INT32 shifter = 0;
28642681
2865         INT32 rec = ((UINT16)(VREG_S(VS2REG, sel)) | ((UINT32)(m_reciprocal_high) & 0xffff0000));
2866
2682         INT32 rec = (INT16)VREG_S(VS2REG, EL & 7);
28672683         INT32 datainput = rec;
28682684
2869         if (rec < 0)
2685         if (m_dp_allowed)
28702686         {
2871            if (m_dp_allowed)
2687            rec = (rec & 0x0000ffff) | m_reciprocal_high;
2688            datainput = rec;
2689
2690            if (rec < 0)
28722691            {
28732692               if (rec < -32768)
28742693               {
r241934r241935
28792698                  datainput = -datainput;
28802699               }
28812700            }
2882            else
2883            {
2884               datainput = -datainput;
2885            }
28862701         }
2702         else if (datainput < 0)
2703         {
2704            datainput = -datainput;
28872705
2706            shifter = 0x10;
2707         }
28882708
2889         if (datainput)
2709
2710         for (i = 0; i < 32; i++)
28902711         {
2891            for (i = 0; i < 32; i++)
2712            if (datainput & (1 << ((~i) & 0x1f)))
28922713            {
2893               if (datainput & (1 << ((~i) & 0x1f)))//?.?.??? 31 - i
2894               {
2895                  shifter = i;
2896                  break;
2897               }
2714               shifter = i;
2715               break;
28982716            }
28992717         }
2900         else
2901         {
2902            if (m_dp_allowed)
2903            {
2904               shifter = 0;
2905            }
2906            else
2907            {
2908               shifter = 0x10;
2909            }
2910         }
29112718
29122719         INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
29132720         INT32 fetchval = rsp_divtable[address];
29142721         INT32 temp = (0x40000000 | (fetchval << 14)) >> ((~shifter) & 0x1f);
2915         if (rec < 0)
2916         {
2917            temp = ~temp;
2918         }
2722         temp ^= rec >> 31;
2723
29192724         if (!rec)
29202725         {
29212726            temp = 0x7fffffff;
r241934r241935
29292734         m_reciprocal_res = rec;
29302735         m_dp_allowed = 0;
29312736
2932         VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
2737         VREG_S(VDREG, VS1REG & 7) = (UINT16)(rec & 0xffff);
29332738
29342739         for (i = 0; i < 8; i++)
29352740         {
2936            sel = VEC_EL_2(EL, i);
2937            ACCUM_L(i) = VREG_S(VS2REG, sel);
2741            ACCUM_L(i) = VREG_S(VS2REG, VEC_EL_2(EL, i));
29382742         }
29392743
29402744         break;
r241934r241935
29492753         //
29502754         // Calculates reciprocal high part
29512755
2952         int del = VS1REG & 7;
2953         int sel = EL & 7;
2954
2955         m_reciprocal_high = (VREG_S(VS2REG, sel)) << 16;
2756         m_reciprocal_high = (VREG_S(VS2REG, EL & 7)) << 16;
29562757         m_dp_allowed = 1;
29572758
29582759         for (i = 0; i < 8; i++)
29592760         {
2960            sel = VEC_EL_2(EL, i);
2961            ACCUM_L(i) = VREG_S(VS2REG, sel);
2761            ACCUM_L(i) = VREG_S(VS2REG, VEC_EL_2(EL, i));
29622762         }
29632763
2964         VREG_S(VDREG, del) = (INT16)(m_reciprocal_res >> 16);
2764         VREG_S(VDREG, VS1REG & 7) = (INT16)(m_reciprocal_res >> 16);
29652765
29662766         break;
29672767      }
r241934r241935
29752775         //
29762776         // Moves element from vector to destination vector
29772777
2978         int del = VS1REG & 7;
2979         int sel = EL & 7;
2980
2981         VREG_S(VDREG, del) = VREG_S(VS2REG, sel);
2778         VREG_S(VDREG, VS1REG & 7) = VREG_S(VS2REG, EL & 7);
29822779         for (i = 0; i < 8; i++)
29832780         {
2984            sel = VEC_EL_2(EL, i);
2985            ACCUM_L(i) = VREG_S(VS2REG, sel);
2781            ACCUM_L(i) = VREG_S(VS2REG, VEC_EL_2(EL, i));
29862782         }
29872783         break;
29882784      }
r241934r241935
29962792         //
29972793         // Calculates reciprocal square-root
29982794
2999         int del = VS1REG & 7;
3000         int sel = EL & 7;
30012795         INT32 shifter = 0;
30022796
3003         INT32 rec = (INT16)(VREG_S(VS2REG, sel));
2797         INT32 rec = (INT16)(VREG_S(VS2REG, EL & 7));
30042798         INT32 datainput = (rec < 0) ? (-rec) : rec;
30052799         if (datainput)
30062800         {
r241934r241935
30402834         m_reciprocal_res = rec;
30412835         m_dp_allowed = 0;
30422836
3043         VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
2837         VREG_S(VDREG, VS1REG & 7) = (UINT16)(rec & 0xffff);
30442838
30452839         for (i = 0; i < 8; i++)
30462840         {
3047            sel = VEC_EL_2(EL, i);
3048            ACCUM_L(i) = VREG_S(VS2REG, sel);
2841            ACCUM_L(i) = VREG_S(VS2REG, VEC_EL_2(EL, i));
30492842         }
30502843
30512844         break;
r241934r241935
30602853         //
30612854         // Calculates reciprocal square-root low part
30622855
3063         int del = VS1REG & 7;
3064         int sel = EL & 7;
30652856         INT32 shifter = 0;
3066
3067         INT32 rec = ((UINT16)(VREG_S(VS2REG, sel)) | ((UINT32)(m_reciprocal_high) & 0xffff0000));
3068
2857         INT32 rec = (INT16)VREG_S(VS2REG, EL & 7);
30692858         INT32 datainput = rec;
30702859
3071         if (rec < 0)
2860         if (m_dp_allowed)
30722861         {
3073            if (m_dp_allowed)
2862            rec = (rec & 0x0000ffff) | m_reciprocal_high;
2863            datainput = rec;
2864
2865            if (rec < 0)
30742866            {
3075               if (rec < -32768)//VDIV.C,208
2867               if (rec < -32768)
30762868               {
30772869                  datainput = ~datainput;
30782870               }
r241934r241935
30812873                  datainput = -datainput;
30822874               }
30832875            }
3084            else
3085            {
3086               datainput = -datainput;
3087            }
30882876         }
2877         else if (datainput < 0)
2878         {
2879            datainput = -datainput;
30892880
2881            shifter = 0x10;
2882         }
2883
30902884         if (datainput)
30912885         {
30922886            for (i = 0; i < 32; i++)
r241934r241935
30982892               }
30992893            }
31002894         }
3101         else
3102         {
3103            if (m_dp_allowed)
3104            {
3105               shifter = 0;
3106            }
3107            else
3108            {
3109               shifter = 0x10;
3110            }
3111         }
31122895
31132896         INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
31142897         address = ((address | 0x200) & 0x3fe) | (shifter & 1);
31152898
31162899         INT32 fetchval = rsp_divtable[address];
31172900         INT32 temp = (0x40000000 | (fetchval << 14)) >> (((~shifter) & 0x1f) >> 1);
3118         if (rec < 0)
3119         {
3120            temp = ~temp;
3121         }
2901         temp ^= rec >> 31;
2902
31222903         if (!rec)
31232904         {
31242905            temp = 0x7fffffff;
r241934r241935
31322913         m_reciprocal_res = rec;
31332914         m_dp_allowed = 0;
31342915
3135         VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
2916         VREG_S(VDREG, VS1REG & 7) = (UINT16)(rec & 0xffff);
31362917
31372918         for (i = 0; i < 8; i++)
31382919         {
3139            sel = VEC_EL_2(EL, i);
3140            ACCUM_L(i) = VREG_S(VS2REG, sel);
2920            ACCUM_L(i) = VREG_S(VS2REG, VEC_EL_2(EL, i));
31412921         }
31422922
31432923         break;
r241934r241935
31522932         //
31532933         // Calculates reciprocal square-root high part
31542934
3155         int del = VS1REG & 7;
3156         int sel = EL & 7;
3157
3158         m_reciprocal_high = (VREG_S(VS2REG, sel)) << 16;
2935         m_reciprocal_high = (VREG_S(VS2REG, EL & 7)) << 16;
31592936         m_dp_allowed = 1;
31602937
31612938         for (i=0; i < 8; i++)
31622939         {
3163            sel = VEC_EL_2(EL, i);
3164            ACCUM_L(i) = VREG_S(VS2REG, sel);
2940            ACCUM_L(i) = VREG_S(VS2REG, VEC_EL_2(EL, i));
31652941         }
31662942
3167         VREG_S(VDREG, del) = (INT16)(m_reciprocal_res >> 16);    // store high part
2943         VREG_S(VDREG, VS1REG & 7) = (INT16)(m_reciprocal_res >> 16);    // store high part
31682944         break;
31692945      }
31702946
r241934r241935
33623138                           break;
33633139                        case 2:
33643140                           // Anciliary clipping flags
3365                           RTVAL = ((CARRY_FLAG(0) & 1) << 0) |
3366                                 ((CARRY_FLAG(1) & 1) << 1) |
3367                                 ((CARRY_FLAG(2) & 1) << 2) |
3368                                 ((CARRY_FLAG(3) & 1) << 3) |
3369                                 ((CARRY_FLAG(4) & 1) << 4) |
3370                                 ((CARRY_FLAG(5) & 1) << 5) |
3371                                 ((CARRY_FLAG(6) & 1) << 6) |
3372                                 ((CARRY_FLAG(7) & 1) << 7) |
3373                                 ((ZERO_FLAG(0) & 1) << 8) |
3374                                 ((ZERO_FLAG(1) & 1) << 9) |
3375                                 ((ZERO_FLAG(2) & 1) << 10) |
3376                                 ((ZERO_FLAG(3) & 1) << 11) |
3377                                 ((ZERO_FLAG(4) & 1) << 12) |
3378                                 ((ZERO_FLAG(5) & 1) << 13) |
3379                                 ((ZERO_FLAG(6) & 1) << 14) |
3380                                 ((ZERO_FLAG(7) & 1) << 15);
3381                           if (RTVAL & 0x8000) RTVAL |= 0xffff0000;
3141                           RTVAL = ((CLIP1_FLAG(0) & 1) << 0) |
3142                                 ((CLIP1_FLAG(1) & 1) << 1) |
3143                                 ((CLIP1_FLAG(2) & 1) << 2) |
3144                                 ((CLIP1_FLAG(3) & 1) << 3) |
3145                                 ((CLIP1_FLAG(4) & 1) << 4) |
3146                                 ((CLIP1_FLAG(5) & 1) << 5) |
3147                                 ((CLIP1_FLAG(6) & 1) << 6) |
3148                                 ((CLIP1_FLAG(7) & 1) << 7);
33823149                     }
33833150                  }
33843151                  break;
trunk/src/emu/cpu/rsp/rsp.h
r241934r241935
133133
134134union ACCUMULATOR_REG
135135{
136   INT64 q;
137   INT32 l[2];
138   INT16 w[4];
136   UINT64 q;
137   UINT32 l[2];
138   UINT16 w[4];
139139};
140140
141141#define MCFG_RSP_DP_REG_R_CB(_devcb) \
trunk/src/emu/cpu/rsp/rspdrc.c
r241934r241935
43904390
43914391      INT32 accum = (UINT32)(UINT16)ACCUM_M(i);
43924392      accum |= ((UINT32)((UINT16)ACCUM_H(i))) << 16;
4393      accum += s1*s2;
4393      accum += s1 * s2;
43944394
43954395      SET_ACCUM_H((UINT16)(accum >> 16), i);
43964396      SET_ACCUM_M((UINT16)accum, i);
r241934r241935
48804880         m_xv[VDREG] = m_accum_l;
48814881         break;
48824882      }
4883      default:    fatalerror("RSP: VSAW: el = %d\n", EL);
4883      default:      // Unsupported, writes 0 to VD
4884      {
4885
4886      }
48844887   }
48854888}
48864889
r241934r241935
48994902   switch (EL)
49004903   {
49014904      case 0x08:      // VSAWH
4902      {
49034905         for (int i = 0; i < 8; i++)
49044906         {
49054907            W_VREG_S(VDREG, i) = ACCUM_H(i);
49064908         }
49074909         break;
4908      }
49094910      case 0x09:      // VSAWM
4910      {
49114911         for (int i = 0; i < 8; i++)
49124912         {
49134913            W_VREG_S(VDREG, i) = ACCUM_M(i);
49144914         }
49154915         break;
4916      }
49174916      case 0x0a:      // VSAWL
4918      {
49194917         for (int i = 0; i < 8; i++)
49204918         {
49214919            W_VREG_S(VDREG, i) = ACCUM_L(i);
49224920         }
49234921         break;
4922      default:      // Unsupported
4923      {
4924         for (int i = 0; i < 8; i++)
4925         {
4926            W_VREG_S(VDREG, i) = 0;
4927         }
49244928      }
4925      default:    fatalerror("RSP: VSAW: el = %d\n", EL);
49264929   }
49274930}
49284931
r241934r241935
52785281               VEC_SET_ACCUM_L(s1, i);
52795282            }
52805283         }
5281         else//VEC_ZERO_FLAG(i)==0
5284         else
52825285         {
52835286            if (VEC_CLIP1_FLAG(i) != 0)
52845287            {
52855288               if (((UINT32)(UINT16)(s1) + (UINT32)(UINT16)(s2)) > 0x10000)
5286               {//proper fix for Harvest Moon 64, r4
5289               {
52875290                  VEC_SET_ACCUM_L(s1, i);
52885291                  VEC_CLEAR_COMPARE_FLAG(i);
52895292               }
r241934r241935
53085311            }
53095312         }
53105313      }
5311      else//VEC_CARRY_FLAG(i)==0
5314      else
53125315      {
53135316         if (VEC_ZERO_FLAG(i) != 0)
53145317         {
r241934r241935
53755378               SET_ACCUM_L(s1, i);
53765379            }
53775380         }
5378         else//ZERO_FLAG(i)==0
5381         else
53795382         {
53805383            if (CLIP1_FLAG(i) != 0)
53815384            {
53825385               if (((UINT32)(UINT16)(s1) + (UINT32)(UINT16)(s2)) > 0x10000)
5383               {//proper fix for Harvest Moon 64, r4
5386               {
53845387                  SET_ACCUM_L(s1, i);
53855388                  CLEAR_COMPARE_FLAG(i);
53865389               }
r241934r241935
54055408            }
54065409         }
54075410      }
5408      else//CARRY_FLAG(i)==0
5411      else
54095412      {
54105413         if (ZERO_FLAG(i) != 0)
54115414         {
r241934r241935
65016504   INT32 fetchval = rsp_divtable[address & 0x1ff];
65026505   INT32 temp = (0x40000000 | (fetchval << 14)) >> ((~shifter) & 0x1f);
65036506   temp ^= rec >> 31;
6507
65046508   if (!rec)
65056509   {
65066510      temp = 0x7fffffff;


Previous 199869 Revisions Next


© 1997-2024 The MAME Team