Implement MOUNT/IMGMOUNT/BOOT batch commands, FAT12/16/32 floppy support, multi-image disc switching, 8272A FDC emulation, CDDA, virtual images, write-back, MSCDEX rework, correct BIOS/DOS layering via IFloppyDriveAccess, and full UI integration#2144
Conversation
maximilien-noal
left a comment
There was a problem hiding this comment.
@copilot implement full emulated floppy disk drive support, including images, fat understanding, UI controls and indicators for the drives and with full TDD driven developpement.
All from:
https://github.com/dosbox-staging/dosbox-staging
Respect OOP, SRP, and our way of writing code.
And the mscdex is not a service. It is owned by dos and provided by DOS via a Spice.Shared interface. The UI always use polling to get updates.
maximilien-noal
left a comment
There was a problem hiding this comment.
// ---------- internals ----------
Avoid such comments
MscdexService is mandatory, not nullable.
Seems like sometimes services are injected but not actually used ?
maximilien-noal
left a comment
There was a problem hiding this comment.
@copilot It's weird for the bios layer to depend on DOS, how does dosbox staging does it ?
…ionChanged for HDD Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/90bcbf5f-0249-4712-9878-c86cb767d710 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…y images - Switch FloppyDiskDrive.Image from Fat12FileSystem to FatFileSystem (FAT12/16/32 auto-detection) - Fix defensive guard in FatFileSystem.ReadFat() and DetectFatType(): return empty FAT table instead of throwing OverflowException when TotalSectors=0, SectorsPerCluster=0, or DataStartSector>=TotalSectors - Fix same defensive guard in Fat12FileSystem.ReadFat() - Add try/catch(InvalidDataException/IOException) in Dos.MountImageAsFloppy() so bad images log an error and return gracefully instead of crashing the emulator - Update DriveMenuItemViewModel_HddDrive_IsHddTrue test to reflect that HDD drives now show their volume label in the disabled combobox Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/b474e3fb-224e-489a-b2e4-cc6358e168f5 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…SamplesNormalized, ISoundChannelCreator interface, MscdexService dedup, CD audio for UI mounts, drive-change command in batch engine, stale CurrentDrive fix, FatDirectoryEntry doc fix, test name fix Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/18c10b0d-5502-4e21-aaaf-d6f774499589 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/18c10b0d-5502-4e21-aaaf-d6f774499589 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…st notifications for mount failures - Change CD-ROM drive icon from ArrowEject to Record (disc-shaped symbol) - Add try/catch in MountFolderAsCdRom and MountImageAsCdRom for graceful error handling (ArgumentException, IOException, InvalidDataException) - Add NotifyError() to IDriveEventNotifier interface for error-severity toast notifications - Implement NotifyError() in WindowDriveEventNotifier (NotificationType.Error) and NullDriveEventNotifier - Change IDriveMountService methods to return bool (success/failure) - Update Dos.cs implementations to return bool - Pass IDriveEventNotifier to DriveMenuItemViewModel for error surfacing - DriveMenuItemViewModel.MountFolder/MountImage now fires NotifyError toast on failure - Update all tests to pass notifier to DriveMenuItemViewModel constructor Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/2a1fe491-bcc0-4e8f-afda-1de1831c55fd Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…geAsCdRom, fix dictionary spelling typo - InvalidDataException from IsoImage/CueBinImage constructors is now caught in the same block as CdRomImageFactory.Open() (where it can actually be thrown), eliminating the unreachable catch reported by code review - Fix typo: 'dictionnary' -> 'dictionary' in Dos.cs XML doc Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/2a1fe491-bcc0-4e8f-afda-1de1831c55fd Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/7fb2e4c8-172e-4d51-bba5-757b635c0a59 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…at +8) per DOSBox Staging; FDC uses actual geometry instead of hardcoded 18 sectors/track Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/bb490cad-a612-4282-b563-8d7b7865fbb6 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…/26h RETF (DOSBox Staging parity) Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/021933f6-8689-4e29-be55-683ae3590ffc Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/a6159f16-b8d6-4044-942c-9f8aa238d597 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…ventions Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/a6159f16-b8d6-4044-942c-9f8aa238d597 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/a6159f16-b8d6-4044-942c-9f8aa238d597 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
- SystemClockInt1AHandler: ReadTimeFromRTC/SetRTCTime/ReadDateFromRTC/SetRTCDate now take calledFromVm and use SetCarryFlag, not State.CarryFlag directly; SetRTCTime/SetRTCDate return CF=0 (success), matching DOSBox Staging's CALLBACK_SCF(false) behaviour - DosInt21Handler.GetLeadByteTable: add calledFromVm param, use SetCarryFlag - DosDiskInt25Handler: extract into AbsoluteDiskRead(bool calledFromVm) - DosDiskInt26Handler: extract into AbsoluteDiskWrite(bool calledFromVm) - DosInt2fHandler.MscdexServices: call SetCarryFlag(State.CarryFlag, calledFromVm) after Dispatch() to propagate carry flag to interrupt stack All 1939 tests pass. Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/9e8789b8-5c63-4be6-be51-770acf505bb7 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…or SetCarryFlag pattern consistency Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/46c8554a-c552-458a-a102-172d9c19c12a Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
… 15h) changes out of scope Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/101b98a5-80c0-477f-b7a8-bad473dab446 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…tions - Add no-op cases for AL=0x06/0x07 (debugging on/off) and AL=0x0A (reserved); DOSBox Staging does nothing for these — previously fell to HandleUnknownSubfunction which incorrectly set carry+error - Fix GetSetVolumeDescriptorPreference (AL=0x0E): validate drive via CX, return DX=0x100 (not 0x000) for get, validate DH=1 for set, error on invalid BX/DH; matches DOSBox Staging case 0x150E exactly - Fix AbsoluteDiskWrite (AL=0x09): return AX=1 (MSCDEX_ERROR_INVALID_FUNCTION) per DOSBox Staging case 0x1509; previously returned AX=0 (WriteProtect) - Fix ReadVolumeTableOfContents (AL=0x05): set full AX register with error code computed from VD type byte (1 for PVD, 0xFF for terminator, 0 otherwise), matching DOSBox Staging's 'error = (type == 1) ? 1 : (type == 0xFF) ? 0xFF : 0' - Fix HandleUnknownSubfunction: use MscdexInvalidFunctionError=1 constant matching DOSBox Staging's MSCDEX_ERROR_INVALID_FUNCTION instead of InvalidFunction=22 - Add MscdexInvalidFunctionError=1 constant to match DOSBox Staging - 6 new TDD tests in MscdexSubfunctionTests covering all fixes (1945 total) Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/5c755ebf-c56a-4f4c-8daa-12ca659e90ef Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…fix misleading test comments Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/5c755ebf-c56a-4f4c-8daa-12ca659e90ef Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…lback - Added 11 synthetic WAV files (fdd_spinup.wav, fdd_spin.wav, fdd_seek1-9.wav) to src/Spice86.Core/Resources/DiskNoises/ as EmbeddedResource items - WavPcmLoader: refactored ParseWav() to accept Stream; added TryLoadFromStream() - FloppyDiskNoiseDevice: constructor now accepts pre-loaded float[] samples instead of file paths (cleaner separation of loading vs playback state) - FloppySoundEmulator: LoadSamples() tries on-disk first, falls back to embedded assembly resource Spice86.Core.DiskNoises.<name> - Tests updated to use new float[]-based FloppyDiskNoiseDevice constructor; added EmbeddedResources_AreLoadedWhenNoOnDiskFileExists test - 1946 tests pass, 0 failures Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/75d0c470-979c-43af-a774-80cd6cd2da49 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…rejects AL=0, matching DOSBox Staging Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/323e847e-2f49-4295-9f34-382d22df0103 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…s, matching DOSBox Staging Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/8e7fd3f6-3cb3-4e04-9ff5-7679feef88ce Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…t, matching DOSBox Staging Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/82c58e77-0c8c-4229-a5fc-6f681532f8a5 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
…bchannel, clearer TOC contract, test comments Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/82c58e77-0c8c-4229-a5fc-6f681532f8a5 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
- Fix RequestDataOffset 13→14 (0x0D→0x0E) to match DOSBox Staging's buffer = PhysicalMake(readw(hdr+0x10), readw(hdr+0x0E)) - affects both IOCTL buffer pointer and PlayAudio start LBA/count offsets - Update all IOCTL Input codes to DOSBox Staging values (0x06-0x0F): DeviceStatus=0x06, SectorSize=0x07, VolumeSize=0x08, MediaChanged=0x09, AudioDiskInfo=0x0A, AudioTrackInfo=0x0B, AudioSubchannel=0x0C, UpcCode=0x0E, AudioStatus=0x0F - Add missing IOCTL Input handlers: 0x00 (DeviceHeader), 0x01 (CurrentPosition with HSG/Red Book modes), 0x04 (ChannelControl), 0x0E (UPC BCD encoding) - Fix AudioDiskInfo MSF byte order: fr/sec/min (frame at lowest address) matching DOSBox Staging case 0x0A - Fix AudioTrackInfo: fr/sec/min/0x00/attr (attr moved to offset 6, 0x00 padding at offset 5), matching DOSBox Staging case 0x0B - Fix AudioSubchannel: BCD track number; 0x00 padding at offset 7; absolute MSF at offsets 8-10 (not 7-9), matching DOSBox Staging case 0x0C - Fix AudioStatus: single byte pause flag (not uint16) and MSF format for start/end positions (not raw LBA), matching DOSBox Staging 0x0F - Add IOCTL Output handler (command 0x0C): eject (0x00), lock/unlock (0x01), reset/stop audio (0x02), channel control store (0x03), load media (0x05) - Add channel control state (identity mapping, settable via 0x03) stored in MscdexService; no ICdRomDrive changes needed - Add missing device driver commands: 0x0D/0x0E (device open/close, no-ops); 0x80/0x82 (Read Long with HSG/Red Book and raw/cooked sector modes using RawSectorSize constant); 0x83 (Seek, no-op) - Fix PlayAudio (0x84) to read addressing mode byte at offset 13 and convert Red Book MSF to LBA before calling PlayAudio(), matching DOSBox Staging case 0x84 - Extract RawSectorSize=2352 constant alongside CookedSectorSize=2048 - Update 6 tests: IOCTL codes, AudioStatus MSF format assertions, AudioTrackInfo attr at offset 6, AudioSubchannel 0x00 at offset 7 and abs MSF at 8-10 Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/cc0985ba-0237-4431-98f6-18f11ff09879 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
|
@copilot reveiw and fix everything by comparing with https://github.com/dosbox-staging/dosbox-staging Without going out of scope. Focus on CDs, folders as hard drives, UI toast notifications repeating when mounting an ISO. |
Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/aefce5a3-aa46-412c-8f13-81f5d165ccdf Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
Focused on the concrete repeating-toast bug for CDs in c0cdc21. Root cause: Fix: collect MSCDEX drive letters first, then skip those letters from the Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
maximilien-noal
left a comment
There was a problem hiding this comment.
@copilot working with https://github.com/dosbox-staging/dosbox-staging and our path for BIOS file support in consideration, support fully the BOOT.COM command when booting a flopy image.
(Ignore booting on a hard disk drive image, and hard disk drive images too)
Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/2be32bc0-adca-4b99-b12d-094c9ad53853 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
Implemented Production:
TDD: 9 new tests cover sector placement, register layout for A: and B:, signature validation, hard-disk rejection, and end-to-end batch-engine wiring ( Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Agent-Logs-Url: https://github.com/OpenRakis/Spice86/sessions/2be32bc0-adca-4b99-b12d-094c9ad53853 Co-authored-by: maximilien-noal <1087524+maximilien-noal@users.noreply.github.com>
Description of Changes
BiosParameterBlock,FatDirectoryEntry,Fat12FileSystem) with full cluster-chain traversalFatFileSystemwithFatTypeenum; Microsoft-spec cluster-count type detection; correct cluster arithmetic for all three FAT variantsFloppyDiskDrive.ApplyCurrentImage()now usesFatFileSystem(FAT12/16/32 auto-detection) instead of the FAT12-onlyFat12FileSystem, preventingOverflowExceptioncrashes when mounting larger or non-standard floppy images (e.g. FAT16 images with >4084 clusters); defensive overflow guards added toFatFileSystem.ReadFat()andDetectFatType()for degenerate BPB values;Dos.MountImageAsFloppy()catchesInvalidDataException/IOExceptionand logs a user-readable error instead of crashingFloppyDiskDriveimage list stores(byte[], string, bool isDirty)tuples;MarkDirty(),IsDirty, andFlushToDisk()operate per-image and reset on image swapISoundChannelCreatorinterface:Dos,DosBatchExecutionEngine, andDosProcessManagerdepend onISoundChannelCreator(implemented bySoftwareMixer) instead of a nullableSoftwareMixer?; CD audio player is wired for UI-mounted CD-ROM drivesX:):DosBatchExecutionEnginerecognises bare drive-letter tokens (e.g.C:) as drive-change commands, matching DOSBox StagingBOOTbatch command for floppy images (DOSBox Staging parity): newBootCommandHandlerandBootFloppyLaunchRequest;TryHandleBootparsesBOOT [image...] [-l A|B], mounts an image on-the-fly when a path is supplied, validates the 0xAA55 boot signature, and rejects hard-disk drive letters (HDD images explicitly out of scope per task).DosProcessManager.BootFromFloppywrites sector 0 to physical 0x7C00 and sets up CPU registers per BIOS bootstrap convention (CS:IP=0000:7C00, SS:SP=0000:7C00, DL=0/1, BX=7C00, CX=1, IF=1) - matching DOSBox Stagingboot.cpp.DosProgramLoader.LoadLaunchRequestdispatches the new request after AUTOEXEC.BATMscdexServiceduplicate-entry prevention:AddDrive()replaces any existing entry for the same drive letterDos.GetDriveStatuses()no longer returns both aFixedand aCdRomentry for MSCDEX-mounted CD letters, fixing a UI bug that caused repeating "ejected"/"mounted" toast notifications every poll tickSeekOnlyguard inFloppyDiskNoiseDevice.ActivateSpin()andAddSamplesNormalizedinFloppySoundEmulatorfor correct floppy noise behaviourEmbeddedResourceitems inSpice86.CoreIDriveStatusProvider), Avalonia toast notifications for drive events, multi-image disc switching via Ctrl-F4 (IDiscSwapper)Rationale behind Changes
DOS games and tools commonly require FAT12/16 floppy images, ISO/CUE+BIN CD-ROMs, MSCDEX, and MOUNT/IMGMOUNT/BOOT batch commands to install and run. Spice86 previously only supported a host-folder shell drive, which prevented running titles that bootstrap from raw floppy/CD images, switch discs mid-game, or rely on a real DOS bootstrap (e.g. boot sectors). Aligning the storage stack and batch command surface with DOSBox Staging makes those workflows possible while keeping clean architectural boundaries (BIOS depends only on
IFloppyDriveAccess, MSCDEX is owned by DOS, UI uses polling).Suggested Testing Steps
dotnet test tests/Spice86.Tests- 1962 tests pass--CDrive'd folder runMOUNT D /path/to/folder,IMGMOUNT D "C:\my games\disc.iso" -t iso, andBOOT image.img -l Ato verify drive-letter, image, and boot bootstrapping