Commit Graph

97 Commits

Author SHA1 Message Date
hap
b7eac7bf5e addrmap: remove unsupported setter, emumem enforces unmapval 0 or ~0 2020-08-01 20:57:30 +02:00
Vas Crabb
f81fbdb8d4 Make devdelegate more like devcb for configuration. This is a
fundamental change to show device delegates are configured.

Device delegates are now aware of the current device during
configuration and will resolve string tags relative to it.  This means
that device delegates need a device to be supplied on construction so
they can find the machine configuration object.  There's a
one-dimensional array helper to make it easier to construct arrays of
device delegates with the same owner.  (I didn't make an n-dimensional
one because I didn't hit a use case, but it would be a simple addition.)

There's no more bind_relative_to member - just call resolve() like you
would for a devcb.  There's also no need to cast nullptr when creating a
late bind device delegate.  The flip side is that for an overloaded or
non-capturing lambda you'll need to cast to the desired type.

There is one less conditional branch in the hot path for calls for
delegates bound to a function pointer of member function pointer.  This
comes at the cost of one additional unconditional branch in the hot
path for calls to delegates bound to functoids (lambdas, functions that
don't take an object reference, other callable objects).  This applies
to all delegates, not just device delegates.

Address spaces will now print an error message if a late bind error is
encountered while installing a handler.  This will give the range and
address range, hopefully making it easier to guess which memory map is
faulty.

For the simple case of allowing a device_delegate member to be
configured, use a member like this:

    template <typename... T> void set_foo(T &&...args) { m_foo_cb.set(std::forward<T>(args)...); }

For a case where different delegates need to be used depending on the
function signature, see src/emu/screen.h (the screen update function
setters).

Device delegates now take a target specification and function pointer.
The target may be:
* Target omitted, implying the current device being configured.  This
  can only be used during configuration.  It will work as long as the
  current device is not removed/replaced.
* A tag string relative to the current device being configured.  This
  can only be used during configuration.  It will not be callable until
  .resolve() is called.  It will work as long as the current device is
  not removed/replaced.
* A device finder (required_device/optional_device).  The delegate will
  late bind to the current target of the device finder.  It will not
  be callable until .resolve() is called.  It will work properly if the
  target device is replaced, as long as the device finder's base object
  isn't removed/replaced.
* A reference to an object.  It will be callable immediately.  It will
  work as long as the target object is not removed/replaced.

The target types and restrictions are pretty similar to what you already
have on object finders and devcb, so it shouldn't cause any surprises.
Note that dereferencing a device finder will changes the effect.  To
illustrate this:

    ...
    required_device<some_device> m_dev;
    ...
    m_dev(*this, "dev")
    ...
    // will late bind to "dev" relative to *this
    // will work if "dev" hasn't been created yet or is replaced later
    // won't work if *this is removed/replaced
    // won't be callable until resolve() is called
    cb1.set(m_dev, FUNC(some_device::w));
    ...
    // will bind to current target of m_dev
    // will not work if m_dev is not resolved
    // will not work if "dev" is replaced later
    // will be callable immediately
    cb2.set(*m_dev, FUNC(some_device::w));
    ...

The order of the target and name has been reversed for functoids
(lambdas and other callable objects).  This allows the NAME macro to
be used on lambdas and functoids.  For example:

    foo.set_something(NAME([this] (u8 data) { m_something = data; }));

I realise the diagnostic messages get ugly if you use NAME on a large
lambda.  You can still give a literal name, you just have to place it
after the lambda rather than before.  This is uglier, but it's
intentional.  I'm trying to drive developers away from a certain style.
While it's nice that you can put half the driver code in the memory map,
it detracts from readability.  It's hard to visualise the memory range
mappings if the memory map functions are punctuated by large lambdas.
There's also slightly higher overhead for calling a delegate bound to a
functoid.

If the code is prettier for trivial lambdas but uglier for non-trivial
lambdas in address maps, it will hopefully steer people away from
putting non-trivial lambdas in memory maps.

There were some devices that were converted from using plain delegates
without adding bind_relative_to calls.  I fixed some of them (e.g.
LaserDisc) but I probably missed some.  These will likely crash on
unresolved delegate calls.

There are some devices that reset delegates at configuration complete or
start time, preventing them from being set up during configuration (e.g.
src/devices/video/ppu2c0x.cpp and src/devices/machine/68307.cpp).  This
goes against the design principles of how device delegates should be
used, but I didn't change them because I don't trust myself to find all
the places they're used.

I've definitely broken some stuff with this (I know about asterix), so
report issues and bear with me until I get it all fixed.
2019-10-26 12:47:04 +11:00
AJR
88fde72e56 addrmap.h: Replace assert with emu_fatalerror using helper function (nw) 2019-10-05 16:46:48 -04:00
AJR
db87759815 addrmap.h: Assert in case subdevice fails to find things (nw) 2019-10-04 22:48:58 -04:00
AJR
c84a6b2530 Make submaps work with address-shifted spaces (nw)
Note that submaps are now assumed to use an address shift of 0. It is possible, though unlikely, for this to cause some breakage.
2019-06-09 19:26:41 -04:00
Olivier Galibert
e78ca34bac memory,devcb: Put capabilities at parity [O. Galibert] 2018-08-10 09:47:03 +02:00
Olivier Galibert
639c9b85fc memory: Allow simplified versions of handlers [O. Galibert]
A standard memory handler has as a prototype (where uX = u8, u16, u32 or u64):
  uX device::read(address_space &space, offs_t offset, uX mem_mask);
  void device::write(address_space &space, offs_t offset, uX data, uX mem_mask);

We now allow simplified versions which are:
  uX device::read(offs_t offset, uX mem_mask);
  void device::write(offs_t offset, uX data, uX mem_mask);

  uX device::read(offs_t offset);
  void device::write(offs_t offset, uX data);

  uX device::read();
  void device::write(uX data);

Use them at will.  Also consider
(DECLARE_)(READ|WRITE)(8|16|32|64)_MEMBER on the way out, use the
explicit prototypes.

Same for lambdas in the memory map, the parameters are now optional
following the same combinations.
2018-08-02 21:08:47 +02:00
Olivier Galibert
a704ed7b1b emumem: Backend modernization [O. Galibert] 2018-06-29 20:04:28 +02:00
Vas Crabb
40fb13e6e7 lift some stuff needed by devcb3 out of address map entry (nw) 2018-06-13 13:25:15 +10:00
Vas Crabb
93eaa6a494 as if millions of this pointers suddenly cried out in terror, and were suddenly silenced
* streamline templates in addrmap.h
* get rid of overloads on read/write member names - this will become even more important in the near future
2018-06-08 01:29:39 +10:00
Vas Crabb
befb02ba66 Next-gen config: make address map config not look like arse 2018-06-06 23:39:57 +10:00
Vas Crabb
062027276e addrmap.h: reduce code duplication and add support for device finders in more places in memory maps 2018-06-01 11:35:02 +10:00
Olivier Galibert
9ac8320ccc addrmap: Remove the now-unused macros [Vas Crabb, Robbbert] 2018-04-21 16:42:27 +02:00
Olivier Galibert
f155992daa Rename some memory stuff (nw) 2018-03-14 14:05:49 +01:00
ajrhacker
5386ad7284 Generalized support for byte-smeared accesses (nw) (#3207)
The new cswidth address map constructor method overrides the masking normally performed on narrow-width accesses. This entailed a lot of reconfiguration to make the shifting and masking of subunits independent operations. There is unlikely to have any significant performance impact on drivers that don't frequently reconfigure their memory handlers.
2018-02-15 06:43:57 +01:00
Olivier Galibert
c521964316 API change: Memory maps are now methods of the owner class [O. Galibert]
Also, a lot more freedom happened, that's going to be more visible
soon.
2018-02-12 10:04:52 +01:00
Vas Crabb
4e8bb7c7e5 srcclean and regenerate localisations (nw) 2018-01-28 14:25:52 +11:00
Olivier Galibert
d0715c830d memory: Deambiguate handlers, also a hint of things to come (nw) 2018-01-19 08:23:19 +01:00
Olivier Galibert
c46e1007a8 emumem: API change [O. Galibert]
* direct_read_data is now a template which takes the address bus shift
  as a parameter.

* address_space::direct<shift>() is now a template method that takes
  the shift as a parameter and returns a pointer instead of a
  reference

* the address to give to {read|write}_* on address_space or
  direct_read_data is now the address one wants to access

Longer explanation:

Up until now, the {read|write}_* methods required the caller to give
the byte offset instead of the actual address.  That's the same on
byte-addressing CPUs, e.g. the ones everyone knows, but it's different
on the word/long/quad addressing ones (tms, sharc, etc...) or the
bit-addressing one (tms340x0).  Changing that required templatizing
the direct access interface on the bus addressing granularity,
historically called address bus shift.  Also, since everybody was
taking the address of the reference returned by direct(), and
structurally didn't have much choice in the matter, it got changed to
return a pointer directly.

Longest historical explanation:

In a cpu core, the hottest memory access, by far, is the opcode
fetching.  It's also an access with very good locality (doesn't move
much, tends to stay in the same rom/ram zone even when jumping around,
tends not to hit handlers), which makes efficient caching worthwhile
(as in, 30-50% faster core iirc on something like the 6502, but that
was 20 years ago and a number of things changed since then).  In fact,
opcode fetching was, in the distant past, just an array lookup indexed
by pc on an offset pointer, which was updated on branches.  It didn't
stay that way because more elaborate access is often needed (handlers,
banking with instructions crossing a bank...) but it still ends up with
a frontend of "if the address is still in the current range read from
pointer+address otherwise do the slowpath", e.g. two usually correctly
predicted branches plus the read most of the time.

Then the >8 bits cpus arrived.  That was ok, it just required to do
the add to a u8 *, then convert to a u16/u32 * and do the read.  At
the asm level, it was all identical except for the final read, and
read_byte/word/long being separate there was no test (and associated
overhead) added in the path.

Then the word-addressing CPUs arrived with, iirc, the tms cpus used in
atari games.  They require, to read from the pointer, to shift the
address, either explicitely, or implicitely through indexing a u16 *.
There were three possibilities:

1- create a new read_* method for each size and granularity.  That
   amounts to a lot of copy/paste in the end, and functions with
   identical prototypes so the compiler can't detect you're using the
   wrong one.

2- put a variable shift in the read path.  That was too expensive
   especially since the most critical cpus are byte-addressing (68000 at
   the time was the key).  Having bit-adressing cpus which means the
   shift can either be right or left depending on the variable makes
   things even worse.

3- require the caller to do the shift himself when needed.

The last solution was chosen, and starting that day the address was a
byte offset and not the real address.  Which is, actually, quite
surprising when writing a new cpu core or, worse, when using the
read/write methods from the driver code.

But since then, C++ happened.  And, in particular, templates with
non-type parameters.  Suddendly, solution 1 can be done without the
copy/paste and with different types allowing to detect (at runtime,
but systematically and at startup) if you got it wrong, while still
generating optimal code.  So it was time to switch to that solution
and makes the address parameter sane again.  Especially since it makes
mucking in the rest of the memory subsystem code a lot more
understandable.
2017-11-29 10:32:31 +01:00
AJR
59f05991cb Improved way to transform offsets for AM_DEVREAD/_DEVWRITE (nw)
In the past few hours AM_DEVREADWRITE_RSHIFT was created. This has made a lot of MAMEdevs (well, mostly R. Belmont) very angry and has widely been regarded as a bad move.

This patch replaces AM_DEVREADWRITE_RSHIFT with a similar but more functional-looking interface (now known as AM_DEVREADWRITE_MOD), which also now supports address line inversion as well as shifting.
2017-08-23 20:57:28 -04:00
ajrhacker
020a6fbf11 Add address-shifted versions of AM_DEVREAD/_DEVWRITE/_DEVREADWRITE (nw) (#2586)
These new macros make it easy to map devices addressed using higher address lines (which on actual HW helps to reduce loads on the lowest address lines) without needing to set up custom handlers and associated device finders. The implementation should not impact the efficiency of the core memory system (which Olivier Galibert is trying to improve) since the semantic details are contained within C++11 lambdas.
2017-08-22 22:32:12 +02:00
Olivier Galibert
cbbbd07484 dimemory: Lift the cap on the number of address spaces per device [O. Galibert] 2017-07-03 08:03:57 +02:00
Vas Crabb
96c9112785 general cleanup:
* move rarely-used output and pty interfaces out of emu.h
* consolidate and de-duplicate forward declarations, also remove some obsolete ones
* clean up more #include guard macros
* scope down a few more things

(nw) Everyone, please keep forward declarations for src/emu in src/emu/emufwd.h -
this will make it far easier to keep them in sync with declarations than having
them scattered through all the other files.
2017-05-23 15:01:11 +10:00
AJR
659eefe592 Perform unitmask checking during validation in non-debug builds (nw) 2017-04-26 12:51:44 -04:00
Vas Crabb
8179a84458 Introduce u8/u16/u32/u64/s8/s16/s32/s64
* New abbreviated types are in osd and util namespaces, and also in global namespace for things that #include "emu.h"
* Get rid of import of cstdint types to global namespace (C99 does this anyway)
* Remove the cstdint types from everything in emu
* Get rid of U64/S64 macros
* Fix a bug in dps16 caused by incorrect use of macro
* Fix debugcon not checking for "do " prefix case-insensitively
* Fix a lot of messed up tabulation
* More constexpr
* Fix up many __names
2016-11-19 05:38:48 +11:00
Olivier Galibert
762b6b9793 addrmem: Obvious renames and helpers [O. Galibert] 2016-11-10 10:06:40 +01:00
Olivier Galibert
b8d8a89812 addrmap: Dotify [O. Galibert] 2016-11-10 09:22:06 +01:00
Olivier Galibert
1333280f8a addrmap: Stream it [O. Galibert] 2016-11-10 09:22:06 +01:00
Olivier Galibert
bb7dc53d0a addrmap: Change setters into passthroughs [O. Galibert] 2016-11-09 16:25:43 +01:00
Olivier Galibert
5799b36a3a addrmap: De-hand-templatize address_map_entry, remove then unneeded entry parameter [O. Galibert] 2016-11-09 14:20:11 +01:00
Olivier Galibert
8536c82ba1 addrmap: Remove device parameter [O. Galibert] 2016-11-09 12:27:40 +01:00
Miodrag Milanovic
ddb290d5f6 NOTICE (TYPE NAME CONSOLIDATION)
Use standard uint64_t, uint32_t, uint16_t or uint8_t instead of UINT64, UINT32, UINT16 or UINT8
also use standard int64_t, int32_t, int16_t or int8_t instead of INT64, INT32, INT16 or INT8
2016-10-22 13:13:17 +02:00
Vas Crabb
523b8d1de8 Fix GCC6 warnings 2016-06-16 17:35:02 +10:00
Olivier Galibert
b82d7c4aef Memory fun [O.Galibert]
- Added AM_SELECT/addrselect field.  Replaces the old
  AM_MIRROR/AM_MASK combo used to mirror a handler and get the mirrored
  bits in the offset.

- Removed mask and/or mirror from where it didn't belong.  Simplified
  a lot of instances of mask that just weren't needed, especially in bus
  handlers.  Used the short forms of install handlers where possible.

- Replaced the 60s hippy, "It's cool man" range parameter handling in
  map_range that tried to guess what was meant when the values passed
  were not entirely sensible, by a cranky, diner waitress-turned IRS
  auditor curmudgeon.  Main control function has a series of 14 tests
  just to find a reason to fatalerror out your requests.  You have
  been warned.

Some drivers, hopefully not many, will fail the gate-guarding
bureaucrat trials.  Should be easy to fix actually, I worked on the
error messages.  A full regression test would be welcome.
2016-06-14 23:21:58 +02:00
Miodrag Milanovic
96d123b42c NULL->nullptr, instead of DEVCB_NULL use always DEVCB_NOOP to prevent confusion (nw) 2016-04-24 15:38:49 +02:00
Miodrag Milanovic
89c5e1f681 Various cleanups suggested by static analyzer (nw) 2016-04-24 12:58:31 +02:00
AJR
c0f366c613 Devfind revision phase 1, cleaning out some legacy stuff
- Eliminate the cached device_t::m_region pointer and its region() getter method. Devices that need to bind to a region with the same tag should use optional/required_memory_region or optional/required_region_ptr with DEVICE_SELF as the subtag; this improves error checking. (DEVICE_SELF has been moved to device.h for greater visibility in the source.)
- Allow required/optional_region_ptr to specify a specific length which must match that of the region found.
- Implement finder_base::finder_tag() getter for diagnostic purposes.
- Perform some (not very efficient) validity checks on memory region finders instead of allowing them to automatically pass.
- Privatize device_memory_interface::m_addrspace.
2016-04-07 18:59:38 -04:00
Miodrag Milanovic
4e8e3066f8 reverting:
SHA-1: 1f90ceab07

* tags are now strings (nw)
fix start project for custom builds in Visual Studio (nw)
2016-01-20 21:42:13 +01:00
Miodrag Milanovic
1f90ceab07 tags are now strings (nw)
fix start project for custom builds in Visual Studio (nw)
2016-01-16 14:54:42 +01:00
AJR
de31dfcf58 Refactoring memory map validity checking 2015-12-19 18:22:19 -05:00
Miodrag Milanovic
91605d3f4d clang-modernize part 1 (nw) 2015-12-03 18:17:25 +01:00
Oliver Stöneberg
56f03a8f8f fixed -Wunused-local-typedefs warnings with ATTR_UNUSED and enabled it again (nw) 2015-02-05 16:41:05 +01:00
Alex W. Jackson
ace8c59d1a Memory system and Namco improvements: [Alex Jackson]
Explicit regions in address maps (AM_REGION) are now looked up relative to the
device rather than as siblings when in an internal address map (similar to
devices and shared pointers)  Besides being more orthogonal than before, this
allows internal ROMs of MCUs and similar devices to be hooked up in a nicer
and more foolproof way. Updated the m37710 and m5074x (m6502 derivative)
to take advantage of this.

Divided the M37702/M37710 into specific models, with each model having its own
internal address map containing the correct amounts of internal RAM and ROM.

M37702 MCUs found on various Namco PCBs are now all unique devices and have
their respective internal ROMs loaded as device ROMs.

(nw)
Also did some spring (fall) cleaning in addrmap.c/memory.c/dimemory.c

m_devbase (the base device used for tagmap lookup when late-binding handlers and
finding memory regions and shares) is now a reference rather than a pointer,
since we know what it is when the address_map_entry is constructed and it
doesn't change (it depends solely on whether it's an entry in an MCFG-provided
address map or an internal one) And for the same reason, there's now only one
m_devbase per address_map_entry rather than individual copies for
read/write/setoffset/sharedptr.

Removed mysterious unused address_map_entry member "m_region_string", along
with a silly assert probably left over from when Aaron was replacing AM_BASE
with AM_SHARE years ago.

Added a comment noting that "make sure all devices exist" in
device_memory_interface::interface_validity_check() actually does nothing,
like the proverbial goggles. The reason there's just a comment and not a fix
is I haven't figured out how to fix it yet
(is it possible to extract the original device tag that was given to a
proto-delegate? Sorry, the template hell in devdelegate.h and
lib/util/delegate.h makes me want to run screaming like a little girl)
2014-09-18 01:07:22 +00:00
Miodrag Milanovic
79246ab917 More cleanups, there is issue with srcclean that needs to be taken care as well, just doing now what we can 2014-07-22 06:21:54 +00:00
Miodrag Milanovic
11986dff32 removed lot of legacy code in memory system and removed corresponding macros (nw) 2014-05-05 11:22:11 +00:00
Miodrag Milanovic
ad21eca4a2 Removed some not used macros (nw) 2014-04-28 13:59:48 +00:00
Oliver Stöneberg
536b269455 removed some unused AM_*_LEGACY macros (nw) 2014-04-21 17:05:09 +00:00
Alex W. Jackson
6513c5b67e device_gfx_interface and memory system improvements: [Alex Jackson]
Added macros to facilitate declaring gfxdecode info arrays as members
of a device class.

AM_SHAREs in a device's internal address map or its default address map are
now tagmapped as children of that device rather than siblings (analogous
to how handlers in internal/default address maps are scoped).

Converted the Namco C45 to device_gfx_interface.
2014-04-08 15:41:46 +00:00
Aaron Giles
5d0ce54f9e Bulk convert files that already had standard BSD license in my name
to new license tagged form.
2013-10-16 08:14:49 +00:00
Michael Zapf
e93e197bb1 New AM_(DEV)SETOFFSET feature for address maps. 2013-09-21 22:35:53 +00:00