diff options
Diffstat (limited to 'src/devices/sound/aica.cpp')
-rw-r--r-- | src/devices/sound/aica.cpp | 510 |
1 files changed, 185 insertions, 325 deletions
diff --git a/src/devices/sound/aica.cpp b/src/devices/sound/aica.cpp index 3784a0727c2..c7ef59e6c49 100644 --- a/src/devices/sound/aica.cpp +++ b/src/devices/sound/aica.cpp @@ -8,7 +8,6 @@ - No FM mode - A third sample format (ADPCM) has been added - Some minor other tweeks (no EGHOLD, slighly more capable DSP) - - Internal ARM7DI Core */ #include "emu.h" @@ -42,56 +41,42 @@ #define LPCTL(slot) ((slot->udata.data[0x0]>>0x9)&0x0001) #define PCMS(slot) ((slot->udata.data[0x0]>>0x7)&0x0003) -#define SA(slot) (((slot->udata.data[0x0]&0x7f)<<16)|(slot->udata.data[0x4/2])) +#define SA(slot) (((slot->udata.data[0x0]&0x7F)<<16)|(slot->udata.data[0x4/2])) #define LSA(slot) (slot->udata.data[0x8/2]) #define LEA(slot) (slot->udata.data[0xc/2]) -#define D2R(slot) ((slot->udata.data[0x10/2]>>0xB)&0x001f) -#define D1R(slot) ((slot->udata.data[0x10/2]>>0x6)&0x001f) -#define AR(slot) ((slot->udata.data[0x10/2]>>0x0)&0x001f) +#define D2R(slot) ((slot->udata.data[0x10/2]>>0xB)&0x001F) +#define D1R(slot) ((slot->udata.data[0x10/2]>>0x6)&0x001F) +#define AR(slot) ((slot->udata.data[0x10/2]>>0x0)&0x001F) #define LPSLNK(slot) ((slot->udata.data[0x14/2]>>0x0)&0x4000) -#define KRS(slot) ((slot->udata.data[0x14/2]>>0xA)&0x000f) -#define DL(slot) ((slot->udata.data[0x14/2]>>0x5)&0x001f) -#define RR(slot) ((slot->udata.data[0x14/2]>>0x0)&0x001f) +#define KRS(slot) ((slot->udata.data[0x14/2]>>0xA)&0x000F) +#define DL(slot) ((slot->udata.data[0x14/2]>>0x5)&0x001F) +#define RR(slot) ((slot->udata.data[0x14/2]>>0x0)&0x001F) -#define TL(slot) ((slot->udata.data[0x28/2]>>0x8)&0x00ff) +#define TL(slot) ((slot->udata.data[0x28/2]>>0x8)&0x00FF) -#define OCT(slot) ((slot->udata.data[0x18/2]>>0xB)&0x000f) +#define OCT(slot) ((slot->udata.data[0x18/2]>>0xB)&0x000F) #define FNS(slot) ((slot->udata.data[0x18/2]>>0x0)&0x03FF) #define LFORE(slot) ((slot->udata.data[0x1c/2]>>0x0)&0x8000) -#define LFOF(slot) ((slot->udata.data[0x1c/2]>>0xA)&0x001f) +#define LFOF(slot) ((slot->udata.data[0x1c/2]>>0xA)&0x001F) #define PLFOWS(slot) ((slot->udata.data[0x1c/2]>>0x8)&0x0003) #define PLFOS(slot) ((slot->udata.data[0x1c/2]>>0x5)&0x0007) #define ALFOWS(slot) ((slot->udata.data[0x1c/2]>>0x3)&0x0003) #define ALFOS(slot) ((slot->udata.data[0x1c/2]>>0x0)&0x0007) -#define ISEL(slot) ((slot->udata.data[0x20/2]>>0x0)&0x000f) -#define IMXL(slot) ((slot->udata.data[0x20/2]>>0x4)&0x000f) +#define ISEL(slot) ((slot->udata.data[0x20/2]>>0x0)&0x000F) +#define IMXL(slot) ((slot->udata.data[0x20/2]>>0x4)&0x000F) -#define DISDL(slot) ((slot->udata.data[0x24/2]>>0x8)&0x000f) -#define DIPAN(slot) ((slot->udata.data[0x24/2]>>0x0)&0x001f) +#define DISDL(slot) ((slot->udata.data[0x24/2]>>0x8)&0x000F) +#define DIPAN(slot) ((slot->udata.data[0x24/2]>>0x0)&0x001F) #define EFSDL(slot) ((m_EFSPAN[slot*4]>>8)&0x000f) #define EFPAN(slot) ((m_EFSPAN[slot*4]>>0)&0x001f) -/* -Unimplemented Registers -#define Q(slot) ((slot->udata.data[0x28/2]>>0x0)&0x001f) // resonance; (0.75 * Q - 3)dB -#define FLV0(slot) ((slot->udata.data[0x2c/2]>>0x0)&0x1fff) // FLV0 : Cutoff frequency at attack start -#define FLV1(slot) ((slot->udata.data[0x30/2]>>0x0)&0x1fff) // FLV1 : Cutoff frequency at attack End(decay start) -#define FLV2(slot) ((slot->udata.data[0x34/2]>>0x0)&0x1fff) // FLV2 : Cutoff frequency at decay End(sustain start) -#define FLV3(slot) ((slot->udata.data[0x38/2]>>0x0)&0x1fff) // FLV3 : Cutoff frequency at KOFF -#define FLV4(slot) ((slot->udata.data[0x3c/2]>>0x0)&0x1fff) // FLV4 : Cutoff frequency after release -#define FAR(slot) ((slot->udata.data[0x40/2]>>0x8)&0x001f) -#define FD1R(slot) ((slot->udata.data[0x40/2]>>0x0)&0x001f) -#define FD2R(slot) ((slot->udata.data[0x44/2]>>0x8)&0x001f) -#define FRR(slot) ((slot->udata.data[0x44/2]>>0x0)&0x001f) -*/ - //Envelope times in ms static constexpr double ARTimes[64]={100000/*infinity*/,100000/*infinity*/,8100.0,6900.0,6000.0,4800.0,4000.0,3400.0,3000.0,2400.0,2000.0,1700.0,1500.0, 1200.0,1000.0,860.0,760.0,600.0,500.0,430.0,380.0,300.0,250.0,220.0,190.0,150.0,130.0,110.0,95.0, @@ -102,10 +87,9 @@ static constexpr double DRTimes[64]={100000/*infinity*/,100000/*infinity*/,11820 920.0,790.0,690.0,550.0,460.0,390.0,340.0,270.0,230.0,200.0,170.0,140.0,110.0,98.0,85.0,68.0,57.0,49.0,43.0,34.0, 28.0,25.0,22.0,18.0,14.0,12.0,11.0,8.5,7.1,6.1,5.4,4.3,3.6,3.1}; -#define MN(aica) ((m_udata.data[0]>>0x0)&0x8000) -#define MEM8B(aica) ((m_udata.data[0]>>0x0)&0x0200) +#define MEM4B(aica) ((m_udata.data[0]>>0x0)&0x0200) #define DAC18B(aica) ((m_udata.data[0]>>0x0)&0x0100) -#define MVOL(aica) ((m_udata.data[0]>>0x0)&0x000f) +#define MVOL(aica) ((m_udata.data[0]>>0x0)&0x000F) #define RBL(aica) ((m_udata.data[2]>>0xD)&0x0003) #define RBP(aica) ((m_udata.data[2]>>0x0)&0x0fff) #define MOFULL(aica) ((m_udata.data[4]>>0x0)&0x1000) @@ -115,7 +99,7 @@ static constexpr double DRTimes[64]={100000/*infinity*/,100000/*infinity*/,11820 #define MIEMPTY(aica) ((m_udata.data[4]>>0x0)&0x0100) #define AFSEL(aica) ((m_udata.data[0xc/2]>>0x0)&0x4000) -#define MSLC(aica) ((m_udata.data[0xc/2]>>0x8)&0x3f) +#define MSLC(aica) ((m_udata.data[0xc/2]>>0x8)&0x3F) #define SCILV0(aica) ((m_udata.data[0xa8/2]>>0x0)&0xff) #define SCILV1(aica) ((m_udata.data[0xac/2]>>0x0)&0xff) @@ -124,7 +108,6 @@ static constexpr double DRTimes[64]={100000/*infinity*/,100000/*infinity*/,11820 #define MCIEB(aica) ((m_udata.data[0xb4/2]>>0x0)&0xff) #define MCIPD(aica) ((m_udata.data[0xb8/2]>>0x0)&0xff) #define MCIRE(aica) ((m_udata.data[0xbc/2]>>0x0)&0xff) -#define MCIEB(aica) ((m_udata.data[0xb4/2]>>0x0)&0xff) #define SCIEX0 0 #define SCIEX1 1 @@ -150,29 +133,16 @@ unsigned char aica_device::DecodeSCI(unsigned char irq) return SCI; } -void aica_device::InterruptUpdate(int line, int state) -{ - switch(line) - { - case 0: m_armirq->in_w<0>(state); break; - case 1: m_armirq->in_w<1>(state); break; - case 2: m_armirq->in_w<2>(state); break; - case 3: m_armirq->in_w<3>(state); break; - case 4: m_armirq->in_w<4>(state); break; - case 5: m_armirq->in_w<5>(state); break; - case 6: m_armirq->in_w<6>(state); break; - case 7: m_armirq->in_w<7>(state); break; - } -} - void aica_device::ResetInterrupts() { +#if 0 uint32_t reset = m_udata.data[0xa4/2]; if (reset & 0x40) - InterruptUpdate(m_IrqTimA, CLEAR_LINE); + m_irq_cb(-m_IrqTimA); if (reset & 0x180) - InterruptUpdate(m_IrqTimBC, CLEAR_LINE); + m_irq_cb(-m_IrqTimBC); +#endif } void aica_device::CheckPendingIRQ() @@ -183,7 +153,7 @@ void aica_device::CheckPendingIRQ() if(m_MidiW!=m_MidiR) { m_IRQL = m_IrqMidi; - InterruptUpdate(m_IrqMidi, ASSERT_LINE); + m_irq_cb(1); return; } if(!pend) @@ -192,21 +162,21 @@ void aica_device::CheckPendingIRQ() if(en&0x40) { m_IRQL = m_IrqTimA; - InterruptUpdate(m_IrqTimA, ASSERT_LINE); + m_irq_cb(1); return; } if(pend&0x80) if(en&0x80) { m_IRQL = m_IrqTimBC; - InterruptUpdate(m_IrqTimBC, ASSERT_LINE); + m_irq_cb(1); return; } if(pend&0x100) if(en&0x100) { m_IRQL = m_IrqTimBC; - InterruptUpdate(m_IrqTimBC, ASSERT_LINE); + m_irq_cb(1); return; } } @@ -222,7 +192,7 @@ void aica_device::CheckPendingIRQ_SH4() TIMER_CALLBACK_MEMBER( aica_device::timerA_cb ) { - m_TimCnt[0] = 0xffff; + m_TimCnt[0] = 0xFFFF; m_udata.data[0xa0/2]|=0x40; m_mcipd |= 0x40; m_udata.data[0x90/2]&=0xff00; @@ -235,7 +205,7 @@ TIMER_CALLBACK_MEMBER( aica_device::timerA_cb ) TIMER_CALLBACK_MEMBER( aica_device::timerB_cb ) { - m_TimCnt[1] = 0xffff; + m_TimCnt[1] = 0xFFFF; m_udata.data[0xa0/2]|=0x80; m_mcipd |= 0x80; m_udata.data[0x94/2]&=0xff00; @@ -247,7 +217,7 @@ TIMER_CALLBACK_MEMBER( aica_device::timerB_cb ) TIMER_CALLBACK_MEMBER( aica_device::timerC_cb ) { - m_TimCnt[2] = 0xffff; + m_TimCnt[2] = 0xFFFF; m_udata.data[0xa0/2]|=0x100; m_mcipd |= 0x100; m_udata.data[0x98/2]&=0xff00; @@ -295,6 +265,7 @@ void aica_device::Compute_EG(AICA_SLOT *slot) slot->EG.D1R=Get_DR(rate,D1R(slot)); slot->EG.D2R=Get_DR(rate,D2R(slot)); slot->EG.RR=Get_RR(rate,RR(slot)); + slot->EG.RR=Get_RR(rate,RR(slot)); slot->EG.DL=0x1f-DL(slot); } @@ -357,6 +328,7 @@ uint32_t aica_device::Step(AICA_SLOT *slot) return Fn; } + void aica_device::Compute_LFO(AICA_SLOT *slot) { if(PLFOS(slot)!=0) @@ -380,7 +352,7 @@ void aica_device::InitADPCM(int *PrevSignal, int *PrevQuant) signed short aica_device::DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQuant) { int x = (*PrevQuant * quant_mul[Delta & 7]) / 8; - if (x > 0x7fff) x = 0x7fff; + if (x > 0x7FFF) x = 0x7FFF; if (Delta & 8) x = -x; x += *PrevSignal; #if 0 // older implementation @@ -446,13 +418,16 @@ void aica_device::Init() m_MidiOutR=m_MidiOutW=0; // get AICA RAM - m_AICARAM = m_ram->pointer(); - m_AICARAM += m_roffset; - m_AICARAM_LENGTH = m_ram->size(); - m_RAM_MASK = m_AICARAM_LENGTH-1; - m_RAM_MASK16 = m_RAM_MASK & ~1; - m_DSP.AICARAM = (uint16_t *)m_AICARAM; - m_DSP.AICARAM_LENGTH = m_AICARAM_LENGTH/2; + if (m_ram_region != nullptr) + { + m_AICARAM = m_ram_region->base(); + m_AICARAM += m_roffset; + m_AICARAM_LENGTH = m_ram_region->bytes(); + m_RAM_MASK = m_AICARAM_LENGTH-1; + m_RAM_MASK16 = m_RAM_MASK & 0x7ffffe; + m_DSP.AICARAM = (uint16_t *)m_AICARAM; + m_DSP.AICARAM_LENGTH = m_AICARAM_LENGTH/2; + } m_timerA = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(aica_device::timerA_cb), this)); m_timerB = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(aica_device::timerB_cb), this)); @@ -469,7 +444,7 @@ void aica_device::Init() { int iTL =(i>>0x0)&0xff; int iPAN=(i>>0x8)&0x1f; - int iSDL=(i>>0xD)&0x0f; + int iSDL=(i>>0xD)&0x0F; float TL; float SegaDB=0; float fSDL; @@ -548,6 +523,8 @@ void aica_device::Init() } AICALFO_Init(); + m_buffertmpl=make_unique_clear<int32_t[]>(44100); + m_buffertmpr=make_unique_clear<int32_t[]>(44100); // no "pend" m_udata.data[0xa0/2] = 0; @@ -677,49 +654,58 @@ void aica_device::UpdateReg(address_space &space, int reg) case 0x90: case 0x91: - uint32_t time; + if(m_master) + { + uint32_t time; - m_TimPris[0]=1<<((m_udata.data[0x90/2]>>8)&0x7); - m_TimCnt[0]=(m_udata.data[0x90/2]&0xff)<<8; + m_TimPris[0]=1<<((m_udata.data[0x90/2]>>8)&0x7); + m_TimCnt[0]=(m_udata.data[0x90/2]&0xff)<<8; - if ((m_udata.data[0x90/2]&0xff) != 255) - { - time = (m_clock / m_TimPris[0]) / (255-(m_udata.data[0x90/2]&0xff)); - if (time) + if ((m_udata.data[0x90/2]&0xff) != 255) { - m_timerA->adjust(attotime::from_ticks(768, time)); + time = (44100 / m_TimPris[0]) / (255-(m_udata.data[0x90/2]&0xff)); + if (time) + { + m_timerA->adjust(attotime::from_hz(time)); + } } } break; case 0x94: case 0x95: - uint32_t time; + if(m_master) + { + uint32_t time; - m_TimPris[1]=1<<((m_udata.data[0x94/2]>>8)&0x7); - m_TimCnt[1]=(m_udata.data[0x94/2]&0xff)<<8; + m_TimPris[1]=1<<((m_udata.data[0x94/2]>>8)&0x7); + m_TimCnt[1]=(m_udata.data[0x94/2]&0xff)<<8; - if ((m_udata.data[0x94/2]&0xff) != 255) - { - time = (m_clock / m_TimPris[1]) / (255-(m_udata.data[0x94/2]&0xff)); - if (time) + if ((m_udata.data[0x94/2]&0xff) != 255) { - m_timerB->adjust(attotime::from_ticks(768, time)); + time = (44100 / m_TimPris[1]) / (255-(m_udata.data[0x94/2]&0xff)); + if (time) + { + m_timerB->adjust(attotime::from_hz(time)); + } } } break; case 0x98: case 0x99: - uint32_t time; + if(m_master) + { + uint32_t time; - m_TimPris[2]=1<<((m_udata.data[0x98/2]>>8)&0x7); - m_TimCnt[2]=(m_udata.data[0x98/2]&0xff)<<8; + m_TimPris[2]=1<<((m_udata.data[0x98/2]>>8)&0x7); + m_TimCnt[2]=(m_udata.data[0x98/2]&0xff)<<8; - if ((m_udata.data[0x98/2]&0xff) != 255) - { - time = (m_clock / m_TimPris[2]) / (255-(m_udata.data[0x98/2]&0xff)); - if (time) + if ((m_udata.data[0x98/2]&0xff) != 255) { - m_timerC->adjust(attotime::from_ticks(768, time)); + time = (44100 / m_TimPris[2]) / (255-(m_udata.data[0x98/2]&0xff)); + if (time) + { + m_timerC->adjust(attotime::from_hz(time)); + } } } break; @@ -733,22 +719,25 @@ void aica_device::UpdateReg(address_space &space, int reg) case 0xa4: //SCIRE case 0xa5: - m_udata.data[0xa0/2] &= ~m_udata.data[0xa4/2]; - ResetInterrupts(); - - // behavior from real hardware (SCSP, assumed to carry over): if you SCIRE a timer that's expired, - // it'll immediately pop up again - if (m_TimCnt[0] >= 0xff00) - { - m_udata.data[0xa0/2] |= 0x40; - } - if (m_TimCnt[1] >= 0xff00) - { - m_udata.data[0xa0/2] |= 0x80; - } - if (m_TimCnt[2] >= 0xff00) + if(m_master) { - m_udata.data[0xa0/2] |= 0x100; + m_udata.data[0xa0/2] &= ~m_udata.data[0xa4/2]; + ResetInterrupts(); + + // behavior from real hardware (SCSP, assumed to carry over): if you SCIRE a timer that's expired, + // it'll immediately pop up again + if (m_TimCnt[0] >= 0xff00) + { + m_udata.data[0xa0/2] |= 0x40; + } + if (m_TimCnt[1] >= 0xff00) + { + m_udata.data[0xa0/2] |= 0x80; + } + if (m_TimCnt[2] >= 0xff00) + { + m_udata.data[0xa0/2] |= 0x100; + } } break; case 0xa8: @@ -757,9 +746,12 @@ void aica_device::UpdateReg(address_space &space, int reg) case 0xad: case 0xb0: case 0xb1: - m_IrqTimA=DecodeSCI(SCITMA); - m_IrqTimBC=DecodeSCI(SCITMB); - m_IrqMidi=DecodeSCI(SCIMID); + if(m_master) + { + m_IrqTimA=DecodeSCI(SCITMA); + m_IrqTimBC=DecodeSCI(SCITMB); + m_IrqMidi=DecodeSCI(SCIMID); + } break; case 0xb4: //MCIEB @@ -793,17 +785,13 @@ void aica_device::UpdateRegR(address_space &space, int reg) { switch(reg&0xff) { - case 0x0: - m_stream->set_output_gain(0,MVOL() / 15.0); - m_stream->set_output_gain(1,MVOL() / 15.0); - break; case 8: case 9: { unsigned short v=m_udata.data[0x8/2]; v&=0xff00; v|=m_MidiStack[m_MidiR]; - InterruptUpdate(m_IrqMidi, CLEAR_LINE); // cancel the IRQ + m_irq_cb(0); // cancel the IRQ if(m_MidiR!=m_MidiW) { ++m_MidiR; @@ -829,10 +817,10 @@ void aica_device::UpdateRegR(address_space &space, int reg) SGC = (slot->EG.state << 13) & 0x6000; EG = slot->active ? slot->EG.volume : 0; EG >>= (EG_SHIFT - 13); - EG = 0x1fff - EG; + EG = 0x1FFF - EG; if (EG < 0) EG = 0; - m_udata.data[0x10/2] = (EG & 0x1ff8) | SGC | LP; + m_udata.data[0x10/2] = (EG & 0x1FF8) | SGC | LP; } else { @@ -884,10 +872,6 @@ void aica_device::w16(address_space &space,unsigned int addr,unsigned short val) } else if (addr < 0x2800) { - if (addr == 0x2000) - { - m_ram_size = MEM8B() ? 0x800000 : 0x200000; - } if (addr <= 0x2044) { // printf("%x to EFSxx slot %d (addr %x)\n", val, (addr-0x2000)/4, addr&0x7f); @@ -903,6 +887,25 @@ void aica_device::w16(address_space &space,unsigned int addr,unsigned short val) UpdateReg(space, addr&0xff); } + else if (addr == 0x2d00) + { + m_IRQL = val; + popmessage("AICA: write to IRQL?"); + } + else if (addr == 0x2d04) + { + m_IRQR = val; + + if (val & 1) + { + m_irq_cb(0); + } + if (val & 0x100) + popmessage("AICA: SH-4 write protection enabled!"); + + if (val & 0xfefe) + popmessage("AICA: IRQR %04x!",val); + } } else { @@ -977,7 +980,16 @@ unsigned short aica_device::r16(address_space &space, unsigned int addr) { UpdateRegR(space, addr&0xff); v= *((unsigned short *) (m_udata.datab+((addr&0xff)))); - if((addr&0xfffe)==0x2810) m_udata.data[0x10/2] &= 0x7fff; // reset LP on read + if((addr&0xfffe)==0x2810) m_udata.data[0x10/2] &= 0x7FFF; // reset LP on read + } + else if (addr == 0x2d00) + { + return m_IRQL; + } + else if (addr == 0x2d04) + { + //popmessage("AICA: read to IRQR?"); + return m_IRQR; } } else @@ -1030,9 +1042,9 @@ void aica_device::TimersAddTicks(int ticks) if(m_TimCnt[0]<=0xff00) { m_TimCnt[0] += ticks << (8-((m_udata.data[0x18/2]>>8)&0x7)); - if (m_TimCnt[0] > 0xfF00) + if (m_TimCnt[0] > 0xFF00) { - m_TimCnt[0] = 0xffff; + m_TimCnt[0] = 0xFFFF; m_udata.data[0xa0/2]|=0x40; } m_udata.data[0x90/2]&=0xff00; @@ -1042,9 +1054,9 @@ void aica_device::TimersAddTicks(int ticks) if(m_TimCnt[1]<=0xff00) { m_TimCnt[1] += ticks << (8-((m_udata.data[0x1a/2]>>8)&0x7)); - if (m_TimCnt[1] > 0xfF00) + if (m_TimCnt[1] > 0xFF00) { - m_TimCnt[1] = 0xffff; + m_TimCnt[1] = 0xFFFF; m_udata.data[0xa0/2]|=0x80; } m_udata.data[0x94/2]&=0xff00; @@ -1054,9 +1066,9 @@ void aica_device::TimersAddTicks(int ticks) if(m_TimCnt[2]<=0xff00) { m_TimCnt[2] += ticks << (8-((m_udata.data[0x1c/2]>>8)&0x7)); - if (m_TimCnt[2] > 0xfF00) + if (m_TimCnt[2] > 0xFF00) { - m_TimCnt[2] = 0xffff; + m_TimCnt[2] = 0xFFFF; m_udata.data[0xa0/2]|=0x100; } m_udata.data[0x98/2]&=0xff00; @@ -1279,16 +1291,8 @@ void aica_device::DoMasterSamples(int nsamples) } } - if (MN()) // Mono - { - *bufl++ = ICLIP16((smpl+smpr)>>4); - *bufr++ = ICLIP16((smpl+smpr)>>4); - } - else - { - *bufl++ = ICLIP16(smpl>>3); - *bufr++ = ICLIP16(smpr>>3); - } + *bufl++ = ICLIP16(smpl>>3); + *bufr++ = ICLIP16(smpr>>3); } } @@ -1328,7 +1332,7 @@ void aica_device::aica_exec_dma(address_space &space) for(i=0;i < m_dma.dlg;i+=2) { uint16_t tmp; - tmp = r16(space, m_dma.drga); + tmp = r16(space, m_dma.drga);; m_AICARAM[m_dma.dmea] = tmp & 0xff; m_AICARAM[m_dma.dmea+1] = tmp>>8; m_dma.dmea+=4; @@ -1395,35 +1399,19 @@ void aica_device::sound_stream_update(sound_stream &stream, stream_sample_t **in } //------------------------------------------------- -// device_add_mconfig - add device configuration -//------------------------------------------------- - -MACHINE_CONFIG_START(aica_device::device_add_mconfig) - MCFG_CPU_ADD("arm7di", ARM7, DERIVED_CLOCK(2, 3*8)) // ARM7DI; AICA bus clock is 2/3rds * 33.8688. ARM7 gets 1 bus cycle out of each 8. - MCFG_CPU_PROGRAM_MAP(internal_map) - - MCFG_INPUT_MERGER_ANY_HIGH("armirq") - MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("arm7di", ARM7_FIRQ_LINE)) - - MCFG_RAM_ADD("ram") - MCFG_RAM_DEFAULT_VALUE(0xff) // TODO : Correct? -MACHINE_CONFIG_END - -//------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void aica_device::device_start() { - m_clock = clock(); - m_rate = clock()/768; // init the emulation Init(); // set up the IRQ callbacks + m_irq_cb.resolve_safe(); m_main_irq_cb.resolve_safe(); - m_stream = machine().sound().stream_alloc(*this, 0, 2, m_rate); + m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100); // save state save_item(NAME(m_IrqTimA)); @@ -1440,148 +1428,28 @@ void aica_device::device_start() save_item(NAME(m_TimCnt),3); } -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void aica_device::device_reset() -{ - /* halt the ARM7 */ - m_armrst = 1; - m_arm7di->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); -} - -//------------------------------------------------- -// device_clock_changed - called if the clock -// changes -//------------------------------------------------- - -void aica_device::device_clock_changed() -{ - if (m_clock != clock()) - { - m_clock = clock(); - m_rate = clock()/768; - m_stream->set_sample_rate(m_rate); - } -} - -READ32_MEMBER( aica_device::host_aica_reg_r ) -{ -// osd_printf_verbose("%s",string_format("AICA REG: [%08x] read %x, mask %x\n", 0x700000+reg*4, (uint64_t)offset, mem_mask).c_str()); - - if(offset == 0x2c00/4) - return m_armrst; - - return r16(space,offset*4); -} - -WRITE32_MEMBER( aica_device::host_aica_reg_w ) -{ - // these are can accessed only on SH4 - if (offset == (0x2c00/4)) - { - if(ACCESSING_BITS_0_7) - { - m_armrst = data & 1; - - if (data & 1) - { - /* halt the ARM7 */ - m_arm7di->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - } - else - { - /* it's alive ! */ - m_arm7di->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); - } - } - } - else - { - mem_mask = 0xffff; // TODO - uint16_t tmp; - - tmp = r16(space, offset*4); - COMBINE_DATA(&tmp); - w16(space, offset*4, tmp); - } - -// osd_printf_verbose("%s",string_format("AICA REG: [%08x=%x] write %x to %x, mask %x\n", 0x700000+reg*4, data, offset, mem_mask).c_str()); -} - -READ8_MEMBER( aica_device::ram_r ) -{ - if (offset < std::min(m_ram->size(), m_ram_size)) - { - return m_ram->read(offset); - } - return 0xff; -} - -READ8_MEMBER( aica_device::ram_host_r ) -{ - if ((m_rp == 0) && (offset < std::min(m_ram->size(), m_ram_size))) - { - return m_ram->read(offset); - } - return 0xff; // Unverified -} - -WRITE8_MEMBER( aica_device::ram_w ) +void aica_device::set_ram_base(void *base, int size) { - assert(offset < std::min(m_ram->size(), m_ram_size)); - m_ram->write(offset, data); + m_AICARAM = (unsigned char *)base; + m_AICARAM_LENGTH = size; + m_RAM_MASK = m_AICARAM_LENGTH-1; + m_RAM_MASK16 = m_RAM_MASK & 0x7ffffe; + m_DSP.AICARAM = (uint16_t *)base; + m_DSP.AICARAM_LENGTH = size; } READ16_MEMBER( aica_device::read ) { - if ((offset*4) == 0x2d00) - { - return m_IRQL; - } - else if ((offset*4) == 0x2d04) - { - //popmessage("AICA: read to IRQR?"); - return m_IRQR; - } - - return r16(space,offset*4); + return r16(space,offset*2); } WRITE16_MEMBER( aica_device::write ) { - // these are can accessed only on internal ARM7DI core - if ((offset*4) == 0x2d00) - { - m_IRQL = data; - popmessage("AICA: write to IRQL?"); - } - else if ((offset*4) == 0x2d04) - { - m_IRQR = data; - - if (data & 1) - { - for (int i = 0; i < 8; i++) - { - InterruptUpdate(i,CLEAR_LINE); - } - } - - m_rp = data & 0x100; + uint16_t tmp; - if (data & 0xfefe) - popmessage("AICA: IRQR %04x!",data); - } - else - { - uint16_t tmp; - - tmp = r16(space, offset*4); - COMBINE_DATA(&tmp); - w16(space, offset*4, tmp); - } + tmp = r16(space, offset*2); + COMBINE_DATA(&tmp); + w16(space, offset*2, tmp); } WRITE16_MEMBER( aica_device::midi_in ) @@ -1599,46 +1467,38 @@ READ16_MEMBER( aica_device::midi_out_r ) return val; } -void aica_device::internal_map(address_map &map) -{ - map.unmap_value_high(); - map(0x00000000, 0x007fffff).rw(this, FUNC(aica_device::ram_r), FUNC(aica_device::ram_w)) - map(0x00800000, 0x00807fff).rw(this, FUNC(aica_device::read), FUNC(aica_device::write)).umask32(0x0000ffff); -} - DEFINE_DEVICE_TYPE(AICA, aica_device, "aica", "AICA") aica_device::aica_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, AICA, tag, owner, clock) - , device_sound_interface(mconfig, *this) - , m_arm7di(*this, "arm7di") - , m_armirq(*this, "armirq") - , m_ram(*this, "ram") - , m_ram_size(0x200000) - , m_roffset(0) - , m_main_irq_cb(*this) - , m_IRQL(0) - , m_IRQR(0) - , m_BUFPTR(0) - , m_AICARAM(nullptr) - , m_AICARAM_LENGTH(0) - , m_RAM_MASK(0) - , m_RAM_MASK16(0) - , m_IrqTimA(0) - , m_IrqTimBC(0) - , m_IrqMidi(0) - , m_MidiOutW(0) - , m_MidiOutR(0) - , m_MidiW(0) - , m_MidiR(0) - , m_armrst(0) - , m_rp(0) - , m_mcieb(0) - , m_mcipd(0) - , m_bufferl(nullptr) - , m_bufferr(nullptr) - , m_length(0) - , m_RBUFDST(nullptr) + : device_t(mconfig, AICA, tag, owner, clock), + device_sound_interface(mconfig, *this), + m_master(false), + m_roffset(0), + m_irq_cb(*this), + m_main_irq_cb(*this), + m_ram_region(*this, this->tag()), + m_IRQL(0), + m_IRQR(0), + m_BUFPTR(0), + m_AICARAM(nullptr), + m_AICARAM_LENGTH(0), + m_RAM_MASK(0), + m_RAM_MASK16(0), + m_buffertmpl(nullptr), + m_buffertmpr(nullptr), + m_IrqTimA(0), + m_IrqTimBC(0), + m_IrqMidi(0), + m_MidiOutW(0), + m_MidiOutR(0), + m_MidiW(0), + m_MidiR(0), + m_mcieb(0), + m_mcipd(0), + m_bufferl(nullptr), + m_bufferr(nullptr), + m_length(0), + m_RBUFDST(nullptr) { memset(&m_udata.data, 0, sizeof(m_udata.data)); |