Few questions in one thread.. What is a register? How to access variables used in one spin program?
JaanDoh
Posts: 129
Hello all,
I have a couple of questions to ask,
At the expense of my seeming stupid...
Question 1
========
Please can someone explain what a register is?
I'm not sure, but from what I can understand...
Is that a Register is the Byte, Word or Long where data received from or sent to a PIN on the micro-controller is stored?
So this could be any memory location within the available memory space.
For example:
========
Say I have written a mouse driver,
And the mouse driver has the variables MouseX, MouseY and Buttons...
And I allocate these variables into WORD variables named as above (MouseX, MouseY and Buttons)
So would the data that is coming from the mouse into the Propeller chip via the Input pins be saved into the Variables MouseX, MouseY and Buttons?
And in a sense these variables ARE the REGISTERS?
So is that a correct assumption?
Question 2
========
If I want to access a variable I have created in one program,
from another program, how is this possible?
And taking the example mouse driver above,
Taking the following for granted:
- Mouse driver program is called MyMouse.Spin
- Inside MyMouse.Spin there as PUBLIC procedures for each of those variables:
GetMyMouseX()
SetMyMouseX(NewX)
GetMyMouseY()
SetMyMouseY(NewY)
GetMyButtons()
SetMyButtons(NewButtonsState)
- Parent Program is called MyFramework.Spin
Inside MyFramework.Spin I would use something like?
- MouseXPos:= MyMouse#GetMyMouseX
- MouseYPos:= MyMouse#GetMyMouseY
- MouseButtonStates:= MyMouse#GetMyButtons
If all of the above is correct....
How do I shorten the calls:
- MouseXPos:= MyMouse#GetMyMouseX
- MouseYPos:= MyMouse#GetMyMouseY
into :
- MousePosNow:= MyMouse#GetMyMouseXY()
and return TWO values instead of the normal one RESULT value?
Thank You In Advance.
JD
I have a couple of questions to ask,
At the expense of my seeming stupid...
Question 1
========
Please can someone explain what a register is?
I'm not sure, but from what I can understand...
Is that a Register is the Byte, Word or Long where data received from or sent to a PIN on the micro-controller is stored?
So this could be any memory location within the available memory space.
For example:
========
Say I have written a mouse driver,
And the mouse driver has the variables MouseX, MouseY and Buttons...
And I allocate these variables into WORD variables named as above (MouseX, MouseY and Buttons)
So would the data that is coming from the mouse into the Propeller chip via the Input pins be saved into the Variables MouseX, MouseY and Buttons?
And in a sense these variables ARE the REGISTERS?
So is that a correct assumption?
Question 2
========
If I want to access a variable I have created in one program,
from another program, how is this possible?
And taking the example mouse driver above,
Taking the following for granted:
- Mouse driver program is called MyMouse.Spin
- Inside MyMouse.Spin there as PUBLIC procedures for each of those variables:
GetMyMouseX()
SetMyMouseX(NewX)
GetMyMouseY()
SetMyMouseY(NewY)
GetMyButtons()
SetMyButtons(NewButtonsState)
- Parent Program is called MyFramework.Spin
Inside MyFramework.Spin I would use something like?
- MouseXPos:= MyMouse#GetMyMouseX
- MouseYPos:= MyMouse#GetMyMouseY
- MouseButtonStates:= MyMouse#GetMyButtons
If all of the above is correct....
How do I shorten the calls:
- MouseXPos:= MyMouse#GetMyMouseX
- MouseYPos:= MyMouse#GetMyMouseY
into :
- MousePosNow:= MyMouse#GetMyMouseXY()
and return TWO values instead of the normal one RESULT value?
Thank You In Advance.
JD
Comments
You can't directly references variables in a child object from the parent or other child objects. To reference a public (PUB) function in a child object from the parent, you'd use <object>.<function> like:
XPos := MyMouse.GetMyMouseX
If there are no parameters, leave out the parentheses in both the declaration and reference.
The "#" notation is only used to reference named constants in the child object.
As is true of functions in general, you can't really return two values, only a single value. That said, you could probably pack both an X and Y value into one 32-bit long like this (in the child):
PUB GetMyMouseXY
return (GetMyMouseX << 16) | (GetMyMouseY & $FFFF)
and this in the parent:
MousePosNow := MyMouse.GetMyMouseXY
MouseXPos := MousePosNow ~> 16 ' extend sign of upper half
MouseYPos := ~~MousePosNow ' extend sign of lower half
Read the Propeller Manual for details. It's downloadable from Parallax.
Q1:
Lets start at the beginning. It is how I remember it, so it could be a little off, but the basics are there.
Original micros had an accumulator. Whenever you needed to do something, you read your value in from memory ("load"ed) into the accumulator, did something with it (eg added 1 to it), and then you wrote it back out to memory ("store"d). The accumulator was a register. Soon, micros added more accumulators and named them A, B, X, Y, etc. These were all registers. The memory at this time was for either the program (usually EPROM) or data (usually RAM).
Next, micros and peripherals (chips such as 6820 which were parallel expanders) had internal registers for configuring the I/O pins. Often, these configuration registers were mapped into memory space. But the micro could not directly use these register to perform ALU operations. Instead, it was necessary to write to these registers using the "store" instruction which wrote the value from an accumulator register to the memory-mapped register.
Then, as chips got smarter, the external peripheral chips were included internally in the micro. So the registers became both the accumulator registers (which could be operated on by the ALU and instructions) and the configuration registers which configured the I/O and any other internal blocks such as counters etc.
Next came the RISC (reduced instruction set computer). They had a lot less instructions that did the basics fast. These RISC processors added a number of addressable accumulators called registers. 16 and 32 registers were common. The instruction set had special bits used to select which register would be used in the instruction, rather than one or a few accumulators. This saved a lot of load/store instructions being executed (faster) by keeping a number of effective accumulators with values/data.
Generally, registers are used for operating on, or storing, data. They usually cannot be used for the physical program, which is usually stored in ROM/EPROM/EEPROM/FLASH. Some micros (and all general computers - mainframe, minis, micros such as PCs, tablets, phones) can have their running program stored in RAM/SRAM/DRAM.
Propeller
The propeller has
* Internal shared ROM (called HUB) where fixed programs and some fixed data values are stored
* Internal shared RAM (called HUB) where programs and data can be stored
* Internal RAM (called COG RAM) exclusive to each processor core (COG)
The internal shared HUB RAM is loaded at boot time (after a reset) from either
* A serial connection to Pins P30 & P31
* An external EEPROM
Then one core/cog (Cog #0) is started by loading its internal RAM from a section of HUB RAM and then this core/cog begins execution from its' COG RAM at address $000.
COG RAM
The COG RAM is 512 x 32bits. In a Propeller, this is all addressable by the instruction set, as well as it contains the program (a set of instructions). So, these 512 longs contain both the program and data. As such, these 512 longs can also be used as registers.
Therefore, the propeller has 8 cores/cogs, each with its' own 512 shared registers & program space. The last 16 longs are "special registers" that under normal operation cannot be used for program space. They are used to configure things such as the counters, I/O, video, etc.
Where does your data reside
Your data may reside inside the cog (COG RAM) or outside in the HUB RAM where it can be read and/or written by any core. You move HUB RAM locations into your registers by reading (RDBYTE/RDWORD/RDLONG) hub ram locations, and move back to HUB RAM by writing (WRBYTE/WRWORD/WRLONG) to hub ram locations.
The whole cog vs hub thing was intensely confusing when I first started programming the Propeller. I just kept reading the descriptions like those offered above and it slow sunk in.
The only time you need to worry about cog RAM is when you're using PASM. All Spin variables are located in the hub.
Hello Mike,
Thank You for your explanation. it has helped clear up some of the questions in my mind.
And I also have some more questions..
I understand from what you state above,
That its not possible to DIRECTLY reference variables in a child object from the parent object
But its possible to INDIRECTLY reference them via PUB(lic) function.
So does this mean that the opposite is true too?
And the child can access variables INDIRECTLY in the parent object via PUB(lic) functions too?
Thank You too for explaining how to PACK more than one return value into larger sized variables like LONGS.
I have already downloaded the Propeller Manual.
It is because I am new-ish to electronics and micro-controllers,
that I struggle to comprehend some of the stuff.
I feel like my programming is up to par,
Having used visual studio with visual basic to design stuff.
But it is my lack of electronics which fails me.
And hence leaves me with my back against the wall and a complete lack of understanding.
Once again,Thank You for your help and explanation.
JD
Hello Cluso99,
Thank You for your explanation too...
Your historical interlude into how processors have evolved helped a LOT in understanding some things
And the explanation of how to access variables from MAIN (HUB) RAM into LOCAL (COG) RAM has REALLY helped.
I guess the main thing I am struggling with is, which Command to use to do what I want.
I have noted down those commands you mentioned above:
RDBYTE/RDWORD/RDLONG
WRBYTE/WRWORD/WRLONG
These are exactly what I needed,
So Now I know how to shadow/transfer a variable in main ram to cog ram
This will help me out lots.
Thanks again, because sometimes a scholarly explanation is much better than reading pages of text,
which simply confuse a new mind even more.
JD
Thank You Duane,
That link was great,
And yes the whole things with Cog Vs Hub is very confusing,
But i'm trying as you stated above, to keep reading and re-reading the manual /descriptions until the penny drops lol
JD
You might be better to just jump in feet first. As you come to problems, just ask (on the Propeller 1 forum).
There is a good set of examples to work through that come with downloading PropTool. There is also a sticky in the Propeller forum that has lots of good beginner info.