diff --git a/.github/workflows/bgfxshaders.yml b/.github/workflows/bgfxshaders.yml
deleted file mode 100644
index bff5085e509..00000000000
--- a/.github/workflows/bgfxshaders.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-name: Rebuild BGFX shaders
-
-on:
- push:
- paths:
- - '.github/workflows/**'
- - 'src/osd/modules/render/bgfx/shaders/**'
- pull_request:
- paths:
- - '.github/workflows/**'
- - 'src/osd/modules/render/bgfx/shaders/**'
-
-permissions:
- contents: read
-
-jobs:
- rebuild:
- runs-on: windows-latest
- defaults:
- run:
- shell: msys2 {0}
- steps:
- - uses: msys2/setup-msys2@v2
- with:
- install: git make mingw-w64-x86_64-gcc mingw-w64-x86_64-python mingw-w64-x86_64-libc++
- - uses: actions/checkout@main
- with:
- fetch-depth: 0
- - name: Prevent make from rebuilding GLSL parser source
- run: |
- touch 3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/glcpp/glcpp-lex.c
- touch 3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/glcpp/glcpp-parse.c
- touch 3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/glcpp/glcpp-parse.h
- touch 3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
- touch 3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp.h
- - name: Build
- env:
- MINGW64: "/mingw64"
- run: make shaders
- - uses: actions/upload-artifact@main
- with:
- name: mame-bgfx-${{ github.sha }}
- path: bgfx/shaders
- if-no-files-found: error
diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml
deleted file mode 100644
index 4610644aa1a..00000000000
--- a/.github/workflows/ci-linux.yml
+++ /dev/null
@@ -1,76 +0,0 @@
-name: CI (Linux)
-
-on:
- push:
- paths:
- - '.github/workflows/**'
- - '3rdparty/**'
- - 'hash/**'
- - 'scripts/**'
- - 'src/**'
- - 'COPYING'
- - 'makefile'
- pull_request:
- paths:
- - '.github/workflows/**'
- - '3rdparty/**'
- - 'hash/**'
- - 'scripts/**'
- - 'src/**'
- - 'COPYING'
- - 'makefile'
-
-permissions:
- contents: read
-
-jobs:
- build-linux:
- strategy:
- matrix:
- compiler: [gcc, clang]
- include:
- - compiler: gcc
- cc: gcc
- cxx: g++
- archopts: -U_FORTIFY_SOURCE
- subtarget: tiny
- executable: mametiny
- - compiler: clang
- cc: clang
- cxx: clang++
- subtarget: mame
- executable: mame
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@main
- with:
- fetch-depth: 0
- - name: Install dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y libsdl2-dev libsdl2-ttf-dev libfontconfig-dev libasound2-dev libxinerama-dev libxi-dev qtbase5-dev qtbase5-dev-tools
- - name: Install clang
- if: matrix.compiler == 'clang'
- run: sudo apt-get install -y clang
- - name: Build
- env:
- OVERRIDE_CC: ${{ matrix.cc }}
- OVERRIDE_CXX: ${{ matrix.cxx }}
- ARCHOPTS: ${{ matrix.archopts }}
- SUBTARGET: ${{ matrix.subtarget }}
- TOOLS: 1
- run: make -j3
- - name: Validate
- run: ./${{ matrix.executable }} -validate
- - name: Reconcile driver list
- run: ./${{ matrix.executable }} -listxml | python scripts/build/makedep.py reconcilelist -l src/mame/${{ matrix.subtarget }}.lst -
- - name: ORM check
- run: python scripts/minimaws/minimaws.py load --executable ./${{ matrix.executable }} --softwarepath hash
- - uses: actions/upload-artifact@main
- with:
- name: ${{ matrix.executable }}-linux-${{ matrix.compiler }}-${{ github.sha }}
- path: |
- ${{ matrix.executable }}
- chdman
- unidasm
- if-no-files-found: error
diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml
deleted file mode 100644
index ba56880902e..00000000000
--- a/.github/workflows/ci-macos.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-name: CI (macOS)
-
-on:
- push:
- paths:
- - '.github/workflows/**'
- - '3rdparty/**'
- - 'scripts/**'
- - 'src/**'
- - 'COPYING'
- - 'makefile'
- pull_request:
- paths:
- - '.github/workflows/**'
- - '3rdparty/**'
- - 'scripts/**'
- - 'src/**'
- - 'COPYING'
- - 'makefile'
-
-permissions:
- contents: read
-
-jobs:
- build-macos:
- runs-on: macOS-latest
- steps:
- - uses: actions/checkout@main
- with:
- fetch-depth: 0
- - name: Install dependencies
- run: brew install python3 sdl2
- - name: Build
- env:
- USE_LIBSDL: 1
- TOOLS: 1
- run: make -j2
- - name: Validate
- run: ./mame -validate
- - uses: actions/upload-artifact@main
- with:
- name: mame-macos-${{ github.sha }}
- path: |
- mame
- chdman
- unidasm
- if-no-files-found: error
diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml
index 6f24659c323..eb1da54b617 100644
--- a/.github/workflows/ci-windows.yml
+++ b/.github/workflows/ci-windows.yml
@@ -25,7 +25,7 @@ jobs:
build-windows:
strategy:
matrix:
- compiler: [gcc-x64, clang-x64, clang-arm64]
+ compiler: [gcc-x64]
include:
- compiler: gcc-x64
os: windows-latest
@@ -35,23 +35,6 @@ jobs:
cxx: g++
subtarget: mame
executable: mame
- - compiler: clang-x64
- os: windows-latest
- msys: MINGW64
- slug: mingw-w64-x86_64
- cc: clang
- cxx: clang++
- subtarget: tiny
- executable: mametiny
- - compiler: clang-arm64
- os: windows-11-arm
- msys: CLANGARM64
- slug: mingw-w64-clang-aarch64
- extrapkg: mingw-w64-clang-aarch64-gcc-compat
- cc: clang
- cxx: clang++
- subtarget: mame
- executable: mame
runs-on: ${{ matrix.os }}
defaults:
run:
@@ -71,15 +54,12 @@ jobs:
OVERRIDE_CXX: ${{ matrix.cxx }}
ARCHOPTS: "-fuse-ld=lld"
SUBTARGET: ${{ matrix.subtarget }}
- TOOLS: 1
- run: make -j3
- - name: Validate
- run: ./${{ matrix.executable }}.exe -validate
+ SOURCES: sinclair/sprinter.cpp,sinclair/tsconf.cpp,sinclair/specnext.cpp
+ TOOLS: 0
+ run: make -j$(nproc)
- uses: actions/upload-artifact@main
with:
name: ${{ matrix.executable }}-windows-${{ matrix.compiler }}-${{ github.sha }}
path: |
${{ matrix.executable }}.exe
- chdman.exe
- unidasm.exe
if-no-files-found: error
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
deleted file mode 100644
index 2c3bf612028..00000000000
--- a/.github/workflows/docs.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: Build documentation
-
-on:
- push:
- paths:
- - '.github/workflows/**'
- - 'docs/**'
- pull_request:
- paths:
- - '.github/workflows/**'
- - 'docs/**'
-
-permissions:
- contents: read
-
-jobs:
- build-docs:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@main
- with:
- fetch-depth: 0
- - name: Install dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y librsvg2-bin latexmk python3-pip python3-sphinx texlive texlive-formats-extra texlive-science
- pip3 install sphinxcontrib-svg2pdfconverter
- - name: Build HTML
- run: make -C docs html
- - name: Build PDF
- run: make -C docs PAPER=a4 latexpdf
- - uses: actions/upload-artifact@main
- with:
- name: mame-docs-${{ github.sha }}
- path: |
- docs/build/html
- docs/build/latex/MAME.pdf
- if-no-files-found: error
diff --git a/.github/workflows/hash.yml b/.github/workflows/hash.yml
deleted file mode 100644
index 5e55145422e..00000000000
--- a/.github/workflows/hash.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: XML/JSON validation
-
-on:
- push:
- paths:
- - '.github/workflows/**'
- - 'ctrlr/*'
- - 'hash/*'
- - 'plugins/**'
- pull_request:
- paths:
- - '.github/workflows/**'
- - 'ctrlr/*'
- - 'hash/*'
- - 'plugins/**'
-
-permissions:
- contents: read
-
-jobs:
- validate:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@main
- with:
- fetch-depth: 0
- - name: Install dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y libxml2-utils python3-jsonschema
- - name: Validate (controller configuration)
- run: for x in ctrlr/*.cfg ; do xmllint --noout "$x" ; done
- - name: Validate (HSI)
- run: for x in hash/*.hsi ; do xmllint --noout "$x" ; done
- - name: Validate (software list)
- run: for x in hash/*.xml ; do xmllint --noout --valid "$x" ; done
- - name: Validate (plugin properties)
- run: for x in plugins/*/plugin.json ; do jsonschema -i "$x" plugins/plugin.schema ; done
diff --git a/.github/workflows/language.yml b/.github/workflows/language.yml
deleted file mode 100644
index a5c6eaf358f..00000000000
--- a/.github/workflows/language.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-name: Compile UI translations
-
-on:
- push:
- paths:
- - '.github/workflows/**'
- - 'language/**'
- pull_request:
- paths:
- - '.github/workflows/**'
- - 'language/**'
-
-permissions:
- contents: read
-
-jobs:
- build-language:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@main
- with:
- fetch-depth: 0
- - name: Compile message catalogs
- run: for x in language/*/*.po ; do python scripts/build/msgfmt.py --output-file "`dirname "$x"`/`basename "$x" .po`.mo" "$x" ; done
- - uses: actions/upload-artifact@main
- with:
- name: mame-language-${{ github.sha }}
- path: language/*/*.mo
- if-no-files-found: error
diff --git a/docs/source/debugger/index.rst b/docs/source/debugger/index.rst
index 2947d0253ac..a035a7e13c0 100644
--- a/docs/source/debugger/index.rst
+++ b/docs/source/debugger/index.rst
@@ -158,6 +158,10 @@ Examples:
Address 9660 in the default address space of the device with the
absolute tag ``:ram``, or the ``ram`` space of the root machine
device.
+``1883:vram.m``
+ Address 1883 in the memory region with the absolute tag ``:vram``.
+``1923:sprites.s``
+ Address 1923 in the memory share with the absolute tag ``:sprites``.
The examples here include a lot of corner cases, but in general the
debugger should take the most likely meaning for a device or address
@@ -327,6 +331,7 @@ The size may optionally be preceded by an access type specification:
* ``o`` specifies direct read/write pointer access defaulting to space 3
(opcodes)
* ``m`` specifies a memory region
+* ``s`` specifies a memory share
Finally, this may be preceded by a tag and/or address space name
followed by a dot (``.``).
diff --git a/docs/source/debugger/memory.rst b/docs/source/debugger/memory.rst
index dfb5914b5a9..b32273a40c6 100644
--- a/docs/source/debugger/memory.rst
+++ b/docs/source/debugger/memory.rst
@@ -65,6 +65,7 @@ find
----
**f[ind][{d|i|o}]
[:],[,[,…]]**
+**f[ind] :.{m|s},[,[,…]]**
Search through memory for the specified sequence of data. The
**** is the address to begin searching from, optionally
@@ -114,6 +115,7 @@ fill
----
**fill[{d|i|o}] [:],[,[,…]]**
+**fill :.{m|s},[,[,…]]**
Overwrite a block of memory with copies of the supplied data sequence.
The **** specifies the address to begin writing at, optionally
@@ -146,6 +148,7 @@ dump
----
**dump[{d|i|o}] ,[:],[,[,[,]]]**
+**dump ,:.{m|s},[,[,[,]]]**
Dump memory to the text file specified by the **** parameter.
The **** specifies the address to start dumping from,
@@ -190,6 +193,7 @@ strdump
-------
**strdump[{d|i|o}] ,[:],[,]**
+**strdump ,:.{m|s},[,]**
Dump memory to the text file specified by the **** parameter.
The **** specifies the address to start dumping from,
@@ -216,6 +220,7 @@ save
----
**save[{d|i|o}] ,[:],**
+**save ,:.{m|s},**
Save raw memory to the binary file specified by the ****
parameter. The **** specifies the address to start saving
@@ -260,6 +265,9 @@ start saving from, and the **** specifies how much memory to
save. The range **** through **+-1**,
inclusive, will be output to the file.
+Alternetevely use :ref:`debugger-command-save` syntax:
+``save ,:.m,``
+
Examples:
``saver data.bin,200,100,:monitor``
@@ -278,6 +286,7 @@ load
----
**load[{d|i|o}] ,[:][,]**
+**load ,:.{m|s}[,]**
Load raw memory from the binary file specified by the ****
parameter. The **** specifies the address to start loading to,
@@ -334,6 +343,9 @@ through **+-1**, inclusive, will be read in from the
file. If the **** is zero, or is greater than the total length
of the file, the entire contents of the file will be loaded but no more.
+Alternetevely use :ref:`debugger-command-load` syntax:
+``load ,:.m[,]``
+
Examples:
``loadr data.bin,200,100,:monitor``
diff --git a/hash/tsconf.xml b/hash/tsconf.xml
new file mode 100644
index 00000000000..357777d345e
--- /dev/null
+++ b/hash/tsconf.xml
@@ -0,0 +1,456 @@
+
+
+
+
+
+
+ Alter Ego
+ 2011
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+ Bomberman
+ 2012
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+
+ Bruce Lee
+ 2015
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Chase
+ 2012
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+ Copter v0.1
+ 2012
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Digger
+ 2016
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+ Edge Grinder v1.01
+ 2018
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+ Jim Power Test
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Lirus
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Touhou Zero. Lost Donation Box Incident
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MultiDude
+ 2014
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+
+ Ninja Gaiden
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Otter & Smoker
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ottifants
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Once Upon a Time in a Kingdom
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PacPack
+ 2018
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Cannon Fodder Parallax
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Sir Ababol
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+ Socoban
+ 2015
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Sonic the Hedgehog
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+ Street Fighter 2 (v1.1)
+ 2023
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+
+ Synchronization
+ 201?
+ Robus
+
+
+
+
+
+
+
+
+
+
+
+
+ T-circles
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Tetris
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ TS-TechDemo
+ 2013
+ Wizart/DT
+
+
+
+
+
+
+
+
+
+ TSolitaire
+ 201?
+ ERA Creative Group (Multinational)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Uwol - Quest for Money
+ 2012
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
+ Wonder Boy
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Xonix
+ 2012
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ Zen Loops
+ 201?
+ <homebrew>
+
+
+
+
+
+
+
+
+
+ ZX Battle City v1.4 (NoVDAC)
+ 2020
+ <homebrew>
+
+
+
+
+
+
+
+
+
+
diff --git a/hash/tsconf_betadisc_flop.xml b/hash/tsconf_betadisc_flop.xml
deleted file mode 100644
index d315425839e..00000000000
--- a/hash/tsconf_betadisc_flop.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
- Copter v0.1
- 2012
- Wizart/DT
-
-
-
-
-
-
-
-
- ZX Battle City v1.4 (NoVDAC)
- 2020
- Marie Slip / n1k-o
-
-
-
-
-
-
-
-
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index ec9498f2976..b07aa482794 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -1920,6 +1920,8 @@ if (BUSES["ISA"]~=null) then
MAME_DIR .. "src/devices/bus/isa/xsu_cards.h",
MAME_DIR .. "src/devices/bus/isa/xtide.cpp",
MAME_DIR .. "src/devices/bus/isa/xtide.h",
+ MAME_DIR .. "src/devices/bus/isa/zxbus_adapter.cpp",
+ MAME_DIR .. "src/devices/bus/isa/zxbus_adapter.h",
}
end
diff --git a/src/devices/bus/isa/com.cpp b/src/devices/bus/isa/com.cpp
index 4a1cc1ebd00..659cb3a226d 100644
--- a/src/devices/bus/isa/com.cpp
+++ b/src/devices/bus/isa/com.cpp
@@ -41,7 +41,7 @@ DEFINE_DEVICE_TYPE(ISA8_COM, isa8_com_device, "isa_com", "Communications Adapter
void isa8_com_device::device_add_mconfig(machine_config &config)
{
- ins8250_device &uart0(INS8250(config, "uart_0", XTAL(1'843'200)));
+ ns16550_device &uart0(NS16550(config, "uart_0", XTAL(1'843'200)));
uart0.out_tx_callback().set("serport0", FUNC(rs232_port_device::write_txd));
uart0.out_dtr_callback().set("serport0", FUNC(rs232_port_device::write_dtr));
uart0.out_rts_callback().set("serport0", FUNC(rs232_port_device::write_rts));
@@ -118,7 +118,7 @@ isa8_com_device::isa8_com_device(const machine_config &mconfig, device_type type
void isa8_com_device::device_start()
{
set_isa_device();
- m_isa->install_device(0x03f8, 0x03ff, read8sm_delegate(*subdevice("uart_0"), FUNC(ins8250_device::ins8250_r)), write8sm_delegate(*subdevice("uart_0"), FUNC(ins8250_device::ins8250_w)));
+ m_isa->install_device(0x03e8, 0x03ef, read8sm_delegate(*subdevice("uart_0"), FUNC(ins8250_device::ins8250_r)), write8sm_delegate(*subdevice("uart_0"), FUNC(ins8250_device::ins8250_w)));
m_isa->install_device(0x02f8, 0x02ff, read8sm_delegate(*subdevice("uart_1"), FUNC(ins8250_device::ins8250_r)), write8sm_delegate(*subdevice("uart_1"), FUNC(ins8250_device::ins8250_w)));
// m_isa->install_device(0x03e8, 0x03ef, read8sm_delegate(*subdevice("uart_2"), FUNC(ins8250_device::ins8250_r)), write8sm_delegate(*subdevice("uart_2"), FUNC(ins8250_device::ins8250_w)));
// m_isa->install_device(0x02e8, 0x02ef, read8sm_delegate(*subdevice("uart_3"), FUNC(ins8250_device::ins8250_r)), write8sm_delegate(*subdevice("uart_3"), FUNC(ins8250_device::ins8250_w)));
diff --git a/src/devices/bus/isa/isa_cards.cpp b/src/devices/bus/isa/isa_cards.cpp
index b11bbc87fa1..98ec21605e7 100644
--- a/src/devices/bus/isa/isa_cards.cpp
+++ b/src/devices/bus/isa/isa_cards.cpp
@@ -9,6 +9,7 @@
#include "emu.h"
#include "isa_cards.h"
+/*
// video
#include "aga.h"
#include "cga.h"
@@ -98,10 +99,13 @@
#include "finalchs.h"
#include "hpblp.h"
#include "opus100pm.h"
+*/
+#include "zxbus_adapter.h"
void pc_isa8_cards(device_slot_interface &device)
{
+/*
device.option_add("mda", ISA8_MDA);
device.option_add("cga", ISA8_CGA);
device.option_add("cga_ec1841", ISA8_EC1841_0002);
@@ -156,10 +160,13 @@ void pc_isa8_cards(device_slot_interface &device)
device.option_add("acb2072", ACB2072);
device.option_add("3xtwin", ISA8_3XTWIN);
device.option_add("opus108pm", ISA8_OPUS108PM);
+*/
+ device.option_add("zxbus_adapter", ISA8_ZXBUS);
}
void pc_isa16_cards(device_slot_interface &device)
{
+/*
// 8-bit
device.option_add("mda", ISA8_MDA);
device.option_add("cga", ISA8_CGA);
@@ -261,4 +268,5 @@ void pc_isa16_cards(device_slot_interface &device)
device.option_add("omti8621", ISA16_OMTI8621);
device.option_add("lrk331", LRK331);
device.option_add("hpblp", HPBLP);
+*/
}
diff --git a/src/devices/bus/isa/zxbus_adapter.cpp b/src/devices/bus/isa/zxbus_adapter.cpp
new file mode 100644
index 00000000000..c65ea81bc74
--- /dev/null
+++ b/src/devices/bus/isa/zxbus_adapter.cpp
@@ -0,0 +1,28 @@
+// license:BSD-3-Clause
+// copyright-holders:Andrei I. Holub
+#include "emu.h"
+#include "zxbus_adapter.h"
+
+DEFINE_DEVICE_TYPE(ISA8_ZXBUS, zxbus_adapter_device, "zxbus_adapter", "ISA8 to ZXBUS Adapter")
+
+zxbus_adapter_device::zxbus_adapter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, ISA8_ZXBUS, tag, owner, clock)
+ , device_isa8_card_interface(mconfig, *this)
+ , m_isa_io_view(*this, "isa_io_view")
+ , m_zxbus(*this, "zxbus")
+{
+}
+
+void zxbus_adapter_device::device_start()
+{
+ set_isa_device();
+ m_isa->space(isa8_device::AS_ISA_IO).install_view(0x0000, 0xffff, m_isa_io_view);
+ m_zxbus->set_io_space(m_isa_io_view[0], m_isa_io_view[0]);
+ m_isa_io_view.select(0);
+}
+
+void zxbus_adapter_device::device_add_mconfig(machine_config &config)
+{
+ ZXBUS(config, m_zxbus, 0);
+ ZXBUS_SLOT(config, "card", 0, m_zxbus, zxbus_cards, nullptr);
+}
diff --git a/src/devices/bus/isa/zxbus_adapter.h b/src/devices/bus/isa/zxbus_adapter.h
new file mode 100644
index 00000000000..89cec709628
--- /dev/null
+++ b/src/devices/bus/isa/zxbus_adapter.h
@@ -0,0 +1,27 @@
+// license:BSD-3-Clause
+// copyright-holders:Andrei I. Holub
+#ifndef MAME_BUS_ISA_ZXBUS_ADAPTER_H
+#define MAME_BUS_ISA_ZXBUS_ADAPTER_H
+
+#include "isa.h"
+
+#include "bus/spectrum/zxbus/bus.h"
+
+class zxbus_adapter_device: public device_t, public device_isa8_card_interface
+{
+public:
+ zxbus_adapter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+
+private:
+ memory_view m_isa_io_view;
+ required_device m_zxbus;
+
+};
+
+DECLARE_DEVICE_TYPE(ISA8_ZXBUS, zxbus_adapter_device)
+
+#endif // MAME_BUS_ISA_ZXBUS_ADAPTER_H
diff --git a/src/devices/bus/pc_kbd/msnat.cpp b/src/devices/bus/pc_kbd/msnat.cpp
index bc6310c9465..12ca536bc9f 100644
--- a/src/devices/bus/pc_kbd/msnat.cpp
+++ b/src/devices/bus/pc_kbd/msnat.cpp
@@ -201,7 +201,13 @@ DEFINE_DEVICE_TYPE(PC_KBD_MICROSOFT_NATURAL, pc_kbd_microsoft_natural_device, "k
ROM_START( microsoft_natural )
ROM_REGION(0x1000, "ms_natrl_cpu", 0)
- ROM_LOAD("natural.bin", 0x0000, 0x1000, CRC(aa8243ab) SHA1(72134882a5c03e785db07cc54dfb7572c0a730d9))
+ ROM_DEFAULT_BIOS("orig")
+
+ ROM_SYSTEM_BIOS(0, "orig", "Original")
+ ROMX_LOAD("natural.bin", 0x0000, 0x1000, CRC(aa8243ab) SHA1(72134882a5c03e785db07cc54dfb7572c0a730d9), ROM_BIOS(0))
+
+ ROM_SYSTEM_BIOS(1, "sp2k", "Sprinter 2k Fix")
+ ROMX_LOAD("natural-sp2k.bin", 0x0000, 0x1000, CRC(16c21ab2) SHA1(72c6ebe8fd88a81a6c9622ff968ad2d0eb04a629), ROM_BIOS(1))
ROM_END
diff --git a/src/devices/bus/spectrum/zxbus/bus.cpp b/src/devices/bus/spectrum/zxbus/bus.cpp
index 3a34319b39c..0dd47039458 100644
--- a/src/devices/bus/spectrum/zxbus/bus.cpp
+++ b/src/devices/bus/spectrum/zxbus/bus.cpp
@@ -40,8 +40,8 @@ zxbus_device::zxbus_device(const machine_config &mconfig, const char *tag, devic
zxbus_device::zxbus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , m_iospace(*this, finder_base::DUMMY_TAG, -1)
- , m_shadow_io_view(nullptr)
+ , m_io(nullptr)
+ , m_shadow_io(nullptr)
{
}
@@ -52,10 +52,14 @@ void zxbus_device::device_start()
void zxbus_device::add_slot(zxbus_slot_device &slot)
{
m_slot_list.push_front(&slot);
- if (m_shadow_io_view)
+
+ device_zxbus_card_interface *card = slot.get_card_device();
+ if (card)
{
- device_zxbus_card_interface *dev = slot.get_card_device();
- (*m_shadow_io_view).install_device(0x0000, 0xffff, *dev, &device_zxbus_card_interface::map_shadow_io);
+ if (m_io)
+ m_io->install_device(0x0000, 0xffff, *card, &device_zxbus_card_interface::io_map);
+ if (m_shadow_io)
+ m_shadow_io->install_device(0x0000, 0xffff, *card, &device_zxbus_card_interface::shadow_io_map);
}
}
@@ -65,11 +69,6 @@ device_zxbus_card_interface::device_zxbus_card_interface(const machine_config &m
{
}
-void zxbus_device::install_shadow_io(memory_view::memory_view_entry &io_view)
-{
- m_shadow_io_view = &io_view;
-}
-
void device_zxbus_card_interface::interface_pre_start()
{
if (!m_zxbus)
diff --git a/src/devices/bus/spectrum/zxbus/bus.h b/src/devices/bus/spectrum/zxbus/bus.h
index 9a198490496..1af694f7e44 100644
--- a/src/devices/bus/spectrum/zxbus/bus.h
+++ b/src/devices/bus/spectrum/zxbus/bus.h
@@ -85,14 +85,13 @@ class zxbus_device : public device_t
public:
zxbus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- template void set_iospace(T &&tag, int spacenum) { m_iospace.set_tag(std::forward(tag), spacenum); }
- template void install_device(offs_t addrstart, offs_t addrend, T &device, void (T::*map)(class address_map &map), u64 unitmask = ~u64(0))
+ void set_io_space(address_space_installer &io, address_space_installer &shadow_io)
{
- m_iospace->install_device(addrstart, addrend, device, map, unitmask);
+ m_io = &io;
+ m_shadow_io = &shadow_io;
}
void add_slot(zxbus_slot_device &slot);
- void install_shadow_io(memory_view::memory_view_entry &io_view);
protected:
zxbus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
@@ -100,8 +99,8 @@ protected:
virtual void device_start() override ATTR_COLD;
private:
- required_address_space m_iospace;
- memory_view::memory_view_entry *m_shadow_io_view;
+ address_space_installer *m_io;
+ address_space_installer *m_shadow_io;
std::forward_list m_slot_list;
};
@@ -114,7 +113,8 @@ class device_zxbus_card_interface : public device_interface
friend class zxbus_slot_device;
public:
- virtual void map_shadow_io(address_map &map) ATTR_COLD {}
+ virtual void io_map(address_map &map) ATTR_COLD {}
+ virtual void shadow_io_map(address_map &map) ATTR_COLD {}
protected:
device_zxbus_card_interface(const machine_config &mconfig, device_t &device);
diff --git a/src/devices/bus/spectrum/zxbus/nemoide.cpp b/src/devices/bus/spectrum/zxbus/nemoide.cpp
index 75c83bc31fe..4aef90df554 100644
--- a/src/devices/bus/spectrum/zxbus/nemoide.cpp
+++ b/src/devices/bus/spectrum/zxbus/nemoide.cpp
@@ -21,12 +21,13 @@ public:
, m_ata(*this, "ata")
{ }
+ virtual void io_map(address_map &map) override ATTR_COLD;
+
protected:
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
private:
- void map_io(address_map &map) ATTR_COLD;
u8 ata_r(offs_t offset);
void ata_w(offs_t offset, u8 data);
@@ -51,7 +52,7 @@ void nemoide_device::ata_w(offs_t offset, u8 data)
m_ata->cs0_w((offset >> 5) & 7, ata_data);
}
-void nemoide_device::map_io(address_map &map)
+void nemoide_device::io_map(address_map &map)
{
map(0x0011, 0x0011).mirror(0xff00).lrw8(NAME([this]() { return m_ata_data_latch; })
, NAME([this](offs_t offset, u8 data) { m_ata_data_latch = data; }));
@@ -74,8 +75,6 @@ void nemoide_device::device_add_mconfig(machine_config &config)
void nemoide_device::device_start()
{
save_item(NAME(m_ata_data_latch));
-
- m_zxbus->install_device(0x0000, 0xffff, *this, &nemoide_device::map_io);
}
} // anonymous namespace
diff --git a/src/devices/bus/spectrum/zxbus/neogs.cpp b/src/devices/bus/spectrum/zxbus/neogs.cpp
index 2848523a328..f77d5071a62 100644
--- a/src/devices/bus/spectrum/zxbus/neogs.cpp
+++ b/src/devices/bus/spectrum/zxbus/neogs.cpp
@@ -85,6 +85,8 @@ public:
, m_neogs_led(*this, "neogs_led")
{ }
+ virtual void io_map(address_map &map) override ATTR_COLD;
+
protected:
// device_t implementation
virtual void device_start() override ATTR_COLD;
@@ -92,8 +94,6 @@ protected:
virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
- void neogsmap(address_map &map) ATTR_COLD;
-
INTERRUPT_GEN_MEMBER(irq0_line_assert);
void map_memory(address_map &map) ATTR_COLD;
@@ -437,7 +437,7 @@ const tiny_rom_entry *neogs_device::device_rom_region() const
return ROM_NAME( neogs );
}
-void neogs_device::neogsmap(address_map &map)
+void neogs_device::io_map(address_map &map)
{
map(0x00bb, 0x00bb).mirror(0xff00).rw(FUNC(neogs_device::neogs_status_r), FUNC(neogs_device::neogs_command_w));
map(0x00b3, 0x00b3).mirror(0xff00).rw(FUNC(neogs_device::neogs_data_r), FUNC(neogs_device::neogs_data_w));
@@ -465,8 +465,6 @@ void neogs_device::device_start()
}
});
- m_zxbus->install_device(0x0000, 0xffff, *this, &neogs_device::neogsmap);
-
m_neogs_led.resolve();
save_item(NAME(m_data_in));
diff --git a/src/devices/bus/spectrum/zxbus/smuc.cpp b/src/devices/bus/spectrum/zxbus/smuc.cpp
index d2ac18278a4..f44cb7a6106 100644
--- a/src/devices/bus/spectrum/zxbus/smuc.cpp
+++ b/src/devices/bus/spectrum/zxbus/smuc.cpp
@@ -25,7 +25,7 @@ public:
, m_ata(*this, "ata")
{ }
- virtual void map_shadow_io(address_map &map) override ATTR_COLD;
+ virtual void shadow_io_map(address_map &map) override ATTR_COLD;
protected:
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
@@ -33,8 +33,6 @@ protected:
virtual void device_reset() override ATTR_COLD;
private:
- void map_io(address_map &map) ATTR_COLD {}
-
void port_ffba_w(offs_t offset, u8 data);
u8 ata_r(offs_t offset);
void ata_w(offs_t offset, u8 data);
@@ -83,7 +81,7 @@ void smuc_device::ata_w(offs_t offset, u8 data)
m_ata->cs0_w(ata_offset, ata_data);
}
-void smuc_device::map_shadow_io(address_map &map)
+void smuc_device::shadow_io_map(address_map &map)
{
map(0x18a2, 0x18a2).mirror(0x4718) // 5fba | 0x011xxx101xx010 | Version: 2
.lr8(NAME([]() { return 0x40; }));
@@ -125,8 +123,6 @@ void smuc_device::device_start()
save_item(NAME(m_port_7fba_data));
save_item(NAME(m_port_ffba_data));
save_item(NAME(m_ide_hi));
-
- m_zxbus->install_device(0x0000, 0xffff, *this, &smuc_device::map_io);
}
void smuc_device::device_reset()
diff --git a/src/devices/machine/atastorage.h b/src/devices/machine/atastorage.h
index 08a3d901b98..27b433b8b28 100644
--- a/src/devices/machine/atastorage.h
+++ b/src/devices/machine/atastorage.h
@@ -61,7 +61,7 @@ protected:
virtual void signature() override;
int m_can_identify_device;
- uint16_t m_num_cylinders;
+ uint32_t m_num_cylinders;
uint8_t m_num_sectors;
uint8_t m_num_heads;
diff --git a/src/devices/machine/z80dma.cpp b/src/devices/machine/z80dma.cpp
index 1e6ce280b0f..9b2e4d29b1a 100644
--- a/src/devices/machine/z80dma.cpp
+++ b/src/devices/machine/z80dma.cpp
@@ -131,17 +131,20 @@ enum
****************************************************************************/
DEFINE_DEVICE_TYPE(Z80DMA, z80dma_device, "z80dma", "Z80 DMA Controller")
+ALLOW_SAVE_TYPE(z80dma_device::dma_mode);
+
/****************************************************************************
* z80dma_device - constructor
****************************************************************************/
z80dma_device::z80dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : z80dma_device(mconfig, Z80DMA, tag, owner, clock)
+ : z80dma_device(mconfig, Z80DMA, tag, owner, clock, dma_mode::ZILOG)
{
}
-z80dma_device::z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+z80dma_device::z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, dma_mode dma_mode)
: device_t(mconfig, type, tag, owner, clock)
, device_z80daisy_interface(mconfig, *this)
+ , m_dma_mode(dma_mode)
, m_out_busreq_cb(*this)
, m_out_int_cb(*this)
, m_out_ieo_cb(*this)
@@ -162,6 +165,7 @@ void z80dma_device::device_start()
m_timer = timer_alloc(FUNC(z80dma_device::clock_w), this);
// register for state saving
+ save_item(NAME(m_dma_mode));
save_item(NAME(m_regs));
save_item(NAME(m_regs_follow));
save_item(NAME(m_num_follow));
@@ -179,6 +183,7 @@ void z80dma_device::device_start()
save_item(NAME(m_rdy));
save_item(NAME(m_force_ready));
save_item(NAME(m_wait));
+ save_item(NAME(m_waits_extra));
save_item(NAME(m_busrq_ack));
save_item(NAME(m_is_pulse));
save_item(NAME(m_latch));
@@ -197,6 +202,7 @@ void z80dma_device::device_reset()
m_rdy = 0;
m_force_ready = 0;
m_wait = 0;
+ m_waits_extra = 0;
m_num_follow = 0;
m_read_num_follow = m_read_cur_follow = 0;
m_reset_pointer = 0;
@@ -445,10 +451,9 @@ void z80dma_device::do_write()
break;
}
+ m_byte_counter++;
m_addressA += PORTA_FIXED ? 0 : PORTA_INC ? 1 : -1;
m_addressB += PORTB_FIXED ? 0 : PORTB_INC ? 1 : -1;
-
- m_byte_counter++;
}
/****************************************************************************
@@ -497,7 +502,8 @@ TIMER_CALLBACK_MEMBER(z80dma_device::clock_w)
}
const attotime clock = clocks_to_attotime(1);
- const attotime next = clock * (3 - ((PORTA_IS_SOURCE ? PORTA_TIMING : PORTB_TIMING) & 0x03));
+ const attotime next = clock * (3 - ((PORTA_IS_SOURCE ? PORTA_TIMING : PORTB_TIMING) & 0x03) + m_waits_extra);
+ m_waits_extra = 0;
m_timer->adjust(next, 0, clock);
m_dma_seq = SEQ_TRANS1_READ_SOURCE;
@@ -517,7 +523,8 @@ TIMER_CALLBACK_MEMBER(z80dma_device::clock_w)
case SEQ_TRANS1_INC_DEC_DEST_ADDRESS:
{
const attotime clock = clocks_to_attotime(1);
- const attotime next = clock * (3 - ((PORTB_IS_SOURCE ? PORTA_TIMING : PORTB_TIMING) & 0x03));
+ const attotime next = clock * (3 - ((PORTB_IS_SOURCE ? PORTA_TIMING : PORTB_TIMING) & 0x03) + m_waits_extra);
+ m_waits_extra = 0;
m_timer->adjust(next, 0, clock);
m_dma_seq = SEQ_TRANS1_WRITE_DEST;
@@ -672,7 +679,7 @@ void z80dma_device::write(u8 data)
if (data & 0x10)
m_regs_follow[m_num_follow++] = GET_REGNUM(MATCH_BYTE);
- if (BIT(data, 6))
+ if (BIT(data, 6) && m_dma_mode != dma_mode::UA858D)
{
enable();
}
@@ -875,7 +882,7 @@ TIMER_CALLBACK_MEMBER(z80dma_device::rdy_write_callback)
void z80dma_device::rdy_w(int state)
{
LOG("Z80DMA RDY: %d Active High: %d\n", state, READY_ACTIVE_HIGH);
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(z80dma_device::rdy_write_callback),this), state);
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(z80dma_device::rdy_write_callback), this), state);
}
/****************************************************************************
@@ -885,3 +892,11 @@ void z80dma_device::bai_w(int state)
{
m_busrq_ack = state;
}
+
+
+DEFINE_DEVICE_TYPE(UA858D, ua858d_device, "ua858d", "UA858D DMA Controller")
+
+ua858d_device::ua858d_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : z80dma_device(mconfig, UA858D, tag, owner, clock, dma_mode::UA858D)
+{
+}
diff --git a/src/devices/machine/z80dma.h b/src/devices/machine/z80dma.h
index b461330eab0..092b70cbee5 100644
--- a/src/devices/machine/z80dma.h
+++ b/src/devices/machine/z80dma.h
@@ -48,6 +48,12 @@ class z80dma_device : public device_t,
public device_z80daisy_interface
{
public:
+ enum class dma_mode : u8
+ {
+ ZILOG = 0,
+ UA858D = 1
+ };
+
// construction/destruction
z80dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
@@ -60,12 +66,14 @@ public:
auto in_iorq_callback() { return m_in_iorq_cb.bind(); }
auto out_iorq_callback() { return m_out_iorq_cb.bind(); }
+ void set_dma_mode(dma_mode dma_mode) { m_dma_mode = dma_mode; }
u8 read();
virtual void write(u8 data);
void iei_w(int state) { m_iei = state; interrupt_check(); }
void rdy_w(int state);
void wait_w(int state) { m_wait = state; }
+ void adjust_wait(int count) { m_waits_extra += count; }
void bai_w(int state);
protected:
@@ -90,7 +98,7 @@ protected:
static inline constexpr int TM_SEARCH = 0x02;
static inline constexpr int TM_SEARCH_TRANSFER = 0x03;
- z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+ z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, dma_mode dma_mode);
// device_t implementation
virtual void device_start() override ATTR_COLD;
@@ -112,6 +120,7 @@ protected:
static constexpr unsigned REGNUM(unsigned m, unsigned s) { return (m << 3) + s; }
+ dma_mode m_dma_mode;
u16 m_addressA;
u16 m_addressB;
u16 m_count;
@@ -153,6 +162,7 @@ private:
u8 m_reset_pointer;
int m_wait;
+ int m_waits_extra;
int m_busrq_ack;
bool m_is_pulse;
u8 m_latch;
@@ -164,8 +174,14 @@ private:
u8 m_vector; // interrupt vector
};
+class ua858d_device : public z80dma_device
+{
+public:
+ ua858d_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
// device type definition
DECLARE_DEVICE_TYPE(Z80DMA, z80dma_device)
+DECLARE_DEVICE_TYPE(UA858D, ua858d_device)
#endif // MAME_MACHINE_Z80DMA_H
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index cded76abf7a..f0c954b2e31 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -28,6 +28,7 @@
#include "softlist.h"
#include "corestr.h"
+#include "multibyte.h"
#include
#include
@@ -2007,6 +2008,9 @@ void debugger_commands::execute_rewind(const std::vector ¶
void debugger_commands::execute_save(int spacenum, const std::vector ¶ms)
{
+ if (execute_save_try_memory(params))
+ return;
+
u64 offset, endoffset, length;
address_space *space;
@@ -2093,31 +2097,42 @@ void debugger_commands::execute_save(int spacenum, const std::vector ¶ms)
+bool debugger_commands::execute_save_try_memory(const std::vector ¶ms)
{
- u64 offset, length;
- memory_region *region;
+ u64 offset = u64(-1);
+ memory_region *region = nullptr;
+ memory_share *share = nullptr;
+ if (!m_console.validate_address_with_memory_parameter(params[1], offset, region, share))
+ return false; // not memory case
- // validate parameters
- if (!m_console.validate_number_parameter(params[1], offset))
- return;
- if (!m_console.validate_number_parameter(params[2], length))
- return;
- if (!m_console.validate_memory_region_parameter(params[3], region))
- return;
+ u64 length;
+ if (offset == u64(-1) || !m_console.validate_number_parameter(params[2], length) || (region == nullptr && share == nullptr))
+ return true;
- if (offset >= region->bytes())
+ u32 msize;
+ u8 *base;
+ if (region != nullptr)
+ {
+ msize = region->bytes();
+ base = region->base();
+ }
+ else // if (share != nullptr)
+ {
+ msize = share->bytes();
+ base = reinterpret_cast(share->ptr());
+ }
+
+ if (offset >= msize)
{
m_console.printf("Invalid offset\n");
- return;
+ return true;
}
- if ((length <= 0) || ((length + offset) >= region->bytes()))
- length = region->bytes() - offset;
+ if ((length <= 0) || ((length + offset) >= msize))
+ length = msize - offset;
// open the file
std::string const filename(params[0]);
@@ -2125,12 +2140,24 @@ void debugger_commands::execute_saveregion(const std::vector &
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
- return;
+ return true;
}
- fwrite(region->base() + offset, 1, length, f);
+ fwrite(base + offset, 1, length, f);
fclose(f);
m_console.printf("Data saved successfully\n");
+
+ return true;
+}
+
+
+/*-------------------------------------------------
+ execute_saveregion - execute the save command on region memory
+-------------------------------------------------*/
+
+void debugger_commands::execute_saveregion(const std::vector ¶ms)
+{
+ execute_save(-1, std::vector{ params[0], std::string(params[1]) + std::string(params[3]) + ".m", params[2] });
}
@@ -2140,6 +2167,9 @@ void debugger_commands::execute_saveregion(const std::vector &
void debugger_commands::execute_load(int spacenum, const std::vector ¶ms)
{
+ if (execute_load_try_memory(params))
+ return;
+
u64 offset, endoffset, length = 0;
address_space *space;
@@ -2247,31 +2277,43 @@ void debugger_commands::execute_load(int spacenum, const std::vector ¶ms)
+bool debugger_commands::execute_load_try_memory(const std::vector ¶ms)
{
- u64 offset, length;
- memory_region *region;
+ u64 offset = u64(-1);
+ memory_region *region = nullptr;
+ memory_share *share = nullptr;
+ if (!m_console.validate_address_with_memory_parameter(params[1], offset, region, share))
+ return false; // not memory case
+ u64 length;
// validate parameters
- if (!m_console.validate_number_parameter(params[1], offset))
- return;
- if (!m_console.validate_number_parameter(params[2], length))
- return;
- if (!m_console.validate_memory_region_parameter(params[3], region))
- return;
+ if (offset == u64(-1) || !m_console.validate_number_parameter(params[2], length) || (region == nullptr && share == nullptr))
+ return true;
- if (offset >= region->bytes())
+ u32 msize;
+ u8 *base;
+ if (region != nullptr)
+ {
+ msize = region->bytes();
+ base = region->base();
+ }
+ else // if (share != nullptr)
+ {
+ msize = share->bytes();
+ base = reinterpret_cast(share->ptr());
+ }
+
+ if (offset >= msize)
{
m_console.printf("Invalid offset\n");
- return;
+ return true;
}
- if ((length <= 0) || ((length + offset) >= region->bytes()))
- length = region->bytes() - offset;
+ if ((length <= 0) || ((length + offset) >= msize))
+ length = msize - offset;
// open the file
std::string filename(params[0]);
@@ -2279,7 +2321,7 @@ void debugger_commands::execute_loadregion(const std::vector &
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
- return;
+ return true;
}
fseek(f, 0L, SEEK_END);
@@ -2290,10 +2332,22 @@ void debugger_commands::execute_loadregion(const std::vector &
if (length >= size)
length = size;
- fread(region->base() + offset, 1, length, f);
+ fread(base + offset, 1, length, f);
fclose(f);
m_console.printf("Data loaded successfully to memory : 0x%X to 0x%X\n", offset, offset + length - 1);
+
+ return true;
+}
+
+
+/*-------------------------------------------------
+ execute_loadregion - execute the load command on region memory
+-------------------------------------------------*/
+
+void debugger_commands::execute_loadregion(const std::vector ¶ms)
+{
+ execute_load(-1, std::vector{ params[0], std::string(params[1]) + std::string(params[3]) + ".m", params[2] });
}
@@ -2303,6 +2357,9 @@ void debugger_commands::execute_loadregion(const std::vector &
void debugger_commands::execute_dump(int spacenum, const std::vector ¶ms)
{
+ if (execute_dump_try_memory(params))
+ return;
+
// validate parameters
address_space *space;
u64 offset;
@@ -2460,6 +2517,172 @@ void debugger_commands::execute_dump(int spacenum, const std::vector ¶ms)
+{
+ u64 offset = u64(-1);
+ memory_region *region = nullptr;
+ memory_share *share = nullptr;
+ if (!m_console.validate_address_with_memory_parameter(params[1], offset, region, share))
+ return false; // not memory case
+
+ u64 length;
+ if (offset == u64(-1) || !m_console.validate_number_parameter(params[2], length) || (region == nullptr && share == nullptr))
+ return true;
+
+ u64 width = 0;
+ if (params.size() > 3 && !m_console.validate_number_parameter(params[3], width))
+ return true;
+
+ bool ascii = true;
+ if (params.size() > 4 && !m_console.validate_boolean_parameter(params[4], ascii))
+ return true;
+
+ u64 rowsize = 16;
+ if (params.size() > 5 && !m_console.validate_number_parameter(params[5], rowsize))
+ return true;
+
+ int shift = 0;
+ u64 granularity = shift >= 0 ? 1 : 1 << -shift;
+
+ u32 msize;
+ u8 *base;
+ bool be;
+ if (region != nullptr)
+ {
+ msize = region->bytes();
+ base = region->base();
+ be = region->endianness() == ENDIANNESS_BIG;
+ if (width == 0)
+ width = region->bytewidth();
+ }
+ else // if (share != nullptr)
+ {
+ msize = share->bytes();
+ base = reinterpret_cast(share->ptr());
+ be = share->endianness() == ENDIANNESS_BIG;
+ if (width == 0)
+ width = share->bytewidth();
+ }
+
+ if (offset >= msize)
+ {
+ m_console.printf("Invalid offset\n");
+ return true;
+ }
+ if ((length <= 0) || ((length + offset) >= msize))
+ length = msize - offset;
+
+ // further validation
+ if (width != 1 && width != 2 && width != 4 && width != 8)
+ {
+ m_console.printf("Invalid width! (must be 1,2,4 or 8)\n");
+ return true;
+ }
+ if (width < granularity)
+ {
+ m_console.printf("Invalid width! (must be at least %d)\n", granularity);
+ return true;
+ }
+ if (rowsize == 0 || (rowsize % width) != 0)
+ {
+ m_console.printf("Invalid row size! (must be a positive multiple of %d)\n", width);
+ return true;
+ }
+
+ u64 endoffset = offset + length - 1;
+
+ // open the file
+ std::string filename(params[0]);
+ FILE *const f = fopen(filename.c_str(), "w");
+ if (!f)
+ {
+ m_console.printf("Error opening file '%s'\n", params[0]);
+ return true;
+ }
+
+ // now write the data out
+ util::ovectorstream output;
+ output.reserve(200);
+
+ const unsigned delta = (shift >= 0) ? (width << shift) : (width >> -shift);
+
+ for (u64 i = offset; i <= endoffset; i += rowsize)
+ {
+ output.clear();
+ output.rdbuf()->clear();
+
+ // print the address
+ util::stream_format(output, "%0*X: ", 8, i);
+
+ // print the bytes
+ for (u64 j = 0; j < rowsize; j += delta)
+ {
+ if (i + j <= endoffset)
+ {
+ switch (width)
+ {
+ case 8:
+ util::stream_format(output, " %016X", get_u64be(&base[i+j]));
+ break;
+ case 4:
+ util::stream_format(output, " %08X", get_u32be(&base[i+j]));
+ break;
+ case 2:
+ util::stream_format(output, " %04X", get_u16be(&base[i+j]));
+ break;
+ case 1:
+ util::stream_format(output, " %02X", base[i+j]);
+ break;
+ }
+ }
+ else
+ util::stream_format(output, " %*s", width * 2, "");
+ }
+
+ // print the ASCII
+ if (ascii)
+ {
+ util::stream_format(output, " ");
+ for (u64 j = 0; j < rowsize && (i + j) <= endoffset; j += delta)
+ {
+ u64 data = 0;
+ switch (width)
+ {
+ case 8:
+ data = get_u64be(&base[i+j]);
+ break;
+ case 4:
+ data = get_u32be(&base[i+j]);
+ break;
+ case 2:
+ data = get_u16be(&base[i+j]);
+ break;
+ case 1:
+ data = base[i+j];
+ break;
+ }
+ for (unsigned int b = 0; b != width; b++) {
+ u8 byte = data >> (8 * (be ? (width-1-b) : b));
+ util::stream_format(output, "%c", (byte >= 32 && byte < 127) ? byte : '.');
+ }
+ }
+ }
+
+ // output the result
+ auto const &text = output.vec();
+ fprintf(f, "%.*s\n", int(unsigned(text.size())), &text[0]);
+ }
+
+ // close the file
+ fclose(f);
+ m_console.printf("Data dumped successfully\n");
+
+ return true;
+}
//-------------------------------------------------
// execute_strdump - execute the strdump command
@@ -2467,6 +2690,9 @@ void debugger_commands::execute_dump(int spacenum, const std::vector ¶ms)
{
+ if (execute_strdump_try_memory(params))
+ return;
+
// validate parameters
u64 offset;
if (!m_console.validate_number_parameter(params[1], offset))
@@ -2637,6 +2863,187 @@ void debugger_commands::execute_strdump(int spacenum, const std::vector ¶ms)
+{
+ u64 offset = u64(-1);
+ memory_region *region = nullptr;
+ memory_share *share = nullptr;
+ if (!m_console.validate_address_with_memory_parameter(params[1], offset, region, share))
+ return false; // not memory case
+
+ u64 length;
+ if (offset == u64(-1) || !m_console.validate_number_parameter(params[2], length) || (region == nullptr && share == nullptr))
+ return true;
+
+ u64 term = 0;
+ if (params.size() > 3 && !m_console.validate_number_parameter(params[3], term))
+ return true;
+
+ // further validation
+ if (term >= 0x100 && term != u64(-0x80))
+ {
+ m_console.printf("Invalid termination character\n");
+ return true;
+ }
+
+ // open the file
+ std::string filename(params[0]);
+ FILE *f = fopen(filename.c_str(), "w");
+ if (!f)
+ {
+ m_console.printf("Error opening file '%s'\n", params[0]);
+ return true;
+ }
+
+ u32 msize;
+ u8 *base;
+ bool be;
+ u64 width;
+ if (region != nullptr)
+ {
+ msize = region->bytes();
+ base = region->base();
+ be = region->endianness() == ENDIANNESS_BIG;
+ width = region->bytewidth();
+ }
+ else // if (share != nullptr)
+ {
+ msize = share->bytes();
+ base = reinterpret_cast(share->ptr());
+ be = share->endianness() == ENDIANNESS_BIG;
+ width = share->bytewidth();
+ }
+
+ if (offset >= msize)
+ {
+ m_console.printf("Invalid offset\n");
+ return true;
+ }
+ if ((length <= 0) || ((length + offset) >= msize))
+ length = msize - offset;
+
+ // now write the data out
+ util::ovectorstream output;
+ output.reserve(200);
+
+ bool terminated = true;
+ while (length-- != 0)
+ {
+ if (terminated)
+ {
+ terminated = false;
+ output.clear();
+ output.rdbuf()->clear();
+
+ // print the address
+ util::stream_format(output, "%0*X: \"", 8, offset);
+ }
+
+ // get the character data
+ u64 data = 0;
+ offs_t curaddr = offset;
+ switch (width)
+ {
+ case 1:
+ data = base[curaddr];
+ break;
+
+ case 2:
+ data = be ? get_u16be(&base[curaddr]) : get_u16le(&base[curaddr]);
+ break;
+
+ case 4:
+ data = be ? get_u32be(&base[curaddr]) : get_u32le(&base[curaddr]);
+ break;
+
+ case 8:
+ data = be ? get_u64be(&base[curaddr]) : get_u64le(&base[curaddr]);
+ break;
+ }
+
+ // print the characters
+ for (int n = 0; n < width; n++)
+ {
+ // check for termination within word
+ if (terminated)
+ {
+ terminated = false;
+
+ // output the result
+ auto const &text = output.vec();
+ fprintf(f, "%.*s\"\n", int(unsigned(text.size())), &text[0]);
+ output.clear();
+ output.rdbuf()->clear();
+
+ // print the address
+ util::stream_format(output, "%0*X.%d: \"", 8, offset, n);
+ }
+
+ u8 ch = data & 0xff;
+ data >>= 8;
+
+ // check for termination
+ if (term == u64(-0x80))
+ {
+ if (BIT(ch, 7))
+ {
+ terminated = true;
+ ch &= 0x7f;
+ }
+ }
+ else if (ch == term)
+ {
+ terminated = true;
+ continue;
+ }
+
+ // check for non-ASCII characters
+ if (ch < 0x20 || ch >= 0x7f)
+ {
+ // use special or octal escape
+ if (ch >= 0x07 && ch <= 0x0d)
+ util::stream_format(output, "\\%c", "abtnvfr"[ch - 0x07]);
+ else
+ util::stream_format(output, "\\%03o", ch);
+ }
+ else
+ {
+ if (ch == '"' || ch == '\\')
+ output << '\\';
+ output << char(ch);
+ }
+ }
+
+ if (terminated)
+ {
+ // output the result
+ auto const &text = output.vec();
+ fprintf(f, "%.*s\"\n", int(unsigned(text.size())), &text[0]);
+ output.clear();
+ output.rdbuf()->clear();
+ }
+
+ offset += width;
+ }
+
+ if (!terminated)
+ {
+ // output the result
+ auto const &text = output.vec();
+ fprintf(f, "%.*s\"\\\n", int(unsigned(text.size())), &text[0]);
+ }
+
+ // close the file
+ fclose(f);
+ m_console.printf("Data dumped successfully\n");
+
+ return true;
+}
+
/*-------------------------------------------------
execute_cheatrange - add a range to search for
@@ -3139,6 +3546,9 @@ void debugger_commands::execute_cheatundo(const std::vector &p
void debugger_commands::execute_find(int spacenum, const std::vector ¶ms)
{
+ if (execute_find_try_memory(params))
+ return;
+
u64 offset, length;
address_space *space;
@@ -3262,6 +3672,140 @@ void debugger_commands::execute_find(int spacenum, const std::vector ¶ms)
+{
+ u64 offset = u64(-1);
+ memory_region *region = nullptr;
+ memory_share *share = nullptr;
+ if (!m_console.validate_address_with_memory_parameter(params[0], offset, region, share))
+ return false; // not memory case
+
+ u64 length;
+ if (offset == u64(-1) || !m_console.validate_number_parameter(params[1], length) || (region == nullptr && share == nullptr))
+ return true;
+
+ u32 msize;
+ u8 *base;
+ bool be;
+ if (region != nullptr)
+ {
+ msize = region->bytes();
+ base = region->base();
+ be = region->endianness() == ENDIANNESS_BIG;
+ }
+ else // if (share != nullptr)
+ {
+ msize = share->bytes();
+ base = reinterpret_cast(share->ptr());
+ be = share->endianness() == ENDIANNESS_BIG;
+ }
+
+ if (offset >= msize)
+ {
+ m_console.printf("Invalid offset\n");
+ return true;
+ }
+ if ((length <= 0) || ((length + offset) >= msize))
+ length = msize - offset;
+
+ // further validation
+ u64 const endoffset = offset + length - 1;
+ int cur_data_size = 1;
+
+ // parse the data parameters
+ u64 data_to_find[256];
+ u8 data_size[256];
+ int data_count = 0;
+ for (int i = 2; i < params.size(); i++)
+ {
+ std::string_view pdata = params[i];
+
+ if (!pdata.empty() && pdata.front() == '"' && pdata.back() == '"') // check for a string
+ {
+ auto const pdatalen = params[i].length() - 1;
+ for (int j = 1; j < pdatalen; j++)
+ {
+ data_to_find[data_count] = pdata[j];
+ data_size[data_count++] = 1;
+ }
+ }
+ else // otherwise, validate as a number
+ {
+ // check for a 'b','w','d',or 'q' prefix
+ data_size[data_count] = cur_data_size;
+ if (pdata.length() >= 2)
+ {
+ if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 1; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 2; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 4; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 8; pdata.remove_prefix(2); }
+ }
+
+ // look for a wildcard
+ if (pdata == "?")
+ data_size[data_count++] |= 0x10;
+
+ // otherwise, validate as a number
+ else if (!m_console.validate_number_parameter(pdata, data_to_find[data_count++]))
+ return true;
+ }
+ }
+
+ // now search
+ int found = 0;
+ for (u64 i = offset; i <= endoffset; i += data_size[0])
+ {
+ int suboffset = 0;
+ bool match = true;
+
+ // find the entire string
+ for (int j = 0; j < data_count && match; j++)
+ {
+ offs_t address = i + suboffset;
+ switch (data_size[j])
+ {
+ case 1:
+ match = u8(data_to_find[j]) == base[address];
+ break;
+
+ case 2:
+ match = u16(data_to_find[j]) == (be ? get_u16be(&base[address]) : get_u16le(&base[address]));
+ break;
+
+ case 4:
+ match = u32(data_to_find[j]) == (be ? get_u32be(&base[address]) : get_u32le(&base[address]));
+ break;
+
+ case 8:
+ match = u64(data_to_find[j]) == (be ? get_u64be(&base[address]) : get_u64le(&base[address]));
+ break;
+
+ default:
+ // all other cases are wildcards
+ break;
+ }
+ suboffset += data_size[j] & 0x0f;
+ }
+
+ // did we find it?
+ if (match)
+ {
+ found++;
+ m_console.printf("Found at %04X\n", i);
+ }
+ }
+
+ // print something if not found
+ if (found == 0)
+ m_console.printf("Not found\n");
+
+ return true;
+}
+
//-------------------------------------------------
// execute_fill - execute the fill command
@@ -3269,6 +3813,9 @@ void debugger_commands::execute_find(int spacenum, const std::vector ¶ms)
{
+ if (execute_fill_try_memory(params))
+ return;
+
u64 offset, length;
address_space *space;
@@ -3371,6 +3918,139 @@ void debugger_commands::execute_fill(int spacenum, const std::vector ¶ms)
+{
+ u64 offset = u64(-1);
+ memory_region *region = nullptr;
+ memory_share *share = nullptr;
+ if (!m_console.validate_address_with_memory_parameter(params[0], offset, region, share))
+ return false; // not memory case
+
+ u64 length;
+ if (offset == u64(-1) || !m_console.validate_number_parameter(params[1], length) || (region == nullptr && share == nullptr))
+ return true;
+
+ u32 msize;
+ u8 *base;
+ bool be;
+ if (region != nullptr)
+ {
+ msize = region->bytes();
+ base = region->base();
+ be = region->endianness() == ENDIANNESS_BIG;
+ }
+ else // if (share != nullptr)
+ {
+ msize = share->bytes();
+ base = reinterpret_cast(share->ptr());
+ be = share->endianness() == ENDIANNESS_BIG;
+ }
+
+ if (offset >= msize)
+ {
+ m_console.printf("Invalid offset\n");
+ return true;
+ }
+ if ((length <= 0) || ((length + offset) >= msize))
+ length = msize - offset;
+
+ // further validation
+ int cur_data_size = 1;
+
+ // parse the data parameters
+ u64 fill_data[256];
+ u8 fill_data_size[256];
+ int data_count = 0;
+ for (int i = 2; i < params.size(); i++)
+ {
+ std::string_view pdata = params[i];
+
+ // check for a string
+ if (!pdata.empty() && pdata.front() == '"' && pdata.back() == '"')
+ {
+ auto const pdatalen = pdata.length() - 1;
+ for (int j = 1; j < pdatalen; j++)
+ {
+ fill_data[data_count] = pdata[j];
+ fill_data_size[data_count++] = 1;
+ }
+ }
+
+ // otherwise, validate as a number
+ else
+ {
+ // check for a 'b','w','d',or 'q' prefix
+ fill_data_size[data_count] = cur_data_size;
+ if (pdata.length() >= 2)
+ {
+ if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 1; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 2; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 4; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 8; pdata.remove_prefix(2); }
+ }
+
+ // validate as a number
+ if (!m_console.validate_number_parameter(pdata, fill_data[data_count++]))
+ return true;
+ }
+ }
+ if (data_count == 0)
+ return true;
+
+ // now fill memory
+ u64 count = length;
+ while (count != 0)
+ {
+ // write the entire string
+ for (int j = 0; j < data_count; j++)
+ {
+ offs_t address = offset;
+ switch (fill_data_size[j])
+ {
+ case 1:
+ base[address] = u8(fill_data[j]);
+ break;
+
+ case 2:
+ if (be)
+ put_u16be(&base[address], u16(fill_data[j]));
+ else
+ put_u16le(&base[address], u16(fill_data[j]));
+ break;
+
+ case 4:
+ if (be)
+ put_u32be(&base[address], u32(fill_data[j]));
+ else
+ put_u32le(&base[address], u32(fill_data[j]));
+ break;
+
+ case 8:
+ if (be)
+ put_u64be(&base[address], u64(fill_data[j]));
+ else
+ put_u64le(&base[address], u64(fill_data[j]));
+ break;
+ }
+
+ offset += fill_data_size[j];
+ if (count <= fill_data_size[j])
+ {
+ count = 0;
+ break;
+ }
+ else
+ count -= fill_data_size[j];
+ }
+ }
+
+ return true;
+}
+
/*-------------------------------------------------
execute_dasm - execute the dasm command
diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h
index cf38c6d903a..0836790e404 100644
--- a/src/emu/debug/debugcmd.h
+++ b/src/emu/debug/debugcmd.h
@@ -127,18 +127,24 @@ private:
void execute_stateload(const std::vector ¶ms);
void execute_rewind(const std::vector ¶ms);
void execute_save(int spacenum, const std::vector ¶ms);
+ bool execute_save_try_memory(const std::vector ¶ms);
void execute_saveregion(const std::vector ¶ms);
void execute_load(int spacenum, const std::vector ¶ms);
+ bool execute_load_try_memory(const std::vector ¶ms);
void execute_loadregion(const std::vector ¶ms);
void execute_dump(int spacenum, const std::vector ¶ms);
+ bool execute_dump_try_memory(const std::vector ¶ms);
void execute_strdump(int spacenum, const std::vector ¶ms);
+ bool execute_strdump_try_memory(const std::vector ¶ms);
void execute_cheatrange(bool init, const std::vector ¶ms);
void execute_cheatnext(bool initial, const std::vector ¶ms);
void execute_cheatlist(const std::vector ¶ms);
void execute_cheatundo(const std::vector ¶ms);
void execute_dasm(const std::vector ¶ms);
void execute_find(int spacenum, const std::vector ¶ms);
+ bool execute_find_try_memory(const std::vector ¶ms);
void execute_fill(int spacenum, const std::vector ¶ms);
+ bool execute_fill_try_memory(const std::vector ¶ms);
void execute_trace(const std::vector ¶ms, bool trace_over);
void execute_traceflush(const std::vector ¶ms);
void execute_history(const std::vector ¶ms);
diff --git a/src/emu/debug/debugcon.cpp b/src/emu/debug/debugcon.cpp
index ec5bc154751..f9076dda523 100644
--- a/src/emu/debug/debugcon.cpp
+++ b/src/emu/debug/debugcon.cpp
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
/***************************************************************************
@@ -883,7 +884,7 @@ bool debugger_console::validate_device_space_parameter(std::string_view param, i
/// optionally followed by a colon and a device identifier. If the
/// device identifier is not presnt, the current CPU with debugger focus
/// is assumed. See #validate_device_parameter for information on how
-/// device parametersare interpreted.
+/// device parameters are interpreted.
/// \param [in] The parameter string.
/// \param [in] spacenum The default address space index. If negative,
/// the first address space exposed by the device (i.e. the address
@@ -916,6 +917,40 @@ bool debugger_console::validate_target_address_parameter(std::string_view param,
}
+/// \brief Validate a parameter as a address with memory region or share name
+///
+/// Validates a parameter as a address with memory region or share tag. addres
+/// parameters stays unchanged if invalid and requires additional validation on
+/// the caller side.
+/// \param [in] The parameter string.
+/// \param [out] addr The address on success, or unchanged on failure.
+/// \param [out] region The region on success, or unchanged on failure.
+/// \param [out] share The share on success, or unchanged on failure.
+/// \return true if the parameter refers to a memory region in the
+/// current system, or false otherwise.
+bool debugger_console::validate_address_with_memory_parameter(std::string_view param, u64 &addr, memory_region *®ion, memory_share *&share)
+{
+ std::string str(param);
+ std::regex re("^([^:]+)(:.+)\\.([ms])$");
+ std::smatch m;
+ if (std::regex_match(str, m, re))
+ {
+ if ('m' == m[3])
+ validate_memory_region_parameter(m.str(2), region);
+ else if ('s' == m[3])
+ validate_memory_share_parameter(m.str(2), share);
+ else
+ return false;
+
+ validate_number_parameter(m.str(1), addr);
+
+ return true;
+ }
+
+ return false;
+}
+
+
/// \brief Validate a parameter as a memory region
///
/// Validates a parameter as a memory region tag and retrieves the
@@ -944,6 +979,34 @@ bool debugger_console::validate_memory_region_parameter(std::string_view param,
}
+/// \brief Validate a parameter as a memory share
+///
+/// Validates a parameter as a memory share tag and retrieves the
+/// specified memory share.
+/// \param [in] The parameter string.
+/// \param [out] result The memory share on success, or unchanged on
+/// failure.
+/// \return true if the parameter refers to a memory share in the
+/// current system, or false otherwise.
+bool debugger_console::validate_memory_share_parameter(std::string_view param, memory_share *&result)
+{
+ auto const &shares = m_machine.memory().shares();
+ std::string_view relative = param;
+ device_t &base = get_device_search_base(relative);
+ auto const iter = shares.find(base.subtag(strmakelower(relative)));
+ if (shares.end() != iter)
+ {
+ result = iter->second.get();
+ return true;
+ }
+ else
+ {
+ printf("No matching memory share found for '%s'\n", param);
+ return false;
+ }
+}
+
+
/// \brief Get search base for device or address space parameter
///
/// Handles prefix prefixes used to indicate that a device tag should be
diff --git a/src/emu/debug/debugcon.h b/src/emu/debug/debugcon.h
index 37b2e235348..b1cef0f7c84 100644
--- a/src/emu/debug/debugcon.h
+++ b/src/emu/debug/debugcon.h
@@ -130,9 +130,15 @@ public:
// validates a parameter as a target address and retrieves the given address space and address
bool validate_target_address_parameter(std::string_view param, int spacenum, address_space *&space, u64 &addr);
+ // validates a parameter as a address with memory region or share name and retrieves the given address and region or share
+ bool validate_address_with_memory_parameter(std::string_view param, u64 &addr, memory_region *®ion, memory_share *&share);
+
// validates a parameter as a memory region name and retrieves the given region
bool validate_memory_region_parameter(std::string_view param, memory_region *&result);
+ // validates a parameter as a memory region name and retrieves the given share
+ bool validate_memory_share_parameter(std::string_view param, memory_share *&result);
+
// validates a parameter as a debugger expression
bool validate_expression_parameter(std::string_view param, parsed_expression &result);
diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp
index 8e5fa1b9c64..e78a31d7568 100644
--- a/src/emu/debug/debughlp.cpp
+++ b/src/emu/debug/debughlp.cpp
@@ -94,26 +94,32 @@ const help_item f_static_help_list[] =
"\n"
" dasm ,,[,[,]] -- disassemble to the given file\n"
" f[ind] ,[,[,...]] -- search memory for data\n"
+ " f[ind] :.{m|s},[,[,...]] -- search memory region or share for data\n"
" f[ind]d ,[,[,...]] -- search data memory for data\n"
" f[ind]i ,[,[,...]] -- search I/O memory for data\n"
" fill ,[,[,...]] -- fill memory with data\n"
+ " fill :.{m|s},[,[,...]] -- fill memory region or share with data\n"
" filld [:],[,[,...]] -- fill data memory with data\n"
" filli [:],[,[,...][ -- fill I/O memory with data\n"
" fillo [:],[,[,...][ -- fill opcode memory with data\n"
" dump ,[:],[,[,[,]]] -- dump memory as text\n"
+ " dump ,:.{m|s},[,[,[,]]] -- dump memory region or share as text\n"
" dumpd ,[:],[,[,[,]]] -- dump data memory as text\n"
" dumpi ,[:],[,[,[,]]] -- dump I/O memory as text\n"
" dumpo ,[:],[,[,[,]]] -- dump opcodes memory as text\n"
" strdump ,[:],[,] -- dump ASCII strings from memory\n"
+ " strdump ,:.{m|s},[,] -- dump ASCII strings from memory region or share\n"
" strdumpd ,[:],[,] -- dump ASCII strings from data memory\n"
" strdumpi ,[:],[,] -- dump ASCII strings from I/O memory\n"
" strdumpo ,[:],[,