Propeller Assembly for beginners
Harprit
Posts: 539
After total frustration in getting things done really fast in Spin, which I'm not very good at, I have decided to learn Assembly Language for the Propeller and to write a book about it as I go along, as I did for the Beginners Book. Maybe that will help me and others.
Its going to take a while in that, for me, the going is slow. I don't know a thing about it right now and I've been at it for quite a while! Meaning that I still cannot write anything but the shortest of programs.
I solicit advise as to where I might learn more about this. I have read the Prop Manual umpteen times so I need more than that. I also need to understand binary manipulations better and was unable to find a suitable book on Amazon.
Any guidance would be greatly appreciated. Please keep in mind my "knows little of nothing" status.
Thanks
Harprit.
Its going to take a while in that, for me, the going is slow. I don't know a thing about it right now and I've been at it for quite a while! Meaning that I still cannot write anything but the shortest of programs.
I solicit advise as to where I might learn more about this. I have read the Prop Manual umpteen times so I need more than that. I also need to understand binary manipulations better and was unable to find a suitable book on Amazon.
Any guidance would be greatly appreciated. Please keep in mind my "knows little of nothing" status.
Thanks
Harprit.
Comments
It also helps to have a "bottom up" programming style. You first break down your objective into tasks, then start with the most repeated / time-sensitive task and program that as efficiently as possible. Then structure all other tasks to feed data to the "core" task.
With ASM the lines between data types also get blurred. There's no type checking. Whether a given 32-bit value is signed or unsigned; integer, fixed-point, float or character(s) (or even code) can change as required. While some opcodes might "prefer" one or the other, you can "bend the rules" as necessary.
PASM also has a few quirks versus most other ASMs:
1. There are 496 "registers" which may contain code or data. Certain constructs require operating on code as data (i.e. arrays in COG RAM).
2. Pipelining means changes to instructions don't take effect until the next instruction.
3. How JMPRET (aka JMP, CALL, RET) and DJNZ/TJNZ/TJZ work thus why you normally put an # before the label.
4. Flags - having to specify which flags get updated, the power of conditional operations, and the limitations of only having two flags.
Here's a link to the thread:
http://forums.parallax.com/showthread.php?96457-Machine-Language-Tutorial&highlight=assembler
This is worth a look too: http://forums.parallax.com/showthread.php?84031-Propeller-Tricks-amp-Traps-(Last-update-21-June-2007)&p=575479&viewfull=1#post575479
You might consider using PropBasic ... it will produce some generic PASM for you.
I hope you're able to figure it all out and produce a quality book.
I promise to look at your posted samples and offer constructive comments.
Good luck.
They do not seem to be in the data sheet
Harprit
Which makes me think that all registers can be used as targets of math/bit/byte manipulations
H
Basic PASM syntax: [if various] <instruction> <destination register>, [#]<source> [W[C|Z|R] | NR]
Examples below show 3 ways to loop 20 times.
take a look at PASD the propeller assembly debugger http://insonix.ch/propeller/prop_pasd.html
The website is german but the manual is in english.
With this tool you can single-step through PASM-code and lookup the value of each long in the COG-RAM.
very helpful for analysing what is going on.
keep the questions coming
best regards
Stefan
Sounds like a great endeavour - having a beginner's perspective can really help identify the tricky concepts for newbies. Perhaps keep this thread alive when you need help with the harder concepts and tricks...
As for binary manipulation I doubt there's a single book that covers the ground - you'll want to familiarised yourself with 2-s complement representation, use of hexadecimal notation, how to multiply works in binary, boolean algebra, and uses for shift and rotate, and of course manipulating ina/outa/dira/cnt/frq/phs registers directly. Wikipedia will have some of this, these forums will have the Propeller-specific stuff.
Nowadays? They don't teach that stuff any more. It's assumed that either you know it already or you don't need it. Which is tragic, because I've seen several majorly fatal mistakes made by otherwise good programmers who simply didn't know, for example, that 1/10 is an infinitely rebeating fraction in binary and it will truncate and expand back to .999999 like 1/3 does in decimal if you don't round off your results -- especially if you use double precision math, where the routines don't automatically round off for you.
The Propeller has a particularly rich set of capabilities for binary work with its wonderfully extensive list of conditions that can be applied to each and every instruction and the ability to separately and selectively repress the C, Z, and numeric results of any operation. I'm doing a big job in 80386 assembly at work right now and I am feeling so spoiled by PASM.
I will look into it all as i proceed
Keep it coming and I'll get the job done
Its starting to make sense
Thanks again
Regards
Harprit
How do I put a picture back under my name on the left
H
H
I'm looking forward to your next book about Propeller. I bought yours about the SPIN language and it's a pretty good read.
Its always encouraging for an author to hear good things about his work.
Harprit
I am thinking I will follow the outline of the beginner's book on SPIN pretty closely
but instead of doing things in SPIN, everything will be in PASM this time. This will
allow comparisons during the learning process that might be very useful. We can
also then compare the speeds of the two languages.
Of course the outline will have to change here and there to allow PASM to be explained
and explored from time to time. Might even include some basic stuff on binary math. Just
enough for reference. Not a tutorial in any way. That would be a book in itself.
I just received Crowder's book on "The arithmetic of Computers" written in 1960!
From Amazon.
I was a Sophomore at the U for Illinois then.
Seems like a long time ago.
Its pretty good on Binary math.
I will be able to learn enough to get the job done.
Comments Please?
Harprit
Maybe have a math appendix document that describes:
1. My book on spin, which you will have as a general reference.
2. The propeller manual version 1.0 and the published errata. See Propeller Tool help tab.
3. The data sheet for the propeller chip. This too can be downloaded from the help menu tab in the propeller tool.
The first program that is is always considered in any tutorial on any language is the blinking of an LED. The propeller manual provides an example of this on this on page 340. Here is a listing of that program as provided by Parallax:
{{AssemblyToggle.spin}}
con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
pub main
cognew(@toggle, 0)
dat
org 0
toggle mov dira, pin
mov time, cnt
add time, #9
:loop waitcnt time, delay
xor outa, pin
jmp #:loop
pin long |<1
delay long 6_000_000
time res 1
The explanations provided in the manual are not as detailed as they need to be for a beginning student of the language. To remedy this, I will provide a line by line description, or if you will, documentation for this program as the first example of proceeding with our learning process.
I will be setting up all the experiments in this book on the propeller professional development board. If you have the education Kit provided by parallax it will provide most of the electronic components that you need. The other components I've been list in the appendix so that you can have them all one hand as you start your experimentation. It is not strictly necessary to use the professional development board but the board does make life a lot easier in that it has an awful lot of the devices that we will be experimenting with built right into the board, and they are well organized and easy to use.
Let's go over the first program in the propeller manual a line at the time so that we can understand exactly what the programmer had in mind as you go over the program.
{{AssemblyToggle.spin}}
the first line is a comment, and as such is not executed by the language.
CON
the second line identifies the following two lines as constants. These constants are the same as we see in SPIN, and they define the speed of the processor as 5 X 16 megahertz. We could have defined this as any other speed as long as we used valid values. Keep in mind that the slower we run the processor, the less energy it uses.
PUB Main
The next line defines the object as a public object and provides a handle for the program.
cognew(@toggle, 0)
this line launches a new cog that will holld the program for blinking the LED that we are addressing.
It tells the propeller that the new program is to be installed starting at location zero in the memory of this cog.
We now need to define what the total toggle program consists of. It is defined in the DAT data provided for this program.
The next line.
DAT.
Tells us that the following lines contain the data that will be interpreted as a program by cognew the cog that we started earlier under MAIN.
{toggle P16}
Is a comment to remind us that we will be toggle line 16 on the propeller. We have a choice of any line from one to 31, but we may want to avoid the last four lines in that they have other uses that we may not want to interfere with at this time.
ORG 0
This line tells us that we are going to start storing our data points into the memory of this cog starting with the first memory location in the cog. We have the option of starting at any memory location within the cog but at this point, there is really no good reason not to start at location zero.
Toggle Mov Dira, Pin
in this line, Toggle is a marker that has no particular purpose. It marks the beginning of a oobject. The command MOV tells the processor to move the value of PIN into the DIRA register. On start up a propeller chip has all its pins in the input mode. In this mode, thy are high impedance pins that will accept data both from TTL level signals and from CMOS level signals. Remember that the propeller is a CMOS device running at 3.3 Volts. The switching point between high-level and low-level signals in a 3.3 volt device is 1.65 V or half of 3.3 volts. Further down in the program our constants can is defined as a long or 32 bit variables. In this 32 bit variable bit 16 is made a one and then the 32-bit number will be moved into the register DIRA.
There are 16 registers that are pre-defined in PASM. A list of these 16 registers is in the data sheet on page 34. Some of these registers can be written to, and some cannot. We will not go into witch is which at this time, but you need to be aware that these registers exist and one of them (DIRA) represent the direction that the pins will be programmed to in our programs.
Before we started DIRA was
00000000_00000000_0000000_0000000
After reading is executed. The instruction DIRA will contain
00000000_00000001_0000000_0000000
This tells us that all the pins on our propeller are inputs except in 16, which is the 17th pin because we always start counting at zero.
In this discussion, and in all subsequent discussions, I will use binary format as used above so that it is easy to see which pin is set to what without having to do any mental manipulations.
mov time cnt
Thi instruction moves the current content of the system clock or counter into the Time register. CNT is also one of the 16 registers that was referred to earlier as being predefined in each cog ram. This register contains the current count in the system clock and is it a read only register. You cannot set the system clock, you can only read it.
add time, #9
this instruction adds, the number nine to the time variable. This is necessary, because there is a short delay between putting the counter into time variable and starting the looping process. Adding the nine compensates for the delay between the two instructions. This number can be nine or higher. Making it higher, would detract from the accuracy of the first delay and making it lower, would make it necessary for the conqueror to go all the way around the 32-bit count the before it could be used correctly.
:loop waitcnt time, delay
this is the wait instruction that determines the delays between turning pin 16 on and off in the program. This delay is based on the clock frequency that we specified under CON. The delay is 6/80 seconds as specified. The LED stays on for 6/80 seconds and then stays off for 6/80 seconds for a full cycle of 3/80 seconds. The way this works in PASM the delay is dependent on the specified speed of the system clock.
xor outa, pin
this instruction inverts the signal on pin 16 each time through the loop.
jmp #:loop
tells the program to jump to the location marked ":loop". This starts the process of converting the target line, and the delay over and begins routine that links the LED at location PIN
We still have the business of defining our constants and telling the processor, where we want the information stored. This is done on the next three lines.
Pin Long |<16
this identifies PIN as location 16 in the register that pin will be used with.
Delay long 6_000_000
tells the processor that delay will be a four byte long with a value of 6 million placed in it.
Time res 1
tells the system that the time variable will be located within the workspace assigned in RES 1. This is one of the registers in the resources area, and we are addressing the first register in this space.
Experimentation.
It is best not to connect the output pin on a propeller directly to an LED. It would be best to use a resistor of between 1 and 5 hundred ohms to limit the load on the line. The larger the value you use the dimmer the LED will be.
Run the program and try changing the various parameters to see what happens. Off particular interest is the number nine, and the number 6 million..
Harprit
Just a suggestion but you may want to write your book with V1.1 of the manual as the reference. A reader can get that just by clicking on help in the Propeller Tool (just like you tell them for the datasheet). To get V1.0, I need to go hunting on the Parallax website??.....oops, the only other version on the website is v1.01....or the errata to v1.0....no actual download for v1.0 of tthe manual!
The reader also needs to be encouraged to read the hardware section of the manual and the datasheet so some of the basics of the hardware are understood. The tight coupling of PASM to the hardware requires an understanding of the chip, how it's structured and what some of the important architecture features and pieces are. Some of this you may need to help explain or elaborate on in the first chapter of your book - anything you found confusing? Anything in particular that makes PASM easier to write and understand?
I like taking the PASM code apart line by line and explaining what it does and what things are. From this respect, you become the processor and perform each instruction step by step.
The propeller manual is also accessible from the Propeller Tool Help Menu.
The first program in most languages is "Hello, World!" .... Blinky is fine for an MCU though.
Edit.
Alternatives for clock are _clkmode RCFAST and _clkmode RCSLOW but can't specify _xinfreq
PUB main is a public method in the object and the starting point for the program.
The next line starts the PASM program. The @ sign means use the address of the toggle program.
movie?
The end of main should end with REPEAT to keep the spin interpreter from accidently executing some bytes.
"tall going" ... spell checker?
That would be from zero to 31 or output P0 to P31 ... Phil would say PA0 to PA31, but there will never be a Propeller with PB0..PB31 so it doesn't matter.
PIN to DIRA
Input signals > 3.3V (or less than 0 for that matter) should have a series resistor that does not allow the current of the potential difference over the resistor to exceed the specified 0.5mA . R > E/0.5mA
Who's Ruby?
Missing comma.
normally people do it in this order
MOV time, #9
ADD time, CNT
If i didn't know boolean operators, I would be a little miffed by now. You might say this is indistinguishable from magic right now and will be explained later.
I would add "please don't forget the # on this line!" Octothorpe, whatever you want to call it ....
I would add "under no circumstances should a res command be used in the middle of a PASM program" .... blah res N must be at the end of code because it does not allocate space for the variable and will cause any longs or instructions that might come after it to have the wrong register addresses.
100 to 500 Ohms is easier to understand ... if that's what you meant.
Hope it's helpful.
Cheers.
--Steve
Again, using e.g. org 32 doesn't magically move your program somewhere else. This directive just initialises what you might call a base counter for all the address calculations the assembler has to do. There are legitimate reasons for using org with something other than 0 but that's maybe a bit too much for beginners.
Note that - English not being my 1st language - I interpret what you wrote the way I just described. It's possible that you meant it in a different way. That said it should be made absolutely clear - without room for mis-interpretation - what's happening here.
The manual makes a good attempt at explaining org. Maybe it would be better to apply Steve's miffed-xor clause and leave a detailed analysis for later.
This suggests that you can have other types of objects e.g. private. Fact is, an object needs at least one public method and the first (public) one is used as the start method (if run/used as the main object).
The way that is written one might confuse "location zero" in the cog with the
zero value of the second parameter to cognew.
Better to say that the first parameter to cognew is the address of the PASM
code, in a DAT section, that will be loaded from hub memory into cog and
executed. It will always be loaded at address zero within the cog. The "@"
symbol is the operator used to get the address of a label rather than the
value stored at that address.
You should also mention that what the second parameter is and that it is not
used here. Expand on it later of course.
Then we have;
Toggle is a label for a place in hub ram, it has a very important purpose here, it is used as the first parameter to cognew and tells were the cog code is to be loaded from.
I am learning more than I thought I would, faster than I thought I would.
Thanks
I have
pin long %0000_0000_0000_0000_0000_0000_0000_0001
It then goes into DIRA and a pause
If I move the data with SHL and SHR I can make line 0 go on and off
However, line 1 does not go on and off
What am I doing wrong?
What do I need to do.
Harprit
but when the 1 is in position 1, it does not seem to turn line 1 on and off.
con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
pub main
cognew(@toggle, 0)
dat
org 0
toggle mov dira, pin
mov time, cnt
add time, #9
:loop waitcnt time, delay
xor outa, pin
shl outa, 1
waitcnt time, delay
xor outa, pin
shr outa, 1
jmp #:loop
pin long %00000000_00000000_00000001
delay long 6_000_000
time res 1
HSS
You only set bit zero of DIRA so you wil not see any output on bit 1.
Your use of xor and shifts only ever puts 0 on bit 1 of outa so even if you dira was correct you would not see a high on the pin.
Let me work on it a bit.
Harprit