minimaws: expose RAM size

This commit is contained in:
Vas Crabb 2018-03-27 01:40:15 +11:00
parent d9231ed334
commit ebcd71b7f1
7 changed files with 127 additions and 11 deletions

View File

@ -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);

View File

@ -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):

View File

@ -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' \

View File

@ -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)

View File

@ -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:

View File

@ -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);
}
}
}

View File

@ -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);
}
}