From 2a6b67e337b896e793689097b72d980dd770e87b Mon Sep 17 00:00:00 2001 From: Andrei Holub Date: Wed, 12 Nov 2025 19:59:08 -0500 Subject: [PATCH 1/2] sinclair/specnext.cpp: fix line interrupt offset --- src/mame/sinclair/specnext.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mame/sinclair/specnext.cpp b/src/mame/sinclair/specnext.cpp index 9a2811cb952eb..76d310d252a6b 100644 --- a/src/mame/sinclair/specnext.cpp +++ b/src/mame/sinclair/specnext.cpp @@ -10,6 +10,8 @@ tracked through PORT_CONFIG TODO: + * identify ctc channel for INT purpose + * interrupt DMA on INT * improve zxnDMA * contention * internal_port_enable() support @@ -2509,10 +2511,8 @@ void specnext_state::line_irq_adjust() { if (m_nr_22_line_interrupt_en && (m_nr_23_line_interrupt <= m_video_timings.max_vc)) { - u16 vtarget = m_nr_23_line_interrupt - ? cvc_to_vpos(m_nr_23_line_interrupt) - : m_video_timings.max_vc; - m_irq_line_timer->adjust(m_screen->time_until_pos(vtarget, m_video_timings.min_hactive << 1)); + u16 vtarget = m_nr_23_line_interrupt ? (m_nr_23_line_interrupt - 1) : m_video_timings.max_vc; + m_irq_line_timer->adjust(m_screen->time_until_pos(cvc_to_vpos(vtarget), m_clip256x192.right())); } else m_irq_line_timer->reset(); From d94ff2f65082a5502983e51ff500ec21898c08f2 Mon Sep 17 00:00:00 2001 From: Andrei Holub Date: Fri, 14 Nov 2025 11:51:31 -0500 Subject: [PATCH 2/2] sinclair/specnext_tiles.cpp: Support global transparent color for tiles mode1 sinclair/spectrum.cpp: Re-enable extra inputs for natural keyboard mapping sinclair/screen_ula.cpp: Fixed alignment optimization --- src/mame/sinclair/screen_ula.cpp | 16 ++++++++-------- src/mame/sinclair/specnext.cpp | 1 + src/mame/sinclair/specnext_tiles.cpp | 28 ++++++++++++++++++++++++++-- src/mame/sinclair/specnext_tiles.h | 3 +++ src/mame/sinclair/spectrum.cpp | 14 +++++++------- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/mame/sinclair/screen_ula.cpp b/src/mame/sinclair/screen_ula.cpp index 772285a26ddce..781213ae953fc 100644 --- a/src/mame/sinclair/screen_ula.cpp +++ b/src/mame/sinclair/screen_ula.cpp @@ -129,14 +129,14 @@ void screen_ula_device::draw_ula(bitmap_rgb32 &bitmap, const rectangle &clip, bo *(prio + 1) |= pcode; } } - } - if (off2) - { - hpos -= 1; - pix -= 1; - prio -= 1; - x2 -= 1; - off2 = false; + if (off2) + { + hpos -= 1; + pix -= 1; + prio -= 1; + x2 -= 1; + off2 = false; + } } x2 %= SCREEN_AREA.width() << 1; if (x2 == 0) diff --git a/src/mame/sinclair/specnext.cpp b/src/mame/sinclair/specnext.cpp index 76d310d252a6b..b6cbdafb8a36a 100644 --- a/src/mame/sinclair/specnext.cpp +++ b/src/mame/sinclair/specnext.cpp @@ -2440,6 +2440,7 @@ void specnext_state::nr_14_global_transparent_rgb_w(u8 data) { m_nr_14_global_transparent_rgb = data; m_ula_scr->set_global_transparent(data); + m_tiles->set_global_transparent(data); m_lores->set_global_transparent(data); m_layer2->set_global_transparent(data); } diff --git a/src/mame/sinclair/specnext_tiles.cpp b/src/mame/sinclair/specnext_tiles.cpp index 2b5a70926d66d..a308c26f6bbaf 100644 --- a/src/mame/sinclair/specnext_tiles.cpp +++ b/src/mame/sinclair/specnext_tiles.cpp @@ -8,6 +8,7 @@ #include "specnext_tiles.h" #include "screen.h" +#include "tilemap.h" static const gfx_layout gfx_8x8x4 = @@ -82,7 +83,20 @@ TILE_GET_INFO_MEMBER(specnext_tiles_device::get_tile_info) tileinfo.category = category; if (BIT(m_control, 3)) // textmode - tileinfo.set(4 | BIT(m_control, 6), code, BIT(attr, 1, 7), 0); + { + const rgb_t gt0 = rgbexpand<3,3,3>((m_global_transparent << 1) | 0, 6, 3, 0); + const rgb_t gt1 = rgbexpand<3,3,3>((m_global_transparent << 1) | 1, 6, 3, 0); + const u8 pal_offset = BIT(attr, 1, 7); + const rgb_t bg = palette().pen(m_tilemap[1]->palette_offset() + (pal_offset << 1)); + const rgb_t fg = palette().pen(m_tilemap[1]->palette_offset() + (pal_offset << 1) + 1); + + u8 group = 0; + if (bg == gt0 || bg == gt1) group |= 2; + if (fg == gt0 || fg == gt1) group |= 1; + + tileinfo.set(4 | BIT(m_control, 6), code, pal_offset, 0); + tileinfo.group = group; + } else tileinfo.set((BIT(attr, 1) << 1) | BIT(m_control, 6), code, BIT(attr, 4, 4), (TILE_FLIPY * BIT(attr, 2) | (TILE_FLIPX * BIT(attr, 3)))); } @@ -100,12 +114,20 @@ void specnext_tiles_device::tilemap_update() for (auto i = 0; i < 2; ++i) { m_tilemap[i]->set_palette_offset(BIT(m_control, 4) ? m_palette_alt_offset : m_palette_base_offset); - m_tilemap[i]->set_transparent_pen(m_transp_colour); m_tilemap[i]->set_scrollx(-m_offset_h + m_tm_scroll_x); m_tilemap[i]->set_scrolly(-m_offset_v + m_tm_scroll_y); m_tilemap[i]->mark_mapping_dirty(); m_tilemap[i]->mark_all_dirty(); } + m_tilemap[0]->set_transparent_pen(m_transp_colour); + m_tilemap[1]->map_pen_to_layer(0, 0, TILEMAP_PIXEL_LAYER0); + m_tilemap[1]->map_pen_to_layer(0, 1, TILEMAP_PIXEL_LAYER0); + m_tilemap[1]->map_pen_to_layer(1, 0, TILEMAP_PIXEL_LAYER0); + m_tilemap[1]->map_pen_to_layer(1, 1, TILEMAP_PIXEL_TRANSPARENT); + m_tilemap[1]->map_pen_to_layer(2, 0, TILEMAP_PIXEL_TRANSPARENT); + m_tilemap[1]->map_pen_to_layer(2, 1, TILEMAP_PIXEL_LAYER0); + m_tilemap[1]->map_pen_to_layer(3, 0, TILEMAP_PIXEL_TRANSPARENT); + m_tilemap[1]->map_pen_to_layer(3, 1, TILEMAP_PIXEL_TRANSPARENT); m_tiles_info = m_host_ram_ptr + ((BIT(m_tm_map_base, 6) ? 7 : 5) << 14) + ((m_tm_map_base & 0x3f) << 8); } @@ -126,6 +148,7 @@ void specnext_tiles_device::device_add_mconfig(machine_config &config) { m_offset_h = 0; m_offset_v = 0; + m_global_transparent = 0xaa; } void specnext_tiles_device::device_start() @@ -137,6 +160,7 @@ void specnext_tiles_device::device_start() , tilemap_get_info_delegate(*this, FUNC(specnext_tiles_device::get_tile_info)) , TILEMAP_SCAN_ROWS, 8, 8, 80, 32); + save_item(NAME(m_global_transparent)); save_item(NAME(m_tm_palette_select)); save_item(NAME(m_control)); save_item(NAME(m_default_flags)); diff --git a/src/mame/sinclair/specnext_tiles.h b/src/mame/sinclair/specnext_tiles.h index 5d3f5e8ae4923..8181650bd607f 100644 --- a/src/mame/sinclair/specnext_tiles.h +++ b/src/mame/sinclair/specnext_tiles.h @@ -18,6 +18,8 @@ class specnext_tiles_device : public device_t, public device_gfx_interface specnext_tiles_device &set_palette(const char *tag, u16 base_offset, u16 alt_offset); void tilemap_update(); + void set_global_transparent(u8 global_transparent) { m_global_transparent = global_transparent; } + void control_w(u8 control) { m_control = control; tilemap_update(); } void default_flags_w(u8 default_flags) { m_default_flags = default_flags; m_tilemap[0]->mark_all_dirty(); m_tilemap[1]->mark_all_dirty(); } void transp_colour_w(u8 transp_colour) { m_transp_colour = transp_colour; tilemap_update(); } @@ -49,6 +51,7 @@ class specnext_tiles_device : public device_t, public device_gfx_interface tilemap_t *m_tilemap[2]; private: + u8 m_global_transparent; u16 m_palette_base_offset; u16 m_palette_alt_offset; bool m_tm_palette_select; diff --git a/src/mame/sinclair/spectrum.cpp b/src/mame/sinclair/spectrum.cpp index ea283f3b8ad26..6a68976b1ac98 100644 --- a/src/mame/sinclair/spectrum.cpp +++ b/src/mame/sinclair/spectrum.cpp @@ -605,11 +605,11 @@ INPUT_PORTS_START( spectrum ) 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_START("LINE1") /* 0xFDFE */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("a A STOP READ ~ NEW") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')// PORT_CHAR('~') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("s S NOT RESTORE | SAVE") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')// PORT_CHAR('|') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("d D STEP DATA \\ DIM") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')// PORT_CHAR('\\') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("f F TO SGN { FOR") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')// PORT_CHAR('{') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("g G THEN ABS } GOTO") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')// PORT_CHAR('}') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("a A STOP READ ~ NEW") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR('~') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("s S NOT RESTORE | SAVE") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR('|') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("d D STEP DATA \\ DIM") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR('\\') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("f F TO SGN { FOR") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR('{') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("g G THEN ABS } GOTO") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR('}') PORT_START("LINE2") /* 0xFBFE */ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("q Q <= SIN ASN PLOT") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') @@ -638,8 +638,8 @@ INPUT_PORTS_START( spectrum ) PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("p P \" TAB (c) PRINT") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR('"') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("o O ; PEEK OUT POKE") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(';') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("i I AT CODE IN INPUT") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("u U OR CHR$ ] IF") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')// PORT_CHAR(']') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("y Y AND STR$ [ RETURN") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')// PORT_CHAR('[') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("u U OR CHR$ ] IF") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(']') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("y Y AND STR$ [ RETURN") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR('[') PORT_START("LINE6") /* 0xBFFE */ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)