/// <summary> /// Marks a newly-allocated block as belonging to a process. /// </summary> /// <param name="block">New block to mark.</param> /// <param name="process">Process which allocated the block.</param> /// <returns>Address of allocated block.</returns> private ushort MarkBlock(MemoryControlBlock block, DosProcess process) { block.PspSegment = process.PrefixSegment; block.ImageName = process.ImageName; block.Write(memory); return((ushort)(block.Segment + 1)); }
/// <summary> /// Attempts to allocate a block of memory of a specified size. /// </summary> /// <param name="requestedSize">Size of allocation in 16-byte paragraphs.</param> /// <param name="process">Process that is making the allocation.</param> /// <returns>Segment of allocated memory if successful; zero if there is insufficient memory available.</returns> public ushort Allocate(ushort requestedSize, DosProcess process) { // First check for free blocks in the list. var block = FindNextAllocationBlock(requestedSize); if (block != null) { // Special case for if the block is exactly the right size. if (block.Length == requestedSize) { return(MarkBlock(block, process)); } ushort address; // Otherwise split the block. if (this.AllocationStrategy == AllocationStrategy.LowLastFit || this.AllocationStrategy == AllocationStrategy.HighLowLastFit) { var newBlock = SplitFreeBlockAtEnd(block, requestedSize); address = MarkBlock(newBlock, process); } else { SplitFreeBlock(block, requestedSize); address = MarkBlock(block, process); } Consolidate(); return(address); } // Return 0 if there is not enough memory available. return(0); }
/// <summary> /// Finds a file and writes information about it to the disk transfer area. /// </summary> /// <param name="process">Process requesting the find.</param> public void FindFirstFile(DosProcess process) { var fileName = vm.PhysicalMemory.GetString(vm.Processor.DS, (ushort)vm.Processor.DX, ushort.MaxValue, 0); if (IsValidSearchPath(fileName)) { var path = vm.FileSystem.ResolvePath(new VirtualPath(fileName)); var files = vm.FileSystem.GetDirectory(path, (VirtualFileAttributes)vm.Processor.CX); if (files.Result != null) { this.findFiles = new Queue <VirtualFileInfo>(files.Result); WriteFindInfo(process.DiskTransferAreaSegment, process.DiskTransferAreaOffset); } else { vm.Processor.AX = (short)files.ErrorCode; vm.Processor.Flags.Carry = true; this.findFiles = null; } } else { vm.Processor.AX = 2; vm.Processor.Flags.Carry = true; findFiles = null; } }
/// <summary> /// Reassignes ownership of an allocation to a new process. /// </summary> /// <param name="segment">Segment of allocation to change ownership on.</param> /// <param name="newOwner">New owner process of the allocation.</param> public void Reassign(ushort segment, DosProcess newOwner) { var block = FindBlock(segment); if (block == null) { throw new ArgumentException("Invalid segment address.", "segment"); } block.PspSegment = newOwner.PrefixSegment; block.ImageName = newOwner.ImageName; block.Write(memory); }
/// <summary> /// Finds the next file and writes information about it to the disk transfer area. /// </summary> /// <param name="process">Process requesting the find.</param> public void FindNextFile(DosProcess process) { WriteFindInfo(process.DiskTransferAreaSegment, process.DiskTransferAreaOffset); }
/// <summary> /// Sets the address of the disk transfer area of a process. /// </summary> /// <param name="process">Process whose DTA will be updated.</param> public void SetDiskTransferAddress(DosProcess process) { process.DiskTransferAreaSegment = vm.Processor.DS; process.DiskTransferAreaOffset = (ushort)vm.Processor.DX; }
/// <summary> /// Gets the address of the disk transfer area of a process. /// </summary> /// <param name="process">Process whose DTA will be returned.</param> public void GetDiskTransferAddress(DosProcess process) { vm.WriteSegmentRegister(SegmentIndex.ES, process.DiskTransferAreaSegment); vm.Processor.BX = (short)process.DiskTransferAreaOffset; }