-ui/ui.cpp, ui/videoopt.cpp: Made pointer activity timeout configurable.

-midway/wmg.cpp: Use a memory bank for NVRAM; also got rid of a really pointless trampoline function.
This commit is contained in:
Vas Crabb 2024-04-18 05:59:03 +10:00
parent 80dd0682d8
commit 520ed5e44b
6 changed files with 377 additions and 66 deletions

View File

@ -71,8 +71,10 @@ with a ``version`` attribute specifying the configuration format version
(currently ``10`` MAME will not load a file using a different version). The
``mameconfig`` element contains one or more ``system`` elements, each of which
has a ``name`` attribute specifying the system(s) it applies to. Each
``system`` element contains an ``input`` element which holds the actual
``system`` element may contain an ``input`` element which holds the actual
``remap`` and ``port`` configuration elements, which will be described later.
Each ``system`` element may also contain a ``pointer_input`` element to set
pointer input options for systems with interactive artwork.
When launching an emulated system, MAME will apply configuration from ``system``
elements where the value of the ``name`` attribute meets one of the following
@ -261,3 +263,45 @@ MAME applies ``mapdevice`` elements found inside the first applicable ``system``
element only. To avoid confusion, its simplest to place the ``system`` element
applying to all systems (``name`` attribute set to ``default``) first in the
file, and use it to assign input device numbers.
.. _ctrlrcfg-pointers:
Setting pointer input options
-----------------------------
A ``pointer_input`` element may contain ``target`` elements to set pointer input
options for each output screen or window. Each ``target`` element must have an
``index`` attribute containing the zero-based index of the screen to which it
applies.
Each ``target`` element may have an ``activity_timeout`` attribute to set the
time after which a mouse pointer that has not moved and has no buttons pressed
will be considered inactive. The value is specified in seconds, and must be in
the range of 0.1 seconds to 10 seconds, inclusive.
Each ``target`` element may have a ``hide_inactive`` element to set whether
inactive pointers may be hidden. If the value is ``0`` (zero), inactive
pointers will not be hidden. If the value is ``1``, inactive pointers may be
hidden, but layout views can still specify that inactive pointers should not be
hidden.
Heres an example demonstrating the use of this feature:
.. code-block:: XML
<system name="default">
<pointer_input>
<target index="0" activity_timeout="1.5" />
</pointer_input>
</system>
<system name="intellec4.cpp">
<pointer_input>
<target index="0" hide_inactive="0" />
</pointer_input>
</system>
For all systems, pointers over the first output screen or window will be
considered inactive after not moving for 1.5 seconds with no buttons pressed.
For systems defined in ``intellec4.cpp``, inactive pointers over the first
window will not be hidden.

View File

@ -63,9 +63,9 @@ copyright = u'1997-2024, MAMEdev and contributors'
# built documents.
#
# The short X.Y version.
version = '0.264'
version = '0.265'
# The full version, including alpha/beta/rc tags.
release = '0.264'
release = '0.265'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -48,7 +48,6 @@
#include "../osd/modules/lib/osdlib.h"
#include "../osd/modules/lib/osdobj_common.h"
#include <chrono>
#include <functional>
#include <type_traits>
@ -189,6 +188,28 @@ struct mame_ui_manager::active_pointer
};
struct mame_ui_manager::pointer_options
{
pointer_options()
: timeout(std::chrono::seconds(3))
, hide_inactive(true)
, timeout_set(false)
, hide_inactive_set(false)
{
}
bool options_set() const
{
return timeout_set || hide_inactive_set;
}
std::chrono::steady_clock::duration timeout;
bool hide_inactive;
bool timeout_set;
bool hide_inactive_set;
};
//-------------------------------------------------
// ctor - set up the user interface
//-------------------------------------------------
@ -252,8 +273,12 @@ void mame_ui_manager::init()
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&mame_ui_manager::exit, this));
machine().configuration().config_register(
"ui_warnings",
configuration_manager::load_delegate(&mame_ui_manager::config_load, this),
configuration_manager::save_delegate(&mame_ui_manager::config_save, this));
configuration_manager::load_delegate(&mame_ui_manager::config_load_warnings, this),
configuration_manager::save_delegate(&mame_ui_manager::config_save_warnings, this));
machine().configuration().config_register(
"pointer_input",
configuration_manager::load_delegate(&mame_ui_manager::config_load_pointers, this),
configuration_manager::save_delegate(&mame_ui_manager::config_save_pointers, this));
// create mouse bitmap
uint32_t *dst = &m_mouse_bitmap.pix(0);
@ -311,10 +336,14 @@ void mame_ui_manager::exit()
//-------------------------------------------------
// config_load - load configuration data
// config_load_warnings - load info on last time
// emulation status warnings showed
//-------------------------------------------------
void mame_ui_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
void mame_ui_manager::config_load_warnings(
config_type cfg_type,
config_level cfg_level,
util::xml::data_node const *parentnode)
{
// make sure it's relevant and there's data available
if (config_type::SYSTEM == cfg_type)
@ -352,10 +381,13 @@ void mame_ui_manager::config_load(config_type cfg_type, config_level cfg_level,
//-------------------------------------------------
// config_save - save configuration data
// config_save_warnings - save information on
// last time emulation status warnings showed
//-------------------------------------------------
void mame_ui_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
void mame_ui_manager::config_save_warnings(
config_type cfg_type,
util::xml::data_node *parentnode)
{
// only save system-level configuration when times are valid
if ((config_type::SYSTEM == cfg_type) && (std::time_t(-1) != m_last_launch_time) && (std::time_t(-1) != m_last_warning_time))
@ -382,6 +414,101 @@ void mame_ui_manager::config_save(config_type cfg_type, util::xml::data_node *pa
}
//-------------------------------------------------
// config_load_pointers - load pointer input
// settings
//-------------------------------------------------
void mame_ui_manager::config_load_pointers(
config_type cfg_type,
config_level cfg_level,
util::xml::data_node const *parentnode)
{
switch (cfg_type)
{
case config_type::INIT:
{
int last(-1);
for (auto const &target : machine().render().targets())
{
assert(target.index() >= 0);
if (!target.hidden())
last = (std::max)(target.index(), last);
}
m_pointer_options.resize(last + 1);
}
break;
case config_type::CONTROLLER:
case config_type::SYSTEM:
if (!parentnode)
break;
for (auto const *targetnode = parentnode->get_child("target"); targetnode; targetnode = targetnode->get_next_sibling("target"))
{
auto const index(targetnode->get_attribute_int("index", -1));
if ((0 <= index) && (m_pointer_options.size() > index))
{
auto const timeout(targetnode->get_attribute_float("activity_timeout", -1.0F));
auto const ms(std::lround(timeout * 1000.0F));
if ((100 <= ms) && (10'000 >= ms))
{
m_pointer_options[index].timeout = std::chrono::milliseconds(ms);
if (config_type::SYSTEM == cfg_type)
m_pointer_options[index].timeout_set = true;
}
auto const hide(targetnode->get_attribute_int("hide_inactive", -1));
if (0 <= hide)
{
m_pointer_options[index].hide_inactive = hide != 0;
if (config_type::SYSTEM == cfg_type)
m_pointer_options[index].hide_inactive_set = true;
}
}
}
break;
case config_type::DEFAULT:
case config_type::FINAL:
break;
}
}
//-------------------------------------------------
// config_save_pointers - save pointer input
// settings
//-------------------------------------------------
void mame_ui_manager::config_save_pointers(
config_type cfg_type,
util::xml::data_node *parentnode)
{
if (config_type::SYSTEM == cfg_type)
{
for (std::size_t i = 0; m_pointer_options.size() > i; ++i)
{
pointer_options const &options(m_pointer_options[i]);
if (options.options_set())
{
util::xml::data_node *const targetnode = parentnode->add_child("target", nullptr);
if (targetnode)
{
targetnode->set_attribute_int("index", i);
if (options.timeout_set)
{
auto const ms(std::chrono::duration_cast<std::chrono::milliseconds>(options.timeout));
targetnode->set_attribute_float("activity_timeout", float(ms.count()) * 0.001F);
}
if (options.hide_inactive_set)
targetnode->set_attribute_int("hide_inactive", options.hide_inactive);
}
}
}
}
}
//-------------------------------------------------
// initialize - initialize ui lists
//-------------------------------------------------
@ -1381,14 +1508,23 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
display_pointer_vector pointers;
pointers.reserve(m_active_pointers.size());
auto const now(std::chrono::steady_clock::now());
auto expiry(now);
render_target *target(nullptr);
layout_view const *view(nullptr);
bool hide_inactive(true);
for (auto const &pointer : m_active_pointers)
{
layout_view const &view(pointer.target->current_view());
if (view.show_pointers())
if (pointer.target != target)
{
// TODO: make timeout configurable
if (!view.hide_inactive_pointers() || (osd::ui_event_handler::pointer::PEN == pointer.type) || ((now - pointer.updated) <= std::chrono::seconds(3)))
pointers.emplace_back(display_pointer{ *pointer.target, pointer.type, pointer.x, pointer.y });
target = pointer.target;
view = &target->current_view();
hide_inactive = m_pointer_options[target->index()].hide_inactive && view->hide_inactive_pointers();
expiry = now - m_pointer_options[target->index()].timeout;
}
if (view->show_pointers())
{
if (!hide_inactive || (osd::ui_event_handler::pointer::PEN == pointer.type) || (pointer.updated >= expiry))
pointers.emplace_back(display_pointer{ *target, pointer.type, pointer.x, pointer.y });
}
}
set_pointers(pointers.begin(), pointers.end());
@ -1590,6 +1726,70 @@ void mame_ui_manager::request_quit()
}
//-------------------------------------------------
// set_pointer_activity_timeout - set per-target
// pointer activity timeout
//-------------------------------------------------
void mame_ui_manager::set_pointer_activity_timeout(int target, std::chrono::steady_clock::duration timeout) noexcept
{
assert((0 <= target) && (m_pointer_options.size() > target));
if ((0 <= target) && (m_pointer_options.size() > target))
{
m_pointer_options[target].timeout = timeout;
m_pointer_options[target].timeout_set = true;
}
}
//-------------------------------------------------
// set_hide_inactive_pointers - set per-target
// hide inactive pointers setting
//-------------------------------------------------
void mame_ui_manager::set_hide_inactive_pointers(int target, bool hide) noexcept
{
assert((0 <= target) && (m_pointer_options.size() > target));
if ((0 <= target) && (m_pointer_options.size() > target))
{
m_pointer_options[target].hide_inactive = hide;
m_pointer_options[target].hide_inactive_set = true;
}
}
//-------------------------------------------------
// pointer_activity_timeout - get per-target
// pointer activity timeout
//-------------------------------------------------
std::chrono::steady_clock::duration mame_ui_manager::pointer_activity_timeout(int target) const noexcept
{
assert((0 <= target) && (m_pointer_options.size() > target));
if ((0 <= target) && (m_pointer_options.size() > target))
return m_pointer_options[target].timeout;
else
return pointer_options().timeout;
}
//-------------------------------------------------
// hide_inactive_pointers - get per-target hide
// inactive pointers setting
//-------------------------------------------------
bool mame_ui_manager::hide_inactive_pointers(int target) const noexcept
{
assert((0 <= target) && (m_pointer_options.size() > target));
if ((0 <= target) && (m_pointer_options.size() > target))
return m_pointer_options[target].hide_inactive;
else
return pointer_options().hide_inactive;
}
/***************************************************************************
SLIDER CONTROLS
***************************************************************************/

View File

@ -26,6 +26,7 @@
#include <any>
#include <cassert>
#include <chrono>
#include <ctime>
#include <functional>
#include <set>
@ -164,13 +165,21 @@ public:
void display_startup_screens(bool first_time);
virtual void set_startup_text(const char *text, bool force) override;
bool update_and_render(render_container &container);
// getting display font and metrics
render_font *get_font();
float get_line_height(float scale = 1.0F);
float target_font_height() const { return m_target_font_height; }
float get_char_width(char32_t ch);
float get_string_width(std::string_view s);
float get_string_width(std::string_view s, float text_size);
float box_lr_border() const { return target_font_height() * 0.25f; }
float box_tb_border() const { return target_font_height() * 0.25f; }
// drawing boxes and text
void draw_outlined_box(render_container &container, float x0, float y0, float x1, float y1, rgb_t backcolor);
void draw_outlined_box(render_container &container, float x0, float y0, float x1, float y1, rgb_t fgcolor, rgb_t bgcolor);
void draw_textured_box(render_container &container, float x0, float y0, float x1, float y1, rgb_t backcolor, rgb_t linecolor, render_texture *texture = nullptr, uint32_t flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
void draw_text(render_container &container, std::string_view buf, float x, float y);
void draw_text_full(render_container &container, std::string_view origs, float x, float y, float origwrapwidth, ui::text_layout::text_justify justify, ui::text_layout::word_wrapping wrap, draw_mode draw, rgb_t fgcolor, rgb_t bgcolor, float *totalwidth = nullptr, float *totalheight = nullptr);
void draw_text_full(render_container &container, std::string_view origs, float x, float y, float origwrapwidth, ui::text_layout::text_justify justify, ui::text_layout::word_wrapping wrap, draw_mode draw, rgb_t fgcolor, rgb_t bgcolor, float *totalwidth, float *totalheight, float text_size);
@ -197,13 +206,17 @@ public:
bool can_paste();
bool found_machine_warnings() const { return m_has_warnings; }
void image_handler_ingame();
void increase_frameskip();
void decrease_frameskip();
void request_quit();
void set_pointer_activity_timeout(int target, std::chrono::steady_clock::duration timeout) noexcept;
void set_hide_inactive_pointers(int target, bool hide) noexcept;
std::chrono::steady_clock::duration pointer_activity_timeout(int target) const noexcept;
bool hide_inactive_pointers(int target) const noexcept;
// drawing informational overlays
void draw_fps_counter(render_container &container);
void draw_profiler(render_container &container);
// pointer display
// pointer display for UI handlers
template <typename T>
void set_pointers(T first, T last)
{
@ -238,9 +251,6 @@ public:
std::vector<ui::menu_item> &get_slider_list();
// metrics
float target_font_height() const { return m_target_font_height; }
float box_lr_border() const { return target_font_height() * 0.25f; }
float box_tb_border() const { return target_font_height() * 0.25f; }
void update_target_font_height();
// other
@ -248,9 +258,6 @@ public:
ui::text_layout create_layout(render_container &container, float width = 1.0, ui::text_layout::text_justify justify = ui::text_layout::text_justify::LEFT, ui::text_layout::word_wrapping wrap = ui::text_layout::word_wrapping::WORD);
void set_image_display_enabled(bool image_display_enabled) { m_image_display_enabled = image_display_enabled; }
bool image_display_enabled() const { return m_image_display_enabled; }
// draw an outlined box with given line color and filled with a texture
void draw_textured_box(render_container &container, float x0, float y0, float x1, float y1, rgb_t backcolor, rgb_t linecolor, render_texture *texture = nullptr, uint32_t flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
virtual void popup_time_string(int seconds, std::string message) override;
virtual void menu_reset() override;
@ -275,11 +282,13 @@ private:
enum class ui_callback_type : int;
struct active_pointer;
struct pointer_options;
using handler_callback_func = delegate<uint32_t (render_container &)>;
using device_feature_set = std::set<std::pair<std::string, std::string> >;
using session_data_map = std::unordered_map<std::type_index, std::any>;
using active_pointer_vector = std::vector<active_pointer>;
using pointer_options_vector = std::vector<pointer_options>;
using display_pointer_vector = std::vector<display_pointer>;
// instance variables
@ -294,6 +303,7 @@ private:
osd_ticks_t m_popup_text_end;
std::unique_ptr<uint8_t []> m_non_char_keys_down;
pointer_options_vector m_pointer_options;
active_pointer_vector m_active_pointers;
display_pointer_vector m_display_pointers;
bitmap_argb32 m_mouse_bitmap;
@ -328,8 +338,12 @@ private:
void set_handler(ui_callback_type callback_type, handler_callback_func &&callback);
void frame_update();
void exit();
void config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
void increase_frameskip();
void decrease_frameskip();
void config_load_warnings(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void config_save_warnings(config_type cfg_type, util::xml::data_node *parentnode);
void config_load_pointers(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void config_save_pointers(config_type cfg_type, util::xml::data_node *parentnode);
template <typename... Params> void slider_alloc(Params &&...args) { m_sliders.push_back(std::make_unique<slider_state>(std::forward<Params>(args)...)); }
// slider controls

View File

@ -15,6 +15,8 @@
#include "rendlay.h"
#include "rendutil.h"
#include <chrono>
namespace ui {
@ -24,6 +26,7 @@ constexpr uintptr_t ITEM_ROTATE = 0x00000100;
constexpr uintptr_t ITEM_ZOOM = 0x00000101;
constexpr uintptr_t ITEM_UNEVENSTRETCH = 0x00000102;
constexpr uintptr_t ITEM_KEEPASPECT = 0x00000103;
constexpr uintptr_t ITEM_POINTERTIMEOUT = 0x00000104;
constexpr uintptr_t ITEM_TOGGLE_FIRST = 0x00000200;
constexpr uintptr_t ITEM_VIEW_FIRST = 0x00000300;
@ -192,6 +195,29 @@ void menu_video_options::populate()
item_append_on_off(_("Maintain Aspect Ratio"), m_target.keepaspect(), 0, reinterpret_cast<void *>(ITEM_KEEPASPECT));
}
// add pointer display options
if (!m_target.hidden())
{
item_append(menu_item_type::SEPARATOR);
// use millisecond precision for timeout display
auto const timeout = std::chrono::duration_cast<std::chrono::milliseconds>(ui().pointer_activity_timeout(m_target.index()));
bool const hide = ui().hide_inactive_pointers(m_target.index());
if (hide)
{
int const precision = (timeout.count() % 10) ? 3 : (timeout.count() % 100) ? 2 : 1;
item_append(
_("Hide Inactive Pointers After Delay"),
util::string_format(_("%1$.*2$f s"), timeout.count() * 1e-3, precision),
((timeout > std::chrono::milliseconds(100)) ? FLAG_LEFT_ARROW : 0) | FLAG_RIGHT_ARROW,
reinterpret_cast<void *>(ITEM_POINTERTIMEOUT));
}
else
{
item_append(_("Hide Inactive Pointers After Delay"), _("Never"), FLAG_LEFT_ARROW, reinterpret_cast<void *>(ITEM_POINTERTIMEOUT));
}
}
item_append(menu_item_type::SEPARATOR);
}
@ -211,6 +237,7 @@ bool menu_video_options::handle(event const *ev)
});
bool const snap_lockout(m_snapshot && machine().video().is_recording());
bool changed(false);
set_process_flags((reinterpret_cast<uintptr_t>(get_selection_ref()) == ITEM_POINTERTIMEOUT) ? PROCESS_LR_REPEAT : 0);
// process the menu
if (ev && uintptr_t(ev->itemref))
@ -306,7 +333,7 @@ bool menu_video_options::handle(event const *ev)
}
break;
// keep aspect handles left/right keys the same (toggle)
// keep aspect handles left/right keys identically (toggle)
case ITEM_KEEPASPECT:
if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT))
{
@ -317,6 +344,55 @@ bool menu_video_options::handle(event const *ev)
}
break;
// pointer inactivity timeout
case ITEM_POINTERTIMEOUT:
if (ev->iptkey == IPT_UI_SELECT)
{
// toggle hide after delay
ui().set_hide_inactive_pointers(m_target.index(), !ui().hide_inactive_pointers(m_target.index()));
changed = true;
}
else if (ev->iptkey == IPT_UI_LEFT)
{
if (!ui().hide_inactive_pointers(m_target.index()))
{
ui().set_hide_inactive_pointers(m_target.index(), true);
ui().set_pointer_activity_timeout(m_target.index(), std::chrono::milliseconds(10'000));
changed = true;
}
else
{
auto const timeout = ui().pointer_activity_timeout(m_target.index());
if (std::chrono::milliseconds(100) < timeout)
{
auto const remainder = timeout % std::chrono::milliseconds(100);
ui().set_pointer_activity_timeout(
m_target.index(),
timeout - (remainder.count() ? remainder : std::chrono::milliseconds(100)));
changed = true;
}
}
}
else if (ev->iptkey == IPT_UI_RIGHT)
{
if (ui().hide_inactive_pointers(m_target.index()))
{
auto const timeout = ui().pointer_activity_timeout(m_target.index());
if (std::chrono::milliseconds(10'000) <= timeout)
{
ui().set_hide_inactive_pointers(m_target.index(), false);
}
else
{
ui().set_pointer_activity_timeout(
m_target.index(),
std::chrono::milliseconds((1 + (timeout / std::chrono::milliseconds(100))) * 100));
}
changed = true;
}
}
break;
// anything else is a view item
default:
if (reinterpret_cast<uintptr_t>(ev->itemref) >= ITEM_VIEW_FIRST)

View File

@ -90,6 +90,7 @@ public:
, m_keyboard(*this, "X%d", 0U)
, m_mainbank(*this, "mainbank")
, m_codebank(*this, "codebank")
, m_nvrambank(*this, "nvrambank")
, m_soundbank(*this, "soundbank")
, m_io_view(*this, "io_view")
{ }
@ -107,6 +108,7 @@ private:
required_ioport_array<17> m_keyboard;
required_memory_bank m_mainbank;
required_memory_bank m_codebank;
required_memory_bank m_nvrambank;
required_memory_bank m_soundbank;
memory_view m_io_view;
@ -114,12 +116,9 @@ private:
uint8_t m_wmg_d000 = 0U;
uint8_t m_port_select = 0U;
u8 wmg_nvram_r(offs_t offset);
void wmg_nvram_w(offs_t offset, u8 data);
u8 wmg_pia_0_r(offs_t offset);
void wmg_c400_w(u8 data);
void wmg_d000_w(u8 data);
void wmg_blitter_w(offs_t, u8);
void wmg_port_select_w(int state);
void wmg_sound_reset_w(u8 data);
void wmg_vram_select_w(u8 data);
@ -149,10 +148,10 @@ void wmg_state::wmg_cpu1(address_map &map)
m_io_view[0](0xc804, 0xc807).r(FUNC(wmg_state::wmg_pia_0_r)).w(m_pia[0], FUNC(pia6821_device::write));
m_io_view[0](0xc80c, 0xc80f).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
m_io_view[0](0xc900, 0xc9ff).nopr().w(FUNC(wmg_state::wmg_vram_select_w));
m_io_view[0](0xca00, 0xca07).w(FUNC(wmg_state::wmg_blitter_w));
m_io_view[0](0xca00, 0xca07).w(FUNC(wmg_state::blitter_w));
m_io_view[0](0xcb00, 0xcbff).r(FUNC(wmg_state::video_counter_r));
m_io_view[0](0xcbff, 0xcbff).w(FUNC(wmg_state::watchdog_reset_w));
m_io_view[0](0xcc00, 0xcfff).rw(FUNC(wmg_state::wmg_nvram_r), FUNC(wmg_state::wmg_nvram_w));
m_io_view[0](0xcc00, 0xcfff).bankrw(m_nvrambank);
m_io_view[1](0xc000, 0xcfff).rom().region("maincpu", 0x58000); // Defender ROMs
m_io_view[2](0xc000, 0xcfff).rom().region("maincpu", 0x59000);
m_io_view[3](0xc000, 0xcfff).rom().region("maincpu", 0x5a000);
@ -320,31 +319,6 @@ static INPUT_PORTS_START( wmg )
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END
/*************************************
*
* NVRAM (8k x 8), banked
*
*************************************/
u8 wmg_state::wmg_nvram_r(offs_t offset)
{
return m_p_ram[offset+(m_wmg_c400<<10)];
}
void wmg_state::wmg_nvram_w(offs_t offset, u8 data)
{
m_p_ram[offset+(m_wmg_c400<<10)] = data;
}
/*************************************
*
* Blitter
*
*************************************/
void wmg_state::wmg_blitter_w(offs_t offset, u8 data)
{
blitter_w(m_maincpu->space(AS_PROGRAM), offset, data);
}
/*************************************
*
* Bankswitching
@ -360,13 +334,14 @@ void wmg_state::wmg_c400_w(u8 data)
if (m_wmg_c400 == data)
return;
if ((data == 0) || (m_wmg_c400 == 0)) // we must be going to/from the menu
if ((data == 0) || (m_wmg_c400 == 0)) // we must be going to/from the menu
{
m_wmg_c400 = data;
wmg_d000_w(0); // select i/o
m_mainbank->set_entry(data); // Gfx etc
wmg_d000_w(0); // select I/O
m_mainbank->set_entry(data); // Graphics, etc.
m_codebank->set_entry(data); // Code
m_soundbank->set_entry(data); // Sound
m_nvrambank->set_entry(data); // NVRAM
m_soundbank->set_entry(data); // Sound
m_soundcpu->reset();
}
}
@ -432,11 +407,12 @@ void wmg_state::machine_start()
{
williams_state::machine_start();
uint8_t *cpu = memregion("maincpu")->base();
uint8_t *snd = memregion("soundcpu")->base();
m_mainbank->configure_entries(0, 8, &cpu[0x00000], 0x10000); // Gfx etc
m_codebank->configure_entries(0, 8, &cpu[0x0d000], 0x10000); // Code
m_soundbank->configure_entries(0, 8, &snd[0x00000], 0x1000); // Sound
uint8_t *const cpu = memregion("maincpu")->base();
uint8_t *const snd = memregion("soundcpu")->base();
m_mainbank->configure_entries(0, 8, &cpu[0x00000], 0x10000); // Graphics, etc.
m_codebank->configure_entries(0, 8, &cpu[0x0d000], 0x10000); // Code
m_nvrambank->configure_entries(0, 8, &m_nvram[0], 0x400); // NVRAM
m_soundbank->configure_entries(0, 8, &snd[0x00000], 0x1000); // Sound
save_item(NAME(m_wmg_c400));
save_item(NAME(m_wmg_d000));
@ -518,6 +494,7 @@ void wmg_state::wmg(machine_config &config)
M6808(config, m_soundcpu, SOUND_CLOCK);
m_soundcpu->set_addrmap(AS_PROGRAM, &wmg_state::wmg_cpu2);
// 8k x 8, banked
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
// set a timer to go off every 32 scanlines, to toggle the VA11 line and update the screen