public const ushort PspSeg = ImageLoadSeg - 16; // 0x192 public RawProgramMain( Processor.x86.CSharpExecutor.Cpu implementation, ConfigurationDto configuration, MethodInfoCollection methodInfoCollection, DefinitionCollection definitionCollection, IServiceProvider serviceProvider) : base(implementation) { MethodInfoCollection = methodInfoCollection; Configuration = configuration; Implementation = implementation; DefinitionCollection = definitionCollection; ServiceProvider = serviceProvider; DosMemory = new DosMemory(implementation, this); DosInterrupt = new DosInterrupt(implementation, this); DosTimer = new DosTimer(implementation, this); DosPort = new DosPort(implementation, this); DosDma = new DosDma(implementation, this); DosPic = new DosPic(implementation, this); Implementation.MethodInfoCollection = MethodInfoCollection; implementation.CompiledMethodCollection = this; implementation.runIrqs += (sender, args) => DosPic.RunIrqs(); DosPort.SubscribeToCpuPortEvents(); }
public void InitializeX86DosProgram() { cr0.UInt32 = 0x0010; var exeBytes = File.ReadAllBytes(Path.Combine(Configuration.Program.WorkingDirectory, Configuration.Program.ExeFileName)); var dosMz = new DosMz(exeBytes); if (!dosMz.IsCorrect) { throw new Exception(); } DosMemory.dos_mem_init(); // Alloc dos - dummy. bx = PspSeg - 2; // internal alloc logic DosMemory.dos_mem_alloc(); if (eflags.cf) { throw new Exception(); } // Alloc image. var exe_image_off = dosMz.ExeDataStart; var image_size = dosMz.ExeDataLength; bx = (image_size + 15) / 16 + 16; // psp_size DosMemory.dos_mem_alloc(); if (eflags.cf) { throw new Exception(); } if (ax.UInt16 != PspSeg) { throw new Exception(); } ds.Selector = (ImageLoadSeg); var image = Implementation.Memory.GetFixSize(ds, 0, image_size); // Upload image of program. exeBytes.AsSpan().Slice(exe_image_off, image_size).CopyTo(image); // Apply realoc. foreach (var relocation in dosMz.Relocations) { var addr = relocation.Seg * 16 + relocation.Ofs; if (image_size <= addr + 1) { throw new Exception(); } image.Ref <ushort>(addr) += ImageLoadSeg; } // set psp var evnseg = PspSeg - 0xa; // 0x188 var evn_init = new byte[] { // PATH=Z:\\ 0x50, 0x41, 0x54, 0x48, 0x3d, 0x5a, 0x3a, 0x5c, 0x0, // COMSPEC=Z:\\COMMAND.COM 0x43, 0x4f, 0x4d, 0x53, 0x50, 0x45, 0x43, 0x3d, 0x5a, 0x3a, 0x5c, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x2e, 0x43, 0x4f, 0x4d, 0x0, // BLASTER=A220 I7 D1 H5 T6 // Port Address - 220, Interrupt - 7, DMA Channel - 1, "High" DMA Channel - 5, Type of Card - 6. 0x42, 0x4c, 0x41, 0x53, 0x54, 0x45, 0x52, 0x3d, 0x41, 0x32, 0x32, 0x30, 0x20, 0x49, 0x37, 0x20, 0x44, 0x31, 0x20, 0x48, 0x35, 0x20, 0x54, 0x36, 0x0, 0x0, 0x1, 0x0, // C:\\MAXRUN.EXE 0x43, 0x3a, 0x5c, 0x4d, 0x41, 0x58, 0x52, 0x55, 0x4e, 0x2e, 0x45, 0x58, 0x45, 0x0 }; ds.Selector = (evnseg); evn_init.CopyTo( Implementation.Memory .GetFixSize(ds, 0, evn_init.Length)); ds.Selector = (PspSeg); // 0x192 memb_a16[ds, 0x81] = 0xd; // Empty command-line (terminated by a 0x0D). memw_a16[ds, 0x2c] = evnseg; // Terminate address of previous program. // memw_a16(ds, 0xa) = 0x20c8; // memw_a16(ds, 0xa + 2) = 0xf000; ds.Selector = (evnseg - 1); // 0x187 memb_a16[ds, 0] = 0x4d; // Не знаю, что это. memw_a16[ds, 1] = PspSeg; memw_a16[ds, 3] = 0x9; ds.Selector = (PspSeg - 1); // 0x191 // memw_a16(ds, 0x3) = 0x1346 - 0x191; memw_a16[ds, 0x3] = 0xc02 - 0x191; // Устанавливаем начальные значения в регистры. ds.Selector = PspSeg; es = ds; ss.Selector = (ImageLoadSeg + dosMz.Hdr.InitialSs); sp = dosMz.Hdr.InitialSp; cs.Selector = (ImageLoadSeg + dosMz.Hdr.InitialCs); eip = dosMz.Hdr.InitialIp; CurrentInstructionAddress = dosMz.Hdr.InitialIp; eax = 0; ebx = 0; ecx = 0xff; edx = PspSeg; esi = 0x2382; edi = 0x340; ebp = 0x91c; eflags.UInt32 = 0x7202; }