diff options
author | 2020-11-09 03:55:50 +1100 | |
---|---|---|
committer | 2020-11-09 03:55:50 +1100 | |
commit | 538221861b3fa38da4df2e75c0809e594693beba (patch) | |
tree | 3c9b9838212297b5fc37ce1e30b000a29c5bb338 /docs/source/techspecs/device_memory_interface.rst | |
parent | 0f2e755432411f6971fd4de9b2666ac188e8806f (diff) |
-emu/dirom.{h,ipp}: Cleaned up and made it stricter.
* Made it an error to specify address map and explicit ROM region.
* Made it an error if explicitly specified ROM region is not found.
* Made the ROM region tag apply relative to the current device.
-Cleaned up formatting for a couple more documentation pages.
Diffstat (limited to 'docs/source/techspecs/device_memory_interface.rst')
-rw-r--r-- | docs/source/techspecs/device_memory_interface.rst | 170 |
1 files changed, 109 insertions, 61 deletions
diff --git a/docs/source/techspecs/device_memory_interface.rst b/docs/source/techspecs/device_memory_interface.rst index 4efa6a75234..3e9356e2bd6 100644 --- a/docs/source/techspecs/device_memory_interface.rst +++ b/docs/source/techspecs/device_memory_interface.rst @@ -1,18 +1,22 @@ The device_memory_interface =========================== +.. contents:: :local: + + 1. Capabilities --------------- The device memory interface provides devices with the capability of creating address spaces, to which address maps can be associated. -It's used for any device that provides a (logically) address/data bus -other devices can be connected to. It's mainly, but not only, cpus. +It’s used for any device that provides a (logical) address/data bus +that other devices can be connected to. That’s mainly, but not solely, +CPUs. The interface allows for an unlimited set of address spaces, numbered -with small positive values. The IDs should stay small because they -index vectors to keep the lookup fast. Spaces number 0-3 have an -associated constant name: +with small, non-negative values. The IDs index vectors, so they should +stay small to keep the lookup fast. Spaces numbered 0-3 have associated +constant name: +----+---------------+ | ID | Name | @@ -26,91 +30,135 @@ associated constant name: | 3 | AS_OPCODES | +----+---------------+ -Spaces 0 and 3, e.g. AS_PROGRAM and AS_OPCODE, are special for the -debugger and some CPUs. AS_PROGRAM is use by the debugger and the -cpus as the space from with the cpu reads its instructions for the -disassembler. When present, AS_OPCODE is used by the debugger and -some cpus to read the opcode part of the instruction. What opcode -means is device-dependant, for instance for the z80 it's the initial -byte(s) which are read with the M1 signal asserted. For the 68000 is -means every instruction word plus the PC-relative accesses. The main, -but not only, use of AS_OPCODE is to implement hardware decrypting -instructions separately from the data. +Spaces 0 and 3, i.e. ``AS_PROGRAM`` and ``AS_OPCODES``, are special for +the debugger and some CPUs. ``AS_PROGRAM`` is use by the debugger and +the CPUs as the space from which the CPU reads its instructions for the +disassembler. When present, ``AS_OPCODES`` is used by the debugger and +some CPUs to read the opcode part of the instruction. What opcode means +is device-dependant, for instance for the Z80 it's the initial byte(s) +which are read with the M1 signal asserted, while for the 68000 is means +every instruction word plus PC-relative accesses. The main, but not +only, use of ``AS_OPCODES`` is to implement hardware decryption of +instructions separately from data. + 2. Setup -------- -| std::vector<std::pair<int, const address_space_config \*>>\ **memory_space_config**\ (int spacenum) const +.. code-block:: C++ + + std::vector<std::pair<int, const address_space_config *>> memory_space_config() const; The device must override that method to provide a vector of pairs -comprising of a space number and its associated -**address_space_config** describing its configuration. Some examples -to look up when needed: +comprising of a space number and an associated ``address_space_config`` +describing its configuration. Some examples to look up when needed: -* Standard two-space vector: v60_device -* Conditional AS_OPCODE: z80_device -* Inherit config and add a space: m6801_device -* Inherit config and patch a space: tmpz84c011_device +* Standard two-space vector: + `v60_device <https://git.redump.net/mame/tree/src/devices/cpu/v60/v60.cpp?h=mame0226>`_ +* Conditional ``AS_OPCODES``: + `z80_device <https://git.redump.net/mame/tree/src/devices/cpu/z80/z80.cpp?h=mame0226>`_ +* Inherit configuration and add a space: m6801_device +* Inherit configuration and modify a space: + `tmpz84c011_device <https://git.redump.net/mame/tree/src/devices/cpu/z80/tmpz84c011.cpp?h=mame0226>`_ +.. code-block:: C++ -| bool **has_configured_map**\ () const -| bool **has_configured_map**\ (int index) const + bool has_configured_map(int index = 0) const; + +The ``has_configured_map`` method allows to test whether an +``address_map`` has been associated with a given space in the +``memory_space_config`` method . That allows optional memory spaces to +be implemented, such as ``AS_OPCODES`` in certain CPU cores. -The **has_configured_map** method allows to test in the -**memory_space_config** method whether an **address_map** has been -associated with a given space. That allows to implement optional -memory spaces, such as AS_OPCODES in certain cpu cores. The -parameterless version tests for space 0. 3. Associating maps to spaces ----------------------------- -Associating maps to spaces is done at the machine config level, after the device declaration. +Associating maps to spaces is done at the machine configuration level, +after the device is instantiated. + +.. code-block:: C++ + + void set_addrmap(int spacenum, T &obj, Ret (U::*func)(Params...)); + void set_addrmap(int spacenum, Ret (T::*func)(Params...)); + void set_addrmap(int spacenum, address_map_constructor map); + +These function associate a map with a given space. Address maps +associated with non-existent spaces are ignored (no warning given). The +first form takes a reference to an object and a method to call on that +object. The second form takes a method to call on the current device +being configured. The third form takes an ``address_map_constructor`` +to copy. In each case, the function must be callable with reference to +an ``address_map`` object as an argument. -| **MCFG_DEVICE_ADDRESS_MAP**\ (_space, _map) -| **MCFG_DEVICE_PROGRAM_MAP**\ (_map) -| **MCFG_DEVICE_DATA_MAP**\ (_map) -| **MCFG_DEVICE_IO_MAP**\ (_map) -| **MCFG_DEVICE_OPCODES_MAP**\ (_map) +To remove a previously configured address map, call ``set_addrmap`` with +a default-constructed ``address_map_constructor`` (useful for removing a +map for an optional space in a derived machine configuration). -The generic macro and the four specific ones associate a map to a -given space. Address maps associated to non-existing spaces are -ignored (no warning given). devcpu.h defines MCFG_CPU_*_MAP aliases -to the specific macros. +As an example, here’s the address map configuration for the main CPU in +the Hana Yayoi and Hana Fubuki machines, with all distractions removed: -| **MCFG_DEVICE_REMOVE_ADDRESS_MAP**\ (_space) +.. code-block:: C++ -That macro removes a memory map associated to a given space. Useful -when removing a map for an optional space in a machine config -derivative. + class hnayayoi_state : public driver_device + { + public: + void hnayayoi(machine_config &config); + void hnfubuki(machine_config &config); + + private: + required_device<cpu_device> m_maincpu; + + void hnayayoi_map(address_map &map); + void hnayayoi_io_map(address_map &map); + void hnfubuki_map(address_map &map); + }; + + void hnayayoi_state::hnayayoi(machine_config &config) + { + Z80(config, m_maincpu, 20000000/4); + m_maincpu->set_addrmap(AS_PROGRAM, &hnayayoi_state::hnayayoi_map); + m_maincpu->set_addrmap(AS_IO, &hnayayoi_state::hnayayoi_io_map); + } + + void hnayayoi_state::hnfubuki(machine_config &config) + { + hnayayoi(config); + + m_maincpu->set_addrmap(AS_PROGRAM, &hnayayoi_state::hnfubuki_map); + m_maincpu->set_addrmap(AS_IO, address_map_constructor()); + } 4. Accessing the spaces ----------------------- -| address_space &\ **space**\ () const -| address_space &\ **space**\ (int index) const +.. code-block:: C++ + + address_space &space(int index = 0) const; -Returns a given address space post-initialization. The parameterless -version tests for AS_PROGRAM/AS_0. Aborts if the space doesn't exist. +Returns the specified address space post-initialization. The specified +address space must exist. -| bool **has_space**\ () const -| bool **has_space**\ (int index) const +.. code-block:: C++ -Indicates whether a given space actually exists. The parameterless -version tests for AS_PROGRAM/AS_0. + bool has_space(int index = 0) const; + +Indicates whether a given space actually exists. 5. MMU support for disassembler ------------------------------- -| bool **translate**\ (int spacenum, int intention, offs_t &address) +.. code-block:: C++ + + bool translate(int spacenum, int intention, offs_t &address); Does a logical to physical address translation through the device's -MMU. spacenum gives the space number, intention the type of the -future access (TRANSLATE_(READ\|WRITE\|FETCH)(\|_USER\|_DEBUG)) and -address is an inout parameter with the address to translate and its -translated version. Should return true if the translation went -correctly, false if the address is unmapped. - -Note that for some historical reason the device itself must override -the virtual method **memory_translate** with the same signature. +MMU. spacenum gives the space number, intention for the type of the +future access (``TRANSLATE_(READ\|WRITE\|FETCH)(\|_USER\|_DEBUG)``) +and address is an in/out parameter holding the address to translate on +entry and the translated version on return. Should return ``true`` if +the translation went correctly, or ``false`` if the address is unmapped. + +Note that for some historical reason, the device itself must override +the virtual method ``memory_translate`` with the same signature. |