Previous 199869 Revisions Next

r17591 Sunday 2nd September, 2012 at 12:32:36 UTC by Ville Linde
ppc: Implemented PPC403 DMA chaining [Ville Linde]
[src/emu/cpu/powerpc]ppc.h ppccom.c ppccom.h

trunk/src/emu/cpu/powerpc/ppccom.c
r17590r17591
3939static TIMER_CALLBACK( ppc4xx_spu_callback );
4040static TIMER_CALLBACK( decrementer_int_callback );
4141
42static TIMER_CALLBACK( ppc4xx_buffered_dma_callback );
43
4244static void ppc4xx_set_irq_line(powerpc_state *ppc, UINT32 bitmask, int state);
4345
4446static void ppc4xx_dma_update_irq_states(powerpc_state *ppc);
r17590r17591
341343      ppc->spu.timer = device->machine().scheduler().timer_alloc(FUNC(ppc4xx_spu_callback), ppc);
342344   }
343345
346   if (cap & PPCCAP_4XX)
347   {
348      ppc->buffered_dma_timer[0] = device->machine().scheduler().timer_alloc(FUNC(ppc4xx_buffered_dma_callback), ppc);
349      ppc->buffered_dma_timer[1] = device->machine().scheduler().timer_alloc(FUNC(ppc4xx_buffered_dma_callback), ppc);
350      ppc->buffered_dma_timer[2] = device->machine().scheduler().timer_alloc(FUNC(ppc4xx_buffered_dma_callback), ppc);
351      ppc->buffered_dma_timer[3] = device->machine().scheduler().timer_alloc(FUNC(ppc4xx_buffered_dma_callback), ppc);
352
353      ppc->buffered_dma_rate[0] = 10000;
354      ppc->buffered_dma_rate[1] = 10000;
355      ppc->buffered_dma_rate[2] = 10000;
356      ppc->buffered_dma_rate[3] = 10000;
357   }
358
344359   /* register for save states */
345360   device->save_item(NAME(ppc->pc));
346361   device->save_item(NAME(ppc->r));
r17590r17591
17491764
17501765   /* update the IRQ state for each DMA channel */
17511766   for (dmachan = 0; dmachan < 4; dmachan++)
1767   {
17521768      if ((ppc->dcr[DCR4XX_DMACR0 + 8 * dmachan] & PPC4XX_DMACR_CIE) && (ppc->dcr[DCR4XX_DMASR] & (0x11 << (27 - dmachan))))
17531769         ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_DMA(dmachan), ASSERT_LINE);
17541770      else
17551771         ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_DMA(dmachan), CLEAR_LINE);
1772
1773      // DMA chaining interrupts
1774      switch (dmachan)
1775      {
1776         case 0:
1777            if ((ppc->dcr[DCR4XX_DMACR0 + 8 * dmachan] & PPC4XX_DMACR_CIE) && (ppc->dcr[DCR4XX_DMASR] & 0x80000))
1778               ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_DMA(dmachan), ASSERT_LINE);
1779            else
1780               ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_DMA(dmachan), CLEAR_LINE);
1781            break;
1782
1783         case 1:
1784         case 2:
1785         case 3:
1786            if ((ppc->dcr[DCR4XX_DMACR0 + 8 * dmachan] & PPC4XX_DMACR_CIE) && (ppc->dcr[DCR4XX_DMASR] & (1 << (7 - dmachan))))
1787               ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_DMA(dmachan), ASSERT_LINE);
1788            else
1789               ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_DMA(dmachan), CLEAR_LINE);
1790            break;
1791      }
1792   }
17561793}
17571794
17581795
r17590r17591
17731810   if ((dmaregs[DCR4XX_DMACT0] & 0xffff) != 0)
17741811      return FALSE;
17751812
1776   /* set the complete bit and handle interrupts */
1777   ppc->dcr[DCR4XX_DMASR] |= 1 << (31 - dmachan);
1778//  ppc->dcr[DCR4XX_DMASR] |= 1 << (27 - dmachan);
1779   ppc4xx_dma_update_irq_states(ppc);
1813   // if chained mode
1814   if (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CH)
1815   {
1816      dmaregs[DCR4XX_DMADA0] = dmaregs[DCR4XX_DMASA0];
1817      dmaregs[DCR4XX_DMACT0] = dmaregs[DCR4XX_DMACC0];
1818      dmaregs[DCR4XX_DMACR0] &= ~PPC4XX_DMACR_CH;
1819
1820      switch (dmachan)
1821      {
1822         case 0:
1823            ppc->dcr[DCR4XX_DMASR] |= 0x00080000;
1824            break;
1825
1826         case 1:
1827         case 2:
1828         case 3:
1829            ppc->dcr[DCR4XX_DMASR] |= 1 << (7 - dmachan);
1830            break;
1831      }
1832     
1833      ppc4xx_dma_update_irq_states(ppc);
1834
1835      INT64 numdata = dmaregs[DCR4XX_DMACT0];
1836      if (numdata == 0)
1837         numdata = 65536;
1838
1839      INT64 time = (numdata * 1000000) / ppc->buffered_dma_rate[dmachan];
1840
1841      ppc->buffered_dma_timer[dmachan]->adjust(attotime::from_usec(time), dmachan);
1842   }
1843   else
1844   {
1845      /* set the complete bit and handle interrupts */
1846      ppc->dcr[DCR4XX_DMASR] |= 1 << (31 - dmachan);
1847   //  ppc->dcr[DCR4XX_DMASR] |= 1 << (27 - dmachan);
1848      ppc4xx_dma_update_irq_states(ppc);
1849
1850      ppc->buffered_dma_timer[dmachan]->adjust(attotime::never, FALSE);
1851   }
17801852   return TRUE;
17811853}
17821854
17831855
17841856/*-------------------------------------------------
1857    buffered_dma_callback - callback that fires
1858    when buffered DMA transfer is ready
1859-------------------------------------------------*/
1860
1861static TIMER_CALLBACK( ppc4xx_buffered_dma_callback )
1862{
1863   powerpc_state *ppc = (powerpc_state *)ptr;
1864   int dmachan = param;
1865
1866   static const UINT8 dma_transfer_width[4] = { 1, 2, 4, 16 };
1867   UINT32 *dmaregs = &ppc->dcr[8 * dmachan];
1868   INT32 destinc;
1869   UINT8 width;
1870
1871   width = dma_transfer_width[(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_PW_MASK) >> 26];
1872   destinc = (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_DAI) ? width : 0;
1873
1874   if (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TD)
1875   {
1876      /* peripheral to memory */
1877
1878      switch (width)
1879      {
1880         /* byte transfer */
1881         case 1:
1882         do
1883         {
1884            UINT8 data = 0;
1885            if (ppc->ext_dma_read_handler[dmachan] != NULL)
1886               data = (*ppc->ext_dma_read_handler[dmachan])(ppc->device, 1);
1887            ppc->program->write_byte(dmaregs[DCR4XX_DMADA0], data);
1888            dmaregs[DCR4XX_DMADA0] += destinc;
1889         } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1890         break;
1891
1892         /* word transfer */
1893         case 2:
1894         do
1895         {
1896            UINT16 data = 0;
1897            if (ppc->ext_dma_read_handler[dmachan] != NULL)
1898               data = (*ppc->ext_dma_read_handler[dmachan])(ppc->device, 2);
1899            ppc->program->write_word(dmaregs[DCR4XX_DMADA0], data);
1900            dmaregs[DCR4XX_DMADA0] += destinc;
1901         } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1902         break;
1903
1904         /* dword transfer */
1905         case 4:
1906         do
1907         {
1908            UINT32 data = 0;
1909            if (ppc->ext_dma_read_handler[dmachan] != NULL)
1910               data = (*ppc->ext_dma_read_handler[dmachan])(ppc->device, 4);
1911            ppc->program->write_dword(dmaregs[DCR4XX_DMADA0], data);
1912            dmaregs[DCR4XX_DMADA0] += destinc;
1913         } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1914         break;
1915      }
1916   }
1917   else
1918   {
1919      /* memory to peripheral */
1920
1921      // data is read from destination address!
1922      switch (width)
1923      {
1924         /* byte transfer */
1925         case 1:
1926         do
1927         {
1928            UINT8 data = ppc->program->read_byte(dmaregs[DCR4XX_DMADA0]);
1929            if (ppc->ext_dma_write_handler[dmachan] != NULL)
1930               (*ppc->ext_dma_write_handler[dmachan])(ppc->device, 1, data);
1931            dmaregs[DCR4XX_DMADA0] += destinc;
1932         } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1933         break;
1934
1935         /* word transfer */
1936         case 2:
1937         do
1938         {
1939            UINT16 data = ppc->program->read_word(dmaregs[DCR4XX_DMADA0]);
1940            if (ppc->ext_dma_write_handler[dmachan] != NULL)
1941               (*ppc->ext_dma_write_handler[dmachan])(ppc->device, 2, data);
1942            dmaregs[DCR4XX_DMADA0] += destinc;
1943         } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1944         break;
1945
1946         /* dword transfer */
1947         case 4:
1948         do
1949         {
1950            UINT32 data = ppc->program->read_dword(dmaregs[DCR4XX_DMADA0]);
1951            if (ppc->ext_dma_write_handler[dmachan] != NULL)
1952               (*ppc->ext_dma_write_handler[dmachan])(ppc->device, 4, data);
1953            dmaregs[DCR4XX_DMADA0] += destinc;
1954         } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1955         break;
1956      }   
1957   }
1958}
1959
1960
1961/*-------------------------------------------------
17851962    ppc4xx_dma_fetch_transmit_byte - fetch a byte
17861963    to send to a peripheral
17871964-------------------------------------------------*/
r17590r17591
18482025   /* check for unsupported features */
18492026   if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TCE))
18502027      fatalerror("ppc4xx_dma_exec: DMA_TCE == 0");
1851   if (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CH)
1852      fatalerror("ppc4xx_dma_exec: DMA chaining not implemented");
18532028
18542029   /* transfer mode */
18552030   switch ((dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TM_MASK) >> 21)
r17590r17591
18602035         {
18612036            /* buffered DMA with external peripheral */
18622037
1863            width = dma_transfer_width[(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_PW_MASK) >> 26];
1864            destinc = (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_DAI) ? width : 0;
2038            INT64 numdata = dmaregs[DCR4XX_DMACT0];
2039            if (numdata == 0)
2040               numdata = 65536;
18652041
1866            if (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TD)
2042            INT64 time;
2043            if (numdata > 100)
18672044            {
1868               /* peripheral to memory */
1869
1870               switch (width)
1871               {
1872                  /* byte transfer */
1873                  case 1:
1874                     do
1875                     {
1876                        UINT8 data = 0;
1877                        if (ppc->ext_dma_read_handler[dmachan] != NULL)
1878                           data = (*ppc->ext_dma_read_handler[dmachan])(ppc->device, 1);
1879                        ppc->program->write_byte(dmaregs[DCR4XX_DMADA0], data);
1880                        dmaregs[DCR4XX_DMADA0] += destinc;
1881                     } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1882                     break;
1883
1884                  /* word transfer */
1885                  case 2:
1886                     do
1887                     {
1888                        UINT16 data = 0;
1889                        if (ppc->ext_dma_read_handler[dmachan] != NULL)
1890                           data = (*ppc->ext_dma_read_handler[dmachan])(ppc->device, 2);
1891                        ppc->program->write_word(dmaregs[DCR4XX_DMADA0], data);
1892                        dmaregs[DCR4XX_DMADA0] += destinc;
1893                     } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1894                     break;
1895
1896                  /* dword transfer */
1897                  case 4:
1898                     do
1899                     {
1900                        UINT32 data = 0;
1901                        if (ppc->ext_dma_read_handler[dmachan] != NULL)
1902                           data = (*ppc->ext_dma_read_handler[dmachan])(ppc->device, 4);
1903                        ppc->program->write_dword(dmaregs[DCR4XX_DMADA0], data);
1904                        dmaregs[DCR4XX_DMADA0] += destinc;
1905                     } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1906                     break;
1907               }
2045               time = (numdata * 1000000) / ppc->buffered_dma_rate[dmachan];
19082046            }
19092047            else
19102048            {
1911               /* memory to peripheral */
2049               time = 0;      // let very short transfers occur instantly
2050            }
19122051
1913               // data is read from destination address!
1914               switch (width)
1915               {
1916                  /* byte transfer */
1917                  case 1:
1918                     do
1919                     {
1920                        UINT8 data = ppc->program->read_byte(dmaregs[DCR4XX_DMADA0]);
1921                        if (ppc->ext_dma_write_handler[dmachan] != NULL)
1922                           (*ppc->ext_dma_write_handler[dmachan])(ppc->device, 1, data);
1923                        dmaregs[DCR4XX_DMADA0] += destinc;
1924                     } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1925                     break;
1926
1927                  /* word transfer */
1928                  case 2:
1929                     do
1930                     {
1931                        UINT16 data = ppc->program->read_word(dmaregs[DCR4XX_DMADA0]);
1932                        if (ppc->ext_dma_write_handler[dmachan] != NULL)
1933                           (*ppc->ext_dma_write_handler[dmachan])(ppc->device, 2, data);
1934                        dmaregs[DCR4XX_DMADA0] += destinc;
1935                     } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1936                     break;
1937
1938                  /* dword transfer */
1939                  case 4:
1940                     do
1941                     {
1942                        UINT32 data = ppc->program->read_dword(dmaregs[DCR4XX_DMADA0]);
1943                        if (ppc->ext_dma_write_handler[dmachan] != NULL)
1944                           (*ppc->ext_dma_write_handler[dmachan])(ppc->device, 4, data);
1945                        dmaregs[DCR4XX_DMADA0] += destinc;
1946                     } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1947                     break;
1948               }
1949            }
2052            ppc->buffered_dma_timer[dmachan]->adjust(attotime::from_usec(time), dmachan);
19502053         }
19512054         else      /* buffered DMA with internal peripheral (SPU) */
19522055         {
r17590r17591
23602463    specific external DMA read handler configuration
23612464-------------------------------------------------*/
23622465
2363void ppc4xx_set_dma_read_handler(device_t *device, int channel, ppc4xx_dma_read_handler handler)
2466void ppc4xx_set_dma_read_handler(device_t *device, int channel, ppc4xx_dma_read_handler handler, int rate)
23642467{
23652468   powerpc_state *ppc = *(powerpc_state **)downcast<legacy_cpu_device *>(device)->token();
23662469   ppc->ext_dma_read_handler[channel] = handler;
2470   ppc->buffered_dma_rate[channel] = rate;
23672471}
23682472
23692473/*-------------------------------------------------
r17590r17591
23712475    specific external DMA write handler configuration
23722476-------------------------------------------------*/
23732477
2374void ppc4xx_set_dma_write_handler(device_t *device, int channel, ppc4xx_dma_write_handler handler)
2478void ppc4xx_set_dma_write_handler(device_t *device, int channel, ppc4xx_dma_write_handler handler, int rate)
23752479{
23762480   powerpc_state *ppc = *(powerpc_state **)downcast<legacy_cpu_device *>(device)->token();
23772481   ppc->ext_dma_write_handler[channel] = handler;
2482   ppc->buffered_dma_rate[channel] = rate;
23782483}
23792484
23802485
trunk/src/emu/cpu/powerpc/ppccom.h
r17590r17591
545545   emu_timer *      wdog_timer;
546546   UINT32         pit_reload;
547547   UINT32         irqstate;
548   emu_timer *      buffered_dma_timer[4];
549   int            buffered_dma_rate[4];
548550
549551   /* PowerPC 603-specific state */
550552   UINT32         mmu603_cmp;
trunk/src/emu/cpu/powerpc/ppc.h
r17590r17591
189189void ppc4xx_spu_receive_byte(device_t *device, UINT8 byteval);
190190
191191void ppc_set_dcstore_callback(device_t *device, ppc_dcstore_handler handler);
192void ppc4xx_set_dma_read_handler(device_t *device, int channel, ppc4xx_dma_read_handler handler);
193void ppc4xx_set_dma_write_handler(device_t *device, int channel, ppc4xx_dma_write_handler handler);
192void ppc4xx_set_dma_read_handler(device_t *device, int channel, ppc4xx_dma_read_handler handler, int rate);
193void ppc4xx_set_dma_write_handler(device_t *device, int channel, ppc4xx_dma_write_handler handler, int rate);
194194
195195
196196DECLARE_LEGACY_CPU_DEVICE(PPC403GA, ppc403ga);

Previous 199869 Revisions Next


© 1997-2024 The MAME Team