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)); }
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() }); }
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, }); }
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); } }
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); }