Skip to content

Spice86 v12 release notes

Maximilien Noal edited this page Apr 18, 2026 · 16 revisions

Spice86 v12 Release Notes

Comparison range: v11 release commit 83b6341 (2025-10-31, #1454) through v12 tag e1f252e (2026-03-08).


1. Broad View

195 commits spanning 752 files changed, with 45 802 insertions and 20 569 deletions.

The heaviest areas of change are the CfgCpu instruction pipeline, the DOS kernel and process/memory services, the entire sound stack (Sound Blaster, OPL, Adlib Gold, PC Speaker), the timer/PIT subsystem, and the debugger UI.

Dune:

  • Rewritten sound emulation, full Adlib Gold support (including surround module), ported from DOSBox Staging
  • Dune glitch with the CFGCPU fixed.
  • Dune floppy versions freeze fixed

Known issues:

  • The Dune demo glitches out

New games (fully) working now:

  • Sid Meier's Civilization
  • Cadaver (fixed rendering glitch issue)
  • The Summonning
  • F-15 Strike Eagle II
  • Wizardry 7
  • Where in Space is Carmen Sandiego
  • Rules of Engagement 2
  • Lotus 3
  • Prince of Persia 2
  • and many more...

Contributors

Contributor
Kevin Ferrare
Stefan Hueg
LowLevelMahn
Alberto Marnetto
Bruno Martinez
Karl Lenz
Joris van Eijden
Ievgenii Meshcheriakov
Maximilien Noal

2. PR-Driven View of Changes

List of pull requests in this release:

PR Summary Lead contributor(s)
#1486 CfgCpu AST converted to .NET Expression trees Kevin
#1924 MCP Server for reverse engineering (stdio + HTTP/SSE transports, CPU/memory/video/audio/input tools, UI integration) Joris van Eijden (initial implementation), Maximilien Noal (completion) - Uses the .NET 10 MCP SDK
#2053 MCP: improve tool descriptions, inline screenshots, custom tool suppliers Joris van Eijden
#1971 HTTP server for memory read/write by other processes Kevin (idea, inspiration from DOSBox Staging), Maximilien Noal (implementation) - Uses the Kestrel HTTP server from the .NET SDK
#1427 New PIT, PIC, OPL3, Adlib Gold, DMA, and many Sound Blaster improvements Stefan Hueg
#1467 CfgCpu instruction correctness fixes (ENTER, LEA, Jcc, ROR, SALC, ALU alignment with DOSBox) Stefan Hueg
#1525 Dock-based debugger window framework Copilot
#1544 Interrupt breakpoint IP display fix copilot-swe-agent
#1567 Conditional breakpoint expressions compiled from CfgCpu AST Copilot
#1572 Emulation loop scheduler redesign with priority-queue event loop Kevin
#1563 Respect EGA/VGA read mode 1 contributions per plane in the video renderer Karl Lenz
#1601 EMS improvements and bug fixes Copilot
#1602 RTC Clock/CMOS device, BIOS Wait handlers, DOS time/date, IVT corruption fix Copilot
#1603 DOS CDS and DBCS structures in DOS kernel initialization Copilot
#1604 Improved DOS Memory Manager (unlinking, allocation strategies, MCB chain validation) Copilot
#1614 Remove old/legacy CPU classes Kevin
#1635 Cross-platform audio: single audio thread, full SB PCM/DSP/mixer, OPL3/OPL2/dual OPL2, Adlib Gold surround, rewired PC Speaker, software mixer UI Maximilien Noal
#1686 Full DOS process support, TSR support, PSP services Maximilien Noal
#1774 Separate CFG node successor determination from instruction execution Kevin
#1780 Full CP/M FCB file API for DOS INT 21h Maximilien Noal
#1810 Minimal handler for DOS INT 2Ah Alberto Marnetto
#1850 CPU Heavy log Kevin
#1852 Emulator state serialization refactor; assembly listing export Kevin
#1855 DOSBox-format ASM output for easier heavy-log comparison Kevin
#1857 VgaBios: handle INT 10h function 0Bh for unexpected BX values Alberto Marnetto
#1858 Fix Colonization game Bruno Martinez
#1869 Open the same file handles as DOS does Alberto Marnetto
#1870 Log registers in heavy log Kevin
#1908 Replace NukedOPL3 in-tree port with NuGet package Stefan Hueg
#1909 Ignore MSHERC.COM's INT 10h/AH=EFh LowLevelMahn
#1947 PCM performance fix Maximilien Noal
#1948 Display correct link type in CFG Kevin
#1778 Preliminary single-step tests with revocation list support Kevin
#1961 Jump arc visualization in disassembly view Maximilien Noal
#1966 Fix CALL-to-RET link self-modifying code detection Kevin
#1994 VGA renderer depends on emulated time; InstructionsPerSecond restored Kevin
#2005 Event-based VGA rendering for deterministic registers and improved performance Kevin
#2011 Allocate space for all DosSysVars Ievgenii Meshcheriakov
#2012 Theme-aware, syntax-highlighted CFG graph rendering Maximilien Noal
#2032 Benchmark mode: stop emulator after N cycles Kevin
#2040 VGA horizontal pixel panning (AR13 smooth scrolling) Copilot

3. New Features and enhancements

  • MCP Server for reverse engineering (#1924, Joris van Eijden / Maximilien Noal): Model Context Protocol server with stdio and HTTP/SSE transports. Exposes CPU state, memory, video, audio, input, I/O ports, breakpoints, EMS/XMS, and CFG inspection tools. UI integration with enable/disable per-tool and port display. Custom tool supplier support (#2053, Joris van Eijden).
  • HTTP server for external memory access (#1971, idea from Kevin, inspired by DOSBox Staging, Maximilien Noal): REST API for reading/writing emulator memory from external processes, with A20Gate-aware addressing, validation, and UI.
  • Cross-platform audio overhaul (#1635): single audio thread, complete SB PCM/DSP/hardware-mixer emulation, SB reset delay, OPL port read/write delays, SB variant selection, OPL3/OPL2/dual OPL2, Adlib Gold music and surround effects, rewired PC Speaker, and a full software mixer UI.
  • CPU Heavy log and ASM output (#1850, #1855, #1870, Kevin / Kevin Ferrare): heavy-log mode records register state per instruction; DOSBox-compatible ASM output format added for easier side-by-side comparison.
  • Emulator state serialization refactor (#1852, Kevin Ferrare): save executed instructions as assembly listings; unified state export API.
  • More complete AST subsystem (Kevin Ferrare): expanded CfgCpu AST and Expression-tree compilation path (#1486).
  • Conditional breakpoint expressions (#1567, Copilot): breakpoints can now evaluate expressions compiled from CfgCpu AST via BreakpointConditionCompiler.
  • Docking debugger framework (#1525, Copilot): debugger window uses a proper docking layout via the Dock library.
  • New PIT, PIC, OPL3, Adlib Gold, DMA (#1427, Stefan Hueg): rewritten PIT/PIC with interrupt shadowing, improved DMA reliability and transfer, NukedOPL3 performance improvements, Adlib Gold surround, adaptive cycle budget.
  • NukedOPL3 moved to NuGet package (#1908, Stefan Hueg): the in-tree port was replaced with a proper NuGet dependency.
  • Additional 386+ instructions and exception handling (#1467, Stefan Hueg): ENTER, LEA 32-bit, Jcc displacement-width fix, interrupt shadowing for LSS, CPUID now throws CpuInvalidOpcodeException.
  • Full DOS process and TSR support (#1686): DOS EXEC (load-and-execute, load-only, overlay), child PSP creation, TSR (Terminate-and-Stay-Resident), return code propagation, and associated INT 21h handlers.
  • Full CP/M FCB file API (#1780): sequential/random read/write, block read/write, find first/next, delete, rename, get file size.
  • DOS INT 21h AH=01h Character Input with Echo (#1781).
  • DOS INT 2Ah minimal handler (#1810, Alberto Marnetto): network installation query stub.
  • DOS kernel structures (#1603, #1604, Copilot): CDS/DBCS tables, MCB chain validation, allocation strategies ported from FreeDOS.
  • RTC Clock/CMOS device and BIOS Wait handlers (#1602, Copilot): real-time clock, alarm, periodic interrupt, INT 15h wait function.
  • EMS improvements (#1601, Copilot): additional status codes, handle limit, page-frame save area.
  • Get List of Lists (#1680): INT 21h function 52h now returns the internal DOS data pointer.
  • Set Typematic rate and delay (#1806): IBM PC BIOS keyboard repeat configuration via INT 16h.
  • Full PS/2 controller, keyboard, and INT 9h rewrite: complete scan-code-set-1 handling, PS/2 controller commands, proper BDA flag management.
  • DOS/V (Japanese DOS) INT 15h error (#1782): returns expected error code so DOS/V programs proceed normally.
  • Emulation loop scheduler redesign (#1572, Kevin): priority-queue event loop decoupled from PIC; cycle-based clock reintroduced.
  • CLI accepts dec/hex/bin for ProgramEntryPointSegment (#1856, LowLevelMahn).
  • Ignore MSHERC.COM's INT 10h/AH=EFh (#1909, LowLevelMahn).
  • Open the same file handles as DOS (#1869, Alberto Marnetto).
  • VgaBios INT 10h,0Bh handling (#1857, Alberto Marnetto).

4. Bugfixes

CPU correctness (Stefan Hueg, #1467)

  • ENTER opcode fix.
  • LEA 32-bit address truncating fix.
  • Interrupt shadowing for LSS instruction.
  • SALC assignment swap fix.
  • Jcc parser now uses displacement width based on operand-size instead of address-size.
  • 32-bit ROR uses correct modulo.
  • ALU operations aligned with DOSBox behavior.
  • Corruption in Dune fixed (#1490, Stefan Hueg).

CPU / CFG

  • CALL-to-RET link self-modifying code detection fix (#1966, Kevin).
  • ModRM parser fix (#1970, Copilot).
  • Display correct link type in CFG (#1948, Kevin).

Performance

  • Breakpoint handling performance regression fixed (#1491, Stefan Hueg).
  • Breakpoint check performance improved (#1488, Stefan Hueg).
  • Performance measurement made self-containing (#1492, Stefan Hueg).
  • Performance counter restored (#1620, Kevin).
  • Adlib Gold and NukedOPL performance improvements (Stefan Hueg).

DOS correctness

  • GetCurrentDirectory crash fixed (#1839).
  • ModifyMemoryBlock returns correct segment in AX; CurrentSize points to first segment after allocated block.
  • COM files now allocated entire available memory as DOS does.
  • CloseFileOrDevice sets AL to file-handle refcount on success (#1844).
  • PSP commandline encoding fixed (#1600, LowLevelMahn).
  • Grp4Callback fix for DOS EXEC (#1589).
  • COM loading behavior fixed (#1610).
  • EXE image loading relaxed to match DOS (fixes INSECTS.EXE) (#1611).
  • FindLargestFree logic fix (#1804).
  • NullReferenceException in CurrentDriveIndex fixed (Ultima V, #1801).
  • Dune 2 crash from DBCS table segmented address miscalculation (#1775).
  • Cycles limiting restored (had been accidentally removed) (#1802).
  • Invalid opcode exception no longer crashes the emulator (#1803, Kevin).
  • Allocate space for all DosSysVars (#2011, Ievgenii Meshcheriakov).
  • IregsFrameSize at 0 prevents stack corruption (#2035).
  • DosSysVars space allocation (#2011, Ievgenii Meshcheriakov): allocate space for all DosSysVars fields.

Game-specific fixes

  • Alpha Waves: TSR support fix (#1854); INT 21h/4Ah specific behavior (#1867).
  • Colonization: fix by Bruno Martinez (#1858).
  • Civilization 1: infinite loop waiting for BDA Floppy Motor Counter (#1808).

Input / video / audio

  • Keyboard lock-up with concurrent queue locks (#1617).
  • KeyboardReset was called twice.
  • A20Gate enabled/disabled was switched.
  • Mouse driver drift prevented (#1809).
  • Unimplemented INT 33h mouse commands now silently ignored (#1779).
  • VGA rendering on unconstructed card prevented (#1571, Kevin).
  • Video aspect ratio corrected with dynamic ScaleTransform (#1833).
  • PCM performance and reliability with tick mode.
  • GetFunctionalityInfo now returns real values instead of dummies (Stefan Hueg, #1487).
  • Cadaver rendering fix (Respect EGA/VGA read mode 1 contributions per plane in the video renderer) (#1563, Karl Lenz).

Debugger / UI

  • Memory view regression fixed (#1465).
  • Multi-exe game dumps no longer share the same folder (#1422).
  • Interrupt breakpoint IP display corrected (#1544).
  • Step-into and EmulatorBreakpointManager exceptions fixed (#1547).
  • Debugger visual glitch when reaching a breakpoint (#1851).
  • Input event handling moved to emulation thread.

Build / CI

  • CS1591 warning treated as error in prerelease workflow (#1455/#1456).
  • \r constraint removed from CLI parameter parsing (#1907, LowLevelMahn).

5. Refactorings

  • Legacy CPU class removal (#1614, Kevin Ferrare): old CPU and related classes deleted.
  • CFG node successor decoupled from execution (#1774, Kevin Ferrare).
  • CfgCpu AST to Expression trees (#1486, Kevin).
  • Emulation loop scheduler rewrite (#1572, Kevin Ferrare): decoupled from PIC, simplified with priority queue, reintroduced cycle-based clock.
  • PicEventQueue renamed to DeviceScheduler (#1512).
  • IO containers removed (#1619).
  • IPauseHandler moved from CfgCpu to EmulatorBreakpointsManager (#1544).
  • NukedOPL3 replaced with NuGet package (#1908, Stefan Hueg).
  • PS/2 keyboard and INT 9h rewrite: removed goto/labels, introduced ScanCode set 1 enum, consolidated four reference fields into one class.
  • Keyboard FIFO (Kevin Ferrare): replaced previous keyboard buffer with a proper FIFO.
  • Breakpoint UI refactored: shared MemoryBreakpointUserControl, pure XAML bindings, ViewModel consolidation (#1485).
  • Optional parameter removal, singleton elimination (#1470).
  • Moved to .NET 10 (#1548).

6. UI Changes

  • Docking debugger layout (#1525): debugger window panels are now dockable/rearrangeable.
  • Register UI improvements (#1845): formatting, highlighting, and theming for CPU register display.
  • CfgCpu graph rendering improved (#1811): cleaner, more informative CFG visualization.
  • Video aspect ratio correction (#1833): dynamic ScaleTransform bound to video-mode aspect ratio.
  • Software mixer UI (part of #1635): visual mixer panel for the new audio stack.
  • CPU Heavy log and ASM output panels (#1850, #1855, #1870): new log views showing register state and DOSBox-format assembly.
  • Breakpoint memory-value conditions (#1485): shared user control for memory breakpoint value conditions across both Breakpoints and Memory views.
  • Debugger visual fix (#1851): resolved visual glitch when hitting a breakpoint.
  • Memory view regression fix (#1465).

7. Breaking Changes for Override Projects (Public APIs)

The following changes in Spice86.Core and Spice86.Shared may require updates in downstream override projects:

Change PR Impact
Old CPU and related classes removed #1614 Any code referencing legacy CPU types must switch to CfgCpu equivalents.
PicEventQueue renamed to DeviceScheduler #1512 Update type references.
PIT/timer subsystem reshaped #1427 Timer, CounterActivator, Pit8254Counter, Pit8254Register removed. New types: PitTimer, IPitControl, IPitSpeaker, IWallClock, PitChannelSnapshot.
State serialization API renamed #1852 RecordedDataReader/WriterEmulationStateDataReader/Writer; ExecutionDumpExecutionAddresses; ExecutionFlowRecorderExecutionAddressesExtractor; GhidraSymbolsDumperGhidraSymbolsExporter; MemoryDataExporter.DumpMemory().Write().
FunctionCall record signature changed #1614 IsReturnRecorded field removed; ICall/Call helper recordReturn parameter removed.
DosProcessManager reshaped #1686 No longer extends DosFileLoader; constructor takes Stack; DosProgramSegmentPrefixTracker removed; process loading moved to internal DosProgramLoader.
DosMemoryManager constructor changed #1604 Now takes initialPspSegment directly instead of DosProgramSegmentPrefixTracker.
EmulatorBreakpointsManager constructor expanded #1567 Now requires IMemory and additional parameters for condition compilation.
VgaCard constructor changed various Takes IGuiVideoPresentation instead of IGui.
Clock class removed #1602 Replaced by CyclesClock/EmulatedClock implementing IEmulatedClock.
CycleLimiterBase abstract class removed #1572 CpuCycleLimiter now implements ICyclesLimiter directly.
CSharpOverrideHelper additions various FarRet32(), NearRet32() added; ReturnOperationsHelper exposed instead of Cpu.
DosProgramSegmentPrefix.NextSegment renamed to CurrentSize #1686 Update field references.
DosInt21Handler constructor changed #1686 Takes DosProcessManager instead of separate DosPspTracker/Clock parameters.

Migration: recompile override projects against v12 and resolve the renamed/removed types listed above. The biggest impact areas are in the CSharpOverrideHelper API, the move to the CFGCPU, the timer/PIT abstractions, state serialization APIs, and DOS process management.

Clone this wiki locally