msx/msx.cpp, bus/msx: Propagate clock to slots, and route audio input from cartridges. (#11074)

This commit is contained in:
wilbertpol 2023-04-13 21:33:34 +01:00 committed by GitHub
parent c925ffe986
commit b56409dbc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 102 additions and 77 deletions

View File

@ -41,8 +41,9 @@ const tiny_rom_entry *msx_cart_easispeech_device::device_rom_region() const
void msx_cart_easispeech_device::device_add_mconfig(machine_config &config) void msx_cart_easispeech_device::device_add_mconfig(machine_config &config)
{ {
SP0256(config, m_speech, 3120000); // frequency unknown SP0256(config, m_speech, DERIVED_CLOCK(1, 1)); // frequency unknown, assuming the system clock is used.
m_speech->add_route(ALL_OUTPUTS, ":speaker", 1.00); if (parent_slot())
m_speech->add_route(ALL_OUTPUTS, soundin(), 1.0);
} }
std::error_condition msx_cart_easispeech_device::initialize_cartridge(std::string &message) std::error_condition msx_cart_easispeech_device::initialize_cartridge(std::string &message)

View File

@ -30,9 +30,9 @@ msx_cart_fmpac_device::msx_cart_fmpac_device(const machine_config &mconfig, cons
void msx_cart_fmpac_device::device_add_mconfig(machine_config &config) void msx_cart_fmpac_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. YM2413(config, m_ym2413, DERIVED_CLOCK(1, 1));
SPEAKER(config, "mono").front_center(); if (parent_slot())
YM2413(config, m_ym2413, XTAL(10'738'635)/3).add_route(ALL_OUTPUTS, "mono", 0.40); m_ym2413->add_route(ALL_OUTPUTS, soundin(), 0.8);
} }

View File

@ -89,9 +89,9 @@ msx_cart_konami_scc_device::msx_cart_konami_scc_device(const machine_config &mco
void msx_cart_konami_scc_device::device_add_mconfig(machine_config &config) void msx_cart_konami_scc_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. K051649(config, m_k051649, DERIVED_CLOCK(1, 1));
SPEAKER(config, "mono").front_center(); if (parent_slot())
K051649(config, m_k051649, XTAL(10'738'635)/3).add_route(ALL_OUTPUTS, "mono", 0.15); m_k051649->add_route(ALL_OUTPUTS, soundin(), 0.4);
} }
void msx_cart_konami_scc_device::device_reset() void msx_cart_konami_scc_device::device_reset()
@ -272,9 +272,9 @@ msx_cart_synthesizer_device::msx_cart_synthesizer_device(const machine_config &m
void msx_cart_synthesizer_device::device_add_mconfig(machine_config &config) void msx_cart_synthesizer_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. DAC_8BIT_R2R(config, m_dac, 0); // unknown DAC
SPEAKER(config, "speaker").front_center(); if (parent_slot())
DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.3); // unknown DAC m_dac->add_route(ALL_OUTPUTS, soundin(), 0.3);
} }
std::error_condition msx_cart_synthesizer_device::initialize_cartridge(std::string &message) std::error_condition msx_cart_synthesizer_device::initialize_cartridge(std::string &message)
@ -319,9 +319,9 @@ msx_cart_konami_sound_device::msx_cart_konami_sound_device(const machine_config
void msx_cart_konami_sound_device::device_add_mconfig(machine_config &config) void msx_cart_konami_sound_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. K051649(config, m_k052539, DERIVED_CLOCK(1, 1));
SPEAKER(config, "mono").front_center(); if (parent_slot())
K051649(config, m_k052539, XTAL(10'738'635)/3).add_route(ALL_OUTPUTS, "mono", 0.15); m_k052539->add_route(ALL_OUTPUTS, soundin(), 0.4);
} }
void msx_cart_konami_sound_device::device_start() void msx_cart_konami_sound_device::device_start()
@ -545,10 +545,9 @@ void msx_cart_keyboard_master_device::vlm_map(address_map &map)
void msx_cart_keyboard_master_device::device_add_mconfig(machine_config &config) void msx_cart_keyboard_master_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. VLM5030(config, m_vlm5030, DERIVED_CLOCK(1, 1));
SPEAKER(config, "mono").front_center(); if (parent_slot())
VLM5030(config, m_vlm5030, XTAL(3'579'545)); m_vlm5030->add_route(ALL_OUTPUTS, soundin(), 1.0);
m_vlm5030->add_route(ALL_OUTPUTS, "mono", 0.40);
m_vlm5030->set_addrmap(0, &msx_cart_keyboard_master_device::vlm_map); m_vlm5030->set_addrmap(0, &msx_cart_keyboard_master_device::vlm_map);
} }

View File

@ -103,7 +103,7 @@ protected:
virtual void device_add_mconfig(machine_config &config) override; virtual void device_add_mconfig(machine_config &config) override;
private: private:
required_device<dac_byte_interface> m_dac; required_device<dac_8bit_r2r_device> m_dac;
}; };

View File

@ -19,9 +19,9 @@ msx_cart_majutsushi_device::msx_cart_majutsushi_device(const machine_config &mco
void msx_cart_majutsushi_device::device_add_mconfig(machine_config &config) void msx_cart_majutsushi_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. DAC_8BIT_R2R(config, m_dac, 0); // unknown DAC
SPEAKER(config, "speaker").front_center(); if (parent_slot())
DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.05); // unknown DAC m_dac->add_route(ALL_OUTPUTS, soundin(), 0.15);
} }
std::error_condition msx_cart_majutsushi_device::initialize_cartridge(std::string &message) std::error_condition msx_cart_majutsushi_device::initialize_cartridge(std::string &message)

View File

@ -28,7 +28,7 @@ protected:
private: private:
template <int Bank> void bank_w(u8 data); template <int Bank> void bank_w(u8 data);
required_device<dac_byte_interface> m_dac; required_device<dac_8bit_r2r_device> m_dac;
memory_bank_array_creator<3> m_rombank; memory_bank_array_creator<3> m_rombank;
}; };

View File

@ -81,10 +81,9 @@ msx_cart_msx_audio_hxmu900_device::msx_cart_msx_audio_hxmu900_device(const machi
void msx_cart_msx_audio_hxmu900_device::device_add_mconfig(machine_config &config) void msx_cart_msx_audio_hxmu900_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. Y8950(config, m_y8950, DERIVED_CLOCK(1, 1)); // Not verified
SPEAKER(config, "mono").front_center(); if (parent_slot())
Y8950(config, m_y8950, XTAL(3'579'545)); // Not verified m_y8950->add_route(ALL_OUTPUTS, soundin(), 0.8);
m_y8950->add_route(ALL_OUTPUTS, "mono", 0.40);
m_y8950->keyboard_write().set("kbdc", FUNC(msx_audio_kbdc_port_device::write)); m_y8950->keyboard_write().set("kbdc", FUNC(msx_audio_kbdc_port_device::write));
m_y8950->keyboard_read().set("kbdc", FUNC(msx_audio_kbdc_port_device::read)); m_y8950->keyboard_read().set("kbdc", FUNC(msx_audio_kbdc_port_device::read));
@ -143,11 +142,10 @@ msx_cart_msx_audio_nms1205_device::msx_cart_msx_audio_nms1205_device(const machi
void msx_cart_msx_audio_nms1205_device::device_add_mconfig(machine_config &config) void msx_cart_msx_audio_nms1205_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. // At the same time the sound is also output on two outputs on the nms1205 cartridge itself
// At the same time the sound is also output on two output on the nms1205 cartridge itself Y8950(config, m_y8950, DERIVED_CLOCK(1, 1));
SPEAKER(config, "mono").front_center(); if (parent_slot())
Y8950(config, m_y8950, XTAL(3'579'545)); m_y8950->add_route(ALL_OUTPUTS, soundin(), 0.8);
m_y8950->add_route(ALL_OUTPUTS, "mono", 0.40);
m_y8950->keyboard_write().set("kbdc", FUNC(msx_audio_kbdc_port_device::write)); m_y8950->keyboard_write().set("kbdc", FUNC(msx_audio_kbdc_port_device::write));
m_y8950->keyboard_read().set("kbdc", FUNC(msx_audio_kbdc_port_device::read)); m_y8950->keyboard_read().set("kbdc", FUNC(msx_audio_kbdc_port_device::read));
m_y8950->irq_handler().set(FUNC(msx_cart_msx_audio_nms1205_device::irq_write)); m_y8950->irq_handler().set(FUNC(msx_cart_msx_audio_nms1205_device::irq_write));
@ -238,10 +236,9 @@ msx_cart_msx_audio_fsca1_device::msx_cart_msx_audio_fsca1_device(const machine_c
void msx_cart_msx_audio_fsca1_device::device_add_mconfig(machine_config &config) void msx_cart_msx_audio_fsca1_device::device_add_mconfig(machine_config &config)
{ {
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. Y8950(config, m_y8950, DERIVED_CLOCK(1, 1));
SPEAKER(config, "mono").front_center(); if (parent_slot())
Y8950(config, m_y8950, XTAL(3'579'545)); m_y8950->add_route(ALL_OUTPUTS, soundin(), 0.8);
m_y8950->add_route(ALL_OUTPUTS, "mono", 0.40);
m_y8950->keyboard_write().set("kbdc", FUNC(msx_audio_kbdc_port_device::write)); m_y8950->keyboard_write().set("kbdc", FUNC(msx_audio_kbdc_port_device::write));
m_y8950->keyboard_read().set("kbdc", FUNC(msx_audio_kbdc_port_device::read)); m_y8950->keyboard_read().set("kbdc", FUNC(msx_audio_kbdc_port_device::read));
m_y8950->io_read().set(FUNC(msx_cart_msx_audio_fsca1_device::y8950_io_r)); m_y8950->io_read().set(FUNC(msx_cart_msx_audio_fsca1_device::y8950_io_r));

View File

@ -78,12 +78,16 @@ private:
template<int Slot> template<int Slot>
void msx_cart_slotexpander_device::add_cartslot(machine_config &mconfig) void msx_cart_slotexpander_device::add_cartslot(machine_config &mconfig)
{ {
MSX_SLOT_CARTRIDGE(mconfig, m_cartslot[Slot], 0); MSX_SLOT_CARTRIDGE(mconfig, m_cartslot[Slot], DERIVED_CLOCK(1, 1));
m_cartslot[Slot]->option_reset(); m_cartslot[Slot]->option_reset();
msx_cart(*m_cartslot[Slot], true); msx_cart(*m_cartslot[Slot], true);
m_cartslot[Slot]->set_default_option(nullptr); m_cartslot[Slot]->set_default_option(nullptr);
m_cartslot[Slot]->set_fixed(false); m_cartslot[Slot]->set_fixed(false);
m_cartslot[Slot]->irq_handler().set(m_irq_out, FUNC(input_merger_device::in_w<Slot>)); m_cartslot[Slot]->irq_handler().set(m_irq_out, FUNC(input_merger_device::in_w<Slot>));
if (parent_slot())
{
m_cartslot[Slot]->add_route(ALL_OUTPUTS, soundin(), 1.0);
}
} }
void msx_cart_slotexpander_device::device_add_mconfig(machine_config &mconfig) void msx_cart_slotexpander_device::device_add_mconfig(machine_config &mconfig)

View File

@ -38,7 +38,7 @@ private:
void msx_cart_ucn01_device::device_add_mconfig(machine_config &mconfig) void msx_cart_ucn01_device::device_add_mconfig(machine_config &mconfig)
{ {
MSX_SLOT_YAMAHA_EXPANSION(mconfig, m_module, 0); MSX_SLOT_YAMAHA_EXPANSION(mconfig, m_module, DERIVED_CLOCK(1, 1));
m_module->option_reset(); m_module->option_reset();
msx_yamaha_60pin(*m_module, false); msx_yamaha_60pin(*m_module, false);
m_module->set_default_option(nullptr); m_module->set_default_option(nullptr);

View File

@ -48,7 +48,7 @@ void msx_cart_sfg_device::device_add_mconfig(machine_config &config)
SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right(); SPEAKER(config, "rspeaker").front_right();
ym2151_device &ym2151(YM2151(config, m_ym2151, XTAL(3'579'545))); // The SFG01 uses a YM2151, the SFG05 uses a YM2164, input clock comes from the main cpu frequency ym2151_device &ym2151(YM2151(config, m_ym2151, DERIVED_CLOCK(1, 1))); // The SFG01 uses a YM2151, the SFG05 uses a YM2164, input clock comes from the main cpu frequency
ym2151.irq_handler().set(FUNC(msx_cart_sfg_device::ym2151_irq_w)); ym2151.irq_handler().set(FUNC(msx_cart_sfg_device::ym2151_irq_w));
ym2151.add_route(0, "lspeaker", 0.80); ym2151.add_route(0, "lspeaker", 0.80);
ym2151.add_route(1, "rspeaker", 0.80); ym2151.add_route(1, "rspeaker", 0.80);
@ -69,7 +69,7 @@ void msx_cart_sfg05_device::device_add_mconfig(machine_config &config)
{ {
msx_cart_sfg_device::device_add_mconfig(config); msx_cart_sfg_device::device_add_mconfig(config);
ym2164_device &ym2164(YM2164(config.replace(), m_ym2151, XTAL(3'579'545))); ym2164_device &ym2164(YM2164(config.replace(), m_ym2151, DERIVED_CLOCK(1, 1)));
ym2164.irq_handler().set(FUNC(msx_cart_sfg05_device::ym2151_irq_w)); ym2164.irq_handler().set(FUNC(msx_cart_sfg05_device::ym2151_irq_w));
ym2164.add_route(0, "lspeaker", 0.80); ym2164.add_route(0, "lspeaker", 0.80);
ym2164.add_route(1, "rspeaker", 0.80); ym2164.add_route(1, "rspeaker", 0.80);

View File

@ -9,6 +9,7 @@ msx_slot_cartridge_base_device::msx_slot_cartridge_base_device(const machine_con
: device_t(mconfig, type, tag, owner, clock) : device_t(mconfig, type, tag, owner, clock)
, device_cartrom_image_interface(mconfig, *this) , device_cartrom_image_interface(mconfig, *this)
, device_slot_interface(mconfig, *this) , device_slot_interface(mconfig, *this)
, device_mixer_interface(mconfig, *this)
, msx_internal_slot_interface(mconfig, *this) , msx_internal_slot_interface(mconfig, *this)
, m_irq_handler(*this) , m_irq_handler(*this)
, m_cartridge(nullptr) , m_cartridge(nullptr)
@ -116,6 +117,11 @@ cpu_device &msx_cart_interface::maincpu() const
return m_exp->maincpu(); return m_exp->maincpu();
} }
device_mixer_interface &msx_cart_interface::soundin() const
{
return *m_exp;
}
void msx_cart_interface::set_views(memory_view::memory_view_entry *page0, memory_view::memory_view_entry *page1, memory_view::memory_view_entry *page2, memory_view::memory_view_entry *page3) void msx_cart_interface::set_views(memory_view::memory_view_entry *page0, memory_view::memory_view_entry *page1, memory_view::memory_view_entry *page2, memory_view::memory_view_entry *page3)
{ {
m_page[0] = page0; m_page[0] = page0;

View File

@ -46,6 +46,7 @@ class msx_cart_interface;
class msx_slot_cartridge_base_device : public device_t class msx_slot_cartridge_base_device : public device_t
, public device_cartrom_image_interface , public device_cartrom_image_interface
, public device_slot_interface , public device_slot_interface
, public device_mixer_interface
, public msx_internal_slot_interface , public msx_internal_slot_interface
{ {
public: public:
@ -101,6 +102,7 @@ protected:
address_space &memory_space() const; address_space &memory_space() const;
address_space &io_space() const; address_space &io_space() const;
cpu_device &maincpu() const; cpu_device &maincpu() const;
device_mixer_interface &soundin() const;
memory_view::memory_view_entry *page(int i) { return m_page[i]; } memory_view::memory_view_entry *page(int i) { return m_page[i]; }
private: private:

View File

@ -114,7 +114,7 @@
#include "logmacro.h" #include "logmacro.h"
msx_state::msx_state(const machine_config &mconfig, device_type type, const char *tag) msx_state::msx_state(const machine_config &mconfig, device_type type, const char *tag, XTAL main_xtal, int cpu_xtal_divider)
: driver_device(mconfig, type, tag) : driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu") , m_maincpu(*this, "maincpu")
, m_cassette(*this, "cassette") , m_cassette(*this, "cassette")
@ -165,6 +165,8 @@ msx_state::msx_state(const machine_config &mconfig, device_type type, const char
, m_code_led(*this, "code_led") , m_code_led(*this, "code_led")
, m_code_led_name(*this, "code_led_name") , m_code_led_name(*this, "code_led_name")
, m_region(REGION_UNKNOWN) , m_region(REGION_UNKNOWN)
, m_main_xtal(main_xtal)
, m_cpu_xtal_divider(cpu_xtal_divider)
{ {
m_view[0] = &m_view_page0; m_view[0] = &m_view_page0;
m_view[1] = &m_view_page1; m_view[1] = &m_view_page1;
@ -563,11 +565,11 @@ void msx_state::kanji_w(offs_t offset, u8 data)
m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5); m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
} }
void msx_state::msx_base(ay8910_type ay8910_type, machine_config &config, XTAL xtal, int cpu_divider, region_type region) void msx_state::msx_base(ay8910_type ay8910_type, machine_config &config, region_type region)
{ {
m_region = region; m_region = region;
// basic machine hardware // basic machine hardware
Z80(config, m_maincpu, xtal / cpu_divider); // 3.579545 MHz Z80(config, m_maincpu, m_main_xtal / m_cpu_xtal_divider); // 3.579545 MHz
m_maincpu->set_addrmap(AS_PROGRAM, &msx_state::memory_map); m_maincpu->set_addrmap(AS_PROGRAM, &msx_state::memory_map);
config.set_maximum_quantum(attotime::from_hz(60)); config.set_maximum_quantum(attotime::from_hz(60));
@ -583,18 +585,19 @@ void msx_state::msx_base(ay8910_type ay8910_type, machine_config &config, XTAL x
// sound hardware // sound hardware
SPEAKER(config, m_speaker).front_center(); SPEAKER(config, m_speaker).front_center();
DAC_1BIT(config, m_dac, 0).add_route(ALL_OUTPUTS, m_speaker, 0.1); DAC_1BIT(config, m_dac, 0);
m_dac->add_route(ALL_OUTPUTS, m_speaker, 0.1);
if (ay8910_type == SND_AY8910) if (ay8910_type == SND_AY8910)
AY8910(config, m_ay8910, xtal / cpu_divider / 2); AY8910(config, m_ay8910, m_main_xtal / m_cpu_xtal_divider / 2);
if (ay8910_type == SND_YM2149) if (ay8910_type == SND_YM2149)
YM2149(config, m_ay8910, xtal / cpu_divider / 2); YM2149(config, m_ay8910, m_main_xtal / m_cpu_xtal_divider / 2);
m_ay8910->set_flags(AY8910_SINGLE_OUTPUT); m_ay8910->set_flags(AY8910_SINGLE_OUTPUT);
m_ay8910->port_a_read_callback().set(FUNC(msx2_base_state::psg_port_a_r)); m_ay8910->port_a_read_callback().set(FUNC(msx2_base_state::psg_port_a_r));
m_ay8910->port_b_read_callback().set(FUNC(msx2_base_state::psg_port_b_r)); m_ay8910->port_b_read_callback().set(FUNC(msx2_base_state::psg_port_b_r));
m_ay8910->port_a_write_callback().set(FUNC(msx2_base_state::psg_port_a_w)); m_ay8910->port_a_write_callback().set(FUNC(msx2_base_state::psg_port_a_w));
m_ay8910->port_b_write_callback().set(FUNC(msx2_base_state::psg_port_b_w)); m_ay8910->port_b_write_callback().set(FUNC(msx2_base_state::psg_port_b_w));
m_ay8910->add_route(ALL_OUTPUTS, m_speaker, 0.3); m_ay8910->add_route(ALL_OUTPUTS, m_speaker, 1.0);
MSX_GENERAL_PURPOSE_PORT(config, m_gen_port1, msx_general_purpose_port_devices, "joystick"); MSX_GENERAL_PURPOSE_PORT(config, m_gen_port1, msx_general_purpose_port_devices, "joystick");
MSX_GENERAL_PURPOSE_PORT(config, m_gen_port2, msx_general_purpose_port_devices, "joystick"); MSX_GENERAL_PURPOSE_PORT(config, m_gen_port2, msx_general_purpose_port_devices, "joystick");
@ -619,7 +622,7 @@ void msx_state::msx_base(ay8910_type ay8910_type, machine_config &config, XTAL x
CASSETTE(config, m_cassette); CASSETTE(config, m_cassette);
m_cassette->set_formats(fmsx_cassette_formats); m_cassette->set_formats(fmsx_cassette_formats);
m_cassette->set_default_state(CASSETTE_PLAY); m_cassette->set_default_state(CASSETTE_PLAY);
m_cassette->add_route(ALL_OUTPUTS, m_speaker, 0.05); m_cassette->add_route(ALL_OUTPUTS, m_speaker, 0.15);
m_cassette->set_interface("msx_cass"); m_cassette->set_interface("msx_cass");
} }
@ -640,24 +643,24 @@ void msx_state::msx1_add_softlists(machine_config &config)
void msx_state::msx1(vdp_type vdp_type, ay8910_type ay8910_type, machine_config &config, region_type region) void msx_state::msx1(vdp_type vdp_type, ay8910_type ay8910_type, machine_config &config, region_type region)
{ {
msx_base(ay8910_type, config, 10.738635_MHz_XTAL, 3, region); msx_base(ay8910_type, config, region);
m_maincpu->set_addrmap(AS_IO, &msx_state::msx1_io_map); m_maincpu->set_addrmap(AS_IO, &msx_state::msx1_io_map);
if (vdp_type == VDP_TMS9118) if (vdp_type == VDP_TMS9118)
TMS9118(config, m_tms9928a, 10.738635_MHz_XTAL); TMS9118(config, m_tms9928a, m_main_xtal);
if (vdp_type == VDP_TMS9128) if (vdp_type == VDP_TMS9128)
TMS9128(config, m_tms9928a, 10.738635_MHz_XTAL); TMS9128(config, m_tms9928a, m_main_xtal);
if (vdp_type == VDP_TMS9129) if (vdp_type == VDP_TMS9129)
TMS9129(config, m_tms9928a, 10.738635_MHz_XTAL); TMS9129(config, m_tms9928a, m_main_xtal);
if (vdp_type == VDP_TMS9918) if (vdp_type == VDP_TMS9918)
TMS9918(config, m_tms9928a, 10.738635_MHz_XTAL); TMS9918(config, m_tms9928a, m_main_xtal);
if (vdp_type == VDP_TMS9918A) if (vdp_type == VDP_TMS9918A)
TMS9918A(config, m_tms9928a, 10.738635_MHz_XTAL); TMS9918A(config, m_tms9928a, m_main_xtal);
if (vdp_type == VDP_TMS9928A) if (vdp_type == VDP_TMS9928A)
TMS9928A(config, m_tms9928a, 10.738635_MHz_XTAL); TMS9928A(config, m_tms9928a, m_main_xtal);
if (vdp_type == VDP_TMS9929A) if (vdp_type == VDP_TMS9929A)
TMS9929A(config, m_tms9928a, 10.738635_MHz_XTAL); TMS9929A(config, m_tms9928a, m_main_xtal);
m_tms9928a->set_screen(m_screen); m_tms9928a->set_screen(m_screen);
m_tms9928a->set_vram_size(0x4000); m_tms9928a->set_vram_size(0x4000);
m_tms9928a->int_callback().set(m_mainirq, FUNC(input_merger_device::in_w<0>)); m_tms9928a->int_callback().set(m_mainirq, FUNC(input_merger_device::in_w<0>));
@ -742,12 +745,12 @@ WRITE_LINE_MEMBER(msx2_base_state::turbo_w)
{ {
// 0 - 5.369317 MHz // 0 - 5.369317 MHz
// 1 - 3.579545 MHz // 1 - 3.579545 MHz
m_maincpu->set_unscaled_clock(21.477272_MHz_XTAL / (state ? 6 : 4)); m_maincpu->set_unscaled_clock(m_main_xtal / (state ? 6 : 4));
} }
void msx2_base_state::msx_ym2413(machine_config &config) void msx2_base_state::msx_ym2413(machine_config &config)
{ {
YM2413(config, "ym2413", 21.477272_MHz_XTAL / 6).add_route(ALL_OUTPUTS, m_speaker, 0.4); YM2413(config, "ym2413", m_main_xtal / m_cpu_xtal_divider).add_route(ALL_OUTPUTS, m_speaker, 0.8);
} }
void msx2_base_state::msx2_64kb_vram(machine_config &config) void msx2_base_state::msx2_64kb_vram(machine_config &config)
@ -823,7 +826,7 @@ void msx2_base_state::turbor_add_softlists(machine_config &config)
void msx2_base_state::msx2_base(ay8910_type ay8910_type, machine_config &config, region_type region) void msx2_base_state::msx2_base(ay8910_type ay8910_type, machine_config &config, region_type region)
{ {
msx_base(ay8910_type, config, 21.477272_MHz_XTAL, 6, region); msx_base(ay8910_type, config, region);
// real time clock // real time clock
RP5C01(config, m_rtc, 32.768_kHz_XTAL); RP5C01(config, m_rtc, 32.768_kHz_XTAL);
@ -836,7 +839,7 @@ void msx2_base_state::msx2(ay8910_type ay8910_type, machine_config &config, regi
m_maincpu->set_addrmap(AS_IO, &msx2_base_state::msx2_io_map); m_maincpu->set_addrmap(AS_IO, &msx2_base_state::msx2_io_map);
// video hardware // video hardware
V9938(config, m_v9938, 21.477272_MHz_XTAL); V9938(config, m_v9938, m_main_xtal);
m_v9938->set_screen_ntsc(m_screen); m_v9938->set_screen_ntsc(m_screen);
m_v9938->set_vram_size(0x20000); m_v9938->set_vram_size(0x20000);
m_v9938->int_cb().set(m_mainirq, FUNC(input_merger_device::in_w<0>)); m_v9938->int_cb().set(m_mainirq, FUNC(input_merger_device::in_w<0>));
@ -858,7 +861,7 @@ void msx2_base_state::msx2plus_base(ay8910_type ay8910_type, machine_config &con
m_maincpu->set_addrmap(AS_IO, &msx2_base_state::msx2plus_io_map); m_maincpu->set_addrmap(AS_IO, &msx2_base_state::msx2plus_io_map);
// video hardware // video hardware
V9958(config, m_v9958, 21.477272_MHz_XTAL); V9958(config, m_v9958, m_main_xtal);
m_v9958->set_screen_ntsc(m_screen); m_v9958->set_screen_ntsc(m_screen);
m_v9958->set_vram_size(0x20000); m_v9958->set_vram_size(0x20000);
m_v9958->int_cb().set(m_mainirq, FUNC(input_merger_device::in_w<0>)); m_v9958->int_cb().set(m_mainirq, FUNC(input_merger_device::in_w<0>));

View File

@ -55,7 +55,7 @@ private:
class msx_state : public driver_device class msx_state : public driver_device
{ {
protected: protected:
msx_state(const machine_config &mconfig, device_type type, const char *tag); msx_state(const machine_config &mconfig, device_type type, const char *tag, XTAL main_xtal, int cpu_xtal_divider);
enum ay8910_type enum ay8910_type
{ {
@ -84,7 +84,7 @@ protected:
REGION_RUSSIA = 5 REGION_RUSSIA = 5
}; };
void msx_base(ay8910_type ay8910_type, machine_config &config, XTAL xtal, int cpu_divider, region_type region); void msx_base(ay8910_type ay8910_type, machine_config &config, region_type region);
void msx1(vdp_type vdp_type, ay8910_type ay8910_type, machine_config &config, region_type region); void msx1(vdp_type vdp_type, ay8910_type ay8910_type, machine_config &config, region_type region);
void msx1_add_softlists(machine_config &config); void msx1_add_softlists(machine_config &config);
@ -166,6 +166,11 @@ protected:
{ {
return add_cartridge_slot<N>(config, prim, false, 0); return add_cartridge_slot<N>(config, prim, false, 0);
} }
template <int N>
auto &add_cartridge_slot(machine_config &config, u8 prim, XTAL xtal)
{
return add_cartridge_slot<N>(config, prim, false, 0, xtal);
}
virtual void driver_start() override; virtual void driver_start() override;
virtual void machine_start() override; virtual void machine_start() override;
virtual void machine_reset() override; virtual void machine_reset() override;
@ -191,7 +196,7 @@ protected:
required_device<z80_device> m_maincpu; required_device<z80_device> m_maincpu;
optional_device<cassette_image_device> m_cassette; optional_device<cassette_image_device> m_cassette;
required_device<ay8910_device> m_ay8910; required_device<ay8910_device> m_ay8910;
required_device<dac_bit_interface> m_dac; required_device<dac_1bit_device> m_dac;
required_device<i8255_device> m_ppi; required_device<i8255_device> m_ppi;
optional_device<tms9928a_device> m_tms9928a; optional_device<tms9928a_device> m_tms9928a;
optional_device<input_buffer_device> m_cent_status_in; optional_device<input_buffer_device> m_cent_status_in;
@ -257,13 +262,15 @@ protected:
output_finder<> m_code_led; output_finder<> m_code_led;
output_finder<> m_code_led_name; output_finder<> m_code_led_name;
region_type m_region; region_type m_region;
const XTAL m_main_xtal;
const int m_cpu_xtal_divider;
private: private:
// configuration helpers // configuration helpers
template <typename T, typename U> template <typename T, typename U>
auto &add_base_slot(machine_config &config, T &&type, U &&tag, u8 prim, bool expanded, u8 sec, u8 page, u8 numpages) auto &add_base_slot(machine_config &config, T &&type, U &&tag, u8 prim, bool expanded, u8 sec, u8 page, u8 numpages, u32 clock = 0)
{ {
auto &device(std::forward<T>(type)(config, std::forward<U>(tag), 0U)); auto &device(std::forward<T>(type)(config, std::forward<U>(tag), clock));
device.set_memory_space(m_maincpu, AS_PROGRAM); device.set_memory_space(m_maincpu, AS_PROGRAM);
device.set_io_space(m_maincpu, AS_IO); device.set_io_space(m_maincpu, AS_IO);
device.set_maincpu(m_maincpu); device.set_maincpu(m_maincpu);
@ -308,16 +315,22 @@ private:
return device; return device;
} }
template <int N, typename T, typename U, typename V> template <int N, typename T, typename U, typename V>
auto &add_cartridge_slot(machine_config &config, T &&type, U &&tag, u8 prim, bool expanded, u8 sec, V &&intf, const char *deft) auto &add_cartridge_slot(machine_config &config, T &&type, U &&tag, u8 prim, bool expanded, u8 sec, V &&intf, const char *deft, u32 clock)
{ {
auto &device = add_base_slot(config, std::forward<T>(type), std::forward<U>(tag), prim, expanded, sec, 0, 4); auto &device = add_base_slot(config, std::forward<T>(type), std::forward<U>(tag), prim, expanded, sec, 0, 4, clock);
device.option_reset(); device.option_reset();
intf(device, expanded); intf(device, expanded);
device.set_default_option(deft); device.set_default_option(deft);
device.set_fixed(false); device.set_fixed(false);
device.irq_handler().set(m_mainirq, FUNC(input_merger_device::in_w<N>)); device.irq_handler().set(m_mainirq, FUNC(input_merger_device::in_w<N>));
device.add_route(ALL_OUTPUTS, m_speaker, 1.0);
return device; return device;
} }
template <int N, typename T, typename U, typename V>
auto &add_cartridge_slot(machine_config &config, T &&type, U &&tag, u8 prim, bool expanded, u8 sec, V &&intf, const char *deft)
{
return add_cartridge_slot<N>(config, std::forward<T>(type), std::forward<U>(tag), prim, expanded, sec, std::forward<V>(intf), deft, (m_main_xtal / m_cpu_xtal_divider).value());
}
template <int N> template <int N>
auto &add_cartridge_slot(machine_config &config, u8 prim, bool expanded, u8 sec) auto &add_cartridge_slot(machine_config &config, u8 prim, bool expanded, u8 sec)
{ {
@ -326,7 +339,7 @@ private:
}; };
static_assert(N >= 1 && N <= 4, "Invalid cartridge slot number"); static_assert(N >= 1 && N <= 4, "Invalid cartridge slot number");
m_hw_def.has_cartslot(true); m_hw_def.has_cartslot(true);
return add_cartridge_slot<N>(config, MSX_SLOT_CARTRIDGE, tags[N-1], prim, expanded, sec, msx_cart, nullptr); return add_cartridge_slot<N>(config, MSX_SLOT_CARTRIDGE, tags[N-1], prim, expanded, sec, msx_cart, nullptr, (m_main_xtal / m_cpu_xtal_divider).value());
} }
}; };
@ -334,8 +347,8 @@ private:
class msx2_base_state : public msx_state class msx2_base_state : public msx_state
{ {
protected: protected:
msx2_base_state(const machine_config &mconfig, device_type type, const char *tag) msx2_base_state(const machine_config &mconfig, device_type type, const char *tag, XTAL main_xtal, int cpu_xtal_divider)
: msx_state(mconfig, type, tag) : msx_state(mconfig, type, tag, main_xtal, cpu_xtal_divider)
, m_v9938(*this, "v9938") , m_v9938(*this, "v9938")
, m_v9958(*this, "v9958") , m_v9958(*this, "v9958")
, m_rtc(*this, "rtc") , m_rtc(*this, "rtc")

View File

@ -98,7 +98,7 @@ class msx1_state : public msx_state
{ {
public: public:
msx1_state(const machine_config &mconfig, device_type type, const char *tag) msx1_state(const machine_config &mconfig, device_type type, const char *tag)
: msx_state(mconfig, type, tag) : msx_state(mconfig, type, tag, 10.738635_MHz_XTAL, 3)
{ {
} }

View File

@ -35,7 +35,7 @@ private:
bruc100_state::bruc100_state(const machine_config &mconfig, device_type type, const char *tag) bruc100_state::bruc100_state(const machine_config &mconfig, device_type type, const char *tag)
: msx_state(mconfig, type, tag) : msx_state(mconfig, type, tag, 10.738635_MHz_XTAL, 3)
, m_bruc100_firm(*this, "firm") , m_bruc100_firm(*this, "firm")
{ {
} }

View File

@ -67,7 +67,7 @@ protected:
}; };
msx1_v9938_state::msx1_v9938_state(const machine_config &mconfig, device_type type, const char *tag) msx1_v9938_state::msx1_v9938_state(const machine_config &mconfig, device_type type, const char *tag)
: msx_state(mconfig, type, tag) : msx_state(mconfig, type, tag, 21.477272_MHz_XTAL, 6)
, m_v9938(*this, "v9938") , m_v9938(*this, "v9938")
{ {
} }
@ -80,7 +80,7 @@ void msx1_v9938_state::io_map(address_map &map)
void msx1_v9938_state::msx1_v9938(ay8910_type ay8910_type, machine_config &config, region_type region) void msx1_v9938_state::msx1_v9938(ay8910_type ay8910_type, machine_config &config, region_type region)
{ {
msx_base(ay8910_type, config, 21.477272_MHz_XTAL, 6, region); msx_base(ay8910_type, config, region);
m_maincpu->set_addrmap(AS_IO, &msx1_v9938_state::io_map); m_maincpu->set_addrmap(AS_IO, &msx1_v9938_state::io_map);

View File

@ -62,7 +62,7 @@ class msx2_state : public msx2_base_state
{ {
public: public:
msx2_state(const machine_config &mconfig, device_type type, const char *tag) msx2_state(const machine_config &mconfig, device_type type, const char *tag)
: msx2_base_state(mconfig, type, tag) : msx2_base_state(mconfig, type, tag, 21.477272_MHz_XTAL, 6)
{ {
} }