-General maintenance on emu/devfind:

* Harmonised memory region/share finder/creator APIs.
 * Moved .found() to optional object finders.
 * Added truth test operator to optional object finders.
 * Fixed things that were testing .found() on required object finders.
 * Improved Doxygen API documentation.

-dec8.cpp: Moved csilver to its own state class.

-docs: Added some notes about setting up and using MSYS2.
This commit is contained in:
Vas Crabb 2020-11-04 03:12:38 +11:00
parent a028db4e8c
commit 9e71712b3b
12 changed files with 543 additions and 331 deletions

View File

@ -119,6 +119,28 @@ with MSYS2 and the **pacman** package manager.
empty string (e.g. using the command **export MINGW32=/mingw32 MINGW64=** in
the Bash shell).
For example you could use these commands to ensure you have the packages you
need to compile MAME, omitting the ones for configurations you dont plan to
build for or combining multiple **pacman** commands to install more packages at
once::
pacman -Syu
pacman -S curl git make
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-libc++ mingw-w64-x86_64-lld mingw-w64-x86_64-python
pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf
pacman -S mingw-w64-x86_64-qt5
pacman -S mingw-w64-i686-gcc mingw-w64-i686-libc++ mingw-w64-i686-lld mingw-w64-i686-python
pacman -S mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_ttf
pacman -S mingw-w64-i686-qt5
You could use these commands to install the current version of the
mame-essentials package and add the MAME package repository to yur pacman
configuration::
curl -O "https://repo.mamedev.org/x86_64/mame-essentials-1.0.6-1-x86_64.pkg.tar.xz"
pacman -U mame-essentials-1.0.6-1-x86_64.pkg.tar.xz
echo -e '\n[mame]\nInclude = /etc/pacman.d/mirrorlist.mame' >> /etc/pacman.conf
Building with Microsoft Visual Studio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -137,6 +159,51 @@ Building with Microsoft Visual Studio
* The MSYS2 environment is still required to generate the project files, convert
built-in layouts, compile UI translations, etc.
Some notes about the MSYS2 environment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MSYS2 uses the pacman tool from Arch Linux for package management. There is a
`page on the Arch Linux wiki <https://wiki.archlinux.org/index.php/Pacman>`_
with helpful information on using the pacman package management tool.
The MSYS2 environment includes two kinds of tools: MSYS2 tools designed to work
in a UNIX-like environment on top of Windows, and MinGW tools designed to work
in a more Windows-like environment. The MSYS2 tools are installed in
``/usr/bin`` while the MinGW tools are installed in ``/ming64/bin`` and/or
``/mingw32/bin`` (relative to the MSYS2 installation directory). MSYS2 tools
work best in an MSYS2 terminal, while MinGW tools work best in a Microsoft
command prompt.
The most obvious symptom of this is that arrow keys dont work in interactive
programs dont work if you run them in the wrong kind of terminal. If you run
MinGW gdb or python from an MSYS2 terminal window, command history wont work
and it may not be possible to interrupt an attached program with gdb. Similarly
it may be very difficult to edit using MSYS2 vim in a Microsoft command prompt
window.
MAME is built using the MinGW compilers, so the MinGW directories are included
earlier in the ``PATH`` for the build environments. If you want to use an
interactive MSYS2 program from an MSYS2 shell, you may need to type the absolute
path to avoid using the MinGW equivalent instead.
MSYS2 gdb may have issues debugging MinGW programs like MAME. You may get
better results by installing the MinGW version of gdb and running it from a
Microsoft command prompt window to debug MAME.
GNU make supports both POSIX-style shells (e.g. bash) and the Microsoft cmd.exe
shell. One issue to be aware of when using the cmd.exe shell is that the
``copy`` command doesnt provide a useful exit status, so file copy tasks can
fail silently.
It is not possible to cross-compile a 32-bit version of MAME using 64-bit MinGW
tools on Windows, the 32-bit MinGW tools must be used. This causes issues due
to the size of MAME. It is not possible to link a full 32-bit MAME build
including the SDL OS-dependent layer and the Qt debugger. GNU ld and lld will
both run out of memory, leaving an output file that doesnt work. Its also
impossible to make a 32-bit build with full local variable symbols. GCC may run
out of memory, and certain source files may exceed the limit of 32,768 sections
imposed by the PE/COFF object file format.
.. _compiling-fedora:

View File

@ -150,12 +150,9 @@ void a2bus_agat840k_hle_device::device_reset()
for (auto &img : m_floppy_image)
{
if (img.found())
{
img->floppy_drive_set_ready_state(FLOPPY_DRIVE_READY, 0);
img->floppy_drive_set_rpm(300.);
img->floppy_drive_seek(-img->floppy_drive_get_current_track());
}
img->floppy_drive_set_ready_state(FLOPPY_DRIVE_READY, 0);
img->floppy_drive_set_rpm(300.);
img->floppy_drive_seek(-img->floppy_drive_get_current_track());
}
m_floppy = m_floppy_image[0].target();

View File

@ -145,7 +145,7 @@ public:
/// \brief Get constant iterator beyond last element
///
/// Returns aconstant iterator one past the last element in the
/// Returns a constant iterator one past the last element in the
/// array.
/// \return Constant iterator one past last element.
const_iterator cend() const { return m_array + Count; }
@ -165,7 +165,7 @@ public:
/// \brief Does array have no elements
///
/// Returns whether the arary has no elements (compile-time
/// Returns whether the array has no elements (compile-time
/// constant).
/// \return True if the array has no elements, false otherwise.
constexpr bool empty() const { return !Count; }
@ -198,7 +198,7 @@ public:
/// \return Reference to element at specified index.
T &operator[](unsigned index) { assert(index < Count); return m_array[index]; }
/// \brief Checked element accesor
/// \brief Checked element accessor
///
/// Returns a reference to the element at the supplied index if less
/// than the size of the array, or throws std::out_of_range
@ -423,9 +423,9 @@ protected:
/// \brief Pointer to next registered discovery helper
///
/// This is a polymorphic class, so it can't be held in a standardlist
/// container that requires elements of the same type. Hence it
/// implements basic single-linked list behaviour.
/// This is a polymorphic class, so it can't be held in a standard
/// list container that requires elements of the same type. Hence
/// it implements basic intrusive single-linked list behaviour.
finder_base *const m_next;
/// \brief Base device to search from
@ -448,7 +448,7 @@ protected:
/// Assumes that non-null pointer is found, and null pointer is not
/// found.
template <class ObjectClass, bool Required>
class object_finder_base : public finder_base
class object_finder_common_base : public finder_base
{
public:
/// \brief Clear temporary binding from configuration
@ -460,16 +460,10 @@ public:
virtual void end_configuration() override { assert(!m_resolved); m_target = nullptr; }
/// \brief Get pointer to target object
///
/// \return Pointer to target object if found, or nullptr otherwise.
ObjectClass *target() const { return m_target; }
/// \brief Return whether target has been found
///
/// Works on the assumption that the target object pointer will be
/// non-null if the target has been found, and null otherwise.
/// \return True if object has been found, or false otherwise.
bool found() const { return m_target != nullptr; }
/// \brief Cast-to-pointer operator
///
/// Allows implicit casting to a pointer to the target object.
@ -495,7 +489,7 @@ protected:
/// \param [in] tag Object tag to search for. This is not copied,
/// it is the caller's responsibility to ensure this pointer
/// remains valid until resolution time.
object_finder_base(device_t &base, const char *tag) : finder_base(base, tag) { }
object_finder_common_base(device_t &base, const char *tag) : finder_base(base, tag) { }
/// \brief Log if object was not found
///
@ -505,7 +499,7 @@ protected:
/// implementation for more detail.
/// \param [in] objname Display name for target object type.
/// \return True if found or not required, false otherwise.
bool report_missing(char const *objname) const { return finder_base::report_missing(found(), objname, Required); }
bool report_missing(char const *objname) const { return finder_base::report_missing(m_target != nullptr, objname, Required); }
/// \brief Pointer to target object
///
@ -516,6 +510,48 @@ protected:
};
/// \brief Base class for object discovery helpers
///
/// Allows partial specialisations to add members based on object class
/// and/or whether the object is required. Template arguments are the
/// type of object to discover, and whether failure to find the object
/// is considered an error.
template <class ObjectClass, bool Required>
class object_finder_base : public object_finder_common_base<ObjectClass, Required>
{
using object_finder_common_base<ObjectClass, Required>::object_finder_common_base;
};
/// \brief Base class for optional object discovery helpers
///
/// Adds helpers for to test whether the object was found, and by
/// extension whether it's safe to dereference. Template argument is
/// the type of object to discover.
template <class ObjectClass>
class object_finder_base<ObjectClass, false> : public object_finder_common_base<ObjectClass, false>
{
public:
/// \brief Return whether target has been found
///
/// Works on the assumption that the target object pointer will
/// be non-null if the target has been found, and null
/// otherwise.
/// \return True if object has been found, or false otherwise.
bool found() const { return this->m_target != nullptr; }
/// \brief Cast-to-Boolean operator
///
/// Allows truth tests to test whether it's safe to dereference
/// the object, similar to pointers and various C++ standard
/// library objects.
/// \return True if safe to dereference, or false otherwise.
explicit operator bool() const { return this->m_target != nullptr; }
using object_finder_common_base<ObjectClass, false>::object_finder_common_base;
};
/// \brief Device finder template
///
/// Template arguments are the device class to find, and whether the
@ -617,7 +653,7 @@ private:
/// \brief Optional device finder
///
/// Finds device with maching type and tag. If a device with matching
/// Finds device with matching type and tag. If a device with matching
/// tag is found but the type does not match, a message is printed at
/// warning level. No error is generated if a matching device is not
/// found (the target object pointer will be null). If you have a
@ -628,7 +664,7 @@ template <class DeviceClass> using optional_device = device_finder<DeviceClass,
/// \brief Required device finder
///
/// Finds device with maching type and tag. If a device with matching
/// Finds device with matching type and tag. If a device with matching
/// tag is found but the type does not match, a message is printed at
/// warning level. A validation error is generated if a matching device
/// is not found. If you have a number of similar required devices,
@ -675,7 +711,7 @@ private:
/// \brief Optional memory region finder
///
/// Finds memory region with maching tag. No error is generated if a
/// Finds memory region with matching tag. No error is generated if a
/// matching memory region is not found (the target object pointer will
/// be null). If you have a number of similar optional memory regions,
/// consider using optional_memory_region_array.
@ -685,7 +721,7 @@ using optional_memory_region = memory_region_finder<false>;
/// \brief Required memory region finder
///
/// Finds memory region with maching tag. A validation error is
/// Finds memory region with matching tag. A validation error is
/// generated if a matching memory region is not found. If you have a
/// number of similar required memory regions, consider using
/// required_memory_region_array.
@ -731,7 +767,7 @@ public:
/// \brief Optional memory bank finder
///
/// Finds memory bank with maching tag. No error is generated if a
/// Finds memory bank with matching tag. No error is generated if a
/// matching memory bank is not found (the target object pointer will
/// be null). If you have a number of similar optional memory banks,
/// consider using optional_memory_bank_array.
@ -741,7 +777,7 @@ using optional_memory_bank = memory_bank_finder<false>;
/// \brief Required memory bank finder
///
/// Finds memory bank with maching tag. A validation error is
/// Finds memory bank with matching tag. A validation error is
/// generated if a matching memory bank is not found. If you have a
/// number of similar required memory banks, consider using
/// required_memory_bank_array.
@ -756,28 +792,34 @@ template <unsigned Count> using required_memory_bank_array = memory_bank_array_f
/// \brief Memory bank creator
///
/// Creates a memory bank or finds an existing one.
/// Creates a memory bank or finds an existing one instantiated via an
/// address map.
class memory_bank_creator : finder_base
{
public:
/// \brief Memory bank creator constructor
/// \param [in] base Base device to search from.
/// \param [in] tag Memory bank tag to search for or create. This
/// is not copied, it is the caller's responsibility to ensure
/// this pointer remains valid until resolution time.
memory_bank_creator(device_t &base, char const *tag) : finder_base(base, tag) { }
virtual ~memory_bank_creator() = default;
/// \brief Get pointer to target bank object
/// \return Pointer to target bank object if found, or nullptr otherwise.
/// \brief Get pointer to memory bank object
/// \return Pointer to found or created bank object.
memory_bank *target() const { return m_target; }
/// \brief Cast-to-pointer operator
///
/// Allows implicit casting to a pointer to the target bank object.
/// \return Pointer to target bank object
/// Allows implicit casting to a pointer to the target
/// memory bank object.
/// \return Pointer to found or created memory bank object.
operator memory_bank *() const { return m_target; }
/// \brief Pointer member access operator
///
/// Allows pointer-member-style access to members of the target
/// bank object.
/// \return Pointer to target bank object
/// memory bank object.
/// \return Pointer to found or created bank object.
memory_bank *operator->() const { return m_target; }
protected:
@ -786,65 +828,14 @@ protected:
/// \brief Pointer to target object
///
/// Pointer to target object, or nullptr if the creation has not been
/// attempted yet.
/// Pointer to target memory bank object, or nullptr if creation has
/// not been attempted yet.
memory_bank *m_target = nullptr;
};
template <unsigned Count> using memory_bank_array_creator = object_array_finder<memory_bank_creator, Count>;
/// \brief Memory share creator template
///
/// Creates a memory share or finds an existing one.
template <typename PointerType> class memory_share_creator : finder_base
{
public:
memory_share_creator(device_t &base, char const *tag, size_t bytes, endianness_t endianness);
virtual ~memory_share_creator() = default;
/// \brief Get pointer to the share object
/// \return Pointer to share object.
memory_share *target() const { return m_target; }
/// \brief Get pointer to the share object backing RAM
/// \return Pointer to the RAM.
PointerType *ptr() const { return reinterpret_cast<PointerType *>(m_target->ptr()); }
/// \brief Cast-to-pointer operator
///
/// Allows implicit casting to a pointer to the target backing RAM.
/// \return Pointer to target bank object
operator PointerType *() const { return reinterpret_cast<PointerType *>(m_target->ptr()); }
/// \brief Pointer member access operator
///
/// Allows pointer-member-style access to members of the target
/// bank object.
/// \return Pointer to target bank object
memory_share *operator->() const { return m_target; }
size_t bytes() const { return m_target->bytes(); }
endianness_t endianness() const { return m_target->endianness(); }
u8 bitwidth() const { return m_target->bitwidth(); }
u8 bytewidth() const { return m_target->bytewidth(); }
protected:
virtual bool findit(validity_checker *valid) override;
virtual void end_configuration() override;
/// \brief Pointer to target object
///
/// Pointer to target object, or nullptr if the creation has not been
/// attempted yet.
memory_share *m_target = nullptr;
const u8 m_width; // width of the shared region in bits
const size_t m_bytes; // size of the shared region in bytes
const endianness_t m_endianness; // endianness of the memory
};
/// \brief I/O port finder template
///
/// Template argument is whether the I/O port is required. It is a
@ -889,7 +880,7 @@ private:
/// \brief Optional I/O port finder
///
/// Finds I/O port with maching tag. No error is generated if a
/// Finds I/O port with matching tag. No error is generated if a
/// matching I/O port is not found (the target object pointer will be
/// null). If you have a number of similar optional I/O ports, consider
/// using optional_ioport_array.
@ -898,9 +889,9 @@ using optional_ioport = ioport_finder<false>;
/// \brief Required I/O port finder
///
/// Finds I/O port with maching tag. A validation error is generated if
/// a matching I/O port is not found. If you have a number of similar
/// required I/O ports, consider using required_ioport_array.
/// Finds I/O port with matching tag. A validation error is generated
/// if a matching I/O port is not found. If you have a number of
/// similar required I/O ports, consider using required_ioport_array.
/// \sa optional_ioport required_ioport_array ioport_finder
using required_ioport = ioport_finder<true>;
@ -985,8 +976,8 @@ private:
/// \param [in] valid Pass a pointer to the validity checker if this
/// is a dry run (i.e. no intention to actually start the device),
/// or nullptr otherwise.
/// \return True if the address space is optional, a matching address space is
/// is found or this is a dry run, false otherwise.
/// \return True if the address space is optional, a matching
/// address space is found or this is a dry run, false otherwise.
virtual bool findit(validity_checker *valid) override;
int m_spacenum;
@ -995,16 +986,16 @@ private:
/// \brief Optional address space finder
///
/// Finds address space with maching tag and number. No error is generated if a
/// matching address space is not found (the target object pointer will be
/// null).
/// Finds address space with matching tag and number. No error is
/// generated if a matching address space is not found (the target
/// object pointer will be null).
/// \sa required_address_space address_space_finder
using optional_address_space = address_space_finder<false>;
/// \brief Required address space finder
///
/// Finds address space with maching tag and number. A validation error is generated if
/// a matching address space is not found.
/// Finds address space with matching tag and number. A validation
/// error is generated if a matching address space is not found.
/// \sa optional_address_space address_space_finder
using required_address_space = address_space_finder<true>;
@ -1039,18 +1030,20 @@ public:
/// \brief Array access operator
///
/// Returns a non-const reference to the element of the memory
/// region at the supplied zero-based index.
/// Behaviour is undefined for negative element indices.
/// region at the supplied zero-based index. Behaviour is undefined
/// for negative element indices.
/// \param [in] index Non-negative element index.
/// \return Non-const reference to element at requested index.
PointerType &operator[](int index) const { assert(index < m_length); return this->m_target[index]; }
/// \brief Get length in units of elements
///
/// \return Length in units of elements or zero if no matching
/// memory region has been found.
u32 length() const { return m_length; }
/// \brief Get length in units of bytes
///
/// \return Length in units of bytes or zero if no matching memory
/// region has been found.
u32 bytes() const { return m_length * sizeof(PointerType); }
@ -1097,7 +1090,7 @@ private:
/// \brief Optional memory region base pointer finder
///
/// Finds base pointer of memory region with maching tag, width and
/// Finds base pointer of memory region with matching tag, width and
/// length. No error is generated if a matching memory region is not
/// found (the target pointer will be null). If you have a number of
/// similar optional memory regions, consider using
@ -1107,7 +1100,7 @@ template <typename PointerType> using optional_region_ptr = region_ptr_finder<Po
/// \brief Required memory region base pointer finder
///
/// Finds base pointer of memory region with maching tag, width and
/// Finds base pointer of memory region with matching tag, width and
/// length. A validation error is generated if a matching memory region
/// is not found. If you have a number of similar required memory
/// regions, consider using required_region_ptr_array.
@ -1119,29 +1112,65 @@ template <typename PointerType, unsigned Count> using optional_region_ptr_array
template <typename PointerType, unsigned Count> using required_region_ptr_array = region_ptr_array_finder<PointerType, Count, true>;
// ======================> shared_ptr_finder
// shared pointer finder template
/// \brief Memory share base pointer finder
///
/// Template arguments are the element type of the memory share and
/// whether the memory share is required. It is a validation error if a
/// required memory share is not found. This class is generally not
/// used directly, instead the optional_shared_ptr and
/// required_shared_ptr helpers are used.
/// \sa optional_shared_ptr required_shared_ptr
template <typename PointerType, bool Required>
class shared_ptr_finder : public object_finder_base<PointerType, Required>
{
public:
// construction/destruction
/// \brief Memory share finder constructor
///
/// Desired width is implied by sizeof(PointerType).
/// \param [in] base Base device to search from.
/// \param [in] tag Memory share tag to search for. This is not
/// copied, it is the caller's responsibility to ensure this
/// pointer remains valid until resolution time.
shared_ptr_finder(device_t &base, char const *tag)
: object_finder_base<PointerType, Required>(base, tag)
, m_bytes(0)
{
}
// operators to make use transparent
/// \brief Array access operator
///
/// Returns a non-const reference to the element of the memory
/// share at the supplied zero-based index. Behaviour is undefined
/// for negative element indices.
/// \param [in] index Non-negative element index.
/// \return Non-const reference to element at requested index.
PointerType &operator[](int index) const { return this->m_target[index]; }
// getter for explicit fetching
/// \brief Get length in units of elements
///
/// \return Length in units of elements or zero if no matching
/// memory region has been found.
u32 length() const { return m_bytes / sizeof(PointerType); }
/// \brief Get length in bytes
///
/// \return Length in bytes or zero if no matching memory share has
/// been found.
u32 bytes() const { return m_bytes; }
u32 mask() const { return m_bytes - 1; } // FIXME: wrong when sizeof(PointerType) != 1
private:
// finder
/// \brief Find memory share base pointer
///
/// Find base pointer of memory share with with requested tag.
/// Width of memory share is checked against sizeof(PointerType).
/// This method is called by the base device at resolution time.
/// \param [in] valid Pass a pointer to the validity checker if this
/// is a dry run (i.e. no intention to actually start the device),
/// or nullptr otherwise.
/// \return True if the memory share is optional or a matching
/// memory share is found, or false otherwise.
virtual bool findit(validity_checker *valid) override
{
if (valid)
@ -1153,17 +1182,131 @@ private:
return this->report_missing("shared pointer");
}
// internal state
/// \brief Memory share length
///
/// Actual length of the memory share that was found in bytes, or
/// zero if no matching region has been found.
size_t m_bytes;
};
/// \brief Optional memory share base pointer finder
///
/// Finds base pointer of memory share with matching tag and width. No
/// error is generated if a matching memory share is not found (the
/// target pointer will be null). If you have a number of similar
/// optional memory regions, consider using optional_shared_ptr_array.
/// \sa required_shared_ptr optional_shared_ptr_array shared_ptr_finder
template <typename PointerType> using optional_shared_ptr = shared_ptr_finder<PointerType, false>;
/// \brief Required memory share base pointer finder
///
/// Finds base pointer of memory share with matching tag and width. A
/// validation error is generated if a matching memory share is not
/// found. If you have a number of similar required memory shares,
/// consider using required_shared_ptr_array.
/// \sa optional_shared_ptr required_shared_ptr_array shared_ptr_finder
template <typename PointerType> using required_shared_ptr = shared_ptr_finder<PointerType, true>;
template <typename PointerType, unsigned Count, bool Required> using shared_ptr_array_finder = object_array_finder<shared_ptr_finder<PointerType, Required>, Count>;
template <typename PointerType, unsigned Count> using optional_shared_ptr_array = shared_ptr_array_finder<PointerType, Count, false>;
template <typename PointerType, unsigned Count> using required_shared_ptr_array = shared_ptr_array_finder<PointerType, Count, true>;
/// \brief Memory share creator template
///
/// Creates a memory share or finds an existing one instantiated via an
/// address map. Template argument is the element type of the memory
/// share. If an existing memory share is found, it is an error if it
/// doesn't match the requested width, length and endianness.
template <typename PointerType>
class memory_share_creator : finder_base
{
public:
/// \brief Memory share creator constructor
///
/// Desired width is implied by sizeof(PointerType).
/// \param [in] base Base device to search from.
/// \param [in] tag Memory share tag to search for or create. This
/// is not copied, it is the caller's responsibility to ensure
/// this pointer remains valid until resolution time.
/// \param [in] bytes Desired memory share length in bytes.
/// \param [in] endianness Desired endianness of the memory share.
memory_share_creator(device_t &base, char const *tag, size_t bytes, endianness_t endianness);
/// \brief Get target memory share base pointer
///
/// Must not be called before creation is attempted.
/// \return Base pointer of found or created memory share.
PointerType *target() const { return reinterpret_cast<PointerType *>(m_target->ptr()); }
/// \brief Cast-to-pointer operator
///
/// Allows implicit casting to the base pointer of the target memory
/// share. Must not be called before creation is attempted.
/// \return Base pointer of found or created memory share.
operator PointerType *() const { return target(); }
/// \brief Array access operator
///
/// Returns a non-const reference to the element of the memory
/// share at the supplied zero-based index. Behaviour is undefined
/// for negative element indices. Must not be called before
/// creation is attempted.
/// \param [in] index Non-negative element index.
/// \return Non-const reference to element at requested index.
PointerType &operator[](int index) const { return target()[index]; }
/// \brief Get length in units of elements
///
/// Must not be called before creation is attempted.
/// \return Length of memory share in units of elements.
size_t length() const { return m_target->bytes() / sizeof(PointerType); }
/// \brief Get length in bytes
///
/// Must not be called before creation is attempted.
/// \return Length of memory share in bytes.
size_t bytes() const { return m_target->bytes(); }
/// \brief Get endianness
///
/// Must not be called before creation is attempted.
/// \return Endianness of memory share.
endianness_t endianness() const { return m_target->endianness(); }
/// \brief Get width in bits
///
/// Must not be called before creation is attempted.
/// \return Memory share width in bits.
u8 bitwidth() const { return m_target->bitwidth(); }
/// \brief Get width in bytes
///
/// Must not be called before creation is attempted.
/// \return Memory share width in bytes.
u8 bytewidth() const { return m_target->bytewidth(); }
protected:
virtual bool findit(validity_checker *valid) override;
virtual void end_configuration() override;
/// \brief Pointer to target object
///
/// Pointer to target memory share object, or nullptr if creation
/// has not been attempted yet.
memory_share *m_target = nullptr;
/// \brief Requested memory share width in bits
u8 const m_width;
/// \brief Requested memory share length in bytes
size_t const m_bytes;
/// \brief Requested memory share endianness
endianness_t const m_endianness;
};
//**************************************************************************
// EXTERNAL TEMPLATE INSTANTIATIONS

View File

@ -203,7 +203,7 @@ void dec8_state::ghostb_bank_w(uint8_t data)
flip_screen_set(BIT(data, 3));
}
void dec8_state::csilver_control_w(uint8_t data)
void csilver_state::csilver_control_w(uint8_t data)
{
/*
Bit 0x0f - ROM bank switch.
@ -222,7 +222,7 @@ void dec8_state::dec8_sound_w(uint8_t data)
m_m6502_timer->adjust(m_audiocpu->cycles_to_attotime(3));
}
WRITE_LINE_MEMBER(dec8_state::csilver_adpcm_int)
WRITE_LINE_MEMBER(csilver_state::csilver_adpcm_int)
{
m_toggle ^= 1;
if (m_toggle)
@ -232,18 +232,18 @@ WRITE_LINE_MEMBER(dec8_state::csilver_adpcm_int)
m_msm5205next <<= 4;
}
uint8_t dec8_state::csilver_adpcm_reset_r()
uint8_t csilver_state::csilver_adpcm_reset_r()
{
m_msm->reset_w(0);
return 0;
}
void dec8_state::csilver_adpcm_data_w(uint8_t data)
void csilver_state::csilver_adpcm_data_w(uint8_t data)
{
m_msm5205next = data;
}
void dec8_state::csilver_sound_bank_w(uint8_t data)
void csilver_state::csilver_sound_bank_w(uint8_t data)
{
m_soundbank->set_entry((data & 0x08) >> 3);
}
@ -455,48 +455,48 @@ void dec8_state::meikyuh_map(address_map &map)
map(0x8000, 0xffff).rom();
}
void dec8_state::csilver_map(address_map &map)
void csilver_state::csilver_map(address_map &map)
{
map(0x0000, 0x0fff).ram().share("share1");
map(0x1000, 0x13ff).ram().w(m_palette, FUNC(deco_rmc3_device::write8)).share("palette");
map(0x1400, 0x17ff).ram().w(m_palette, FUNC(deco_rmc3_device::write8_ext)).share("palette_ext");
map(0x1800, 0x1800).portr("IN1").w(FUNC(dec8_state::sub_irq_off_w));
map(0x1801, 0x1801).portr("IN0").w(FUNC(dec8_state::main_irq_off_w));
map(0x1802, 0x1802).w(FUNC(dec8_state::main_firq_off_w));
map(0x1803, 0x1803).portr("IN2").w(FUNC(dec8_state::main_irq_on_w));
map(0x1804, 0x1804).portr("DSW1").w(FUNC(dec8_state::sub_irq_on_w));
map(0x1805, 0x1805).portr("DSW0").w(FUNC(dec8_state::dec8_mxc06_karn_buffer_spriteram_w)); /* Dip 1, DMA */
map(0x1807, 0x1807).w(FUNC(dec8_state::flip_screen_w));
map(0x1808, 0x180b).w(FUNC(dec8_state::dec8_scroll2_w));
map(0x180c, 0x180c).w(FUNC(dec8_state::dec8_sound_w));
map(0x180d, 0x180d).w(FUNC(dec8_state::csilver_control_w));
map(0x180e, 0x180f).w(FUNC(dec8_state::dec8_i8751_w));
map(0x1c00, 0x1c00).r(FUNC(dec8_state::i8751_h_r));
map(0x1e00, 0x1e00).r(FUNC(dec8_state::i8751_l_r));
map(0x2000, 0x27ff).ram().w(FUNC(dec8_state::dec8_videoram_w));
map(0x1800, 0x1800).portr("IN1").w(FUNC(csilver_state::sub_irq_off_w));
map(0x1801, 0x1801).portr("IN0").w(FUNC(csilver_state::main_irq_off_w));
map(0x1802, 0x1802).w(FUNC(csilver_state::main_firq_off_w));
map(0x1803, 0x1803).portr("IN2").w(FUNC(csilver_state::main_irq_on_w));
map(0x1804, 0x1804).portr("DSW1").w(FUNC(csilver_state::sub_irq_on_w));
map(0x1805, 0x1805).portr("DSW0").w(FUNC(csilver_state::dec8_mxc06_karn_buffer_spriteram_w)); /* Dip 1, DMA */
map(0x1807, 0x1807).w(FUNC(csilver_state::flip_screen_w));
map(0x1808, 0x180b).w(FUNC(csilver_state::dec8_scroll2_w));
map(0x180c, 0x180c).w(FUNC(csilver_state::dec8_sound_w));
map(0x180d, 0x180d).w(FUNC(csilver_state::csilver_control_w));
map(0x180e, 0x180f).w(FUNC(csilver_state::dec8_i8751_w));
map(0x1c00, 0x1c00).r(FUNC(csilver_state::i8751_h_r));
map(0x1e00, 0x1e00).r(FUNC(csilver_state::i8751_l_r));
map(0x2000, 0x27ff).ram().w(FUNC(csilver_state::dec8_videoram_w));
map(0x2800, 0x2fff).ram().share("spriteram");
map(0x3000, 0x37ff).ram().share("share2");
map(0x3800, 0x3fff).rw(FUNC(dec8_state::dec8_bg_data_r), FUNC(dec8_state::dec8_bg_data_w)).share("bg_data");
map(0x3800, 0x3fff).rw(FUNC(csilver_state::dec8_bg_data_r), FUNC(csilver_state::dec8_bg_data_w)).share("bg_data");
map(0x4000, 0x7fff).bankr("mainbank");
map(0x8000, 0xffff).rom();
}
void dec8_state::csilver_sub_map(address_map &map)
void csilver_state::csilver_sub_map(address_map &map)
{
map(0x0000, 0x0fff).ram().share("share1");
map(0x1000, 0x13ff).ram().w(m_palette, FUNC(deco_rmc3_device::write8)).share("palette");
map(0x1400, 0x17ff).ram().w(m_palette, FUNC(deco_rmc3_device::write8_ext)).share("palette_ext");
map(0x1800, 0x1800).w(FUNC(dec8_state::sub_irq_off_w));
map(0x1801, 0x1801).w(FUNC(dec8_state::main_irq_off_w));
map(0x1802, 0x1802).w(FUNC(dec8_state::main_firq_off_w));
map(0x1803, 0x1803).portr("IN2").w(FUNC(dec8_state::main_irq_on_w));
map(0x1804, 0x1804).portr("DSW1").w(FUNC(dec8_state::sub_irq_on_w));
map(0x1805, 0x1805).portr("DSW0").w(FUNC(dec8_state::dec8_mxc06_karn_buffer_spriteram_w)); /* DMA */
map(0x180c, 0x180c).w(FUNC(dec8_state::dec8_sound_w));
map(0x2000, 0x27ff).ram().w(FUNC(dec8_state::dec8_videoram_w)).share("videoram");
map(0x1800, 0x1800).w(FUNC(csilver_state::sub_irq_off_w));
map(0x1801, 0x1801).w(FUNC(csilver_state::main_irq_off_w));
map(0x1802, 0x1802).w(FUNC(csilver_state::main_firq_off_w));
map(0x1803, 0x1803).portr("IN2").w(FUNC(csilver_state::main_irq_on_w));
map(0x1804, 0x1804).portr("DSW1").w(FUNC(csilver_state::sub_irq_on_w));
map(0x1805, 0x1805).portr("DSW0").w(FUNC(csilver_state::dec8_mxc06_karn_buffer_spriteram_w)); /* DMA */
map(0x180c, 0x180c).w(FUNC(csilver_state::dec8_sound_w));
map(0x2000, 0x27ff).ram().w(FUNC(csilver_state::dec8_videoram_w)).share("videoram");
map(0x2800, 0x2fff).ram().share("spriteram");
map(0x3000, 0x37ff).ram().share("share2");
map(0x3800, 0x3fff).rw(FUNC(dec8_state::dec8_bg_data_r), FUNC(dec8_state::dec8_bg_data_w));
map(0x3800, 0x3fff).rw(FUNC(csilver_state::dec8_bg_data_r), FUNC(csilver_state::dec8_bg_data_w));
map(0x4000, 0xffff).rom();
}
@ -623,15 +623,15 @@ void dec8_state::ym3526_s_map(address_map &map)
}
/* Captain Silver - same sound system as Pocket Gal */
void dec8_state::csilver_s_map(address_map &map)
void csilver_state::csilver_s_map(address_map &map)
{
map(0x0000, 0x07ff).ram();
map(0x0800, 0x0801).w("ym1", FUNC(ym2203_device::write));
map(0x1000, 0x1001).w("ym2", FUNC(ym3526_device::write));
map(0x1800, 0x1800).w(FUNC(dec8_state::csilver_adpcm_data_w)); /* ADPCM data for the MSM5205 chip */
map(0x2000, 0x2000).w(FUNC(dec8_state::csilver_sound_bank_w));
map(0x1800, 0x1800).w(FUNC(csilver_state::csilver_adpcm_data_w)); /* ADPCM data for the MSM5205 chip */
map(0x2000, 0x2000).w(FUNC(csilver_state::csilver_sound_bank_w));
map(0x3000, 0x3000).r(m_soundlatch, FUNC(generic_latch_8_device::read));
map(0x3400, 0x3400).r(FUNC(dec8_state::csilver_adpcm_reset_r)); /* ? not sure */
map(0x3400, 0x3400).r(FUNC(csilver_state::csilver_adpcm_reset_r)); /* ? not sure */
map(0x4000, 0x7fff).bankr("soundbank");
map(0x8000, 0xffff).rom();
}
@ -747,7 +747,7 @@ void dec8_state::srdarwin_mcu_to_main_w(uint8_t data)
}
void dec8_state::csilver_mcu_to_main_w(uint8_t data)
void csilver_state::csilver_mcu_to_main_w(uint8_t data)
{
if (~data & 0x10)
m_i8751_port0 = m_i8751_value >> 8;
@ -1784,9 +1784,15 @@ WRITE_LINE_MEMBER(dec8_state::shackled_coin_irq)
void dec8_state::machine_start()
{
uint8_t *ROM = memregion("maincpu")->base();
uint32_t max_bank = (memregion("maincpu")->bytes() - 0x10000) / 0x4000;
m_mainbank->configure_entries(0, max_bank, &ROM[0x10000], 0x4000);
m_i8751_timer = timer_alloc(TIMER_DEC8_I8751);
m_m6502_timer = timer_alloc(TIMER_DEC8_M6502);
m_i8751_p2 = 0xff;
m_latch = 0;
save_item(NAME(m_secclr));
save_item(NAME(m_i8751_p2));
@ -1805,8 +1811,6 @@ void dec8_state::machine_start()
save_item(NAME(m_cred2));
save_item(NAME(m_credits));
save_item(NAME(m_snd));
save_item(NAME(m_msm5205next));
save_item(NAME(m_toggle));
save_item(NAME(m_scroll2));
save_item(NAME(m_bg_control));
@ -1815,18 +1819,14 @@ void dec8_state::machine_start()
void dec8_state::machine_reset()
{
int i;
m_i8751_port0 = m_i8751_port1 = 0;
m_i8751_return = m_i8751_value = 0;
m_coinage_id = 0;
m_coin1 = m_coin2 = m_credits = m_snd = 0;
m_need1 = m_need2 = m_cred1 = m_cred2 = 1;
m_msm5205next = 0;
m_toggle = 0;
m_scroll2[0] = m_scroll2[1] = m_scroll2[2] = m_scroll2[3] = 0;
for (i = 0; i < 0x20; i++)
for (int i = 0; i < 0x20; i++)
{
m_bg_control[i] = 0;
m_pf1_control[i] = 0;
@ -1838,6 +1838,26 @@ void dec8_state::machine_reset()
}
void csilver_state::machine_start()
{
dec8_state::machine_start();
uint8_t *RAM = memregion("audiocpu")->base();
m_soundbank->configure_entries(0, 2, &RAM[0], 0x4000);
save_item(NAME(m_msm5205next));
save_item(NAME(m_toggle));
}
void csilver_state::machine_reset()
{
dec8_state::machine_reset();
m_msm5205next = 0;
m_toggle = 0;
}
// DECO video CRTC, unverified
void dec8_state::set_screen_raw_params_data_east(machine_config &config)
{
@ -2143,26 +2163,26 @@ void dec8_state::meikyuh(machine_config &config)
}
void dec8_state::csilver(machine_config &config)
void csilver_state::csilver(machine_config &config)
{
/* basic machine hardware */
MC6809E(config, m_maincpu, XTAL(12'000'000)/8); /* verified on pcb */
m_maincpu->set_addrmap(AS_PROGRAM, &dec8_state::csilver_map);
m_maincpu->set_addrmap(AS_PROGRAM, &csilver_state::csilver_map);
MC6809E(config, m_subcpu, XTAL(12'000'000)/8); /* verified on pcb */
m_subcpu->set_addrmap(AS_PROGRAM, &dec8_state::csilver_sub_map);
m_subcpu->set_addrmap(AS_PROGRAM, &csilver_state::csilver_sub_map);
M6502(config, m_audiocpu, XTAL(12'000'000)/8); /* verified on pcb */
m_audiocpu->set_addrmap(AS_PROGRAM, &dec8_state::csilver_s_map); /* NMIs are caused by the main CPU */
m_audiocpu->set_addrmap(AS_PROGRAM, &csilver_state::csilver_s_map); /* NMIs are caused by the main CPU */
config.set_maximum_quantum(attotime::from_hz(6000));
I8751(config, m_mcu, XTAL(8'000'000));
m_mcu->port_in_cb<0>().set(FUNC(dec8_state::i8751_port0_r));
m_mcu->port_out_cb<0>().set(FUNC(dec8_state::i8751_port0_w));
m_mcu->port_in_cb<1>().set(FUNC(dec8_state::i8751_port1_r));
m_mcu->port_out_cb<1>().set(FUNC(dec8_state::i8751_port1_w));
m_mcu->port_out_cb<2>().set(FUNC(dec8_state::csilver_mcu_to_main_w));
m_mcu->port_in_cb<0>().set(FUNC(csilver_state::i8751_port0_r));
m_mcu->port_out_cb<0>().set(FUNC(csilver_state::i8751_port0_w));
m_mcu->port_in_cb<1>().set(FUNC(csilver_state::i8751_port1_r));
m_mcu->port_out_cb<1>().set(FUNC(csilver_state::i8751_port1_w));
m_mcu->port_out_cb<2>().set(FUNC(csilver_state::csilver_mcu_to_main_w));
m_mcu->port_in_cb<3>().set_ioport("I8751");
config.set_perfect_quantum(m_maincpu);
@ -2178,14 +2198,14 @@ void dec8_state::csilver(machine_config &config)
// m_screen->set_size(32*8, 32*8);
// m_screen->set_visarea(0*8, 32*8-1, 1*8, 31*8-1);
set_screen_raw_params_data_east(config);
m_screen->set_screen_update(FUNC(dec8_state::screen_update_lastmisn));
m_screen->set_screen_update(FUNC(csilver_state::screen_update_lastmisn));
m_screen->set_palette(m_palette);
m_screen->screen_vblank().set_inputline(m_subcpu, INPUT_LINE_NMI);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_shackled);
DECO_RMC3(config, m_palette, 0, 1024); // xxxxBBBBGGGGRRRR with custom weighting
MCFG_VIDEO_START_OVERRIDE(dec8_state,lastmisn)
MCFG_VIDEO_START_OVERRIDE(csilver_state,lastmisn)
/* sound hardware */
SPEAKER(config, "mono").front_center();
@ -2203,7 +2223,7 @@ void dec8_state::csilver(machine_config &config)
ym2.add_route(ALL_OUTPUTS, "mono", 0.70);
MSM5205(config, m_msm, XTAL(384'000)); /* verified on pcb */
m_msm->vck_legacy_callback().set(FUNC(dec8_state::csilver_adpcm_int)); /* interrupt function */
m_msm->vck_legacy_callback().set(FUNC(csilver_state::csilver_adpcm_int)); /* interrupt function */
m_msm->set_prescaler_selector(msm5205_device::S48_4B); /* 8KHz */
m_msm->add_route(ALL_OUTPUTS, "mono", 0.88);
}
@ -3700,59 +3720,39 @@ ROM_START( cobracomjb )
ROM_LOAD( "pal16l8a-2cn.bin", 0x0000, 0x0104, CRC(3ef8cf68) SHA1(9410a139fb10628bc612d198f5c9f04b2b34f52f) )
ROM_END
/******************************************************************************/
void dec8_state::init_dec8()
{
if (m_mainbank.found())
{
uint8_t *ROM = memregion("maincpu")->base();
uint32_t max_bank = (memregion("maincpu")->bytes() - 0x10000) / 0x4000;
m_mainbank->configure_entries(0, max_bank, &ROM[0x10000], 0x4000);
}
m_latch = 0;
}
void dec8_state::init_csilver()
{
uint8_t *RAM = memregion("audiocpu")->base();
m_soundbank->configure_entries(0, 2, &RAM[0], 0x4000);
init_dec8();
}
/******************************************************************************/
GAME( 1986, lastmisn, 0, lastmisn, lastmisn, dec8_state, init_dec8, ROT270, "Data East Corporation", "Last Mission (World revision 8)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, lastmisnu6, lastmisn, lastmisn, lastmisn, dec8_state, init_dec8, ROT270, "Data East USA", "Last Mission (US revision 6)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, lastmisnu5, lastmisn, lastmisn, lastmisn, dec8_state, init_dec8, ROT270, "Data East USA", "Last Mission (US revision 5)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, lastmisnj, lastmisn, lastmisn, lastmisnj, dec8_state, init_dec8, ROT270, "Data East Corporation", "Last Mission (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, shackled, 0, shackled, shackled, dec8_state, init_dec8, ROT0, "Data East USA", "Shackled (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, breywood, shackled, shackled, breywood, dec8_state, init_dec8, ROT0, "Data East Corporation", "Breywood (Japan revision 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, gondo, 0, gondo, gondo, dec8_state, init_dec8, ROT270, "Data East Corporation", "Gondomania (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, gondou, gondo, gondo, gondo, dec8_state, init_dec8, ROT270, "Data East USA", "Gondomania (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, makyosen, gondo, gondo, gondo, dec8_state, init_dec8, ROT270, "Data East Corporation", "Makyou Senshi (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, garyoret, 0, garyoret, garyoret, dec8_state, init_dec8, ROT0, "Data East Corporation", "Garyo Retsuden (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ghostb, 0, ghostb, ghostb, dec8_state, init_dec8, ROT0, "Data East USA", "The Real Ghostbusters (US 2 Players, revision 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ghostb2a, ghostb, ghostb, ghostb2a, dec8_state, init_dec8, ROT0, "Data East USA", "The Real Ghostbusters (US 2 Players)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ghostb3, ghostb, ghostb, ghostb3, dec8_state, init_dec8, ROT0, "Data East USA", "The Real Ghostbusters (US 3 Players, revision 3B?)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ghostb3a, ghostb, ghostb, ghostb3, dec8_state, init_dec8, ROT0, "Data East USA", "The Real Ghostbusters (US 3 Players, revision 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // ROMs confirmed working on PCB - stalls in demo mode
GAME( 1987, meikyuh, ghostb, meikyuh, meikyuh, dec8_state, init_dec8, ROT0, "Data East Corporation", "Meikyuu Hunter G (Japan, set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, meikyuha, ghostb, meikyuh, meikyuh, dec8_state, init_dec8, ROT0, "Data East Corporation", "Meikyuu Hunter G (Japan, set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, csilver, 0, csilver, csilver, dec8_state, init_csilver, ROT0, "Data East Corporation", "Captain Silver (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, csilverj, csilver, csilver, csilverj, dec8_state, init_csilver, ROT0, "Data East Corporation", "Captain Silver (Japan, revision 3)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, csilverja, csilver, csilver, csilverj, dec8_state, init_csilver, ROT0, "Data East Corporation", "Captain Silver (Japan, revision 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, oscar, 0, oscar, oscar, dec8_state, init_dec8, ROT0, "Data East Corporation", "Psycho-Nics Oscar (World revision 0)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, oscaru, oscar, oscar, oscarj, dec8_state, init_dec8, ROT0, "Data East USA", "Psycho-Nics Oscar (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, oscarj1, oscar, oscar, oscarj, dec8_state, init_dec8, ROT0, "Data East Corporation", "Psycho-Nics Oscar (Japan revision 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, oscarj2, oscar, oscar, oscarj, dec8_state, init_dec8, ROT0, "Data East Corporation", "Psycho-Nics Oscar (Japan revision 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, srdarwin, 0, srdarwin, srdarwin, dec8_state, init_dec8, ROT270, "Data East Corporation", "Super Real Darwin (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, srdarwinj, srdarwin, srdarwin, srdarwinj, dec8_state, init_dec8, ROT270, "Data East Corporation", "Super Real Darwin (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, lastmisn, 0, lastmisn, lastmisn, dec8_state, empty_init, ROT270, "Data East Corporation", "Last Mission (World revision 8)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, lastmisnu6, lastmisn, lastmisn, lastmisn, dec8_state, empty_init, ROT270, "Data East USA", "Last Mission (US revision 6)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, lastmisnu5, lastmisn, lastmisn, lastmisn, dec8_state, empty_init, ROT270, "Data East USA", "Last Mission (US revision 5)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, lastmisnj, lastmisn, lastmisn, lastmisnj, dec8_state, empty_init, ROT270, "Data East Corporation", "Last Mission (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, shackled, 0, shackled, shackled, dec8_state, empty_init, ROT0, "Data East USA", "Shackled (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, breywood, shackled, shackled, breywood, dec8_state, empty_init, ROT0, "Data East Corporation", "Breywood (Japan revision 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, gondo, 0, gondo, gondo, dec8_state, empty_init, ROT270, "Data East Corporation", "Gondomania (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, gondou, gondo, gondo, gondo, dec8_state, empty_init, ROT270, "Data East USA", "Gondomania (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, makyosen, gondo, gondo, gondo, dec8_state, empty_init, ROT270, "Data East Corporation", "Makyou Senshi (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, garyoret, 0, garyoret, garyoret, dec8_state, empty_init, ROT0, "Data East Corporation", "Garyo Retsuden (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ghostb, 0, ghostb, ghostb, dec8_state, empty_init, ROT0, "Data East USA", "The Real Ghostbusters (US 2 Players, revision 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ghostb2a, ghostb, ghostb, ghostb2a, dec8_state, empty_init, ROT0, "Data East USA", "The Real Ghostbusters (US 2 Players)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ghostb3, ghostb, ghostb, ghostb3, dec8_state, empty_init, ROT0, "Data East USA", "The Real Ghostbusters (US 3 Players, revision 3B?)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ghostb3a, ghostb, ghostb, ghostb3, dec8_state, empty_init, ROT0, "Data East USA", "The Real Ghostbusters (US 3 Players, revision 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // ROMs confirmed working on PCB - stalls in demo mode
GAME( 1987, meikyuh, ghostb, meikyuh, meikyuh, dec8_state, empty_init, ROT0, "Data East Corporation", "Meikyuu Hunter G (Japan, set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, meikyuha, ghostb, meikyuh, meikyuh, dec8_state, empty_init, ROT0, "Data East Corporation", "Meikyuu Hunter G (Japan, set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, csilver, 0, csilver, csilver, csilver_state, empty_init, ROT0, "Data East Corporation", "Captain Silver (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, csilverj, csilver, csilver, csilverj, csilver_state, empty_init, ROT0, "Data East Corporation", "Captain Silver (Japan, revision 3)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, csilverja, csilver, csilver, csilverj, csilver_state, empty_init, ROT0, "Data East Corporation", "Captain Silver (Japan, revision 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, oscar, 0, oscar, oscar, dec8_state, empty_init, ROT0, "Data East Corporation", "Psycho-Nics Oscar (World revision 0)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, oscaru, oscar, oscar, oscarj, dec8_state, empty_init, ROT0, "Data East USA", "Psycho-Nics Oscar (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, oscarj1, oscar, oscar, oscarj, dec8_state, empty_init, ROT0, "Data East Corporation", "Psycho-Nics Oscar (Japan revision 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, oscarj2, oscar, oscar, oscarj, dec8_state, empty_init, ROT0, "Data East Corporation", "Psycho-Nics Oscar (Japan revision 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, srdarwin, 0, srdarwin, srdarwin, dec8_state, empty_init, ROT270, "Data East Corporation", "Super Real Darwin (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, srdarwinj, srdarwin, srdarwin, srdarwinj, dec8_state, empty_init, ROT270, "Data East Corporation", "Super Real Darwin (Japan)", MACHINE_SUPPORTS_SAVE )
// Unlike most Deco games of this period Cobra Command does not seem to have a Data East USA release. Instead the Data East Corporation release
// was used in the US as evidenced by boards with the EL romset bearing AAMA seal stickers (American Amusement Machine Association)
GAME( 1988, cobracom, 0, cobracom, cobracom, dec8_state, init_dec8, ROT0, "Data East Corporation", "Cobra-Command (World/US revision 5)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracoma, cobracom, cobracom, cobracom, dec8_state, init_dec8, ROT0, "Data East Corporation", "Cobra-Command (World/US revision 4)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracomb, cobracom, cobracom, cobracom, dec8_state, init_dec8, ROT0, "Data East Corporation", "Cobra-Command (World/US)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracomj, cobracom, cobracom, cobracom, dec8_state, init_dec8, ROT0, "Data East Corporation", "Cobra-Command (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracomjb, cobracom, cobracom, cobracom, dec8_state, init_dec8, ROT0, "bootleg", "Cobra-Command (Japan, bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracom, 0, cobracom, cobracom, dec8_state, empty_init, ROT0, "Data East Corporation", "Cobra-Command (World/US revision 5)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracoma, cobracom, cobracom, cobracom, dec8_state, empty_init, ROT0, "Data East Corporation", "Cobra-Command (World/US revision 4)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracomb, cobracom, cobracom, cobracom, dec8_state, empty_init, ROT0, "Data East Corporation", "Cobra-Command (World/US)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracomj, cobracom, cobracom, cobracom, dec8_state, empty_init, ROT0, "Data East Corporation", "Cobra-Command (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, cobracomjb, cobracom, cobracom, cobracom, dec8_state, empty_init, ROT0, "bootleg", "Cobra-Command (Japan, bootleg)", MACHINE_SUPPORTS_SAVE )

View File

@ -510,7 +510,15 @@ void mpu4vid_state::video_start()
assert(m_gfx_index != MAX_GFX_ELEMENTS);
/* create the char set (gfx will then be updated dynamically from RAM) */
m_gfxdecode->set_gfx(m_gfx_index+0, std::make_unique<gfx_element>(m_palette, mpu4_vid_char_8x8_layout, reinterpret_cast<uint8_t *>(m_vid_vidram.ptr()), NATIVE_ENDIAN_VALUE_LE_BE(8,0), m_palette->entries() / 16, 0));
m_gfxdecode->set_gfx(
m_gfx_index+0,
std::make_unique<gfx_element>(
m_palette,
mpu4_vid_char_8x8_layout,
reinterpret_cast<uint8_t *>(m_vid_vidram.target()),
NATIVE_ENDIAN_VALUE_LE_BE(8,0),
m_palette->entries() / 16,
0));
}
EF9369_COLOR_UPDATE( mpu4vid_state::ef9369_color_update )

View File

@ -764,20 +764,15 @@ void mz3500_state::machine_reset()
//m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
m_srdy = 0;
if (m_fdc.found())
m_fdd_sel = 0;
for(auto & elem : m_floppy_connector)
{
m_fdd_sel = 0;
{
for(auto & elem : m_floppy_connector)
{
elem->get_device()->mon_w(ASSERT_LINE);
elem->get_device()->set_rpm(300);
}
m_fdc->set_rate(250000);
}
elem->get_device()->mon_w(ASSERT_LINE);
elem->get_device()->set_rpm(300);
}
m_fdc->set_rate(250000);
m_beeper->set_state(0);
}

View File

@ -32,27 +32,24 @@ public:
m_subcpu(*this, "sub"),
m_audiocpu(*this, "audiocpu"),
m_mcu(*this, "mcu"),
m_nmigate(*this, "nmigate"),
m_spriteram(*this, "spriteram") ,
m_msm(*this, "msm"),
m_tilegen(*this, "tilegen%u", 1),
m_spritegen_krn(*this, "spritegen_krn"),
m_spritegen_mxc(*this, "spritegen_mxc"),
m_gfxdecode(*this, "gfxdecode"),
m_spriteram(*this, "spriteram") ,
m_screen(*this, "screen"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_soundlatch(*this, "soundlatch"),
m_mainbank(*this, "mainbank"),
m_nmigate(*this, "nmigate"),
m_tilegen(*this, "tilegen%u", 1),
m_spritegen_mxc(*this, "spritegen_mxc"),
m_videoram(*this, "videoram"),
m_bg_data(*this, "bg_data"),
m_mainbank(*this, "mainbank"),
m_soundbank(*this, "soundbank"),
m_coin_port(*this, "I8751")
{ }
void shackled(machine_config &config);
void meikyuh(machine_config &config);
void lastmisn(machine_config &config);
void csilver(machine_config &config);
void cobracom(machine_config &config);
void garyoret(machine_config &config);
void srdarwin(machine_config &config);
@ -60,34 +57,69 @@ public:
void oscar(machine_config &config);
void gondo(machine_config &config);
void init_dec8();
void init_csilver();
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
virtual void machine_start() override;
virtual void machine_reset() override;
uint8_t i8751_h_r();
uint8_t i8751_l_r();
void dec8_i8751_w(offs_t offset, uint8_t data);
void dec8_mxc06_karn_buffer_spriteram_w(uint8_t data);
void dec8_sound_w(uint8_t data);
void main_irq_on_w(uint8_t data);
void main_irq_off_w(uint8_t data);
void main_firq_off_w(uint8_t data);
void sub_irq_on_w(uint8_t data);
void sub_irq_off_w(uint8_t data);
void flip_screen_w(uint8_t data);
void dec8_bg_data_w(offs_t offset, uint8_t data);
uint8_t dec8_bg_data_r(offs_t offset);
void dec8_videoram_w(offs_t offset, uint8_t data);
void dec8_scroll2_w(offs_t offset, uint8_t data);
uint8_t i8751_port0_r();
void i8751_port0_w(uint8_t data);
uint8_t i8751_port1_r();
void i8751_port1_w(uint8_t data);
DECLARE_VIDEO_START(lastmisn);
uint32_t screen_update_lastmisn(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void set_screen_raw_params_data_east(machine_config &config);
private:
/* devices */
required_device<cpu_device> m_maincpu;
optional_device<cpu_device> m_subcpu;
required_device<cpu_device> m_audiocpu;
optional_device<i8751_device> m_mcu;
optional_device<input_merger_device> m_nmigate;
required_device<buffered_spriteram8_device> m_spriteram;
optional_device<msm5205_device> m_msm;
optional_device_array<deco_bac06_device, 2> m_tilegen;
optional_device<deco_karnovsprites_device> m_spritegen_krn;
optional_device<deco_mxc06_device> m_spritegen_mxc;
required_device<gfxdecode_device> m_gfxdecode;
required_device<buffered_spriteram8_device> m_spriteram;
required_device<screen_device> m_screen;
required_device<gfxdecode_device> m_gfxdecode;
required_device<deco_rmc3_device> m_palette;
required_device<generic_latch_8_device> m_soundlatch;
/* memory regions */
required_memory_bank m_mainbank;
// MCU communication
uint8_t m_i8751_p2;
int m_i8751_port0;
int m_i8751_port1;
int m_i8751_return;
int m_i8751_value;
private:
optional_device<input_merger_device> m_nmigate;
optional_device_array<deco_bac06_device, 2> m_tilegen;
optional_device<deco_mxc06_device> m_spritegen_mxc;
/* memory pointers */
required_shared_ptr<uint8_t> m_videoram;
optional_shared_ptr<uint8_t> m_bg_data;
/* memory regions */
required_memory_bank m_mainbank;
optional_memory_bank m_soundbank;
uint8_t * m_pf1_data;
uint8_t * m_row;
std::unique_ptr<uint16_t[]> m_buffered_spriteram16; // for the mxc06 sprite chip emulation (oscar, cobra)
@ -105,11 +137,6 @@ private:
/* misc */
bool m_secclr;
bool m_nmi_enable;
uint8_t m_i8751_p2;
int m_i8751_port0;
int m_i8751_port1;
int m_i8751_return;
int m_i8751_value;
int m_coinage_id;
int m_coin1;
int m_coin2;
@ -121,52 +148,26 @@ private:
int m_latch;
bool m_coin_state;
int m_snd;
int m_msm5205next;
int m_toggle;
emu_timer *m_i8751_timer;
emu_timer *m_m6502_timer;
void dec8_mxc06_karn_buffer_spriteram_w(uint8_t data);
uint8_t i8751_h_r();
uint8_t i8751_l_r();
void i8751_reset_w(uint8_t data);
uint8_t gondo_player_1_r(offs_t offset);
uint8_t gondo_player_2_r(offs_t offset);
void dec8_i8751_w(offs_t offset, uint8_t data);
void dec8_bank_w(uint8_t data);
void ghostb_bank_w(uint8_t data);
void csilver_control_w(uint8_t data);
void dec8_sound_w(uint8_t data);
void csilver_adpcm_data_w(uint8_t data);
void csilver_sound_bank_w(uint8_t data);
void main_irq_on_w(uint8_t data);
void main_irq_off_w(uint8_t data);
void main_firq_off_w(uint8_t data);
void sub_irq_on_w(uint8_t data);
void sub_irq_off_w(uint8_t data);
void sub_firq_off_w(uint8_t data);
void flip_screen_w(uint8_t data);
uint8_t i8751_port0_r();
void i8751_port0_w(uint8_t data);
uint8_t i8751_port1_r();
void i8751_port1_w(uint8_t data);
void gondo_mcu_to_main_w(uint8_t data);
void shackled_mcu_to_main_w(uint8_t data);
void srdarwin_mcu_to_main_w(uint8_t data);
void csilver_mcu_to_main_w(uint8_t data);
void dec8_bg_data_w(offs_t offset, uint8_t data);
uint8_t dec8_bg_data_r(offs_t offset);
void dec8_videoram_w(offs_t offset, uint8_t data);
void srdarwin_videoram_w(offs_t offset, uint8_t data);
void dec8_scroll2_w(offs_t offset, uint8_t data);
void srdarwin_control_w(offs_t offset, uint8_t data);
void lastmisn_control_w(uint8_t data);
void shackled_control_w(uint8_t data);
void lastmisn_scrollx_w(uint8_t data);
void lastmisn_scrolly_w(uint8_t data);
void gondo_scroll_w(offs_t offset, uint8_t data);
uint8_t csilver_adpcm_reset_r();
TILE_GET_INFO_MEMBER(get_cobracom_fix_tile_info);
TILE_GET_INFO_MEMBER(get_ghostb_fix_tile_info);
TILE_GET_INFO_MEMBER(get_oscar_fix_tile_info);
@ -177,9 +178,6 @@ private:
TILE_GET_INFO_MEMBER(get_srdarwin_tile_info);
TILE_GET_INFO_MEMBER(get_gondo_fix_tile_info);
TILE_GET_INFO_MEMBER(get_gondo_tile_info);
virtual void machine_start() override;
virtual void machine_reset() override;
DECLARE_VIDEO_START(lastmisn);
DECLARE_VIDEO_START(shackled);
DECLARE_VIDEO_START(gondo);
DECLARE_VIDEO_START(garyoret);
@ -188,7 +186,6 @@ private:
DECLARE_VIDEO_START(srdarwin);
DECLARE_VIDEO_START(cobracom);
void allocate_buffered_spriteram16();
uint32_t screen_update_lastmisn(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_shackled(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_gondo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_garyoret(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
@ -204,14 +201,8 @@ private:
void gondo_colpri_cb(u32 &colour, u32 &pri_mask);
void cobracom_colpri_cb(u32 &colour, u32 &pri_mask);
void oscar_tile_cb(tile_data &tileinfo, u32 &tile, u32 &colour, u32 &flags);
DECLARE_WRITE_LINE_MEMBER(csilver_adpcm_int);
void set_screen_raw_params_data_east(machine_config &config);
void cobra_map(address_map &map);
void csilver_map(address_map &map);
void csilver_s_map(address_map &map);
void csilver_sub_map(address_map &map);
void dec8_s_map(address_map &map);
void garyoret_map(address_map &map);
void gondo_map(address_map &map);
@ -225,12 +216,45 @@ private:
void shackled_sub_map(address_map &map);
void srdarwin_map(address_map &map);
void ym3526_s_map(address_map &map);
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
/* ports */
optional_ioport m_coin_port;
};
class csilver_state : public dec8_state
{
public:
csilver_state(const machine_config &mconfig, device_type type, const char *tag) :
dec8_state(mconfig, type, tag),
m_msm(*this, "msm"),
m_soundbank(*this, "soundbank")
{
}
void csilver(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
void csilver_control_w(uint8_t data);
void csilver_adpcm_data_w(uint8_t data);
void csilver_sound_bank_w(uint8_t data);
void csilver_mcu_to_main_w(uint8_t data);
uint8_t csilver_adpcm_reset_r();
DECLARE_WRITE_LINE_MEMBER(csilver_adpcm_int);
void csilver_map(address_map &map);
void csilver_s_map(address_map &map);
void csilver_sub_map(address_map &map);
required_device<msm5205_device> m_msm;
required_memory_bank m_soundbank;
int m_toggle;
int m_msm5205next;
};
#endif // MAME_INCLUDES_DEC8_H

View File

@ -52,7 +52,7 @@ void harddriv_state::device_reset()
if (m_slapstic_device.found()) m_slapstic_device->slapstic_reset();
/* halt several of the DSPs to start */
if (m_adsp.found()) m_adsp->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
m_adsp->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
if (m_dsp32.found()) m_dsp32->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
m_last_gsp_shiftreg = 0;
@ -427,8 +427,7 @@ void harddriv_state::hd68k_nwr_w(offs_t offset, uint16_t data)
break;
case 6: /* /GSPRES */
logerror("Write to /GSPRES(%d)\n", data);
if (m_gsp.found())
m_gsp->set_input_line(INPUT_LINE_RESET, data ? CLEAR_LINE : ASSERT_LINE);
m_gsp->set_input_line(INPUT_LINE_RESET, data ? CLEAR_LINE : ASSERT_LINE);
break;
case 7: /* /MSPRES */
logerror("Write to /MSPRES(%d)\n", data);

View File

@ -892,14 +892,14 @@ void hp48_state::init_hp48()
LOG(( "hp48: driver init called\n" ));
for (int i = 0; i < 6; i++)
{
m_modules[i].off_mask = 0x00fff; /* 2 KB */
m_modules[i].off_mask = 0x00fff; // 2 KB
m_modules[i].read = read8sm_delegate(*this);
m_modules[i].write = write8sm_delegate(*this);
m_modules[i].data = nullptr;
m_modules[i].isnop = 0;
m_modules[i].state = 0;
m_modules[i].base = 0;
m_modules[i].mask = 0;
m_modules[i].base = 0;
m_modules[i].mask = 0;
}
m_rom = nullptr;
}

View File

@ -405,12 +405,9 @@ void thomson_state::to7_5p14sd_reset()
LOG(( "to7_5p14sd_reset: CD 90-015 controller\n" ));
for (auto &img : m_floppy_image)
{
if (img.found())
{
img->floppy_drive_set_ready_state( FLOPPY_DRIVE_READY, 0 );
img->floppy_drive_set_rpm( 300. );
img->floppy_drive_seek( - img->floppy_drive_get_current_track() );
}
img->floppy_drive_set_ready_state( FLOPPY_DRIVE_READY, 0 );
img->floppy_drive_set_rpm( 300. );
img->floppy_drive_seek( - img->floppy_drive_get_current_track() );
}
}
@ -1464,11 +1461,8 @@ void thmfc1_device::floppy_reset()
for (auto &img : m_floppy_image)
{
if (img.found())
{
img->floppy_drive_set_ready_state( FLOPPY_DRIVE_READY, 0 );
img->floppy_drive_seek( - img->floppy_drive_get_current_track() );
}
img->floppy_drive_set_ready_state( FLOPPY_DRIVE_READY, 0 );
img->floppy_drive_seek( - img->floppy_drive_get_current_track() );
}
m_op = OP_RESET;

View File

@ -31,27 +31,12 @@ void kaneko16_state::video_start()
template<class BitmapClass>
void kaneko16_state::fill_bitmap(BitmapClass &bitmap, const rectangle &cliprect)
{
int pen = 0;
const int pen = (m_kaneko_spr->get_sprite_type() == 1) ? 0x7f00 : 0;
if (m_kaneko_spr.found())
{
if (m_kaneko_spr->get_sprite_type() == 1)
{
pen = 0x7f00;
}
}
typename BitmapClass::pixel_t *dest;
(void)dest; // shut up Visual Studio
if (sizeof(*dest) == 2)
{
if (sizeof(typename BitmapClass::pixel_t) == 2)
bitmap.fill(pen, cliprect);
}
else
{
const pen_t *pal = m_palette->pens();
bitmap.fill(pal[pen], cliprect);
}
bitmap.fill(m_palette->pens()[pen], cliprect);
}

View File

@ -404,7 +404,7 @@ void suna8_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, cons
void suna8_state::draw_text_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int start, int end, int ypos, bool write_mask)
{
uint8_t *spriteram = m_spriteram ? m_spriteram : m_banked_spriteram;
uint8_t *spriteram = m_spriteram ? m_spriteram.target() : m_banked_spriteram.target();
int max_x = m_screen->width() - 8;
int max_y = m_screen->height() - 8;