mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
AICA: Implemented DMA [Angelo Salese]
This commit is contained in:
parent
268de4b9d0
commit
3fdc34d03b
@ -194,9 +194,14 @@ struct aica_state
|
||||
emu_timer *timerA, *timerB, *timerC;
|
||||
|
||||
// DMA stuff
|
||||
UINT32 aica_dmea;
|
||||
UINT16 aica_drga;
|
||||
UINT16 aica_dtlg;
|
||||
struct{
|
||||
UINT32 dmea;
|
||||
UINT16 drga;
|
||||
UINT16 dlg;
|
||||
UINT8 dgate;
|
||||
UINT8 ddir;
|
||||
}dma;
|
||||
|
||||
|
||||
int ARTABLE[64], DRTABLE[64];
|
||||
|
||||
@ -204,6 +209,8 @@ struct aica_state
|
||||
device_t *device;
|
||||
};
|
||||
|
||||
static void aica_exec_dma(aica_state *aica,address_space &space); /*state DMA transfer function*/
|
||||
|
||||
static const float SDLT[16]={-1000000.0,-42.0,-39.0,-36.0,-33.0,-30.0,-27.0,-24.0,-21.0,-18.0,-15.0,-12.0,-9.0,-6.0,-3.0,0.0};
|
||||
|
||||
static stream_sample_t *bufferl;
|
||||
@ -712,6 +719,32 @@ static void AICA_UpdateReg(aica_state *AICA, address_space &space, int reg)
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
AICA->dma.dmea = ((AICA->udata.data[0x80/2] & 0xfe00) << 7) | (AICA->dma.dmea & 0xfffc);
|
||||
/* TODO: $TSCD - MRWINH regs */
|
||||
break;
|
||||
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
AICA->dma.dmea = (AICA->udata.data[0x84/2] & 0xfffc) | (AICA->dma.dmea & 0x7f0000);
|
||||
break;
|
||||
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
AICA->dma.drga = (AICA->udata.data[0x88/2] & 0x7ffc);
|
||||
AICA->dma.dgate = (AICA->udata.data[0x88/2] & 0x8000) >> 15;
|
||||
break;
|
||||
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
AICA->dma.dlg = (AICA->udata.data[0x8c/2] & 0x7ffc);
|
||||
AICA->dma.ddir = (AICA->udata.data[0x8c/2] & 0x8000) >> 15;
|
||||
if(AICA->udata.data[0x8c/2] & 1) // dexe
|
||||
aica_exec_dma(AICA,space);
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
case 0x91:
|
||||
if(AICA->Master)
|
||||
@ -920,6 +953,7 @@ static void AICA_w16(aica_state *AICA,address_space &space,unsigned int addr,uns
|
||||
// printf("%x to AICA global @ %x\n", val, addr & 0xff);
|
||||
*((unsigned short *) (AICA->udata.datab+((addr&0xff)))) = val;
|
||||
AICA_UpdateReg(AICA, space, addr&0xff);
|
||||
|
||||
}
|
||||
else if (addr == 0x2d00)
|
||||
{
|
||||
@ -986,6 +1020,16 @@ static unsigned short AICA_r16(aica_state *AICA, address_space &space, unsigned
|
||||
return AICA->IRQR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(addr<0x3200) //COEF
|
||||
v= *((unsigned short *) (AICA->DSP.COEF+(addr-0x3000)/2));
|
||||
else if(addr<0x3400)
|
||||
v= *((unsigned short *) (AICA->DSP.MADRS+(addr-0x3200)/2));
|
||||
else if(addr<0x3c00)
|
||||
v= *((unsigned short *) (AICA->DSP.MPRO+(addr-0x3400)/2));
|
||||
|
||||
}
|
||||
// else if (addr<0x700)
|
||||
// v=AICA->RINGBUF[(addr-0x600)/2];
|
||||
return v;
|
||||
@ -1250,6 +1294,85 @@ static void AICA_DoMasterSamples(aica_state *AICA, int nsamples)
|
||||
}
|
||||
}
|
||||
|
||||
static void aica_exec_dma(aica_state *aica,address_space &space)
|
||||
{
|
||||
static UINT16 tmp_dma[4];
|
||||
int i;
|
||||
|
||||
printf("AICA: DMA transfer START\n"
|
||||
"DMEA: %08x DRGA: %08x DLG: %04x\n"
|
||||
"DGATE: %d DDIR: %d\n",aica->dma.dmea,aica->dma.drga,aica->dma.dlg,aica->dma.dgate,aica->dma.ddir);
|
||||
|
||||
/* Copy the dma values in a temp storage for resuming later */
|
||||
/* (DMA *can't* overwrite his parameters). */
|
||||
if(!(aica->dma.ddir))
|
||||
{
|
||||
for(i=0;i<4;i++)
|
||||
tmp_dma[i] = aica->udata.data[(0x80+(i*4))/2];
|
||||
}
|
||||
|
||||
/* TODO: don't know if params auto-updates, I guess not ... */
|
||||
if(aica->dma.ddir)
|
||||
{
|
||||
if(aica->dma.dgate)
|
||||
{
|
||||
for(i=0;i < aica->dma.dlg;i+=2)
|
||||
{
|
||||
aica->AICARAM[aica->dma.dmea] = 0;
|
||||
aica->AICARAM[aica->dma.dmea+1] = 0;
|
||||
aica->dma.dmea+=2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i < aica->dma.dlg;i+=2)
|
||||
{
|
||||
UINT16 tmp;
|
||||
tmp = AICA_r16(aica, space, aica->dma.drga);;
|
||||
aica->AICARAM[aica->dma.dmea] = tmp & 0xff;
|
||||
aica->AICARAM[aica->dma.dmea+1] = tmp>>8;
|
||||
aica->dma.dmea+=4;
|
||||
aica->dma.drga+=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(aica->dma.dgate)
|
||||
{
|
||||
for(i=0;i < aica->dma.dlg;i+=2)
|
||||
{
|
||||
AICA_w16(aica, space, aica->dma.drga, 0);
|
||||
aica->dma.drga+=4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i < aica->dma.dlg;i+=2)
|
||||
{
|
||||
UINT16 tmp;
|
||||
tmp = aica->AICARAM[aica->dma.dmea];
|
||||
tmp|= aica->AICARAM[aica->dma.dmea+1]<<8;
|
||||
AICA_w16(aica, space, aica->dma.drga, tmp);
|
||||
aica->dma.dmea+=4;
|
||||
aica->dma.drga+=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Resume the values*/
|
||||
if(!(aica->dma.ddir))
|
||||
{
|
||||
for(i=0;i<4;i++)
|
||||
aica->udata.data[(0x80+(i*4))/2] = tmp_dma[i];
|
||||
}
|
||||
|
||||
/* Job done, clear DEXE */
|
||||
aica->udata.data[0x8c/2] &= ~1;
|
||||
/* request a dma end irq (TBD) */
|
||||
// ...
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
static int AICA_IRQCB(void *param)
|
||||
{
|
||||
|
@ -57,8 +57,8 @@ class dc_state : public driver_device
|
||||
TIMER_CALLBACK_MEMBER(ch2_dma_irq);
|
||||
TIMER_CALLBACK_MEMBER(yuv_fifo_irq);
|
||||
TIMER_CALLBACK_MEMBER(dc_rtc_increment);
|
||||
DECLARE_READ64_MEMBER(dc_aica_reg_r);
|
||||
DECLARE_WRITE64_MEMBER(dc_aica_reg_w);
|
||||
DECLARE_READ32_MEMBER(dc_aica_reg_r);
|
||||
DECLARE_WRITE32_MEMBER(dc_aica_reg_w);
|
||||
DECLARE_READ32_MEMBER(dc_arm_aica_r);
|
||||
DECLARE_WRITE32_MEMBER(dc_arm_aica_w);
|
||||
void wave_dma_execute(address_space &space);
|
||||
|
@ -762,30 +762,18 @@ void dc_state::machine_reset()
|
||||
dc_sysctrl_regs[SB_SBREV] = 0x0b;
|
||||
}
|
||||
|
||||
READ64_MEMBER(dc_state::dc_aica_reg_r)
|
||||
READ32_MEMBER(dc_state::dc_aica_reg_r)
|
||||
{
|
||||
//int reg;
|
||||
UINT64 shift;
|
||||
|
||||
/*reg = */decode_reg32_64(offset, mem_mask, &shift);
|
||||
|
||||
// mame_printf_verbose("AICA REG: [%08x] read %" I64FMT "x, mask %" I64FMT "x\n", 0x700000+reg*4, (UINT64)offset, mem_mask);
|
||||
|
||||
return (UINT64) aica_r(machine().device("aica"), space, offset*2, 0xffff)<<shift;
|
||||
return aica_r(machine().device("aica"), space, offset*2, 0xffff);
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(dc_state::dc_aica_reg_w)
|
||||
WRITE32_MEMBER(dc_state::dc_aica_reg_w)
|
||||
{
|
||||
int reg;
|
||||
UINT64 shift;
|
||||
UINT32 dat;
|
||||
|
||||
reg = decode_reg32_64(offset, mem_mask, &shift);
|
||||
dat = (UINT32)(data >> shift);
|
||||
|
||||
if (reg == (0x2c00/4))
|
||||
if (offset == (0x2c00/4))
|
||||
{
|
||||
if (dat & 1)
|
||||
if (data & 1)
|
||||
{
|
||||
/* halt the ARM7 */
|
||||
m_soundcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
|
||||
@ -797,9 +785,9 @@ WRITE64_MEMBER(dc_state::dc_aica_reg_w)
|
||||
}
|
||||
}
|
||||
|
||||
aica_w(machine().device("aica"), space, offset*2, dat, shift ? ((mem_mask>>32)&0xffff) : (mem_mask & 0xffff));
|
||||
aica_w(machine().device("aica"), space, offset*2, data, 0xffff);
|
||||
|
||||
// mame_printf_verbose("AICA REG: [%08x=%x] write %" I64FMT "x to %x, mask %" I64FMT "x\n", 0x700000+reg*4, dat, data, offset, mem_mask);
|
||||
// mame_printf_verbose("AICA REG: [%08x=%x] write %x to %x, mask %" I64FMT "x\n", 0x700000+reg*4, data, offset, mem_mask);
|
||||
}
|
||||
|
||||
READ32_MEMBER(dc_state::dc_arm_aica_r)
|
||||
|
@ -371,7 +371,7 @@ static ADDRESS_MAP_START( dc_map, AS_PROGRAM, 64, dc_cons_state )
|
||||
AM_RANGE(0x005f7c00, 0x005f7cff) AM_DEVICE32("powervr2", powervr2_device, pd_dma_map, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0x005f8000, 0x005f9fff) AM_DEVICE32("powervr2", powervr2_device, ta_map, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0x00600000, 0x006007ff) AM_READWRITE(dc_modem_r, dc_modem_w )
|
||||
AM_RANGE(0x00700000, 0x00707fff) AM_READWRITE(dc_aica_reg_r, dc_aica_reg_w )
|
||||
AM_RANGE(0x00700000, 0x00707fff) AM_READWRITE32(dc_aica_reg_r, dc_aica_reg_w, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0x00710000, 0x0071000f) AM_MIRROR(0x02000000) AM_READWRITE32(dc_rtc_r, dc_rtc_w, U64(0xffffffffffffffff) )
|
||||
AM_RANGE(0x00800000, 0x009fffff) AM_READWRITE(dc_arm_r, dc_arm_w )
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user