private static bool r(uint b, Tlcs90Disassembler dasm) { // Register encoded in low 3 bits of b. dasm.dataWidth = PrimitiveType.Byte; dasm.ops.Add(new RegisterOperand(Registers.byteRegs[b & 7])); return(true); }
public override Tlcs90Instruction Decode(byte b, Tlcs90Disassembler dasm) { return(new Tlcs90Instruction { Opcode = Opcode.invalid, InstructionClass = InstrClass.Invalid }); }
/// <summary> /// Use word register from previous mutator. /// </summary> private static bool G(uint b, Tlcs90Disassembler dasm) { if (dasm.wordReg is null) { return(false); } dasm.ops.Add(dasm.wordReg); return(true); }
private static bool G(uint b, Tlcs90Disassembler dasm) { if (dasm.wordReg is null) { throw new InvalidOperationException(); } dasm.ops.Add(dasm.wordReg); return(true); }
// relative jump private static bool jb(uint u, Tlcs90Disassembler dasm) { if (!dasm.rdr.TryReadByte(out byte b)) { return(false); } var dest = dasm.rdr.Address + (sbyte)b; dasm.ops.Add(AddressOperand.Create(dest)); return(true); }
private static bool jw(uint b, Tlcs90Disassembler dasm) { if (!dasm.rdr.TryReadLeInt16(out short off)) { return(false); } var dest = dasm.rdr.Address + off; dasm.ops.Add(AddressOperand.Create(dest)); return(true); }
public override Tlcs90Instruction Decode(uint bPrev, Tlcs90Disassembler dasm) { if (!dasm.rdr.TryReadByte(out byte b)) { return(null); } 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, }); }
private static bool x(uint b, Tlcs90Disassembler dasm) { dasm.backPatchOp = dasm.ops.Count; return(true); }
private static bool c(uint b, Tlcs90Disassembler dasm) { dasm.ops.Add(new ConditionOperand((CondCode)(b & 0xF))); return(true); }
private static bool Y(uint b, Tlcs90Disassembler dasm) { dasm.dataWidth = PrimitiveType.Word16; dasm.ops.Add(new RegisterOperand(Registers.iy)); return(true); }
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); }
/// <summary> /// Set <see cref="dataWidth"/> to 'word16'. /// </summary> private static bool dw(uint b, Tlcs90Disassembler dasm) { dasm.dataWidth = PrimitiveType.Word16; return(true); }
/// <summary> /// Immediate value from opcode bits. /// </summary> /// <returns></returns> private static bool i(uint b, Tlcs90Disassembler dasm) { dasm.ops.Add(ImmediateOperand.Byte((byte)(b & 0x7))); return(true); }
private static bool H(uint b, Tlcs90Disassembler dasm) { dasm.ops.Add(new RegisterOperand(Registers.hl)); return(true); }
private static bool G(uint b, Tlcs90Disassembler dasm) { Debug.Assert(dasm.wordReg != null); dasm.ops.Add(dasm.wordReg); return(true); }
public abstract Tlcs90Instruction Decode(byte b, Tlcs90Disassembler dasm);
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); }
public override Tlcs90Instruction Decode(byte b, Tlcs90Disassembler dasm) { return(dasm.DecodeOperands(b, opcode, format)); }
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); }
private static bool i(uint b, Tlcs90Disassembler dasm) // immediate value from opcode bits { dasm.ops.Add(ImmediateOperand.Byte((byte)(b & 0x7))); return(true); }