From 1826712d68c7d0352f8edd01dc4d869e8b99e345 Mon Sep 17 00:00:00 2001 From: Andrei Holub Date: Fri, 28 Mar 2025 20:08:27 -0400 Subject: [PATCH] WIP: all-in-one --- .github/workflows/bgfxshaders.yml | 44 --- .github/workflows/ci-linux.yml | 76 ----- .github/workflows/ci-macos.yml | 47 --- .github/workflows/ci-windows.yml | 16 +- .github/workflows/docs.yml | 38 --- .github/workflows/hash.yml | 38 --- .github/workflows/language.yml | 29 -- hash/tsconf.xml | 456 ++++++++++++++++++++++++++ hash/tsconf_betadisc_flop.xml | 30 -- scripts/src/bus.lua | 2 + src/devices/bus/isa/com.cpp | 4 +- src/devices/bus/isa/isa_cards.cpp | 8 + src/devices/bus/isa/zxbus_adapter.cpp | 28 ++ src/devices/bus/isa/zxbus_adapter.h | 27 ++ src/devices/bus/pc_kbd/msnat.cpp | 8 +- src/devices/bus/spectrum/nemoide.cpp | 7 +- src/devices/bus/spectrum/neogs.cpp | 8 +- src/devices/bus/spectrum/smuc.cpp | 8 +- src/devices/bus/spectrum/zxbus.cpp | 19 +- src/devices/bus/spectrum/zxbus.h | 14 +- src/devices/machine/atastorage.h | 2 +- src/devices/machine/z80dma.cpp | 23 +- src/devices/machine/z80dma.h | 16 +- src/mame/sinclair/atm.cpp | 8 +- src/mame/sinclair/beta_m.cpp | 37 ++- src/mame/sinclair/beta_m.h | 2 - src/mame/sinclair/chloe.cpp | 15 +- src/mame/sinclair/pentevo.cpp | 31 +- src/mame/sinclair/scorpion.cpp | 44 ++- src/mame/sinclair/spec128.cpp | 34 ++ src/mame/sinclair/spec128.h | 15 +- src/mame/sinclair/spec_snqk.cpp | 452 +++++++++++++++++++++++++ src/mame/sinclair/spec_snqk.h | 9 + src/mame/sinclair/specnext.cpp | 13 +- src/mame/sinclair/specnext_dma.cpp | 25 +- src/mame/sinclair/specnext_dma.h | 4 +- src/mame/sinclair/spectrum.cpp | 4 +- src/mame/sinclair/spectrum.h | 5 +- src/mame/sinclair/sprinter.cpp | 68 +++- src/mame/sinclair/tsconf.cpp | 42 ++- src/mame/sinclair/tsconf.h | 13 +- src/mame/sinclair/tsconf_beta.cpp | 275 ++++++++++++++++ src/mame/sinclair/tsconf_beta.h | 72 ++++ src/mame/sinclair/tsconf_m.cpp | 68 ++-- 44 files changed, 1691 insertions(+), 493 deletions(-) delete mode 100644 .github/workflows/bgfxshaders.yml delete mode 100644 .github/workflows/ci-linux.yml delete mode 100644 .github/workflows/ci-macos.yml delete mode 100644 .github/workflows/docs.yml delete mode 100644 .github/workflows/hash.yml delete mode 100644 .github/workflows/language.yml create mode 100644 hash/tsconf.xml delete mode 100644 hash/tsconf_betadisc_flop.xml create mode 100644 src/devices/bus/isa/zxbus_adapter.cpp create mode 100644 src/devices/bus/isa/zxbus_adapter.h create mode 100644 src/mame/sinclair/tsconf_beta.cpp create mode 100644 src/mame/sinclair/tsconf_beta.h 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 eecc258d3bf..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: - runs-on: ubuntu-latest - 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 - 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 8d537fab236..165ace9e489 100644 --- a/.github/workflows/ci-windows.yml +++ b/.github/workflows/ci-windows.yml @@ -29,18 +29,13 @@ jobs: shell: msys2 {0} strategy: matrix: - compiler: [gcc, clang] + compiler: [gcc] include: - compiler: gcc cc: gcc cxx: g++ subtarget: mame executable: mame - - compiler: clang - cc: clang - cxx: clang++ - subtarget: tiny - executable: mametiny steps: - uses: msys2/setup-msys2@v2 with: @@ -56,15 +51,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 + 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/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 9c4c6e72f97..73113100fa9 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1896,6 +1896,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..00fd353e75a --- /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.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/nemoide.cpp b/src/devices/bus/spectrum/nemoide.cpp index 75c83bc31fe..4aef90df554 100644 --- a/src/devices/bus/spectrum/nemoide.cpp +++ b/src/devices/bus/spectrum/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/neogs.cpp b/src/devices/bus/spectrum/neogs.cpp index 156c2e2895c..32fc939b509 100644 --- a/src/devices/bus/spectrum/neogs.cpp +++ b/src/devices/bus/spectrum/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; @@ -438,7 +438,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)); @@ -466,8 +466,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/smuc.cpp b/src/devices/bus/spectrum/smuc.cpp index d2ac18278a4..f44cb7a6106 100644 --- a/src/devices/bus/spectrum/smuc.cpp +++ b/src/devices/bus/spectrum/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/bus/spectrum/zxbus.cpp b/src/devices/bus/spectrum/zxbus.cpp index ac5e83436dd..67beb56fb37 100644 --- a/src/devices/bus/spectrum/zxbus.cpp +++ b/src/devices/bus/spectrum/zxbus.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.h b/src/devices/bus/spectrum/zxbus.h index ddaa176cf9e..5caa0f023ef 100644 --- a/src/devices/bus/spectrum/zxbus.h +++ b/src/devices/bus/spectrum/zxbus.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/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..d9dbc66876d 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)); @@ -445,10 +449,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++; } /**************************************************************************** @@ -672,7 +675,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 +878,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 +888,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..11466cd197f 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,6 +66,7 @@ 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); @@ -90,7 +97,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 +119,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; @@ -164,8 +172,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/mame/sinclair/atm.cpp b/src/mame/sinclair/atm.cpp index 1a355649658..77d2dd52a93 100644 --- a/src/mame/sinclair/atm.cpp +++ b/src/mame/sinclair/atm.cpp @@ -515,7 +515,7 @@ void atm_state::atm(machine_config &config) output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); m_centronics->set_output_latch(cent_data_out); - config.device_remove("exp"); + //config.device_remove("exp"); } @@ -587,6 +587,12 @@ ROM_START( atmtb2plus ) ROM_SYSTEM_BIOS(3, "v1.37", "Dual eXtra v1.37XT: BIOS v1.07.15, CP/M v2.2, TR-DOS v5.04R") ROMX_LOAD( "atmtb2x37xt.rom", 0x010000, 0x20000, CRC(e5ef44d9) SHA1(3fbb9ace7cb031e7365c19e4f8b67ed366e24064), ROM_BIOS(3)) + ROM_SYSTEM_BIOS(4, "gluk", "Gluk") + ROMX_LOAD( "glukatm.rom", 0x020000, 0x10000, CRC(7a017f0d) SHA1(301d9195ecaeeba31b7a7d6b7c4037b8cc72a240), ROM_BIOS(4)) + ROM_SYSTEM_BIOS(5, "gluk2", "Gluk2") + ROMX_LOAD( "glukatm2.rom", 0x020000, 0x10000, CRC(64cfee77) SHA1(cd180493e6c3ae4b0a0f753f0efff2debd43a329), ROM_BIOS(5)) + + ROM_REGION(0x01000, "keyboard", ROMREGION_ERASEFF) ROM_LOAD( "rf2ve3.rom", 0x0000, 0x0580, CRC(35e0f9ec) SHA1(adcf14758fab8472cfa0167af7e8326c66416416)) // XT Keyboard ROM_LOAD( "rfat710.rom", 0x0600, 0x0680, CRC(03734365) SHA1(6cb6311727fad9bc4ccb18919c3c39b37529b8e6)) // AT Keyboard diff --git a/src/mame/sinclair/beta_m.cpp b/src/mame/sinclair/beta_m.cpp index 05c3bda085d..31df2aec398 100644 --- a/src/mame/sinclair/beta_m.cpp +++ b/src/mame/sinclair/beta_m.cpp @@ -20,6 +20,26 @@ BUGS: #include "formats/trd_dsk.h" +namespace { + +void floppy_formats(format_registration &fr) +{ + fr.add_mfm_containers(); + fr.add_pc_formats(); + fr.add(FLOPPY_TRD_FORMAT); +} + +void beta_disk_floppies(device_slot_interface &device) +{ + device.option_add("525hd", FLOPPY_525_HD); + device.option_add("525qd", FLOPPY_525_QD); + device.option_add("35hd", FLOPPY_35_HD); + device.option_add("35dd", FLOPPY_35_DD); +} + +} // anonymous namespace + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ @@ -205,21 +225,6 @@ void beta_disk_device::motors_control() } } -void beta_disk_device::floppy_formats(format_registration &fr) -{ - fr.add_mfm_containers(); - fr.add_pc_formats(); - fr.add(FLOPPY_TRD_FORMAT); -} - -static void beta_disk_floppies(device_slot_interface &device) -{ - device.option_add("525hd", FLOPPY_525_HD); - device.option_add("525qd", FLOPPY_525_QD); - device.option_add("35hd", FLOPPY_35_HD); - device.option_add("35dd", FLOPPY_35_DD); -} - ROM_START( beta_disk ) ROM_REGION( 0x60000, "beta", 0 ) @@ -312,7 +317,7 @@ void beta_disk_device::device_add_mconfig(machine_config &config) KR1818VG93(config, m_wd179x, 8_MHz_XTAL / 8); m_wd179x->hld_wr_callback().set(FUNC(beta_disk_device::fdc_hld_w)); for (auto &floppy : m_floppy) - FLOPPY_CONNECTOR(config, floppy, beta_disk_floppies, "525qd", beta_disk_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, floppy, beta_disk_floppies, "525qd", floppy_formats).enable_sound(true); } //------------------------------------------------- diff --git a/src/mame/sinclair/beta_m.h b/src/mame/sinclair/beta_m.h index 042e62b3743..1db7e615cf7 100644 --- a/src/mame/sinclair/beta_m.h +++ b/src/mame/sinclair/beta_m.h @@ -59,8 +59,6 @@ private: void motors_control(); u8 m_control; bool m_motor_active; - - static void floppy_formats(format_registration &fr); }; DECLARE_DEVICE_TYPE(BETA_DISK, beta_disk_device) diff --git a/src/mame/sinclair/chloe.cpp b/src/mame/sinclair/chloe.cpp index c8af1e9d9e5..1b7f5f31f06 100644 --- a/src/mame/sinclair/chloe.cpp +++ b/src/mame/sinclair/chloe.cpp @@ -988,11 +988,18 @@ void chloe_state::chloe(machine_config &config) ROM_START(chloe) ROM_REGION(0xc000, "maincpu", ROMREGION_ERASEFF) + ROM_DEFAULT_BIOS("v101b") - // SE/OS 1.0 - ROM_LOAD( "10_boot.rom", 0x0000, 0x4000, CRC(efbfe46e) SHA1(f5a86b56955661f72fa416e7e644de0b3afe6509)) - ROM_LOAD( "10_basic_42.rom", 0x4000, 0x4000, CRC(c6273eaa) SHA1(f09a26c50f5cfe454e4d56c920cdcc62bc4f90cb)) - ROM_LOAD( "10_dos_31.rom", 0x8000, 0x2000, CRC(67dfef09) SHA1(ba9616494071dfe65834d7db657e0d3bcce0b732)) + ROM_SYSTEM_BIOS(0, "v10", "System 1.0") // 05.01.2024 - SE/OS 1.0 + ROMX_LOAD( "10_boot.rom", 0x0000, 0x4000, CRC(efbfe46e) SHA1(f5a86b56955661f72fa416e7e644de0b3afe6509), ROM_BIOS(0)) + ROMX_LOAD( "10_basic_42.rom", 0x4000, 0x4000, CRC(c6273eaa) SHA1(f09a26c50f5cfe454e4d56c920cdcc62bc4f90cb), ROM_BIOS(0)) + ROMX_LOAD( "10_dos_31.rom", 0x8000, 0x2000, CRC(67dfef09) SHA1(ba9616494071dfe65834d7db657e0d3bcce0b732), ROM_BIOS(0)) + + // SE/OS 1.1 + ROM_SYSTEM_BIOS(1, "v101b", "System 1.0.1b") // 05.xx.2024 - SE/OS 1.0.1b + ROMX_LOAD( "101_boot.rom", 0x0000, 0x4000, CRC(26c57f5a) SHA1(6680aaeac288c688f0400080faf07214959d5a1c), ROM_BIOS(1)) + ROMX_LOAD( "101_basic_42.rom", 0x4000, 0x4000, CRC(0f8658ba) SHA1(b6975e66c029165a39a1ee85ebec50c8e7f4ec1e), ROM_BIOS(1)) + ROMX_LOAD( "10_dos_31.rom", 0x8000, 0x2000, CRC(67dfef09) SHA1(ba9616494071dfe65834d7db657e0d3bcce0b732), ROM_BIOS(1)) ROM_END } // Anonymous namespace diff --git a/src/mame/sinclair/pentevo.cpp b/src/mame/sinclair/pentevo.cpp index c1ac0017368..02317273416 100644 --- a/src/mame/sinclair/pentevo.cpp +++ b/src/mame/sinclair/pentevo.cpp @@ -158,7 +158,7 @@ void pentevo_state::atm_update_io() { if (BIT(m_port_bf_data, 0) || is_dos_active()) { - m_io_view.select(0); + m_io_view.select(1); if (m_beta_drive_selected && m_beta_drive_virtual == m_beta_drive_selected) m_io_dos_view.disable(); else @@ -168,7 +168,7 @@ void pentevo_state::atm_update_io() } else { - m_io_view.disable(); + m_io_view.select(0); if (BIT(m_port_eff7_data, 7)) m_glukrs->enable(); else @@ -623,28 +623,32 @@ void pentevo_state::pentevo_io(address_map &map) map(0xffdf, 0xffdf).lr8(NAME([this]() -> u8 { return ~m_io_mouse[1]->read(); })); map(0x001f, 0x001f).mirror(0xff00).lr8(NAME([]() -> u8 { return 0x00; })); // TODO Kepmston Joystick - // PORTS: Shadow map(0x0000, 0xffff).view(m_io_view); - m_io_view[0](0x0000, 0xffff).view(m_io_dos_view); + m_io_view[0]; + + // PORTS: Shadow + m_io_view[1](0x0000, 0xffff).view(m_io_dos_view); m_io_dos_view[0](0x001f, 0x001f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w)); m_io_dos_view[0](0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w)); m_io_dos_view[0](0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w)); m_io_dos_view[0](0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w)); m_io_dos_view[0](0x00ff, 0x00ff).select(0xff00).r(m_beta, FUNC(beta_disk_device::state_r)); - m_io_view[0](0x00ff, 0x00ff).select(0xff00).w(FUNC(pentevo_state::atm_port_ff_w)); - m_io_view[0](0x0077, 0x0077).select(0xff00).lr8(NAME([]() { return 0xff; })).w(FUNC(pentevo_state::atm_port_77_w)); - m_io_view[0](0x3ff7, 0x3ff7).select(0xc000).w(FUNC(pentevo_state::atm_port_f7_w)); // ATM - m_io_view[0](0x37f7, 0x37f7).select(0xc000).w(FUNC(pentevo_state::pentevo_port_7f7_w)); // PENTEVO - m_io_view[0](0x3bf7, 0x3bf7).select(0xc000).w(FUNC(pentevo_state::pentevo_port_bf7_w)); // RO + m_io_view[1](0x00ff, 0x00ff).select(0xff00).w(FUNC(pentevo_state::atm_port_ff_w)); + m_io_view[1](0x0077, 0x0077).select(0xff00).lr8(NAME([]() { return 0xff; })).w(FUNC(pentevo_state::atm_port_77_w)); + m_io_view[1](0x3ff7, 0x3ff7).select(0xc000).w(FUNC(pentevo_state::atm_port_f7_w)); // ATM + m_io_view[1](0x37f7, 0x37f7).select(0xc000).w(FUNC(pentevo_state::pentevo_port_7f7_w)); // PENTEVO + m_io_view[1](0x3bf7, 0x3bf7).select(0xc000).w(FUNC(pentevo_state::pentevo_port_bf7_w)); // RO // SPI - m_io_view[0](0x0057, 0x0057).select(0xff00) + m_io_view[1](0x0057, 0x0057).select(0xff00) .lw8(NAME([this](offs_t offset, u8 data) { if (BIT(offset, 15)) spi_port_77_w(offset, data); else spi_port_57_w(offset, data); })); // Gluk - m_io_view[0](0xdef7, 0xdef7).lw8(NAME([this](offs_t offset, u8 data) { m_glukrs->address_w(data); } )); - m_io_view[0](0xbef7, 0xbef7).rw(FUNC(pentevo_state::gluk_data_r), FUNC(pentevo_state::gluk_data_w)); + m_io_view[1](0xdef7, 0xdef7).lw8(NAME([this](offs_t offset, u8 data) { m_glukrs->address_w(data); } )); + m_io_view[1](0xbef7, 0xbef7).rw(FUNC(pentevo_state::gluk_data_r), FUNC(pentevo_state::gluk_data_w)); + + subdevice("zxbus")->set_io_space(m_io_view[0], m_io_view[1]); } void pentevo_state::init_mem_write() @@ -786,8 +790,7 @@ void pentevo_state::pentevo(machine_config &config) AT_KEYB(config, m_keyboard, pc_keyboard_device::KEYBOARD_TYPE::AT, 3); zxbus_device &zxbus(ZXBUS(config, "zxbus", 0)); - zxbus.set_iospace("maincpu", AS_IO); - ZXBUS_SLOT(config, "zxbus1", 0, "zxbus", zxbus_cards, nullptr); + ZXBUS_SLOT(config, "zxbus1", 0, zxbus, zxbus_cards, nullptr); } diff --git a/src/mame/sinclair/scorpion.cpp b/src/mame/sinclair/scorpion.cpp index 901f420beb1..bfc50a73efe 100644 --- a/src/mame/sinclair/scorpion.cpp +++ b/src/mame/sinclair/scorpion.cpp @@ -242,10 +242,7 @@ void scorpion_state::update_io(bool dos_enable) scorpion_update_memory(); - if (dos()) - m_io_shadow_view.select(0); - else - m_io_shadow_view.disable(); + m_io_shadow_view.select(dos() ? 1 : 0); } u8 scorpion_state::port_ff_r() @@ -336,10 +333,7 @@ void scorpion_state::scorpion_mem(address_map &map) void scorpion_state::scorpion_io(address_map &map) { map.unmap_value_high(); - map(0x0022, 0x0022).select(0xffdc) // FE | xxxxxxxxxx1xxx10 - .rw(FUNC(scorpion_state::spectrum_ula_r), FUNC(scorpion_state::spectrum_ula_w)); - map(0x0023, 0x0023).mirror(0xffdc) // FF | xxxxxxxxxx1xxx11 - .r(FUNC(scorpion_state::port_ff_r)); + map(0x0021, 0x0021).mirror(0x3fdc) // 1FFD | 00xxxxxxxx1xxx01 .w(FUNC(scorpion_state::port_1ffd_w)); map(0x4021, 0x4021).mirror(0x3fdc) // 7FFD | 01xxxxxxxx1xxx01 @@ -350,23 +344,28 @@ void scorpion_state::scorpion_io(address_map &map) map(0xe021, 0xe021).mirror(0x1fdc) // FFFD | 111xxxxxxx1xxx01 .lr8(NAME([this]() { return m_ay[m_ay_selected]->data_r(); })).w(FUNC(scorpion_state::ay_address_w)); - // Mouse - map(0xfadf, 0xfadf).lr8(NAME([this]() -> u8 { return 0x80 | (m_io_mouse[2]->read() & 0x07); })); - map(0xfbdf, 0xfbdf).lr8(NAME([this]() -> u8 { return m_io_mouse[0]->read(); })); - map(0xffdf, 0xffdf).lr8(NAME([this]() -> u8 { return ~m_io_mouse[1]->read(); })); - map(0x0003, 0x0003) // 1F | xxxxxxxx0x0xxx11 + map(0x0000, 0xffff).view(m_io_shadow_view); + + // !Shadow + m_io_shadow_view[0](0x0022, 0x0022).select(0xffdc) // FE | xxxxxxxxxx1xxx10 + .rw(FUNC(scorpion_state::spectrum_ula_r), FUNC(scorpion_state::spectrum_ula_w)); + m_io_shadow_view[0](0x0023, 0x0023).mirror(0xffdc) // FF | xxxxxxxxxx1xxx11 + .r(FUNC(scorpion_state::port_ff_r)); + m_io_shadow_view[0](0xfadf, 0xfadf).lr8(NAME([this]() -> u8 { return 0x80 | (m_io_mouse[2]->read() & 0x07); })); + m_io_shadow_view[0](0xfbdf, 0xfbdf).lr8(NAME([this]() -> u8 { return m_io_mouse[0]->read(); })); + m_io_shadow_view[0](0xffdf, 0xffdf).lr8(NAME([this]() -> u8 { return ~m_io_mouse[1]->read(); })); + m_io_shadow_view[0](0x0003, 0x0003) // 1F | xxxxxxxx0x0xxx11 .select(0xff5c).lr8(NAME([this]() -> u8 { return (m_beta->state_r() & 0xc0) | 0x00; })); // TODO Kepmston Joystick // Shadow // DOS + xxxxxxxx0nnxxx11 - map(0x0000, 0xffff).view(m_io_shadow_view); - m_io_shadow_view[0](0x0003, 0x0003).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w)); - m_io_shadow_view[0](0x0023, 0x0023).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w)); - m_io_shadow_view[0](0x0043, 0x0043).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w)); - m_io_shadow_view[0](0x0063, 0x0063).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w)); - m_io_shadow_view[0](0x00e3, 0x00e3).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w)); + m_io_shadow_view[1](0x0003, 0x0003).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w)); + m_io_shadow_view[1](0x0023, 0x0023).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w)); + m_io_shadow_view[1](0x0043, 0x0043).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w)); + m_io_shadow_view[1](0x0063, 0x0063).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w)); + m_io_shadow_view[1](0x00e3, 0x00e3).mirror(0xff1c).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w)); - subdevice("zxbus")->install_shadow_io(m_io_shadow_view[0]); + subdevice("zxbus")->set_io_space(m_io_shadow_view[0], m_io_shadow_view[1]); } void scorpion_state::scorpion_switch(address_map &map) @@ -528,9 +527,8 @@ void scorpion_state::scorpion(machine_config &config) config.device_remove("exp"); zxbus_device &zxbus(ZXBUS(config, "zxbus", 0)); - zxbus.set_iospace("maincpu", AS_IO); - ZXBUS_SLOT(config, "zxbus:1", 0, "zxbus", zxbus_gmx_cards, nullptr); - ZXBUS_SLOT(config, "zxbus:2", 0, "zxbus", zxbus_gmx_cards, nullptr); + ZXBUS_SLOT(config, "zxbus:1", 0, zxbus, zxbus_gmx_cards, nullptr); + ZXBUS_SLOT(config, "zxbus:2", 0, zxbus, zxbus_gmx_cards, nullptr); } void scorpion_state::profi(machine_config &config) diff --git a/src/mame/sinclair/spec128.cpp b/src/mame/sinclair/spec128.cpp index c6a1c4353d2..ff307348390 100644 --- a/src/mame/sinclair/spec128.cpp +++ b/src/mame/sinclair/spec128.cpp @@ -238,6 +238,13 @@ void spectrum_128_state::spectrum_128_port_7ffd_w(offs_t offset, uint8_t data) m_exp->iorq_w(offset | 1, data); } +void spectrum_128_state::bank3_set_page(u8 page) +{ + m_port_7ffd_data &= 0xf8; + m_port_7ffd_data |= page & 0x07; + spectrum_128_update_memory(); +} + void spectrum_128_state::spectrum_128_update_memory() { m_bank_rom[0]->set_entry(BIT(m_port_7ffd_data, 4)); @@ -344,6 +351,15 @@ INPUT_PORTS_END INPUT_PORTS_START( spec_plus ) PORT_INCLUDE( spec128 ) PORT_INCLUDE( spec_plus_joys ) + + PORT_START("MOD_DMA") + PORT_CONFNAME( 0x03, 0x00, "DMA") + PORT_CONFSETTING( 0x00, DEF_STR( No )) + PORT_CONFSETTING( 0x01, "UA858D") + PORT_CONFSETTING( 0x03, "Zilog") + PORT_CONFNAME( 0x04, 0x00, "DMA Port") PORT_CONDITION("MOD_DMA", 0x01, EQUALS, 0x01) + PORT_CONFSETTING( 0x00, "11: MB02+") + PORT_CONFSETTING( 0x04, "107: DATAGEAR") INPUT_PORTS_END void spectrum_128_state::machine_start() @@ -374,6 +390,15 @@ void spectrum_128_state::machine_reset() // set initial ram config m_port_7ffd_data = 0; spectrum_128_update_memory(); + + const u8 mod_dma = m_mod_dma.read_safe(0); + if (mod_dma & 1) + { + m_dma->set_dma_mode(mod_dma & 2 ? z80dma_device::dma_mode::ZILOG : z80dma_device::dma_mode::UA858D); + + const u8 port = mod_dma & 4 ? 0x6b : 0x0b; + m_maincpu->space(AS_IO).install_readwrite_handler(port, port, 0, 0xff00, 0, read8smo_delegate(*m_dma, FUNC(z80dma_device::read)), write8smo_delegate(*m_dma, FUNC(z80dma_device::write))); + } } bool spectrum_128_state::is_vram_write(offs_t offset) { @@ -419,9 +444,18 @@ void spectrum_128_state::spectrum_128(machine_config &config) m_maincpu->set_m1_map(&spectrum_128_state::spectrum_128_fetch); m_maincpu->set_vblank_int("screen", FUNC(spectrum_128_state::spec_interrupt)); m_maincpu->nomreq_cb().set(FUNC(spectrum_128_state::spectrum_nomreq)); + m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w)); config.set_maximum_quantum(attotime::from_hz(60)); + Z80DMA(config, m_dma, X1_128_SINCLAIR / 10); + m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ); + m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_dma->in_mreq_callback().set([this](offs_t offset) { return m_program.read_byte(offset); }); + m_dma->out_mreq_callback().set([this](offs_t offset, u8 data) { m_program.write_byte(offset, data); }); + m_dma->in_iorq_callback().set([this](offs_t offset) { return m_io.read_byte(offset); }); + m_dma->out_iorq_callback().set([this](offs_t offset, u8 data) { m_io.write_byte(offset, data); }); + // video hardware rectangle visarea = { get_screen_area().left() - SPEC_LEFT_BORDER, get_screen_area().right() + SPEC_RIGHT_BORDER, get_screen_area().top() - SPEC_TOP_BORDER, get_screen_area().bottom() + SPEC_BOTTOM_BORDER }; diff --git a/src/mame/sinclair/spec128.h b/src/mame/sinclair/spec128.h index 1422c3d74db..635b61a9412 100644 --- a/src/mame/sinclair/spec128.h +++ b/src/mame/sinclair/spec128.h @@ -13,14 +13,18 @@ #include "spectrum.h" +#include "machine/z80dma.h" + class spectrum_128_state : public spectrum_state { public: spectrum_128_state(const machine_config &mconfig, device_type type, const char *tag) : - spectrum_state(mconfig, type, tag), - m_bank_rom(*this, "bank_rom%u", 0U), - m_bank_ram(*this, "bank_ram%u", 0U) + spectrum_state(mconfig, type, tag) + , m_bank_rom(*this, "bank_rom%u", 0U) + , m_bank_ram(*this, "bank_ram%u", 0U) + , m_dma(*this, "dma_ext") + , m_mod_dma(*this, "MOD_DMA") { } void spectrum_128(machine_config &config); @@ -35,6 +39,7 @@ protected: virtual void machine_start() override ATTR_COLD; virtual void machine_reset() override ATTR_COLD; + virtual void bank3_set_page(u8 page) override; virtual void spectrum_128_update_memory() override; virtual rectangle get_screen_area() override; @@ -57,6 +62,10 @@ private: void spectrum_128_io(address_map &map) ATTR_COLD; void spectrum_128_mem(address_map &map) ATTR_COLD; void spectrum_128_fetch(address_map &map) ATTR_COLD; + + optional_device m_dma; + + optional_ioport m_mod_dma; }; #define X1_128_AMSTRAD 35'469'000 // Main clock (Amstrad 128K model, +2A?) diff --git a/src/mame/sinclair/spec_snqk.cpp b/src/mame/sinclair/spec_snqk.cpp index 93db167cb22..6a6b69708c5 100644 --- a/src/mame/sinclair/spec_snqk.cpp +++ b/src/mame/sinclair/spec_snqk.cpp @@ -206,6 +206,15 @@ SNAPSHOT_LOAD_MEMBER(spectrum_state::snapshot_cb) setup_frz(&snapshot_data[0], snapshot_size); } + else if (image.is_filetype("spg")) + { + if (snapshot_data[32] != 'S' || snapshot_data[33] != 'p' || snapshot_data[34] != 'e' || snapshot_data[35] != 'c' + || snapshot_data[36] != 't' || snapshot_data[37] != 'r' || snapshot_data[38] != 'u' || snapshot_data[39] != 'm' + || snapshot_data[40] != 'P' || snapshot_data[41] != 'r' ||snapshot_data[42] != 'o' || snapshot_data[43] != 'g') + return std::make_pair(image_error::INVALIDIMAGE, "Invalid .SPG file header."); + + setup_spg(&snapshot_data[0], snapshot_size); + } else { setup_z80(&snapshot_data[0], snapshot_size); @@ -2396,6 +2405,449 @@ void spectrum_state::setup_z80(const uint8_t *snapdata, uint32_t snapsize) } } +void spectrum_state::hrust_decompress_block(address_space &space, const u8 *source, u16 dest, u16 size) +{ + class bb_stream + { + private: + const u8 *m_base; + const u8 *m_read; + int m_offset; + int m_length; + bool m_eof; + u16 m_buffer; + + public: + bb_stream(const u8 *src, int src_length) + { + m_base = m_read = src; + + m_length = src_length; + m_offset = 0; + m_eof = false; + + m_buffer = get_byte(); + m_buffer += get_byte() << 8; + } + + u8 get_byte() + { + m_eof |= ((m_read - m_base) == m_length); + return m_eof ? 0 : *m_read++; + } + + u8 get_bit() + { + u8 bit = BIT(m_buffer, 15 - m_offset); + if (m_offset == 15) + { + m_buffer = get_byte(); + m_buffer += get_byte() << 8; + } + m_offset = (m_offset + 1) & 0xf; + + return bit; + } + + u8 get_bits(u8 n) + { + u8 r = 0; + do + { + r = (r << 1) + get_bit(); + } while (--n); + + return r; + } + + bool overflow() { return m_eof; } + }; + + constexpr u8 mask[] = { 0, 0, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0 }; + u8 no_bits = 2; + bb_stream bitbuf(source, size); + + space.write_byte(dest++, bitbuf.get_byte()); + + while (!bitbuf.overflow()) + { + while (bitbuf.get_bit()) + { + space.write_byte(dest++, bitbuf.get_byte()); + } + + u16 len = 0; + u8 bb; + do + { + bb = bitbuf.get_bits(2); + len += bb; + + } while (bb == 0x03 && len != 0x0f); + + s16 offset = 0; + if (len == 0) + { + offset = 0xfff8 + bitbuf.get_bits(3); + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + continue; + } + else if (len == 1) + { + const u8 code = bitbuf.get_bits(2); + if (code == 0 || code == 1) + { + offset = bitbuf.get_byte(); + offset += (code ? 0xfe : 0xfd) << 8; + } + else if (code == 2) + { + u8 b = bitbuf.get_byte(); + if (b >= 0xe0) + { + b <<= 1; + ++b; // rlca + b ^= 2; // xor c + + if (b == 0xff) + { + ++no_bits; + continue; + } + + offset = 0xff00 + b - 0x0f; + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + space.write_byte(dest++, bitbuf.get_byte()); + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + continue; + } + offset = 0xff00 + b; + } + else if (code == 3) + { + offset = 0xffe0 + bitbuf.get_bits(5); + } + + for (auto i = 0; i < 2; ++i) + { + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + } + continue; + } + else if (len == 3) + { + if (bitbuf.get_bit()) + { + offset = 0xfff0 + bitbuf.get_bits(4); + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + space.write_byte(dest++, bitbuf.get_byte()); + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + continue; + } + + if (bitbuf.get_bit()) + { + u8 bytes_no = 6 + bitbuf.get_bits(4); + for (u8 i = 0; i < (bytes_no << 1); ++i) + space.write_byte(dest++, bitbuf.get_byte()); + continue; + } + + len = bitbuf.get_bits(7); + if (len == 0x0f) + { + break; // EOF + } + if (len < 0x0f) + { + len = (len << 8) + bitbuf.get_byte(); + } + } + + if (len == 2) + { + ++len; + } + + + const u8 code = bitbuf.get_bits(2); + if (code == 0) + { + offset = 0xfe00 + bitbuf.get_byte(); + } + else if (code == 1) + { + u8 b = bitbuf.get_byte(); + + if (b >= 0xe0) + { + if (len > 3) + { + // logerror + break; + } + + b <<= 1; + ++b; // rlca + b ^= 3; // xor c + + offset = 0xff00 + b - 0x0f; + + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + space.write_byte(dest++, bitbuf.get_byte()); + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + continue; + } + offset = 0xff00 + b; + } + else if (code == 2) + { + offset = 0xffe0 + bitbuf.get_bits(5); + } + else if (code == 3) + { + offset = (mask[no_bits] + bitbuf.get_bits(no_bits)) << 8; + offset += bitbuf.get_byte(); + } + + for (u16 i = 0; i < len; ++i) + { + space.write_byte(dest, space.read_byte(dest + offset)); + ++dest; + } + } +} + +void spectrum_state::mlz_decompress_block(address_space &space, const u8 *source, u16 dest, u16 size) +{ + class de_mlz + { + private: + address_space &m_space; + const u8 *m_src; + u16 m_to; + u8 m_buffer; + int m_buffer_size; + + public: + de_mlz(address_space &space, const u8 *src, u16 dst) : m_space(space) + { + m_src = src; + m_to = dst; + } + + void init_bitstream() + { + m_buffer = get_byte(); + m_buffer_size = 8; + } + + u8 get_byte() + { + return *m_src++; + } + + void put_byte(u8 val) + { + m_space.write_byte(m_to++, val); + } + + void repeat(u32 disp, int num) + { + for (int i = 0; i < num; i++) + { + u8 val = m_space.read_byte(m_to - disp); + put_byte(val); + } + } + + // gets specified number of bits from bitstream + // returns them LSB-aligned + u32 get_bits(int count) + { + u32 bits = 0; + while (count--) + { + if (m_buffer_size--) + { + bits <<= 1; + bits |= 1 & (m_buffer >> 7); + m_buffer <<= 1; + } + else + { + init_bitstream(); + count++; // repeat loop once more + } + } + + return bits; + } + + int get_bigdisp() + { + u32 bits; + + // inter displacement + if (get_bits(1)) + { + bits = get_bits(4); + return 0x1100 - (bits << 8) - get_byte(); + } + + // shorter displacement + else + return 256 - get_byte(); + } + }; + + de_mlz s(space, source, dest); + u32 done = 0; + int i; + + // get first byte of packed file and write to output + s.put_byte(s.get_byte()); + + // second byte goes to bitstream + s.init_bitstream(); + + // actual depacking loop! + do + { + // get 1st bit - either OUTBYTE or beginning of LZ code + // OUTBYTE + if (s.get_bits(1)) + s.put_byte(s.get_byte()); + + // LZ code + else + { + switch (s.get_bits(2)) + { + case 0: // 000 + s.repeat(8 - s.get_bits(3), 1); + break; + + case 1: // 001 + s.repeat(256 - s.get_byte(), 2); + break; + + case 2: // 010 + s.repeat(s.get_bigdisp(), 3); + break; + + case 3: // 011 + // extract num of length bits + for (i = 1; !s.get_bits(1); i++) + ; + + // check for exit code + if (i == 9) + { + done = 1; + } + else if (i <= 7) + { + // get length bits itself + int bits = s.get_bits(i); + s.repeat(s.get_bigdisp(), 2 + (1 << i) + bits); + } + break; + } + } + } while (!done); +} + +/* + Load a .SPG (Spectrum Prog) file. + + v1.1: https://raw.githubusercontent.com/tslabs/zx-evo/master/pentevo/docs/Formats/SPGv1_1.txt + v1.0: https://raw.githubusercontent.com/tslabs/zx-evo/master/pentevo/docs/Formats/SPGv1_0.txt + v0.2 https://raw.githubusercontent.com/tslabs/zx-evo/master/pentevo/docs/Formats/SPGv0_2.txt +*/ +void spectrum_state::setup_spg(const u8 *snapdata, u32 snapsize) +{ + u16 data; + address_space &space = m_maincpu->space(AS_PROGRAM); + + data = snapdata[SPG_OFFSET + 0x2c]; + if (BIT(data, 4, 4) != 1 || BIT(data, 0, 4) != 0) // just v1.0 for now + { + logerror("Can't load .SPG file v%d.%d\n", BIT(data, 4, 4), BIT(data, 0, 4)); + return; + } + + m_maincpu->set_state_int(Z80_IY, 0x5c3a); + m_maincpu->set_state_int(Z80_HL2, 0x2758); + m_maincpu->set_state_int(Z80_I, 0x3f); + m_maincpu->set_state_int(Z80_IM, 1); + m_port_7ffd_data = 16; + + data = (snapdata[SPG_OFFSET + 0x31] << 8) | snapdata[SPG_OFFSET + 0x30]; + if (data < 0x4000) + { + logerror("PC(%04x) < 0x4000 is not allowed\n", data); + } + m_maincpu->set_state_int(Z80_PC, data); + + data = (snapdata[SPG_OFFSET + 0x33] << 8) | snapdata[SPG_OFFSET + 0x32]; + m_maincpu->set_state_int(Z80_SP, data); + + const u8 page3 = snapdata[SPG_OFFSET + 0x34]; + + data = snapdata[SPG_OFFSET + 0x35]; + m_maincpu->set_state_int(Z80_IFF1, BIT(data, 2)); + + offs_t data_offset = SPG_DATA; + for (auto b = 0; b < 0x100; b++) + { + data = snapdata[SPG_BLOCK_INFO(b) + 0]; + const u16 offs = BIT(data, 0, 5) * 512; + const bool is_last = BIT(data, 7); + + data = snapdata[SPG_BLOCK_INFO(b) + 1]; + const u16 size = (BIT(data, 0, 5) + 1) * 512; + const u8 compression = BIT(data, 6, 2); + + data = snapdata[SPG_BLOCK_INFO(b) + 2]; + bank3_set_page(data); + + switch (compression) + { + case 0x00: + for (auto i = 0; i < size; i++) + space.write_byte(0xc000 + offs + i, snapdata[data_offset + i]); + break; + + case 0x01: + mlz_decompress_block(space, &snapdata[data_offset], 0xc000 + offs, size); + break; + + case 0x02: + hrust_decompress_block(space, &snapdata[data_offset], 0xc000 + offs, size); + break; + + default: + logerror("Unsupported compression: %d\n", compression); + return; + } + + data_offset += size; + if (is_last) + break; + } + + bank3_set_page(page3); +} + QUICKLOAD_LOAD_MEMBER(spectrum_state::quickload_cb) { size_t quickload_size = image.length(); diff --git a/src/mame/sinclair/spec_snqk.h b/src/mame/sinclair/spec_snqk.h index 419820aba0d..587b7e92460 100644 --- a/src/mame/sinclair/spec_snqk.h +++ b/src/mame/sinclair/spec_snqk.h @@ -119,6 +119,15 @@ #define SNX_COMPRESSED 0xff #define SNX_UNCOMPRESSED 0x00 +/***************************************************************************** + * + * .SPG format (used by TS-Conf, BASECONF, Next) + * + ****************************************************************************/ +#define SPG_OFFSET 0 +#define SPG_BLOCK_INFO(_n) (SPG_OFFSET + 0x100 + (3 * _n)) +#define SPG_DATA SPG_BLOCK_INFO(256) + /***************************************************************************** * * .FRZ format (used by CBSpeccy, ZX-Live and ASp) diff --git a/src/mame/sinclair/specnext.cpp b/src/mame/sinclair/specnext.cpp index 9bfd6a11207..5741e704904 100644 --- a/src/mame/sinclair/specnext.cpp +++ b/src/mame/sinclair/specnext.cpp @@ -68,6 +68,7 @@ public: specnext_state(const machine_config &mconfig, device_type type, const char *tag) : spectrum_128_state(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_io_shadow_view(*this, "io_shadow_view") , m_bank_boot_rom(*this, "bootrom") , m_bank_ram(*this, "bank_ram%u", 0U) , m_view0(*this, "mem_view0") @@ -80,7 +81,7 @@ public: , m_view7(*this, "mem_view7") , m_copper(*this, "copper") , m_ctc(*this, "ctc") - , m_dma(*this, "ndma") + , m_dma(*this, "dma") , m_i2cmem(*this, "i2cmem") , m_sdcard(*this, "sdcard") , m_ay(*this, "ay%u", 0U) @@ -287,6 +288,7 @@ private: void port_e7_reg_w(u8 data); memory_access<8, 0, 0, ENDIANNESS_LITTLE>::specific m_next_regs; + memory_view m_io_shadow_view; memory_bank_creator m_bank_boot_rom; memory_bank_array_creator<8> m_bank_ram; memory_view m_view0, m_view1, m_view2, m_view3, m_view4, m_view5, m_view6, m_view7; @@ -2254,7 +2256,7 @@ void specnext_state::nr_1a_ula_clip_y2_w(u8 data) static const z80_daisy_config z80_daisy_chain[] = { - { "ndma" }, + { "dma" }, { "ctc" }, { nullptr } }; @@ -2753,6 +2755,10 @@ void specnext_state::map_io(address_map &map) if (m_nr_08_dac_en) m_dac[3]->data_w(data); })); + + map(0x0000, 0xffff).view(m_io_shadow_view); + subdevice("zxbus")->set_io_space(m_io_shadow_view[0], m_io_shadow_view[1]); + m_io_shadow_view.select(0); } void specnext_state::map_regs(address_map &map) @@ -3489,8 +3495,7 @@ void specnext_state::tbblue(machine_config &config) SPECNEXT_DIVMMC(config, m_divmmc, 0); zxbus_device &zxbus(ZXBUS(config, "zxbus", 0)); - zxbus.set_iospace("maincpu", AS_IO); - ZXBUS_SLOT(config, "zxbus:1", 0, "zxbus", zxbus_cards, nullptr); + ZXBUS_SLOT(config, "zxbus:1", 0, zxbus, zxbus_cards, nullptr); const rectangle scr_full = { SCR_320x256.left() - 16, SCR_320x256.right() + 16, SCR_320x256.top() - 8, SCR_320x256.bottom() + 8 }; m_screen->set_raw(28_MHz_XTAL / 2, CYCLES_HORIZ, CYCLES_VERT, scr_full); diff --git a/src/mame/sinclair/specnext_dma.cpp b/src/mame/sinclair/specnext_dma.cpp index 7fbcae4f9cf..4c2b29a7d85 100644 --- a/src/mame/sinclair/specnext_dma.cpp +++ b/src/mame/sinclair/specnext_dma.cpp @@ -33,33 +33,22 @@ DEFINE_DEVICE_TYPE(SPECNEXT_DMA, specnext_dma_device, "specnext_dma", "Spectrum specnext_dma_device::specnext_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : z80dma_device(mconfig, SPECNEXT_DMA, tag, owner, clock) + : z80dma_device(mconfig, SPECNEXT_DMA, tag, owner, clock, dma_mode::ZILOG) { } void specnext_dma_device::write(u8 data) { - z80dma_device::write(data); - - if (num_follow() == 0) + if (!m_ndma_mode && data == COMMAND_ENABLE_DMA && num_follow() == 0) { - if ((data & 0x83) == 0x83) // WR6 - { - switch (data) - { - case COMMAND_ENABLE_DMA: - m_byte_counter = 0; - break; - default: - break; - } - } + m_byte_counter = 0; } + z80dma_device::write(data); } void specnext_dma_device::do_write() { - if (m_dma_mode) + if (m_ndma_mode) { z80dma_device::do_write(); return; @@ -101,12 +90,12 @@ void specnext_dma_device::device_start() { z80dma_device::device_start(); - save_item(NAME(m_dma_mode)); + save_item(NAME(m_ndma_mode)); } void specnext_dma_device::device_reset() { z80dma_device::device_reset(); - m_dma_mode = 0; + m_ndma_mode = 0; } diff --git a/src/mame/sinclair/specnext_dma.h b/src/mame/sinclair/specnext_dma.h index e1bc1fa19f7..66225b3c456 100644 --- a/src/mame/sinclair/specnext_dma.h +++ b/src/mame/sinclair/specnext_dma.h @@ -12,7 +12,7 @@ class specnext_dma_device : public z80dma_device public: specnext_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - void dma_mode_w(bool dma_mode) { m_dma_mode = dma_mode; } + void dma_mode_w(bool dma_mode) { m_ndma_mode = dma_mode; } virtual void write(u8 data) override; @@ -23,7 +23,7 @@ protected: virtual void do_write() override; private: - bool m_dma_mode; // 0 = zxn dma, 1 = z80 dma + bool m_ndma_mode; // 0 = zxn dma, 1 = z80 dma }; DECLARE_DEVICE_TYPE(SPECNEXT_DMA, specnext_dma_device) diff --git a/src/mame/sinclair/spectrum.cpp b/src/mame/sinclair/spectrum.cpp index cb92826746d..3c91f8e7a70 100644 --- a/src/mame/sinclair/spectrum.cpp +++ b/src/mame/sinclair/spectrum.cpp @@ -775,7 +775,9 @@ void spectrum_state::spectrum_common(machine_config &config) m_exp->fb_r_handler().set(FUNC(spectrum_state::floating_bus_r)); /* devices */ - SNAPSHOT(config, "snapshot", "ach,frz,plusd,prg,sem,sit,sna,snp,snx,sp,z80,zx").set_load_callback(FUNC(spectrum_state::snapshot_cb)); + snapshot_image_device &snapshot(SNAPSHOT(config, "snapshot", "ach,frz,plusd,prg,sem,sit,sna,snp,snx,sp,spg,z80,zx")); + snapshot.set_load_callback(FUNC(spectrum_state::snapshot_cb)); + snapshot.set_interface("spectrum_snapshot"); QUICKLOAD(config, "quickload", "raw,scr", attotime::from_seconds(2)).set_load_callback(FUNC(spectrum_state::quickload_cb)); // The delay prevents the screen from being cleared by the RAM test at boot CASSETTE(config, m_cassette); diff --git a/src/mame/sinclair/spectrum.h b/src/mame/sinclair/spectrum.h index 980d13be694..bf8e3b69b78 100644 --- a/src/mame/sinclair/spectrum.h +++ b/src/mame/sinclair/spectrum.h @@ -91,6 +91,7 @@ protected: virtual void video_start() override ATTR_COLD; // until machine/spec_snqk.cpp gets somehow disentangled + virtual void bank3_set_page(u8 page) { } virtual void plus3_update_memory() { } virtual void spectrum_128_update_memory() { } virtual void ts2068_update_memory() { } @@ -209,7 +210,9 @@ protected: void setup_frz(const uint8_t *snapdata, uint32_t snapsize); void z80_decompress_block(address_space &space, const uint8_t *source, uint16_t dest, uint16_t size); void setup_z80(const uint8_t *snapdata, uint32_t snapsize); - + void hrust_decompress_block(address_space &space, const u8 *source, u16 dest, u16 size); + void mlz_decompress_block(address_space &space, const u8 *source, u16 dest, u16 size); + void setup_spg(const u8 *snapdata, u32 snapsize); // quickload helpers void log_quickload(const char *type, uint32_t start, uint32_t length, uint32_t exec, const char *exec_format); void setup_scr(const uint8_t *quickdata, uint32_t quicksize); diff --git a/src/mame/sinclair/sprinter.cpp b/src/mame/sinclair/sprinter.cpp index a01a35d525b..47d079ba32d 100644 --- a/src/mame/sinclair/sprinter.cpp +++ b/src/mame/sinclair/sprinter.cpp @@ -46,7 +46,6 @@ TODO: #include "bus/pc_kbd/pc_kbdc.h" #include "bus/rs232/hlemouse.h" #include "bus/rs232/rs232.h" -#include "bus/spectrum/zxbus.h" #include "cpu/z80/z84c015.h" #include "machine/ds128x.h" #include "machine/input_merger.h" @@ -80,7 +79,7 @@ public: sprinter_state(const machine_config &mconfig, device_type type, const char *tag) : spectrum_128_state(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_isa(*this, "isa%u", 0U) + , m_isa(*this, "isa8%u", 0U) , m_irqs(*this, "irqs") , m_rtc(*this, "rtc") , m_ata(*this, "ata%u", 1U) @@ -105,6 +104,7 @@ public: void sprinter(machine_config &config); INPUT_CHANGED_MEMBER(turbo_changed); + INPUT_CHANGED_MEMBER(on_nmi); protected: virtual void machine_start() override ATTR_COLD; @@ -260,6 +260,7 @@ private: bool m_turbo; bool m_turbo_hard; bool m_arom16; + bool m_nmi_ena; u8 m_rom_rg; u8 m_pn; u8 m_sc; @@ -317,7 +318,7 @@ void sprinter_state::update_memory() else { const bool cash_on = 0; - const bool nmi_ena = 1; + const bool nmi_ena = m_nmi_ena; const bool sc0 = BIT(m_sc, 0); const bool sc_lc = !(sc0 && m_ram_sys) && !cash_on; const u8 spr_ = BIT(m_sc, 1) ? 0 : ((m_dos << 1) | (BIT(m_pn, 4) || !m_dos)); @@ -1427,6 +1428,7 @@ void sprinter_state::machine_start() save_item(NAME(m_turbo)); save_item(NAME(m_turbo_hard)); save_item(NAME(m_arom16)); + save_item(NAME(m_nmi_ena)); save_item(NAME(m_rom_rg)); save_item(NAME(m_pn)); save_item(NAME(m_sc)); @@ -1468,6 +1470,13 @@ void sprinter_state::machine_start() m_dcp_location = m_ram->pointer() + (0x40 << 14); + for (int addr = 0; addr < m_fastram.bytes(); ++addr) + m_fastram.target()[addr] = machine().rand(); + for (int addr = 0; addr < m_vram.bytes(); ++addr) + m_vram.target()[addr] = machine().rand(); + for (int addr = 0; addr < m_ram->size(); ++addr) + m_ram->pointer()[addr] = machine().rand(); + const u8 port_default[0x40] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Cx - SYS PORTS COPIES 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // Dx - RAM PAGES @@ -1482,6 +1491,31 @@ void sprinter_state::machine_start() m_hold = {0, 0}; // cb m_conf_loading = 1; m_conf = 0; + + int idx = Z84_MCR + 1; + m_maincpu->state_add_divider(-1); + m_maincpu->state_add(idx++, "PG0", m_pages[0]); + m_maincpu->state_add(idx++, "PG1", m_pages[1]); + m_maincpu->state_add(idx++, "PG2", m_pages[2]); + m_maincpu->state_add(idx++, "PG3", m_pages[3]); + m_maincpu->state_add(idx++, "7FFD", m_pn); + m_maincpu->state_add(idx++, "1FFD", m_sc); + + m_maincpu->state_add_divider(-1); + + m_maincpu->state_add(idx++, "DOS OFF", m_dos); + m_maincpu->state_add(idx++, "CNF", m_cnf); + m_maincpu->state_add(idx++, "PORT_Y", m_port_y); + m_maincpu->state_add(idx++, "RGMOD", m_rgmod); + + m_maincpu->state_add_divider(-1); + m_maincpu->state_add(idx++, "ACC MODE", m_acc_dir); + m_maincpu->state_add(idx++, "ACC Buffer", m_rgacc); + m_maincpu->state_add(idx++, "Ext ACC", m_alt_acc); + m_maincpu->state_add(idx++, "ACC Counter", m_acc_cnt); + + m_maincpu->state_add_divider(-1); + m_maincpu->state_add(idx++, "ISA_ADDR_EXT", m_isa_addr_ext); } void sprinter_state::machine_reset() @@ -1499,6 +1533,7 @@ void sprinter_state::machine_reset() m_ram_sys = 0; m_sys_pg = 0; m_arom16 = 0; + m_nmi_ena = 1; // off m_cnf = 0x00; m_pn = 0x00; m_sc = 0x00; @@ -1697,6 +1732,18 @@ INPUT_CHANGED_MEMBER(sprinter_state::turbo_changed) update_cpu(); } +INPUT_CHANGED_MEMBER(sprinter_state::on_nmi) +{ + if ((m_io_nmi->read() & 0x01) && m_nmi_ena) + { + m_nmi_ena = false; + update_memory(); + m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); + machine().debug_break(); + } +} + + INPUT_PORTS_START( sprinter ) /* PORT_NAME = KEY Mode CAPS Mode SYMBOL Mode EXT Mode EXT+Shift Mode BASIC Mode */ PORT_START("IO_LINE0") /* 0xFEFE */ @@ -1865,6 +1912,9 @@ INPUT_PORTS_START( sprinter ) PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON6) PORT_NAME("%p Z") + PORT_START("NMI") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("NMI") PORT_CODE(KEYCODE_F11) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(sprinter_state::on_nmi), 0) + PORT_START("TURBO") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("TURBO") PORT_CODE(KEYCODE_F12) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(sprinter_state::turbo_changed), 0) INPUT_PORTS_END @@ -1897,13 +1947,11 @@ void sprinter_state::sprinter(machine_config &config) ISA8(config, m_isa[0], X_SP / 5); m_isa[0]->set_custom_spaces(); - zxbus_device &zxbus(ZXBUS(config, "zxbus", 0)); - zxbus.set_iospace(m_isa[0], isa8_device::AS_ISA_IO); - ZXBUS_SLOT(config, "zxbus2isa", 0, "zxbus", zxbus_cards, nullptr); + ISA8_SLOT(config, "isa0", 0, m_isa[0], pc_isa8_cards, "zxbus_adapter", false); ISA8(config, m_isa[1], X_SP / 5); m_isa[1]->set_custom_spaces(); - ISA8_SLOT(config, "isa8", 0, m_isa[1], pc_isa8_cards, nullptr, false); + ISA8_SLOT(config, "isa1", 0, m_isa[1], pc_isa8_cards, nullptr, false); m_screen->set_raw(X_SP / 3, SPRINT_WIDTH, SPRINT_HEIGHT, { 0, SPRINT_XVIS - 1, 0, SPRINT_YVIS - 1 }); m_screen->set_screen_update(FUNC(sprinter_state::screen_update)); @@ -1967,6 +2015,12 @@ ROM_START( sprinter ) ROM_SYSTEM_BIOS(4, "v3.04.253", "BIOS v3.04, SETUP v253") // 06.16.2003 ROMX_LOAD( "sp2k-3.04.253.rom", 0x000000, 0x40000, CRC(1729cb5c) SHA1(fb4c9f80651aa87526f141839fb4d6cb86b654c7), ROM_BIOS(4)) + + ROM_SYSTEM_BIOS(5, "v3.05.254", "BIOS v3.05, SETUP v254") // 01.01.2022 + ROMX_LOAD( "sp2k-3.05.254.rom", 0x000000, 0x40000, CRC(fe1c2685) SHA1(10e4e29bdc058cd4380837fb8831ce4f5977f6b8), ROM_BIOS(5)) + + ROM_SYSTEM_BIOS(6, "dev", "BIOS v3.06 beta9") // 24.10.2024 + ROMX_LOAD( "_sprin.bin", 0x000000, 0x40000, CRC(c8e8ca64) SHA1(51757b7953f8260b412286a659647c58426e5283), ROM_BIOS(6)) ROM_END } // Anonymous namespace diff --git a/src/mame/sinclair/tsconf.cpp b/src/mame/sinclair/tsconf.cpp index cc6f12dd4c0..8494f52e0a5 100644 --- a/src/mame/sinclair/tsconf.cpp +++ b/src/mame/sinclair/tsconf.cpp @@ -29,7 +29,6 @@ FAQ-RUS: https://forum.tslabs.info/viewtopic.php?f=35&t=157 TODO: - Ram cache -- VDos ****************************************************************************/ @@ -80,17 +79,20 @@ void tsconf_state::tsconf_mem(address_map &map) } void tsconf_state::tsconf_io(address_map &map) +{ + map(0x0000, 0xffff).lrw8( + NAME([this](offs_t offset) { return m_ioext.read_byte((m_beta->dos_io_r() << 16) | offset); }), + NAME([this](offs_t offset, u8 data) { m_ioext.write_byte((m_beta->dos_io_r() << 16) | offset, data); })); +} + +void tsconf_state::tsconf_ioext(address_map &map) { map.unmap_value_high(); map(0x0000, 0x0000).mirror(0x7ffd).w(FUNC(tsconf_state::tsconf_port_7ffd_w)); - map(0x001f, 0x001f).mirror(0xff00).r(FUNC(tsconf_state::tsconf_port_xx1f_r)).w(m_beta, FUNC(beta_disk_device::command_w)); - map(0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w)); + map(0x001f, 0x001f).mirror(0xff00).r(FUNC(tsconf_state::tsconf_port_xx1f_r)); map(0x0057, 0x0057).mirror(0xff00).rw(FUNC(tsconf_state::tsconf_port_57_zctr_r), FUNC(tsconf_state::tsconf_port_57_zctr_w)); // spi config map(0x0077, 0x0077).mirror(0xff00).rw(FUNC(tsconf_state::tsconf_port_77_zctr_r), FUNC(tsconf_state::tsconf_port_77_zctr_w)); // spi data - map(0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w)); - map(0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w)); map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(tsconf_state::spectrum_ula_r), FUNC(tsconf_state::tsconf_ula_w)); - map(0x00ff, 0x00ff).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w)); map(0x00af, 0x00af).select(0xff00).rw(FUNC(tsconf_state::tsconf_port_xxaf_r), FUNC(tsconf_state::tsconf_port_xxaf_w)); map(0xfadf, 0xfadf).lr8(NAME([this]() -> u8 { return 0x80 | (m_io_mouse[2]->read() & 0x07); })); map(0xfbdf, 0xfbdf).lr8(NAME([this]() -> u8 { return m_io_mouse[0]->read(); })); @@ -101,6 +103,10 @@ void tsconf_state::tsconf_io(address_map &map) map(0x80fd, 0x80fd).mirror(0x3f00).lw8(NAME([this](u8 data) { return m_ay[m_ay_selected]->data_w(data); })); map(0xc0fd, 0xc0fd).mirror(0x3f00).lr8(NAME([this]() { return m_ay[m_ay_selected]->data_r(); })) .w(FUNC(tsconf_state::tsconf_ay_address_w)); + + // IO: Shadow + map(0x0000, 0xffff).view(m_io_shadow_view); + m_io_shadow_view[0](0x0000, 0xffff).m(m_beta, FUNC(tsconf_beta_device::tsconf_beta_io)); } void tsconf_state::tsconf_switch(address_map &map) @@ -177,6 +183,7 @@ void tsconf_state::machine_start() m_bank_ram[0]->configure_entries(0, m_ram->size() / 0x4000, m_ram->pointer(), 0x4000); save_item(NAME(m_int_mask)); + save_item(NAME(m_update_on_m1)); save_pointer(NAME(m_regs), 0x100); save_item(NAME(m_zctl_di)); save_item(NAME(m_zctl_cs)); @@ -187,6 +194,8 @@ void tsconf_state::machine_start() void tsconf_state::machine_reset() { + m_update_on_m1 = false; + m_frame_irq_timer->adjust(attotime::never); m_scanline_irq_timer->adjust(attotime::never); m_int_mask = 0; @@ -218,8 +227,7 @@ void tsconf_state::machine_reset() m_regs[INT_MASK] = 0x01; // xxxxx001 m_regs[CACHE_CONFIG] &= 0xf0; // xxxx0000 - if (m_beta->started()) - m_beta->enable(); + m_beta->fddvirt_w(m_regs[FDD_VIRT] & 0x0f); m_zctl_cs = 1; m_zctl_di = 0xff; @@ -270,9 +278,9 @@ void tsconf_state::tsconf(machine_config &config) config.device_remove("palette"); Z80(config.replace(), m_maincpu, 14_MHz_XTAL / 4); - m_maincpu->set_addrmap(AS_PROGRAM, &tsconf_state::tsconf_mem); - m_maincpu->set_addrmap(AS_IO, &tsconf_state::tsconf_io); - m_maincpu->set_addrmap(AS_OPCODES, &tsconf_state::tsconf_switch); + m_maincpu->set_memory_map(&tsconf_state::tsconf_mem); + m_maincpu->set_io_map(&tsconf_state::tsconf_io); + m_maincpu->set_m1_map(&tsconf_state::tsconf_switch); m_maincpu->set_irq_acknowledge_callback(FUNC(tsconf_state::irq_vector)); m_maincpu->set_vblank_int("screen", FUNC(tsconf_state::tsconf_vblank_interrupt)); @@ -282,9 +290,8 @@ void tsconf_state::tsconf(machine_config &config) m_sdcard->spi_miso_callback().set(FUNC(tsconf_state::tsconf_spi_miso_w)); zxbus_device &zxbus(ZXBUS(config, "zxbus", 0)); - zxbus.set_iospace("maincpu", AS_IO); - ZXBUS_SLOT(config, "zxbus1", 0, "zxbus", zxbus_cards, nullptr); - //ZXBUS_SLOT(config, "zxbus2", 0, "zxbus", zxbus_cards, nullptr); + ZXBUS_SLOT(config, "zxbus1", 0, zxbus, zxbus_cards, nullptr); + //ZXBUS_SLOT(config, "zxbus2", 0, zxbus, zxbus_cards, nullptr); m_ram->set_default_size("4096K"); @@ -298,7 +305,10 @@ void tsconf_state::tsconf(machine_config &config) m_dma->out_sfile_callback().set(FUNC(tsconf_state::sfile_write16)); m_dma->on_ready_callback().set(FUNC(tsconf_state::dma_ready)); - BETA_DISK(config, m_beta, 0); + TSCONF_BETA(config, m_beta, 0); + m_beta->out_dos_callback().set(FUNC(tsconf_state::update_io)); + m_beta->out_vdos_m1_callback().set([this](int state) { m_update_on_m1 = true; }); + SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -328,7 +338,7 @@ void tsconf_state::tsconf(machine_config &config) AT_KEYB(config, m_keyboard, pc_keyboard_device::KEYBOARD_TYPE::AT, 3); SOFTWARE_LIST(config, "betadisc_list_pent").set_original("spectrum_betadisc_flop"); - SOFTWARE_LIST(config, "betadisc_list_tsconf").set_original("tsconf_betadisc_flop"); + SOFTWARE_LIST(config, "tsconf_list").set_original("tsconf"); } ROM_START(tsconf) diff --git a/src/mame/sinclair/tsconf.h b/src/mame/sinclair/tsconf.h index 8810cc6aacf..282715f68d8 100644 --- a/src/mame/sinclair/tsconf.h +++ b/src/mame/sinclair/tsconf.h @@ -13,9 +13,9 @@ #include "spec128.h" #include "glukrs.h" +#include "tsconf_beta.h" #include "tsconfdma.h" -#include "beta_m.h" #include "machine/pckeybrd.h" #include "machine/spi_sdcard.h" #include "sound/ay8910.h" @@ -28,12 +28,13 @@ class tsconf_state : public spectrum_128_state public: tsconf_state(const machine_config &mconfig, device_type type, const char *tag) : spectrum_128_state(mconfig, type, tag) + , m_io_shadow_view(*this, "io_shadow_view") , m_bank0_rom(*this, "bank0_rom") , m_tiles_raw(*this, "tiles%u_raw", 0U, 64U * 64 * 8 * 8, ENDIANNESS_LITTLE) , m_sprites_raw(*this, "sprites_raw", 64U * 64 * 8 * 8, ENDIANNESS_LITTLE) , m_keyboard(*this, "pc_keyboard") , m_io_mouse(*this, "mouse_input%u", 1U) - , m_beta(*this, BETA_DISK_TAG) + , m_beta(*this, "beta") , m_dma(*this, "dma") , m_sdcard(*this, "sdcard") , m_glukrs(*this, "glukrs") @@ -58,6 +59,8 @@ protected: virtual void machine_reset() override ATTR_COLD; virtual void device_post_load() override ATTR_COLD; + virtual void bank3_set_page(u8 page) override; + virtual TIMER_CALLBACK_MEMBER(irq_off) override; TIMER_CALLBACK_MEMBER(irq_frame); TIMER_CALLBACK_MEMBER(irq_scanline); @@ -157,6 +160,7 @@ private: INTERRUPT_GEN_MEMBER(tsconf_vblank_interrupt); IRQ_CALLBACK_MEMBER(irq_vector); u8 m_int_mask; + bool m_update_on_m1; DECLARE_VIDEO_START(tsconf); TILE_GET_INFO_MEMBER(get_tile_info_txt); @@ -190,11 +194,13 @@ private: void tsconf_ay_address_w(u8 data); void tsconf_update_bank0(); + void update_io(int dos); u8 beta_neutral_r(offs_t offset); u8 beta_enable_r(offs_t offset); u8 beta_disable_r(offs_t offset); void tsconf_io(address_map &map) ATTR_COLD; + void tsconf_ioext(address_map &map) ATTR_COLD; void tsconf_mem(address_map &map) ATTR_COLD; void tsconf_switch(address_map &map) ATTR_COLD; @@ -214,6 +220,7 @@ private: std::map m_scanline_delayed_regs_update; u8 m_regs[0x100]; + memory_view m_io_shadow_view; memory_view m_bank0_rom; memory_share_array_creator m_tiles_raw; memory_share_creator m_sprites_raw; @@ -221,7 +228,7 @@ private: required_device m_keyboard; required_ioport_array<3> m_io_mouse; - required_device m_beta; + required_device m_beta; required_device m_dma; required_device m_sdcard; u8 m_zctl_di = 0; diff --git a/src/mame/sinclair/tsconf_beta.cpp b/src/mame/sinclair/tsconf_beta.cpp new file mode 100644 index 00000000000..1d836225cbb --- /dev/null +++ b/src/mame/sinclair/tsconf_beta.cpp @@ -0,0 +1,275 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +/********************************************************************** + Beta TR-DOS with virtual drives +**********************************************************************/ + +#include "emu.h" +#include "tsconf_beta.h" + +#include "formats/trd_dsk.h" + + +namespace { + +void floppy_formats(format_registration &fr) +{ + fr.add_mfm_containers(); + fr.add_pc_formats(); + fr.add(FLOPPY_TRD_FORMAT); +} + +void beta_disk_floppies(device_slot_interface &device) +{ + device.option_add("525hd", FLOPPY_525_HD); + device.option_add("525qd", FLOPPY_525_QD); + device.option_add("35hd", FLOPPY_35_HD); + device.option_add("35dd", FLOPPY_35_DD); +} + +} // anonymous namespace + + +// device type definition +DEFINE_DEVICE_TYPE(TSCONF_BETA, tsconf_beta_device, "tsconf_beta", "Virtual TR-DOS") + +void tsconf_beta_device::tsconf_beta_io(address_map &map) +{ + map(0x001f, 0x001f).mirror(0xff00).rw(FUNC(tsconf_beta_device::status_r), FUNC(tsconf_beta_device::command_w)); + map(0x003f, 0x003f).mirror(0xff00).rw(FUNC(tsconf_beta_device::track_r), FUNC(tsconf_beta_device::track_w)); + map(0x005f, 0x005f).mirror(0xff00).rw(FUNC(tsconf_beta_device::sector_r), FUNC(tsconf_beta_device::sector_w)); + map(0x007f, 0x007f).mirror(0xff00).rw(FUNC(tsconf_beta_device::data_r), FUNC(tsconf_beta_device::data_w)); + map(0x009f, 0x009f).select(0xff60).rw(FUNC(tsconf_beta_device::state_r), FUNC(tsconf_beta_device::param_w)); +} + + +tsconf_beta_device::tsconf_beta_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, TSCONF_BETA, tag, owner, clock) + , m_out_dos_cb(*this) + , m_out_vdos_m1_cb(*this) + , m_wd179x(*this, "wd179x") + , m_floppy(*this, "wd179x:%u", 0U) + , m_floppy_led(*this, "fdd%u_led", 0U) + , m_control(0) + , m_motor_active(false) +{ +} + +bool tsconf_beta_device::pre_vg_in_check() +{ + if (m_dos) + { + if (m_vdos) + { + m_vdos = false; + m_out_dos_cb(dos_io_r()); + return false; + } + else if ((1 << (m_control & 3)) & m_fddvirt) + { + m_out_vdos_m1_cb(1); + return false; + } + } + + return true; +} + +u8 tsconf_beta_device::status_r() +{ + return pre_vg_in_check() ? m_wd179x->status_r() : 0xff; +} + +u8 tsconf_beta_device::track_r() +{ + return pre_vg_in_check() ? m_wd179x->track_r() : 0xff; +} + +u8 tsconf_beta_device::sector_r() +{ + return pre_vg_in_check() ? m_wd179x->sector_r() : 0xff; +} + +u8 tsconf_beta_device::data_r() +{ + return pre_vg_in_check() ? m_wd179x->data_r() : 0xff; +} + +u8 tsconf_beta_device::state_r() +{ + if (pre_vg_in_check()) + { + u8 result = 0x3f; // actually open bus + result |= m_wd179x->drq_r() ? 0x40 : 0; + result |= m_wd179x->intrq_r() ? 0x80 : 0; + return result; + } + else + { + return 0xff; + } +} + +bool tsconf_beta_device::pre_vg_out_check(bool is_port_match = true) +{ + if (m_dos) + { + if (m_vdos) + { + if (is_port_match) + { + m_vdos = false; + m_out_dos_cb(dos_io_r()); + return false; + } + } + else if ((1 << (m_control & 3)) & m_fddvirt) + { + m_vdos = true; + m_out_dos_cb(dos_io_r()); + return false; + } + } + + return true; +} + +void tsconf_beta_device::param_w(offs_t offset, u8 data) +{ + if (pre_vg_out_check((offset & 0x60) != 0x60)) // not through 0xff + { + m_control = data; + floppy_image_device* floppy = m_floppy[data & 3]->get_device(); + m_wd179x->set_floppy(floppy); + + if (!m_vdos) + { + floppy->ss_w(BIT(data, 4) ? 0 : 1); + m_wd179x->dden_w(BIT(data, 6)); + m_wd179x->mr_w(BIT(data, 2)); + + m_wd179x->hlt_w(BIT(data, 3)); + + motors_control(); + } + } +} + +void tsconf_beta_device::command_w(u8 data) +{ + if (pre_vg_out_check()) + { + m_wd179x->cmd_w(data); + } +} + +void tsconf_beta_device::track_w(u8 data) +{ + if (pre_vg_out_check()) + { + m_wd179x->track_w(data); + } +} + +void tsconf_beta_device::sector_w(u8 data) +{ + if (pre_vg_out_check()) + { + m_wd179x->sector_w(data); + } +} + +void tsconf_beta_device::data_w(u8 data) +{ + if (pre_vg_out_check()) + { + m_wd179x->data_w(data); + } +} + +void tsconf_beta_device::turbo_w(int state) +{ + m_wd179x->set_clock_scale(1 << (state & 1)); +} + +void tsconf_beta_device::on_m1_w() +{ + m_vdos = true; + m_out_dos_cb(dos_io_r()); +} + +void tsconf_beta_device::enable_w(bool state) +{ + if ((state && !m_dos) || (!state && m_dos && !m_vdos)) + { + m_dos = state; + m_out_dos_cb(dos_io_r()); + } +} + +void tsconf_beta_device::fddvirt_w(u8 fddvirt) +{ + m_fddvirt = fddvirt & 0x0f; +} + +void tsconf_beta_device::io_forced_w(bool io_forced) +{ + m_io_forced = io_forced; + m_out_dos_cb(dos_io_r()); +} + +void tsconf_beta_device::fdc_hld_w(int state) +{ + m_wd179x->set_force_ready(state); // HLD connected to RDY pin + m_motor_active = state; + motors_control(); +} + +void tsconf_beta_device::motors_control() +{ + for (int i = 0; i < 4; i++) + { + if (m_motor_active && (m_control & 3) == i) + { + m_floppy[i]->get_device()->mon_w(CLEAR_LINE); + m_floppy_led[i] = 1; + } + else + { + m_floppy[i]->get_device()->mon_w(ASSERT_LINE); + m_floppy_led[i] = 0; + } + } +} + +void tsconf_beta_device::device_start() +{ + save_item(NAME(m_control)); + save_item(NAME(m_motor_active)); + save_item(NAME(m_dos)); + save_item(NAME(m_vdos)); + save_item(NAME(m_io_forced)); + save_item(NAME(m_fddvirt)); + + m_floppy_led.resolve(); +} + +void tsconf_beta_device::device_reset() +{ + m_control = 0; + for (int i = 0; i < m_floppy_led.size(); i++) + m_floppy_led[i] = 0; + + m_dos = false; + m_vdos = false; + m_io_forced = false; + m_fddvirt = 0; +} + +void tsconf_beta_device::device_add_mconfig(machine_config &config) +{ + KR1818VG93(config, m_wd179x, 8_MHz_XTAL / 8); + m_wd179x->hld_wr_callback().set(FUNC(tsconf_beta_device::fdc_hld_w)); + for (auto &floppy : m_floppy) + FLOPPY_CONNECTOR(config, floppy, beta_disk_floppies, "525qd", floppy_formats).enable_sound(true); +} diff --git a/src/mame/sinclair/tsconf_beta.h b/src/mame/sinclair/tsconf_beta.h new file mode 100644 index 00000000000..c7eac15cfd4 --- /dev/null +++ b/src/mame/sinclair/tsconf_beta.h @@ -0,0 +1,72 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +#ifndef MAME_SINCLAIR_TSCONF_BETA_H +#define MAME_SINCLAIR_TSCONF_BETA_H + +#pragma once + +#include "imagedev/floppy.h" +#include "machine/wd_fdc.h" + + +class tsconf_beta_device : public device_t +{ +public: + tsconf_beta_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + void tsconf_beta_io(address_map &map) ATTR_COLD; + + auto out_dos_callback() { return m_out_dos_cb.bind(); } + auto out_vdos_m1_callback() { return m_out_vdos_m1_cb.bind(); } + + u8 status_r(); + u8 track_r(); + u8 sector_r(); + u8 data_r(); + u8 state_r(); + + void param_w(offs_t offset, u8 data); + void command_w(u8 data); + void track_w(u8 data); + void sector_w(u8 data); + void data_w(u8 data); + void turbo_w(int state); + + void on_m1_w(); + bool dos_r() { return m_dos; } + bool vdos_r() { return m_vdos; } + bool dos_io_r() { return m_dos || m_io_forced; } + void enable_w(bool state); + void fddvirt_w(u8 fddvirt); + void io_forced_w(bool io_forced); + +protected: + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + devcb_write_line m_out_dos_cb; + devcb_write_line m_out_vdos_m1_cb; + +private: + required_device m_wd179x; + required_device_array m_floppy; + output_finder<4> m_floppy_led; + void fdc_hld_w(int state); + void motors_control(); + u8 m_control; + bool m_motor_active; + + bool m_dos; + bool m_vdos; + bool m_io_forced; + u8 m_fddvirt; + + bool pre_vg_in_check(); + bool pre_vg_out_check(bool is_port_match); +}; + + +DECLARE_DEVICE_TYPE(TSCONF_BETA, tsconf_beta_device) + +#endif // MAME_SINCLAIR_TSCONF_BETA_H diff --git a/src/mame/sinclair/tsconf_m.cpp b/src/mame/sinclair/tsconf_m.cpp index bf1f05ecad9..c7245423821 100644 --- a/src/mame/sinclair/tsconf_m.cpp +++ b/src/mame/sinclair/tsconf_m.cpp @@ -55,13 +55,13 @@ void tsconf_state::tsconf_update_bank0() if (!NW0_MAP) { /* ROM: 0-SYS, 1-DOS, 2-128, 3-48 */ - page0 = m_beta->started() && m_beta->is_active() ? ROM128 : (0x02 | ROM128); - page0 |= (m_regs[PAGE0] & 0xfc); + page0 &= 0xfc; + page0 |= m_beta->dos_r() ? ROM128 : (0x02 | ROM128); } - if (W0_RAM) + if (W0_RAM || m_beta->vdos_r()) { - m_bank_ram[0]->set_entry(page0); + m_bank_ram[0]->set_entry(m_beta->vdos_r() ? 0xff : page0); m_bank0_rom.disable(); } else @@ -71,6 +71,16 @@ void tsconf_state::tsconf_update_bank0() } } +void tsconf_state::update_io(int dos) +{ + if (dos) + m_io_shadow_view.select(0); + else + m_io_shadow_view.disable(); + + tsconf_update_bank0(); +} + void tsconf_state::tsconf_update_video_mode() { rectangle visarea = screen_area[3]; @@ -380,8 +390,10 @@ void tsconf_state::ram_bank_write(u8 bank, offs_t offset, u8 data) } } - if (bank > 0 || (W0_WE && W0_RAM)) + if (bank > 0 || W0_WE) ram_page_write(m_regs[PAGE0 + bank], offset, data); + else if (!bank && m_beta->vdos_r()) + ram_page_write(0xff, offset, data); } static int tiles_offset_to_raw(int t_offset) @@ -477,9 +489,12 @@ void tsconf_state::sfile_write16(offs_t offset, u16 data) } u8 tsconf_state::tsconf_port_xx1f_r(offs_t offset) { - return m_beta->started() && m_beta->is_active() - ? m_beta->status_r() - : 0x00; // TODO kempston read + return 0x00; // TODO kempston read +} + +void tsconf_state::bank3_set_page(u8 page) +{ + tsconf_port_xxaf_w(PAGE3 << 8, page); } void tsconf_state::tsconf_port_7ffd_w(u8 data) @@ -700,11 +715,15 @@ void tsconf_state::tsconf_port_xxaf_w(offs_t port, u8 data) update_frame_timer(); break; + case FDD_VIRT: + m_beta->io_forced_w(BIT(data, 7)); + m_beta->fddvirt_w(data & 0x0f); + break; + case FMAPS: case TS_CONFIG: case INT_MASK: // TODO - case FDD_VIRT: case CACHE_CONFIG: break; @@ -888,7 +907,7 @@ INTERRUPT_GEN_MEMBER(tsconf_state::tsconf_vblank_interrupt) void tsconf_state::dma_ready(int line) { - if (BIT(m_regs[INT_MASK], 2)) + if (BIT(m_regs[INT_MASK], 2) && !(m_beta->vdos_r() || m_update_on_m1)) { m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); m_int_mask |= 4; @@ -897,7 +916,7 @@ void tsconf_state::dma_ready(int line) TIMER_CALLBACK_MEMBER(tsconf_state::irq_frame) { - if (BIT(m_regs[INT_MASK], 0)) + if (BIT(m_regs[INT_MASK], 0) && !(m_beta->vdos_r() || m_update_on_m1)) { m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); m_irq_off_timer->adjust(attotime::from_ticks(32, m_maincpu->unscaled_clock())); @@ -907,7 +926,7 @@ TIMER_CALLBACK_MEMBER(tsconf_state::irq_frame) TIMER_CALLBACK_MEMBER(tsconf_state::irq_scanline) { - if (BIT(m_regs[INT_MASK], 1)) + if (BIT(m_regs[INT_MASK], 1) && !(m_beta->vdos_r() || m_update_on_m1)) { m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); m_int_mask |= 2; @@ -966,6 +985,11 @@ TIMER_CALLBACK_MEMBER(tsconf_state::irq_scanline) u8 tsconf_state::beta_neutral_r(offs_t offset) { + if (!machine().side_effects_disabled() && m_update_on_m1) + { + m_update_on_m1 = false; + m_beta->on_m1_w(); + } return m_program.read_byte(offset); } @@ -973,13 +997,14 @@ u8 tsconf_state::beta_enable_r(offs_t offset) { if (!machine().side_effects_disabled()) { - if (!W0_RAM && m_bank_rom[0]->entry() == 3) + if (m_update_on_m1) { - if (m_beta->started() && !m_beta->is_active()) - { - m_beta->enable(); - tsconf_update_bank0(); - } + m_update_on_m1 = false; + m_beta->on_m1_w(); + } + if (ROM128 && !NW0_MAP) + { + m_beta->enable_w(1); } } return m_program.read_byte(offset + 0x3d00); @@ -989,11 +1014,12 @@ u8 tsconf_state::beta_disable_r(offs_t offset) { if (!machine().side_effects_disabled()) { - if (m_beta->started() && m_beta->is_active()) + if (m_update_on_m1) { - m_beta->disable(); - tsconf_update_bank0(); + m_update_on_m1 = false; + m_beta->on_m1_w(); } + m_beta->enable_w(0); } return m_program.read_byte(offset + 0x4000); }