diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 0a76485d2..b7fce6dea 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -242,7 +242,7 @@ void DivPlatformAmiga::notifyInsDeletion(void* ins) { } void DivPlatformAmiga::setFlags(unsigned int flags) { - if (flags) { + if (flags&1) { chipClock=COLOR_PAL*4.0/5.0; } else { chipClock=COLOR_NTSC; diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index d0a86a864..425c74f77 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -202,15 +202,15 @@ void DivPlatformArcade::tick() { if (chan[i].std.hadArp) { if (!chan[i].inPorta) { if (chan[i].std.arpMode) { - chan[i].baseFreq=chan[i].std.arp<<6; + chan[i].baseFreq=(chan[i].std.arp<<6)+baseFreqOff; } else { - chan[i].baseFreq=(chan[i].note+(signed char)chan[i].std.arp)<<6; + chan[i].baseFreq=((chan[i].note+(signed char)chan[i].std.arp)<<6)+baseFreqOff; } } chan[i].freqChanged=true; } else { if (chan[i].std.arpMode && chan[i].std.finishedArp) { - chan[i].baseFreq=chan[i].note<<6; + chan[i].baseFreq=(chan[i].note<<6)+baseFreqOff; chan[i].freqChanged=true; } } @@ -368,7 +368,7 @@ int DivPlatformArcade::dispatch(DivCommand c) { break; } chan[c.chan].pcm.pos=0; - chan[c.chan].baseFreq=c.value<<6; + chan[c.chan].baseFreq=(c.value<<6)+baseFreqOff; chan[c.chan].freqChanged=true; chan[c.chan].furnacePCM=true; if (dumpWrites) { // Sega PCM writes @@ -458,7 +458,7 @@ int DivPlatformArcade::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=c.value<<6; + chan[c.chan].baseFreq=(c.value<<6)+baseFreqOff; chan[c.chan].note=c.value; chan[c.chan].freqChanged=true; } @@ -537,7 +537,7 @@ int DivPlatformArcade::dispatch(DivCommand c) { break; } case DIV_CMD_NOTE_PORTA: { - int destFreq=c.value2<<6; + int destFreq=(c.value2<<6)+baseFreqOff; int newFreq; bool return2=false; if (destFreq>chan[c.chan].baseFreq) { @@ -562,7 +562,7 @@ int DivPlatformArcade::dispatch(DivCommand c) { break; } case DIV_CMD_LEGATO: { - chan[c.chan].baseFreq=c.value<<6; + chan[c.chan].baseFreq=(c.value<<6)+baseFreqOff; chan[c.chan].freqChanged=true; break; } @@ -754,6 +754,24 @@ void DivPlatformArcade::reset() { extMode=false; } +void DivPlatformArcade::setFlags(unsigned int flags) { + if (flags==2) { + chipClock=4000000.0; + baseFreqOff=-122; + } else if (flags==1) { + chipClock=COLOR_PAL*4.0/5.0; + baseFreqOff=12; + } else { + chipClock=COLOR_NTSC; + baseFreqOff=0; + } + if (useYMFM) { + rate=chipClock/64; + } else { + rate=chipClock/8; + } +} + bool DivPlatformArcade::isStereo() { return true; } @@ -769,12 +787,8 @@ int DivPlatformArcade::init(DivEngine* p, int channels, int sugRate, unsigned in for (int i=0; i<13; i++) { isMuted[i]=false; } - if (useYMFM) { - rate=447443/8; - fm_ymfm=new ymfm::ym2151(iface); - } else { - rate=447443; - } + setFlags(flags); + if (useYMFM) fm_ymfm=new ymfm::ym2151(iface); reset(); return 13; diff --git a/src/engine/platform/arcade.h b/src/engine/platform/arcade.h index 90629f736..4cc1e3640 100644 --- a/src/engine/platform/arcade.h +++ b/src/engine/platform/arcade.h @@ -42,7 +42,7 @@ class DivPlatformArcade: public DivDispatch { }; std::queue writes; opm_t fm; - int delay; + int delay, baseFreqOff; int pcmL, pcmR, pcmCycles; unsigned char sampleBank; unsigned char lastBusy; @@ -76,6 +76,7 @@ class DivPlatformArcade: public DivDispatch { void tick(); void muteChannel(int ch, bool mute); void notifyInsChange(int ins); + void setFlags(unsigned int flags); bool isStereo(); void setYMFM(bool use); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index f2882d8b3..2847fd065 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -24,8 +24,21 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l writes.pop(); } ay->sound_stream_update(ayBuf,len); - for (size_t i=0; i>4)&3) { + case 1: + ay=new ym2149_device(rate); + sunsoft=false; + break; + case 2: + ay=new sunsoft_5b_sound_device(rate); + sunsoft=true; + break; + default: + ay=new ay8910_device(rate); + sunsoft=false; + break; + } + ay->device_start(); + + stereo=flags>>6; } int DivPlatformAY8910::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { @@ -371,10 +427,8 @@ int DivPlatformAY8910::init(DivEngine* p, int channels, int sugRate, unsigned in for (int i=0; i<3; i++) { isMuted[i]=false; } + ay=NULL; setFlags(flags); - ay=new ay8910_device(rate); - ay->set_psg_type(ay8910_device::PSG_TYPE_AY); - ay->device_start(); ayBufLen=65536; for (int i=0; i<3; i++) ayBuf[i]=new short[ayBufLen]; reset(); @@ -383,5 +437,5 @@ int DivPlatformAY8910::init(DivEngine* p, int channels, int sugRate, unsigned in void DivPlatformAY8910::quit() { for (int i=0; i<3; i++) delete[] ayBuf[i]; - delete ay; + if (ay!=NULL) delete ay; } diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 0f05b1662..822aa5faa 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -40,6 +40,7 @@ class DivPlatformAY8910: public DivDispatch { int delay; bool extMode; + bool stereo, sunsoft; short oldWrites[16]; short pendingWrites[16]; diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 9bb54eb4f..dd3fbe96c 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -33,8 +33,16 @@ void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t l writes.pop(); } ay->sound_stream_update(ayBuf,len); - for (size_t i=0; i>6; } int DivPlatformAY8930::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 778fbafb1..36405bde8 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -33,7 +33,7 @@ class DivPlatformAY8930: public DivDispatch { int delay; - bool extMode; + bool extMode, stereo; short oldWrites[32]; short pendingWrites[32]; diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 9931c5516..4565c9b69 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -356,7 +356,7 @@ void DivPlatformC64::setChipModel(bool is6581) { } void DivPlatformC64::setFlags(unsigned int flags) { - if (flags) { + if (flags&1) { rate=COLOR_PAL*2.0/9.0; } else { rate=COLOR_NTSC*2.0/7.0; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index ce277030b..a739573b5 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -639,12 +639,14 @@ void DivPlatformGenesis::notifyInsDeletion(void* ins) { } void DivPlatformGenesis::setFlags(unsigned int flags) { - if (flags) { + if (flags==2) { + chipClock=8000000.0; + } else if (flags==1) { chipClock=COLOR_PAL*12.0/7.0; } else { chipClock=COLOR_NTSC*15.0/7.0; } - psg.setFlags(flags); + psg.setFlags(flags==1); rate=chipClock/36; } @@ -655,9 +657,8 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i for (int i=0; i<10; i++) { isMuted[i]=false; } + psg.init(p,4,sugRate,flags==1); setFlags(flags); - // PSG - psg.init(p,4,sugRate,flags); reset(); return 10; diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 7def3de7b..6b8ef535a 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -375,11 +375,15 @@ bool DivPlatformNES::keyOffAffectsArp(int ch) { } void DivPlatformNES::setFlags(unsigned int flags) { - if (flags) { + if (flags==2) { // Dendy + rate=COLOR_PAL*2.0/5.0; + apuType=2; + nes->apu.type=apuType; + } else if (flags==1) { // PAL rate=COLOR_PAL*3.0/8.0; apuType=1; nes->apu.type=apuType; - } else { + } else { // NTSC rate=COLOR_NTSC/2.0; apuType=0; nes->apu.type=apuType; diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 96dac808a..eb2c39ed3 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -397,7 +397,7 @@ void DivPlatformPCE::notifyInsDeletion(void* ins) { } void DivPlatformPCE::setFlags(unsigned int flags) { - if (flags) { // technically there is no PAL PC Engine but oh well... + if (flags&1) { // technically there is no PAL PC Engine but oh well... chipClock=COLOR_PAL*4.0/5.0; } else { chipClock=COLOR_NTSC; diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index 895bd7d5d..c37fe0831 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -308,7 +308,13 @@ void DivPlatformSAA1099::notifyInsDeletion(void* ins) { } void DivPlatformSAA1099::setFlags(unsigned int flags) { - chipClock=8000000; + if (flags==2) { + chipClock=COLOR_PAL*8.0/5.0; + } else if (flags==1) { + chipClock=COLOR_NTSC*2.0; + } else { + chipClock=8000000; + } rate=chipClock/32; } diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 6024d1675..1ab490e0c 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -57,7 +57,7 @@ void DivPlatformSMS::tick() { if (chan[3].freqChanged || updateSNMode) { updateSNMode=false; // seems arbitrary huh? - chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch-1,true); + chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch-1-(isRealSN?127:0),true); if (chan[3].freq>1023) chan[3].freq=1023; if (chan[3].note>0x5d) chan[3].freq=0x01; chan[3].freqChanged=false; @@ -222,11 +222,32 @@ void DivPlatformSMS::notifyInsDeletion(void* ins) { } void DivPlatformSMS::setFlags(unsigned int flags) { - if (flags) { + if ((flags&3)==2) { + chipClock=4000000; + } else if ((flags&3)==1) { chipClock=COLOR_PAL*4.0/5.0; } else { chipClock=COLOR_NTSC; } + if (sn!=NULL) delete sn; + switch (flags>>2) { + case 1: // TI + sn=new sn76496_base_device(0x4000, 0x4000, 0x01, 0x02, true, 1, false, true); + isRealSN=true; + break; + case 2: // TI+Atari + sn=new sn76496_base_device(0x4000, 0x0f35, 0x01, 0x02, true, 1, false, true); + isRealSN=true; + break; + case 3: // Game Gear (not fully emulated yet!) + sn=new sn76496_base_device(0x8000, 0x8000, 0x01, 0x08, false, 1, false, false); + isRealSN=false; + break; + default: // Sega + sn=new sn76496_base_device(0x8000, 0x8000, 0x01, 0x08, false, 1, false, false); + isRealSN=false; + break; + } rate=chipClock/16; } @@ -237,14 +258,14 @@ int DivPlatformSMS::init(DivEngine* p, int channels, int sugRate, unsigned int f for (int i=0; i<4; i++) { isMuted[i]=false; } + sn=NULL; setFlags(flags); - sn=new sn76496_device(rate); reset(); return 4; } void DivPlatformSMS::quit() { - delete sn; + if (sn!=NULL) delete sn; } DivPlatformSMS::~DivPlatformSMS() { diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index 8fbe38683..bf650e6c8 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -30,7 +30,8 @@ class DivPlatformSMS: public DivDispatch { bool isMuted[4]; unsigned char snNoiseMode; bool updateSNMode; - sn76496_device* sn; + bool isRealSN; + sn76496_base_device* sn; friend void putDispatchChan(void*,int,int); public: int acquireOne(); diff --git a/src/engine/platform/sound/ay8910.cpp b/src/engine/platform/sound/ay8910.cpp index 302b5a96a..bf874ec99 100644 --- a/src/engine/platform/sound/ay8910.cpp +++ b/src/engine/platform/sound/ay8910.cpp @@ -822,12 +822,12 @@ static inline void build_3D_table(double rl, const ay8910_device::ay_ym_param *p if (normalize) { for (int j = 0; j < 32*32*32*8; j++) - tab[j] = 16384 * MAX_OUTPUT * (((temp[j] - min)/(max-min))) * factor; + tab[j] = 8000 * MAX_OUTPUT * (((temp[j] - min)/(max-min))) * factor; } else { for (int j = 0; j < 32*32*32*8; j++) - tab[j] = 16384 * MAX_OUTPUT * temp[j]; + tab[j] = 8000 * MAX_OUTPUT * temp[j]; } /* for (e = 0;e<16;e++) printf("%d %d\n",e << 10, tab[e << 10]); */ diff --git a/src/engine/platform/sound/sn76496.cpp b/src/engine/platform/sound/sn76496.cpp index 6e584e1ab..351c94d86 100644 --- a/src/engine/platform/sound/sn76496.cpp +++ b/src/engine/platform/sound/sn76496.cpp @@ -145,19 +145,20 @@ #define MAX_OUTPUT 0x7fff -#define NOISE_START 0x8000 +//#define NOISE_START 0x8000 //#define NOISE_START 0x0f35 sn76496_base_device::sn76496_base_device( int feedbackmask, + int noise_start, int noisetap1, int noisetap2, bool negate, int clockdivider, bool ncr, - bool sega, - uint32_t clock) + bool sega) : m_feedback_mask(feedbackmask) + , m_noise_start(noise_start) , m_whitenoise_tap1(noisetap1) , m_whitenoise_tap2(noisetap2) , m_negate(negate) @@ -167,8 +168,8 @@ sn76496_base_device::sn76496_base_device( { } -sn76496_device::sn76496_device(uint32_t clock) - : sn76496_base_device(0x8000, 0x01, 0x08, false, 1, false, false, clock) +sn76496_device::sn76496_device() + : sn76496_base_device(0x8000, 0x8000, 0x01, 0x08, false, 1, false, false) { } @@ -195,7 +196,7 @@ void sn76496_base_device::device_start() m_count[i] = 0; } - m_RNG = NOISE_START; + m_RNG = m_feedback_mask; m_output[3] = m_RNG & 1; m_current_clock = m_clock_divider-1; @@ -232,7 +233,7 @@ void sn76496_base_device::write(u8 data) { r = (data & 0x70) >> 4; m_last_register = r; - if (((m_ncr_style_psg) && (r == 6)) && ((data&0x04) != (m_register[6]&0x04))) m_RNG = NOISE_START; // NCR-style PSG resets the LFSR only on a mode write which actually changes the state of bit 2 of register 6 + if (((m_ncr_style_psg) && (r == 6)) && ((data&0x04) != (m_register[6]&0x04))) m_RNG = m_noise_start; // NCR-style PSG resets the LFSR only on a mode write which actually changes the state of bit 2 of register 6 m_register[r] = (m_register[r] & 0x3f0) | (data & 0x0f); } else @@ -271,7 +272,7 @@ void sn76496_base_device::write(u8 data) n = m_register[6]; // N/512,N/1024,N/2048,Tone #3 output m_period[3] = ((n&3) == 3)? (m_period[2]<<1) : (1 << (5+(n&3))); - if (!(m_ncr_style_psg)) m_RNG = NOISE_START; + if (!(m_ncr_style_psg)) m_RNG = m_noise_start; } break; } diff --git a/src/engine/platform/sound/sn76496.h b/src/engine/platform/sound/sn76496.h index 0dda93ecf..2387574d1 100644 --- a/src/engine/platform/sound/sn76496.h +++ b/src/engine/platform/sound/sn76496.h @@ -18,16 +18,15 @@ public: void sound_stream_update(short* outputs, int outLen); //DECLARE_READ_LINE_MEMBER( ready_r ) { return m_ready_state ? 1 : 0; } -protected: sn76496_base_device( int feedbackmask, + int noise_start, int noisetap1, int noisetap2, bool negate, int clockdivider, bool ncr, - bool sega, - uint32_t clock); + bool sega); private: inline bool in_noise_mode(); @@ -35,6 +34,7 @@ private: bool m_ready_state; const int32_t m_feedback_mask; // mask for feedback + const int32_t m_noise_start; // noise start value const int32_t m_whitenoise_tap1; // mask for white noise tap 1 (higher one, usually bit 14) const int32_t m_whitenoise_tap2; // mask for white noise tap 2 (lower one, usually bit 13) bool m_negate; // output negate flag @@ -42,7 +42,6 @@ private: const bool m_ncr_style_psg; // flag to ignore writes to regs 1,3,5,6,7 with bit 7 low const bool m_sega_style_psg; // flag to make frequency zero acts as if it is one more than max (0x3ff+1) or if it acts like 0; the initial register is pointing to 0x3 instead of 0x0; the volume reg is preloaded with 0xF instead of 0x0 - int32_t m_clock; int32_t m_vol_table[16]; // volume table (for 4-bit to db conversion) int32_t m_register[8]; // registers int32_t m_last_register; // last register written @@ -58,7 +57,7 @@ private: class sn76496_device : public sn76496_base_device { public: - sn76496_device(uint32_t clock); + sn76496_device(); }; #endif // MAME_SOUND_SN76496_H diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index 94f768354..ea69978f5 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -255,11 +255,12 @@ void DivPlatformTIA::notifyInsDeletion(void* ins) { } void DivPlatformTIA::setFlags(unsigned int flags) { - if (flags) { + if (flags&1) { rate=31250; } else { - rate=31400; + rate=31468; } + chipClock=rate; } int DivPlatformTIA::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index a79541944..2b11b7248 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4580,9 +4580,9 @@ bool FurnaceGUI::loop() { if (ImGui::RadioButton("TI SN76489 with Atari-like short noise",(flags>>2)==2)) { e->setSysFlags(i,(flags&3)|8); } - if (ImGui::RadioButton("Game Gear",(flags>>2)==3)) { + /*if (ImGui::RadioButton("Game Gear",(flags>>2)==3)) { e->setSysFlags(i,(flags&3)|12); - } + }*/ break; case DIV_SYSTEM_ARCADE: case DIV_SYSTEM_YM2151: @@ -4650,9 +4650,11 @@ bool FurnaceGUI::loop() { } } bool stereo=flags&0x40; + ImGui::BeginDisabled((flags&0x30)==32); if (ImGui::Checkbox("Stereo##_AY_STEREO",&stereo)) { e->setSysFlags(i,(flags&(~0x40))|(stereo?0x40:0)); } + ImGui::EndDisabled(); break; } case DIV_SYSTEM_SAA1099: @@ -4667,12 +4669,13 @@ bool FurnaceGUI::loop() { } break; case DIV_SYSTEM_AMIGA: + /* TODO LATER: I want 0.5 out already if (ImGui::RadioButton("Amiga 500 (OCS)",(flags&2)==0)) { e->setSysFlags(i,flags&1); } if (ImGui::RadioButton("Amiga 1200 (AGA)",(flags&2)==2)) { e->setSysFlags(i,(flags&1)|2); - } + }*/ sysPal=flags&1; if (ImGui::Checkbox("PAL",&sysPal)) { e->setSysFlags(i,(flags&2)|sysPal);