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/atm.cpp b/src/mame/sinclair/atm.cpp
index 7b37c488aa5..5df94a09d1e 100644
--- a/src/mame/sinclair/atm.cpp
+++ b/src/mame/sinclair/atm.cpp
@@ -95,7 +95,7 @@ void atm_state::atm_port_ff_w(offs_t offset, u8 data)
{
// Must read current ULA value (which is doesn't work now) from the BUS.
// Good enough as non-border case is too complicated and possibly no software uses it.
- u8 pen = get_border_color(m_screen->hpos(), m_screen->vpos());
+ u8 pen = 0x0f & get_border_color(m_screen->hpos(), m_screen->vpos());
m_palette_data[pen] = data;
m_palette->set_pen_color(pen,
(BIT(~data, 1) * 0xaa) | (BIT(~data, 6) * 0x55),
@@ -440,12 +440,12 @@ void atm_state::machine_reset()
m_beta->enable();
m_beta_drive_selected = 0;
+ m_port_fe_data = -1;
m_port_7ffd_data = 0;
m_port_1ffd_data = -1;
m_port_77_data = 0;
m_br3 = 0;
- m_palette_data = { 0xff };
atm_port_77_w(0x4000, 3); // m_port_77_data: CPM=0(on), PEN=0(off), PEN2=1(off); vmode: zx
}
diff --git a/src/mame/sinclair/atm.h b/src/mame/sinclair/atm.h
index e6cbfeaaa2b..c04285a083a 100644
--- a/src/mame/sinclair/atm.h
+++ b/src/mame/sinclair/atm.h
@@ -102,7 +102,7 @@ protected:
bool m_pen2; // palette selector
u8 m_rg = 0b011; // 0:320x200lo, 2:640:200hi, 3:256x192zx, 6:80x25txt
u8 m_br3;
- std::vector m_palette_data;
+ u8 m_palette_data[16];
u8 m_ata_data_latch;
u8 m_beta_drive_selected;
};
diff --git a/src/mame/sinclair/pentevo.cpp b/src/mame/sinclair/pentevo.cpp
index 2a7896255e8..c1ac0017368 100644
--- a/src/mame/sinclair/pentevo.cpp
+++ b/src/mame/sinclair/pentevo.cpp
@@ -194,7 +194,7 @@ void pentevo_state::atm_port_ff_w(offs_t offset, u8 data)
{
if (BIT(m_port_bf_data, 5) && !m_pen2)
{
- u8 pen = get_border_color(m_screen->hpos(), m_screen->vpos());
+ u8 pen = 0x0f & get_border_color(m_screen->hpos(), m_screen->vpos());
m_palette_data[pen] = data;
m_palette->set_pen_color(pen,
(BIT(~data, 1) * 0x88) | (BIT(~data, 6) * 0x44) | (BIT(~offset, 9) * 0x22) | (BIT(~offset, 14) * 0x11),
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);