public static void ADDI(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { gen.EmitGetRegister(inst.Value.Reg0, ctx); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Ldind_U1); gen.EmitLoadImmediate(inst); gen.Emit(OpCodes.Add); gen.Emit(OpCodes.Conv_U1); gen.Emit(OpCodes.Stind_I1); }
public static void LDREG(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { var method = typeof(Interpreter.Implementation).GetMethod(nameof(Implementation.LDREG)); //Args are: Chip8State state, byte regx gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4_S, inst.Value.Reg0); gen.Emit(OpCodes.Call, method); }
public static void STBCD(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { var method = typeof(Interpreter.Implementation).GetMethod(nameof(Implementation.STBCD)); //Args are: Chip8State state, ref byte regx gen.Emit(OpCodes.Ldarg_0); gen.EmitGetRegister(inst.Value.Reg0, ctx); gen.Emit(OpCodes.Call, method); }
public static void SNER(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { gen.EmitGetRegister(inst.Value.Reg0, ctx); gen.Emit(OpCodes.Ldind_I1); gen.Emit(OpCodes.Conv_U1); gen.EmitGetRegister(inst.Value.Reg1, ctx); gen.Emit(OpCodes.Ldind_I1); gen.Emit(OpCodes.Conv_U1); gen.Emit(OpCodes.Bne_Un, ctx.Label(inst.Offset + 4)); }
public static void JMP(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { if (inst.Instr.Value.Immediate16 == inst.Offset) { gen.Emit(OpCodes.Ret); } else { gen.Emit(OpCodes.Br, ctx.Labels[inst.Value.Immediate16]); } }
public static void ADDRI(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { gen.Emit(OpCodes.Ldarg_0); //reference for the last store call gen.EmitGetRegister(inst.Value.Reg0, ctx); gen.Emit(OpCodes.Ldind_I1); gen.Emit(OpCodes.Conv_U1); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Call, ctx.RegisterI.GetMethod); gen.Emit(OpCodes.Add); gen.Emit(OpCodes.Call, ctx.RegisterI.SetMethod); }
public static void DRW(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { var method = typeof(Interpreter.Implementation).GetMethod(nameof(Implementation.DRW)); //Args are: Chip8State state, ref byte regx, ref byte regy, byte imm4 gen.Emit(OpCodes.Ldarg_0); gen.EmitGetRegister(inst.Value.Reg0, ctx); gen.EmitGetRegister(inst.Value.Reg1, ctx); gen.Emit(OpCodes.Ldc_I4_S, inst.Value.Immediate4); gen.Emit(OpCodes.Call, method); }
public static void JMP0(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { List <Label> JumpTable = new List <Label>(); for (int i = inst.Value.Immediate16; i < inst.Value.Immediate16 + 256; i++) { JumpTable.Add(ctx.Label(i)); } gen.EmitGetRegister(0, ctx); gen.Emit(OpCodes.Ldind_I1); gen.Emit(OpCodes.Conv_U1); gen.Emit(OpCodes.Switch, JumpTable.ToArray()); }
public static void SHR(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { gen.EmitGetRegister(inst.Value.Reg0, ctx); gen.Emit(OpCodes.Dup); //Duplicate address for loading gen.Emit(OpCodes.Ldind_U1); //Load value gen.Emit(OpCodes.Dup); //duplicate value for VF comparison gen.Emit(OpCodes.Stloc_0); //Store for VF comparison gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Shr_Un); //Shift and store gen.Emit(OpCodes.Stind_I1); gen.EmitGetRegister(0xF, ctx); gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.And); gen.Emit(OpCodes.Stind_I1); }
public static void CALL(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Call, ctx.Functions[inst.Value.Immediate16].Method); }
public static void RET(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { gen.Emit(OpCodes.Ret); }
public static void SYS(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { Debug.WriteLine("WARN: Sys called"); }
public static void SKNP(JITContext ctx, Disassembler.DecompEntry inst, ILGenerator gen) { Debug.WriteLine("WARN: Unimplemented input instruction"); //Skip next instruction if key with the value of Vx is pressed. }
internal static void EmitLoadImmediate(this ILGenerator gen, Disassembler.DecompEntry inst) => gen.Emit(OpCodes.Ldc_I4, (int)inst.Value.Immediate16);