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));
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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
                });
            }
        }
Esempio n. 5
0
        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));
            }
Esempio n. 7
0
        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);
     }