summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/sg1000_exp
diff options
context:
space:
mode:
author MetalliC <0vetal0@gmail.com>2016-10-10 23:56:29 +0300
committer MetalliC <0vetal0@gmail.com>2016-10-10 23:56:29 +0300
commit3d850be07114792395541ee554cf002cb31df00b (patch)
tree63d29ed66cdb6534e6a6bf570b2bae5a41f9f945 /src/devices/bus/sg1000_exp
parent980588badf8e80013ee60470b63a287a5bc603ba (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.cpp51
-rw-r--r--src/devices/bus/sg1000_exp/fm_unit.h2
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;
};