Exemplo n.º 1
0
 public override RegisterStorage GetRegister(StorageDomain domain, BitRange range)
 {
     return(Registers.GetRegister(domain - StorageDomain.Register));
 }
Exemplo n.º 2
0
        private BitOperand BitReg(int b, bool neg)
        {
            var reg = Registers.GetRegister(b & 0xF0);

            return(new BitOperand(reg, b & 0x7, neg));
        }
Exemplo n.º 3
0
 // @Ri	An internal data RAM location (0-255) addressed indirectly through R0 or R1.
 private static bool Ind(uint uInstr, i8051Disassembler dasm)
 {
     dasm.ops.Add(MemoryOperand.Indirect(Registers.GetRegister((int)uInstr & 1)));
     return(true);
 }
Exemplo n.º 4
0
 private RegisterOperand Reg(int r)
 {
     return(new RegisterOperand(Registers.GetRegister(r)));
 }
Exemplo n.º 5
0
        private i8051Instruction Decode(Mnemonic opcode, byte uInstr, string fmt)
        {
            byte b;
            var  ops = new List <MachineOperand>();

            foreach (var ch in fmt)
            {
                switch (ch)
                {
                case ',':
                    continue;

                case 'j': // An 11-bit address destination. This argument is used by ACALL and AJMP instructions. The target of the CALL or JMP must lie within the same 2K page as the first byte of the following instruction.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(AddressOperand.Ptr16(
                                (ushort)(
                                    (rdr.Address.ToLinear() & ~0x7Ful) |
                                    (uInstr & 0xE0u) << 3 |
                                        b)));
                    break;

                case 'J':                                    // A 16-bit address destination. This argument is used by LCALL and LJMP instructions.
                    if (!rdr.TryReadBeUInt16(out var uAddr)) // Yes, big endian!
                    {
                        return(null);
                    }
                    ops.Add(AddressOperand.Ptr16(uAddr));
                    break;

                case 'o': // A signed (two's complement) 8-bit offset (-128 to 127) relative to the first byte of the following instruction.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(AddressOperand.Create(rdr.Address + (sbyte)b));
                    break;

                case 'A': // The accumulator.
                    ops.Add(new RegisterOperand(Registers.A));
                    break;

                case 'd': // An internal data RAM location (0-127) or SFR (128-255).
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(MemoryOperand.Direct(Address.Ptr16(b)));
                    break;

                case 'r': // Register r0-r7
                    ops.Add(Reg(uInstr & 7));
                    break;

                case 'b': // A direct addressed bit in internal data RAM or SFR memory.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(BitReg(b, false));
                    break;

                case 'B': // A direct addressed bit in internal data RAM or SFR memory.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(BitReg(b, true));
                    break;

                case 'C':   // C flag of PSW
                    ops.Add(new FlagGroupOperand(arch.GetFlagGroup(Registers.PSW, (uint)FlagM.C)));
                    break;

                case 'D':   // @DPTR
                    ops.Add(MemoryOperand.Indirect(Registers.DPTR));
                    break;

                case 'p':   // DPTR register pair
                    ops.Add(new SequenceOperand(Registers.DPTR));
                    break;

                case 'i': // A constant included in the instruction encoding.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(ImmediateOperand.Byte(b));
                    break;

                case 'I': // A constant included in the instruction encoding.
                    if (!rdr.TryReadUInt16(out var w))
                    {
                        return(null);
                    }
                    ops.Add(ImmediateOperand.Word16(w));
                    break;

                case '@': // @Ri	An internal data RAM location (0-255) addressed indirectly through R0 or R1.
                    ops.Add(MemoryOperand.Indirect(Registers.GetRegister(uInstr & 1)));
                    break;

                case '+': // @A + DPTR:
                    ops.Add(MemoryOperand.Indexed(Registers.DPTR, Registers.A));
                    break;

                case 'P': // @A + PC:
                    ops.Add(MemoryOperand.Indexed(Registers.PC, Registers.A));
                    break;

                case '*': // AB register pair
                    ops.Add(new SequenceOperand(Registers.AB));
                    break;

                default:
                    EmitUnitTest(opcode, uInstr);
                    break;
                }
            }

            return(new i8051Instruction
            {
                Mnemonic = opcode,
                Address = this.addr,
                Length = (int)(rdr.Address - this.addr),
                Operands = ops.ToArray()
            });
        }