diff --git a/src/devices/machine/ram.cpp b/src/devices/machine/ram.cpp index a57f144ae0d..92cc93f24bc 100644 --- a/src/devices/machine/ram.cpp +++ b/src/devices/machine/ram.cpp @@ -8,13 +8,14 @@ **************************************************************************/ -#include -#include - #include "emu.h" #include "ram.h" #include "emuopts.h" +#include +#include +#include + /***************************************************************************** LIVE DEVICE @@ -30,41 +31,62 @@ DEFINE_DEVICE_TYPE(RAM, ram_device, "ram", "RAM") ram_device::ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, RAM, tag, owner, clock) + , m_size(0) + , m_default_size(0) + , m_default_value(0xCD) + , m_extra_options_string(nullptr) { - m_size = 0; - m_default_size = nullptr; - m_extra_options = nullptr; - m_default_value = 0xCD; } + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void ram_device::device_start() { - /* the device named 'ram' can get ram options from command line */ + // the device named 'ram' can get ram options from command line m_size = 0; if (strcmp(tag(), ":" RAM_TAG) == 0) { const char *ramsize_string = machine().options().ram_size(); - if ((ramsize_string != nullptr) && (ramsize_string[0] != '\0')) + if (ramsize_string && *ramsize_string) + { m_size = parse_string(ramsize_string); + if (!is_valid_size(m_size)) + { + std::ostringstream output; + util::stream_format(output, "Cannot recognize the RAM option %s", ramsize_string); + util::stream_format(output, " (valid options are %s", m_default_size); + + if (m_extra_options_string) + util::stream_format(output, ",%s).\n", m_extra_options_string); + else + util::stream_format(output, ").\n"); + + osd_printf_error("%s", output.str().c_str()); + + osd_printf_warning("Setting value to default %s\n", m_default_size); + + m_size = 0; + } + } } - /* if we didn't get a size yet, use the default */ + // if we didn't get a size yet, use the default if (m_size == 0) m_size = default_size(); - /* allocate space for the ram */ + // allocate space for the ram m_pointer.resize(m_size); memset(&m_pointer[0], m_default_value, m_size); - /* register for state saving */ + // register for state saving save_item(NAME(m_size)); save_item(NAME(m_pointer)); } + //------------------------------------------------- // device_validity_check - device-specific validity // checks @@ -72,101 +94,33 @@ void ram_device::device_start() void ram_device::device_validity_check(validity_checker &valid) const { - const char *ramsize_string = nullptr; - int is_valid = false; - uint32_t specified_ram; - const char *gamename_option; - - /* verify default ram value */ + // verify default ram value if (default_size() == 0) osd_printf_error("Invalid default RAM option: %s\n", m_default_size); - /* command line options are only parsed for the device named RAM_TAG */ - if (tag() != nullptr && strcmp(tag(), ":" RAM_TAG) == 0) - { - /* verify command line ram option */ - ramsize_string = mconfig().options().ram_size(); - gamename_option = mconfig().options().system_name(); + // calculate any extra options + std::vector extra_options; + std::string bad_option; + if (m_extra_options_string) + extra_options = calculate_extra_options(m_extra_options_string, &bad_option); - if ((ramsize_string != nullptr) && (ramsize_string[0] != '\0')) - { - specified_ram = parse_string(ramsize_string); - - if (specified_ram == 0) - osd_printf_error("Cannot recognize the RAM option %s\n", ramsize_string); - - if (gamename_option != nullptr && *gamename_option != 0 && strcmp(gamename_option, mconfig().gamedrv().name) == 0) - { - /* compare command line option to default value */ - if (default_size() == specified_ram) - is_valid = true; - - /* verify extra ram options */ - if (m_extra_options != nullptr) - { - int j; - int size = strlen(m_extra_options); - char * const s = core_strdup(m_extra_options); - char * const e = s + size; - char *p = s; - for (j=0;j &ram_device::extra_options(void) const +{ + if (m_extra_options_string && m_extra_options.empty()) + m_extra_options = calculate_extra_options(m_extra_options_string, nullptr); + return m_extra_options; +} + + +//------------------------------------------------- +// calculate_extra_options +//------------------------------------------------- + +std::vector ram_device::calculate_extra_options(const char *extra_options_string, std::string *bad_option) +{ + std::vector result; + std::string options(extra_options_string); + + bool done = false; + for (std::string::size_type start = 0, end = options.find_first_of(','); !done; start = end + 1, end = options.find_first_of(',', start)) + { + // parse the option + const std::string ram_option_string = options.substr(start, (end == -1) ? -1 : end - start); + const uint32_t ram_option = parse_string(ram_option_string.c_str()); + if (ram_option == 0) + { + if (bad_option) + *bad_option = std::move(ram_option_string); + return result; + } + + // and add it to the results + result.push_back(ram_option); + done = end == std::string::npos; + } + return result; +} diff --git a/src/devices/machine/ram.h b/src/devices/machine/ram.h index e35e9bf51c5..e54406cc32f 100644 --- a/src/devices/machine/ram.h +++ b/src/devices/machine/ram.h @@ -56,12 +56,11 @@ public: ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // accessors - uint32_t size(void) const { return m_size; } - uint32_t mask(void) const { return m_size - 1; } - uint8_t *pointer(void) { return &m_pointer[0]; } - static uint32_t parse_string(const char *s); - uint32_t default_size(void) const; - const char *extra_options(void) const { return m_extra_options; } + uint32_t size() const { return m_size; } + uint32_t mask() const { return m_size - 1; } + uint8_t *pointer() { return &m_pointer[0]; } + uint32_t default_size() const; + const std::vector &extra_options() const; // read/write uint8_t read(offs_t offset) { return m_pointer[offset % m_size]; } @@ -69,22 +68,27 @@ public: // inline configuration helpers static void static_set_default_size(device_t &device, const char *default_size) { downcast(device).m_default_size = default_size; } - static void static_set_extra_options(device_t &device, const char *extra_options) { downcast(device).m_extra_options = extra_options; } + static void static_set_extra_options(device_t &device, const char *extra_options) { downcast(device).m_extra_options_string = extra_options && extra_options[0] ? extra_options : nullptr; downcast(device).m_extra_options.clear(); } static void static_set_default_value(device_t &device, uint8_t default_value) { downcast(device).m_default_value = default_value; } protected: - virtual void device_start(void) override; + virtual void device_start() override; virtual void device_validity_check(validity_checker &valid) const override; private: + static std::vector calculate_extra_options(const char *extra_options_string, std::string *bad_option); + static uint32_t parse_string(const char *s); + bool is_valid_size(uint32_t size) const; + // device state - uint32_t m_size; - std::vector m_pointer; + uint32_t m_size; + std::vector m_pointer; // device config - const char *m_default_size; - const char *m_extra_options; - uint8_t m_default_value; + const char * m_default_size; + uint8_t m_default_value; + mutable std::vector m_extra_options; + const char * m_extra_options_string; }; diff --git a/src/frontend/mame/info.cpp b/src/frontend/mame/info.cpp index 8af0df55e60..d65f1d932bb 100644 --- a/src/frontend/mame/info.cpp +++ b/src/frontend/mame/info.cpp @@ -1686,19 +1686,12 @@ void info_xml_creator::output_ramoptions(device_t &root) { for (const ram_device &ram : ram_device_iterator(root)) { - fprintf(m_output, "\t\t%u\n", ram.default_size()); - - if (ram.extra_options() != nullptr) + for (uint32_t option : ram.extra_options()) { - std::string options(ram.extra_options()); - for (int start = 0, end = options.find_first_of(',');; start = end + 1, end = options.find_first_of(',', start)) - { - std::string option; - option.assign(options.substr(start, (end == -1) ? -1 : end - start)); - fprintf(m_output, "\t\t%u\n", ram_device::parse_string(option.c_str())); - if (end == -1) - break; - } + if (option == ram.default_size()) + fprintf(m_output, "\t\t%u\n", option); + else + fprintf(m_output, "\t\t%u\n", option); } } }