Esempio n. 1
0
        VMCommand ReadOpCode(Stream binary, ref int didread)
        {
            int op = DataReader.Read8(binary, ref didread) & 0xff; // get unsigned

            if (op == 0x09)                                        // opcode for CALL
            {
                return(null);
            }

            // check if there is  a single-byte opcode
            foreach (var de in commands)
            {
                VMCommand cmd = de.Value;
                if (cmd.opcode.Length == 1 && cmd.opcode[0] == op)
                {
                    return(cmd);
                }
            }
            // extend search to get two-byte opcodes as well
            int op1 = DataReader.Read8(binary, ref didread) & 0xff;

            foreach (var de in commands)
            {
                VMCommand cmd = de.Value;
                if (cmd.opcode.Length == 2 && cmd.opcode[0] == op && cmd.opcode[1] == op1)
                {
                    return(cmd);
                }
            }
            throw new Exception("Unrecognized opcode: " + op + "(" + op1 + ")");
        }
Esempio n. 2
0
        private void readByteCodeList()
        {
            StringReader reader = new StringReader(LMSAssembler.Properties.Resources.bytecodelist);

            String line;

            while ((line = reader.ReadLine()) != null)
            {
                int idx = line.IndexOf("//");
                if (idx >= 0)
                {
                    line = line.Substring(0, idx);
                }
                line = line.Trim();
                if (line.Length > 0)
                {
                    VMCommand c = new VMCommand(line);
                    commands.Add(c.name, c);
                }
            }
            reader.Close();

//            foreach (VMCommand c in commands.Values)
//            {
//                Console.WriteLine(c);
//            }
        }
Esempio n. 3
0
        // ---------------------------------- DISASSEMLER ----------------------------------------------

        public void Disassemble(Stream binary, TextWriter writer)
        {
            Dictionary <int, String> vmobjects = new Dictionary <int, String>();
            int didread = 0;

            // read file header and object definitions
            int magic = DataReader.Read32(binary, ref didread);

            if (magic != 0x4F47454C)
            {
                throw new Exception("Missing LEGO header");
            }
            int imgsize     = DataReader.Read32(binary, ref didread);
            int version     = DataReader.Read16(binary, ref didread);
            int numobjects  = DataReader.Read16(binary, ref didread);
            int globalbytes = DataReader.Read32(binary, ref didread);

            writer.WriteLine("Image size: " + imgsize);
            writer.WriteLine("Version: " + version);
            writer.WriteLine("Objects: " + numobjects);
            writer.WriteLine("Globals bytes: " + globalbytes);

            for (int i = 0; i < numobjects; i++)
            {
                int offset       = DataReader.Read32(binary, ref didread);
                int owner        = DataReader.Read16(binary, ref didread);
                int triggercount = DataReader.Read16(binary, ref didread);
                int localbytes   = DataReader.Read32(binary, ref didread);
                if (owner == 0)
                {
                    if (triggercount == 0)
                    {
                        vmobjects[offset] = "VMTHREAD THREAD" + (i + 1) + " ( " + localbytes + " locals)";
                    }
                    else if (triggercount == 1)
                    {
                        vmobjects[offset] = "SUBCALL SUB" + (i + 1) + " ( " + localbytes + " locals)";
                    }
                    else
                    {
                        throw new Exception("Encountered invalid triggercount value");
                    }
                }
                else
                {
                    if (localbytes != 0)
                    {
                        throw new Exception("Can not have local bytes for object with owner");
                    }
                    vmobjects[offset] = "OBJECT " + (i + 1) + " (+trigercount=" + triggercount + ", owner=" + owner + ")";
                }
            }

            // read all objects
            while (didread < imgsize)
            {
                if (!vmobjects.ContainsKey(didread))
                {
                    throw new Exception("No object starts at position " + didread);
                }
                String o = vmobjects[didread];
                vmobjects.Remove(didread);
                writer.WriteLine(o);

                // decode parameter specifier for SUBCALL
                if (o.StartsWith("SUBCALL"))
                {
                    int localpos = 0;
                    int numpar   = DataReader.Read8(binary, ref didread) & 0xff;
                    for (int i = 0; i < numpar; i++)
                    {
                        String prefix = "";
                        int    desc   = DataReader.Read8(binary, ref didread) & 0xff;
                        if ((desc & 0x80) != 0)
                        {
                            prefix = "IN";
                        }
                        if ((desc & 0x40) != 0)
                        {
                            prefix = prefix + "OUT";
                        }
                        switch (desc & 0x07)
                        {
                        case 0:
                            writer.WriteLine(format(localpos, 4) + " " + prefix + "_8");
                            localpos += 1;
                            break;

                        case 1:
                            writer.WriteLine(format(localpos, 4) + " " + prefix + "_16");
                            localpos += 2;
                            break;

                        case 2:
                            writer.WriteLine(format(localpos, 4) + " " + prefix + "_32");
                            localpos += 4;
                            break;

                        case 3:
                            writer.WriteLine(format(localpos, 4) + " " + prefix + "_F");
                            localpos += 4;
                            break;

                        case 4:
                            int len = DataReader.Read8(binary, ref didread) & 0xff;
                            writer.WriteLine(format(localpos, 4) + " " + prefix + "_S " + len);
                            localpos += len;
                            break;

                        default:
                            throw new Exception("Can not decode subcall parameter list");
                        }
                    }
                }

                int objectstart = didread;
                for (; ;)
                {
                    writer.Write(format(didread - objectstart, 4) + "  ");

                    // decode bytecodes
                    VMCommand cmd = ReadOpCode(binary, ref didread);
                    if (cmd == null)
                    {
                        int    n;
                        String objid = ReadParameter(binary, ref didread);
                        if (!int.TryParse(ReadParameter(binary, ref didread), NumberStyles.Integer, CultureInfo.InvariantCulture, out n))
                        {
                            throw new Exception("Invalid specifier for number of CALL parameters");
                        }
                        // special handling for CALL
                        writer.Write("CALL SUB" + objid);
                        for (int i = 0; i < n; i++)
                        {
                            writer.Write(" " + ReadParameter(binary, ref didread));
                        }
                        writer.WriteLine();
                    }
                    else
                    {   // normal opcodes
                        writer.Write(cmd.name);

                        // decode parameters
                        int numparameters = cmd.parameters.Length;
                        for (int i = 0; i < numparameters; i++)
                        {
                            String p = ReadParameter(binary, ref didread);
                            writer.Write(" " + p);

                            // check if this parameter is a counter to extend the parameter list
                            if (i < cmd.parameters.Length && cmd.parameters[i] == DataType.ParameterCount)
                            {
                                int n;
                                if (int.TryParse(p, NumberStyles.Integer, CultureInfo.InvariantCulture, out n))
                                {
                                    numparameters += (n - 1);
                                }
                            }
                        }
                        writer.WriteLine();

                        if (cmd.name.Equals("OBJECT_END"))
                        {
                            break;
                        }
                    }
                }
            }
        }