예제 #1
0
 public override Tlcs90Instruction Decode(uint bPrev, Tlcs90Disassembler dasm)
 {
     if (!dasm.rdr.TryReadByte(out byte b))
     {
         return(dasm.CreateInvalidInstruction());
     }
     dasm.byteReg = new RegisterOperand(regByte);
     if (regWord != null)
     {
         dasm.wordReg = new RegisterOperand(regWord);
     }
     return(regEncodings[b].Decode(b, dasm));
 }
예제 #2
0
 public override Tlcs90Instruction Decode(uint b, Tlcs90Disassembler dasm)
 {
     foreach (var m in mutators)
     {
         if (!m(b, dasm))
         {
             return(dasm.CreateInvalidInstruction());
         }
     }
     return(new Tlcs90Instruction
     {
         Mnemonic = opcode,
         InstructionClass = iclass,
         Operands = dasm.ops.ToArray()
     });
 }
예제 #3
0
 public override Tlcs90Instruction Decode(byte b, Tlcs90Disassembler dasm)
 {
     foreach (var m in mutators)
     {
         if (!m(b, dasm))
         {
             return(dasm.CreateInvalidInstruction());
         }
     }
     return(new Tlcs90Instruction
     {
         Opcode = opcode,
         InstructionClass = iclass,
         op1 = dasm.ops.Count > 0 ? dasm.ops[0] : null,
         op2 = dasm.ops.Count > 1 ? dasm.ops[1] : null,
     });
 }
예제 #4
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(dasm.CreateInvalidInstruction());
                        }
                        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(dasm.CreateInvalidInstruction());
                    }
                    offset = Constant.UInt16(us);
                    break;

                case 'm':
                    byte pageAddr;
                    if (!dasm.rdr.TryReadByte(out pageAddr))
                    {
                        return(dasm.CreateInvalidInstruction());
                    }
                    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(dasm.CreateInvalidInstruction());
                }
                instr = srcEncodings[b].Decode(b, dasm);
                if (instr == null)
                {
                    return(dasm.CreateInvalidInstruction());
                }

                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(dasm.CreateInvalidInstruction());
                }
                return(instr);
            }
        }
예제 #5
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':
                    if (!dasm.rdr.TryReadLeUInt16(out ushort a))
                    {
                        return(dasm.CreateInvalidInstruction());
                    }
                    absAddr = a;
                    break;

                case 'm':
                    if (!dasm.rdr.TryReadByte(out byte bb))
                    {
                        return(dasm.CreateInvalidInstruction());
                    }
                    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(dasm.CreateInvalidInstruction());
                        }
                        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(dasm.CreateInvalidInstruction());
                }
                var instr = dstEncodings[b].Decode(b, dasm);

                if (instr == null)
                {
                    return(dasm.CreateInvalidInstruction());
                }

                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(dasm.CreateInvalidInstruction());
                }
                return(instr);
            }