From 45063c44c03ae8b9341635b8671d18e4efb37fc8 Mon Sep 17 00:00:00 2001 From: Andrei Holub Date: Fri, 27 Dec 2024 09:28:48 -0500 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 -- src/devices/bus/isa/com.cpp | 4 +- src/devices/bus/isa/isa_cards.cpp | 7 +- src/devices/bus/pc_kbd/msnat.cpp | 8 +- src/devices/machine/atastorage.h | 2 +- src/emu/drawgfx.cpp | 8 +- src/emu/drawgfx.h | 7 +- src/mame/sinclair/spec128.cpp | 7 + src/mame/sinclair/spec128.h | 1 + src/mame/sinclair/spec_snqk.cpp | 452 +++++++++++++++++++++++++++++ src/mame/sinclair/spec_snqk.h | 9 + src/mame/sinclair/spectrum.cpp | 4 +- src/mame/sinclair/spectrum.h | 5 +- src/mame/sinclair/sprinter.cpp | 61 +++- src/mame/sinclair/tsconf.cpp | 23 +- src/mame/sinclair/tsconf.h | 2 + src/mame/sinclair/tsconf_m.cpp | 12 +- 25 files changed, 1045 insertions(+), 341 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 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 ab8601406dd..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 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..376eaf658b4 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,sinclair/byte.cpp,sinclair/pentevo.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 0b80859804e..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 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/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 720b6b49d3a..0f4f50dfde3 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 "mda.h" #include "cga.h" @@ -89,10 +90,11 @@ #include "finalchs.h" #include "bblue2.h" #include "opus100pm.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); @@ -146,10 +148,12 @@ 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); +*/ } void pc_isa16_cards(device_slot_interface &device) { +/* // 8-bit device.option_add("mda", ISA8_MDA); device.option_add("cga", ISA8_CGA); @@ -250,4 +254,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/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/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/emu/drawgfx.cpp b/src/emu/drawgfx.cpp index 8a63d71467c..6695a46b908 100644 --- a/src/emu/drawgfx.cpp +++ b/src/emu/drawgfx.cpp @@ -122,7 +122,8 @@ gfx_element::gfx_element(device_palette_interface *palette, const gfx_layout &gl m_layout_is_raw(false), m_layout_planes(0), m_layout_xormask(xormask), - m_layout_charincrement(0) + m_layout_charincrement(0), + m_layout_char_offset(nullptr) { // set the layout set_layout(gl, srcdata); @@ -281,7 +282,6 @@ void gfx_element::set_source_clip(u32 xoffs, u32 width, u32 yoffs, u32 height) m_starty = yoffs; } - //------------------------------------------------- // decode - decode a single character //------------------------------------------------- @@ -301,7 +301,9 @@ void gfx_element::decode(u32 code) plane < m_layout_planes; plane++, planebit >>= 1) { - int planeoffs = code * m_layout_charincrement + m_layout_planeoffset[plane]; + int planeoffs = m_layout_planeoffset[plane] + (m_layout_char_offset == nullptr + ? code * m_layout_charincrement + : m_layout_char_offset(code, m_width, m_height, m_layout_planes, m_layout_charincrement)); // iterate over rows for (int y = 0; y < m_origheight; y++) diff --git a/src/emu/drawgfx.h b/src/emu/drawgfx.h index 4b5be8a4fa3..c96709eb860 100644 --- a/src/emu/drawgfx.h +++ b/src/emu/drawgfx.h @@ -140,7 +140,6 @@ enum GFX_PMASK_8 = 0xff00 }; - /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ @@ -148,6 +147,8 @@ enum class gfx_element { public: + typedef u32 (*layout_char_offset_delegate)(u32, u16, u16, u8, u32); + // construction/destruction #ifdef UNUSED_FUNCTION gfx_element(); @@ -182,6 +183,7 @@ public: void set_colorbase(u16 colorbase) { m_color_base = colorbase; } void set_granularity(u16 granularity) { m_color_granularity = granularity; } void set_source_clip(u32 xoffs, u32 width, u32 yoffs, u32 height); + void set_layout_char_offset_func(layout_char_offset_delegate func) { m_layout_char_offset = func; }; // operations void mark_dirty(u32 code) { if (code < elements()) { m_dirty[code] = 1; m_dirtyseq++; } } @@ -317,6 +319,7 @@ private: std::vector m_layout_planeoffset;// plane offsets std::vector m_layout_xoffset; // X offsets std::vector m_layout_yoffset; // Y offsets + layout_char_offset_delegate m_layout_char_offset = nullptr; // char offset not common calculation }; @@ -550,4 +553,6 @@ protected: virtual void device_start() override {} }; +#define LAYOUT_CHAR_OFFSET_FUNC(_name) u32 _name(u32 code, u16 width, u16 height, u8 planes, u32 charincrement) + #endif // MAME_EMU_DRAWGFX_H diff --git a/src/mame/sinclair/spec128.cpp b/src/mame/sinclair/spec128.cpp index 8895627ffcb..7247d7ac237 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)); diff --git a/src/mame/sinclair/spec128.h b/src/mame/sinclair/spec128.h index 819a7502978..5c6f3ccfada 100644 --- a/src/mame/sinclair/spec128.h +++ b/src/mame/sinclair/spec128.h @@ -33,6 +33,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; 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/spectrum.cpp b/src/mame/sinclair/spectrum.cpp index 25a0b41df8b..9a0cfa3d0a7 100644 --- a/src/mame/sinclair/spectrum.cpp +++ b/src/mame/sinclair/spectrum.cpp @@ -835,7 +835,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 f14ed0fe4e9..efd1eca56c5 100644 --- a/src/mame/sinclair/spectrum.h +++ b/src/mame/sinclair/spectrum.h @@ -90,6 +90,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() { } @@ -207,7 +208,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 733d1c62177..e2f2c7f06e1 100644 --- a/src/mame/sinclair/sprinter.cpp +++ b/src/mame/sinclair/sprinter.cpp @@ -103,6 +103,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; @@ -259,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 +319,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)); @@ -1424,6 +1426,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)); @@ -1467,6 +1470,13 @@ void sprinter_state::machine_start() m_dcp_location = m_ram->pointer() + (0x40 << 14); m_maincpu->space(AS_PROGRAM).specific(m_program); + 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 @@ -1481,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() @@ -1498,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; @@ -1699,13 +1735,25 @@ 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 */ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CAPS SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_CHAR(UCHAR_SHIFT_2) PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("z Z : LN BEEP COPY") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(':') PORT_CODE(KEYCODE_BACKSLASH) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"x X £ EXP INK CLEAR") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(U'£') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("x X $ EXP INK CLEAR") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR('$') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("c C ? LPRINT PAPER CONT") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR('?') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("v V / LLIST FLASH CLS") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR('/') PORT_CODE(KEYCODE_SLASH) PORT_CODE(KEYCODE_SLASH_PAD) @@ -1867,6 +1915,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 @@ -1965,6 +2016,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 ebe7ec88a71..b9fdcf51e55 100644 --- a/src/mame/sinclair/tsconf.cpp +++ b/src/mame/sinclair/tsconf.cpp @@ -58,8 +58,7 @@ TILE_GET_INFO_MEMBER(tsconf_state::get_tile_info_16c) u8 *tile_info_addr = &m_ram->pointer()[(m_regs[T_MAP_PAGE] << 14) + row_offset + col_offset]; u8 hi = tile_info_addr[1]; - u32 /*u16*/ tile = ((u16(hi) & 0x0f) << 8) | tile_info_addr[0]; - tile = tile / tilemap.cols() * 64 * 8 + (tile % tilemap.cols()); // same as: tmp_tile_oversized_to_code() + u16 tile = ((u16(hi) & 0x0f) << 8) | tile_info_addr[0]; u8 pal = (BIT(m_regs[PAL_SEL], 4 + Layer * 2, 2) << 2) | BIT(hi, 4, 2); tileinfo.set(TM_TILES0 + Layer, tile, pal, TILE_FLIPYX(BIT(hi, 6, 2))); tileinfo.category = tile == 0 ? 2 : 1; @@ -137,16 +136,20 @@ static const gfx_layout tsconf_charlayout = static const gfx_layout tsconf_tile_16cpp_layout = { - 8, - 8, - 64 * 64 * 8, + 8, 8, + 64 * 64, 4, {STEP4(0, 1)}, {STEP8(0, 4)}, - {STEP8(0, 256 * 8)}, // Much more tiles when needed. Because tiles are in RAW format but we don't know region properties. - 8 * 4 + {STEP8(0, 256 * 8)} }; +static LAYOUT_CHAR_OFFSET_FUNC(layout_tile_offset) { + u32 col = code % 64; + u32 row = code / 64; + return (width * planes) * (row * height * 8 * 8 + col); +} + static GFXDECODE_START(gfx_tsconf) GFXDECODE_ENTRY("maincpu", 0, tsconf_charlayout, 0xf7, 1) // TM_TS_CHAR : TXT GFXDECODE_ENTRY("maincpu", 0, tsconf_tile_16cpp_layout, 0, 16) // TM_TILES0 : T0 16cpp @@ -162,12 +165,16 @@ void tsconf_state::video_start() m_ts_tilemap[TM_TS_CHAR] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_tile_info_txt)), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); + m_gfxdecode->gfx(TM_TILES0)->set_layout_char_offset_func(layout_tile_offset); m_ts_tilemap[TM_TILES0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_tile_info_16c<0>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_ts_tilemap[TM_TILES0]->set_transparent_pen(0); + m_gfxdecode->gfx(TM_TILES1)->set_layout_char_offset_func(layout_tile_offset); m_ts_tilemap[TM_TILES1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_tile_info_16c<1>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_ts_tilemap[TM_TILES1]->set_transparent_pen(0); + m_gfxdecode->gfx(TM_SPRITES)->set_layout_char_offset_func(layout_tile_offset); + m_frame_irq_timer = timer_alloc(FUNC(tsconf_state::irq_frame), this); m_scanline_irq_timer = timer_alloc(FUNC(tsconf_state::irq_scanline), this); } @@ -326,7 +333,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 37dfe65b808..890327b6569 100644 --- a/src/mame/sinclair/tsconf.h +++ b/src/mame/sinclair/tsconf.h @@ -56,6 +56,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); diff --git a/src/mame/sinclair/tsconf_m.cpp b/src/mame/sinclair/tsconf_m.cpp index 92f9678fd17..0bd8fe6ba51 100644 --- a/src/mame/sinclair/tsconf_m.cpp +++ b/src/mame/sinclair/tsconf_m.cpp @@ -29,11 +29,6 @@ enum v_mode : u8 VM_TXT }; -static constexpr u32 tmp_tile_oversized_to_code(u16 code) -{ - return code / 64 * 64 * 8 + (code % 64); -} - // https://github.com/tslabs/zx-evo/blob/master/pentevo/vdac/vdac1/cpld/top.v static constexpr u8 pwm_to_rgb[32] = { 0, 10, 21, 31, 42, 53, 63, 74, @@ -364,7 +359,7 @@ void tsconf_state::draw_sprites(screen_device &screen_d, bitmap_rgb32 &bitmap, c for (auto spr = m_sprites_cache.rbegin(); spr != m_sprites_cache.rend(); ++spr) { m_gfxdecode->gfx(TM_SPRITES)->prio_transpen(bitmap, cliprect, - tmp_tile_oversized_to_code(spr->code), spr->color, spr->flipx, spr->flipy, spr->destx, spr->desty, + spr->code, spr->color, spr->flipx, spr->flipy, spr->destx, spr->desty, screen_d.priority(), spr->pmask, 0); } @@ -477,6 +472,11 @@ u8 tsconf_state::tsconf_port_xx1f_r(offs_t offset) { : 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) { // LOCK? BIT(data, 5);