Skip to content

Fix/civilization#2180

Merged
maximilien-noal merged 7 commits into
masterfrom
fix/civilization
May 17, 2026
Merged

Fix/civilization#2180
maximilien-noal merged 7 commits into
masterfrom
fix/civilization

Conversation

@maximilien-noal

@maximilien-noal maximilien-noal commented May 17, 2026

Copy link
Copy Markdown
Member

Description of Changes

Removes regression from commit 5b8a876 which broke Civilization.

Rationale behind Changes

Fixes Civilization :

image

Makes us stick to FreeDOS kernel behavior regarding FindFirst and FindNext

Suggested Testing Steps

Tests updated accordingly. They all pass. Tested manually with Civilization.

Copilot AI review requested due to automatic review settings May 17, 2026 08:18
@maximilien-noal maximilien-noal self-assigned this May 17, 2026
@maximilien-noal maximilien-noal added DOS Related to DOS bugfix fixes a bug labels May 17, 2026
@maximilien-noal maximilien-noal marked this pull request as draft May 17, 2026 08:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR (titled "Fix/civilization", presumably for the Civilization DOS game) refactors DosFcbManager's public FCB entry points to take SegmentedAddress instead of pre-computed uint linear addresses, and updates the only caller (DosInt21Handler) accordingly. It also inlines the two previously-extracted FCB log helpers and rewords a few XML doc summaries / the implementation-reference paragraph. The PR description is empty, so the specific Civilization-related symptom and fix rationale are not documented.

Changes:

  • Change every FCB-related method signature in DosFcbManager (e.g. OpenFile, CloseFile, SequentialRead/Write, RandomRead/Write, RandomBlockRead/Write, ParseFilename, GetFcb, etc.) from uint fcbAddress to SegmentedAddress fcbAddress, converting back to a physical address inside via MemoryUtils.ToPhysicalAddress(seg, off) (which is the same computation as SegmentedAddress.Linear).
  • Update all call sites in DosInt21Handler to pass the SegmentedAddress directly instead of .Linear.
  • Inline the LogFcbWarning / LogFcbDebug private helpers into ~35+ duplicated if (IsEnabled) { _loggerService.Warning/Debug(...) } blocks, and tweak a few XML doc strings.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/Spice86.Core/Emulator/OperatingSystem/DosFcbManager.cs FCB API now takes SegmentedAddress; address converted via MemoryUtils.ToPhysicalAddress; log helpers inlined; some doc comments reworded but <param> docs still say "Linear address".
src/Spice86.Core/Emulator/InterruptHandlers/Dos/DosInt21Handler.cs All FCB call sites updated to pass fcbAddress / stringAddress directly instead of .Linear.
Comments suppressed due to low confidence (2)

src/Spice86.Core/Emulator/OperatingSystem/DosFcbManager.cs:1213

  • MemoryUtils.ToPhysicalAddress(fcbAddress.Segment, fcbAddress.Offset) is computed identically to SegmentedAddress.Linear (both do segment << 4 + offset, see SegmentedAddress.cs:22 and MemoryUtils.cs:20). The repeated explicit call adds verbosity without changing behavior — using fcbAddress.Linear would be clearer and consistent with the rest of the codebase. Note that switching to ToPhysicalAddress does NOT address the segment-rollover concern described in the codebase guidelines, since the formula is identical. If the intent of this refactor was to handle rollover correctly, an MMU-based translation (IMmu.TranslateAddress) should be used instead. This pattern is repeated throughout GetFcb and GetActualFcbBaseAddress.
    private uint GetActualFcbBaseAddress(SegmentedAddress fcbAddress) {
        // Extended FCB detection via drive marker 0xFF
        DosFileControlBlock probe = new DosFileControlBlock(_memory, MemoryUtils.ToPhysicalAddress(fcbAddress.Segment, fcbAddress.Offset));
        if (probe.DriveNumber == 0xFF) {
            return MemoryUtils.ToPhysicalAddress(fcbAddress.Segment, fcbAddress.Offset) + DosExtendedFileControlBlock.HeaderSize;
        }
        return MemoryUtils.ToPhysicalAddress(fcbAddress.Segment, fcbAddress.Offset);
    }

src/Spice86.Core/Emulator/OperatingSystem/DosFcbManager.cs:301

  • Inlining the previous LogFcbWarning / LogFcbDebug helpers duplicates the same if (_loggerService.IsEnabled(...)) { _loggerService.Warning/Debug("FCB {Operation} ...", ...) } block roughly 35+ times. The deleted helpers (former lines 1374–1383) were a clean, low-cost abstraction that ensured a consistent log format and consistent IsEnabled gating. Reintroducing them (or keeping them) would substantially reduce noise in this file and avoid future drift between log call sites. Consider keeping the helpers.
            if (_loggerService.IsEnabled(LogEventLevel.Warning)) {
                _loggerService.Warning("FCB {Operation} failed at 0x{Address:X} because {Reason}", "OPEN", baseAddr, "Blank filename");
            }
            return FcbStatus.Error;
        }

        DosFileOperationResult result = _dosFileManager.OpenFileOrDevice(fileSpec, FileAccessMode.ReadWrite);
        if (result.IsError || result.Value == null) {
            if (_loggerService.IsEnabled(LogEventLevel.Warning)) {
                _loggerService.Warning("FCB {Operation} failed at 0x{Address:X} because {Reason}", "OPEN", baseAddr, "OpenFileOrDevice failed");
            }

Comment thread src/Spice86.Core/Emulator/OperatingSystem/DosFcbManager.cs Outdated
Comment thread tests/Spice86.Tests/Dos/DosFcbManagerTests.cs Fixed
Comment thread tests/Spice86.Tests/Dos/DosFcbManagerTests.cs Fixed
Comment thread tests/Spice86.Tests/Dos/DosFcbManagerTests.cs Fixed
@maximilien-noal maximilien-noal marked this pull request as ready for review May 17, 2026 09:10
All FCB-related methods in DosInt21Handler and DosFcbManager now accept SegmentedAddress instead of raw linear addresses. This makes segment:offset usage explicit, reduces manual address translation, and improves correctness. Address translation to physical addresses is now handled internally where needed, and FCB structure instantiations are updated accordingly.

fix: Inline FCB logs to avoid string allocations

Fix XML doc comments: update param descriptions from "Linear address" to "Segmented address" in DosFcbManager

Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/49811e96-8ffc-42de-9b9f-50e396e4bdb4

Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>

tests: fix FCB tests not building

refactor: removed unused helper in FCB tests
Refactored DosFcbManager.FindFirst to delegate to the unified file search, matching FreeDOS behavior and populating the DTA in the standard extended format. Updated XML docs to clarify this. Rewrote and removed tests in DosFcbManagerTests to expect the extended DTA layout, including for volume label handling.
…ugger)

Updated the project version from 13.1.2 to 14 in Directory.Build.props. Also changed the package release notes link to reference the v14 release notes.
Added "Quick navigation" to README and documented the new I/O port handler system in both README.md and index.html. Introduced a dedicated "I/O Port Handlers" section with usage instructions, a summary table, and callouts. Updated index.html with new callout styles and enhanced navigation, including quick start and compatibility tips.
@maximilien-noal maximilien-noal merged commit c4c92ae into master May 17, 2026
4 checks passed
@maximilien-noal maximilien-noal deleted the fix/civilization branch May 17, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix fixes a bug DOS Related to DOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants