mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Cleanups to ram_device (#2324)
Specifically: 1. Changed ram_device to expose specific options, removing the burden for clients to parse RAM strings 2. Moved validation of command line arguments out of device_validity_check(); that method is only intended for checking the device itself 3. Miscellaneous polishing
This commit is contained in:
parent
f3d04843e3
commit
a20c2428d6
@ -8,13 +8,14 @@
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "emu.h"
|
||||
#include "ram.h"
|
||||
#include "emuopts.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
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<uint32_t> 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<size;j++) {
|
||||
if (p[j]==',') p[j]=0;
|
||||
}
|
||||
|
||||
/* try to parse each option */
|
||||
while(p <= e)
|
||||
{
|
||||
uint32_t option_ram_size = parse_string(p);
|
||||
|
||||
if (option_ram_size == 0)
|
||||
osd_printf_error("Invalid RAM option: %s\n", p);
|
||||
|
||||
if (option_ram_size == specified_ram)
|
||||
is_valid = true;
|
||||
|
||||
p += strlen(p);
|
||||
if (p == e)
|
||||
break;
|
||||
p += 1;
|
||||
}
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* if not for this driver then return ok */
|
||||
is_valid = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* not specifying the ramsize on the command line is valid as well */
|
||||
is_valid = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
is_valid = true;
|
||||
|
||||
if (!is_valid)
|
||||
{
|
||||
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 != nullptr)
|
||||
util::stream_format(output, ",%s).\n", m_extra_options);
|
||||
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);
|
||||
std::string error;
|
||||
mconfig().options().set_value(OPTION_RAMSIZE, m_default_size, OPTION_PRIORITY_CMDLINE, error);
|
||||
assert(error.empty());
|
||||
}
|
||||
// report any errors
|
||||
if (!bad_option.empty())
|
||||
osd_printf_error("Invalid RAM option: %s\n", bad_option.c_str());
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// is_valid_size
|
||||
//-------------------------------------------------
|
||||
|
||||
bool ram_device::is_valid_size(uint32_t size) const
|
||||
{
|
||||
return size == default_size()
|
||||
|| std::find(extra_options().begin(), extra_options().end(), size) != extra_options().end();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// parse_string - convert a ram string to an
|
||||
// integer value
|
||||
@ -204,6 +158,7 @@ uint32_t ram_device::parse_string(const char *s)
|
||||
return ram;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// default_size
|
||||
//-------------------------------------------------
|
||||
@ -212,3 +167,45 @@ uint32_t ram_device::default_size(void) const
|
||||
{
|
||||
return parse_string(m_default_size);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// extra_options
|
||||
//-------------------------------------------------
|
||||
|
||||
const std::vector<uint32_t> &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<uint32_t> ram_device::calculate_extra_options(const char *extra_options_string, std::string *bad_option)
|
||||
{
|
||||
std::vector<uint32_t> 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;
|
||||
}
|
||||
|
@ -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<uint32_t> &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<ram_device &>(device).m_default_size = default_size; }
|
||||
static void static_set_extra_options(device_t &device, const char *extra_options) { downcast<ram_device &>(device).m_extra_options = extra_options; }
|
||||
static void static_set_extra_options(device_t &device, const char *extra_options) { downcast<ram_device &>(device).m_extra_options_string = extra_options && extra_options[0] ? extra_options : nullptr; downcast<ram_device &>(device).m_extra_options.clear(); }
|
||||
static void static_set_default_value(device_t &device, uint8_t default_value) { downcast<ram_device &>(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<uint32_t> 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<uint8_t> m_pointer;
|
||||
uint32_t m_size;
|
||||
std::vector<uint8_t> 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<uint32_t> m_extra_options;
|
||||
const char * m_extra_options_string;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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<ramoption default=\"1\">%u</ramoption>\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<ramoption>%u</ramoption>\n", ram_device::parse_string(option.c_str()));
|
||||
if (end == -1)
|
||||
break;
|
||||
}
|
||||
if (option == ram.default_size())
|
||||
fprintf(m_output, "\t\t<ramoption default=\"1\">%u</ramoption>\n", option);
|
||||
else
|
||||
fprintf(m_output, "\t\t<ramoption>%u</ramoption>\n", option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user