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); }
/// @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; }
public FreqGenerator(PropellerCPU host, PLLGroup phaseLockLoop, bool freqA) { Host = host; OutA = false; OutB = false; FreqA = freqA; PhaseLockLoop = phaseLockLoop; }
/// @brief Reset the propeller CPU to initial state. /// @details Release cog instances, clock sources, clear locks and pins, and reset plugins. /// @version 15.03.26 - Separate reset loops for clock sources, cogs and locks. public void Reset() { ResetMemory.CopyTo(Memory, 0); SystemCounter = 0; Time = 0; RingPosition = 0; for (int i = 0; i < ClockSources.Length; i++) //clear clock source references { ClockSources[i] = null; } for (int i = 0; i < TOTAL_COGS; i++) //clear cog references { Cogs[i] = null; } CogsRunning = 0; for (int i = 0; i < TOTAL_LOCKS; i++) //clear locks state { LocksAvailable[i] = true; LocksState[i] = false; } PinChanged(); //update situation of pins foreach (PluginCommon plugin in PlugIns) { plugin.OnReset(); } SetClockMode((byte)(ClockMode & 0x7F)); // Start the runtime in interpreted mode (fake boot) // Pushes the 3 primary offsets (local offset, var offset, and object offset) // Stack -1 is the boot parameter uint InitFrame = ReadWord(10); WriteWord(InitFrame - 8, ReadWord(6)); // Object WriteWord(InitFrame - 6, ReadWord(8)); // Var WriteWord(InitFrame - 4, ReadWord(12)); // Local WriteWord(InitFrame - 2, ReadWord(14)); // Stack // Boot parameter is Initial PC in the lo word, and the stack frame in the hi word ClockSources[0] = new PLLGroup(); Cogs[0] = new InterpretedCog(this, InitFrame, CoreFreq, (PLLGroup)ClockSources[0]); CogsRunning = 1; }
/// @brief Execute the hub operations. /// @details This method is called from a cog to do the operations related to all the CPU. /// @version 15.03.26 - corrected problem in COGSTOP return. /// @param[in] caller Reference to the caller Cog of this method. /// @param[in] operation Hub operation to execute. /// @param[in] argument Parameter given to the opcode (destination field in PASM). /// @param[in,out] carry Carry flag that could be affected by the operation. /// @param[in,out] zero Zero flag that could be affected by the operation. /// @returns Value depending on operation. /// @note Reference of supported Operations, based in Propeller Manual v1.2: /// @arg HUBOP_CLKSET - page 271. /// @arg HUBOP_COGID - page 283. /// @arg HUBOP_COGINIT - page 284. /// @arg HUBOP_COGSTOP - page 286. /// @arg HUBOP_LOCKNEW - page 304. /// @arg HUBOP_LOCKRET - page 305. /// @arg HUBOP_LOCKSET - page 306. /// @arg HUBOP_LOCKCLR - page 303. public uint HubOp(Cog caller, uint operation, uint argument, ref bool carry, ref bool zero) { uint maskedArg = (argument & 0x7); uint cog = (uint)Cogs.Length; switch ((HubOperationCodes)operation) { case HubOperationCodes.HUBOP_CLKSET: zero = false; carry = false; SetClockMode((byte)argument); break; case HubOperationCodes.HUBOP_COGID: carry = false; cog = CogID(caller); zero = (cog == 0) ? true : false; return(cog); case HubOperationCodes.HUBOP_COGINIT: //determine witch cog start if ((argument & 0x8) != 0) //if free cog should be started (bit 3 is set) { for (uint i = 0; i < Cogs.Length; i++) //assign the first free cog { if (Cogs[i] == null) { cog = i; break; } } if (cog >= Cogs.Length) { carry = true; //no free cog return(0xFFFFFFFF); } else { carry = false; } } else // instead specific cog should be started { cog = maskedArg; } zero = (cog == 0) ? true : false; PLLGroup pll = new PLLGroup(); ClockSources[cog] = (ClockSource)pll; uint param = (argument >> 16) & 0xFFFC; //decode param value uint progm = (argument >> 2) & 0xFFFC; //decode program address to load to if (progm == 0xF004) { Cogs[cog] = new InterpretedCog(this, param, CoreFreq, pll); } else { Cogs[cog] = new NativeCog(this, progm, param, CoreFreq, pll); } CogsRunning++; return((uint)cog); case HubOperationCodes.HUBOP_COGSTOP: zero = (maskedArg == 0) ? true: false; carry = (CogsRunning < TOTAL_COGS) ? false : true; Stop((int)maskedArg); CogsRunning--; return(maskedArg); case HubOperationCodes.HUBOP_LOCKCLR: zero = (maskedArg == 0) ? true : false; carry = LocksState[maskedArg]; LocksState[maskedArg] = false; return(argument); case HubOperationCodes.HUBOP_LOCKNEW: zero = false; // initial value if no Locks available carry = true; // initial value if no Locks available for (uint i = 0; i < LocksAvailable.Length; i++) { if (LocksAvailable[i]) { LocksAvailable[i] = false; carry = false; if (i == 0) { zero = true; } return(i); } } return(7); // if all are occupied, return a 7, but carry is true case HubOperationCodes.HUBOP_LOCKRET: zero = (maskedArg == 0) ? true : false; carry = true; // initial value if no Locks available for (uint i = 0; i < LocksAvailable.Length; i++) { if (LocksAvailable[i]) { carry = false; } } LocksAvailable[maskedArg] = true; return(maskedArg); case HubOperationCodes.HUBOP_LOCKSET: zero = (maskedArg == 0) ? true : false; carry = LocksState[maskedArg]; LocksState[maskedArg] = true; return(maskedArg); default: // TODO: RAISE EXCEPTION break; } return(0); }