diff --git a/src/engine/platform/arcade.h b/src/engine/platform/arcade.h index 00af8f259..daa883620 100644 --- a/src/engine/platform/arcade.h +++ b/src/engine/platform/arcade.h @@ -30,7 +30,7 @@ class DivArcadeInterface: public ymfm::ymfm_interface { }; -class DivPlatformArcade: public DivPlatformOPMBase { +class DivPlatformArcade: public DivPlatformOPM { protected: const unsigned short chanOffs[8]={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 diff --git a/src/engine/platform/fmshared_OPM.h b/src/engine/platform/fmshared_OPM.h index c21d1c180..97844656d 100644 --- a/src/engine/platform/fmshared_OPM.h +++ b/src/engine/platform/fmshared_OPM.h @@ -24,7 +24,7 @@ #define NOTE_LINEAR(x) (((x)<<6)+baseFreqOff+log2(parent->song.tuning/440.0)*12.0*64.0) -class DivPlatformOPMBase: public DivPlatformFMBase { +class DivPlatformOPM: public DivPlatformFMBase { protected: const unsigned char ADDR_MULT_DT=0x40; const unsigned char ADDR_TL=0x60; @@ -41,7 +41,7 @@ class DivPlatformOPMBase: public DivPlatformFMBase { 0x00, 0x08, 0x10, 0x18 }; - DivPlatformOPMBase(): + DivPlatformOPM(): DivPlatformFMBase() {} }; diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 43ce2f5f3..45cbd619b 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1723,7 +1723,7 @@ void DivPlatformOPL::setFlags(unsigned int flags) { chipClock=3000000.0; break; case 0x04: - chipClock=31948800/8; + chipClock=38400*13*8; // 31948800/8 break; case 0x05: chipClock=3500000.0; diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index f6624b97f..e5be23045 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -472,8 +472,12 @@ void DivPlatformSMS::setFlags(unsigned int flags) { case 0x0101: chipClock=2000000; break; + case 0x0102: + chipClock=COLOR_NTSC/8.0; + break; } resetPhase=!(flags&16); + divider=16; noiseDivider=64; if (sn!=NULL) delete sn; switch (flags&0xcc) { @@ -524,8 +528,22 @@ void DivPlatformSMS::setFlags(unsigned int flags) { noiseDivider=64; stereo=false; break; + case 0x80: // TI SN94624 + sn=new sn94624_device(); + isRealSN=true; + noiseDivider=60; + stereo=false; + divider=2; + break; + case 0x84: // TI SN76494 + sn=new sn76494_device(); + isRealSN=false; // TODO + noiseDivider=68; + stereo=false; + divider=2; + break; } - rate=nuked?chipClock/16:chipClock/2; + rate=chipClock/divider; for (int i=0; i<4; i++) { oscBuf[i]->rate=rate; } diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index c4e4179fe..423995772 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -63,6 +63,7 @@ class DivPlatformSMS: public DivDispatch { size_t snBufLen; unsigned char oldValue; unsigned char snNoiseMode; + int divider=16; int noiseDivider=64; bool updateSNMode; bool resetPhase; diff --git a/src/engine/platform/sound/sn76496.cpp b/src/engine/platform/sound/sn76496.cpp index 5062ea7a8..afb82ad3a 100644 --- a/src/engine/platform/sound/sn76496.cpp +++ b/src/engine/platform/sound/sn76496.cpp @@ -171,22 +171,22 @@ sn76496_base_device::sn76496_base_device( } sn76496_device::sn76496_device() - : sn76496_base_device(0x10000, 0x04, 0x08, false, false, 8, false, true) + : sn76496_base_device(0x10000, 0x04, 0x08, false, false, 1/*8*/, false, true) { } y2404_device::y2404_device() - : sn76496_base_device(0x10000, 0x04, 0x08, false, false, 8, false, true) + : sn76496_base_device(0x10000, 0x04, 0x08, false, false, 1/*8*/, false, true) { } sn76489_device::sn76489_device() - : sn76496_base_device(0x4000, 0x01, 0x02, true, false, 8, false, true) + : sn76496_base_device(0x4000, 0x01, 0x02, true, false, 1/*8*/, false, true) { } sn76489a_device::sn76489a_device() - : sn76496_base_device(0x10000, 0x04, 0x08, false, false, 8, false, true) + : sn76496_base_device(0x10000, 0x04, 0x08, false, false, 1/*8*/, false, true) { } @@ -201,22 +201,22 @@ sn94624_device::sn94624_device() } ncr8496_device::ncr8496_device() - : sn76496_base_device(0x8000, 0x02, 0x20, true, false, 8, true, true) + : sn76496_base_device(0x8000, 0x02, 0x20, true, false, 1/*8*/, true, true) { } pssj3_device::pssj3_device() - : sn76496_base_device(0x8000, 0x02, 0x20, false, false, 8, true, true) + : sn76496_base_device(0x8000, 0x02, 0x20, false, false, 1/*8*/, true, true) { } gamegear_device::gamegear_device() - : sn76496_base_device(0x8000, 0x01, 0x08, true, true, 8, false, false) + : sn76496_base_device(0x8000, 0x01, 0x08, true, true, 1/*8*/, false, false) { } segapsg_device::segapsg_device() - : sn76496_base_device(0x8000, 0x01, 0x08, true, false, 8, false, false) + : sn76496_base_device(0x8000, 0x01, 0x08, true, false, 1/*8*/, false, false) { } diff --git a/src/engine/platform/tx81z.h b/src/engine/platform/tx81z.h index 16167ede4..e867416cf 100644 --- a/src/engine/platform/tx81z.h +++ b/src/engine/platform/tx81z.h @@ -29,7 +29,7 @@ class DivTXInterface: public ymfm::ymfm_interface { }; -class DivPlatformTX81Z: public DivPlatformOPMBase { +class DivPlatformTX81Z: public DivPlatformOPM { protected: const unsigned short chanOffs[8]={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index 3176a1a4b..42314615b 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -1027,7 +1027,7 @@ void DivPlatformYM2203::setFlags(unsigned int flags) { chipClock=3000000.0; break; case 0x04: - chipClock=31948800/8; + chipClock=38400*13*8; // 31948800/8 break; case 0x05: chipClock=3000000.0/2.0; diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index d4871486b..875f4148d 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -1400,7 +1400,7 @@ void DivPlatformYM2608::setFlags(unsigned int flags) { chipClock=8000000.0; break; case 0x01: - chipClock=31948800/4; + chipClock=38400*13*16; // 31948800/4 break; } rate=fm->sample_rate(chipClock); diff --git a/src/engine/song.h b/src/engine/song.h index a5b68c267..6bbb00cf8 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -244,6 +244,7 @@ struct DivSong { // - 0003: 1.79MHz (half NTSC) // - 0100: 3MHz // - 0101: 2MHz + // - 0102: 447KHz (NTSC / 8) // - bit 2-3, 6-7: chip type // - 00: Sega VDP (16-bit noise) // - 04: real SN76489 (15-bit noise) @@ -253,6 +254,8 @@ struct DivSong { // - 44: real SN76496 (17-bit noise) // - 48: NCR 8496 (16-bit noise) // - 4c: Tandy PSSJ-3 (16-bit noise) + // - 80: real SN94624 (15-bit noise) + // - 84: real SN76494 (17-bit noise) // - bit 4: disable noise phase reset // - YM2612/YM3438: // - bit 0-30: clock rate diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index a841f15b1..d0e63c111 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -1211,6 +1211,12 @@ void FurnaceGUI::initSystemPresets() { 0 } )); + cat.systems.push_back(FurnaceGUISysDef( + "TI-99/4A", { + DIV_SYSTEM_SMS, 64, 0, 0x182, // SN94624 447KHz + 0 + } + )); sysCategories.push_back(cat); cat=FurnaceGUISysCategory("Arcade systems","INSERT COIN"); diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index e758b1798..02d06db30 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -69,6 +69,9 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool if (ImGui::RadioButton("2MHz (Sega System 1)",(flags&0xff03)==0x0101)) { copyOfFlags=(flags&(~0xff03))|0x0101; } + if (ImGui::RadioButton("447KHz (TI-99/4A)",(flags&0xff03)==0x0102)) { + copyOfFlags=(flags&(~0xff03))|0x0102; + } ImGui::Text("Chip type:"); if (ImGui::RadioButton("Sega VDP/Master System",(flags&0xcc)==0x00)) { copyOfFlags=(flags&(~0xcc))|0x00; @@ -94,6 +97,12 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool if (ImGui::RadioButton("Tandy PSSJ 3-voice sound",(flags&0xcc)==0x4c)) { copyOfFlags=(flags&(~0xcc))|0x4c; } + if (ImGui::RadioButton("TI SN94624",(flags&0xcc)==0x80)) { + copyOfFlags=(flags&(~0xcc))|0x80; + } + if (ImGui::RadioButton("TI SN76494",(flags&0xcc)==0x84)) { + copyOfFlags=(flags&(~0xcc))|0x84; + } bool noPhaseReset=flags&16; if (ImGui::Checkbox("Disable noise period change phase reset",&noPhaseReset)) { copyOfFlags=(flags&(~16))|(noPhaseReset<<4);