public Instruction(OpCodeTypes typ, params Value[] values) { this.Type = typ; Args = new List<Value>(); foreach (Value v in values) { Args.Add(v); } }
public static Instruction From(OpCodeTypes typ, Value[] values) { Instruction i = new Instruction(); i.Type = typ; i.Args = new List<Value>(); foreach (Value v in values) { i.Args.Add(v); } return i; }
static void Main(string[] args) { MemoryHandler memoryHandler = new MemoryHandler(ref AddressSpace); var docsFold = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var binaryFile = Path.Combine(docsFold, "asmBinaries", "Binary.bin"); byte[] binary = File.ReadAllBytes(binaryFile); binary.AsSpan().CopyTo(AddressSpace.AsSpan().Slice(0x8000)); ushort sp = 0x8000; ushort pc = 0x8000; Registers Register = new Registers(ref sp, ref pc); Register[31] = 0x8000; Register[30] = 0x8000; Execution execution = new Execution(memoryHandler, Register); MMIO mmio = new MMIO(AddressSpace); while (true) { mmio.Update(); Span <byte> instruction = memoryHandler.ByteInstructionSpace.Slice(Register[31] - 0x8000, 4); Register[31] += 4; int code = instruction[0]; OpCodeTypes opType = OpCodeHelpers.OpCodeTypeMap[(OpCodes)code]; switch (opType) { case OpCodeTypes.NoArgs: execution.NoArgs(code); break; case OpCodeTypes.OneAddr: ushort addr = (ushort)((instruction[2] << 8) | (instruction[3])); execution.OneAddress(code, addr); break; case OpCodeTypes.OneRegOneAddr: ushort address = (ushort)((instruction[2] << 8) | (instruction[3])); execution.OneRegOneAdr(code, instruction[1], address); break; case OpCodeTypes.OneReg: execution.OneReg(code, instruction[1]); break; case OpCodeTypes.TwoReg: execution.TwoReg(code, instruction[1], instruction[2]); break; case OpCodeTypes.TwoRegOneOffset: execution.TwoRegOneOffset(code, instruction[1], instruction[2], instruction[3]); break; case OpCodeTypes.ThreeReg: execution.ThreeReg(code, instruction[1], instruction[2], instruction[3]); break; } } }
/// <summary> /// Creates a new request for the specified type /// </summary> protected RequestBase(OpCodeTypes code) { OpCode = code; }
// Interpreting public static string[] ParseScript(uint[] cmd, int sanity = -1) { // sub_148CBC Moon v1.0 List <string> parse = new List <string>(); const int sanityMode = 0; // todo string ErrorNear(int line, string error) { var start = Math.Max(line - 6, 0); var end = Math.Min(line + 6, cmd.Length - 1); var toPrint = cmd.Skip(start).Take(end - start); var message = $"Error at line {line}:" + Environment.NewLine; message += string.Join(" ", toPrint.Select(b => $"{b:X2}")) + Environment.NewLine; for (var x = 0; x < line - start; x++) { message += " "; } message += "^^" + Environment.NewLine; message += error; return(message); } int i = 0; // Current Offset of decompressed instructions while (i < cmd.Length) // read away { // Read a Command string instrLine; var line = i; var opcodeval = cmd[i++]; var opcodesafe = opcodeval & 0xFFFF; if (!Enum.IsDefined(typeof(AmxOpCode), opcodesafe)) { throw new ArgumentException(ErrorNear(line, $"Invalid command ID: {opcodesafe:X4} ({opcodesafe})")); } var opcode = (AmxOpCode)opcodesafe; if (!OpCodeTypes.TryGetValue(opcode, out var optype)) { throw new ArgumentException(ErrorNear(line, $"Unknown OpCode: {opcodesafe:X4} ({opcodesafe})")); } switch (optype) { default: throw new ArgumentException("Invalid Command Type"); case AmxOpCodeType.NoParams: { instrLine = EchoIntCommand(opcode); break; } case AmxOpCodeType.OneParam: { var param = (int)cmd[i++]; instrLine = EchoIntCommand(opcode, param); break; } case AmxOpCodeType.TwoParams: { var param1 = (int)cmd[i++]; var param2 = (int)cmd[i++]; instrLine = EchoIntCommand(opcode, param1, param2); break; } case AmxOpCodeType.ThreeParams: { var param1 = (int)cmd[i++]; var param2 = (int)cmd[i++]; var param3 = (int)cmd[i++]; instrLine = EchoIntCommand(opcode, param1, param2, param3); break; } case AmxOpCodeType.FourParams: { var param1 = (int)cmd[i++]; var param2 = (int)cmd[i++]; var param3 = (int)cmd[i++]; var param4 = (int)cmd[i++]; instrLine = EchoIntCommand(opcode, param1, param2, param3, param4); break; } case AmxOpCodeType.FiveParams: { var param1 = (int)cmd[i++]; var param2 = (int)cmd[i++]; var param3 = (int)cmd[i++]; var param4 = (int)cmd[i++]; var param5 = (int)cmd[i++]; instrLine = EchoIntCommand(opcode, param1, param2, param3, param4, param5); break; } case AmxOpCodeType.Jump: { var jumpOffset = (int)cmd[i++]; var jumpDest = (line * 4) + jumpOffset; instrLine = $"{Commands[opcode].PadRight(MaxCommandLength, ' ')} => 0x{jumpDest:X4} ({jumpOffset})"; break; } case AmxOpCodeType.Packed: { var param = (short)(opcodeval >> 16); instrLine = EchoIntCommand(opcode, param); break; } case AmxOpCodeType.CaseTable: { //var jOffset = (i * 4) - 4; // this may be the correct jump start point... var count = cmd[i++]; // switch case table // sanity check // Populate Switch-Case Tree var tree = new List <string>(); // Cases for (int j = 0; j < count; j++) { var jmp = (int)cmd[i++]; var toOffset = ((i - 2) * 4) + jmp; var ifValue = (int)cmd[i++]; tree.Add($"\t{ifValue} => 0x{toOffset:X4} ({jmp})"); } // Default { int jmp = (int)cmd[i++]; var toOffset = ((i - 2) * 4) + jmp; tree.Add($"\t* => 0x{toOffset:X4} ({jmp})"); } instrLine = Commands[opcode] + Environment.NewLine + string.Join(Environment.NewLine, tree); break; } } if (opcode == AmxOpCode.RET || opcode == AmxOpCode.RETN || opcode == AmxOpCode.IRETN) { // Newline after return instrLine += Environment.NewLine; } if (parse.Count == 0 && opcode == AmxOpCode.HALT_P) { // Newline after 0x0000 HALT.P instrLine += Environment.NewLine; } parse.Add($"0x{line * 4:X4}: [{opcodeval & 0x7FF:X2}] {instrLine}"); } if (sanity >= 0 && sanity != sanityMode) { throw new ArgumentException(); } return(parse.ToArray()); }
/// <summary> /// Creates a request targeting a collection /// </summary> public CollectionRequestBase(OpCodeTypes code, string database, string collection) : base(code) { this.Database = (database ?? string.Empty).Trim(); this.Collection = (collection ?? string.Empty).Trim(); }
/// <summary> /// Creates a request targeting a collection /// </summary> public CollectionRequestBase(OpCodeTypes code, MongoCollection collection) : this(code, collection.Database.Name, collection.Name) { }
/// <summary> /// Creates a new request for the specified type /// </summary> public RequestBase(OpCodeTypes code) { this.OpCode = code; }
static void Main(string[] args) { byte[] AddressSpace = new byte[0x10000]; var docsFold = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var binaryFile = Path.Combine(docsFold, "asmBinaries", "Binary.bin"); byte[] binary = File.ReadAllBytes(binaryFile); binary.AsSpan().CopyTo(AddressSpace.AsSpan().Slice(0x8000)); for (int i = 0; i < binary.Length; i += 4) { OpCodes x = (OpCodes)binary[i]; if ((int)x == 175) { int length = binary[i + 2]; length = length * 2; for (int l = 0; l < length; l += 2) { Console.Write($"{(char)binary[(i + 4) + l]}"); } i += 2; i += length; Console.WriteLine(); continue; } Console.Write(x); OpCodeTypes opType = OpCodeHelpers.OpCodeTypeMap[x]; switch (opType) { case OpCodeTypes.NoArgs: Console.WriteLine(); break; case OpCodeTypes.OneAddr: ushort addr = (ushort)((binary[i + 2] << 8) | (binary[i + 3])); if (x == OpCodes.PSC) { Console.Write($" {addr}\n"); } else { Console.Write($" {AddressSpace[addr]}\n"); } break; case OpCodeTypes.OneReg: Console.Write($" r{binary[i + 1]}\n"); break; case OpCodeTypes.OneRegOneAddr: ushort address = (ushort)((binary[i + 2] << 8) | (binary[i + 3])); if (x == OpCodes.Set) { Console.Write($" r{binary[i + 1]} {address}\n"); } else { Console.Write($" r{binary[i+1]} {AddressSpace[address]}\n"); } break; case OpCodeTypes.ThreeReg: Console.Write($" r{binary[i + 1]} r{binary[i + 2]} r{binary[i + 3]}\n"); break; case OpCodeTypes.TwoReg: Console.Write($" r{binary[i + 1]} r{binary[i + 2]}\n"); break; case OpCodeTypes.TwoRegOneOffset: Console.Write($" r{binary[i + 1]} r{binary[i + 2]} {binary[i + 3]}\n"); break; } } Console.ReadKey(); }
static void ParseInstruction(ReadOnlySpan <char> instruction, List <byte> binary, Dictionary <int, string> labelReplacements) { if (instruction.IndexOf('"') >= 0) { instruction = instruction.Slice(1, instruction.Length - 1); instruction = instruction.Slice(0, instruction.IndexOf('"')); StringHan(instruction, binary); return; } if (instruction.IndexOf('[') >= 0) { instruction = instruction.Slice(1, instruction.Length - 1); instruction = instruction.Slice(0, instruction.IndexOf(']')); ArrayHan(instruction, binary); return; } int firstSpace = instruction.IndexOf(' '); if (firstSpace < 0) { firstSpace = instruction.ToString().Length; } ReadOnlySpan <char> opCodeSpan = instruction.Slice(0, firstSpace); instruction = instruction.Slice(firstSpace).Trim(); OpCodes opCode = Enum.Parse <OpCodes>(opCodeSpan.ToString(), true); OpCodeTypes opType = OpCodeHelpers.OpCodeTypeMap[opCode]; switch (opType) { case OpCodeTypes.NoArgs: binary.Add((byte)opCode); for (int i = 0; i < 3; i++) { binary.Add(0); } break; case OpCodeTypes.OneReg: WriteOneReg(opCode, instruction, binary); break; case OpCodeTypes.TwoReg: WriteTwoReg(opCode, instruction, binary); break; case OpCodeTypes.ThreeReg: WriteThreeRegister(opCode, instruction, binary); break; case OpCodeTypes.OneAddr: WriteOneAddress(opCode, instruction, binary, labelReplacements); break; case OpCodeTypes.OneRegOneAddr: WriteOneRegAndOneAddr(opCode, instruction, binary, labelReplacements); break; case OpCodeTypes.TwoRegOneOffset: WriteTwoRegOneOffSet(opCode, instruction, binary); break; default: throw new Exception("Something happened"); } }
public Instruction(OpCodeTypes typ) { this.Type = typ; Args = new List<Value>(); }