mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +03:00
Merge pull request #3777 from cam900/aicaclock
aica.cpp : Add input clock related to sample rate, Implement MONO/MVOL
This commit is contained in:
commit
71ec3b4019
@ -72,10 +72,10 @@
|
|||||||
#define IMXL(slot) ((slot->udata.data[0x20/2]>>0x4)&0x000F)
|
#define IMXL(slot) ((slot->udata.data[0x20/2]>>0x4)&0x000F)
|
||||||
|
|
||||||
#define DISDL(slot) ((slot->udata.data[0x24/2]>>0x8)&0x000F)
|
#define DISDL(slot) ((slot->udata.data[0x24/2]>>0x8)&0x000F)
|
||||||
#define DIPAN(slot) ((slot->udata.data[0x24/2]>>0x0)&0x001F)
|
#define DIPAN(slot) (MONO() ? 0 : ((slot->udata.data[0x24/2]>>0x0)&0x001F))
|
||||||
|
|
||||||
#define EFSDL(slot) ((m_EFSPAN[slot*4]>>8)&0x000f)
|
#define EFSDL(slot) ((m_EFSPAN[slot*4]>>8)&0x000f)
|
||||||
#define EFPAN(slot) ((m_EFSPAN[slot*4]>>0)&0x001f)
|
#define EFPAN(slot) (MONO() ? 0 : ((m_EFSPAN[slot*4]>>0)&0x001f))
|
||||||
|
|
||||||
//Unimplemented
|
//Unimplemented
|
||||||
#define Q(slot) ((slot->udata.data[0x28/2]>>0x0)&0x001F) // (0.75 × register value - 3)
|
#define Q(slot) ((slot->udata.data[0x28/2]>>0x0)&0x001F) // (0.75 × register value - 3)
|
||||||
@ -99,6 +99,7 @@ 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,
|
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};
|
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 MONO(aica) ((m_udata.data[0]>>0x0)&0x8000)
|
||||||
#define MEM8MB(aica) ((m_udata.data[0]>>0x0)&0x0200)
|
#define MEM8MB(aica) ((m_udata.data[0]>>0x0)&0x0200)
|
||||||
#define DAC18B(aica) ((m_udata.data[0]>>0x0)&0x0100)
|
#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)
|
||||||
@ -505,24 +506,7 @@ void aica_device::Init()
|
|||||||
|
|
||||||
m_ARTABLE[0]=m_DRTABLE[0]=0; //Infinite time
|
m_ARTABLE[0]=m_DRTABLE[0]=0; //Infinite time
|
||||||
m_ARTABLE[1]=m_DRTABLE[1]=0; //Infinite time
|
m_ARTABLE[1]=m_DRTABLE[1]=0; //Infinite time
|
||||||
for(i=2;i<64;++i)
|
ClockChange();
|
||||||
{
|
|
||||||
double t,step,scale;
|
|
||||||
t=ARTimes[i]; //In ms
|
|
||||||
if(t!=0.0)
|
|
||||||
{
|
|
||||||
step=(1023*1000.0)/(44100.0*t);
|
|
||||||
scale=(double) (1<<EG_SHIFT);
|
|
||||||
m_ARTABLE[i]=(int) (step*scale);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_ARTABLE[i]=1024<<EG_SHIFT;
|
|
||||||
|
|
||||||
t=DRTimes[i]; //In ms
|
|
||||||
step=(1023*1000.0)/(44100.0*t);
|
|
||||||
scale=(double) (1<<EG_SHIFT);
|
|
||||||
m_DRTABLE[i]=(int) (step*scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure all the slots are off
|
// make sure all the slots are off
|
||||||
for(i=0;i<64;++i)
|
for(i=0;i<64;++i)
|
||||||
@ -535,8 +519,6 @@ void aica_device::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
AICALFO_Init();
|
AICALFO_Init();
|
||||||
m_buffertmpl=make_unique_clear<int32_t[]>(44100);
|
|
||||||
m_buffertmpr=make_unique_clear<int32_t[]>(44100);
|
|
||||||
|
|
||||||
// no "pend"
|
// no "pend"
|
||||||
m_udata.data[0xa0/2] = 0;
|
m_udata.data[0xa0/2] = 0;
|
||||||
@ -546,6 +528,32 @@ void aica_device::Init()
|
|||||||
m_TimCnt[2] = 0xffff;
|
m_TimCnt[2] = 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void aica_device::ClockChange()
|
||||||
|
{
|
||||||
|
m_rate = ((double)clock()) / 512.0;
|
||||||
|
for(int i=2;i<64;++i)
|
||||||
|
{
|
||||||
|
double t,step,scale;
|
||||||
|
t=ARTimes[i]; //In ms
|
||||||
|
if(t!=0.0)
|
||||||
|
{
|
||||||
|
step=(1023*1000.0)/(m_rate*t);
|
||||||
|
scale=(double) (1<<EG_SHIFT);
|
||||||
|
m_ARTABLE[i]=(int) (step*scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_ARTABLE[i]=1024<<EG_SHIFT;
|
||||||
|
|
||||||
|
t=DRTimes[i]; //In ms
|
||||||
|
step=(1023*1000.0)/(m_rate*t);
|
||||||
|
scale=(double) (1<<EG_SHIFT);
|
||||||
|
m_DRTABLE[i]=(int) (step*scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffertmpl.resize((int)m_rate, 0);
|
||||||
|
m_buffertmpr.resize((int)m_rate, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void aica_device::UpdateSlotReg(int s,int r)
|
void aica_device::UpdateSlotReg(int s,int r)
|
||||||
{
|
{
|
||||||
AICA_SLOT *slot=m_Slots+s;
|
AICA_SLOT *slot=m_Slots+s;
|
||||||
@ -675,10 +683,10 @@ void aica_device::UpdateReg(address_space &space, int reg)
|
|||||||
|
|
||||||
if ((m_udata.data[0x90/2]&0xff) != 255)
|
if ((m_udata.data[0x90/2]&0xff) != 255)
|
||||||
{
|
{
|
||||||
time = (44100 / m_TimPris[0]) / (255-(m_udata.data[0x90/2]&0xff));
|
time = (clock() / m_TimPris[0]) / (255-(m_udata.data[0x90/2]&0xff));
|
||||||
if (time)
|
if (time)
|
||||||
{
|
{
|
||||||
m_timerA->adjust(attotime::from_hz(time));
|
m_timerA->adjust(attotime::from_ticks(512, time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -694,10 +702,10 @@ void aica_device::UpdateReg(address_space &space, int reg)
|
|||||||
|
|
||||||
if ((m_udata.data[0x94/2]&0xff) != 255)
|
if ((m_udata.data[0x94/2]&0xff) != 255)
|
||||||
{
|
{
|
||||||
time = (44100 / m_TimPris[1]) / (255-(m_udata.data[0x94/2]&0xff));
|
time = (clock() / m_TimPris[1]) / (255-(m_udata.data[0x94/2]&0xff));
|
||||||
if (time)
|
if (time)
|
||||||
{
|
{
|
||||||
m_timerB->adjust(attotime::from_hz(time));
|
m_timerB->adjust(attotime::from_ticks(512, time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -713,10 +721,10 @@ void aica_device::UpdateReg(address_space &space, int reg)
|
|||||||
|
|
||||||
if ((m_udata.data[0x98/2]&0xff) != 255)
|
if ((m_udata.data[0x98/2]&0xff) != 255)
|
||||||
{
|
{
|
||||||
time = (44100 / m_TimPris[2]) / (255-(m_udata.data[0x98/2]&0xff));
|
time = (clock() / m_TimPris[2]) / (255-(m_udata.data[0x98/2]&0xff));
|
||||||
if (time)
|
if (time)
|
||||||
{
|
{
|
||||||
m_timerC->adjust(attotime::from_hz(time));
|
m_timerC->adjust(attotime::from_ticks(512, time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1305,8 +1313,8 @@ void aica_device::DoMasterSamples(int nsamples)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*bufl++ = ICLIP16(smpl>>3);
|
*bufl++ = (ICLIP16(smpl>>3)*m_LPANTABLE[MVOL()<<0xd])>>SHIFT;
|
||||||
*bufr++ = ICLIP16(smpr>>3);
|
*bufr++ = (ICLIP16(smpr>>3)*m_LPANTABLE[MVOL()<<0xd])>>SHIFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1425,7 +1433,7 @@ void aica_device::device_start()
|
|||||||
m_irq_cb.resolve_safe();
|
m_irq_cb.resolve_safe();
|
||||||
m_main_irq_cb.resolve_safe();
|
m_main_irq_cb.resolve_safe();
|
||||||
|
|
||||||
m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100);
|
m_stream = machine().sound().stream_alloc(*this, 0, 2, (int)m_rate);
|
||||||
|
|
||||||
// save state
|
// save state
|
||||||
save_item(NAME(m_IrqTimA));
|
save_item(NAME(m_IrqTimA));
|
||||||
@ -1442,6 +1450,17 @@ void aica_device::device_start()
|
|||||||
save_item(NAME(m_TimCnt),3);
|
save_item(NAME(m_TimCnt),3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_clock_changed - called if the clock
|
||||||
|
// changes
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void aica_device::device_clock_changed()
|
||||||
|
{
|
||||||
|
ClockChange();
|
||||||
|
m_stream->set_sample_rate((int)m_rate);
|
||||||
|
}
|
||||||
|
|
||||||
void aica_device::set_ram_base(void *base, int size)
|
void aica_device::set_ram_base(void *base, int size)
|
||||||
{
|
{
|
||||||
m_AICARAM = (unsigned char *)base;
|
m_AICARAM = (unsigned char *)base;
|
||||||
@ -1481,12 +1500,13 @@ READ16_MEMBER( aica_device::midi_out_r )
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_DEVICE_TYPE(AICA, aica_device, "aica", "AICA")
|
DEFINE_DEVICE_TYPE(AICA, aica_device, "aica", "Yamaha AICA")
|
||||||
|
|
||||||
aica_device::aica_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
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_t(mconfig, AICA, tag, owner, clock),
|
||||||
device_sound_interface(mconfig, *this),
|
device_sound_interface(mconfig, *this),
|
||||||
m_master(false),
|
m_master(false),
|
||||||
|
m_rate(44100.0),
|
||||||
m_roffset(0),
|
m_roffset(0),
|
||||||
m_irq_cb(*this),
|
m_irq_cb(*this),
|
||||||
m_main_irq_cb(*this),
|
m_main_irq_cb(*this),
|
||||||
@ -1498,8 +1518,6 @@ aica_device::aica_device(const machine_config &mconfig, const char *tag, device_
|
|||||||
m_AICARAM_LENGTH(0),
|
m_AICARAM_LENGTH(0),
|
||||||
m_RAM_MASK(0),
|
m_RAM_MASK(0),
|
||||||
m_RAM_MASK16(0),
|
m_RAM_MASK16(0),
|
||||||
m_buffertmpl(nullptr),
|
|
||||||
m_buffertmpr(nullptr),
|
|
||||||
m_IrqTimA(0),
|
m_IrqTimA(0),
|
||||||
m_IrqTimBC(0),
|
m_IrqTimBC(0),
|
||||||
m_IrqMidi(0),
|
m_IrqMidi(0),
|
||||||
@ -1651,7 +1669,7 @@ signed int aica_device::AICAALFO_Step(AICA_LFO_t *LFO)
|
|||||||
|
|
||||||
void aica_device::AICALFO_ComputeStep(AICA_LFO_t *LFO,uint32_t LFOF,uint32_t LFOWS,uint32_t LFOS,int ALFO)
|
void aica_device::AICALFO_ComputeStep(AICA_LFO_t *LFO,uint32_t LFOF,uint32_t LFOWS,uint32_t LFOS,int ALFO)
|
||||||
{
|
{
|
||||||
float step=(float) LFOFreq[LFOF]*256.0f/(float)44100.0f;
|
float step=(float) LFOFreq[LFOF]*256.0f/(float)m_rate;
|
||||||
LFO->phase_step=(unsigned int) ((float) (1<<LFO_SHIFT)*step);
|
LFO->phase_step=(unsigned int) ((float) (1<<LFO_SHIFT)*step);
|
||||||
if(ALFO)
|
if(ALFO)
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
|
virtual void device_clock_changed() override;
|
||||||
|
|
||||||
// sound stream update overrides
|
// sound stream update overrides
|
||||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||||
@ -128,6 +129,7 @@ private:
|
|||||||
void StartSlot(AICA_SLOT *slot);
|
void StartSlot(AICA_SLOT *slot);
|
||||||
void StopSlot(AICA_SLOT *slot,int keyoff);
|
void StopSlot(AICA_SLOT *slot,int keyoff);
|
||||||
void Init();
|
void Init();
|
||||||
|
void ClockChange();
|
||||||
void UpdateSlotReg(int s,int r);
|
void UpdateSlotReg(int s,int r);
|
||||||
void UpdateReg(address_space &space, int reg);
|
void UpdateReg(address_space &space, int reg);
|
||||||
void UpdateSlotRegR(int slot,int reg);
|
void UpdateSlotRegR(int slot,int reg);
|
||||||
@ -145,6 +147,7 @@ private:
|
|||||||
void AICALFO_ComputeStep(AICA_LFO_t *LFO,uint32_t LFOF,uint32_t LFOWS,uint32_t LFOS,int ALFO);
|
void AICALFO_ComputeStep(AICA_LFO_t *LFO,uint32_t LFOF,uint32_t LFOWS,uint32_t LFOS,int ALFO);
|
||||||
|
|
||||||
bool m_master;
|
bool m_master;
|
||||||
|
double m_rate;
|
||||||
int m_roffset; /* offset in the region */
|
int m_roffset; /* offset in the region */
|
||||||
devcb_write_line m_irq_cb;
|
devcb_write_line m_irq_cb;
|
||||||
devcb_write_line m_main_irq_cb;
|
devcb_write_line m_main_irq_cb;
|
||||||
@ -165,8 +168,8 @@ private:
|
|||||||
uint32_t m_AICARAM_LENGTH, m_RAM_MASK, m_RAM_MASK16;
|
uint32_t m_AICARAM_LENGTH, m_RAM_MASK, m_RAM_MASK16;
|
||||||
sound_stream * m_stream;
|
sound_stream * m_stream;
|
||||||
|
|
||||||
std::unique_ptr<int32_t[]> m_buffertmpl;
|
std::vector<int32_t> m_buffertmpl;
|
||||||
std::unique_ptr<int32_t[]> m_buffertmpr;
|
std::vector<int32_t> m_buffertmpr;
|
||||||
|
|
||||||
uint32_t m_IrqTimA;
|
uint32_t m_IrqTimA;
|
||||||
uint32_t m_IrqTimBC;
|
uint32_t m_IrqTimBC;
|
||||||
|
@ -621,12 +621,13 @@ MACHINE_CONFIG_START(dc_cons_state::dc)
|
|||||||
|
|
||||||
SPEAKER(config, "lspeaker").front_left();
|
SPEAKER(config, "lspeaker").front_left();
|
||||||
SPEAKER(config, "rspeaker").front_right();
|
SPEAKER(config, "rspeaker").front_right();
|
||||||
MCFG_DEVICE_ADD("aica", AICA, 0)
|
|
||||||
|
MCFG_DEVICE_ADD("aica", AICA, (XTAL(33'868'800)*2)/3) // 67.7376MHz(2*33.8688MHz), div 3 for audio block
|
||||||
MCFG_AICA_MASTER
|
MCFG_AICA_MASTER
|
||||||
MCFG_AICA_IRQ_CB(WRITELINE(*this, dc_state, aica_irq))
|
MCFG_AICA_IRQ_CB(WRITELINE(*this, dc_state, aica_irq))
|
||||||
MCFG_AICA_MAIN_IRQ_CB(WRITELINE(*this, dc_state, sh4_aica_irq))
|
MCFG_AICA_MAIN_IRQ_CB(WRITELINE(*this, dc_state, sh4_aica_irq))
|
||||||
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
|
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
|
||||||
MCFG_SOUND_ROUTE(0, "rspeaker", 1.0)
|
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
|
||||||
|
|
||||||
MCFG_AICARTC_ADD("aicartc", XTAL(32'768))
|
MCFG_AICARTC_ADD("aicartc", XTAL(32'768))
|
||||||
|
|
||||||
|
@ -531,9 +531,14 @@ MACHINE_CONFIG_START(hikaru_state::hikaru)
|
|||||||
|
|
||||||
// SPEAKER(config, "lspeaker").front_left();
|
// SPEAKER(config, "lspeaker").front_left();
|
||||||
// SPEAKER(config, "rspeaker").front_right();
|
// SPEAKER(config, "rspeaker").front_right();
|
||||||
// MCFG_DEVICE_ADD("aica", AICA, 0)
|
|
||||||
|
// MCFG_DEVICE_ADD("aica", AICA, (XTAL(33'868'800)*2)/3) // 67.7376MHz(2*33.8688MHz), div 3 for audio block // 33.8688MHz on Board
|
||||||
// MCFG_SOUND_ROUTE(0, "lspeaker", 2.0)
|
// MCFG_SOUND_ROUTE(0, "lspeaker", 2.0)
|
||||||
// MCFG_SOUND_ROUTE(0, "rspeaker", 2.0)
|
// MCFG_SOUND_ROUTE(1, "rspeaker", 2.0)
|
||||||
|
|
||||||
|
// MCFG_DEVICE_ADD("aica_pcb", AICA, (XTAL(33'868'800)*2)/3) // AICA PCB
|
||||||
|
// MCFG_SOUND_ROUTE(0, "lspeaker", 2.0)
|
||||||
|
// MCFG_SOUND_ROUTE(1, "rspeaker", 2.0)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
|
@ -2923,11 +2923,11 @@ MACHINE_CONFIG_START(dc_state::naomi_aw_base)
|
|||||||
|
|
||||||
SPEAKER(config, "lspeaker").front_left();
|
SPEAKER(config, "lspeaker").front_left();
|
||||||
SPEAKER(config, "rspeaker").front_right();
|
SPEAKER(config, "rspeaker").front_right();
|
||||||
MCFG_DEVICE_ADD("aica", AICA, 0)
|
|
||||||
|
MCFG_DEVICE_ADD("aica", AICA, (XTAL(33'868'800)*2)/3) // 67.7376MHz(2*33.8688MHz), div 3 for audio block
|
||||||
MCFG_AICA_MASTER
|
MCFG_AICA_MASTER
|
||||||
MCFG_AICA_IRQ_CB(WRITELINE(*this, dc_state, aica_irq))
|
MCFG_AICA_IRQ_CB(WRITELINE(*this, dc_state, aica_irq))
|
||||||
MCFG_AICA_MAIN_IRQ_CB(WRITELINE(*this, dc_state, sh4_aica_irq))
|
MCFG_AICA_MAIN_IRQ_CB(WRITELINE(*this, dc_state, sh4_aica_irq))
|
||||||
|
|
||||||
MCFG_SOUND_ROUTE(0, "lspeaker", 2.0)
|
MCFG_SOUND_ROUTE(0, "lspeaker", 2.0)
|
||||||
MCFG_SOUND_ROUTE(1, "rspeaker", 2.0)
|
MCFG_SOUND_ROUTE(1, "rspeaker", 2.0)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user