Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@ public override void Run() {
/// The number of potentially valid drive letters in AL.
/// </returns>
public void SelectDefaultDrive() {
if(_dosDriveManager.TryGetValue(DosDriveManager.DriveLetters.ElementAtOrDefault(State.DL).Key, out VirtualDrive? mountedDrive)) {
if(_dosDriveManager.TryGetValue(DosDriveManager.DriveLetters.ElementAtOrDefault(State.DL).Key, out HostFolderDrive? mountedDrive)) {
_dosDriveManager.CurrentDrive = mountedDrive;
}
if (State.DL > DosDriveManager.MaxDriveCount && LoggerService.IsEnabled(LogEventLevel.Error)) {
Expand Down
52 changes: 26 additions & 26 deletions src/Spice86.Core/Emulator/OperatingSystem/DosDriveManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
/// <summary>
/// The class responsible for centralizing all the mounted DOS drives.
/// </summary>
public class DosDriveManager : IDictionary<char, VirtualDrive> {
private readonly SortedDictionary<char, VirtualDrive?> _driveMap = new();
public class DosDriveManager : IDictionary<char, HostFolderDrive> {
private readonly SortedDictionary<char, HostFolderDrive?> _driveMap = new();
private readonly ILoggerService _loggerService;

/// <summary>
Expand All @@ -31,7 +31,7 @@ public DosDriveManager(ILoggerService loggerService, string? cDriveFolderPath, s
cDriveFolderPath = ConvertUtils.ToSlashFolderPath(cDriveFolderPath);
_driveMap.Add('A', null);
_driveMap.Add('B', null);
_driveMap.Add('C', new VirtualDrive { DriveLetter = 'C', MountedHostDirectory = cDriveFolderPath, CurrentDosDirectory = "" });
_driveMap.Add('C', new HostFolderDrive { DriveLetter = 'C', MountedHostDirectory = cDriveFolderPath, CurrentDosDirectory = "" });
CurrentDrive = _driveMap.ElementAt(2).Value!;
if(loggerService.IsEnabled(Serilog.Events.LogEventLevel.Verbose)) {
loggerService.Verbose("DOS Drives initialized: {@Drives}", _driveMap.Values);
Expand All @@ -41,7 +41,7 @@ public DosDriveManager(ILoggerService loggerService, string? cDriveFolderPath, s
/// <summary>
/// The currently selected drive.
/// </summary>
public VirtualDrive CurrentDrive { get; set; }
public HostFolderDrive CurrentDrive { get; set; }

internal static readonly ImmutableSortedDictionary<char, byte> DriveLetters = new Dictionary<char, byte>() {
{ 'A', 0 },
Expand Down Expand Up @@ -92,57 +92,57 @@ public byte NumberOfPotentiallyValidDriveLetters {
}
}

public ICollection<char> Keys => ((IDictionary<char, VirtualDrive>)_driveMap).Keys;
public ICollection<char> Keys => ((IDictionary<char, HostFolderDrive>)_driveMap).Keys;

public ICollection<VirtualDrive> Values => ((IDictionary<char, VirtualDrive>)_driveMap).Values;
public ICollection<HostFolderDrive> Values => ((IDictionary<char, HostFolderDrive>)_driveMap).Values;

public int Count => ((ICollection<KeyValuePair<char, VirtualDrive>>)_driveMap).Count;
public int Count => ((ICollection<KeyValuePair<char, HostFolderDrive>>)_driveMap).Count;

public bool IsReadOnly => ((ICollection<KeyValuePair<char, VirtualDrive>>)_driveMap).IsReadOnly;
public bool IsReadOnly => ((ICollection<KeyValuePair<char, HostFolderDrive>>)_driveMap).IsReadOnly;

public VirtualDrive this[char key] { get => ((IDictionary<char, VirtualDrive>)_driveMap)[key]; set => ((IDictionary<char, VirtualDrive>)_driveMap)[key] = value; }
public HostFolderDrive this[char key] { get => ((IDictionary<char, HostFolderDrive>)_driveMap)[key]; set => ((IDictionary<char, HostFolderDrive>)_driveMap)[key] = value; }


public const int MaxDriveCount = 26;

public void Add(char key, VirtualDrive value) {
((IDictionary<char, VirtualDrive>)_driveMap).Add(key, value);
public void Add(char key, HostFolderDrive value) {
((IDictionary<char, HostFolderDrive>)_driveMap).Add(key, value);
}

public bool ContainsKey(char key) {
return ((IDictionary<char, VirtualDrive>)_driveMap).ContainsKey(key);
return ((IDictionary<char, HostFolderDrive>)_driveMap).ContainsKey(key);
}

public bool Remove(char key) {
return ((IDictionary<char, VirtualDrive>)_driveMap).Remove(key);
return ((IDictionary<char, HostFolderDrive>)_driveMap).Remove(key);
}

public bool TryGetValue(char key, [MaybeNullWhen(false)] out VirtualDrive value) {
return ((IDictionary<char, VirtualDrive>)_driveMap).TryGetValue(key, out value);
public bool TryGetValue(char key, [MaybeNullWhen(false)] out HostFolderDrive value) {
return ((IDictionary<char, HostFolderDrive>)_driveMap).TryGetValue(key, out value);
}

public void Add(KeyValuePair<char, VirtualDrive> item) {
((ICollection<KeyValuePair<char, VirtualDrive>>)_driveMap).Add(item);
public void Add(KeyValuePair<char, HostFolderDrive> item) {
((ICollection<KeyValuePair<char, HostFolderDrive>>)_driveMap).Add(item);
}

public void Clear() {
((ICollection<KeyValuePair<char, VirtualDrive>>)_driveMap).Clear();
((ICollection<KeyValuePair<char, HostFolderDrive>>)_driveMap).Clear();
}

public bool Contains(KeyValuePair<char, VirtualDrive> item) {
return ((ICollection<KeyValuePair<char, VirtualDrive>>)_driveMap).Contains(item);
public bool Contains(KeyValuePair<char, HostFolderDrive> item) {
return ((ICollection<KeyValuePair<char, HostFolderDrive>>)_driveMap).Contains(item);
}

public void CopyTo(KeyValuePair<char, VirtualDrive>[] array, int arrayIndex) {
((ICollection<KeyValuePair<char, VirtualDrive>>)_driveMap).CopyTo(array, arrayIndex);
public void CopyTo(KeyValuePair<char, HostFolderDrive>[] array, int arrayIndex) {
((ICollection<KeyValuePair<char, HostFolderDrive>>)_driveMap).CopyTo(array, arrayIndex);
}

public bool Remove(KeyValuePair<char, VirtualDrive> item) {
return ((ICollection<KeyValuePair<char, VirtualDrive>>)_driveMap).Remove(item);
public bool Remove(KeyValuePair<char, HostFolderDrive> item) {
return ((ICollection<KeyValuePair<char, HostFolderDrive>>)_driveMap).Remove(item);
}

public IEnumerator<KeyValuePair<char, VirtualDrive>> GetEnumerator() {
return ((IEnumerable<KeyValuePair<char, VirtualDrive>>)_driveMap).GetEnumerator();
public IEnumerator<KeyValuePair<char, HostFolderDrive>> GetEnumerator() {
return ((IEnumerable<KeyValuePair<char, HostFolderDrive>>)_driveMap).GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ public DosFileOperationResult IoControl(State state) {
{
// 1) Build the 11-byte volume label (padded with spaces)
// 1) pull the raw label (or default), split name/ext
VirtualDrive vDrive = _dosDriveManager.ElementAtOrDefault(drive).Value;
HostFolderDrive vDrive = _dosDriveManager.ElementAtOrDefault(drive).Value;
string driveLabel = vDrive.Label.ToUpperInvariant();


Expand Down
8 changes: 4 additions & 4 deletions src/Spice86.Core/Emulator/OperatingSystem/DosPathResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ public DosPathResolver(DosDriveManager dosDriveManager) {
public DosFileOperationResult GetCurrentDosDirectory(byte driveNumber, out string currentDir) {
//0 = default drive
if (driveNumber == 0 && _dosDriveManager.Count > 0) {
VirtualDrive virtualDrive = _dosDriveManager.CurrentDrive;
HostFolderDrive virtualDrive = _dosDriveManager.CurrentDrive;
currentDir = virtualDrive.CurrentDosDirectory;
return DosFileOperationResult.NoValue();
} else {
char driveLetter = DosDriveManager.DriveLetters.Keys.ElementAtOrDefault(driveNumber - 1);
if (_dosDriveManager.TryGetValue(driveLetter,
out VirtualDrive? virtualDrive)) {
out HostFolderDrive? virtualDrive)) {
currentDir = virtualDrive.CurrentDosDirectory;
return DosFileOperationResult.NoValue();
}
Expand All @@ -50,7 +50,7 @@ public DosFileOperationResult GetCurrentDosDirectory(byte driveNumber, out strin
return DosFileOperationResult.Error(DosErrorCode.InvalidDrive);
}

private static string GetFullCurrentDosPathOnDrive(VirtualDrive virtualDrive) =>
private static string GetFullCurrentDosPathOnDrive(HostFolderDrive virtualDrive) =>
Path.Combine($"{virtualDrive.DosVolume}{DirectorySeparatorChar}", virtualDrive.CurrentDosDirectory);

internal static string GetExeParentFolder(string? exe) {
Expand All @@ -62,7 +62,7 @@ internal static string GetExeParentFolder(string? exe) {
return string.IsNullOrWhiteSpace(parent) ? fallbackValue : ConvertUtils.ToSlashFolderPath(parent);
}

private static bool IsWithinMountPoint(string hostFullPath, VirtualDrive virtualDrive) => hostFullPath.StartsWith(virtualDrive.MountedHostDirectory);
private static bool IsWithinMountPoint(string hostFullPath, HostFolderDrive virtualDrive) => hostFullPath.StartsWith(virtualDrive.MountedHostDirectory);

/// <summary>
/// Sets the current DOS folder.
Expand Down
24 changes: 24 additions & 0 deletions src/Spice86.Core/Emulator/OperatingSystem/Programs/AutoExecFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Spice86.Core.Emulator.OperatingSystem.Programs;

using Spice86.Core.Emulator.OperatingSystem.Structures;

internal class AutoExecFile : IVirtualFile {
private readonly Configuration _configuration;

public AutoExecFile(Configuration configuration) {
_configuration = configuration;
}

public string Name {
get => "AUTOEXEC.BAT";
set => throw new InvalidOperationException("Cannot rename a built-in operating system file");
}

public IEnumerable<string> GetLines() {
string? hostFilePath = _configuration.Exe;
string? arguments = _configuration.ExeArgs;
string? cDrivePath = _configuration.CDrive;
string commandLine = $"{Path.GetRelativePath(cDrivePath!, hostFilePath!)} {arguments}";
yield return commandLine;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Spice86.Core.Emulator.OperatingSystem.Programs;

using Spice86.Core.Emulator.InterruptHandlers.Common.MemoryWriter;
using Spice86.Core.Emulator.Memory.ReaderWriter;

internal class CommandInterpreter : DosInternalProgram {
public CommandInterpreter(MemoryAsmWriter memoryAsmWriter, IByteReaderWriter byteReaderWriter, uint baseAddress)
: base(memoryAsmWriter, byteReaderWriter, baseAddress) {

}

public override string Name {
get => "COMMAND.COM";
set => throw new InvalidOperationException("Cannot rename a built-in operating system file");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Spice86.Core.Emulator.OperatingSystem.Programs;

using Spice86.Core.Emulator.InterruptHandlers.Common.MemoryWriter;
using Spice86.Core.Emulator.Memory.ReaderWriter;
using Spice86.Core.Emulator.OperatingSystem.Structures;

internal abstract class DosInternalProgram : DosProgramSegmentPrefix, IVirtualFile {
protected DosInternalProgram(MemoryAsmWriter memoryAsmWriter,
IByteReaderWriter byteReaderWriter, uint baseAddress)
: base(byteReaderWriter, baseAddress) {
}

public abstract string Name { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace Spice86.Core.Emulator.OperatingSystem.Structures;

using Spice86.Core.Emulator.InterruptHandlers.Common.MemoryWriter;
using Spice86.Core.Emulator.Memory.ReaderWriter;
using Spice86.Core.Emulator.ReverseEngineer.DataStructure;
using Spice86.Core.Emulator.ReverseEngineer.DataStructure.Array;
Expand All @@ -10,10 +11,13 @@
/// Represents the Program Segment Prefix (PSP)
/// </summary>
[DebuggerDisplay("BaseAddress={BaseAddress}, Parent={ParentProgramSegmentPrefix}, EnvSegment={EnvironmentTableSegment}, NextSegment={NextSegment}, StackPointer={StackPointer}, Cmd={DosCommandTail.Command}")]
public sealed class DosProgramSegmentPrefix : MemoryBasedDataStructure {
public class DosProgramSegmentPrefix : MemoryBasedDataStructure {
public const ushort MaxLength = 0x80 + 128;

public DosProgramSegmentPrefix(IByteReaderWriter byteReaderWriter, uint baseAddress) : base(byteReaderWriter, baseAddress) {
public DosProgramSegmentPrefix(IByteReaderWriter byteReaderWriter, uint baseAddress)
: base(byteReaderWriter, baseAddress) {
Exit[0] = 0xCD; // INT instruction
Exit[1] = 0x20; // DOS INT 20h
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
/// Represents a disk image mounted as a floppy disk drive.
/// </summary>
/// <remarks>Unimplemented.</remarks>
public class FloppyDiskDrive : DosDriveBase {
public FloppyDiskDrive() {
public class FloppyDiskImage : DosDriveBase {
public FloppyDiskImage() {
IsRemovable = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/// <summary>
/// Represents a host folder used as a drive by DOS.
/// </summary>
public class VirtualDrive : DosDriveBase {
public class HostFolderDrive : DosDriveBase {
/// <summary>
/// The full host path to the mounted folder. This path serves as the root of the DOS drive.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
namespace Spice86.Core.Emulator.OperatingSystem.Structures;

using System.ComponentModel.DataAnnotations;

public interface IVirtualFile {
/// <summary>
/// The DOS file name of the file or device.
/// </summary>
[Range(0, 13)]
public string Name { get; set; }
}
Loading