Addressed some Lua scripting pitfalls. (#9294)
Addressed pure virtual function call crash on end of emulation session if you haven't explicitly removed all address space taps, memory corruption on end of emulation session if you haven't explicitly removed all address space change notifiers, and symbol being garbage-collected out from under you while you have parsed expressions or other symbol tables that depend on them. Removed the copy constructor for parsed expressions as the underlying C++ copy constructor appears to be broken, and simplified symbol table constructors. Also made symbol table add methods return the new entry to avoid the need for an extra lookup. Fixed breakpoint/watchpoint objects being inappropriately copied into the tables returned by bplist() and wplist(), allowing the enabled property to be modifiable for breakpoint and watchpoint objects in Lua. Fixed drivers and devices causing a new memory pass-through handler to be allocated on each soft reset, and fixed multiple instances of taps being installed in the event the machine is reset before the tap is removed. Added classes for managing broadcast subscriptions, and adapted address spaces to use this for change notifications.
This commit is contained in:
parent
f0fc52d32c
commit
a185091855
@ -63,6 +63,29 @@ Core classes
|
||||
Many of MAME’s core classes used to implement an emulation session are available
|
||||
to Lua scripts.
|
||||
|
||||
.. _luareference-core-notifiersub:
|
||||
|
||||
Notifier subscription
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Wraps MAME’s ``util::notifier_subscription`` class, which manages a subscription
|
||||
to a broadcast notification.
|
||||
|
||||
Methods
|
||||
^^^^^^^
|
||||
|
||||
subscription:unsubscribe()
|
||||
Unsubscribes from notifications. The subscription will become inactive and
|
||||
no future notifications will be received.
|
||||
|
||||
Properties
|
||||
^^^^^^^^^^
|
||||
|
||||
subscription.is_active (read-only)
|
||||
A Boolean indicating whether the subscription is active. A subscription
|
||||
becomes inactive after explicitly unsubscribing or if the underlying
|
||||
notifier is destroyed.
|
||||
|
||||
.. _luareference-core-attotime:
|
||||
|
||||
Attotime
|
||||
@ -1364,15 +1387,13 @@ space:read_range(start, end, width, [step])
|
||||
greater than or equal to the start address. The width must be 8, 16, 30 or
|
||||
64. If the step is provided, it must be a positive number of elements.
|
||||
space:add_change_notifier(callback)
|
||||
Adds a
|
||||
:ref:`handler change subscription <luareference-mem-spacechangenotif>` to
|
||||
the address space. The callback function is passed a single string as an
|
||||
argument, either ``r`` if read handlers have potentially changed, ``w`` if
|
||||
write handlers have potentially changed, or ``rw`` if both read and write
|
||||
handlers have potentially changed.
|
||||
Add a callback to receive notifications for handler changes in address
|
||||
space. The callback function is passed a single string as an argument,
|
||||
either ``r`` if read handlers have potentially changed, ``w`` if write
|
||||
handlers have potentially changed, or ``rw`` if both read and write handlers
|
||||
have potentially changed.
|
||||
|
||||
Note that handler change subscriptions must be explicitly removed before the
|
||||
emulation session ends.
|
||||
Returns a :ref:`notifier subscription <luareference-core-notifiersub>`.
|
||||
space:install_read_tap(start, end, name, callback)
|
||||
Installs a :ref:`pass-through handler <luareference-mem-tap>` that will
|
||||
receive notifications on reads from the specified range of addresses in the
|
||||
@ -1383,9 +1404,6 @@ space:install_read_tap(start, end, name, callback)
|
||||
and the memory access mask. To modify the data being read, return the
|
||||
modified value from the callback function as an integer. If the callback
|
||||
does not return an integer, the data will not be modified.
|
||||
|
||||
Note that pass-through handlers must be explicitly removed before the
|
||||
emulation session ends.
|
||||
space:install_write_tap(start, end, name, callback)
|
||||
Installs a :ref:`pass-through handler <luareference-mem-tap>` that will
|
||||
receive notifications on write to the specified range of addresses in the
|
||||
@ -1397,9 +1415,6 @@ space:install_write_tap(start, end, name, callback)
|
||||
return the modified value from the callback function as an integer. If the
|
||||
callback does not return an integer, the data will not be modified.
|
||||
|
||||
Note that pass-through handlers must be explicitly removed before the
|
||||
emulation session ends.
|
||||
|
||||
Properties
|
||||
^^^^^^^^^^
|
||||
|
||||
@ -1423,29 +1438,6 @@ space.map (read-only)
|
||||
The configured :ref:`address map <luareference-mem-map>` for the space or
|
||||
``nil``.
|
||||
|
||||
.. _luareference-mem-spacechangenotif:
|
||||
|
||||
Address space change notifier
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tracks a subscription to :ref:`address space <luareference-mem-space>` handler
|
||||
changes. Note that you must remove subscriptions before the emulation session
|
||||
ends.
|
||||
|
||||
Instantiation
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
manager.machine.devices[tag].spaces[name]:add_change_notifier(callback)
|
||||
Adds a handler change subscriptions to an
|
||||
:ref:`address space <luareference-mem-space>`.
|
||||
|
||||
Methods
|
||||
^^^^^^^
|
||||
|
||||
notifier:remove()
|
||||
Removes the notification subscription. The associated callback will not be
|
||||
called on future handler changes for the address space.
|
||||
|
||||
.. _luareference-mem-tap:
|
||||
|
||||
Pass-through handler
|
||||
@ -1454,8 +1446,7 @@ Pass-through handler
|
||||
Tracks a pass-through handler installed in an
|
||||
:ref:`address space <luareference-mem-space>`. A memory pass-through handler
|
||||
receives notifications on accesses to a specified range of addresses, and can
|
||||
modify the data that is read or written if desired. Note that you must remove
|
||||
pass-through handlers before the emulation session ends.
|
||||
modify the data that is read or written if desired.
|
||||
|
||||
Instantiation
|
||||
^^^^^^^^^^^^^
|
||||
@ -3155,15 +3146,22 @@ debugger is not enabled.
|
||||
Instantiation
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
emu.symbol_table(machine, [parent], [device])
|
||||
emu.symbol_table(machine)
|
||||
Creates a new symbol table in the context of the specified machine,
|
||||
optionally supplying a parent symbol table. If a parent symbol table is
|
||||
supplied, it must not be destroyed before the new symbol table. If a device
|
||||
is specified and it implements ``device_memory_interface``, it is used as
|
||||
the base for looking up address spaces and memory regions. Note that if a
|
||||
device that does not implement ``device_memory_interface`` is supplied, it
|
||||
will not be used (address spaces and memory regions will be looked up
|
||||
relative to the root device).
|
||||
emu.symbol_table(parent, [device])
|
||||
Creates a new symbol table with the specified parent symbol table. If a
|
||||
device is specified and it implements ``device_memory_interface``, it will
|
||||
be used as the base for looking up address spaces and memory regions. Note
|
||||
that if a device that does not implement ``device_memory_interface`` is
|
||||
supplied, it will not be used (address spaces and memory regions will be
|
||||
looked up relative to the root device).
|
||||
emu.symbol_table(device)
|
||||
Creates a new symbol table in the context of the specified device. If the
|
||||
device implements ``device_memory_interface``, it will be used as the base
|
||||
for looking up address spaces and memory regions. Note that if a device
|
||||
that does not implement ``device_memory_interface`` is supplied, it will
|
||||
only be used to determine the machine context (address spaces and memory
|
||||
regions will be looked up relative to the root device).
|
||||
|
||||
Methods
|
||||
^^^^^^^
|
||||
@ -3178,6 +3176,8 @@ symbols:add(name, [value])
|
||||
is added with the supplied value. If no value is supplied, a read/write
|
||||
symbol is created with and initial value of zero. If a symbol entry with
|
||||
the specified name already exists in the symbol table, it will be replaced.
|
||||
|
||||
Returns the new :ref:`symbol entry <luareference-debug-symentry>`.
|
||||
symbols:add(name, getter, [setter], [format])
|
||||
Adds a named integer symbol using getter and optional setter callbacks. The
|
||||
name must be a string. The getter must be a function returning an integer
|
||||
@ -3186,10 +3186,14 @@ symbols:add(name, getter, [setter], [format])
|
||||
string for displaying the symbol value may optionally be supplied. If a
|
||||
symbol entry with the specified name already exists in the symbol table, it
|
||||
will be replaced.
|
||||
|
||||
Returns the new :ref:`symbol entry <luareference-debug-symentry>`.
|
||||
symbols:add(name, minparams, maxparams, execute)
|
||||
Adds a named function symbol. The name must be a string. The minimum and
|
||||
maximum numbers of parameters must be integers. If a symbol entry with the
|
||||
specified name already exists in the symbol table, it will be replaced.
|
||||
|
||||
Returns the new :ref:`symbol entry <luareference-debug-symentry>`.
|
||||
symbols:find(name)
|
||||
Returns the :ref:`symbol entry <luareference-debug-symentry>` with the
|
||||
specified name, or ``nil`` if there is no symbol with the specified name in
|
||||
@ -3258,8 +3262,6 @@ emu.parsed_expression(symbols, string, [default_base])
|
||||
default base for interpreting integer literals is not supplied, 16 is used
|
||||
(hexadecimal). Raises an error if the string contains syntax errors or uses
|
||||
undefined symbols.
|
||||
emu.parsed_expression(expression)
|
||||
Creates a copy of an existing parsed expression.
|
||||
|
||||
Methods
|
||||
^^^^^^^
|
||||
@ -3274,7 +3276,7 @@ expression:parse(string)
|
||||
expression is not preserved when attempting to parse an invalid expression
|
||||
string.
|
||||
expression:execute()
|
||||
Evaluates the expression, returning an unsigned integer result. Raises an
|
||||
Evaluates the expression, returning an unsigned integer result. Raises an
|
||||
error if the expression cannot be evaluated (e.g. calling a function with an
|
||||
invalid number of arguments).
|
||||
|
||||
@ -3295,19 +3297,24 @@ Symbol entry
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Wraps MAME’s ``symbol_entry`` class, which represents an entry in a
|
||||
:ref:`symbol table <luareference-debug-symtable>`.
|
||||
:ref:`symbol table <luareference-debug-symtable>`. Note that symbol entries
|
||||
must not be used after the symbol table they belong to is destroyed.
|
||||
|
||||
Instantiation
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
symbols:find(name)
|
||||
Obtains the symbol entry with the specified name from a
|
||||
:ref:`symbol table <luareference-debug-symtable>`, but does not search
|
||||
parent symbol tables.
|
||||
symbols:deep_find(name)
|
||||
Obtains the symbol entry with the specified name from a
|
||||
:ref:`symbol table <luareference-debug-symtable>`, recursively searching
|
||||
parent symbol tables.
|
||||
symbols:add(name, [value])
|
||||
Adds an integer symbol to a
|
||||
:ref:`symbol table <luareference-debug-symtable>`, returning the new symbol
|
||||
entry.
|
||||
symbols:add(name, getter, [setter], [format])
|
||||
Adds an integer symbol to a
|
||||
:ref:`symbol table <luareference-debug-symtable>`, returning the new symbol
|
||||
entry.
|
||||
symbols:add(name, minparams, maxparams, execute)
|
||||
Adds function symbol to a
|
||||
:ref:`symbol table <luareference-debug-symtable>`, returning the new symbol
|
||||
entry.
|
||||
|
||||
Properties
|
||||
^^^^^^^^^^
|
||||
@ -3377,7 +3384,7 @@ emulated CPU device.
|
||||
Instantiation
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
manager.machine.devices[tag]:debug()
|
||||
manager.machine.devices[tag].debug
|
||||
Returns the debugger interface for an emulated CPU device, or ``nil`` if the
|
||||
device is not a CPU.
|
||||
|
||||
@ -3462,7 +3469,7 @@ emulated CPU device.
|
||||
Instantiation
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
manager.machine.devices[tag]:debug():bplist()[bp]
|
||||
manager.machine.devices[tag].debug:bplist()[bp]
|
||||
Gets the specified breakpoint for an emulated CPU device, or ``nil`` if no
|
||||
breakpoint corresponds to the specified index.
|
||||
|
||||
@ -3473,7 +3480,7 @@ breakpoint.index (read-only)
|
||||
The breakpoint’s index. The can be used to enable, disable or clear the
|
||||
breakpoint via the
|
||||
:ref:`CPU debugger interface <luareference-debug-devdebug>`.
|
||||
breakpoint.enabled (read-only)
|
||||
breakpoint.enabled (read/write)
|
||||
A Boolean indicating whether the breakpoint is currently enabled.
|
||||
breakpoint.address (read-only)
|
||||
The breakpoint’s address.
|
||||
@ -3496,7 +3503,7 @@ emulated CPU device.
|
||||
Instantiation
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
manager.machine.devices[tag]:debug():wplist(space)[wp]
|
||||
manager.machine.devices[tag].debug:wplist(space)[wp]
|
||||
Gets the specified watchpoint for an address space of an emulated CPU
|
||||
device, or ``nil`` if no watchpoint in the address space corresponds to the
|
||||
specified index.
|
||||
@ -3508,7 +3515,7 @@ watchpoint.index (read-only)
|
||||
The watchpoint’s index. The can be used to enable, disable or clear the
|
||||
watchpoint via the
|
||||
:ref:`CPU debugger interface <luareference-debug-devdebug>`.
|
||||
watchpoint.enabled (read-only)
|
||||
watchpoint.enabled (read/write)
|
||||
A Boolean indicating whether the watchpoint is currently enabled.
|
||||
watchpoint.type (read-only)
|
||||
Either ``"r"``, ``"w"`` or ``"rw"`` for a read, write or read/write
|
||||
|
@ -98,6 +98,7 @@ end
|
||||
MAME_DIR .. "src/lib/util/msdib.h",
|
||||
MAME_DIR .. "src/lib/util/nanosvg.cpp",
|
||||
MAME_DIR .. "src/lib/util/nanosvg.h",
|
||||
MAME_DIR .. "src/lib/util/notifier.h",
|
||||
MAME_DIR .. "src/lib/util/opresolv.cpp",
|
||||
MAME_DIR .. "src/lib/util/opresolv.h",
|
||||
MAME_DIR .. "src/lib/util/options.cpp",
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "tube_32016.h"
|
||||
|
||||
#include "softlist_dev.h"
|
||||
|
||||
|
||||
@ -242,18 +243,23 @@ void bbc_tube_32016_device::device_reset()
|
||||
// address map during booting
|
||||
program.install_rom(0x000000, 0x007fff, 0xff8000, m_rom->base());
|
||||
|
||||
m_rom_shadow_tap = program.install_write_tap(0x000000, 0xffffff, "rom_shadow_w",[this](offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_write_tap(
|
||||
0x000000, 0xffffff,
|
||||
"rom_shadow_w",
|
||||
[this] (offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// address map after booting
|
||||
m_maincpu->space(AS_PROGRAM).nop_readwrite(0x000000, 0xffffff);
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x000000, m_ram->mask(), 0x7fffff ^ m_ram->mask(), m_ram->pointer());
|
||||
m_maincpu->space(AS_PROGRAM).install_rom(0xf00000, 0xf07fff, 0x038000, m_rom->base());
|
||||
m_maincpu->space(AS_PROGRAM).install_read_port(0xf90000, 0xf90001, 0x00fffe, "CONFIG");
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xfffff0, 0xffffff, read8sm_delegate(*m_ula, FUNC(tube_device::parasite_r)), write8sm_delegate(*m_ula, FUNC(tube_device::parasite_w)), 0xff);
|
||||
});
|
||||
// address map after booting
|
||||
m_maincpu->space(AS_PROGRAM).nop_readwrite(0x000000, 0xffffff);
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x000000, m_ram->mask(), 0x7fffff ^ m_ram->mask(), m_ram->pointer());
|
||||
m_maincpu->space(AS_PROGRAM).install_rom(0xf00000, 0xf07fff, 0x038000, m_rom->base());
|
||||
m_maincpu->space(AS_PROGRAM).install_read_port(0xf90000, 0xf90001, 0x00fffe, "CONFIG");
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xfffff0, 0xffffff, read8sm_delegate(*m_ula, FUNC(tube_device::parasite_r)), write8sm_delegate(*m_ula, FUNC(tube_device::parasite_w)), 0xff);
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,7 +57,7 @@ protected:
|
||||
required_device<ram_device> m_ram;
|
||||
required_memory_region m_rom;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
|
||||
void tube_32016_mem(address_map &map);
|
||||
};
|
||||
|
@ -113,14 +113,19 @@ void bbc_tube_arm_device::device_reset()
|
||||
/* enable the reset vector to be fetched from ROM */
|
||||
m_maincpu->space(AS_PROGRAM).install_rom(0x000000, 0x003fff, 0x3fc000, m_bootstrap->base());
|
||||
|
||||
m_rom_shadow_tap = program.install_write_tap(0x0000000, 0x03fffff, "rom_shadow_w",[this](offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
/* delete this tap */
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_write_tap(
|
||||
0x0000000, 0x03fffff,
|
||||
"rom_shadow_w",
|
||||
[this] (offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
/* delete this tap */
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
/* install ram */
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000000, 0x03fffff, m_ram->pointer());
|
||||
});
|
||||
/* install ram */
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000000, 0x03fffff, m_ram->pointer());
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ private:
|
||||
required_device<ram_device> m_ram;
|
||||
required_memory_region m_bootstrap;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
|
||||
void tube_arm_mem(address_map &map);
|
||||
};
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "mc68k.h"
|
||||
|
||||
#include "machine/6522via.h"
|
||||
#include "machine/6850acia.h"
|
||||
#include "machine/clock.h"
|
||||
@ -161,20 +162,22 @@ void electron_mc68k_device::device_reset()
|
||||
// address map during booting
|
||||
program.install_rom(0x0000, 0x0fff, m_boot_rom->base());
|
||||
|
||||
m_rom_shadow_tap = program.install_read_tap(0x800000, 0xffffff, "rom_shadow_r", [this](offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0x800000, 0xffffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// address map after booting
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x000000, m_ram->mask(), m_ram->pointer());
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// address map after booting
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x000000, m_ram->mask(), m_ram->pointer());
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -48,7 +48,7 @@ private:
|
||||
required_memory_region m_boot_rom;
|
||||
required_memory_region m_exp_rom;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
|
||||
void mem_map(address_map &map);
|
||||
|
||||
|
@ -296,20 +296,22 @@ void vme_cp31_card_device::device_reset()
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
program.install_rom(0x00000000, 0x00000007, m_sysrom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xff000000, 0xff007fff, "rom_shadow_r", [this](offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xff000000, 0xff007fff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x00000000, 0x00000007, m_p_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x00000000, 0x00000007, m_p_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void vme_cp31_card_device::device_timer(emu_timer &timer, device_timer_id id, int param)
|
||||
|
@ -5,8 +5,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vme.h"
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "bus/vme/vme.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "machine/68153bim.h"
|
||||
#include "machine/68230pit.h"
|
||||
@ -44,7 +45,7 @@ private:
|
||||
required_region_ptr<uint32_t> m_sysrom;
|
||||
|
||||
// Pointer to System ROMs needed by bootvect_r and masking RAM buffer for post reset accesses
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
bool m_bus_error;
|
||||
emu_timer *m_bus_error_timer;
|
||||
|
||||
|
@ -582,20 +582,22 @@ void vme_hcpu30_card_device::device_reset()
|
||||
m_fdc->ready_w(false);
|
||||
|
||||
program.install_rom(0x00000000, 0x00000007, m_sysrom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xff000000, 0xff007fff, "rom_shadow_r", [this](offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xff000000, 0xff007fff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x00000000, 0x00000007, m_p_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x00000000, 0x00000007, m_p_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void vme_hcpu30_card_device::device_timer(emu_timer &timer, device_timer_id id, int param)
|
||||
|
@ -5,10 +5,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vme.h"
|
||||
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "bus/nscsi/hd.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "bus/vme/vme.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/clock.h"
|
||||
@ -60,7 +61,7 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER(fdcdrq_callback);
|
||||
|
||||
// Pointer to System ROMs needed by bootvect_r and masking RAM buffer for post reset accesses
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
uint16_t m_irq_state;
|
||||
uint16_t m_irq_mask;
|
||||
uint8_t m_rtc_reg[16];
|
||||
|
@ -235,30 +235,33 @@ void vme_mvme120_device::device_reset()
|
||||
program.install_rom(0x000000, 0x000007, m_sysrom);
|
||||
m_memory_read_count = 0;
|
||||
|
||||
m_rom_shadow_tap = program.install_read_tap(0x000000, 0x000007, "rom_shadow_r",[this](offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
rom_shadow_tap(offset, data, mem_mask);
|
||||
});
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0x000000, 0x000007,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
rom_shadow_tap(offset, data, mem_mask);
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
|
||||
ctrlreg_w(0, 0xFF); // /RESET flips the latch bits to $FF
|
||||
}
|
||||
|
||||
uint16_t vme_mvme120_device::rom_shadow_tap(offs_t address, u16 data, u16 mem_mask)
|
||||
void vme_mvme120_device::rom_shadow_tap(offs_t address, u16 data, u16 mem_mask)
|
||||
{
|
||||
if(!machine().side_effects_disabled())
|
||||
{
|
||||
if(m_memory_read_count >= 3)
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x000000, 0x000007, m_localram);
|
||||
}
|
||||
m_memory_read_count++;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(vme_mvme120_device::watchdog_reset)
|
||||
|
@ -61,8 +61,7 @@ protected:
|
||||
|
||||
required_ioport m_input_s3;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler *m_ram_wwp_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
|
||||
required_region_ptr<uint16_t> m_sysrom;
|
||||
required_shared_ptr<uint16_t> m_localram;
|
||||
@ -80,7 +79,7 @@ protected:
|
||||
uint16_t vme_a16_r();
|
||||
void vme_a16_w(uint16_t data);
|
||||
|
||||
uint16_t rom_shadow_tap(offs_t address, u16 data, u16 mem_mask);
|
||||
void rom_shadow_tap(offs_t address, u16 data, u16 mem_mask);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(watchdog_reset);
|
||||
DECLARE_WRITE_LINE_MEMBER(mfp_interrupt);
|
||||
|
@ -56,7 +56,6 @@ i386_device::i386_device(const machine_config &mconfig, device_type type, const
|
||||
, device_vtlb_interface(mconfig, *this, AS_PROGRAM)
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, program_data_width, program_addr_width, 0, 32, 12)
|
||||
, m_io_config("io", ENDIANNESS_LITTLE, io_data_width, 16, 0)
|
||||
, m_dr_breakpoints{nullptr, nullptr, nullptr, nullptr}
|
||||
, m_smiact(*this)
|
||||
, m_ferr_handler(*this)
|
||||
{
|
||||
@ -2026,10 +2025,7 @@ void i386_device::i386_common_init()
|
||||
m_ferr_handler(0);
|
||||
|
||||
set_icountptr(m_cycles);
|
||||
m_notifier = m_program->add_change_notifier([this](read_or_write mode)
|
||||
{
|
||||
dri_changed();
|
||||
});
|
||||
m_notifier = m_program->add_change_notifier([this] (read_or_write mode) { dri_changed(); });
|
||||
}
|
||||
|
||||
void i386_device::device_start()
|
||||
|
@ -274,8 +274,8 @@ protected:
|
||||
uint32_t m_dr[8]; // Debug registers
|
||||
uint32_t m_tr[8]; // Test registers
|
||||
|
||||
memory_passthrough_handler* m_dr_breakpoints[4];
|
||||
int m_notifier;
|
||||
memory_passthrough_handler m_dr_breakpoints[4];
|
||||
util::notifier_subscription m_notifier;
|
||||
|
||||
//386 Debug Register change handlers.
|
||||
inline void dri_changed();
|
||||
|
@ -2482,7 +2482,7 @@ inline void i386_device::dri_changed()
|
||||
if(!(m_dr[7] & 0xff)) return;
|
||||
for(dr = 0; dr < 4; dr++)
|
||||
{
|
||||
if(m_dr_breakpoints[dr]) m_dr_breakpoints[dr]->remove();
|
||||
m_dr_breakpoints[dr].remove();
|
||||
int dr_enabled = (m_dr[7] & (1 << (dr << 1))) || (m_dr[7] & (1 << ((dr << 1) + 1))); // Check both local enable AND global enable bits for this breakpoint.
|
||||
if(dr_enabled)
|
||||
{
|
||||
@ -2512,9 +2512,9 @@ inline void i386_device::dri_changed()
|
||||
m_dr[6] |= 1 << dr;
|
||||
i386_trap(1,0,0);
|
||||
}
|
||||
}, m_dr_breakpoints[dr]);
|
||||
}, &m_dr_breakpoints[dr]);
|
||||
else if(breakpoint_type == 3) m_dr_breakpoints[dr] = m_program->install_readwrite_tap(phys_addr, phys_addr + 3, "i386_debug_readwrite_breakpoint",
|
||||
[&, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
|
||||
[this, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
|
||||
{
|
||||
if(true_mask & mem_mask)
|
||||
{
|
||||
@ -2522,14 +2522,14 @@ inline void i386_device::dri_changed()
|
||||
i386_trap(1,0,0);
|
||||
}
|
||||
},
|
||||
[&, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
|
||||
[this, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
|
||||
{
|
||||
if(true_mask & mem_mask)
|
||||
{
|
||||
m_dr[6] |= 1 << dr;
|
||||
i386_trap(1,0,0);
|
||||
}
|
||||
}, m_dr_breakpoints[dr]);
|
||||
}, &m_dr_breakpoints[dr]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -458,14 +458,14 @@ device_debug::device_debug(device_t &device)
|
||||
// set up notifiers and clear the passthrough handlers
|
||||
if (m_memory) {
|
||||
int count = m_memory->max_space_count();
|
||||
m_phw.resize(count, nullptr);
|
||||
m_phw.resize(count);
|
||||
for (int i=0; i != count; i++)
|
||||
if (m_memory->has_space(i)) {
|
||||
address_space &space = m_memory->space(i);
|
||||
m_notifiers.push_back(space.add_change_notifier([this, &space](read_or_write mode) { reinstall(space, mode); }));
|
||||
m_notifiers.emplace_back(space.add_change_notifier([this, &space] (read_or_write mode) { reinstall(space, mode); }));
|
||||
}
|
||||
else
|
||||
m_notifiers.push_back(-1);
|
||||
m_notifiers.emplace_back();
|
||||
}
|
||||
|
||||
// set up state-related stuff
|
||||
@ -562,15 +562,14 @@ void device_debug::reinstall(address_space &space, read_or_write mode)
|
||||
int id = space.spacenum();
|
||||
if (u32(mode) & u32(read_or_write::WRITE))
|
||||
{
|
||||
if (m_phw[id])
|
||||
m_phw[id]->remove();
|
||||
m_phw[id].remove();
|
||||
if (m_track_mem)
|
||||
switch (space.data_width())
|
||||
{
|
||||
case 8: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space](offs_t address, u8 &data, u8 ) { write_tracking(space, address, data); }, m_phw[id]); break;
|
||||
case 16: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space](offs_t address, u16 &data, u16) { write_tracking(space, address, data); }, m_phw[id]); break;
|
||||
case 32: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space](offs_t address, u32 &data, u32) { write_tracking(space, address, data); }, m_phw[id]); break;
|
||||
case 64: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space](offs_t address, u64 &data, u64) { write_tracking(space, address, data); }, m_phw[id]); break;
|
||||
case 8: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space] (offs_t address, u8 &data, u8 ) { write_tracking(space, address, data); }, &m_phw[id]); break;
|
||||
case 16: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space] (offs_t address, u16 &data, u16) { write_tracking(space, address, data); }, &m_phw[id]); break;
|
||||
case 32: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space] (offs_t address, u32 &data, u32) { write_tracking(space, address, data); }, &m_phw[id]); break;
|
||||
case 64: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space] (offs_t address, u64 &data, u64) { write_tracking(space, address, data); }, &m_phw[id]); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -239,10 +239,10 @@ private:
|
||||
// (0 = not tracing over,
|
||||
// ~0 = not currently tracing over)
|
||||
};
|
||||
std::unique_ptr<tracer> m_trace; // tracer state
|
||||
std::unique_ptr<tracer> m_trace; // tracer state
|
||||
|
||||
std::vector<memory_passthrough_handler *> m_phw; // passthrough handler reference for each space, write mode
|
||||
std::vector<int> m_notifiers; // notifiers for each space
|
||||
std::vector<memory_passthrough_handler> m_phw; // passthrough handler reference for each space, write mode
|
||||
std::vector<util::notifier_subscription> m_notifiers; // notifiers for each space
|
||||
|
||||
// pc tracking
|
||||
class dasm_pc_tag
|
||||
|
@ -387,10 +387,10 @@ void symbol_table::set_memory_modified_func(memory_modified_func modified)
|
||||
// add - add a new u64 pointer symbol
|
||||
//-------------------------------------------------
|
||||
|
||||
void symbol_table::add(const char *name, read_write rw, u64 *ptr)
|
||||
symbol_entry &symbol_table::add(const char *name, read_write rw, u64 *ptr)
|
||||
{
|
||||
m_symlist.erase(name);
|
||||
m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, rw, ptr));
|
||||
return *m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, rw, ptr)).first->second;
|
||||
}
|
||||
|
||||
|
||||
@ -398,10 +398,10 @@ void symbol_table::add(const char *name, read_write rw, u64 *ptr)
|
||||
// add - add a new value symbol
|
||||
//-------------------------------------------------
|
||||
|
||||
void symbol_table::add(const char *name, u64 value)
|
||||
symbol_entry &symbol_table::add(const char *name, u64 value)
|
||||
{
|
||||
m_symlist.erase(name);
|
||||
m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, value));
|
||||
return *m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, value)).first->second;
|
||||
}
|
||||
|
||||
|
||||
@ -409,10 +409,10 @@ void symbol_table::add(const char *name, u64 value)
|
||||
// add - add a new register symbol
|
||||
//-------------------------------------------------
|
||||
|
||||
void symbol_table::add(const char *name, getter_func getter, setter_func setter, const std::string &format_string)
|
||||
symbol_entry &symbol_table::add(const char *name, getter_func getter, setter_func setter, const std::string &format_string)
|
||||
{
|
||||
m_symlist.erase(name);
|
||||
m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, getter, setter, format_string));
|
||||
return *m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, getter, setter, format_string)).first->second;
|
||||
}
|
||||
|
||||
|
||||
@ -420,10 +420,10 @@ void symbol_table::add(const char *name, getter_func getter, setter_func setter,
|
||||
// add - add a new function symbol
|
||||
//-------------------------------------------------
|
||||
|
||||
void symbol_table::add(const char *name, int minparams, int maxparams, execute_func execute)
|
||||
symbol_entry &symbol_table::add(const char *name, int minparams, int maxparams, execute_func execute)
|
||||
{
|
||||
m_symlist.erase(name);
|
||||
m_symlist.emplace(name, std::make_unique<function_symbol_entry>(*this, name, minparams, maxparams, execute));
|
||||
return *m_symlist.emplace(name, std::make_unique<function_symbol_entry>(*this, name, minparams, maxparams, execute)).first->second;
|
||||
}
|
||||
|
||||
|
||||
|
@ -175,15 +175,16 @@ public:
|
||||
// getters
|
||||
const std::unordered_map<std::string, std::unique_ptr<symbol_entry>> &entries() const { return m_symlist; }
|
||||
symbol_table *parent() const { return m_parent; }
|
||||
running_machine &machine() { return m_machine; }
|
||||
|
||||
// setters
|
||||
void set_memory_modified_func(memory_modified_func modified);
|
||||
|
||||
// symbol access
|
||||
void add(const char *name, read_write rw, u64 *ptr = nullptr);
|
||||
void add(const char *name, u64 constvalue);
|
||||
void add(const char *name, getter_func getter, setter_func setter = nullptr, const std::string &format_string = "");
|
||||
void add(const char *name, int minparams, int maxparams, execute_func execute);
|
||||
symbol_entry &add(const char *name, read_write rw, u64 *ptr = nullptr);
|
||||
symbol_entry &add(const char *name, u64 constvalue);
|
||||
symbol_entry &add(const char *name, getter_func getter, setter_func setter = nullptr, const std::string &format_string = "");
|
||||
symbol_entry &add(const char *name, int minparams, int maxparams, execute_func execute);
|
||||
symbol_entry *find(const char *name) const { if (name) { auto search = m_symlist.find(name); if (search != m_symlist.end()) return search->second.get(); else return nullptr; } else return nullptr; }
|
||||
symbol_entry *find_deep(const char *name);
|
||||
|
||||
|
@ -184,11 +184,9 @@ debug_watchpoint::debug_watchpoint(
|
||||
|
||||
debug_watchpoint::~debug_watchpoint()
|
||||
{
|
||||
m_space.remove_change_notifier(m_notifier);
|
||||
if (m_phr)
|
||||
m_phr->remove();
|
||||
if (m_phw)
|
||||
m_phw->remove();
|
||||
m_notifier.reset();
|
||||
m_phr.remove();
|
||||
m_phw.remove();
|
||||
}
|
||||
|
||||
void debug_watchpoint::setEnabled(bool value)
|
||||
@ -201,10 +199,8 @@ void debug_watchpoint::setEnabled(bool value)
|
||||
else
|
||||
{
|
||||
m_installing = true;
|
||||
if(m_phr)
|
||||
m_phr->remove();
|
||||
if(m_phw)
|
||||
m_phw->remove();
|
||||
m_phr.remove();
|
||||
m_phw.remove();
|
||||
m_installing = false;
|
||||
}
|
||||
}
|
||||
@ -215,24 +211,28 @@ void debug_watchpoint::install(read_or_write mode)
|
||||
if (m_installing)
|
||||
return;
|
||||
m_installing = true;
|
||||
if ((u32(mode) & u32(read_or_write::READ)) && m_phr)
|
||||
m_phr->remove();
|
||||
if ((u32(mode) & u32(read_or_write::WRITE)) && m_phw)
|
||||
m_phw->remove();
|
||||
if (u32(mode) & u32(read_or_write::READ))
|
||||
m_phr.remove();
|
||||
if (u32(mode) & u32(read_or_write::WRITE))
|
||||
m_phw.remove();
|
||||
std::string name = util::string_format("wp@%x", m_address);
|
||||
switch (m_space.data_width())
|
||||
{
|
||||
case 8:
|
||||
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
|
||||
m_phr = m_space.install_read_tap(m_start_address[0], m_end_address[0], name,
|
||||
[this](offs_t offset, u8 &data, u8 mem_mask) {
|
||||
triggered(read_or_write::READ, offset, data, mem_mask);
|
||||
}, m_phr);
|
||||
m_phr = m_space.install_read_tap(
|
||||
m_start_address[0], m_end_address[0], name,
|
||||
[this](offs_t offset, u8 &data, u8 mem_mask) {
|
||||
triggered(read_or_write::READ, offset, data, mem_mask);
|
||||
},
|
||||
&m_phr);
|
||||
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
|
||||
m_phw = m_space.install_write_tap(m_start_address[0], m_end_address[0], name,
|
||||
[this](offs_t offset, u8 &data, u8 mem_mask) {
|
||||
triggered(read_or_write::WRITE, offset, data, mem_mask);
|
||||
}, m_phw);
|
||||
m_phw = m_space.install_write_tap(
|
||||
m_start_address[0], m_end_address[0], name,
|
||||
[this](offs_t offset, u8 &data, u8 mem_mask) {
|
||||
triggered(read_or_write::WRITE, offset, data, mem_mask);
|
||||
},
|
||||
&m_phw);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
@ -241,17 +241,21 @@ void debug_watchpoint::install(read_or_write mode)
|
||||
{
|
||||
u16 mask = m_masks[i];
|
||||
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
|
||||
m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u16 &data, u16 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::READ, offset, data, mem_mask);
|
||||
}, m_phr);
|
||||
m_phr = m_space.install_read_tap(
|
||||
m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u16 &data, u16 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::READ, offset, data, mem_mask);
|
||||
},
|
||||
&m_phr);
|
||||
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
|
||||
m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u16 &data, u16 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::WRITE, offset, data, mem_mask);
|
||||
}, m_phw);
|
||||
m_phw = m_space.install_write_tap(
|
||||
m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u16 &data, u16 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::WRITE, offset, data, mem_mask);
|
||||
},
|
||||
&m_phw);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -261,17 +265,21 @@ void debug_watchpoint::install(read_or_write mode)
|
||||
{
|
||||
u32 mask = m_masks[i];
|
||||
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
|
||||
m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u32 &data, u32 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::READ, offset, data, mem_mask);
|
||||
}, m_phr);
|
||||
m_phr = m_space.install_read_tap(
|
||||
m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u32 &data, u32 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::READ, offset, data, mem_mask);
|
||||
},
|
||||
&m_phr);
|
||||
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
|
||||
m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u32 &data, u32 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::WRITE, offset, data, mem_mask);
|
||||
}, m_phw);
|
||||
m_phw = m_space.install_write_tap(
|
||||
m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u32 &data, u32 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::WRITE, offset, data, mem_mask);
|
||||
},
|
||||
&m_phw);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -281,17 +289,20 @@ void debug_watchpoint::install(read_or_write mode)
|
||||
{
|
||||
u64 mask = m_masks[i];
|
||||
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
|
||||
m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u64 &data, u64 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::READ, offset, data, mem_mask);
|
||||
}, m_phr);
|
||||
m_phr = m_space.install_read_tap(
|
||||
m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u64 &data, u64 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::READ, offset, data, mem_mask);
|
||||
},
|
||||
&m_phr);
|
||||
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
|
||||
m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
|
||||
[this, mask](offs_t offset, u64 &data, u64 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::WRITE, offset, data, mem_mask);
|
||||
}, m_phw);
|
||||
[this, mask](offs_t offset, u64 &data, u64 mem_mask) {
|
||||
if (mem_mask & mask)
|
||||
triggered(read_or_write::WRITE, offset, data, mem_mask);
|
||||
},
|
||||
&m_phw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -102,8 +102,8 @@ private:
|
||||
void triggered(read_or_write type, offs_t address, u64 data, u64 mem_mask);
|
||||
|
||||
device_debug * m_debugInterface; // the interface we were created from
|
||||
memory_passthrough_handler *m_phr; // passthrough handler reference, read access
|
||||
memory_passthrough_handler *m_phw; // passthrough handler reference, write access
|
||||
memory_passthrough_handler m_phr; // passthrough handler reference, read access
|
||||
memory_passthrough_handler m_phw; // passthrough handler reference, write access
|
||||
address_space & m_space; // address space
|
||||
int m_index; // user reported index
|
||||
bool m_enabled; // enabled?
|
||||
@ -112,7 +112,7 @@ private:
|
||||
offs_t m_length; // length of watch area
|
||||
parsed_expression m_condition; // condition
|
||||
std::string m_action; // action
|
||||
int m_notifier; // address map change notifier id
|
||||
util::notifier_subscription m_notifier; // address map change notifier ID
|
||||
|
||||
offs_t m_start_address[3]; // the start addresses of the checks to install
|
||||
offs_t m_end_address[3]; // the end addresses
|
||||
|
@ -18,6 +18,9 @@
|
||||
#ifndef __EMU_H__
|
||||
#define __EMU_H__
|
||||
|
||||
// get forward declarations before anything else
|
||||
#include "emufwd.h"
|
||||
|
||||
#include <list>
|
||||
#include <forward_list>
|
||||
#include <vector>
|
||||
|
@ -865,62 +865,62 @@ void address_space_installer::populate_map_entry(const address_map_entry &entry,
|
||||
|
||||
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 8-bits wide bus read tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 16-bits wide bus read tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 32-bits wide bus read tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 64-bits wide bus read tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 8-bits wide bus write tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 16-bits wide bus write tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 32-bits wide bus write tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 64-bits wide bus write tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 8-bits wide bus read/write tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 16-bits wide bus read/write tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Tryingw to install a 32-bits wide bus read/write tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
memory_passthrough_handler address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
{
|
||||
fatalerror("Trying to install a 64-bits wide bus read/write tap in a %d-bits wide bus\n", data_width());
|
||||
}
|
||||
|
131
src/emu/emumem.h
131
src/emu/emumem.h
@ -17,6 +17,8 @@
|
||||
#ifndef MAME_EMU_EMUMEM_H
|
||||
#define MAME_EMU_EMUMEM_H
|
||||
|
||||
#include "notifier.h"
|
||||
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
@ -50,6 +52,14 @@ enum class read_or_write
|
||||
};
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// FORWARD DECLARATIONS
|
||||
//**************************************************************************
|
||||
|
||||
class handler_entry;
|
||||
template<int Width, int AddrShift> class handler_entry_read_passthrough;
|
||||
template<int Width, int AddrShift> class handler_entry_write_passthrough;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
@ -90,7 +100,7 @@ struct memory_entry_context {
|
||||
|
||||
struct memory_entry {
|
||||
offs_t start, end;
|
||||
class handler_entry *entry;
|
||||
handler_entry *entry;
|
||||
std::vector<memory_entry_context> context;
|
||||
};
|
||||
|
||||
@ -465,6 +475,29 @@ constexpr int handler_entry_dispatch_lowbits(int highbits, int width, int ashift
|
||||
width + ashift;
|
||||
}
|
||||
|
||||
|
||||
// =====================-> Passthrough handler management structure
|
||||
|
||||
class memory_passthrough_handler_impl
|
||||
{
|
||||
public:
|
||||
memory_passthrough_handler_impl(address_space &space) : m_space(space) {}
|
||||
memory_passthrough_handler_impl(memory_passthrough_handler_impl const &) = delete;
|
||||
|
||||
void remove();
|
||||
|
||||
private:
|
||||
address_space &m_space;
|
||||
std::unordered_set<handler_entry *> m_handlers;
|
||||
|
||||
void add_handler(handler_entry *handler) { m_handlers.insert(handler); }
|
||||
void remove_handler(handler_entry *handler) { m_handlers.erase(m_handlers.find(handler)); }
|
||||
|
||||
friend address_space;
|
||||
template<int Width, int AddrShift> friend class ::handler_entry_read_passthrough;
|
||||
template<int Width, int AddrShift> friend class ::handler_entry_write_passthrough;
|
||||
};
|
||||
|
||||
} // namespace emu::detail
|
||||
|
||||
|
||||
@ -561,8 +594,6 @@ protected:
|
||||
|
||||
// Provides the populate/read/get_ptr/lookup API
|
||||
|
||||
template<int Width, int AddrShift> class handler_entry_read_passthrough;
|
||||
|
||||
template<int Width, int AddrShift> class handler_entry_read : public handler_entry
|
||||
{
|
||||
public:
|
||||
@ -596,7 +627,7 @@ public:
|
||||
virtual void populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read<Width, AddrShift> *handler);
|
||||
virtual void populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read<Width, AddrShift> *handler);
|
||||
|
||||
inline void populate_mismatched(offs_t start, offs_t end, offs_t mirror, const memory_units_descriptor<Width, AddrShift> &descriptor) {
|
||||
void populate_mismatched(offs_t start, offs_t end, offs_t mirror, const memory_units_descriptor<Width, AddrShift> &descriptor) {
|
||||
start &= ~NATIVE_MASK;
|
||||
end |= NATIVE_MASK;
|
||||
std::vector<mapping> mappings;
|
||||
@ -609,7 +640,7 @@ public:
|
||||
virtual void populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, const memory_units_descriptor<Width, AddrShift> &descriptor, u8 rkey, std::vector<mapping> &mappings);
|
||||
virtual void populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, const memory_units_descriptor<Width, AddrShift> &descriptor, std::vector<mapping> &mappings);
|
||||
|
||||
inline void populate_passthrough(offs_t start, offs_t end, offs_t mirror, handler_entry_read_passthrough<Width, AddrShift> *handler) {
|
||||
void populate_passthrough(offs_t start, offs_t end, offs_t mirror, handler_entry_read_passthrough<Width, AddrShift> *handler) {
|
||||
start &= ~NATIVE_MASK;
|
||||
end |= NATIVE_MASK;
|
||||
std::vector<mapping> mappings;
|
||||
@ -636,8 +667,6 @@ public:
|
||||
|
||||
// Provides the populate/write/get_ptr/lookup API
|
||||
|
||||
template<int Width, int AddrShift> class handler_entry_write_passthrough;
|
||||
|
||||
template<int Width, int AddrShift> class handler_entry_write : public handler_entry
|
||||
{
|
||||
public:
|
||||
@ -711,20 +740,21 @@ public:
|
||||
// =====================-> Passthrough handler management structure
|
||||
class memory_passthrough_handler
|
||||
{
|
||||
template<int Width, int AddrShift> friend class handler_entry_read_passthrough;
|
||||
template<int Width, int AddrShift> friend class handler_entry_write_passthrough;
|
||||
|
||||
public:
|
||||
memory_passthrough_handler(address_space &space) : m_space(space) {}
|
||||
memory_passthrough_handler() : m_impl() {}
|
||||
memory_passthrough_handler(std::shared_ptr<emu::detail::memory_passthrough_handler_impl> const &impl) : m_impl(impl) {}
|
||||
|
||||
inline void remove();
|
||||
void remove()
|
||||
{
|
||||
auto impl(m_impl.lock());
|
||||
if (impl)
|
||||
impl->remove();
|
||||
}
|
||||
|
||||
private:
|
||||
address_space &m_space;
|
||||
std::unordered_set<handler_entry *> m_handlers;
|
||||
std::weak_ptr<emu::detail::memory_passthrough_handler_impl> m_impl;
|
||||
|
||||
void add_handler(handler_entry *handler) { m_handlers.insert(handler); }
|
||||
void remove_handler(handler_entry *handler) { m_handlers.erase(m_handlers.find(handler)); }
|
||||
friend class address_space;
|
||||
};
|
||||
|
||||
// =====================-> Forward declaration for address_space
|
||||
@ -1687,32 +1717,32 @@ public:
|
||||
virtual void install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_constructor &map, u64 unitmask = 0, int cswidth = 0, u16 flags = 0) = 0;
|
||||
|
||||
// install taps without mirroring
|
||||
memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
|
||||
memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
|
||||
memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
|
||||
memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
|
||||
memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
|
||||
memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
|
||||
memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
|
||||
memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
|
||||
memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
|
||||
|
||||
// install taps with mirroring
|
||||
virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
|
||||
virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
|
||||
|
||||
// install views
|
||||
void install_view(offs_t addrstart, offs_t addrend, memory_view &view) { install_view(addrstart, addrend, 0, view); }
|
||||
@ -1918,11 +1948,6 @@ class address_space : public address_space_installer
|
||||
template<int Width, int AddrShift> friend class handler_entry_read_unmapped;
|
||||
template<int Width, int AddrShift> friend class handler_entry_write_unmapped;
|
||||
|
||||
struct notifier_t {
|
||||
std::function<void (read_or_write)> m_notifier;
|
||||
int m_id;
|
||||
};
|
||||
|
||||
protected:
|
||||
// construction/destruction
|
||||
address_space(memory_manager &manager, device_memory_interface &memory, int spacenum);
|
||||
@ -1962,15 +1987,14 @@ public:
|
||||
v.set(this, get_specific_info());
|
||||
}
|
||||
|
||||
int add_change_notifier(std::function<void (read_or_write)> n);
|
||||
void remove_change_notifier(int id);
|
||||
util::notifier_subscription add_change_notifier(delegate<void (read_or_write)> &&n);
|
||||
template <typename T> util::notifier_subscription add_change_notifier(T &&n) { return add_change_notifier(delegate<void (read_or_write)>(std::forward<T>(n))); }
|
||||
|
||||
void invalidate_caches(read_or_write mode) {
|
||||
if(u32(mode) & ~m_in_notification) {
|
||||
u32 old = m_in_notification;
|
||||
m_in_notification |= u32(mode);
|
||||
for(const auto &n : m_notifiers)
|
||||
n.m_notifier(mode);
|
||||
m_notifiers(mode);
|
||||
m_in_notification = old;
|
||||
}
|
||||
}
|
||||
@ -1981,7 +2005,7 @@ public:
|
||||
|
||||
u64 unmap() const { return m_unmap; }
|
||||
|
||||
memory_passthrough_handler *make_mph();
|
||||
std::shared_ptr<emu::detail::memory_passthrough_handler_impl> make_mph(memory_passthrough_handler *mph);
|
||||
|
||||
// debug helpers
|
||||
virtual std::string get_handler_string(read_or_write readorwrite, offs_t byteaddress) const = 0;
|
||||
@ -2088,10 +2112,9 @@ protected:
|
||||
handler_entry *m_nop_r;
|
||||
handler_entry *m_nop_w;
|
||||
|
||||
std::vector<std::unique_ptr<memory_passthrough_handler>> m_mphs;
|
||||
std::vector<std::shared_ptr<emu::detail::memory_passthrough_handler_impl>> m_mphs;
|
||||
|
||||
std::vector<notifier_t> m_notifiers; // notifier list for address map change
|
||||
int m_notifier_id; // next notifier id
|
||||
util::notifier<read_or_write> m_notifiers; // notifier list for address map change
|
||||
u32 m_in_notification; // notification(s) currently being done
|
||||
};
|
||||
|
||||
@ -2397,7 +2420,7 @@ write_native(offs_t address, typename emu::detail::handler_entry_size<Width>::uX
|
||||
m_cache_w->write(address, data, mask);
|
||||
}
|
||||
|
||||
void memory_passthrough_handler::remove()
|
||||
inline void emu::detail::memory_passthrough_handler_impl::remove()
|
||||
{
|
||||
m_space.remove_passthrough(m_handlers);
|
||||
}
|
||||
|
@ -292,9 +292,9 @@ public:
|
||||
using address_space::install_write_tap;
|
||||
using address_space::install_readwrite_tap;
|
||||
|
||||
virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph) override;
|
||||
|
||||
// construction/destruction
|
||||
address_space_specific(memory_manager &manager, device_memory_interface &memory, int spacenum, int address_width)
|
||||
@ -810,7 +810,6 @@ address_space::address_space(memory_manager &manager, device_memory_interface &m
|
||||
m_spacenum(spacenum),
|
||||
m_log_unmap(true),
|
||||
m_name(memory.space_config(spacenum)->name()),
|
||||
m_notifier_id(0),
|
||||
m_in_notification(0)
|
||||
{
|
||||
}
|
||||
@ -1084,73 +1083,78 @@ template<int Level, int Width, int AddrShift, endianness_t Endian> void address_
|
||||
view.make_subdispatch(""); // Must be called after populate
|
||||
}
|
||||
|
||||
memory_passthrough_handler *address_space::make_mph()
|
||||
std::shared_ptr<emu::detail::memory_passthrough_handler_impl> address_space::make_mph(memory_passthrough_handler *mph)
|
||||
{
|
||||
m_mphs.emplace_back(std::make_unique<memory_passthrough_handler>(*this));
|
||||
return m_mphs.back().get();
|
||||
if (mph)
|
||||
{
|
||||
auto impl(mph->m_impl.lock());
|
||||
if (impl)
|
||||
{
|
||||
assert(&impl->m_space == this);
|
||||
return impl;
|
||||
}
|
||||
}
|
||||
return m_mphs.emplace_back(std::make_shared<emu::detail::memory_passthrough_handler_impl>(*this));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// install_read_tap - install a read tap on the bus
|
||||
//-------------------------------------------------
|
||||
|
||||
template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler *address_space_specific<Level, Width, AddrShift, Endian>::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler address_space_specific<Level, Width, AddrShift, Endian>::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
offs_t nstart, nend, nmask, nmirror;
|
||||
check_optimize_mirror("install_read_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
|
||||
if (!mph)
|
||||
mph = make_mph();
|
||||
auto impl = make_mph(mph);
|
||||
|
||||
auto handler = new handler_entry_read_tap<Width, AddrShift>(this, *mph, name, tap);
|
||||
auto handler = new handler_entry_read_tap<Width, AddrShift>(this, *impl, name, tap);
|
||||
m_root_read->populate_passthrough(nstart, nend, nmirror, handler);
|
||||
handler->unref();
|
||||
|
||||
invalidate_caches(read_or_write::READ);
|
||||
|
||||
return mph;
|
||||
return impl;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// install_write_tap - install a write tap on the bus
|
||||
//-------------------------------------------------
|
||||
|
||||
template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler *address_space_specific<Level, Width, AddrShift, Endian>::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler address_space_specific<Level, Width, AddrShift, Endian>::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
offs_t nstart, nend, nmask, nmirror;
|
||||
check_optimize_mirror("install_write_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
|
||||
if (!mph)
|
||||
mph = make_mph();
|
||||
auto impl = make_mph(mph);
|
||||
|
||||
auto handler = new handler_entry_write_tap<Width, AddrShift>(this, *mph, name, tap);
|
||||
auto handler = new handler_entry_write_tap<Width, AddrShift>(this, *impl, name, tap);
|
||||
m_root_write->populate_passthrough(nstart, nend, nmirror, handler);
|
||||
handler->unref();
|
||||
|
||||
invalidate_caches(read_or_write::WRITE);
|
||||
|
||||
return mph;
|
||||
return impl;
|
||||
}
|
||||
//-------------------------------------------------
|
||||
// install_write_tap - install a read and a write tap on the bus
|
||||
//-------------------------------------------------
|
||||
|
||||
template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler *address_space_specific<Level, Width, AddrShift, Endian>::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler address_space_specific<Level, Width, AddrShift, Endian>::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
{
|
||||
offs_t nstart, nend, nmask, nmirror;
|
||||
check_optimize_mirror("install_readwrite_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
|
||||
if (!mph)
|
||||
mph = make_mph();
|
||||
auto impl = make_mph(mph);
|
||||
|
||||
auto rhandler = new handler_entry_read_tap <Width, AddrShift>(this, *mph, name, tapr);
|
||||
auto rhandler = new handler_entry_read_tap <Width, AddrShift>(this, *impl, name, tapr);
|
||||
m_root_read ->populate_passthrough(nstart, nend, nmirror, rhandler);
|
||||
rhandler->unref();
|
||||
|
||||
auto whandler = new handler_entry_write_tap<Width, AddrShift>(this, *mph, name, tapw);
|
||||
auto whandler = new handler_entry_write_tap<Width, AddrShift>(this, *impl, name, tapw);
|
||||
m_root_write->populate_passthrough(nstart, nend, nmirror, whandler);
|
||||
whandler->unref();
|
||||
|
||||
invalidate_caches(read_or_write::READWRITE);
|
||||
|
||||
return mph;
|
||||
return impl;
|
||||
}
|
||||
|
||||
|
||||
@ -1291,19 +1295,7 @@ template<int Level, int Width, int AddrShift, endianness_t Endian> void address_
|
||||
// MEMORY MAPPING HELPERS
|
||||
//**************************************************************************
|
||||
|
||||
int address_space::add_change_notifier(std::function<void (read_or_write)> n)
|
||||
util::notifier_subscription address_space::add_change_notifier(delegate<void (read_or_write)> &&n)
|
||||
{
|
||||
int id = m_notifier_id++;
|
||||
m_notifiers.emplace_back(notifier_t{ std::move(n), id });
|
||||
return id;
|
||||
}
|
||||
|
||||
void address_space::remove_change_notifier(int id)
|
||||
{
|
||||
for(auto i = m_notifiers.begin(); i != m_notifiers.end(); i++)
|
||||
if (i->m_id == id) {
|
||||
m_notifiers.erase(i);
|
||||
return;
|
||||
}
|
||||
fatalerror("Unknown notifier id %d, double remove?\n", id);
|
||||
return m_notifiers.subscribe(std::move(n));
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ template<int Width, int AddrShift> class handler_entry_read_passthrough : public
|
||||
public:
|
||||
using uX = typename emu::detail::handler_entry_size<Width>::uX;
|
||||
|
||||
handler_entry_read_passthrough(address_space *space, memory_passthrough_handler &mph) : handler_entry_read<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(nullptr) {}
|
||||
handler_entry_read_passthrough(address_space *space, emu::detail::memory_passthrough_handler_impl &mph) : handler_entry_read<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(nullptr) {}
|
||||
~handler_entry_read_passthrough();
|
||||
|
||||
virtual handler_entry_read_passthrough<Width, AddrShift> *instantiate(handler_entry_read<Width, AddrShift> *next) const = 0;
|
||||
@ -20,10 +20,10 @@ public:
|
||||
void detach(const std::unordered_set<handler_entry *> &handlers) override;
|
||||
|
||||
protected:
|
||||
memory_passthrough_handler &m_mph;
|
||||
emu::detail::memory_passthrough_handler_impl &m_mph;
|
||||
handler_entry_read<Width, AddrShift> *m_next;
|
||||
|
||||
handler_entry_read_passthrough(address_space *space, memory_passthrough_handler &mph, handler_entry_read<Width, AddrShift> *next) : handler_entry_read<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(next) { next->ref(); mph.add_handler(this); }
|
||||
handler_entry_read_passthrough(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, handler_entry_read<Width, AddrShift> *next) : handler_entry_read<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(next) { next->ref(); mph.add_handler(this); }
|
||||
};
|
||||
|
||||
template<int Width, int AddrShift> class handler_entry_write_passthrough : public handler_entry_write<Width, AddrShift>
|
||||
@ -31,7 +31,7 @@ template<int Width, int AddrShift> class handler_entry_write_passthrough : publi
|
||||
public:
|
||||
using uX = typename emu::detail::handler_entry_size<Width>::uX;
|
||||
|
||||
handler_entry_write_passthrough(address_space *space, memory_passthrough_handler &mph) : handler_entry_write<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(nullptr) {}
|
||||
handler_entry_write_passthrough(address_space *space, emu::detail::memory_passthrough_handler_impl &mph) : handler_entry_write<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(nullptr) {}
|
||||
~handler_entry_write_passthrough();
|
||||
|
||||
virtual handler_entry_write_passthrough<Width, AddrShift> *instantiate(handler_entry_write<Width, AddrShift> *next) const = 0;
|
||||
@ -41,8 +41,8 @@ public:
|
||||
void detach(const std::unordered_set<handler_entry *> &handlers) override;
|
||||
|
||||
protected:
|
||||
memory_passthrough_handler &m_mph;
|
||||
emu::detail::memory_passthrough_handler_impl &m_mph;
|
||||
handler_entry_write<Width, AddrShift> *m_next;
|
||||
|
||||
handler_entry_write_passthrough(address_space *space, memory_passthrough_handler &mph, handler_entry_write<Width, AddrShift> *next) : handler_entry_write<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(next) { next->ref(); mph.add_handler(this); }
|
||||
handler_entry_write_passthrough(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, handler_entry_write<Width, AddrShift> *next) : handler_entry_write<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(next) { next->ref(); mph.add_handler(this); }
|
||||
};
|
||||
|
@ -14,7 +14,7 @@ template<int Width, int AddrShift> class handler_entry_read_tap : public handler
|
||||
public:
|
||||
using uX = typename emu::detail::handler_entry_size<Width>::uX;
|
||||
|
||||
handler_entry_read_tap(address_space *space, memory_passthrough_handler &mph, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_read_passthrough<Width, AddrShift>(space, mph), m_name(name), m_tap(std::move(tap)) {}
|
||||
handler_entry_read_tap(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_read_passthrough<Width, AddrShift>(space, mph), m_name(name), m_tap(std::move(tap)) {}
|
||||
~handler_entry_read_tap() = default;
|
||||
|
||||
uX read(offs_t offset, uX mem_mask) const override;
|
||||
@ -28,7 +28,7 @@ protected:
|
||||
std::string m_name;
|
||||
std::function<void (offs_t offset, uX &data, uX mem_mask)> m_tap;
|
||||
|
||||
handler_entry_read_tap(address_space *space, memory_passthrough_handler &mph, handler_entry_read<Width, AddrShift> *next, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_read_passthrough<Width, AddrShift>(space, mph, next), m_name(name), m_tap(tap) {}
|
||||
handler_entry_read_tap(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, handler_entry_read<Width, AddrShift> *next, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_read_passthrough<Width, AddrShift>(space, mph, next), m_name(name), m_tap(tap) {}
|
||||
};
|
||||
|
||||
template<int Width, int AddrShift> class handler_entry_write_tap : public handler_entry_write_passthrough<Width, AddrShift>
|
||||
@ -36,7 +36,7 @@ template<int Width, int AddrShift> class handler_entry_write_tap : public handle
|
||||
public:
|
||||
using uX = typename emu::detail::handler_entry_size<Width>::uX;
|
||||
|
||||
handler_entry_write_tap(address_space *space, memory_passthrough_handler &mph, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_write_passthrough<Width, AddrShift>(space, mph), m_name(name), m_tap(std::move(tap)) {}
|
||||
handler_entry_write_tap(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_write_passthrough<Width, AddrShift>(space, mph), m_name(name), m_tap(std::move(tap)) {}
|
||||
~handler_entry_write_tap() = default;
|
||||
|
||||
void write(offs_t offset, uX data, uX mem_mask) const override;
|
||||
@ -50,7 +50,7 @@ protected:
|
||||
std::string m_name;
|
||||
std::function<void (offs_t offset, uX &data, uX mem_mask)> m_tap;
|
||||
|
||||
handler_entry_write_tap(address_space *space, memory_passthrough_handler &mph, handler_entry_write<Width, AddrShift> *next, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_write_passthrough<Width, AddrShift>(space, mph, next), m_name(name), m_tap(tap) {}
|
||||
handler_entry_write_tap(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, handler_entry_write<Width, AddrShift> *next, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_write_passthrough<Width, AddrShift>(space, mph, next), m_name(name), m_tap(tap) {}
|
||||
};
|
||||
|
||||
#endif // MAME_EMU_EMUMEM_HET_H
|
||||
|
@ -126,9 +126,9 @@ public:
|
||||
using address_space_installer::install_write_tap;
|
||||
using address_space_installer::install_readwrite_tap;
|
||||
|
||||
virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
|
||||
virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph) override;
|
||||
|
||||
virtual void unmap_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, u16 flags, read_or_write readorwrite, bool quiet) override;
|
||||
virtual void install_ram_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, u16 flags, read_or_write readorwrite, void *baseptr) override;
|
||||
@ -898,65 +898,62 @@ template<int Level, int Width, int AddrShift> void memory_view_entry_specific<Le
|
||||
view.make_subdispatch(key()); // Must be called after populate
|
||||
}
|
||||
|
||||
template<int Level, int Width, int AddrShift> memory_passthrough_handler *memory_view_entry_specific<Level, Width, AddrShift>::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
template<int Level, int Width, int AddrShift> memory_passthrough_handler memory_view_entry_specific<Level, Width, AddrShift>::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
offs_t nstart, nend, nmask, nmirror;
|
||||
check_range_optimize_mirror("install_read_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
|
||||
if (!mph)
|
||||
mph = m_view.m_space->make_mph();
|
||||
auto impl = m_view.m_space->make_mph(mph);
|
||||
|
||||
r()->select_u(m_id);
|
||||
w()->select_u(m_id);
|
||||
|
||||
auto handler = new handler_entry_read_tap<Width, AddrShift>(m_view.m_space, *mph, name, tap);
|
||||
auto handler = new handler_entry_read_tap<Width, AddrShift>(m_view.m_space, *impl, name, tap);
|
||||
r()->populate_passthrough(nstart, nend, nmirror, handler);
|
||||
handler->unref();
|
||||
|
||||
invalidate_caches(read_or_write::READ);
|
||||
|
||||
return mph;
|
||||
return impl;
|
||||
}
|
||||
|
||||
template<int Level, int Width, int AddrShift> memory_passthrough_handler *memory_view_entry_specific<Level, Width, AddrShift>::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
template<int Level, int Width, int AddrShift> memory_passthrough_handler memory_view_entry_specific<Level, Width, AddrShift>::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
|
||||
{
|
||||
offs_t nstart, nend, nmask, nmirror;
|
||||
check_range_optimize_mirror("install_write_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
|
||||
if (!mph)
|
||||
mph = m_view.m_space->make_mph();
|
||||
auto impl = m_view.m_space->make_mph(mph);
|
||||
|
||||
r()->select_u(m_id);
|
||||
w()->select_u(m_id);
|
||||
|
||||
auto handler = new handler_entry_write_tap<Width, AddrShift>(m_view.m_space, *mph, name, tap);
|
||||
auto handler = new handler_entry_write_tap<Width, AddrShift>(m_view.m_space, *impl, name, tap);
|
||||
w()->populate_passthrough(nstart, nend, nmirror, handler);
|
||||
handler->unref();
|
||||
|
||||
invalidate_caches(read_or_write::WRITE);
|
||||
|
||||
return mph;
|
||||
return impl;
|
||||
}
|
||||
|
||||
template<int Level, int Width, int AddrShift> memory_passthrough_handler *memory_view_entry_specific<Level, Width, AddrShift>::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
template<int Level, int Width, int AddrShift> memory_passthrough_handler memory_view_entry_specific<Level, Width, AddrShift>::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph)
|
||||
{
|
||||
offs_t nstart, nend, nmask, nmirror;
|
||||
check_range_optimize_mirror("install_readwrite_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
|
||||
if (!mph)
|
||||
mph = m_view.m_space->make_mph();
|
||||
auto impl = m_view.m_space->make_mph(mph);
|
||||
|
||||
r()->select_u(m_id);
|
||||
w()->select_u(m_id);
|
||||
|
||||
auto rhandler = new handler_entry_read_tap <Width, AddrShift>(m_view.m_space, *mph, name, tapr);
|
||||
auto rhandler = new handler_entry_read_tap <Width, AddrShift>(m_view.m_space, *impl, name, tapr);
|
||||
r() ->populate_passthrough(nstart, nend, nmirror, rhandler);
|
||||
rhandler->unref();
|
||||
|
||||
auto whandler = new handler_entry_write_tap<Width, AddrShift>(m_view.m_space, *mph, name, tapw);
|
||||
auto whandler = new handler_entry_write_tap<Width, AddrShift>(m_view.m_space, *impl, name, tapw);
|
||||
w()->populate_passthrough(nstart, nend, nmirror, whandler);
|
||||
whandler->unref();
|
||||
|
||||
invalidate_caches(read_or_write::READWRITE);
|
||||
|
||||
return mph;
|
||||
return impl;
|
||||
}
|
||||
|
||||
template<int Level, int Width, int AddrShift> void memory_view_entry_specific<Level, Width, AddrShift>::install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_constructor &delegate, u64 unitmask, int cswidth, u16 flags)
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "uiinput.h"
|
||||
|
||||
#include "corestr.h"
|
||||
#include "notifier.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
@ -741,6 +742,10 @@ void lua_engine::initialize()
|
||||
[] (device_t &dev, int maxdepth) { return devenum<slot_interface_enumerator>(dev, maxdepth); });
|
||||
|
||||
|
||||
auto notifier_subscription_type = sol().registry().new_usertype<util::notifier_subscription>("notifier_subscription", sol::no_constructor);
|
||||
notifier_subscription_type["unsubscribe"] = &util::notifier_subscription::reset;
|
||||
notifier_subscription_type["is_active"] = sol::property(&util::notifier_subscription::operator bool);
|
||||
|
||||
auto attotime_type = emu.new_usertype<attotime>(
|
||||
"attotime",
|
||||
sol::call_constructor, sol::constructors<attotime(), attotime(seconds_t, attoseconds_t), attotime(attotime const &)>());
|
||||
|
@ -30,6 +30,78 @@ struct wrap_textbuf
|
||||
};
|
||||
|
||||
|
||||
class symbol_table_wrapper
|
||||
{
|
||||
public:
|
||||
symbol_table_wrapper(symbol_table_wrapper const &) = delete;
|
||||
|
||||
symbol_table_wrapper(running_machine &machine, std::shared_ptr<symbol_table_wrapper> const &parent, device_t *device)
|
||||
: m_table(machine, parent ? &parent->table() : nullptr, device)
|
||||
, m_parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
symbol_table &table() { return m_table; }
|
||||
symbol_table const &table() const { return m_table; }
|
||||
std::shared_ptr<symbol_table_wrapper> const &parent() { return m_parent; }
|
||||
|
||||
symbol_entry &add(char const *name) { return m_table.add(name, symbol_table::READ_WRITE); }
|
||||
symbol_entry &add(char const *name, u64 value) { return m_table.add(name, value); }
|
||||
symbol_entry *find(char const *name) const { return m_table.find(name); }
|
||||
symbol_entry *find_deep(char const *name) { return m_table.find_deep(name); }
|
||||
|
||||
u64 value(const char *symbol) { return m_table.value(symbol); }
|
||||
void set_value(const char *symbol, u64 value) { m_table.set_value(symbol, value); }
|
||||
|
||||
private:
|
||||
symbol_table m_table;
|
||||
std::shared_ptr<symbol_table_wrapper> const m_parent;
|
||||
};
|
||||
|
||||
|
||||
class expression_wrapper
|
||||
{
|
||||
public:
|
||||
expression_wrapper(expression_wrapper const &) = delete;
|
||||
expression_wrapper &operator=(expression_wrapper const &) = delete;
|
||||
|
||||
expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &symtable)
|
||||
: m_expression(symtable->table())
|
||||
, m_symbols(symtable)
|
||||
{
|
||||
}
|
||||
|
||||
expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &symtable, char const *expression, int default_base)
|
||||
: m_expression(symtable->table(), expression, default_base)
|
||||
, m_symbols(symtable)
|
||||
{
|
||||
}
|
||||
|
||||
expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &symtable, char const *expression)
|
||||
: m_expression(symtable->table(), expression)
|
||||
, m_symbols(symtable)
|
||||
{
|
||||
}
|
||||
|
||||
void set_default_base(int base) { m_expression.set_default_base(base); }
|
||||
void parse(char const *string) { m_expression.parse(string); }
|
||||
u64 execute() { return m_expression.execute(); }
|
||||
bool is_empty() const { return m_expression.is_empty(); }
|
||||
char const *original_string() const { return m_expression.original_string(); }
|
||||
std::shared_ptr<symbol_table_wrapper> const &symbols() { return m_symbols; }
|
||||
|
||||
void set_symbols(std::shared_ptr<symbol_table_wrapper> const &symtable)
|
||||
{
|
||||
m_expression.set_symbols(symtable->table());
|
||||
m_symbols = symtable;
|
||||
}
|
||||
|
||||
private:
|
||||
parsed_expression m_expression;
|
||||
std::shared_ptr<symbol_table_wrapper> m_symbols;
|
||||
};
|
||||
|
||||
|
||||
template <bool Enable>
|
||||
sol::object do_breakpoint_enable(device_debug &dev, sol::this_state s, sol::object index)
|
||||
{
|
||||
@ -106,12 +178,12 @@ void lua_engine::initialize_debug(sol::table &emu)
|
||||
{ "m", EXPSPACE_REGION }
|
||||
};
|
||||
|
||||
auto const do_add_symbol = [this] (symbol_table &st, char const *name, sol::protected_function getter, std::optional<sol::protected_function> setter, std::optional<char const *> format)
|
||||
auto const do_add_symbol = [this] (symbol_table_wrapper &st, char const *name, sol::protected_function getter, std::optional<sol::protected_function> setter, std::optional<char const *> format) -> symbol_entry &
|
||||
{
|
||||
symbol_table::setter_func setfun;
|
||||
if (setter)
|
||||
setfun = [this, cbfunc = std::move(*setter)] (u64 value) { invoke(cbfunc, value); };
|
||||
st.add(
|
||||
return st.table().add(
|
||||
name,
|
||||
[this, cbfunc = std::move(getter)] () -> u64
|
||||
{
|
||||
@ -130,46 +202,50 @@ void lua_engine::initialize_debug(sol::table &emu)
|
||||
(format && *format) ? *format : "");
|
||||
};
|
||||
|
||||
auto symbol_table_type = emu.new_usertype<symbol_table>(
|
||||
auto symbol_table_type = emu.new_usertype<symbol_table_wrapper>(
|
||||
"symbol_table",
|
||||
sol::call_constructor, sol::factories(
|
||||
[] (running_machine &machine, symbol_table *parent, device_t *device) { return std::make_unique<symbol_table>(machine, parent, device); },
|
||||
[] (running_machine &machine, symbol_table *parent) { return std::make_unique<symbol_table>(machine, parent); },
|
||||
[] (running_machine &machine, device_t &device) { return std::make_unique<symbol_table>(machine, nullptr, &device); },
|
||||
[] (running_machine &machine) { return std::make_unique<symbol_table>(machine); }));
|
||||
[] (running_machine &machine)
|
||||
{ return std::make_shared<symbol_table_wrapper>(machine, nullptr, nullptr); },
|
||||
[] (std::shared_ptr<symbol_table_wrapper> const &parent, device_t *device)
|
||||
{ return std::make_shared<symbol_table_wrapper>(parent->table().machine(), parent, device); },
|
||||
[] (std::shared_ptr<symbol_table_wrapper> const &parent)
|
||||
{ return std::make_shared<symbol_table_wrapper>(parent->table().machine(), parent, nullptr); },
|
||||
[] (device_t &device)
|
||||
{ return std::make_shared<symbol_table_wrapper>(device.machine(), nullptr, &device); }));
|
||||
symbol_table_type["set_memory_modified_func"] =
|
||||
[this] (symbol_table &st, sol::object cb)
|
||||
[this] (symbol_table_wrapper &st, sol::object cb)
|
||||
{
|
||||
if (cb == sol::lua_nil)
|
||||
st.set_memory_modified_func(nullptr);
|
||||
st.table().set_memory_modified_func(nullptr);
|
||||
else if (cb.is<sol::protected_function>())
|
||||
st.set_memory_modified_func([this, cbfunc = cb.as<sol::protected_function>()] () { invoke(cbfunc); });
|
||||
st.table().set_memory_modified_func([this, cbfunc = cb.as<sol::protected_function>()] () { invoke(cbfunc); });
|
||||
else
|
||||
osd_printf_error("[LUA ERROR] must call set_memory_modified_func with function or nil\n");
|
||||
};
|
||||
symbol_table_type["add"] = sol::overload(
|
||||
[] (symbol_table &st, char const *name) { st.add(name, symbol_table::READ_WRITE); },
|
||||
static_cast<void (symbol_table::*)(char const *, u64)>(&symbol_table::add),
|
||||
static_cast<symbol_entry &(symbol_table_wrapper::*)(char const *)>(&symbol_table_wrapper::add),
|
||||
static_cast<symbol_entry &(symbol_table_wrapper::*)(char const *, u64)>(&symbol_table_wrapper::add),
|
||||
do_add_symbol,
|
||||
[do_add_symbol] (symbol_table &st, char const *name, sol::protected_function getter, sol::lua_nil_t, char const *format)
|
||||
[do_add_symbol] (symbol_table_wrapper &st, char const *name, sol::protected_function getter, sol::lua_nil_t, char const *format) -> symbol_entry &
|
||||
{
|
||||
do_add_symbol(st, name, getter, std::nullopt, format);
|
||||
return do_add_symbol(st, name, getter, std::nullopt, format);
|
||||
},
|
||||
[do_add_symbol] (symbol_table &st, char const *name, sol::protected_function getter, std::optional<sol::protected_function> setter)
|
||||
[do_add_symbol] (symbol_table_wrapper &st, char const *name, sol::protected_function getter, std::optional<sol::protected_function> setter) -> symbol_entry &
|
||||
{
|
||||
do_add_symbol(st, name, getter, setter, nullptr);
|
||||
return do_add_symbol(st, name, getter, setter, nullptr);
|
||||
},
|
||||
[do_add_symbol] (symbol_table &st, char const *name, sol::protected_function getter, char const *format)
|
||||
[do_add_symbol] (symbol_table_wrapper &st, char const *name, sol::protected_function getter, char const *format) -> symbol_entry &
|
||||
{
|
||||
do_add_symbol(st, name, getter, std::nullopt, format);
|
||||
return do_add_symbol(st, name, getter, std::nullopt, format);
|
||||
},
|
||||
[do_add_symbol] (symbol_table &st, char const *name, sol::protected_function getter)
|
||||
[do_add_symbol] (symbol_table_wrapper &st, char const *name, sol::protected_function getter) -> symbol_entry &
|
||||
{
|
||||
do_add_symbol(st, name, getter, std::nullopt, nullptr);
|
||||
return do_add_symbol(st, name, getter, std::nullopt, nullptr);
|
||||
},
|
||||
[this] (symbol_table &st, char const *name, int minparams, int maxparams, sol::protected_function execute)
|
||||
[this] (symbol_table_wrapper &st, char const *name, int minparams, int maxparams, sol::protected_function execute) -> symbol_entry &
|
||||
{
|
||||
st.add(
|
||||
return st.table().add(
|
||||
name,
|
||||
minparams,
|
||||
maxparams,
|
||||
@ -185,41 +261,40 @@ void lua_engine::initialize_debug(sol::table &emu)
|
||||
return result ? *result : 0;
|
||||
});
|
||||
});
|
||||
symbol_table_type["find"] = &symbol_table::find;
|
||||
symbol_table_type["find_deep"] = &symbol_table::find_deep;
|
||||
symbol_table_type["value"] = &symbol_table::value;
|
||||
symbol_table_type["set_value"] = &symbol_table::set_value;
|
||||
symbol_table_type["find"] = &symbol_table_wrapper::find;
|
||||
symbol_table_type["find_deep"] = &symbol_table_wrapper::find_deep;
|
||||
symbol_table_type["value"] = &symbol_table_wrapper::value;
|
||||
symbol_table_type["set_value"] = &symbol_table_wrapper::set_value;
|
||||
symbol_table_type["memory_value"] =
|
||||
[] (symbol_table &st, char const *name, char const *space, u32 offset, int size, bool disable_se)
|
||||
[] (symbol_table_wrapper &st, char const *name, char const *space, u32 offset, int size, bool disable_se)
|
||||
{
|
||||
expression_space const es = s_expression_space_parser(space);
|
||||
return st.memory_value(name, es, offset, size, disable_se);
|
||||
return st.table().memory_value(name, es, offset, size, disable_se);
|
||||
};
|
||||
symbol_table_type["set_memory_value"] =
|
||||
[] (symbol_table &st, char const *name, char const *space, u32 offset, int size, u64 value, bool disable_se)
|
||||
[] (symbol_table_wrapper &st, char const *name, char const *space, u32 offset, int size, u64 value, bool disable_se)
|
||||
{
|
||||
expression_space const es = s_expression_space_parser(space);
|
||||
st.set_memory_value(name, es, offset, size, value, disable_se);
|
||||
st.table().set_memory_value(name, es, offset, size, value, disable_se);
|
||||
};
|
||||
//symbol_table_type["read_memory"] = &symbol_table::read_memory; crashes if you try to use it, need to work out why
|
||||
//symbol_table_type["write_memory"] = &symbol_table::write_memory; crashes if you try to use it, need to work out why
|
||||
symbol_table_type["entries"] = sol::property([] (symbol_table const &st) { return standard_tag_object_ptr_map<symbol_entry>(st.entries()); });
|
||||
symbol_table_type["parent"] = sol::property(&symbol_table::parent);
|
||||
symbol_table_type["entries"] = sol::property([] (symbol_table_wrapper const &st) { return standard_tag_object_ptr_map<symbol_entry>(st.table().entries()); });
|
||||
symbol_table_type["parent"] = sol::property(&symbol_table_wrapper::parent);
|
||||
|
||||
|
||||
auto parsed_expression_type = emu.new_usertype<parsed_expression>(
|
||||
auto parsed_expression_type = emu.new_usertype<expression_wrapper>(
|
||||
"parsed_expression",
|
||||
sol::call_constructor, sol::factories(
|
||||
[] (symbol_table &symtable) { return std::make_unique<parsed_expression>(symtable); },
|
||||
[] (symbol_table &symtable, char const *expression, int default_base) { return std::make_unique<parsed_expression>(symtable, expression, default_base); },
|
||||
[] (symbol_table &symtable, char const *expression) { return std::make_unique<parsed_expression>(symtable, expression); },
|
||||
[] (parsed_expression const &src) { return std::make_unique<parsed_expression>(src); }));
|
||||
parsed_expression_type["set_default_base"] = &parsed_expression::set_default_base;
|
||||
parsed_expression_type["parse"] = [] (parsed_expression &e, char const *string) { e.parse(string); };
|
||||
parsed_expression_type["execute"] = &parsed_expression::execute;
|
||||
parsed_expression_type["is_empty"] = sol::property(&parsed_expression::is_empty);
|
||||
parsed_expression_type["original_string"] = sol::property(&parsed_expression::original_string);
|
||||
parsed_expression_type["symbols"] = sol::property(&parsed_expression::symbols, &parsed_expression::set_symbols);
|
||||
sol::call_constructor, sol::constructors<
|
||||
expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &),
|
||||
expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &, char const *, int),
|
||||
expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &, char const *)>());
|
||||
parsed_expression_type["set_default_base"] = &expression_wrapper::set_default_base;
|
||||
parsed_expression_type["parse"] = &expression_wrapper::parse;
|
||||
parsed_expression_type["execute"] = &expression_wrapper::execute;
|
||||
parsed_expression_type["is_empty"] = sol::property(&expression_wrapper::is_empty);
|
||||
parsed_expression_type["original_string"] = sol::property(&expression_wrapper::original_string);
|
||||
parsed_expression_type["symbols"] = sol::property(&expression_wrapper::symbols, &expression_wrapper::set_symbols);
|
||||
|
||||
|
||||
auto symbol_entry_type = sol().registry().new_usertype<symbol_entry>("symbol_entry", sol::no_constructor);
|
||||
@ -266,22 +341,22 @@ void lua_engine::initialize_debug(sol::table &emu)
|
||||
|
||||
auto device_debug_type = sol().registry().new_usertype<device_debug>("device_debug", sol::no_constructor);
|
||||
device_debug_type["step"] =
|
||||
[] (device_debug &dev, sol::object num)
|
||||
{
|
||||
int steps = 1;
|
||||
if (num.is<int>())
|
||||
steps = num.as<int>();
|
||||
dev.single_step(steps);
|
||||
};
|
||||
[] (device_debug &dev, sol::object num)
|
||||
{
|
||||
int steps = 1;
|
||||
if (num.is<int>())
|
||||
steps = num.as<int>();
|
||||
dev.single_step(steps);
|
||||
};
|
||||
device_debug_type["go"] = &device_debug::go;
|
||||
device_debug_type["bpset"] =
|
||||
[] (device_debug &dev, offs_t address, char const *cond, char const *act)
|
||||
{
|
||||
int result(dev.breakpoint_set(address, cond, act));
|
||||
dev.device().machine().debug_view().update_all(DVT_DISASSEMBLY);
|
||||
dev.device().machine().debug_view().update_all(DVT_BREAK_POINTS);
|
||||
return result;
|
||||
};
|
||||
[] (device_debug &dev, offs_t address, char const *cond, char const *act)
|
||||
{
|
||||
int result(dev.breakpoint_set(address, cond, act));
|
||||
dev.device().machine().debug_view().update_all(DVT_DISASSEMBLY);
|
||||
dev.device().machine().debug_view().update_all(DVT_BREAK_POINTS);
|
||||
return result;
|
||||
};
|
||||
device_debug_type["bpclear"] = sol::overload(
|
||||
[] (device_debug &dev, int index)
|
||||
{
|
||||
@ -302,21 +377,21 @@ void lua_engine::initialize_debug(sol::table &emu)
|
||||
device_debug_type["bpenable"] = &do_breakpoint_enable<true>;
|
||||
device_debug_type["bpdisable"] = &do_breakpoint_enable<false>;
|
||||
device_debug_type["bplist"] =
|
||||
[this] (device_debug &dev)
|
||||
{
|
||||
sol::table table = sol().create_table();
|
||||
for (auto const &bpp : dev.breakpoint_list())
|
||||
table[bpp.second->index()] = sol::make_reference(sol(), *bpp.second);
|
||||
return table;
|
||||
};
|
||||
[this] (device_debug &dev)
|
||||
{
|
||||
sol::table table = sol().create_table();
|
||||
for (auto const &bpp : dev.breakpoint_list())
|
||||
table[bpp.second->index()] = sol::make_reference(sol(), bpp.second.get());
|
||||
return table;
|
||||
};
|
||||
device_debug_type["wpset"] =
|
||||
[] (device_debug &dev, addr_space &sp, std::string const &type, offs_t addr, offs_t len, char const *cond, char const *act)
|
||||
{
|
||||
read_or_write const wptype = s_read_or_write_parser(type);
|
||||
int result(dev.watchpoint_set(sp.space, wptype, addr, len, cond, act));
|
||||
dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS);
|
||||
return result;
|
||||
};
|
||||
[] (device_debug &dev, addr_space &sp, std::string const &type, offs_t addr, offs_t len, char const *cond, char const *act)
|
||||
{
|
||||
read_or_write const wptype = s_read_or_write_parser(type);
|
||||
int result(dev.watchpoint_set(sp.space, wptype, addr, len, cond, act));
|
||||
dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS);
|
||||
return result;
|
||||
};
|
||||
device_debug_type["wpclear"] = sol::overload(
|
||||
[] (device_debug &dev, int index)
|
||||
{
|
||||
@ -333,18 +408,28 @@ void lua_engine::initialize_debug(sol::table &emu)
|
||||
device_debug_type["wpenable"] = &do_watchpoint_enable<true>;
|
||||
device_debug_type["wpdisable"] = &do_watchpoint_enable<false>;
|
||||
device_debug_type["wplist"] =
|
||||
[this] (device_debug &dev, addr_space &sp)
|
||||
{
|
||||
sol::table table = sol().create_table();
|
||||
for (auto &wpp : dev.watchpoint_vector(sp.space.spacenum()))
|
||||
table[wpp->index()] = sol::make_reference(sol(), *wpp);
|
||||
return table;
|
||||
};
|
||||
[this] (device_debug &dev, addr_space &sp)
|
||||
{
|
||||
sol::table table = sol().create_table();
|
||||
for (auto &wpp : dev.watchpoint_vector(sp.space.spacenum()))
|
||||
table[wpp->index()] = sol::make_reference(sol(), wpp.get());
|
||||
return table;
|
||||
};
|
||||
|
||||
|
||||
auto breakpoint_type = sol().registry().new_usertype<debug_breakpoint>("breakpoint", sol::no_constructor);
|
||||
breakpoint_type["index"] = sol::property(&debug_breakpoint::index);
|
||||
breakpoint_type["enabled"] = sol::property(&debug_breakpoint::enabled);
|
||||
breakpoint_type["enabled"] = sol::property(
|
||||
&debug_breakpoint::enabled,
|
||||
[] (debug_breakpoint &bp, bool val)
|
||||
{
|
||||
if (bp.enabled() != val)
|
||||
{
|
||||
bp.setEnabled(val);
|
||||
bp.debugInterface()->device().machine().debug_view().update_all(DVT_DISASSEMBLY);
|
||||
bp.debugInterface()->device().machine().debug_view().update_all(DVT_BREAK_POINTS);
|
||||
}
|
||||
});
|
||||
breakpoint_type["address"] = sol::property(&debug_breakpoint::address);
|
||||
breakpoint_type["condition"] = sol::property(&debug_breakpoint::condition);
|
||||
breakpoint_type["action"] = sol::property(&debug_breakpoint::action);
|
||||
@ -352,7 +437,16 @@ void lua_engine::initialize_debug(sol::table &emu)
|
||||
|
||||
auto watchpoint_type = sol().registry().new_usertype<debug_watchpoint>("watchpoint", sol::no_constructor);
|
||||
watchpoint_type["index"] = sol::property(&debug_watchpoint::index);
|
||||
watchpoint_type["enabled"] = sol::property(&debug_watchpoint::enabled);
|
||||
watchpoint_type["enabled"] = sol::property(
|
||||
&debug_watchpoint::enabled,
|
||||
[] (debug_watchpoint &wp, bool val)
|
||||
{
|
||||
if (wp.enabled() != val)
|
||||
{
|
||||
wp.setEnabled(val);
|
||||
wp.debugInterface()->device().machine().debug_view().update_all(DVT_WATCH_POINTS);
|
||||
}
|
||||
});
|
||||
watchpoint_type["type"] = sol::property(
|
||||
[] (debug_watchpoint &wp) -> char const *
|
||||
{
|
||||
|
@ -205,21 +205,19 @@ public:
|
||||
: m_callback(std::move(callback))
|
||||
, m_engine(engine)
|
||||
, m_space(space)
|
||||
, m_handler(nullptr)
|
||||
, m_handler()
|
||||
, m_name(std::move(name))
|
||||
, m_start(start)
|
||||
, m_end(end)
|
||||
, m_mode(mode)
|
||||
, m_installing(false)
|
||||
, m_installed(false)
|
||||
, m_installing(0U)
|
||||
{
|
||||
reinstall();
|
||||
}
|
||||
|
||||
~tap_helper()
|
||||
{
|
||||
if (m_handler && m_installed)
|
||||
m_handler->remove();
|
||||
remove();
|
||||
}
|
||||
|
||||
offs_t start() const noexcept { return m_start; }
|
||||
@ -239,11 +237,9 @@ public:
|
||||
|
||||
void remove()
|
||||
{
|
||||
if (m_handler)
|
||||
{
|
||||
m_handler->remove();
|
||||
m_installed = false;
|
||||
}
|
||||
++m_installing;
|
||||
m_handler.remove();
|
||||
--m_installing;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -252,9 +248,8 @@ private:
|
||||
{
|
||||
if (m_installing)
|
||||
return;
|
||||
m_installing = true;
|
||||
if (m_handler)
|
||||
m_handler->remove();
|
||||
++m_installing;
|
||||
m_handler.remove();
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
@ -269,7 +264,7 @@ private:
|
||||
if (result)
|
||||
data = *result;
|
||||
},
|
||||
m_handler);
|
||||
&m_handler);
|
||||
break;
|
||||
case read_or_write::WRITE:
|
||||
m_handler = m_space.install_write_tap(
|
||||
@ -282,118 +277,25 @@ private:
|
||||
if (result)
|
||||
data = *result;
|
||||
},
|
||||
m_handler);
|
||||
&m_handler);
|
||||
break;
|
||||
case read_or_write::READWRITE:
|
||||
// won't ever get here, but compilers complain about unhandled enum value
|
||||
break;
|
||||
}
|
||||
|
||||
m_installed = true;
|
||||
m_installing = false;
|
||||
--m_installing;
|
||||
};
|
||||
|
||||
sol::protected_function m_callback;
|
||||
lua_engine &m_engine;
|
||||
address_space &m_space;
|
||||
memory_passthrough_handler *m_handler;
|
||||
memory_passthrough_handler m_handler;
|
||||
std::string m_name;
|
||||
offs_t const m_start;
|
||||
offs_t const m_end;
|
||||
read_or_write const m_mode;
|
||||
bool m_installing;
|
||||
bool m_installed;
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// addr_space_change_notif - helper for hanging
|
||||
// on to an address space change notification
|
||||
// subscription
|
||||
//-------------------------------------------------
|
||||
|
||||
class lua_engine::addr_space_change_notif
|
||||
{
|
||||
public:
|
||||
addr_space_change_notif(addr_space_change_notif const &) = delete;
|
||||
|
||||
addr_space_change_notif(addr_space_change_notif &&that)
|
||||
: m_callback(std::move(that.m_callback))
|
||||
, m_engine(that.m_engine)
|
||||
, m_space(that.m_space)
|
||||
, m_id(-1)
|
||||
{
|
||||
that.remove();
|
||||
install();
|
||||
}
|
||||
|
||||
addr_space_change_notif &operator=(addr_space_change_notif &&that)
|
||||
{
|
||||
if (&that != this)
|
||||
{
|
||||
remove();
|
||||
m_callback = std::move(that.m_callback);
|
||||
m_engine = that.m_engine;
|
||||
m_space = that.m_space;
|
||||
that.remove();
|
||||
install();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
addr_space_change_notif(lua_engine &engine, address_space &space, sol::protected_function &&callback)
|
||||
: m_callback(std::move(callback))
|
||||
, m_engine(&engine)
|
||||
, m_space(&space)
|
||||
, m_id(-1)
|
||||
{
|
||||
install();
|
||||
}
|
||||
|
||||
~addr_space_change_notif()
|
||||
{
|
||||
if (m_space)
|
||||
m_space->remove_change_notifier(m_id);
|
||||
}
|
||||
|
||||
void remove()
|
||||
{
|
||||
if (m_space)
|
||||
{
|
||||
m_space->remove_change_notifier(m_id);
|
||||
m_space = nullptr;
|
||||
m_id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void install()
|
||||
{
|
||||
if (m_space)
|
||||
{
|
||||
m_id = m_space->add_change_notifier(
|
||||
[this] (read_or_write mode)
|
||||
{
|
||||
char const *modestr = "";
|
||||
switch (mode)
|
||||
{
|
||||
case read_or_write::READ: modestr = "r"; break;
|
||||
case read_or_write::WRITE: modestr = "w"; break;
|
||||
case read_or_write::READWRITE: modestr = "rw"; break;
|
||||
}
|
||||
m_engine->invoke(m_callback, modestr);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
m_id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
sol::protected_function m_callback;
|
||||
lua_engine *m_engine;
|
||||
address_space *m_space;
|
||||
int m_id;
|
||||
unsigned m_installing;
|
||||
};
|
||||
|
||||
|
||||
@ -724,7 +626,18 @@ void lua_engine::initialize_memory(sol::table &emu)
|
||||
addr_space_type["add_change_notifier"] =
|
||||
[this] (addr_space &sp, sol::protected_function &&cb)
|
||||
{
|
||||
return addr_space_change_notif(*this, sp.space, std::move(cb));
|
||||
return sp.space.add_change_notifier(
|
||||
[this, callback = std::move(cb)] (read_or_write mode)
|
||||
{
|
||||
char const *modestr = "";
|
||||
switch (mode)
|
||||
{
|
||||
case read_or_write::READ: modestr = "r"; break;
|
||||
case read_or_write::WRITE: modestr = "w"; break;
|
||||
case read_or_write::READWRITE: modestr = "rw"; break;
|
||||
}
|
||||
invoke(callback, modestr);
|
||||
});
|
||||
};
|
||||
addr_space_type["install_read_tap"] =
|
||||
[this] (addr_space &sp, offs_t start, offs_t end, std::string &&name, sol::protected_function &&cb)
|
||||
@ -745,9 +658,6 @@ void lua_engine::initialize_memory(sol::table &emu)
|
||||
addr_space_type["map"] = sol::property([] (addr_space &sp) { return sp.space.map(); });
|
||||
|
||||
|
||||
auto change_notif_type = sol().registry().new_usertype<addr_space_change_notif>("addr_space_change", sol::no_constructor);
|
||||
change_notif_type["remove"] = &addr_space_change_notif::remove;
|
||||
|
||||
auto tap_type = sol().registry().new_usertype<tap_helper>("mempassthrough", sol::no_constructor);
|
||||
tap_type["reinstall"] = &tap_helper::reinstall;
|
||||
tap_type["remove"] = &tap_helper::remove;
|
||||
|
240
src/lib/util/notifier.h
Normal file
240
src/lib/util/notifier.h
Normal file
@ -0,0 +1,240 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
/// \file
|
||||
/// \brief Simple broadcast notifier
|
||||
///
|
||||
/// Classes for managing subscriptions and calling multiple listener
|
||||
/// functions for notifications.
|
||||
#ifndef MAME_LIB_UTIL_NOTIFIER_H
|
||||
#define MAME_LIB_UTIL_NOTIFIER_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "delegate.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace util {
|
||||
|
||||
/// \brief A subscription to a notification source
|
||||
///
|
||||
/// Class for representing a subscription to a notifier. Automatically
|
||||
/// unsubscribes on destruction, if explicitly reset, if assigned to, or
|
||||
/// when taking ownership of a different subscription by move
|
||||
/// assignment.
|
||||
/// \sa notifier
|
||||
class notifier_subscription
|
||||
{
|
||||
public:
|
||||
/// \brief Create an empty subscription
|
||||
///
|
||||
/// Initialises an instance not referring to a subscription.
|
||||
notifier_subscription() noexcept : m_token(), m_live(nullptr), m_index(0U) { }
|
||||
|
||||
/// \brief Transfer ownership of a subscription
|
||||
///
|
||||
/// Transfers ownership of a subscription to a new instance.
|
||||
/// \param [in,out] that The subscription to transfer ownership
|
||||
/// from. Will no longer refer to a subscription after ownership
|
||||
/// is transferred away.
|
||||
notifier_subscription(notifier_subscription &&that) noexcept :
|
||||
m_token(std::move(that.m_token)),
|
||||
m_live(that.m_live),
|
||||
m_index(that.m_index)
|
||||
{
|
||||
that.m_token.reset();
|
||||
}
|
||||
|
||||
/// \brief Unsubscribe and destroy a subscription
|
||||
///
|
||||
/// Unsubscribes if the subscription is active and cleans up the
|
||||
/// subscription instance.
|
||||
~notifier_subscription() noexcept
|
||||
{
|
||||
auto token(m_token.lock());
|
||||
if (token)
|
||||
(*m_live)[m_index] = false;
|
||||
}
|
||||
|
||||
/// \brief Swap two subscriptions
|
||||
///
|
||||
/// Exchanges ownership of subscriptions between two instances.
|
||||
/// \param [in,out] that The subscription to exchange ownership
|
||||
/// with.
|
||||
void swap(notifier_subscription &that) noexcept
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_token, that.m_token);
|
||||
swap(m_live, that.m_live);
|
||||
swap(m_index, that.m_index);
|
||||
}
|
||||
|
||||
/// \brief Unsubscribe from notifications
|
||||
///
|
||||
/// If the instance refers to an active subscription, cancel it so
|
||||
/// no future notifications will be received.
|
||||
void reset() noexcept
|
||||
{
|
||||
auto token(m_token.lock());
|
||||
if (token)
|
||||
(*m_live)[m_index] = false;
|
||||
m_token.reset();
|
||||
}
|
||||
|
||||
/// \brief Test whether a subscription is active
|
||||
///
|
||||
/// Tests whether a subscription is active. A subscription will be
|
||||
/// inactive if it is default constructed, reset, transferred away,
|
||||
/// or if the underlying notifier is destructed.
|
||||
/// \return True if the subscription is active, false otherwise.
|
||||
explicit operator bool() const noexcept { return bool(m_token.lock()); }
|
||||
|
||||
/// \brief Transfer ownership of a subscription
|
||||
///
|
||||
/// Transfers ownership of a subscription to an existing instance.
|
||||
/// If the subscription is active, it will be cancelled before it
|
||||
/// takes ownership of the other subscription.
|
||||
/// \param [in,out] that The subscription to transfer ownership
|
||||
/// from. Will no longer refer to a subscription after ownership
|
||||
/// is transferred away.
|
||||
/// \return A reference to the instance that ownership was
|
||||
/// transferred to.
|
||||
notifier_subscription &operator=(notifier_subscription &&that) noexcept
|
||||
{
|
||||
{
|
||||
auto token(m_token.lock());
|
||||
if (token)
|
||||
(*m_live)[m_index] = false;
|
||||
}
|
||||
m_token = std::move(that.m_token);
|
||||
m_live = that.m_live;
|
||||
m_index = that.m_index;
|
||||
that.m_token.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
notifier_subscription(
|
||||
std::shared_ptr<int> const &token,
|
||||
std::vector<bool> &live,
|
||||
std::vector<bool>::size_type index) :
|
||||
m_token(token),
|
||||
m_live(&live),
|
||||
m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
notifier_subscription(notifier_subscription const &) = delete;
|
||||
notifier_subscription &operator=(notifier_subscription const &) = delete;
|
||||
|
||||
std::weak_ptr<int> m_token;
|
||||
std::vector<bool> *m_live;
|
||||
std::vector<bool>::size_type m_index;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Broadcast notifier
|
||||
///
|
||||
/// Calls multiple listener functions. Allows listeners to subscribe
|
||||
/// and unsubscribe. Subscriptions are managed using
|
||||
/// \c notifier_subscription instances.
|
||||
/// \tparam Params Argument types for the listener functions.
|
||||
/// \sa notifier_subscription
|
||||
template <typename... Params>
|
||||
class notifier
|
||||
{
|
||||
public:
|
||||
/// \brief Listener delegate type
|
||||
///
|
||||
/// The delegate type used to represent listener functions.
|
||||
using delegate_type = delegate<void (Params...)>;
|
||||
|
||||
/// \brief Create a new notifier
|
||||
///
|
||||
/// Creates a new notifier with no initial subscribers.
|
||||
notifier() : m_token(std::make_shared<int>(0)) { }
|
||||
|
||||
/// \brief Destroy a notifier
|
||||
///
|
||||
/// Destroys a notifier, causing any subscriptions to become
|
||||
/// inactive.
|
||||
~notifier() noexcept { m_token.reset(); }
|
||||
|
||||
/// \brief Add a listener
|
||||
///
|
||||
/// Adds a listener function subscription, returning an object for
|
||||
/// managing the subscription.
|
||||
/// \param [in] listener The function to be called on notifications.
|
||||
/// \return A subscription object. Destroy the object or call its
|
||||
/// \c reset member function to unsubscribe.
|
||||
notifier_subscription subscribe(delegate_type &&listener)
|
||||
{
|
||||
struct subscription_impl : notifier_subscription
|
||||
{
|
||||
subscription_impl(notifier &host, std::size_t index) noexcept :
|
||||
notifier_subscription(host.m_token, host.m_live, index)
|
||||
{
|
||||
}
|
||||
};
|
||||
for (std::size_t i = 0U; m_listeners.size() > i; ++i)
|
||||
{
|
||||
if (!m_live[i])
|
||||
{
|
||||
m_live[i] = true;
|
||||
m_listeners[i] = std::move(listener);
|
||||
return subscription_impl(*this, i);
|
||||
}
|
||||
}
|
||||
m_live.emplace_back(true);
|
||||
try
|
||||
{
|
||||
m_listeners.emplace_back(std::move(listener));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
m_live.pop_back();
|
||||
throw;
|
||||
}
|
||||
return subscription_impl(*this, m_listeners.size() - 1);
|
||||
}
|
||||
|
||||
/// \brief Call listeners
|
||||
///
|
||||
/// Calls all active listener functions.
|
||||
/// \param [in] args Arguments to pass to the listener functions.
|
||||
void operator()(Params... args) const
|
||||
{
|
||||
for (std::size_t i = 0U; m_listeners.size() > i; ++i)
|
||||
{
|
||||
if (m_live[i])
|
||||
m_listeners[i](args...);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
notifier(notifier const &) = delete;
|
||||
notifier &operator=(notifier const &) = delete;
|
||||
|
||||
std::shared_ptr<int> m_token;
|
||||
std::vector<bool> m_live;
|
||||
std::vector<delegate_type> m_listeners;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Swap two notifier subscriptions
|
||||
///
|
||||
/// Exchanges ownership of two notifier subscriptions. Allows the
|
||||
/// swappable idiom to be used with notifier subscriptions.
|
||||
/// \param [in,out] x Takes ownership of the subscription from \p y.
|
||||
/// \param [in,out] y Takes ownership of the subscription from \p x.
|
||||
/// \sa notifier_subscription
|
||||
inline void swap(notifier_subscription &x, notifier_subscription &y) noexcept { x.swap(y); }
|
||||
|
||||
} // namespace util
|
||||
|
||||
#endif // MAME_LIB_UTIL_NOTIFIER_H
|
@ -76,22 +76,26 @@ ToDo:
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/clock.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/clock.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/upd765.h"
|
||||
#include "sound/beep.h"
|
||||
#include "machine/timer.h"
|
||||
#include "video/mc6845.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class amust_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -149,7 +153,7 @@ private:
|
||||
bool m_hsync = 0;
|
||||
bool m_vsync = 0;
|
||||
std::unique_ptr<u8[]> m_vram;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
@ -417,20 +421,22 @@ void amust_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf800, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf800, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void amust_state::machine_start()
|
||||
@ -536,6 +542,8 @@ ROM_START( amust )
|
||||
ROM_LOAD( "kbd_3.rom", 0x000, 0x800, CRC(d9441b35) SHA1(ce250ab1e892a13fd75182703f259855388c6bf4) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "formats/rk_cas.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class apogee_state : public radio86_state
|
||||
{
|
||||
public:
|
||||
@ -178,20 +180,22 @@ void apogee_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x0fff, m_rom+0x0800); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf000, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf000, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void apogee_state::machine_start()
|
||||
@ -307,6 +311,8 @@ ROM_START( apogee )
|
||||
ROM_LOAD ("apogee.fnt", 0x0000, 0x0800, CRC(fe5867f0) SHA1(82c5aca63ada5e4533eb0516384aaa7b77a1f8e2))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -27,19 +27,23 @@ ToDo:
|
||||
****************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/i8257.h"
|
||||
#include "video/i8275.h"
|
||||
#include "imagedev/cassette.h"
|
||||
//#include "sound/spkrdev.h"
|
||||
#include "speaker.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/i8257.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/timer.h"
|
||||
//#include "sound/spkrdev.h"
|
||||
#include "video/i8275.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class argo_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -76,7 +80,7 @@ private:
|
||||
void io_map(address_map &map);
|
||||
void mem_map(address_map &map);
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -426,20 +430,22 @@ void argo_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf800, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf800, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void argo_state::machine_start()
|
||||
@ -518,6 +524,8 @@ ROM_START( argo )
|
||||
ROM_LOAD( "c10_char.bin", 0x0000, 0x2000, BAD_DUMP CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
|
@ -56,6 +56,8 @@
|
||||
#define LOGDBG(...) LOGMASKED(LOG_DEBUG, __VA_ARGS__)
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class blit_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -95,7 +97,7 @@ private:
|
||||
required_shared_ptr<uint16_t> m_p_ram;
|
||||
required_region_ptr<uint16_t> m_sysrom;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
int m_videostart = 0;
|
||||
};
|
||||
|
||||
@ -211,20 +213,22 @@ void blit_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x000000, 0x000007, m_sysrom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0x040000, 0x045fff, "rom_shadow_r",[this](offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0x040000, 0x045fff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x000000, 0x000007, m_p_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x000000, 0x000007, m_p_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
|
||||
*m_misccr = 0;
|
||||
}
|
||||
@ -284,6 +288,8 @@ ROM_START( blit )
|
||||
ROMX_LOAD("rom5.bin", 0x4000, 0x08bf, CRC(d87f121f) SHA1(6e776ac29554b8a8bb332168c155bcc502c927b5), ROM_BIOS(0)|ROM_SKIP(1))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 1981, blit, 0, 0, blit, blit, blit_state, empty_init, "AT&T", "Blit", MACHINE_IS_SKELETON )
|
||||
|
@ -17,11 +17,15 @@ constantly looking at.
|
||||
*****************************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class c10_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -34,15 +38,18 @@ public:
|
||||
, m_p_chargen(*this, "chargen")
|
||||
{ }
|
||||
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void c10(machine_config &config);
|
||||
|
||||
private:
|
||||
void io_map(address_map &map);
|
||||
void mem_map(address_map &map);
|
||||
void machine_reset() override;
|
||||
void machine_start() override;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
|
||||
void io_map(address_map &map);
|
||||
void mem_map(address_map &map);
|
||||
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -77,20 +84,22 @@ void c10_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x0fff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0x8000, 0x8fff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0x8000, 0x8fff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
/* This system appears to have inline attribute bytes of unknown meaning.
|
||||
@ -189,6 +198,8 @@ ROM_START( c10 )
|
||||
ROM_LOAD( "c10_char.ic9", 0x0000, 0x2000, CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
|
@ -39,16 +39,19 @@ I/O ports: These ranges are what is guessed
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/terminal.h"
|
||||
#include "machine/upd765.h"
|
||||
#include "machine/z80ctc.h"
|
||||
#include "machine/z80daisy.h"
|
||||
#include "machine/z80pio.h"
|
||||
#include "machine/z80sio.h"
|
||||
#include "machine/z80ctc.h"
|
||||
#include "machine/terminal.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class ckz80_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -77,7 +80,7 @@ private:
|
||||
void io_map(address_map &map);
|
||||
void mem_map(address_map &map);
|
||||
u8 m_term_data = 0U;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -163,20 +166,22 @@ void ckz80_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x1fff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xe000, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xe000, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x1fff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x1fff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
|
||||
m_bank1->set_entry(1);
|
||||
}
|
||||
@ -227,6 +232,8 @@ ROM_START( ckz80 )
|
||||
ROM_LOAD( "ckz80.rom", 0x0000, 0x2000, CRC(7081b7c6) SHA1(13f75b14ea73b252bdfa2384e6eead6e720e49e3))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -17,13 +17,16 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/i8085/i8085.h"
|
||||
|
||||
//#include "bus/s100/s100.h"
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/terminal.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class imsai_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -49,7 +52,7 @@ private:
|
||||
u8 m_term_data = 0U;
|
||||
void machine_reset() override;
|
||||
void machine_start() override;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_device<generic_terminal_device> m_terminal;
|
||||
@ -109,20 +112,22 @@ void imsai_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xd800, 0xdfff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xd800, 0xdfff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// remove from the memory map
|
||||
m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x07ff);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// remove from the memory map
|
||||
m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x07ff);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void imsai_state::machine_start()
|
||||
@ -164,6 +169,8 @@ ROM_START( imsai )
|
||||
ROM_LOAD( "74s288.u38", 0x00, 0x20, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -51,10 +51,12 @@ TO DO
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "video/mc6845.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
@ -64,6 +66,8 @@ TO DO
|
||||
#define HD46505SP_TAG "h45"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class lola8a_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -95,7 +99,7 @@ private:
|
||||
void mem_map(address_map &map);
|
||||
|
||||
u8 m_portb = 0U;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<i8085a_cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -290,20 +294,22 @@ void lola8a_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x1fff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0x8000, 0x9fff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0x8000, 0x9fff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x1fff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x1fff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void lola8a_state::machine_start()
|
||||
@ -361,6 +367,8 @@ ROM_START( lola8a )
|
||||
ROM_LOAD( "lola 8a r2 w06 22.11.86.h67", 0x4000, 0x2000, CRC(1e7cd46b) SHA1(048b2583ee7baeb9621e629b79ed64583ac5d554))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -9,7 +9,7 @@ Bull (Originally R2E) Micral 80-22G
|
||||
http://www.ti99.com/exelvision/website/index.php?page=r2e-micral-8022-g
|
||||
|
||||
This expensive, futuristic-looking design featured a motherboard and slots,
|
||||
much like an ancient pc. The known chip complement is:
|
||||
much like an ancient PC. The known chip complement is:
|
||||
Z80A, 4MHz; 64KB RAM, 2KB BIOS ROM, 256x4 prom (7611);
|
||||
CRT8002, TMS9937 (=CRT5037), 4KB video RAM, 256x4 prom (7611);
|
||||
2x 5.25 inch floppy drives, one ST506 5MB hard drive;
|
||||
@ -56,17 +56,21 @@ https://www.esocop.org/docs/Questar.pdf
|
||||
*********************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "video/tms9927.h"
|
||||
#include "machine/ay31015.h"
|
||||
#include "machine/clock.h"
|
||||
//#include "sound/beep.h"
|
||||
#include "video/tms9927.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "machine/ay31015.h"
|
||||
#include "machine/clock.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class micral_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -101,7 +105,7 @@ private:
|
||||
u8 s_command = 0U;
|
||||
u8 s_data = 0U;
|
||||
std::unique_ptr<u8[]> m_vram;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -373,20 +377,22 @@ void micral_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf800, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf800, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void micral_state::machine_start()
|
||||
@ -464,6 +470,8 @@ ROM_START( questarm )
|
||||
ROM_LOAD( "c10_char.bin", 0x0000, 0x2000, BAD_DUMP CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -42,12 +42,16 @@ All input must in UPPER case.
|
||||
***********************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/keyboard.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class modellot_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -74,7 +78,7 @@ private:
|
||||
u8 m_term_data = 0U;
|
||||
void machine_start() override;
|
||||
void machine_reset() override;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -126,20 +130,22 @@ void modellot_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xe000, 0xe7ff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xe000, 0xe7ff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void modellot_state::machine_start()
|
||||
@ -246,6 +252,8 @@ ROM_START( modellot )
|
||||
ROM_CONTINUE(0x600, 0x200)
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
COMP( 1979, modellot, 0, 0, modellot, modellot, modellot_state, empty_init, "General Processor", "Modello T", MACHINE_IS_SKELETON | MACHINE_SUPPORTS_SAVE )
|
||||
|
||||
|
@ -75,17 +75,21 @@ Keyboard:
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "machine/keyboard.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/keyboard.h"
|
||||
#include "machine/pic8259.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "machine/timer.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "emupal.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class okean240_state : public driver_device
|
||||
{
|
||||
@ -132,7 +136,7 @@ private:
|
||||
required_shared_ptr<u8> m_p_videoram;
|
||||
optional_ioport_array<11> m_io_keyboard;
|
||||
optional_ioport m_io_modifiers;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<i8080_cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -399,20 +403,22 @@ void okean240_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom+0x2000); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xe000, 0xe7ff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xe000, 0xe7ff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
u32 okean240_state::screen_update_okean240(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
@ -554,6 +560,8 @@ ROM_START( okean240t )
|
||||
ROM_LOAD( "test.bin", 0x2000, 0x0800, CRC(e9e2b7b9) SHA1(e4e0b6984a2514b6ba3e97500d487ea1a68b7577) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -68,12 +68,15 @@ Assembler:
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "machine/clock.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class pimps_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -91,7 +94,7 @@ private:
|
||||
void mem_map(address_map &map);
|
||||
virtual void machine_reset() override;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -120,20 +123,22 @@ void pimps_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf000, 0xf7ff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf000, 0xf7ff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
// baud is not documented, we will use 9600
|
||||
@ -185,6 +190,8 @@ ROM_START( pimps )
|
||||
ROM_LOAD( "pimps.bin", 0x0000, 0x1000, CRC(5da1898f) SHA1(d20e31d0981a1f54c83186dbdfcf4280e49970d0))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */
|
||||
|
@ -24,13 +24,17 @@ ToDo:
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "sound/spkrdev.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "sound/spkrdev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class plan80_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -57,7 +61,7 @@ private:
|
||||
bool m_spk_pol = 0;
|
||||
virtual void machine_reset() override;
|
||||
virtual void machine_start() override;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -171,20 +175,22 @@ void plan80_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf800, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf800, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void plan80_state::machine_start()
|
||||
@ -278,6 +284,8 @@ ROM_START( plan80 )
|
||||
ROM_LOAD( "pl80gzn.bin", 0x0000, 0x0800, CRC(b4ddbdb6) SHA1(31bf9cf0f2ed53f48dda29ea830f74cea7b9b9b2) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -22,7 +22,10 @@
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/ieee488/ieee488.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/6840ptm.h"
|
||||
#include "machine/6850acia.h"
|
||||
#include "machine/bankdev.h"
|
||||
@ -32,13 +35,10 @@
|
||||
#include "machine/ram.h"
|
||||
#include "machine/tms9914.h"
|
||||
#include "video/saa5050.h"
|
||||
#include "bus/ieee488/ieee488.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
// Debugging
|
||||
@ -112,7 +112,7 @@ private:
|
||||
required_shared_ptr<uint8_t> m_lores_ram;
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
|
||||
memory_passthrough_handler *m_mmu_shadow_tap;
|
||||
memory_passthrough_handler m_mmu_shadow_tap;
|
||||
|
||||
uint8_t m_prev_opcode;
|
||||
};
|
||||
@ -152,30 +152,32 @@ void positron_state::machine_reset()
|
||||
m_mmu.active_key = 0;
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
m_mmu_shadow_tap = program.install_read_tap(0x0000, 0xffff, "mmu_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_fuse_timer_running && m_prev_opcode == 0x3b) // RTI
|
||||
m_mmu_shadow_tap.remove();
|
||||
m_mmu_shadow_tap = program.install_read_tap(
|
||||
0x0000, 0xffff,
|
||||
"mmu_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
m_mmu.active_key = m_mmu.operate_key;
|
||||
logerror("mmu_shadow_r: switched to task %d\n", m_mmu.active_key);
|
||||
m_mmu.sbit = false;
|
||||
m_fuse_timer_running = false;
|
||||
}
|
||||
else if (m_irq_ack && offset >= 0xfff0 && offset != 0xffff)
|
||||
{
|
||||
m_mmu.active_key = 0;
|
||||
logerror("irq_callback: switched to task %d\n", m_mmu.active_key);
|
||||
m_mmu.sbit = true;
|
||||
m_irq_ack = false;
|
||||
data = m_maincpu->space(AS_PROGRAM).read_byte(offset);
|
||||
}
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_fuse_timer_running && m_prev_opcode == 0x3b) // RTI
|
||||
{
|
||||
m_mmu.active_key = m_mmu.operate_key;
|
||||
logerror("mmu_shadow_r: switched to task %d\n", m_mmu.active_key);
|
||||
m_mmu.sbit = false;
|
||||
m_fuse_timer_running = false;
|
||||
}
|
||||
else if (m_irq_ack && offset >= 0xfff0 && offset != 0xffff)
|
||||
{
|
||||
m_mmu.active_key = 0;
|
||||
logerror("irq_callback: switched to task %d\n", m_mmu.active_key);
|
||||
m_mmu.sbit = true;
|
||||
m_irq_ack = false;
|
||||
data = m_maincpu->space(AS_PROGRAM).read_byte(offset);
|
||||
}
|
||||
}
|
||||
},
|
||||
&m_mmu_shadow_tap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -133,18 +133,7 @@
|
||||
#include "formats/sol_cas.h"
|
||||
|
||||
|
||||
struct cass_data_t {
|
||||
struct {
|
||||
int length; /* time cassette level is at input.level */
|
||||
int level; /* cassette level */
|
||||
int bit; /* bit being read */
|
||||
} input;
|
||||
struct {
|
||||
int length; /* time cassette level is at output.level */
|
||||
int level; /* cassette level */
|
||||
int bit; /* bit to output */
|
||||
} output;
|
||||
};
|
||||
namespace {
|
||||
|
||||
class sol20_state : public driver_device
|
||||
{
|
||||
@ -180,6 +169,20 @@ private:
|
||||
TIMER_SOL20_CASSETTE_TC,
|
||||
};
|
||||
|
||||
struct cass_data_t
|
||||
{
|
||||
struct {
|
||||
int length; /* time cassette level is at input.level */
|
||||
int level; /* cassette level */
|
||||
int bit; /* bit being read */
|
||||
} input;
|
||||
struct {
|
||||
int length; /* time cassette level is at output.level */
|
||||
int level; /* cassette level */
|
||||
int bit; /* bit to output */
|
||||
} output;
|
||||
};
|
||||
|
||||
u8 sol20_f8_r();
|
||||
u8 sol20_fa_r();
|
||||
u8 sol20_fc_r();
|
||||
@ -205,7 +208,7 @@ private:
|
||||
cass_data_t m_cass_data;
|
||||
emu_timer *m_cassette_timer;
|
||||
cassette_image_device *cassette_device_image();
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<i8080a_cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -625,20 +628,22 @@ void sol20_state::machine_reset()
|
||||
// Boot tap
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xc000, 0xc7ff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xc000, 0xc7ff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
|
||||
@ -821,6 +826,8 @@ ROM_START( sol20 )
|
||||
ROM_LOAD( "8574.u18", 0x000, 0x100, NO_DUMP ) // 256x4 bipolar PROM or mask ROM; second half unused
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 1976, sol20, 0, 0, sol20, sol20, sol20_state, empty_init, "Processor Technology Corporation", "Sol-20 Terminal Computer", MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -39,17 +39,20 @@ X - Test off-board memory banks
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/com8116.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/msm5832.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "machine/z80daisy.h"
|
||||
#include "machine/z80sio.h"
|
||||
#include "machine/msm5832.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/com8116.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class pulsar_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -80,7 +83,7 @@ private:
|
||||
void mem_map(address_map &map);
|
||||
|
||||
floppy_image_device *m_floppy;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -191,20 +194,22 @@ void pulsar_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf800, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf800, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void pulsar_state::machine_start()
|
||||
@ -264,6 +269,8 @@ ROM_START( pulsarlb )
|
||||
ROMX_LOAD( "lboot6.u2", 0x0000, 0x0800, CRC(3bca9096) SHA1(ff99288e51a9e832785ce8e3ab5a9452b1064231), ROM_BIOS(1))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -42,15 +42,19 @@ Status:
|
||||
*****************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
//#include "bus/s100/s100.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/z80ctc.h"
|
||||
#include "machine/z80pio.h"
|
||||
#include "machine/z80sio.h"
|
||||
//#include "bus/s100/s100.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class sys2900_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -70,7 +74,7 @@ private:
|
||||
|
||||
virtual void machine_reset() override;
|
||||
virtual void machine_start() override;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -105,20 +109,22 @@ void sys2900_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf000, 0xf7ff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf000, 0xf7ff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void sys2900_state::machine_start()
|
||||
@ -160,6 +166,8 @@ ROM_START( sys2900 )
|
||||
ROM_LOAD( "104401cpc.bin", 0x0000, 0x0800, CRC(6c8848bc) SHA1(890e0578e5cb0e3433b4b173e5ed71d72a92af26)) // label says BE 5 1/4 107701
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -128,9 +128,10 @@ private:
|
||||
u8 m_ssr; // system status register
|
||||
|
||||
// ram parity state
|
||||
memory_passthrough_handler *m_parity_mph;
|
||||
std::unique_ptr<u32[]> m_parity_flag;
|
||||
memory_passthrough_handler m_parity_mph;
|
||||
std::unique_ptr<u32 []> m_parity_flag;
|
||||
unsigned m_parity_bad;
|
||||
bool m_parity_check;
|
||||
};
|
||||
|
||||
class tek6100_state : public tekigw_state_base
|
||||
@ -233,6 +234,8 @@ void tekigw_state_base::machine_start()
|
||||
m_per = 0;
|
||||
m_ssr = 0;
|
||||
|
||||
m_parity_check = false;
|
||||
|
||||
m_buserror = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tek4132_state::buserror), this));
|
||||
}
|
||||
|
||||
@ -349,93 +352,97 @@ void tekigw_state_base::scr_w(u8 data)
|
||||
m_ssr &= ~(SSR_BERR | SSR_DMACH);
|
||||
|
||||
// install parity handlers
|
||||
if (!(m_scr & SCR_PARB) && (data & SCR_PARB) && !m_parity_mph)
|
||||
if (!(m_scr & SCR_PARB) && (data & SCR_PARB) && !m_parity_check)
|
||||
{
|
||||
m_parity_flag = std::make_unique<u32[]>(m_ram->size() / 32);
|
||||
m_parity_bad = 0;
|
||||
m_parity_check = true;
|
||||
|
||||
m_parity_mph = m_cpu->space(0).install_readwrite_tap(0, m_ram->mask(), "parity",
|
||||
[this](offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
if (m_scr & SCR_PARE)
|
||||
m_parity_mph = m_cpu->space(0).install_readwrite_tap(
|
||||
0, m_ram->mask(),
|
||||
"parity",
|
||||
[this] (offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
bool error = false;
|
||||
|
||||
// check bad parity (lo)
|
||||
if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0))
|
||||
if (m_scr & SCR_PARE)
|
||||
{
|
||||
m_ssr |= SSR_PERR;
|
||||
m_per &= ~PER_PARADR;
|
||||
m_per |= PER_LOERR | ((offset >> 9) & PER_PARADR);
|
||||
bool error = false;
|
||||
|
||||
error = true;
|
||||
// check bad parity (lo)
|
||||
if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0))
|
||||
{
|
||||
m_ssr |= SSR_PERR;
|
||||
m_per &= ~PER_PARADR;
|
||||
m_per |= PER_LOERR | ((offset >> 9) & PER_PARADR);
|
||||
|
||||
error = true;
|
||||
}
|
||||
|
||||
// check bad parity (hi)
|
||||
if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1))
|
||||
{
|
||||
m_ssr |= SSR_PERR;
|
||||
m_per &= ~PER_PARADR;
|
||||
m_per |= PER_HIERR | ((offset >> 9) & PER_PARADR);
|
||||
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (error && (m_scr & SCR_NMIE))
|
||||
m_cpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
}
|
||||
|
||||
// check bad parity (hi)
|
||||
if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1))
|
||||
{
|
||||
m_ssr |= SSR_PERR;
|
||||
m_per &= ~PER_PARADR;
|
||||
m_per |= PER_HIERR | ((offset >> 9) & PER_PARADR);
|
||||
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (error && (m_scr & SCR_NMIE))
|
||||
m_cpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
}
|
||||
},
|
||||
[this](offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
if (m_scr & SCR_PARB)
|
||||
},
|
||||
[this] (offs_t offset, u16 &data, u16 mem_mask)
|
||||
{
|
||||
// mark bad parity (lo)
|
||||
if ((mem_mask & 0x00ff) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 0))
|
||||
if (m_scr & SCR_PARB)
|
||||
{
|
||||
m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 0);
|
||||
m_parity_bad++;
|
||||
}
|
||||
// mark bad parity (lo)
|
||||
if ((mem_mask & 0x00ff) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 0))
|
||||
{
|
||||
m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 0);
|
||||
m_parity_bad++;
|
||||
}
|
||||
|
||||
// mark bad parity (hi)
|
||||
if ((mem_mask & 0xff00) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 1))
|
||||
{
|
||||
m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 1);
|
||||
m_parity_bad++;
|
||||
// mark bad parity (hi)
|
||||
if ((mem_mask & 0xff00) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 1))
|
||||
{
|
||||
m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 1);
|
||||
m_parity_bad++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// clear bad parity (lo)
|
||||
if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0))
|
||||
else
|
||||
{
|
||||
m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 0));
|
||||
m_parity_bad--;
|
||||
}
|
||||
// clear bad parity (lo)
|
||||
if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0))
|
||||
{
|
||||
m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 0));
|
||||
m_parity_bad--;
|
||||
}
|
||||
|
||||
// clear bad parity (hi)
|
||||
if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1))
|
||||
{
|
||||
m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 1));
|
||||
m_parity_bad--;
|
||||
}
|
||||
// clear bad parity (hi)
|
||||
if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1))
|
||||
{
|
||||
m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 1));
|
||||
m_parity_bad--;
|
||||
}
|
||||
|
||||
// stop checking parity if all clear
|
||||
if (!m_parity_bad)
|
||||
{
|
||||
m_parity_flag.reset();
|
||||
m_parity_mph->remove();
|
||||
m_parity_mph = nullptr;
|
||||
// stop checking parity if all clear
|
||||
if (!m_parity_bad)
|
||||
{
|
||||
m_parity_flag.reset();
|
||||
m_parity_mph.remove();
|
||||
m_parity_check = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
&m_parity_mph);
|
||||
}
|
||||
|
||||
// stop checking parity if all clear
|
||||
if ((m_scr & SCR_PARB) && !(data & SCR_PARB) && m_parity_mph && !m_parity_bad)
|
||||
if ((m_scr & SCR_PARB) && !(data & SCR_PARB) && m_parity_check && !m_parity_bad)
|
||||
{
|
||||
m_parity_flag.reset();
|
||||
m_parity_mph->remove();
|
||||
m_parity_mph = nullptr;
|
||||
m_parity_mph.remove();
|
||||
m_parity_check = false;
|
||||
}
|
||||
|
||||
if (data & SCR_PARE)
|
||||
|
@ -36,20 +36,24 @@ ToDo:
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/i8257.h"
|
||||
#include "video/i8275.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "sound/spkrdev.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/spkrdev.h"
|
||||
#include "video/i8275.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class unior_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -96,7 +100,7 @@ private:
|
||||
virtual void machine_reset() override;
|
||||
virtual void machine_start() override;
|
||||
std::unique_ptr<u8[]> m_vram;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -441,20 +445,22 @@ void unior_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf800, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf800, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void unior_state::machine_start()
|
||||
@ -545,6 +551,8 @@ ROM_START( unior )
|
||||
ROM_LOAD( "palette.rom.d9", 0x0800, 0x0040, BAD_DUMP CRC(b4574ceb) SHA1(f7a82c61ab137de8f6a99b0c5acf3ac79291f26a))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
|
@ -42,14 +42,17 @@ TODO:
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/clock.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "machine/pit8253.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class vector4_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -66,7 +69,7 @@ private:
|
||||
void vector4_io(address_map &map);
|
||||
void vector4_mem(address_map &map);
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -112,20 +115,22 @@ void vector4_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x0fff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xe000, 0xefff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xe000, 0xefff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
|
||||
@ -204,6 +209,8 @@ ROM_START( vector4 )
|
||||
ROM_LOAD( "chargen2.bin", 0x0800, 0x0800, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -128,13 +128,16 @@ Natural Keyboard and Paste:
|
||||
|
||||
/* Core includes */
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "includes/z80ne.h"
|
||||
#include "formats/dmk_dsk.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/ram.h"
|
||||
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "formats/dmk_dsk.h"
|
||||
|
||||
/* Layout */
|
||||
#include "z80ne.lh"
|
||||
#include "z80net.lh"
|
||||
|
@ -50,6 +50,9 @@ ToDo:
|
||||
// temporary
|
||||
#include "machine/keyboard.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class z9001_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -82,7 +85,7 @@ private:
|
||||
bool m_cassbit = 0;
|
||||
virtual void machine_reset() override;
|
||||
virtual void machine_start() override;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
@ -150,20 +153,22 @@ void z9001_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x0fff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf000, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf000, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void z9001_state::machine_start()
|
||||
@ -342,6 +347,8 @@ ROM_END
|
||||
|
||||
#define rom_kc87_21 rom_kc87_20
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* Driver */
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
|
@ -9,13 +9,15 @@
|
||||
#ifndef MAME_INCLUDES_DAI_H
|
||||
#define MAME_INCLUDES_DAI_H
|
||||
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "audio/dai_snd.h"
|
||||
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/tms5501.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/tms5501.h"
|
||||
|
||||
#include "emupal.h"
|
||||
|
||||
|
||||
@ -65,7 +67,7 @@ private:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<pit8253_device> m_pit;
|
||||
required_device<tms5501_device> m_tms5501;
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/i8255.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "sound/dac.h"
|
||||
|
||||
class mikro80_state : public driver_device
|
||||
@ -59,7 +59,7 @@ private:
|
||||
void mikro80_mem(address_map &map);
|
||||
void radio99_io(address_map &map);
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_shared_ptr<uint8_t> m_aram;
|
||||
required_shared_ptr<uint8_t> m_vram;
|
||||
required_device<i8255_device> m_ppi;
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "formats/mm_dsk.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/am9517a.h"
|
||||
#include "machine/bankdev.h"
|
||||
@ -15,12 +14,15 @@
|
||||
#include "machine/mm1kb.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/z80sio.h"
|
||||
#include "machine/upd765.h"
|
||||
#include "machine/z80sio.h"
|
||||
#include "video/i8275.h"
|
||||
#include "video/upd7220.h"
|
||||
|
||||
#include "emupal.h"
|
||||
|
||||
#include "formats/mm_dsk.h"
|
||||
|
||||
#define SCREEN_TAG "screen"
|
||||
#define I8085A_TAG "ic40"
|
||||
#define I8212_TAG "ic12"
|
||||
|
@ -81,7 +81,7 @@ protected:
|
||||
uint8_t memory_read_byte(offs_t offset);
|
||||
void memory_write_byte(offs_t offset, uint8_t data);
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
optional_device<generic_slot_device> m_cart; // for ROMDisk - only Radio86K & Orion?
|
||||
|
@ -10,22 +10,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "bus/generic/carts.h"
|
||||
#include "bus/generic/slot.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "imagedev/snapquik.h"
|
||||
#include "machine/ay31015.h"
|
||||
#include "machine/clock.h"
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "machine/ram.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "imagedev/snapquik.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "formats/sorc_dsk.h"
|
||||
#include "formats/sorc_cas.h"
|
||||
#include "machine/micropolis.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "machine/z80dma.h"
|
||||
#include "bus/generic/slot.h"
|
||||
#include "bus/generic/carts.h"
|
||||
|
||||
#include "formats/sorc_cas.h"
|
||||
#include "formats/sorc_dsk.h"
|
||||
|
||||
|
||||
class sorcerer_state : public driver_device
|
||||
@ -141,7 +142,7 @@ protected:
|
||||
required_ioport m_iop_config;
|
||||
required_ioport m_iop_vs;
|
||||
required_ioport_array<16> m_iop_x;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
|
||||
private:
|
||||
u8 m_port48;
|
||||
|
@ -19,9 +19,11 @@
|
||||
#include "sound/samples.h"
|
||||
#include "sound/spkrdev.h"
|
||||
#include "video/mc6845.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
/* Bits in m_portf0 variable:
|
||||
d5 cassette LED
|
||||
d4 super80v rom or pcg bankswitch (1=pcg ram, 0=char gen rom)
|
||||
@ -84,7 +86,7 @@ protected:
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_region_ptr<u8> m_rom;
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
required_region_ptr<u8> m_p_chargen;
|
||||
required_device<z80pio_device> m_pio;
|
||||
@ -99,11 +101,12 @@ protected:
|
||||
output_finder<> m_cass_led;
|
||||
|
||||
private:
|
||||
|
||||
void machine_reset() override;
|
||||
void machine_start() override;
|
||||
|
||||
void portf1_w(u8 data);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(timer_h);
|
||||
|
||||
uint32_t screen_update_super80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_super80d(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_super80e(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
@ -11,12 +11,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "sound/dac.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/dac.h"
|
||||
|
||||
#include "emupal.h"
|
||||
|
||||
|
||||
class ut88_common : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -79,7 +81,7 @@ private:
|
||||
|
||||
int m_keyboard_mask;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<i8255_device> m_ppi;
|
||||
required_device<dac_bit_interface> m_dac;
|
||||
required_shared_ptr<uint8_t> m_vram;
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "video/mc6847.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/ay31015.h"
|
||||
@ -23,6 +22,7 @@
|
||||
#include "machine/kr2376.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "video/mc6847.h"
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
@ -120,7 +120,7 @@ protected:
|
||||
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
|
||||
|
||||
memory_passthrough_handler *m_rom_shadow_tap;
|
||||
memory_passthrough_handler m_rom_shadow_tap;
|
||||
required_device<ay31015_device> m_uart;
|
||||
required_device<clock_device> m_uart_clock;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
|
@ -73,20 +73,22 @@ void dai_state::machine_reset()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xc000, 0xc7ff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xc000, 0xc7ff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -81,28 +81,29 @@ void fidel_clockdiv_state::div_refresh(ioport_value val)
|
||||
m_div_timer->adjust(period, 0, period);
|
||||
|
||||
// set up memory passthroughs
|
||||
if (m_read_tap)
|
||||
{
|
||||
m_read_tap->remove();
|
||||
m_write_tap->remove();
|
||||
m_read_tap = nullptr;
|
||||
m_write_tap = nullptr;
|
||||
}
|
||||
m_read_tap.remove();
|
||||
m_write_tap.remove();
|
||||
|
||||
if (val)
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
m_read_tap = program.install_read_tap(0x0000, 0xffff, "program_div_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
div_set_cpu_freq(offset & 0x6000);
|
||||
return data;
|
||||
});
|
||||
m_write_tap = program.install_write_tap(0x0000, 0xffff, "program_div_w",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
div_set_cpu_freq(offset & 0x6000);
|
||||
return data;
|
||||
});
|
||||
m_read_tap = program.install_read_tap(
|
||||
0x0000, 0xffff,
|
||||
"program_div_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
div_set_cpu_freq(offset & 0x6000);
|
||||
},
|
||||
&m_read_tap);
|
||||
m_write_tap = program.install_write_tap(
|
||||
0x0000, 0xffff,
|
||||
"program_div_w",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
div_set_cpu_freq(offset & 0x6000);
|
||||
},
|
||||
&m_write_tap);
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ protected:
|
||||
private:
|
||||
inline void div_set_cpu_freq(offs_t offset);
|
||||
|
||||
memory_passthrough_handler *m_read_tap = nullptr;
|
||||
memory_passthrough_handler *m_write_tap = nullptr;
|
||||
memory_passthrough_handler m_read_tap;
|
||||
memory_passthrough_handler m_write_tap;
|
||||
|
||||
u16 m_div_status;
|
||||
double m_div_scale;
|
||||
|
@ -65,25 +65,27 @@ void mikro80_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf800, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf800, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void mikro80_state::tape_w(u8 data)
|
||||
{
|
||||
// Todo: this is incorrect, to be fixed when the CMT schematic can be found
|
||||
// TODO: this is incorrect, to be fixed when the CMT schematic can be found
|
||||
m_cassette->output(BIT(data, 0) ? 1.0 : -1.0);
|
||||
}
|
||||
|
||||
|
@ -142,20 +142,22 @@ void radio86_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x0fff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf000, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf000, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void radio86_state::machine_start()
|
||||
|
@ -498,20 +498,22 @@ void sorcerer_state::machine_reset_common()
|
||||
portfe_w(0);
|
||||
|
||||
space.install_rom(0x0000, 0x0fff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = space.install_read_tap(0xe000, 0xefff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = space.install_read_tap(
|
||||
0xe000, 0xefff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram->pointer());
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram->pointer());
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void sorcerer_state::machine_reset()
|
||||
|
@ -230,20 +230,22 @@ void super80_state::machine_reset_common()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x0fff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xc000, 0xcfff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xc000, 0xcfff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void super80_state::machine_reset()
|
||||
|
@ -70,20 +70,22 @@ void ut88_state::machine_reset()
|
||||
m_keyboard_mask = 0;
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0xf800, 0xffff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0xf800, 0xffff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void ut88_state::machine_start()
|
||||
|
@ -265,20 +265,22 @@ void z80ne_state::machine_reset()
|
||||
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
program.install_rom(0x0000, 0x03ff, m_rom); // do it here for F3
|
||||
m_rom_shadow_tap = program.install_read_tap(0x8000, 0x83ff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0x8000, 0x83ff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x03ff, m_mram);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x03ff, m_mram);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
|
||||
void z80net_state::machine_reset()
|
||||
@ -303,20 +305,22 @@ void z80netf_state::machine_reset()
|
||||
if ((m_io_config->read() & 0x07) != 2)
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
m_rom_shadow_tap = program.install_read_tap(0x8000, 0xf3ff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap->remove();
|
||||
m_rom_shadow_tap.remove();
|
||||
m_rom_shadow_tap = program.install_read_tap(
|
||||
0x8000, 0xf3ff,
|
||||
"rom_shadow_r",
|
||||
[this] (offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
// delete this tap
|
||||
m_rom_shadow_tap.remove();
|
||||
|
||||
// reinstall ram over the rom shadow
|
||||
m_bank1->set_entry(0);
|
||||
}
|
||||
|
||||
// return the original data
|
||||
return data;
|
||||
});
|
||||
// reinstall RAM over the ROM shadow
|
||||
m_bank1->set_entry(0);
|
||||
}
|
||||
},
|
||||
&m_rom_shadow_tap);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user