diff options
25 files changed, 1184 insertions, 671 deletions
diff --git a/hash/ibm5170.xml b/hash/ibm5170.xml index b432828c952..85fd33436ce 100644 --- a/hash/ibm5170.xml +++ b/hash/ibm5170.xml @@ -1436,36 +1436,43 @@ license:CC0 <year>1990</year> <publisher>Microsoft</publisher> <part name="flop1" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Installation Diskette A"/> <dataarea name="flop" size="1474560"> <rom name="install a.img" size="1474560" crc="e40194dd" sha1="c2003f08e2e88d327ba5a469a4436a58abcfeb01"/> </dataarea> </part> <part name="flop2" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Installation Diskette B"/> <dataarea name="flop" size="1474560"> <rom name="install b.img" size="1474560" crc="03d72834" sha1="9cd1b6f43f2157b4ba2e1fdecf4992789c7a6c45"/> </dataarea> </part> <part name="flop3" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Diskette 1"/> <dataarea name="flop" size="1474560"> <rom name="disk 1.img" size="1474560" crc="7f933590" sha1="1165ecd0a0b891d29f4096cf690edfacbd6b2da6"/> </dataarea> </part> <part name="flop4" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Diskette 2"/> <dataarea name="flop" size="1474560"> <rom name="disk 2.img" size="1474560" crc="ed2d93d1" sha1="cabd43e5c263d7891e731ac3728c932b737021e5"/> </dataarea> </part> <part name="flop5" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Diskette 3"/> <dataarea name="flop" size="1474560"> <rom name="disk 3.img" size="1474560" crc="45616040" sha1="d7a7b2fdacb71308188b6fc9dba7260572d6a40f"/> </dataarea> </part> <part name="flop6" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Diskette 4"/> <dataarea name="flop" size="1474560"> <rom name="disk 4.img" size="1474560" crc="62c716f6" sha1="4a1d5b916f93974a66407660a77f4b3e2e5cb561"/> </dataarea> </part> <part name="flop7" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Diskette 5"/> <dataarea name="flop" size="1474560"> <rom name="disk 5.img" size="1474560" crc="515501af" sha1="2fa2fce813156ad16cef094961f40ffc44c57953"/> </dataarea> @@ -1476,16 +1483,19 @@ license:CC0 </dataarea> </part> <part name="flop9" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Presentation Manager Device Driver Diskette 1"/> <dataarea name="flop" size="1474560"> <rom name="presentation manager 1.img" size="1474560" crc="0a16d365" sha1="8dec8913728738b7aee4929fdd8e117129edd9e0"/> </dataarea> </part> <part name="flop10" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Presentation Manager Device Driver Diskette 2"/> <dataarea name="flop" size="1474560"> <rom name="presentation manager 2.img" size="1474560" crc="024aa1a8" sha1="d8eee0971f67de90259450639ef608de29983150"/> </dataarea> </part> <part name="flop11" interface="floppy_3_5"> + <feature name="part_id" value="Operating System/2 Systems Support Diskette"/> <dataarea name="flop" size="1474560"> <rom name="support.img" size="1474560" crc="dc433ce5" sha1="a46a1cb3d796c3f3726e74222d2c09129b82574e"/> </dataarea> diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index 6dacf7acee1..c3dd9a0c3a6 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -1490,7 +1490,7 @@ bool device_debug::comment_export(util::xml::data_node &curnode) // iterate through the comments for (const auto & elem : m_comment_set) { - util::xml::data_node *datanode = curnode.add_child("comment", util::xml::normalize_string(elem.m_text.c_str())); + util::xml::data_node *datanode = curnode.add_child("comment", elem.m_text.c_str()); if (datanode == nullptr) return false; datanode->set_attribute_int("address", elem.m_address); diff --git a/src/emu/render.cpp b/src/emu/render.cpp index fe62b3c0bf8..4d621508a20 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -37,20 +37,22 @@ ***************************************************************************/ #include "emu.h" -#include "emuopts.h" #include "render.h" + +#include "emuopts.h" #include "rendfont.h" #include "rendlay.h" #include "rendutil.h" #include "config.h" #include "drivenum.h" -#include "xmlfile.h" + #include "ui/uimain.h" +#include "xmlfile.h" + #include <zlib.h> #include <algorithm> -#include <functional> @@ -893,7 +895,7 @@ render_target::render_target(render_manager &manager, util::xml::data_node const template <typename T> render_target::render_target(render_manager &manager, T &&layout, u32 flags, constructor_impl_t) : m_next(nullptr) , m_manager(manager) - , m_curview(nullptr) + , m_curview(0U) , m_flags(flags) , m_listindex(0) , m_width(640) @@ -949,6 +951,10 @@ template <typename T> render_target::render_target(render_manager &manager, T && // load the layout files load_layout_files(std::forward<T>(layout), flags & RENDER_CREATE_SINGLE_FILE); + for (layout_file &file : m_filelist) + for (layout_view &view : file.views()) + if (!(m_flags & RENDER_CREATE_NO_ART) || !view.has_art()) + m_views.emplace_back(view, view.default_visibility_mask()); // set the current view to the first one set_view(0); @@ -1010,13 +1016,12 @@ void render_target::set_bounds(s32 width, s32 height, float pixel_aspect) // a target //------------------------------------------------- -void render_target::set_view(int viewindex) +void render_target::set_view(unsigned viewindex) { - layout_view *view = view_by_index(viewindex); - if (view) + if (m_views.size() > viewindex) { - m_curview = view; - view->recompute(m_layerconfig); + m_curview = viewindex; + current_view().recompute(visibility_mask(), m_layerconfig.zoom_to_screen()); } } @@ -1034,38 +1039,54 @@ void render_target::set_max_texture_size(int maxwidth, int maxheight) //------------------------------------------------- +// set_visibility_toggle - show or hide selected +// parts of a view +//------------------------------------------------- + +void render_target::set_visibility_toggle(unsigned index, bool enable) +{ + assert(visibility_toggles().size() > index); + if (enable) + m_views[m_curview].second |= u32(1) << index; + else + m_views[m_curview].second &= ~(u32(1) << index); + current_view().recompute(visibility_mask(), m_layerconfig.zoom_to_screen()); +} + + +//------------------------------------------------- // configured_view - select a view for this // target based on the configuration parameters //------------------------------------------------- -int render_target::configured_view(const char *viewname, int targetindex, int numtargets) +unsigned render_target::configured_view(const char *viewname, int targetindex, int numtargets) { layout_view *view = nullptr; - int viewindex; // auto view just selects the nth view if (strcmp(viewname, "auto") != 0) { // scan for a matching view name size_t viewlen = strlen(viewname); - for (view = view_by_index(viewindex = 0); view != nullptr; view = view_by_index(++viewindex)) - if (core_strnicmp(view->name().c_str(), viewname, viewlen) == 0) - break; + for (unsigned i = 0; !view && (m_views.size() > i); ++i) + if (!core_strnicmp(m_views[i].first.get().name().c_str(), viewname, viewlen)) + view = &m_views[i].first.get(); } // if we don't have a match, default to the nth view - screen_device_iterator iter(m_manager.machine().root_device()); - int scrcount = iter.count(); - if (view == nullptr && scrcount > 0) + std::vector<std::reference_wrapper<screen_device> > screens; + for (screen_device &screen : screen_device_iterator(m_manager.machine().root_device())) + screens.push_back(screen); + if (!view && !screens.empty()) { // if we have enough targets to be one per screen, assign in order - if (numtargets >= scrcount) + if (numtargets >= screens.size()) { - int ourindex = index() % scrcount; - screen_device *screen = iter.byindex(ourindex); - assert(screen != nullptr); + int const ourindex = index() % screens.size(); + screen_device &screen = screens[ourindex]; // find the first view with this screen and this screen only + unsigned viewindex; for (view = view_by_index(viewindex = 0); view != nullptr; view = view_by_index(++viewindex)) { auto const &viewscreens = view->screens(); @@ -1074,36 +1095,34 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu view = nullptr; break; } - else if (std::find_if(viewscreens.begin(), viewscreens.end(), [&screen](auto const &scr) { return &scr.get() != screen; }) == viewscreens.end()) + else if (std::find_if(viewscreens.begin(), viewscreens.end(), [&screen] (auto const &scr) { return &scr.get() != &screen; }) == viewscreens.end()) break; } } // otherwise, find the first view that has all the screens - if (view == nullptr) + if (!view) { - for (view = view_by_index(viewindex = 0); view != nullptr; view = view_by_index(++viewindex)) + for (unsigned i = 0; !view && (m_views.size() > i); ++i) { - if (view->screen_count() >= scrcount) + view = &m_views[i].first.get(); + if (view->screen_count() >= screens.size()) { - bool screen_missing(false); - for (screen_device &screen : iter) + for (screen_device &screen : screens) { if (!view->has_screen(screen)) { - screen_missing = true; + view = nullptr; break; } } - if (!screen_missing) - break; } } } } // make sure it's a valid view - return (view != nullptr) ? view_index(*view) : 0; + return view ? view_index(*view) : 0; } @@ -1111,10 +1130,14 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu // view_name - return the name of the given view //------------------------------------------------- -const char *render_target::view_name(int viewindex) +const char *render_target::view_name(unsigned viewindex) +{ + return (m_views.size() > viewindex) ? m_views[viewindex].first.get().name().c_str() : nullptr; +} + +layout_view::visibility_toggle_vector const &render_target::visibility_toggles() { - layout_view const *const view = view_by_index(viewindex); - return view ? view->name().c_str() : nullptr; + return current_view().visibility_toggles(); } @@ -1137,7 +1160,7 @@ void render_target::compute_visible_area(s32 target_width, s32 target_height, fl if (m_keepaspect) { // start with the aspect ratio of the square pixel layout - width = m_curview->effective_aspect(m_layerconfig); + width = current_view().effective_aspect(); height = 1.0f; // first apply target orientation @@ -1173,7 +1196,7 @@ void render_target::compute_visible_area(s32 target_width, s32 target_height, fl // get source size and aspect s32 src_width, src_height; compute_minimum_size(src_width, src_height); - float src_aspect = m_curview->effective_aspect(m_layerconfig); + float src_aspect = current_view().effective_aspect(); // apply orientation if required if (target_orientation & ORIENTATION_SWAP_XY) @@ -1242,11 +1265,11 @@ void render_target::compute_minimum_size(s32 &minwidth, s32 &minheight) return; } - if (!m_curview) + if (m_views.empty()) throw emu_fatalerror("Mandatory artwork is missing"); // scan the current view for all screens - for (layout_view::item &curitem : m_curview->items()) + for (layout_view::item &curitem : current_view().items()) { if (curitem.screen()) { @@ -1301,8 +1324,8 @@ void render_target::compute_minimum_size(s32 &minwidth, s32 &minheight) render_primitive_list &render_target::get_primitives() { // remember the base values if this is the first frame - if (m_base_view == nullptr) - m_base_view = m_curview; + if (!m_base_view) + m_base_view = ¤t_view(); // switch to the next primitive list render_primitive_list &list = m_primlist[m_listindex]; @@ -1326,38 +1349,42 @@ render_primitive_list &render_target::get_primitives() root_xform.orientation = m_orientation; root_xform.no_center = false; - // iterate over items in the view, but only if we're running if (m_manager.machine().phase() >= machine_phase::RESET) - for (layout_view::item &curitem : m_curview->items()) + { + // we're running - iterate over items in the view + for (layout_view::item &curitem : current_view().items()) { - // first apply orientation to the bounds - render_bounds bounds = curitem.bounds(); - apply_orientation(bounds, root_xform.orientation); - normalize_bounds(bounds); - - // apply the transform to the item - object_transform item_xform; - item_xform.xoffs = root_xform.xoffs + bounds.x0 * root_xform.xscale; - item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale; - item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale; - item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale; - item_xform.color.r = curitem.color().r * root_xform.color.r; - item_xform.color.g = curitem.color().g * root_xform.color.g; - item_xform.color.b = curitem.color().b * root_xform.color.b; - item_xform.color.a = curitem.color().a * root_xform.color.a; - item_xform.orientation = orientation_add(curitem.orientation(), root_xform.orientation); - item_xform.no_center = false; - - // if there is no associated element, it must be a screen element - if (curitem.screen() != nullptr) - add_container_primitives(list, root_xform, item_xform, curitem.screen()->container(), curitem.blend_mode()); - else - add_element_primitives(list, item_xform, *curitem.element(), curitem.state(), curitem.blend_mode()); + if ((visibility_mask() & curitem.visibility_mask()) == curitem.visibility_mask()) + { + // first apply orientation to the bounds + render_bounds bounds = curitem.bounds(); + apply_orientation(bounds, root_xform.orientation); + normalize_bounds(bounds); + + // apply the transform to the item + object_transform item_xform; + item_xform.xoffs = root_xform.xoffs + bounds.x0 * root_xform.xscale; + item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale; + item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale; + item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale; + item_xform.color.r = curitem.color().r * root_xform.color.r; + item_xform.color.g = curitem.color().g * root_xform.color.g; + item_xform.color.b = curitem.color().b * root_xform.color.b; + item_xform.color.a = curitem.color().a * root_xform.color.a; + item_xform.orientation = orientation_add(curitem.orientation(), root_xform.orientation); + item_xform.no_center = false; + + // if there is no associated element, it must be a screen element + if (curitem.screen()) + add_container_primitives(list, root_xform, item_xform, curitem.screen()->container(), curitem.blend_mode()); + else + add_element_primitives(list, item_xform, *curitem.element(), curitem.state(), curitem.blend_mode()); + } } - - // if we are not in the running stage, draw an outer box + } else { + // if we are not in the running stage, draw an outer box render_primitive *prim = list.alloc(render_primitive::QUAD); set_render_bounds_xy(prim->bounds, 0.0f, 0.0f, (float)m_width, (float)m_height); prim->full_bounds = prim->bounds; @@ -1520,7 +1547,7 @@ void render_target::resolve_tags() void render_target::update_layer_config() { - m_curview->recompute(m_layerconfig); + current_view().recompute(visibility_mask(), m_layerconfig.zoom_to_screen()); } @@ -1694,10 +1721,9 @@ void render_target::load_additional_layout_files(const char *basename, bool have throw emu_fatalerror("Couldn't create XML node??"); viewnode->set_attribute( "name", - util::xml::normalize_string( - util::string_format( - "Screen %1$u Standard (%2$u:%3$u)", - i, screens[i].physical_x(), screens[i].physical_y()).c_str())); + util::string_format( + "Screen %1$u Standard (%2$u:%3$u)", + i, screens[i].physical_x(), screens[i].physical_y()).c_str()); util::xml::data_node *const screennode(viewnode->add_child("screen", nullptr)); if (!screennode) throw emu_fatalerror("Couldn't create XML node??"); @@ -1721,10 +1747,9 @@ void render_target::load_additional_layout_files(const char *basename, bool have throw emu_fatalerror("Couldn't create XML node??"); viewnode->set_attribute( "name", - util::xml::normalize_string( - util::string_format( - "Screen %1$u Pixel Aspect (%2$u:%3$u)", - i, screens[i].native_x(), screens[i].native_y()).c_str())); + util::string_format( + "Screen %1$u Pixel Aspect (%2$u:%3$u)", + i, screens[i].native_x(), screens[i].native_y()).c_str()); util::xml::data_node *const screennode(viewnode->add_child("screen", nullptr)); if (!screennode) throw emu_fatalerror("Couldn't create XML node??"); @@ -1841,7 +1866,7 @@ void render_target::load_additional_layout_files(const char *basename, bool have util::xml::data_node *viewnode = layoutnode->add_child("view", nullptr); if (!viewnode) throw emu_fatalerror("Couldn't create XML node??"); - viewnode->set_attribute("name", util::xml::normalize_string(title)); + viewnode->set_attribute("name", title); float ypos(0.0F); for (unsigned y = 0U; rows > y; ypos += heights[y] + spacing, ++y) { @@ -2479,8 +2504,11 @@ bool render_target::map_point_internal(s32 target_x, s32 target_y, render_contai } // iterate over items in the view - for (layout_view::item &item : m_curview->items()) + for (layout_view::item &item : current_view().items()) { + if ((visibility_mask() & item.visibility_mask()) != item.visibility_mask()) + continue; + bool checkit; // if we're looking for a particular container, verify that we have the right one @@ -2511,15 +2539,9 @@ bool render_target::map_point_internal(s32 target_x, s32 target_y, render_contai // view, or nullptr if it doesn't exist //------------------------------------------------- -layout_view *render_target::view_by_index(int index) +layout_view *render_target::view_by_index(unsigned index) { - // scan the list of views within each layout, skipping those that don't apply - for (layout_file &file : m_filelist) - for (layout_view &view : file.views()) - if (!(m_flags & RENDER_CREATE_NO_ART) || !view.has_art()) - if (index-- == 0) - return &view; - return nullptr; + return (m_views.size() > index) ? &m_views[index].first.get() : nullptr; } @@ -2552,8 +2574,6 @@ int render_target::view_index(layout_view &targetview) const void render_target::config_load(util::xml::data_node const &targetnode) { - int tmpint; - // find the view const char *viewname = targetnode.get_attribute_string("view", nullptr); if (viewname != nullptr) @@ -2570,23 +2590,23 @@ void render_target::config_load(util::xml::data_node const &targetnode) } // modify the artwork config - tmpint = targetnode.get_attribute_int("zoom", -1); - if (tmpint == 0 || tmpint == 1) - set_zoom_to_screen(tmpint); + int const zoom = targetnode.get_attribute_int("zoom", -1); + if (zoom == 0 || zoom == 1) + set_zoom_to_screen(zoom); // apply orientation - tmpint = targetnode.get_attribute_int("rotate", -1); - if (tmpint != -1) - { - if (tmpint == 90) - tmpint = ROT90; - else if (tmpint == 180) - tmpint = ROT180; - else if (tmpint == 270) - tmpint = ROT270; + int rotate = targetnode.get_attribute_int("rotate", -1); + if (rotate != -1) + { + if (rotate == 90) + rotate = ROT90; + else if (rotate == 180) + rotate = ROT180; + else if (rotate == 270) + rotate = ROT270; else - tmpint = ROT0; - set_orientation(orientation_add(tmpint, orientation())); + rotate = ROT0; + set_orientation(orientation_add(rotate, orientation())); // apply the opposite orientation to the UI if (is_ui_target()) @@ -2595,10 +2615,46 @@ void render_target::config_load(util::xml::data_node const &targetnode) render_container &ui_container = m_manager.ui_container(); ui_container.get_user_settings(settings); - settings.m_orientation = orientation_add(orientation_reverse(tmpint), settings.m_orientation); + settings.m_orientation = orientation_add(orientation_reverse(rotate), settings.m_orientation); ui_container.set_user_settings(settings); } } + + // apply per-view settings + for (util::xml::data_node const *viewnode = targetnode.get_child("view"); viewnode; viewnode = viewnode->get_next_sibling("view")) + { + char const *const viewname = viewnode->get_attribute_string("name", nullptr); + if (!viewname) + continue; + + auto const view = std::find_if(m_views.begin(), m_views.end(), [viewname] (auto const &x) { return x.first.get().name() == viewname; }); + if (m_views.end() == view) + continue; + + for (util::xml::data_node const *vistogglenode = viewnode->get_child("vistoggle"); vistogglenode; vistogglenode = vistogglenode->get_next_sibling("vistoggle")) + { + char const *const vistogglename = vistogglenode->get_attribute_string("name", nullptr); + if (!vistogglename) + continue; + + auto const &vistoggles = view->first.get().visibility_toggles(); + auto const vistoggle = std::find_if(vistoggles.begin(), vistoggles.end(), [vistogglename] (auto const &x) { return x.name() == vistogglename; }); + if (vistoggles.end() == vistoggle) + continue; + + int const enable = vistogglenode->get_attribute_int("enabled", -1); + if (0 <= enable) + { + if (enable) + view->second |= u32(1) << std::distance(vistoggles.begin(), vistoggle); + else + view->second &= ~(u32(1) << std::distance(vistoggles.begin(), vistoggle)); + } + } + + if (¤t_view() == &view->first.get()) + current_view().recompute(visibility_mask(), m_layerconfig.zoom_to_screen()); + } } @@ -2615,9 +2671,9 @@ bool render_target::config_save(util::xml::data_node &targetnode) targetnode.set_attribute_int("index", index()); // output the view - if (m_curview != m_base_view) + if (¤t_view() != m_base_view) { - targetnode.set_attribute("view", m_curview->name().c_str()); + targetnode.set_attribute("view", current_view().name().c_str()); changed = true; } @@ -2643,6 +2699,33 @@ bool render_target::config_save(util::xml::data_node &targetnode) changed = true; } + // output layer configuration + for (auto const &view : m_views) + { + u32 const defvismask = view.first.get().default_visibility_mask(); + if (defvismask != view.second) + { + util::xml::data_node *viewnode = nullptr; + unsigned i = 0; + for (layout_view::visibility_toggle const &toggle : view.first.get().visibility_toggles()) + { + if (BIT(defvismask, i) != BIT(view.second, i)) + { + if (!viewnode) + { + viewnode = targetnode.add_child("view", nullptr); + viewnode->set_attribute("name", view.first.get().name().c_str()); + } + util::xml::data_node *const vistogglenode = viewnode->add_child("vistoggle", nullptr); + vistogglenode->set_attribute("name", toggle.name().c_str()); + vistogglenode->set_attribute_int("enabled", BIT(view.second, i)); + changed = true; + } + ++i; + } + } + } + return changed; } @@ -2968,8 +3051,8 @@ bool render_manager::is_live(screen_device &screen) const { if (!target.hidden()) { - layout_view const *view = target.current_view(); - if (view != nullptr && view->has_screen(screen)) + layout_view const *view = &target.current_view(); + if (view->has_screen(screen)) return true; } } @@ -3201,35 +3284,31 @@ void render_manager::container_free(render_container *container) void render_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode) { - // we only care about game files - if (cfg_type != config_type::GAME) - return; - - // might not have any data - if (parentnode == nullptr) + // we only care about game files with matching nodes + if ((cfg_type != config_type::GAME) || !parentnode) return; // check the UI target util::xml::data_node const *const uinode = parentnode->get_child("interface"); - if (uinode != nullptr) + if (uinode) { - render_target *target = target_by_index(uinode->get_attribute_int("target", 0)); - if (target != nullptr) + render_target *const target = target_by_index(uinode->get_attribute_int("target", 0)); + if (target) set_ui_target(*target); } // iterate over target nodes for (util::xml::data_node const *targetnode = parentnode->get_child("target"); targetnode; targetnode = targetnode->get_next_sibling("target")) { - render_target *target = target_by_index(targetnode->get_attribute_int("index", -1)); - if (target != nullptr) + render_target *const target = target_by_index(targetnode->get_attribute_int("index", -1)); + if (target) target->config_load(*targetnode); } // iterate over screen nodes for (util::xml::data_node const *screennode = parentnode->get_child("screen"); screennode; screennode = screennode->get_next_sibling("screen")) { - int index = screennode->get_attribute_int("index", -1); + int const index = screennode->get_attribute_int("index", -1); render_container *container = m_screen_container_list.find(index); render_container::user_settings settings; @@ -3283,7 +3362,7 @@ void render_manager::config_save(config_type cfg_type, util::xml::data_node *par // create a node util::xml::data_node *const targetnode = parentnode->add_child("target", nullptr); - if (targetnode != nullptr && !target->config_save(*targetnode)) + if (targetnode && !target->config_save(*targetnode)) targetnode->delete_node(); } diff --git a/src/emu/render.h b/src/emu/render.h index 0a59d7d894e..d846dce58c1 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -48,17 +48,24 @@ #include "screen.h" -#include <cmath> #include <array> +#include <cmath> +#include <functional> #include <map> #include <memory> #include <mutex> #include <string> #include <unordered_map> +#include <utility> #include <vector> -namespace emu { namespace render { namespace detail { class layout_environment; } } } +namespace emu { namespace render { namespace detail { + +class layout_environment; +class view_environment; + +} } } // namespace emu::render::detail //************************************************************************** @@ -176,6 +183,7 @@ struct render_bounds constexpr float width() const { return x1 - x0; } constexpr float height() const { return y1 - y0; } + constexpr float aspect() const { return width() / height(); } }; @@ -725,20 +733,17 @@ private: class layout_view { public: - using environment = emu::render::detail::layout_environment; + using layout_environment = emu::render::detail::layout_environment; + using view_environment = emu::render::detail::view_environment; using element_map = std::unordered_map<std::string, layout_element>; using group_map = std::unordered_map<std::string, layout_group>; using render_screen_list = std::list<std::reference_wrapper<screen_device>>; - /// \brief A single backdrop/screen/overlay/bezel/cpanel/marquee item + /// \brief A single item in a view /// - /// Each view has four lists of view_items, one for each "layer." - /// Each view item is specified using floating point coordinates in - /// arbitrary units, and is assumed to have square pixels. Each - /// view item can control its orientation independently. Each item - /// can also have an optional name, and can be set at runtime into - /// different "states", which control how the embedded elements are - /// displayed. + /// Each view has a list of item structures describing the visual + /// elements to draw, where they are located, additional blending + /// modes, and bindings for inputs and outputs. class item { friend class layout_view; @@ -746,7 +751,7 @@ public: public: // construction/destruction item( - environment &env, + view_environment &env, util::xml::data_node const &itemnode, element_map &elemmap, int orientation, @@ -760,6 +765,7 @@ public: const render_bounds &bounds() const { return m_bounds; } const render_color &color() const { return m_color; } int blend_mode() const { return m_blend_mode; } + u32 visibility_mask() const { return m_visibility_mask; } int orientation() const { return m_orientation; } render_container *screen_container(running_machine &machine) const; bool has_input() const { return bool(m_input_port); } @@ -775,10 +781,10 @@ public: void set_blend_mode(int mode) { m_blend_mode = mode; } private: - static layout_element *find_element(environment &env, util::xml::data_node const &itemnode, element_map &elemmap); - static render_bounds make_bounds(environment &env, util::xml::data_node const &itemnode, layout_group::transform const &trans); - static std::string make_input_tag(environment &env, util::xml::data_node const &itemnode); - static int get_blend_mode(environment &env, util::xml::data_node const &itemnode); + static layout_element *find_element(view_environment &env, util::xml::data_node const &itemnode, element_map &elemmap); + static render_bounds make_bounds(view_environment &env, util::xml::data_node const &itemnode, layout_group::transform const &trans); + static std::string make_input_tag(view_environment &env, util::xml::data_node const &itemnode); + static int get_blend_mode(view_environment &env, util::xml::data_node const &itemnode); // internal state layout_element *const m_element; // pointer to the associated element (non-screens only) @@ -796,12 +802,37 @@ public: render_bounds const m_rawbounds; // raw (original) bounds of the item render_color m_color; // color of the item int m_blend_mode; // blending mode to use when drawing + u32 m_visibility_mask; // combined mask of parent visibility groups }; using item_list = std::list<item>; + /// \brief A subset of items in a view that can be hidden or shown + /// + /// Visibility toggles allow the user to show or hide selected parts + /// of a view. + class visibility_toggle + { + public: + // construction/destruction/assignment + visibility_toggle(std::string &&name, u32 mask); + visibility_toggle(visibility_toggle const &) = default; + visibility_toggle(visibility_toggle &&) = default; + visibility_toggle &operator=(visibility_toggle const &) = default; + visibility_toggle &operator=(visibility_toggle &&) = default; + + // getters + std::string const &name() const { return m_name; } + u32 mask() const { return m_mask; } + + private: + std::string m_name; // display name for the toggle + u32 m_mask; // toggle combination to show + }; + using visibility_toggle_vector = std::vector<visibility_toggle>; + // construction/destruction layout_view( - environment &env, + layout_environment &env, util::xml::data_node const &viewnode, element_map &elemmap, group_map &groupmap); @@ -810,18 +841,17 @@ public: // getters item_list &items() { return m_items; } const std::string &name() const { return m_name; } - const render_bounds &bounds() const { return m_bounds; } - const render_bounds &screen_bounds() const { return m_scrbounds; } const render_screen_list &screens() const { return m_screens; } size_t screen_count() const { return m_screens.size(); } + float effective_aspect() const { return m_effaspect; } + const render_bounds &bounds() const { return m_bounds; } bool has_screen(screen_device &screen) const; - - // bool has_art() const { return m_has_art; } - float effective_aspect(render_layer_config config) const { return (config.zoom_to_screen() && !m_screens.empty()) ? m_scraspect : m_aspect; } + u32 default_visibility_mask() const { return m_defvismask; } + const visibility_toggle_vector &visibility_toggles() const { return m_vistoggles; } // operations - void recompute(render_layer_config layerconfig); + void recompute(u32 visibility_mask, bool zoom_to_screens); // resolve tags, if any void resolve_tags(); @@ -832,7 +862,7 @@ private: // add items, recursing for groups void add_items( layer_lists &layers, - environment &env, + view_environment &env, util::xml::data_node const &parentnode, element_map &elemmap, group_map &groupmap, @@ -843,18 +873,18 @@ private: bool repeat, bool init); - static std::string make_name(environment &env, util::xml::data_node const &viewnode); + static std::string make_name(layout_environment &env, util::xml::data_node const &viewnode); // internal state std::string m_name; // name of the layout - float m_aspect; // X/Y of the layout - float m_scraspect; // X/Y of the screen areas - render_screen_list m_screens; // list of active screens - render_bounds m_bounds; // computed bounds of the view - render_bounds m_scrbounds; // computed bounds of the screens within the view + render_screen_list m_screens; // list screens visible in current configuration + float m_effaspect; // X/Y of the layout in current configuration + render_bounds m_bounds; // computed bounds of the view in current configuration render_bounds m_expbounds; // explicit bounds of the view item_list m_items; // list of layout items bool m_has_art; // true if the layout contains non-screen elements + u32 m_defvismask; // default visibility mask + visibility_toggle_vector m_vistoggles; }; @@ -920,8 +950,8 @@ public: float max_update_rate() const { return m_max_refresh; } int orientation() const { return m_orientation; } render_layer_config layer_config() const { return m_layerconfig; } - layout_view *current_view() const { return m_curview; } - int view() const { return view_index(*m_curview); } + layout_view ¤t_view() const { return m_views[m_curview].first.get(); } + unsigned view() const { return m_curview; } bool external_artwork() const { return m_external_artwork; } bool hidden() const { return ((m_flags & RENDER_CREATE_HIDDEN) != 0); } bool is_ui_target() const; @@ -931,7 +961,7 @@ public: void set_bounds(s32 width, s32 height, float pixel_aspect = 0); void set_max_update_rate(float updates_per_second) { m_max_refresh = updates_per_second; } void set_orientation(int orientation) { m_orientation = orientation; } - void set_view(int viewindex); + void set_view(unsigned viewindex); void set_max_texture_size(int maxwidth, int maxheight); void set_transform_container(bool transform_container) { m_transform_container = transform_container; } void set_keepaspect(bool keepaspect) { m_keepaspect = keepaspect; } @@ -940,16 +970,19 @@ public: // layer config getters bool screen_overlay_enabled() const { return m_layerconfig.screen_overlay_enabled(); } bool zoom_to_screen() const { return m_layerconfig.zoom_to_screen(); } + u32 visibility_mask() const { return m_views[m_curview].second; } // layer config setters + void set_visibility_toggle(unsigned index, bool enable); void set_screen_overlay_enabled(bool enable) { m_layerconfig.set_screen_overlay_enabled(enable); update_layer_config(); } void set_zoom_to_screen(bool zoom) { m_layerconfig.set_zoom_to_screen(zoom); update_layer_config(); } // view configuration helper - int configured_view(const char *viewname, int targetindex, int numtargets); + unsigned configured_view(const char *viewname, int targetindex, int numtargets); // view information - const char *view_name(int viewindex); + char const *view_name(unsigned index); + layout_view::visibility_toggle_vector const &visibility_toggles(); // bounds computations void compute_visible_area(s32 target_width, s32 target_height, float target_pixel_aspect, int target_orientation, s32 &visible_width, s32 &visible_height); @@ -974,6 +1007,9 @@ public: void resolve_tags(); private: + using view_mask_pair = std::pair<std::reference_wrapper<layout_view>, u32>; + using view_mask_vector = std::vector<view_mask_pair>; + // private classes declared in render.cpp struct object_transform; @@ -996,7 +1032,7 @@ private: bool config_save(util::xml::data_node &targetnode); // view lookups - layout_view *view_by_index(int index); + layout_view *view_by_index(unsigned index); int view_index(layout_view &view) const; // optimized clearing @@ -1012,8 +1048,9 @@ private: // internal state render_target * m_next; // link to next target render_manager & m_manager; // reference to our owning manager - layout_view * m_curview; // current view std::list<layout_file> m_filelist; // list of layout files + view_mask_vector m_views; // views we consider + unsigned m_curview; // current view index u32 m_flags; // creation flags render_primitive_list m_primlist[NUM_PRIMLISTS]; // list of primitives int m_listindex; // index of next primlist to use diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index 4db27e47762..1d4a8f23265 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -518,6 +518,39 @@ private: return expand(str, str + strlen(str)); } + int parse_int(char const *begin, char const *end, int defvalue) + { + std::istringstream stream; + stream.imbue(f_portable_locale); + int result; + if (begin[0] == '$') + { + stream.str(std::string(begin + 1, end)); + unsigned uvalue; + stream >> std::hex >> uvalue; + result = int(uvalue); + } + else if ((begin[0] == '0') && ((begin[1] == 'x') || (begin[1] == 'X'))) + { + stream.str(std::string(begin + 2, end)); + unsigned uvalue; + stream >> std::hex >> uvalue; + result = int(uvalue); + } + else if (begin[0] == '#') + { + stream.str(std::string(begin + 1, end)); + stream >> result; + } + else + { + stream.str(std::string(begin, end)); + stream >> result; + } + + return stream ? result : defvalue; + } + std::string parameter_name(util::xml::data_node const &node) { char const *const attrib(node.get_attribute_string("name", nullptr)); @@ -547,8 +580,15 @@ private: bool m_cached = false; public: - explicit layout_environment(device_t &device) : m_device(device) { } - explicit layout_environment(layout_environment &next) : m_device(next.m_device), m_next(&next) { } + explicit layout_environment(device_t &device) + : m_device(device) + { + } + explicit layout_environment(layout_environment &next) + : m_device(next.m_device) + , m_next(&next) + { + } layout_environment(layout_environment const &) = delete; device_t &device() { return m_device; } @@ -706,35 +746,7 @@ public: // similar to what XML nodes do std::pair<char const *, char const *> const expanded(expand(attrib)); - std::istringstream stream; - stream.imbue(f_portable_locale); - int result; - if (expanded.first[0] == '$') - { - stream.str(std::string(expanded.first + 1, expanded.second)); - unsigned uvalue; - stream >> std::hex >> uvalue; - result = int(uvalue); - } - else if ((expanded.first[0] == '0') && ((expanded.first[1] == 'x') || (expanded.first[1] == 'X'))) - { - stream.str(std::string(expanded.first + 2, expanded.second)); - unsigned uvalue; - stream >> std::hex >> uvalue; - result = int(uvalue); - } - else if (expanded.first[0] == '#') - { - stream.str(std::string(expanded.first + 1, expanded.second)); - stream >> result; - } - else - { - stream.str(std::string(expanded.first, expanded.second)); - stream >> result; - } - - return stream ? result : defvalue; + return parse_int(expanded.first, expanded.second, defvalue); } float get_attribute_float(util::xml::data_node const &node, char const *name, float defvalue) @@ -751,6 +763,23 @@ public: return (stream >> result) ? result : defvalue; } + bool get_attribute_bool(util::xml::data_node const &node, char const *name, bool defvalue) + { + char const *const attrib(node.get_attribute_string(name, nullptr)); + if (!attrib) + return defvalue; + + // first try yes/no strings + std::pair<char const *, char const *> const expanded(expand(attrib)); + if (!std::strcmp("yes", expanded.first) || !std::strcmp("true", expanded.first)) + return true; + if (!std::strcmp("no", expanded.first) || !std::strcmp("false", expanded.first)) + return false; + + // fall back to integer parsing + return parse_int(expanded.first, expanded.second, defvalue ? 1 : 0) != 0; + } + void parse_bounds(util::xml::data_node const *node, render_bounds &result) { // default to unit rectangle @@ -826,16 +855,50 @@ public: case 270: result = ROT270; break; default: throw layout_syntax_error(util::string_format("invalid rotate attribute %d", rotate)); } - if (!std::strcmp("yes", get_attribute_string(*node, "swapxy", "no"))) + if (get_attribute_bool(*node, "swapxy", false)) result ^= ORIENTATION_SWAP_XY; - if (!std::strcmp("yes", get_attribute_string(*node, "flipx", "no"))) + if (get_attribute_bool(*node, "flipx", false)) result ^= ORIENTATION_FLIP_X; - if (!std::strcmp("yes", get_attribute_string(*node, "flipy", "no"))) + if (get_attribute_bool(*node, "flipy", false)) result ^= ORIENTATION_FLIP_Y; return result; } }; + +class view_environment : public layout_environment +{ +private: + view_environment *const m_next_view = nullptr; + char const *const m_name; + u32 const m_visibility_mask = 0U; + unsigned m_next_visibility_bit = 0U; + +public: + view_environment(layout_environment &next, char const *name) + : layout_environment(next) + , m_name(name) + { + } + view_environment(view_environment &next, bool visibility) + : layout_environment(next) + , m_next_view(&next) + , m_name(next.m_name) + , m_visibility_mask(next.m_visibility_mask | (u32(visibility ? 1 : 0) << next.m_next_visibility_bit)) + , m_next_visibility_bit(next.m_next_visibility_bit + (visibility ? 1 : 0)) + { + if (32U < m_next_visibility_bit) + throw layout_syntax_error(util::string_format("view '%s' contains too many visibility toggles", m_name)); + } + ~view_environment() + { + if (m_next_view) + m_next_view->m_next_visibility_bit = m_next_visibility_bit; + } + + u32 visibility_mask() const { return m_visibility_mask; } +}; + } } } // namespace emu::render::detail @@ -1157,6 +1220,13 @@ void layout_group::resolve_bounds( local.increment_parameters(); } } + else if (!strcmp(itemnode->get_name(), "vistoggle")) + { + if (!env.get_attribute_string(*itemnode, "name", nullptr)) + throw layout_syntax_error("vistoggle must have name attribute"); + environment local(env); + resolve_bounds(local, *itemnode, groupmap, seen, empty, false, true); + } else { throw layout_syntax_error(util::string_format("unknown group element %s", itemnode->get_name())); @@ -2955,23 +3025,70 @@ struct layout_view::layer_lists { item_list backdrops, screens, overlays, bezels //------------------------------------------------- layout_view::layout_view( - environment &env, + layout_environment &env, util::xml::data_node const &viewnode, element_map &elemmap, group_map &groupmap) : m_name(make_name(env, viewnode)) - , m_aspect(1.0f) - , m_scraspect(1.0f) + , m_effaspect(1.0f) , m_items() , m_has_art(false) + , m_defvismask(0U) { // parse the layout m_expbounds.x0 = m_expbounds.y0 = m_expbounds.x1 = m_expbounds.y1 = 0; - environment local(env); + view_environment local(env, m_name.c_str()); layer_lists layers; local.set_parameter("viewname", std::string(m_name)); add_items(layers, local, viewnode, elemmap, groupmap, ROT0, identity_transform, render_color{ 1.0F, 1.0F, 1.0F, 1.0F }, true, false, true); + // can't support legacy layers and modern visibility toggles at the same time + if (!m_vistoggles.empty() && (!layers.backdrops.empty() || !layers.overlays.empty() || !layers.bezels.empty() || !layers.cpanels.empty() || !layers.marquees.empty())) + throw layout_syntax_error("view contains visibility toggles as well as legacy backdrop, overlay, bezel, cpanel and/or marquee elements"); + + // create visibility toggles for legacy layers + u32 mask(1U); + if (!layers.backdrops.empty()) + { + m_vistoggles.emplace_back("Backdrops", mask); + for (item &backdrop : layers.backdrops) + backdrop.m_visibility_mask = mask; + m_defvismask |= mask; + mask <<= 1; + } + if (!layers.overlays.empty()) + { + m_vistoggles.emplace_back("Overlays", mask); + for (item &overlay : layers.overlays) + overlay.m_visibility_mask = mask; + m_defvismask |= mask; + mask <<= 1; + } + if (!layers.bezels.empty()) + { + m_vistoggles.emplace_back("Bezels", mask); + for (item &bezel : layers.bezels) + bezel.m_visibility_mask = mask; + m_defvismask |= mask; + mask <<= 1; + } + if (!layers.cpanels.empty()) + { + m_vistoggles.emplace_back("Control Panels", mask); + for (item &cpanel : layers.cpanels) + cpanel.m_visibility_mask = mask; + m_defvismask |= mask; + mask <<= 1; + } + if (!layers.marquees.empty()) + { + m_vistoggles.emplace_back("Backdrops", mask); + for (item &marquee : layers.marquees) + marquee.m_visibility_mask = mask; + m_defvismask |= mask; + mask <<= 1; + } + // deal with legacy element groupings if (!layers.overlays.empty() || (layers.backdrops.size() <= 1)) { @@ -3002,7 +3119,7 @@ layout_view::layout_view( } // calculate metrics - recompute(render_layer_config()); + recompute(default_visibility_mask(), false); for (group_map::value_type &group : groupmap) group.second.set_bounds_unresolved(); } @@ -3024,7 +3141,7 @@ layout_view::~layout_view() bool layout_view::has_screen(screen_device &screen) const { - return std::find_if(m_screens.begin(), m_screens.end(), [&screen](auto const &scr) { return &scr.get() == &screen; }) != m_screens.end(); + return std::find_if(m_screens.begin(), m_screens.end(), [&screen] (auto const &scr) { return &scr.get() == &screen; }) != m_screens.end(); } @@ -3033,36 +3150,39 @@ bool layout_view::has_screen(screen_device &screen) const // ratio of a view and all of its contained items //------------------------------------------------- -void layout_view::recompute(render_layer_config layerconfig) +void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen) { // reset the bounds - m_bounds.x0 = m_bounds.y0 = m_bounds.x1 = m_bounds.y1 = 0.0f; - m_scrbounds.x0 = m_scrbounds.y0 = m_scrbounds.x1 = m_scrbounds.y1 = 0.0f; + render_bounds scrbounds{ 0.0f, 0.0f, 0.0f, 0.0f }; + m_bounds = scrbounds; m_screens.clear(); - // loop over all layers + // loop over items and filter by visibility mask bool first = true; bool scrfirst = true; for (item &curitem : m_items) { - // accumulate bounds - if (first) - m_bounds = curitem.m_rawbounds; - else - union_render_bounds(m_bounds, curitem.m_rawbounds); - first = false; - - // accumulate screen bounds - if (curitem.m_screen) + if ((visibility_mask & curitem.visibility_mask()) == curitem.visibility_mask()) { - if (scrfirst) - m_scrbounds = curitem.m_rawbounds; + // accumulate bounds + if (first) + m_bounds = curitem.m_rawbounds; else - union_render_bounds(m_scrbounds, curitem.m_rawbounds); - scrfirst = false; + union_render_bounds(m_bounds, curitem.m_rawbounds); + first = false; - // accumulate the screens in use while we're scanning - m_screens.emplace_back(*curitem.m_screen); + // accumulate visible screens and their bounds bounds + if (curitem.m_screen) + { + if (scrfirst) + scrbounds = curitem.m_rawbounds; + else + union_render_bounds(scrbounds, curitem.m_rawbounds); + scrfirst = false; + + // accumulate the screens in use while we're scanning + m_screens.emplace_back(*curitem.m_screen); + } } } @@ -3070,36 +3190,29 @@ void layout_view::recompute(render_layer_config layerconfig) if (m_expbounds.x1 > m_expbounds.x0) m_bounds = m_expbounds; - // if we're handling things normally, the target bounds are (0,0)-(1,1) render_bounds target_bounds; - if (!layerconfig.zoom_to_screen() || m_screens.empty()) + if (!zoom_to_screen || scrfirst) { - // compute the aspect ratio of the view - m_aspect = (m_bounds.x1 - m_bounds.x0) / (m_bounds.y1 - m_bounds.y0); - + // if we're handling things normally, the target bounds are (0,0)-(1,1) + m_effaspect = ((m_bounds.x1 > m_bounds.x0) && (m_bounds.y1 > m_bounds.y0)) ? m_bounds.aspect() : 1.0f; target_bounds.x0 = target_bounds.y0 = 0.0f; target_bounds.x1 = target_bounds.y1 = 1.0f; } - - // if we're cropping, we want the screen area to fill (0,0)-(1,1) else { - // compute the aspect ratio of the screen - m_scraspect = (m_scrbounds.x1 - m_scrbounds.x0) / (m_scrbounds.y1 - m_scrbounds.y0); - - float targwidth = (m_bounds.x1 - m_bounds.x0) / (m_scrbounds.x1 - m_scrbounds.x0); - float targheight = (m_bounds.y1 - m_bounds.y0) / (m_scrbounds.y1 - m_scrbounds.y0); - target_bounds.x0 = (m_bounds.x0 - m_scrbounds.x0) / (m_bounds.x1 - m_bounds.x0) * targwidth; - target_bounds.y0 = (m_bounds.y0 - m_scrbounds.y0) / (m_bounds.y1 - m_bounds.y0) * targheight; - target_bounds.x1 = target_bounds.x0 + targwidth; - target_bounds.y1 = target_bounds.y0 + targheight; + // if we're cropping, we want the screen area to fill (0,0)-(1,1) + m_effaspect = ((scrbounds.x1 > scrbounds.x0) && (scrbounds.y1 > scrbounds.y0)) ? scrbounds.aspect() : 1.0f; + target_bounds.x0 = (m_bounds.x0 - scrbounds.x0) / scrbounds.width(); + target_bounds.y0 = (m_bounds.y0 - scrbounds.y0) / scrbounds.height(); + target_bounds.x1 = target_bounds.x0 + (m_bounds.width() / scrbounds.width()); + target_bounds.y1 = target_bounds.y0 + (m_bounds.height() / scrbounds.height()); } // determine the scale/offset for normalization - float xoffs = m_bounds.x0; - float yoffs = m_bounds.y0; - float xscale = (target_bounds.x1 - target_bounds.x0) / (m_bounds.x1 - m_bounds.x0); - float yscale = (target_bounds.y1 - target_bounds.y0) / (m_bounds.y1 - m_bounds.y0); + float const xoffs = m_bounds.x0; + float const yoffs = m_bounds.y0; + float const xscale = (target_bounds.x1 - target_bounds.x0) / (m_bounds.x1 - m_bounds.x0); + float const yscale = (target_bounds.y1 - target_bounds.y0) / (m_bounds.y1 - m_bounds.y0); // normalize all the item bounds for (item &curitem : items()) @@ -3129,7 +3242,7 @@ void layout_view::resolve_tags() void layout_view::add_items( layer_lists &layers, - environment &env, + view_environment &env, util::xml::data_node const &parentnode, element_map &elemmap, group_map &groupmap, @@ -3202,7 +3315,7 @@ void layout_view::add_items( { char const *ref(env.get_attribute_string(*itemnode, "ref", nullptr)); if (!ref) - throw layout_syntax_error("nested group must have ref attribute"); + throw layout_syntax_error("group instantiation must have ref attribute"); group_map::iterator const found(groupmap.find(ref)); if (groupmap.end() == found) @@ -3225,7 +3338,7 @@ void layout_view::add_items( grouptrans = found->second.make_transform(grouporient, trans); } - environment local(env); + view_environment local(env, false); add_items( layers, local, @@ -3244,13 +3357,23 @@ void layout_view::add_items( int const count(env.get_attribute_int(*itemnode, "count", -1)); if (0 >= count) throw layout_syntax_error("repeat must have positive integer count attribute"); - environment local(env); + view_environment local(env, false); for (int i = 0; count > i; ++i) { add_items(layers, local, *itemnode, elemmap, groupmap, orientation, trans, color, false, true, !i); local.increment_parameters(); } } + else if (!strcmp(itemnode->get_name(), "vistoggle")) + { + char const *name(env.get_attribute_string(*itemnode, "name", nullptr)); + if (!name) + throw layout_syntax_error("vistoggle must have name attribute"); + m_defvismask |= u32(env.get_attribute_bool(*itemnode, "enabled", true) ? 1 : 0) << m_vistoggles.size(); // TODO: make this less hacky + view_environment local(env, true); + m_vistoggles.emplace_back(name, local.visibility_mask()); + add_items(layers, local, *itemnode, elemmap, groupmap, orientation, trans, color, false, false, true); + } else { throw layout_syntax_error(util::string_format("unknown view item %s", itemnode->get_name())); @@ -3264,7 +3387,7 @@ void layout_view::add_items( } } -std::string layout_view::make_name(environment &env, util::xml::data_node const &viewnode) +std::string layout_view::make_name(layout_environment &env, util::xml::data_node const &viewnode) { char const *const name(env.get_attribute_string(viewnode, "name", nullptr)); if (!name) @@ -3294,7 +3417,7 @@ std::string layout_view::make_name(environment &env, util::xml::data_node const //------------------------------------------------- layout_view::item::item( - environment &env, + view_environment &env, util::xml::data_node const &itemnode, element_map &elemmap, int orientation, @@ -3314,6 +3437,7 @@ layout_view::item::item( , m_rawbounds(make_bounds(env, itemnode, trans)) , m_color(render_color_multiply(env.parse_color(itemnode.get_child("color")), color)) , m_blend_mode(get_blend_mode(env, itemnode)) + , m_visibility_mask(env.visibility_mask()) { // fetch common data int index = env.get_attribute_int(itemnode, "index", -1); @@ -3435,7 +3559,7 @@ void layout_view::item::resolve_tags() // find_element - find element definition //--------------------------------------------- -layout_element *layout_view::item::find_element(environment &env, util::xml::data_node const &itemnode, element_map &elemmap) +layout_element *layout_view::item::find_element(view_environment &env, util::xml::data_node const &itemnode, element_map &elemmap) { char const *const name(env.get_attribute_string(itemnode, !strcmp(itemnode.get_name(), "element") ? "ref" : "element", nullptr)); if (!name) @@ -3455,7 +3579,7 @@ layout_element *layout_view::item::find_element(environment &env, util::xml::dat //--------------------------------------------- render_bounds layout_view::item::make_bounds( - environment &env, + view_environment &env, util::xml::data_node const &itemnode, layout_group::transform const &trans) { @@ -3474,7 +3598,7 @@ render_bounds layout_view::item::make_bounds( // make_input_tag - get absolute input tag //--------------------------------------------- -std::string layout_view::item::make_input_tag(environment &env, util::xml::data_node const &itemnode) +std::string layout_view::item::make_input_tag(view_environment &env, util::xml::data_node const &itemnode) { char const *tag(env.get_attribute_string(itemnode, "inputtag", nullptr)); return tag ? env.device().subtag(tag) : std::string(); @@ -3485,7 +3609,7 @@ std::string layout_view::item::make_input_tag(environment &env, util::xml::data_ // get_blend_mode - explicit or implicit blend //--------------------------------------------- -int layout_view::item::get_blend_mode(environment &env, util::xml::data_node const &itemnode) +int layout_view::item::get_blend_mode(view_environment &env, util::xml::data_node const &itemnode) { // see if there's a blend mode attribute char const *const mode(env.get_attribute_string(itemnode, "blend", nullptr)); @@ -3515,6 +3639,23 @@ int layout_view::item::get_blend_mode(environment &env, util::xml::data_node con //************************************************************************** +// LAYOUT VIEW VISIBILITY TOGGLE +//************************************************************************** + +//------------------------------------------------- +// visibility_toggle - constructor +//------------------------------------------------- + +layout_view::visibility_toggle::visibility_toggle(std::string &&name, u32 mask) + : m_name(std::move(name)) + , m_mask(mask) +{ + assert(mask); +} + + + +//************************************************************************** // LAYOUT FILE //************************************************************************** @@ -3548,7 +3689,7 @@ layout_file::layout_file(device_t &device, util::xml::data_node const &rootnode, for (util::xml::data_node const *viewnode = mamelayoutnode->get_child("view"); viewnode != nullptr; viewnode = viewnode->get_next_sibling("view")) { // the trouble with allowing errors to propagate here is that it wreaks havoc with screenless systems that use a terminal by default - // e.g. intlc44 and intlc440 have a terminal on the tty port by default and have a view with the front panel with the terminal screen + // e.g. intlc44 and intlc440 have a terminal on the TTY port by default and have a view with the front panel with the terminal screen // however, they have a second view with just the front panel which is very useful if you're using e.g. -tty null_modem with a socket // if the error is allowed to propagate, the entire layout is dropped so you can't select the useful view try diff --git a/src/emu/video.cpp b/src/emu/video.cpp index e14ad211f23..e28e6aa1bae 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -138,7 +138,7 @@ video_manager::video_manager(running_machine &machine) util::xml::data_node *const viewnode(layoutnode->add_child("view", nullptr)); if (!viewnode) throw emu_fatalerror("Couldn't create XML node??"); - viewnode->set_attribute("name", util::xml::normalize_string(util::string_format("s%1$u", i).c_str())); + viewnode->set_attribute("name", util::string_format("s%1$u", i).c_str()); util::xml::data_node *const screennode(viewnode->add_child("screen", nullptr)); if (!screennode) throw emu_fatalerror("Couldn't create XML node??"); diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index 93f4fa85e94..022d88f6515 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -2495,7 +2495,7 @@ void lua_engine::initialize() auto target_type = sol().registry().create_simple_usertype<render_target>("new", sol::no_constructor); target_type.set("view_bounds", [](render_target &rt) { - const render_bounds b = rt.current_view()->bounds(); + const render_bounds b = rt.current_view().bounds(); return std::tuple<float, float, float, float>(b.x0, b.x1, b.y0, b.y1); }); target_type.set("width", &render_target::width); diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp index beca0b10a6e..bd7f274da29 100644 --- a/src/frontend/mame/ui/mainmenu.cpp +++ b/src/frontend/mame/ui/mainmenu.cpp @@ -228,7 +228,7 @@ void menu_main::handle() break; case VIDEO_OPTIONS: - menu::stack_push<menu_video_options>(ui(), container(), machine().render().first_target()); + menu::stack_push<menu_video_options>(ui(), container(), *machine().render().first_target()); break; case CROSSHAIR: diff --git a/src/frontend/mame/ui/videoopt.cpp b/src/frontend/mame/ui/videoopt.cpp index baa0a265cb6..58818328d41 100644 --- a/src/frontend/mame/ui/videoopt.cpp +++ b/src/frontend/mame/ui/videoopt.cpp @@ -9,12 +9,52 @@ *********************************************************************/ #include "emu.h" - #include "ui/videoopt.h" #include "rendutil.h" + namespace ui { + +namespace { + +constexpr uintptr_t ITEM_ROTATE = 0x00000100; +constexpr uintptr_t ITEM_ZOOM = 0x00000101; +constexpr uintptr_t ITEM_TOGGLE_FIRST = 0x00000200; +constexpr uintptr_t ITEM_VIEW_FIRST = 0x00000300; + +} // anonymous namespace + + +/*------------------------------------------------- + menu_video_targets_populate - populate the + video targets menu +-------------------------------------------------*/ + +menu_video_targets::menu_video_targets(mame_ui_manager &mui, render_container &container) + : menu(mui, container) +{ +} + +menu_video_targets::~menu_video_targets() +{ +} + +void menu_video_targets::populate(float &customtop, float &custombottom) +{ + // find the targets + for (unsigned targetnum = 0; ; targetnum++) + { + // stop when we run out + render_target *const target = machine().render().target_by_index(targetnum); + if (!target) + break; + + // add a menu item + item_append(util::string_format(_("Screen #%d"), targetnum), "", 0, target); + } +} + /*------------------------------------------------- menu_video_targets - handle the video targets menu @@ -22,46 +62,74 @@ namespace ui { void menu_video_targets::handle() { - /* process the menu */ - const event *menu_event = process(0); - if (menu_event != nullptr && menu_event->iptkey == IPT_UI_SELECT) - menu::stack_push<menu_video_options>(ui(), container(), static_cast<render_target *>(menu_event->itemref)); + event const *const menu_event = process(0); + if (menu_event && (menu_event->iptkey == IPT_UI_SELECT)) + menu::stack_push<menu_video_options>(ui(), container(), *reinterpret_cast<render_target *>(menu_event->itemref)); } /*------------------------------------------------- - menu_video_targets_populate - populate the - video targets menu + menu_video_options_populate - populate the + video options menu -------------------------------------------------*/ -menu_video_targets::menu_video_targets(mame_ui_manager &mui, render_container &container) : menu(mui, container) +menu_video_options::menu_video_options(mame_ui_manager &mui, render_container &container, render_target &target) + : menu(mui, container) + , m_target(target) { } -void menu_video_targets::populate(float &customtop, float &custombottom) +menu_video_options::~menu_video_options() { - int targetnum; +} + +void menu_video_options::populate(float &customtop, float &custombottom) +{ + uintptr_t ref; - /* find the targets */ - for (targetnum = 0; ; targetnum++) + // add items for each view + for (char const *name = m_target.view_name(ref = 0); name; name = m_target.view_name(++ref)) + item_append(name, "", 0, reinterpret_cast<void *>(ITEM_VIEW_FIRST + ref)); + item_append(menu_item_type::SEPARATOR); + + // add items for visibility toggles + auto const &toggles = m_target.visibility_toggles(); + if (!toggles.empty()) { - render_target *target = machine().render().target_by_index(targetnum); - char buffer[40]; + ref = 0U; + auto const current_mask(m_target.visibility_mask()); + for (auto toggle = toggles.begin(); toggles.end() != toggle; ++toggle, ++ref) + { + auto const toggle_mask(toggle->mask()); + bool const enabled(BIT(current_mask, ref)); + bool eclipsed(false); + for (auto it = toggles.begin(); !eclipsed && (toggle != it); ++it) + eclipsed = ((current_mask & it->mask()) != it->mask()) && ((toggle_mask & it->mask()) == it->mask()); + u32 const flags((enabled ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW) | (eclipsed ? (FLAG_INVERT | FLAG_DISABLE) : 0U)); + item_append(toggle->name(), enabled ? _("On") : _("Off"), flags, reinterpret_cast<void *>(ITEM_TOGGLE_FIRST + ref)); + } + item_append(menu_item_type::SEPARATOR); + } - /* stop when we run out */ - if (target == nullptr) - break; + const char *subtext = ""; - /* add a menu item */ - sprintf(buffer, _("Screen #%d"), targetnum); - item_append(buffer, "", 0, target); + // add a rotate item + switch (m_target.orientation()) + { + case ROT0: subtext = "None"; break; + case ROT90: subtext = "CW 90" UTF8_DEGREES; break; + case ROT180: subtext = "180" UTF8_DEGREES; break; + case ROT270: subtext = "CCW 90" UTF8_DEGREES; break; } -} + item_append(_("Rotate"), subtext, FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, reinterpret_cast<void *>(ITEM_ROTATE)); -menu_video_targets::~menu_video_targets() -{ + // cropping + int enabled; + enabled = m_target.zoom_to_screen(); + item_append(_("Zoom to Screen Area"), enabled ? _("On") : _("Off"), enabled ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, reinterpret_cast<void *>(ITEM_ZOOM)); } + /*------------------------------------------------- menu_video_options - handle the video options menu @@ -69,21 +137,21 @@ menu_video_targets::~menu_video_targets() void menu_video_options::handle() { - bool changed = false; + bool changed(false); // process the menu - const event *menu_event = process(0); - if (menu_event != nullptr && menu_event->itemref != nullptr) + event const *const menu_event(process(0)); + if (menu_event && menu_event->itemref) { - switch ((uintptr_t)menu_event->itemref) + switch (reinterpret_cast<uintptr_t>(menu_event->itemref)) { // rotate adds rotation depending on the direction - case VIDEO_ITEM_ROTATE: + case ITEM_ROTATE: if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) { - int delta = (menu_event->iptkey == IPT_UI_LEFT) ? ROT270 : ROT90; - target->set_orientation(orientation_add(delta, target->orientation())); - if (target->is_ui_target()) + int const delta((menu_event->iptkey == IPT_UI_LEFT) ? ROT270 : ROT90); + m_target.set_orientation(orientation_add(delta, m_target.orientation())); + if (m_target.is_ui_target()) { render_container::user_settings settings; container().get_user_settings(settings); @@ -95,20 +163,31 @@ void menu_video_options::handle() break; // layer config bitmasks handle left/right keys the same (toggle) - case VIDEO_ITEM_ZOOM: - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) + case ITEM_ZOOM: + if ((menu_event->iptkey == IPT_UI_LEFT) || (menu_event->iptkey == IPT_UI_RIGHT)) { - target->set_zoom_to_screen(!target->zoom_to_screen()); + m_target.set_zoom_to_screen(menu_event->iptkey == IPT_UI_RIGHT); changed = true; } break; // anything else is a view item default: - if (menu_event->iptkey == IPT_UI_SELECT && (int)(uintptr_t)menu_event->itemref >= VIDEO_ITEM_VIEW) + if (reinterpret_cast<uintptr_t>(menu_event->itemref) >= ITEM_VIEW_FIRST) { - target->set_view((uintptr_t)menu_event->itemref - VIDEO_ITEM_VIEW); - changed = true; + if (menu_event->iptkey == IPT_UI_SELECT) + { + m_target.set_view(reinterpret_cast<uintptr_t>(menu_event->itemref) - ITEM_VIEW_FIRST); + changed = true; + } + } + else if (reinterpret_cast<uintptr_t>(menu_event->itemref) >= ITEM_TOGGLE_FIRST) + { + if ((menu_event->iptkey == IPT_UI_LEFT) || (menu_event->iptkey == IPT_UI_RIGHT)) + { + m_target.set_visibility_toggle(reinterpret_cast<uintptr_t>(menu_event->itemref) - ITEM_TOGGLE_FIRST, menu_event->iptkey == IPT_UI_RIGHT); + changed = true; + } } break; } @@ -119,56 +198,4 @@ void menu_video_options::handle() reset(reset_options::REMEMBER_REF); } - -/*------------------------------------------------- - menu_video_options_populate - populate the - video options menu --------------------------------------------------*/ - -menu_video_options::menu_video_options(mame_ui_manager &mui, render_container &container, render_target *_target) : menu(mui, container) -{ - target = _target; -} - -void menu_video_options::populate(float &customtop, float &custombottom) -{ - const char *subtext = ""; - std::string tempstring; - int enabled; - - // add items for each view - for (int viewnum = 0; ; viewnum++) - { - const char *name = target->view_name(viewnum); - if (name == nullptr) - break; - - // create a string for the item, replacing underscores with spaces - tempstring.assign(name); - strreplace(tempstring, "_", " "); - item_append(tempstring, "", 0, (void *)(uintptr_t)(VIDEO_ITEM_VIEW + viewnum)); - } - - // add a separator - item_append(menu_item_type::SEPARATOR); - - // add a rotate item - switch (target->orientation()) - { - case ROT0: subtext = "None"; break; - case ROT90: subtext = "CW 90" UTF8_DEGREES; break; - case ROT180: subtext = "180" UTF8_DEGREES; break; - case ROT270: subtext = "CCW 90" UTF8_DEGREES; break; - } - item_append(_("Rotate"), subtext, FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_ROTATE); - - // cropping - enabled = target->zoom_to_screen(); - item_append(_("View"), enabled ? _("Cropped") : _("Full"), enabled ? FLAG_RIGHT_ARROW : FLAG_LEFT_ARROW, (void *)VIDEO_ITEM_ZOOM); -} - -menu_video_options::~menu_video_options() -{ -} - } // namespace ui diff --git a/src/frontend/mame/ui/videoopt.h b/src/frontend/mame/ui/videoopt.h index 6e07e14a029..a70e7b8aa94 100644 --- a/src/frontend/mame/ui/videoopt.h +++ b/src/frontend/mame/ui/videoopt.h @@ -7,15 +7,16 @@ Internal menus for video options ***************************************************************************/ - -#pragma once - #ifndef MAME_FRONTEND_UI_VIDEOOPT_H #define MAME_FRONTEND_UI_VIDEOOPT_H +#pragma once + #include "ui/menu.h" + namespace ui { + class menu_video_targets : public menu { public: @@ -27,25 +28,20 @@ private: virtual void handle() override; }; + class menu_video_options : public menu { public: - menu_video_options(mame_ui_manager &mui, render_container &container, render_target *target); + menu_video_options(mame_ui_manager &mui, render_container &container, render_target &target); virtual ~menu_video_options() override; private: - enum : uint32_t { - VIDEO_ITEM_ROTATE = 0x80000000, - VIDEO_ITEM_ZOOM, - VIDEO_ITEM_VIEW - }; - virtual void populate(float &customtop, float &custombottom) override; virtual void handle() override; - render_target *target; + render_target &m_target; }; } // namespace ui -#endif /* MAME_FRONTEND_UI_VIDEOOPT_H */ +#endif // MAME_FRONTEND_UI_VIDEOOPT_H diff --git a/src/lib/util/xmlfile.cpp b/src/lib/util/xmlfile.cpp index ad4d4e1e8f8..a61c20d2e3c 100644 --- a/src/lib/util/xmlfile.cpp +++ b/src/lib/util/xmlfile.cpp @@ -33,6 +33,37 @@ namespace { constexpr unsigned TEMP_BUFFER_SIZE(4096U); std::locale const f_portable_locale("C"); + +/*************************************************************************** + UTILITY FUNCTIONS +***************************************************************************/ + +void write_escaped(core_file &file, std::string const &str) +{ + std::string::size_type pos = 0; + while ((str.size() > pos) && (std::string::npos != pos)) + { + std::string::size_type const found = str.find_first_of("\"&<>", pos); + if (found != std::string::npos) + { + file.write(&str[pos], found - pos); + switch (str[found]) + { + case '"': file.puts("""); pos = found + 1; break; + case '&': file.puts("&"); pos = found + 1; break; + case '<': file.puts("<"); pos = found + 1; break; + case '>': file.puts(">"); pos = found + 1; break; + default: pos = found; + } + } + else + { + file.write(&str[pos], str.size() - pos); + pos = found; + } + } +} + } // anonymous namespace @@ -950,9 +981,13 @@ void data_node::write_recursive(int indent, util::core_file &file) const /* output this tag */ file.printf("%*s<%s", indent, "", get_name()); - /* output any attributes */ + /* output any attributes, escaping as necessary */ for (attribute_node const &anode : m_attributes) - file.printf(" %s=\"%s\"", anode.name, anode.value); + { + file.printf(" %s=\"", anode.name); + write_escaped(file, anode.value); + file.puts("\""); + } if (!get_first_child() && !get_value()) { @@ -965,8 +1000,12 @@ void data_node::write_recursive(int indent, util::core_file &file) const file.printf(">\n"); /* if there is a value, output that here */ - if (get_value()) - file.printf("%*s%s\n", indent + 4, "", get_value()); + if (!m_value.empty()) + { + file.printf("%*s", indent + 4, ""); + write_escaped(file, m_value); + file.puts("\n"); + } /* loop over children and output them as well */ if (get_first_child()) diff --git a/src/mame/drivers/micronic.cpp b/src/mame/drivers/micronic.cpp index 3f93808ee0d..a27725ee614 100644 --- a/src/mame/drivers/micronic.cpp +++ b/src/mame/drivers/micronic.cpp @@ -2,7 +2,11 @@ // copyright-holders:Sandro Ronco /*************************************************************************** - Micronics 1000 + Micronic 1000 + + This is a small handheld CP/M computer with a 4x8 keypad and a 128x64 + LCD display. It was produced by Victor Micronic Ltd, a UK subsidiary + of Datronic AB. 06/2010 (Sandro Ronco) - ROM/RAM banking @@ -18,9 +22,10 @@ The display shows "TESTING..." for about 2 min before showing the information screen More info: - http://www.philpem.me.uk/elec/micronic/ - http://members.lycos.co.uk/leeedavison/z80/micronic/index.html - http://reocities.com/SiliconValley/Port/8052/ + http://web.archive.org/web/20180104024745/http://www.philpem.me.uk/elec/micronic/ + http://web.archive.org/web/20080411235036/http://members.lycos.co.uk:80/leeedavison/z80/micronic/index.html + https://geocities.restorativland.org/SiliconValley/Port/8052/ + https://www.cbronline.com/news/victor_micronic_has_the_m1000_handheld_computer_terminal/ ****************************************************************************/ @@ -395,4 +400,4 @@ ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 198?, micronic, 0, 0, micronic, micronic, micronic_state, empty_init, "Victor Micronic", "Micronic 1000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1987, micronic, 0, 0, micronic, micronic, micronic_state, empty_init, "Victor Micronic", "Micronic 1000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/microtan.cpp b/src/mame/drivers/microtan.cpp index 15c7a98a302..2e155561761 100644 --- a/src/mame/drivers/microtan.cpp +++ b/src/mame/drivers/microtan.cpp @@ -49,6 +49,12 @@ * BAS Start BASIC * WAR Re-enter BASIC (warm start) * + * The keyboard is essentially an ordinary ASCII keyboard, with 71 keys, 8 + * TTL chips and an undumped 2716 eprom labelled MON V1. We currently use a + * generic keyboard because of the lack of a schematic. Unemulated keys are + * 'SHIFT LOCK' and 'REPT'. Since all commands must be uppercase, capslock + * is defaulted to on. + * *****************************************************************************/ #include "emu.h" @@ -105,68 +111,68 @@ static INPUT_PORTS_START( microtan ) PORT_START("KBD0") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 \'") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR(39) PORT_START("KBD1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("` ~") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BACK SPACE") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('~') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(": *") PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- =") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NEW PAGE") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(12) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RUB OUT") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_TAB) PORT_CHAR('^') PORT_CHAR('_') PORT_START("KBD2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') PORT_START("KBD3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(127) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_DEL) PORT_CHAR(3) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ALFA LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE PORT_START("KBD4") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') PORT_START("KBD5") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(39) PORT_CHAR(34) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\ |") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('@') PORT_CHAR('`') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SHIFT (L)") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') PORT_START("KBD6") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') diff --git a/src/mame/drivers/pb1000.cpp b/src/mame/drivers/pb1000.cpp index a9b9f4b52da..d5f9a1c02e2 100644 --- a/src/mame/drivers/pb1000.cpp +++ b/src/mame/drivers/pb1000.cpp @@ -12,6 +12,9 @@ Known issues: - the second memory card is not recognized by the HW + - pb2000c, ai1000: the shift key has to be released before hitting + the key that is to be shifted. Therefore natural keyboard/paste + will misbehave for shifted characters. More info: http://www.itkp.uni-bonn.de/~wichmann/pb1000-wrobel.html @@ -37,13 +40,14 @@ class pb1000_state : public driver_device { public: - pb1000_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_beeper(*this, "beeper"), - m_hd44352(*this, "hd44352"), - m_card1(*this, "cardslot1"), - m_card2(*this, "cardslot2") + pb1000_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_beeper(*this, "beeper") + , m_hd44352(*this, "hd44352") + , m_card1(*this, "cardslot1") + , m_card2(*this, "cardslot2") + , m_io_keyboard(*this, "KO%u", 0U) { } void pb2000c(machine_config &config); @@ -55,6 +59,7 @@ private: required_device<hd44352_device> m_hd44352; optional_device<generic_slot_device> m_card1; optional_device<generic_slot_device> m_card2; + required_ioport_array<13> m_io_keyboard; emu_timer *m_kb_timer; uint8_t m_kb_matrix; @@ -104,24 +109,25 @@ void pb1000_state::pb2000c_mem(address_map &map) /* Input ports */ static INPUT_PORTS_START( pb1000 ) + PORT_START("KO0") PORT_START("KO1") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_F10) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("OFF") PORT_CODE(KEYCODE_7_PAD) PORT_START("KO2") PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXE") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("IN") PORT_CODE(KEYCODE_F4) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("IN") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MEMO IN") PORT_CODE(KEYCODE_0_PAD) - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('?') - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("'") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('"') PORT_CHAR('!') - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("$") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('$') PORT_CHAR('#') - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("&") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('&') PORT_CHAR('%') - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('\'') - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('<') - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(":") PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(':') PORT_CHAR('>') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(", ?") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('?') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("\" !") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('"') PORT_CHAR('!') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("$ #") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('$') PORT_CHAR('#') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("& %") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('&') PORT_CHAR('%') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("= '") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('\'') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("; <") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('<') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(": >") PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(':') PORT_CHAR('>') PORT_START("KO3") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("OUT") PORT_CODE(KEYCODE_F3) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MEMO") PORT_CODE(KEYCODE_F11) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("OUT") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MEMO") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') @@ -130,9 +136,9 @@ static INPUT_PORTS_START( pb1000 ) PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_START("KO4") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CALC") PORT_CODE(KEYCODE_HOME) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CAL") PORT_CODE(KEYCODE_F9) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CAL") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CAPS") PORT_CODE(KEYCODE_CAPSLOCK) PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') @@ -141,9 +147,9 @@ static INPUT_PORTS_START( pb1000 ) PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_START("KO5") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MENU") PORT_CODE(KEYCODE_F5) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MENU") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') @@ -152,14 +158,14 @@ static INPUT_PORTS_START( pb1000 ) PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_START("KO6") - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LCKEY") PORT_CODE(KEYCODE_F1) - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CONTR") PORT_CODE(KEYCODE_F2) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LCKEY") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CONTRAST") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(")") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(')') PORT_CHAR(']') - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("STOP") PORT_CODE(KEYCODE_F7) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("STOP") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("INS") PORT_CODE(KEYCODE_INSERT) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NEW ALL") PORT_CODE(KEYCODE_ESC) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CLS") PORT_CODE(KEYCODE_DEL) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NEW ALL") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CLS") PORT_CODE(KEYCODE_DEL) PORT_CHAR(12) PORT_START("KO7") PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("^") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('^') PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('}') @@ -167,7 +173,7 @@ static INPUT_PORTS_START( pb1000 ) PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('\'') PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('_') PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('@') - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ENG") PORT_CODE(KEYCODE_F6) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ENG") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_START("KO8") PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("*") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') PORT_CHAR('{') @@ -195,9 +201,7 @@ static INPUT_PORTS_START( pb1000 ) PORT_START("KO11") PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_START("KO12") - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_LALT) - PORT_START("NULL") - PORT_BIT(0xffff, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("White F") PORT_CODE(KEYCODE_LALT) //touchscreen PORT_START("POSX") @@ -209,100 +213,98 @@ static INPUT_PORTS_START( pb1000 ) INPUT_PORTS_END static INPUT_PORTS_START( pb2000c ) + PORT_START("KO0") PORT_START("KO1") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_F10) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("OFF") PORT_CODE(KEYCODE_7_PAD) PORT_START("KO2") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("'") PORT_CODE(KEYCODE_QUOTE) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("'") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(39, 33) PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CAPS") PORT_CODE(KEYCODE_CAPSLOCK) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q','?') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W','@') PORT_START("KO3") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(") PORT_CODE(KEYCODE_PGUP) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(")") PORT_CODE(KEYCODE_PGDN) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M1") PORT_CODE(KEYCODE_F1) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(") PORT_CODE(KEYCODE_PGUP) PORT_CHAR('(','"') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(")") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(')','#') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E','\\') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('_') PORT_START("KO4") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M2") PORT_CODE(KEYCODE_F2) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[','$') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']','%') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T',39) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y','{') PORT_START("KO5") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("|") PORT_CODE(KEYCODE_BACKSLASH) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MEMO") PORT_CODE(KEYCODE_F11) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M3") PORT_CODE(KEYCODE_F3) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("|") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('|','&') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MEMO") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U','}') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I','~') PORT_START("KO6") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("IN") PORT_CODE(KEYCODE_F6) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("OUT") PORT_CODE(KEYCODE_F7) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M4") PORT_CODE(KEYCODE_F4) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("IN") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("OUT") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O','<') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P','>') PORT_START("KO7") PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CALC") PORT_CODE(KEYCODE_HOME) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ETC") PORT_CODE(KEYCODE_F12) - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SS") PORT_CODE(KEYCODE_LSHIFT) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ETC") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Red S") PORT_CODE(KEYCODE_LSHIFT) // PORT_CHAR(UCHAR_SHIFT_1) design of the computer breaks this PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ANS") PORT_CODE(KEYCODE_END) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(":") PORT_CODE(KEYCODE_BACKSLASH2) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(":") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(':') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=','^') PORT_START("KO8") - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NEW ALL") PORT_CODE(KEYCODE_ESC) - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NEW ALL") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_START("KO9") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXE") PORT_CODE(KEYCODE_ENTER) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_PLUS_PAD) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXE") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_START("KO10") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_F8) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MENU") PORT_CODE(KEYCODE_F5) - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("*") PORT_CODE(KEYCODE_ASTERISK) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CAL") PORT_CODE(KEYCODE_F9) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MENU") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("*") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CAL") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_START("KO11") PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("INS") PORT_CODE(KEYCODE_INSERT) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CLS") PORT_CODE(KEYCODE_DEL) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CLS") PORT_CODE(KEYCODE_DEL) PORT_CHAR(12) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_START("KO12") - PORT_BIT(0xffff, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_START("NULL") - PORT_BIT(0xffff, IP_ACTIVE_HIGH, IPT_UNUSED) INPUT_PORTS_END void pb1000_state::pb1000_palette(palette_device &palette) const @@ -356,23 +358,23 @@ uint16_t pb1000_state::read_touchscreen(uint8_t line) uint16_t pb1000_state::pb1000_kb_r() { - static const char *const bitnames[] = {"NULL", "KO1", "KO2", "KO3", "KO4", "KO5", "KO6", "KO7", "KO8", "KO9", "KO10", "KO11", "KO12", "NULL", "NULL", "NULL"}; uint16_t data = 0; + u8 kb = m_kb_matrix & 15; - if ((m_kb_matrix & 0x0f) == 0x0d) + if (kb == 13) { //Read all the input lines - for (int line = 1; line <= 12; line++) + for (u8 line = 1; line < 13; line++) { - data |= ioport(bitnames[line])->read(); + data |= m_io_keyboard[line]->read(); data |= read_touchscreen(line); } - } else + if (kb < 13) { - data = ioport(bitnames[m_kb_matrix & 0x0f])->read(); - data |= read_touchscreen(m_kb_matrix & 0x0f); + data = m_io_keyboard[kb]->read(); + data |= read_touchscreen(kb); } return data; @@ -380,38 +382,34 @@ uint16_t pb1000_state::pb1000_kb_r() uint16_t pb1000_state::pb2000c_kb_r() { - static const char *const bitnames[] = {"NULL", "KO1", "KO2", "KO3", "KO4", "KO5", "KO6", "KO7", "KO8", "KO9", "KO10", "KO11", "KO12", "NULL", "NULL", "NULL"}; uint16_t data = 0; + u8 kb = m_kb_matrix & 15; - if ((m_kb_matrix & 0x0f) == 0x0d) + if (kb == 13) { //Read all the input lines - for (int line = 1; line <= 12; line++) - { - data |= ioport(bitnames[line])->read(); - } - + for (u8 line = 1; line < 12; line++) + data |= m_io_keyboard[line]->read(); } else - { - data = ioport(bitnames[m_kb_matrix & 0x0f])->read(); - } + if (kb < 12) + data = m_io_keyboard[kb]->read(); return data; } void pb1000_state::kb_matrix_w(uint8_t data) { - if (data & 0x80) + if (BIT(data, 7)) { - if ((m_kb_matrix & 0x80) != (data & 0x80)) + if (!BIT(m_kb_matrix, 7)) m_kb_timer->adjust(attotime::never, 0, attotime::never); } else { - if ((m_kb_matrix & 0x40) != (data & 0x40)) + if (BIT(m_kb_matrix, 6) != BIT(data, 6)) { - if (data & 0x40) + if (BIT(data, 6)) m_kb_timer->adjust(attotime::from_hz(32), 0, attotime::from_hz(32)); else m_kb_timer->adjust(attotime::from_hz(256), 0, attotime::from_hz(256)); diff --git a/src/mame/drivers/pet.cpp b/src/mame/drivers/pet.cpp index 944f39c3d7f..bf020d6c52e 100644 --- a/src/mame/drivers/pet.cpp +++ b/src/mame/drivers/pet.cpp @@ -2,6 +2,9 @@ // copyright-holders:Curt Coder /* +PET = Personal Electronic Transactor + + http://www.6502.org/users/andre/petindex/boards.html Static Board (PET 2001) @@ -911,51 +914,51 @@ static INPUT_PORTS_START( pet ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91 Pi") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('^') PORT_CHAR(0x03C0) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_START( "ROW3" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR('/') PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_START( "ROW4" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6') PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_START( "ROW5" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_START( "ROW6" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR(';') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_START( "ROW7" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+') @@ -963,9 +966,9 @@ static INPUT_PORTS_START( pet ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('?') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_START( "ROW8" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR('-') diff --git a/src/mame/drivers/plus4.cpp b/src/mame/drivers/plus4.cpp index 0baa1aebd41..d10e12e4b7d 100644 --- a/src/mame/drivers/plus4.cpp +++ b/src/mame/drivers/plus4.cpp @@ -489,13 +489,13 @@ static INPUT_PORTS_START( plus4 ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CHAR(UCHAR_MAMEKEY(F4)) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("HELP f7") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("HELP F7") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(0xA3) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INST DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PORT_START( "ROW1" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Shift (Left & Right)") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Shift (Left & Right)") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') @@ -529,7 +529,7 @@ static INPUT_PORTS_START( plus4 ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("0 \xE2\x86\x91") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(0x2191) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("0 \xE2\x86\x91") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('^') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') @@ -546,13 +546,13 @@ static INPUT_PORTS_START( plus4 ) PORT_START( "ROW6" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("= Pi \xE2\x86\x90") PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('=') PORT_CHAR(0x03C0) PORT_CHAR(0x2190) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("= Pi \xE2\x86\x90") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('=') PORT_CHAR(0x03C0) PORT_CHAR(0x2190) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR(']') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_CHAR('*') - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_CHAR('*') + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_START( "ROW7" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RUN STOP") PORT_CODE(KEYCODE_HOME) @@ -560,8 +560,8 @@ static INPUT_PORTS_START( plus4 ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CBM") PORT_CODE(KEYCODE_LALT) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_SHIFT_2) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Home Clear") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(HOME)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Control") PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Home Clear") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') PORT_START( "LOCK" ) @@ -582,7 +582,7 @@ static INPUT_PORTS_START( c16 ) PORT_MODIFY( "ROW5" ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_MODIFY( "ROW6" ) diff --git a/src/mame/drivers/sega_sawatte.cpp b/src/mame/drivers/sega_sawatte.cpp index 3f09bc1b459..8e96f53a811 100644 --- a/src/mame/drivers/sega_sawatte.cpp +++ b/src/mame/drivers/sega_sawatte.cpp @@ -1,13 +1,12 @@ // license:BSD-3-Clause -// copyright-holders: +// copyright-holders:AJR /* Sega Sawatte / S-Pico a sound-only Pico type system (one of the boards even says S-PICO) -CPU is unknown (I can't see one?! MCU with internal ROM?) cartridge dumps contain 6502 code +CPU is unknown (MCU with internal ROM?) cartridge dumps contain 6502 code and have been tested as working using a flash cart. -driver does nothing except allow the softlist to be connected to the -romident commands etc. images supplied by Team Europe @@ -26,6 +25,9 @@ http://mamedev.emulab.it/haze/reference/sawatte/cartridge_example.jpg */ #include "emu.h" +#include "bus/generic/carts.h" +#include "bus/generic/slot.h" +#include "cpu/m6502/m6502.h" #include "softlist_dev.h" @@ -34,19 +36,210 @@ class sawatte_state : public driver_device public: sawatte_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_cartslot(*this, "cartslot") + , m_soundram(*this, "soundram") + , m_irq3_timer(nullptr) + , m_irq4_timer(nullptr) + , m_data_bank(0) + , m_prog_bank(0) + , m_irq_status(0) + , m_irq_mask(0) { } void sawatte(machine_config &config); + protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + TIMER_CALLBACK_MEMBER(irq3_timer); + TIMER_CALLBACK_MEMBER(irq4_timer); + + void bank08_w(u8 data); + void bank09_w(u8 data); + void bank0a_w(u8 data); + u8 irq_status_r(); + void irq_mask_w(u8 data); + void irq3_timer_w(u8 data); + void irq4_timer_w(u8 data); + u8 fixed_r(offs_t offset); + u8 data_bank_r(offs_t offset); + u8 prog_bank_r(offs_t offset); + + void mem_map(address_map &map); + + required_device<cpu_device> m_maincpu; + required_device<generic_slot_device> m_cartslot; + required_shared_ptr<u8> m_soundram; + + emu_timer *m_irq3_timer; + emu_timer *m_irq4_timer; + + u16 m_data_bank; + u8 m_prog_bank; + u8 m_irq_status; + u8 m_irq_mask; }; +void sawatte_state::machine_start() +{ + m_irq3_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sawatte_state::irq3_timer), this)); + m_irq4_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sawatte_state::irq4_timer), this)); + + save_item(NAME(m_data_bank)); + save_item(NAME(m_prog_bank)); + save_item(NAME(m_irq_status)); + save_item(NAME(m_irq_mask)); +} + +void sawatte_state::machine_reset() +{ + m_data_bank = 0; + m_prog_bank = 0; + + m_irq_status = 0; + m_irq_mask = 0; + m_maincpu->set_input_line(m6502_device::IRQ_LINE, CLEAR_LINE); + + m_irq3_timer->adjust(attotime::never); + m_irq4_timer->adjust(attotime::never); +} + +TIMER_CALLBACK_MEMBER(sawatte_state::irq3_timer) +{ + if (BIT(m_irq_mask, 3)) + { + m_irq_status |= 0x08; + m_maincpu->set_input_line(m6502_device::IRQ_LINE, ASSERT_LINE); + } +} + +TIMER_CALLBACK_MEMBER(sawatte_state::irq4_timer) +{ + if (BIT(m_irq_mask, 4)) + { + m_irq_status |= 0x10; + m_maincpu->set_input_line(m6502_device::IRQ_LINE, ASSERT_LINE); + } +} + + +void sawatte_state::bank08_w(u8 data) +{ + m_data_bank = (m_data_bank & 0xff00) | data; +} + +void sawatte_state::bank09_w(u8 data) +{ + m_data_bank = u16(data) << 8 | (m_data_bank & 0x00ff); +} + +void sawatte_state::bank0a_w(u8 data) +{ + m_prog_bank = data; +} + +u8 sawatte_state::irq_status_r() +{ + return m_irq_status; +} + +void sawatte_state::irq_mask_w(u8 data) +{ + m_irq_mask = data; + if (m_irq_status != 0) + { + m_irq_status &= data; + if (m_irq_status == 0) + m_maincpu->set_input_line(m6502_device::IRQ_LINE, CLEAR_LINE); + } +} + +void sawatte_state::irq3_timer_w(u8 data) +{ + if (data == 0) + m_irq3_timer->adjust(attotime::never); + else + { + attotime period = attotime::from_hz(10'000); // probably incorrect + m_irq3_timer->adjust(period, 0, period); + } +} + +void sawatte_state::irq4_timer_w(u8 data) +{ + if (!BIT(data, 0)) + m_irq4_timer->adjust(attotime::never); + else + { + attotime period = attotime::from_hz(8'000); // probably incorrect + m_irq4_timer->adjust(period, 0, period); + } +} + +u8 sawatte_state::fixed_r(offs_t offset) +{ + return m_cartslot->read_rom(offset + 0x200); +} + +u8 sawatte_state::data_bank_r(offs_t offset) +{ + return m_cartslot->read_rom(offset | offs_t(m_data_bank) << 11); +} + +u8 sawatte_state::prog_bank_r(offs_t offset) +{ + return m_cartslot->read_rom(offset | offs_t(m_prog_bank) << 12); +} + + +void sawatte_state::mem_map(address_map &map) +{ + map.global_mask(0x1fff); + map(0x0000, 0x0000).nopr(); + map(0x0008, 0x0008).w(FUNC(sawatte_state::bank08_w)); + map(0x0009, 0x0009).w(FUNC(sawatte_state::bank09_w)); + map(0x000a, 0x000a).w(FUNC(sawatte_state::bank0a_w)); + map(0x0011, 0x0011).portr("IN1"); + map(0x0012, 0x0012).portr("IN2"); + map(0x0016, 0x0016).nopr(); + map(0x0017, 0x0017).r(FUNC(sawatte_state::irq_status_r)); + map(0x0020, 0x0020).nopw(); // matrix scanning? + map(0x0022, 0x0022).nopw(); // matrix scanning? + map(0x0026, 0x0026).w(FUNC(sawatte_state::irq3_timer_w)); + map(0x0027, 0x0027).w(FUNC(sawatte_state::irq_mask_w)); + map(0x002f, 0x002f).w(FUNC(sawatte_state::irq4_timer_w)); + map(0x0060, 0x007f).ram(); + map(0x0080, 0x009f).ram().share("soundram"); + map(0x00a0, 0x01ff).ram(); // might not all exist + map(0x0200, 0x07ff).r(FUNC(sawatte_state::fixed_r)); + map(0x0800, 0x0fff).r(FUNC(sawatte_state::data_bank_r)); + map(0x1000, 0x1fff).r(FUNC(sawatte_state::prog_bank_r)); +} + static INPUT_PORTS_START( sawatte ) + PORT_START("IN1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON2) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON3) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON4) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON5) + + PORT_START("IN2") + PORT_BIT(0x1f, IP_ACTIVE_HIGH, IPT_UNKNOWN) // matrix inputs? + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON6) INPUT_PORTS_END void sawatte_state::sawatte(machine_config &config) { + M6502(config, m_maincpu, 4'000'000); // could be some stock SoC, type and clock unknown + m_maincpu->set_addrmap(AS_PROGRAM, &sawatte_state::mem_map); + + GENERIC_CARTSLOT(config, m_cartslot, generic_plain_slot, "sawatte_cart"); SOFTWARE_LIST(config, "cart_list").set_original("sawatte"); } diff --git a/src/mame/machine/microtan.cpp b/src/mame/machine/microtan.cpp index aa5a3c0f815..fa68bcdecc3 100644 --- a/src/mame/machine/microtan.cpp +++ b/src/mame/machine/microtan.cpp @@ -24,73 +24,73 @@ static const char keyboard[8][9][8] = { { /* normal */ { 27,'1','2','3','4','5','6','7'}, - {'8','9','0','-','=','`',127, 9}, + {'8','9','0',':','-', 12,127,'^'}, {'q','w','e','r','t','y','u','i'}, - {'o','p','[',']', 13,127, 0, 0}, + {'o','p','[',']', 13, 3, 0, 0}, {'a','s','d','f','g','h','j','k'}, - {'l',';', 39, 92, 0,'z','x','c'}, + {'l',';','@', 92, 0,'z','x','c'}, {'v','b','n','m',',','.','/', 0}, { 10,' ','-',',', 13,'.','0','1'}, {'2','3','4','5','6','7','8','9'}, }, { /* Shift */ - { 27,'!','@','#','$','%','^','&'}, - {'*','(',')','_','+','~',127, 9}, + { 27,'!','"','#','$','%','&', 39}, + {'(',')','~','*','=', 12,127,'_'}, {'Q','W','E','R','T','Y','U','I'}, - {'O','P','{','}', 13,127, 0, 0}, + {'O','P','{','}', 13, 3, 0, 0}, {'A','S','D','F','G','H','J','K'}, - {'L',':','"','|', 0,'Z','X','C'}, + {'L','+','`','|', 0,'Z','X','C'}, {'V','B','N','M','<','>','?', 0}, { 10,' ','-',',', 13,'.','0','1'}, {'2','3','4','5','6','7','8','9'}, }, { /* Control */ { 27,'1','2','3','4','5','6','7'}, - {'8','9','0','-','=','`',127, 9}, + {'8','9','0',':','-','`',127, 30}, { 17, 23, 5, 18, 20, 25, 21, 9}, - { 15, 16, 27, 29, 13,127, 0, 0}, + { 15, 16, 27, 29, 13, 3, 0, 0}, { 1, 19, 4, 6, 7, 8, 10, 11}, - { 12,';', 39, 28, 0, 26, 24, 3}, + { 12,';','@', 28, 0, 26, 24, 3}, { 22, 2, 14, 13,',','.','/', 0}, { 10,' ','-',',', 13,'.','0','1'}, {'2','3','4','5','6','7','8','9'}, }, { /* Shift+Control */ - { 27,'!', 0,'#','$','%', 30,'&'}, - {'*','(',')', 31,'+','~',127, 9}, + { 27,'!','"','#','$','%','&', 39}, + {'(',')','~','*','=', 12,127, 31}, { 17, 23, 5, 18, 20, 25, 21, 9}, { 15, 16, 27, 29, 13,127, 0, 0}, { 1, 19, 4, 6, 7, 8, 10, 11}, - { 12,':','"', 28, 0, 26, 24, 3}, + { 12,'+','`', 28, 0, 26, 24, 3}, { 22, 2, 14, 13,',','.','/', 0}, { 10,' ','-',',', 13,'.','0','1'}, {'2','3','4','5','6','7','8','9'}, }, { /* CapsLock */ { 27,'1','2','3','4','5','6','7'}, - {'8','9','0','-','=','`',127, 9}, + {'8','9','0',':','-', 12,127,'^'}, {'Q','W','E','R','T','Y','U','I'}, - {'O','P','[',']', 13,127, 0, 0}, + {'O','P','[',']', 13, 3, 0, 0}, {'A','S','D','F','G','H','J','K'}, - {'L',';', 39, 92, 0,'Z','X','C'}, + {'L',';','@', 92, 0,'Z','X','C'}, {'V','B','N','M',',','.','/', 0}, { 10,' ','-',',', 13,'.','0','1'}, {'2','3','4','5','6','7','8','9'}, }, { /* Shift+CapsLock */ - { 27,'!','@','#','$','%','^','&'}, - {'*','(',')','_','+','~',127, 9}, - {'Q','W','E','R','T','Y','U','I'}, - {'O','P','{','}', 13,127, 0, 0}, - {'A','S','D','F','G','H','J','K'}, - {'L',':','"','|', 0,'Z','X','C'}, - {'V','B','N','M','<','>','?', 0}, + { 27,'!','"','#','$','%','&', 39}, + {'(',')','~','*','=', 12,127,'_'}, + {'q','w','e','r','t','y','u','i'}, + {'o','p','{','}', 13, 3, 0, 0}, + {'a','s','d','f','g','h','j','k'}, + {'l','+','`','|', 0,'z','x','c'}, + {'v','b','n','m','<','>','?', 0}, { 10,' ','-',',', 13,'.','0','1'}, {'2','3','4','5','6','7','8','9'}, }, { /* Control+CapsLock */ { 27,'1','2','3','4','5','6','7'}, - {'8','9','0','-','=','`',127, 9}, + {'8','9','0',':','-', 12,127, 9}, { 17, 23, 5, 18, 20, 25, 21, 9}, { 15, 16, 27, 29, 13,127, 0, 0}, { 1, 19, 4, 6, 7, 8, 10, 11}, @@ -100,8 +100,8 @@ static const char keyboard[8][9][8] = { {'2','3','4','5','6','7','8','9'}, }, { /* Shift+Control+CapsLock */ - { 27,'!', 0,'#','$','%', 30,'&'}, - {'*','(',')', 31,'+','~',127, 9}, + { 27,'!','"','#','$','%','&', 39}, + {'(',')','~','*','=', 12,127, 9}, { 17, 23, 5, 18, 20, 25, 21, 9}, { 15, 16, 27, 29, 13,127, 0, 0}, { 1, 19, 4, 6, 7, 8, 10, 11}, @@ -149,11 +149,10 @@ uint8_t microtan_state::bffx_r(offs_t offset) break; case 1: /* Hex Keypad */ data = 0x00; - for (int i = 0; i < 4; i++) - { - if (m_keypad_column & (1 << i)) + for (u8 i = 0; i < 4; i++) + if (BIT(m_keypad_column, i)) data |= m_io_keypad[i]->read(); - } + break; case 2: /* ETI Keypad */ data = (m_keypad->read() & 0x1f) | (m_config->read() & 0x60); @@ -204,7 +203,7 @@ uint8_t mt6809_state::keyboard_r() m_keyboard_ascii = 0x00; return data; - } +} void mt6809_state::store_key(int key) { @@ -220,7 +219,7 @@ void microtan_state::store_key(int key) TIMER_DEVICE_CALLBACK_MEMBER(microtan_state::kbd_scan) { /* ASCII Keyboard only */ - if ((m_config->read() & 3) != 0) + if (m_config->read() & 3) return; int mod, row, col, chg, newvar; @@ -231,9 +230,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(microtan_state::kbd_scan) m_repeater = 4; } else if( m_repeater ) - { m_repeat = m_repeater; - } row = 9; newvar = m_io_keyboard[8]->read(); @@ -296,16 +293,13 @@ TIMER_DEVICE_CALLBACK_MEMBER(microtan_state::kbd_scan) m_keyrows[row] |= newvar; } else - { m_keyrows[row] = newvar; - } + m_repeat = m_repeater; } else if ( m_key && (m_keyrows[m_lastrow] & m_mask) && m_repeat == 0 ) - { store_key(m_key); - } } @@ -340,7 +334,7 @@ void microtan_state::init_gfx2() case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; } dst += 4; - switch ((i >> 2) & 3) + switch (BIT(i, 2, 2)) { case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; @@ -348,7 +342,7 @@ void microtan_state::init_gfx2() case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; } dst += 4; - switch ((i >> 4) & 3) + switch (BIT(i, 4, 2)) { case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; @@ -356,7 +350,7 @@ void microtan_state::init_gfx2() case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; } dst += 4; - switch ((i >> 6) & 3) + switch (BIT(i, 6, 2)) { case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; @@ -391,9 +385,8 @@ void microtan_state::machine_start() void microtan_state::machine_reset() { for (int i = 1; i < 10; i++) - { m_keyrows[i] = m_io_keyboard[i-1].read_safe(0); - } + m_led = BIT(~m_keyrows[3], 7); } @@ -439,26 +432,19 @@ image_init_result microtan_state::parse_intel_hex(uint8_t *snapshot_buff, char * &b[24], &b[25], &b[26], &b[27], &b[28], &b[29], &b[30], &b[31], &cs); if (n == 0) - { logerror("parse_intel_hex: malformed line [%s]\n", line); - } - else if (n == 1) - { + else + if (n == 1) logerror("parse_intel_hex: only size found [%s]\n", line); - } - else if (n == 2) - { + else + if (n == 2) logerror("parse_intel_hex: only size and addr found [%s]\n", line); - } - else if (n == 3) - { + else + if (n == 3) logerror("parse_intel_hex: only size, addr and null found [%s]\n", line); - } else if (null != 0) - { logerror("parse_intel_hex: warning null byte is != 0 [%s]\n", line); - } else { int i, sum; @@ -483,9 +469,8 @@ image_init_result microtan_state::parse_intel_hex(uint8_t *snapshot_buff, char * column = 0; } else - { line[column++] = *src; - } + src++; } /* register preset? */ @@ -520,19 +505,14 @@ image_init_result microtan_state::parse_zillion_hex(uint8_t *snapshot_buff, char /*row++;*/ n = sscanf(line, "%x %x %x %x %x %x %x %x %x", &addr, &b[0], &b[1], &b[2], &b[3], &b[4], &b[5], &b[6], &b[7]); if (n == 0) - { logerror("parse_zillion_hex: malformed line [%s]\n", line); - } - else if (n == 1) - { + else + if (n == 1) logerror("parse_zillion_hex: only addr found [%s]\n", line); - } else { - int i; - logerror("parse_zillion_hex: %04X", addr); - for (i = 0; i < n-1; i++) + for (int i = 0; i < n-1; i++) snapshot_buff[addr++] = b[i]; logerror("-%04X\n", addr-1); } @@ -540,9 +520,7 @@ image_init_result microtan_state::parse_zillion_hex(uint8_t *snapshot_buff, char column = 0; } else - { line[column++] = *src; - } } } else @@ -551,11 +529,11 @@ image_init_result microtan_state::parse_zillion_hex(uint8_t *snapshot_buff, char { if (column) { - int addr, n; + int addr; /*row++;*/ line[column] = '\0'; - n = sscanf(line, "G%x", (unsigned int *) &addr); + int n = sscanf(line, "G%x", (unsigned int *) &addr); if (n == 1 && !snapshot_buff[8192+64+0] && !snapshot_buff[8192+64+1]) { logerror("microtan_hexfile_init: go addr %04X\n", addr); @@ -566,9 +544,8 @@ image_init_result microtan_state::parse_zillion_hex(uint8_t *snapshot_buff, char column = 0; } else - { line[column++] = *src; - } + if (*src == '{') { parsing = 1; @@ -614,9 +591,8 @@ void microtan_state::snapshot_copy(uint8_t *snapshot_buff, int snapshot_size) base += 8192; /* 64 bytes of chunky graphics info */ for (int i = 0; i < 32*16; i++) - { m_chunky_buffer[i] = (snapshot_buff[base+i/8] >> (i&7)) & 1; - } + base += 64; set_cpu_regs(snapshot_buff, base); } @@ -681,9 +657,8 @@ void microtan_state::snapshot_copy(uint8_t *snapshot_buff, int snapshot_size) } for (int i = 0; i < 32*16; i++) - { m_chunky_buffer[i] = (snapshot_buff[base+i/8] >> (i&7)) & 1; - } + base += 64; set_cpu_regs(snapshot_buff, base); diff --git a/src/osd/modules/debugger/osx/debugwindowhandler.mm b/src/osd/modules/debugger/osx/debugwindowhandler.mm index fd1eb44f6d3..67910f92f99 100644 --- a/src/osd/modules/debugger/osx/debugwindowhandler.mm +++ b/src/osd/modules/debugger/osx/debugwindowhandler.mm @@ -493,7 +493,7 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo - (void)saveConfigurationToNode:(util::xml::data_node *)node { [super saveConfigurationToNode:node]; - node->add_child("expression", util::xml::normalize_string([[self expression] UTF8String])); + node->add_child("expression", [[self expression] UTF8String]); } diff --git a/src/osd/modules/render/bgfx/chain.cpp b/src/osd/modules/render/bgfx/chain.cpp index c5bb7cf94b6..297d7686837 100644 --- a/src/osd/modules/render/bgfx/chain.cpp +++ b/src/osd/modules/render/bgfx/chain.cpp @@ -81,7 +81,7 @@ void bgfx_chain::process(chain_manager::screen_prim &prim, int view, int screen, screen_device_iterator screen_iterator(window.machine().root_device()); screen_device* screen_device = screen_iterator.byindex(screen); - uint16_t screen_count(window.target()->current_view()->screen_count()); + uint16_t screen_count(window.target()->current_view().screen_count()); uint16_t screen_width = prim.m_quad_width; uint16_t screen_height = prim.m_quad_height; uint32_t rotation_type = diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index 9233aabc002..78e3e2f226f 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -2431,7 +2431,7 @@ void uniform::update() } case CU_SCREEN_COUNT: { - int screen_count = win->target()->current_view()->screen_count(); + int screen_count = win->target()->current_view().screen_count(); m_shader->set_int("ScreenCount", screen_count); break; } diff --git a/src/osd/uwp/window.cpp b/src/osd/uwp/window.cpp index 12c67308f22..7aae818b958 100644 --- a/src/osd/uwp/window.cpp +++ b/src/osd/uwp/window.cpp @@ -257,6 +257,7 @@ uwp_window_info::uwp_window_info( m_target(nullptr), m_targetview(0), m_targetorient(0), + m_targetvismask(0), m_lastclicktime(std::chrono::system_clock::time_point::min()), m_lastclickx(0), m_lastclicky(0), @@ -403,6 +404,7 @@ void uwp_window_info::create(running_machine &machine, int index, std::shared_pt window->m_targetview = window->m_target->view(); window->m_targetorient = window->m_target->orientation(); window->m_targetlayerconfig = window->m_target->layer_config(); + window->m_targetvismask = window->m_target->visibility_mask(); // make the window title if (video_config.numscreens == 1) @@ -472,20 +474,19 @@ void uwp_window_info::destroy() void uwp_window_info::update() { - int targetview, targetorient; - render_layer_config targetlayerconfig; - assert(GetCurrentThreadId() == main_threadid); // see if the target has changed significantly in window mode - targetview = m_target->view(); - targetorient = m_target->orientation(); - targetlayerconfig = m_target->layer_config(); - if (targetview != m_targetview || targetorient != m_targetorient || targetlayerconfig != m_targetlayerconfig) + unsigned const targetview = m_target->view(); + int const targetorient = m_target->orientation(); + render_layer_config const targetlayerconfig = m_target->layer_config(); + u32 const targetvismask = m_target->visibility_mask(); + if (targetview != m_targetview || targetorient != m_targetorient || targetlayerconfig != m_targetlayerconfig || targetvismask != m_targetvismask) { m_targetview = targetview; m_targetorient = targetorient; m_targetlayerconfig = targetlayerconfig; + m_targetvismask = targetvismask; // in window mode, reminimize/maximize if (!fullscreen()) diff --git a/src/osd/uwp/window.h b/src/osd/uwp/window.h index 21948028343..a58a163284e 100644 --- a/src/osd/uwp/window.h +++ b/src/osd/uwp/window.h @@ -101,9 +101,10 @@ public: // rendering info std::mutex m_render_lock; render_target * m_target; - int m_targetview; + unsigned m_targetview; int m_targetorient; render_layer_config m_targetlayerconfig; + u32 m_targetvismask; // input info std::chrono::system_clock::time_point m_lastclicktime; diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp index 8e6d3665e82..ac4349cf36b 100644 --- a/src/osd/windows/window.cpp +++ b/src/osd/windows/window.cpp @@ -312,6 +312,7 @@ win_window_info::win_window_info( m_target(nullptr), m_targetview(0), m_targetorient(0), + m_targetvismask(0), m_lastclicktime(std::chrono::system_clock::time_point::min()), m_lastclickx(0), m_lastclicky(0), @@ -790,6 +791,7 @@ void win_window_info::create(running_machine &machine, int index, std::shared_pt window->m_targetview = window->m_target->view(); window->m_targetorient = window->m_target->orientation(); window->m_targetlayerconfig = window->m_target->layer_config(); + window->m_targetvismask = window->m_target->visibility_mask(); // make the window title if (video_config.numscreens == 1) @@ -859,20 +861,19 @@ void win_window_info::destroy() void win_window_info::update() { - int targetview, targetorient; - render_layer_config targetlayerconfig; - assert(GetCurrentThreadId() == main_threadid); // see if the target has changed significantly in window mode - targetview = m_target->view(); - targetorient = m_target->orientation(); - targetlayerconfig = m_target->layer_config(); - if (targetview != m_targetview || targetorient != m_targetorient || targetlayerconfig != m_targetlayerconfig) + unsigned const targetview = m_target->view(); + int const targetorient = m_target->orientation(); + render_layer_config const targetlayerconfig = m_target->layer_config(); + u32 const targetvismask = m_target->visibility_mask(); + if (targetview != m_targetview || targetorient != m_targetorient || targetlayerconfig != m_targetlayerconfig || targetvismask != m_targetvismask) { m_targetview = targetview; m_targetorient = targetorient; m_targetlayerconfig = targetlayerconfig; + m_targetvismask = targetvismask; // in window mode, reminimize/maximize if (!fullscreen()) diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h index b04e35aa110..3dccc520a83 100644 --- a/src/osd/windows/window.h +++ b/src/osd/windows/window.h @@ -122,9 +122,10 @@ public: // rendering info std::mutex m_render_lock; render_target * m_target; - int m_targetview; + unsigned m_targetview; int m_targetorient; render_layer_config m_targetlayerconfig; + u32 m_targetvismask; // input info std::chrono::system_clock::time_point m_lastclicktime; |