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 PPI8255(X8086 cpu, InterruptRequest irq) { task = new TaskSC(this); for (int i = 0x60; i <= 0x6F; i++) { ValidPortAddress.Add((uint)i); } //PPISystemControl = x8086.WordToBitsArray(&HA5, PPISystemControl.Length) //PPI = x8086.WordToBitsArray(&HA, PPISystemControl.Length) //PPICommandModeRegister = &H99 this.cpu = cpu; this.sched = cpu.Sched; this.irq = irq; if (cpu.PIT != null) { timer = cpu.PIT; timer.SetCh2Gate((ppiB & 1) != 0); } keyBuf = ""; keyShiftPending = false; keyMap = new KeyMap(); }
public FloppyControllerAdapter(X8086 cpu) : base(cpu) { task = new TaskSC(this); this.sched = cpu.Sched; if (cpu.PIC != null) { this.irq = cpu.PIC.GetIrqLine((byte)6); } if (cpu.DMA != null) { this.dma = cpu.DMA.GetChannel(2); cpu.DMA.BindChannel(2, this); } curCylinder = new byte[4]; diskimg = new DiskImage[512]; regDOR = (byte)(0xC); ctlStepRateTime = (byte)0; ctlHeadUnloadTime = (byte)0; ctlHeadLoadTime = (byte)0; ctlNonDma = false; for (uint i = 0x3F0; i <= 0x3F7; i++) { ValidPortAddress.Add(i); } }
private Scheduler.Task task;// = new TaskSC(this); public RTC(X8086 cpu, InterruptRequest irq) { task = new TaskSC(this); this.irq = irq; for (int i = 0x70; i <= 0x71; i++) { ValidPortAddress.Add((uint)i); } for (int i = 0x240; i <= 0x24F; i++) { ValidPortAddress.Add((uint)i); } // FIXME: Although this works, when pausing the emulation causes the internal timers to get out of sync: // The contents at 46C no longer reflect what's returned by INT 1A, 02 // So the x8086.Resume method should perform a re-sync setting the new tick values into 46C. // It also appears that the x8086.Resume method should also advance the time... cpu.TryAttachHook((byte)(0x8), new X8086.IntHandler(() => { uint ticks = (uint)((DateTime.Now - new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0)).Ticks / 10000000 * 18.206); //cpu.RAM16[0x40, 0x6E] = (ticks >> 16) & 0xFFFF; //cpu.RAM16[0x40, 0x6C] = ticks & 0xFFFF; //cpu.RAM8[0x40, 0x70] = 0; cpu.set_RAM16(0x40, 0x6E, 0x0, false, (ushort)((long)(ticks >> 16) & 0xFFFF)); cpu.set_RAM16(0x40, 0x6C, 0x0, false, (ushort)((long)(ticks) & 0xFFFF)); cpu.set_RAM8(0x40, 0x70, 0x0, false, 0x00); cpu.TryDetachHook(0x8); return(false); })); cpu.TryAttachHook((byte)(0x1A), new X8086.IntHandler(() => { switch (cpu.Registers.AH) { case 0x2: // Read real time clock time cpu.Registers.CH = (byte)ToBCD((ushort)DateTime.Now.Hour); cpu.Registers.CL = (byte)ToBCD((ushort)DateTime.Now.Minute); cpu.Registers.DH = (byte)ToBCD((ushort)DateTime.Now.Second); cpu.Registers.DL = 0; cpu.Flags.CF = 0; return(true); case 0x4: // Read real time clock date cpu.Registers.CH = (byte)ToBCD((ushort)(DateTime.Now.Year / 100)); cpu.Registers.CL = (byte)ToBCD((ushort)DateTime.Now.Year); cpu.Registers.DH = (byte)ToBCD((ushort)DateTime.Now.Month); cpu.Registers.DL = (byte)ToBCD((ushort)DateTime.Now.Day); cpu.Flags.CF = 0; return(true); default: return(false); } })); }
public SpeakerAdpater(X8086 cpu) : base(cpu) { if (base.CPU.PIT != null) { base.CPU.PIT.Speaker = this; } Volume = 0.08; }
public Scheduler(X8086 cpu) { mCPU = cpu; pq = new PriorityQueue(); pendingInput = new ArrayList(); syncQuantum = BASECLOCK / 20; syncSimTimePerWallMs = BASECLOCK / 1000; }
public CGAConsole(X8086 cpu) : base(cpu) { InitiAdapter(); AutoSize(); Console.TreatControlCAsInput = true; Console.OutputEncoding = new System.Text.UTF8Encoding(); Console.Clear(); i2a = new Image2Ascii() { Charset = Image2Ascii.Charsets.Standard, ColorMode = Image2Ascii.ColorModes.Color, GrayScaleMode = Image2Ascii.GrayscaleModes.Average, ScanMode = Image2Ascii.ScanModes.Fast }; System.Threading.Tasks.Task.Run(() => { int x = 0; int y = 0; int width = 0; int height = 0; do { Thread.Sleep(1000 / frameRate); try { if (MainMode == MainModes.Graphics) { i2a.ProcessImage(false); width = Console.WindowWidth; height = Console.WindowHeight; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { //ConsoleCrayon.WriteFast(i2a.Canvas(x)[y].Character, //Image2Ascii.ToConsoleColor(i2a.Canvas(x)[y].Color), //ConsoleColor.Black, ConsoleCrayon.WriteFast(Char.ToString(i2a.Canvas[x][y].Character), Image2Ascii.ToConsoleColor(i2a.Canvas[x][y].Color), ConsoleColor.Black, x, y); } } } } catch { } } while (!base.cancelAllThreads); }); }
private const int M = 77; //M as ascii public MouseAdapter(X8086 cpu) : base(cpu) { if (base.CPU.PIC != null) { irq = base.CPU.PIC.GetIrqLine((byte)4); } for (uint i = 0x3F8; i <= 0x3F8 + 7; i++) { ValidPortAddress.Add(i); } }
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 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); }
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 ? "<<" : ""); } }
protected virtual void OnModeControlRegisterChanged() { // http://www.seasip.info/VintagePC/cga.html uint v = (uint)(X8086.BitsArrayToWord(CGAModeControlRegister)); VideoModes newMode = (VideoModes)(v & 0x17); // 10111 if ((v & vidModeChangeFlag) != 0 && (int)newMode != mVideoMode) { VideoMode = (uint)newMode; } mVideoEnabled = CGAModeControlRegister[(int)CGAModeControlRegisters.video_enabled] || VideoMode == (int)VideoModes.Mode7_Text_BW_80x25; }
//protected WebUI wui; public CGAAdapter(X8086 cpu, bool useInternalTimer = true, bool enableWebUI = false) : base(cpu) { CGABasePalette = new Color[] { Color.FromArgb(0x0, 0x0, 0x0), Color.FromArgb(0x0, 0x0, 0xAA), Color.FromArgb(0x0, 0xAA, 0x0), Color.FromArgb(0x0, 0xAA, 0xAA), Color.FromArgb(0xAA, 0x0, 0x0), Color.FromArgb(0xAA, 0x0, 0xAA), Color.FromArgb(0xAA, 0x55, 0x0), Color.FromArgb(0xAA, 0xAA, 0xAA), Color.FromArgb(0x55, 0x55, 0x55), Color.FromArgb(0x55, 0x55, 0xFF), Color.FromArgb(0x55, 0xFF, 0x55), Color.FromArgb(0x55, 0xFF, 0xFF), Color.FromArgb(0xFF, 0x55, 0x55), Color.FromArgb(0xFF, 0x55, 0xFF), Color.FromArgb(0xFF, 0xFF, 0x55), Color.FromArgb(0xFF, 0xFF, 0xFF) }; vidModeChangeFlag = (int)(+0b1000); this.useInternalTimer = useInternalTimer; //if (enableWebUI) //{ // wui = new WebUI(cpu, videoBMP, chars); //} for (uint i = 0x3D0; i <= 0x3DF; i++) // CGA { ValidPortAddress.Add(i); } ValidPortAddress.Add(0x3B8); for (int i = 0; i <= 255; i++) { if (i >= 32 && i < 255) { chars[i] = Convert.ToChar(i); } else { chars[i] = ' '; } } Reset(); //VideoMode = VideoModes.Mode7_Text_BW_80x25 }
public AdlibAdapter(X8086 cpu) : base(cpu) { for (int i = 0; i <= Opl.Length - 1; i++) { Opl[i] = new OplStruct[2]; } ValidPortAddress.Add(0x388); ValidPortAddress.Add(0x389); Array.Resize(ref attackTable, 16); Array.Resize(ref decayTable, 16); Array.Resize(ref oplTable, 16); }
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 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)); } }
public override void Out(uint port, ushort value) { if (port == ((uint)(0x3B8))) { if ((value & 2) == 2 && mVideoMode != (int)VideoModes.Mode7_Text_BW_80x25) { VideoMode = (uint)VideoModes.Mode7_Text_BW_80x25; } } // CRT (6845) index register else if (((((((port == ((uint)(0x3D0))) || (port == ((uint)(0x3D2)))) || (port == ((uint)(0x3D4)))) || (port == ((uint)(0x3D6)))) || (port == +0x3B0)) || (port == ((uint)(0x3B2)))) || (port == ((uint)(0x3B4)))) { CRT6845IndexRegister = (byte)(value & 31); } // CRT (6845) data register else if (((((((port == ((uint)(0x3D1))) || (port == ((uint)(0x3D3)))) || (port == ((uint)(0x3D5)))) || (port == ((uint)(0x3D7)))) || (port == +0x3B1)) || (port == ((uint)(0x3B3)))) || (port == ((uint)(0x3B5)))) { CRT6845DataRegister[CRT6845IndexRegister] = (byte)(value & CtrlMask[CRT6845IndexRegister]); OnDataRegisterChanged(); } // CGA mode control register (except PCjr) else if ((port == ((uint)(0x3D8))) || (port == ((uint)(0x3B8)))) { X8086.WordToBitsArray(value, CGAModeControlRegister); OnModeControlRegisterChanged(); } // CGA palette register else if ((port == ((uint)(0x3D9))) || (port == ((uint)(0x3B9)))) { X8086.WordToBitsArray(value, CGAPaletteRegister); OnPaletteRegisterChanged(); } // CGA status register EGA/VGA: input status 1 register / EGA/VGA feature control register else if ((port == ((uint)(0x3DA))) || (port == ((uint)(0x3BA)))) { X8086.WordToBitsArray(value, CGAStatusRegister); } // The trigger is cleared by writing any value to port 03DBh (undocumented) else if (port == ((uint)(0x3DB))) { CGAStatusRegister[(int)CGAStatusRegisters.light_pen_trigger_set] = false; } // CRT/CPU page register (PCjr only) else if (port == ((uint)(0x3DF))) { //Stop } else { base.CPU.RaiseException("CGA: Unknown Out Port: " + port.ToString("X4")); } }
protected virtual void OnPaletteRegisterChanged() { if (MainMode == MainModes.Text) { CGAPalette = (Color[])(CGABasePalette.Clone()); } else { Color[] colors = null; uint cgaModeReg = (uint)(X8086.BitsArrayToWord(CGAModeControlRegister)); uint cgaColorReg = (uint)(X8086.BitsArrayToWord(CGAPaletteRegister)); if (VideoMode == ((uint)VideoModes.Mode4_Graphic_Color_320x200)) { int intense = (int)((cgaColorReg & 0x10) >> 1); int pal1 = (int)((cgaColorReg >> 5) & (~(cgaModeReg >> 2)) & 1); int pal2 = (int)(((~cgaColorReg) >> 5) & (~(cgaModeReg >> 2)) & 1); colors = new Color[] { CGABasePalette[cgaColorReg & 0xF], CGABasePalette[3 ^ pal2 | intense], CGABasePalette[4 ^ pal1 | intense], CGABasePalette[7 ^ pal2 | intense] }; } else if (VideoMode == ((uint)VideoModes.Mode6_Graphic_Color_640x200)) { colors = new Color[] { CGABasePalette[0], CGABasePalette[cgaColorReg & 0xF] }; } if (colors != null) { for (int i = 0; i <= colors.Length - 1; i++) { CGAPalette[i] = colors[i]; } } } }
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()); }
public DMAI8237(X8086 cpu) { task = new TaskSC(this); this.cpu = cpu; channels = new Channel[5]; for (int i = 0; i <= 4 - 1; i++) { channels[i] = new Channel(this); } MaskReg = 0xF; // mask all channels ch0NextTrigger = -1; for (uint i = 0x0; i <= 0xF; i++) { ValidPortAddress.Add(i); } for (uint i = 0x80; i <= 0x8F; i++) { ValidPortAddress.Add(i); } }
public PIT8254(X8086 cpu, InterruptRequest irq) { task = new TaskSC(this); this.cpu = cpu; this.irq = irq; this.currentTime = cpu.Sched.CurrentTime; // construct 3 timer channels mChannels[0] = new Counter(this); mChannels[1] = new Counter(this); mChannels[2] = new Counter(this); // gate input for channels 0 and 1 is always high mChannels[0].Gate = true; mChannels[1].Gate = true; for (int i = 0x40; i <= 0x43; i++) { ValidPortAddress.Add((uint)i); } UpdateClock(); }
public override ushort In(uint port) { if ((((port == ((uint)(0x3D0))) || (port == ((uint)(0x3D2)))) || (port == ((uint)(0x3D4)))) || (port == ((uint)(0x3D6)))) // CRT (6845) index register { return((ushort)(CRT6845IndexRegister)); } // CRT (6845) data register else if (((((port == ((uint)(0x3D1))) || (port == ((uint)(0x3D3)))) || (port == ((uint)(0x3D5)))) || (port == ((uint)(0x3D7)))) || (port == ((uint)(0x3B5)))) { return((ushort)(CRT6845DataRegister[CRT6845IndexRegister])); } // CGA mode control register (except PCjr) else if (port == ((uint)(0x3D8))) { return(X8086.BitsArrayToWord(CGAModeControlRegister)); } // CGA palette register else if (port == ((uint)(0x3D9))) { return(X8086.BitsArrayToWord(CGAPaletteRegister)); } // CGA status register else if ((port == ((uint)(0x3DA))) || (port == ((uint)(0x3BA)))) { UpdateStatusRegister(); return(X8086.BitsArrayToWord(CGAStatusRegister)); } // CRT/CPU page register (PCjr only) else if (port == ((uint)(0x3DF))) { #if DEBUG //stop #endif } else { base.CPU.RaiseException("CGA: Unknown In Port: " + port.ToString("X4")); } return((ushort)(0xFF)); }
public override void Reset() { X8086.WordToBitsArray((ushort)(0x29), CGAModeControlRegister); X8086.WordToBitsArray((ushort)(0x0), CGAColorControlRegister); CRT6845DataRegister[0] = (byte)(0x71); CRT6845DataRegister[1] = (byte)(0x50); CRT6845DataRegister[2] = (byte)(0x5A); CRT6845DataRegister[3] = (byte)(0xA); CRT6845DataRegister[4] = (byte)(0x1F); CRT6845DataRegister[5] = (byte)(0x6); CRT6845DataRegister[6] = (byte)(0x19); CRT6845DataRegister[7] = (byte)(0x1C); CRT6845DataRegister[8] = (byte)(0x2); CRT6845DataRegister[9] = (byte)(0x7); CRT6845DataRegister[10] = (byte)(0x6); CRT6845DataRegister[11] = (byte)(0x71); for (int i = 12; i <= 32 - 1; i++) { CRT6845DataRegister[i] = (byte)0; } //HandleCGAModeControlRegisterUpdated() InitVideoMemory(false); }
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 Adapter(X8086 cpu) { mCPU = cpu; Task.Run((Action)InitiAdapter); //System.Threading.Tasks.Task.Run(InitiAdapter); }
public override void Run() { X8086.Notify("{Name} Running", X8086.NotificationReasons.Info); }
public KeyboardAdapter(X8086 cpu) : base(cpu) { }
public void CopyToMemory(byte[] bytes, ushort segment, ushort offset) { CopyToMemory(bytes, X8086.SegmentOffetToAbsolute(segment, offset)); }
public override void Run() { X8086.Notify("Speaker Running", X8086.NotificationReasons.Info); }