From a6ebfe2ce2aac624733642c39a0a1bd98ec16160 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 12 May 2023 22:09:15 -0400 Subject: [PATCH 01/10] Add has_msx_music flag. --- Analyser/Static/MSX/Target.hpp | 2 ++ Machines/MSX/MSX.cpp | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Analyser/Static/MSX/Target.hpp b/Analyser/Static/MSX/Target.hpp index 4b6ae5185..9d938f624 100644 --- a/Analyser/Static/MSX/Target.hpp +++ b/Analyser/Static/MSX/Target.hpp @@ -18,6 +18,7 @@ namespace Analyser::Static::MSX { struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl { bool has_disk_drive = false; + bool has_msx_music = false; std::string loading_command; ReflectableEnum(Model, @@ -36,6 +37,7 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl< Target(): Analyser::Static::Target(Machine::MSX) { if(needs_declare()) { DeclareField(has_disk_drive); + DeclareField(has_msx_music); DeclareField(region); AnnounceEnum(Region); DeclareField(model); diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index d341ce2da..0e12a5d6d 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -131,7 +131,7 @@ class AYPortHandler: public GI::AY38910::PortHandler { using Target = Analyser::Static::MSX::Target; -template +template class ConcreteMachine: public Machine, public CPU::Z80::BusHandler, @@ -978,10 +978,18 @@ using namespace MSX; Machine *Machine::MSX(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) { const auto msx_target = dynamic_cast(target); - switch(msx_target->model) { - default: return nullptr; - case Target::Model::MSX1: return new ConcreteMachine(*msx_target, rom_fetcher); - case Target::Model::MSX2: return new ConcreteMachine(*msx_target, rom_fetcher); + if(msx_target->has_msx_music) { + switch(msx_target->model) { + default: return nullptr; + case Target::Model::MSX1: return new ConcreteMachine(*msx_target, rom_fetcher); + case Target::Model::MSX2: return new ConcreteMachine(*msx_target, rom_fetcher); + } + } else { + switch(msx_target->model) { + default: return nullptr; + case Target::Model::MSX1: return new ConcreteMachine(*msx_target, rom_fetcher); + case Target::Model::MSX2: return new ConcreteMachine(*msx_target, rom_fetcher); + } } } From 0b53c73da88e5dded008809663fb67a4b1863f1f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 12 May 2023 22:13:55 -0400 Subject: [PATCH 02/10] Add additional consts. --- Machines/MSX/MSX.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 0e12a5d6d..79c5c72c7 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -148,7 +148,6 @@ class ConcreteMachine: private: // Provide 512kb of memory for an MSX 2; 64kb for an MSX 1. 'Slightly' arbitrary. static constexpr size_t RAMSize = model == Target::Model::MSX2 ? 512 * 1024 : 64 * 1024; - static constexpr int ClockRate = 3579545; public: @@ -742,8 +741,8 @@ class ConcreteMachine: } void set_key_state(uint16_t key, bool is_pressed) final { - int mask = 1 << (key & 7); - int line = key >> 4; + const int mask = 1 << (key & 7); + const int line = key >> 4; if(is_pressed) key_states_[line] &= ~mask; else key_states_[line] |= mask; } @@ -774,7 +773,7 @@ class ConcreteMachine: // MARK: - Activity::Source void set_activity_observer(Activity::Observer *observer) final { - DiskROM *handler = disk_handler(); + DiskROM *const handler = disk_handler(); if(handler) { handler->set_activity_observer(observer); } From e7888497b7a971fe14f100f075728fefcb587123 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 12 May 2023 23:30:03 -0400 Subject: [PATCH 03/10] Add an OPLL. --- Machines/MSX/MSX.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 79c5c72c7..b0b21b780 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -27,8 +27,9 @@ #include "../../Components/9918/9918.hpp" #include "../../Components/AudioToggle/AudioToggle.hpp" #include "../../Components/AY38910/AY38910.hpp" -#include "../../Components/RP5C01/RP5C01.hpp" #include "../../Components/KonamiSCC/KonamiSCC.hpp" +#include "../../Components/OPx/OPLL.hpp" +#include "../../Components/RP5C01/RP5C01.hpp" #include "../../Storage/Tape/Parsers/MSX.hpp" #include "../../Storage/Tape/Tape.hpp" @@ -154,10 +155,11 @@ class ConcreteMachine: ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher): z80_(*this), i8255_(i8255_port_handler_), + opll_(audio_queue_, 1), ay_(GI::AY38910::Personality::AY38910, audio_queue_), audio_toggle_(audio_queue_), scc_(audio_queue_), - mixer_(ay_, audio_toggle_, scc_), + mixer_(ay_, audio_toggle_, scc_, opll_), speaker_(mixer_), tape_player_(3579545 * 2), i8255_port_handler_(*this, audio_toggle_, tape_player_), @@ -172,7 +174,7 @@ class ConcreteMachine: tape_player_.set_clocking_hint_observer(this); // Set the AY to 50% of available volume, the toggle to 10% and leave 40% for an SCC. - mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f}); + mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f, has_opll ? 0.4f : 0.0f}); // Install the proper TV standard and select an ideal BIOS name. const std::string machine_name = "MSX"; @@ -667,6 +669,13 @@ class ConcreteMachine: update_paging(); } break; + case 0x7c: case 0x7d: + if constexpr (has_opll) { + opll_.write(address, *cycle.value); + break; + } + [[fallthrough]]; + default: printf("Unhandled write %02x of %02x\n", address & 0xff, *cycle.value); break; @@ -855,11 +864,14 @@ class ConcreteMachine: Intel::i8255::i8255 i8255_; Concurrency::AsyncTaskQueue audio_queue_; + Yamaha::OPL::OPLL opll_; GI::AY38910::AY38910 ay_; Audio::Toggle audio_toggle_; Konami::SCC scc_; - Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC> mixer_; - Outputs::Speaker::PullLowpass, Audio::Toggle, Konami::SCC>> speaker_; + + using CompundSource = Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC, Yamaha::OPL::OPLL>; + CompundSource mixer_; + Outputs::Speaker::PullLowpass speaker_; Storage::Tape::BinaryTapePlayer tape_player_; bool tape_player_is_sleeping_ = false; From fed97b8d265f5a7adcee8fe944aae56c9e19e25f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 12 May 2023 23:33:28 -0400 Subject: [PATCH 04/10] Add MSX-MUSIC entry. --- Machines/Utility/ROMCatalogue.cpp | 1 + Machines/Utility/ROMCatalogue.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/Machines/Utility/ROMCatalogue.cpp b/Machines/Utility/ROMCatalogue.cpp index e5b20cb8d..fec569c69 100644 --- a/Machines/Utility/ROMCatalogue.cpp +++ b/Machines/Utility/ROMCatalogue.cpp @@ -576,6 +576,7 @@ Description::Description(Name name) { case Name::MSX2GenericBIOS: *this = Description(name, "MSX", "a generic MSX2 BIOS", "msx2.rom", 32*1024, 0x6cdaf3a5u); break; case Name::MSX2Extension: *this = Description(name, "MSX", "the MSX2 extension ROM", "msx2ext.rom", 16*1024, 0x66237ecfu); break; + case Name::MSXMusic: *this = Description(name, "MSX", "the MSX-MUSIC / FM-PAC ROM", "fmpac.rom", 64*1024, 0x0e84505du); break; case Name::SinclairQLJS: *this = Description(name, "SinclairQL", "the Sinclair QL 'JS' ROM", "js.rom", 48*1024, 0x0f95aab5u); diff --git a/Machines/Utility/ROMCatalogue.hpp b/Machines/Utility/ROMCatalogue.hpp index e085cbf09..475bab65d 100644 --- a/Machines/Utility/ROMCatalogue.hpp +++ b/Machines/Utility/ROMCatalogue.hpp @@ -119,6 +119,7 @@ enum Name { MSX2GenericBIOS, MSX2Extension, + MSXMusic, // Oric. OricColourROM, From 4989701de96d245d2f1617680a062baebbb80027 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 12 May 2023 23:50:43 -0400 Subject: [PATCH 05/10] Install MSX-MUSIC ROM. --- Machines/MSX/MSX.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index b0b21b780..07bd9b2d9 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -174,7 +174,7 @@ class ConcreteMachine: tape_player_.set_clocking_hint_observer(this); // Set the AY to 50% of available volume, the toggle to 10% and leave 40% for an SCC. - mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f, has_opll ? 0.4f : 0.0f}); + mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f, has_opll ? 0.5f : 0.0f}); // Install the proper TV standard and select an ideal BIOS name. const std::string machine_name = "MSX"; @@ -230,11 +230,12 @@ class ConcreteMachine: // Fetch the necessary ROMs; try the region-specific ROM first, // but failing that fall back on patching the main one. - ROM::Request request; + ROM::Request request = bios_request; if(target.has_disk_drive) { - request = ROM::Request(ROM::Name::MSXDOS) && bios_request; - } else { - request = bios_request; + request = request && ROM::Request(ROM::Name::MSXDOS); + } + if(target.has_msx_music) { + request = request && ROM::Request(ROM::Name::MSXMusic); } auto roms = rom_fetcher(request); @@ -295,6 +296,14 @@ class ConcreteMachine: disk_slot().map_handler(0x6000, 0x2000); } + // Grab the MSX-MUSIC ROM if applicable. + if(target.has_msx_music) { + std::vector &msx_music = roms.find(ROM::Name::MSXMusic)->second; + msx_music.resize(65536); + msx_music_slot().set_source(msx_music); + msx_music_slot().map(0, 0, 0x10000); + } + // Insert the media. insert_media(target.media); @@ -950,7 +959,7 @@ class ConcreteMachine: // // Slot 3-1 holds the BIOS extension ROM. // - // [Slot 3-2 will likely hold MSX-MUSIC, but that's TODO] + // Slot 3-2 holds the MSX-MUSIC. // MemorySlot &bios_slot() { return memory_slots_[0].subslot(0); @@ -961,6 +970,9 @@ class ConcreteMachine: MemorySlot &extension_rom_slot() { return memory_slots_[3].subslot(1); } + MemorySlot &msx_music_slot() { + return memory_slots_[3].subslot(2); + } MemorySlot &cartridge_slot() { return cartridge_primary().subslot(0); @@ -981,7 +993,8 @@ class ConcreteMachine: } DiskROM *disk_handler() { return dynamic_cast(disk_primary().handler.get()); - }}; + } +}; } From e1d671daf7aac0c13297f780a8306524cd09bb43 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 13 May 2023 22:16:42 -0400 Subject: [PATCH 06/10] Avoid paying for an OPLL if not connected. --- Machines/MSX/MSX.cpp | 82 +++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 07bd9b2d9..d897795fd 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -130,6 +130,47 @@ class AYPortHandler: public GI::AY38910::PortHandler { }; }; + +template struct Speaker; + +template <> struct Speaker { + Speaker() : + ay(GI::AY38910::Personality::AY38910, audio_queue), + audio_toggle(audio_queue), + scc(audio_queue), + mixer(ay, audio_toggle, scc), + speaker(mixer) {} + + Concurrency::AsyncTaskQueue audio_queue; + GI::AY38910::AY38910 ay; + Audio::Toggle audio_toggle; + Konami::SCC scc; + + using CompundSource = Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC>; + CompundSource mixer; + Outputs::Speaker::PullLowpass speaker; +}; + +template <> struct Speaker { + Speaker() : + opll(audio_queue, 1), + ay(GI::AY38910::Personality::AY38910, audio_queue), + audio_toggle(audio_queue), + scc(audio_queue), + mixer(ay, audio_toggle, scc, opll), + speaker(mixer) {} + + Concurrency::AsyncTaskQueue audio_queue; + Yamaha::OPL::OPLL opll; + GI::AY38910::AY38910 ay; + Audio::Toggle audio_toggle; + Konami::SCC scc; + + using CompundSource = Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC, Yamaha::OPL::OPLL>; + CompundSource mixer; + Outputs::Speaker::PullLowpass speaker; +}; + using Target = Analyser::Static::MSX::Target; template @@ -155,26 +196,20 @@ class ConcreteMachine: ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher): z80_(*this), i8255_(i8255_port_handler_), - opll_(audio_queue_, 1), - ay_(GI::AY38910::Personality::AY38910, audio_queue_), - audio_toggle_(audio_queue_), - scc_(audio_queue_), - mixer_(ay_, audio_toggle_, scc_, opll_), - speaker_(mixer_), tape_player_(3579545 * 2), - i8255_port_handler_(*this, audio_toggle_, tape_player_), + i8255_port_handler_(*this, speaker_.audio_toggle, tape_player_), ay_port_handler_(tape_player_), memory_slots_{{*this}, {*this}, {*this}, {*this}}, clock_(ClockRate) { set_clock_rate(ClockRate); clear_all_keys(); - ay_.set_port_handler(&ay_port_handler_); - speaker_.set_input_rate(3579545.0f / 2.0f); + speaker_.ay.set_port_handler(&ay_port_handler_); + speaker_.speaker.set_input_rate(3579545.0f / 2.0f); tape_player_.set_clocking_hint_observer(this); // Set the AY to 50% of available volume, the toggle to 10% and leave 40% for an SCC. - mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f, has_opll ? 0.5f : 0.0f}); + speaker_.mixer.set_relative_volumes({0.5f, 0.1f, 0.4f, has_opll ? 0.5f : 0.0f}); // Install the proper TV standard and select an ideal BIOS name. const std::string machine_name = "MSX"; @@ -317,7 +352,7 @@ class ConcreteMachine: } ~ConcreteMachine() { - audio_queue_.flush(); + speaker_.audio_queue.flush(); } void set_scan_target(Outputs::Display::ScanTarget *scan_target) final { @@ -337,7 +372,7 @@ class ConcreteMachine: } Outputs::Speaker::Speaker *get_speaker() final { - return &speaker_; + return &speaker_.speaker; } void run_for(const Cycles cycles) final { @@ -375,7 +410,7 @@ class ConcreteMachine: cartridge_primary().handler = std::make_unique(static_cast(slot)); break; case Analyser::Static::MSX::Cartridge::KonamiWithSCC: - cartridge_primary().handler = std::make_unique(static_cast(slot), scc_); + cartridge_primary().handler = std::make_unique(static_cast(slot), speaker_.scc); break; case Analyser::Static::MSX::Cartridge::ASCII8kb: cartridge_primary().handler = std::make_unique(static_cast(slot)); @@ -590,7 +625,7 @@ class ConcreteMachine: case 0xa2: update_audio(); - *cycle.value = GI::AY38910::Utility::read(ay_); + *cycle.value = GI::AY38910::Utility::read(speaker_.ay); break; case 0xa8: case 0xa9: @@ -634,7 +669,7 @@ class ConcreteMachine: case 0xa0: case 0xa1: update_audio(); - GI::AY38910::Utility::write(ay_, port == 0xa1, *cycle.value); + GI::AY38910::Utility::write(speaker_.ay, port == 0xa1, *cycle.value); break; case 0xa8: case 0xa9: @@ -680,7 +715,7 @@ class ConcreteMachine: case 0x7c: case 0x7d: if constexpr (has_opll) { - opll_.write(address, *cycle.value); + speaker_.opll.write(address, *cycle.value); break; } [[fallthrough]]; @@ -742,7 +777,7 @@ class ConcreteMachine: } if(outputs & Output::Audio) { update_audio(); - audio_queue_.perform(); + speaker_.audio_queue.perform(); } } @@ -805,7 +840,7 @@ class ConcreteMachine: private: void update_audio() { - speaker_.run_for(audio_queue_, time_since_ay_update_.divide_cycles(Cycles(2))); + speaker_.speaker.run_for(speaker_.audio_queue, time_since_ay_update_.divide_cycles(Cycles(2))); } class i8255PortHandler: public Intel::i8255::PortHandler { @@ -872,16 +907,6 @@ class ConcreteMachine: JustInTimeActor> vdp_; Intel::i8255::i8255 i8255_; - Concurrency::AsyncTaskQueue audio_queue_; - Yamaha::OPL::OPLL opll_; - GI::AY38910::AY38910 ay_; - Audio::Toggle audio_toggle_; - Konami::SCC scc_; - - using CompundSource = Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC, Yamaha::OPL::OPLL>; - CompundSource mixer_; - Outputs::Speaker::PullLowpass speaker_; - Storage::Tape::BinaryTapePlayer tape_player_; bool tape_player_is_sleeping_ = false; bool allow_fast_tape_ = false; @@ -896,6 +921,7 @@ class ConcreteMachine: } i8255PortHandler i8255_port_handler_; + Speaker speaker_; AYPortHandler ay_port_handler_; /// The current primary and secondary slot selections; the former retains whatever was written From b768e438b22823d9477ec22de81502673d40429b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 13 May 2023 22:17:09 -0400 Subject: [PATCH 07/10] Enable MSX-MUSIC by default. --- Analyser/Static/MSX/Target.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Analyser/Static/MSX/Target.hpp b/Analyser/Static/MSX/Target.hpp index 9d938f624..e34386eec 100644 --- a/Analyser/Static/MSX/Target.hpp +++ b/Analyser/Static/MSX/Target.hpp @@ -18,7 +18,7 @@ namespace Analyser::Static::MSX { struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl { bool has_disk_drive = false; - bool has_msx_music = false; + bool has_msx_music = true; std::string loading_command; ReflectableEnum(Model, From 876fc6d1e055ecfbbac4165c4a2bcd0d63de565f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 13 May 2023 22:18:40 -0400 Subject: [PATCH 08/10] Eliminate redundant line break. --- Machines/MSX/MSX.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index d897795fd..0eb24e17b 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -130,7 +130,6 @@ class AYPortHandler: public GI::AY38910::PortHandler { }; }; - template struct Speaker; template <> struct Speaker { From 413ab42b16e942f991e8d90755d2ee196776b4a0 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 13 May 2023 22:25:50 -0400 Subject: [PATCH 09/10] Add MSX-MUSIC option for macOS. --- .../Machine/StaticAnalyser/CSStaticAnalyser.h | 2 +- .../StaticAnalyser/CSStaticAnalyser.mm | 5 +++-- .../Base.lproj/MachinePicker.xib | 19 +++++++++++++++---- .../MachinePicker/MachinePicker.swift | 6 +++++- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h index ddc82dd54..bcb958cb1 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h @@ -137,7 +137,7 @@ typedef int Kilobytes; - (instancetype)initWithElectronDFS:(BOOL)dfs adfs:(BOOL)adfs ap6:(BOOL)ap6 sidewaysRAM:(BOOL)sidewaysRAM; - (instancetype)initWithEnterpriseModel:(CSMachineEnterpriseModel)model speed:(CSMachineEnterpriseSpeed)speed exosVersion:(CSMachineEnterpriseEXOS)exosVersion basicVersion:(CSMachineEnterpriseBASIC)basicVersion dos:(CSMachineEnterpriseDOS)dos; - (instancetype)initWithMacintoshModel:(CSMachineMacintoshModel)model; -- (instancetype)initWithMSXModel:(CSMachineMSXModel)model region:(CSMachineMSXRegion)region hasDiskDrive:(BOOL)hasDiskDrive; +- (instancetype)initWithMSXModel:(CSMachineMSXModel)model region:(CSMachineMSXRegion)region hasDiskDrive:(BOOL)hasDiskDrive hasMSXMUSIC:(BOOL)hasMSXMUSIC; - (instancetype)initWithOricModel:(CSMachineOricModel)model diskInterface:(CSMachineOricDiskInterface)diskInterface; - (instancetype)initWithSpectrumModel:(CSMachineSpectrumModel)model; - (instancetype)initWithVic20Region:(CSMachineVic20Region)region memorySize:(Kilobytes)memorySize hasC1540:(BOOL)hasC1540; diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm index 2ef4dc36c..dbca34373 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm @@ -229,12 +229,13 @@ return self; } -- (instancetype)initWithMSXModel:(CSMachineMSXModel)model region:(CSMachineMSXRegion)region hasDiskDrive:(BOOL)hasDiskDrive { +- (instancetype)initWithMSXModel:(CSMachineMSXModel)model region:(CSMachineMSXRegion)region hasDiskDrive:(BOOL)hasDiskDrive hasMSXMUSIC:(BOOL)hasMSXMUSIC { self = [super init]; if(self) { using Target = Analyser::Static::MSX::Target; auto target = std::make_unique(); - target->has_disk_drive = !!hasDiskDrive; + target->has_disk_drive = hasDiskDrive; + target->has_msx_music = hasMSXMUSIC; switch(region) { case CSMachineMSXRegionAmerican: target->region = Target::Region::USA; break; case CSMachineMSXRegionEuropean: target->region = Target::Region::Europe; break; diff --git a/OSBindings/Mac/Clock Signal/MachinePicker/Base.lproj/MachinePicker.xib b/OSBindings/Mac/Clock Signal/MachinePicker/Base.lproj/MachinePicker.xib index d0557d959..c3733c142 100644 --- a/OSBindings/Mac/Clock Signal/MachinePicker/Base.lproj/MachinePicker.xib +++ b/OSBindings/Mac/Clock Signal/MachinePicker/Base.lproj/MachinePicker.xib @@ -1,8 +1,8 @@ - + - + @@ -18,7 +18,7 @@ - + @@ -628,6 +628,13 @@ Gw + @@ -636,11 +643,14 @@ Gw + + - + + @@ -1017,6 +1027,7 @@ Gw + diff --git a/OSBindings/Mac/Clock Signal/MachinePicker/MachinePicker.swift b/OSBindings/Mac/Clock Signal/MachinePicker/MachinePicker.swift index 2d37addc2..74fd0da35 100644 --- a/OSBindings/Mac/Clock Signal/MachinePicker/MachinePicker.swift +++ b/OSBindings/Mac/Clock Signal/MachinePicker/MachinePicker.swift @@ -57,6 +57,7 @@ class MachinePicker: NSObject, NSTableViewDataSource, NSTableViewDelegate { @IBOutlet var msxModelButton: NSPopUpButton! @IBOutlet var msxRegionButton: NSPopUpButton! @IBOutlet var msxHasDiskDriveButton: NSButton! + @IBOutlet var msxHasMSXMUSICButton: NSButton! // MARK: - Oric properties @IBOutlet var oricModelTypeButton: NSPopUpButton! @@ -138,6 +139,7 @@ class MachinePicker: NSObject, NSTableViewDataSource, NSTableViewDelegate { msxModelButton.selectItem(withTag: standardUserDefaults.integer(forKey: "new.msxModel")) msxRegionButton.selectItem(withTag: standardUserDefaults.integer(forKey: "new.msxRegion")) msxHasDiskDriveButton.state = standardUserDefaults.bool(forKey: "new.msxDiskDrive") ? .on : .off + msxHasMSXMUSICButton.state = standardUserDefaults.bool(forKey: "new.msxMSXMUSIC") ? .on : .off // Oric settings oricDiskInterfaceButton.selectItem(withTag: standardUserDefaults.integer(forKey: "new.oricDiskInterface")) @@ -203,6 +205,7 @@ class MachinePicker: NSObject, NSTableViewDataSource, NSTableViewDelegate { standardUserDefaults.set(msxModelButton.selectedTag(), forKey: "new.msxModel") standardUserDefaults.set(msxRegionButton.selectedTag(), forKey: "new.msxRegion") standardUserDefaults.set(msxHasDiskDriveButton.state == .on, forKey: "new.msxDiskDrive") + standardUserDefaults.set(msxHasMSXMUSICButton.state == .on, forKey: "new.msxMSXMUSIC") // Oric settings standardUserDefaults.set(oricDiskInterfaceButton.selectedTag(), forKey: "new.oricDiskInterface") @@ -358,6 +361,7 @@ class MachinePicker: NSObject, NSTableViewDataSource, NSTableViewDelegate { case "msx": let hasDiskDrive = msxHasDiskDriveButton.state == .on + let hasMSXMUSIC = msxHasMSXMUSICButton.state == .on var region: CSMachineMSXRegion switch msxRegionButton.selectedTag() { case 2: region = .japanese @@ -371,7 +375,7 @@ class MachinePicker: NSObject, NSTableViewDataSource, NSTableViewDelegate { case 1: fallthrough default: model = .MSX1 } - return CSStaticAnalyser(msxModel: model, region: region, hasDiskDrive: hasDiskDrive) + return CSStaticAnalyser(msxModel: model, region: region, hasDiskDrive: hasDiskDrive, hasMSXMUSIC: hasMSXMUSIC) case "oric": var diskInterface: CSMachineOricDiskInterface = .none From 22ac13d3f2bd0be12460d63698ad2165a2ff4dd5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 13 May 2023 22:29:09 -0400 Subject: [PATCH 10/10] Set proper number of volumes. --- Machines/MSX/MSX.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 0eb24e17b..7a5c3a7ca 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -208,7 +208,12 @@ class ConcreteMachine: tape_player_.set_clocking_hint_observer(this); // Set the AY to 50% of available volume, the toggle to 10% and leave 40% for an SCC. - speaker_.mixer.set_relative_volumes({0.5f, 0.1f, 0.4f, has_opll ? 0.5f : 0.0f}); + // If there is an OPLL, give it equal volume to the AY and expect some clipping. + if constexpr (has_opll) { + speaker_.mixer.set_relative_volumes({0.5f, 0.1f, 0.4f, 0.5f}); + } else { + speaker_.mixer.set_relative_volumes({0.5f, 0.1f, 0.4f}); + } // Install the proper TV standard and select an ideal BIOS name. const std::string machine_name = "MSX";