protected CpuTestBase() { mbbsEmuMemoryCore = new MemoryCore(); mbbsEmuCpuRegisters = new CpuRegisters(); mbbsEmuCpuCore = new CpuCore(); mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, null); }
protected override async void OnCreateControl() { base.OnCreateControl(); DoubleBuffered = true; _resizeGripRect = new Rectangle(Width - 12, Height - 12, 11, 11); int y = CpuMonitor.Properties.Settings.Default.BorderSize; int nCores = await CpuCore.GetCpuCores(); for (int i = 0; i < nCores; i++) { var coreControl = new CpuControl(i); _cpuCores.Add(coreControl); Controls.Add(coreControl); coreControl.Top = y; coreControl.Left = CpuMonitor.Properties.Settings.Default.BorderSize; coreControl.Width = Width - (CpuMonitor.Properties.Settings.Default.BorderSize * 2); y += coreControl.Height; } }
public static void InfoRegisters(this ILogger l, CpuCore cpu) { var output = new StringBuilder(); output.Append($"AX={cpu.Registers.AX:X4} "); output.Append($"BX={cpu.Registers.BX:X4} "); output.Append($"CX={cpu.Registers.CX:X4} "); output.Append($"DX={cpu.Registers.DX:X4} "); output.Append($"DS={cpu.Registers.DS:X4} "); output.AppendLine($"ES={cpu.Registers.ES:X4}"); output.Append($"SI={cpu.Registers.SI:X4} "); output.Append($"DI={cpu.Registers.DI:X4} "); output.Append($"SS={cpu.Registers.SS:X4} "); output.Append($"IP={cpu.Registers.IP:X4} "); output.Append($"SP={cpu.Registers.SP:X4} "); output.AppendLine($"BP={cpu.Registers.BP:X4}"); output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.CF) ? "C" : "c"); output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.PF) ? "P" : "p"); output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.ZF) ? "Z" : "z"); output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.SF) ? "S" : "s"); output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.OF) ? "O" : "o"); foreach (var line in output.ToString().Split("\r\n")) { l.Info(line); } }
protected ExportedModuleTestBase(string modulePath) { mbbsEmuMemoryCore = new MemoryCore(); mbbsEmuCpuRegisters = new CpuRegisters(); mbbsEmuCpuCore = new CpuCore(); mbbsModule = new MbbsModule(FileUtility.CreateForTest(), _serviceResolver.GetService <ILogger>(), null, modulePath, mbbsEmuMemoryCore); testSessions = new PointerDictionary <SessionBase>(); testSessions.Allocate(new TestSession(null)); testSessions.Allocate(new TestSession(null)); majorbbs = new HostProcess.ExportedModules.Majorbbs( _serviceResolver.GetService <ILogger>(), _serviceResolver.GetService <AppSettings>(), _serviceResolver.GetService <IFileUtility>(), _serviceResolver.GetService <IGlobalCache>(), mbbsModule, testSessions, _serviceResolver.GetService <IAccountKeyRepository>(), _serviceResolver.GetService <IAccountRepository>()); galgsbl = new HostProcess.ExportedModules.Galgsbl( _serviceResolver.GetService <ILogger>(), _serviceResolver.GetService <AppSettings>(), _serviceResolver.GetService <IFileUtility>(), _serviceResolver.GetService <IGlobalCache>(), mbbsModule, testSessions); mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, ExportedFunctionDelegate); }
static Program() { mbbsEmuMemoryCore = new MemoryCore(); mbbsEmuCpuRegisters = new CpuRegisters(); mbbsEmuCpuCore = new CpuCore(); mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, null); }
public static void InfoRegisters(this ILogger l, CpuCore cpu) { var output = new StringBuilder(); output.Append($"AX={cpu.Registers.AX:X4} "); output.Append($"BX={cpu.Registers.BX:X4} "); output.Append($"CX={cpu.Registers.CX:X4} "); output.Append($"DX={cpu.Registers.DX:X4} "); output.Append($"DS={cpu.Registers.DS:X4} "); output.AppendLine($"ES={cpu.Registers.ES:X4}"); output.Append($"SI={cpu.Registers.SI:X4} "); output.Append($"DI={cpu.Registers.DI:X4} "); output.Append($"SS={cpu.Registers.SS:X4} "); output.Append($"IP={cpu.Registers.IP:X4} "); output.Append($"SP={cpu.Registers.SP:X4} "); output.AppendLine($"BP={cpu.Registers.BP:X4}"); output.Append(cpu.Registers.CarryFlag ? "C" : "c"); //output.Append(cpu.Registers.Parity ? "P" : "p"); output.Append(cpu.Registers.ZeroFlag ? "Z" : "z"); output.Append(cpu.Registers.SignFlag ? "S" : "s"); output.Append(cpu.Registers.OverflowFlag ? "O" : "o"); foreach (var line in output.ToString().Split("\r\n")) { l.Info(line); } }
/// <summary> /// Fx0A - LD Vx, K ///Wait for a key press, store the value of the key in Vx. /// ///All execution stops until a key is pressed, then the value of that key is stored in Vx. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool LDK(CpuCore context, Instruction instruction) { var key = context.Input.WaitUntilKeyDown(); context.GPR[instruction.X] = ( byte )key; return(true); }
public Emulator(EmulatorConfig config) { Memory = new Memory(); Display = new ConsoleDisplayDevice(); Sound = new WindowsBeepSoundDevice(); Input = new WindowsKeyboardInputDevice(); Cpu = new CpuCore(Memory, Display, Sound, Input, new InstructionInterpreter()); }
protected MajorbbsTestBase() { mbbsEmuMemoryCore = new MemoryCore(); mbbsEmuCpuRegisters = new CpuRegisters(); mbbsEmuCpuCore = new CpuCore(); majorbbs = new HostProcess.ExportedModules.Majorbbs(new MbbsModule(null, string.Empty, mbbsEmuMemoryCore), new PointerDictionary <Session.SessionBase>()); mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, MajorbbsFunctionDelegate); }
/// <summary> /// 3xkk - SE Vx, byte ///Skip next instruction if Vx = kk. /// ///The interpreter compares register Vx to kk, and if they are equal, increments the program counter by 2. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool SEIMM(CpuCore context, Instruction instruction) { if (context.GPR[instruction.X] == instruction.KK) { context.PC += Instruction.SIZE; } return(true); }
/// <summary> /// 9xy0 - SNE Vx, Vy ///Skip next instruction if Vx != Vy. /// ///The values of Vx and Vy are compared, and if they are not equal, the program counter is increased by 2. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool SNE(CpuCore context, Instruction instruction) { if (context.GPR[instruction.X] != context.GPR[instruction.Y]) { context.PC += Instruction.SIZE; } return(true); }
/// <summary> /// 1nnn - JP addr ///Jump to location nnn. /// ///The interpreter sets the program counter to nnn. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool JP(CpuCore context, Instruction instruction) { if (context.PC == instruction.NNN) { Debug.WriteLine("JP: Branch to self"); } context.PC = instruction.NNN; return(false); }
/// <summary> /// Fx65 - LD Vx, [I] ///Read registers V0 through Vx from memory starting at location I. /// ///The interpreter reads values from memory starting at location I into registers V0 through Vx. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool LDRS(CpuCore context, Instruction instruction) { var count = instruction.X + 1; for (int i = 0; i < count; i++) { context.GPR[i] = context.Memory.ReadByte(( ushort )(context.I + i)); } return(true); }
/// <summary> /// ExA1 - SKNP Vx ///Skip next instruction if key with the value of Vx is not pressed. /// ///Checks the keyboard, and if the key corresponding to the value of Vx is currently in the up position, PC is increased by 2. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool SKNP(CpuCore context, Instruction instruction) { var key = context.GPR[instruction.X]; if (!context.Input.IsKeyDown(( Key )key)) { context.PC += Instruction.SIZE; } return(true); }
/// <summary> /// Bnnn - JP V0, addr ///Jump to location nnn + V0. /// ///The program counter is set to nnn plus the value of V0. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool JPV0(CpuCore context, Instruction instruction) { var pc = ( ushort )(instruction.NNN + context.V0); if (context.PC == pc) { Debug.WriteLine("JPV0: Branch to self"); } context.PC = pc; return(false); }
/// <summary> /// Fx33 - LD B, Vx ///Store BCD representation of Vx in memory locations I, I+1, and I+2. /// ///The interpreter takes the decimal value of Vx, and places the hundreds digit in memory at location in I, the tens digit at location I+1, and the ones digit at location I+2. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool LDBCD(CpuCore context, Instruction instruction) { var vx = context.GPR[instruction.X]; var hundreds = ( byte )((vx / 100) % 10); var tens = ( byte )(vx / 10); var ones = ( byte )(vx % 10); context.Memory.WriteByte(context.I, hundreds); context.Memory.WriteByte((ushort)(context.I + 1), tens); context.Memory.WriteByte((ushort)(context.I + 2), ones); return(true); }
/// <summary> /// 00EE - RET ///Return from a subroutine. /// ///The interpreter sets the program counter to the address at the top of the stack, then subtracts 1 from the stack pointer. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool RET(CpuCore context, Instruction instruction) { if (context.SP == 0) #if DEBUG { throw new StackUnderflowException(); } #else { return(true); } #endif context.PC = context.Stack[context.SP--]; return(true); }
/// <summary> /// 2nnn - CALL addr ///Call subroutine at nnn. /// ///The interpreter increments the stack pointer, then puts the current PC on the top of the stack. The PC is then set to nnn. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool CALL(CpuCore context, Instruction instruction) { if (context.SP + 1 >= context.Stack.Length) #if DEBUG { throw new StackOverflowException(); } #else { return(true); } #endif context.Stack[++context.SP] = context.PC; context.PC = instruction.NNN; return(false); }
protected MajorbbsTestBase() { mbbsEmuMemoryCore = new MemoryCore(); mbbsEmuCpuRegisters = new CpuRegisters(); mbbsEmuCpuCore = new CpuCore(); mbbsModule = new MbbsModule(FileUtility.CreateForTest(), _serviceResolver.GetService <ILogger>(), null, string.Empty, mbbsEmuMemoryCore); majorbbs = new HostProcess.ExportedModules.Majorbbs( _serviceResolver.GetService <ILogger>(), _serviceResolver.GetService <IConfiguration>(), _serviceResolver.GetService <IFileUtility>(), _serviceResolver.GetService <IGlobalCache>(), mbbsModule, new PointerDictionary <Session.SessionBase>()); mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, MajorbbsFunctionDelegate); }
public Kernel(Xbox box) { Box = box; Cpu = box.Cpu; foreach (var method in typeof(Kernel).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { var attr = method.GetCustomAttribute <ExportAttribute>(); if (attr != null) { Functions[attr.Number] = MakeWrapper(method, attr.CallingConvention); } } Console.WriteLine($"Implemented {Functions.Count}/366 kernel functions"); }
private void Execute(string[] args) { var realMode = args.Length == 1 && (args[0].Equals("-realmode") || args[0].Equals("-real")); if (realMode) { memoryCore = realModeMemoryCore = new RealModeMemoryCore(logger: null); } else { memoryCore = protectedModeMemoryCore = new ProtectedModeMemoryCore(null); } mbbsEmuCpuCore = new CpuCore(logger: null); mbbsEmuCpuRegisters = (ICpuRegisters)mbbsEmuCpuCore; mbbsEmuCpuCore.Reset(memoryCore, null, null, null); // Reset mbbsEmuCpuRegisters.Zero(); mbbsEmuCpuCore.Reset(); memoryCore.Clear(); mbbsEmuCpuCore.Registers.CS = 0x1000; mbbsEmuCpuCore.Registers.DS = 2; mbbsEmuCpuCore.Registers.IP = 0; var instructions = new Assembler(16); var label_start = instructions.CreateLabel(); var label_loop = instructions.CreateLabel(); instructions.Label(ref label_start); instructions.mov(__word_ptr[0], 1); instructions.Label(ref label_loop); instructions.mov(ax, __word_ptr[0]); instructions.cmp(ax, 0x7FFF); instructions.je(label_start); instructions.inc(__word_ptr[0]); instructions.jmp(label_loop); CreateCodeSegment(instructions); CreateDataSegment(new ReadOnlySpan <byte>()); _isRunning = true; new Thread(RunThread).Start(); new Thread(MonitorThread).Start(); Console.ReadKey(); _isRunning = false; }
/// <summary> /// 8xy4 - ADD Vx, Vy ///Set Vx = Vx + Vy, set VF = carry. /// ///The values of Vx and Vy are added together. If the result is greater than 8 bits (i.e., > 255,) VF is set to 1, otherwise 0. Only the lowest 8 bits of the result are kept, and stored in Vx. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool ADD(CpuCore context, Instruction instruction) { var res = context.GPR[instruction.X] + context.GPR[instruction.Y]; if (res > byte.MaxValue) { context.VF = 1; } else { context.VF = 0; } context.GPR[instruction.X] = ( byte )res; return(true); }
/// <summary> /// 8xy6 - SHR Vx {, Vy} ///Set Vx = Vx SHR 1. /// ///If the least-significant bit of Vx is 1, then VF is set to 1, otherwise 0. Then Vx is divided by 2. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool SHR(CpuCore context, Instruction instruction) { var x = instruction.X; if ((context.GPR[x] & 1) == 1) { context.VF = 1; } else { context.VF = 0; } context.GPR[x] /= 2; return(true); }
/// <summary> /// 8xyE - SHL Vx {, Vy} ///Set Vx = Vx SHL 1. /// ///If the most-significant bit of Vx is 1, then VF is set to 1, otherwise to 0. Then Vx is multiplied by 2. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool SHL(CpuCore context, Instruction instruction) { var x = instruction.X; if ((context.GPR[x] & 0x80) == 0x80) { context.VF = 1; } else { context.VF = 0; } context.GPR[x] *= 2; return(true); }
protected ExportedModuleTestBase(string modulePath) { _serviceResolver = new ServiceResolver(fakeClock, SessionBuilder.ForTest($"MBBSDb_{RANDOM.Next()}")); var textVariableService = _serviceResolver.GetService <ITextVariableService>(); mbbsEmuMemoryCore = mbbsEmuProtectedModeMemoryCore = new ProtectedModeMemoryCore(_serviceResolver.GetService <ILogger>()); mbbsEmuCpuCore = new CpuCore(_serviceResolver.GetService <ILogger>()); mbbsEmuCpuRegisters = mbbsEmuCpuCore; var testModuleConfig = new ModuleConfiguration { ModulePath = modulePath, ModuleEnabled = true }; mbbsModule = new MbbsModule(FileUtility.CreateForTest(), fakeClock, _serviceResolver.GetService <ILogger>(), testModuleConfig, mbbsEmuProtectedModeMemoryCore); testSessions = new PointerDictionary <SessionBase>(); testSessions.Allocate(new TestSession(null, textVariableService)); testSessions.Allocate(new TestSession(null, textVariableService)); majorbbs = new HostProcess.ExportedModules.Majorbbs( _serviceResolver.GetService <IClock>(), _serviceResolver.GetService <ILogger>(), _serviceResolver.GetService <AppSettings>(), _serviceResolver.GetService <IFileUtility>(), _serviceResolver.GetService <IGlobalCache>(), mbbsModule, testSessions, _serviceResolver.GetService <IAccountKeyRepository>(), _serviceResolver.GetService <IAccountRepository>(), textVariableService); galgsbl = new HostProcess.ExportedModules.Galgsbl( _serviceResolver.GetService <IClock>(), _serviceResolver.GetService <ILogger>(), _serviceResolver.GetService <AppSettings>(), _serviceResolver.GetService <IFileUtility>(), _serviceResolver.GetService <IGlobalCache>(), mbbsModule, testSessions, textVariableService); mbbsEmuCpuCore.Reset( mbbsEmuMemoryCore, (ordinal, functionOrdinal) => ExportedFunctionDelegate(ordinal, functionOrdinal, offsetsOnly: false), null, null); }
/// <summary> /// 8xy5 - SUB Vx, Vy ///Set Vx = Vx - Vy, set VF = NOT borrow. /// ///If Vx > Vy, then VF is set to 1, otherwise 0. Then Vy is subtracted from Vx, and the results stored in Vx. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool SUB(CpuCore context, Instruction instruction) { var x = instruction.X; var y = instruction.Y; if (context.GPR[x] > context.GPR[y]) { context.VF = 1; } else { context.VF = 0; } context.GPR[x] -= context.GPR[y]; return(true); }
/// <summary> /// 8xy7 - SUBN Vx, Vy ///Set Vx = Vy - Vx, set VF = NOT borrow. /// ///If Vy > Vx, then VF is set to 1, otherwise 0. Then Vx is subtracted from Vy, and the results stored in Vx. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool SUBN(CpuCore context, Instruction instruction) { var x = instruction.X; var y = instruction.Y; if (context.GPR[y] > context.GPR[x]) { context.VF = 1; } else { context.VF = 0; } context.GPR[x] = ( byte )(context.GPR[y] - context.GPR[x]); return(true); }
/// <summary> /// Dxyn - DRW Vx, Vy, nibble /// Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision. /// /// The interpreter reads n bytes from memory, starting at the address stored in I. /// These bytes are then displayed as sprites on screen at coordinates (Vx, Vy). Sprites are XORed onto the existing screen. /// If this causes any pixels to be erased, VF is set to 1, otherwise it is set to 0. /// If the sprite is positioned so part of it is outside the coordinates of the display, it wraps around to the opposite side of the screen. /// See instruction 8xy3 for more information on XOR, and section 2.4, Display, for more information on the Chip-8 screen and sprites. /// </summary> /// <param name="context"></param> /// <param name="instruction"></param> /// <returns></returns> private static bool DRW(CpuCore context, Instruction instruction) { var x = context.GPR[instruction.X]; var y = context.GPR[instruction.Y]; var bytes = context.Memory.ReadBytes(context.I, instruction.N); if (context.Display.DrawSprite(x, y, bytes)) { context.VF = 1; } else { context.VF = 0; } return(true); }
private static List <CpuCore> GetCpuCoreList() { List <CpuCore> cpuCoreList = new List <CpuCore>(); using ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'"); foreach (ManagementObject mo in mos.Get()) { CpuCore core = new CpuCore { Name = GetPropertyString(mo["Name"]), PercentProcessorTime = GetPropertyValue <ulong>(mo["PercentProcessorTime"]) }; cpuCoreList.Add(core); } return(cpuCoreList); }
protected CpuTestBase() { mbbsEmuMemoryCore = mbbsEmuProtectedModeMemoryCore = new ProtectedModeMemoryCore(logger: null); mbbsEmuCpuCore = new CpuCore(logger: null); mbbsEmuCpuRegisters = mbbsEmuCpuCore; pit = new ProgrammableIntervalTimer(logger: null, fakeClock, mbbsEmuCpuCore); mbbsEmuCpuCore.Reset( mbbsEmuMemoryCore, null, null, new Dictionary <int, IIOPort> { { 0x40, pit }, { 0x41, pit }, { 0x42, pit }, { 0x43, pit }, }); }