예제 #1
0
        // various mem formats
        private static Mutator <Tlcs900Disassembler> m(PrimitiveType size)
        {
            return((b, dasm) =>
            {
                if (!dasm.rdr.TryReadByte(out byte m))
                {
                    return false;
                }
                switch (m & 3)
                {
                case 0: // Register indirect
                    dasm.ops.Add(MemoryOperand.Indirect(dasm.Size(size), dasm.Reg(PrimitiveType.Word32, (m >> 2) & 0x3F)));
                    dasm.SetSize(size);
                    return true;

                case 1: // indexed (16-bit offset)
                    if (!dasm.rdr.TryReadLeInt16(out short o16))
                    {
                        return false;
                    }
                    dasm.ops.Add(MemoryOperand.Indexed16(dasm.Size(size), dasm.Reg(PrimitiveType.Word32, (m >> 2) & 0x3F), o16));
                    dasm.SetSize(size);
                    return true;

                case 3:
                    if (m != 3 && m != 7)
                    {
                        return false;
                    }
                    if (!dasm.rdr.TryReadByte(out byte rBase))
                    {
                        return false;
                    }
                    if (!dasm.rdr.TryReadByte(out byte rIdx))
                    {
                        return false;
                    }
                    var regBase = dasm.Reg(PrimitiveType.Word32, rBase);
                    var regIdx = dasm.Reg(m == 3 ? PrimitiveType.Byte : PrimitiveType.Word16, rIdx);
                    dasm.ops.Add(MemoryOperand.RegisterIndexed(dasm.Size(size), regBase, regIdx));
                    dasm.SetSize(size);
                    return true;

                default:
                    return false;
                }
            });
        }
예제 #2
0
        private MachineOperand DecodeOperand(byte b, string fmt)
        {
            MachineOperand op;
            byte           r;
            Constant       c;
            byte           o8;
            int            incCode;

            switch (fmt[0])
            {
            case '+': // Predecrement
                if (!rdr.TryReadByte(out r))
                {
                    return(null);
                }
                incCode = r & 3;
                if (incCode >= incDecSize.Length)
                {
                    return(null);
                }
                op = MemoryOperand.PostIncrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F));
                SetSize(fmt[1]);
                return(op);

            case '-':
                if (!rdr.TryReadByte(out r))
                {
                    return(null);
                }
                incCode = r & 3;
                if (incCode >= incDecSize.Length)
                {
                    return(null);
                }
                op = MemoryOperand.PreDecrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F));
                SetSize(fmt[1]);
                return(op);

            case '3': // Immediate encoded in low 3 bits
                c = Constant.Create(Size(fmt[1]), b & 7);
                SetSize(fmt[1]);
                return(new ImmediateOperand(c));

            case '#': // Immediate encoded in low 3 bits, with 8 encoded as 0
                c = Constant.Create(Size(fmt[1]), imm3Const[b & 7]);
                SetSize(fmt[1]);
                return(new ImmediateOperand(c));

            case 'A': // A register
                op = new RegisterOperand(Tlcs900Registers.a);
                return(op);

            case 'C': // condition code
                op = new ConditionOperand((CondCode)(b & 0xF));
                return(op);

            case 'I': // immediate
                op = Immediate(fmt[1]);
                return(op);

            case 'j': // Relative jump
                switch (fmt[1])
                {
                case 'b':
                    if (!rdr.TryReadByte(out o8))
                    {
                        return(null);
                    }
                    else
                    {
                        return(AddressOperand.Create(rdr.Address + (sbyte)o8));
                    }

                case 'w':
                    short o16;
                    if (!rdr.TryReadLeInt16(out o16))
                    {
                        return(null);
                    }
                    else
                    {
                        return(AddressOperand.Create(rdr.Address + o16));
                    }
                }
                return(null);

            case 'r': // Register
            case 'R':
                //$TODO: 'r' may encode other registers. manual is dense
                op = new RegisterOperand(Reg(fmt[1], b & 0x7));
                SetSize(fmt[1]);
                return(op);

            case 'M': // Register indirect
                op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', b & 7));
                SetSize(fmt[1]);
                return(op);

            case 'N': // indexed (8-bit offset)
                if (!rdr.TryReadByte(out o8))
                {
                    return(null);
                }
                op = MemoryOperand.Indexed8(Size(fmt[1]), Reg('x', b & 7), (sbyte)o8);
                SetSize(fmt[1]);
                return(op);

            case 'm': // various mem formats
                byte m;
                if (!rdr.TryReadByte(out m))
                {
                    return(null);
                }
                switch (m & 3)
                {
                case 0: // Register indirect
                    op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F));
                    break;

                case 1: // indexed (16-bit offset)
                    short o16;
                    if (!rdr.TryReadLeInt16(out o16))
                    {
                        return(null);
                    }
                    op = MemoryOperand.Indexed16(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F), o16);
                    SetSize(fmt[1]);
                    return(op);

                case 3:
                    if (m != 3 && m != 7)
                    {
                        return(null);
                    }
                    byte rBase;
                    if (!rdr.TryReadByte(out rBase))
                    {
                        return(null);
                    }
                    byte rIdx;
                    if (!rdr.TryReadByte(out rIdx))
                    {
                        return(null);
                    }
                    var regBase = Reg('x', rBase);
                    var regIdx  = Reg(m == 3 ? 'b' : 'w', rIdx);
                    op = MemoryOperand.RegisterIndexed(Size(fmt[1]), regBase, regIdx);
                    SetSize(fmt[1]);
                    return(op);

                default:
                    throw new FormatException(string.Format(
                                                  "Unknown format {0} decoding bytes {1:X2}{2:X2}.",
                                                  fmt[0], (int)b, (int)m));
                }
                SetSize(fmt[1]);
                return(op);

            case 'O': return(Absolute(1, fmt[1]));

            case 'P': return(Absolute(2, fmt[1]));

            case 'Q': return(Absolute(3, fmt[1]));

            default: throw new FormatException(
                          string.Format(
                              "Unknown format {0} decoding byte {1:X2}.", fmt[0], (int)b));
            }
        }