summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author etabeta78 <etabeta78@users.noreply.github.com>2015-04-24 11:08:10 +0200
committer etabeta78 <etabeta78@users.noreply.github.com>2015-04-24 11:08:10 +0200
commitd7b972048e8594da3631634f03e28561fdd899e0 (patch)
treee3721625257186db6a36997089a3b459e52bd275
parentdfd7ac44a4e7d8319152152e1121c06b45097689 (diff)
(MESS) sms.c: misc improvements: [Enik Land]
- when GG runs in SMS compatibility mode, avoid access to the PSG stereo register. - implement the audio control that enables/disables the PSG chip on Japanese SMS. - play FM sound only when FM chip is enabled. - remove mirrors of the IO and memory control ports on the GG driver, fixing emulation of G-LOC Air Battle.
-rw-r--r--src/mess/drivers/sms.c34
-rw-r--r--src/mess/includes/sms.h13
-rw-r--r--src/mess/machine/sms.c87
3 files changed, 77 insertions, 57 deletions
diff --git a/src/mess/drivers/sms.c b/src/mess/drivers/sms.c
index 30299616356..d6c029b5434 100644
--- a/src/mess/drivers/sms.c
+++ b/src/mess/drivers/sms.c
@@ -13,18 +13,17 @@
To do:
- SIO interface for Game Gear (needs netplay, I guess)
- - Sega Demo Unit II (kiosk expansion device)
- - SMS 8 slot game changer (kiosk expansion device)
- - SMS Disk System (floppy disk drive expansion device) - unreleased
+ - Support for other DE-9 compatible controllers, like the Mega Drive 6-Button
+ that has homebrew software support
- Rapid button of Japanese Master System
- Keyboard support for Sega Mark III (sg1000m3 driver)
- Link between two Mark III's through keyboard, supported by F-16 Fighting Falcon
- Mark III expansion slot, used by keyboard and FM module
- - Disabling of the SN76489 PSG chip on smsj system (sms1krfm not confirmed)
- Software compatibility flags, by region and/or BIOS
+ - Sega Demo Unit II (kiosk expansion device)
+ - SMS 8 slot game changer (kiosk expansion device)
+ - SMS Disk System (floppy disk drive expansion device) - unreleased
- Emulate SRAM cartridges? (for use with Bock's dump tool)
- - Support for other DE-9 compatible controllers, like the Mega Drive 6-Button
- that has homebrew software support
The Game Gear SIO hardware is not emulated but has some
placeholders in 'machine/sms.c'
@@ -293,8 +292,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( sg1000m3_io, AS_IO, 8, sms_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
ADDRESS_MAP_UNMAP_HIGH
- AM_RANGE(0x40, 0x7f) AM_READ(sms_count_r)
- AM_RANGE(0x40, 0x7f) AM_DEVWRITE("segapsg", segapsg_device, write)
+ AM_RANGE(0x40, 0x7f) AM_READWRITE(sms_count_r, sms_psg_w)
AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write)
AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write)
AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_dc_r)
@@ -303,7 +301,7 @@ static ADDRESS_MAP_START( sg1000m3_io, AS_IO, 8, sms_state )
AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_dd_r)
AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_dc_r, sms_ym2413_register_port_w)
AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_dd_r, sms_ym2413_data_port_w)
- AM_RANGE(0xf2, 0xf2) AM_READWRITE(sms_fm_detect_r, sms_fm_detect_w)
+ AM_RANGE(0xf2, 0xf2) AM_READWRITE(sms_audio_control_r, sms_audio_control_w)
AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_dd_r)
AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_dc_r)
AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_dd_r)
@@ -331,7 +329,7 @@ static ADDRESS_MAP_START( smsj_io, AS_IO, 8, sms_state )
ADDRESS_MAP_END
-// The first Korean version also seems to lack I/O port $3F.
+// The first Korean SMS version also seems to lack I/O port $3F.
// Games detect the first version as Japanese region (opposite to the second
// version). The region detection tests the behavior of the TH bits of port
// $DD. Port $3F sets the mode used by those bits. If the first version would
@@ -344,21 +342,17 @@ static ADDRESS_MAP_START( sms1kr_io, AS_IO, 8, sms_state )
ADDRESS_MAP_END
+// It seems the mirrors for I/O ports $3E/$3F also don't seem to exist on the
+// Game Gear. Leaving the mirrors breaks 'gloc' (it freezes after 1st stage).
static ADDRESS_MAP_START( gg_io, AS_IO, 8, sms_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x00, 0x00) AM_READ(gg_input_port_00_r)
AM_RANGE(0x01, 0x05) AM_READWRITE(gg_sio_r, gg_sio_w)
- AM_RANGE(0x06, 0x06) AM_DEVWRITE("gamegear", gamegear_device, stereo_w)
- AM_RANGE(0x07, 0x07) AM_WRITE(sms_io_control_w)
- AM_RANGE(0x08, 0x08) AM_MIRROR(0x06) AM_WRITE(sms_mem_control_w)
- AM_RANGE(0x09, 0x09) AM_MIRROR(0x06) AM_WRITE(sms_io_control_w)
- AM_RANGE(0x10, 0x10) AM_MIRROR(0x0e) AM_WRITE(sms_mem_control_w)
- AM_RANGE(0x11, 0x11) AM_MIRROR(0x0e) AM_WRITE(sms_io_control_w)
- AM_RANGE(0x20, 0x20) AM_MIRROR(0x1e) AM_WRITE(sms_mem_control_w)
- AM_RANGE(0x21, 0x21) AM_MIRROR(0x1e) AM_WRITE(sms_io_control_w)
- AM_RANGE(0x40, 0x7f) AM_READ(sms_count_r)
- AM_RANGE(0x40, 0x7f) AM_DEVWRITE("gamegear", gamegear_device, write)
+ AM_RANGE(0x06, 0x06) AM_WRITE(gg_psg_stereo_w)
+ AM_RANGE(0x3e, 0x3e) AM_WRITE(sms_mem_control_w)
+ AM_RANGE(0x3f, 0x3f) AM_WRITE(sms_io_control_w)
+ AM_RANGE(0x40, 0x7f) AM_READWRITE(sms_count_r, gg_psg_w)
AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write)
AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write)
AM_RANGE(0xc0, 0xc0) AM_READ(sms_input_port_dc_r)
diff --git a/src/mess/includes/sms.h b/src/mess/includes/sms.h
index c6f85a0e735..aa7eb1b5d37 100644
--- a/src/mess/includes/sms.h
+++ b/src/mess/includes/sms.h
@@ -33,6 +33,8 @@ public:
m_maincpu(*this, "maincpu"),
m_vdp(*this, "sms_vdp"),
m_main_scr(*this, "screen"),
+ m_psg_sms(*this, "segapsg"),
+ m_psg_gg(*this, "gamegear"),
m_ym(*this, "ym2413"),
m_port_ctrl1(*this, CONTROL1_TAG),
m_port_ctrl2(*this, CONTROL2_TAG),
@@ -62,6 +64,8 @@ public:
required_device<cpu_device> m_maincpu;
required_device<sega315_5124_device> m_vdp;
required_device<screen_device> m_main_scr;
+ optional_device<segapsg_device> m_psg_sms;
+ optional_device<gamegear_device> m_psg_gg;
optional_device<ym2413_device> m_ym;
optional_device<sms_control_port_device> m_port_ctrl1;
optional_device<sms_control_port_device> m_port_ctrl2;
@@ -116,7 +120,7 @@ public:
UINT8 m_io_ctrl_reg;
UINT8 m_mem_ctrl_reg;
UINT8 m_mem_device_enabled;
- UINT8 m_fm_detect;
+ UINT8 m_audio_control;
UINT8 m_port_dc_reg;
UINT8 m_port_dd_reg;
UINT8 m_gg_sio[5];
@@ -164,8 +168,11 @@ public:
DECLARE_READ8_MEMBER(gg_input_port_00_r);
DECLARE_READ8_MEMBER(gg_sio_r);
DECLARE_WRITE8_MEMBER(gg_sio_w);
- DECLARE_READ8_MEMBER(sms_fm_detect_r);
- DECLARE_WRITE8_MEMBER(sms_fm_detect_w);
+ DECLARE_WRITE8_MEMBER(gg_psg_stereo_w);
+ DECLARE_WRITE8_MEMBER(gg_psg_w);
+ DECLARE_WRITE8_MEMBER(sms_psg_w);
+ DECLARE_READ8_MEMBER(sms_audio_control_r);
+ DECLARE_WRITE8_MEMBER(sms_audio_control_w);
DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_w);
DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_w);
DECLARE_READ8_MEMBER(sms_sscope_r);
diff --git a/src/mess/machine/sms.c b/src/mess/machine/sms.c
index 6cc56fc1302..402caedba67 100644
--- a/src/mess/machine/sms.c
+++ b/src/mess/machine/sms.c
@@ -1,6 +1,7 @@
#include "emu.h"
#include "crsshair.h"
#include "video/315_5124.h"
+#include "sound/sn76496.h"
#include "sound/2413intf.h"
#include "includes/sms.h"
@@ -124,34 +125,6 @@ void sms_state::sms_get_inputs()
}
-WRITE8_MEMBER(sms_state::sms_fm_detect_w)
-{
- if (m_has_fm)
- m_fm_detect = (data & 0x01);
-}
-
-
-READ8_MEMBER(sms_state::sms_fm_detect_r)
-{
- if (m_has_fm)
- {
- return m_fm_detect;
- }
- else
- {
- if (!m_is_mark_iii && (m_mem_ctrl_reg & IO_CHIP))
- {
- return 0xff;
- }
- else
- {
- sms_get_inputs();
- return m_port_dc_reg;
- }
- }
-}
-
-
WRITE8_MEMBER(sms_state::sms_io_control_w)
{
bool latch_hcount = false;
@@ -400,16 +373,37 @@ READ8_MEMBER(sms_state::sms_input_port_dd_r)
}
-WRITE8_MEMBER(sms_state::sms_ym2413_register_port_w)
+WRITE8_MEMBER(sms_state::sms_audio_control_w)
{
if (m_has_fm)
- m_ym->write(space, 0, (data & 0x3f));
+ {
+ if (m_is_smsj)
+ m_audio_control = data & 0x03;
+ else
+ m_audio_control = data & 0x01;
+ }
}
-WRITE8_MEMBER(sms_state::sms_ym2413_data_port_w)
+READ8_MEMBER(sms_state::sms_audio_control_r)
{
if (m_has_fm)
+ return m_audio_control & 0x01; // just one bit even for smsj.
+ else
+ return sms_input_port_dc_r(space, offset);
+}
+
+
+WRITE8_MEMBER(sms_state::sms_ym2413_register_port_w)
+{
+ if (m_has_fm && (m_audio_control & 0x01))
+ m_ym->write(space, 0, data & 0x3f);
+}
+
+
+WRITE8_MEMBER(sms_state::sms_ym2413_data_port_w)
+{
+ if (m_has_fm && (m_audio_control & 0x01))
{
//logerror("data_port_w %x %x\n", offset, data);
m_ym->write(space, 1, data);
@@ -417,6 +411,31 @@ WRITE8_MEMBER(sms_state::sms_ym2413_data_port_w)
}
+WRITE8_MEMBER(sms_state::sms_psg_w)
+{
+ // On Japanese SMS, if FM is enabled, PSG must be explicitly enabled too.
+ if (m_is_smsj && (m_audio_control & 0x01) && !(m_audio_control & 0x02))
+ return;
+
+ m_psg_sms->write(space, offset, data, mem_mask);
+}
+
+
+WRITE8_MEMBER(sms_state::gg_psg_w)
+{
+ m_psg_gg->write(space, offset, data, mem_mask);
+}
+
+
+WRITE8_MEMBER(sms_state::gg_psg_stereo_w)
+{
+ if (m_cartslot->exists() && m_cartslot->m_cart->get_sms_mode())
+ return;
+
+ m_psg_gg->stereo_w(space, offset, data, mem_mask);
+}
+
+
READ8_MEMBER(sms_state::gg_input_port_00_r)
{
if (m_cartslot->exists() && m_cartslot->m_cart->get_sms_mode())
@@ -871,7 +890,7 @@ MACHINE_START_MEMBER(sms_state,sms)
// a F0 pattern on power up; F0 = RET P.
// This initialization breaks some Game Gear games though (e.g.
// tempojr), suggesting that not all systems had the same initialization.
- // This also breaks some homebrew software (e.g. Nine Pixels).
+ // This also breaks some homebrew softwares (e.g. Nine Pixels).
// For the moment we apply this to systems that have the Japanese SMS
// cartridge slot.
if (m_has_jpn_sms_cart_slot)
@@ -888,7 +907,7 @@ MACHINE_START_MEMBER(sms_state,sms)
if (m_has_fm)
{
- save_item(NAME(m_fm_detect));
+ save_item(NAME(m_audio_control));
}
if (!m_is_mark_iii)
@@ -935,7 +954,7 @@ MACHINE_START_MEMBER(sms_state,sms)
MACHINE_RESET_MEMBER(sms_state,sms)
{
if (m_has_fm)
- m_fm_detect = 0x01;
+ m_audio_control = 0x00;
if (!m_is_mark_iii)
{