Modernized MultiPCM, mjkjidai, renegage, ninjaw_subwoofer devices [Osso]

Multisession bug fix for exidy440 audio from Osso (nw)
This commit is contained in:
Scott Stone 2013-07-30 17:09:46 +00:00
parent ad4546e878
commit 6cf4b6c27f
14 changed files with 492 additions and 529 deletions

View File

@ -33,79 +33,11 @@
#include "emu.h"
#include "multipcm.h"
#include "devlegcy.h"
//????
#define MULTIPCM_CLOCKDIV (180.0)
struct Sample_t
{
unsigned int Start;
unsigned int Loop;
unsigned int End;
unsigned char AR,DR1,DR2,DL,RR;
unsigned char KRS;
unsigned char LFOVIB;
unsigned char AM;
};
enum STATE {ATTACK,DECAY1,DECAY2,RELEASE};
ALLOW_SAVE_TYPE(STATE); // allow save_item on a non-fundamental type
struct EG_t
{
int volume; //
STATE state;
int step;
//step vals
int AR; //Attack
int D1R; //Decay1
int D2R; //Decay2
int RR; //Release
int DL; //Decay level
};
struct LFO_t
{
unsigned short phase;
UINT32 phase_step;
int *table;
int *scale;
};
struct SLOT
{
unsigned char Num;
unsigned char Regs[8];
int Playing;
Sample_t *Sample;
unsigned int Base;
unsigned int offset;
unsigned int step;
unsigned int Pan,TL;
unsigned int DstTL;
int TLStep;
signed int Prev;
EG_t EG;
LFO_t PLFO; //Phase lfo
LFO_t ALFO; //AM lfo
};
struct MultiPCM
{
sound_stream * stream;
Sample_t Samples[0x200]; //Max 512 samples
SLOT Slots[28];
unsigned int CurSlot;
unsigned int Address;
unsigned int BankR,BankL;
float Rate;
INT8 *ROM;
//I include these in the chip because they depend on the chip clock
unsigned int ARStep[0x40],DRStep[0x40]; //Envelope step table
unsigned int FNS_Table[0x400]; //Frequency step table
};
static signed int LPANTABLE[0x800],RPANTABLE[0x800];
@ -126,12 +58,6 @@ static const int val2chan[] =
#define MULTIPCM_RATE 44100.0
INLINE MultiPCM *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == MULTIPCM);
return (MultiPCM *)downcast<multipcm_device *>(device)->token();
}
/*******************************
@ -202,7 +128,7 @@ static unsigned int Get_RATE(unsigned int *Steps,unsigned int rate,unsigned int
return Steps[r];
}
static void EG_Calc(MultiPCM *ptChip,SLOT *slot)
void multipcm_device::EG_Calc(SLOT *slot)
{
int octave=((slot->Regs[3]>>4)-1)&0xf;
int rate;
@ -212,10 +138,10 @@ static void EG_Calc(MultiPCM *ptChip,SLOT *slot)
else
rate=0;
slot->EG.AR=Get_RATE(ptChip->ARStep,rate,slot->Sample->AR);
slot->EG.D1R=Get_RATE(ptChip->DRStep,rate,slot->Sample->DR1);
slot->EG.D2R=Get_RATE(ptChip->DRStep,rate,slot->Sample->DR2);
slot->EG.RR=Get_RATE(ptChip->DRStep,rate,slot->Sample->RR);
slot->EG.AR=Get_RATE(m_ARStep,rate,slot->Sample->AR);
slot->EG.D1R=Get_RATE(m_DRStep,rate,slot->Sample->DR1);
slot->EG.D2R=Get_RATE(m_DRStep,rate,slot->Sample->DR2);
slot->EG.RR=Get_RATE(m_DRStep,rate,slot->Sample->RR);
slot->EG.DL=0xf-slot->Sample->DL;
}
@ -302,9 +228,9 @@ INLINE signed int ALFO_Step(LFO_t *LFO)
return p<<(SHIFT-LFO_SHIFT);
}
static void LFO_ComputeStep(MultiPCM *ptChip,LFO_t *LFO,UINT32 LFOF,UINT32 LFOS,int ALFO)
void multipcm_device::LFO_ComputeStep(LFO_t *LFO,UINT32 LFOF,UINT32 LFOS,int ALFO)
{
float step=(float) LFOFreq[LFOF]*256.0/(float) ptChip->Rate;
float step=(float) LFOFreq[LFOF]*256.0/(float) m_Rate;
LFO->phase_step=(unsigned int) ((float) (1<<LFO_SHIFT)*step);
if(ALFO)
{
@ -320,7 +246,7 @@ static void LFO_ComputeStep(MultiPCM *ptChip,LFO_t *LFO,UINT32 LFOF,UINT32 LFOS,
static void WriteSlot(MultiPCM *ptChip,SLOT *slot,int reg,unsigned char data)
void multipcm_device::WriteSlot(SLOT *slot,int reg,unsigned char data)
{
slot->Regs[reg]=data;
@ -333,9 +259,9 @@ static void WriteSlot(MultiPCM *ptChip,SLOT *slot,int reg,unsigned char data)
//according to YMF278 sample write causes some base params written to the regs (envelope+lfos)
//the game should never change the sample while playing.
{
Sample_t *Sample=ptChip->Samples+slot->Regs[1];
WriteSlot(ptChip,slot,6,Sample->LFOVIB);
WriteSlot(ptChip,slot,7,Sample->AM);
Sample_t *Sample=m_Samples+slot->Regs[1];
WriteSlot(slot,6,Sample->LFOVIB);
WriteSlot(slot,7,Sample->AM);
}
break;
case 2: //Pitch
@ -343,35 +269,35 @@ static void WriteSlot(MultiPCM *ptChip,SLOT *slot,int reg,unsigned char data)
{
unsigned int oct=((slot->Regs[3]>>4)-1)&0xf;
unsigned int pitch=((slot->Regs[3]&0xf)<<6)|(slot->Regs[2]>>2);
pitch=ptChip->FNS_Table[pitch];
pitch=m_FNS_Table[pitch];
if(oct&0x8)
pitch>>=(16-oct);
else
pitch<<=oct;
slot->step=pitch/ptChip->Rate;
slot->step=pitch/m_Rate;
}
break;
case 4: //KeyOn/Off (and more?)
{
if(data&0x80) //KeyOn
{
slot->Sample=ptChip->Samples+slot->Regs[1];
slot->Sample=m_Samples+slot->Regs[1];
slot->Playing=1;
slot->Base=slot->Sample->Start;
slot->offset=0;
slot->Prev=0;
slot->TL=slot->DstTL<<SHIFT;
EG_Calc(ptChip,slot);
EG_Calc(slot);
slot->EG.state=ATTACK;
slot->EG.volume=0;
if(slot->Base>=0x100000)
{
if(slot->Pan&8)
slot->Base=(slot->Base&0xfffff)|(ptChip->BankL);
slot->Base=(slot->Base&0xfffff)|(m_BankL);
else
slot->Base=(slot->Base&0xfffff)|(ptChip->BankR);
slot->Base=(slot->Base&0xfffff)|(m_BankR);
}
}
@ -405,8 +331,8 @@ static void WriteSlot(MultiPCM *ptChip,SLOT *slot,int reg,unsigned char data)
{
if(data)
{
LFO_ComputeStep(ptChip,&(slot->PLFO),(slot->Regs[6]>>3)&7,slot->Regs[6]&7,0);
LFO_ComputeStep(ptChip,&(slot->ALFO),(slot->Regs[6]>>3)&7,slot->Regs[7]&7,1);
LFO_ComputeStep(&(slot->PLFO),(slot->Regs[6]>>3)&7,slot->Regs[6]&7,0);
LFO_ComputeStep(&(slot->ALFO),(slot->Regs[6]>>3)&7,slot->Regs[7]&7,1);
}
}
break;
@ -414,96 +340,87 @@ static void WriteSlot(MultiPCM *ptChip,SLOT *slot,int reg,unsigned char data)
{
if(data)
{
LFO_ComputeStep(ptChip,&(slot->PLFO),(slot->Regs[6]>>3)&7,slot->Regs[6]&7,0);
LFO_ComputeStep(ptChip,&(slot->ALFO),(slot->Regs[6]>>3)&7,slot->Regs[7]&7,1);
LFO_ComputeStep(&(slot->PLFO),(slot->Regs[6]>>3)&7,slot->Regs[6]&7,0);
LFO_ComputeStep(&(slot->ALFO),(slot->Regs[6]>>3)&7,slot->Regs[7]&7,1);
}
}
break;
}
}
static STREAM_UPDATE( MultiPCM_update )
READ8_MEMBER( multipcm_device::read )
{
MultiPCM *ptChip = (MultiPCM *)param;
stream_sample_t *datap[2];
int i,sl;
datap[0] = outputs[0];
datap[1] = outputs[1];
memset(datap[0], 0, sizeof(*datap[0])*samples);
memset(datap[1], 0, sizeof(*datap[1])*samples);
for(i=0;i<samples;++i)
{
signed int smpl=0;
signed int smpr=0;
for(sl=0;sl<28;++sl)
{
SLOT *slot=ptChip->Slots+sl;
if(slot->Playing)
{
unsigned int vol=(slot->TL>>SHIFT)|(slot->Pan<<7);
unsigned int adr=slot->offset>>SHIFT;
signed int sample;
unsigned int step=slot->step;
signed int csample=(signed short) (ptChip->ROM[slot->Base+adr]<<8);
signed int fpart=slot->offset&((1<<SHIFT)-1);
sample=(csample*fpart+slot->Prev*((1<<SHIFT)-fpart))>>SHIFT;
if(slot->Regs[6]&7) //Vibrato enabled
{
step=step*PLFO_Step(&(slot->PLFO));
step>>=SHIFT;
}
slot->offset+=step;
if(slot->offset>=(slot->Sample->End<<SHIFT))
{
slot->offset=slot->Sample->Loop<<SHIFT;
}
if(adr^(slot->offset>>SHIFT))
{
slot->Prev=csample;
}
if((slot->TL>>SHIFT)!=slot->DstTL)
slot->TL+=slot->TLStep;
if(slot->Regs[7]&7) //Tremolo enabled
{
sample=sample*ALFO_Step(&(slot->ALFO));
sample>>=SHIFT;
}
sample=(sample*EG_Update(slot))>>10;
smpl+=(LPANTABLE[vol]*sample)>>SHIFT;
smpr+=(RPANTABLE[vol]*sample)>>SHIFT;
}
}
#define ICLIP16(x) (x<-32768)?-32768:((x>32767)?32767:x)
datap[0][i]=ICLIP16(smpl);
datap[1][i]=ICLIP16(smpr);
}
}
READ8_DEVICE_HANDLER( multipcm_r )
{
// MultiPCM *ptChip = get_safe_token(device);
return 0;
}
static DEVICE_START( multipcm )
WRITE8_MEMBER( multipcm_device::write )
{
MultiPCM *ptChip = get_safe_token(device);
int i;
switch(offset)
{
case 0: //Data write
WriteSlot(m_Slots+m_CurSlot,m_Address,data);
break;
case 1:
m_CurSlot=val2chan[data&0x1f];
break;
ptChip->ROM=*device->region();
ptChip->Rate=(float) device->clock() / MULTIPCM_CLOCKDIV;
case 2:
m_Address=(data>7)?7:data;
break;
}
}
ptChip->stream = device->machine().sound().stream_alloc(*device, 0, 2, ptChip->Rate, ptChip, MultiPCM_update);
/* MAME/M1 access functions */
void multipcm_device::set_bank(UINT32 leftoffs, UINT32 rightoffs)
{
m_BankL = leftoffs;
m_BankR = rightoffs;
}
const device_type MULTIPCM = &device_creator<multipcm_device>;
multipcm_device::multipcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MULTIPCM, "Sega/Yamaha 315-5560", tag, owner, clock, "multipcm", __FILE__),
device_sound_interface(mconfig, *this),
m_stream(NULL),
//m_Samples(0x200),
//m_Slots[28],
m_CurSlot(0),
m_Address(0),
m_BankR(0),
m_BankL(0),
m_Rate(0),
m_ROM(NULL)
//m_ARStep(0),
//m_DRStep(0),
//m_FNS_Table(0)
{
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void multipcm_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void multipcm_device::device_start()
{
int i;
m_ROM=*region();
m_Rate=(float) clock() / MULTIPCM_CLOCKDIV;
m_stream = machine().sound().stream_alloc(*this, 0, 2, m_Rate, this);
//Volume+pan table
for(i=0;i<0x800;++i)
@ -561,20 +478,20 @@ static DEVICE_START( multipcm )
//Pitch steps
for(i=0;i<0x400;++i)
{
float fcent=ptChip->Rate*(1024.0+(float) i)/1024.0;
ptChip->FNS_Table[i]=(unsigned int ) ((float) (1<<SHIFT) *fcent);
float fcent=m_Rate*(1024.0+(float) i)/1024.0;
m_FNS_Table[i]=(unsigned int ) ((float) (1<<SHIFT) *fcent);
}
//Envelope steps
for(i=0;i<0x40;++i)
{
//Times are based on 44100 clock, adjust to real chip clock
ptChip->ARStep[i]=(float) (0x400<<EG_SHIFT)/(BaseTimes[i]*44100.0/(1000.0));
ptChip->DRStep[i]=(float) (0x400<<EG_SHIFT)/(BaseTimes[i]*AR2DR*44100.0/(1000.0));
m_ARStep[i]=(float) (0x400<<EG_SHIFT)/(BaseTimes[i]*44100.0/(1000.0));
m_DRStep[i]=(float) (0x400<<EG_SHIFT)/(BaseTimes[i]*AR2DR*44100.0/(1000.0));
}
ptChip->ARStep[0]=ptChip->ARStep[1]=ptChip->ARStep[2]=ptChip->ARStep[3]=0;
ptChip->ARStep[0x3f]=0x400<<EG_SHIFT;
ptChip->DRStep[0]=ptChip->DRStep[1]=ptChip->DRStep[2]=ptChip->DRStep[3]=0;
m_ARStep[0]=m_ARStep[1]=m_ARStep[2]=m_ARStep[3]=0;
m_ARStep[0x3f]=0x400<<EG_SHIFT;
m_DRStep[0]=m_DRStep[1]=m_DRStep[2]=m_DRStep[3]=0;
//TL Interpolation steps
//lower
@ -592,121 +509,124 @@ static DEVICE_START( multipcm )
for(i=0;i<512;++i)
{
UINT8 *ptSample=(UINT8 *) ptChip->ROM+i*12;
ptChip->Samples[i].Start=(ptSample[0]<<16)|(ptSample[1]<<8)|(ptSample[2]<<0);
ptChip->Samples[i].Loop=(ptSample[3]<<8)|(ptSample[4]<<0);
ptChip->Samples[i].End=0xffff-((ptSample[5]<<8)|(ptSample[6]<<0));
ptChip->Samples[i].LFOVIB=ptSample[7];
ptChip->Samples[i].DR1=ptSample[8]&0xf;
ptChip->Samples[i].AR=(ptSample[8]>>4)&0xf;
ptChip->Samples[i].DR2=ptSample[9]&0xf;
ptChip->Samples[i].DL=(ptSample[9]>>4)&0xf;
ptChip->Samples[i].RR=ptSample[10]&0xf;
ptChip->Samples[i].KRS=(ptSample[10]>>4)&0xf;
ptChip->Samples[i].AM=ptSample[11];
UINT8 *ptSample=(UINT8 *) m_ROM+i*12;
m_Samples[i].Start=(ptSample[0]<<16)|(ptSample[1]<<8)|(ptSample[2]<<0);
m_Samples[i].Loop=(ptSample[3]<<8)|(ptSample[4]<<0);
m_Samples[i].End=0xffff-((ptSample[5]<<8)|(ptSample[6]<<0));
m_Samples[i].LFOVIB=ptSample[7];
m_Samples[i].DR1=ptSample[8]&0xf;
m_Samples[i].AR=(ptSample[8]>>4)&0xf;
m_Samples[i].DR2=ptSample[9]&0xf;
m_Samples[i].DL=(ptSample[9]>>4)&0xf;
m_Samples[i].RR=ptSample[10]&0xf;
m_Samples[i].KRS=(ptSample[10]>>4)&0xf;
m_Samples[i].AM=ptSample[11];
}
device->save_item(NAME(ptChip->CurSlot));
device->save_item(NAME(ptChip->Address));
device->save_item(NAME(ptChip->BankL));
device->save_item(NAME(ptChip->BankR));
save_item(NAME(m_CurSlot));
save_item(NAME(m_Address));
save_item(NAME(m_BankL));
save_item(NAME(m_BankR));
for(i=0;i<28;++i)
{
ptChip->Slots[i].Num=i;
ptChip->Slots[i].Playing=0;
m_Slots[i].Num=i;
m_Slots[i].Playing=0;
device->save_item(NAME(ptChip->Slots[i].Num), i);
device->save_item(NAME(ptChip->Slots[i].Regs), i);
device->save_item(NAME(ptChip->Slots[i].Playing), i);
device->save_item(NAME(ptChip->Slots[i].Base), i);
device->save_item(NAME(ptChip->Slots[i].offset), i);
device->save_item(NAME(ptChip->Slots[i].step), i);
device->save_item(NAME(ptChip->Slots[i].Pan), i);
device->save_item(NAME(ptChip->Slots[i].TL), i);
device->save_item(NAME(ptChip->Slots[i].DstTL), i);
device->save_item(NAME(ptChip->Slots[i].TLStep), i);
device->save_item(NAME(ptChip->Slots[i].Prev), i);
device->save_item(NAME(ptChip->Slots[i].EG.volume), i);
device->save_item(NAME(ptChip->Slots[i].EG.state), i);
device->save_item(NAME(ptChip->Slots[i].EG.step), i);
device->save_item(NAME(ptChip->Slots[i].EG.AR), i);
device->save_item(NAME(ptChip->Slots[i].EG.D1R), i);
device->save_item(NAME(ptChip->Slots[i].EG.D2R), i);
device->save_item(NAME(ptChip->Slots[i].EG.RR), i);
device->save_item(NAME(ptChip->Slots[i].EG.DL), i);
device->save_item(NAME(ptChip->Slots[i].PLFO.phase), i);
device->save_item(NAME(ptChip->Slots[i].PLFO.phase_step), i);
device->save_item(NAME(ptChip->Slots[i].ALFO.phase), i);
device->save_item(NAME(ptChip->Slots[i].ALFO.phase_step), i);
save_item(NAME(m_Slots[i].Num), i);
save_item(NAME(m_Slots[i].Regs), i);
save_item(NAME(m_Slots[i].Playing), i);
save_item(NAME(m_Slots[i].Base), i);
save_item(NAME(m_Slots[i].offset), i);
save_item(NAME(m_Slots[i].step), i);
save_item(NAME(m_Slots[i].Pan), i);
save_item(NAME(m_Slots[i].TL), i);
save_item(NAME(m_Slots[i].DstTL), i);
save_item(NAME(m_Slots[i].TLStep), i);
save_item(NAME(m_Slots[i].Prev), i);
save_item(NAME(m_Slots[i].EG.volume), i);
save_item(NAME(m_Slots[i].EG.state), i);
save_item(NAME(m_Slots[i].EG.step), i);
save_item(NAME(m_Slots[i].EG.AR), i);
save_item(NAME(m_Slots[i].EG.D1R), i);
save_item(NAME(m_Slots[i].EG.D2R), i);
save_item(NAME(m_Slots[i].EG.RR), i);
save_item(NAME(m_Slots[i].EG.DL), i);
save_item(NAME(m_Slots[i].PLFO.phase), i);
save_item(NAME(m_Slots[i].PLFO.phase_step), i);
save_item(NAME(m_Slots[i].ALFO.phase), i);
save_item(NAME(m_Slots[i].ALFO.phase_step), i);
}
LFO_Init();
}
WRITE8_DEVICE_HANDLER( multipcm_w )
{
MultiPCM *ptChip = get_safe_token(device);
switch(offset)
{
case 0: //Data write
WriteSlot(ptChip,ptChip->Slots+ptChip->CurSlot,ptChip->Address,data);
break;
case 1:
ptChip->CurSlot=val2chan[data&0x1f];
break;
case 2:
ptChip->Address=(data>7)?7:data;
break;
}
}
/* MAME/M1 access functions */
void multipcm_set_bank(device_t *device, UINT32 leftoffs, UINT32 rightoffs)
{
MultiPCM *ptChip = get_safe_token(device);
ptChip->BankL = leftoffs;
ptChip->BankR = rightoffs;
}
const device_type MULTIPCM = &device_creator<multipcm_device>;
multipcm_device::multipcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MULTIPCM, "Sega/Yamaha 315-5560", tag, owner, clock, "multipcm", __FILE__),
device_sound_interface(mconfig, *this)
{
m_token = global_alloc_clear(MultiPCM);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void multipcm_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void multipcm_device::device_start()
{
DEVICE_START_NAME( multipcm )(this);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void multipcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// should never get here
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
stream_sample_t *datap[2];
int i,sl;
datap[0] = outputs[0];
datap[1] = outputs[1];
memset(datap[0], 0, sizeof(*datap[0])*samples);
memset(datap[1], 0, sizeof(*datap[1])*samples);
for(i=0;i<samples;++i)
{
signed int smpl=0;
signed int smpr=0;
for(sl=0;sl<28;++sl)
{
SLOT *slot=m_Slots+sl;
if(slot->Playing)
{
unsigned int vol=(slot->TL>>SHIFT)|(slot->Pan<<7);
unsigned int adr=slot->offset>>SHIFT;
signed int sample;
unsigned int step=slot->step;
signed int csample=(signed short) (m_ROM[slot->Base+adr]<<8);
signed int fpart=slot->offset&((1<<SHIFT)-1);
sample=(csample*fpart+slot->Prev*((1<<SHIFT)-fpart))>>SHIFT;
if(slot->Regs[6]&7) //Vibrato enabled
{
step=step*PLFO_Step(&(slot->PLFO));
step>>=SHIFT;
}
slot->offset+=step;
if(slot->offset>=(slot->Sample->End<<SHIFT))
{
slot->offset=slot->Sample->Loop<<SHIFT;
}
if(adr^(slot->offset>>SHIFT))
{
slot->Prev=csample;
}
if((slot->TL>>SHIFT)!=slot->DstTL)
slot->TL+=slot->TLStep;
if(slot->Regs[7]&7) //Tremolo enabled
{
sample=sample*ALFO_Step(&(slot->ALFO));
sample>>=SHIFT;
}
sample=(sample*EG_Update(slot))>>10;
smpl+=(LPANTABLE[vol]*sample)>>SHIFT;
smpr+=(RPANTABLE[vol]*sample)>>SHIFT;
}
}
#define ICLIP16(x) (x<-32768)?-32768:((x>32767)?32767:x)
datap[0][i]=ICLIP16(smpl);
datap[1][i]=ICLIP16(smpr);
}
}

View File

@ -3,21 +3,71 @@
#ifndef __MULTIPCM_H__
#define __MULTIPCM_H__
struct Sample_t
{
unsigned int Start;
unsigned int Loop;
unsigned int End;
unsigned char AR,DR1,DR2,DL,RR;
unsigned char KRS;
unsigned char LFOVIB;
unsigned char AM;
};
DECLARE_WRITE8_DEVICE_HANDLER( multipcm_w );
DECLARE_READ8_DEVICE_HANDLER( multipcm_r );
enum STATE {ATTACK,DECAY1,DECAY2,RELEASE};
void multipcm_set_bank(device_t *device, UINT32 leftoffs, UINT32 rightoffs);
struct EG_t
{
int volume; //
STATE state;
int step;
//step vals
int AR; //Attack
int D1R; //Decay1
int D2R; //Decay2
int RR; //Release
int DL; //Decay level
};
struct LFO_t
{
unsigned short phase;
UINT32 phase_step;
int *table;
int *scale;
};
struct SLOT
{
unsigned char Num;
unsigned char Regs[8];
int Playing;
Sample_t *Sample;
unsigned int Base;
unsigned int offset;
unsigned int step;
unsigned int Pan,TL;
unsigned int DstTL;
int TLStep;
signed int Prev;
EG_t EG;
LFO_t PLFO; //Phase lfo
LFO_t ALFO; //AM lfo
};
class multipcm_device : public device_t,
public device_sound_interface
{
public:
multipcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~multipcm_device() { global_free(m_token); }
~multipcm_device() {}
DECLARE_WRITE8_MEMBER( write );
DECLARE_READ8_MEMBER( read );
void set_bank(UINT32 leftoffs, UINT32 rightoffs);
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
@ -25,9 +75,24 @@ protected:
// 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
void *m_token;
sound_stream * m_stream;
Sample_t m_Samples[0x200]; //Max 512 samples
SLOT m_Slots[28];
unsigned int m_CurSlot;
unsigned int m_Address;
unsigned int m_BankR, m_BankL;
float m_Rate;
INT8 *m_ROM;
//I include these in the chip because they depend on the chip clock
unsigned int m_ARStep[0x40], m_DRStep[0x40]; //Envelope step table
unsigned int m_FNS_Table[0x400]; //Frequency step table
void EG_Calc(SLOT *slot);
void LFO_ComputeStep(LFO_t *LFO,UINT32 LFOF,UINT32 LFOS,int ALFO);
void WriteSlot(SLOT *slot,int reg,unsigned char data);
};
extern const device_type MULTIPCM;

View File

@ -61,6 +61,14 @@ exidy440_sound_device::exidy440_sound_device(const machine_config &mconfig, cons
m_m6844_chain(0x00),
m_stream(NULL)
{
m_sound_banks[0] = m_sound_banks[1] = m_sound_banks[2] = m_sound_banks[3] = 0;
for (int i = 0; i < 4; i++)
{
m_sound_channel[i].base = NULL;
m_sound_channel[i].offset = 0;
m_sound_channel[i].remaining = 0;
}
}
//-------------------------------------------------
@ -100,7 +108,7 @@ void exidy440_sound_device::device_start()
save_item(NAME(m_m6844_priority));
save_item(NAME(m_m6844_interrupt));
save_item(NAME(m_m6844_chain));
m_channel_frequency[0] = clock(); /* channels 0 and 1 are run by FCLK */
m_channel_frequency[1] = clock();
m_channel_frequency[2] = clock()/2; /* channels 2 and 3 are run by SCLK */

View File

@ -24,91 +24,23 @@ TODO:
#include "emu.h"
#include "cpu/z80/z80.h"
#include "sound/sn76496.h"
#include "sound/okiadpcm.h"
#include "includes/mjkjidai.h"
#include "devlegcy.h"
#include "mcfglgcy.h"
class mjkjidai_adpcm_device : public device_t,
public device_sound_interface
{
public:
mjkjidai_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~mjkjidai_adpcm_device() { global_free(m_token); }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
// 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
void *m_token;
};
extern const device_type MJKJIDAI;
/* Start of ADPCM custom chip code */
struct mjkjidai_adpcm_state
{
oki_adpcm_state m_adpcm;
sound_stream *m_stream;
UINT32 m_current;
UINT32 m_end;
UINT8 m_nibble;
UINT8 m_playing;
UINT8 *m_base;
} _mjkjidai_adpcm_state_dummy;
static STREAM_UPDATE( mjkjidai_adpcm_callback )
{
mjkjidai_adpcm_state *state = (mjkjidai_adpcm_state *)param;
stream_sample_t *dest = outputs[0];
while (state->m_playing && samples > 0)
{
int val = (state->m_base[state->m_current] >> state->m_nibble) & 15;
state->m_nibble ^= 4;
if (state->m_nibble == 4)
{
state->m_current++;
if (state->m_current >= state->m_end)
state->m_playing = 0;
}
*dest++ = state->m_adpcm.clock(val) << 4;
samples--;
}
while (samples > 0)
{
*dest++ = 0;
samples--;
}
}
static DEVICE_START( mjkjidai_adpcm )
{
running_machine &machine = device->machine();
mjkjidai_adpcm_state *state = (mjkjidai_adpcm_state *)downcast<mjkjidai_adpcm_device *>(device)->token();
state->m_playing = 0;
state->m_stream = device->machine().sound().stream_alloc(*device, 0, 1, device->clock(), state, mjkjidai_adpcm_callback);
state->m_base = machine.root_device().memregion("adpcm")->base();
state->m_adpcm.reset();
}
const device_type MJKJIDAI = &device_creator<mjkjidai_adpcm_device>;
mjkjidai_adpcm_device::mjkjidai_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MJKJIDAI, "Custom ADPCM", tag, owner, clock, "mjkjidai_adpcm", __FILE__),
device_sound_interface(mconfig, *this)
device_sound_interface(mconfig, *this),
m_stream(NULL),
m_current(0),
m_end(0),
m_nibble(0),
m_playing(0),
m_base(NULL)
{
m_token = global_alloc_clear(mjkjidai_adpcm_state);
}
//-------------------------------------------------
@ -127,7 +59,15 @@ void mjkjidai_adpcm_device::device_config_complete()
void mjkjidai_adpcm_device::device_start()
{
DEVICE_START_NAME( mjkjidai_adpcm )(this);
m_playing = 0;
m_stream = machine().sound().stream_alloc(*this, 0, 1, clock(), this);
m_base = machine().root_device().memregion("adpcm")->base();
m_adpcm.reset();
save_item(NAME(m_current));
save_item(NAME(m_end));
save_item(NAME(m_nibble));
save_item(NAME(m_playing));
}
//-------------------------------------------------
@ -136,26 +76,41 @@ void mjkjidai_adpcm_device::device_start()
void mjkjidai_adpcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// should never get here
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
stream_sample_t *dest = outputs[0];
while (m_playing && samples > 0)
{
int val = (m_base[m_current] >> m_nibble) & 15;
m_nibble ^= 4;
if (m_nibble == 4)
{
m_current++;
if (m_current >= m_end)
m_playing = 0;
}
*dest++ = m_adpcm.clock(val) << 4;
samples--;
}
while (samples > 0)
{
*dest++ = 0;
samples--;
}
}
static void mjkjidai_adpcm_play (mjkjidai_adpcm_state *state, int offset, int length)
void mjkjidai_adpcm_device::mjkjidai_adpcm_play (int offset, int length)
{
state->m_current = offset;
state->m_end = offset + length/2;
state->m_nibble = 4;
state->m_playing = 1;
m_current = offset;
m_end = offset + length/2;
m_nibble = 4;
m_playing = 1;
}
WRITE8_MEMBER(mjkjidai_state::adpcm_w)
{
device_t *device = machine().device("adpcm");
mjkjidai_adpcm_state *state = (mjkjidai_adpcm_state *)downcast<mjkjidai_adpcm_device *>(device)->token();
mjkjidai_adpcm_play (state, (data & 0x07) * 0x1000, 0x1000 * 2);
m_mjk_adpcm->mjkjidai_adpcm_play ((data & 0x07) * 0x1000, 0x1000 * 2);
}
/* End of ADPCM custom chip code */

View File

@ -629,7 +629,6 @@ Notes:
#include "video/segaic24.h"
#include "cpu/m68000/m68000.h"
#include "cpu/mb86233/mb86233.h"
#include "sound/multipcm.h"
#include "sound/2612intf.h"
#include "machine/nvram.h"
#include "includes/model1.h"
@ -1013,13 +1012,11 @@ READ16_MEMBER(model1_state::m1_snd_v60_ready_r)
WRITE16_MEMBER(model1_state::m1_snd_mpcm_bnk1_w)
{
device_t *device = machine().device("sega1");
multipcm_set_bank(device, 0x100000 * (data & 3), 0x100000 * (data & 3));
m_multipcm_1->set_bank(0x100000 * (data & 3), 0x100000 * (data & 3));
}
WRITE16_MEMBER(model1_state::m1_snd_mpcm_bnk2_w)
{
device_t *device = machine().device("sega2");
multipcm_set_bank(device, 0x100000 * (data & 3), 0x100000 * (data & 3));
m_multipcm_2->set_bank(0x100000 * (data & 3), 0x100000 * (data & 3));
}
WRITE16_MEMBER(model1_state::m1_snd_68k_latch1_w)
{
@ -1033,10 +1030,10 @@ static ADDRESS_MAP_START( model1_snd, AS_PROGRAM, 16, model1_state )
AM_RANGE(0x000000, 0x0bffff) AM_ROM
AM_RANGE(0xc20000, 0xc20001) AM_READWRITE(m1_snd_68k_latch_r, m1_snd_68k_latch1_w )
AM_RANGE(0xc20002, 0xc20003) AM_READWRITE(m1_snd_v60_ready_r, m1_snd_68k_latch2_w )
AM_RANGE(0xc40000, 0xc40007) AM_DEVREADWRITE8_LEGACY("sega1", multipcm_r, multipcm_w, 0x00ff )
AM_RANGE(0xc40000, 0xc40007) AM_DEVREADWRITE8("sega1", multipcm_device, read, write, 0x00ff )
AM_RANGE(0xc40012, 0xc40013) AM_WRITENOP
AM_RANGE(0xc50000, 0xc50001) AM_WRITE(m1_snd_mpcm_bnk1_w )
AM_RANGE(0xc60000, 0xc60007) AM_DEVREADWRITE8_LEGACY("sega2", multipcm_r, multipcm_w, 0x00ff )
AM_RANGE(0xc60000, 0xc60007) AM_DEVREADWRITE8("sega2", multipcm_device, read, write, 0x00ff )
AM_RANGE(0xc70000, 0xc70001) AM_WRITE(m1_snd_mpcm_bnk2_w )
AM_RANGE(0xd00000, 0xd00007) AM_DEVREADWRITE8("ymsnd", ym3438_device, read, write, 0x00ff )
AM_RANGE(0xf00000, 0xf0ffff) AM_RAM

View File

@ -96,7 +96,6 @@
#include "cpu/mb86233/mb86233.h"
#include "cpu/z80/z80.h"
#include "sound/scsp.h"
#include "sound/multipcm.h"
#include "sound/2612intf.h"
#include "includes/model2.h"
@ -1808,14 +1807,12 @@ READ16_MEMBER(model2_state::m1_snd_v60_ready_r)
WRITE16_MEMBER(model2_state::m1_snd_mpcm_bnk1_w)
{
device_t *device = machine().device("sega1");
multipcm_set_bank(device, 0x100000 * (data & 0xf), 0x100000 * (data & 0xf));
m_multipcm_1->set_bank(0x100000 * (data & 0xf), 0x100000 * (data & 0xf));
}
WRITE16_MEMBER(model2_state::m1_snd_mpcm_bnk2_w)
{
device_t *device = machine().device("sega2");
multipcm_set_bank(device, 0x100000 * (data & 0xf), 0x100000 * (data & 0xf));
m_multipcm_2->set_bank(0x100000 * (data & 0xf), 0x100000 * (data & 0xf));
}
WRITE16_MEMBER(model2_state::m1_snd_68k_latch1_w)
@ -1831,10 +1828,10 @@ static ADDRESS_MAP_START( model1_snd, AS_PROGRAM, 16, model2_state )
AM_RANGE(0x080000, 0x0bffff) AM_ROM AM_REGION("audiocpu", 0x20000) // mirror of second program ROM
AM_RANGE(0xc20000, 0xc20001) AM_READWRITE(m1_snd_68k_latch_r, m1_snd_68k_latch1_w )
AM_RANGE(0xc20002, 0xc20003) AM_READWRITE(m1_snd_v60_ready_r, m1_snd_68k_latch2_w )
AM_RANGE(0xc40000, 0xc40007) AM_DEVREADWRITE8_LEGACY("sega1", multipcm_r, multipcm_w, 0x00ff )
AM_RANGE(0xc40000, 0xc40007) AM_DEVREADWRITE8("sega1", multipcm_device, read, write, 0x00ff )
AM_RANGE(0xc40012, 0xc40013) AM_WRITENOP
AM_RANGE(0xc50000, 0xc50001) AM_WRITE(m1_snd_mpcm_bnk1_w )
AM_RANGE(0xc60000, 0xc60007) AM_DEVREADWRITE8_LEGACY("sega2", multipcm_r, multipcm_w, 0x00ff )
AM_RANGE(0xc60000, 0xc60007) AM_DEVREADWRITE8("sega2", multipcm_device, read, write, 0x00ff )
AM_RANGE(0xc70000, 0xc70001) AM_WRITE(m1_snd_mpcm_bnk2_w )
AM_RANGE(0xd00000, 0xd00007) AM_DEVREADWRITE8("ymsnd", ym3438_device, read, write, 0x00ff )
AM_RANGE(0xf00000, 0xf0ffff) AM_RAM

View File

@ -642,31 +642,15 @@ WRITE_LINE_MEMBER(ninjaw_state::irqhandler)
/**************************************************************
SUBWOOFER (SOUND)
**************************************************************/
#if 0
static DEVICE_START( subwoofer )
{
/* Adjust the lowpass filter of the first three YM2610 channels */
/* The 150 Hz is a common top frequency played by a generic */
/* subwoofer, the real Arcade Machine may differs */
mixer_set_lowpass_frequency(0, 20);
mixer_set_lowpass_frequency(1, 20);
mixer_set_lowpass_frequency(2, 20);
return 0;
}
class subwoofer_device : public device_t,
public device_sound_interface
{
public:
subwoofer_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~subwoofer_device() { global_free(m_token); }
~subwoofer_device() {}
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
@ -674,9 +658,10 @@ protected:
// 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
void *m_token;
};
extern const device_type SUBWOOFER;
@ -687,7 +672,6 @@ subwoofer_device::subwoofer_device(const machine_config &mconfig, const char *ta
: device_t(mconfig, SUBWOOFER, "Subwoofer", tag, owner, clock),
device_sound_interface(mconfig, *this)
{
m_token = global_alloc_array_clear(UINT8, sizeof());
}
//-------------------------------------------------
@ -706,7 +690,16 @@ void subwoofer_device::device_config_complete()
void subwoofer_device::device_start()
{
DEVICE_START_NAME( subwoofer )(this);
/* Adjust the lowpass filter of the first three YM2610 channels */
/* The 150 Hz is a common top frequency played by a generic */
/* subwoofer, the real Arcade Machine may differs */
mixer_set_lowpass_frequency(0, 20);
mixer_set_lowpass_frequency(1, 20);
mixer_set_lowpass_frequency(2, 20);
return 0;
}
//-------------------------------------------------
@ -715,8 +708,6 @@ void subwoofer_device::device_start()
void subwoofer_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// should never get here
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
}

View File

@ -105,99 +105,23 @@ $8000 - $ffff ROM
#include "cpu/m6809/m6809.h"
#include "cpu/m6805/m6805.h"
#include "sound/3526intf.h"
#include "sound/okiadpcm.h"
#include "includes/renegade.h"
#include "devlegcy.h"
/********************************************************************************************/
struct renegade_adpcm_state
{
oki_adpcm_state m_adpcm;
sound_stream *m_stream;
UINT32 m_current;
UINT32 m_end;
UINT8 m_nibble;
UINT8 m_playing;
UINT8 *m_base;
} _renegade_adpcm_state_dummy;
class renegade_adpcm_device : public device_t,
public device_sound_interface
{
public:
renegade_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~renegade_adpcm_device() { global_free(m_token); }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
// 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
void *m_token;
};
extern const device_type RENEGADE_ADPCM;
INLINE renegade_adpcm_state *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == RENEGADE_ADPCM);
return (renegade_adpcm_state *)downcast<renegade_adpcm_device *>(device)->token();
}
static STREAM_UPDATE( renegade_adpcm_callback )
{
renegade_adpcm_state *state = (renegade_adpcm_state *)param;
stream_sample_t *dest = outputs[0];
while (state->m_playing && samples > 0)
{
int val = (state->m_base[state->m_current] >> state->m_nibble) & 15;
state->m_nibble ^= 4;
if (state->m_nibble == 4)
{
state->m_current++;
if (state->m_current >= state->m_end)
state->m_playing = 0;
}
*dest++ = state->m_adpcm.clock(val) << 4;
samples--;
}
while (samples > 0)
{
*dest++ = 0;
samples--;
}
}
static DEVICE_START( renegade_adpcm )
{
renegade_adpcm_state *state = get_safe_token(device);
state->m_playing = 0;
state->m_stream = device->machine().sound().stream_alloc(*device, 0, 1, device->clock(), state, renegade_adpcm_callback);
state->m_base = device->machine().root_device().memregion("adpcm")->base();
state->m_adpcm.reset();
}
const device_type RENEGADE_ADPCM = &device_creator<renegade_adpcm_device>;
renegade_adpcm_device::renegade_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, RENEGADE_ADPCM, "Renegade Custom ADPCM", tag, owner, clock, "renegade_adpcm", __FILE__),
device_sound_interface(mconfig, *this)
device_sound_interface(mconfig, *this),
m_stream(NULL),
m_current(0),
m_end(0),
m_nibble(0),
m_playing(0),
m_base(NULL)
{
m_token = global_alloc_clear(renegade_adpcm_state);
}
//-------------------------------------------------
@ -216,7 +140,15 @@ void renegade_adpcm_device::device_config_complete()
void renegade_adpcm_device::device_start()
{
DEVICE_START_NAME( renegade_adpcm )(this);
m_playing = 0;
m_stream = machine().sound().stream_alloc(*this, 0, 1, clock(), this);
m_base = machine().root_device().memregion("adpcm")->base();
m_adpcm.reset();
save_item(NAME(m_current));
save_item(NAME(m_end));
save_item(NAME(m_nibble));
save_item(NAME(m_playing));
}
//-------------------------------------------------
@ -225,17 +157,33 @@ void renegade_adpcm_device::device_start()
void renegade_adpcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// should never get here
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
stream_sample_t *dest = outputs[0];
while (m_playing && samples > 0)
{
int val = (m_base[m_current] >> m_nibble) & 15;
m_nibble ^= 4;
if (m_nibble == 4)
{
m_current++;
if (m_current >= m_end)
m_playing = 0;
}
*dest++ = m_adpcm.clock(val) << 4;
samples--;
}
while (samples > 0)
{
*dest++ = 0;
samples--;
}
}
WRITE8_MEMBER(renegade_state::adpcm_play_w)
WRITE8_MEMBER(renegade_adpcm_device::play_w)
{
device_t *device = machine().device("adpcm");
renegade_adpcm_state *renstate = get_safe_token(device);
int offs = (data - 0x2c) * 0x2000;
int len = 0x2000 * 2;
@ -245,13 +193,13 @@ WRITE8_MEMBER(renegade_state::adpcm_play_w)
if (offs >= 0 && offs+len <= 0x20000)
{
renstate->m_stream->update();
renstate->m_adpcm.reset();
m_stream->update();
m_adpcm.reset();
renstate->m_current = offs;
renstate->m_end = offs + len/2;
renstate->m_nibble = 4;
renstate->m_playing = 1;
m_current = offs;
m_end = offs + len/2;
m_nibble = 4;
m_playing = 1;
}
else
logerror("out of range adpcm command: 0x%02x\n", data);
@ -705,7 +653,7 @@ static ADDRESS_MAP_START( renegade_sound_map, AS_PROGRAM, 8, renegade_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM
AM_RANGE(0x1000, 0x1000) AM_READ(soundlatch_byte_r)
AM_RANGE(0x1800, 0x1800) AM_WRITENOP // this gets written the same values as 0x2000
AM_RANGE(0x2000, 0x2000) AM_WRITE(adpcm_play_w)
AM_RANGE(0x2000, 0x2000) AM_DEVWRITE("adpcm", renegade_adpcm_device, play_w)
AM_RANGE(0x2800, 0x2801) AM_DEVREADWRITE("ymsnd", ym3526_device, read, write)
AM_RANGE(0x3000, 0x3000) AM_WRITENOP /* adpcm related? stereo pan? */
AM_RANGE(0x8000, 0xffff) AM_ROM

View File

@ -338,7 +338,6 @@ orunners: Interleaved with the dj and << >> buttons is the data the drives the
#include "machine/eepromser.h"
#include "sound/2612intf.h"
#include "sound/rf5c68.h"
#include "sound/multipcm.h"
#include "radr.lh"
@ -1133,15 +1132,13 @@ WRITE8_MEMBER(segas32_state::sound_bank_hi_w)
WRITE8_MEMBER(segas32_state::multipcm_bank_w)
{
device_t *device = machine().device("sega");
multipcm_set_bank(device, 0x80000 * ((data >> 3) & 7), 0x80000 * (data & 7));
m_multipcm->set_bank(0x80000 * ((data >> 3) & 7), 0x80000 * (data & 7));
}
WRITE8_MEMBER(segas32_state::scross_bank_w)
{
multipcm_device *multipcm = machine().device<multipcm_device>("sega");
multipcm_set_bank(multipcm, 0x80000 * (data & 7), 0x80000 * (data & 7));
m_multipcm->set_bank(0x80000 * (data & 7), 0x80000 * (data & 7));
}
@ -1243,7 +1240,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( multi32_sound_map, AS_PROGRAM, 8, segas32_state )
AM_RANGE(0x0000, 0x9fff) AM_ROM AM_REGION("soundcpu", 0x100000)
AM_RANGE(0xa000, 0xbfff) AM_ROMBANK("bank1")
AM_RANGE(0xc000, 0xdfff) AM_DEVREADWRITE_LEGACY("sega", multipcm_r, multipcm_w)
AM_RANGE(0xc000, 0xdfff) AM_DEVREADWRITE("sega", multipcm_device, read, write)
AM_RANGE(0xe000, 0xffff) AM_RAM AM_SHARE("z80_shared_ram")
ADDRESS_MAP_END

View File

@ -1,3 +1,7 @@
#include "sound/okiadpcm.h"
class mjkjidai_adpcm_device;
class mjkjidai_state : public driver_device
{
public:
@ -8,13 +12,17 @@ public:
m_spriteram2(*this, "spriteram2"),
m_spriteram3(*this, "spriteram3"),
m_videoram(*this, "videoram"),
m_maincpu(*this, "maincpu") { }
m_maincpu(*this, "maincpu"),
m_mjk_adpcm(*this, "adpcm") { }
required_shared_ptr<UINT8> m_nvram;
required_shared_ptr<UINT8> m_spriteram1;
required_shared_ptr<UINT8> m_spriteram2;
required_shared_ptr<UINT8> m_spriteram3;
required_shared_ptr<UINT8> m_videoram;
required_device<cpu_device> m_maincpu;
required_device<mjkjidai_adpcm_device> m_mjk_adpcm;
int m_keyb;
int m_nvram_init_count;
@ -32,5 +40,33 @@ public:
UINT32 screen_update_mjkjidai(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(vblank_irq);
void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect);
required_device<cpu_device> m_maincpu;
};
class mjkjidai_adpcm_device : public device_t,
public device_sound_interface
{
public:
mjkjidai_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~mjkjidai_adpcm_device() {}
void mjkjidai_adpcm_play (int offset, int length);
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
// 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
oki_adpcm_state m_adpcm;
sound_stream *m_stream;
UINT32 m_current;
UINT32 m_end;
UINT8 m_nibble;
UINT8 m_playing;
UINT8 *m_base;
};
extern const device_type MJKJIDAI;

View File

@ -1,4 +1,5 @@
#include "audio/dsbz80.h"
#include "sound/multipcm.h"
typedef void (*tgp_func)(running_machine &machine);
@ -12,6 +13,8 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_multipcm_1(*this, "sega1"),
m_multipcm_2(*this, "sega2"),
m_dsbz80(*this, DSBZ80_TAG),
m_mr2(*this, "mr2"),
m_mr(*this, "mr"),
@ -21,6 +24,8 @@ public:
required_device<cpu_device> m_maincpu; // V60
required_device<cpu_device> m_audiocpu; // sound 68000
required_device<multipcm_device> m_multipcm_1;
required_device<multipcm_device> m_multipcm_2;
optional_device<dsbz80_device> m_dsbz80; // Digital Sound Board
required_shared_ptr<UINT16> m_mr2;

View File

@ -1,6 +1,7 @@
#include "video/poly.h"
#include "audio/dsbz80.h"
#include "machine/eepromser.h"
#include "sound/multipcm.h"
struct raster_state;
struct geo_state;
@ -11,7 +12,6 @@ class model2_state : public driver_device
public:
model2_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this,"maincpu"),
m_workram(*this, "workram"),
m_bufferram(*this, "bufferram"),
m_paletteram32(*this, "paletteram32"),
@ -20,15 +20,17 @@ public:
m_textureram1(*this, "textureram1"),
m_lumaram(*this, "lumaram"),
m_soundram(*this, "soundram"),
m_dsbz80(*this, DSBZ80_TAG),
m_tgp_program(*this, "tgp_program"),
m_maincpu(*this,"maincpu"),
m_dsbz80(*this, DSBZ80_TAG),
m_audiocpu(*this, "audiocpu"),
m_multipcm_1(*this, "sega1"),
m_multipcm_2(*this, "sega2"),
m_tgp(*this, "tgp"),
m_dsp(*this, "dsp"),
m_drivecpu(*this, "drivecpu"),
m_eeprom(*this, "eeprom") { }
required_device<cpu_device> m_maincpu;
required_shared_ptr<UINT32> m_workram;
required_shared_ptr<UINT32> m_bufferram;
required_shared_ptr<UINT32> m_paletteram32;
@ -37,8 +39,17 @@ public:
required_shared_ptr<UINT32> m_textureram1;
required_shared_ptr<UINT32> m_lumaram;
optional_shared_ptr<UINT16> m_soundram;
optional_device<dsbz80_device> m_dsbz80; // Z80-based MPEG Digital Sound Board
optional_shared_ptr<UINT32> m_tgp_program;
required_device<cpu_device> m_maincpu;
optional_device<dsbz80_device> m_dsbz80; // Z80-based MPEG Digital Sound Board
required_device<cpu_device> m_audiocpu;
optional_device<multipcm_device> m_multipcm_1;
optional_device<multipcm_device> m_multipcm_2;
optional_device<cpu_device> m_tgp;
optional_device<cpu_device> m_dsp;
optional_device<cpu_device> m_drivecpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
UINT32 m_intreq;
UINT32 m_intena;
@ -176,11 +187,6 @@ public:
TIMER_DEVICE_CALLBACK_MEMBER(model2c_interrupt);
void model2_exit();
DECLARE_WRITE_LINE_MEMBER(scsp_irq);
required_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_tgp;
optional_device<cpu_device> m_dsp;
optional_device<cpu_device> m_drivecpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
};
/*----------- defined in video/model2.c -----------*/

View File

@ -1,5 +1,9 @@
#include "sound/okiadpcm.h"
#define MCU_BUFFER_MAX 6
class renegade_adpcm_device;
class renegade_state : public driver_device
{
public:
@ -81,3 +85,33 @@ public:
required_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_mcu;
};
class renegade_adpcm_device : public device_t,
public device_sound_interface
{
public:
renegade_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~renegade_adpcm_device() {}
DECLARE_WRITE8_MEMBER(play_w);
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
// 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
oki_adpcm_state m_adpcm;
sound_stream *m_stream;
UINT32 m_current;
UINT32 m_end;
UINT8 m_nibble;
UINT8 m_playing;
UINT8 *m_base;
};
extern const device_type RENEGADE_ADPCM;

View File

@ -5,6 +5,7 @@
***************************************************************************/
#include "machine/eepromser.h"
#include "sound/multipcm.h"
class segas32_state : public driver_device
@ -20,6 +21,7 @@ public:
m_system32_paletteram(*this,"paletteram", 0) ,
m_maincpu(*this, "maincpu"),
m_soundcpu(*this, "soundcpu"),
m_multipcm(*this, "sega"),
m_eeprom(*this, "eeprom") { }
required_shared_ptr<UINT8> m_z80_shared_ram;
@ -27,6 +29,12 @@ public:
optional_shared_ptr<UINT16> m_system32_workram;
required_shared_ptr<UINT16> m_system32_videoram;
required_shared_ptr<UINT16> m_system32_spriteram;
optional_shared_ptr_array<UINT16, 2> m_system32_paletteram;
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
optional_device<multipcm_device> m_multipcm;
required_device<eeprom_serial_93cxx_device> m_eeprom;
typedef void (segas32_state::*sys32_output_callback)(int which, UINT16 data);
@ -68,7 +76,6 @@ public:
sys32_output_callback m_sw3_output;
UINT16* m_dual_pcb_comms;
UINT16 *m_system32_protram;
optional_shared_ptr_array<UINT16, 2> m_system32_paletteram;
UINT16 m_system32_displayenable[2];
UINT16 m_system32_tilebank_external;
UINT16 m_arescue_dsp_io[6];
@ -252,9 +259,6 @@ public:
void update_bitmap(screen_device &screen, struct layer_info *layer, const rectangle &cliprect);
void update_background(struct layer_info *layer, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(ym3438_irq_handler);
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
};
/*----------- defined in machine/segas32.c -----------*/