diff --git a/.gitattributes b/.gitattributes index 9628a206b39..ab3c6627825 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2735,7 +2735,6 @@ src/emu/sound/aica.c svneol=native#text/plain src/emu/sound/aica.h svneol=native#text/plain src/emu/sound/aicadsp.c svneol=native#text/plain src/emu/sound/aicadsp.h svneol=native#text/plain -src/emu/sound/aicalfo.inc svneol=native#text/plain src/emu/sound/asc.c svneol=native#text/plain src/emu/sound/asc.h svneol=native#text/plain src/emu/sound/astrocde.c svneol=native#text/plain diff --git a/src/emu/sound/aica.c b/src/emu/sound/aica.c index 7efec4ffd70..52c82e30187 100644 --- a/src/emu/sound/aica.c +++ b/src/emu/sound/aica.c @@ -10,8 +10,6 @@ #include "emu.h" #include "aica.h" -#include "aicadsp.h" -#include "devlegcy.h" #define ICLIP16(x) (x<-32768)?-32768:((x>32767)?32767:x) @@ -19,9 +17,15 @@ #define FIX(v) ((UINT32) ((float) (1<udata.data[0x24/2]>>0x8)&0x000F) #define DIPAN(slot) ((slot->udata.data[0x24/2]>>0x0)&0x001F) -#define EFSDL(slot) ((AICA->EFSPAN[slot*4]>>8)&0x000f) -#define EFPAN(slot) ((AICA->EFSPAN[slot*4]>>0)&0x001f) +#define EFSDL(slot) ((m_EFSPAN[slot*4]>>8)&0x000f) +#define EFPAN(slot) ((m_EFSPAN[slot*4]>>0)&0x001f) //Envelope times in ms static const 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, @@ -80,72 +84,28 @@ static const double DRTimes[64]={100000/*infinity*/,100000/*infinity*/,118200.0, 14800.0,12700.0,11100.0,8900.0,7400.0,6300.0,5500.0,4400.0,3700.0,3200.0,2800.0,2200.0,1800.0,1600.0,1400.0,1100.0, 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}; -static INT32 EG_TABLE[0x400]; -enum STATE {ATTACK,DECAY1,DECAY2,RELEASE}; -struct EG_t -{ - int volume; // - STATE state; - int step; - //step vals - int AR; //Attack - int D1R; //Decay1 - int D2R; //Decay2 - int RR; //Release +#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 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) +#define MOEMPTY(aica) ((m_udata.data[4]>>0x0)&0x0800) +#define MIOVF(aica) ((m_udata.data[4]>>0x0)&0x0400) +#define MIFULL(aica) ((m_udata.data[4]>>0x0)&0x0200) +#define MIEMPTY(aica) ((m_udata.data[4]>>0x0)&0x0100) - int DL; //Decay level - UINT8 LPLINK; -}; +#define AFSEL(aica) ((m_udata.data[0xc/2]>>0x0)&0x4000) +#define MSLC(aica) ((m_udata.data[0xc/2]>>0x8)&0x3F) -struct SLOT -{ - union - { - UINT16 data[0x40]; //only 0x1a bytes used - UINT8 datab[0x80]; - } udata; - UINT8 active; //this slot is currently playing - UINT8 *base; //samples base address - UINT32 prv_addr; // previous play address (for ADPCM) - UINT32 cur_addr; //current play address (24.8) - UINT32 nxt_addr; //next play address - UINT32 step; //pitch step (24.8) - UINT8 Backwards; //the wave is playing backwards - EG_t EG; //Envelope - LFO_t PLFO; //Phase LFO - LFO_t ALFO; //Amplitude LFO - int slot; - int cur_sample; //current ADPCM sample - int cur_quant; //current ADPCM step - int curstep; - int cur_lpquant, cur_lpsample, cur_lpstep; - UINT8 *adbase, *adlpbase; - UINT8 lpend; -}; +#define SCILV0(aica) ((m_udata.data[0xa8/2]>>0x0)&0xff) +#define SCILV1(aica) ((m_udata.data[0xac/2]>>0x0)&0xff) +#define SCILV2(aica) ((m_udata.data[0xb0/2]>>0x0)&0xff) - -#define MEM4B(aica) ((aica->udata.data[0]>>0x0)&0x0200) -#define DAC18B(aica) ((aica->udata.data[0]>>0x0)&0x0100) -#define MVOL(aica) ((aica->udata.data[0]>>0x0)&0x000F) -#define RBL(aica) ((aica->udata.data[2]>>0xD)&0x0003) -#define RBP(aica) ((aica->udata.data[2]>>0x0)&0x0fff) -#define MOFULL(aica) ((aica->udata.data[4]>>0x0)&0x1000) -#define MOEMPTY(aica) ((aica->udata.data[4]>>0x0)&0x0800) -#define MIOVF(aica) ((aica->udata.data[4]>>0x0)&0x0400) -#define MIFULL(aica) ((aica->udata.data[4]>>0x0)&0x0200) -#define MIEMPTY(aica) ((aica->udata.data[4]>>0x0)&0x0100) - -#define AFSEL(aica) ((aica->udata.data[0xc/2]>>0x0)&0x4000) -#define MSLC(aica) ((aica->udata.data[0xc/2]>>0x8)&0x3F) - -#define SCILV0(aica) ((aica->udata.data[0xa8/2]>>0x0)&0xff) -#define SCILV1(aica) ((aica->udata.data[0xac/2]>>0x0)&0xff) -#define SCILV2(aica) ((aica->udata.data[0xb0/2]>>0x0)&0xff) - -#define MCIEB(aica) ((aica->udata.data[0xb4/2]>>0x0)&0xff) -#define MCIPD(aica) ((aica->udata.data[0xb8/2]>>0x0)&0xff) -#define MCIRE(aica) ((aica->udata.data[0xbc/2]>>0x0)&0xff) +#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 SCIEX0 0 #define SCIEX1 1 @@ -156,81 +116,9 @@ struct SLOT #define SCITMA 6 #define SCITMB 7 -struct aica_state -{ - union - { - UINT16 data[0xc0/2]; - UINT8 datab[0xc0]; - } udata; - UINT16 IRQL, IRQR; - UINT16 EFSPAN[0x48]; - SLOT Slots[64]; - signed short RINGBUF[64]; - unsigned char BUFPTR; - unsigned char *AICARAM; - UINT32 AICARAM_LENGTH, RAM_MASK, RAM_MASK16; - char Master; - devcb_resolved_write_line IntARMCB; - devcb_resolved_write_line IntSH4CB; - sound_stream * stream; - - INT32 *buffertmpl, *buffertmpr; - - UINT32 IrqTimA; - UINT32 IrqTimBC; - UINT32 IrqMidi; - - UINT8 MidiOutW,MidiOutR; - UINT8 MidiStack[16]; - UINT8 MidiW,MidiR; - - int LPANTABLE[0x20000]; - int RPANTABLE[0x20000]; - - int TimPris[3]; - int TimCnt[3]; - - UINT16 mcieb, mcipd; - - // timers - emu_timer *timerA, *timerB, *timerC; - - // DMA stuff - struct{ - UINT32 dmea; - UINT16 drga; - UINT16 dlg; - UINT8 dgate; - UINT8 ddir; - }dma; - - - int ARTABLE[64], DRTABLE[64]; - - AICADSP DSP; - device_t *device; -}; - -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 stream_sample_t *bufferl; -static stream_sample_t *bufferr; - -static int length; - -static signed short *RBUFDST; //this points to where the sample will be stored in the RingBuf - -INLINE aica_state *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == AICA); - return (aica_state *)downcast(device)->token(); -} - -static unsigned char DecodeSCI(aica_state *AICA, unsigned char irq) +unsigned char aica_device::DecodeSCI(unsigned char irq) { unsigned char SCI=0; unsigned char v; @@ -243,27 +131,27 @@ static unsigned char DecodeSCI(aica_state *AICA, unsigned char irq) return SCI; } -static void ResetInterrupts(aica_state *AICA) +void aica_device::ResetInterrupts() { #if 0 - UINT32 reset = AICA->udata.data[0xa4/2]; + UINT32 reset = m_udata.data[0xa4/2]; if (reset & 0x40) - AICA->IntARMCB(AICA->device, -AICA->IrqTimA); + m_irq_cb(-m_IrqTimA); if (reset & 0x180) - AICA->IntARMCB(AICA->device, -AICA->IrqTimBC); + m_irq_cb(-m_IrqTimBC); #endif } -static void CheckPendingIRQ(aica_state *AICA) +void aica_device::CheckPendingIRQ() { - UINT32 pend=AICA->udata.data[0xa0/2]; - UINT32 en=AICA->udata.data[0x9c/2]; + UINT32 pend=m_udata.data[0xa0/2]; + UINT32 en=m_udata.data[0x9c/2]; - if(AICA->MidiW!=AICA->MidiR) + if(m_MidiW!=m_MidiR) { - AICA->IRQL = AICA->IrqMidi; - AICA->IntARMCB(1); + m_IRQL = m_IrqMidi; + m_irq_cb(1); return; } if(!pend) @@ -271,103 +159,97 @@ static void CheckPendingIRQ(aica_state *AICA) if(pend&0x40) if(en&0x40) { - AICA->IRQL = AICA->IrqTimA; - AICA->IntARMCB(1); + m_IRQL = m_IrqTimA; + m_irq_cb(1); return; } if(pend&0x80) if(en&0x80) { - AICA->IRQL = AICA->IrqTimBC; - AICA->IntARMCB(1); + m_IRQL = m_IrqTimBC; + m_irq_cb(1); return; } if(pend&0x100) if(en&0x100) { - AICA->IRQL = AICA->IrqTimBC; - AICA->IntARMCB(1); + m_IRQL = m_IrqTimBC; + m_irq_cb(1); return; } } -static void CheckPendingIRQ_SH4(aica_state *AICA) +void aica_device::CheckPendingIRQ_SH4() { - if(AICA->mcipd & AICA->mcieb) - AICA->IntSH4CB(1); + if(m_mcipd & m_mcieb) + m_main_irq_cb(1); - if((AICA->mcipd & AICA->mcieb) == 0) - AICA->IntSH4CB(0); + if((m_mcipd & m_mcieb) == 0) + m_main_irq_cb(0); } -static TIMER_CALLBACK( timerA_cb ) +TIMER_CALLBACK_MEMBER( aica_device::timerA_cb ) { - aica_state *AICA = (aica_state *)ptr; + m_TimCnt[0] = 0xFFFF; + m_udata.data[0xa0/2]|=0x40; + m_mcipd |= 0x40; + m_udata.data[0x90/2]&=0xff00; + m_udata.data[0x90/2]|=m_TimCnt[0]>>8; - AICA->TimCnt[0] = 0xFFFF; - AICA->udata.data[0xa0/2]|=0x40; - AICA->mcipd |= 0x40; - AICA->udata.data[0x90/2]&=0xff00; - AICA->udata.data[0x90/2]|=AICA->TimCnt[0]>>8; - - CheckPendingIRQ(AICA); - CheckPendingIRQ_SH4(AICA); + CheckPendingIRQ(); + CheckPendingIRQ_SH4(); } -static TIMER_CALLBACK( timerB_cb ) +TIMER_CALLBACK_MEMBER( aica_device::timerB_cb ) { - aica_state *AICA = (aica_state *)ptr; + m_TimCnt[1] = 0xFFFF; + m_udata.data[0xa0/2]|=0x80; + m_mcipd |= 0x80; + m_udata.data[0x94/2]&=0xff00; + m_udata.data[0x94/2]|=m_TimCnt[1]>>8; - AICA->TimCnt[1] = 0xFFFF; - AICA->udata.data[0xa0/2]|=0x80; - AICA->mcipd |= 0x80; - AICA->udata.data[0x94/2]&=0xff00; - AICA->udata.data[0x94/2]|=AICA->TimCnt[1]>>8; - - CheckPendingIRQ(AICA); - CheckPendingIRQ_SH4(AICA); + CheckPendingIRQ(); + CheckPendingIRQ_SH4(); } -static TIMER_CALLBACK( timerC_cb ) +TIMER_CALLBACK_MEMBER( aica_device::timerC_cb ) { - aica_state *AICA = (aica_state *)ptr; + m_TimCnt[2] = 0xFFFF; + m_udata.data[0xa0/2]|=0x100; + m_mcipd |= 0x100; + m_udata.data[0x98/2]&=0xff00; + m_udata.data[0x98/2]|=m_TimCnt[2]>>8; - AICA->TimCnt[2] = 0xFFFF; - AICA->udata.data[0xa0/2]|=0x100; - AICA->mcipd |= 0x100; - AICA->udata.data[0x98/2]&=0xff00; - AICA->udata.data[0x98/2]|=AICA->TimCnt[2]>>8; - - CheckPendingIRQ(AICA); - CheckPendingIRQ_SH4(AICA); + CheckPendingIRQ(); + CheckPendingIRQ_SH4(); } -static int Get_AR(aica_state *AICA,int base,int R) +int aica_device::Get_AR(int base,int R) { int Rate=base+(R<<1); if(Rate>63) Rate=63; if(Rate<0) Rate=0; - return AICA->ARTABLE[Rate]; + return m_ARTABLE[Rate]; } -static int Get_DR(aica_state *AICA,int base,int R) +int aica_device::Get_DR(int base,int R) { int Rate=base+(R<<1); if(Rate>63) Rate=63; if(Rate<0) Rate=0; - return AICA->DRTABLE[Rate]; + return m_DRTABLE[Rate]; } -static int Get_RR(aica_state *AICA,int base,int R) +int aica_device::Get_RR(int base,int R) { int Rate=base+(R<<1); if(Rate>63) Rate=63; if(Rate<0) Rate=0; - return AICA->DRTABLE[Rate]; + return m_DRTABLE[Rate]; } -static void Compute_EG(aica_state *AICA,SLOT *slot) +void aica_device::Compute_EG(AICA_SLOT *slot) { int octave=(OCT(slot)^8)-8; int rate; @@ -377,40 +259,39 @@ static void Compute_EG(aica_state *AICA,SLOT *slot) rate=0; //rate=((FNS(slot)>>9)&1); slot->EG.volume=0x17f<EG.AR=Get_AR(AICA,rate,AR(slot)); - slot->EG.D1R=Get_DR(AICA,rate,D1R(slot)); - slot->EG.D2R=Get_DR(AICA,rate,D2R(slot)); - slot->EG.RR=Get_RR(AICA,rate,RR(slot)); + slot->EG.AR=Get_AR(rate,AR(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); } -static void AICA_StopSlot(SLOT *slot,int keyoff); - -static int EG_Update(SLOT *slot) +int aica_device::EG_Update(AICA_SLOT *slot) { switch(slot->EG.state) { - case ATTACK: + case AICA_ATTACK: slot->EG.volume+=slot->EG.AR; if(slot->EG.volume>=(0x3ff<EG.D1R) { - slot->EG.state=DECAY1; + slot->EG.state=AICA_DECAY1; if(slot->EG.D1R>=(1024<EG.D2R) //Skip DECAY1, go directly to DECAY2 - slot->EG.state=DECAY2; + slot->EG.state=AICA_DECAY2; } slot->EG.volume=0x3ff<EG.volume-=slot->EG.D1R; if(slot->EG.volume<=0) slot->EG.volume=0; if(slot->EG.volume>>(EG_SHIFT+5)<=slot->EG.DL) - slot->EG.state=DECAY2; + slot->EG.state=AICA_DECAY2; break; - case DECAY2: + case AICA_DECAY2: if(D2R(slot)==0) return (slot->EG.volume>>EG_SHIFT)<<(SHIFT-10); slot->EG.volume-=slot->EG.D2R; @@ -418,14 +299,14 @@ static int EG_Update(SLOT *slot) slot->EG.volume=0; break; - case RELEASE: + case AICA_RELEASE: slot->EG.volume-=slot->EG.RR; if(slot->EG.volume<=0) { slot->EG.volume=0; - AICA_StopSlot(slot,0); + StopSlot(slot,0); // slot->EG.volume=0x17f<EG.state=ATTACK; +// slot->EG.state=AICA_ATTACK; } break; default: @@ -434,7 +315,7 @@ static int EG_Update(SLOT *slot) return (slot->EG.volume>>EG_SHIFT)<<(SHIFT-10); } -static UINT32 AICA_Step(SLOT *slot) +UINT32 aica_device::Step(AICA_SLOT *slot) { int octave=(OCT(slot)^8)-8+SHIFT-10; UINT32 Fn=FNS(slot) + (0x400); @@ -446,7 +327,7 @@ static UINT32 AICA_Step(SLOT *slot) } -static void Compute_LFO(SLOT *slot) +void aica_device::Compute_LFO(AICA_SLOT *slot) { if(PLFOS(slot)!=0) AICALFO_ComputeStep(&(slot->PLFO),LFOF(slot),PLFOWS(slot),PLFOS(slot),0); @@ -460,13 +341,13 @@ static void Compute_LFO(SLOT *slot) static const int TableQuant[8]={ADFIX(0.8984375),ADFIX(0.8984375),ADFIX(0.8984375),ADFIX(0.8984375),ADFIX(1.19921875),ADFIX(1.59765625),ADFIX(2.0),ADFIX(2.3984375)}; static const int quant_mul[16]= { 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}; -static void InitADPCM(int *PrevSignal, int *PrevQuant) +void aica_device::InitADPCM(int *PrevSignal, int *PrevQuant) { *PrevSignal=0; *PrevQuant=0x7f; } -INLINE signed short DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQuant) +signed short aica_device::DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQuant) { int x = *PrevQuant * quant_mul [Delta & 15]; x = *PrevSignal + ((int)(x + ((UINT32)x >> 29)) >> 3); @@ -476,7 +357,7 @@ INLINE signed short DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQ return *PrevSignal; } -static void AICA_StartSlot(aica_state *AICA, SLOT *slot) +void aica_device::StartSlot(AICA_SLOT *slot) { UINT64 start_offset; @@ -484,17 +365,17 @@ static void AICA_StartSlot(aica_state *AICA, SLOT *slot) slot->Backwards=0; slot->cur_addr=0; slot->nxt_addr=1<prv_addr=-1; start_offset = SA(slot); // AICA can play 16-bit samples from any boundry - slot->base=&AICA->AICARAM[start_offset]; - slot->step=AICA_Step(slot); - Compute_EG(AICA,slot); - slot->EG.state=ATTACK; + slot->base=&m_AICARAM[start_offset]; + slot->step=Step(slot); + Compute_EG(slot); + slot->EG.state=AICA_ATTACK; slot->EG.volume=0x17f<= 2) { slot->curstep = 0; - slot->adbase = (unsigned char *) (AICA->AICARAM+((SA(slot))&0x7fffff)); + slot->adbase = (unsigned char *) (m_AICARAM+((SA(slot))&0x7fffff)); InitADPCM(&(slot->cur_sample), &(slot->cur_quant)); InitADPCM(&(slot->cur_lpsample), &(slot->cur_lpquant)); @@ -506,11 +387,11 @@ static void AICA_StartSlot(aica_state *AICA, SLOT *slot) } } -static void AICA_StopSlot(SLOT *slot,int keyoff) +void aica_device::StopSlot(AICA_SLOT *slot,int keyoff) { - if(keyoff /*&& slot->EG.state!=RELEASE*/) + if(keyoff /*&& slot->EG.state!=AICA_RELEASE*/) { - slot->EG.state=RELEASE; + slot->EG.state=AICA_RELEASE; } else { @@ -522,40 +403,37 @@ static void AICA_StopSlot(SLOT *slot,int keyoff) #define log_base_2(n) (log((float) n)/log((float) 2)) -static void AICA_Init(device_t *device, aica_state *AICA, const aica_interface *intf) +void aica_device::Init() { int i; - AICA->device = device; - AICA->IrqTimA = AICA->IrqTimBC = AICA->IrqMidi = 0; - AICA->MidiR=AICA->MidiW=0; - AICA->MidiOutR=AICA->MidiOutW=0; + m_IrqTimA = m_IrqTimBC = m_IrqMidi = 0; + m_MidiR=m_MidiW=0; + m_MidiOutR=m_MidiOutW=0; // get AICA RAM { - AICA->Master = intf->master; - - AICA->AICARAM = *device->region(); - if (AICA->AICARAM) + m_AICARAM = *region(); + if (m_AICARAM) { - AICA->AICARAM += intf->roffset; - AICA->AICARAM_LENGTH = device->region()->bytes(); - AICA->RAM_MASK = AICA->AICARAM_LENGTH-1; - AICA->RAM_MASK16 = AICA->RAM_MASK & 0x7ffffe; - AICA->DSP.AICARAM = (UINT16 *)AICA->AICARAM; - AICA->DSP.AICARAM_LENGTH = AICA->AICARAM_LENGTH/2; + m_AICARAM += m_roffset; + m_AICARAM_LENGTH = region()->bytes(); + m_RAM_MASK = m_AICARAM_LENGTH-1; + m_RAM_MASK16 = m_RAM_MASK & 0x7ffffe; + m_DSP.AICARAM = (UINT16 *)m_AICARAM; + m_DSP.AICARAM_LENGTH = m_AICARAM_LENGTH/2; } } - AICA->timerA = device->machine().scheduler().timer_alloc(FUNC(timerA_cb), AICA); - AICA->timerB = device->machine().scheduler().timer_alloc(FUNC(timerB_cb), AICA); - AICA->timerC = device->machine().scheduler().timer_alloc(FUNC(timerC_cb), AICA); + 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)); + m_timerC = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(aica_device::timerC_cb), this)); for(i=0;i<0x400;++i) { float envDB=((float)(3*(i-0x3ff)))/32.0; float scale=(float)(1<LPANTABLE[i]=FIX((4.0*LPAN*TL*fSDL)); - AICA->RPANTABLE[i]=FIX((4.0*RPAN*TL*fSDL)); + m_LPANTABLE[i]=FIX((4.0*LPAN*TL*fSDL)); + m_RPANTABLE[i]=FIX((4.0*RPAN*TL*fSDL)); } - AICA->ARTABLE[0]=AICA->DRTABLE[0]=0; //Infinite time - AICA->ARTABLE[1]=AICA->DRTABLE[1]=0; //Infinite time + m_ARTABLE[0]=m_DRTABLE[0]=0; //Infinite time + m_ARTABLE[1]=m_DRTABLE[1]=0; //Infinite time for(i=2;i<64;++i) { double t,step,scale; @@ -619,42 +497,42 @@ static void AICA_Init(device_t *device, aica_state *AICA, const aica_interface * { step=(1023*1000.0)/((float) 44100.0f*t); scale=(double) (1<ARTABLE[i]=(int) (step*scale); + m_ARTABLE[i]=(int) (step*scale); } else - AICA->ARTABLE[i]=1024<DRTABLE[i]=(int) (step*scale); + m_DRTABLE[i]=(int) (step*scale); } // make sure all the slots are off for(i=0;i<64;++i) { - AICA->Slots[i].slot=i; - AICA->Slots[i].active=0; - AICA->Slots[i].base=NULL; - AICA->Slots[i].EG.state=RELEASE; - AICA->Slots[i].lpend=1; + m_Slots[i].slot=i; + m_Slots[i].active=0; + m_Slots[i].base=NULL; + m_Slots[i].EG.state=AICA_RELEASE; + m_Slots[i].lpend=1; } - AICALFO_Init(device->machine()); - AICA->buffertmpl=auto_alloc_array_clear(device->machine(), signed int, 44100); - AICA->buffertmpr=auto_alloc_array_clear(device->machine(), signed int, 44100); + AICALFO_Init(); + m_buffertmpl=auto_alloc_array_clear(machine(), signed int, 44100); + m_buffertmpr=auto_alloc_array_clear(machine(), signed int, 44100); // no "pend" - AICA[0].udata.data[0xa0/2] = 0; + m_udata.data[0xa0/2] = 0; //AICA[1].udata.data[0x20/2] = 0; - AICA->TimCnt[0] = 0xffff; - AICA->TimCnt[1] = 0xffff; - AICA->TimCnt[2] = 0xffff; + m_TimCnt[0] = 0xffff; + m_TimCnt[1] = 0xffff; + m_TimCnt[2] = 0xffff; } -static void AICA_UpdateSlotReg(aica_state *AICA,int s,int r) +void aica_device::UpdateSlotReg(int s,int r) { - SLOT *slot=AICA->Slots+s; + AICA_SLOT *slot=m_Slots+s; int sl; switch(r&0x7f) { @@ -664,12 +542,12 @@ static void AICA_UpdateSlotReg(aica_state *AICA,int s,int r) { for(sl=0;sl<64;++sl) { - SLOT *s2=AICA->Slots+sl; + AICA_SLOT *s2=m_Slots+sl; { - if(KEYONB(s2) && s2->EG.state==RELEASE/*&& !s2->active*/) + if(KEYONB(s2) && s2->EG.state==AICA_RELEASE/*&& !s2->active*/) { s2->lpend = 0; - AICA_StartSlot(AICA, s2); + StartSlot(s2); #if 0 printf("StartSlot[%02X]: SSCTL %01X SA %06X LSA %04X LEA %04X PCMS %01X LPCTL %01X\n",sl,SSCTL(s2),SA(s2),LSA(s2),LEA(s2),PCMS(s2),LPCTL(s2)); printf(" AR %02X D1R %02X D2R %02X RR %02X DL %02X KRS %01X LPSLNK %01X\n",AR(s2),D1R(s2),D2R(s2),RR(s2),DL(s2),KRS(s2),LPSLNK(s2)>>14); @@ -682,7 +560,7 @@ static void AICA_UpdateSlotReg(aica_state *AICA,int s,int r) } if(!KEYONB(s2) /*&& s2->active*/) { - AICA_StopSlot(s2,1); + StopSlot(s2,1); } } } @@ -691,11 +569,11 @@ static void AICA_UpdateSlotReg(aica_state *AICA,int s,int r) break; case 0x18: case 0x19: - slot->step=AICA_Step(slot); + slot->step=Step(slot); break; case 0x14: case 0x15: - slot->EG.RR=Get_RR(AICA,0,RR(slot)); + slot->EG.RR=Get_RR(0,RR(slot)); slot->EG.DL=0x1f-DL(slot); break; case 0x1c: @@ -708,33 +586,33 @@ static void AICA_UpdateSlotReg(aica_state *AICA,int s,int r) } } -static void AICA_UpdateReg(aica_state *AICA, address_space &space, int reg) +void aica_device::UpdateReg(address_space &space, int reg) { switch(reg&0xff) { case 0x4: case 0x5: { - unsigned int v=RBL(AICA); - AICA->DSP.RBP=RBP(AICA); + unsigned int v=RBL(); + m_DSP.RBP=RBP(); if(v==0) - AICA->DSP.RBL=8*1024; + m_DSP.RBL=8*1024; else if(v==1) - AICA->DSP.RBL=16*1024; + m_DSP.RBL=16*1024; else if(v==2) - AICA->DSP.RBL=32*1024; + m_DSP.RBL=32*1024; else if(v==3) - AICA->DSP.RBL=64*1024; + m_DSP.RBL=64*1024; } break; case 0x8: case 0x9: - aica_midi_in(AICA->device, space, 0, AICA->udata.data[0x8/2]&0xff, 0xffff); + midi_in(space, 0, m_udata.data[0x8/2]&0xff, 0xffff); break; //case 0x0c: //case 0x0d: - // printf("%04x\n",AICA->udata.data[0xc/2]); + // printf("%04x\n",m_udata.data[0xc/2]); // break; case 0x12: @@ -747,82 +625,82 @@ static void AICA_UpdateReg(aica_state *AICA, address_space &space, int reg) case 0x80: case 0x81: - AICA->dma.dmea = ((AICA->udata.data[0x80/2] & 0xfe00) << 7) | (AICA->dma.dmea & 0xfffc); + m_dma.dmea = ((m_udata.data[0x80/2] & 0xfe00) << 7) | (m_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); + m_dma.dmea = (m_udata.data[0x84/2] & 0xfffc) | (m_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; + m_dma.drga = (m_udata.data[0x88/2] & 0x7ffc); + m_dma.dgate = (m_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(space,AICA); + m_dma.dlg = (m_udata.data[0x8c/2] & 0x7ffc); + m_dma.ddir = (m_udata.data[0x8c/2] & 0x8000) >> 15; + if(m_udata.data[0x8c/2] & 1) // dexe + aica_exec_dma(space); break; case 0x90: case 0x91: - if(AICA->Master) + if(m_master) { UINT32 time; - AICA->TimPris[0]=1<<((AICA->udata.data[0x90/2]>>8)&0x7); - AICA->TimCnt[0]=(AICA->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 ((AICA->udata.data[0x90/2]&0xff) != 255) + if ((m_udata.data[0x90/2]&0xff) != 255) { - time = (44100 / AICA->TimPris[0]) / (255-(AICA->udata.data[0x90/2]&0xff)); + time = (44100 / m_TimPris[0]) / (255-(m_udata.data[0x90/2]&0xff)); if (time) { - AICA->timerA->adjust(attotime::from_hz(time)); + m_timerA->adjust(attotime::from_hz(time)); } } } break; case 0x94: case 0x95: - if(AICA->Master) + if(m_master) { UINT32 time; - AICA->TimPris[1]=1<<((AICA->udata.data[0x94/2]>>8)&0x7); - AICA->TimCnt[1]=(AICA->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 ((AICA->udata.data[0x94/2]&0xff) != 255) + if ((m_udata.data[0x94/2]&0xff) != 255) { - time = (44100 / AICA->TimPris[1]) / (255-(AICA->udata.data[0x94/2]&0xff)); + time = (44100 / m_TimPris[1]) / (255-(m_udata.data[0x94/2]&0xff)); if (time) { - AICA->timerB->adjust(attotime::from_hz(time)); + m_timerB->adjust(attotime::from_hz(time)); } } } break; case 0x98: case 0x99: - if(AICA->Master) + if(m_master) { UINT32 time; - AICA->TimPris[2]=1<<((AICA->udata.data[0x98/2]>>8)&0x7); - AICA->TimCnt[2]=(AICA->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 ((AICA->udata.data[0x98/2]&0xff) != 255) + if ((m_udata.data[0x98/2]&0xff) != 255) { - time = (44100 / AICA->TimPris[2]) / (255-(AICA->udata.data[0x98/2]&0xff)); + time = (44100 / m_TimPris[2]) / (255-(m_udata.data[0x98/2]&0xff)); if (time) { - AICA->timerC->adjust(attotime::from_hz(time)); + m_timerC->adjust(attotime::from_hz(time)); } } } @@ -830,31 +708,31 @@ static void AICA_UpdateReg(aica_state *AICA, address_space &space, int reg) case 0x9c: //SCIEB case 0x9d: - if(AICA->udata.data[0x9c/2] & 0x631) - popmessage("AICA: SCIEB enabled %04x, contact MAME/MESSdev",AICA->udata.data[0x9c/2]); + if(m_udata.data[0x9c/2] & 0x631) + popmessage("AICA: SCIEB enabled %04x, contact MAME/MESSdev",m_udata.data[0x9c/2]); break; case 0xa4: //SCIRE case 0xa5: - if(AICA->Master) + if(m_master) { - AICA->udata.data[0xa0/2] &= ~AICA->udata.data[0xa4/2]; - ResetInterrupts(AICA); + 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 (AICA->TimCnt[0] >= 0xff00) + if (m_TimCnt[0] >= 0xff00) { - AICA->udata.data[0xa0/2] |= 0x40; + m_udata.data[0xa0/2] |= 0x40; } - if (AICA->TimCnt[1] >= 0xff00) + if (m_TimCnt[1] >= 0xff00) { - AICA->udata.data[0xa0/2] |= 0x80; + m_udata.data[0xa0/2] |= 0x80; } - if (AICA->TimCnt[2] >= 0xff00) + if (m_TimCnt[2] >= 0xff00) { - AICA->udata.data[0xa0/2] |= 0x100; + m_udata.data[0xa0/2] |= 0x100; } } break; @@ -864,68 +742,68 @@ static void AICA_UpdateReg(aica_state *AICA, address_space &space, int reg) case 0xad: case 0xb0: case 0xb1: - if(AICA->Master) + if(m_master) { - AICA->IrqTimA=DecodeSCI(AICA,SCITMA); - AICA->IrqTimBC=DecodeSCI(AICA,SCITMB); - AICA->IrqMidi=DecodeSCI(AICA,SCIMID); + m_IrqTimA=DecodeSCI(SCITMA); + m_IrqTimBC=DecodeSCI(SCITMB); + m_IrqMidi=DecodeSCI(SCIMID); } break; case 0xb4: //MCIEB case 0xb5: - if(AICA->udata.data[0xb4/2] & 0x7df) - popmessage("AICA: MCIEB enabled %04x, contact MAME/MESSdev",AICA->udata.data[0xb4/2]); - AICA->mcieb = AICA->udata.data[0xb4/2]; - CheckPendingIRQ_SH4(AICA); + if(m_udata.data[0xb4/2] & 0x7df) + popmessage("AICA: MCIEB enabled %04x, contact MAME/MESSdev",m_udata.data[0xb4/2]); + m_mcieb = m_udata.data[0xb4/2]; + CheckPendingIRQ_SH4(); break; case 0xb8: case 0xb9: - if(AICA->udata.data[0xb8/2] & 0x20) - AICA->mcipd |= 0x20; - CheckPendingIRQ_SH4(AICA); + if(m_udata.data[0xb8/2] & 0x20) + m_mcipd |= 0x20; + CheckPendingIRQ_SH4(); break; case 0xbc: case 0xbd: - AICA->mcipd &= ~AICA->udata.data[0xbc/2]; - CheckPendingIRQ_SH4(AICA); + m_mcipd &= ~m_udata.data[0xbc/2]; + CheckPendingIRQ_SH4(); break; } } -static void AICA_UpdateSlotRegR(aica_state *AICA, int slot,int reg) +void aica_device::UpdateSlotRegR(int slot,int reg) { } -static void AICA_UpdateRegR(aica_state *AICA, address_space &space, int reg) +void aica_device::UpdateRegR(address_space &space, int reg) { switch(reg&0xff) { case 8: case 9: { - unsigned short v=AICA->udata.data[0x8/2]; + unsigned short v=m_udata.data[0x8/2]; v&=0xff00; - v|=AICA->MidiStack[AICA->MidiR]; - AICA->IntARMCB(0); // cancel the IRQ - if(AICA->MidiR!=AICA->MidiW) + v|=m_MidiStack[m_MidiR]; + m_irq_cb(0); // cancel the IRQ + if(m_MidiR!=m_MidiW) { - ++AICA->MidiR; - AICA->MidiR&=15; + ++m_MidiR; + m_MidiR&=15; } - AICA->udata.data[0x8/2]=v; + m_udata.data[0x8/2]=v; } break; case 0x10: // LP check case 0x11: { - int slotnum = MSLC(AICA); - SLOT *slot=AICA->Slots + slotnum; + int slotnum = MSLC(); + AICA_SLOT *slot=m_Slots + slotnum; UINT16 LP = 0; - if (!(AFSEL(AICA))) + if (!(AFSEL())) { UINT16 SGC; int EG; @@ -938,12 +816,12 @@ static void AICA_UpdateRegR(aica_state *AICA, address_space &space, int reg) EG = 0x1FFF - EG; if (EG < 0) EG = 0; - AICA->udata.data[0x10/2] = (EG & 0x1FF8) | SGC | LP; + m_udata.data[0x10/2] = (EG & 0x1FF8) | SGC | LP; } else { LP = slot->lpend ? 0x8000 : 0x0000; - AICA->udata.data[0x10/2] = LP; + m_udata.data[0x10/2] = LP; } } break; @@ -951,33 +829,33 @@ static void AICA_UpdateRegR(aica_state *AICA, address_space &space, int reg) case 0x14: // CA (slot address) case 0x15: { - //AICA->stream->update(); - int slotnum = MSLC(AICA); - SLOT *slot=AICA->Slots+slotnum; + //m_stream->update(); + int slotnum = MSLC(); + AICA_SLOT *slot=m_Slots+slotnum; unsigned int CA = 0; if (PCMS(slot) == 0) // 16-bit samples { - CA = (slot->cur_addr>>(SHIFT-1))&AICA->RAM_MASK16; + CA = (slot->cur_addr>>(SHIFT-1))&m_RAM_MASK16; } else // 8-bit PCM and 4-bit ADPCM { - CA = (slot->cur_addr>>SHIFT)&AICA->RAM_MASK; + CA = (slot->cur_addr>>SHIFT)&m_RAM_MASK; } - //printf("%08x %08x\n",CA,slot->cur_addr&AICA->RAM_MASK16); + //printf("%08x %08x\n",CA,slot->cur_addr&m_RAM_MASK16); - AICA->udata.data[0x14/2] = CA; + m_udata.data[0x14/2] = CA; } break; case 0xb8: case 0xb9: - AICA->udata.data[0xb8/2] = AICA->mcipd; + m_udata.data[0xb8/2] = m_mcipd; break; } } -static void AICA_w16(aica_state *AICA,address_space &space,unsigned int addr,unsigned short val) +void aica_device::w16(address_space &space,unsigned int addr,unsigned short val) { addr&=0xffff; if(addr<0x2000) @@ -985,15 +863,15 @@ static void AICA_w16(aica_state *AICA,address_space &space,unsigned int addr,uns int slot=addr/0x80; addr&=0x7f; // printf("%x to slot %d offset %x\n", val, slot, addr); - *((unsigned short *) (AICA->Slots[slot].udata.datab+(addr))) = val; - AICA_UpdateSlotReg(AICA,slot,addr&0x7f); + *((unsigned short *) (m_Slots[slot].udata.datab+(addr))) = val; + UpdateSlotReg(slot,addr&0x7f); } else if (addr < 0x2800) { if (addr <= 0x2044) { // printf("%x to EFSxx slot %d (addr %x)\n", val, (addr-0x2000)/4, addr&0x7f); - AICA->EFSPAN[addr&0x7f] = val; + m_EFSPAN[addr&0x7f] = val; } } else if(addr<0x3000) @@ -1001,22 +879,22 @@ static void AICA_w16(aica_state *AICA,address_space &space,unsigned int addr,uns if (addr < 0x28be) { // printf("%x to AICA global @ %x\n", val, addr & 0xff); - *((unsigned short *) (AICA->udata.datab+((addr&0xff)))) = val; - AICA_UpdateReg(AICA, space, addr&0xff); + *((unsigned short *) (m_udata.datab+((addr&0xff)))) = val; + UpdateReg(space, addr&0xff); } else if (addr == 0x2d00) { - AICA->IRQL = val; + m_IRQL = val; popmessage("AICA: write to IRQL?"); } else if (addr == 0x2d04) { - AICA->IRQR = val; + m_IRQR = val; if (val & 1) { - AICA->IntARMCB(0); + m_irq_cb(0); } if (val & 0x100) popmessage("AICA: SH-4 write protection enabled!"); @@ -1029,16 +907,16 @@ static void AICA_w16(aica_state *AICA,address_space &space,unsigned int addr,uns { //DSP if(addr<0x3200) //COEF - *((unsigned short *) (AICA->DSP.COEF+(addr-0x3000)/2))=val; + *((unsigned short *) (m_DSP.COEF+(addr-0x3000)/2))=val; else if(addr<0x3400) - *((unsigned short *) (AICA->DSP.MADRS+(addr-0x3200)/2))=val; + *((unsigned short *) (m_DSP.MADRS+(addr-0x3200)/2))=val; else if(addr<0x3c00) { - *((unsigned short *) (AICA->DSP.MPRO+(addr-0x3400)/2))=val; + *((unsigned short *) (m_DSP.MPRO+(addr-0x3400)/2))=val; if (addr == 0x3bfe) { - aica_dsp_start(&AICA->DSP); + aica_dsp_start(&m_DSP); } } else if(addr<0x4000) @@ -1048,32 +926,32 @@ static void AICA_w16(aica_state *AICA,address_space &space,unsigned int addr,uns else if(addr<0x4400) { if(addr & 4) - AICA->DSP.TEMP[(addr >> 3) & 0x7f] = (AICA->DSP.TEMP[(addr >> 3) & 0x7f] & 0xffff0000) | (val & 0xffff); + m_DSP.TEMP[(addr >> 3) & 0x7f] = (m_DSP.TEMP[(addr >> 3) & 0x7f] & 0xffff0000) | (val & 0xffff); else - AICA->DSP.TEMP[(addr >> 3) & 0x7f] = (AICA->DSP.TEMP[(addr >> 3) & 0x7f] & 0xffff) | (val << 16); + m_DSP.TEMP[(addr >> 3) & 0x7f] = (m_DSP.TEMP[(addr >> 3) & 0x7f] & 0xffff) | (val << 16); } else if(addr<0x4500) { if(addr & 4) - AICA->DSP.MEMS[(addr >> 3) & 0x1f] = (AICA->DSP.MEMS[(addr >> 3) & 0x1f] & 0xffff0000) | (val & 0xffff); + m_DSP.MEMS[(addr >> 3) & 0x1f] = (m_DSP.MEMS[(addr >> 3) & 0x1f] & 0xffff0000) | (val & 0xffff); else - AICA->DSP.MEMS[(addr >> 3) & 0x1f] = (AICA->DSP.MEMS[(addr >> 3) & 0x1f] & 0xffff) | (val << 16); + m_DSP.MEMS[(addr >> 3) & 0x1f] = (m_DSP.MEMS[(addr >> 3) & 0x1f] & 0xffff) | (val << 16); } else if(addr<0x4580) { if(addr & 4) - AICA->DSP.MIXS[(addr >> 3) & 0xf] = (AICA->DSP.MIXS[(addr >> 3) & 0xf] & 0xffff0000) | (val & 0xffff); + m_DSP.MIXS[(addr >> 3) & 0xf] = (m_DSP.MIXS[(addr >> 3) & 0xf] & 0xffff0000) | (val & 0xffff); else - AICA->DSP.MIXS[(addr >> 3) & 0xf] = (AICA->DSP.MIXS[(addr >> 3) & 0xf] & 0xffff) | (val << 16); + m_DSP.MIXS[(addr >> 3) & 0xf] = (m_DSP.MIXS[(addr >> 3) & 0xf] & 0xffff) | (val << 16); } else if(addr<0x45c0) - *((unsigned short *) (AICA->DSP.EFREG+(addr-0x4580)/4))=val; + *((unsigned short *) (m_DSP.EFREG+(addr-0x4580)/4))=val; else if(addr<0x45c8) - *((unsigned short *) (AICA->DSP.EXTS+(addr-0x45c0)/2))=val; + *((unsigned short *) (m_DSP.EXTS+(addr-0x45c0)/2))=val; } } -static unsigned short AICA_r16(aica_state *AICA, address_space &space, unsigned int addr) +unsigned short aica_device::r16(address_space &space, unsigned int addr) { unsigned short v=0; addr&=0xffff; @@ -1081,39 +959,39 @@ static unsigned short AICA_r16(aica_state *AICA, address_space &space, unsigned { int slot=addr/0x80; addr&=0x7f; - AICA_UpdateSlotRegR(AICA, slot,addr&0x7f); - v=*((unsigned short *) (AICA->Slots[slot].udata.datab+(addr))); + UpdateSlotRegR(slot,addr&0x7f); + v=*((unsigned short *) (m_Slots[slot].udata.datab+(addr))); } else if(addr<0x3000) { if (addr <= 0x2044) { - v = AICA->EFSPAN[addr&0x7f]; + v = m_EFSPAN[addr&0x7f]; } else if (addr < 0x28be) { - AICA_UpdateRegR(AICA, space, addr&0xff); - v= *((unsigned short *) (AICA->udata.datab+((addr&0xff)))); - if((addr&0xfffe)==0x2810) AICA->udata.data[0x10/2] &= 0x7FFF; // reset LP on read + 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 } else if (addr == 0x2d00) { - return AICA->IRQL; + return m_IRQL; } else if (addr == 0x2d04) { //popmessage("AICA: read to IRQR?"); - return AICA->IRQR; + return m_IRQR; } } else { if(addr<0x3200) //COEF - v= *((unsigned short *) (AICA->DSP.COEF+(addr-0x3000)/2)); + v= *((unsigned short *) (m_DSP.COEF+(addr-0x3000)/2)); else if(addr<0x3400) - v= *((unsigned short *) (AICA->DSP.MADRS+(addr-0x3200)/2)); + v= *((unsigned short *) (m_DSP.MADRS+(addr-0x3200)/2)); else if(addr<0x3c00) - v= *((unsigned short *) (AICA->DSP.MPRO+(addr-0x3400)/2)); + v= *((unsigned short *) (m_DSP.MPRO+(addr-0x3400)/2)); else if(addr<0x4000) { v= 0xffff; @@ -1122,31 +1000,31 @@ static unsigned short AICA_r16(aica_state *AICA, address_space &space, unsigned else if(addr<0x4400) { if(addr & 4) - v= AICA->DSP.TEMP[(addr >> 3) & 0x7f] & 0xffff; + v= m_DSP.TEMP[(addr >> 3) & 0x7f] & 0xffff; else - v= AICA->DSP.TEMP[(addr >> 3) & 0x7f] >> 16; + v= m_DSP.TEMP[(addr >> 3) & 0x7f] >> 16; } else if(addr<0x4500) { if(addr & 4) - v= AICA->DSP.MEMS[(addr >> 3) & 0x1f] & 0xffff; + v= m_DSP.MEMS[(addr >> 3) & 0x1f] & 0xffff; else - v= AICA->DSP.MEMS[(addr >> 3) & 0x1f] >> 16; + v= m_DSP.MEMS[(addr >> 3) & 0x1f] >> 16; } else if(addr<0x4580) { if(addr & 4) - v= AICA->DSP.MIXS[(addr >> 3) & 0xf] & 0xffff; + v= m_DSP.MIXS[(addr >> 3) & 0xf] & 0xffff; else - v= AICA->DSP.MIXS[(addr >> 3) & 0xf] >> 16; + v= m_DSP.MIXS[(addr >> 3) & 0xf] >> 16; } else if(addr<0x45c0) - v = *((unsigned short *) (AICA->DSP.EFREG+(addr-0x4580)/4)); + v = *((unsigned short *) (m_DSP.EFREG+(addr-0x4580)/4)); else if(addr<0x45c8) - v = *((unsigned short *) (AICA->DSP.EXTS+(addr-0x45c0)/2)); + v = *((unsigned short *) (m_DSP.EXTS+(addr-0x45c0)/2)); } // else if (addr<0x700) -// v=AICA->RINGBUF[(addr-0x600)/2]; +// v=m_RINGBUF[(addr-0x600)/2]; return v; } @@ -1154,47 +1032,47 @@ static unsigned short AICA_r16(aica_state *AICA, address_space &space, unsigned #define REVSIGN(v) ((~v)+1) #ifdef UNUSED_FUNCTION -static void AICA_TimersAddTicks(aica_state *AICA, int ticks) +void aica_device::TimersAddTicks(int ticks) { - if(AICA->TimCnt[0]<=0xff00) + if(m_TimCnt[0]<=0xff00) { - AICA->TimCnt[0] += ticks << (8-((AICA->udata.data[0x18/2]>>8)&0x7)); - if (AICA->TimCnt[0] > 0xFF00) + m_TimCnt[0] += ticks << (8-((m_udata.data[0x18/2]>>8)&0x7)); + if (m_TimCnt[0] > 0xFF00) { - AICA->TimCnt[0] = 0xFFFF; - AICA->udata.data[0xa0/2]|=0x40; + m_TimCnt[0] = 0xFFFF; + m_udata.data[0xa0/2]|=0x40; } - AICA->udata.data[0x90/2]&=0xff00; - AICA->udata.data[0x90/2]|=AICA->TimCnt[0]>>8; + m_udata.data[0x90/2]&=0xff00; + m_udata.data[0x90/2]|=m_TimCnt[0]>>8; } - if(AICA->TimCnt[1]<=0xff00) + if(m_TimCnt[1]<=0xff00) { - AICA->TimCnt[1] += ticks << (8-((AICA->udata.data[0x1a/2]>>8)&0x7)); - if (AICA->TimCnt[1] > 0xFF00) + m_TimCnt[1] += ticks << (8-((m_udata.data[0x1a/2]>>8)&0x7)); + if (m_TimCnt[1] > 0xFF00) { - AICA->TimCnt[1] = 0xFFFF; - AICA->udata.data[0xa0/2]|=0x80; + m_TimCnt[1] = 0xFFFF; + m_udata.data[0xa0/2]|=0x80; } - AICA->udata.data[0x94/2]&=0xff00; - AICA->udata.data[0x94/2]|=AICA->TimCnt[1]>>8; + m_udata.data[0x94/2]&=0xff00; + m_udata.data[0x94/2]|=m_TimCnt[1]>>8; } - if(AICA->TimCnt[2]<=0xff00) + if(m_TimCnt[2]<=0xff00) { - AICA->TimCnt[2] += ticks << (8-((AICA->udata.data[0x1c/2]>>8)&0x7)); - if (AICA->TimCnt[2] > 0xFF00) + m_TimCnt[2] += ticks << (8-((m_udata.data[0x1c/2]>>8)&0x7)); + if (m_TimCnt[2] > 0xFF00) { - AICA->TimCnt[2] = 0xFFFF; - AICA->udata.data[0xa0/2]|=0x100; + m_TimCnt[2] = 0xFFFF; + m_udata.data[0xa0/2]|=0x100; } - AICA->udata.data[0x98/2]&=0xff00; - AICA->udata.data[0x98/2]|=AICA->TimCnt[2]>>8; + m_udata.data[0x98/2]&=0xff00; + m_udata.data[0x98/2]|=m_TimCnt[2]>>8; } } #endif -INLINE INT32 AICA_UpdateSlot(aica_state *AICA, SLOT *slot) +INT32 aica_device::UpdateSlot(AICA_SLOT *slot) { INT32 sample; int step=slot->step; @@ -1218,8 +1096,8 @@ INLINE INT32 AICA_UpdateSlot(aica_state *AICA, SLOT *slot) } else if(PCMS(slot) == 0) { - addr1=(slot->cur_addr>>(SHIFT-1))&AICA->RAM_MASK16; - addr2=(slot->nxt_addr>>(SHIFT-1))&AICA->RAM_MASK16; + addr1=(slot->cur_addr>>(SHIFT-1))&m_RAM_MASK16; + addr2=(slot->nxt_addr>>(SHIFT-1))&m_RAM_MASK16; } else { @@ -1229,8 +1107,8 @@ INLINE INT32 AICA_UpdateSlot(aica_state *AICA, SLOT *slot) if(PCMS(slot) == 1) // 8-bit signed { - INT8 *p1=(signed char *) (AICA->AICARAM+(((SA(slot)+addr1))&AICA->RAM_MASK)); - INT8 *p2=(signed char *) (AICA->AICARAM+(((SA(slot)+addr2))&AICA->RAM_MASK)); + INT8 *p1=(signed char *) (m_AICARAM+(((SA(slot)+addr1))&m_RAM_MASK)); + INT8 *p2=(signed char *) (m_AICARAM+(((SA(slot)+addr2))&m_RAM_MASK)); INT32 s; INT32 fpart=slot->cur_addr&((1<AICARAM+((SA(slot)+addr1)&AICA->RAM_MASK)); - UINT8 *p2=(UINT8 *) (AICA->AICARAM+((SA(slot)+addr2)&AICA->RAM_MASK)); + UINT8 *p1=(UINT8 *) (m_AICARAM+((SA(slot)+addr1)&m_RAM_MASK)); + UINT8 *p2=(UINT8 *) (m_AICARAM+((SA(slot)+addr2)&m_RAM_MASK)); INT32 s; INT32 fpart=slot->cur_addr&((1<=LSA(slot)) { - if(LPSLNK(slot) && slot->EG.state==ATTACK && slot->EG.D1R) - slot->EG.state = DECAY1; + if(LPSLNK(slot) && slot->EG.state==AICA_ATTACK && slot->EG.D1R) + slot->EG.state = AICA_DECAY1; } for (addr_select=0; addr_select<2; addr_select++) @@ -1310,7 +1188,7 @@ INLINE INT32 AICA_UpdateSlot(aica_state *AICA, SLOT *slot) case 0: //no loop if(*addr[addr_select]>=LSA(slot) && *addr[addr_select]>=LEA(slot)) { - AICA_StopSlot(slot,0); + StopSlot(slot,0); } break; case 1: //normal loop @@ -1323,7 +1201,7 @@ INLINE INT32 AICA_UpdateSlot(aica_state *AICA, SLOT *slot) if(PCMS(slot)>=2) { // restore the state @ LSA - the sampler will naturally walk to (LSA + remainder) - slot->adbase = &AICA->AICARAM[SA(slot)+(LSA(slot)/2)]; + slot->adbase = &m_AICARAM[SA(slot)+(LSA(slot)/2)]; slot->curstep = LSA(slot); if (PCMS(slot) == 2) { @@ -1344,21 +1222,21 @@ INLINE INT32 AICA_UpdateSlot(aica_state *AICA, SLOT *slot) sample>>=SHIFT; } - if(slot->EG.state==ATTACK) + if(slot->EG.state==AICA_ATTACK) sample=(sample*EG_Update(slot))>>SHIFT; else - sample=(sample*EG_TABLE[EG_Update(slot)>>(SHIFT-10)])>>SHIFT; + sample=(sample*m_EG_TABLE[EG_Update(slot)>>(SHIFT-10)])>>SHIFT; return sample; } -static void AICA_DoMasterSamples(aica_state *AICA, int nsamples) +void aica_device::DoMasterSamples(int nsamples) { stream_sample_t *bufr,*bufl; int sl, s, i; - bufr=bufferr; - bufl=bufferl; + bufr=m_bufferr; + bufl=m_bufferl; for(s=0;sSlots+sl; - RBUFDST=AICA->RINGBUF+AICA->BUFPTR; - if(AICA->Slots[sl].active) + AICA_SLOT *slot=m_Slots+sl; + m_RBUFDST=m_RINGBUF+m_BUFPTR; + if(m_Slots[sl].active) { unsigned int Enc; signed int sample; - sample=AICA_UpdateSlot(AICA, slot); + sample=UpdateSlot(slot); Enc=((TL(slot))<<0x0)|((IMXL(slot))<<0xd); - aica_dsp_setsample(&AICA->DSP,(sample*AICA->LPANTABLE[Enc])>>(SHIFT-2),ISEL(slot),IMXL(slot)); + aica_dsp_setsample(&m_DSP,(sample*m_LPANTABLE[Enc])>>(SHIFT-2),ISEL(slot),IMXL(slot)); Enc=((TL(slot))<<0x0)|((DIPAN(slot))<<0x8)|((DISDL(slot))<<0xd); { - smpl+=(sample*AICA->LPANTABLE[Enc])>>SHIFT; - smpr+=(sample*AICA->RPANTABLE[Enc])>>SHIFT; + smpl+=(sample*m_LPANTABLE[Enc])>>SHIFT; + smpr+=(sample*m_RPANTABLE[Enc])>>SHIFT; } } - AICA->BUFPTR&=63; + m_BUFPTR&=63; } // process the DSP - aica_dsp_step(&AICA->DSP); + aica_dsp_step(&m_DSP); // mix DSP output for(i=0;i<16;++i) @@ -1399,8 +1277,8 @@ static void AICA_DoMasterSamples(aica_state *AICA, int nsamples) if(EFSDL(i)) { unsigned int Enc=((EFPAN(i))<<0x8)|((EFSDL(i))<<0xd); - smpl+=(AICA->DSP.EFREG[i]*AICA->LPANTABLE[Enc])>>SHIFT; - smpr+=(AICA->DSP.EFREG[i]*AICA->RPANTABLE[Enc])>>SHIFT; + smpl+=(m_DSP.EFREG[i]*m_LPANTABLE[Enc])>>SHIFT; + smpr+=(m_DSP.EFREG[i]*m_RPANTABLE[Enc])>>SHIFT; } } @@ -1410,209 +1288,105 @@ static void AICA_DoMasterSamples(aica_state *AICA, int nsamples) } /* TODO: this needs to be timer-ized */ -static void aica_exec_dma(address_space &space, aica_state *aica) +void aica_device::aica_exec_dma(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); + "DGATE: %d DDIR: %d\n",m_dma.dmea,m_dma.drga,m_dma.dlg,m_dma.dgate,m_dma.ddir); /* Copy the dma values in a temp storage for resuming later */ /* (DMA *can't* overwrite its parameters). */ - if(!(aica->dma.ddir)) + if(!(m_dma.ddir)) { for(i=0;i<4;i++) - tmp_dma[i] = aica->udata.data[(0x80+(i*4))/2]; + tmp_dma[i] = m_udata.data[(0x80+(i*4))/2]; } /* note: we don't use space.read_word / write_word because it can happen that SH-4 enables the DMA instead of ARM like in DCLP tester. */ /* TODO: don't know if params auto-updates, I guess not ... */ - if(aica->dma.ddir) + if(m_dma.ddir) { - if(aica->dma.dgate) + if(m_dma.dgate) { - for(i=0;i < aica->dma.dlg;i+=2) + for(i=0;i < m_dma.dlg;i+=2) { - aica->AICARAM[aica->dma.dmea] = 0; - aica->AICARAM[aica->dma.dmea+1] = 0; - aica->dma.dmea+=2; + m_AICARAM[m_dma.dmea] = 0; + m_AICARAM[m_dma.dmea+1] = 0; + m_dma.dmea+=2; } } else { - for(i=0;i < aica->dma.dlg;i+=2) + for(i=0;i < m_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; + 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; + m_dma.drga+=4; } } } else { - if(aica->dma.dgate) + if(m_dma.dgate) { - for(i=0;i < aica->dma.dlg;i+=2) + for(i=0;i < m_dma.dlg;i+=2) { - AICA_w16(aica, space, aica->dma.drga, 0); - aica->dma.drga+=4; + w16(space, m_dma.drga, 0); + m_dma.drga+=4; } } else { - for(i=0;i < aica->dma.dlg;i+=2) + for(i=0;i < m_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; + tmp = m_AICARAM[m_dma.dmea]; + tmp|= m_AICARAM[m_dma.dmea+1]<<8; + w16(space, m_dma.drga, tmp); + m_dma.dmea+=4; + m_dma.drga+=4; } } } /*Resume the values*/ - if(!(aica->dma.ddir)) + if(!(m_dma.ddir)) { for(i=0;i<4;i++) - aica->udata.data[(0x80+(i*4))/2] = tmp_dma[i]; + m_udata.data[(0x80+(i*4))/2] = tmp_dma[i]; } /* Job done, clear DEXE */ - aica->udata.data[0x8c/2] &= ~1; + m_udata.data[0x8c/2] &= ~1; /* request a dma end irq */ - aica->mcipd |= 0x10; - CheckPendingIRQ_SH4(aica); + m_mcipd |= 0x10; + CheckPendingIRQ_SH4(); } #ifdef UNUSED_FUNCTION -static int AICA_IRQCB(void *param) +int aica_device::IRQCB(void *param) { CheckPendingIRQ(param); return -1; } #endif -static STREAM_UPDATE( AICA_Update ) -{ - aica_state *AICA = (aica_state *)param; - bufferl = outputs[0]; - bufferr = outputs[1]; - length = samples; - AICA_DoMasterSamples(AICA, samples); -} - -static DEVICE_START( aica ) -{ - const aica_interface *intf; - - aica_state *AICA = get_safe_token(device); - - intf = (const aica_interface *)device->static_config(); - - // init the emulation - AICA_Init(device, AICA, intf); - - // set up the IRQ callbacks - { - AICA->IntARMCB.resolve(intf->irq_callback,*device); - AICA->IntSH4CB.resolve(intf->master_irq_callback,*device); - - AICA->stream = device->machine().sound().stream_alloc(*device, 0, 2, 44100, AICA, AICA_Update); - } - - // save state - { - device->save_item(NAME(AICA->IrqTimA)); - device->save_item(NAME(AICA->IrqTimBC)); - device->save_item(NAME(AICA->IrqMidi)); - device->save_item(NAME(AICA->MidiOutW)); - device->save_item(NAME(AICA->MidiOutR)); - device->save_item(NAME(AICA->MidiStack),16); - device->save_item(NAME(AICA->MidiW)); - device->save_item(NAME(AICA->MidiR)); - device->save_item(NAME(AICA->LPANTABLE),0x20000); - device->save_item(NAME(AICA->RPANTABLE),0x20000); - device->save_item(NAME(AICA->TimPris),3); - device->save_item(NAME(AICA->TimCnt),3); - } -} - -void aica_set_ram_base(device_t *device, void *base, int size) -{ - aica_state *AICA = get_safe_token(device); - if (AICA) - { - AICA->AICARAM = (unsigned char *)base; - AICA->AICARAM_LENGTH = size; - AICA->RAM_MASK = AICA->AICARAM_LENGTH-1; - AICA->RAM_MASK16 = AICA->RAM_MASK & 0x7ffffe; - AICA->DSP.AICARAM = (UINT16 *)base; - AICA->DSP.AICARAM_LENGTH = size; - } -} - -READ16_DEVICE_HANDLER( aica_r ) -{ - aica_state *AICA = get_safe_token(device); - return AICA_r16(AICA, space,offset*2); -} - -WRITE16_DEVICE_HANDLER( aica_w ) -{ - aica_state *AICA = get_safe_token(device); - UINT16 tmp; - - tmp = AICA_r16(AICA, space, offset*2); - COMBINE_DATA(&tmp); - AICA_w16(AICA, space, offset*2, tmp); -} - -WRITE16_DEVICE_HANDLER( aica_midi_in ) -{ - aica_state *AICA = get_safe_token(device); - AICA->MidiStack[AICA->MidiW++]=data; - AICA->MidiW &= 15; -} - -READ16_DEVICE_HANDLER( aica_midi_out_r ) -{ - aica_state *AICA = get_safe_token(device); - unsigned char val; - - val=AICA->MidiStack[AICA->MidiR++]; - AICA->MidiR&=7; - return val; -} - -const device_type AICA = &device_creator; - -aica_device::aica_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, AICA, "AICA", tag, owner, clock, "aica", __FILE__), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(aica_state); -} - -aica_device::~aica_device() -{ - global_free(m_token); -} - //------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete +// sound_stream_update - handle a stream update //------------------------------------------------- -void aica_device::device_config_complete() +void aica_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { + m_bufferl = outputs[0]; + m_bufferr = outputs[1]; + m_length = samples; + DoMasterSamples(samples); } //------------------------------------------------- @@ -1621,23 +1395,262 @@ void aica_device::device_config_complete() void aica_device::device_start() { - DEVICE_START_NAME( aica )(this); + // 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, 44100); + + // save state + save_item(NAME(m_IrqTimA)); + save_item(NAME(m_IrqTimBC)); + save_item(NAME(m_IrqMidi)); + save_item(NAME(m_MidiOutW)); + save_item(NAME(m_MidiOutR)); + save_item(NAME(m_MidiStack),16); + save_item(NAME(m_MidiW)); + save_item(NAME(m_MidiR)); + save_item(NAME(m_LPANTABLE),0x20000); + save_item(NAME(m_RPANTABLE),0x20000); + save_item(NAME(m_TimPris),3); + save_item(NAME(m_TimCnt),3); } -//------------------------------------------------- -// device_stop - device-specific stop -//------------------------------------------------- - -void aica_device::device_stop() +void aica_device::set_ram_base(void *base, int size) { + 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 *)base; + m_DSP.AICARAM_LENGTH = size; } -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void aica_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +READ16_MEMBER( aica_device::read ) { - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); + return r16(space,offset*2); +} + +WRITE16_MEMBER( aica_device::write ) +{ + UINT16 tmp; + + tmp = r16(space, offset*2); + COMBINE_DATA(&tmp); + w16(space, offset*2, tmp); +} + +WRITE16_MEMBER( aica_device::midi_in ) +{ + m_MidiStack[m_MidiW++]=data; + m_MidiW &= 15; +} + +READ16_MEMBER( aica_device::midi_out_r ) +{ + unsigned char val; + + val=m_MidiStack[m_MidiR++]; + m_MidiR&=7; + return val; +} + +const device_type AICA = &device_creator; + +aica_device::aica_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, AICA, "AICA", tag, owner, clock, "aica", __FILE__), + device_sound_interface(mconfig, *this), + m_master(false), + m_roffset(0), + m_irq_cb(*this), + m_main_irq_cb(*this), + m_IRQL(0), + m_IRQR(0), + m_BUFPTR(0), + m_AICARAM(NULL), + m_AICARAM_LENGTH(0), + m_RAM_MASK(0), + m_RAM_MASK16(0), + m_buffertmpl(NULL), + m_buffertmpr(NULL), + 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(NULL), + m_bufferr(NULL), + m_length(0), + m_RBUFDST(NULL) + +{ + memset(&m_udata.data, 0, sizeof(m_udata.data)); + memset(m_EFSPAN, 0, sizeof(m_EFSPAN)); + memset(m_Slots, 0, sizeof(m_Slots)); + memset(m_RINGBUF, 0, sizeof(m_RINGBUF)); + memset(m_MidiStack, 0, sizeof(m_MidiStack)); + + memset(m_LPANTABLE, 0, sizeof(m_LPANTABLE)); + memset(m_RPANTABLE, 0, sizeof(m_RPANTABLE)); + + memset(m_TimPris, 0, sizeof(m_TimPris)); + memset(m_TimCnt, 0, sizeof(m_TimCnt)); + + memset(&m_dma, 0, sizeof(m_dma)); + + memset(m_ARTABLE, 0, sizeof(m_ARTABLE)); + memset(m_DRTABLE, 0, sizeof(m_DRTABLE)); + + memset(&m_DSP, 0, sizeof(m_DSP)); + + memset(m_EG_TABLE, 0, sizeof(m_EG_TABLE)); + memset(m_PLFO_TRI, 0, sizeof(m_PLFO_TRI)); + memset(m_PLFO_SQR, 0, sizeof(m_PLFO_SQR)); + memset(m_PLFO_SAW, 0, sizeof(m_PLFO_SAW)); + memset(m_PLFO_NOI, 0, sizeof(m_PLFO_NOI)); + + memset(m_ALFO_TRI, 0, sizeof(m_ALFO_TRI)); + memset(m_ALFO_SQR, 0, sizeof(m_ALFO_SQR)); + memset(m_ALFO_SAW, 0, sizeof(m_ALFO_SAW)); + memset(m_ALFO_NOI, 0, sizeof(m_ALFO_NOI)); + + memset(m_PSCALES, 0, sizeof(m_PSCALES)); + memset(m_ASCALES, 0, sizeof(m_ASCALES)); +} + + +static const float LFOFreq[32]={0.17f,0.19f,0.23f,0.27f,0.34f,0.39f,0.45f,0.55f,0.68f,0.78f,0.92f,1.10f,1.39f,1.60f,1.87f,2.27f, + 2.87f,3.31f,3.92f,4.79f,6.15f,7.18f,8.60f,10.8f,14.4f,17.2f,21.5f,28.7f,43.1f,57.4f,86.1f,172.3f}; +static const float ASCALE[8]={0.0f,0.4f,0.8f,1.5f,3.0f,6.0f,12.0f,24.0f}; +static const float PSCALE[8]={0.0f,7.0f,13.5f,27.0f,55.0f,112.0f,230.0f,494.0f}; + +void aica_device::AICALFO_Init() +{ + int i,s; + for(i=0;i<256;++i) + { + int a,p; +// float TL; + //Saw + a=255-i; + if(i<128) + p=i; + else + p=i-256; + m_ALFO_SAW[i]=a; + m_PLFO_SAW[i]=p; + + //Square + if(i<128) + { + a=255; + p=127; + } + else + { + a=0; + p=-128; + } + m_ALFO_SQR[i]=a; + m_PLFO_SQR[i]=p; + + //Tri + if(i<128) + a=255-(i*2); + else + a=(i*2)-256; + if(i<64) + p=i*2; + else if(i<128) + p=255-i*2; + else if(i<192) + p=256-i*2; + else + p=i*2-511; + m_ALFO_TRI[i]=a; + m_PLFO_TRI[i]=p; + + //noise + //a=lfo_noise[i]; + a=machine().rand()&0xff; + p=128-a; + m_ALFO_NOI[i]=a; + m_PLFO_NOI[i]=p; + } + + for(s=0;s<8;++s) + { + float limit=PSCALE[s]; + for(i=-128;i<128;++i) + { + m_PSCALES[s][i+128]=CENTS(((limit*(float) i)/128.0)); + } + limit=-ASCALE[s]; + for(i=0;i<256;++i) + { + m_ASCALES[s][i]=DB(((limit*(float) i)/256.0)); + } + } +} + +signed int aica_device::AICAPLFO_Step(AICA_LFO_t *LFO) +{ + int p; + + LFO->phase+=LFO->phase_step; +#if LFO_SHIFT!=8 + LFO->phase&=(1<<(LFO_SHIFT+8))-1; +#endif + p=LFO->table[LFO->phase>>LFO_SHIFT]; + p=LFO->scale[p+128]; + return p<<(SHIFT-LFO_SHIFT); +} + +signed int aica_device::AICAALFO_Step(AICA_LFO_t *LFO) +{ + int p; + LFO->phase+=LFO->phase_step; +#if LFO_SHIFT!=8 + LFO->phase&=(1<<(LFO_SHIFT+8))-1; +#endif + p=LFO->table[LFO->phase>>LFO_SHIFT]; + p=LFO->scale[p]; + return p<<(SHIFT-LFO_SHIFT); +} + +void aica_device::AICALFO_ComputeStep(AICA_LFO_t *LFO,UINT32 LFOF,UINT32 LFOWS,UINT32 LFOS,int ALFO) +{ + float step=(float) LFOFreq[LFOF]*256.0/(float)44100.0; + LFO->phase_step=(unsigned int) ((float) (1<table=m_ALFO_SAW; break; + case 1: LFO->table=m_ALFO_SQR; break; + case 2: LFO->table=m_ALFO_TRI; break; + case 3: LFO->table=m_ALFO_NOI; break; + default: printf("Unknown ALFO %d\n", LFOWS); + } + LFO->scale=m_ASCALES[LFOS]; + } + else + { + switch(LFOWS) + { + case 0: LFO->table=m_PLFO_SAW; break; + case 1: LFO->table=m_PLFO_SQR; break; + case 2: LFO->table=m_PLFO_TRI; break; + case 3: LFO->table=m_PLFO_NOI; break; + default: printf("Unknown PLFO %d\n", LFOWS); + } + LFO->scale=m_PSCALES[LFOS]; + } } diff --git a/src/emu/sound/aica.h b/src/emu/sound/aica.h index 3f5b2e029de..25bcc011155 100644 --- a/src/emu/sound/aica.h +++ b/src/emu/sound/aica.h @@ -6,45 +6,203 @@ #ifndef __AICA_H__ #define __AICA_H__ +#include "aicadsp.h" -struct aica_interface +#define MCFG_AICA_MASTER \ + aica_device::set_master(*device); + +#define MCFG_AICA_ROFFSET(_offs) \ + aica_device::set_roffset(*device, _offs); + +#define MCFG_AICA_IRQ_CB(_devcb) \ + devcb = &aica_device::set_irq_callback(*device, DEVCB2_##_devcb); + +#define MCFG_AICA_MAIN_IRQ_CB(_devcb) \ + devcb = &aica_device::set_main_irq_callback(*device, DEVCB2_##_devcb); + +enum AICA_STATE {AICA_ATTACK,AICA_DECAY1,AICA_DECAY2,AICA_RELEASE}; + +struct AICA_LFO_t { - int master; - int roffset; /* offset in the region */ - devcb_write_line irq_callback; /* irq callback */ - devcb_write_line master_irq_callback; + unsigned short phase; + UINT32 phase_step; + int *table; + int *scale; }; -void aica_set_ram_base(device_t *device, void *base, int size); -// AICA register access -DECLARE_READ16_DEVICE_HANDLER( aica_r ); -DECLARE_WRITE16_DEVICE_HANDLER( aica_w ); +struct AICA_EG_t +{ + int volume; // + AICA_STATE state; + int step; + //step vals + int AR; //Attack + int D1R; //Decay1 + int D2R; //Decay2 + int RR; //Release -// MIDI I/O access -DECLARE_WRITE16_DEVICE_HANDLER( aica_midi_in ); -DECLARE_READ16_DEVICE_HANDLER( aica_midi_out_r ); + int DL; //Decay level + UINT8 LPLINK; +}; + +struct AICA_SLOT +{ + union + { + UINT16 data[0x40]; //only 0x1a bytes used + UINT8 datab[0x80]; + } udata; + UINT8 active; //this slot is currently playing + UINT8 *base; //samples base address + UINT32 prv_addr; // previous play address (for ADPCM) + UINT32 cur_addr; //current play address (24.8) + UINT32 nxt_addr; //next play address + UINT32 step; //pitch step (24.8) + UINT8 Backwards; //the wave is playing backwards + AICA_EG_t EG; //Envelope + AICA_LFO_t PLFO; //Phase LFO + AICA_LFO_t ALFO; //Amplitude LFO + int slot; + int cur_sample; //current ADPCM sample + int cur_quant; //current ADPCM step + int curstep; + int cur_lpquant, cur_lpsample, cur_lpstep; + UINT8 *adbase, *adlpbase; + UINT8 lpend; +}; class aica_device : public device_t, public device_sound_interface { public: aica_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~aica_device(); - // access to legacy token - struct aica_state *token() const { assert(m_token != NULL); return m_token; } + static void set_master(device_t &device) { downcast(device).m_master = true; } + static void set_roffset(device_t &device, int roffset) { downcast(device).m_roffset = roffset; } + template static devcb2_base &set_irq_callback(device_t &device, _Object object) { return downcast(device).m_irq_cb.set_callback(object); } + template static devcb2_base &set_main_irq_callback(device_t &device, _Object object) { return downcast(device).m_main_irq_cb.set_callback(object); } + + // AICA register access + DECLARE_READ16_MEMBER( read ); + DECLARE_WRITE16_MEMBER( write ); + + // MIDI I/O access + DECLARE_WRITE16_MEMBER( midi_in ); + DECLARE_READ16_MEMBER( midi_out_r ); + + void set_ram_base(void *base, int size); + protected: // device-level overrides - virtual void device_config_complete(); virtual void device_start(); - virtual void device_stop(); // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); private: - // internal state - struct aica_state *m_token; + unsigned char DecodeSCI(unsigned char irq); + void ResetInterrupts(); + + void CheckPendingIRQ(); + void CheckPendingIRQ_SH4(); + TIMER_CALLBACK_MEMBER( timerA_cb ); + TIMER_CALLBACK_MEMBER( timerB_cb ); + TIMER_CALLBACK_MEMBER( timerC_cb ); + int Get_AR(int base,int R); + int Get_DR(int base,int R); + int Get_RR(int base,int R); + void Compute_EG(AICA_SLOT *slot); + int EG_Update(AICA_SLOT *slot); + UINT32 Step(AICA_SLOT *slot); + void Compute_LFO(AICA_SLOT *slot); + void InitADPCM(int *PrevSignal, int *PrevQuant); + inline signed short DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQuant); + void StartSlot(AICA_SLOT *slot); + void StopSlot(AICA_SLOT *slot,int keyoff); + void Init(); + void UpdateSlotReg(int s,int r); + void UpdateReg(address_space &space, int reg); + void UpdateSlotRegR(int slot,int reg); + void UpdateRegR(address_space &space, int reg); + void w16(address_space &space,unsigned int addr,unsigned short val); + unsigned short r16(address_space &space, unsigned int addr); + inline INT32 UpdateSlot(AICA_SLOT *slot); + void DoMasterSamples(int nsamples); + void aica_exec_dma(address_space &space); + + + void AICALFO_Init(); + inline signed int AICAPLFO_Step(AICA_LFO_t *LFO); + inline signed int AICAALFO_Step(AICA_LFO_t *LFO); + void AICALFO_ComputeStep(AICA_LFO_t *LFO,UINT32 LFOF,UINT32 LFOWS,UINT32 LFOS,int ALFO); + + bool m_master; + int m_roffset; /* offset in the region */ + devcb2_write_line m_irq_cb; + devcb2_write_line m_main_irq_cb; + + union + { + UINT16 data[0xc0/2]; + UINT8 datab[0xc0]; + } m_udata; + + UINT16 m_IRQL, m_IRQR; + UINT16 m_EFSPAN[0x48]; + AICA_SLOT m_Slots[64]; + signed short m_RINGBUF[64]; + unsigned char m_BUFPTR; + unsigned char *m_AICARAM; + UINT32 m_AICARAM_LENGTH, m_RAM_MASK, m_RAM_MASK16; + sound_stream * m_stream; + + INT32 *m_buffertmpl, *m_buffertmpr; + + UINT32 m_IrqTimA; + UINT32 m_IrqTimBC; + UINT32 m_IrqMidi; + + UINT8 m_MidiOutW,m_MidiOutR; + UINT8 m_MidiStack[16]; + UINT8 m_MidiW,m_MidiR; + + int m_LPANTABLE[0x20000]; + int m_RPANTABLE[0x20000]; + + int m_TimPris[3]; + int m_TimCnt[3]; + + UINT16 m_mcieb, m_mcipd; + + // timers + emu_timer *m_timerA, *m_timerB, *m_timerC; + + // DMA stuff + struct{ + UINT32 dmea; + UINT16 drga; + UINT16 dlg; + UINT8 dgate; + UINT8 ddir; + }m_dma; + + + int m_ARTABLE[64], m_DRTABLE[64]; + + AICADSP m_DSP; + + stream_sample_t *m_bufferl; + stream_sample_t *m_bufferr; + + int m_length; + + signed short *m_RBUFDST; //this points to where the sample will be stored in the RingBuf + INT32 m_EG_TABLE[0x400]; + int m_PLFO_TRI[256],m_PLFO_SQR[256],m_PLFO_SAW[256],m_PLFO_NOI[256]; + int m_ALFO_TRI[256],m_ALFO_SQR[256],m_ALFO_SAW[256],m_ALFO_NOI[256]; + int m_PSCALES[8][256]; + int m_ASCALES[8][256]; + }; extern const device_type AICA; diff --git a/src/emu/sound/aicadsp.c b/src/emu/sound/aicadsp.c index 42a05825478..3c1d0971b78 100644 --- a/src/emu/sound/aicadsp.c +++ b/src/emu/sound/aicadsp.c @@ -1,5 +1,4 @@ #include "emu.h" -#include "aica.h" #include "aicadsp.h" static UINT16 PACK(INT32 val) diff --git a/src/emu/sound/aicalfo.inc b/src/emu/sound/aicalfo.inc deleted file mode 100644 index d955b815894..00000000000 --- a/src/emu/sound/aicalfo.inc +++ /dev/null @@ -1,159 +0,0 @@ -/* - AICA LFO handling - - Part of the AICA emulator package. - (not compiled directly, #included from aica.c) - - By ElSemi, kingshriek, Deunan Knute, and R. Belmont -*/ - -#define LFO_SHIFT 8 - -struct LFO_t -{ - unsigned short phase; - UINT32 phase_step; - int *table; - int *scale; -}; - -#define LFIX(v) ((unsigned int) ((float) (1<phase+=LFO->phase_step; -#if LFO_SHIFT!=8 - LFO->phase&=(1<<(LFO_SHIFT+8))-1; -#endif - p=LFO->table[LFO->phase>>LFO_SHIFT]; - p=LFO->scale[p+128]; - return p<<(SHIFT-LFO_SHIFT); -} - -INLINE signed int AICAALFO_Step(LFO_t *LFO) -{ - int p; - LFO->phase+=LFO->phase_step; -#if LFO_SHIFT!=8 - LFO->phase&=(1<<(LFO_SHIFT+8))-1; -#endif - p=LFO->table[LFO->phase>>LFO_SHIFT]; - p=LFO->scale[p]; - return p<<(SHIFT-LFO_SHIFT); -} - -static void AICALFO_ComputeStep(LFO_t *LFO,UINT32 LFOF,UINT32 LFOWS,UINT32 LFOS,int ALFO) -{ - float step=(float) LFOFreq[LFOF]*256.0/(float)44100.0; - LFO->phase_step=(unsigned int) ((float) (1<table=ALFO_SAW; break; - case 1: LFO->table=ALFO_SQR; break; - case 2: LFO->table=ALFO_TRI; break; - case 3: LFO->table=ALFO_NOI; break; - default: printf("Unknown ALFO %d\n", LFOWS); - } - LFO->scale=ASCALES[LFOS]; - } - else - { - switch(LFOWS) - { - case 0: LFO->table=PLFO_SAW; break; - case 1: LFO->table=PLFO_SQR; break; - case 2: LFO->table=PLFO_TRI; break; - case 3: LFO->table=PLFO_NOI; break; - default: printf("Unknown PLFO %d\n", LFOWS); - } - LFO->scale=PSCALES[LFOS]; - } -} diff --git a/src/emu/sound/scsp.c b/src/emu/sound/scsp.c index 9b6d32e6dfc..5d429d8442e 100644 --- a/src/emu/sound/scsp.c +++ b/src/emu/sound/scsp.c @@ -204,13 +204,10 @@ void scsp_device::device_start() init(); // set up the IRQ callbacks - { - m_irq_cb.resolve_safe(); - - m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100, this); - } - + m_irq_cb.resolve_safe(); m_main_irq_cb.resolve_safe(); + + m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100, this); } //------------------------------------------------- diff --git a/src/emu/sound/scsp.h b/src/emu/sound/scsp.h index 495f0aca341..cd66eb8f6c8 100644 --- a/src/emu/sound/scsp.h +++ b/src/emu/sound/scsp.h @@ -76,7 +76,6 @@ class scsp_device : public device_t, { public: scsp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~scsp_device() {} static void set_roffset(device_t &device, int roffset) { downcast(device).m_roffset = roffset; } template static devcb2_base &set_irq_callback(device_t &device, _Object object) { return downcast(device).m_irq_cb.set_callback(object); } diff --git a/src/emu/sound/sound.mak b/src/emu/sound/sound.mak index a4d2fa23689..070534c8e09 100644 --- a/src/emu/sound/sound.mak +++ b/src/emu/sound/sound.mak @@ -536,10 +536,6 @@ ifneq ($(filter AICA,$(SOUNDS)),) SOUNDOBJS += $(SOUNDOBJ)/aica.o $(SOUNDOBJ)/aicadsp.o endif -$(SOUNDOBJ)/aica.o: $(SOUNDSRC)/aicalfo.inc - - - #------------------------------------------------- # Seta custom sound chips #@src/emu/sound/st0016.h,SOUNDS += ST0016 diff --git a/src/mame/drivers/naomi.c b/src/mame/drivers/naomi.c index 4484a46558a..53437467093 100644 --- a/src/mame/drivers/naomi.c +++ b/src/mame/drivers/naomi.c @@ -1812,15 +1812,6 @@ WRITE_LINE_MEMBER(naomi_state::sh4_aica_irq) dc_update_interrupt_status(); } -static const aica_interface aica_config = -{ - TRUE, - 0, - DEVCB_DRIVER_LINE_MEMBER(naomi_state,aica_irq), - DEVCB_DRIVER_LINE_MEMBER(naomi_state,sh4_aica_irq) -}; - - static ADDRESS_MAP_START( dc_audio_map, AS_PROGRAM, 32, naomi_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00000000, 0x007fffff) AM_RAM AM_SHARE("dc_sound_ram") /* shared with SH-4 */ @@ -2487,7 +2478,7 @@ INPUT_PORTS_END MACHINE_RESET_MEMBER(naomi_state,naomi) { naomi_state::machine_reset(); - aica_set_ram_base(machine().device("aica"), dc_sound_ram, 8*1024*1024); + m_aica->set_ram_base(dc_sound_ram, 8*1024*1024); } /* @@ -2521,7 +2512,10 @@ static MACHINE_CONFIG_START( naomi_aw_base, naomi_state ) MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SOUND_ADD("aica", AICA, 0) - MCFG_SOUND_CONFIG(aica_config) + MCFG_AICA_MASTER + MCFG_AICA_IRQ_CB(WRITELINE(naomi_state, aica_irq)) + MCFG_AICA_MAIN_IRQ_CB(WRITELINE(naomi_state, sh4_aica_irq)) + MCFG_SOUND_ROUTE(0, "lspeaker", 2.0) MCFG_SOUND_ROUTE(1, "rspeaker", 2.0) diff --git a/src/mame/includes/dc.h b/src/mame/includes/dc.h index df07d828911..f11be2619f9 100644 --- a/src/mame/includes/dc.h +++ b/src/mame/includes/dc.h @@ -10,6 +10,7 @@ #include "video/powervr2.h" #include "machine/naomig1.h" #include "machine/maple-dc.h" +#include "sound/aica.h" class dc_state : public driver_device { @@ -24,7 +25,8 @@ class dc_state : public driver_device m_soundcpu(*this, "soundcpu"), m_powervr2(*this, "powervr2"), m_maple(*this, "maple_dc"), - m_naomig1(*this, "rom_board") { } + m_naomig1(*this, "rom_board"), + m_aica(*this, "aica") { } required_shared_ptr dc_framebuffer_ram; // '32-bit access area' required_shared_ptr dc_texture_ram; // '64-bit access area' @@ -80,6 +82,7 @@ class dc_state : public driver_device required_device m_powervr2; required_device m_maple; optional_device m_naomig1; + required_device m_aica; void generic_dma(UINT32 main_adr, void *dma_ptr, UINT32 length, UINT32 size, bool to_mainram); TIMER_DEVICE_CALLBACK_MEMBER(dc_scanline); diff --git a/src/mame/machine/dc.c b/src/mame/machine/dc.c index 7314eaf7ff4..b62c871b968 100644 --- a/src/mame/machine/dc.c +++ b/src/mame/machine/dc.c @@ -8,7 +8,6 @@ #include "debugger.h" #include "includes/dc.h" #include "cpu/sh4/sh4.h" -#include "sound/aica.h" #include "machine/mie.h" #include "machine/naomig1.h" #include "video/powervr2.h" @@ -681,7 +680,7 @@ READ32_MEMBER(dc_state::dc_aica_reg_r) if(offset == 0x2c00/4) return m_armrst; - return aica_r(machine().device("aica"), space, offset*2, 0xffff); + return m_aica->read(space, offset*2, 0xffff); } WRITE32_MEMBER(dc_state::dc_aica_reg_w) @@ -705,19 +704,19 @@ WRITE32_MEMBER(dc_state::dc_aica_reg_w) } } - aica_w(machine().device("aica"), space, offset*2, data, 0xffff); + m_aica->write(space, offset*2, data, 0xffff); // 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) { - return aica_r(machine().device("aica"), space, offset*2, 0xffff) & 0xffff; + return m_aica->read(space, offset*2, 0xffff) & 0xffff; } WRITE32_MEMBER(dc_state::dc_arm_aica_w) { - aica_w(machine().device("aica"), space, offset*2, data, mem_mask&0xffff); + m_aica->write(space, offset*2, data, mem_mask&0xffff); } TIMER_DEVICE_CALLBACK_MEMBER(dc_state::dc_scanline) diff --git a/src/mess/drivers/dccons.c b/src/mess/drivers/dccons.c index e2673fb4e12..445cdf644fb 100644 --- a/src/mess/drivers/dccons.c +++ b/src/mess/drivers/dccons.c @@ -576,9 +576,8 @@ INPUT_PORTS_END MACHINE_RESET_MEMBER(dc_cons_state,dc_console) { - device_t *aica = machine().device("aica"); dc_state::machine_reset(); - aica_set_ram_base(aica, dc_sound_ram, 2*1024*1024); + m_aica->set_ram_base(dc_sound_ram, 2*1024*1024); } WRITE_LINE_MEMBER(dc_cons_state::aica_irq) @@ -596,14 +595,6 @@ WRITE_LINE_MEMBER(dc_cons_state::sh4_aica_irq) dc_update_interrupt_status(); } -static const aica_interface dc_aica_interface = -{ - TRUE, - 0, - DEVCB_DRIVER_LINE_MEMBER(dc_cons_state,aica_irq), - DEVCB_DRIVER_LINE_MEMBER(dc_cons_state,sh4_aica_irq) -}; - static const struct sh4_config sh4cpu_config = { 1, 0, 1, 0, 0, 0, 1, 1, 0, CPU_CLOCK }; static MACHINE_CONFIG_FRAGMENT( gdrom_config ) @@ -642,7 +633,9 @@ static MACHINE_CONFIG_START( dc, dc_cons_state ) MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SOUND_ADD("aica", AICA, 0) - MCFG_SOUND_CONFIG(dc_aica_interface) + MCFG_AICA_MASTER + MCFG_AICA_IRQ_CB(WRITELINE(dc_cons_state, aica_irq)) + MCFG_AICA_MAIN_IRQ_CB(WRITELINE(dc_cons_state, sh4_aica_irq)) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(0, "rspeaker", 1.0)