Exemple #1
0
        static TreeNode PopulateTree(CallingDetail CallingDetail, TreeNode node)
        {
            int sourceaddress = CallingDetail.SourceAddress;
            int address       = CallingDetail.DestinationAddress;
            int imageindex    = (int)CallingDetail.CallType;

            if (!DisassembleROM)
            {
                if (address < 0x4000)
                {
                    return(node);
                }
            }
            //TreeNode[] tn = node.Nodes.Find(address.ToString("X4"), false);
            //if (tn.Length == 0)
            {
                string text = sourceaddress.ToString("X4");
                node              = node.Nodes.Add(text, text, imageindex, imageindex);
                node.ToolTipText  = tooltiptext[imageindex];
                node.Tag         += CallingDetail.DestinationAddress.ToString("X4");
                node.ToolTipText += " To " + node.Tag.ToString();

                text             = address.ToString("X4");
                node             = node.Nodes.Add(text, text, 0, 0);
                node.ToolTipText = "Procedure entry point: " + tooltiptext[imageindex];
                node.ImageIndex  = node.SelectedImageIndex = 0;
                if (node.Tag == null)
                {
                    node.Tag += CallingDetail.SourceAddress.ToString("X4");
                }
                else
                {
                    node.Tag += ", " + CallingDetail.SourceAddress.ToString("X4");
                }
                node.ToolTipText += " From " + node.Tag.ToString();
            }
            //else
            {
                //    node = tn[0];
                //    node.Text += ">";
            }
            return(node);
        }
Exemple #2
0
        static string DecodeOpcode(byte[] memory, int address)
        {
            //
            // Decode one opcode
            //
            DOpcode     opcode;
            List <byte> opcodebytes  = new List <byte>();
            int         startaddress = address;

            Visited[address] = true;
            if (address + 1 > memory.Length)
            {
                return("");
            }
            byte opcodebyte = memory[address++];

            opcodebytes.Add(opcodebyte);
            switch (opcodebyte)
            {
            case 0xCB:
            {
                opcodebyte = memory[address++];
                opcodebytes.Add(opcodebyte);
                opcode = (DOpcode)Opcodes.CBPrefix[opcodebyte].Clone();
            }
            break;

            case 0xED:
            {
                opcodebyte = memory[address++];
                opcodebytes.Add(opcodebyte);
                opcode = (DOpcode)Opcodes.EDPrefix[opcodebyte].Clone();
            }
            break;

            case 0xDD:
            {
                opcodebyte = memory[address++];
                opcodebytes.Add(opcodebyte);
                if (opcodebyte == 0xCB)
                {
                    byte offset = memory[address++];
                    opcodebytes.Add(offset);
                    opcodebyte = memory[address++];
                    opcodebytes.Add(opcodebyte);
                    opcode        = (DOpcode)Opcodes.DDCBPrefix[opcodebyte].Clone();
                    opcode.Offset = offset;
                }
                else
                {
                    opcode = (DOpcode)Opcodes.DDPrefix[opcodebyte].Clone();
                }
            }
            break;

            case 0xFD:
            {
                opcodebyte = memory[address++];
                opcodebytes.Add(opcodebyte);
                if (opcodebyte == 0xCB)
                {
                    byte offset = memory[address++];
                    opcodebytes.Add(offset);
                    opcodebyte = memory[address++];
                    opcodebytes.Add(opcodebyte);
                    opcode        = (DOpcode)Opcodes.FDCBPrefix[opcodebyte].Clone();
                    opcode.Offset = offset;
                }
                else
                {
                    opcode = (DOpcode)Opcodes.FDPrefix[opcodebyte].Clone();
                }
            }
            break;

            default:
                opcode = (DOpcode)Opcodes.NoPrefix[opcodebyte].Clone();
                break;
            }

            //
            // Decode operands
            //
            if (opcode.Mnemonic != null)
            {
                // Index offset i.e. (IX+$o)
                if (opcode.Mnemonic.Contains("$o"))
                {
                    sbyte offset = (sbyte)memory[address++];
                    opcodebytes.Add((byte)offset);
                    opcode.Offset = (byte)offset;
                }
                // Word; i.e. LD HL,$nn
                if (opcode.Mnemonic.Contains("$nn"))
                {
                    byte lo = memory[address++];
                    byte hi = memory[address++];
                    opcodebytes.Add(lo);
                    opcodebytes.Add(hi);
                    int word = ((hi << 8) | lo);
                    opcode.Operand = word;
                }
                // Address; i.e. CALL $aa
                CallingDetail callingDetail = null;
                if (opcode.Mnemonic.Contains("$aa"))
                {
                    byte lo = memory[address++];
                    byte hi = memory[address++];
                    opcodebytes.Add(lo);
                    opcodebytes.Add(hi);
                    int word = ((hi << 8) | lo);
                    Destination[word] = true;
                    opcode.Operand    = word;

                    if (opcode.Mnemonic.StartsWith("JP"))
                    {
                        if ((opcode.OpcodePropertys & OpcodeProperty.Conditional) == OpcodeProperty.Conditional)
                        {
                            callingDetail = new CallingDetail(word, startaddress, CallingType.JpCC);
                        }
                        else
                        {
                            callingDetail = new CallingDetail(word, startaddress, CallingType.Jp);
                        }
                    }
                    else
                    {
                        if ((opcode.OpcodePropertys & OpcodeProperty.Conditional) == OpcodeProperty.Conditional)
                        {
                            callingDetail = new CallingDetail(word, startaddress, CallingType.CallCC);
                        }
                        else
                        {
                            callingDetail = new CallingDetail(word, startaddress, CallingType.Call);
                        }
                    }
                }
                // Displacement i.e. DJNZ $d
                else if (opcode.Mnemonic.Contains("$d"))
                {
                    sbyte displacement = (sbyte)memory[address++];
                    opcodebytes.Add((byte)displacement);
                    int dispaddress = address + displacement;

                    opcode.Operand           = dispaddress;
                    Destination[dispaddress] = true;

                    if (opcode.Mnemonic.StartsWith("JR"))
                    {
                        if ((opcode.OpcodePropertys & OpcodeProperty.Conditional) == OpcodeProperty.Conditional)
                        {
                            callingDetail = new CallingDetail(dispaddress, startaddress, CallingType.JrCC);
                        }
                        else
                        {
                            callingDetail = new CallingDetail(dispaddress, startaddress, CallingType.Jr);
                        }
                    }
                    else
                    {
                        callingDetail = new CallingDetail(dispaddress, startaddress, CallingType.Djnz);
                    }
                }
                // Byte; i.e. LD A,$b
                else if (opcode.Mnemonic.Contains("$b"))
                {
                    byte value = memory[address++];
                    opcodebytes.Add(value);
                    opcode.Operand = value;
                }
            }
            return(opcode.Disassembly);
        }
Exemple #3
0
        public static void Disassemble(CallingDetail callDetail, byte[] memory, TreeNode node)
        {
            if (callDetail.DestinationAddress > memory.Length)
            {
                return;
            }

            int address    = callDetail.DestinationAddress;
            int imageindex = (int)callDetail.CallType;

            node = PopulateTree(callDetail, node);
            if (Visited[callDetail.DestinationAddress])
            {
                return;
            }
            Stack <CallingDetail> CallStack = new Stack <CallingDetail>();

            while (true)
            {
                try
                {
                    if (!DisassembleROM)
                    {
                        if (address < 0x4000)
                        {
                            break;
                        }
                    }
                    if (address > 0xffff)
                    {
                        break;
                    }
                    //if (address == 0x162c)
                    //    Console.Write("");

                    //
                    // Decode one opcode
                    //
                    DOpcode     opcode;
                    List <byte> opcodebytes  = new List <byte>();
                    int         startaddress = address;
                    Visited[address] = true;
                    if (address + 1 > memory.Length)
                    {
                        return;
                    }
                    byte opcodebyte = (byte)memory[address++];
                    opcodebytes.Add(opcodebyte);
                    switch (opcodebyte)
                    {
                    case 0xCB:
                    {
                        opcodebyte = (byte)memory[address++];
                        opcodebytes.Add(opcodebyte);
                        opcode = (DOpcode)Opcodes.CBPrefix[opcodebyte].Clone();
                    }
                    break;

                    case 0xED:
                    {
                        opcodebyte = (byte)memory[address++];
                        opcodebytes.Add(opcodebyte);
                        opcode = (DOpcode)Opcodes.EDPrefix[opcodebyte].Clone();
                    }
                    break;

                    case 0xDD:
                    {
                        opcodebyte = (byte)memory[address++];
                        opcodebytes.Add(opcodebyte);
                        if (opcodebyte == 0xCB)
                        {
                            byte offset = (byte)memory[address++];
                            opcodebytes.Add(offset);
                            opcodebyte = (byte)memory[address++];
                            opcodebytes.Add(opcodebyte);
                            opcode        = (DOpcode)Opcodes.DDCBPrefix[opcodebyte].Clone();
                            opcode.Offset = offset;
                        }
                        else
                        {
                            opcode = (DOpcode)Opcodes.DDPrefix[opcodebyte].Clone();
                        }
                    }
                    break;

                    case 0xFD:
                    {
                        opcodebyte = (byte)memory[address++];
                        opcodebytes.Add(opcodebyte);
                        if (opcodebyte == 0xCB)
                        {
                            byte offset = (byte)memory[address++];
                            opcodebytes.Add(offset);
                            opcodebyte = (byte)memory[address++];
                            opcodebytes.Add(opcodebyte);
                            opcode        = (DOpcode)Opcodes.FDCBPrefix[opcodebyte].Clone();
                            opcode.Offset = offset;
                        }
                        else
                        {
                            opcode = (DOpcode)Opcodes.FDPrefix[opcodebyte].Clone();
                        }
                    }
                    break;

                    default:
                        opcode = (DOpcode)Opcodes.NoPrefix[opcodebyte].Clone();
                        break;
                    }

                    //
                    // Decode operands
                    //
                    if (opcode.Mnemonic != null)
                    {
                        // Index offset i.e. (IX+$o)
                        if (opcode.Mnemonic.Contains("$o"))
                        {
                            sbyte offset = (sbyte)memory[address++];
                            opcodebytes.Add((byte)offset);
                            opcode.Offset = (byte)offset;
                        }
                        // Word; i.e. LD HL,$nn
                        if (opcode.Mnemonic.Contains("$nn"))
                        {
                            byte lo = (byte)memory[address++];
                            byte hi = (byte)memory[address++];
                            opcodebytes.Add(lo);
                            opcodebytes.Add(hi);
                            int word = ((hi << 8) | lo);
                            opcode.Operand = word;
                        }
                        // Address; i.e. CALL $aa
                        CallingDetail callingDetail = null;
                        if (opcode.Mnemonic.Contains("$aa"))
                        {
                            byte lo = (byte)memory[address++];
                            byte hi = (byte)memory[address++];
                            opcodebytes.Add(lo);
                            opcodebytes.Add(hi);
                            int word = ((hi << 8) | lo);
                            Destination[word] = true;
                            opcode.Operand    = word;

                            if (opcode.Mnemonic.StartsWith("JP"))
                            {
                                if ((opcode.OpcodePropertys & OpcodeProperty.Conditional) == OpcodeProperty.Conditional)
                                {
                                    callingDetail = new CallingDetail(word, startaddress, CallingType.JpCC);
                                }
                                else
                                {
                                    callingDetail = new CallingDetail(word, startaddress, CallingType.Jp);
                                }
                            }
                            else
                            {
                                if ((opcode.OpcodePropertys & OpcodeProperty.Conditional) == OpcodeProperty.Conditional)
                                {
                                    callingDetail = new CallingDetail(word, startaddress, CallingType.CallCC);
                                }
                                else
                                {
                                    callingDetail = new CallingDetail(word, startaddress, CallingType.Call);
                                }
                            }
                            if (word != 0x335E)
                            {
                                CallStack.Push(callingDetail);
                            }
                            else
                            {
                                Disassembly[startaddress] = opcode;
                                break;
                            }
                        }
                        // Displacement i.e. DJNZ $d
                        else if (opcode.Mnemonic.Contains("$d"))
                        {
                            sbyte displacement = (sbyte)memory[address++];
                            opcodebytes.Add((byte)displacement);
                            int dispaddress = address + displacement;

                            opcode.Operand           = dispaddress;
                            Destination[dispaddress] = true;

                            if (opcode.Mnemonic.StartsWith("JR"))
                            {
                                if ((opcode.OpcodePropertys & OpcodeProperty.Conditional) == OpcodeProperty.Conditional)
                                {
                                    callingDetail = new CallingDetail(dispaddress, startaddress, CallingType.JrCC);
                                }
                                else
                                {
                                    callingDetail = new CallingDetail(dispaddress, startaddress, CallingType.Jr);
                                }
                            }
                            else
                            {
                                callingDetail = new CallingDetail(dispaddress, startaddress, CallingType.Djnz);
                            }

                            CallStack.Push(callingDetail);
                        }
                        // Byte; i.e. LD A,$b
                        else if (opcode.Mnemonic.Contains("$b"))
                        {
                            byte value = (byte)memory[address++];
                            opcodebytes.Add(value);
                            opcode.Operand = value;
                        }
                    }
                    opcode.Address = startaddress;
                    opcode.Bytes   = opcodebytes;
                    //Visited[startaddress] = true;

                    // RST 08H; THE 'ERROR' RESTART (0xcf)
                    if (opcode.Value == 0xcf)
                    {
                        Disassembly[startaddress] = opcode;
                        Visited[address++]        = true;
                        //CallingDetail callingDetail = new CallingDetail(address, address, CallingType.Jp);
                        //CallStack.Push(callingDetail);
                        break;
                    }

                    // RST 28H; THE 'CALCULATE' RESTART (0xef)
                    if (opcode.Value == 0xef)
                    {
                        Disassembly[startaddress] = opcode;
                        while (true)
                        {
                            Visited[address++] = true;
                            // END WITH 0x38
                            if (memory[address] == 0x38)
                            {
                                if (memory[address - 1] != 0x8f)
                                {
                                    break;
                                }
                            }
                        }
                        Visited[address++] = true;
                        CallingDetail callingDetail = new CallingDetail(address, address, CallingType.Jp);
                        CallStack.Push(callingDetail);
                        break;
                    }
                    // Any other opcode
                    for (int i = startaddress; i < startaddress + opcodebytes.Count; i++)
                    {
                        Disassembly[i] = null;
                    }

                    Disassembly[startaddress] = opcode;
                    if (opcode.IsTerminal)
                    {
                        break;
                    }
                }
                catch { break; }
            }
            IEnumerable <CallingDetail> list = CallStack.Reverse();

            foreach (CallingDetail callingDetail in list)
            {
                Disassemble(callingDetail, memory, node);
            }
        }