Ejemplo n.º 1
0
            public override Tlcs90Instruction Decode(uint bPrev, Tlcs90Disassembler dasm)
            {
                Tlcs90Instruction instr;
                Constant          offset  = null;
                RegisterStorage   baseReg = null;
                RegisterStorage   idxReg  = null;

                switch (format[0])
                {
                case 'E':
                    switch (format[1])
                    {
                    case 'S': baseReg = Registers.sp; break;

                    case 'X': baseReg = Registers.ix; break;

                    case 'Y': baseReg = Registers.iy; break;

                    case 'H': baseReg = Registers.hl; idxReg = Registers.a;  break;

                    default: throw new NotImplementedException(string.Format("Tlcs-90: src {0}", format));
                    }
                    ;
                    if (idxReg == null)
                    {
                        if (!dasm.rdr.TryReadByte(out byte bOff))
                        {
                            return(null);
                        }
                        offset = Constant.SByte((sbyte)bOff);
                    }
                    break;

                case 'B': baseReg = Registers.bc; break;

                case 'D': baseReg = Registers.de; break;

                case 'H': baseReg = Registers.hl; break;

                case 'S': baseReg = Registers.sp; break;

                case 'X': baseReg = Registers.ix; break;

                case 'Y': baseReg = Registers.iy; break;

                case 'M':
                    ushort us;
                    if (!dasm.rdr.TryReadLeUInt16(out us))
                    {
                        return(null);
                    }
                    offset = Constant.UInt16(us);
                    break;

                case 'm':
                    byte pageAddr;
                    if (!dasm.rdr.TryReadByte(out pageAddr))
                    {
                        return(null);
                    }
                    offset = Constant.UInt16((ushort)(0xFF00 | pageAddr));
                    break;

                default: throw new NotImplementedException(string.Format("Tlcs-90: src {0}", format));
                }

                if (!dasm.rdr.TryReadByte(out byte b))
                {
                    return(null);
                }
                instr = srcEncodings[b].Decode(b, dasm);
                if (instr == null)
                {
                    return(null);
                }

                var operand = new MemoryOperand(dasm.dataWidth)
                {
                    Base   = baseReg,
                    Index  = idxReg,
                    Offset = offset
                };

                if (dasm.backPatchOp == 0)
                {
                    if (instr.Operands.Length == 1)
                    {
                        instr.Operands = new MachineOperand[] { operand, instr.Operands[0] };
                    }
                    else
                    {
                        instr.Operands = new MachineOperand[] { operand };
                    }
                    if (instr.Operands.Length >= 2)
                    {
                        operand.Width = instr.Operands[1].Width;
                    }
                }
                else if (dasm.backPatchOp == 1)
                {
                    if (operand != null)
                    {
                        instr.Operands = new MachineOperand[] { instr.Operands[0], operand };
                    }
                    operand.Width = instr.Operands[0].Width;
                }
                else
                {
                    return(null);
                }
                return(instr);
            }
Ejemplo n.º 2
0
        private Tlcs90Instruction DecodeOperands(byte b, Opcode opcode, string format)
        {
            int           op  = 0;
            var           ops = new MachineOperand[2];
            Constant      c;
            PrimitiveType size;

            for (int i = 0; i < format.Length; ++i)
            {
                switch (format[i])
                {
                case ',':
                    continue;

                case 'a':
                    this.dataWidth = PrimitiveType.Byte;
                    ops[op]        = new RegisterOperand(Registers.a);
                    break;

                case '@':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.af_);
                    break;

                case 'A':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.af);
                    break;

                case 'B':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.bc);
                    break;

                case 'c':
                    ops[op] = new ConditionOperand((CondCode)(b & 0xF));
                    break;

                case 'D':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.de);
                    break;

                case 'I':
                    // Immediate value
                    this.dataWidth = GetSize(format[++i]);
                    if (!rdr.TryReadLe(this.dataWidth, out c))
                    {
                        return(null);
                    }
                    ops[op] = new ImmediateOperand(c);
                    break;

                case 'i': // immediate value from opcode bits
                    ops[op] = ImmediateOperand.Byte((byte)(b & 0x7));
                    break;

                case 'g':
                    Debug.Assert(byteReg != null);
                    ops[op] = this.byteReg;
                    break;

                case 'G':
                    Debug.Assert(wordReg != null);
                    ops[op] = this.wordReg;
                    break;

                case 'H':
                    ops[op] = new RegisterOperand(Registers.hl);
                    break;

                case 'J':
                    // Absolute jump.
                    size = GetSize(format[++i]);
                    if (!rdr.TryReadLe(size, out c))
                    {
                        return(null);
                    }
                    ops[op] = AddressOperand.Ptr16(c.ToUInt16());
                    break;

                case 'j':
                    // relative jump
                    size = GetSize(format[++i]);
                    Address dest;
                    if (size.Size == 1)
                    {
                        if (!rdr.TryReadByte(out b))
                        {
                            return(null);
                        }
                        dest = rdr.Address + (sbyte)b;
                    }
                    else
                    {
                        if (!rdr.TryReadLeInt16(out short off))
                        {
                            return(null);
                        }
                        dest = rdr.Address + off;
                    }
                    ops[op] = AddressOperand.Create(dest);
                    break;

                case 'M':
                    this.dataWidth = GetSize(format[++i]);
                    ushort absAddr;
                    if (!rdr.TryReadLeUInt16(out absAddr))
                    {
                        return(null);
                    }
                    ops[op] = MemoryOperand.Absolute(this.dataWidth, absAddr);
                    break;

                case 'm':
                    size = GetSize(format[++i]);
                    byte pageAddr;
                    if (!rdr.TryReadByte(out pageAddr))
                    {
                        return(null);
                    }
                    ops[op] = MemoryOperand.Absolute(size, (ushort)(0xFF00 | pageAddr));
                    break;

                case 'S':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.sp);
                    break;

                case 'X':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.ix);
                    break;

                case 'Y':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.iy);
                    break;

                case 'r':
                    // Register encoded in low 3 bits of b.
                    ops[op]   = new RegisterOperand(Registers.byteRegs[b & 7]);
                    dataWidth = PrimitiveType.Byte;
                    break;

                case 'x':
                    this.backPatchOp = op;
                    break;

                default: throw new NotImplementedException(string.Format("Encoding '{0}' not implemented yet.", format[i]));
                }
                ++op;
            }
            return(new Tlcs90Instruction
            {
                Opcode = opcode,
                op1 = op > 0 ? ops[0] : null,
                op2 = op > 1 ? ops[1] : null,
            });
        }
Ejemplo n.º 3
0
            public override Tlcs90Instruction Decode(uint bPrev, Tlcs90Disassembler dasm)
            {
                RegisterStorage baseReg = null;
                RegisterStorage idxReg  = null;
                ushort?         absAddr = null;
                Constant        offset  = null;

                switch (format[0])
                {
                case 'M':
                    ushort a;
                    if (!dasm.rdr.TryReadLeUInt16(out a))
                    {
                        return(null);
                    }
                    absAddr = a;
                    break;

                case 'm':
                    byte bb;
                    if (!dasm.rdr.TryReadByte(out bb))
                    {
                        return(null);
                    }
                    absAddr = (ushort)(0xFF00 | bb);
                    break;

                case 'B': baseReg = Registers.bc; break;

                case 'D': baseReg = Registers.de; break;

                case 'H': baseReg = Registers.hl; break;

                case 'X': baseReg = Registers.ix; break;

                case 'Y': baseReg = Registers.iy; break;

                case 'S': baseReg = Registers.sp; break;

                case 'E':
                    switch (format[1])
                    {
                    case 'S': baseReg = Registers.sp;  break;

                    case 'X': baseReg = Registers.ix;  break;

                    case 'Y': baseReg = Registers.ix;  break;

                    case 'H': baseReg = Registers.hl; idxReg = Registers.a;  break;

                    default: throw new NotImplementedException(string.Format("Tlcs-90: dst {0}", format));
                    }
                    if (idxReg == null)
                    {
                        if (!dasm.rdr.TryReadByte(out byte bOff))
                        {
                            return(null);
                        }
                        offset = Constant.SByte((sbyte)bOff);
                    }
                    break;

                default: throw new NotImplementedException(string.Format("Tlcs-90: dst {0}", format));
                }
                if (!dasm.rdr.TryReadByte(out byte b))
                {
                    return(null);
                }
                var instr = dstEncodings[b].Decode(b, dasm);

                if (instr == null)
                {
                    return(null);
                }

                var operand = new MemoryOperand(dasm.dataWidth)
                {
                    Base   = baseReg,
                    Offset = absAddr.HasValue
                        ? Constant.UInt16(absAddr.Value)
                        : offset,
                };

                if (dasm.backPatchOp == 0)
                {
                    if (instr.Operands.Length == 0)
                    {
                        instr.Operands = new MachineOperand[] { operand };
                    }
                    else
                    {
                        instr.Operands = new MachineOperand[] { operand, instr.Operands[0] };
                    }
                    if (instr.Operands.Length == 2)
                    {
                        instr.Operands[0].Width = instr.Operands[1].Width;
                    }
                }
                else if (dasm.backPatchOp == 1)
                {
                    if ((instr.Mnemonic == Mnemonic.jp || instr.Mnemonic == Mnemonic.call)
                        &&
                        operand.Base == null &&
                        operand.Index == null &&
                        operand.Offset != null)
                    {
                        // JP cc,(XXXX) should be JP cc,XXXX
                        var op = AddressOperand.Ptr16(operand.Offset.ToUInt16());
                        op.Width       = PrimitiveType.Ptr16;
                        instr.Operands = new MachineOperand[] { instr.Operands[0], op };
                    }
                    else
                    {
                        instr.Operands = new MachineOperand[] {
                            instr.Operands[0],
                            operand
                        };
                        instr.Operands[1].Width = instr.Operands[0].Width;
                    }
                }
                else
                {
                    return(null);
                }
                return(instr);
            }
Ejemplo n.º 4
0
            public override Tlcs90Instruction Decode(byte b, Tlcs90Disassembler dasm)
            {
                RegisterStorage baseReg = null;
                RegisterStorage idxReg  = null;
                ushort?         absAddr = null;
                Constant        offset  = null;

                switch (format[0])
                {
                case 'M':
                    ushort a;
                    if (!dasm.rdr.TryReadLeUInt16(out a))
                    {
                        return(null);
                    }
                    absAddr = a;
                    break;

                case 'm':
                    byte bb;
                    if (!dasm.rdr.TryReadByte(out bb))
                    {
                        return(null);
                    }
                    absAddr = (ushort)(0xFF00 | bb);
                    break;

                case 'B': baseReg = Registers.bc; break;

                case 'D': baseReg = Registers.de; break;

                case 'H': baseReg = Registers.hl; break;

                case 'X': baseReg = Registers.ix; break;

                case 'Y': baseReg = Registers.iy; break;

                case 'S': baseReg = Registers.sp; break;

                case 'E':
                    switch (format[1])
                    {
                    case 'S': baseReg = Registers.sp;  break;

                    case 'X': baseReg = Registers.ix;  break;

                    case 'Y': baseReg = Registers.ix;  break;

                    case 'H': baseReg = Registers.hl; idxReg = Registers.a;  break;

                    default: throw new NotImplementedException(string.Format("Tlcs-90: dst {0}", format));
                    }
                    if (idxReg == null)
                    {
                        if (!dasm.rdr.TryReadByte(out b))
                        {
                            return(null);
                        }
                        offset = Constant.SByte((sbyte)b);
                    }
                    break;

                default: throw new NotImplementedException(string.Format("Tlcs-90: dst {0}", format));
                }
                if (!dasm.rdr.TryReadByte(out b))
                {
                    return(null);
                }
                var instr = dstEncodings[b].Decode(b, dasm);

                if (instr == null)
                {
                    return(null);
                }

                var operand = new MemoryOperand(dasm.dataWidth)
                {
                    Base   = baseReg,
                    Offset = absAddr.HasValue
                        ? Constant.UInt16(absAddr.Value)
                        : offset,
                };

                if (dasm.backPatchOp == 0)
                {
                    instr.op1 = operand;
                    if (instr.op2 != null)
                    {
                        instr.op1.Width = instr.op2.Width;
                    }
                }
                else if (dasm.backPatchOp == 1)
                {
                    instr.op2       = operand;
                    instr.op2.Width = instr.op1.Width;
                }
                else
                {
                    return(null);
                }
                return(instr);
            }