private void NoIOPort(int port) { X8086.Notify("No IO port response from {0} called at {1}:{2}", NotificationReasons.Warn, port.ToString("X4"), mRegisters.CS.ToString("X4"), mRegisters.IP.ToString("X4")); }
public void HandleInput(ExternalInputEvent e) { if (ReferenceEquals(e.Handler, null)) { return; } if (e.TheEvent is KeyEventArgs) { var theEvent = (KeyEventArgs)e.TheEvent; if (cadCounter > 0) { cadCounter--; return; } if (((int)(theEvent.Modifiers) & (int)Keys.Control) == (int)Keys.Control) { isCtrlDown = !System.Convert.ToBoolean(e.Extra); } else { isCtrlDown = false; } if (((int)(theEvent.Modifiers) & (int)Keys.Alt) == (int)Keys.Alt) { isAltDown = !System.Convert.ToBoolean(e.Extra); } else { isAltDown = false; } if (isCtrlDown && isAltDown && ((int)(theEvent.KeyCode) & (int)Keys.Insert) == (int)Keys.Insert) { cadCounter = 3; // Ignore the next three events, which will be the release of CTRL, ALT and DEL e.TheEvent = new KeyEventArgs(Keys.Delete); X8086.Notify("Sending CTRL+ALT+DEL", X8086.NotificationReasons.Info); } } if (pendingInput.Count == 0) { // Wake up the scheduler in case it is sleeping Notify(); // Kick the CPU simulation to make it yield mCPU.DoReschedule = true; } pendingInput.Add(e); }
private void PrintStack() { int f = Math.Min(mRegisters.SP + (0xFFFF - mRegisters.SP) - 1, mRegisters.SP + 10); int t = Math.Max(0, mRegisters.SP - 10); for (int i = f; i >= t; i -= 2) { X8086.Notify("{0}:{1} {2}{3}", NotificationReasons.Info, mRegisters.SS.ToString("X4"), i.ToString("X4"), get_RAM16(mRegisters.SS, (ushort)i, (byte)0, true).ToString("X4"), i == mRegisters.SP ? "<<" : ""); } }
private void PrintFlags() { X8086.Notify("{0}{1}{2}{3}{4}{5}{6}{7}", NotificationReasons.Info, mFlags.CF, mFlags.ZF, mFlags.SF, mFlags.OF, mFlags.PF, mFlags.AF, mFlags.IF, mFlags.DF); X8086.Notify("CZSOPAID", NotificationReasons.Info); }
public void LoadBIN(string fileName, ushort segment, ushort offset) { //X8086.Notify("Loading: {fileName} @ {segment:X4}:{offset:X4}", NotificationReasons.Info, null); X8086.Notify($"Loading: {fileName} @ {segment:X4}:{offset:X4}", NotificationReasons.Info); fileName = X8086.FixPath(fileName); if (System.IO.File.Exists(fileName)) { CopyToMemory(System.IO.File.ReadAllBytes(fileName), segment, offset); } else { ThrowException(System.Convert.ToString("File Not Found: " + "\r\n" + fileName)); } }
private void ThrowException(string message) { if (mEnableExceptions) { throw (new Exception(message)); } else { X8086.Notify(message, NotificationReasons.Err); if (ErrorEvent != null) { ErrorEvent(this, new EmulatorErrorEventArgs(message)); } } }
public DiskImage(string fileName, bool mountInReadOnlyMode = false, bool isHardDisk = false) { mFileName = X8086.FixPath(fileName); mCylinders = (ushort)(0); mHeads = (ushort)(0); mSectors = (ushort)(0); mFileLength = 0; if (!System.IO.File.Exists(mFileName)) { mStatus = ImageStatus.DiskImageNotFound; } else { OpenImage(mountInReadOnlyMode, isHardDisk); } X8086.Notify("DiskImage '{0}': {1}", X8086.NotificationReasons.Info, mFileName, mStatus.ToString()); }
public HostFolderAsDisk(string fileName, bool mountInReadOnlyMode = false) { throw (new NotImplementedException()); mFileName = fileName; s = new System.IO.FileStream(mFileName, System.IO.FileMode.Open); image = new StandardDiskFormat(s); //mSectorSize = image.BootSectors(0).BIOSParameterBlock.BytesPerSector //mCylinders = image.Partitions(0).Cylinders + 1 //mHeads = image.Partitions(0).Heads * 2 //mSectors = image.Partitions(0).Sectors + 1 //mFileLength = s.Length //mReadOnly = mountInReadOnlyMode //mIsHardDisk = CType(image.Partitions(0).FileSystem, FAT12_16.BootSector).BIOSParameterBlock.MediaDescriptor = &HF8 //mStatus = ImageStatus.DiskLoaded X8086.Notify("DiskImage '{0}': {1}", X8086.NotificationReasons.Info, mFileName, mStatus.ToString()); }
private void PrintRegisters() { X8086.Notify("AX: {0} SP: {1} ", NotificationReasons.Info, mRegisters.AX.ToString("X4"), mRegisters.SP.ToString("X4")); X8086.Notify("BX: {0} DI: {1} ", NotificationReasons.Info, mRegisters.BX.ToString("X4"), mRegisters.DI.ToString("X4")); X8086.Notify("CX: {0} BP: {1} ", NotificationReasons.Info, mRegisters.CX.ToString("X4"), mRegisters.BP.ToString("X4")); X8086.Notify("DX: {0} SI: {1} ", NotificationReasons.Info, mRegisters.DX.ToString("X4"), mRegisters.SI.ToString("X4")); X8086.Notify("ES: {0} CS: {1} ", NotificationReasons.Info, mRegisters.ES.ToString("X4"), mRegisters.CS.ToString("X4")); X8086.Notify("SS: {0} DS: {1} ", NotificationReasons.Info, mRegisters.SS.ToString("X4"), mRegisters.DS.ToString("X4")); X8086.Notify("IP: {0} FLGS: {1}{2}{3}{4}{5}{6}{7}{8}", NotificationReasons.Info, mRegisters.IP.ToString("X4"), mFlags.CF, mFlags.ZF, mFlags.SF, mFlags.OF, mFlags.PF, mFlags.AF, mFlags.IF, mFlags.DF); X8086.Notify(" CZSOPAID", NotificationReasons.Info); for (int i = 0; i <= 3; i++) { Debug.Write(get_RAM8(mRegisters.CS, (ushort)(mRegisters.IP + i), (byte)0, false).ToString("X2") + " "); } }
public override void Run() { X8086.Notify("{Name} Running", X8086.NotificationReasons.Info); }
public override void Run() { X8086.Notify("Speaker Running", X8086.NotificationReasons.Info); }
private bool HandleINT13() { if (mFloppyController == null) { ThrowException("Disk Adapter Not Found"); return(true); } int ret = 0; int AL = 0; long offset = 0; DiskImage dskImg = mFloppyController.get_DiskImage((int)mRegisters.DL); int bufSize = 0; if (mRegisters.AH == ((byte)(0x0))) // Reset drive { X8086.Notify("Drive {0:000} Reset", NotificationReasons.Info, mRegisters.DL); ret = (int)(ReferenceEquals(dskImg, null) ? 0xAA : 0); } // Get last operation status else if (mRegisters.AH == ((byte)(0x1))) { X8086.Notify("Drive {0:000} Get Last Operation Status", NotificationReasons.Info, mRegisters.DL); mRegisters.AH = (byte)lastAH[mRegisters.DL]; mFlags.CF = lastCF[mRegisters.DL]; ret = 0; } // Read sectors else if (mRegisters.AH == ((byte)(0x2))) { if (dskImg == null) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { offset = dskImg.LBA((uint)(mRegisters.CH), (uint)(mRegisters.DH), (uint)(mRegisters.CL)); bufSize = mRegisters.AL * dskImg.SectorSize; if (offset < 0 || (int)(offset + bufSize) > (int)dskImg.FileLength) { X8086.Notify("Read Sectors: Drive {0:000} Seek Fail", NotificationReasons.Warn, mRegisters.DL); ret = 0x40; // seek failed } X8086.Notify("Drive {0:000} Read H{1:00} T{2:000} S{3:000} x {4:000} {5:X6} -> {6:X4}:{7:X4}", NotificationReasons.Info, mRegisters.DL, mRegisters.DH, mRegisters.CH, mRegisters.CL, mRegisters.AL, offset, mRegisters.ES, mRegisters.BX); byte[] buf = new byte[bufSize]; ret = dskImg.Read((ulong)offset, buf); if (ret == DiskImage.EIO) { X8086.Notify("Read Sectors: Drive {0:000} CRC Error", NotificationReasons.Warn, mRegisters.DL); ret = 0x10; // CRC error } else if (ret == DiskImage.EOF) { X8086.Notify("Read Sectors: Drive {0:000} Sector Not Found", NotificationReasons.Warn, mRegisters.DL); ret = 0x4; // sector not found } CopyToMemory(buf, X8086.SegmentOffetToAbsolute(mRegisters.ES, mRegisters.BX)); AL = bufSize / dskImg.SectorSize; } } // Write sectors else if (mRegisters.AH == ((byte)(0x3))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { if (dskImg.IsReadOnly) { X8086.Notify("Write Sectors: Drive {0:000} Failed / Read Only", NotificationReasons.Warn, mRegisters.DL); ret = 0x3; // write protected } offset = dskImg.LBA((uint)(mRegisters.CH), (uint)(mRegisters.DH), (uint)(mRegisters.CL)); bufSize = mRegisters.AL * dskImg.SectorSize; if (offset < 0 || (int)(offset + bufSize) > (int)dskImg.FileLength) { X8086.Notify("Write Sectors: Drive {0:000} Seek Failed", NotificationReasons.Warn, mRegisters.DL); ret = 0x40; // seek failed } X8086.Notify("Drive {0:000} Write H{1:00} T{2:000} S{3:000} x {4:000} {5:X6} <- {6:X4}:{7:X4}", NotificationReasons.Info, mRegisters.DL, mRegisters.DH, mRegisters.CH, mRegisters.CL, mRegisters.AL, offset, mRegisters.ES, mRegisters.BX); byte[] buf = new byte[bufSize]; CopyFromMemory(buf, X8086.SegmentOffetToAbsolute(mRegisters.ES, mRegisters.BX)); ret = dskImg.Write((ulong)offset, buf); if (ret == DiskImage.EIO) { X8086.Notify("Write Sectors: Drive {0:000} CRC Error", NotificationReasons.Warn, mRegisters.DL); ret = 0x10; // CRC error } else if (ret == DiskImage.EOF) { X8086.Notify("Write Sectors: Drive {0:000} Sector Not Found", NotificationReasons.Warn, mRegisters.DL); ret = 0x4; // sector not found } AL = bufSize / dskImg.SectorSize; } } // Verify Sectors else if (mRegisters.AH == ((byte)(0x4))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { offset = dskImg.LBA((uint)(mRegisters.CH), (uint)(mRegisters.DH), (uint)(mRegisters.CL)); bufSize = mRegisters.AL * dskImg.SectorSize; if (offset < 0 || (int)(offset + bufSize) > (int)dskImg.FileLength) { X8086.Notify("Verify Sector: Drive {0} Seek Failed", NotificationReasons.Warn, mRegisters.DL); ret = 0x40; // seek failed } X8086.Notify("Drive {0:000} Verify Sectors H{1:00} T{2:000} S{3:000} ? {4:000} {5:X6} ? {6:X4}:{7:X4}", NotificationReasons.Info, mRegisters.DL, mRegisters.DH, mRegisters.CH, mRegisters.CL, mRegisters.AL, offset, mRegisters.ES, mRegisters.BX); AL = bufSize / dskImg.SectorSize; ret = 0; } } // Format Track else if (mRegisters.AH == ((byte)(0x5))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { offset = dskImg.LBA((uint)(mRegisters.CH), (uint)(mRegisters.DH), (uint)(mRegisters.CL)); bufSize = mRegisters.AL * dskImg.SectorSize; if (offset < 0 || (int)(offset + bufSize) > (int)dskImg.FileLength) { X8086.Notify("Format Track: Drive {0:000} Seek Failed", NotificationReasons.Warn, mRegisters.DL); ret = 0x40; // seek failed } X8086.Notify("Drive {0:000} Format Track H{1:00} T{2:000} S{3:000} ? {4:000} {5:X6} = {6:X4}:{7:X4}", NotificationReasons.Info, mRegisters.DL, mRegisters.DH, mRegisters.CH, mRegisters.CL, mRegisters.AL, offset, mRegisters.ES, mRegisters.BX); ret = 0; } } // Format Track - Set Bad Sector Flag else if (mRegisters.AH == ((byte)(0x6))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { X8086.Notify("Drive {0:000} Format Track (SBSF) H{1:00} T{2:000} S{3:000} ? {4:000}", NotificationReasons.Info, mRegisters.DL, mRegisters.DH, mRegisters.CH, mRegisters.CL, mRegisters.AL); ret = 0; } } // Format Drive Starting at Track else if (mRegisters.AH == ((byte)(0x7))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { X8086.Notify("Drive {0:000} Format Drive H{1:00} T{2:000} S{3:000}", NotificationReasons.Info, mRegisters.DL, mRegisters.DH, mRegisters.CH, mRegisters.CL, mRegisters.AL); ret = 0; } } // Get Drive Parameters else if (mRegisters.AH == ((byte)(0x8))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { if (dskImg.Tracks <= 0) { X8086.Notify("Get Drive Parameters: Drive {0:000} Unknown Geometry", NotificationReasons.Warn, mRegisters.DL); ret = 0xAA; } else { mRegisters.CH = (byte)((dskImg.Cylinders - 1) & 0xFF); mRegisters.CL = (byte)(dskImg.Sectors & 63); mRegisters.CL += (byte)(((dskImg.Cylinders - 1) / 256) * 64); mRegisters.DH = (byte)(dskImg.Heads - 1); if (mRegisters.DL < 0x80) { mRegisters.BL = (byte)4; mRegisters.DL = (byte)2; } else { mRegisters.DL = (byte)DiskImage.HardDiskCount; } X8086.Notify("Drive {0:000} Get Parameters", NotificationReasons.Info, mRegisters.DL); ret = 0; } } } // Initialize Drive Pair Characteristic else if (mRegisters.AH == ((byte)(0x9))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } X8086.Notify("Drive {0:000} Init Drive Pair Characteristic", NotificationReasons.Info, mRegisters.DL); ret = 0; // The following are meant to keep diagnostic tools happy ;) } // Read Long Sectors else if (mRegisters.AH == ((byte)(0xA))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { offset = dskImg.LBA((uint)(mRegisters.CH), (uint)(mRegisters.DH), (uint)(mRegisters.CL)); bufSize = mRegisters.AL * dskImg.SectorSize; if (offset < 0 || (int)(offset + bufSize) > (int)dskImg.FileLength) { X8086.Notify("Read Sectors Long: Drive {0:000} Seek Fail", NotificationReasons.Warn, mRegisters.DL); ret = 0x40; // seek failed } X8086.Notify("Drive {0:000} Read Long H{1:00} T{2:000} S{3:000} x {4:000} {5:X6} -> {6:X4}:{7:X4}", NotificationReasons.Info, mRegisters.DL, mRegisters.DH, mRegisters.CH, mRegisters.CL, mRegisters.AL, offset, mRegisters.ES, mRegisters.BX); byte[] buf = new byte[bufSize]; ret = dskImg.Read((ulong)offset, buf); if (ret == DiskImage.EIO) { X8086.Notify("Read Sectors Long: Drive {0:000} CRC Error", NotificationReasons.Warn, mRegisters.DL); ret = 0x10; // CRC error } else if (ret == DiskImage.EOF) { X8086.Notify("Read Sectors Long: Drive {0:000} Sector Not Found", NotificationReasons.Warn, mRegisters.DL); ret = 0x4; // sector not found } byte[] ecc = BitConverter.GetBytes(buf.Sum(b => b)); Array.Resize(ref buf, buf.Length + 4 + 1); buf[buf.Length - 4] = ecc[1]; buf[buf.Length - 3] = ecc[0]; buf[buf.Length - 2] = ecc[3]; buf[buf.Length - 1] = ecc[2]; CopyToMemory(buf, X8086.SegmentOffetToAbsolute(mRegisters.ES, mRegisters.BX)); AL = bufSize / dskImg.SectorSize; } } // Seek to Cylinder else if (mRegisters.AH == ((byte)(0xC))) { X8086.Notify("Drive {0:000} Seek to Cylinder ", NotificationReasons.Info, mRegisters.DL); ret = 0; } // Alternate Disk Reset else if (mRegisters.AH == ((byte)(0xD))) { X8086.Notify("Drive {0:000} Alternate Disk Reset", NotificationReasons.Info, mRegisters.DL); ret = 0; } // Controller Internal Diagnostic else if (mRegisters.AH == ((byte)(0x14))) { X8086.Notify("Drive {0:000} Controller Internal Diagnostic", NotificationReasons.Info, mRegisters.DL); ret = 0; } // Recalibrate else if (mRegisters.AH == ((byte)(0x11))) { X8086.Notify("Drive {0:000} Recalibrate", NotificationReasons.Info, mRegisters.DL); ret = 0; } // Read DASD Type else if (mRegisters.AH == ((byte)(0x15))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { if (mRegisters.DL < 0x80) { ret = 0x64; } else { mRegisters.CX = (ushort)(dskImg.Sectors / 256); mRegisters.DX = (ushort)(dskImg.Sectors & 0xFF); ret = 0x12C; } X8086.Notify("Drive {0:000} Read DASD Type", NotificationReasons.Info, mRegisters.DL); } } // Controller RAM Diagnostic else if (mRegisters.AH == ((byte)(0x12))) { X8086.Notify("Drive {0:000} Controller RAM Diagnostic", NotificationReasons.Info, mRegisters.DL); ret = 0; } // Drive Diagnostic else if (mRegisters.AH == ((byte)(0x13))) { X8086.Notify("Drive {0:000} Drive Diagnostic", NotificationReasons.Info, mRegisters.DL); ret = 0; } // Check Extensions Support else if (mRegisters.AH == ((byte)(0x41))) { X8086.Notify("Drive {0:000} Extensions Check", NotificationReasons.Info, mRegisters.DL); if (mRegisters.BX == 0x55AA) { mFlags.CF = (byte)0; mRegisters.AH = (byte)(0x1); mRegisters.CX = (ushort)(0x4); } else { mFlags.CF = (byte)1; mRegisters.AH = (byte)(0xFF); } return(true); } // Extended Sectors Read else if (mRegisters.AH == ((byte)(0x42))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { uint dap = X8086.SegmentOffetToAbsolute(mRegisters.DS, mRegisters.SI); bufSize = (int)(get_RAM(dap + 3) << 8 | get_RAM(dap + 2)); int seg = (int)(get_RAM(dap + 7) << 8 | get_RAM(dap + 6)); int Off = (int)(get_RAM(dap + 5) << 8 | get_RAM(dap + 4)); offset = (long)(get_RAM(dap + 0xF) << 56 | get_RAM(dap + 0xE) << 48 | get_RAM(dap + 0xD) << 40 | get_RAM(dap + 0xC) << 32 | get_RAM(dap + 0xB) << 24 | get_RAM(dap + 0xA) << 16 | get_RAM(dap + 0x9) << 8 | get_RAM(dap + 0x8)); if (offset < 0 || (int)(offset + bufSize) > (int)dskImg.FileLength) { X8086.Notify("Read Sectors: Drive {0:000} Seek Fail", NotificationReasons.Warn, mRegisters.DL); ret = 0x40; // seek failed } X8086.Notify("Drive {0:000} Read {4:000} {5:X6} -> {6:X4}:{7:X4}", NotificationReasons.Info, mRegisters.DL, bufSize, offset, seg, Off); byte[] buf = new byte[bufSize]; ret = dskImg.Read((ulong)offset, buf); if (ret == DiskImage.EIO) { X8086.Notify("Read Sectors: Drive {0:000} CRC Error", NotificationReasons.Warn, mRegisters.DL); ret = 0x10; // CRC error } else if (ret == DiskImage.EOF) { X8086.Notify("Read Sectors: Drive {0:000} Sector Not Found", NotificationReasons.Warn, mRegisters.DL); ret = 0x4; // sector not found } CopyToMemory(buf, X8086.SegmentOffetToAbsolute((ushort)seg, (ushort)(Off))); AL = bufSize / dskImg.SectorSize; } } // Extended Sectors Write else if (mRegisters.AH == ((byte)(0x43))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { uint dap = X8086.SegmentOffetToAbsolute(mRegisters.DS, mRegisters.SI); bufSize = (int)(get_RAM(dap + 3) << 8 | get_RAM(dap + 2)); int seg = (int)(get_RAM(dap + 7) << 8 | get_RAM(dap + 6)); int Off = (int)(get_RAM(dap + 5) << 8 | get_RAM(dap + 4)); offset = (long)(get_RAM(dap + 0xF) << 56 | get_RAM(dap + 0xE) << 48 | get_RAM(dap + 0xD) << 40 | get_RAM(dap + 0xC) << 32 | get_RAM(dap + 0xB) << 24 | get_RAM(dap + 0xA) << 16 | get_RAM(dap + 0x9) << 8 | get_RAM(dap + 0x8)); if (offset < 0 || (int)(offset + bufSize) > (int)dskImg.FileLength) { X8086.Notify("Write Sectors: Drive {0:000} Seek Fail", NotificationReasons.Warn, mRegisters.DL); ret = 0x40; // seek failed } X8086.Notify("Drive {0:000} Write {4:000} {5:X6} <- {6:X4}:{7:X4}", NotificationReasons.Info, mRegisters.DL, bufSize, offset, seg, Off); byte[] buf = new byte[bufSize]; CopyFromMemory(buf, X8086.SegmentOffetToAbsolute((ushort)seg, (ushort)(Off))); ret = dskImg.Write((ulong)offset, buf); if (ret == DiskImage.EIO) { X8086.Notify("Write Sectors: Drive {0:000} CRC Error", NotificationReasons.Warn, mRegisters.DL); ret = 0x10; // CRC error } else if (ret == DiskImage.EOF) { X8086.Notify("Write Sectors: Drive {0:000} Sector Not Found", NotificationReasons.Warn, mRegisters.DL); ret = 0x4; // sector not found } AL = bufSize / dskImg.SectorSize; } } // Extended get Drive Parameters else if (mRegisters.AH == ((byte)(0x48))) { if (ReferenceEquals(dskImg, null)) { X8086.Notify("Invalid Drive Number: Drive {0:000} Not Ready", NotificationReasons.Info, mRegisters.DL); ret = 0xAA; // fixed disk drive not ready } else { if (dskImg.Tracks <= 0) { X8086.Notify("Get Drive Parameters: Drive {0:000} Unknown Geometry", NotificationReasons.Warn, mRegisters.DL); ret = 0xAA; } else { throw (new NotImplementedException("Extended get Drive Parameters is not Implemented")); X8086.Notify("Drive {0:000} Get Parameters", NotificationReasons.Info, mRegisters.DL); ret = 0; } } } else { X8086.Notify("Drive {0:000} Unknown Request {1}", NotificationReasons.Err, mRegisters.DL, ((mRegisters.AX & 0xFF00) >> 8).ToString("X2")); ret = 0x1; } if (mRegisters.AH != 0) { set_RAM8((ushort)(0x40), (ushort)(0x41), 0, false, (byte)ret); mRegisters.AX = (ushort)((ret << 8) | AL); } mFlags.CF = (byte)(ret != 0 ? 1 : 0); lastAH[mRegisters.DL] = (ushort)(mRegisters.AH); lastCF[mRegisters.DL] = mFlags.CF; if ((mRegisters.DL & 0x80) != 0) { Memory[0x474] = mRegisters.AH; } return(true); }
private void Run() { ArrayList cleanInputBuf = new ArrayList(); ArrayList inputBuf = new ArrayList(); Task tsk = null; ExternalInputEvent evt = default(ExternalInputEvent); while (true) { // Detect the end of the simulation run if (nextTime == STOPPING) { nextTime = pq.MinPriority(); break; } if (pendingInput.Count > 0) { // Fetch pending input events inputBuf = pendingInput; pendingInput = cleanInputBuf; } else if (nextTime <= mCurrentTime) { // Fetch the next pending task tsk = NextTask(); if (ReferenceEquals(tsk, null)) { continue; // This task was canceled, go round again } inputBuf.Clear(); } else { tsk = null; } if (inputBuf.Count > 0) { // Process pending input events for (int i = 0; i <= inputBuf.Count - 1; i++) { evt = (ExternalInputEvent)(inputBuf[i]); evt.TimeStamp = mCurrentTime; evt.Handler.HandleInput(evt); } inputBuf.Clear(); cleanInputBuf = inputBuf; } else if (tsk != null) { // Run the first pending task tsk.Start(); } else { // Run the CPU simulation for a bit (maxRunCycl) try { mCPU.RunEmulation(); } catch (Exception ex) { X8086.Notify("Shit happens at {0}:{1}: {2}", X8086.NotificationReasons.Fck, mCPU.Registers.CS.ToString("X4"), mCPU.Registers.IP.ToString("X4"), ex.Message); mCPU.RaiseException($"Scheduler Main Loop Error: {ex.Message}"); } if (mCPU.IsHalted) { SkipToNextEvent(); // The CPU is halted, skip immediately to the next event } } } }