Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        public void ConstructsFromArray()
        {
            var farPtr = new FarPtr((new byte[] { 0x10, 0x20, 0x30, 0x40 }));

            farPtr.Segment.Should().Be(0x4030);
            farPtr.Offset.Should().Be(0x2010);
        }
Exemple #5
0
        protected short fclose(FarPtr filep)
        {
            ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FCLOSE_ORDINAL, new List <FarPtr> {
                filep
            });

            return((short)mbbsEmuCpuRegisters.AX);
        }
Exemple #6
0
        protected short fflush(FarPtr srcPtr)
        {
            ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FFLUSH_ORDINAL, new List <FarPtr> {
                srcPtr
            });

            return((short)mbbsEmuCpuRegisters.AX);
        }
Exemple #7
0
        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));
        }
Exemple #8
0
        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));
        }
Exemple #9
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));
        }
Exemple #10
0
        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));
        }
Exemple #11
0
        protected ushort fgetc(FarPtr srcPtr)
        {
            ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FGETC_ORDINAL, new List <FarPtr>
            {
                srcPtr
            });

            return(mbbsEmuCpuRegisters.AX);
        }
Exemple #12
0
        protected ushort fputs(FarPtr putStringPtr, FarPtr srcPtr)
        {
            ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, FPUTS_ORDINAL, new List <FarPtr>
            {
                putStringPtr,
                srcPtr
            });

            return(mbbsEmuCpuRegisters.AX);
        }
Exemple #13
0
        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);
        }
Exemple #15
0
        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);
        }
Exemple #16
0
 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);
        }
Exemple #19
0
        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);
        }
Exemple #20
0
        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);
        }
Exemple #21
0
        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);
        }
Exemple #22
0
        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());
        }
Exemple #23
0
 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);
 }
Exemple #24
0
 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();
 }
Exemple #25
0
        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);
        }
Exemple #26
0
        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);
        }
Exemple #27
0
        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);
        }
Exemple #28
0
        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();
        }
Exemple #29
0
        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);
        }
Exemple #30
0
        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);
        }