diff options
author | 2016-10-10 23:56:29 +0300 | |
---|---|---|
committer | 2016-10-10 23:56:29 +0300 | |
commit | 3d850be07114792395541ee554cf002cb31df00b (patch) | |
tree | 63d29ed66cdb6534e6a6bf570b2bae5a41f9f945 /src/devices/bus/sg1000_exp | |
parent | 980588badf8e80013ee60470b63a287a5bc603ba (diff) |
sms.cpp: fix Out Run sound in FM mode [Enik Land]
Diffstat (limited to 'src/devices/bus/sg1000_exp')
-rw-r--r-- | src/devices/bus/sg1000_exp/fm_unit.cpp | 51 | ||||
-rw-r--r-- | src/devices/bus/sg1000_exp/fm_unit.h | 2 |
2 files changed, 43 insertions, 10 deletions
diff --git a/src/devices/bus/sg1000_exp/fm_unit.cpp b/src/devices/bus/sg1000_exp/fm_unit.cpp index da3759ca26f..7e5e5998357 100644 --- a/src/devices/bus/sg1000_exp/fm_unit.cpp +++ b/src/devices/bus/sg1000_exp/fm_unit.cpp @@ -11,13 +11,31 @@ Release data from the Sega Retro project: Notes: -This emulation is based on Charles MacDonald's analysis of Enri's schematics -of the FM unit hardware. +The FM Unit add-on was released for the Mark III, so compatible games were +released only for that console and the Japanese SMS, that has the FM chip +built-in. The games play FM sound only when detect the FM hardware. The normal +PSG sound is replaced, except when sampled voices, not supported by the FM +chip, are played. Some games released for western SMS versions also contain FM +code, that is played on a Mark III / SMSJ when connected through a cartridge +adapter. + +The IO address map (read/write ports) is based on Charles MacDonald's analysis +of Enri's schematics of the FM unit hardware. Any software that access controllers through IO ports $C0/$C1 instead $DC/$DD (the game Fushigi no Oshiro Pit Pot is a known example) has control problems when the FM Sound Unit is attached (real hardware behavior). +TODO: + +- Confirm the assumption that PSG and FM sound are not mixed by the FM unit +and there is only FM sound when the unit is enabled. Two evidences that were +observed: every time a game with FM sound plays sampled voices through PSG, +the game disables/enables the FM chip before/after playing the PSG sound, and +a user reported, on the topic of the SMSPower Forums where the PSG/FM mixing +control of the SMSJ was discovered, that the hack that adds FM sound to Sonic +SMS version is not playing PSG sound on his Mark III with the FM unit. + **********************************************************************/ #include "fm_unit.h" @@ -33,6 +51,8 @@ const device_type SEGA_FM_UNIT = &device_creator<sega_fm_unit_device>; static MACHINE_CONFIG_FRAGMENT( fm_config ) MCFG_SOUND_ADD("ym2413", YM2413, XTAL_10_738635MHz/3) + // if this output gain is changed, the gain set when unmute the output need + // to be changed too, probably along the gain set for SMSJ/SMSKRFM drivers. MCFG_SOUND_ROUTE(ALL_OUTPUTS, ":mono", 1.00) MACHINE_CONFIG_END @@ -56,6 +76,7 @@ sega_fm_unit_device::sega_fm_unit_device(const machine_config &mconfig, const ch device_t(mconfig, SEGA_FM_UNIT, "Sega FM Sound Unit", tag, owner, clock, "sega_fm_unit", __FILE__), device_sg1000_expansion_slot_interface(mconfig, *this), m_ym(*this, "ym2413"), + m_psg(*this, ":segapsg"), m_audio_control(0) { } @@ -78,6 +99,8 @@ void sega_fm_unit_device::device_start() READ8_MEMBER(sega_fm_unit_device::peripheral_r) { + // the value previously written to the control port is returned on all + // active read offsets. if (offset <= 3) { return m_audio_control & 0x01; @@ -95,20 +118,28 @@ WRITE8_MEMBER(sega_fm_unit_device::peripheral_w) switch (offset) { case 0: // register port - if (m_audio_control == 0x01) - { - m_ym->write(space, 0, data & 0x3f); - } + m_ym->write(space, 0, data & 0x3f); break; case 1: // data port - if (m_audio_control == 0x01) - { - m_ym->write(space, 1, data); - } + m_ym->write(space, 1, data); break; case 2: // control port case 3: // mirror m_audio_control = data & 0x01; + if (m_audio_control == 0x01) + { + m_ym->set_output_gain(0, 1.0); + // assume the PSG output is muted when FM is active. + // Out Run need this. Needs confirmation (see TODO). + if (m_psg.found()) + m_psg->set_output_gain(0, 0.0); + } + else + { + m_ym->set_output_gain(0, 0.0); + if (m_psg.found()) + m_psg->set_output_gain(0, 1.0); + } break; default: break; diff --git a/src/devices/bus/sg1000_exp/fm_unit.h b/src/devices/bus/sg1000_exp/fm_unit.h index 36ee2678350..9f71ff81190 100644 --- a/src/devices/bus/sg1000_exp/fm_unit.h +++ b/src/devices/bus/sg1000_exp/fm_unit.h @@ -14,6 +14,7 @@ #include "emu.h" #include "sound/ym2413.h" +#include "sound/sn76496.h" #include "sg1000exp.h" @@ -44,6 +45,7 @@ protected: private: required_device<ym2413_device> m_ym; + optional_device<segapsg_device> m_psg; UINT8 m_audio_control; }; |