public uint match; /* what to match after masking */ public opcode_handler_struct(opcode opcode_handler, uint bits, uint mask, uint match) { this.opcode_handler = opcode_handler; this.bits = bits; this.mask = mask; this.match = match; }
private static void ConsoleHelpText() { Console.WriteLine("Assemble folder or disassemble file for Smash 4 AI. Usage:"); Console.WriteLine("\t>no args: open the GUI"); foreach (int opValue in Enum.GetValues(typeof(opcode))) { opcode op = (opcode)opValue; Console.Write("\t>"); Console.ForegroundColor = ConsoleColor.Green; Console.Write(Enum.GetName(typeof(opcode), opValue)); Console.ResetColor(); Console.WriteLine(": " + descriptions[op]); } }
foreach (var(opcode, a, b, c) in program)
public s_opcode(uint cycles, opcode function) { this.cycles = cycles; this.function = function; }
public bool Step() { opcode currentInstruction = Decode(read(_PC)); _PC = (byte)(_PC + 1); instructionCount += 1; switch (currentInstruction) { case opcode.NOP: break; case opcode.STA: write(read(_PC), _AC); _PC = (byte)(_PC + 1); break; case opcode.LDA: _AC = read(read(_PC)); _PC = (byte)(_PC + 1); break; case opcode.ADD: // byte[] conv = new byte[2]; // conv[0] = _AC; // conv[1] = read(read(_PC)); // short data = BitConverter.ToInt16(conv,0); //byte g =_AC; //sbyte q =(read(read(_PC)); //sbyte t = (sbyte)(g + q); // if (t < 0) int resultADD = _AC + read(read(_PC)); _AC = (byte)(resultADD & 0xFF); _PC = (byte)(_PC + 1); updateFLAGS(); break; case opcode.OR: int resultOR = (_AC | read(read(_PC))); _AC = (byte)resultOR; _PC = (byte)(_PC + 1); updateFLAGS(); break; case opcode.AND: int resultAND = (_AC & read(read(_PC))); _AC = (byte)resultAND; _PC = (byte)(_PC + 1); updateFLAGS(); break; case opcode.NOT: int resultNOT = ~(_AC); _AC = (byte)resultNOT; updateFLAGS(); break; case opcode.JMP: _PC = (byte)(read(_PC)); break; case opcode.JN: if (_N == true) { _PC = read(_PC); } else { read(_PC); _PC = (byte)(_PC + 1); } break; case opcode.JZ: if (_Z == true) { _PC = read(_PC); } else { read(_PC); _PC = (byte)(_PC + 1); } break; case opcode.HLT: return(false); case opcode.INVALID: break; } if (_PC >= 255) { // _PC = 0; return(false); } return(true); }
=> this.Update(opcode, low, high);
set => RegisterInstruction(opcode, value);
: super(opcode) { }
: super(opcode) { this.type = type; }
: super(opcode) { this.method = method; }
: super(opcode) { this.field = field; }
: super(opcode) { this.labelMarker = labelMarker; }
: super(opcode) { this.intOperand = intOperand; }
: super(opcode) { this.localVariable = localVariable; }
private static void ConsoleMain(string[] args) { //project handling variables AITree tree = null; string[] fighters = new string[0]; bool allFighters = true; AITree.AIType[] types = new AITree.AIType[0]; bool allTypes = true; try { for (int i = 0; i < args.Length; i++) { opcode op = (opcode)Enum.Parse(typeof(opcode), args[i].TrimStart('-')); string notOpenMsg = "ERROR: project must be open for opcode " + args[i]; string notClosedMsg = "ERROR: project must be closed for opcode " + args[i]; switch (op) { case opcode.h: ConsoleHelpText(); break; case opcode.wp: if (tree != null) { throw new Exception(notClosedMsg); } util.workDir = args[++i]; if (!Directory.Exists(util.workDir)) { Directory.CreateDirectory(util.workDir); } break; case opcode.cp: util.compDir = args[++i]; if (!Directory.Exists(util.compDir)) { Directory.CreateDirectory(util.compDir); } break; case opcode.gp: util.gameFtDir = args[++i]; break; case opcode.fl: i++; if (args[i] == "all") { allFighters = true; break; } allFighters = false; fighters = args[i].Split(','); break; case opcode.tl: { i++; if (args[i] == "all") { allTypes = true; break; } allTypes = false; string[] strTypes = args[i].Split(','); List <AITree.AIType> typeList = new List <AITree.AIType>(); for (int j = 0; j < strTypes.Length; j++) { AITree.AIType newType = AITree.StringToAIType[strTypes[j]]; if (!typeList.Contains(newType)) { typeList.Add(newType); } } types = typeList.ToArray(); break; } case opcode.d: aism.DisassembleFile(args[++i], util.workDir); break; case opcode.a: aism.AssembleFolder(args[++i], util.compDir); break; case opcode.po: if (tree != null) { throw new Exception(notClosedMsg); } tree = new AITree(); tree.InitOpenProject(); break; case opcode.pn: { if (tree != null) { throw new Exception(notClosedMsg); } tree = new AITree(); string[] loc_fighters = fighters; AITree.AIType[] loc_types = types; if (allFighters) { List <string> fighterNames = new List <string>(); foreach (string dir in Directory.EnumerateDirectories(util.gameFtDir)) { fighterNames.Add(util.GetFolderName(dir)); } loc_fighters = fighterNames.ToArray(); } if (allTypes) { loc_types = new AITree.AIType[] { AITree.AIType.attack_data, AITree.AIType.param, AITree.AIType.param_nfp, AITree.AIType.script } } ; tree.InitNewProject(loc_fighters, loc_types); break; } case opcode.pac: { if (tree == null) { throw new Exception(notOpenMsg); } string[] loc_fighters = fighters; AITree.AIType[] loc_types = types; if (allFighters) { List <string> fighterNames = new List <string>(); foreach (string dir in Directory.EnumerateDirectories(util.compDir)) { fighterNames.Add(util.GetFolderName(dir)); } loc_fighters = fighterNames.ToArray(); } if (allTypes) { loc_types = new AITree.AIType[] { AITree.AIType.attack_data, AITree.AIType.param, AITree.AIType.param_nfp, AITree.AIType.script } } ; tree.AddProjectFiles(loc_fighters, loc_types, AITree.AISource.compiled); break; } case opcode.pag: { if (tree == null) { throw new Exception(notOpenMsg); } string[] loc_fighters = fighters; AITree.AIType[] loc_types = types; if (allFighters) { List <string> fighterNames = new List <string>(); foreach (string dir in Directory.EnumerateDirectories(util.gameFtDir)) { fighterNames.Add(util.GetFolderName(dir)); } loc_fighters = fighterNames.ToArray(); } if (allTypes) { loc_types = new AITree.AIType[] { AITree.AIType.attack_data, AITree.AIType.param, AITree.AIType.param_nfp, AITree.AIType.script } } ; tree.AddProjectFiles(loc_fighters, loc_types, AITree.AISource.game_file); break; } case opcode.pcm: { if (tree == null) { throw new Exception(notOpenMsg); } string[] loc_fighters = fighters; AITree.AIType[] loc_types = types; if (allFighters) { List <string> fighterNames = new List <string>(); foreach (string dir in Directory.EnumerateDirectories(util.workDir)) { fighterNames.Add(util.GetFolderName(dir)); } loc_fighters = fighterNames.ToArray(); } if (allTypes) { loc_types = new AITree.AIType[] { AITree.AIType.attack_data, AITree.AIType.param, AITree.AIType.param_nfp, AITree.AIType.script } } ; foreach (var ft in loc_fighters) { foreach (var type in loc_types) { string pathIn = AITree.GetFolderPath(ft, type, AITree.AISource.work); if (Directory.Exists(pathIn)) { string pathOut = AITree.GetFolderPath(ft, type, AITree.AISource.compiled); aism.AssembleFolder(pathIn, pathOut); } } } break; } case opcode.pcl: if (tree == null) { throw new Exception(notOpenMsg); } tree = null; break; case opcode.pd: Console.WriteLine("workspace: " + util.workDir); Console.WriteLine("compile: " + util.compDir); Console.WriteLine("game: " + util.gameFtDir); break; case opcode.pt: { if (tree == null) { throw new Exception(notOpenMsg); } foreach (var ft in tree.fighters) { Console.Write(ft.name + ": {"); int count = ft.files.Count; for (int j = 0; j < count; j++) { Console.Write(AITree.AITypeToString[ft.files[j].type]); if (j < count - 1) { Console.Write(", "); } } Console.WriteLine("}"); } break; } } } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(helpReminder); } }
void m68k_set_instr_hook_callback(opcode callback) { m68k_cpu.instr_hook_callback = callback != null ? callback : default_instr_hook_callback; }
public override line GetNextLine(ByteProvider bp) { x86_64_line l = new x86_64_line(); List <byte> os = new List <byte>(); l.offset_start = bp.Offset; byte rex = 0x0; bool has_prefix_66 = false; bool has_prefix_f2 = false; bool has_prefix_f3 = false; byte b = bp.GetNextByte(); os.Add(b); // read any prefixes bool reading_prefixes = true; List <ulong> prefixes = new List <ulong>(); while (reading_prefixes) { switch (b) { case 0xf2: case 0x66: case 0xf3: if (b == 0xf2) { has_prefix_f2 = true; } if (b == 0xf3) { has_prefix_f3 = true; } if (b == 0x66) { has_prefix_66 = true; } b = bp.GetNextByte(); os.Add(b); break; case 0xf0: case 0x2e: case 0x36: case 0x3e: case 0x26: case 0x64: case 0x65: case 0x67: prefixes.Add(b); b = bp.GetNextByte(); os.Add(b); break; default: reading_prefixes = false; break; } } l.prefixes = prefixes.ToArray(); // read any rex prefix if ((b >= 0x40) && (b <= 0x4f)) { prefixes.Add(b); l.prefixes = prefixes.ToArray(); rex = b; b = bp.GetNextByte(); os.Add(b); } // read the opcode if (b == 0x0f) { // two byte opcode /* read any rex prefix (in multi-byte opcodes, the rex * prefix comes after the 0x0f byte) */ byte b2 = bp.GetNextByte(); os.Add(b2); if ((b2 >= 0x40) && (b2 <= 0x4f)) { prefixes.Add(b2); l.prefixes = prefixes.ToArray(); rex = b; b2 = bp.GetNextByte(); os.Add(b2); } if ((b2 == 0x38) || (b2 == 0x3a)) { byte b3 = bp.GetNextByte(); os.Add(b3); l.opcode = (ulong)((b << 16) + (b2 << 8) + b3); } else if (has_prefix_f2) { l.opcode = (ulong)((0xf2 << 16) + (b << 8) + b2); } else if (has_prefix_f3) { l.opcode = (ulong)((0xf3 << 16) + (b << 8) + b2); } else if (has_prefix_66) { l.opcode = (ulong)((0x66 << 16) + (b << 8) + b2); } else { l.opcode = (ulong)((b << 8) + b2); } } else { if (has_prefix_f2) { prefixes.Add(0xf2); } if (has_prefix_f3) { prefixes.Add(0xf3); } if (has_prefix_66) { prefixes.Add(0x66); } l.opcode = (ulong)b; } opcode o = null; if (opcodes.ContainsKey(l.opcode)) { o = opcodes[l.opcode]; } if (o == null) { l.offset_end = bp.Offset; return(l); } else { byte modrm; byte sib = 0; long disp = 0; ulong imm = 0; if (o.has_rm) { // read the rm byte modrm = bp.GetNextByte(); os.Add(modrm); byte mod = (byte)(modrm >> 6); byte rm = (byte)(modrm & 7); byte reg = (byte)((modrm >> 3) & 7); if (o.reinterpret_after_r) { l.opcode = (((ulong)reg) << 24) + l.opcode + 0x10000000; if (opcodes.ContainsKey(l.opcode)) { o = opcodes[l.opcode]; } else { l.offset_end = bp.Offset; return(l); } } // decide if we need an sib byte if ((mod != 3) && (rm == 4)) { sib = bp.GetNextByte(); os.Add(sib); } // decide if we need a displacement if (((mod == 0) && (rm == 5)) || (mod == 2)) { // 4 byte displacement byte d1 = bp.GetNextByte(); os.Add(d1); byte d2 = bp.GetNextByte(); os.Add(d2); byte d3 = bp.GetNextByte(); os.Add(d3); byte d4 = bp.GetNextByte(); os.Add(d4); byte[] dval = new byte[] { d1, d2, d3, d4 }; disp = BitConverter.ToInt32(dval, 0); //disp = (ulong)d1 + (((ulong)d2) << 8) + (((ulong)d3) << 16) + (((ulong)d4) << 24); } else if (mod == 1) { // 1 byte displacement byte d1 = bp.GetNextByte(); os.Add(d1); byte extend = 0; if ((d1 & 0x80) == 0x80) { extend = 0xff; } byte[] dval = new byte[] { d1, extend, extend, extend }; disp = BitConverter.ToInt32(dval, 0); } // load a immediate value if necessary int imm_length = o.immediate_length; if ((imm_length == 4) && (o.immediate_extends_on_rexw) && ((rex & 0x08) == 0x08)) { imm_length = 8; } for (int i = 0; i < imm_length; i++) { byte cur_b = bp.GetNextByte(); os.Add(cur_b); imm += ((ulong)cur_b) << (i * 8); } // work out the opcodes List <location> args = new List <location>(); foreach (opcode.operand_source osrc in o.operand_sources) { switch (osrc.type) { case opcode.operand_source.src_type.Fixed: if (osrc.Fixed_Location.type == location.location_type.Register) { ulong reg_no = osrc.Fixed_Location.reg_no; reg_no = reg_no % 8; if (osrc.extends_on_rexb && ((rex & 0x01) == 0x01)) { reg_no += reg_nos["r8"]; } else if ((rex & 0x08) == 0x08) { reg_no += reg_nos["rax"]; } else { reg_no = osrc.Fixed_Location.reg_no; } args.Add(new location { type = location.location_type.Register, reg_no = reg_no }); } else { args.Add(osrc.Fixed_Location); } break; case opcode.operand_source.src_type.Imm: args.Add(new location { type = location.location_type.Immediate, immediate = imm, is_pc_relative = osrc.is_pc_relative }); break; case opcode.operand_source.src_type.ModRM_Reg: { ulong base_reg = 0; switch (osrc.length) { case opcode.operand_source.reg_length.r8: base_reg = reg_nos["al"]; break; case opcode.operand_source.reg_length.r16: base_reg = reg_nos["ax"]; break; case opcode.operand_source.reg_length.r32: base_reg = reg_nos["eax"]; if (has_prefix_66) { base_reg = reg_nos["ax"]; } else { if (((rex & rex_w) == rex_w) && osrc.extends_on_rexw) { base_reg = reg_nos["rax"]; } if ((rex & 0x4) == 0x4) { base_reg = reg_nos["r8"]; } } break; case opcode.operand_source.reg_length.r64: base_reg = reg_nos["rax"]; if ((rex & 0x4) == 0x4) { base_reg = reg_nos["r8"]; } break; case opcode.operand_source.reg_length.mm: base_reg = reg_nos["mm0"]; break; case opcode.operand_source.reg_length.xmm: base_reg = reg_nos["xmm0"]; if ((rex & 0x4) == 0x4) { base_reg = reg_nos["xmm8"]; } break; case opcode.operand_source.reg_length.cr: base_reg = reg_nos["cr0"]; break; } args.Add(new location { type = location.location_type.Register, reg_no = base_reg + (ulong)reg }); } break; case opcode.operand_source.src_type.ModRM_RM: { if (mod == 3) { ulong base_reg = 0; switch (osrc.length) { case opcode.operand_source.reg_length.r8: base_reg = reg_nos["al"]; break; case opcode.operand_source.reg_length.r16: base_reg = reg_nos["ax"]; break; case opcode.operand_source.reg_length.r32: base_reg = reg_nos["eax"]; if (has_prefix_66) { base_reg = reg_nos["ax"]; } else { if (((rex & rex_w) == rex_w) && osrc.extends_on_rexw) { base_reg = reg_nos["rax"]; } if ((rex & 0x1) == 0x1) { base_reg = reg_nos["r8"]; } } break; case opcode.operand_source.reg_length.r64: base_reg = reg_nos["rax"]; if ((rex & 0x1) == 0x1) { base_reg = reg_nos["r8"]; } break; case opcode.operand_source.reg_length.mm: base_reg = reg_nos["mm0"]; break; case opcode.operand_source.reg_length.xmm: base_reg = reg_nos["xmm0"]; if ((rex & 0x1) == 0x1) { base_reg = reg_nos["xmm8"]; } break; case opcode.operand_source.reg_length.cr: base_reg = reg_nos["cr0"]; break; } args.Add(new location { type = location.location_type.Register, reg_no = base_reg + (ulong)rm }); } else { ulong base_reg = reg_nos["rax"]; switch (rm) { case 0: base_reg = reg_nos["rax"]; break; case 1: base_reg = reg_nos["rcx"]; break; case 2: base_reg = reg_nos["rdx"]; break; case 3: base_reg = reg_nos["rbx"]; break; case 4: { // interpret sib byte byte s_scale = (byte)(sib >> 6); byte s_base = (byte)(sib & 7); byte s_index = (byte)((sib >> 3) & 7); List <location> sib_args = new List <location>(); bool need_plus = false; // the special combination of base = 5, mod = 0, rex_b = 0 means no base if (!((s_base == 5) && (mod == 0) && ((rex & rex_b) == rex_b))) { // otherwise we have a base ulong s_base_base_reg = reg_nos["rax"]; if ((rex & rex_b) == rex_b) { s_base_base_reg = reg_nos["r8"]; } need_plus = true; sib_args.Add(new location { type = location.location_type.Register, reg_no = s_base_base_reg + s_base }); } // if s_index != 4, then we have a index register if (!((s_index == 4) && ((rex & rex_x) != rex_x))) { location.scale_func scale = location.scale_func.None; if (need_plus) { scale = location.scale_func.Plus; } ulong s_index_base_reg = reg_nos["rax"]; if ((rex & rex_x) == rex_x) { s_index_base_reg = reg_nos["r8"]; } need_plus = true; sib_args.Add(new location { type = location.location_type.Register, reg_no = s_index_base_reg + s_index, scale = scale }); if (s_scale == 1) { sib_args.Add(new location { type = location.location_type.Const, immediate = 2, scale = location.scale_func.Multiply }); } else if (s_scale == 2) { sib_args.Add(new location { type = location.location_type.Const, immediate = 4, scale = location.scale_func.Multiply }); } else if (s_scale == 3) { sib_args.Add(new location { type = location.location_type.Const, immediate = 8, scale = location.scale_func.Multiply }); } } if ((mod == 1) || (mod == 2) || ((mod == 0) && (s_base == 5) && ((rex & rex_b) == rex_b))) { // add displacement location.scale_func scale = location.scale_func.None; if (need_plus) { scale = ((disp >= 0) ? location.scale_func.Plus : location.scale_func.Minus); } sib_args.Add(new location { type = location.location_type.Immediate, immediate = ((disp >= 0) ? (ulong)disp : (ulong)(-disp)), scale = scale }); } args.Add(new location { type = location.location_type.ContentsOf, args = sib_args.ToArray() }); continue; } case 5: { if (mod == 0) { args.Add(new location { type = location.location_type.ContentsOf, args = new location[] { new location { type = location.location_type.Register, reg_no = reg_nos["rip"] }, new location { type = location.location_type.Immediate, scale = ((disp >= 0) ? location.scale_func.Plus : location.scale_func.Minus), immediate = ((disp >= 0) ? (ulong)disp : (ulong)(-disp)) } } }); continue; } else { base_reg = reg_nos["rbp"]; } } break; case 6: base_reg = reg_nos["rsi"]; break; case 7: base_reg = reg_nos["rdi"]; break; } if ((rex & 0x1) == 0x1) { base_reg = base_reg - reg_nos["rax"] + reg_nos["r8"]; } location loc = new location { type = location.location_type.ContentsOf, args = new location[] { new location { type = location.location_type.Register, reg_no = base_reg } } }; if ((mod == 1) || (mod == 2)) { loc.args = new location[] { loc.args[0], new location { type = location.location_type.Immediate, scale = ((disp >= 0) ? location.scale_func.Plus : location.scale_func.Minus), immediate = ((disp >= 0) ? (ulong)disp : (ulong)(-disp)) } } } ; args.Add(loc); } } break; } } l.arguments = args.ToArray(); } else { // no mod_rm // load a immediate value if necessary int imm_length = o.immediate_length; if ((imm_length == 4) && (o.immediate_extends_on_rexw) && ((rex & 0x08) == 0x08)) { imm_length = 8; } for (int i = 0; i < imm_length; i++) { byte cur_b = bp.GetNextByte(); os.Add(cur_b); imm += ((ulong)cur_b) << (i * 8); } List <location> args = new List <location>(); foreach (opcode.operand_source osrc in o.operand_sources) { switch (osrc.type) { case opcode.operand_source.src_type.Fixed: if (osrc.Fixed_Location.type == location.location_type.Register) { ulong reg_no = osrc.Fixed_Location.reg_no; reg_no = reg_no % 8; if (osrc.extends_on_rexb && ((rex & 0x01) == 0x01)) { reg_no += reg_nos["r8"]; } else if ((rex & 0x08) == 0x08) { reg_no += reg_nos["rax"]; } else { reg_no = osrc.Fixed_Location.reg_no; } args.Add(new location { type = location.location_type.Register, reg_no = reg_no }); } else { args.Add(osrc.Fixed_Location); } break; case opcode.operand_source.src_type.Imm: args.Add(new location { type = location.location_type.Immediate, immediate = imm, is_pc_relative = osrc.is_pc_relative }); break; } } l.arguments = args.ToArray(); } } l.o = o; l.opcodes = os.ToArray(); l.bp = bp; l.offset_end = bp.Offset; return(l); }