mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
aica.cpp, aicadsp.cpp : Updates (#4858)
* aica.cpp, aicadsp.cpp : Updates device_rom_interface for PCM and DSP memory, Fix code styles, Fix some namings, Reduce unnecessary lines, Reduce unused values, Use shorter/correct type values, Simplify handlers * aica.cpp : Add save state * aica.cpp : Updates device_memory_interface'd memory handlers, Reduce memset, Fix spacing
This commit is contained in:
parent
28a0152d7f
commit
8e062e927f
File diff suppressed because it is too large
Load Diff
@ -14,42 +14,44 @@
|
||||
#include "aicadsp.h"
|
||||
|
||||
|
||||
class aica_device : public device_t, public device_sound_interface
|
||||
class aica_device : public device_t, public device_sound_interface, public device_memory_interface
|
||||
{
|
||||
public:
|
||||
static constexpr feature_type imperfect_features() { return feature::SOUND; }
|
||||
|
||||
aica_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
aica_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
void set_roffset(int roffset) { m_roffset = roffset; }
|
||||
auto irq() { return m_irq_cb.bind(); }
|
||||
auto main_irq() { return m_main_irq_cb.bind(); }
|
||||
|
||||
// AICA register access
|
||||
DECLARE_READ16_MEMBER( read );
|
||||
DECLARE_WRITE16_MEMBER( write );
|
||||
u16 read(offs_t offset);
|
||||
void write(offs_t offset, u16 data, u16 mem_mask = ~0);
|
||||
|
||||
// MIDI I/O access
|
||||
DECLARE_WRITE16_MEMBER( midi_in );
|
||||
DECLARE_READ16_MEMBER( midi_out_r );
|
||||
|
||||
void set_ram_base(void *base, int size);
|
||||
void midi_in(u8 data);
|
||||
u8 midi_out_r();
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_post_load() override;
|
||||
virtual void device_clock_changed() override;
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||
|
||||
// device_memory_interface configuration
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
address_space_config m_data_config;
|
||||
private:
|
||||
enum AICA_STATE {AICA_ATTACK,AICA_DECAY1,AICA_DECAY2,AICA_RELEASE};
|
||||
|
||||
struct AICA_LFO_t
|
||||
{
|
||||
unsigned short phase;
|
||||
uint32_t phase_step;
|
||||
u16 phase;
|
||||
u32 phase_step;
|
||||
int *table;
|
||||
int *scale;
|
||||
};
|
||||
@ -72,16 +74,15 @@ private:
|
||||
{
|
||||
union
|
||||
{
|
||||
uint16_t data[0x40]; //only 0x1a bytes used
|
||||
uint8_t datab[0x80];
|
||||
u16 data[0x40]; //only 0x1a bytes used
|
||||
u8 datab[0x80];
|
||||
} udata;
|
||||
uint8_t active; //this slot is currently playing
|
||||
uint8_t *base; //samples base address
|
||||
uint32_t prv_addr; // previous play address (for ADPCM)
|
||||
uint32_t cur_addr; //current play address (24.8)
|
||||
uint32_t nxt_addr; //next play address
|
||||
uint32_t step; //pitch step (24.8)
|
||||
uint8_t Backwards; //the wave is playing backwards
|
||||
u8 active; //this slot is currently playing
|
||||
u32 prv_addr; // previous play address (for ADPCM)
|
||||
u32 cur_addr; //current play address (24.8)
|
||||
u32 nxt_addr; //next play address
|
||||
u32 step; //pitch step (24.8)
|
||||
u8 Backwards; //the wave is playing backwards
|
||||
AICA_EG_t EG; //Envelope
|
||||
AICA_LFO_t PLFO; //Phase LFO
|
||||
AICA_LFO_t ALFO; //Amplitude LFO
|
||||
@ -90,12 +91,12 @@ private:
|
||||
int cur_quant; //current ADPCM step
|
||||
int curstep;
|
||||
int cur_lpquant, cur_lpsample, cur_lpstep;
|
||||
uint8_t *adbase, *adlpbase;
|
||||
uint8_t lpend;
|
||||
u32 adbase;
|
||||
u8 lpend;
|
||||
};
|
||||
|
||||
|
||||
unsigned char DecodeSCI(unsigned char irq);
|
||||
u8 DecodeSCI(u8 irq);
|
||||
void ResetInterrupts();
|
||||
|
||||
void CheckPendingIRQ();
|
||||
@ -108,56 +109,55 @@ private:
|
||||
int Get_RR(int base,int R);
|
||||
void Compute_EG(AICA_SLOT *slot);
|
||||
int EG_Update(AICA_SLOT *slot);
|
||||
uint32_t Step(AICA_SLOT *slot);
|
||||
u32 Step(AICA_SLOT *slot);
|
||||
void Compute_LFO(AICA_SLOT *slot);
|
||||
void InitADPCM(int *PrevSignal, int *PrevQuant);
|
||||
inline signed short DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQuant);
|
||||
inline s16 DecodeADPCM(int *PrevSignal, u8 Delta, int *PrevQuant);
|
||||
void StartSlot(AICA_SLOT *slot);
|
||||
void StopSlot(AICA_SLOT *slot,int keyoff);
|
||||
void Init();
|
||||
void ClockChange();
|
||||
void UpdateSlotReg(int s,int r);
|
||||
void UpdateReg(address_space &space, int reg);
|
||||
void UpdateReg(int reg);
|
||||
void UpdateSlotRegR(int slot,int reg);
|
||||
void UpdateRegR(address_space &space, int reg);
|
||||
void w16(address_space &space,unsigned int addr,unsigned short val);
|
||||
unsigned short r16(address_space &space, unsigned int addr);
|
||||
inline int32_t UpdateSlot(AICA_SLOT *slot);
|
||||
void UpdateRegR(int reg);
|
||||
void w16(u32 addr,u16 val);
|
||||
u16 r16(u32 addr);
|
||||
inline s32 UpdateSlot(AICA_SLOT *slot);
|
||||
void DoMasterSamples(int nsamples);
|
||||
void aica_exec_dma(address_space &space);
|
||||
void exec_dma();
|
||||
|
||||
|
||||
void AICALFO_Init();
|
||||
inline signed int AICAPLFO_Step(AICA_LFO_t *LFO);
|
||||
inline signed int AICAALFO_Step(AICA_LFO_t *LFO);
|
||||
void AICALFO_ComputeStep(AICA_LFO_t *LFO,uint32_t LFOF,uint32_t LFOWS,uint32_t LFOS,int ALFO);
|
||||
void LFO_Init();
|
||||
inline s32 PLFO_Step(AICA_LFO_t *LFO);
|
||||
inline s32 ALFO_Step(AICA_LFO_t *LFO);
|
||||
void LFO_ComputeStep(AICA_LFO_t *LFO,u32 LFOF,u32 LFOWS,u32 LFOS,int ALFO);
|
||||
|
||||
double m_rate;
|
||||
int m_roffset; /* offset in the region */
|
||||
devcb_write_line m_irq_cb;
|
||||
devcb_write_line m_main_irq_cb;
|
||||
optional_memory_region m_ram_region;
|
||||
|
||||
union
|
||||
{
|
||||
uint16_t data[0xc0/2];
|
||||
uint8_t datab[0xc0];
|
||||
u16 data[0xc0/2];
|
||||
u8 datab[0xc0];
|
||||
} m_udata;
|
||||
|
||||
uint16_t m_IRQL, m_IRQR;
|
||||
uint16_t m_EFSPAN[0x48];
|
||||
u16 m_IRQL, m_IRQR;
|
||||
u16 m_EFSPAN[0x48];
|
||||
AICA_SLOT m_Slots[64];
|
||||
unsigned char *m_AICARAM;
|
||||
uint32_t m_AICARAM_LENGTH, m_RAM_MASK, m_RAM_MASK16;
|
||||
|
||||
address_space *m_data;
|
||||
memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_cache;
|
||||
sound_stream * m_stream;
|
||||
|
||||
uint32_t m_IrqTimA;
|
||||
uint32_t m_IrqTimBC;
|
||||
uint32_t m_IrqMidi;
|
||||
u32 m_IrqTimA;
|
||||
u32 m_IrqTimBC;
|
||||
u32 m_IrqMidi;
|
||||
|
||||
uint8_t m_MidiOutW,m_MidiOutR;
|
||||
uint8_t m_MidiStack[16];
|
||||
uint8_t m_MidiW,m_MidiR;
|
||||
u8 m_MidiOutW,m_MidiOutR;
|
||||
u8 m_MidiStack[16];
|
||||
u8 m_MidiW,m_MidiR;
|
||||
|
||||
int m_LPANTABLE[0x20000];
|
||||
int m_RPANTABLE[0x20000];
|
||||
@ -165,18 +165,18 @@ private:
|
||||
int m_TimPris[3];
|
||||
int m_TimCnt[3];
|
||||
|
||||
uint16_t m_mcieb, m_mcipd;
|
||||
u16 m_mcieb, m_mcipd;
|
||||
|
||||
// timers
|
||||
emu_timer *m_timerA, *m_timerB, *m_timerC;
|
||||
|
||||
// DMA stuff
|
||||
struct {
|
||||
uint32_t dmea;
|
||||
uint16_t drga;
|
||||
uint16_t dlg;
|
||||
uint8_t dgate;
|
||||
uint8_t ddir;
|
||||
u32 dmea;
|
||||
u16 drga;
|
||||
u16 dlg;
|
||||
u8 dgate;
|
||||
u8 ddir;
|
||||
} m_dma;
|
||||
|
||||
|
||||
@ -189,9 +189,7 @@ private:
|
||||
stream_sample_t *m_exts0;
|
||||
stream_sample_t *m_exts1;
|
||||
|
||||
int m_length;
|
||||
|
||||
int32_t m_EG_TABLE[0x400];
|
||||
s32 m_EG_TABLE[0x400];
|
||||
int m_PLFO_TRI[256],m_PLFO_SQR[256],m_PLFO_SAW[256],m_PLFO_NOI[256];
|
||||
int m_ALFO_TRI[256],m_ALFO_SQR[256],m_ALFO_SAW[256],m_ALFO_NOI[256];
|
||||
int m_PSCALES[8][256];
|
||||
|
@ -4,15 +4,14 @@
|
||||
#include "emu.h"
|
||||
#include "aicadsp.h"
|
||||
|
||||
static uint16_t PACK(int32_t val)
|
||||
{
|
||||
uint32_t temp;
|
||||
int sign,exponent,k;
|
||||
#include <algorithm>
|
||||
|
||||
sign = (val >> 23) & 0x1;
|
||||
temp = (val ^ (val << 1)) & 0xFFFFFF;
|
||||
exponent = 0;
|
||||
for (k=0; k<12; k++)
|
||||
static u16 PACK(s32 val)
|
||||
{
|
||||
const int sign = (val >> 23) & 0x1;
|
||||
u32 temp = (val ^ (val << 1)) & 0xFFFFFF;
|
||||
int exponent = 0;
|
||||
for (int k = 0; k < 12; k++)
|
||||
{
|
||||
if (temp & 0x800000)
|
||||
break;
|
||||
@ -28,18 +27,15 @@ static uint16_t PACK(int32_t val)
|
||||
val |= sign << 15;
|
||||
val |= exponent << 11;
|
||||
|
||||
return (uint16_t)val;
|
||||
return (u16)val;
|
||||
}
|
||||
|
||||
static int32_t UNPACK(uint16_t val)
|
||||
static s32 UNPACK(u16 val)
|
||||
{
|
||||
int sign,exponent,mantissa;
|
||||
int32_t uval;
|
||||
|
||||
sign = (val >> 15) & 0x1;
|
||||
exponent = (val >> 11) & 0xF;
|
||||
mantissa = val & 0x7FF;
|
||||
uval = mantissa << 11;
|
||||
const int sign = (val >> 15) & 0x1;
|
||||
int exponent = (val >> 11) & 0xF;
|
||||
const int mantissa = val & 0x7FF;
|
||||
u32 uval = mantissa << 11;
|
||||
if (exponent > 11)
|
||||
{
|
||||
exponent = 11;
|
||||
@ -58,84 +54,75 @@ static int32_t UNPACK(uint16_t val)
|
||||
void AICADSP::init()
|
||||
{
|
||||
memset(this,0,sizeof(*this));
|
||||
RBL=(8 * 1024); // Initial RBL is 0
|
||||
Stopped=1;
|
||||
RBL = (8 * 1024); // Initial RBL is 0
|
||||
Stopped = true;
|
||||
}
|
||||
|
||||
void AICADSP::step()
|
||||
{
|
||||
int32_t ACC=0; //26 bit
|
||||
int32_t SHIFTED=0; //24 bit
|
||||
int32_t X; //24 bit
|
||||
int32_t Y=0; //13 bit
|
||||
int32_t B; //26 bit
|
||||
int32_t INPUTS=0; //24 bit
|
||||
int32_t MEMVAL=0;
|
||||
int32_t FRC_REG=0; //13 bit
|
||||
int32_t Y_REG=0; //24 bit
|
||||
uint32_t ADDR;
|
||||
uint32_t ADRS_REG=0; //13 bit
|
||||
int step;
|
||||
s32 ACC=0; //26 bit
|
||||
s32 MEMVAL=0;
|
||||
s32 FRC_REG=0; //13 bit
|
||||
s32 Y_REG=0; //24 bit
|
||||
u32 ADRS_REG=0; //13 bit
|
||||
|
||||
if(Stopped)
|
||||
if (Stopped)
|
||||
return;
|
||||
|
||||
memset(EFREG,0,2*16);
|
||||
std::fill(std::begin(EFREG), std::end(EFREG), 0);
|
||||
#if 0
|
||||
int dump=0;
|
||||
FILE *f=nullptr;
|
||||
if(dump)
|
||||
if (dump)
|
||||
f=fopen("dsp.txt","wt");
|
||||
#endif
|
||||
for(step=0;step</*128*/LastStep;++step)
|
||||
for (int step = 0; step < /*128*/LastStep; ++step)
|
||||
{
|
||||
uint16_t *IPtr=MPRO+step*8;
|
||||
u16 *IPtr=MPRO+step*8;
|
||||
|
||||
// if(IPtr[0]==0 && IPtr[1]==0 && IPtr[2]==0 && IPtr[3]==0)
|
||||
// if (IPtr[0]==0 && IPtr[1]==0 && IPtr[2]==0 && IPtr[3]==0)
|
||||
// break;
|
||||
|
||||
uint32_t TRA=(IPtr[0]>>9)&0x7F;
|
||||
uint32_t TWT=(IPtr[0]>>8)&0x01;
|
||||
uint32_t TWA=(IPtr[0]>>1)&0x7F;
|
||||
const u32 TRA = (IPtr[0] >> 9) & 0x7F;
|
||||
const u32 TWT = (IPtr[0] >> 8) & 0x01;
|
||||
const u32 TWA = (IPtr[0] >> 1) & 0x7F;
|
||||
|
||||
uint32_t XSEL=(IPtr[2]>>15)&0x01;
|
||||
uint32_t YSEL=(IPtr[2]>>13)&0x03;
|
||||
uint32_t IRA=(IPtr[2]>>7)&0x3F;
|
||||
uint32_t IWT=(IPtr[2]>>6)&0x01;
|
||||
uint32_t IWA=(IPtr[2]>>1)&0x1F;
|
||||
const u32 XSEL = (IPtr[2] >> 15) & 0x01;
|
||||
const u32 YSEL = (IPtr[2] >> 13) & 0x03;
|
||||
const u32 IRA = (IPtr[2] >> 7) & 0x3F;
|
||||
const u32 IWT = (IPtr[2] >> 6) & 0x01;
|
||||
const u32 IWA = (IPtr[2] >> 1) & 0x1F;
|
||||
|
||||
uint32_t TABLE=(IPtr[4]>>15)&0x01;
|
||||
uint32_t MWT=(IPtr[4]>>14)&0x01;
|
||||
uint32_t MRD=(IPtr[4]>>13)&0x01;
|
||||
uint32_t EWT=(IPtr[4]>>12)&0x01;
|
||||
uint32_t EWA=(IPtr[4]>>8)&0x0F;
|
||||
uint32_t ADRL=(IPtr[4]>>7)&0x01;
|
||||
uint32_t FRCL=(IPtr[4]>>6)&0x01;
|
||||
uint32_t SHIFT=(IPtr[4]>>4)&0x03;
|
||||
uint32_t YRL=(IPtr[4]>>3)&0x01;
|
||||
uint32_t NEGB=(IPtr[4]>>2)&0x01;
|
||||
uint32_t ZERO=(IPtr[4]>>1)&0x01;
|
||||
uint32_t BSEL=(IPtr[4]>>0)&0x01;
|
||||
const u32 TABLE = (IPtr[4] >> 15) & 0x01;
|
||||
const u32 MWT = (IPtr[4] >> 14) & 0x01;
|
||||
const u32 MRD = (IPtr[4] >> 13) & 0x01;
|
||||
const u32 EWT = (IPtr[4] >> 12) & 0x01;
|
||||
const u32 EWA = (IPtr[4] >> 8) & 0x0F;
|
||||
const u32 ADRL = (IPtr[4] >> 7) & 0x01;
|
||||
const u32 FRCL = (IPtr[4] >> 6) & 0x01;
|
||||
const u32 SHIFT = (IPtr[4] >> 4) & 0x03;
|
||||
const u32 YRL = (IPtr[4] >> 3) & 0x01;
|
||||
const u32 NEGB = (IPtr[4] >> 2) & 0x01;
|
||||
const u32 ZERO = (IPtr[4] >> 1) & 0x01;
|
||||
const u32 BSEL = (IPtr[4] >> 0) & 0x01;
|
||||
|
||||
uint32_t NOFL=(IPtr[6]>>15)&1; //????
|
||||
uint32_t COEF=step;
|
||||
const u32 NOFL = (IPtr[6] >> 15) & 1; //????
|
||||
const u32 COEF = step;
|
||||
|
||||
uint32_t MASA=(IPtr[6]>>9)&0x1f; //???
|
||||
uint32_t ADREB=(IPtr[6]>>8)&0x1;
|
||||
uint32_t NXADR=(IPtr[6]>>7)&0x1;
|
||||
|
||||
int64_t v;
|
||||
const u32 MASA = (IPtr[6] >> 9) & 0x1f; //???
|
||||
const u32 ADREB = (IPtr[6] >> 8) & 0x1;
|
||||
const u32 NXADR = (IPtr[6] >> 7) & 0x1;
|
||||
|
||||
//operations are done at 24 bit precision
|
||||
#if 0
|
||||
if(MASA)
|
||||
if (MASA)
|
||||
int a=1;
|
||||
if(NOFL)
|
||||
if (NOFL)
|
||||
int a=1;
|
||||
|
||||
// int dump=0;
|
||||
|
||||
if(f)
|
||||
if (f)
|
||||
{
|
||||
#define DUMP(v) fprintf(f," " #v ": %04X",v);
|
||||
|
||||
@ -156,196 +143,190 @@ void AICADSP::step()
|
||||
#endif
|
||||
//INPUTS RW
|
||||
assert(IRA<0x32);
|
||||
if(IRA<=0x1f)
|
||||
INPUTS=MEMS[IRA];
|
||||
else if(IRA<=0x2F)
|
||||
INPUTS=MIXS[IRA-0x20]<<4; //MIXS is 20 bit
|
||||
else if(IRA<=0x31)
|
||||
INPUTS=EXTS[IRA-0x30]<<8; //EXTS is 16 bit
|
||||
s32 INPUTS=0; //24 bit
|
||||
if (IRA <= 0x1f)
|
||||
INPUTS = MEMS[IRA];
|
||||
else if (IRA <= 0x2F)
|
||||
INPUTS = MIXS[IRA - 0x20] << 4; //MIXS is 20 bit
|
||||
else if (IRA <= 0x31)
|
||||
INPUTS = EXTS[IRA - 0x30] << 8; //EXTS is 16 bit
|
||||
|
||||
INPUTS<<=8;
|
||||
INPUTS>>=8;
|
||||
//if(INPUTS&0x00800000)
|
||||
// INPUTS|=0xFF000000;
|
||||
INPUTS <<= 8;
|
||||
INPUTS >>= 8;
|
||||
//if (INPUTS & 0x00800000)
|
||||
// INPUTS |= 0xFF000000;
|
||||
|
||||
if(IWT)
|
||||
if (IWT)
|
||||
{
|
||||
MEMS[IWA]=MEMVAL; //MEMVAL was selected in previous MRD
|
||||
if(IRA==IWA)
|
||||
INPUTS=MEMVAL;
|
||||
MEMS[IWA] = MEMVAL; //MEMVAL was selected in previous MRD
|
||||
if (IRA == IWA)
|
||||
INPUTS = MEMVAL;
|
||||
}
|
||||
|
||||
//Operand sel
|
||||
//B
|
||||
if(!ZERO)
|
||||
s32 B; //26 bit
|
||||
if (!ZERO)
|
||||
{
|
||||
if(BSEL)
|
||||
B=ACC;
|
||||
if (BSEL)
|
||||
B = ACC;
|
||||
else
|
||||
{
|
||||
B=TEMP[(TRA+DEC)&0x7F];
|
||||
B<<=8;
|
||||
B>>=8;
|
||||
//if(B&0x00800000)
|
||||
// B|=0xFF000000; //Sign extend
|
||||
B = TEMP[(TRA + DEC) & 0x7F];
|
||||
B <<= 8;
|
||||
B >>= 8;
|
||||
//if (B & 0x00800000)
|
||||
// B |= 0xFF000000; //Sign extend
|
||||
}
|
||||
if(NEGB)
|
||||
B=0-B;
|
||||
if (NEGB)
|
||||
B = 0 - B;
|
||||
}
|
||||
else
|
||||
B=0;
|
||||
B = 0;
|
||||
|
||||
//X
|
||||
if(XSEL)
|
||||
X=INPUTS;
|
||||
s32 X; //24 bit
|
||||
if (XSEL)
|
||||
X = INPUTS;
|
||||
else
|
||||
{
|
||||
X=TEMP[(TRA+DEC)&0x7F];
|
||||
X<<=8;
|
||||
X>>=8;
|
||||
//if(X&0x00800000)
|
||||
// X|=0xFF000000;
|
||||
X = TEMP[(TRA + DEC) & 0x7F];
|
||||
X <<= 8;
|
||||
X >>= 8;
|
||||
//if (X & 0x00800000)
|
||||
// X |= 0xFF000000;
|
||||
}
|
||||
|
||||
//Y
|
||||
if(YSEL==0)
|
||||
Y=FRC_REG;
|
||||
else if(YSEL==1)
|
||||
Y=this->COEF[COEF<<1]>>3; //COEF is 16 bits
|
||||
else if(YSEL==2)
|
||||
Y=(Y_REG>>11)&0x1FFF;
|
||||
else if(YSEL==3)
|
||||
Y=(Y_REG>>4)&0x0FFF;
|
||||
s32 Y = 0; //13 bit
|
||||
if (YSEL == 0)
|
||||
Y = FRC_REG;
|
||||
else if (YSEL == 1)
|
||||
Y = this->COEF[COEF << 1] >> 3; //COEF is 16 bits
|
||||
else if (YSEL == 2)
|
||||
Y = (Y_REG >> 11) & 0x1FFF;
|
||||
else if (YSEL == 3)
|
||||
Y = (Y_REG >> 4) & 0x0FFF;
|
||||
|
||||
if(YRL)
|
||||
Y_REG=INPUTS;
|
||||
if (YRL)
|
||||
Y_REG = INPUTS;
|
||||
|
||||
//Shifter
|
||||
if(SHIFT==0)
|
||||
s32 SHIFTED = 0; //24 bit
|
||||
if (SHIFT == 0)
|
||||
SHIFTED = std::max<s32>(std::min<s32>(ACC, 0x007FFFFF), -0x00800000);
|
||||
else if (SHIFT == 1)
|
||||
SHIFTED = std::max<s32>(std::min<s32>(ACC * 2, 0x007FFFFF), -0x00800000);
|
||||
else if (SHIFT == 2)
|
||||
{
|
||||
SHIFTED=ACC;
|
||||
if(SHIFTED>0x007FFFFF)
|
||||
SHIFTED=0x007FFFFF;
|
||||
if(SHIFTED<(-0x00800000))
|
||||
SHIFTED=-0x00800000;
|
||||
SHIFTED = ACC * 2;
|
||||
SHIFTED <<= 8;
|
||||
SHIFTED >>= 8;
|
||||
//SHIFTED &= 0x00FFFFFF;
|
||||
//if (SHIFTED & 0x00800000)
|
||||
// SHIFTED |= 0xFF000000;
|
||||
}
|
||||
else if(SHIFT==1)
|
||||
else if (SHIFT == 3)
|
||||
{
|
||||
SHIFTED=ACC*2;
|
||||
if(SHIFTED>0x007FFFFF)
|
||||
SHIFTED=0x007FFFFF;
|
||||
if(SHIFTED<(-0x00800000))
|
||||
SHIFTED=-0x00800000;
|
||||
}
|
||||
else if(SHIFT==2)
|
||||
{
|
||||
SHIFTED=ACC*2;
|
||||
SHIFTED<<=8;
|
||||
SHIFTED>>=8;
|
||||
//SHIFTED&=0x00FFFFFF;
|
||||
//if(SHIFTED&0x00800000)
|
||||
// SHIFTED|=0xFF000000;
|
||||
}
|
||||
else if(SHIFT==3)
|
||||
{
|
||||
SHIFTED=ACC;
|
||||
SHIFTED<<=8;
|
||||
SHIFTED>>=8;
|
||||
//SHIFTED&=0x00FFFFFF;
|
||||
//if(SHIFTED&0x00800000)
|
||||
// SHIFTED|=0xFF000000;
|
||||
SHIFTED = ACC;
|
||||
SHIFTED <<= 8;
|
||||
SHIFTED >>= 8;
|
||||
//SHIFTED &= 0x00FFFFFF;
|
||||
//if (SHIFTED & 0x00800000)
|
||||
// SHIFTED |= 0xFF000000;
|
||||
}
|
||||
|
||||
//ACCUM
|
||||
Y<<=19;
|
||||
Y>>=19;
|
||||
//if(Y&0x1000)
|
||||
// Y|=0xFFFFF000;
|
||||
Y <<= 19;
|
||||
Y >>= 19;
|
||||
//if (Y & 0x1000)
|
||||
// Y |= 0xFFFFF000;
|
||||
|
||||
v=(((int64_t) X*(int64_t) Y)>>12);
|
||||
ACC=(int) v+B;
|
||||
const s64 v = (((s64)X * (s64)Y) >> 12);
|
||||
ACC = (int)v + B;
|
||||
|
||||
if(TWT)
|
||||
TEMP[(TWA+DEC)&0x7F]=SHIFTED;
|
||||
if (TWT)
|
||||
TEMP[(TWA + DEC) & 0x7F] = SHIFTED;
|
||||
|
||||
if(FRCL)
|
||||
if (FRCL)
|
||||
{
|
||||
if(SHIFT==3)
|
||||
FRC_REG=SHIFTED&0x0FFF;
|
||||
if (SHIFT == 3)
|
||||
FRC_REG = SHIFTED & 0x0FFF;
|
||||
else
|
||||
FRC_REG=(SHIFTED>>11)&0x1FFF;
|
||||
FRC_REG = (SHIFTED >> 11) & 0x1FFF;
|
||||
}
|
||||
|
||||
if(MRD || MWT)
|
||||
//if(0)
|
||||
u32 ADDR;
|
||||
if (MRD || MWT)
|
||||
//if (0)
|
||||
{
|
||||
ADDR=MADRS[MASA<<1];
|
||||
if(!TABLE)
|
||||
ADDR+=DEC;
|
||||
if(ADREB)
|
||||
ADDR+=ADRS_REG&0x0FFF;
|
||||
if(NXADR)
|
||||
ADDR = MADRS[MASA << 1];
|
||||
if (!TABLE)
|
||||
ADDR += DEC;
|
||||
if (ADREB)
|
||||
ADDR += ADRS_REG & 0x0FFF;
|
||||
if (NXADR)
|
||||
ADDR++;
|
||||
if(!TABLE)
|
||||
ADDR&=RBL-1;
|
||||
if (!TABLE)
|
||||
ADDR &= RBL - 1;
|
||||
else
|
||||
ADDR&=0xFFFF;
|
||||
//ADDR<<=1;
|
||||
//ADDR+=RBP<<13;
|
||||
//MEMVAL=AICARAM[ADDR>>1];
|
||||
ADDR+=RBP<<10;
|
||||
if(MRD && (step&1)) //memory only allowed on odd? DoA inserts NOPs on even
|
||||
ADDR &= 0xFFFF;
|
||||
//ADDR <<= 1;
|
||||
//ADDR += RBP << 13;
|
||||
//MEMVAL = space->read_word(ADDR >> 1);
|
||||
ADDR += RBP << 10;
|
||||
if (MRD && (step & 1)) //memory only allowed on odd? DoA inserts NOPs on even
|
||||
{
|
||||
if(NOFL)
|
||||
MEMVAL=AICARAM[ADDR]<<8;
|
||||
if (NOFL)
|
||||
MEMVAL = cache->read_word(ADDR) << 8;
|
||||
else
|
||||
MEMVAL=UNPACK(AICARAM[ADDR]);
|
||||
MEMVAL = UNPACK(cache->read_word(ADDR));
|
||||
}
|
||||
if(MWT && (step&1))
|
||||
if (MWT && (step&1))
|
||||
{
|
||||
if(NOFL)
|
||||
AICARAM[ADDR]=SHIFTED>>8;
|
||||
if (NOFL)
|
||||
space->write_word(ADDR, SHIFTED>>8);
|
||||
else
|
||||
AICARAM[ADDR]=PACK(SHIFTED);
|
||||
space->write_word(ADDR, PACK(SHIFTED));
|
||||
}
|
||||
}
|
||||
|
||||
if(ADRL)
|
||||
if (ADRL)
|
||||
{
|
||||
if(SHIFT==3)
|
||||
ADRS_REG=(SHIFTED>>12)&0xFFF;
|
||||
if (SHIFT == 3)
|
||||
ADRS_REG = (SHIFTED >> 12) & 0xFFF;
|
||||
else
|
||||
ADRS_REG=(INPUTS>>16);
|
||||
ADRS_REG = (INPUTS >> 16);
|
||||
}
|
||||
|
||||
if(EWT)
|
||||
EFREG[EWA]+=SHIFTED>>8;
|
||||
if (EWT)
|
||||
EFREG[EWA] += SHIFTED >> 8;
|
||||
|
||||
}
|
||||
--DEC;
|
||||
memset(MIXS,0,4*16);
|
||||
// if(f)
|
||||
std::fill(std::begin(MIXS), std::end(MIXS), 0);
|
||||
// if (f)
|
||||
// fclose(f);
|
||||
}
|
||||
|
||||
void AICADSP::setsample(int32_t sample,int SEL,int MXL)
|
||||
void AICADSP::setsample(s32 sample, u8 SEL, s32 MXL)
|
||||
{
|
||||
//MIXS[SEL]+=sample<<(MXL+1)/*7*/;
|
||||
MIXS[SEL]+=sample;
|
||||
// if(MXL)
|
||||
//MIXS[SEL] += sample << (MXL + 1)/*7*/;
|
||||
MIXS[SEL] += sample;
|
||||
// if (MXL)
|
||||
// int a=1;
|
||||
}
|
||||
|
||||
void AICADSP::start()
|
||||
{
|
||||
int i;
|
||||
Stopped=0;
|
||||
for(i=127;i>=0;--i)
|
||||
Stopped = false;
|
||||
for (i = 127; i >= 0; --i)
|
||||
{
|
||||
uint16_t *IPtr=MPRO+i*8;
|
||||
u16 *IPtr = MPRO + i * 8;
|
||||
|
||||
if(IPtr[0]!=0 || IPtr[2]!=0 || IPtr[4]!=0 || IPtr[6]!=0)
|
||||
if (IPtr[0] != 0 || IPtr[2] != 0 || IPtr[4] != 0 || IPtr[6] != 0)
|
||||
break;
|
||||
}
|
||||
LastStep=i+1;
|
||||
LastStep = i + 1;
|
||||
}
|
||||
|
@ -9,33 +9,33 @@
|
||||
struct AICADSP
|
||||
{
|
||||
void init();
|
||||
void setsample(int32_t sample, int32_t SEL, int32_t MXL);
|
||||
void setsample(s32 sample, u8 SEL, s32 MXL);
|
||||
void step();
|
||||
void start();
|
||||
|
||||
//Config
|
||||
uint16_t *AICARAM;
|
||||
uint32_t AICARAM_LENGTH;
|
||||
uint32_t RBP; //Ring buf pointer
|
||||
uint32_t RBL; //Delay ram (Ring buffer) size in words
|
||||
address_space *space;
|
||||
memory_access_cache<1, 0, ENDIANNESS_LITTLE> *cache;
|
||||
u32 RBP; //Ring buf pointer
|
||||
u32 RBL; //Delay ram (Ring buffer) size in words
|
||||
|
||||
//context
|
||||
|
||||
int16_t COEF[128*2]; //16 bit signed
|
||||
uint16_t MADRS[64*2]; //offsets (in words), 16 bit
|
||||
uint16_t MPRO[128*4*2*2]; //128 steps 64 bit
|
||||
int32_t TEMP[128]; //TEMP regs,24 bit signed
|
||||
int32_t MEMS[32]; //MEMS regs,24 bit signed
|
||||
uint32_t DEC;
|
||||
s16 COEF[128 * 2]; //16 bit signed
|
||||
u16 MADRS[64 * 2]; //offsets (in words), 16 bit
|
||||
u16 MPRO[128 * 4 * 2 * 2]; //128 steps 64 bit
|
||||
s32 TEMP[128]; //TEMP regs,24 bit signed
|
||||
s32 MEMS[32]; //MEMS regs,24 bit signed
|
||||
u32 DEC;
|
||||
|
||||
//input
|
||||
int32_t MIXS[16]; //MIXS, 24 bit signed
|
||||
int16_t EXTS[2]; //External inputs (CDDA) 16 bit signed
|
||||
s32 MIXS[16]; //MIXS, 24 bit signed
|
||||
s16 EXTS[2]; //External inputs (CDDA) 16 bit signed
|
||||
|
||||
//output
|
||||
int16_t EFREG[16]; //EFREG, 16 bit signed
|
||||
s16 EFREG[16]; //EFREG, 16 bit signed
|
||||
|
||||
int Stopped;
|
||||
bool Stopped;
|
||||
int LastStep;
|
||||
};
|
||||
|
||||
|
@ -392,7 +392,7 @@ void dc_cons_state::dc_map(address_map &map)
|
||||
map(0x00600000, 0x006007ff).rw(FUNC(dc_cons_state::dc_modem_r), FUNC(dc_cons_state::dc_modem_w));
|
||||
map(0x00700000, 0x00707fff).rw(FUNC(dc_cons_state::dc_aica_reg_r), FUNC(dc_cons_state::dc_aica_reg_w));
|
||||
map(0x00710000, 0x0071000f).mirror(0x02000000).rw("aicartc", FUNC(aicartc_device::read), FUNC(aicartc_device::write)).umask64(0x0000ffff0000ffff);
|
||||
map(0x00800000, 0x009fffff).rw(FUNC(dc_cons_state::sh4_soundram_r), FUNC(dc_cons_state::sh4_soundram_w));
|
||||
map(0x00800000, 0x009fffff).rw(FUNC(dc_cons_state::soundram_r), FUNC(dc_cons_state::soundram_w));
|
||||
// AM_RANGE(0x01000000, 0x01ffffff) G2 Ext Device #1
|
||||
// AM_RANGE(0x02700000, 0x02707fff) AICA reg mirror
|
||||
// AM_RANGE(0x02800000, 0x02ffffff) AICA wave mem mirror
|
||||
@ -433,10 +433,16 @@ void dc_cons_state::dc_port(address_map &map)
|
||||
void dc_cons_state::dc_audio_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x00000000, 0x001fffff).ram().share("dc_sound_ram"); /* shared with SH-4 */
|
||||
map(0x00000000, 0x001fffff).rw(FUNC(dc_cons_state::soundram_r), FUNC(dc_cons_state::soundram_w)); /* shared with SH-4 */
|
||||
map(0x00800000, 0x00807fff).rw(FUNC(dc_cons_state::dc_arm_aica_r), FUNC(dc_cons_state::dc_arm_aica_w));
|
||||
}
|
||||
|
||||
void dc_cons_state::aica_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x000000, 0x1fffff).ram().share("dc_sound_ram");
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( dc )
|
||||
PORT_START("P1:0")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) PORT_NAME("P1 RIGHT")
|
||||
@ -672,6 +678,7 @@ void dc_cons_state::dc(machine_config &config)
|
||||
AICA(config, m_aica, (XTAL(33'868'800)*2)/3); // 67.7376MHz(2*33.8688MHz), div 3 for audio block
|
||||
m_aica->irq().set(FUNC(dc_state::aica_irq));
|
||||
m_aica->main_irq().set(FUNC(dc_state::sh4_aica_irq));
|
||||
m_aica->set_addrmap(0, &dc_cons_state::aica_map);
|
||||
m_aica->add_route(0, "lspeaker", 1.0);
|
||||
m_aica->add_route(1, "rspeaker", 1.0);
|
||||
|
||||
|
@ -1728,7 +1728,7 @@ void naomi_state::naomi_map(address_map &map)
|
||||
map(0x00600000, 0x006007ff).mirror(0x02000000).rw(FUNC(naomi_state::dc_modem_r), FUNC(naomi_state::dc_modem_w));
|
||||
map(0x00700000, 0x00707fff).mirror(0x02000000).rw(FUNC(naomi_state::dc_aica_reg_r), FUNC(naomi_state::dc_aica_reg_w));
|
||||
map(0x00710000, 0x0071000f).mirror(0x02000000).rw("aicartc", FUNC(aicartc_device::read), FUNC(aicartc_device::write)).umask64(0x0000ffff0000ffff);
|
||||
map(0x00800000, 0x00ffffff).mirror(0x02000000).rw(FUNC(naomi_state::sh4_soundram_r), FUNC(naomi_state::sh4_soundram_w)); // sound RAM (8 MB)
|
||||
map(0x00800000, 0x00ffffff).mirror(0x02000000).rw(FUNC(naomi_state::soundram_r), FUNC(naomi_state::soundram_w)); // sound RAM (8 MB)
|
||||
|
||||
/* External Device */
|
||||
map(0x01000000, 0x01ffffff).mirror(0x02000000).r(FUNC(naomi_state::naomi_g2bus_r));
|
||||
@ -1787,7 +1787,7 @@ void naomi2_state::naomi2_map(address_map &map)
|
||||
map(0x00600000, 0x006007ff).mirror(0x02000000).rw(FUNC(naomi2_state::dc_modem_r), FUNC(naomi2_state::dc_modem_w));
|
||||
map(0x00700000, 0x00707fff).mirror(0x02000000).rw(FUNC(naomi2_state::dc_aica_reg_r), FUNC(naomi2_state::dc_aica_reg_w));
|
||||
map(0x00710000, 0x0071000f).mirror(0x02000000).rw("aicartc", FUNC(aicartc_device::read), FUNC(aicartc_device::write)).umask64(0x0000ffff0000ffff);
|
||||
map(0x00800000, 0x00ffffff).mirror(0x02000000).rw(FUNC(naomi2_state::sh4_soundram_r), FUNC(naomi2_state::sh4_soundram_w)); // sound RAM (8 MB)
|
||||
map(0x00800000, 0x00ffffff).mirror(0x02000000).rw(FUNC(naomi2_state::soundram_r), FUNC(naomi2_state::soundram_w)); // sound RAM (8 MB)
|
||||
|
||||
/* External Device */
|
||||
map(0x01000000, 0x01ffffff).mirror(0x02000000).r(FUNC(naomi2_state::naomi_g2bus_r));
|
||||
@ -1964,7 +1964,7 @@ void atomiswave_state::aw_map(address_map &map)
|
||||
map(0x00600000, 0x006007ff).rw(FUNC(atomiswave_state::aw_modem_r), FUNC(atomiswave_state::aw_modem_w));
|
||||
map(0x00700000, 0x00707fff).rw(FUNC(atomiswave_state::dc_aica_reg_r), FUNC(atomiswave_state::dc_aica_reg_w));
|
||||
map(0x00710000, 0x0071000f).mirror(0x02000000).rw("aicartc", FUNC(aicartc_device::read), FUNC(aicartc_device::write)).umask64(0x0000ffff0000ffff);
|
||||
map(0x00800000, 0x00ffffff).rw(FUNC(atomiswave_state::sh4_soundram_r), FUNC(atomiswave_state::sh4_soundram_w)); // sound RAM (8 MB)
|
||||
map(0x00800000, 0x00ffffff).rw(FUNC(atomiswave_state::soundram_r), FUNC(atomiswave_state::soundram_w)); // sound RAM (8 MB)
|
||||
|
||||
/* Area 1 - half the texture memory, like dreamcast, not naomi */
|
||||
map(0x04000000, 0x047fffff).ram().mirror(0x00800000).share("dc_texture_ram"); // texture memory 64 bit access
|
||||
@ -2008,10 +2008,16 @@ void atomiswave_state::aw_port(address_map &map)
|
||||
void dc_state::dc_audio_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x00000000, 0x007fffff).ram().share("dc_sound_ram"); /* shared with SH-4 */
|
||||
map(0x00000000, 0x007fffff).rw(FUNC(naomi_state::soundram_r), FUNC(naomi_state::soundram_w)); /* shared with SH-4 */
|
||||
map(0x00800000, 0x00807fff).rw(FUNC(dc_state::dc_arm_aica_r), FUNC(dc_state::dc_arm_aica_w));
|
||||
}
|
||||
|
||||
void dc_state::aica_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x000000, 0x7fffff).ram().share("dc_sound_ram");
|
||||
}
|
||||
|
||||
/*
|
||||
* Input ports
|
||||
*/
|
||||
@ -2908,7 +2914,6 @@ INPUT_PORTS_END
|
||||
MACHINE_RESET_MEMBER(naomi_state,naomi)
|
||||
{
|
||||
naomi_state::machine_reset();
|
||||
m_aica->set_ram_base(dc_sound_ram, 8*1024*1024);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2953,6 +2958,7 @@ void dc_state::naomi_aw_base(machine_config &config)
|
||||
AICA(config, m_aica, (XTAL(33'868'800)*2)/3); // 67.7376MHz(2*33.8688MHz), div 3 for audio block
|
||||
m_aica->irq().set(FUNC(dc_state::aica_irq));
|
||||
m_aica->main_irq().set(FUNC(dc_state::sh4_aica_irq));
|
||||
m_aica->set_addrmap(0, &dc_state::aica_map);
|
||||
m_aica->add_route(0, "lspeaker", 1.0);
|
||||
m_aica->add_route(1, "rspeaker", 1.0);
|
||||
|
||||
|
@ -35,7 +35,7 @@ class dc_state : public driver_device
|
||||
required_shared_ptr<uint64_t> dc_framebuffer_ram; // '32-bit access area'
|
||||
required_shared_ptr<uint64_t> dc_texture_ram; // '64-bit access area'
|
||||
|
||||
required_shared_ptr<uint32_t> dc_sound_ram;
|
||||
required_shared_ptr<uint16_t> dc_sound_ram;
|
||||
required_shared_ptr<uint64_t> dc_ram;
|
||||
|
||||
/* machine related */
|
||||
@ -80,8 +80,8 @@ class dc_state : public driver_device
|
||||
DECLARE_WRITE8_MEMBER( g1_irq );
|
||||
DECLARE_WRITE8_MEMBER( pvr_irq );
|
||||
DECLARE_WRITE8_MEMBER( maple_irq );
|
||||
DECLARE_READ64_MEMBER( sh4_soundram_r );
|
||||
DECLARE_WRITE64_MEMBER( sh4_soundram_w );
|
||||
DECLARE_READ16_MEMBER( soundram_r );
|
||||
DECLARE_WRITE16_MEMBER( soundram_w );
|
||||
DECLARE_WRITE_LINE_MEMBER(aica_irq);
|
||||
DECLARE_WRITE_LINE_MEMBER(sh4_aica_irq);
|
||||
|
||||
@ -98,6 +98,7 @@ class dc_state : public driver_device
|
||||
DECLARE_MACHINE_RESET(dc_console);
|
||||
|
||||
void naomi_aw_base(machine_config &config);
|
||||
void aica_map(address_map &map);
|
||||
void dc_audio_map(address_map &map);
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
|
||||
static void gdrom_config(device_t *device);
|
||||
void dc(machine_config &config);
|
||||
void aica_map(address_map &map);
|
||||
void dc_audio_map(address_map &map);
|
||||
void dc_map(address_map &map);
|
||||
void dc_port(address_map &map);
|
||||
|
@ -660,7 +660,6 @@ void dc_state::machine_start()
|
||||
// save states
|
||||
save_pointer(NAME(dc_sysctrl_regs), 0x200/4);
|
||||
save_pointer(NAME(g2bus_regs), 0x100/4);
|
||||
save_pointer(NAME(dc_sound_ram.target()),dc_sound_ram.bytes()/4);
|
||||
SAVE_G2DMA(0)
|
||||
SAVE_G2DMA(1)
|
||||
SAVE_G2DMA(2)
|
||||
@ -685,7 +684,7 @@ READ32_MEMBER(dc_state::dc_aica_reg_r)
|
||||
if(offset == 0x2c00/4)
|
||||
return m_armrst;
|
||||
|
||||
return m_aica->read(space, offset*2, 0xffff);
|
||||
return m_aica->read(offset*2);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(dc_state::dc_aica_reg_w)
|
||||
@ -709,29 +708,29 @@ WRITE32_MEMBER(dc_state::dc_aica_reg_w)
|
||||
}
|
||||
}
|
||||
|
||||
m_aica->write(space, offset*2, data, 0xffff);
|
||||
m_aica->write(offset*2, data, 0xffff);
|
||||
|
||||
// osd_printf_verbose("%s",string_format("AICA REG: [%08x=%x] write %x to %x, mask %x\n", 0x700000+reg*4, data, offset, mem_mask).c_str());
|
||||
}
|
||||
|
||||
READ32_MEMBER(dc_state::dc_arm_aica_r)
|
||||
{
|
||||
return m_aica->read(space, offset*2, 0xffff) & 0xffff;
|
||||
return m_aica->read(offset*2) & 0xffff;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(dc_state::dc_arm_aica_w)
|
||||
{
|
||||
m_aica->write(space, offset*2, data, mem_mask&0xffff);
|
||||
m_aica->write(offset*2, data, mem_mask&0xffff);
|
||||
}
|
||||
|
||||
READ64_MEMBER(dc_state::sh4_soundram_r )
|
||||
READ16_MEMBER(dc_state::soundram_r )
|
||||
{
|
||||
return *((uint64_t *)dc_sound_ram.target()+offset);
|
||||
return dc_sound_ram[offset];
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(dc_state::sh4_soundram_w )
|
||||
WRITE16_MEMBER(dc_state::soundram_w )
|
||||
{
|
||||
COMBINE_DATA((uint64_t *)dc_sound_ram.target() + offset);
|
||||
COMBINE_DATA(&dc_sound_ram[offset]);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(dc_state::aica_irq)
|
||||
@ -753,7 +752,6 @@ MACHINE_RESET_MEMBER(dc_state,dc_console)
|
||||
{
|
||||
dc_state::machine_reset();
|
||||
m_maincpu->sh2drc_set_options(SH2DRC_STRICT_VERIFY | SH2DRC_STRICT_PCREL);
|
||||
m_aica->set_ram_base(dc_sound_ram, 2*1024*1024);
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(dc_state::dc_scanline)
|
||||
|
Loading…
Reference in New Issue
Block a user