mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
Modernized MultiPCM, mjkjidai, renegage, ninjaw_subwoofer devices [Osso]
Multisession bug fix for exidy440 audio from Osso (nw)
This commit is contained in:
parent
ad4546e878
commit
6cf4b6c27f
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 -----------*/
|
||||
|
@ -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;
|
||||
|
@ -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 -----------*/
|
||||
|
Loading…
Reference in New Issue
Block a user