public ReadOnlySpan <byte> Invoke(ushort ordinal, bool offsetsOnly = false) { if (offsetsOnly) { var methodPointer = new FarPtr(0xFFFC, ordinal); #if DEBUG //_logger.Debug($"({Module.ModuleIdentifier}) Returning Method Offset {methodPointer.Segment:X4}:{methodPointer.Offset:X4}"); #endif return(methodPointer.Data); } switch (ordinal) { case 49: DosRealIntr(); break; case 16: DosAllocRealSeg(); break; default: throw new ArgumentOutOfRangeException($"Unknown Exported Function Ordinal in PHAPI: {ordinal}"); } return(null); }
public void ToInt32(ushort segment, ushort offset, uint expected) { var farPtr = new FarPtr(segment, offset); farPtr.ToUInt32().Should().Be(expected); farPtr.GetHashCode().Should().Be((int)expected); }
/// <summary> /// Tells the module to begin x86 execution at the specified Entry Point /// </summary> /// <param name="entryPoint">Entry Point where execution will begin</param> /// <param name="channelNumber">Channel Number calling for execution</param> /// <param name="simulateCallFar">Are we simulating a CALL FAR? This is usually when we're calling a local function pointer</param> /// <param name="bypassSetState">Should we bypass setting a startup state? This is true for execution of things like Text Variable processing</param> /// <param name="initialStackValues">Initial Stack Values to be pushed to the stack prior to executing (simulating parameters on a method call)</param> /// <param name="initialStackPointer"> /// Initial Stack Pointer Value. Because EU's share the same memory space, including stack space, we need to sometimes need to manually decrement the /// stack pointer enough to where the stack on the nested call won't overlap with the stack on the parent caller. /// </param> /// <returns></returns> public CpuRegisters Execute(FarPtr entryPoint, ushort channelNumber, bool simulateCallFar = false, bool bypassSetState = false, Queue <ushort> initialStackValues = null, ushort initialStackPointer = CpuCore.STACK_BASE) { //Set the proper DLL making the call based on the Segment for (ushort i = 0; i < ModuleDlls.Count; i++) { var dll = ModuleDlls[i]; if (entryPoint.Segment >= dll.SegmentOffset && entryPoint.Segment <= (dll.SegmentOffset + dll.File.SegmentTable.Count)) { foreach (var(_, value) in ExportedModuleDictionary) { ((ExportedModuleBase)value).ModuleDll = i; } } } //Try to dequeue an execution unit, if one doesn't exist, create a new one if (!ExecutionUnits.TryDequeue(out var executionUnit)) { _logger.Debug($"({ModuleIdentifier}) Exhausted execution Units, creating additional"); executionUnit = new ExecutionUnit(Memory, _clock, ExportedModuleDictionary, _logger, ModulePath); } var resultRegisters = executionUnit.Execute(entryPoint, channelNumber, simulateCallFar, bypassSetState, initialStackValues, initialStackPointer); ExecutionUnits.Enqueue(executionUnit); return(resultRegisters); }
public void ConstructsFromArray() { var farPtr = new FarPtr((new byte[] { 0x10, 0x20, 0x30, 0x40 })); farPtr.Segment.Should().Be(0x4030); farPtr.Offset.Should().Be(0x2010); }
protected short fclose(FarPtr filep) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FCLOSE_ORDINAL, new List <FarPtr> { filep }); return((short)mbbsEmuCpuRegisters.AX); }
protected short fflush(FarPtr srcPtr) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FFLUSH_ORDINAL, new List <FarPtr> { srcPtr }); return((short)mbbsEmuCpuRegisters.AX); }
public void PreUnaryAddition() { var farPtr = new FarPtr(50, 0xFFFE); (++farPtr).Should().Be(new FarPtr(50, 0xFFFF)); (++farPtr).Should().Be(new FarPtr(50, 0)); (++farPtr).Should().Be(new FarPtr(50, 1)); }
public void PostUnaryAddition() { var farPtr = new FarPtr(50, 0xFFFE); (farPtr++).Should().Be(new FarPtr(50, 0xFFFE)); (farPtr++).Should().Be(new FarPtr(50, 0xFFFF)); (farPtr++).Should().Be(new FarPtr(50, 0)); }
public void PreUnarySubtraction() { var farPtr = new FarPtr(50, 1); (--farPtr).Should().Be(new FarPtr(50, 0)); (--farPtr).Should().Be(new FarPtr(50, 0xFFFF)); (--farPtr).Should().Be(new FarPtr(50, 0xFFFE)); }
public void PostUnarySubtraction() { var farPtr = new FarPtr(50, 1); (farPtr--).Should().Be(new FarPtr(50, 1)); (farPtr--).Should().Be(new FarPtr(50, 0)); (farPtr--).Should().Be(new FarPtr(50, 0xFFFF)); }
protected ushort fgetc(FarPtr srcPtr) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FGETC_ORDINAL, new List <FarPtr> { srcPtr }); return(mbbsEmuCpuRegisters.AX); }
protected ushort fputs(FarPtr putStringPtr, FarPtr srcPtr) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FPUTS_ORDINAL, new List <FarPtr> { putStringPtr, srcPtr }); return(mbbsEmuCpuRegisters.AX); }
private string GetFileFromFndblk(FarPtr fndblkPointer) { var fbs = new FndblkStruct(mbbsEmuMemoryCore.GetArray(fndblkPointer, FndblkStruct.StructSize)); Assert.Equal(9, fbs.Size); Assert.Equal(0, (byte)fbs.Attributes & (byte)~FndblkStruct.AttributeFlags.Archive); Assert.True(Math.Abs(ticksNow - fbs.DateTime.Ticks) <= FIVE_SECOND_TICKS); return(fbs.Name); }
public void MemoryMap_DWord() { var memoryCore = new RealModeMemoryCore(_logger); // these two point to the same physical address var ptr1 = new FarPtr(0x6002, 0x12); var ptr2 = new FarPtr(0x6003, 2); (memoryCore as IMemoryCore).SetDWord(ptr1, 0x10203040); (memoryCore as IMemoryCore).GetDWord(ptr1).Should().Be(0x10203040); (memoryCore as IMemoryCore).GetDWord(ptr2).Should().Be(0x10203040); }
protected ushort fputc(ushort putChar, FarPtr srcPtr) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FPUTC_ORDINAL, new List <ushort> { putChar, srcPtr.Offset, srcPtr.Segment }); return(mbbsEmuCpuRegisters.AX); }
public int WriteTo(IMemoryCore memoryCore, FarPtr ptr) { memoryCore.SetWord(ptr, record_length); memoryCore.SetWord(ptr + 2, page_size); memoryCore.SetWord(ptr + 4, number_of_keys); memoryCore.SetDWord(ptr + 6, number_of_records); memoryCore.SetWord(ptr + 10, flags); memoryCore.SetWord(ptr + 12, reserved); memoryCore.SetWord(ptr + 14, unused_pages); return(16); }
public void MemoryMap_StringStripNull() { var str = "This is a test"; var memoryCore = new RealModeMemoryCore(_logger); // these two point to the same physical address var ptr1 = new FarPtr(0x6002, 0x12); var ptr2 = new FarPtr(0x6003, 2); (memoryCore as IMemoryCore).SetArray(ptr1, Encoding.ASCII.GetBytes(str + "\0")); Encoding.ASCII.GetString((memoryCore as IMemoryCore).GetString(ptr1, stripNull: true)).Should().Be(str); Encoding.ASCII.GetString((memoryCore as IMemoryCore).GetString(ptr2, stripNull: true)).Should().Be(str); }
public void MemoryMap_Array() { var bytes = new byte[] { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 }; var memoryCore = new RealModeMemoryCore(_logger); // these two point to the same physical address var ptr1 = new FarPtr(0x6002, 0x12); var ptr2 = new FarPtr(0x6003, 2); (memoryCore as IMemoryCore).SetArray(ptr1, bytes); (memoryCore as IMemoryCore).GetArray(ptr1, (ushort)bytes.Length).ToArray().Should().BeEquivalentTo(bytes); (memoryCore as IMemoryCore).GetArray(ptr2, (ushort)bytes.Length).ToArray().Should().BeEquivalentTo(bytes); }
protected ushort read(ushort fd, FarPtr destPtr, ushort count) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, READ_ORDINAL, new List <ushort> { fd, destPtr.Offset, destPtr.Segment, count }); return(mbbsEmuCpuRegisters.AX); }
public void Equality(ushort leftSegment, ushort leftOffset, ushort rightSegment, ushort rightOffset, bool expectedEquality) { var left = new FarPtr(leftSegment, leftOffset); var right = new FarPtr(rightSegment, rightOffset); left.Equals(right).Should().Be(expectedEquality); right.Equals(left).Should().Be(expectedEquality); (left == right).Should().Be(expectedEquality); (right == left).Should().Be(expectedEquality); (left != right).Should().Be(!expectedEquality); (right != left).Should().Be(!expectedEquality); }
protected ushort write(ushort fd, FarPtr srcPtr, ushort count) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, WRITE_ORDINAL, new List <ushort> { fd, srcPtr.Offset, srcPtr.Segment, count, }); return(mbbsEmuCpuRegisters.AX); }
protected FarPtr fgets(FarPtr putStringPtr, ushort numChars, FarPtr srcPtr) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FGETS_ORDINAL, new List <ushort> { putStringPtr.Offset, putStringPtr.Segment, numChars, srcPtr.Offset, srcPtr.Segment }); return(mbbsEmuCpuRegisters.GetPointer()); }
public int WriteTo(IMemoryCore memoryCore, FarPtr ptr) { memoryCore.SetWord(ptr, position); memoryCore.SetWord(ptr + 2, length); memoryCore.SetWord(ptr + 4, flags); memoryCore.SetDWord(ptr + 6, number_of_keys); memoryCore.SetByte(ptr + 10, data_type); memoryCore.SetByte(ptr + 11, null_value); memoryCore.SetWord(ptr + 12, unused); memoryCore.SetByte(ptr + 14, number_only_if_explicit_key_flag_is_set); memoryCore.SetByte(ptr + 15, acs_number); return(16); }
public ModuleStruct() { descrp = new byte[25]; lonrou = new FarPtr(); sttrou = new FarPtr(); stsrou = new FarPtr(); injrou = new FarPtr(); lofrou = new FarPtr(); huprou = new FarPtr(); mcurou = new FarPtr(); dlarou = new FarPtr(); finrou = new FarPtr(); }
protected ushort fseek(FarPtr srcPtr, int offset, ushort origin) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FSEEK_ORDINAL, new List <ushort> { srcPtr.Offset, srcPtr.Segment, (ushort)offset, (ushort)(offset >> 16), origin }); return(mbbsEmuCpuRegisters.AX); }
public void strlen(string str, ushort expectedLength) { Reset(); mbbsEmuProtectedModeMemoryCore.AddSegment(0); mbbsEmuProtectedModeMemoryCore.AddSegment(2); mbbsEmuCpuRegisters.DS = mbbsEmuCpuRegisters.ES = 2; mbbsEmuCpuRegisters.SS = 0; mbbsEmuCpuRegisters.SP = 0x100; var strPtr = new FarPtr(mbbsEmuCpuRegisters.DS, 0x1000); mbbsEmuMemoryCore.SetArray(strPtr, Encoding.ASCII.GetBytes(str + "\0")); var instructions = new Assembler(16); var strlen = instructions.CreateLabel(); instructions.push(strPtr.Offset); instructions.call(strlen); instructions.hlt(); /* * str = word ptr 4 */ instructions.Label(ref strlen); instructions.push(bp); instructions.mov(bp, sp); instructions.push(di); instructions.push(cx); instructions.mov(di, __word_ptr[bp + 4]); // str instructions.mov(cx, -1); instructions.xor(al, al); // search for null instructions.cld(); instructions.repne.scasb(); instructions.not(cx); instructions.mov(ax, cx); instructions.dec(ax); instructions.pop(cx); instructions.pop(di); instructions.pop(bp); instructions.ret(); CreateCodeSegment(instructions); while (!mbbsEmuCpuRegisters.Halt) { mbbsEmuCpuCore.Tick(); } mbbsEmuCpuRegisters.AX.Should().Be(expectedLength); }
protected ushort fwrite(FarPtr srcPtr, ushort size, ushort count, FarPtr filep) { ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FWRITE_ORDINAL, new List <ushort> { srcPtr.Offset, srcPtr.Segment, size, count, filep.Offset, filep.Segment, }); return(mbbsEmuCpuRegisters.AX); }
public void EqualityNull() { FarPtr.Empty.Equals(null).Should().BeFalse(); (FarPtr.Empty == null).Should().BeFalse(); (null == FarPtr.Empty).Should().BeFalse(); (FarPtr.Empty != null).Should().BeTrue(); (null != FarPtr.Empty).Should().BeTrue(); FarPtr left = null; FarPtr right = null; (left == right).Should().BeTrue(); (left != right).Should().BeFalse(); }
public void AlignmentAllocations() { var allocator = new MemoryAllocator(_logger, new FarPtr(SEGMENT, 0), 0x1000, alignment: 16); int expectedAllocations = 0x1000 / 32; int allocations = 0; for (FarPtr ptr = allocator.Malloc(31); !ptr.IsNull(); ptr = allocator.Malloc(31)) { allocator.GetAllocatedMemorySize(ptr).Should().Be(32); ptr.IsAligned(16).Should().BeTrue(); ++allocations; } allocations.Should().Be(expectedAllocations); }
public void GreaterOrLess(ushort leftSegment, ushort leftOffset, ushort rightSegment, ushort rightOffset, bool greater) { var left = new FarPtr(leftSegment, leftOffset); var right = new FarPtr(rightSegment, rightOffset); (left > right).Should().Be(greater); (left >= right).Should().Be(greater); (right > left).Should().Be(!greater); (right >= left).Should().Be(!greater); (left < right).Should().Be(!greater); (left <= right).Should().Be(!greater); (right < left).Should().Be(greater); (right <= left).Should().Be(greater); }