Commit Graph

63 Commits

Author SHA1 Message Date
hap
128640144a emu: correct some file headers (nw) 2020-06-19 12:38:41 +02:00
AJR
f5980cb683 Enforce that width and endianness of directly-mapped ROM regions should match those of the address space (nw)
All of the once-numerous validation failures that this change induced have been fixed in preceding commits. Unmerged drivers may need to be modified to comply with this.
2019-12-11 08:40:51 -05: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
Ivan Vangelista
52d873062c (nw) removed every remaining AM_ macro I could find in comments, but one in emu\memarray.h cause I didn't want to cause a full recompile for this (nw) 2019-10-10 18:02:58 +02:00
Vas Crabb
9a12ab37af Make osd_printf_* use util/strformat semantics.
(nw) This has been a long time coming but it's here at last.  It should
be easier now that logerror, popmessage and osd_printf_* behave like
string_format and stream_format.  Remember the differences from printf:
* Any object with a stream out operator works with %s
* %d, %i, %o, %x, %X, etc. work out the size by magic
* No sign extending promotion to int for short/char
* No widening/narrowing conversions for characters/strings
* Same rules on all platforms, insulated from C runtime library
* No format warnings from compiler
* Assert in debug builds if number of arguments doesn't match format

(nw) Also removed a pile of redundant c_str and string_format, and some
workarounds for not being able to portably format 64-bit integers or
long long.
2019-09-26 20:53:06 +10: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
Vas Crabb
97b6717027 (nw) Clean up the mess on master
This effectively reverts b380514764 and
c24473ddff, restoring the state at
598cd52272.

Before pushing, please check that what you're about to push is sane.
Check your local commit log and ensure there isn't anything out-of-place
before pushing to mainline.  When things like this happen, it wastes
everyone's time.  I really don't need this in a week when real work™ is
busting my balls and I'm behind where I want to be with preparing for
MAME release.
2019-03-26 11:13:37 +11:00
andreasnaive
b380514764 Revert "conflict resolution (nw)"
This reverts commit c24473ddff, reversing
changes made to 009cba4fb8.
2019-03-25 23:13:40 +01:00
AJR
50f045ba74 Eliminate the default address map member of address_space_config (nw)
Since all device address maps are now class methods defined in ordinary C++, default RAM maps can be provided more simply with an explicit has_configured_map check in an internal map definition.

A number of default address maps that probably weren't meant to be overridden have also been changed to ordinary internal maps.
2019-02-17 11:50:17 -05:00
mooglyguy
bf0cfcf13d -keyboard/a1200, changela, goldnpkr, m68705prg, mexico86, pipeline, pitnrun, qix, quizpun2, stfight, tigeroad: Removed MACHINE_CONFIG. [Ryan Holtz]
-m68705, m68hc05: Removed MCFG. [Ryan Holtz]

-qix: First-pass cleanup. [Ryan Holtz]

-core: Fixed spelling of "nonexistent". [Ryan Holtz]
2018-12-14 23:45:04 +01:00
Olivier Galibert
e78ca34bac memory,devcb: Put capabilities at parity [O. Galibert] 2018-08-10 09:47:03 +02:00
Olivier Galibert
d6d228f5f1 I did say it would be dreafully stupid (nw) 2018-08-03 12:40:50 +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
AJR
297b99c0fa Move ROM loading macros to romentry.h and remove romload.h from emu.h (nw) 2018-06-24 09:05:55 -04: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
AJR
7c273f213a Remove some machine().device usage from the core (nw) 2018-05-20 18:39:57 -04:00
AJR
daec5f3639 Relax constraints on address mirroring/global mask combinations. Mirror bits are now allowed to fall outside the driver-specified global mask, though memory map validation requires that they cover the entire masked-out portions of the address space if any do.
This change is intended to expedite debugging of software written for the TMPZ84C015 or similar Z80-based controllers which use 8-bit I/O addressing for the on-chip peripherals but may use either 8-bit or 16-bit addressing externally.
2018-04-11 10:04:31 -04:00
Olivier Galibert
efacbf5f4c Some corners of C/C++ are just a pain (nw) 2018-03-14 20:48:30 +01:00
Olivier Galibert
a13478f416 addrmap: Fix subtle bug with nonsubtle effects, also ensure initialization (nw) 2018-03-14 19:56:26 +01: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
bc909f20e8 emumem: Fix extra-large device map (nw) 2018-02-12 15:04:41 +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
AJR
fe500377ad address_map: Internal maps must now be constructed last to have priority (nw)
This fixes sound in mpatrol.
2018-02-01 20:06:15 -05: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
7c8a1fa409 Pet peeving with extreme prejudice (nw) 2017-11-30 12:29:32 +01:00
smf-
53eb635ddd remove debug code (nw) 2017-11-29 11:43:22 +00: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
Vas Crabb
165da5efa4 Start adding stuff for iterating ROM entries in a more C++ way without needing to allocate everywhere, improve performance of -listxml by another 10% or so 2017-09-22 21:36:37 +10: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
AJR
137a83532b Improve validation checking for address ranges (nw)
arcompact: Attempt at fixing I/O space (nw)
2017-06-22 17:35:08 -04:00
Olivier Galibert
9ef9bee33b Sorry test, it's not that I don't like you anymore, but there's this
AM_IMPORT_FROM guy there, and it's real love this time (nw)
2017-06-21 13:32:02 +02:00
AJR
902d2d924b NPOT subunit compromise (nw)
Handlers with a non-power-of-2 number of subunits are allowed once again. However, the offset multiplier will be rounded up to the nearest power of 2.
2017-04-28 12:23:49 -04:00
AJR
659eefe592 Perform unitmask checking during validation in non-debug builds (nw) 2017-04-26 12:51:44 -04:00
AJR
323eb04ded Memory unit masking and address mirroring fixes (nw)
- Fix a bug which effectively treated AM_MIRROR as AM_SELECT when applied to a single-address range mirrored into a contiguous block. The automatic expansion of zero address masks now only applies to those stemming from (default) configuration, not from optimization. (This allows the assertion in latch8_device to be reinstated.)
- Fix a bug where AM_SELECT applied to narrow-width handlers with a submaximal number of subunits would select the wrong address bits or none at all. (This allows rpunch_gga_w to be WRITE8 as intended.)
- Add more stringent appropriateness checking of unit masks for narrow-width handlers.
2017-03-25 17:35:45 -04:00
Nathan Woods
3a3520e916 Adds a new addrmap.cpp validation intended to catch AM_REGION declarations not tied to anything meaningful 2017-03-09 06:26:08 -05:00
AJR
67df9e6432 Address map fixes (nw)
- tms32025: Correct space of internal data maps
- mc1000: Separate out opcodes map
- addrmap.cpp: Replace a few debug asserts with friendlier error messages (makes validation less dangerous in debug builds)
2016-12-25 01:13:44 -05:00
Vas Crabb
7238415d1f srcclean (nw) 2016-11-27 09:56:49 +11: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
bb7dc53d0a addrmap: Change setters into passthroughs [O. Galibert] 2016-11-09 16:25:43 +01:00
Olivier Galibert
37e5d22fe4 addrmap: Simplify constructor, thanks Micko [O. Galibert] 2016-11-09 15:16:37 +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
AJR
828f824708 Make address maps complain when entry bounds lie outside the global mask (nw)
- Alter a bunch of address maps so all validity checks pass. These includes global address masks in Hexaa and the Newbrain FDC (regression testing should be done here).
- Remove the Lisa wraparound read/write handlers.
2016-08-08 13:38:40 -04:00
AJR
0d6f7bc4b0 Validity checking for AM_MASK/AM_MIRROR/AM_SELECT, based on OG's recent restrictions (nw)
- Update address maps so all drivers pass checks
- Comment out some irregularly-patterned mirrors on RAM areas (needs better solution)
2016-06-17 14:05:34 -04: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