summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2018-03-27 01:40:15 +1100
committer Vas Crabb <vas@vastheman.com>2018-03-27 01:40:15 +1100
commitebcd71b7f163c7732ab082d43a4a165e67c3353b (patch)
treea89eab4a82b4cc80acecb6590872f5901174da13
parentd9231ed334d1411ed64ad400d5d8a1991e7eae1d (diff)
minimaws: expose RAM size
-rw-r--r--scripts/minimaws/lib/assets/machine.js29
-rw-r--r--scripts/minimaws/lib/dbaccess.py35
-rw-r--r--scripts/minimaws/lib/htmltmpl.py9
-rw-r--r--scripts/minimaws/lib/lxparse.py20
-rw-r--r--scripts/minimaws/lib/wsgiserve.py16
-rw-r--r--src/devices/machine/ram.cpp25
-rw-r--r--src/frontend/mame/info.cpp4
7 files changed, 127 insertions, 11 deletions
diff --git a/scripts/minimaws/lib/assets/machine.js b/scripts/minimaws/lib/assets/machine.js
index 368b56b349c..d0774d02c0a 100644
--- a/scripts/minimaws/lib/assets/machine.js
+++ b/scripts/minimaws/lib/assets/machine.js
@@ -47,6 +47,11 @@ function update_cmd_preview()
if (sysbios && (!elide_defaults || (sysbios.selectedOptions[0].getAttribute('data-isdefault') != 'yes')))
add_option('bios', sysbios.value);
+ // add RAM option if applicable
+ var ramopt = document.getElementById('select-ram-option');
+ if (ramopt && (!elide_defaults || (ramopt.selectedOptions[0].getAttribute('data-isdefault') != 'yes')))
+ add_option('ramsize', ramopt.value);
+
var slotslist = document.getElementById('list-slot-options');
if (slotslist)
{
@@ -71,7 +76,7 @@ function update_cmd_preview()
// replace the preview with appropriate element
var target = document.getElementById('para-cmd-preview');
- var replacement = document.createElement(inifmt ? 'pre' : 'p');
+ var replacement = document.createElement(inifmt ? 'pre' : 'tt');
replacement.setAttribute('id', 'para-cmd-preview');
replacement.textContent = result;
target.parentNode.replaceChild(replacement, target);
@@ -100,6 +105,28 @@ function set_default_system_bios()
}
+function set_default_ram_option()
+{
+ // search for an explicit default option
+ var ramopt = document.getElementById('select-ram-option');
+ var len = ramopt.options.length;
+ for (var i = 0; i < len; i++)
+ {
+ if (ramopt.options[i].getAttribute('data-isdefault') == 'yes')
+ {
+ // select it and add a button for restoring it
+ ramopt.selectedIndex = i;
+ var dflt = make_restore_default_button('default', 'btn-def-ram-option', ramopt, i);
+ ramopt.onchange = make_slot_bios_change_handler(dflt);
+ ramopt.parentNode.appendChild(document.createTextNode(' '));
+ ramopt.parentNode.appendChild(dflt);
+ break;
+ }
+ }
+ update_cmd_preview();
+}
+
+
var fetch_bios_sets = (function ()
{
var pending = Object.create(null);
diff --git a/scripts/minimaws/lib/dbaccess.py b/scripts/minimaws/lib/dbaccess.py
index 3366d6f7eb5..57de6aeb236 100644
--- a/scripts/minimaws/lib/dbaccess.py
+++ b/scripts/minimaws/lib/dbaccess.py
@@ -128,6 +128,19 @@ class SchemaQueries(object):
' slotoption INTEGER NOT NULL,\n' \
' FOREIGN KEY (id) REFERENCES slot (id),\n' \
' FOREIGN KEY (slotoption) REFERENCES slotoption (id))'
+ CREATE_RAMOPTION = \
+ 'CREATE TABLE ramoption (\n' \
+ ' machine INTEGER NOT NULL,\n' \
+ ' size INTEGER NOT NULL,\n' \
+ ' name TEXT NOT NULL,\n' \
+ ' PRIMARY KEY (machine ASC, size ASC),\n' \
+ ' FOREIGN KEY (machine) REFERENCES machine (id))'
+ CREATE_RAMDEFAULT = \
+ 'CREATE TABLE ramdefault (\n' \
+ ' machine INTEGER PRIMARY KEY,\n' \
+ ' size INTEGER NOT NULL,\n' \
+ ' FOREIGN KEY (machine) REFERENCES machine (id),\n' \
+ ' FOREIGN KEY (machine, size) REFERENCES ramoption (machine, size))'
CREATE_TEMPORARY_DEVICEREFERENCE = 'CREATE TEMPORARY TABLE temp_devicereference (id INTEGER PRIMARY KEY, machine INTEGER NOT NULL, device TEXT NOT NULL, UNIQUE (machine, device))'
CREATE_TEMPORARY_SLOTOPTION = 'CREATE TEMPORARY TABLE temp_slotoption (id INTEGER PRIMARY KEY, slot INTEGER NOT NULL, device TEXT NOT NULL, name TEXT NOT NULL)'
@@ -181,7 +194,9 @@ class SchemaQueries(object):
CREATE_FEATURE,
CREATE_SLOT,
CREATE_SLOTOPTION,
- CREATE_SLOTDEFAULT)
+ CREATE_SLOTDEFAULT,
+ CREATE_RAMOPTION,
+ CREATE_RAMDEFAULT)
CREATE_TEMPORARY_TABLES = (
CREATE_TEMPORARY_DEVICEREFERENCE,
@@ -225,6 +240,8 @@ class UpdateQueries(object):
ADD_DIPVALUE = 'INSERT INTO dipvalue (dipswitch, name, value, isdefault) VALUES (?, ?, ?, ?)'
ADD_FEATURE = 'INSERT INTO feature (machine, featuretype, status, overall) SELECT ?, id, ?, ? FROM featuretype WHERE name = ?'
ADD_SLOT = 'INSERT INTO slot (machine, name) VALUES (?, ?)'
+ ADD_RAMOPTION = 'INSERT INTO ramoption (machine, size, name) VALUES (?, ?, ?)'
+ ADD_RAMDEFAULT = 'INSERT INTO ramdefault (machine, size) VALUES (?, ?)'
ADD_TEMPORARY_DEVICEREFERENCE = 'INSERT OR IGNORE INTO temp_devicereference (machine, device) VALUES (?, ?)'
ADD_TEMPORARY_SLOTOPTION = 'INSERT INTO temp_slotoption (slot, device, name) VALUES (?, ?, ?)'
@@ -433,6 +450,14 @@ class QueryCursor(object):
'WHERE slot.machine = ?',
(machine, ))
+ def get_ram_options(self, machine):
+ return self.dbcurs.execute(
+ 'SELECT ramoption.name AS name, ramoption.size AS size, COUNT(ramdefault.machine) AS isdefault ' \
+ 'FROM ramoption LEFT JOIN ramdefault USING (machine, size) WHERE ramoption.machine = ? ' \
+ 'GROUP BY ramoption.machine, ramoption.size ' \
+ 'ORDER BY ramoption.size',
+ (machine, ))
+
class UpdateCursor(object):
def __init__(self, dbconn, **kwargs):
@@ -503,6 +528,14 @@ class UpdateCursor(object):
self.dbcurs.execute(UpdateQueries.ADD_TEMPORARY_SLOTDEFAULT, (slot, slotoption))
return self.dbcurs.lastrowid
+ def add_ramoption(self, machine, name, size):
+ self.dbcurs.execute(UpdateQueries.ADD_RAMOPTION, (machine, size, name))
+ return self.dbcurs.lastrowid
+
+ def add_ramdefault(self, machine, size):
+ self.dbcurs.execute(UpdateQueries.ADD_RAMDEFAULT, (machine, size))
+ return self.dbcurs.lastrowid
+
class QueryConnection(object):
def __init__(self, database, **kwargs):
diff --git a/scripts/minimaws/lib/htmltmpl.py b/scripts/minimaws/lib/htmltmpl.py
index 105f901711b..1a030d04e93 100644
--- a/scripts/minimaws/lib/htmltmpl.py
+++ b/scripts/minimaws/lib/htmltmpl.py
@@ -58,11 +58,18 @@ MACHINE_OPTIONS_HEADING = string.Template(
MACHINE_BIOS_PROLOGUE = string.Template(
'<h3>System BIOS</h3>' \
- '<div><select id="select-system-bios" onchange="update_cmd_preview()"></div>')
+ '<select id="select-system-bios" onchange="update_cmd_preview()">')
MACHINE_BIOS_OPTION = string.Template(
' <option value="${name}" data-isdefault="${isdefault}">${name} - ${description}</option>\n')
+MACHINE_RAM_PROLOGUE = string.Template(
+ '<h3>RAM Size</h3>' \
+ '<select id="select-ram-option" onchange="update_cmd_preview()">')
+
+MACHINE_RAM_OPTION = string.Template(
+ ' <option value="${name}" data-isdefault="${isdefault}">${name} (${size})</option>\n')
+
MACHINE_SLOTS_PLACEHOLDER = string.Template(
'<h3>Slots</h3>\n' \
'<p id="para-slots-placeholder">Loading slot information&hellip;<p>\n' \
diff --git a/scripts/minimaws/lib/lxparse.py b/scripts/minimaws/lib/lxparse.py
index 69d5b91ba0e..dfd8cbae45e 100644
--- a/scripts/minimaws/lib/lxparse.py
+++ b/scripts/minimaws/lib/lxparse.py
@@ -151,6 +151,23 @@ class SlotHandler(ElementHandler):
self.setChildHandler(name, attrs, self.IGNORE)
+class RamOptionHandler(TextAccumulator):
+ def __init__(self, parent, **kwargs):
+ super(RamOptionHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = parent.dbcurs
+ self.machine = parent.id
+
+ def startMainElement(self, name, attrs):
+ self.name = attrs['name']
+ self.default = attrs.get('default', 'no') == 'yes';
+
+ def endMainElement(self, name):
+ self.size = int(self.text)
+ self.dbcurs.add_ramoption(self.machine, self.name, self.size)
+ if self.default:
+ self.dbcurs.add_ramdefault(self.machine, self.size)
+
+
class MachineHandler(ElementHandler):
CHILD_HANDLERS = {
'description': TextAccumulator,
@@ -158,7 +175,8 @@ class MachineHandler(ElementHandler):
'manufacturer': TextAccumulator,
'dipswitch': DipSwitchHandler,
'configuration': DipSwitchHandler,
- 'slot': SlotHandler }
+ 'slot': SlotHandler,
+ 'ramoption': RamOptionHandler }
def __init__(self, parent, **kwargs):
super(MachineHandler, self).__init__(parent=parent, **kwargs)
diff --git a/scripts/minimaws/lib/wsgiserve.py b/scripts/minimaws/lib/wsgiserve.py
index e8182f06077..b30828e01e0 100644
--- a/scripts/minimaws/lib/wsgiserve.py
+++ b/scripts/minimaws/lib/wsgiserve.py
@@ -221,6 +221,22 @@ class MachineHandler(QueryPageHandler):
if haveoptions:
yield '</select>\n<script>set_default_system_bios();</script>\n'.encode('utf-8')
+ # allow RAM size selection
+ first = True
+ for name, size, isdef in self.dbcurs.get_ram_options(id):
+ if first:
+ if not haveoptions:
+ haveoptions = True;
+ yield htmltmpl.MACHINE_OPTIONS_HEADING.substitute().encode('utf-8')
+ yield htmltmpl.MACHINE_RAM_PROLOGUE.substitute().encode('utf-8')
+ first = False
+ yield htmltmpl.MACHINE_RAM_OPTION.substitute(
+ name=cgi.escape(name, True),
+ size=cgi.escape('{:,}'.format(size)),
+ isdefault=('yes' if isdef else 'no')).encode('utf-8')
+ if not first:
+ yield '</select>\n<script>set_default_ram_option();</script>\n'.encode('utf-8')
+
# placeholder for machine slots - populated by client-side JavaScript
if self.dbcurs.count_slots(id):
if not haveoptions:
diff --git a/src/devices/machine/ram.cpp b/src/devices/machine/ram.cpp
index 1559de7a2e7..da73376f7fe 100644
--- a/src/devices/machine/ram.cpp
+++ b/src/devices/machine/ram.cpp
@@ -14,7 +14,10 @@
#include <stdio.h>
#include <ctype.h>
+
#include <algorithm>
+#include <functional>
+#include <set>
namespace {
@@ -176,13 +179,25 @@ void ram_device::device_validity_check(validity_checker &valid) const
osd_printf_error("Invalid default RAM option: %s\n", m_default_size);
// calculate any extra options
- std::string bad_option;
if (m_extra_options_string)
- calculate_extra_options(m_extra_options_string, &bad_option);
+ {
+ std::string bad_option;
+ extra_option_vector const extras(calculate_extra_options(m_extra_options_string, &bad_option));
+
+ // report any errors
+ if (!bad_option.empty())
+ osd_printf_error("Invalid RAM option: %s\n", bad_option.c_str());
- // report any errors
- if (!bad_option.empty())
- osd_printf_error("Invalid RAM option: %s\n", bad_option.c_str());
+ // report duplicates
+ using extra_option_ref_set = std::set<std::reference_wrapper<extra_option const>, bool (*)(extra_option const &, extra_option const &)>;
+ extra_option_ref_set sorted([] (extra_option const &a, extra_option const &b) { return a.second < b.second; });
+ for (extra_option const &opt : extras)
+ {
+ auto const ins(sorted.emplace(opt));
+ if (!ins.second)
+ osd_printf_error("Duplicate RAM options: %s == %s (%u)\n", ins.first->get().first.c_str(), opt.first.c_str(), opt.second);
+ }
+ }
}
diff --git a/src/frontend/mame/info.cpp b/src/frontend/mame/info.cpp
index bcf9bceb1d0..613997c3e7f 100644
--- a/src/frontend/mame/info.cpp
+++ b/src/frontend/mame/info.cpp
@@ -1828,7 +1828,7 @@ void info_xml_creator::output_ramoptions(device_t &root)
{
assert(!havedefault);
havedefault = true;
- fprintf(m_output, "\t\t<ramoption name=\"%s\" default=\"1\">%u</ramoption>\n", util::xml::normalize_string(option.first.c_str()), option.second);
+ fprintf(m_output, "\t\t<ramoption name=\"%s\" default=\"yes\">%u</ramoption>\n", util::xml::normalize_string(option.first.c_str()), option.second);
}
else
{
@@ -1836,7 +1836,7 @@ void info_xml_creator::output_ramoptions(device_t &root)
}
}
if (!havedefault)
- fprintf(m_output, "\t\t<ramoption name=\"%s\" default=\"1\">%u</ramoption>\n", ram.default_size_string(), defsize);
+ fprintf(m_output, "\t\t<ramoption name=\"%s\" default=\"yes\">%u</ramoption>\n", ram.default_size_string(), defsize);
}
}