public void TestInterpreter() { var ExecuteStep = Chip8Interpreter.CreateExecuteStep(); var CpuContext = new CpuContext(new SimpleFastMemory4BigEndian(12), new Display(), new Syscall(), new Controller()); var Instructions = new ushort[] { 0x70FF, 0x7102, 0x7103, }; CpuContext.PC = 0; foreach (var Instruction in Instructions) { CpuContext.WriteInstruction(Instruction); } CpuContext.PC = 0; Assert.AreEqual(0, CpuContext.PC); Assert.AreEqual(0x00, CpuContext.V[0]); Assert.AreEqual(0x00, CpuContext.V[1]); { for (int n = 0; n < Instructions.Length; n++) { ExecuteStep(CpuContext.ReadInstruction, CpuContext); } } Assert.AreEqual(Instructions.Length * 2, CpuContext.PC); Assert.AreEqual(0xFF, CpuContext.V[0]); Assert.AreEqual(0x05, CpuContext.V[1]); }
public Action<ThreadContext> GenerateMethod(CpuContext CpuContext, Stream Stream) { var Generator = new Generator(CpuContext, Stream); //Console.WriteLine("Generate"); Generator.GenerateMethod(); return Generator.CreateDelegate(); }
public ConfiguratePage() { InitializeComponent(); CpuContext dbCpu; dbCpu = new CpuContext(); dbCpu.CPUs.Load(); cpusGrid.ItemsSource = dbCpu.CPUs.Local.ToBindingList(); GpuContext dbGpu; dbGpu = new GpuContext(); dbGpu.GPUs.Load(); gpusGrid.ItemsSource = dbGpu.GPUs.Local.ToBindingList(); MotherboardContext dbMotherboard; dbMotherboard = new MotherboardContext(); dbMotherboard.Motherboards.Load(); // загружаем данные motherboardsGrid.ItemsSource = dbMotherboard.Motherboards.Local.ToBindingList(); RamContext dbRam; dbRam = new RamContext(); dbRam.Rams.Load(); // загружаем данные motherboardsGrid.ItemsSource = dbRam.Rams.Local.ToBindingList(); }
public ManageCpu() { InitializeComponent(); db = new CpuContext(); db.CPUs.Load(); // загружаем данные cpusGrid.ItemsSource = db.CPUs.Local.ToBindingList(); // устанавливаем привязку к кэшу }
public ArmProcessContext(T memoryManager, bool for64Bit) { if (memoryManager is IRefCounted rc) { rc.IncrementReferenceCount(); } _memoryManager = memoryManager; _cpuContext = new CpuContext(memoryManager, for64Bit); }
public Generator(CpuContext CpuContext, Stream Stream) { this.CpuContext = CpuContext; this.Stream = Stream; this.Reader = new BinaryReader(Stream); this.DynamicMethod = new DynamicMethod( "MethodGenerator.GenerateMethod", typeof(void), new Type[] { typeof(ThreadContext) }, Assembly.GetExecutingAssembly().ManifestModule ); this.ILGenerator = DynamicMethod.GetILGenerator(); }
public ArmProcessContext(ulong pid, GpuContext gpuContext, T memoryManager, bool for64Bit) { if (memoryManager is IRefCounted rc) { rc.IncrementReferenceCount(); } gpuContext.RegisterProcess(pid, memoryManager); _pid = pid; _gpuContext = gpuContext; _cpuContext = new CpuContext(memoryManager, for64Bit); _memoryManager = memoryManager; }
private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion) { int addrSpaceBits = addrSpaceType switch { AddressSpaceType.Addr32Bits => 32, AddressSpaceType.Addr36Bits => 36, AddressSpaceType.Addr32BitsNoMap => 32, AddressSpaceType.Addr39Bits => 39, _ => throw new ArgumentException(nameof(addrSpaceType)) }; CpuMemory = new MemoryManager(KernelContext.Memory, 1UL << addrSpaceBits, InvalidAccessHandler); CpuContext = new CpuContext(CpuMemory); // TODO: This should eventually be removed. // The GPU shouldn't depend on the CPU memory manager at all. KernelContext.Device.Gpu.SetVmm(CpuMemory); MemoryManager = new KMemoryManager(KernelContext, CpuMemory); }
public static byte doArithmeticByte(CpuContext ctx, byte a1, byte a2, bool withCarry, bool isSub) { ushort res; /* To detect carry */ if (isSub) { ctx.SETFLAG(Z80Flags.F_N); ctx.VALFLAG(Z80Flags.F_H, (((a1 & 0x0F) - (a2 & 0x0F)) & 0x10) != 0); res = (ushort)(a1 - a2); if (withCarry && ctx.GETFLAG(Z80Flags.F_C)) res--; } else { ctx.RESFLAG(Z80Flags.F_N); ctx.VALFLAG(Z80Flags.F_H, (((a1 & 0x0F) + (a2 & 0x0F)) & 0x10) != 0); res = (ushort)(a1 + a2); if (withCarry && ctx.GETFLAG(Z80Flags.F_C)) res++; } ctx.VALFLAG(Z80Flags.F_S, ((res & 0x80) != 0)); ctx.VALFLAG(Z80Flags.F_C, ((res & 0x100) != 0)); ctx.VALFLAG(Z80Flags.F_Z, ((res & 0xff) == 0)); int minuend_sign = a1 & 0x80; int subtrahend_sign = a2 & 0x80; int result_sign = res & 0x80; bool overflow; if (isSub) { overflow = minuend_sign != subtrahend_sign && result_sign != minuend_sign; } else { overflow = minuend_sign == subtrahend_sign && result_sign != minuend_sign; } ctx.VALFLAG(Z80Flags.F_PV, overflow); adjustFlags(ctx, (byte)res); return (byte)(res & 0xFF); }
private static void _ADD(CpuContext Context, byte X, byte Value) { Context.V[15] = (byte)(((Context.V[X] + Value) > 255) ? 1 : 0); Context.V[X] += Value; }
public static void AND(CpuContext Context, byte X, byte Y) { Context.V[X] &= Context.V[Y]; }
/// <summary> /// Fx65: Fills V0 to VX with values from memory starting at address I. /// On the original interpreter, when the operation is done, I=I+X+1. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> public static void LD_vx_Iptr(CpuContext Context, byte X) { for (int n = 0; n < X; n++) { Context.V[n] = Context.Memory.Read1(Context.I++); } }
public static void XOR(CpuContext Context, byte X, byte Y) { Context.V[X] ^= Context.V[Y]; }
/// <summary> /// /// </summary> /// <param name="Context"></param> public static void INVALID(CpuContext Context) { throw (new Exception("Invalid instruction!")); }
/// <summary> /// 8xy0: LD Vx, Vy /// </summary> /// <param name="Context"></param> /// <param name="X"></param> /// <param name="Y"></param> public static void LD_v(CpuContext Context, byte X, byte Y) { Context.V[X] = Context.V[Y]; }
/// <summary> /// Ex9E: Skips the next instruction if the key stored in VX is pressed. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> public static void SKP(CpuContext Context, byte X) { if (Context.Controller.IsPressed(Context.V[X])) Context.PC += 2; }
public static void CLS(CpuContext Context) { Context.Display.Clear(); }
/// <summary> /// Cxnn: Sets VX to a random number and NN. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> /// <param name="Byte"></param> public static void RND(CpuContext Context, byte X, byte Byte) { Context.V[X] = (byte)(Context.Random.Next() & Byte); }
public static void ADD_v(CpuContext Context, byte X, byte Y) { _ADD(Context, X, Context.V[Y]); }
public static void ADD_n(CpuContext Context, byte X, byte Byte) { _ADD(Context, X, Byte); //Context.V[X] += Byte; }
public static void RET(CpuContext Context) { Context.PC = Context.CallStack.Pop(); }
/// <summary> /// Fx0A: 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 /// A key press is awaited, and then stored in VX. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> public static void LD_vx_k(CpuContext Context, byte X) { while (true) { var Ret = Context.Controller.GetPressMask(); if (Ret.HasValue) { Context.V[X] = Ret.Value; return; } else { Thread.Sleep(1); continue; } } }
private static void _SUB(CpuContext Context, byte X, byte Value) { Context.V[15] = (byte)(((Context.V[X] > Value)) ? 1 : 0); Context.V[X] -= Value; }
/// <summary> /// 4XNN : Skips the next instruction if VX doesn't equal NN. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> /// <param name="Byte"></param> public static void SNE_n(CpuContext Context, byte X, byte Byte) { if (Context.V[X] != Byte) Context.PC += 2; }
/// <summary> /// 2NNN: Calls subroutine at NNN. /// </summary> /// <param name="Context"></param> /// <param name="Address"></param> public static void CALL(CpuContext Context, ushort Address) { Context.CallStack.Push(Context.PC); JP(Context, Address); }
void ISyscall.Call(CpuContext CpuContext, ushort Address) { //throw new NotImplementedException(); }
/// <summary> /// Dxyn: Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N pixels. /// Each row of 8 pixels is read as bit-coded (with the most significant bit of each byte displayed on the left) /// starting from memory location I; I value doesn't change after the execution of this instruction. /// As described above, VF is set to 1 if any screen pixels are flipped from set to unset when the sprite is drawn, and to 0 if that doesn't happen. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> /// <param name="Y"></param> /// <param name="Nibble"></param> public static void DRW(CpuContext Context, byte X, byte Y, byte Nibble) { //Console.WriteLine("Draw({0}, {1}, {2})", Context.V[X], Context.V[Y], Nibble); Context.Display.Draw(ref Context.I, ref Context.V15, Context.Memory, Context.V[X], Context.V[Y], Nibble); }
/// <summary> /// Fx07: LD Vx, DT /// Set Vx = delay timer value /// The value of DT is placed into Vx. /// Sets VX to the value of the delay timer. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> public static void LD_vx_dt(CpuContext Context, byte X) { //Console.WriteLine("{0}", Context.DelayTimer.Value); Context.V[X] = Context.DelayTimer.Value; }
public ArmProcessContext(MemoryManager memoryManager) { _memoryManager = memoryManager; _cpuContext = new CpuContext(memoryManager); }
/// <summary> /// Fx18: Sets the sound timer to VX. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> public static void LD_st_vx(CpuContext Context, byte X) { Context.SoundTimer.Value = Context.V[X]; }
/// <summary> /// Fx55: Stores V0 to VX in memory starting at address I. /// On the original interpreter, when the operation is done, I=I+X+1. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> public static void LD_Iptr_vx(CpuContext Context, byte X) { for (int n = 0; n < X; n++) { Context.Memory.Write1(Context.I++, Context.V[n]); } }
/// <summary> /// Fx1E: Adds VX to I. /// VF is set to 1 when range overflow (I+VX>0xFFF), and 0 when there isn't. /// This is undocumented feature of the Chip-8 and used by Spacefight 2019! game. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> public static void ADD_i_vx(CpuContext Context, byte X) { Context.I += Context.V[X]; }
public static void SUB(CpuContext Context, byte X, byte Y) { _SUB(Context, X, Context.V[Y]); }
public static void SUBN(CpuContext Context, byte X, byte Y) { throw (new NotImplementedException()); }
/// <summary> /// /// </summary> /// <param name="Context"></param> /// <param name="X"></param> /// <param name="Y"></param> public static void SNE_v(CpuContext Context, byte X, byte Y) { if (Context.V[X] != Context.V[Y]) Context.PC += 2; }
/// <summary> /// 6XNN: Sets VX to NN. /// </summary> /// <param name="Context"></param> /// <param name="X"></param> /// <param name="Byte"></param> public static void LD_n(CpuContext Context, byte X, byte Byte) { Context.V[X] = Byte; }