From fe9ac15ca9f027d0eb5e21aa5496e3d6fa674e45 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 13 Nov 2020 15:26:31 +1100 Subject: =?UTF-8?q?-emu/devfind:=20More=20cleanup/consistency=20changes.?= =?UTF-8?q?=20=20*=20Removed=20.mask(),=20as=20it=E2=80=99s=20not=20reliab?= =?UTF-8?q?le=20in=20the=20general=20case.=20=20*=20Added=20asserts=20to?= =?UTF-8?q?=20things=20that=20assume=20power-of-two=20sizes.=20=20*=20Got?= =?UTF-8?q?=20rid=20of=20virtual=20qualifier=20on=20pointer-to-member=20op?= =?UTF-8?q?erator.=20=20*=20Made=20helpers=20a=20bit=20more=20assertive=20?= =?UTF-8?q?about=20logging=20warnings.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -emu/rendlay.cpp: Use delegates to avoid hot conditional branches. -docs: Finished off description of object finders and output finders. --- docs/source/techspecs/object_finders.rst | 375 ++++++++++++++++++++++++++++- scripts/minimaws/lib/wsgiserve.py | 224 ++++++++--------- src/devices/machine/tc009xlvc.cpp | 3 + src/devices/machine/tc009xlvc.h | 2 +- src/devices/sound/k007232.cpp | 7 +- src/devices/sound/k007232.h | 2 +- src/devices/sound/l7a1045_l6028_dsp_a.cpp | 41 ++-- src/devices/sound/l7a1045_l6028_dsp_a.h | 2 +- src/devices/sound/tc8830f.cpp | 13 +- src/devices/video/ef9364.cpp | 5 +- src/emu/devfind.cpp | 10 +- src/emu/devfind.h | 68 +++--- src/emu/render.h | 32 ++- src/emu/rendlay.cpp | 194 +++++++++------ src/mame/audio/taito_en.cpp | 5 +- src/mame/drivers/5clown.cpp | 19 +- src/mame/drivers/am1000.cpp | 7 +- src/mame/drivers/coolpool.cpp | 28 +-- src/mame/drivers/f1gp.cpp | 60 ++--- src/mame/drivers/gunpey.cpp | 289 +++++++++++----------- src/mame/drivers/m68705prg.cpp | 2 +- src/mame/drivers/metlfrzr.cpp | 7 +- src/mame/drivers/mmd2.cpp | 29 +-- src/mame/drivers/psikyo.cpp | 3 + src/mame/drivers/qvt70.cpp | 10 +- src/mame/drivers/tvboy.cpp | 2 +- src/mame/drivers/usgames.cpp | 8 +- src/mame/includes/coolpool.h | 34 ++- src/mame/machine/nb1412m2.cpp | 5 +- src/mame/video/artmagic.cpp | 7 +- src/mame/video/dcheese.cpp | 19 +- src/mame/video/homedata.cpp | 8 +- src/mame/video/k051316.cpp | 5 +- src/mame/video/k051960.cpp | 5 +- src/mame/video/k052109.cpp | 5 +- src/mame/video/k053244_k053245.cpp | 5 +- src/mame/video/k053246_k053247_k055673.cpp | 8 +- src/mame/video/k053246_k053247_k055673.h | 45 ++-- src/mame/video/pastelg.cpp | 5 +- src/mame/video/pgm.cpp | 22 +- src/mame/video/pgm2.cpp | 16 +- src/mame/video/psikyo.cpp | 4 +- src/mame/video/rltennis.cpp | 5 +- src/mame/video/usgames.cpp | 5 +- 44 files changed, 1074 insertions(+), 576 deletions(-) diff --git a/docs/source/techspecs/object_finders.rst b/docs/source/techspecs/object_finders.rst index 1acb475a7fa..2256d74b677 100644 --- a/docs/source/techspecs/object_finders.rst +++ b/docs/source/techspecs/object_finders.rst @@ -515,10 +515,10 @@ object finder to access it. We’ll use the Sega X-board device as an example: { } - optional_device m_soundcpu; - optional_device m_soundcpu2; - required_device m_watchdog; - required_device m_segaic16vid; + optional_device m_soundcpu; + optional_device m_soundcpu2; + required_device m_watchdog; + required_device m_segaic16vid; bool m_adc_reverse[8]; u8 m_pc_0; u8 m_lastsurv_mux; @@ -564,7 +564,7 @@ otherwise: return value; } - uint8_t segaxbd_state::lastsurv_port_r() + u8 segaxbd_state::lastsurv_port_r() { return m_mux_ports[m_lastsurv_mux].read_safe(0xff); } @@ -611,17 +611,17 @@ functions for configuring them: public: vboy_cart_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0U); - template void set_exp(T &&tag, int no, offs_t base) + template void set_exp(T &&tag, int no, offs_t base) { m_exp_space.set_tag(std::forward(tag), no); m_exp_base = base; } - template void set_chip(T &&tag, int no, offs_t base) + template void set_chip(T &&tag, int no, offs_t base) { m_chip_space.set_tag(std::forward(tag), no); m_chip_base = base; } - template void set_rom(T &&tag, int no, offs_t base) + template void set_rom(T &&tag, int no, offs_t base) { m_rom_space.set_tag(std::forward(tag), no); m_rom_base = base; @@ -638,7 +638,7 @@ functions for configuring them: offs_t m_chip_base; offs_t m_rom_base; - device_vboy_cart_interface *m_cart; + device_vboy_cart_interface *m_cart; }; DECLARE_DEVICE_TYPE(VBOY_CART_SLOT, vboy_cart_slot_device) @@ -680,3 +680,360 @@ have been configured but aren’t present: m_cart = get_card_device(); } + + +Object finder types in more detail +---------------------------------- + +All object finders provide configuration functionality: + +.. code-block:: C++ + + char const *finder_tag() const { return m_tag; } + std::pair finder_target(); + void set_tag(device_t &base, char const *tag); + void set_tag(char const *tag); + void set_tag(finder_base const &finder); + +The ``finder_tag`` and ``finder_target`` member function provides access to the +currently configured target. Note that the tag returned by ``finder`` tag is +relative to the base device. It is not sufficient on its own to identify the +target. + +The ``set_tag`` member functions configure the target of the object finder. +These members must not be called after the object finder is resolved. The first +form configures the base device and relative tag. The second form sets the +relative tag and also implicitly sets the base device to the device that is +currently being configured. This form must only be called from machine +configuration functions. The third form sets the base object and relative tag +to the current target of another object finder. + +Note that the ``set_tag`` member functions **do not** copy the relative tag. It +is the caller’s responsibility to ensure the C string remains valid until the +object finder is resolved (or reconfigured with a different tag). The base +device must also be valid at resolution time. This may not be the case if the +device could be removed or replaced later. + +All object finders provide the same interface for accessing the target object: + +.. code-block:: C++ + + ObjectClass *target() const; + operator ObjectClass *() const; + ObjectClass *operator->() const; + +These members all provide access to the target object. The ``target`` member +function and cast-to-pointer operator will return ``nullptr`` if the target has +not been found. The pointer member access operator asserts that the target has +been found. + +Optional object finders additionally provide members for testing whether the +target object has been found: + +.. code-block:: C++ + + bool found() const; + explicit operator bool() const; + +These members return ``true`` if the target was found, on the assumption +that the target pointer will be non-null if the target was found. + +Device finders +~~~~~~~~~~~~~~ + +Device finders require one template argument for the expected device class. +This should derive from either ``device_t`` or ``device_interface``. The target +device object must either be an instance of this class, an instance of a class +that derives from it. A warning message is logged if a matching device is found +but it is not an instance of the expected class. + +Device finders provide an additional ``set_tag`` overload: + +.. code-block:: C++ + + set_tag(DeviceClass &object); + +This is equivalent to calling ``set_tag(object, DEVICE_SELF)``. Note that the +device object must not be removed or replaced before the object finder is +resolved. + +Memory system object finders +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The memory system object finders, ``required_memory_region``, +``optional_memory_region``, ``required_memory_bank``, ``optional_memory_bank`` +and ``memory_bank_creator``, do not have any special functionality. They are +often used in place of literal tags when installing memory banks in an address +space. + +Example using memory bank finders in an address map: + +.. code-block:: C++ + + class qvt70_state : public driver_device + { + public: + qvt70_state(machine_config const &mconfig, device_type type, char const *tag) : + driver_device(mconfig, type, tag), + m_rombank(*this, "rom"), + m_rambank(*this, "ram%d", 0U), + { } + + private: + required_memory_bank m_rombank; + required_memory_bank_array<2> m_rambank; + + void mem_map(address_map &map); + + void rombank_w(u8 data); + }; + + void qvt70_state::mem_map(address_map &map) + { + map(0x0000, 0x7fff).bankr(m_rombank); + map(0x8000, 0x8000).w(FUNC(qvt70_state::rombank_w)); + map(0xa000, 0xbfff).ram(); + map(0xc000, 0xdfff).bankrw(m_rambank[0]); + map(0xe000, 0xffff).bankrw(m_rambank[1]); + } + +Example using a memory bank creator to install a memory bank dynamically: + +.. code-block:: C++ + + class vegaeo_state : public eolith_state + { + public: + vegaeo_state(machine_config const &mconfig, device_type type, char const *tag) : + eolith_state(mconfig, type, tag), + m_qs1000_bank(*this, "qs1000_bank") + { + } + + void init_vegaeo(); + + private: + memory_bank_creator m_qs1000_bank; + }; + + void vegaeo_state::init_vegaeo() + { + // Set up the QS1000 program ROM banking, taking care not to overlap the internal RAM + m_qs1000->cpu().space(AS_IO).install_read_bank(0x0100, 0xffff, m_qs1000_bank); + m_qs1000_bank->configure_entries(0, 8, memregion("qs1000:cpu")->base() + 0x100, 0x10000); + + init_speedup(); + } + +I/O port finders +~~~~~~~~~~~~~~~~ + +Optional I/O port finders provide an additional convenience member function: + +.. code-block:: C++ + + ioport_value read_safe(ioport_value defval); + +This will read the port’s value if the target I/O port was found, or return +``defval`` otherwise. It is useful in situations where certain input devices +are not always present. + + +Address space finders +~~~~~~~~~~~~~~~~~~~~~ + +Address space finders accept an additional argument for the address space number +to find. A required data width can optionally be supplied to the constructor. + +.. code-block:: C++ + + address_space_finder(device_t &base, char const *tag, int spacenum, u8 width = 0); + void set_tag(device_t &base, char const *tag, int spacenum); + void set_tag(char const *tag, int spacenum); + void set_tag(finder_base const &finder, int spacenum); + template void set_tag(address_space_finder const &finder); + +The base device and tag must identify a device that implements +``device_memory_interface``. The address space number is a zero-based index to +one of the device’s address spaces. + +If the width is non-zero, it must match the target address space’s data width in +bits. If the target address space exists but has a different data width, a +warning message will be logged, and it will be treated as not being found. If +the width is zero (the default argument value), the target address space’s data +width won’t be checked. + +Member functions are also provided to get the configured address space number +and set the required data width: + +.. code-block:: C++ + + int spacenum() const; + void set_data_width(u8 width); + +Memory pointer finders +~~~~~~~~~~~~~~~~~~~~~~ + +The memory pointer finders, ``required_region_ptr``, ``optional_region_ptr``, +``required_shared_ptr``, ``optional_shared_ptr`` and ``memory_share_creator``, +all require one template argument for the element type of the memory area. This +should usually be an explicitly-sized unsigned integer type (``u8``, ``u16``, +``u32`` or ``u64``). The size of this type is compared to the width of the +memory area. If it doesn’t match, a warning message is logged and the region or +share is treated as not being found. + +The memory pointer finders provide an array access operator, and members for +accessing the size of the memory area: + +.. code-block:: C++ + + PointerType &operator[](int index) const; + size_t length() const; + size_t bytes() const; + +The array access operator returns a non-\ ``const`` reference to an element of +the memory area. The index is in units of the element type; it must be +non-negative and less than the length of the memory area. The ``length`` member +returns the number of elements in the memory area. The ``bytes`` member returns +the size of the memory area in bytes. These members should not be called if the +target region/share has not been found. + +The ``memory_share_creator`` requires additional constructor arguments for the +size and Endianness of the memory share: + +.. code-block:: C++ + + memory_share_creator(device_t &base, char const *tag, size_t bytes, endianness_t endianness); + +The size is specified in bytes. If an existing memory share is found, it is an +error if its size does not match the specified size. If the width is wider than +eight bits and an existing memory share is found, it is an error if its +Endianness does not match the specified Endianness. + +The ``memory_share_creator`` provides additional members for accessing +properties of the memory share: + +.. code-block:: C++ + + endianness_t endianness() const; + u8 bitwidth() const; + u8 bytewidth() const; + +These members return the Endianness, width in bits and width in bytes of the +memory share, respectively. They must not be called if the memory share has not +been found. + + +Output finders +-------------- + +Output finders are used for exposing outputs that can be used by the artwork +system, or by external programs. A common application using an external program +is a control panel or cabinet lighting controller. + +Output finders are not really object finders, but they’re described here because +they’re used in a similar way. There are a number of important differences to +be aware of: + +* Output finders always create outputs if they do not exist. +* Output finders must be manually resolved, they are not automatically resolved. +* Output finders cannot have their target changed after construction. +* Output finders are array-like, and support an arbitrary number of dimensions. +* Output names are global, the base device has no influence. (This will change + in the future.) + +Output finders take a variable number of template arguments corresponding to the +number of array dimensions you want. Let’s look at an example that uses zero-, +one- and two-dimensional output finders: + +.. code-block:: C++ + + class mmd2_state : public driver_device + { + public: + mmd2_state(machine_config const &mconfig, device_type type, char const *tag) : + driver_device(mconfig, type, tag), + m_digits(*this, "digit%u", 0U), + m_p(*this, "p%u_%u", 0U, 0U), + m_led_halt(*this, "led_halt"), + m_led_hold(*this, "led_hold") + { } + + protected: + virtual void machine_start() override; + + private: + void round_leds_w(offs_t, u8); + void digit_w(u8 data); + void status_callback(u8 data); + + u8 m_digit; + + output_finder<9> m_digits; + output_finder<3, 8> m_p; + output_finder<> m_led_halt; + output_finder<> m_led_hold; + }; + +The ``m_led_halt`` and ``m_led_hold`` members are zero-dimensional output +finders. They find a single output each. The ``m_digits`` member is a +one-dimensional output finder. It finds nine outputs organised as a +single-dimensional array. The ``m_p`` member is a two-dimensional output +finder. It finds 24 outputs organised as three rows of eight columns each. +Larger numbers of dimensions are supported. + +The output finder constructor takes a base device reference, a format string, +and an index offset for each dimension. In this case, all the offsets are +zero. The one-dimensional output finder ``m_digits`` will find outputs +``digit0``, ``digit1``, ``digit2``, … ``digit8``. The two-dimensional output +finder ``m_p`` will find the outputs ``p0_0``, ``p0_1``, … ``p0_7`` for the +first row, ``p1_0``, ``p1_1``, … ``p1_7`` for the second row, and ``p2_0``, +``p2_1``, … ``p2_7`` for the third row. + +You must call ``resolve`` on each output finder before it can be used. This +should be done at start time for the output values to be included in save +states: + +.. code-block:: C++ + + void mmd2_state::machine_start() + { + m_digits.resolve(); + m_p.resolve(); + m_led_halt.resolve(); + m_led_hold.resolve(); + + save_item(NAME(m_digit)); + } + +Output finders provide operators allowing them to be assigned from or cast to +32-bit signed integers. The assignment operator will send a notification if the +new value is different to the output’s current value. + +.. code-block:: C++ + + operator s32() const; + s32 operator=(s32 value); + +To set output values, assign through the output finders, as you would with an +array of the same rank: + +.. code-block:: C++ + + void mmd2_state::round_leds_w(offs_t offset, u8 data) + { + for (u8 i = 0; i < 8; i++) + m_p[offset][i] = BIT(~data, i); + } + + void mmd2_state::digit_w(u8 data) + { + if (m_digit < 9) + m_digits[m_digit] = data; + } + + void mmd2_state::status_callback(u8 data) + { + m_led_halt = (~data & i8080_cpu_device::STATUS_HLTA) ? 1 : 0; + m_led_hold = (data & i8080_cpu_device::STATUS_WO) ? 1 : 0; + } diff --git a/scripts/minimaws/lib/wsgiserve.py b/scripts/minimaws/lib/wsgiserve.py index e77bb3f637f..f1ddc5df220 100644 --- a/scripts/minimaws/lib/wsgiserve.py +++ b/scripts/minimaws/lib/wsgiserve.py @@ -16,10 +16,16 @@ import sys import urllib import wsgiref.util -if sys.version_info >= (3, ): +if hasattr(cgi, 'escape'): + htmlescape = cgi.escape +else: + import html + htmlescape = html.escape + +try: import urllib.parse as urlparse urlquote = urlparse.quote -else: +except ImportError: import urlparse urlquote = urllib.quote @@ -47,7 +53,7 @@ class HandlerBase(object): self.start_response = start_response def error_page(self, code): - yield htmltmpl.ERROR_PAGE.substitute(code=cgi.escape('%d' % (code, )), message=cgi.escape(self.STATUS_MESSAGE[code])).encode('utf-8') + yield htmltmpl.ERROR_PAGE.substitute(code=htmlescape('%d' % (code, )), message=htmlescape(self.STATUS_MESSAGE[code])).encode('utf-8') class ErrorPageHandler(HandlerBase): @@ -98,16 +104,16 @@ class QueryPageHandler(HandlerBase): self.dbcurs = app.dbconn.cursor() def machine_href(self, shortname): - return cgi.escape(urlparse.urljoin(self.application_uri, 'machine/%s' % (urlquote(shortname), )), True) + return htmlescape(urlparse.urljoin(self.application_uri, 'machine/%s' % (urlquote(shortname), )), True) def sourcefile_href(self, sourcefile): - return cgi.escape(urlparse.urljoin(self.application_uri, 'sourcefile/%s' % (urlquote(sourcefile), )), True) + return htmlescape(urlparse.urljoin(self.application_uri, 'sourcefile/%s' % (urlquote(sourcefile), )), True) def softwarelist_href(self, softwarelist): - return cgi.escape(urlparse.urljoin(self.application_uri, 'softwarelist/%s' % (urlquote(softwarelist), )), True) + return htmlescape(urlparse.urljoin(self.application_uri, 'softwarelist/%s' % (urlquote(softwarelist), )), True) def software_href(self, softwarelist, software): - return cgi.escape(urlparse.urljoin(self.application_uri, 'softwarelist/%s/%s' % (urlquote(softwarelist), urlquote(software))), True) + return htmlescape(urlparse.urljoin(self.application_uri, 'softwarelist/%s/%s' % (urlquote(softwarelist), urlquote(software))), True) def bios_data(self, machine): result = { } @@ -238,39 +244,39 @@ class MachineHandler(QueryPageHandler): id = machine_info['id'] description = machine_info['description'] yield htmltmpl.MACHINE_PROLOGUE.substitute( - app=self.js_escape(cgi.escape(self.application_uri, True)), - assets=self.js_escape(cgi.escape(urlparse.urljoin(self.application_uri, 'static'), True)), + app=self.js_escape(htmlescape(self.application_uri, True)), + assets=self.js_escape(htmlescape(urlparse.urljoin(self.application_uri, 'static'), True)), sourcehref=self.sourcefile_href(machine_info['sourcefile']), - description=cgi.escape(description), - shortname=cgi.escape(self.shortname), - isdevice=cgi.escape('Yes' if machine_info['isdevice'] else 'No'), - runnable=cgi.escape('Yes' if machine_info['runnable'] else 'No'), - sourcefile=cgi.escape(machine_info['sourcefile'])).encode('utf-8') + description=htmlescape(description), + shortname=htmlescape(self.shortname), + isdevice=htmlescape('Yes' if machine_info['isdevice'] else 'No'), + runnable=htmlescape('Yes' if machine_info['runnable'] else 'No'), + sourcefile=htmlescape(machine_info['sourcefile'])).encode('utf-8') if machine_info['year'] is not None: yield ( ' Year:%s\n' \ ' Manufacturer:%s\n' % - (cgi.escape(machine_info['year']), cgi.escape(machine_info['Manufacturer']))).encode('utf-8') + (htmlescape(machine_info['year']), htmlescape(machine_info['Manufacturer']))).encode('utf-8') if machine_info['cloneof'] is not None: parent = self.dbcurs.listfull(machine_info['cloneof']).fetchone() if parent: yield ( ' Parent machine:%s (%s)\n' % - (self.machine_href(machine_info['cloneof']), cgi.escape(parent[1]), cgi.escape(machine_info['cloneof']))).encode('utf-8') + (self.machine_href(machine_info['cloneof']), htmlescape(parent[1]), htmlescape(machine_info['cloneof']))).encode('utf-8') else: yield ( ' Parent machine:%s\n' % - (self.machine_href(machine_info['cloneof']), cgi.escape(machine_info['cloneof']))).encode('utf-8') + (self.machine_href(machine_info['cloneof']), htmlescape(machine_info['cloneof']))).encode('utf-8') if (machine_info['romof'] is not None) and (machine_info['romof'] != machine_info['cloneof']): parent = self.dbcurs.listfull(machine_info['romof']).fetchone() if parent: yield ( ' Parent ROM set:%s (%s)\n' % - (self.machine_href(machine_info['romof']), cgi.escape(parent[1]), cgi.escape(machine_info['romof']))).encode('utf-8') + (self.machine_href(machine_info['romof']), htmlescape(parent[1]), htmlescape(machine_info['romof']))).encode('utf-8') else: yield ( ' Parent machine:%s\n' % - (self.machine_href(machine_info['romof']), cgi.escape(machine_info['romof']))).encode('utf-8') + (self.machine_href(machine_info['romof']), htmlescape(machine_info['romof']))).encode('utf-8') unemulated = [] imperfect = [] for feature, status, overall in self.dbcurs.get_feature_flags(id): @@ -297,10 +303,10 @@ class MachineHandler(QueryPageHandler): first = False yield htmltmpl.MACHINE_CLONES_ROW.substitute( href=self.machine_href(clone), - shortname=cgi.escape(clone), - description=cgi.escape(clonedescription), - year=cgi.escape(cloneyear or ''), - manufacturer=cgi.escape(clonemanufacturer or '')).encode('utf-8') + shortname=htmlescape(clone), + description=htmlescape(clonedescription), + year=htmlescape(cloneyear or ''), + manufacturer=htmlescape(clonemanufacturer or '')).encode('utf-8') if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-clones').encode('utf-8') @@ -309,15 +315,15 @@ class MachineHandler(QueryPageHandler): for softwarelist in self.dbcurs.get_machine_softwarelists(id): total = softwarelist['total'] yield htmltmpl.MACHINE_SOFTWARELISTS_TABLE_ROW.substitute( - rowid=cgi.escape(softwarelist['tag'].replace(':', '-'), True), + rowid=htmlescape(softwarelist['tag'].replace(':', '-'), True), href=self.softwarelist_href(softwarelist['shortname']), - shortname=cgi.escape(softwarelist['shortname']), - description=cgi.escape(softwarelist['description']), - status=cgi.escape(softwarelist['status']), - total=cgi.escape('%d' % (total, )), - supported=cgi.escape('%.1f%%' % (softwarelist['supported'] * 100.0 / (total or 1), )), - partiallysupported=cgi.escape('%.1f%%' % (softwarelist['partiallysupported'] * 100.0 / (total or 1), )), - unsupported=cgi.escape('%.1f%%' % (softwarelist['unsupported'] * 100.0 / (total or 1), ))).encode('utf-8') + shortname=htmlescape(softwarelist['shortname']), + description=htmlescape(softwarelist['description']), + status=htmlescape(softwarelist['status']), + total=htmlescape('%d' % (total, )), + supported=htmlescape('%.1f%%' % (softwarelist['supported'] * 100.0 / (total or 1), )), + partiallysupported=htmlescape('%.1f%%' % (softwarelist['partiallysupported'] * 100.0 / (total or 1), )), + unsupported=htmlescape('%.1f%%' % (softwarelist['unsupported'] * 100.0 / (total or 1), ))).encode('utf-8') yield htmltmpl.MACHINE_SOFTWARELISTS_TABLE_EPILOGUE.substitute().encode('utf-8') # allow system BIOS selection @@ -328,8 +334,8 @@ class MachineHandler(QueryPageHandler): yield htmltmpl.MACHINE_OPTIONS_HEADING.substitute().encode('utf-8') yield htmltmpl.MACHINE_BIOS_PROLOGUE.substitute().encode('utf-8') yield htmltmpl.MACHINE_BIOS_OPTION.substitute( - name=cgi.escape(name, True), - description=cgi.escape(desc), + name=htmlescape(name, True), + description=htmlescape(desc), isdefault=('yes' if isdef else 'no')).encode('utf-8') if haveoptions: yield '\n\n'.encode('utf-8') @@ -344,8 +350,8 @@ class MachineHandler(QueryPageHandler): yield htmltmpl.MACHINE_RAM_PROLOGUE.substitute().encode('utf-8') first = False yield htmltmpl.MACHINE_RAM_OPTION.substitute( - name=cgi.escape(name, True), - size=cgi.escape('{:,}'.format(size)), + name=htmlescape(name, True), + size=htmlescape('{:,}'.format(size)), isdefault=('yes' if isdef else 'no')).encode('utf-8') if not first: yield '\n\n'.encode('utf-8') @@ -410,11 +416,11 @@ class MachineHandler(QueryPageHandler): yield htmltmpl.COMPATIBLE_SLOT_ROW.substitute( machinehref=self.machine_href(name), sourcehref=self.sourcefile_href(src), - shortname=cgi.escape(name), - description=cgi.escape(desc), - sourcefile=cgi.escape(src), - slot=cgi.escape(slot), - slotoption=cgi.escape(opt)).encode('utf-8') + shortname=htmlescape(name), + description=htmlescape(desc), + sourcefile=htmlescape(src), + slot=htmlescape(slot), + slotoption=htmlescape(opt)).encode('utf-8') if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-comp-slots').encode('utf-8') @@ -440,9 +446,9 @@ class MachineHandler(QueryPageHandler): return (htmltmpl.MACHINE_ROW if description is not None else htmltmpl.EXCL_MACHINE_ROW).substitute( machinehref=self.machine_href(shortname), sourcehref=self.sourcefile_href(sourcefile), - shortname=cgi.escape(shortname), - description=cgi.escape(description or ''), - sourcefile=cgi.escape(sourcefile or '')).encode('utf-8') + shortname=htmlescape(shortname), + description=htmlescape(description or ''), + sourcefile=htmlescape(sourcefile or '')).encode('utf-8') @staticmethod def sanitised_json(data): @@ -493,21 +499,21 @@ class SourceFileHandler(QueryPageHandler): title = heading = 'All Source Files' else: heading = self.linked_title(pattern) - title = 'Source Files: ' + cgi.escape(pattern) + title = 'Source Files: ' + htmlescape(pattern) yield htmltmpl.SOURCEFILE_LIST_PROLOGUE.substitute( - assets=cgi.escape(urlparse.urljoin(self.application_uri, 'static'), True), + assets=htmlescape(urlparse.urljoin(self.application_uri, 'static'), True), title=title, heading=heading).encode('utf-8') for filename, machines in self.dbcurs.get_sourcefiles(pattern): yield htmltmpl.SOURCEFILE_LIST_ROW.substitute( sourcefile=self.linked_title(filename, True), - machines=cgi.escape('%d' % (machines, ))).encode('utf-8') + machines=htmlescape('%d' % (machines, ))).encode('utf-8') yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-sourcefiles').encode('utf-8') def sourcefile_page(self, id): yield htmltmpl.SOURCEFILE_PROLOGUE.substitute( - assets=cgi.escape(urlparse.urljoin(self.application_uri, 'static'), True), - filename=cgi.escape(self.filename), + assets=htmlescape(urlparse.urljoin(self.application_uri, 'static'), True), + filename=htmlescape(self.filename), title=self.linked_title(self.filename)).encode('utf-8') first = True @@ -543,10 +549,10 @@ class SourceFileHandler(QueryPageHandler): title = '' for part in parts: uri = urlparse.urljoin(uri + '/', urlquote(part)) - title += '{1}/'.format(cgi.escape(uri, True), cgi.escape(part)) + title += '{1}/'.format(htmlescape(uri, True), htmlescape(part)) if linkfinal: uri = urlparse.urljoin(uri + '/', urlquote(final)) - return title + '{1}'.format(cgi.escape(uri, True), cgi.escape(final)) + return title + '{1}'.format(htmlescape(uri, True), htmlescape(final)) else: return title + final @@ -554,12 +560,12 @@ class SourceFileHandler(QueryPageHandler): return (htmltmpl.SOURCEFILE_ROW_PARENT if machine_info['cloneof'] is None else htmltmpl.SOURCEFILE_ROW_CLONE).substitute( machinehref=self.machine_href(machine_info['shortname']), parenthref=self.machine_href(machine_info['cloneof'] or '__invalid'), - shortname=cgi.escape(machine_info['shortname']), - description=cgi.escape(machine_info['description']), - year=cgi.escape(machine_info['year'] or ''), - manufacturer=cgi.escape(machine_info['manufacturer'] or ''), - runnable=cgi.escape('Yes' if machine_info['runnable'] else 'No'), - parent=cgi.escape(machine_info['cloneof'] or '')).encode('utf-8') + shortname=htmlescape(machine_info['shortname']), + description=htmlescape(machine_info['description']), + year=htmlescape(machine_info['year'] or ''), + manufacturer=htmlescape(machine_info['manufacturer'] or ''), + runnable=htmlescape('Yes' if machine_info['runnable'] else 'No'), + parent=htmlescape(machine_info['cloneof'] or '')).encode('utf-8') class SoftwareListHandler(QueryPageHandler): @@ -606,41 +612,41 @@ class SoftwareListHandler(QueryPageHandler): if not pattern: title = heading = 'All Software Lists' else: - title = heading = 'Software Lists: ' + cgi.escape(pattern) + title = heading = 'Software Lists: ' + htmlescape(pattern) yield htmltmpl.SOFTWARELIST_LIST_PROLOGUE.substitute( - assets=cgi.escape(urlparse.urljoin(self.application_uri, 'static'), True), + assets=htmlescape(urlparse.urljoin(self.application_uri, 'static'), True), title=title, heading=heading).encode('utf-8') for shortname, description, total, supported, partiallysupported, unsupported in self.dbcurs.get_softwarelists(pattern): yield htmltmpl.SOFTWARELIST_LIST_ROW.substitute( href=self.softwarelist_href(shortname), - shortname=cgi.escape(shortname), - description=cgi.escape(description), - total=cgi.escape('%d' % (total, )), - supported=cgi.escape('%.1f%%' % (supported * 100.0 / (total or 1), )), - partiallysupported=cgi.escape('%.1f%%' % (partiallysupported * 100.0 / (total or 1), )), - unsupported=cgi.escape('%.1f%%' % (unsupported * 100.0 / (total or 1), ))).encode('utf-8') + shortname=htmlescape(shortname), + description=htmlescape(description), + total=htmlescape('%d' % (total, )), + supported=htmlescape('%.1f%%' % (supported * 100.0 / (total or 1), )), + partiallysupported=htmlescape('%.1f%%' % (partiallysupported * 100.0 / (total or 1), )), + unsupported=htmlescape('%.1f%%' % (unsupported * 100.0 / (total or 1), ))).encode('utf-8') yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-softwarelists').encode('utf-8') def softwarelist_page(self, softwarelist_info, pattern): if not pattern: - title = 'Software List: %s (%s)' % (cgi.escape(softwarelist_info['description']), cgi.escape(softwarelist_info['shortname'])) - heading = cgi.escape(softwarelist_info['description']) + title = 'Software List: %s (%s)' % (htmlescape(softwarelist_info['description']), htmlescape(softwarelist_info['shortname'])) + heading = htmlescape(softwarelist_info['description']) else: - title = 'Software List: %s (%s): %s' % (cgi.escape(softwarelist_info['description']), cgi.escape(softwarelist_info['shortname']), cgi.escape(pattern)) - heading = '%s: %s' % (self.softwarelist_href(softwarelist_info['shortname']), cgi.escape(softwarelist_info['description']), cgi.escape(pattern)) + title = 'Software List: %s (%s): %s' % (htmlescape(softwarelist_info['description']), htmlescape(softwarelist_info['shortname']), htmlescape(pattern)) + heading = '%s: %s' % (self.softwarelist_href(softwarelist_info['shortname']), htmlescape(softwarelist_info['description']), htmlescape(pattern)) yield htmltmpl.SOFTWARELIST_PROLOGUE.substitute( - assets=cgi.escape(urlparse.urljoin(self.application_uri, 'static'), True), + assets=htmlescape(urlparse.urljoin(self.application_uri, 'static'), True), title=title, heading=heading, - shortname=cgi.escape(softwarelist_info['shortname']), - total=cgi.escape('%d' % (softwarelist_info['total'], )), - supported=cgi.escape('%d' % (softwarelist_info['supported'], )), - supportedpc=cgi.escape('%.1f' % (softwarelist_info['supported'] * 100.0 / (softwarelist_info['total'] or 1), )), - partiallysupported=cgi.escape('%d' % (softwarelist_info['partiallysupported'], )), - partiallysupportedpc=cgi.escape('%.1f' % (softwarelist_info['partiallysupported'] * 100.0 / (softwarelist_info['total'] or 1), )), - unsupported=cgi.escape('%d' % (softwarelist_info['unsupported'], )), - unsupportedpc=cgi.escape('%.1f' % (softwarelist_info['unsupported'] * 100.0 / (softwarelist_info['total'] or 1), ))).encode('utf-8') + shortname=htmlescape(softwarelist_info['shortname']), + total=htmlescape('%d' % (softwarelist_info['total'], )), + supported=htmlescape('%d' % (softwarelist_info['supported'], )), + supportedpc=htmlescape('%.1f' % (softwarelist_info['supported'] * 100.0 / (softwarelist_info['total'] or 1), )), + partiallysupported=htmlescape('%d' % (softwarelist_info['partiallysupported'], )), + partiallysupportedpc=htmlescape('%.1f' % (softwarelist_info['partiallysupported'] * 100.0 / (softwarelist_info['total'] or 1), )), + unsupported=htmlescape('%d' % (softwarelist_info['unsupported'], )), + unsupportedpc=htmlescape('%.1f' % (softwarelist_info['unsupported'] * 100.0 / (softwarelist_info['total'] or 1), ))).encode('utf-8') first = True for machine_info in self.dbcurs.get_softwarelist_machines(softwarelist_info['id']): @@ -649,11 +655,11 @@ class SoftwareListHandler(QueryPageHandler): first = False yield htmltmpl.SOFTWARELIST_MACHINE_TABLE_ROW.substitute( machinehref=self.machine_href(machine_info['shortname']), - shortname=cgi.escape(machine_info['shortname']), - description=cgi.escape(machine_info['description']), - year=cgi.escape(machine_info['year'] or ''), - manufacturer=cgi.escape(machine_info['manufacturer'] or ''), - status=cgi.escape(machine_info['status'])).encode('utf-8') + shortname=htmlescape(machine_info['shortname']), + description=htmlescape(machine_info['description']), + year=htmlescape(machine_info['year'] or ''), + manufacturer=htmlescape(machine_info['manufacturer'] or ''), + status=htmlescape(machine_info['status'])).encode('utf-8') if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-machines').encode('utf-8') @@ -672,20 +678,20 @@ class SoftwareListHandler(QueryPageHandler): def software_page(self, software_info): yield htmltmpl.SOFTWARE_PROLOGUE.substitute( - assets=cgi.escape(urlparse.urljoin(self.application_uri, 'static'), True), - title=cgi.escape(software_info['description']), - heading=cgi.escape(software_info['description']), + assets=htmlescape(urlparse.urljoin(self.application_uri, 'static'), True), + title=htmlescape(software_info['description']), + heading=htmlescape(software_info['description']), softwarelisthref=self.softwarelist_href(self.shortname), - softwarelistdescription=cgi.escape(software_info['softwarelistdescription']), - softwarelist=cgi.escape(self.shortname), - shortname=cgi.escape(software_info['shortname']), - year=cgi.escape(software_info['year']), - publisher=cgi.escape(software_info['publisher'])).encode('utf-8') + softwarelistdescription=htmlescape(software_info['softwarelistdescription']), + softwarelist=htmlescape(self.shortname), + shortname=htmlescape(software_info['shortname']), + year=htmlescape(software_info['year']), + publisher=htmlescape(software_info['publisher'])).encode('utf-8') if software_info['parent'] is not None: - yield (' Parent:%s\n' % (self.software_href(software_info['parentsoftwarelist'], software_info['parent']), cgi.escape(software_info['parentdescription']))).encode('utf-8') + yield (' Parent:%s\n' % (self.software_href(software_info['parentsoftwarelist'], software_info['parent']), htmlescape(software_info['parentdescription']))).encode('utf-8') yield (' Supported:%s\n' % (self.format_supported(software_info['supported']), )).encode('utf-8') for name, value in self.dbcurs.get_software_info(software_info['id']): - yield (' %s:%s\n' % (cgi.escape(name), cgi.escape(value))).encode('utf-8') + yield (' %s:%s\n' % (htmlescape(name), htmlescape(value))).encode('utf-8') yield '\n\n'.encode('utf-8') first = True @@ -704,11 +710,11 @@ class SoftwareListHandler(QueryPageHandler): yield '

Parts

\n'.encode('utf-8') first = False yield htmltmpl.SOFTWARE_PART_PROLOGUE.substitute( - heading=cgi.escape(('%s (%s)' % (part_id, partname)) if part_id is not None else partname), - shortname=cgi.escape(partname), - interface=cgi.escape(interface)).encode('utf-8') + heading=htmlescape(('%s (%s)' % (part_id, partname)) if part_id is not None else partname), + shortname=htmlescape(partname), + interface=htmlescape(interface)).encode('utf-8') for name, value in self.dbcurs.get_softwarepart_features(id): - yield (' %s:%s\n' % (cgi.escape(name), cgi.escape(value))).encode('utf-8') + yield (' %s:%s\n' % (htmlescape(name), htmlescape(value))).encode('utf-8') yield '\n\n'.encode('utf-8') yield '\n\n'.encode('utf-8') @@ -717,22 +723,22 @@ class SoftwareListHandler(QueryPageHandler): parent = software_info['parent'] return htmltmpl.SOFTWARELIST_SOFTWARE_ROW.substitute( softwarehref=self.software_href(self.shortname, software_info['shortname']), - shortname=cgi.escape(software_info['shortname']), - description=cgi.escape(software_info['description']), - year=cgi.escape(software_info['year']), - publisher=cgi.escape(software_info['publisher']), + shortname=htmlescape(software_info['shortname']), + description=htmlescape(software_info['description']), + year=htmlescape(software_info['year']), + publisher=htmlescape(software_info['publisher']), supported=self.format_supported(software_info['supported']), - parts=cgi.escape('%d' % (software_info['parts'], )), - baddumps=cgi.escape('%d' % (software_info['baddumps'], )), - parent='%s' % (self.software_href(software_info['parentsoftwarelist'], parent), cgi.escape(parent)) if parent is not None else '').encode('utf-8') + parts=htmlescape('%d' % (software_info['parts'], )), + baddumps=htmlescape('%d' % (software_info['baddumps'], )), + parent='%s' % (self.software_href(software_info['parentsoftwarelist'], parent), htmlescape(parent)) if parent is not None else '').encode('utf-8') def clone_row(self, clone_info): return htmltmpl.SOFTWARE_CLONES_ROW.substitute( href=self.software_href(clone_info['softwarelist'], clone_info['shortname']), - shortname=cgi.escape(clone_info['shortname']), - description=cgi.escape(clone_info['description']), - year=cgi.escape(clone_info['year']), - publisher=cgi.escape(clone_info['publisher']), + shortname=htmlescape(clone_info['shortname']), + description=htmlescape(clone_info['description']), + year=htmlescape(clone_info['year']), + publisher=htmlescape(clone_info['publisher']), supported=self.format_supported(clone_info['supported'])).encode('utf-8') @staticmethod @@ -758,8 +764,8 @@ class RomIdentHandler(QueryPageHandler): def form_page(self): yield htmltmpl.ROMIDENT_PAGE.substitute( - app=self.js_escape(cgi.escape(self.application_uri, True)), - assets=self.js_escape(cgi.escape(urlparse.urljoin(self.application_uri, 'static'), True))).encode('utf-8') + app=self.js_escape(htmlescape(self.application_uri, True)), + assets=self.js_escape(htmlescape(urlparse.urljoin(self.application_uri, 'static'), True))).encode('utf-8') class BiosRpcHandler(MachineRpcHandlerBase): diff --git a/src/devices/machine/tc009xlvc.cpp b/src/devices/machine/tc009xlvc.cpp index b2d302d3922..c4a2db2c18d 100644 --- a/src/devices/machine/tc009xlvc.cpp +++ b/src/devices/machine/tc009xlvc.cpp @@ -214,6 +214,9 @@ void tc0090lvc_device::device_post_load() void tc0090lvc_device::device_start() { + // rom_r assumes it can make a mask with (m_rom.length() - 1) + assert(!(m_rom.length() & (m_rom.length() - 1))); + m_tile_cb.resolve(); std::fill_n(&m_vram[0], m_vram.bytes(), 0); diff --git a/src/devices/machine/tc009xlvc.h b/src/devices/machine/tc009xlvc.h index 5654d1a6f8b..367e47eaadd 100644 --- a/src/devices/machine/tc009xlvc.h +++ b/src/devices/machine/tc009xlvc.h @@ -27,7 +27,7 @@ public: void set_tilemap_yoffs(int yoffs, int flipped_yoffs) { m_tilemap_yoffs = yoffs; m_tilemap_flipped_yoffs = flipped_yoffs; } // memory handlers - u8 rom_r(offs_t offset) { return m_rom[offset & m_rom.mask()]; } + u8 rom_r(offs_t offset) { return m_rom[offset & (m_rom.length() - 1)]; } // internal functions u8 vregs_r(offs_t offset) { return m_vregs[offset]; } diff --git a/src/devices/sound/k007232.cpp b/src/devices/sound/k007232.cpp index a8b6c135a51..de6c2cdb4ec 100644 --- a/src/devices/sound/k007232.cpp +++ b/src/devices/sound/k007232.cpp @@ -52,15 +52,18 @@ k007232_device::k007232_device(const machine_config &mconfig, const char *tag, d void k007232_device::device_start() { + // assumes it can make an address mask with m_rom.length() - 1 + assert (!m_rom.found() || !(m_rom.length() & (m_rom.length() - 1))); + m_pcmlimit = 1 << 17; // default mapping (bankswitched ROM) - if ((m_rom.target() != nullptr) && (!has_configured_map(0))) + if (m_rom.found() && !has_configured_map(0)) { if (m_rom.bytes() > 0x20000) space(0).install_read_handler(0x00000, std::min(0x1ffff, m_rom.bytes() - 1), read8sm_delegate(*this, FUNC(k007232_device::read_rom_default))); else { - space(0).install_rom(0x00000, m_rom.mask(), m_rom.target()); + space(0).install_rom(0x00000, m_rom.length() - 1, m_rom.target()); m_pcmlimit = m_rom.bytes(); } } diff --git a/src/devices/sound/k007232.h b/src/devices/sound/k007232.h index 57cb72fcf7b..f467670fc9b 100644 --- a/src/devices/sound/k007232.h +++ b/src/devices/sound/k007232.h @@ -62,7 +62,7 @@ private: bool play; }; - u8 read_rom_default(offs_t offset) { return m_rom[(m_bank + (offset & 0x1ffff)) & m_rom.mask()]; } + u8 read_rom_default(offs_t offset) { return m_rom[(m_bank + (offset & 0x1ffff)) & (m_rom.length() - 1)]; } inline u8 read_sample(int channel, u32 addr) { m_bank = m_channel[channel].bank; return m_cache.read_byte(addr & 0x1ffff); } channel_t m_channel[KDAC_A_PCM_MAX]; // 2 channels diff --git a/src/devices/sound/l7a1045_l6028_dsp_a.cpp b/src/devices/sound/l7a1045_l6028_dsp_a.cpp index 7f567f86cbb..a9db61b5deb 100644 --- a/src/devices/sound/l7a1045_l6028_dsp_a.cpp +++ b/src/devices/sound/l7a1045_l6028_dsp_a.cpp @@ -116,29 +116,23 @@ l7a1045_sound_device::l7a1045_sound_device(const machine_config &mconfig, const void l7a1045_sound_device::device_start() { - /* Allocate the stream */ + // assumes it can make an address mask with m_rom.length() - 1 + assert(!(m_rom.length() & (m_rom.length() - 1))); + + // Allocate the stream m_stream = stream_alloc(0, 2, 66150); //clock() / 384); - for (int voice = 0; voice < 32; voice++) - { - save_item(NAME(m_voice[voice].start), voice); - save_item(NAME(m_voice[voice].end), voice); - save_item(NAME(m_voice[voice].mode), voice); - save_item(NAME(m_voice[voice].pos), voice); - save_item(NAME(m_voice[voice].frac), voice); - save_item(NAME(m_voice[voice].l_volume), voice); - save_item(NAME(m_voice[voice].r_volume), voice); - } + save_item(STRUCT_MEMBER(m_voice, start)); + save_item(STRUCT_MEMBER(m_voice, end)); + save_item(STRUCT_MEMBER(m_voice, mode)); + save_item(STRUCT_MEMBER(m_voice, pos)); + save_item(STRUCT_MEMBER(m_voice, frac)); + save_item(STRUCT_MEMBER(m_voice, l_volume)); + save_item(STRUCT_MEMBER(m_voice, r_volume)); save_item(NAME(m_key)); save_item(NAME(m_audiochannel)); save_item(NAME(m_audioregister)); - for (int reg = 0; reg < 0x10; reg++) - { - for (int voice = 0; voice < 0x20; voice++) - { - save_item(NAME(m_audiodat[reg][voice].dat), (reg << 8) | voice); - } - } + save_item(STRUCT_MEMBER(m_audiodat, dat)); } @@ -188,8 +182,8 @@ void l7a1045_sound_device::sound_stream_update(sound_stream &stream, std::vector } - data = m_rom[(start + pos) & m_rom.mask()]; - sample = ((int8_t)(data & 0xfc)) << (3 - (data & 3)); + data = m_rom[(start + pos) & (m_rom.length() - 1)]; + sample = int8_t(data & 0xfc) << (3 - (data & 3)); frac += step; outputs[0].add_int(j, sample * vptr->l_volume, 32768 * 512); @@ -277,7 +271,7 @@ void l7a1045_sound_device::sound_data_w(offs_t offset, uint16_t data) //logerror("%s: channel %d start = %08x\n", tag(), m_audiochannel, vptr->start); - vptr->start &= m_rom.mask(); + vptr->start &= m_rom.length() - 1; // if voice isn't active, clear the pos on start writes (required for DMA tests on MPC3000) if (!(m_key & (1 << m_audiochannel))) @@ -297,8 +291,7 @@ void l7a1045_sound_device::sound_data_w(offs_t offset, uint16_t data) vptr->end += vptr->start; vptr->mode = false; // hopefully it'll never happen? Maybe assert here? - vptr->end &= m_rom.mask(); - + vptr->end &= m_rom.length() - 1; } else // absolute { @@ -307,7 +300,7 @@ void l7a1045_sound_device::sound_data_w(offs_t offset, uint16_t data) vptr->end |= (m_audiodat[m_audioregister][m_audiochannel].dat[0] & 0xf000) >> (12); vptr->mode = true; - vptr->end &= m_rom.mask(); + vptr->end &= m_rom.length() - 1; } //logerror("%s: channel %d end = %08x\n", tag(), m_audiochannel, vptr->start); break; diff --git a/src/devices/sound/l7a1045_l6028_dsp_a.h b/src/devices/sound/l7a1045_l6028_dsp_a.h index 542b6aad386..4fff2caa465 100644 --- a/src/devices/sound/l7a1045_l6028_dsp_a.h +++ b/src/devices/sound/l7a1045_l6028_dsp_a.h @@ -38,7 +38,7 @@ protected: private: struct l7a1045_voice { - l7a1045_voice() { } + constexpr l7a1045_voice() { } uint32_t start = 0; uint32_t end = 0; diff --git a/src/devices/sound/tc8830f.cpp b/src/devices/sound/tc8830f.cpp index 85635f2f466..f9f65975347 100644 --- a/src/devices/sound/tc8830f.cpp +++ b/src/devices/sound/tc8830f.cpp @@ -45,6 +45,9 @@ tc8830f_device::tc8830f_device(const machine_config &mconfig, const char *tag, d void tc8830f_device::device_start() { + // assumes it can make an address mask with m_mem.length() - 1 + assert(!(m_mem.length() & (m_mem.length() - 1))); + // create the stream m_stream = stream_alloc(0, 1, clock() / 0x10); @@ -92,7 +95,7 @@ void tc8830f_device::sound_stream_update(sound_stream &stream, std::vectorread_byte( ( r * NB_OF_COLUMNS ) + ( x>>3 ) ); - if( m_charset[((c<<3) + y) & m_charset.mask()] & (0x80>>(x&7)) ) + if( BIT(m_charset[((c<<3) + y) & (m_charset.length() - 1)], 7 - (x & 7)) ) m_screen_out.pix((r*12)+y, x) = palette[1]; else m_screen_out.pix((r*12)+y, x) = palette[0]; diff --git a/src/emu/devfind.cpp b/src/emu/devfind.cpp index 330ebc7c14a..bbf3d35c1fb 100644 --- a/src/emu/devfind.cpp +++ b/src/emu/devfind.cpp @@ -127,8 +127,7 @@ void *finder_base::find_memshare(u8 width, size_t &bytes, bool required) const // check the width and warn if not correct if (width != 0 && share->bitwidth() != width) { - if (required) - osd_printf_warning("Shared ptr '%s' found but is width %d, not %d as requested\n", m_tag, share->bitwidth(), width); + osd_printf_warning("Shared ptr '%s' found but is width %d, not %d as requested\n", m_tag, share->bitwidth(), width); return nullptr; } @@ -168,8 +167,7 @@ address_space *finder_base::find_addrspace(int spacenum, u8 width, bool required address_space &space(memory->space(spacenum)); if (width != 0 && width != space.data_width()) { - if (required) - osd_printf_warning("Device '%s' found but address space #%d has the wrong data width (expected %d, found %d)\n", m_tag, spacenum, width, space.data_width()); + osd_printf_warning("Device '%s' found but address space #%d has the wrong data width (expected %d, found %d)\n", m_tag, spacenum, width, space.data_width()); return nullptr; } @@ -186,7 +184,7 @@ bool finder_base::validate_addrspace(int spacenum, u8 width, bool required) cons { // look up the device and return false if not found device_t *const device(m_base.get().subdevice(m_tag)); - if (device == nullptr) + if (!device) return report_missing(false, "address space", required); // check for memory interface and a configuration for the designated space @@ -395,13 +393,13 @@ bool memory_share_creator::findit(validity_checker *valid) memory_share *const share = manager.share_find(tag); if (share) { - m_target = share; std::string const result = share->compare(m_width, m_bytes, m_endianness); if (!result.empty()) { osd_printf_error("%s\n", result); return false; } + m_target = share; } else { diff --git a/src/emu/devfind.h b/src/emu/devfind.h index 885ba479aae..f7a5a09d3ad 100644 --- a/src/emu/devfind.h +++ b/src/emu/devfind.h @@ -477,7 +477,7 @@ public: /// Allows pointer-member-style access to members of the target /// object. Asserts that the target object has been found. /// \return Pointer to target object if found, or nullptr otherwise. - virtual ObjectClass *operator->() const { assert(m_target); return m_target; } + ObjectClass *operator->() const { assert(m_target); return m_target; } protected: /// \brief Designated constructor @@ -818,9 +818,9 @@ public: /// \brief Pointer member access operator /// /// Allows pointer-member-style access to members of the target - /// memory bank object. + /// memory bank object. Asserts that the target has been found. /// \return Pointer to found or created bank object. - memory_bank *operator->() const { return m_target; } + memory_bank *operator->() const { assert(m_target); return m_target; } protected: virtual bool findit(validity_checker *valid) override; @@ -931,9 +931,9 @@ template using required_ioport_array = ioport_array_finder class address_space_finder : public object_finder_base @@ -941,11 +941,12 @@ class address_space_finder : public object_finder_base public: /// \brief Address space finder constructor /// \param [in] base Base device to search from. - /// \param [in] tag Address space tag to search for. This is not copied, - /// it is the caller's responsibility to ensure this pointer - /// remains valid until resolution time. + /// \param [in] tag Address space device tag to search for. + /// This is not copied, it is the caller's responsibility to + /// ensure this pointer remains valid until resolution time. /// \param [in] spacenum Address space number. - /// \param [in] width Specific data width (optional). + /// \param [in] width Required data width in bits, or zero if + /// any data width is acceptable. address_space_finder(device_t &base, char const *tag, int spacenum, u8 width = 0); /// \brief Set search tag and space number @@ -963,9 +964,9 @@ public: /// \brief Set search tag and space number /// - /// Allows search tag to be changed after construction. Note that - /// this must be done before resolution time to take effect. Also - /// note that the tag is not copied. + /// Allows search tag and address space number to be changed after + /// construction. Note that this must be done before resolution + /// time to take effect. Also note that the tag is not copied. /// \param [in] tag Updated search tag relative to the current /// device being configured. This is not copied, it is the /// caller's responsibility to ensure this pointer remains valid @@ -975,19 +976,30 @@ public: /// \brief Set search tag and space number /// - /// Allows search tag to be changed after construction. Note that - /// this must be done before resolution time to take effect. + /// Allows search tag and address space number to be changed after + /// construction. Note that this must be done before resolution + /// time to take effect. Also note that the tag is not copied. /// \param [in] finder Object finder to take the search base and tag /// from. /// \param [in] spacenum Address space number. void set_tag(finder_base const &finder, int spacenum) { finder_base::set_tag(finder); this->m_spacenum = spacenum; } + /// \brief Set search tag and space number + /// + /// Allows search tag and address space number to be changed after + /// construction. Note that this must be done before resolution + /// time to take effect. Also note that the tag is not copied. + /// \param [in] finder Address space finder to take the search base, + /// tag and address space number from. + template void set_tag(address_space_finder const &finder) { set_tag(finder, finder.spacenum()); } + /// \brief Set data width of space /// - /// Allows data width to be specified after construction. Note that - /// this must be done before resolution time to take effect. - /// \param [in] width Data width in bits (0 = don't care). - void set_data_width(u8 width) { this->m_data_width = width; } + /// Allows data width to be specified after construction. Note + /// that this must be done before resolution time to take effect. + /// \param [in] width Required data width in bits, or zero if any + /// data width is acceptable. + void set_data_width(u8 width) { assert(!this->m_resolved); this->m_data_width = width; } /// \brief Get space number /// @@ -1068,21 +1080,13 @@ public: /// /// \return Length in units of elements or zero if no matching /// memory region has been found. - u32 length() const { return m_length; } + size_t length() const { return m_length; } /// \brief Get length in units of bytes /// /// \return Length in units of bytes or zero if no matching memory /// region has been found. - u32 bytes() const { return m_length * sizeof(PointerType); } - - /// \brief Get index mask - /// - /// Returns the length in units of elements minus one, which can be - /// used as a mask for index values if the length is a power of two. - /// Result is undefined if no matching memory region has been found. - /// \return Length in units of elements minus one. - u32 mask() const { return m_length - 1; } + size_t bytes() const { return m_length * sizeof(PointerType); } private: /// \brief Find memory region base pointer @@ -1178,15 +1182,13 @@ public: /// /// \return Length in units of elements or zero if no matching /// memory region has been found. - u32 length() const { return m_bytes / sizeof(PointerType); } + size_t length() const { return m_bytes / sizeof(PointerType); } /// \brief Get length in bytes /// /// \return Length in bytes or zero if no matching memory share has /// been found. - u32 bytes() const { return m_bytes; } - - u32 mask() const { return m_bytes - 1; } // FIXME: wrong when sizeof(PointerType) != 1 + size_t bytes() const { return m_bytes; } private: /// \brief Find memory share base pointer diff --git a/src/emu/render.h b/src/emu/render.h index 41cf1e42e1c..72e47c4b05f 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -176,6 +176,8 @@ namespace emu { namespace render { namespace detail { struct bounds_step { + constexpr render_bounds get() const { return bounds; } + int state; render_bounds bounds; render_bounds delta; @@ -184,6 +186,8 @@ using bounds_vector = std::vector; struct color_step { + constexpr render_color get() const { return color; } + int state; render_color color; render_color delta; @@ -744,8 +748,8 @@ public: // getters layout_element *element() const { return m_element; } screen_device *screen() { return m_screen; } - render_bounds bounds() const; - render_color color() const; + render_bounds bounds() const { return m_get_bounds(); } + render_color color() const { return m_get_color(); } int blend_mode() const { return m_blend_mode; } u32 visibility_mask() const { return m_visibility_mask; } int orientation() const { return m_orientation; } @@ -757,7 +761,7 @@ public: bool clickthrough() const { return m_clickthrough; } // fetch state based on configured source - int state() const; + int state() const { return m_get_elem_state(); } // resolve tags, if any void resolve_tags(); @@ -765,8 +769,18 @@ public: private: using bounds_vector = emu::render::detail::bounds_vector; using color_vector = emu::render::detail::color_vector; - - int animation_state() const; + using state_delegate = delegate; + using bounds_delegate = delegate; + using color_delegate = delegate; + + int get_output() const; + int get_input_raw() const; + int get_input_field_cached() const; + int get_input_field_conditional() const; + int get_anim_output() const; + int get_anim_input() const; + render_bounds get_interpolated_bounds() const; + render_color get_interpolated_color() const; static layout_element *find_element(view_environment &env, util::xml::data_node const &itemnode, element_map &elemmap); static bounds_vector make_bounds(view_environment &env, util::xml::data_node const &itemnode, layout_group::transform const &trans); @@ -780,10 +794,12 @@ public: // internal state layout_element *const m_element; // pointer to the associated element (non-screens only) + state_delegate m_get_elem_state; // resolved element state function + state_delegate m_get_anim_state; // resolved animation state function + bounds_delegate m_get_bounds; // resolved bounds function + color_delegate m_get_color; // resolved color function output_finder<> m_output; // associated output output_finder<> m_animoutput; // associated output for animation if different - bool const m_have_output; // whether we actually have an output - bool const m_have_animoutput; // whether we actually have an output for animation ioport_port * m_animinput_port; // input port used for animation ioport_value const m_animmask; // mask for animation state u8 const m_animshift; // shift for animation state @@ -804,6 +820,8 @@ public: std::string const m_input_tag; // input tag of this item std::string const m_animinput_tag; // tag of input port for animation state bounds_vector const m_rawbounds; // raw (original) bounds of the item + bool const m_have_output; // whether we actually have an output + bool const m_have_animoutput; // whether we actually have an output for animation bool const m_has_clickthrough; // whether clickthrough was explicitly configured }; using item_list = std::list; diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index 7215061df15..0a88d42902b 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -86,9 +86,14 @@ constexpr layout_group::transform identity_transform{{ {{ 1.0F, 0.0F, 0.0F }}, { //************************************************************************** -// INLINE HELPERS +// HELPERS //************************************************************************** +constexpr int get_state_dummy(layout_view::item &item) +{ + return 0; +} + inline void render_bounds_transform(render_bounds &bounds, layout_group::transform const &trans) { bounds = render_bounds{ @@ -4425,8 +4430,6 @@ layout_view::item::item( : m_element(find_element(env, itemnode, elemmap)) , m_output(env.device(), env.get_attribute_string(itemnode, "name", "")) , m_animoutput(env.device(), make_animoutput_tag(env, itemnode)) - , m_have_output(env.get_attribute_string(itemnode, "name", "")[0]) - , m_have_animoutput(!make_animoutput_tag(env, itemnode).empty()) , m_animinput_port(nullptr) , m_animmask(make_animmask(env, itemnode)) , m_animshift(get_state_shift(m_animmask)) @@ -4444,6 +4447,8 @@ layout_view::item::item( , m_input_tag(make_input_tag(env, itemnode)) , m_animinput_tag(make_animinput_tag(env, itemnode)) , m_rawbounds(make_bounds(env, itemnode, trans)) + , m_have_output(env.get_attribute_string(itemnode, "name", "")[0]) + , m_have_animoutput(!make_animoutput_tag(env, itemnode).empty()) , m_has_clickthrough(env.get_attribute_string(itemnode, "clickthrough", "")[0]) { // fetch common data @@ -4482,71 +4487,13 @@ layout_view::item::~item() } -//------------------------------------------------- -// bounds - get bounds for current state -//------------------------------------------------- - -render_bounds layout_view::item::bounds() const -{ - if (m_bounds.size() == 1U) - return m_bounds.front().bounds; - else - return interpolate_bounds(m_bounds, animation_state()); -} - - -//------------------------------------------------- -// color - get color for current state -//------------------------------------------------- - -render_color layout_view::item::color() const -{ - if (m_color.size() == 1U) - return m_color.front().color; - else - return interpolate_color(m_color, animation_state()); -} - - -//------------------------------------------------- -// state - fetch state based on configured source -//------------------------------------------------- - -int layout_view::item::state() const -{ - assert(m_element); - - if (m_have_output) - { - // if configured to track an output, fetch its value - return m_output; - } - else if (m_input_port) - { - // if configured to an input, fetch the input value - if (m_input_raw) - { - return (m_input_port->read() & m_input_mask) >> m_input_shift; - } - else - { - ioport_field const *const field(m_input_field ? m_input_field : m_input_port->field(m_input_mask)); - if (field) - return ((m_input_port->read() ^ field->defvalue()) & m_input_mask) ? 1 : 0; - } - } - - // default to zero - return 0; -} - - //--------------------------------------------- // resolve_tags - resolve tags, if any are set //--------------------------------------------- void layout_view::item::resolve_tags() { + // resolve element state output and set default value if (m_have_output) { m_output.resolve(); @@ -4554,12 +4501,15 @@ void layout_view::item::resolve_tags() m_output = m_element->default_state(); } + // resolve animation state output if (m_have_animoutput) m_animoutput.resolve(); + // resolve animation state input if (!m_animinput_tag.empty()) m_animinput_port = m_element->machine().root_device().ioport(m_animinput_tag); + // resolve element state input if (!m_input_tag.empty()) { m_input_port = m_element->machine().root_device().ioport(m_input_tag); @@ -4581,21 +4531,125 @@ void layout_view::item::resolve_tags() m_clickthrough = false; } } + + // choose optimal element state function + if (m_have_output) + m_get_elem_state = state_delegate(&item::get_output, this); + else if (!m_input_port) + m_get_elem_state = state_delegate(&get_state_dummy, this); + else if (m_input_raw) + m_get_elem_state = state_delegate(&item::get_input_raw, this); + else if (m_input_field) + m_get_elem_state = state_delegate(&item::get_input_field_cached, this); + else + m_get_elem_state = state_delegate(&item::get_input_field_conditional, this); + + // choose optimal animation state function + if (m_have_animoutput) + m_get_anim_state = state_delegate(&item::get_anim_output, this); + else if (m_animinput_port) + m_get_anim_state = state_delegate(&item::get_anim_input, this); + else + m_get_anim_state = m_get_elem_state; + + // choose optional bounds and colour functions + m_get_bounds = (m_bounds.size() == 1U) + ? bounds_delegate(&emu::render::detail::bounds_step::get, &const_cast(m_bounds.front())) + : bounds_delegate(&item::get_interpolated_bounds, this); + m_get_color = (m_color.size() == 1U) + ? color_delegate(&emu::render::detail::color_step::get, &const_cast(m_color.front())) + : color_delegate(&item::get_interpolated_color, this); } //--------------------------------------------- -// find_element - find element definition +// get_output - get element state output //--------------------------------------------- -inline int layout_view::item::animation_state() const +int layout_view::item::get_output() const { - if (m_have_animoutput) - return (s32(m_animoutput) & m_animmask) >> m_animshift; - else if (m_animinput_port) - return (m_animinput_port->read() & m_animmask) >> m_animshift; - else - return state(); + assert(m_have_output); + return int(s32(m_output)); +} + + +//--------------------------------------------- +// get_input_raw - get element state input +//--------------------------------------------- + +int layout_view::item::get_input_raw() const +{ + assert(m_input_port); + return int(std::make_signed_t((m_input_port->read() & m_input_mask) >> m_input_shift)); +} + + +//--------------------------------------------- +// get_input_field_cached - element state +//--------------------------------------------- + +int layout_view::item::get_input_field_cached() const +{ + assert(m_input_port); + assert(m_input_field); + return ((m_input_port->read() ^ m_input_field->defvalue()) & m_input_mask) ? 1 : 0; +} + + +//--------------------------------------------- +// get_input_field_conditional - element state +//--------------------------------------------- + +int layout_view::item::get_input_field_conditional() const +{ + assert(m_input_port); + assert(!m_input_field); + ioport_field const *const field(m_input_port->field(m_input_mask)); + return (field && ((m_input_port->read() ^ field->defvalue()) & m_input_mask)) ? 1 : 0; +} + + +//--------------------------------------------- +// get_anim_output - get animation output +//--------------------------------------------- + +int layout_view::item::get_anim_output() const +{ + assert(m_have_animoutput); + return int(unsigned((u32(s32(m_animoutput) & m_animmask) >> m_animshift))); +} + + +//--------------------------------------------- +// get_anim_input - get animation input +//--------------------------------------------- + +int layout_view::item::get_anim_input() const +{ + assert(m_animinput_port); + return int(std::make_signed_t((m_animinput_port->read() & m_animmask) >> m_animshift)); +} + + +//--------------------------------------------- +// get_interpolated_bounds - animated bounds +//--------------------------------------------- + +render_bounds layout_view::item::get_interpolated_bounds() const +{ + assert(m_bounds.size() > 1U); + return interpolate_bounds(m_bounds, m_get_anim_state()); +} + + +//--------------------------------------------- +// get_interpolated_color - animated color +//--------------------------------------------- + +render_color layout_view::item::get_interpolated_color() const +{ + assert(m_color.size() > 1U); + return interpolate_color(m_color, m_get_anim_state()); } diff --git a/src/mame/audio/taito_en.cpp b/src/mame/audio/taito_en.cpp index f4f15533fbf..bfda6b59aef 100644 --- a/src/mame/audio/taito_en.cpp +++ b/src/mame/audio/taito_en.cpp @@ -44,6 +44,9 @@ taito_en_device::taito_en_device(const machine_config &mconfig, const char *tag, void taito_en_device::device_start() { + // assumes it can make an address mask with .length() - 1 + assert(!(m_otisrom.length() & (m_otisrom.length() - 1))); + // tell the pump about the ESP chips uint8_t *ROM = m_osrom->base(); uint32_t max = (m_osrom->bytes() - 0x100000) / 0x20000; @@ -132,7 +135,7 @@ void taito_en_device::fc7_map(address_map &map) void taito_en_device::en_otis_map(address_map &map) { map(0x000000, 0x0fffff).lr16( - [this](offs_t offset) -> u16 { return m_otisrom[(m_calculated_otisbank[m_ensoniq->get_voice_index()] + offset) & m_otisrom.mask()]; }, "banked_otisrom"); + [this](offs_t offset) -> u16 { return m_otisrom[(m_calculated_otisbank[m_ensoniq->get_voice_index()] + offset) & (m_otisrom.length() - 1)]; }, "banked_otisrom"); } diff --git a/src/mame/drivers/5clown.cpp b/src/mame/drivers/5clown.cpp index 387a2362366..898c54bb8c8 100644 --- a/src/mame/drivers/5clown.cpp +++ b/src/mame/drivers/5clown.cpp @@ -527,6 +527,9 @@ private: void _5clown_state::machine_start() { + // assumes it can make an address mask with m_videoram.length() - 1 + assert(!(m_videoram.length() & (m_videoram.length() - 1))); + m_main_latch_d800 = m_snd_latch_0800 = m_snd_latch_0a02 = m_ay8910_addr = m_mux_data = 0; save_item(NAME(m_main_latch_d800)); @@ -558,7 +561,7 @@ MC6845_UPDATE_ROW(_5clown_state::update_row) for (int x = 0; x < x_count; x++) { - int tile_index = (x + ma) & m_videoram.mask(); + int tile_index = (x + ma) & (m_videoram.length() - 1); int attr = m_colorram[tile_index]; int code = ((attr & 0x01) << 8) | ((attr & 0x40) << 2) | m_videoram[tile_index]; /* bit 8 for extended char set */ int bank = (attr & 0x02) >> 1; /* bit 1 switch the gfx banks */ @@ -758,18 +761,18 @@ void _5clown_state::fclown_map(address_map &map) map(0x0801, 0x0801).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); map(0x0844, 0x0847).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); map(0x0848, 0x084b).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x1000, 0x13ff).ram().share("videoram"); /* Init'ed at $2042 */ - map(0x1800, 0x1bff).ram().share("colorram"); /* Init'ed at $2054 */ - map(0x2000, 0x7fff).rom(); /* ROM space */ + map(0x1000, 0x13ff).ram().share(m_videoram); // Init'ed at $2042 + map(0x1800, 0x1bff).ram().share(m_colorram); // Init'ed at $2054 + map(0x2000, 0x7fff).rom(); // ROM space map(0xc048, 0xc048).w(FUNC(_5clown_state::cpu_c048_w)); map(0xd800, 0xd800).w(FUNC(_5clown_state::cpu_d800_w)); - map(0xc400, 0xc400).portr("SW1"); /* DIP Switches bank */ - map(0xcc00, 0xcc00).portr("SW2"); /* DIP Switches bank */ - map(0xd400, 0xd400).portr("SW3"); /* Second DIP Switches bank */ + map(0xc400, 0xc400).portr("SW1"); // DIP Switches bank + map(0xcc00, 0xcc00).portr("SW2"); // DIP Switches bank + map(0xd400, 0xd400).portr("SW3"); // Second DIP Switches bank - map(0xe000, 0xffff).rom(); /* ROM space */ + map(0xe000, 0xffff).rom(); // ROM space } /* diff --git a/src/mame/drivers/am1000.cpp b/src/mame/drivers/am1000.cpp index bab4bb80447..d05d6196b2d 100644 --- a/src/mame/drivers/am1000.cpp +++ b/src/mame/drivers/am1000.cpp @@ -52,6 +52,9 @@ private: void am1000_state::machine_start() { + // assumes it can make an address mask from m_mainprom.length() - 1 + assert(!(m_mainprom.length() & (m_mainprom.length() - 1))); + save_item(NAME(m_ram_enabled)); } @@ -66,7 +69,7 @@ u16 am1000_state::rom_ram_r(offs_t offset, u16 mem_mask) if (m_ram_enabled) return m_mainram[offset]; else - return m_mainprom[offset & m_mainprom.mask()]; + return m_mainprom[offset & (m_mainprom.length() - 1)]; } void am1000_state::control_w(u8 data) @@ -77,7 +80,7 @@ void am1000_state::control_w(u8 data) void am1000_state::main_map(address_map &map) { - map(0x000000, 0x07ffff).r(FUNC(am1000_state::rom_ram_r)).writeonly().share("mainram"); // TMM41256P-12 x16 + map(0x000000, 0x07ffff).r(FUNC(am1000_state::rom_ram_r)).writeonly().share(m_mainram); // TMM41256P-12 x16 map(0x800000, 0x801fff).rom().region("mainprom", 0); map(0xfffe00, 0xfffe00).w(FUNC(am1000_state::control_w)); } diff --git a/src/mame/drivers/coolpool.cpp b/src/mame/drivers/coolpool.cpp index 576bec7aff8..511ed975311 100644 --- a/src/mame/drivers/coolpool.cpp +++ b/src/mame/drivers/coolpool.cpp @@ -425,7 +425,7 @@ uint16_t coolpool_state::dsp_hold_line_r() uint16_t coolpool_state::dsp_rom_r() { - return m_dsp_rom[m_iop_romaddr & (m_dsp_rom.mask())]; + return m_dsp_rom[m_iop_romaddr & (m_dsp_rom.length() - 1)]; } @@ -521,7 +521,7 @@ uint16_t coolpool_state::coolpool_input_r(offs_t offset) void coolpool_state::amerdart_map(address_map &map) { - map(0x00000000, 0x000fffff).ram().share("vram_base"); + map(0x00000000, 0x000fffff).ram().share(m_vram_base); map(0x04000000, 0x0400000f).w(FUNC(coolpool_state::amerdart_misc_w)); map(0x05000000, 0x0500000f).r(m_dsp2main, FUNC(generic_latch_16_device::read)).w(m_main2dsp, FUNC(generic_latch_16_device::write)); map(0x06000000, 0x06007fff).ram().w(FUNC(coolpool_state::nvram_thrash_data_w)).share("nvram"); @@ -531,7 +531,7 @@ void coolpool_state::amerdart_map(address_map &map) void coolpool_state::coolpool_map(address_map &map) { - map(0x00000000, 0x001fffff).ram().share("vram_base"); + map(0x00000000, 0x001fffff).ram().share(m_vram_base); map(0x01000000, 0x010000ff).rw(m_tlc34076, FUNC(tlc34076_device::read), FUNC(tlc34076_device::write)).umask16(0x00ff); // IMSG176P-40 map(0x02000000, 0x020000ff).r(m_dsp2main, FUNC(generic_latch_16_device::read)).w(m_main2dsp, FUNC(generic_latch_16_device::write)); map(0x03000000, 0x0300000f).w(FUNC(coolpool_state::coolpool_misc_w)); @@ -1039,8 +1039,11 @@ ROM_END * *************************************/ -void coolpool_state::register_state_save() +void coolpool_state::machine_start() { + // assumes it can make an address mask with m_dsp_rom.length() - 1 + assert(!(m_dsp_rom.length() & (m_dsp_rom.length() - 1))); + save_item(NAME(m_oldx)); save_item(NAME(m_oldy)); save_item(NAME(m_result)); @@ -1054,19 +1057,12 @@ void coolpool_state::register_state_save() void coolpool_state::init_amerdart() { m_lastresult = 0xffff; - - register_state_save(); -} - -void coolpool_state::init_coolpool() -{ - register_state_save(); } void coolpool_state::init_9ballsht() { - /* decrypt the main program ROMs */ + // decrypt the main program ROMs uint16_t *rom = (uint16_t *)memregion("maincpu")->base(); int len = memregion("maincpu")->bytes(); for (int a = 0; a < len/2; a++) @@ -1088,18 +1084,16 @@ void coolpool_state::init_9ballsht() rom[a] = (nhi << 8) | nlo; } - /* decrypt the sub data ROMs */ + // decrypt the sub data ROMs rom = (uint16_t *)memregion("dspdata")->base(); len = memregion("dspdata")->bytes(); for (int a = 1; a < len/2; a += 4) { - /* just swap bits 1 and 2 of the address */ + // just swap bits 1 and 2 of the address uint16_t tmp = rom[a]; rom[a] = rom[a+1]; rom[a+1] = tmp; } - - register_state_save(); } @@ -1113,7 +1107,7 @@ void coolpool_state::init_9ballsht() GAME( 1989, amerdart, 0, amerdart, amerdart, coolpool_state, init_amerdart, ROT0, "Ameri", "AmeriDarts (set 1)", MACHINE_SUPPORTS_SAVE ) GAME( 1989, amerdart2, amerdart, amerdart, amerdart, coolpool_state, init_amerdart, ROT0, "Ameri", "AmeriDarts (set 2)", MACHINE_SUPPORTS_SAVE ) GAME( 1989, amerdart3, amerdart, amerdart, amerdart, coolpool_state, init_amerdart, ROT0, "Ameri", "AmeriDarts (set 3)", MACHINE_SUPPORTS_SAVE ) -GAME( 1992, coolpool, 0, coolpool, coolpool, coolpool_state, init_coolpool, ROT0, "Catalina", "Cool Pool", 0 ) +GAME( 1992, coolpool, 0, coolpool, coolpool, coolpool_state, empty_init, ROT0, "Catalina", "Cool Pool", 0 ) GAME( 1993, 9ballsht, 0, _9ballsht, 9ballsht, coolpool_state, init_9ballsht, ROT0, "E-Scape EnterMedia (Bundra license)", "9-Ball Shootout (set 1)", 0 ) GAME( 1993, 9ballsht2, 9ballsht, _9ballsht, 9ballsht, coolpool_state, init_9ballsht, ROT0, "E-Scape EnterMedia (Bundra license)", "9-Ball Shootout (set 2)", 0 ) GAME( 1993, 9ballsht3, 9ballsht, _9ballsht, 9ballsht, coolpool_state, init_9ballsht, ROT0, "E-Scape EnterMedia (Bundra license)", "9-Ball Shootout (set 3)", 0 ) diff --git a/src/mame/drivers/f1gp.cpp b/src/mame/drivers/f1gp.cpp index cfc71d8f96e..7e3cd72442b 100644 --- a/src/mame/drivers/f1gp.cpp +++ b/src/mame/drivers/f1gp.cpp @@ -58,16 +58,16 @@ void f1gp_state::f1gp_cpu1_map(address_map &map) map(0x000000, 0x03ffff).rom(); map(0x100000, 0x2fffff).rom().region("user1", 0); map(0xa00000, 0xbfffff).rom().region("user2", 0); - map(0xc00000, 0xc3ffff).ram().w(FUNC(f1gp_state::rozgfxram_w)).share("rozgfxram"); - map(0xd00000, 0xd01fff).mirror(0x006000).ram().w(FUNC(f1gp_state::rozvideoram_w)).share("rozvideoram"); - map(0xe00000, 0xe03fff).ram().share("spr1cgram"); // SPR-1 CG RAM - map(0xe04000, 0xe07fff).ram().share("spr2cgram"); // SPR-2 CG RAM - map(0xf00000, 0xf003ff).ram().share("spr1vram"); // SPR-1 VRAM - map(0xf10000, 0xf103ff).ram().share("spr2vram"); // SPR-2 VRAM - map(0xff8000, 0xffbfff).ram(); // WORK RAM-1 - map(0xffc000, 0xffcfff).ram().share("sharedram"); // DUAL RAM - map(0xffd000, 0xffdfff).ram().w(FUNC(f1gp_state::fgvideoram_w)).share("fgvideoram"); // CHARACTER - map(0xffe000, 0xffefff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // PALETTE + map(0xc00000, 0xc3ffff).ram().w(FUNC(f1gp_state::rozgfxram_w)).share(m_rozgfxram); + map(0xd00000, 0xd01fff).mirror(0x006000).ram().w(FUNC(f1gp_state::rozvideoram_w)).share(m_rozvideoram); + map(0xe00000, 0xe03fff).ram().share(m_sprcgram[0]); // SPR-1 CG RAM + map(0xe04000, 0xe07fff).ram().share(m_sprcgram[1]); // SPR-2 CG RAM + map(0xf00000, 0xf003ff).ram().share(m_sprvram[0]); // SPR-1 VRAM + map(0xf10000, 0xf103ff).ram().share(m_sprvram[1]); // SPR-2 VRAM + map(0xff8000, 0xffbfff).ram(); // WORK RAM-1 + map(0xffc000, 0xffcfff).ram().share(m_sharedram); // DUAL RAM + map(0xffd000, 0xffdfff).ram().w(FUNC(f1gp_state::fgvideoram_w)).share(m_fgvideoram); // CHARACTER + map(0xffe000, 0xffefff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // PALETTE map(0xfff000, 0xfff001).portr("INPUTS"); map(0xfff001, 0xfff001).w(FUNC(f1gp_state::gfxctrl_w)); map(0xfff002, 0xfff003).portr("WHEEL"); @@ -84,13 +84,13 @@ void f1gp2_state::f1gp2_cpu1_map(address_map &map) { map(0x000000, 0x03ffff).rom(); map(0x100000, 0x2fffff).rom().region("user1", 0); - map(0xa00000, 0xa07fff).ram().share("spr1cgram"); // SPR-1 CG RAM + SPR-2 CG RAM - map(0xd00000, 0xd01fff).ram().w(FUNC(f1gp2_state::rozvideoram_w)).share("rozvideoram"); // BACK VRAM - map(0xe00000, 0xe00fff).ram().share("spr1vram"); // not checked + SPR-1 VRAM + SPR-2 VRAM - map(0xff8000, 0xffbfff).ram(); // WORK RAM-1 - map(0xffc000, 0xffcfff).ram().share("sharedram"); // DUAL RAM - map(0xffd000, 0xffdfff).ram().w(FUNC(f1gp2_state::fgvideoram_w)).share("fgvideoram"); // CHARACTER - map(0xffe000, 0xffefff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // PALETTE + map(0xa00000, 0xa07fff).ram().share(m_sprcgram[0]); // SPR-1 CG RAM + SPR-2 CG RAM + map(0xd00000, 0xd01fff).ram().w(FUNC(f1gp2_state::rozvideoram_w)).share(m_rozvideoram); // BACK VRAM + map(0xe00000, 0xe00fff).ram().share(m_sprvram[0]); // not checked + SPR-1 VRAM + SPR-2 VRAM + map(0xff8000, 0xffbfff).ram(); // WORK RAM-1 + map(0xffc000, 0xffcfff).ram().share(m_sharedram); // DUAL RAM + map(0xffd000, 0xffdfff).ram().w(FUNC(f1gp2_state::fgvideoram_w)).share(m_fgvideoram); // CHARACTER + map(0xffe000, 0xffefff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // PALETTE map(0xfff000, 0xfff001).portr("INPUTS"); map(0xfff000, 0xfff000).w(FUNC(f1gp2_state::rozbank_w)); map(0xfff001, 0xfff001).w(FUNC(f1gp2_state::gfxctrl_w)); @@ -107,7 +107,7 @@ void f1gp_state::f1gp_cpu2_map(address_map &map) { map(0x000000, 0x01ffff).rom(); map(0xff8000, 0xffbfff).ram(); - map(0xffc000, 0xffcfff).ram().share("sharedram"); + map(0xffc000, 0xffcfff).ram().share(m_sharedram); map(0xfff030, 0xfff033).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0x00ff); } @@ -115,7 +115,7 @@ void f1gp_state::sound_map(address_map &map) { map(0x0000, 0x77ff).rom(); map(0x7800, 0x7fff).ram(); - map(0x8000, 0xffff).bankr("z80bank"); + map(0x8000, 0xffff).bankr(m_z80bank); } void f1gp_state::sound_io_map(address_map &map) @@ -157,16 +157,16 @@ void f1gp_state::f1gpb_cpu1_map(address_map &map) map(0x000000, 0x03ffff).rom(); map(0x100000, 0x2fffff).rom().region("user1", 0); map(0xa00000, 0xbfffff).rom().region("user2", 0); - map(0x800000, 0x801fff).ram().share("spriteram"); - map(0xc00000, 0xc3ffff).ram().w(FUNC(f1gp_state::rozgfxram_w)).share("rozgfxram"); - map(0xd00000, 0xd01fff).mirror(0x006000).ram().w(FUNC(f1gp_state::rozvideoram_w)).share("rozvideoram"); + map(0x800000, 0x801fff).ram().share(m_spriteram); + map(0xc00000, 0xc3ffff).ram().w(FUNC(f1gp_state::rozgfxram_w)).share(m_rozgfxram); + map(0xd00000, 0xd01fff).mirror(0x006000).ram().w(FUNC(f1gp_state::rozvideoram_w)).share(m_rozvideoram); map(0xe00000, 0xe03fff).ram(); //unused map(0xe04000, 0xe07fff).ram(); //unused map(0xf00000, 0xf003ff).ram(); //unused map(0xf10000, 0xf103ff).ram(); //unused map(0xff8000, 0xffbfff).ram(); - map(0xffc000, 0xffcfff).ram().share("sharedram"); - map(0xffd000, 0xffdfff).ram().w(FUNC(f1gp_state::fgvideoram_w)).share("fgvideoram"); + map(0xffc000, 0xffcfff).ram().share(m_sharedram); + map(0xffd000, 0xffdfff).ram().w(FUNC(f1gp_state::fgvideoram_w)).share(m_fgvideoram); map(0xffe000, 0xffefff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); map(0xfff000, 0xfff001).portr("INPUTS"); map(0xfff002, 0xfff003).portr("WHEEL"); @@ -174,20 +174,20 @@ void f1gp_state::f1gpb_cpu1_map(address_map &map) map(0xfff006, 0xfff007).portr("DSW2"); map(0xfff008, 0xfff009).nopr(); //? map(0xfff006, 0xfff007).nopw(); - map(0xfff00a, 0xfff00b).ram().share("fgregs"); + map(0xfff00a, 0xfff00b).ram().share(m_fgregs); map(0xfff00f, 0xfff00f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); map(0xfff00c, 0xfff00d).w(FUNC(f1gp_state::f1gpb_misc_w)); map(0xfff010, 0xfff011).nopw(); map(0xfff020, 0xfff023).nopw(); // GGA access map(0xfff050, 0xfff051).portr("DSW3"); - map(0xfff800, 0xfff809).ram().share("rozregs"); + map(0xfff800, 0xfff809).ram().share(m_rozregs); } void f1gp_state::f1gpb_cpu2_map(address_map &map) { map(0x000000, 0x01ffff).rom(); map(0xff8000, 0xffbfff).ram(); - map(0xffc000, 0xffcfff).ram().share("sharedram"); + map(0xffc000, 0xffcfff).ram().share(m_sharedram); map(0xfff030, 0xfff033).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0x00ff); } @@ -333,6 +333,10 @@ GFXDECODE_END void f1gp_state::machine_start() { + // assumes it can make an address mask with .length() - 1 + assert(!m_sprcgram[0].found() || !(m_sprcgram[0].length() & (m_sprcgram[0].length() - 1))); + assert(!m_sprcgram[1].found() || !(m_sprcgram[1].length() & (m_sprcgram[1].length() - 1))); + if (m_z80bank) m_z80bank->configure_entries(0, 2, memregion("audiocpu")->base() + 0x8000, 0x8000); @@ -357,7 +361,7 @@ void f1gp2_state::machine_reset() template uint32_t f1gp_state::tile_callback( uint32_t code ) { - return m_sprcgram[Chip][code & (m_sprcgram[Chip].mask()>>1)]; + return m_sprcgram[Chip][code & (m_sprcgram[Chip].length() - 1)]; } void f1gp_state::f1gp(machine_config &config) diff --git a/src/mame/drivers/gunpey.cpp b/src/mame/drivers/gunpey.cpp index db35f1242dc..46890dff81e 100644 --- a/src/mame/drivers/gunpey.cpp +++ b/src/mame/drivers/gunpey.cpp @@ -201,6 +201,39 @@ Release: November 1999 #include "screen.h" #include "speaker.h" +namespace { + +struct state_s +{ + unsigned char *buf; + unsigned char bits; + int num_bits; + unsigned char colour[16]; + int basex; + int ix, iy, iw; + int dx, dy; + int ow, oh; + int ox, oy; + + void set_o(unsigned char v); + unsigned char get_o(int x, int y) const; + + static void hn_bytes_new_colour(state_s &s, unsigned char v, int n); + static void hn_bytes_prev_colour(state_s &s, unsigned char v, int n); + static void hn_copy_directly(state_s &s, unsigned char v, int n); + static void hn_copy_plus_one(state_s &s, unsigned char v, int n); + static void hn_copy_minus_one(state_s &s, unsigned char v, int n); +}; + + +struct huffman_node_s +{ + const char *bits; + void (*func)(state_s &, unsigned char, int); + int arg0_bits; + int arg1_val; +}; + class gunpey_state : public driver_device { @@ -214,21 +247,14 @@ public: , m_blit_rom(*this, "blit_data") { } - // TODO: make these non-static and private - static void set_o(struct state_s *s, unsigned char v); - static unsigned char get_o(struct state_s *s, int x, int y); - static void hn_bytes_new_colour(struct state_s *s, unsigned char v, int n); - static void hn_bytes_prev_colour(struct state_s *s, unsigned char v, int n); - static void hn_copy_directly(struct state_s *s, unsigned char v, int n); - static void hn_copy_plus_one(struct state_s *s, unsigned char v, int n); - static void hn_copy_minus_one(struct state_s *s, unsigned char v, int n); - void gunpey(machine_config &config); - void io_map(address_map &map); - void mem_map(address_map &map); - void init_gunpey(); +protected: + virtual void video_start() override; + private: + void io_map(address_map &map); + void mem_map(address_map &map); void status_w(offs_t offset, uint8_t data); uint8_t status_r(offs_t offset); @@ -239,7 +265,6 @@ private: void output_w(uint8_t data); void vram_bank_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void vregs_addr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - virtual void video_start() override; uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); TIMER_DEVICE_CALLBACK_MEMBER(scanline); TIMER_CALLBACK_MEMBER(blitter_end); @@ -269,8 +294,8 @@ private: uint8_t get_vrom_byte(int x, int y); int write_dest_byte(uint8_t usedata); int decompress_sprite(unsigned char *buf, int ix, int iy, int ow, int oh, int dx, int dy); - int next_node(struct huffman_node_s **res, struct state_s *s); - int get_next_bit(struct state_s *s); + int next_node(const huffman_node_s **res, state_s *s); + int get_next_bit(state_s *s); uint8_t m_irq_cause, m_irq_mask; std::unique_ptr m_blit_buffer; @@ -286,6 +311,9 @@ private: void gunpey_state::video_start() { + // assumes it can make an address mask from m_blit_rom.length() - 1 + assert(!(m_blit_rom.length() & (m_blit_rom.length() - 1))); + m_blit_buffer = std::make_unique(512*512); m_vram = std::make_unique(0x400000); std::fill_n(&m_vram[0], 0x400000, 0xff); @@ -641,23 +669,10 @@ int gunpey_state::write_dest_byte(uint8_t usedata) inline uint8_t gunpey_state::get_vrom_byte(int x, int y) { - return m_blit_rom[((x)+2048 * (y)) & m_blit_rom.mask()]; + return m_blit_rom[((x)+2048 * (y)) & (m_blit_rom.length() - 1)]; } -struct state_s -{ - unsigned char *buf; - unsigned char bits; - int num_bits; - unsigned char colour[16]; - int basex; - int ix, iy, iw; - int dx, dy; - int ow, oh; - int ox, oy; -}; - -inline int gunpey_state::get_next_bit(struct state_s *s) +inline int gunpey_state::get_next_bit(state_s *s) { if (s->num_bits == 0) { @@ -680,178 +695,156 @@ inline int gunpey_state::get_next_bit(struct state_s *s) } -void gunpey_state::set_o(struct state_s *s, unsigned char v) +void state_s::set_o(unsigned char v) { - assert(s->ox >= 0); - assert(s->ox < s->ow); - assert(s->ox < 256); - assert(s->oy >= 0); - assert(s->oy < s->oh); - assert(s->oy < 256); + assert(ox >= 0); + assert(ox < ow); + assert(ox < 256); + assert(oy >= 0); + assert(oy < oh); + assert(oy < 256); unsigned char a = v; - for (int i = 0; i < sizeof(s->colour) / sizeof(*s->colour); i++) + for (int i = 0; i < ARRAY_LENGTH(colour); i++) { - unsigned char b = s->colour[i]; - s->colour[i] = a; + unsigned char b = colour[i]; + colour[i] = a; a = b; if (a == v) break; } - s->buf[((s->dx + s->ox++) & 0x7ff) + (((s->dy + s->oy) & 0x7ff) * 0x800)] = v; + buf[((dx + ox++) & 0x7ff) + (((dy + oy) & 0x7ff) * 0x800)] = v; } -unsigned char gunpey_state::get_o(struct state_s *s, int x, int y) +unsigned char state_s::get_o(int x, int y) const { assert(x >= 0); - assert(x < s->ow); + assert(x < ow); assert(x < 256); assert(y >= 0); - assert(y < s->oh); + assert(y < oh); assert(y < 256); - return s->buf[((s->dx + x) & 0x7ff) + (((s->dy + y) & 0x7ff) * 0x800)]; + return buf[((dx + x) & 0x7ff) + (((dy + y) & 0x7ff) * 0x800)]; } -void gunpey_state::hn_bytes_new_colour(struct state_s *s, unsigned char v, int n) +void state_s::hn_bytes_new_colour(state_s &s, unsigned char v, int n) { for (int i = 0; i < n; i++) - { - set_o(s, v); - } + s.set_o(v); } -void gunpey_state::hn_bytes_prev_colour(struct state_s *s, unsigned char v, int n) +void state_s::hn_bytes_prev_colour(state_s &s, unsigned char v, int n) { - int c = s->colour[v]; + int c = s.colour[v]; for (int i = 0; i < n; i++) - { - set_o(s, c); - } + s.set_o(c); } -void gunpey_state::hn_copy_directly(struct state_s *s, unsigned char v, int n) +void state_s::hn_copy_directly(state_s &s, unsigned char v, int n) { for (int i = 0; i < n; i++) { - if ((s->ox / 12) & 1) - { - set_o(s, get_o(s, s->ox, s->oy + 1)); - } + if ((s.ox / 12) & 1) + s.set_o(s.get_o(s.ox, s.oy + 1)); else - { - set_o(s, get_o(s, s->ox, s->oy - 1)); - } + s.set_o(s.get_o(s.ox, s.oy - 1)); } } -void gunpey_state::hn_copy_plus_one(struct state_s *s, unsigned char v, int n) +void state_s::hn_copy_plus_one(state_s &s, unsigned char v, int n) { for (int i = 0; i < n; i++) { - if ((s->ox / 12) & 1) - { - set_o(s, get_o(s, s->ox + 1, s->oy + 1)); - } + if ((s.ox / 12) & 1) + s.set_o(s.get_o(s.ox + 1, s.oy + 1)); else - { - set_o(s, get_o(s, s->ox + 1, s->oy - 1)); - } + s.set_o(s.get_o(s.ox + 1, s.oy - 1)); } } -void gunpey_state::hn_copy_minus_one(struct state_s *s, unsigned char v, int n) +void state_s::hn_copy_minus_one(state_s &s, unsigned char v, int n) { for (int i = 0; i < n; i++) { - if ((s->ox / 12) & 1) - { - set_o(s, get_o(s, s->ox - 1, s->oy + 1)); - } + if ((s.ox / 12) & 1) + s.set_o(s.get_o(s.ox - 1, s.oy + 1)); else - { - set_o(s, get_o(s, s->ox - 1, s->oy - 1)); - } + s.set_o(s.get_o(s.ox - 1, s.oy - 1)); } } -static struct huffman_node_s -{ - const char *bits; - void (*func)(struct state_s *, unsigned char, int); - int arg0_bits; - int arg1_val; -} hn[] = { - { "11", gunpey_state::hn_bytes_new_colour, 8, 1 }, - { "10111", gunpey_state::hn_bytes_new_colour, 8, 2 }, - { "10110011", gunpey_state::hn_bytes_new_colour, 8, 3 }, - { "1010011000", gunpey_state::hn_bytes_new_colour, 8, 4 }, - { "1010101010000", gunpey_state::hn_bytes_new_colour, 8, 5 }, - { "101010001011110", gunpey_state::hn_bytes_new_colour, 8, 6 }, - { "101010010101110", gunpey_state::hn_bytes_new_colour, 8, 7 }, - { "101010010101111", gunpey_state::hn_bytes_new_colour, 8, 8 }, - { "101010010101100", gunpey_state::hn_bytes_new_colour, 8, 9 }, - { "10101000101100", gunpey_state::hn_bytes_new_colour, 8, 10 }, - { "101010010101101", gunpey_state::hn_bytes_new_colour, 8, 11 }, - { "10101000101101", gunpey_state::hn_bytes_new_colour, 8, 12 }, - { "0", gunpey_state::hn_bytes_prev_colour, 4, 1 }, - { "100", gunpey_state::hn_bytes_prev_colour, 4, 2 }, - { "101011", gunpey_state::hn_bytes_prev_colour, 4, 3 }, - { "1010010", gunpey_state::hn_bytes_prev_colour, 4, 4 }, - { "101010100", gunpey_state::hn_bytes_prev_colour, 4, 5 }, - { "1010100100", gunpey_state::hn_bytes_prev_colour, 4, 6 }, - { "10101010110", gunpey_state::hn_bytes_prev_colour, 4, 7 }, - { "10100111000", gunpey_state::hn_bytes_prev_colour, 4, 8 }, - { "101010101001", gunpey_state::hn_bytes_prev_colour, 4, 9 }, - { "101001111000", gunpey_state::hn_bytes_prev_colour, 4, 10 }, - { "101010010100", gunpey_state::hn_bytes_prev_colour, 4, 11 }, - { "1010011001", gunpey_state::hn_bytes_prev_colour, 4, 12 }, - { "101101", gunpey_state::hn_copy_directly, 0, 2 }, - { "10101011", gunpey_state::hn_copy_directly, 0, 3 }, - { "101010011", gunpey_state::hn_copy_directly, 0, 4 }, - { "101001101", gunpey_state::hn_copy_directly, 0, 5 }, - { "1010011111", gunpey_state::hn_copy_directly, 0, 6 }, - { "1010100011", gunpey_state::hn_copy_directly, 0, 7 }, - { "10101000100", gunpey_state::hn_copy_directly, 0, 8 }, - { "101010101111", gunpey_state::hn_copy_directly, 0, 9 }, - { "101001110010", gunpey_state::hn_copy_directly, 0, 10 }, - { "1010011100111", gunpey_state::hn_copy_directly, 0, 11 }, - { "101100101", gunpey_state::hn_copy_directly, 0, 12 }, - { "1011000", gunpey_state::hn_copy_plus_one, 0, 2 }, - { "101010000", gunpey_state::hn_copy_plus_one, 0, 3 }, - { "10101001011", gunpey_state::hn_copy_plus_one, 0, 4 }, - { "101010001010", gunpey_state::hn_copy_plus_one, 0, 5 }, - { "1010101011101", gunpey_state::hn_copy_plus_one, 0, 6 }, - { "1010101011100", gunpey_state::hn_copy_plus_one, 0, 7 }, - { "1010011110010", gunpey_state::hn_copy_plus_one, 0, 8 }, - { "10101000101110", gunpey_state::hn_copy_plus_one, 0, 9 }, - { "101010001011111", gunpey_state::hn_copy_plus_one, 0, 10 }, - { "1010011110011", gunpey_state::hn_copy_plus_one, 0, 11 }, - { "101000", gunpey_state::hn_copy_minus_one, 0, 2 }, - { "101100100", gunpey_state::hn_copy_minus_one, 0, 3 }, - { "1010011101", gunpey_state::hn_copy_minus_one, 0, 4 }, - { "10101010101", gunpey_state::hn_copy_minus_one, 0, 5 }, - { "101001111011", gunpey_state::hn_copy_minus_one, 0, 6 }, - { "101001111010", gunpey_state::hn_copy_minus_one, 0, 7 }, - { "1010101010001", gunpey_state::hn_copy_minus_one, 0, 8 }, - { "1010011100110", gunpey_state::hn_copy_minus_one, 0, 9 }, - { "10101001010101", gunpey_state::hn_copy_minus_one, 0, 10 }, - { "10101001010100", gunpey_state::hn_copy_minus_one, 0, 11 }, - { NULL }, +static const huffman_node_s hn[] = { + { "11", state_s::hn_bytes_new_colour, 8, 1 }, + { "10111", state_s::hn_bytes_new_colour, 8, 2 }, + { "10110011", state_s::hn_bytes_new_colour, 8, 3 }, + { "1010011000", state_s::hn_bytes_new_colour, 8, 4 }, + { "1010101010000", state_s::hn_bytes_new_colour, 8, 5 }, + { "101010001011110", state_s::hn_bytes_new_colour, 8, 6 }, + { "101010010101110", state_s::hn_bytes_new_colour, 8, 7 }, + { "101010010101111", state_s::hn_bytes_new_colour, 8, 8 }, + { "101010010101100", state_s::hn_bytes_new_colour, 8, 9 }, + { "10101000101100", state_s::hn_bytes_new_colour, 8, 10 }, + { "101010010101101", state_s::hn_bytes_new_colour, 8, 11 }, + { "10101000101101", state_s::hn_bytes_new_colour, 8, 12 }, + { "0", state_s::hn_bytes_prev_colour, 4, 1 }, + { "100", state_s::hn_bytes_prev_colour, 4, 2 }, + { "101011", state_s::hn_bytes_prev_colour, 4, 3 }, + { "1010010", state_s::hn_bytes_prev_colour, 4, 4 }, + { "101010100", state_s::hn_bytes_prev_colour, 4, 5 }, + { "1010100100", state_s::hn_bytes_prev_colour, 4, 6 }, + { "10101010110", state_s::hn_bytes_prev_colour, 4, 7 }, + { "10100111000", state_s::hn_bytes_prev_colour, 4, 8 }, + { "101010101001", state_s::hn_bytes_prev_colour, 4, 9 }, + { "101001111000", state_s::hn_bytes_prev_colour, 4, 10 }, + { "101010010100", state_s::hn_bytes_prev_colour, 4, 11 }, + { "1010011001", state_s::hn_bytes_prev_colour, 4, 12 }, + { "101101", state_s::hn_copy_directly, 0, 2 }, + { "10101011", state_s::hn_copy_directly, 0, 3 }, + { "101010011", state_s::hn_copy_directly, 0, 4 }, + { "101001101", state_s::hn_copy_directly, 0, 5 }, + { "1010011111", state_s::hn_copy_directly, 0, 6 }, + { "1010100011", state_s::hn_copy_directly, 0, 7 }, + { "10101000100", state_s::hn_copy_directly, 0, 8 }, + { "101010101111", state_s::hn_copy_directly, 0, 9 }, + { "101001110010", state_s::hn_copy_directly, 0, 10 }, + { "1010011100111", state_s::hn_copy_directly, 0, 11 }, + { "101100101", state_s::hn_copy_directly, 0, 12 }, + { "1011000", state_s::hn_copy_plus_one, 0, 2 }, + { "101010000", state_s::hn_copy_plus_one, 0, 3 }, + { "10101001011", state_s::hn_copy_plus_one, 0, 4 }, + { "101010001010", state_s::hn_copy_plus_one, 0, 5 }, + { "1010101011101", state_s::hn_copy_plus_one, 0, 6 }, + { "1010101011100", state_s::hn_copy_plus_one, 0, 7 }, + { "1010011110010", state_s::hn_copy_plus_one, 0, 8 }, + { "10101000101110", state_s::hn_copy_plus_one, 0, 9 }, + { "101010001011111", state_s::hn_copy_plus_one, 0, 10 }, + { "1010011110011", state_s::hn_copy_plus_one, 0, 11 }, + { "101000", state_s::hn_copy_minus_one, 0, 2 }, + { "101100100", state_s::hn_copy_minus_one, 0, 3 }, + { "1010011101", state_s::hn_copy_minus_one, 0, 4 }, + { "10101010101", state_s::hn_copy_minus_one, 0, 5 }, + { "101001111011", state_s::hn_copy_minus_one, 0, 6 }, + { "101001111010", state_s::hn_copy_minus_one, 0, 7 }, + { "1010101010001", state_s::hn_copy_minus_one, 0, 8 }, + { "1010011100110", state_s::hn_copy_minus_one, 0, 9 }, + { "10101001010101", state_s::hn_copy_minus_one, 0, 10 }, + { "10101001010100", state_s::hn_copy_minus_one, 0, 11 }, + { nullptr, nullptr, 0, 0 }, }; -int gunpey_state::next_node(struct huffman_node_s **res, struct state_s *s) +int gunpey_state::next_node(const huffman_node_s **res, state_s *s) { char bits[128]; @@ -882,8 +875,8 @@ int gunpey_state::next_node(struct huffman_node_s **res, struct state_s *s) int gunpey_state::decompress_sprite(unsigned char *buf, int ix, int iy, int ow, int oh, int dx, int dy) { - struct huffman_node_s *n; - struct state_s s; + const huffman_node_s *n; + state_s s; unsigned char v; int eol; @@ -922,7 +915,7 @@ int gunpey_state::decompress_sprite(unsigned char *buf, int ix, int iy, int ow, v |= get_next_bit(&s) << i; } - n->func(&s, v, n->arg1_val); + n->func(s, v, n->arg1_val); if ((s.ox % 12) == 0) { @@ -1250,8 +1243,6 @@ ROM_START( gunpey ) ROM_LOAD( "gp_rom5.622", 0x000000, 0x400000, CRC(f79903e0) SHA1(4fd50b4138e64a48ec1504eb8cd172a229e0e965)) // 1xxxxxxxxxxxxxxxxxxxxx = 0xFF ROM_END -void gunpey_state::init_gunpey() -{ -} +} // anonymous namespace -GAME( 2000, gunpey, 0, gunpey, gunpey, gunpey_state, init_gunpey, ROT0, "Bandai / Banpresto", "Gunpey (Japan)", 0 ) +GAME( 2000, gunpey, 0, gunpey, gunpey, gunpey_state, empty_init, ROT0, "Bandai / Banpresto", "Gunpey (Japan)", 0 ) diff --git a/src/mame/drivers/m68705prg.cpp b/src/mame/drivers/m68705prg.cpp index 5cf53deeab3..0bd877b0cf2 100644 --- a/src/mame/drivers/m68705prg.cpp +++ b/src/mame/drivers/m68705prg.cpp @@ -168,7 +168,7 @@ protected: m_pb_val = data; u8 const *const ptr(m_eprom_image->get_rom_base()); - m_mcu->pa_w(ptr ? ptr[m_addr & m_mcu_region.mask()] : 0xff); + m_mcu->pa_w(ptr ? ptr[m_addr & (m_mcu_region.length() - 1)] : 0xff); m_digits[0] = s_7seg[(m_addr >> 0) & 0x0f]; m_digits[1] = s_7seg[(m_addr >> 4) & 0x0f]; diff --git a/src/mame/drivers/metlfrzr.cpp b/src/mame/drivers/metlfrzr.cpp index 7e7183db1bf..e092dc58fb1 100644 --- a/src/mame/drivers/metlfrzr.cpp +++ b/src/mame/drivers/metlfrzr.cpp @@ -79,6 +79,9 @@ private: void metlfrzr_state::video_start() { + // assumes it can make an address mask with m_vram.length() - 1 + assert(!(m_vram.length() & (m_vram.length() - 1))); + m_fg_tilebank = 0; m_rowscroll_enable = false; @@ -98,7 +101,7 @@ void metlfrzr_state::video_start() void metlfrzr_state::legacy_bg_draw(bitmap_ind16 &bitmap,const rectangle &cliprect) { gfx_element *gfx = m_gfxdecode->gfx(m_fg_tilebank); - const uint16_t vram_mask = m_vram.mask() >> 1; + const uint16_t vram_mask = (m_vram.length() - 1) >> 1; int count; int x_scroll_base; int x_scroll_shift; @@ -195,7 +198,7 @@ void metlfrzr_state::metlfrzr_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0x8000, 0xbfff).bankr("bank1"); - map(0xc000, 0xcfff).ram().share("vram"); + map(0xc000, 0xcfff).ram().share(m_vram); map(0xd000, 0xd1ff).ram().w(m_palette, FUNC(palette_device::write_indirect)).share("palette"); map(0xd200, 0xd3ff).ram().w(m_palette, FUNC(palette_device::write_indirect_ext)).share("palette_ext"); diff --git a/src/mame/drivers/mmd2.cpp b/src/mame/drivers/mmd2.cpp index 8bad4fa2b59..e27960aa533 100644 --- a/src/mame/drivers/mmd2.cpp +++ b/src/mame/drivers/mmd2.cpp @@ -113,7 +113,6 @@ public: , m_p(*this, "p%u_%u", 0U, 0U) , m_led_halt(*this, "led_halt") , m_led_hold(*this, "led_hold") - , m_led_inte(*this, "led_inte") { } void mmd2(machine_config &config); @@ -122,9 +121,11 @@ public: DECLARE_INPUT_CHANGED_MEMBER(reset_button); -private: +protected: virtual void machine_start() override; virtual void machine_reset() override; + +private: void round_leds_w(offs_t, u8); void port05_w(u8 data); u8 port01_r(); @@ -134,7 +135,6 @@ private: void scanlines_w(u8 data); void digit_w(u8 data); void status_callback(u8 data); - DECLARE_WRITE_LINE_MEMBER(inte_callback); void io_map(address_map &map); void mem_map(address_map &map); @@ -151,14 +151,13 @@ private: output_finder<3, 8> m_p; output_finder<> m_led_halt; output_finder<> m_led_hold; - output_finder<> m_led_inte; }; void mmd2_state::round_leds_w(offs_t offset, u8 data) { for (u8 i = 0; i < 8; i++) - m_p[offset][i] = BIT(data, i) ? 0 : 1; + m_p[offset][i] = BIT(~data, i); } void mmd2_state::mem_map(address_map &map) @@ -300,16 +299,10 @@ u8 mmd2_state::keyboard_r() void mmd2_state::status_callback(u8 data) { // operate the HALT LED - m_led_halt = ~data & i8080_cpu_device::STATUS_HLTA; + m_led_halt = (~data & i8080_cpu_device::STATUS_HLTA) ? 1 : 0; // operate the HOLD LED - this should connect to the HLDA pin, // but it isn't emulated, using WO instead (whatever that does). - m_led_hold = data & i8080_cpu_device::STATUS_WO; -} - -WRITE_LINE_MEMBER( mmd2_state::inte_callback ) -{ - // operate the INTE LED - m_led_inte = state; + m_led_hold = (data & i8080_cpu_device::STATUS_WO) ? 1 : 0; } void mmd2_state::machine_start() @@ -318,7 +311,7 @@ void mmd2_state::machine_start() m_p.resolve(); m_led_halt.resolve(); m_led_hold.resolve(); - m_led_inte.resolve(); + save_pointer(NAME(m_ram), 0x1400); save_item(NAME(m_digit)); } @@ -374,17 +367,17 @@ void mmd2_state::mmd2(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &mmd2_state::mem_map); m_maincpu->set_addrmap(AS_IO, &mmd2_state::io_map); m_maincpu->out_status_func().set(FUNC(mmd2_state::status_callback)); - m_maincpu->out_inte_func().set(FUNC(mmd2_state::inte_callback)); + m_maincpu->out_inte_func().set_output("led_inte"); // operate the INTE LED /* video hardware */ config.set_default_layout(layout_mmd2); /* Devices */ - i8279_device &kbdc(I8279(config, "i8279", 400000)); // based on divider + i8279_device &kbdc(I8279(config, "i8279", 400000)); // based on divider kbdc.out_sl_callback().set(FUNC(mmd2_state::scanlines_w)); // scan SL lines kbdc.out_disp_callback().set(FUNC(mmd2_state::digit_w)); // display A&B - kbdc.in_rl_callback().set(FUNC(mmd2_state::keyboard_r)); // kbd RL lines - kbdc.in_shift_callback().set_constant(1); // Shift key + kbdc.in_rl_callback().set(FUNC(mmd2_state::keyboard_r)); // kbd RL lines + kbdc.in_shift_callback().set_constant(1); // Shift key kbdc.in_ctrl_callback().set_constant(1); // Cassette diff --git a/src/mame/drivers/psikyo.cpp b/src/mame/drivers/psikyo.cpp index 7de0ddb99b6..1f3fe77f484 100644 --- a/src/mame/drivers/psikyo.cpp +++ b/src/mame/drivers/psikyo.cpp @@ -1011,6 +1011,9 @@ GFXDECODE_END void psikyo_state::machine_start() { + // assumes it can make an address mask with m_spritelut.length() - 1 + assert(!(m_spritelut.length() & (m_spritelut.length() - 1))); + save_item(NAME(m_mcu_status)); save_item(NAME(m_tilemap_bank)); } diff --git a/src/mame/drivers/qvt70.cpp b/src/mame/drivers/qvt70.cpp index 2e40ec44d68..36a3f6468f3 100644 --- a/src/mame/drivers/qvt70.cpp +++ b/src/mame/drivers/qvt70.cpp @@ -45,8 +45,8 @@ class qvt70_state : public driver_device { public: - qvt70_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), + qvt70_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_rombank(*this, "rom"), m_rambank(*this, "ram%d", 0U), @@ -95,11 +95,11 @@ private: void qvt70_state::mem_map(address_map &map) { - map(0x0000, 0x7fff).bankr("rom"); + map(0x0000, 0x7fff).bankr(m_rombank); map(0x8000, 0x8000).w(FUNC(qvt70_state::rombank_w)); map(0xa000, 0xbfff).ram(); - map(0xc000, 0xdfff).bankrw("ram0"); - map(0xe000, 0xffff).bankrw("ram1"); + map(0xc000, 0xdfff).bankrw(m_rambank[0]); + map(0xe000, 0xffff).bankrw(m_rambank[1]); } void qvt70_state::io_map(address_map &map) diff --git a/src/mame/drivers/tvboy.cpp b/src/mame/drivers/tvboy.cpp index becb1da2785..b1588cae326 100644 --- a/src/mame/drivers/tvboy.cpp +++ b/src/mame/drivers/tvboy.cpp @@ -72,7 +72,7 @@ void tvboy_state::tvboy_mem(address_map &map) map(0x0280, 0x029f).mirror(0x0d00).rw("riot", FUNC(riot6532_device::read), FUNC(riot6532_device::write)); #endif map(0x1000, 0x1fff).w(FUNC(tvboy_state::bank_write)); - map(0x1000, 0x1fff).bankr("crom"); + map(0x1000, 0x1fff).bankr(m_crom); } #define MASTER_CLOCK_PAL 3546894 diff --git a/src/mame/drivers/usgames.cpp b/src/mame/drivers/usgames.cpp index 8a7296a5f18..35e16228553 100644 --- a/src/mame/drivers/usgames.cpp +++ b/src/mame/drivers/usgames.cpp @@ -76,8 +76,8 @@ void usgames_state::usgames_map(address_map &map) map(0x2060, 0x2060).w(FUNC(usgames_state::rombank_w)); map(0x2070, 0x2070).portr("UNK2"); map(0x2400, 0x2401).w("aysnd", FUNC(ay8912_device::address_data_w)); - map(0x2800, 0x2fff).ram().w(FUNC(usgames_state::charram_w)).share("charram"); - map(0x3000, 0x3fff).ram().share("videoram"); + map(0x2800, 0x2fff).ram().w(FUNC(usgames_state::charram_w)).share(m_charram); + map(0x3000, 0x3fff).ram().share(m_videoram); map(0x4000, 0x7fff).bankr("bank1"); map(0x8000, 0xffff).rom(); } @@ -96,8 +96,8 @@ void usgames_state::usg185_map(address_map &map) map(0x2441, 0x2441).w("crtc", FUNC(mc6845_device::register_w)); map(0x2460, 0x2460).w(FUNC(usgames_state::rombank_w)); map(0x2470, 0x2470).portr("UNK2"); - map(0x2800, 0x2fff).ram().w(FUNC(usgames_state::charram_w)).share("charram"); - map(0x3000, 0x3fff).ram().share("videoram"); + map(0x2800, 0x2fff).ram().w(FUNC(usgames_state::charram_w)).share(m_charram); + map(0x3000, 0x3fff).ram().share(m_videoram); map(0x4000, 0x7fff).bankr("bank1"); map(0x8000, 0xffff).rom(); } diff --git a/src/mame/includes/coolpool.h b/src/mame/includes/coolpool.h index 989d44a75fb..23f0926de7f 100644 --- a/src/mame/includes/coolpool.h +++ b/src/mame/includes/coolpool.h @@ -1,6 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Aaron Giles,Nicola Salmoria -#define NVRAM_UNLOCK_SEQ_LEN 10 +#ifndef MAME_INCLUDES_COOLPOOL_H +#define MAME_INCLUDES_COOLPOOL_H + +#pragma once #include "cpu/tms34010/tms34010.h" #include "machine/gen_latch.h" @@ -23,6 +26,19 @@ public: , m_dsp_rom(*this, "dspdata") { } + void _9ballsht(machine_config &config); + void coolpool(machine_config &config); + void amerdart(machine_config &config); + + void init_amerdart(); + void init_9ballsht(); + +protected: + virtual void machine_start() override; + +private: + static constexpr unsigned NVRAM_UNLOCK_SEQ_LEN = 10; + required_device m_maincpu; required_device m_dsp; optional_device m_tlc34076; @@ -52,9 +68,11 @@ public: uint8_t m_nvram_write_enable; bool m_old_cmd; uint8_t m_same_cmd_count; + void nvram_thrash_w(offs_t offset, uint16_t data); void nvram_data_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void nvram_thrash_data_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void amerdart_misc_w(uint16_t data); DECLARE_READ_LINE_MEMBER(amerdart_dsp_bio_line_r); uint16_t amerdart_trackball_r(offs_t offset); @@ -64,22 +82,20 @@ public: uint16_t dsp_rom_r(); void dsp_romaddr_w(offs_t offset, uint16_t data); uint16_t coolpool_input_r(offs_t offset); + TMS340X0_TO_SHIFTREG_CB_MEMBER(to_shiftreg); TMS340X0_FROM_SHIFTREG_CB_MEMBER(from_shiftreg); TMS340X0_SCANLINE_RGB32_CB_MEMBER(amerdart_scanline); TMS340X0_SCANLINE_RGB32_CB_MEMBER(coolpool_scanline); - void init_coolpool(); - void init_amerdart(); - void init_9ballsht(); + DECLARE_MACHINE_RESET(amerdart); DECLARE_MACHINE_RESET(coolpool); + TIMER_DEVICE_CALLBACK_MEMBER(nvram_write_timeout); TIMER_DEVICE_CALLBACK_MEMBER(amerdart_audio_int_gen); - void register_state_save(); + int amerdart_trackball_direction(int num, int data); - void _9ballsht(machine_config &config); - void coolpool(machine_config &config); - void amerdart(machine_config &config); + void amerdart_dsp_io_map(address_map &map); void amerdart_dsp_pgm_map(address_map &map); void amerdart_map(address_map &map); @@ -90,3 +106,5 @@ public: void nballsht_dsp_io_map(address_map &map); void nballsht_map(address_map &map); }; + +#endif // MAME_INCLUDES_COOLPOOL_H diff --git a/src/mame/machine/nb1412m2.cpp b/src/mame/machine/nb1412m2.cpp index 5884548201a..0a4edfb590c 100644 --- a/src/mame/machine/nb1412m2.cpp +++ b/src/mame/machine/nb1412m2.cpp @@ -145,6 +145,9 @@ device_memory_interface::space_config_vector nb1412m2_device::memory_space_confi void nb1412m2_device::device_start() { + // assumes it can make an address mask with m_data.length() - 1 + assert(!(m_data.length() & (m_data.length() - 1))); + save_item(NAME(m_command)); save_item(NAME(m_rom_address)); save_item(NAME(m_dac_start_address)); @@ -197,7 +200,7 @@ void nb1412m2_device::device_timer(emu_timer &timer, device_timer_id id, int par dac_value = m_data[m_dac_current_address]; m_dac_cb(dac_value); m_dac_current_address++; - m_dac_current_address&= m_data.mask(); + m_dac_current_address &= m_data.length() - 1; if(dac_value == 0x80) m_dac_playback = false; } diff --git a/src/mame/video/artmagic.cpp b/src/mame/video/artmagic.cpp index 0fede06b4a5..6f3364ef29b 100644 --- a/src/mame/video/artmagic.cpp +++ b/src/mame/video/artmagic.cpp @@ -42,6 +42,9 @@ inline uint16_t *artmagic_state::address_to_vram(offs_t *address) void artmagic_state::video_start() { + // assumes it can make an address mask from m_blitter_base.length() - 1 + assert(!(m_blitter_base.length() & (m_blitter_base.length() - 1))); + save_item(NAME(m_xor)); save_item(NAME(m_is_stoneball)); save_item(NAME(m_blitter_data)); @@ -219,7 +222,7 @@ void artmagic_state::execute_blit() } else /* following lines */ { - int val = m_blitter_base[offset & m_blitter_base.mask()]; + int val = m_blitter_base[offset & (m_blitter_base.length() - 1)]; /* ultennis, stonebal */ last ^= 4; @@ -234,7 +237,7 @@ void artmagic_state::execute_blit() for (j = 0; j < w; j += 4) { - uint16_t val = m_blitter_base[(offset + j/4) & m_blitter_base.mask()]; + uint16_t val = m_blitter_base[(offset + j/4) & (m_blitter_base.length() - 1)]; if (sx < 508) { if (h == 1 && m_is_stoneball) diff --git a/src/mame/video/dcheese.cpp b/src/mame/video/dcheese.cpp index 2f50d3877a3..f851be6c49d 100644 --- a/src/mame/video/dcheese.cpp +++ b/src/mame/video/dcheese.cpp @@ -89,14 +89,17 @@ void dcheese_state::device_timer(emu_timer &timer, device_timer_id id, int param void dcheese_state::video_start() { - /* the destination bitmap is not directly accessible to the CPU */ + // assumes it can make an address mask from m_gfxrom.length() - 1 + assert(!(m_gfxrom.length() & (m_gfxrom.length() - 1))); + + // the destination bitmap is not directly accessible to the CPU m_dstbitmap = std::make_unique(DSTBITMAP_WIDTH, DSTBITMAP_HEIGHT); - /* create timers */ + // create timers m_blitter_timer = timer_alloc(TIMER_BLITTER_SCANLINE); m_signal_irq_timer = timer_alloc(TIMER_SIGNAL_IRQ); - /* register for saving */ + // register for saving save_item(NAME(m_blitter_color)); save_item(NAME(m_blitter_xparam)); save_item(NAME(m_blitter_yparam)); @@ -153,11 +156,11 @@ void dcheese_state::do_blit() s32 const srcmaxy = m_blitter_yparam[1] << 12; s32 const srcx = ((m_blitter_xparam[2] & 0x0fff) | ((m_blitter_xparam[3] & 0x0fff) << 12)) << 7; s32 const srcy = ((m_blitter_yparam[2] & 0x0fff) | ((m_blitter_yparam[3] & 0x0fff) << 12)) << 7; - s32 const dxdx = (s32)(((m_blitter_xparam[4] & 0x0fff) | ((m_blitter_xparam[5] & 0x0fff) << 12)) << 12) >> 12; - s32 const dxdy = (s32)(((m_blitter_xparam[6] & 0x0fff) | ((m_blitter_xparam[7] & 0x0fff) << 12)) << 12) >> 12; - s32 const dydx = (s32)(((m_blitter_yparam[4] & 0x0fff) | ((m_blitter_yparam[5] & 0x0fff) << 12)) << 12) >> 12; - s32 const dydy = (s32)(((m_blitter_yparam[6] & 0x0fff) | ((m_blitter_yparam[7] & 0x0fff) << 12)) << 12) >> 12; - u32 const pagemask = m_gfxrom.mask() >> 18; + s32 const dxdx = s32(((m_blitter_xparam[4] & 0x0fff) | ((m_blitter_xparam[5] & 0x0fff) << 12)) << 12) >> 12; + s32 const dxdy = s32(((m_blitter_xparam[6] & 0x0fff) | ((m_blitter_xparam[7] & 0x0fff) << 12)) << 12) >> 12; + s32 const dydx = s32(((m_blitter_yparam[4] & 0x0fff) | ((m_blitter_yparam[5] & 0x0fff) << 12)) << 12) >> 12; + s32 const dydy = s32(((m_blitter_yparam[6] & 0x0fff) | ((m_blitter_yparam[7] & 0x0fff) << 12)) << 12) >> 12; + u32 const pagemask = (m_gfxrom.length() - 1) >> 18; int const xstart = m_blitter_xparam[14]; int const xend = m_blitter_xparam[15] + 1; int const ystart = m_blitter_yparam[14]; diff --git a/src/mame/video/homedata.cpp b/src/mame/video/homedata.cpp index e801414d2a9..aaef1f2dee4 100644 --- a/src/mame/video/homedata.cpp +++ b/src/mame/video/homedata.cpp @@ -45,7 +45,7 @@ void homedata_state::mrokumei_handleblit( int rom_base ) int dest_addr; int base_addr; int opcode, data, num_tiles; - uint8_t *pBlitData = &m_blit_rom[rom_base & m_blit_rom.mask()]; + uint8_t *pBlitData = &m_blit_rom[rom_base & (m_blit_rom.length() - 1)]; dest_param = m_blitter_param[(m_blitter_param_count - 4) & 3] * 256 + m_blitter_param[(m_blitter_param_count - 3) & 3]; @@ -130,7 +130,7 @@ void homedata_state::reikaids_handleblit( int rom_base ) int flipx; int source_addr, base_addr; int dest_addr; - uint8_t *pBlitData = &m_blit_rom[rom_base & m_blit_rom.mask()]; + uint8_t *pBlitData = &m_blit_rom[rom_base & (m_blit_rom.length() - 1)]; int opcode, data, num_tiles; @@ -227,7 +227,7 @@ void homedata_state::pteacher_handleblit( int rom_base ) int source_addr; int dest_addr, base_addr; int opcode, data, num_tiles; - uint8_t *pBlitData = &m_blit_rom[rom_base & m_blit_rom.mask()]; + uint8_t *pBlitData = &m_blit_rom[rom_base & (m_blit_rom.length() - 1)]; dest_param = m_blitter_param[(m_blitter_param_count - 4) & 3] * 256 + m_blitter_param[(m_blitter_param_count - 3) & 3]; @@ -777,7 +777,7 @@ void homedata_state::reikaids_blitter_start_w(uint8_t data) void homedata_state::pteacher_blitter_start_w(uint8_t data) { - pteacher_handleblit((m_blitter_bank >> 5) * 0x10000 & m_blit_rom.mask()); + pteacher_handleblit((m_blitter_bank >> 5) * 0x10000 & (m_blit_rom.length() - 1)); } diff --git a/src/mame/video/k051316.cpp b/src/mame/video/k051316.cpp index a927bc6c010..5f59e3f8b83 100644 --- a/src/mame/video/k051316.cpp +++ b/src/mame/video/k051316.cpp @@ -150,6 +150,9 @@ void k051316_device::set_bpp(int bpp) void k051316_device::device_start() { + // assumes it can make an address mask with .length() - 1 + assert(!(m_zoom_rom.length() & (m_zoom_rom.length() - 1))); + if (!palette().device().started()) throw device_missing_dependencies(); @@ -210,7 +213,7 @@ u8 k051316_device::rom_r(offs_t offset) { int addr = offset + (m_ctrlram[0x0c] << 11) + (m_ctrlram[0x0d] << 19); addr /= m_pixels_per_byte; - addr &= m_zoom_rom.mask(); + addr &= m_zoom_rom.length() - 1; // popmessage("%s: offset %04x addr %04x", machine().describe_context(), offset, addr); diff --git a/src/mame/video/k051960.cpp b/src/mame/video/k051960.cpp index 2657331e441..42fa9627bd5 100644 --- a/src/mame/video/k051960.cpp +++ b/src/mame/video/k051960.cpp @@ -175,6 +175,9 @@ void k051960_device::set_plane_order(int order) void k051960_device::device_start() { + // assumes it can make an address mask with m_sprite_rom.length() - 1 + assert(!(m_sprite_rom.length() & (m_sprite_rom.length() - 1))); + // make sure our screen is started if (!screen().started()) throw device_missing_dependencies(); @@ -262,7 +265,7 @@ int k051960_device::k051960_fetchromdata( int byte ) m_k051960_cb(&code, &color, &pri, &shadow); addr = (code << 7) | (off1 << 2) | byte; - addr &= m_sprite_rom.mask(); + addr &= m_sprite_rom.length() - 1; // popmessage("%s: addr %06x", machine().describe_context(), addr); diff --git a/src/mame/video/k052109.cpp b/src/mame/video/k052109.cpp index 661ba6ddae0..de90be17715 100644 --- a/src/mame/video/k052109.cpp +++ b/src/mame/video/k052109.cpp @@ -210,6 +210,9 @@ void k052109_device::set_char_ram(bool ram) void k052109_device::device_start() { + // assumes it can make an address mask with m_char_rom.length() - 1 + assert(!m_char_rom.found() || !(m_char_rom.length() & (m_char_rom.length() - 1))); + if (has_screen()) { // make sure our screen is started @@ -353,7 +356,7 @@ u8 k052109_device::read(offs_t offset) m_k052109_cb(0, bank, &code, &color, &flags, &priority); addr = (code << 5) + (offset & 0x1f); - addr &= m_char_rom.mask(); + addr &= m_char_rom.length() - 1; // logerror("%s: off = %04x sub = %02x (bnk = %x) adr = %06x\n", m_maincpu->pc(), offset, m_romsubbank, bank, addr); diff --git a/src/mame/video/k053244_k053245.cpp b/src/mame/video/k053244_k053245.cpp index c5b3ef0a272..0ca46f52847 100644 --- a/src/mame/video/k053244_k053245.cpp +++ b/src/mame/video/k053244_k053245.cpp @@ -119,6 +119,9 @@ void k05324x_device::set_bpp(int bpp) void k05324x_device::device_start() { + // assumes it can make an address mask with m_sprite_rom.length() - 1 + assert(!(m_sprite_rom.length() & (m_sprite_rom.length() - 1))); + if (!palette().device().started()) throw device_missing_dependencies(); @@ -210,7 +213,7 @@ u8 k05324x_device::k053244_r(offs_t offset) addr = (m_rombank << 19) | ((m_regs[11] & 0x7) << 18) | (m_regs[8] << 10) | (m_regs[9] << 2) | ((offset & 3) ^ 1); - addr &= m_sprite_rom.mask(); + addr &= m_sprite_rom.length() - 1; // popmessage("%s: offset %02x addr %06x", machine().describe_context(), offset & 3, addr); diff --git a/src/mame/video/k053246_k053247_k055673.cpp b/src/mame/video/k053246_k053247_k055673.cpp index 26845ed68d3..389c6de42a2 100644 --- a/src/mame/video/k053246_k053247_k055673.cpp +++ b/src/mame/video/k053246_k053247_k055673.cpp @@ -204,7 +204,7 @@ u8 k053247_device::k053246_r(offs_t offset) int addr; addr = (m_kx46_regs[6] << 17) | (m_kx46_regs[7] << 9) | (m_kx46_regs[4] << 1) | ((offset & 1) ^ 1); - addr &= m_gfxrom.mask(); + addr &= m_gfxrom.length() - 1; return m_gfxrom[addr]; } else @@ -899,6 +899,9 @@ k055673_device::k055673_device(const machine_config &mconfig, const char *tag, d void k055673_device::device_start() { + // assumes it can make an address mask with m_gfxrom.length() - 1 + assert(!(m_gfxrom.length() & (m_gfxrom.length() - 1))); + if (!palette().device().started()) throw device_missing_dependencies(); @@ -1065,6 +1068,9 @@ k053247_device::k053247_device(const machine_config &mconfig, device_type type, void k053247_device::device_start() { + // assumes it can make an address mask with m_gfxrom.length() - 1 + assert(!(m_gfxrom.length() & (m_gfxrom.length() - 1))); + if (!palette().device().started()) throw device_missing_dependencies(); diff --git a/src/mame/video/k053246_k053247_k055673.h b/src/mame/video/k053246_k053247_k055673.h index 48e47396c26..d293806244b 100644 --- a/src/mame/video/k053246_k053247_k055673.h +++ b/src/mame/video/k053246_k053247_k055673.h @@ -109,9 +109,9 @@ public: /* alt implementation - to be collapsed */ void zdrawgfxzoom32GP( - bitmap_rgb32 &bitmap, const rectangle &cliprect, - u32 code, u32 color, int flipx, int flipy, int sx, int sy, - int scalex, int scaley, int alpha, int drawmode, int zcode, int pri, u8* gx_objzbuf, u8* gx_shdzbuf); + bitmap_rgb32 &bitmap, const rectangle &cliprect, + u32 code, u32 color, int flipx, int flipy, int sx, int sy, + int scalex, int scaley, int alpha, int drawmode, int zcode, int pri, u8* gx_objzbuf, u8* gx_shdzbuf); void zdrawgfxzoom32GP( bitmap_ind16 &bitmap, const rectangle &cliprect, @@ -119,10 +119,10 @@ public: int scalex, int scaley, int alpha, int drawmode, int zcode, int pri, u8* gx_objzbuf, u8* gx_shdzbuf); template - inline void k053247_draw_single_sprite_gxcore(BitmapClass &bitmap , rectangle const &cliprect, - u8* gx_objzbuf, u8* gx_shdzbuf, int code, u16* gx_spriteram, int offs, - int color, int alpha, int drawmode, int zcode, int pri, - int primask, int shadow, u8* drawmode_table, u8* shadowmode_table, int shdmask) + void k053247_draw_single_sprite_gxcore(BitmapClass &bitmap , rectangle const &cliprect, + u8* gx_objzbuf, u8* gx_shdzbuf, int code, u16* gx_spriteram, int offs, + int color, int alpha, int drawmode, int zcode, int pri, + int primask, int shadow, u8* drawmode_table, u8* shadowmode_table, int shdmask) { int xa,ya,ox,oy,flipx,flipy,mirrorx,mirrory,zoomx,zoomy,scalex,scaley,nozoom; int temp, temp4; @@ -294,22 +294,21 @@ public: template void k053247_draw_yxloop_gx(BitmapClass &bitmap, const rectangle &cliprect, - int code, - int color, - int height, int width, - int zoomx, int zoomy, int flipx, int flipy, - int ox, int oy, - int xa, int ya, - int mirrorx, int mirrory, - int nozoom, - /* gx specifics */ - int pri, - int zcode, int alpha, int drawmode, - u8* gx_objzbuf, u8* gx_shdzbuf, - /* non-gx specifics */ - int primask, - u8* whichtable - ) + int code, + int color, + int height, int width, + int zoomx, int zoomy, int flipx, int flipy, + int ox, int oy, + int xa, int ya, + int mirrorx, int mirrory, + int nozoom, + /* gx specifics */ + int pri, + int zcode, int alpha, int drawmode, + u8* gx_objzbuf, u8* gx_shdzbuf, + /* non-gx specifics */ + int primask, + u8* whichtable) { static const int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 }; static const int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 }; diff --git a/src/mame/video/pastelg.cpp b/src/mame/video/pastelg.cpp index c15ea0eea58..22433ec6140 100644 --- a/src/mame/video/pastelg.cpp +++ b/src/mame/video/pastelg.cpp @@ -25,11 +25,12 @@ void pastelg_state::romsel_w(uint8_t data) m_palbank = ((data & 0x10) >> 4); m_nb1413m3->sndrombank1_w(data); - if ((m_gfxbank << 16) > m_blitter_rom.mask()) + if ((m_gfxbank << 16) >= m_blitter_rom.length()) { #ifdef MAME_DEBUG popmessage("GFXROM BANK OVER!!"); #endif + // FIXME: this isn't a power-of-two size, subtracting 1 doesn't generate a valid mask m_gfxbank &= (m_blitter_rom.length() / 0x20000 - 1); } } @@ -185,7 +186,7 @@ void pastelg_common_state::gfxdraw() { gfxaddr = (m_gfxbank << 16) + ((m_blitter_src_addr + count)); - if (gfxaddr > m_blitter_rom.mask()) + if (gfxaddr >= m_blitter_rom.length()) { #ifdef MAME_DEBUG popmessage("GFXROM ADDRESS OVER!!"); diff --git a/src/mame/video/pgm.cpp b/src/mame/video/pgm.cpp index fab7088207e..a632049b261 100644 --- a/src/mame/video/pgm.cpp +++ b/src/mame/video/pgm.cpp @@ -5,8 +5,10 @@ #include "emu.h" #include "includes/pgm.h" + #include "screen.h" + /****************************************************************************** Sprites @@ -19,8 +21,8 @@ // bg pri is 2 // sprite already here is 1 / 3 -static inline bool get_flipy(u8 flip) { return BIT(flip, 1); } -static inline bool get_flipx(u8 flip) { return BIT(flip, 0); } +static constexpr bool get_flipy(u8 flip) { return BIT(flip, 1); } +static constexpr bool get_flipx(u8 flip) { return BIT(flip, 0); } inline void pgm_state::pgm_draw_pix(int xdrawpos, int pri, u16* dest, u8* destpri, const rectangle &cliprect, u16 srcdat) { @@ -74,7 +76,7 @@ inline void pgm_state::pgm_draw_pix_pri(int xdrawpos, u16* dest, u8* destpri, co inline u8 pgm_state::get_sprite_pix() { - const u8 srcdat = ((m_adata[m_aoffset & m_adata.mask()] >> m_abit) & 0x1f); + const u8 srcdat = ((m_adata[m_aoffset & (m_adata.length() - 1)] >> m_abit) & 0x1f); m_abit += 5; // 5 bit per pixel, 3 pixels in each word; 15 bit used if (m_abit >= 15) { @@ -97,7 +99,7 @@ void pgm_state::draw_sprite_line(int wide, u16* dest, u8* destpri, const rectang for (int xcnt = 0; xcnt < wide; xcnt++) { - u16 msk = m_bdata[m_boffset & m_bdata.mask()]; + u16 msk = m_bdata[m_boffset & (m_bdata.length() - 1)]; for (int x = 0; x < 16; x++) { @@ -170,7 +172,7 @@ void pgm_state::draw_sprite_new_zoomed(int wide, int high, int xpos, int ypos, i int ydrawpos; int xcnt = 0; - m_aoffset = (m_bdata[(m_boffset + 1) & m_bdata.mask()] << 16) | (m_bdata[(m_boffset + 0) & m_bdata.mask()] << 0); + m_aoffset = (m_bdata[(m_boffset + 1) & (m_bdata.length() - 1)] << 16) | (m_bdata[(m_boffset + 0) & (m_bdata.length() - 1)] << 0); m_aoffset = m_aoffset >> 2; m_abit = 0; @@ -328,7 +330,7 @@ void pgm_state::draw_sprite_line_basic(int wide, u16* dest, u8* destpri, const r { for (int xcnt = 0; xcnt < wide; xcnt++) { - u16 msk = m_bdata[m_boffset & m_bdata.mask()]; + u16 msk = m_bdata[m_boffset & (m_bdata.length() - 1)]; for (int x = 0; x < 16; x++) { @@ -367,7 +369,7 @@ void pgm_state::draw_sprite_line_basic(int wide, u16* dest, u8* destpri, const r { for (int xcnt = 0; xcnt < wide; xcnt++) { - u16 msk = m_bdata[m_boffset & m_bdata.mask()]; + u16 msk = m_bdata[m_boffset & (m_bdata.length() - 1)]; for (int x = 0; x < 16; x++) { @@ -413,7 +415,7 @@ void pgm_state::draw_sprite_new_basic(int wide, int high, int xpos, int ypos, in { int ydrawpos; - m_aoffset = (m_bdata[(m_boffset + 1) & m_bdata.mask()] << 16) | (m_bdata[(m_boffset + 0) & m_bdata.mask()] << 0); + m_aoffset = (m_bdata[(m_boffset + 1) & (m_bdata.length() - 1)] << 16) | (m_bdata[(m_boffset + 0) & (m_bdata.length() - 1)] << 0); m_aoffset = m_aoffset >> 2; m_abit = 0; @@ -617,6 +619,10 @@ TILE_GET_INFO_MEMBER(pgm_state::get_bg_tile_info) void pgm_state::video_start() { + // assumes it can make an address mask with .length() - 1 on these + assert(!(m_adata.length() & (m_adata.length() - 1))); + assert(!(m_bdata.length() & (m_bdata.length() - 1))); + m_spritelist = std::make_unique(0xa00/2/5); m_sprite_ptr_pre = m_spritelist.get(); diff --git a/src/mame/video/pgm2.cpp b/src/mame/video/pgm2.cpp index e235549f8c7..1e5e6d311f2 100644 --- a/src/mame/video/pgm2.cpp +++ b/src/mame/video/pgm2.cpp @@ -51,14 +51,14 @@ inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, u32 &palett } palette_offset += palette_inc; - palette_offset &= m_sprites_colour.mask(); + palette_offset &= m_sprites_colour.length() - 1; } else // shrink { if (xzoombit) draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal); palette_offset += palette_inc; - palette_offset &= m_sprites_colour.mask(); + palette_offset &= m_sprites_colour.length() - 1; if (xzoombit) realxdraw += realdraw_inc; @@ -100,7 +100,7 @@ inline void pgm2_state::skip_sprite_chunk(u32 &palette_offset, u32 maskdata, boo palette_offset -= bits; } - palette_offset &= m_sprites_colour.mask(); + palette_offset &= m_sprites_colour.length() - 1; } @@ -130,7 +130,7 @@ inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, u32 &mask_of mask_offset += 4; } - mask_offset &= m_sprites_mask.mask(); + mask_offset &= m_sprites_mask.length() - 1; if (zoomybit) { @@ -214,8 +214,8 @@ void pgm2_state::draw_sprites(const rectangle &cliprect) if (reverse) mask_offset -= 2; - mask_offset &= m_sprites_mask.mask(); - palette_offset &= m_sprites_colour.mask(); + mask_offset &= m_sprites_mask.length() - 1; + palette_offset &= m_sprites_colour.length() - 1; pal |= (pri << 6); // encode priority with the palette for manual mixing later @@ -369,6 +369,10 @@ TILE_GET_INFO_MEMBER(pgm2_state::get_bg_tile_info) void pgm2_state::video_start() { + // assumes it can make an address mask with .length() - 1 on these + assert(!(m_sprites_mask.length() & (m_sprites_mask.length() - 1))); + assert(!(m_sprites_colour.length() & (m_sprites_colour.length() - 1))); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode2, tilemap_get_info_delegate(*this, FUNC(pgm2_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 96, 64); // 0x6000 bytes m_fg_tilemap->set_transparent_pen(0); diff --git a/src/mame/video/psikyo.cpp b/src/mame/video/psikyo.cpp index b2e8d8dfc42..adb01b282b0 100644 --- a/src/mame/video/psikyo.cpp +++ b/src/mame/video/psikyo.cpp @@ -257,7 +257,7 @@ void psikyo_state::get_sprites() for (int dx = xstart; dx != xend; dx += xinc) { m_sprite_ptr_pre->gfx = 0; - m_sprite_ptr_pre->code = m_spritelut[code & m_spritelut.mask()]; + m_sprite_ptr_pre->code = m_spritelut[code & (m_spritelut.length() - 1)]; m_sprite_ptr_pre->color = attr >> 8; m_sprite_ptr_pre->flipx = flipx; m_sprite_ptr_pre->flipy = flipy; @@ -364,7 +364,7 @@ void psikyo_state::get_sprites_bootleg() for (int dx = xstart; dx != xend; dx += xinc) { m_sprite_ptr_pre->gfx = 0; - m_sprite_ptr_pre->code = m_spritelut[code & m_spritelut.mask()]; + m_sprite_ptr_pre->code = m_spritelut[code & (m_spritelut.length() - 1)]; m_sprite_ptr_pre->color = attr >> 8; m_sprite_ptr_pre->flipx = flipx; m_sprite_ptr_pre->flipy = flipy; diff --git a/src/mame/video/rltennis.cpp b/src/mame/video/rltennis.cpp index 6a393babd55..3b5c7bfdc7e 100644 --- a/src/mame/video/rltennis.cpp +++ b/src/mame/video/rltennis.cpp @@ -204,7 +204,7 @@ void rltennis_state::blitter_w(offs_t offset, uint16_t data, uint16_t mem_mask) int address=yy*512+xx; - int pix = m_gfx[ address & m_gfx.mask() ]; + int pix = m_gfx[address & (m_gfx.length() - 1)]; int screen_x=(x&0xff)+((m_blitter[BLT_FLAGS] & BLTFLAG_DST_LR )?256:0); if((pix || force_blit)&& screen_x >0 && y >0 && screen_x < 512 && y < 256 ) @@ -218,6 +218,9 @@ void rltennis_state::blitter_w(offs_t offset, uint16_t data, uint16_t mem_mask) void rltennis_state::video_start() { + // assumes it can make an address mask with m_gfx.length() - 1 + assert(!(m_gfx.length() & (m_gfx.length() - 1))); + m_tmp_bitmap[BITMAP_BG] = std::make_unique(512, 256); m_tmp_bitmap[BITMAP_FG_1] = std::make_unique(512, 256); m_tmp_bitmap[BITMAP_FG_2] = std::make_unique(512, 256); diff --git a/src/mame/video/usgames.cpp b/src/mame/video/usgames.cpp index af8721edf66..ea098f84dda 100644 --- a/src/mame/video/usgames.cpp +++ b/src/mame/video/usgames.cpp @@ -23,6 +23,9 @@ void usgames_state::usgames_palette(palette_device &palette) const void usgames_state::video_start() { + // assumes it can make an address mask from m_videoram.length() - 1 + assert(!(m_videoram.length() & (m_videoram.length() - 1))); + m_gfxdecode->gfx(0)->set_source(m_charram); } @@ -39,7 +42,7 @@ MC6845_UPDATE_ROW(usgames_state::update_row) for (int x = 0; x < x_count; x++) { - int tile_index = (x + ma) & (m_videoram.mask()/2); + int tile_index = (x + ma) & ((m_videoram.length() - 1)/2); int tile = m_videoram[tile_index*2]; int attr = m_videoram[tile_index*2+1]; uint8_t bg_color = attr & 0xf; -- cgit v1.2.3