public override IEnumerable <TmsCommand> Translate(Z80AssemblyParsing.Commands.UnconditionalReturnCommand returnCommand) { var stackOperand = new IndirectAutoIncrementTmsOperand(_extendedRegisterMap[Z80AssemblyParsing.ExtendedRegister.SP]); var registerOperand = new RegisterTmsOperand(WorkspaceRegister.R11); yield return(new MoveCommand(returnCommand, stackOperand, registerOperand)); yield return(new ReturnCommand(returnCommand)); }
public override IEnumerable <TmsCommand> Translate(Z80AssemblyParsing.Commands.NegateCommand z80Command) { var negOneByte = new LabeledAddressTmsOperand(_labelHighlighter.NegOneByteLabel); var accumulatorLowByte = new IndirectRegisterTmsOperand(WorkspaceRegister.R12); var accumulatorOperand = new RegisterTmsOperand(_registerMap[Z80AssemblyParsing.Register.A]); yield return(new MoveByteCommand(z80Command, negOneByte, accumulatorLowByte)); yield return(new NegateCommand(z80Command, accumulatorOperand)); }
public override IEnumerable <TmsCommand> Translate(Z80AssemblyParsing.Commands.RotateRightCarryCommand rotateRightCarryCommand) { var registerOperand = new RegisterTmsOperand(_registerMap[Z80AssemblyParsing.Register.A]); var indirectRegisterOperand = new IndirectRegisterTmsOperand(WorkspaceRegister.R12); var oneBitOperand = new ImmediateTmsOperand(1); yield return(new MoveByteCommand(rotateRightCarryCommand, registerOperand, indirectRegisterOperand)); yield return(new ShiftRightCircularCommand(rotateRightCarryCommand, oneBitOperand, registerOperand)); }
public override IEnumerable <TmsCommand> Translate(ConditionalReturnCommand returnCommand) { var stackPointerOperand = new IndirectAutoIncrementTmsOperand(_extendedRegisterMap[Z80AssemblyParsing.ExtendedRegister.SP]); var returnAddressRegister = new RegisterTmsOperand(WorkspaceRegister.R11); if (returnCommand.ConditionOperand.Condition == Z80AssemblyParsing.JumpConditions.PO || returnCommand.ConditionOperand.Condition == Z80AssemblyParsing.JumpConditions.PE) { yield return(new UntranslateableComment(returnCommand, $"ret translations on PO or PE condition are not automated.")); yield return(new UntranslateableComment(returnCommand, "Z80 used a single flag for Parity and Overflow, TMS9900 used two flags.")); yield return(new UntranslateableComment(returnCommand, "A human must decide whether to use JNO or JOP.")); yield return(new UntranslateableComment(returnCommand, returnCommand.SourceText)); } else if (_typesByCondition.ContainsKey(returnCommand.ConditionOperand.Condition)) { var retLabel = _labelHighlighter.GetNextRtLabel(); yield return(GetInverseJumpCommand(returnCommand, retLabel)); yield return(new MoveCommand(returnCommand, stackPointerOperand, returnAddressRegister)); yield return(new ReturnCommand(returnCommand)); yield return(new BlankLineInTms(returnCommand) { Label = retLabel }); } else if (returnCommand.ConditionOperand.Condition == Z80AssemblyParsing.JumpConditions.M) { var retLabel1 = _labelHighlighter.GetNextRtLabel(); var retLabel2 = _labelHighlighter.GetNextRtLabel(); yield return(new JumpIfLessThanCommand(returnCommand, new LabeledAddressWithoutAtTmsOperand(retLabel1))); yield return(new JumpCommand(returnCommand, new LabeledAddressWithoutAtTmsOperand(retLabel2))); yield return(new BlankLineInTms(returnCommand) { Label = retLabel1 }); yield return(new MoveCommand(returnCommand, stackPointerOperand, returnAddressRegister)); yield return(new ReturnCommand(returnCommand)); yield return(new BlankLineInTms(returnCommand) { Label = retLabel2 }); } }
public override IEnumerable <TmsCommand> Translate(T logicCommand) { var zeroByte = new LabeledAddressTmsOperand(_labelHighlighter.ZeroByteLabel); var accumulatorLowByte = new IndirectRegisterTmsOperand(WorkspaceRegister.R12); var accumulatorOperand = new RegisterTmsOperand(_registerMap[Z80AssemblyParsing.Register.A]); if (logicCommand.Operand is Z80AssemblyParsing.Operands.IndirectRegisterOperand && MustUnifyRegisterPairs(logicCommand.Operand, out var copyFromOperand, out var copyToOperand, out var unifiedOperand)) { yield return(new MoveByteCommand(logicCommand, copyFromOperand, copyToOperand)); yield return(GetEquivCommand <TmsEquivCommand>(logicCommand, unifiedOperand, accumulatorOperand)); }
public override IEnumerable <TmsCommand> Translate(Z80AssemblyParsing.Commands.XorCommand xorCommand) { var regZeroOperand = new RegisterTmsOperand(WorkspaceRegister.R0); var accumulatorOperand = new RegisterTmsOperand(_registerMap[Z80AssemblyParsing.Register.A]); if (xorCommand.Operand is Z80AssemblyParsing.Operands.IndirectRegisterOperand && MustUnifyRegisterPairs(xorCommand.Operand, out var copyFromOperand, out var copyToOperand, out var unifiedOperand)) { yield return(new MoveByteCommand(xorCommand, copyFromOperand, copyToOperand)); yield return(new XorCommand(xorCommand, unifiedOperand, accumulatorOperand)); yield return(new MoveByteCommand(xorCommand, accumulatorOperand, accumulatorOperand)); }
public override IEnumerable <TmsCommand> Translate(Z80AssemblyParsing.Commands.AndCommand andCommand) { var regZeroOperand = new RegisterTmsOperand(WorkspaceRegister.R0); if (andCommand.Operand is Z80AssemblyParsing.Operands.IndirectRegisterOperand && MustUnifyRegisterPairs(andCommand.Operand, out var copyFromOperand, out var copyToOperand, out var unifiedOperand)) { yield return(new MoveByteCommand(andCommand, copyFromOperand, copyToOperand)); yield return(new MoveByteCommand(andCommand, unifiedOperand, regZeroOperand)); yield return(new InvertCommand(andCommand, regZeroOperand)); yield return(new SetZerosCorrespondingByteCommand(andCommand, regZeroOperand, new RegisterTmsOperand(_registerMap[Z80AssemblyParsing.Register.A]))); }
protected bool MustUnifyRegisterPairs(Z80AssemblyParsing.Operand z80operand, out Operand copyFromOperand, out Operand copyToOperand, out Operand unifiedOperand) { if (z80operand is Z80Operands.IndirectRegisterOperand indirectRegisterOperand && !RegisterPairIsMappedToSameWorkspaceRegister(indirectRegisterOperand.Register)) { var registerPair = indirectRegisterOperand.Register; if (_unsplitableRegisters.Contains(registerPair)) { throw new Exception("Can't do unify operation for " + registerPair); } else { copyFromOperand = new RegisterTmsOperand(_registerMap[GetLastRegisterInPair(registerPair)]); copyToOperand = new IndirectRegisterTmsOperand(GetRegisterPointingToLowerByte(registerPair)); unifiedOperand = new IndirectRegisterTmsOperand(_registerMap[GetFirstRegisterInPair(registerPair)]); } return(true); }