private static string GetEffectCode(PropellerCPU chip, ref uint address, bool useShortOpcodes)
        {
            Spin.ParsedAssignment ParsedAssignment = new Spin.ParsedAssignment(chip.ReadByte(address++));

            string effect = ParsedAssignment.Push ? string.Empty : "POP ";

            if (useShortOpcodes)
            {
                effect += "(" + ParsedAssignment.GetBasicInstruction().NameBrief + ")";
            }
            else
            {
                effect += ParsedAssignment.GetBasicInstruction().Name;
            }

            if (!ParsedAssignment.Math)
            {
                Spin.SubAssignment SubAssignment = ParsedAssignment.GetSubAssignment();
                switch (SubAssignment.ArgumentMode)
                {
                case Spin.ArgumentMode.None:
                    break;

                case Spin.ArgumentMode.SignedPackedOffset:
                    effect += " " + GetSignedPackedOffset(chip, ref address);
                    break;

                default:
                    throw new Exception("Unexpected Spin Argument Mode: " + SubAssignment.ArgumentMode.ToString());
                }
            }

            return(effect);
        }
Example #2
0
        public const int TOTAL_COG_MEMORY = 0x200;  // 512 longs of memory

        /// @brief Default constructor.
        public Cog(PropellerCPU host, uint programAddress, uint param, uint frequency, PLLGroup pll)
        {
            Hub = host;

            Memory         = new uint[TOTAL_COG_MEMORY];
            ProgramAddress = programAddress;
            ParamAddress   = param;

            FreqA           = new FreqGenerator(host, pll, true);
            FreqB           = new FreqGenerator(host, pll, false);
            Video           = new VideoGenerator(host);
            PhaseLockedLoop = pll;

            // Attach the video generator to PLLs
            PhaseLockedLoop.SetupPLL(Video);

            PC = 0;
            BreakPointCogCursor = -1;    // Breakpoint disabled initially

            // We are in boot time load
            Memory[(int)Assembly.RegisterAddress.PAR] = param;
            State      = CogRunState.WAIT_LOAD_PROGRAM;
            StateCount = 0;

            // Clear the special purpose registers
            for (int i = (int)Assembly.RegisterAddress.CNT; i <= 0x1FF; i++)
            {
                this[i] = 0;
            }

            SetClock(frequency);
        }
Example #3
0
 /// @brief Default constructor for a Cog running in PASM mode.
 /// @param host PropellerCPU where this cog resides.
 /// @param programAddress Start of program to load from main memory.
 /// @param paramAddress PARAM value given to the Cog.
 /// @param frequency Frequency running the cog (the same as the Propeller).
 /// @param pll PLL Multiplier running the cog (the same as the Propeller).
 public NativeCog(PropellerCPU host,
                  uint programAddress, uint paramAddress, uint frequency,
                  PLLGroup pll)
     : base(host, programAddress, paramAddress, frequency, pll)
 {
     Carry = false;
     Zero  = false;
 }
Example #4
0
        public FreqGenerator(PropellerCPU host, PLLGroup phaseLockLoop, bool freqA)
        {
            Host  = host;
            OutA  = false;
            OutB  = false;
            FreqA = freqA;

            PhaseLockLoop = phaseLockLoop;
        }
Example #5
0
        public VideoGenerator(PropellerCPU chip)
        {
            // Clear our phase accumulator
            PhaseAccumulator = 0;
            Chip             = chip;

            // Scale is dirty
            ScaleDirty = true;
        }
        private static int GetPackedOffset(PropellerCPU chip, ref uint address)
        {
            ushort op = chip.ReadByte(address++);

            if ((op & 0x80) == 0)
            {
                return(op & 0x7F);
            }

            op &= 0x7F;

            return((op << 8) | (chip.ReadByte(address++)));
        }
        private static short GetSignedPackedOffset(PropellerCPU chip, ref uint address)
        {
            short op       = chip.ReadByte(address++);
            bool  extended = (op & 0x80) != 0;

            op = (short)((op & 0x7F) | ((op << 1) & 0x80));

            if (!extended)
            {
                return((short)(sbyte)op);
            }

            return((short)((op << 8) | chip.ReadByte(address++)));
        }
        public static string GetMemoryOp(PropellerCPU chip, ref uint address, bool useShortOpcodes)
        {
            Spin.ParsedMemoryOperation OP = new Spin.ParsedMemoryOperation(chip.ReadByte(address++));

            string Name = OP.GetRegister().Name;

            switch (OP.Action)
            {
            case Spin.MemoryAction.PUSH:
                return(String.Format("PUSH {0}", Name));

            case Spin.MemoryAction.POP:
                return(String.Format("POP {0}", Name));

            case Spin.MemoryAction.EFFECT:
                return(String.Format("EFFECT {0} {1}", Name, GetEffectCode(chip, ref address, useShortOpcodes)));

            default:
                return(String.Format("UNKNOWN_{0} {1}", OP.Action, Name));
            }
        }
        private static uint GetPackedLiteral(PropellerCPU chip, ref uint address)
        {
            byte op = chip.ReadByte(address++);

            if (op >= 0x80)
            {
                // TODO: COMPLAIN!
                return(0x55555555);
            }

            uint data = (uint)2 << (op & 0x1F);

            if ((op & 0x20) != 0)
            {
                data--;
            }
            if ((op & 0x40) != 0)
            {
                data = ~data;
            }

            return(data);
        }
        public static string InterpreterText(PropellerCPU chip, ref uint address, bool displayAsHexadecimal, bool useShortOpcodes)
        {
            string format;

            if (displayAsHexadecimal)
            {
                format = "{0} ${1:X}";
            }
            else
            {
                format = "{0} {1}";
            }

            Spin.Instruction Instr = Spin.Instructions[chip.ReadByte(address++)];

            string Name;

            if (useShortOpcodes)
            {
                Name = Instr.NameBrief;
            }
            else
            {
                Name = Instr.Name;
            }

            switch (Instr.ArgumentMode)
            {
            case Spin.ArgumentMode.None:
                return(Name);

            case Spin.ArgumentMode.UnsignedOffset:
                return(String.Format(format, Name, GetPackedOffset(chip, ref address)));

            case Spin.ArgumentMode.UnsignedEffectedOffset:
            {
                int arg = GetPackedOffset(chip, ref address);
                format = "{0} {1} {2}";
                return(String.Format(format, Name, arg, GetEffectCode(chip, ref address, useShortOpcodes)));
            }

            case Spin.ArgumentMode.Effect:
                return(String.Format(format, Name, GetEffectCode(chip, ref address, useShortOpcodes)));

            case Spin.ArgumentMode.SignedOffset:
            {
                uint result = chip.ReadByte(address++);

                if ((result & 0x80) == 0)
                {
                    if ((result & 0x40) != 0)
                    {
                        result |= 0xFFFFFF80;
                    }
                }
                else
                {
                    result = (result << 8) | chip.ReadByte(address++);

                    if ((result & 0x4000) != 0)
                    {
                        result |= 0xFFFF8000;
                    }
                }
                return(String.Format(format, Name, (int)result));
            }

            case Spin.ArgumentMode.PackedLiteral:
                return(String.Format(format, Name, GetPackedLiteral(chip, ref address)));

            case Spin.ArgumentMode.ByteLiteral:
                return(String.Format(format, Name, chip.ReadByte(address++)));

            case Spin.ArgumentMode.WordLiteral:
            {
                int result = 0;
                for (int i = 0; i < 2; i++)
                {
                    result <<= 8;
                    result  |= chip.ReadByte(address++);
                }
                return(String.Format(format, Name, result));
            }

            case Spin.ArgumentMode.NearLongLiteral:
            {
                int result = 0;
                for (int i = 0; i < 3; i++)
                {
                    result <<= 8;
                    result  |= chip.ReadByte(address++);
                }
                return(String.Format(format, Name, result));
            }

            case Spin.ArgumentMode.LongLiteral:
            {
                int result = 0;
                for (int i = 0; i < 4; i++)
                {
                    result <<= 8;
                    result  |= chip.ReadByte(address++);
                }
                return(String.Format(format, Name, result));
            }

            case Spin.ArgumentMode.ObjCallPair:
            {
                byte obj   = chip.ReadByte(address++);
                byte funct = chip.ReadByte(address++);
                return(String.Format("{0} {1}.{2}", Name, obj, funct));
            }

            case Spin.ArgumentMode.MemoryOpCode:
                return(String.Format("{0} {1}", Name, GetMemoryOp(chip, ref address, useShortOpcodes)));

            default:
                throw new Exception("Unknown Spin Argument Mode: " + Instr.ArgumentMode.ToString());
            }
        }