Skip to content

Merge upstream Fuse master (fuse-1.7.0 + 70 commits)#36

Merged
desertkun merged 151 commits into
speccytools:masterfrom
morozov:merge/fuse-1.7.0
May 12, 2026
Merged

Merge upstream Fuse master (fuse-1.7.0 + 70 commits)#36
desertkun merged 151 commits into
speccytools:masterfrom
morozov:merge/fuse-1.7.0

Conversation

@morozov
Copy link
Copy Markdown
Member

@morozov morozov commented May 11, 2026

Summary

Atomic merge of upstream Fuse at 07d6bba (= fuse-1.7.0 + 70 commits) into the FuseX fork as a single commit. Tree contents = auto-merge result + conflict resolutions + atomic-commit fix-ups for the merged tree to be a working state.

Sequencing

Built on top of two submodule PRs that have been merged into speccytools master:

This branch's submodule pointers now reference the resulting speccytools master tips, so a fresh clone resolves them cleanly.

CI

A follow-up commit ("Trim and fix CI") adapts the workflows brought in by the merge:

  • Reverts upstream's broken actions/upload-artifact@v8 bump (v8 doesn't exist for upload-artifact; max is v7).
  • Removes Linux and WII workflows (off-target for this fork).
  • Adds the fork's nsarray setting type to the root settings-header.pl.
  • Drops the Fuse-UI fan-out jobs from build_macos.yml and build_windows.yml because machine.c and ui/sdl/sdlkeyboard.c include fusepb/FuseMenus.h unconditionally — the Xcode build resolves it via fusepb/'s include path, autotools builds don't. These jobs can be restored separately if needed.

PR CI now runs only the libspectrum macOS and Windows sub-builds, both green.

Rationale

The merge commit message documents the conflict resolutions and atomic-commit fix-ups in detail.

Supersedes #35.

arki55 and others added 30 commits November 9, 2022 20:20
… output from configure script contains certain text.
build: Implemented full workflow for building Fuse APP on Linux.
- It reuses build_linux.yml workflow from fuse libspectrum repository.
- Split into 2 files : _build_linux_sub.yml  with logic and steps for building main Fuse APP - checkout, configure, make, make install, etc.  And build_linux with actually triggered workflow upon push and pull_request .
- First step is to build libspectrum with its reusable workflow. FOr that purpose repo needs to define variable LIBSPECTRUM_REPO - address of libspectrum repo in github.
- Libspectrum is built, all files zipped into artifact file, which is then loaded by build subprocess and its content installed (make install)
- Libspectrum is built once, then all the dependant various LInux based configurations are built.
- Each build variant provides its specific .configure params, what to verify in .configure output, etc.

Supporting configurations:
- Default built (no params for ./configure)
- NULL UI
- GTK 3 UI
- SDL 1 UI
- SDL 2 UI (only checks that it shows not supported yet)

Deprecated UIs (as per official site):
- GTK 2 UI
- Frame Buffer UI
- X UI
…kflows

https://sourceforge.net/p/arki55-fuse-mod/tickets/9/
feature: GitHub workflow build scripts for FUSE App -  for linux, WII, WIN32 and MacOS
Suppressing doubleclick message on title bar to not do window maximizing
(fixes bug #488).
Created separate menu for sound peripherals, moved 4 devices there.
Moved sound related peripherals' source files into standalone folder (like disk related stuff is in)

See more
https://sourceforge.net/u/arki55/tickets/4/
Multiple changes, fixes needed to make cross compiling for WII fork again:
- Make sure GEKKO constant is set from configure.
- Explicit defining of GEKKO constant removed from wiijoystick.c and wiimouse.c (as it is set from configure).
- Function clock_gettime (wii only) has changed its signature, needing 2 parameters now. I made a best guess here and chose CLOCK_REALTIME as the first parameter.
- In WII mode most of optional stuff is turned off. Sockets including. However some code was still requiring winsock2.h. Wrapped it into ifdef HAVE_SOCKETS.
- compat_dir variable does not need WII specific type override.
- Added missing key mappings based on build failure. Some keys cannot be mapped 1:1, so leaving them at the end. They will not be mapped.
- Removing compatibility file dir.c for WII, as it has now standard POSIX dir related functions.
- Updated github workflow file, fixed path to allow cross-compiling. Also added checks to make sure cross-compiling was active.
- Installing missing packages bison, flex

https://sourceforge.net/p/arki55-fuse-mod/tickets/11/
Modified GitHub build workflow files for Windows and so introduced configuration with SDL UI (widget) + SDL Sound
Small fixes within the sub workflow file.

https://sourceforge.net/p/arki55-fuse-mod/tickets/12/
- Remove AC_CHECK_INCLUDES_DEFAULT macro. Improves compatibility with
  older autoconf versions. AC_INCLUDES_DEFAULT are implicitly checked
  by LT_INIT and AC_CHECK_HEADERS macros.
- Remove unused AC_PROG_EGREP macro.
- ax_string_strcasecmp.m4 file updated from upstream.
- gtk-2.0.m4 file updated by autoupdate.
- sdl.m4 file updated from upstream.
The Freedesktop theme spec says that icons are first searched in
the current theme, then in its parents and finally in the default
"hicolor" theme.

"hicolor" is where Fuse installs its icons, however if generic-icon is
not specified in fuse.xml then it defaults to application-x-generic.

This means that if the current theme provides an icon named
application-x-generic it will be used instead of the ZX Spectrum one.

Fixes bug #494
as are also commonly used for non ZX Spectrum content
and is better to not associate as the preferred application.
(more from bug #494) (thanks, Berto).
SP0256 ROM initialisation moved to the uspeech.c and produces meaningful
error messages if something goes wrong.
- Memory read/write at 0x38 should page the ROM in/out
- ROM is mapped to the first 4 Kb only

Thanks to Tim Busse tests tape. Now Booty launches the hidden "diving" game.
bertogg and others added 21 commits April 17, 2026 13:53
On Unix systems use $XDG_CONFIG_HOME/fuse-emulator/fuserc as
the new location for the configuration file, defaulting to
~/.config/fuse-emulator/fuserc if $XDG_CONFIG_HOME is unset.

If that file is not found, reading falls back to ~/.fuserc on Unix as
before so users can keep using the existing configuration. Writing
always goes to the XDG location.

With this change Flatpak builds can use $XDG_CONFIG_HOME as expected.

(patches #443)
Three code paths in compare_and_merge_rectangles() were untested:

1. y-merge where source is ABOVE the inactive rectangle.
   The existing Test 7 only covers source below inactive (y=3 following
   y=0..2).  The new Test 10 covers the mirrored branch:
     source->y < rectangle_inactive[z].y
   and verifies that the merged y and h are correct.

2. x-merge where source is to the LEFT of inactive.
   Test 9 only tests source with the same x but a larger w (first OR
   branch).  The new Test 11 exercises the second OR branch:
     source->x < rectangle_inactive[z].x
   and confirms the merged x and w.

3. Non-overlapping rectangles at frame_rate > 1 that must NOT merge.
   Tests 1-5 flushed rects with frame_rate == 1 (no merge path at all).
   The new Test 12 confirms that when two rectangles share neither an
   overlapping x-range nor a common y-range, both are retained as
   separate inactive entries (inactive_count == 2).
Add four test cases to unittests/displaytest.c exercising the Timex
display path (display_write_if_dirty_timex), which previously had no
test coverage:

- timex_lores_no_redraw_if_unchanged: verifies the cache is not
  invalidated when pixel data and SCLD mode byte are unchanged.
- timex_lores_write_called_for_new_data: verifies uidisplay_plot8 is
  called with the correct arguments when new pixel/attribute data
  appears, and that display_last_screen is updated to include the
  mode_data byte.
- timex_mode_change_causes_redraw: verifies that changing the SCLD
  byte (mode_data) forces a cache miss and a redraw even when the
  pixel and attribute bytes have not changed.  This is the key
  behavioural difference between the Timex and Sinclair paths.
- timex_hires_plot16_called_with_correct_data: verifies that in true
  HIRES mode uidisplay_plot16 is called with the correct combined
  16-bit word assembled from the two screen planes.

Supporting changes:
- Add plot16 tracking infrastructure (plot16_fn_t, plot16_null,
  plot16_count_fn, plot16_assert, plot16_last_write) mirroring the
  existing plot8 machinery.
- Add timex_test_before() setup helper that mirrors test_before() but
  sets the SCLD byte and routes through display_write_if_dirty_timex.
- Fix uidisplay_plot16 stub: was declared with libspectrum_byte for
  the data parameter; corrected to libspectrum_word to match the
  function signature in ui/uidisplay.h.
- Initialise plot16_fn to plot16_null in test_before() so Sinclair
  tests are safe if plot16 is ever called unexpectedly.
This makes it easier to load as we don't need to look for it in the
filesystem.
The GTK build no longer needs external auxiliary files
Move the libspectrum build coverage into this repository's GitHub Actions workflows
and add a manual Windows release workflow for producing distribution artifacts.
currently saved to XDG configuration directory.
(fixes bug #515) (thanks, Cesar Hernandez).
Adds nine new test cases to debugger_disassemble_unittest():

- CB BIT/RES/SET on registers (CB 47 'BIT 0,A', CB 87 'RES 0,A',
  CB CF 'SET 1,A') — the plain CB prefix path had no bit-operation
  tests at all.

- DD CB and FD CB BIT/RES/SET on (IX+d)/(IY+d) — tests the
  disassemble_ddfd_cb() branches for b in 0x40-0x7F and 0x80-0xFF
  with b&7==6 (the documented indexed bit operations).

- DD CB undocumented LD reg,RES/SET n,(IX+d) — regression tests for
  the bug fixed in 7be9ae54 ('Fix missing bit number in DD/FD CB
  disassembly', fixes bug #515).  The pre-fix code used the format
  'LD %s,%s %s' which omitted the bit number; the fix changed it to
  'LD %s,%s %d,%s'.  These tests would have caught that regression.

Also increases the run_test() disassembly buffer from 16 to 40 bytes
to accommodate the longest disassembly strings (e.g.
'LD A,RES 0,(IX+55)' is 18 characters; the old 16-byte buffer would
have silently truncated them, causing spurious failures).
Add three unit tests for display_dirty_flashing_sinclair() which
had no test coverage:

- flash_dirty_no_flash_attrs: zeroed RAM (all attrs non-flash)
  must leave display_maybe_dirty fully clear.
- flash_dirty_with_flash_attr_row0_col0: a flash attr at 0x1800
  (row 0, col 0) must mark all eight corresponding pixel rows
  dirty at column bit 0.
- flash_dirty_non_flash_attr: a non-flash attr (bit 7 clear) must
  not set any maybe_dirty bits.

To support direct inspection of display_maybe_dirty in tests, add
display_get_maybe_dirty() alongside the existing display_get_is_dirty()
in the DISPLAYTEST helper block of display.c.
Three new unit tests for the Pentagon 16-colour display path, which
previously had zero coverage in unittests/displaytest.c:

- pentagon_no_write_if_data_unchanged: verifies the cache-hit fast path
  — when all RAM pages and display_last_screen are zero, no pixels are
  emitted via uidisplay_putpixel.

- pentagon_write_called_for_new_data: verifies that when page 5 data
  changes, uidisplay_putpixel is called 8 times, display_last_screen is
  updated with the correct last_chunk_detail value, and the appropriate
  display_is_dirty bit is set.

- pentagon_page7_reads_correct_pages: verifies page-selection logic —
  when memory_current_screen == 7, data is read from pages 7 and 6
  (not 5 and 4), and the last_chunk_detail reflects that.

Supporting infrastructure:
- putpixel_fn / putpixel_count tracking (mirrors the existing plot8
  machinery) to intercept uidisplay_putpixel calls in tests.
- pentagon_test_before() setup helper that clears pages 4–7,
  display_last_screen, and display_is_dirty, then arms the count
  callback.
- putpixel_fn = putpixel_null initialisation in test_before() so
  Sinclair tests are safe if putpixel is unexpectedly called.
All download-artifact calls already use v8, but the four upload-artifact
calls in the libspectrum and Windows build sub-workflows were still on v7.
Align them to v8 so that upload and download versions are consistent.
Add 11 new unit tests to debugger_disassemble_unittest():

FD CB documented RES/SET on (IY+d):
- test25: FD CB 55 86 -> RES 0,(IY+55)
- test26: FD CB 55 C6 -> SET 0,(IY+55)

FD CB undocumented LD reg,RES/SET n,(IY+d):
- test27: FD CB 55 87 -> LD A,RES 0,(IY+55)
- test28: FD CB 55 CF -> LD A,SET 1,(IY+55)

Negative (IX-d)/(IY-d) offsets (offset byte >= 0x80):
- test29: DD CB FF 46 -> BIT 0,(IX-01)
- test30: FD CB FF 46 -> BIT 0,(IY-01)
- test31: DD 7E FF    -> LD A,(IX-01)

Relative jump instructions (DJNZ/JR):
- test32: 18 00 -> JR 4002  (zero forward offset)
- test33: 18 FE -> JR 4000  (backward -2 offset)
- test34: 10 FE -> DJNZ 4000 (backward -2 offset)
- test35: 20 04 -> JR NZ,4006 (conditional forward +4)
Add five unit tests:

- timex_flash_hires_skips_flashing: when hires=1, the function is a
  no-op regardless of flash bits in memory.

- timex_flash_b1_no_attrs_clean: when b1=1 and no flash bits are set in
  the alternate pixel area (0x2000-0x37ff), no maybe_dirty bits are set.

- timex_flash_b1_marks_dirty: when b1=1 and the flash bit is set at
  ALTDFILE_OFFSET (0x2000), display_dirty8() is called and
  display_maybe_dirty[0] bit 0 is set.

- timex_flash_altdfile_marks_dirty: when altdfile=1 and a flash attr is
  set at 0x3800 (second screen attr area, row 0 col 0), display_dirty64()
  marks all 8 corresponding pixel rows dirty.

- timex_flash_standard_delegates_to_sinclair: when scld=STANDARD, the
  function delegates to display_dirty_flashing_sinclair() and the result
  matches the existing sinclair flash tests.
Add printf() diagnostics so that a failing CI run immediately shows:

  disassemble test: expected 'BIT 0,A', got 'BIT 0,B'
  disassemble test: 'LD (3456),BC': expected length 4, got 3
Add 20 new unit tests to debugger_disassemble_unittest() covering the
full range of ED-prefix (extended) instructions:

ED IN reg,(C) / OUT (C),reg:
- test36: ED 40 -> IN B,(C)
- test37: ED 70 -> IN F,(C)  (special-cased flag register form)
- test38: ED 41 -> OUT (C),B
- test39: ED 71 -> OUT (C),0  (special-cased zero form)

ED SBC HL,rr and ADC HL,rr:
- test40: ED 42 -> SBC HL,BC
- test41: ED 4A -> ADC HL,BC

ED LD (nn),rr and LD rr,(nn):
- test42: ED 43 56 34 -> LD (3456),BC
- test43: ED 4B 56 34 -> LD BC,(3456)

ED NEG / RETN / RETI:
- test44: ED 44 -> NEG
- test45: ED 45 -> RETN
- test46: ED 4D -> RETI

ED interrupt mode:
- test47: ED 46 -> IM 0
- test48: ED 56 -> IM 1
- test49: ED 5E -> IM 2

ED register-pair accumulator ops:
- test50: ED 47 -> LD I,A
- test51: ED 57 -> LD A,I

ED block instructions:
- test52: ED A0 -> LDI
- test53: ED B0 -> LDIR
- test54: ED A8 -> LDD
- test55: ED B8 -> LDDR
@morozov morozov force-pushed the merge/fuse-1.7.0 branch from ef2153a to 648cd7e Compare May 12, 2026 00:26
@desertkun
Copy link
Copy Markdown
Collaborator

Submodules have been merged, please update the pointers, thanks.

morozov added 2 commits May 12, 2026 08:15
Atomic merge of upstream Fuse at 07d6bba (= fuse-1.7.0 + 70 commits) into the
FuseX fork as a single commit. Tree contents = auto-merge result + conflict
resolutions + atomic-commit fix-ups for the merged tree to be a working state.

== Conflict resolutions (seven text conflicts, resolved 3-way) ==

  memory_pages.c, peripherals/spectranet.{c,h}
    Both sides added independent paged-memory regions to the Spectranet
    handler -- fork added xfs and spectranext_config; upstream added
    flash_rom. All three preserved.

    spectranet.c additionally has a region inside `#ifdef BUILD_SPECTRANET`
    where upstream added stubs for spectranet_flash_rom_read /
    spectranet_flash_rom_write inside the `#else` branch (= when
    BUILD_SPECTRANET is OFF). Fork removed that entire `#else` stub branch
    in fork master, so upstream's stub additions are dead code in the fork's
    structure. Took HEAD's `spectranet_config_get_total_size` only;
    discarded upstream's stub additions to the removed branch.

  peripherals/nic/w5100.c
    Fork added a `nic_w5100_t *self` parameter to nic_w5100_socket_add_to_sets
    and nic_w5100_socket_process_io call sites (with matching signature
    changes in w5100_socket.c and w5100_internals.h, which auto-merged), and
    swapped `compat_socket_networking_init()` for the refcounted
    `utils_networking_init()` wrapper in `nic_w5100_alloc`. Upstream
    independently extracted `w5100_start_io_thread`, switched to lazy thread
    start (nic_w5100_alloc no longer starts the io thread; nic_w5100_enable
    does), and made nic_w5100_free conditionally stop the thread only if
    started. Deltas are non-overlapping; took both verbatim.

  settings.dat
    start_scaler_mode: fork added an empty 'string-option processing
    function' column, upstream changed the default value from "normal"
    to "2x". Both kept (= "2x" with the empty extra column).

  settings.pl
    Fork removed the libxml2/ini config-file readers and the
    CONFIG_FILE_NAME defines (Cocoa builds use NSUserDefaults). Upstream
    added FALLBACK_CONFIG_FILE_NAME inside that same removed block --
    irrelevant in the fork's structure. Fork side kept.

  ui/sdl/sdlui.c
    Copyright year conflict only; took upstream's wider range (2000-2021).

== Atomic-commit fix-ups (changes the merge tree requires to be buildable) ==

Background: bumping `3rdparty/libspectrum` is not a backward-compatible
operation here -- new libspectrum (1) renames `libspectrum_creator_*`
signatures, (2) adds new symbols upstream Fuse 07d6bba uses
(`libspectrum_snap_uspeech_*`, `LIBSPECTRUM_ID_SNAPSHOT_DSNAP`), and (3)
splits wav.c into a frontend + backend pair (wav_audiofile.c or
wav_macos.c). A standalone bump commit on fork master therefore would not
build, so the bump must live inside this merge commit, paired with all
the changes the new libspectrum requires.

  3rdparty/libspectrum: 8ba1310 -> e4a2d6e1
    The speccytools/libspectrum master tip, itself a real 2-parent merge
    of fork-side and upstream-side libspectrum.

  3rdparty/FuseGenerator and 3rdparty/FuseImporter: bumped to speccytools master tips
    Each subproject commits its own copy of `libspectrum.h` (an artifact
    of the fork's earlier choice to switch these from libspectrum-as-subtree
    to libspectrum-as-submodule without keeping the header auto-regenerated).
    The committed headers had to be regenerated against the bumped libspectrum,
    and each subproject also needed Xcode wiring for new libspectrum source
    files (dsnap.c, wav_macos.c) plus AudioToolbox.framework linkage for the
    wav backend. See subproject commits for details. FuseImporter additionally
    has a fix to `generate.pl` (missing `#define WIN32_DLL`) latent until
    libspectrum.h.in started using LIBSPECTRUM_DEFINE_TYPES marker.

  fusepb/libspectrum.h
    Regenerated from the bumped 3rdparty/libspectrum/libspectrum.h.in via
    the Xcode build phase script. Adds the new symbols and updates
    libspectrum_creator_* signatures. Committed in-tree to keep the merge
    tree self-consistent.

  fusepb/FuseX.xcodeproj/project.pbxproj
    Three categories of changes:
    1. Sound peripherals upstream moved from peripherals/ into
       peripherals/sound/ (5 files: ay, covox, fuller, melodik, specdrum)
       get 'sound/' path prefixes.
    2. New sound peripherals upstream added (sp0256, uspeech): four file
       references and two build entries.
    3. New libspectrum source files (dsnap.c, wav_macos.c, wav_internals.h)
       referenced and compiled into FuseX, plus AudioToolbox.framework
       linkage for the wav_macos backend (matches upstream macOS CI's
       `--without-libaudiofile` choice).
Upstream's workflows came in with the 1.7.0 merge (fork master had
none) and need adjustments to run cleanly on github.com:

- upload-artifact pinned to v8 doesn't exist (max v7); revert the
  upstream "alignment" bump (0b4c6dd).
- Linux and WII workflows are off-target for this fork; remove.
- Root settings-header.pl didn't know the fork's `nsarray` setting
  type; treat like `null`.
- machine.c and ui/sdl/sdlkeyboard.c include fusepb/FuseMenus.h
  without a guard, breaking autotools UI builds. Pre-existing fork
  issue, out of merge scope; drop the Fuse-UI fan-out jobs from
  build_macos.yml and build_windows.yml until the include is
  conditional. Libspectrum sub-builds, which pass, remain.
@morozov morozov force-pushed the merge/fuse-1.7.0 branch from 648cd7e to b537481 Compare May 12, 2026 15:16
@morozov
Copy link
Copy Markdown
Member Author

morozov commented May 12, 2026

please update the pointers

Done.

@desertkun desertkun merged commit 2042ba8 into speccytools:master May 12, 2026
2 checks passed
@desertkun
Copy link
Copy Markdown
Collaborator

Thanks for support.

@morozov morozov deleted the merge/fuse-1.7.0 branch May 12, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.