mirror of
https://github.com/holub/mame
synced 2025-10-07 01:16:22 +03:00
SCSP: improved DMA and fixed triggering from SH-2 side [Angelo Salese]
This commit is contained in:
parent
e23db94051
commit
0003b69a0b
@ -212,7 +212,7 @@ struct aica_state
|
|||||||
device_t *device;
|
device_t *device;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void aica_exec_dma(aica_state *aica,address_space &space); /*state DMA transfer function*/
|
static void aica_exec_dma(address_space &space,aica_state *aica); /*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 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};
|
||||||
|
|
||||||
@ -767,7 +767,7 @@ static void AICA_UpdateReg(aica_state *AICA, address_space &space, int reg)
|
|||||||
AICA->dma.dlg = (AICA->udata.data[0x8c/2] & 0x7ffc);
|
AICA->dma.dlg = (AICA->udata.data[0x8c/2] & 0x7ffc);
|
||||||
AICA->dma.ddir = (AICA->udata.data[0x8c/2] & 0x8000) >> 15;
|
AICA->dma.ddir = (AICA->udata.data[0x8c/2] & 0x8000) >> 15;
|
||||||
if(AICA->udata.data[0x8c/2] & 1) // dexe
|
if(AICA->udata.data[0x8c/2] & 1) // dexe
|
||||||
aica_exec_dma(AICA,space);
|
aica_exec_dma(space,AICA);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x90:
|
case 0x90:
|
||||||
@ -1410,7 +1410,7 @@ static void AICA_DoMasterSamples(aica_state *AICA, int nsamples)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: this needs to be timer-ized */
|
/* TODO: this needs to be timer-ized */
|
||||||
static void aica_exec_dma(aica_state *aica,address_space &space)
|
static void aica_exec_dma(address_space &space, aica_state *aica)
|
||||||
{
|
{
|
||||||
static UINT16 tmp_dma[4];
|
static UINT16 tmp_dma[4];
|
||||||
int i;
|
int i;
|
||||||
|
@ -216,12 +216,13 @@ struct scsp_state
|
|||||||
emu_timer *timerA, *timerB, *timerC;
|
emu_timer *timerA, *timerB, *timerC;
|
||||||
|
|
||||||
// DMA stuff
|
// DMA stuff
|
||||||
UINT32 scsp_dmea;
|
struct{
|
||||||
UINT16 scsp_drga;
|
UINT32 dmea;
|
||||||
UINT16 scsp_dtlg;
|
UINT16 drga;
|
||||||
UINT16 scsp_dmactrl;
|
UINT16 dtlg;
|
||||||
|
UINT8 dgate;
|
||||||
UINT16 dma_regs[3];
|
UINT8 ddir;
|
||||||
|
}dma;
|
||||||
|
|
||||||
UINT16 mcieb;
|
UINT16 mcieb;
|
||||||
UINT16 mcipd;
|
UINT16 mcipd;
|
||||||
@ -234,10 +235,7 @@ struct scsp_state
|
|||||||
device_t *device;
|
device_t *device;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dma_scsp(address_space &space, scsp_state *scsp); /*state DMA transfer function*/
|
static void scsp_exec_dma(address_space &space, scsp_state *scsp); /*state DMA transfer function*/
|
||||||
#define scsp_dgate scsp->scsp_dmactrl & 0x4000
|
|
||||||
#define scsp_ddir scsp->scsp_dmactrl & 0x2000
|
|
||||||
#define scsp_dexe scsp->scsp_dmactrl & 0x1000
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
//#define dma_transfer_end ((scsp_regs[0x24/2] & 0x10)>>4)|(((scsp_regs[0x26/2] & 0x10)>>4)<<1)|(((scsp_regs[0x28/2] & 0x10)>>4)<<2)
|
//#define dma_transfer_end ((scsp_regs[0x24/2] & 0x10)>>4)|(((scsp_regs[0x26/2] & 0x10)>>4)<<1)|(((scsp_regs[0x28/2] & 0x10)>>4)<<2)
|
||||||
|
|
||||||
@ -747,10 +745,20 @@ static void SCSP_UpdateReg(scsp_state *scsp, address_space &space, int reg)
|
|||||||
break;
|
break;
|
||||||
case 0x12:
|
case 0x12:
|
||||||
case 0x13:
|
case 0x13:
|
||||||
|
scsp->dma.dmea = (scsp->udata.data[0x12/2] & 0xfffe) | (scsp->dma.dmea & 0xf0000);
|
||||||
|
break;
|
||||||
case 0x14:
|
case 0x14:
|
||||||
case 0x15:
|
case 0x15:
|
||||||
|
scsp->dma.dmea = ((scsp->udata.data[0x14/2] & 0xf000) << 4) | (scsp->dma.dmea & 0xfffe);
|
||||||
|
scsp->dma.drga = (scsp->udata.data[0x14/2] & 0x0ffe);
|
||||||
|
break;
|
||||||
case 0x16:
|
case 0x16:
|
||||||
case 0x17:
|
case 0x17:
|
||||||
|
scsp->dma.dtlg = (scsp->udata.data[0x16/2] & 0x0ffe);
|
||||||
|
scsp->dma.ddir = (scsp->udata.data[0x16/2] & 0x2000) >> 13;
|
||||||
|
scsp->dma.dgate = (scsp->udata.data[0x16/2] & 0x4000) >> 14;
|
||||||
|
if(scsp->udata.data[0x16/2] & 0x1000) // dexe
|
||||||
|
scsp_exec_dma(space,scsp);
|
||||||
break;
|
break;
|
||||||
case 0x18:
|
case 0x18:
|
||||||
case 0x19:
|
case 0x19:
|
||||||
@ -999,8 +1007,6 @@ static unsigned short SCSP_r16(scsp_state *scsp, address_space &space, unsigned
|
|||||||
SCSP_UpdateSlotRegR(scsp, slot,addr&0x1f);
|
SCSP_UpdateSlotRegR(scsp, slot,addr&0x1f);
|
||||||
v=*((unsigned short *) (scsp->Slots[slot].udata.datab+(addr)));
|
v=*((unsigned short *) (scsp->Slots[slot].udata.datab+(addr)));
|
||||||
}
|
}
|
||||||
else if(addr>=0x412 && addr <= 0x416)
|
|
||||||
v = scsp->dma_regs[((addr-0x412)/2) & 3];
|
|
||||||
else if(addr<0x600)
|
else if(addr<0x600)
|
||||||
{
|
{
|
||||||
if (addr < 0x430)
|
if (addr < 0x430)
|
||||||
@ -1319,94 +1325,84 @@ static void SCSP_DoMasterSamples(scsp_state *scsp, int nsamples)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: this needs to be timer-ized */
|
/* TODO: this needs to be timer-ized */
|
||||||
static void dma_scsp(address_space &space, scsp_state *scsp)
|
static void scsp_exec_dma(address_space &space, scsp_state *scsp)
|
||||||
{
|
{
|
||||||
static UINT16 tmp_dma[3];
|
static UINT16 tmp_dma[3];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
scsp->scsp_dmactrl = scsp->dma_regs[2] & 0x7000;
|
|
||||||
|
|
||||||
if(!(scsp_dexe)) //don't bother if DMA is off
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* calc the registers */
|
|
||||||
scsp->scsp_dmea = ((scsp->dma_regs[1] & 0xf000) << 4) | (scsp->dma_regs[0] & 0xfffe); /* RAM address */
|
|
||||||
scsp->scsp_drga = (scsp->dma_regs[1] & 0x0ffe);
|
|
||||||
scsp->scsp_dtlg = (scsp->dma_regs[2] & 0x0ffe);
|
|
||||||
|
|
||||||
logerror("SCSP: DMA transfer START\n"
|
logerror("SCSP: DMA transfer START\n"
|
||||||
"DMEA: %04x DRGA: %04x DTLG: %04x\n"
|
"DMEA: %04x DRGA: %04x DTLG: %04x\n"
|
||||||
"DGATE: %d DDIR: %d\n",scsp->scsp_dmea,scsp->scsp_drga,scsp->scsp_dtlg,scsp_dgate ? 1 : 0,scsp_ddir ? 1 : 0);
|
"DGATE: %d DDIR: %d\n",scsp->dma.dmea,scsp->dma.drga,scsp->dma.dtlg,scsp->dma.dgate ? 1 : 0,scsp->dma.ddir ? 1 : 0);
|
||||||
|
|
||||||
/* Copy the dma values in a temp storage for resuming later */
|
/* Copy the dma values in a temp storage for resuming later */
|
||||||
/* (DMA *can't* overwrite its parameters). */
|
/* (DMA *can't* overwrite its parameters). */
|
||||||
if(!(scsp_ddir))
|
if(!(scsp->dma.ddir))
|
||||||
{
|
{
|
||||||
for(i=0;i<3;i++)
|
for(i=0;i<3;i++)
|
||||||
tmp_dma[i] = scsp->dma_regs[i];
|
tmp_dma[i] = scsp->udata.data[(0x12+(i*2))/2];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note: we don't use space.read_word / write_word because it can happen that SH-2 enables the DMA instead of m68k. */
|
/* note: we don't use space.read_word / write_word because it can happen that SH-2 enables the DMA instead of m68k. */
|
||||||
/* TODO: don't know if params auto-updates, I guess not ... */
|
/* TODO: don't know if params auto-updates, I guess not ... */
|
||||||
if(scsp_ddir)
|
if(scsp->dma.ddir)
|
||||||
{
|
{
|
||||||
if(scsp_dgate)
|
if(scsp->dma.dgate)
|
||||||
{
|
{
|
||||||
popmessage("Check: SCSP DMA DGATE enabled, contact MAME/MESSdev");
|
popmessage("Check: SCSP DMA DGATE enabled, contact MAME/MESSdev");
|
||||||
for(i=0;i < scsp->scsp_dtlg;i+=2)
|
for(i=0;i < scsp->dma.dtlg;i+=2)
|
||||||
{
|
{
|
||||||
scsp->SCSPRAM[scsp->scsp_dmea] = 0;
|
scsp->SCSPRAM[scsp->dma.dmea] = 0;
|
||||||
scsp->SCSPRAM[scsp->scsp_dmea+1] = 0;
|
scsp->SCSPRAM[scsp->dma.dmea+1] = 0;
|
||||||
scsp->scsp_dmea+=2;
|
scsp->dma.dmea+=2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(i=0;i < scsp->scsp_dtlg;i+=2)
|
for(i=0;i < scsp->dma.dtlg;i+=2)
|
||||||
{
|
{
|
||||||
UINT16 tmp;
|
UINT16 tmp;
|
||||||
tmp = SCSP_r16(scsp, space, scsp->scsp_drga);
|
tmp = SCSP_r16(scsp, space, scsp->dma.drga);
|
||||||
scsp->SCSPRAM[scsp->scsp_dmea] = tmp & 0xff;
|
scsp->SCSPRAM[scsp->dma.dmea] = tmp & 0xff;
|
||||||
scsp->SCSPRAM[scsp->scsp_dmea+1] = tmp>>8;
|
scsp->SCSPRAM[scsp->dma.dmea+1] = tmp>>8;
|
||||||
scsp->scsp_dmea+=2;
|
scsp->dma.dmea+=2;
|
||||||
scsp->scsp_drga+=2;
|
scsp->dma.drga+=2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(scsp_dgate)
|
if(scsp->dma.dgate)
|
||||||
{
|
{
|
||||||
popmessage("Check: SCSP DMA DGATE enabled, contact MAME/MESSdev");
|
popmessage("Check: SCSP DMA DGATE enabled, contact MAME/MESSdev");
|
||||||
for(i=0;i < scsp->scsp_dtlg;i+=2)
|
for(i=0;i < scsp->dma.dtlg;i+=2)
|
||||||
{
|
{
|
||||||
SCSP_w16(scsp, space, scsp->scsp_drga, 0);
|
SCSP_w16(scsp, space, scsp->dma.drga, 0);
|
||||||
scsp->scsp_drga+=2;
|
scsp->dma.drga+=2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(i=0;i < scsp->scsp_dtlg;i+=2)
|
for(i=0;i < scsp->dma.dtlg;i+=2)
|
||||||
{
|
{
|
||||||
UINT16 tmp;
|
UINT16 tmp;
|
||||||
tmp = scsp->SCSPRAM[scsp->scsp_dmea];
|
tmp = scsp->SCSPRAM[scsp->dma.dmea];
|
||||||
tmp|= scsp->SCSPRAM[scsp->scsp_dmea+1]<<8;
|
tmp|= scsp->SCSPRAM[scsp->dma.dmea+1]<<8;
|
||||||
SCSP_w16(scsp, space, scsp->scsp_drga, tmp);
|
SCSP_w16(scsp, space, scsp->dma.drga, tmp);
|
||||||
scsp->scsp_dmea+=2;
|
scsp->dma.dmea+=2;
|
||||||
scsp->scsp_drga+=2;
|
scsp->dma.drga+=2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Resume the values*/
|
/*Resume the values*/
|
||||||
if(!(scsp_ddir))
|
if(!(scsp->dma.ddir))
|
||||||
{
|
{
|
||||||
for(i=0;i<3;i++)
|
for(i=0;i<3;i++)
|
||||||
scsp->dma_regs[i] = tmp_dma[i];
|
scsp->udata.data[(0x12+(i*2))/2] = tmp_dma[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Job done */
|
/* Job done */
|
||||||
scsp->dma_regs[2] &= ~0x1000;
|
scsp->udata.data[0x16/2] &= ~0x1000;
|
||||||
/* request a dma end irq (TODO: make it inside the interface) */
|
/* request a dma end irq (TODO: make it inside the interface) */
|
||||||
if(scsp->udata.data[0x1e/2] & 0x10)
|
if(scsp->udata.data[0x1e/2] & 0x10)
|
||||||
{
|
{
|
||||||
@ -1486,19 +1482,6 @@ WRITE16_DEVICE_HANDLER( scsp_w )
|
|||||||
tmp = SCSP_r16(scsp, space, offset*2);
|
tmp = SCSP_r16(scsp, space, offset*2);
|
||||||
COMBINE_DATA(&tmp);
|
COMBINE_DATA(&tmp);
|
||||||
SCSP_w16(scsp,space,offset*2, tmp);
|
SCSP_w16(scsp,space,offset*2, tmp);
|
||||||
|
|
||||||
/* TODO: move in UpdateSlot structure */
|
|
||||||
switch(offset*2)
|
|
||||||
{
|
|
||||||
// check DMA
|
|
||||||
case 0x412:
|
|
||||||
case 0x414:
|
|
||||||
case 0x416:
|
|
||||||
COMBINE_DATA(&scsp->dma_regs[((offset-0x412)/2) & 3]);
|
|
||||||
if(ACCESSING_BITS_8_15 && offset*2 == 0x416)
|
|
||||||
dma_scsp(space, scsp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE16_DEVICE_HANDLER( scsp_midi_in )
|
WRITE16_DEVICE_HANDLER( scsp_midi_in )
|
||||||
|
Loading…
Reference in New Issue
Block a user