Пример #1
0
 public Instruction(OpCodeTypes typ, params Value[] values)
 {
     this.Type = typ;
     Args = new List<Value>();
     foreach (Value v in values) {
         Args.Add(v);
     }
 }
Пример #2
0
 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;
 }
Пример #3
0
        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;
                }
            }
        }
Пример #4
0
 /// <summary>
 /// Creates a new request for the specified type
 /// </summary>
 protected RequestBase(OpCodeTypes code)
 {
     OpCode = code;
 }
Пример #5
0
        // 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());
        }
Пример #6
0
 /// <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();
 }
Пример #7
0
 /// <summary>
 /// Creates a request targeting a collection
 /// </summary>
 public CollectionRequestBase(OpCodeTypes code, MongoCollection collection)
     : this(code, collection.Database.Name, collection.Name)
 {
 }
Пример #8
0
 /// <summary>
 /// Creates a new request for the specified type
 /// </summary>
 public RequestBase(OpCodeTypes code)
 {
     this.OpCode = code;
 }
Пример #9
0
        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();
        }
Пример #10
0
        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");
            }
        }
Пример #11
0
 public Instruction(OpCodeTypes typ)
 {
     this.Type = typ;
     Args = new List<Value>();
 }