From f4b165a631305500884fb0dfb6df68a0d63f878b Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Tue, 21 Mar 2023 16:54:48 +1100 Subject: Miscellaneous cleanup: render/bgfx/chainmanager.cpp: Only treat source file or more sepecific INI as higher priority than CFG file for setting screen chains. sega/model2.cpp, taito/taitocchip.cpp: Got rid of bankdev. Adjusted some doucmentation files. --- README.md | 37 ++++++-------- src/emu/render.cpp | 42 +++++++-------- src/mame/arcade.flt | 3 ++ src/mame/jaleco/tetrisp2_v.cpp | 5 +- src/mame/mess.flt | 3 ++ src/mame/sega/model2.cpp | 31 +++--------- src/mame/sega/model2.h | 4 +- src/mame/taito/taitocchip.cpp | 76 +++++++--------------------- src/mame/taito/taitocchip.h | 27 +++++----- src/osd/modules/render/bgfx/chainmanager.cpp | 6 ++- 10 files changed, 89 insertions(+), 145 deletions(-) diff --git a/README.md b/README.md index 159654c43a4..11e1a799e2a 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,16 @@ [![Join the chat at https://gitter.im/mamedev/mame](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mamedev/mame?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -Build status: +Continuous integration build status: -| OS/Compiler | Status | -| ------------- |:-------------:| -| Linux/GCC and clang | ![CI (Linux)](https://github.com/mamedev/mame/workflows/CI%20(Linux)/badge.svg) | -| Windows/MinGW GCC | ![CI (Windows)](https://github.com/mamedev/mame/workflows/CI%20(Windows)/badge.svg) | -| macOS/clang | ![CI (macOS)](https://github.com/mamedev/mame/workflows/CI%20(macOS)/badge.svg) | -| UI Translations | ![Compile UI translations](https://github.com/mamedev/mame/workflows/Compile%20UI%20translations/badge.svg) | -| Documentation | ![Build documentation](https://github.com/mamedev/mame/workflows/Build%20documentation/badge.svg) | +| OS/Compiler | Status | +| --------------------------- |:-------------:| +| Linux/clang and GCC | ![CI (Linux)](https://github.com/mamedev/mame/workflows/CI%20(Linux)/badge.svg) | +| Windows/MinGW GCC and clang | ![CI (Windows)](https://github.com/mamedev/mame/workflows/CI%20(Windows)/badge.svg) | +| macOS/clang | ![CI (macOS)](https://github.com/mamedev/mame/workflows/CI%20(macOS)/badge.svg) | +| UI Translations | ![Compile UI translations](https://github.com/mamedev/mame/workflows/Compile%20UI%20translations/badge.svg) | +| Documentation | ![Build documentation](https://github.com/mamedev/mame/workflows/Build%20documentation/badge.svg) | +| BGFX Shaders | ![Rebuild BGFX shaders](https://github.com/mamedev/mame/workflows/Rebuild%20BGFX%20shaders/badge.svg) | Static analysis status for entire build (except for third-party parts of project): @@ -33,27 +34,21 @@ If you're on a UNIX-like system (including Linux and macOS), it could be as easy make ``` -for a MAME build, +for a full build, ``` -make SUBTARGET=arcade +make SUBTARGET=tiny ``` -for an arcade-only build, or - -``` -make SUBTARGET=mess -``` - -for a MESS build. +for a build including a small subset of supported systems. See the [Compiling MAME](http://docs.mamedev.org/initialsetup/compilingmame.html) page on our documentation site for more information, including prerequisites for macOS and popular Linux distributions. -For recent versions of macOS you need to install [Xcode](https://developer.apple.com/xcode/) including command-line tools and [SDL 2.0](https://www.libsdl.org/download-2.0.php). +For recent versions of macOS you need to install [Xcode](https://developer.apple.com/xcode/) including command-line tools and [SDL 2.0](https://github.com/libsdl-org/SDL/releases/latest). -For Windows users, we provide a ready-made [build environment](http://mamedev.org/tools/) based on MinGW-w64. +For Windows users, we provide a ready-made [build environment](http://www.mamedev.org/tools/) based on MinGW-w64. -Visual Studio builds are also possible, but you still need [build environment](http://mamedev.org/tools/) based on MinGW-w64. +Visual Studio builds are also possible, but you still need [build environment](http://www.mamedev.org/tools/) based on MinGW-w64. In order to generate solution and project files just run: ``` @@ -69,7 +64,7 @@ make vs2019 MSBUILD=1 Where can I find out more? ============= -* [Official MAME Development Team Site](https://mamedev.org/) (includes binary downloads, wiki, forums, and more) +* [Official MAME Development Team Site](https://www.mamedev.org/) (includes binary downloads, wiki, forums, and more) * [Official MESS Wiki](http://mess.redump.net/) * [MAME Testers](https://mametesters.org/) (official bug tracker for MAME and MESS) diff --git a/src/emu/render.cpp b/src/emu/render.cpp index a02f39f841e..5fd430d16d4 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -1072,28 +1072,29 @@ void render_target::set_visibility_toggle(unsigned index, bool enable) unsigned render_target::configured_view(const char *viewname, int targetindex, int numtargets) { - layout_view *view = nullptr; - // if it isn't "auto" or an empty string, try to match it as a view name prefix if (viewname && *viewname && strcmp(viewname, "auto")) { // scan for a matching view name size_t const viewlen = strlen(viewname); - for (unsigned i = 0; !view && (m_views.size() > i); ++i) + for (unsigned i = 0; m_views.size() > i; ++i) + { if (!core_strnicmp(m_views[i].first.name().c_str(), viewname, viewlen)) - view = &m_views[i].first; + return i; + } } // if we don't have a match, default to the nth view std::vector > screens; for (screen_device &screen : screen_device_enumerator(m_manager.machine().root_device())) screens.push_back(screen); - if (!view && !screens.empty()) + if (!screens.empty()) { // if we have enough targets to be one per screen, assign in order if (numtargets >= screens.size()) { // find the first view with this screen and this screen only + layout_view *view = nullptr; screen_device const &screen = screens[index() % screens.size()]; for (unsigned i = 0; !view && (m_views.size() > i); ++i) { @@ -1111,22 +1112,21 @@ unsigned render_target::configured_view(const char *viewname, int targetindex, i } } } + if (view) + return view_index(*view); } // otherwise, find the first view that has all the screens - if (!view) + for (unsigned i = 0; m_views.size() > i; ++i) { - for (unsigned i = 0; !view && (m_views.size() > i); ++i) - { - layout_view &curview = m_views[i].first; - if (std::find_if(screens.begin(), screens.end(), [&curview] (screen_device &screen) { return !curview.has_screen(screen); }) == screens.end()) - view = &curview; - } + layout_view &curview = m_views[i].first; + if (std::find_if(screens.begin(), screens.end(), [&curview] (screen_device &screen) { return !curview.has_screen(screen); }) == screens.end()) + return i; } } - // make sure it's a valid view - return view ? view_index(*view) : 0; + // default to the first view + return 0; } @@ -2661,20 +2661,22 @@ void render_target::config_load(util::xml::data_node const *targetnode) if (!targetnode) return; + // TODO: consider option priority - command line should take precedence over CFG + // not practical at the moment because view selection options are in the OSD layer + // find the view const char *viewname = targetnode->get_attribute_string("view", nullptr); - if (viewname != nullptr) - for (int viewnum = 0; viewnum < 1000; viewnum++) + if (viewname) + { + for (unsigned viewnum = 0; m_views.size() > viewnum; viewnum++) { - const char *testname = view_name(viewnum); - if (testname == nullptr) - break; - if (!strcmp(viewname, testname)) + if (!strcmp(viewname, view_name(viewnum))) { set_view(viewnum); break; } } + } // modify the artwork config int const zoom = targetnode->get_attribute_int("zoom", -1); diff --git a/src/mame/arcade.flt b/src/mame/arcade.flt index 1a7e3179b28..77454fac01d 100644 --- a/src/mame/arcade.flt +++ b/src/mame/arcade.flt @@ -1,3 +1,6 @@ +// Example system driver filter file - includes only arcade amusement and gambling machines +// May be out of sync with source code + acorn/aristmk5.cpp acorn/ertictac.cpp acorn/ssfindo.cpp diff --git a/src/mame/jaleco/tetrisp2_v.cpp b/src/mame/jaleco/tetrisp2_v.cpp index 3d69a5a0c0b..af5756aef03 100644 --- a/src/mame/jaleco/tetrisp2_v.cpp +++ b/src/mame/jaleco/tetrisp2_v.cpp @@ -157,7 +157,10 @@ void tetrisp2_state::tetrisp2_vram_fg_w(offs_t offset, u16 data, u16 mem_mask) { // VJ and Stepping Stage write to the upper byte here to display ASCII text, // other usages in those games outside of ASCII text write a full 16-bit value. - m_vram_fg[offset] = data & 0x00ff; + if (mem_mask == 0xff00) + m_vram_fg[offset] = data & 0x00ff; + else + m_vram_fg[offset] = data; m_tilemap_fg->mark_tile_dirty(offset/2); } diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 8e42048892f..f75d8daace1 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -1,3 +1,6 @@ +// Example system driver filter file - includes systems that are not arcade amusement or gambling machines +// May be out of sync with source code + access/acvirus.cpp acorn/aa310.cpp acorn/accomm.cpp diff --git a/src/mame/sega/model2.cpp b/src/mame/sega/model2.cpp index 6629f919a59..7ddbb1bdff7 100644 --- a/src/mame/sega/model2.cpp +++ b/src/mame/sega/model2.cpp @@ -439,19 +439,15 @@ void model2_tgp_state::copro_tgp_data_map(address_map &map) map(0x0200, 0x03ff).ram(); } -void model2_tgp_state::copro_tgp_bank_map(address_map &map) +void model2_tgp_state::copro_tgp_io_map(address_map &map) { map(0x00020, 0x00023).rw(FUNC(model2_tgp_state::copro_sincos_r), FUNC(model2_tgp_state::copro_sincos_w)); map(0x00024, 0x00027).rw(FUNC(model2_tgp_state::copro_atan_r), FUNC(model2_tgp_state::copro_atan_w)); map(0x00028, 0x00029).rw(FUNC(model2_tgp_state::copro_inv_r), FUNC(model2_tgp_state::copro_inv_w)); map(0x0002a, 0x0002b).rw(FUNC(model2_tgp_state::copro_isqrt_r), FUNC(model2_tgp_state::copro_isqrt_w)); - map(0x10000, 0x1ffff).rw(FUNC(model2_tgp_state::copro_tgp_memory_r), FUNC(model2_tgp_state::copro_tgp_memory_w)); -} - -void model2_tgp_state::copro_tgp_io_map(address_map &map) -{ - map(0x0000, 0xffff).m(m_copro_tgp_bank, FUNC(address_map_bank_device::amap32)); + map(0x0000, 0xffff).view(m_copro_tgp_bank); + m_copro_tgp_bank[0](0x0000, 0xffff).rw(FUNC(model2_tgp_state::copro_tgp_memory_r), FUNC(model2_tgp_state::copro_tgp_memory_w)); } void model2_tgp_state::copro_tgp_rf_map(address_map &map) @@ -491,7 +487,10 @@ void model2_tgp_state::copro_tgp_memory_w(offs_t offset, u32 data, u32 mem_mask) void model2_tgp_state::copro_tgp_bank_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_copro_tgp_bank_reg); - m_copro_tgp_bank->set_bank(m_copro_tgp_bank_reg & 0xc00000 ? 1 : 0); + if(m_copro_tgp_bank_reg & 0xc00000) + m_copro_tgp_bank.select(0); + else + m_copro_tgp_bank.disable(); } void model2_tgp_state::copro_sincos_w(offs_t offset, u32 data, u32 mem_mask) @@ -2520,14 +2519,6 @@ void model2o_state::model2o(machine_config &config) m_copro_tgp->set_addrmap(AS_IO, &model2o_state::copro_tgp_io_map); m_copro_tgp->set_addrmap(mb86233_device::AS_RF, &model2o_state::copro_tgp_rf_map); - ADDRESS_MAP_BANK(config, m_copro_tgp_bank, 0); - m_copro_tgp_bank->set_addrmap(0, &model2o_state::copro_tgp_bank_map); - m_copro_tgp_bank->set_endianness(ENDIANNESS_LITTLE); - m_copro_tgp_bank->set_data_width(32); - m_copro_tgp_bank->set_addr_width(17); - m_copro_tgp_bank->set_shift(-2); - m_copro_tgp_bank->set_stride(0x10000); - GENERIC_FIFO_U32(config, m_copro_fifo_in, 0); GENERIC_FIFO_U32(config, m_copro_fifo_out, 0); @@ -2678,14 +2669,6 @@ void model2a_state::model2a(machine_config &config) m_copro_tgp->set_addrmap(AS_IO, &model2a_state::copro_tgp_io_map); m_copro_tgp->set_addrmap(mb86233_device::AS_RF, &model2a_state::copro_tgp_rf_map); - ADDRESS_MAP_BANK(config, m_copro_tgp_bank, 0); - m_copro_tgp_bank->set_addrmap(0, &model2a_state::copro_tgp_bank_map); - m_copro_tgp_bank->set_endianness(ENDIANNESS_LITTLE); - m_copro_tgp_bank->set_data_width(32); - m_copro_tgp_bank->set_addr_width(17); - m_copro_tgp_bank->set_shift(-2); - m_copro_tgp_bank->set_stride(0x10000); - GENERIC_FIFO_U32(config, m_copro_fifo_in, 0); GENERIC_FIFO_U32(config, m_copro_fifo_out, 0); diff --git a/src/mame/sega/model2.h b/src/mame/sega/model2.h index d87125da55d..73437e023e1 100644 --- a/src/mame/sega/model2.h +++ b/src/mame/sega/model2.h @@ -18,7 +18,6 @@ #include "cpu/mb86233/mb86233.h" #include "cpu/sharc/sharc.h" #include "cpu/mb86235/mb86235.h" -#include "machine/bankdev.h" #include "machine/eepromser.h" #include "machine/gen_fifo.h" #include "machine/i8251.h" @@ -342,7 +341,7 @@ protected: required_device m_copro_tgp; required_shared_ptr m_copro_tgp_program; required_region_ptr m_copro_tgp_tables; - required_device m_copro_tgp_bank; + memory_view m_copro_tgp_bank; u32 m_copro_tgp_bank_reg = 0; u32 m_copro_sincos_base = 0; @@ -373,7 +372,6 @@ protected: void copro_tgp_prog_map(address_map &map); void copro_tgp_data_map(address_map &map); - void copro_tgp_bank_map(address_map &map); void copro_tgp_io_map(address_map &map); void copro_tgp_rf_map(address_map &map); diff --git a/src/mame/taito/taitocchip.cpp b/src/mame/taito/taitocchip.cpp index 2ed4694ea69..02110b540b0 100644 --- a/src/mame/taito/taitocchip.cpp +++ b/src/mame/taito/taitocchip.cpp @@ -107,6 +107,9 @@ This chip *ALWAYS* has a bypass capacitor (ceramic, 104, 0.10 uF) soldered on to #include "cpu/upd7810/upd7811.h" +//#define VERBOSE 1 +#include "logmacro.h" + DEFINE_DEVICE_TYPE(TAITO_CCHIP, taito_cchip_device, "cchip", "Taito TC0030CMD (C-Chip)") @@ -115,7 +118,7 @@ taito_cchip_device::taito_cchip_device(const machine_config &mconfig, const char m_upd7811(*this, "upd7811"), m_upd4464_bank(*this, "upd4464_bank"), m_upd4464_bank68(*this, "upd4464_bank68"), - m_upd4464(*this, "upd4464"), + m_sharedram(*this, "upd4464", 0x2000, ENDIANNESS_LITTLE), m_in_pa_cb(*this), m_in_pb_cb(*this), m_in_pc_cb(*this), @@ -138,16 +141,6 @@ ROM_START( taito_cchip ) ROM_END -void taito_cchip_device::cchip_ram_bank(address_map &map) -{ - map(0x0000, 0x1fff).ram().share("upd4464"); // upd4464 -} - -void taito_cchip_device::cchip_ram_bank68(address_map &map) -{ - map(0x0000, 0x1fff).ram().share("upd4464"); -} - u8 taito_cchip_device::asic_r(offs_t offset) { if ((offset != 0x001) && (!machine().side_effects_disabled())) // prevent logerror spam for now @@ -159,11 +152,11 @@ u8 taito_cchip_device::asic_r(offs_t offset) void taito_cchip_device::asic_w(offs_t offset, u8 data) { - //logerror("%s: asic_w %04x %02x\n", machine().describe_context(), offset, data); + LOG("%s: asic_w %04x %02x\n", machine().describe_context(), offset, data); if (offset == 0x200) { - //logerror("cchip set bank to %02x\n", data & 0x7); - m_upd4464_bank->set_bank(data & 0x7); + LOG("cchip set bank to %02x\n", data & 0x7); + m_upd4464_bank->set_entry(data & 0x7); } else { @@ -173,11 +166,11 @@ void taito_cchip_device::asic_w(offs_t offset, u8 data) void taito_cchip_device::asic68_w(offs_t offset, u8 data) { - //logerror("%s: asic68_w %04x %02x\n", machine().describe_context(), offset, data); + LOG("%s: asic68_w %04x %02x\n", machine().describe_context(), offset, data); if (offset == 0x200) { - //logerror("cchip (68k side) set bank to %02x\n", data & 0x7); - m_upd4464_bank68->set_bank(data & 0x7); + LOG("cchip (68k side) set bank to %02x\n", data & 0x7); + m_upd4464_bank68->set_entry(data & 0x7); } else { @@ -185,30 +178,10 @@ void taito_cchip_device::asic68_w(offs_t offset, u8 data) } } -u8 taito_cchip_device::mem_r(offs_t offset) -{ - return m_upd4464_bank->read8(offset & 0x03ff); -} - -void taito_cchip_device::mem_w(offs_t offset, u8 data) -{ - return m_upd4464_bank->write8(offset & 0x03ff, data); -} - -u8 taito_cchip_device::mem68_r(offs_t offset) -{ - return m_upd4464_bank68->read8(offset & 0x03ff); -} - -void taito_cchip_device::mem68_w(offs_t offset, u8 data) -{ - return m_upd4464_bank68->write8(offset & 0x03ff, data); -} - void taito_cchip_device::cchip_map(address_map &map) { //map(0x0000, 0x0fff).rom(); // internal ROM of uPD7811 - map(0x1000, 0x13ff).m(m_upd4464_bank, FUNC(address_map_bank_device::amap8)); + map(0x1000, 0x13ff).bankrw(m_upd4464_bank); map(0x1400, 0x17ff).rw(FUNC(taito_cchip_device::asic_r), FUNC(taito_cchip_device::asic_w)); map(0x2000, 0x3fff).rom().region("cchip_eprom", 0); } @@ -234,21 +207,6 @@ void taito_cchip_device::device_add_mconfig(machine_config &config) upd.an5_func().set([this] { return BIT(m_in_ad_cb(), 5) ? 0xff : 0; }); upd.an6_func().set([this] { return BIT(m_in_ad_cb(), 6) ? 0xff : 0; }); upd.an7_func().set([this] { return BIT(m_in_ad_cb(), 7) ? 0xff : 0; }); - - ADDRESS_MAP_BANK(config, m_upd4464_bank, 0); - m_upd4464_bank->set_map(&taito_cchip_device::cchip_ram_bank); - m_upd4464_bank->set_endianness(ENDIANNESS_LITTLE); - m_upd4464_bank->set_data_width(8); - m_upd4464_bank->set_addr_width(13); - m_upd4464_bank->set_stride(0x400); - - // the 68k has a different view into the banked memory? - ADDRESS_MAP_BANK(config, m_upd4464_bank68, 0); - m_upd4464_bank68->set_map(&taito_cchip_device::cchip_ram_bank68); - m_upd4464_bank68->set_endianness(ENDIANNESS_LITTLE); - m_upd4464_bank68->set_data_width(8); - m_upd4464_bank68->set_addr_width(13); - m_upd4464_bank68->set_stride(0x400); } void taito_cchip_device::device_resolve_objects() @@ -264,17 +222,17 @@ void taito_cchip_device::device_resolve_objects() void taito_cchip_device::device_start() { - m_upd4464_bank->set_bank(0); - m_upd4464_bank68->set_bank(0); + m_upd4464_bank->configure_entries(0, m_sharedram.length() / 0x400, &m_sharedram[0], 0x400); + m_upd4464_bank->set_entry(0); + + // the 68k has a different view into the banked memory? + m_upd4464_bank68->configure_entries(0, m_sharedram.length() / 0x400, &m_sharedram[0], 0x400); + m_upd4464_bank68->set_entry(0); save_item(NAME(m_asic_ram)); m_asic_ram[0] = m_asic_ram[1] = m_asic_ram[2] = m_asic_ram[3] = 0; } -void taito_cchip_device::device_reset() -{ -} - const tiny_rom_entry *taito_cchip_device::device_rom_region() const { return ROM_NAME(taito_cchip); diff --git a/src/mame/taito/taitocchip.h b/src/mame/taito/taitocchip.h index 5dddc1ec6f5..840d1174f8d 100644 --- a/src/mame/taito/taitocchip.h +++ b/src/mame/taito/taitocchip.h @@ -29,32 +29,29 @@ public: void asic_w(offs_t offset, u8 data); void asic68_w(offs_t offset, u8 data); - u8 mem_r(offs_t offset); - void mem_w(offs_t offset, u8 data); + u8 mem_r(offs_t offset) { return reinterpret_cast(m_upd4464_bank->base())[offset & 0x03ff]; } + void mem_w(offs_t offset, u8 data) { reinterpret_cast(m_upd4464_bank->base())[offset & 0x03ff] = data; } - u8 mem68_r(offs_t offset); - void mem68_w(offs_t offset, u8 data); + u8 mem68_r(offs_t offset) { return reinterpret_cast(m_upd4464_bank68->base())[offset & 0x03ff]; } + void mem68_w(offs_t offset, u8 data) { reinterpret_cast(m_upd4464_bank68->base())[offset & 0x03ff] = data; } void ext_interrupt(int state); protected: - void cchip_map(address_map &map); - void cchip_ram_bank(address_map &map); - void cchip_ram_bank68(address_map &map); + void cchip_map(address_map &map) ATTR_COLD; - virtual void device_add_mconfig(machine_config &config) override; - virtual void device_resolve_objects() override; - virtual void device_start() override; - virtual const tiny_rom_entry *device_rom_region() const override; - virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + virtual void device_resolve_objects() override ATTR_COLD; + virtual void device_start() override ATTR_COLD; + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; private: u8 m_asic_ram[4]; required_device m_upd7811; - required_device m_upd4464_bank; - required_device m_upd4464_bank68; - required_shared_ptr m_upd4464; + required_memory_bank m_upd4464_bank; + memory_bank_creator m_upd4464_bank68; + memory_share_creator m_sharedram; devcb_read8 m_in_pa_cb; devcb_read8 m_in_pb_cb; diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp index 8d2ed4124af..063306d05e8 100644 --- a/src/osd/modules/render/bgfx/chainmanager.cpp +++ b/src/osd/modules/render/bgfx/chainmanager.cpp @@ -278,7 +278,7 @@ void chain_manager::parse_chain_selections(std::string_view chain_str) if (chain_names.empty()) chain_names.push_back("default"); - while (m_current_chain.size() != chain_names.size()) + while (m_current_chain.size() < chain_names.size()) { m_screen_chains.emplace_back(nullptr); m_chain_names.emplace_back(); @@ -728,8 +728,10 @@ void chain_manager::restore_slider_settings(int32_t id, std::vector m_options.get_entry(OSDOPTION_BGFX_SCREEN_CHAINS)->priority(); + bool const default_chains = (OPTION_PRIORITY_NORMAL + 6) > m_options.get_entry(OSDOPTION_BGFX_SCREEN_CHAINS)->priority(); bool const explicit_chains = !persist && !default_chains && *m_options.bgfx_screen_chains(); // if chains weren't explicitly specified, restore the chains from the config file -- cgit v1.2.3