PAR LOCK.family Counters. High end video control.
But its not just the commands, its how to put them together in an elegant way. How does a beginner write a serial interface?
Harprit
RTFM < 10%, tutorials 10%, practice and experience 80% or more. Elegance is over-rated. The criteria I would aim for are 1) working to specification, 2) optimized, and 3) maintainable for the product life cycle. Some obfuscated PERL could be considered elegant, some grossly optimized. Both marginally maintainable. Real work/world. 1day in a Microchip PIC course / 2 years @200 working days = what percentage practice?
That's a tough call
I will add LEDs to this code for now but eventually we will need a scope.
Its really a very basic piece of equipment every serious beginner need to learn how to use.
Just too much stuff that goes too fast to not own one. Its our eyes in electronics.
HSS
Debugger, Debugger, Debugger. Most don't have the budget for a decent scope. They are getting fewer on eBay as well...........
Yes indeed.
Beginners surely cannot be expected to have oscilloscope. You can't really expect young boys and girls to have such a thing in their dens. Perhaps after being inspired by your book they will find themselves desparately saving to get one but then they are not beginners anymore.
You can do a surprising amount of debugging with simple tricks. As a teenager I built a nixie clock at home with this new digital logic(ttl). When it did not work my father, also new to such things, suggested I listen to the signals with a small speaker. Soon had it working.
Now a days he might have suggested feeding signals into the PC audio port, then you can look at it as well.
Of course the Prop can act as a logic analyser of it's own signal, even without adding any extra wires.
(sideline to this whole thread I guess, but your note re: USPTO triggered this one)
Gotta love the whole process!!! One of my recent projects was for a group that had twice already had problems presenting their "thing" to the USPTO. No joy at all. Why? The kept sending in the lawyer to present it. Hey they are great experts....AT LAW, maybe some at technology. Our corporate group brought in our IP firm to do a presentation on the patent process and the best advice I took away from them was present the "thing" yourself and you will have a better chance of it being presented understandably and successfully. Passed that to the former mentioned group and they then got their patent. Lawyers, use them for their expertise, not yours was what I learned from that one.
"Beginners surely cannot be expected to have oscilloscope"
The second thing I made, as a kid was an oscilloscope, an ex-service 3" tube and a bunch of components from old scrap valve televisions. I was fortunate to have a father that taught me how to "make do". Now it is a case of wanting so much more at the very start.
As for loudspeakers, we often used earpieces and small powered speakers to prove that video was coming out of a wire. If we felt naughty, in front of production people,we would hold meaningful conversations about the differential phase errors that we could hear ;-)
Frankly, I think it's good to use lights, sounds, serial output and text on screen as well. Those are my normal modes. Most of the time, thinking through the timing cases gets rid of most of the issues, and I use the scope for verification more than debugging. I have used it for multi-cog things, or to discover a signal. I kind of want to write a raster display for it, so two of the channels can put text on screen, while the other two plot a signal...
I love all the audio tricks mentioned here! Used all of them. Can still hear video well enough to know whether a signal is synced or not just by the sound of it. Pretty amazing the smaller things we can hear, once we get used to trying to hear them.
my reasons for it:
visualisation of all 32 bits of DIRA, OUTA
visualisation of COG-RAM
visualisation of HUB-RAM
automatic download of code from propellertool into propeller-RAM and automatic copying PASM-code into PASD
common debug-commands
run, step, step-over, breakpoints
I attach a small introduction of how to use PASD. All beginners are invited to follow the instructions and report back if this worked for them or what difficulties they encountered
As I'm already a somehow advanced user of PASD I may be blind for some beginners difficulties. So please post all the hurdles and questions.
Thanks,
Will have to revisit that. Did not work for me, so at a first read, the xor seemed prime suspect.
Frank
Hey Jazzed,
Looked into the potatohead papers which clarified how the PASM compiler handled the pin value, and from a safety and maintainability aspect, I would probably not use such a construct as the shifted one in the example code. Does not appear to save anything at runtime, and seems an unnecessary obfuscation. I know that some prefer to lay out bits in hex as well, but I think the 1s and 0s laid out makes for more clarity for me, especially if I am having to maintain someone else's code. Also easier to train someone else as well.
Maybe in a few months or projects (and they are already starting to stack up in my ima wanna do this book) and I'm not so d@mn green with the propchip, I may see other things and perhaps get a bit tricksy as well. Or not as a couple of devices are going to have medical uses. I do thank you for the response though. More questions to come.......
I'm of two minds on the shifted construct. On one hand, the shift operator is totally handy in SPIN, so if a SPIN programmer looks at PASM, and sees that, they probably will know what is going on.
On the other hand, that exact question has come up a lot of times, and for clarity, I favor putting the bits out there, delinted by bit field, so they match the data sheet. For things like video, I find this easiest to decode what was done.
Finally, once somebody is up to speed, the shifted operator is productive, and somewhat consistent, compared to always long forming the thing.
I'm chuckling at "the potatohead papers"
What I've done so far is rewrite the primer for a bit more brevity, cleaned up some language that was too casual, etc... It's the default entry point. The secondary one is simply, "Learning PASM" and starts off where the primer ends, using lots of code examples to highlight concepts that build on one another. The challenge is visuals for me. The secondary one is actual examples that are useful and fun. Not always easy to do that and keep focus high, complexity low.
reaching deep into the gray matter, into the 8080/Z80 days, a fast trick to clearing the accumulator was to use XOR A producing all ZEROs in the accumulator.
Frank
@localroger, I also have the Z80 book (paperback 4th printing 1980), and the aforementioned Comer book for hardware design. Built my long gone IMSAI 8080 one board at a time.....
On the subject of beginner errors, calling subroutines, etc. The propeller call method probably seems strange if you're used to dealing with a stack and a traditional call/ret construction. The first machine I ever programmed in assembler was a PDP-8, also stackless, and it used a very similar scheme to the prop, except that the call aka JSR=jump to subroutine instruction stored a JMP $+1 in the first word of the subroutine, then jumped to the 2nd word of the subroutine (IIRC). A ret was then just a matter of JMPing to the 1st word of the subroutine. Any way, my next processor was the 8080, my first exposure to stacks. So after a bit of reading I wrote a little routine to test it: PUSH B / PUSH D/ PUSH H/ PUSH PSW / CALL XYZ / POP B / POP D / POP H / POP PSW. That's how you learn I suppose......
Looked into the potatohead papers which clarified how the PASM compiler handled the pin value, and from a safety and maintainability aspect ...
There are even weirder syntax operators to avoid in SPIN syntax (some are actually useful). Using "1 << number" is common in other languages and is convenient when dealing with device specifications that have bit numbers for given functions. I do think using a mask like %00000000_00000001_00000000_00000000 is more obvious as long as the syntax is understood - but that's just another drive down Semantics Boulevard.
I've been doing some serious research into my project
Current conclusions
So far everything I have written is really pretty much garbage, I need to take a different tack, start over.
It will continue to be garbage for a while, there is a learning curve re style, vocabulary and sophistication that will take lots and lots of time.
PASM has very few instructions but learning to use them effectively is not going to be simple
Debuggers are very useful but do not replace oscilloscopes, both are needed
I am reading and I am learning. Slowly.
I hope to post something interesting re the debugger soon
and post an outline for the work that has jelled in my mind as I have progressed
There are even weirder syntax operators to avoid in SPIN syntax (some are actually useful). Using "1 << number" is common in other languages and is convenient when dealing with device specifications that have bit numbers for given functions. I do think using a mask like %00000000_00000001_00000000_00000000 is more obvious as long as the syntax is understood - but that's just another drive down Semantics Boulevard.
Hey Jazzed,
Not looking for a road trip down the Blvd; as mentioned I am new w/ PASM and prop, just was concerned that if the shift was not a preprocessor/compiler function, but rather actually doing a shift through the OUTA register like an actual shift register could make for an interestingly bad time for anything connected to the prop pins set for output.
Not looking for a road trip down the Blvd; as mentioned I am new w/ PASM and prop, just was concerned that if the shift was not a preprocessor/compiler function ...
Indeed. The shift was a compiler function just to set a bit for use as a mask.
The general consensus is that the debugger of choice is the PASD debugger by the German group Insonics. The software was written by Andy Schenk and Eric Moyer. It is down loadable from the web site at
There is no charge. The manual I available both in English and in German.
Download the debugger and start reading the manual while we put together our first PAM program.
In the propeller system, all programs reside within a SPIN shell. Even a 100% PASM needs to be called from a SPIN instruction that starts the Cog the PASM instructions the executed in and tells the system where to load the program within the target Cog. If any constants will be used or if other OBJECTs will be called by the program, they too are called out in the SPIN part of the program. The program itself is defined as a set of DAT (data) statements that are the PASM instructions that will make up the program.
A typical program might look like this
{{
*****************************************
* The first thing we need is a good *
* description of what the program does, *
* who wrote it and when. *
* Terms of use if any. Copyrights etc *
*****************************************
}}
CON
..Set the clock speed parameters here
List the constants here
OBJ
lists the objects to be use here
PUB ProgName (sample)
cognew(@program_Loc, variable) 'launch assembly program in a COG
display of variables is done here in SPIN
DAT
org
The body of the PASM program goes here
It is almost always a loop that need to
do something very fast and provide a
result in a variable defined earlier as
a part of the cognew statement.
Next let us fill in the above program so that we have a working program that we can follow with the debugger. We want to make the program as simple as possible or now so that there are no logical manipulations that are hard to follow
The program will be designed to turn count from 1 to 100 over and over again and display the number as fast as possible to keep up with the PASM code. Here is a listing of the program. You can copy this program and run it to watch its operation. It is described after the listing.
{{
*****************************************
* Test program for introducing the use *
* of a debugger. *
* Harprit Sandhu 02 Aug '11 *
* MIT license terms apply. *
*****************************************
}}
CON
_clkmode = xtal1 + pll2x
_xinfreq = 5_000_000
VAR
long count, old_count
OBJ
fds : "FullDuplexSerial"
PUB count_1to100
fds.start(31,30,0,115200) 'start console at 115200 for debug output
cognew(@counter,@count) 'start PASM routine in its own cog
waitcnt(clkfreq/20+cnt) 'to let everything start up and stabilize
old_count:=0 'set the initial value of the old counter to 0
repeat 'print loop
if(old_count)==count 'check to see if we have a new value
'if not we do not print value to console
else 'if so we have to print to the console
fds.dec(count) 'print value
fds.tx(" ") 'print a separating space
if count==maximum_value 'check to see if we have reached 100
fds.tx($d) 'new line
fds.tx($d) 'new line
old_count:=count 'remember the value as the old value
DAT org 0 'start at location 0
counter mov current_count, #0 'put a 0 into the counter
add_one add current_count, #1 'add 1 to the counter
call #delay 'delay to allow print routine to catch up
'there is a minimum value that is needed for
'the print routine to get done before proceeding
wrlong current_count, par 'write the value into the PASM/SPIN shared long
sub current_count, maximum_value wz 'subtract the maximum value
'to be printed and set Z flag
if_z jmp #counter 'if the answer is 0 we are done and start over
add current_count, maximum_value 'add the max value back in
jmp #add_one 'go back and keep adding 1
delay mov delay_counter, delay_value 'load the delay counter
redo sub delay_counter, #1 wz 'subtract 1 and set zero test value
if_z jmp #delay_ret 'if it is 0 we are done so return from sub
jmp #redo 'if not keep subtracting
delay_ret ret
delay_value long 6000 'delay value has to be long enough for print
maximum_value long 100 'max value can be anything above 1
current_count res 1 'define variable
delay_counter res 1 'define variable
The program is divided into two components, the SPIN method and the PASM method. The counting takes place in the PASM method and the displayed is done in the SPIN method. Since the PASM counting routine is much faster than the ability of the SPIN code to output the values to the console, a delay (of 6000 loops) has to be added in the PASM routine to slow things down. When things are slowed down, the possibility exists that the print routine will print a value more than once. In order to avoid this the print routine makes sure that the old value and the new value are not the same before printing the value.
It is worth the time to vary the delay_value and observe what happens when it gets too small.
Next we will look at the program with the PASD debugger.
I am working on it, it will be the next post
Following errors can be added quite easily.
Make counter for delay small to 5000 loops and see what happens
Take out the duplication check in the Spin code and see what happens
Write the wrong value to PAR register or error other on this line
I took myself the freedom to add more comments right into the code and to change some commands and labels.
IMO my label-names are more selfexplaining
These changes show how the code could be more elegant through introducing the new command "djnz" and the CMP-command
which just compares to values without changing them
a waitcnt would make the delay more elegant.
I know that you are on the learning curve and that the finished and polsihed example will look different than the code posted right now.
My postings are meant as suggestions for improving. You will decide what to take in and what not.
{{
*****************************************
* Test program for introducing the use *
* of a debugger. *
* Harprit Sandhu 02 Aug '11 *
*modified by StefanL38 04.08. 11
* MIT license terms apply. *
*****************************************
}}
CON
_clkmode = xtal1 + pll2x
_xinfreq = 5_000_000
VAR
long count
long old_count
OBJ
fds : "FullDuplexSerial"
PUB count_1to100
fds.start(31,30,0,115200) 'start console at 115200 for debug output
'count is a SPIN-variable defined in the VAR-section above
'SPIN-variables are al stored into HUB-RAM
'the first parameter in the cognew-command is the label where the PASM-code starts
'This label is calculated to the according COG-RAM-adress
'The second parameter has a "@" too. This is the adress-operator
'This means the HUB-RAM-adress of variable "count"
'the second parameter will be stored in the "par"-register of the cog
'through using par as the destination or source of a WRLONG or RDLONG command
'the value stored at this HUB-RAM-adress can easily be accessed.
cognew(@Start_Count_at_0,@count) 'start PASM routine in its own cog
'copying the PASM-code from HUB-RAM (DAT-section to COG-RAM needs a bit of time
waitcnt(clkfreq/20+cnt) 'to let everything start up and stabilize
old_count:=0 'set the initial value of the old counter to 0
repeat 'print loop
if(old_count)==count 'check to see if we have a new value
'if not we do not print value to console
else 'if so we have to print to the console
fds.dec(count) 'print value
fds.tx(" ") 'print a separating space
if count==maximum_value 'check to see if we have reached 100
fds.tx($d) 'new line
fds.tx($d) 'new line
old_count:=count 'remember the value as the old value
DAT org 0 'start at location 0
Start_Count_at_0 mov current_count, #0 'put a 0 into the counter
add_one add current_count, #1 'add 1 to the counter
call #Init_delaying 'delay to allow print routine to catch up
'there is a minimum value that is needed for
'the print routine to get done before proceeding
'this wrlong-command writes the value of COG-RAM variable "current_count"
'at HUB-RAM-adress "par"
'if you remember the PASM-cog was started with cognew(@counter,@count)
'which means par contains the HUB-RAM-adress of SPIN-variable "count"
wrlong current_count, par 'write the value into the PASM/SPIN shared long
'the optional wz effect sets the Z-flag to 0 or 1 depending on the result
'of the comparison of the values "current_count" and "maximum_value"
'the command cmp does not change the value it really just compares
cmp current_count, maximum_value wz
'the if_z-condition makes the jmp-command conditional only if Z-Flag is set
'jump to label "Start_Count_at_0"
if_z jmp #Start_Count_at_0
jmp #add_one 'go back and keep adding 1s
'start of "sub-routine "delay"
Init_delaying mov delay_counter, delay_value 'load the delay counter with vaue stored in "delay_value"
'need a NOP here to distinguis between init with zero and counting up
delay_loop nop
'the acronym "djnz" means d)ecrement and j)ump if n)ot z)ero
'the COG-RAM variable "delay_counter" is decremented by one
'if the result after decrementing is NOT zero jump to label "delay_loop"
'if result is zero don't jump but execute command below
djnz delay_counter, #delay_loop
Init_delaying_ret ret
delay_value long 12000 'delay value has to be long enough for print
maximum_value long 100 'max value can be anything above 1
current_count res 1 'define variable
delay_counter res 1 'define variable
Please comment on the inserted comments. Is the PASM-code still readable? From a beginners view!
If it is not readable for beginners I suggest to put the comments in an extra text near to the code (maybe code on the left page comment on the right page)
to have handy the explanation of what the code does.
The command djnz is predestinated for loops. So my opnion is if you want to introduce loops introduce to djnz which is almost analog to
spin
I := 100
...
repeat i := i - 1 until i == 0
Also for comparing the command cmp does what its name is. And in my opinion this is easy to understand.
I understand that djnz (etc etc) is more efficient but in the first program the students needs to
see a usual construction and understand that it is easily implemented in PASM. Now
we are learning the basics. Later we make it fast and more elegant.
Thank you for the extended code and descriptions. I like them very much. Beginners
will also enjoy looking at the code in two ways.
@Stefan: Can you please elaborate on this comment (I only just started on my coffee)?
Init_delaying mov delay_counter, delay_value 'load the delay counter with vaue stored in "delay_value"
[COLOR="red"]'need a NOP here to distinguis between init with zero and counting up [/COLOR]
delay_loop nop
'the acronym "djnz" means d)ecrement and j)ump if n)ot z)ero
'the COG-RAM variable "delay_counter" is decremented by one
'if the result after decrementing is NOT zero jump to label "delay_loop"
'if result is zero don't jump but execute command below
djnz delay_counter, #delay_loop
Init_delaying_ret ret
hm - oh yes !! I should ave written 'need a NOP here to distinguis between init with delay_value and counting up
Do you mean the label could be at adress of djnz itself eliminating the nop?
got to test this.... indeed
Init_delaying mov delay_counter, delay_value 'load the delay counter with vaue stored in "delay_value"
'the acronym "djnz" means d)ecrement and j)ump if n)ot z)ero
'the COG-RAM variable "delay_counter" is decremented by one
'if the result after decrementing is NOT zero jump to label "delay_loop"
'if result is zero don't jump but execute command below
delay_loop djnz delay_counter, #delay_loop
Init_delaying_ret ret
Works too! Cool ! Learned something new.
But squeezing it to this is not the first loop for beginners
The general consensus is that the debugger of choice is the PASD debugger by the German group Insonics. The software was written by Andy Schenk and Eric Moyer. It is down loadable from the web site at
Comments
RTFM < 10%, tutorials 10%, practice and experience 80% or more. Elegance is over-rated. The criteria I would aim for are 1) working to specification, 2) optimized, and 3) maintainable for the product life cycle. Some obfuscated PERL could be considered elegant, some grossly optimized. Both marginally maintainable. Real work/world. 1day in a Microchip PIC course / 2 years @200 working days = what percentage practice?
Frank
Debugger, Debugger, Debugger. Most don't have the budget for a decent scope. They are getting fewer on eBay as well...........
Frank
Thanks,
Will have to revisit that. Did not work for me, so at a first read, the xor seemed prime suspect.
Frank
Beginners surely cannot be expected to have oscilloscope. You can't really expect young boys and girls to have such a thing in their dens. Perhaps after being inspired by your book they will find themselves desparately saving to get one but then they are not beginners anymore.
You can do a surprising amount of debugging with simple tricks. As a teenager I built a nixie clock at home with this new digital logic(ttl). When it did not work my father, also new to such things, suggested I listen to the signals with a small speaker. Soon had it working.
Now a days he might have suggested feeding signals into the PC audio port, then you can look at it as well.
Of course the Prop can act as a logic analyser of it's own signal, even without adding any extra wires.
(sideline to this whole thread I guess, but your note re: USPTO triggered this one)
Gotta love the whole process!!! One of my recent projects was for a group that had twice already had problems presenting their "thing" to the USPTO. No joy at all. Why? The kept sending in the lawyer to present it. Hey they are great experts....AT LAW, maybe some at technology. Our corporate group brought in our IP firm to do a presentation on the patent process and the best advice I took away from them was present the "thing" yourself and you will have a better chance of it being presented understandably and successfully. Passed that to the former mentioned group and they then got their patent. Lawyers, use them for their expertise, not yours was what I learned from that one.
Frank
@frank fredman - Well Frank that is the funny thing, the drawing requirements for the USPTO are specified by federal law.
For a patent attorney that had been in business for approximately 50 years, he had inadequate knowledge of the type of law he practiced. Go figure.
Bruce
EDIT: That was his specialty. "An Expert" LOL
The second thing I made, as a kid was an oscilloscope, an ex-service 3" tube and a bunch of components from old scrap valve televisions. I was fortunate to have a father that taught me how to "make do". Now it is a case of wanting so much more at the very start.
As for loudspeakers, we often used earpieces and small powered speakers to prove that video was coming out of a wire. If we felt naughty, in front of production people,we would hold meaningful conversations about the differential phase errors that we could hear ;-)
A consensus would be best
So what is the best debugger for beginners
I will learn how to use it
Harprit
Frankly, I think it's good to use lights, sounds, serial output and text on screen as well. Those are my normal modes. Most of the time, thinking through the timing cases gets rid of most of the issues, and I use the scope for verification more than debugging. I have used it for multi-cog things, or to discover a signal. I kind of want to write a raster display for it, so two of the channels can put text on screen, while the other two plot a signal...
I love all the audio tricks mentioned here! Used all of them. Can still hear video well enough to know whether a signal is synced or not just by the sound of it. Pretty amazing the smaller things we can hear, once we get used to trying to hear them.
my reasons for it:
visualisation of all 32 bits of DIRA, OUTA
visualisation of COG-RAM
visualisation of HUB-RAM
automatic download of code from propellertool into propeller-RAM and automatic copying PASM-code into PASD
common debug-commands
run, step, step-over, breakpoints
I attach a small introduction of how to use PASD. All beginners are invited to follow the instructions and report back if this worked for them or what difficulties they encountered
As I'm already a somehow advanced user of PASD I may be blind for some beginners difficulties. So please post all the hurdles and questions.
PASD itself can be downloaded from http://insonix.ch/propeller/objects/PASD_07.zip
keep the questions coming
best regards
Stefan
Hey Jazzed,
Looked into the potatohead papers which clarified how the PASM compiler handled the pin value, and from a safety and maintainability aspect, I would probably not use such a construct as the shifted one in the example code. Does not appear to save anything at runtime, and seems an unnecessary obfuscation. I know that some prefer to lay out bits in hex as well, but I think the 1s and 0s laid out makes for more clarity for me, especially if I am having to maintain someone else's code. Also easier to train someone else as well.
Maybe in a few months or projects (and they are already starting to stack up in my ima wanna do this book) and I'm not so d@mn green with the propchip, I may see other things and perhaps get a bit tricksy as well. Or not as a couple of devices are going to have medical uses. I do thank you for the response though. More questions to come.......
Frank
On the other hand, that exact question has come up a lot of times, and for clarity, I favor putting the bits out there, delinted by bit field, so they match the data sheet. For things like video, I find this easiest to decode what was done.
Finally, once somebody is up to speed, the shifted operator is productive, and somewhat consistent, compared to always long forming the thing.
I'm chuckling at "the potatohead papers"
What I've done so far is rewrite the primer for a bit more brevity, cleaned up some language that was too casual, etc... It's the default entry point. The secondary one is simply, "Learning PASM" and starts off where the primer ends, using lots of code examples to highlight concepts that build on one another. The challenge is visuals for me. The secondary one is actual examples that are useful and fun. Not always easy to do that and keep focus high, complexity low.
On the subject of beginner errors, calling subroutines, etc. The propeller call method probably seems strange if you're used to dealing with a stack and a traditional call/ret construction. The first machine I ever programmed in assembler was a PDP-8, also stackless, and it used a very similar scheme to the prop, except that the call aka JSR=jump to subroutine instruction stored a JMP $+1 in the first word of the subroutine, then jumped to the 2nd word of the subroutine (IIRC). A ret was then just a matter of JMPing to the 1st word of the subroutine. Any way, my next processor was the 8080, my first exposure to stacks. So after a bit of reading I wrote a little routine to test it: PUSH B / PUSH D/ PUSH H/ PUSH PSW / CALL XYZ / POP B / POP D / POP H / POP PSW. That's how you learn I suppose......
Current conclusions
So far everything I have written is really pretty much garbage, I need to take a different tack, start over.
It will continue to be garbage for a while, there is a learning curve re style, vocabulary and sophistication that will take lots and lots of time.
PASM has very few instructions but learning to use them effectively is not going to be simple
Debuggers are very useful but do not replace oscilloscopes, both are needed
I am reading and I am learning. Slowly.
I hope to post something interesting re the debugger soon
and post an outline for the work that has jelled in my mind as I have progressed
Harprit.
Hey Jazzed,
Not looking for a road trip down the Blvd; as mentioned I am new w/ PASM and prop, just was concerned that if the shift was not a preprocessor/compiler function, but rather actually doing a shift through the OUTA register like an actual shift register could make for an interestingly bad time for anything connected to the prop pins set for output.
Uh, Oh, Gotta chase the kiddo,
Frank
The general consensus is that the debugger of choice is the PASD debugger by the German group Insonics. The software was written by Andy Schenk and Eric Moyer. It is down loadable from the web site at
www.insonix.ch/propeller/prop_pasd.html
There is no charge. The manual I available both in English and in German.
Download the debugger and start reading the manual while we put together our first PAM program.
In the propeller system, all programs reside within a SPIN shell. Even a 100% PASM needs to be called from a SPIN instruction that starts the Cog the PASM instructions the executed in and tells the system where to load the program within the target Cog. If any constants will be used or if other OBJECTs will be called by the program, they too are called out in the SPIN part of the program. The program itself is defined as a set of DAT (data) statements that are the PASM instructions that will make up the program.
A typical program might look like this
{{
*****************************************
* The first thing we need is a good *
* description of what the program does, *
* who wrote it and when. *
* Terms of use if any. Copyrights etc *
*****************************************
}}
CON
..Set the clock speed parameters here
List the constants here
OBJ
lists the objects to be use here
PUB ProgName (sample)
cognew(@program_Loc, variable) 'launch assembly program in a COG
display of variables is done here in SPIN
DAT
org
The body of the PASM program goes here
It is almost always a loop that need to
do something very fast and provide a
result in a variable defined earlier as
a part of the cognew statement.
Next let us fill in the above program so that we have a working program that we can follow with the debugger. We want to make the program as simple as possible or now so that there are no logical manipulations that are hard to follow
The program will be designed to turn count from 1 to 100 over and over again and display the number as fast as possible to keep up with the PASM code. Here is a listing of the program. You can copy this program and run it to watch its operation. It is described after the listing.
The program is divided into two components, the SPIN method and the PASM method. The counting takes place in the PASM method and the displayed is done in the SPIN method. Since the PASM counting routine is much faster than the ability of the SPIN code to output the values to the console, a delay (of 6000 loops) has to be added in the PASM routine to slow things down. When things are slowed down, the possibility exists that the print routine will print a value more than once. In order to avoid this the print routine makes sure that the old value and the new value are not the same before printing the value.
It is worth the time to vary the delay_value and observe what happens when it gets too small.
Next we will look at the program with the PASD debugger.
Harprit
I tested your code. works as expected.
I just saw a "bug" in a comment
I guess
should be
I'm curious how you explain the use of the PASDebugger in this case.
keep the questions coming
best regards
Stefan
I am working on it, it will be the next post
Following errors can be added quite easily.
Make counter for delay small to 5000 loops and see what happens
Take out the duplication check in the Spin code and see what happens
Write the wrong value to PAR register or error other on this line
Harprit.
IMO my label-names are more selfexplaining
These changes show how the code could be more elegant through introducing the new command "djnz" and the CMP-command
which just compares to values without changing them
a waitcnt would make the delay more elegant.
I know that you are on the learning curve and that the finished and polsihed example will look different than the code posted right now.
My postings are meant as suggestions for improving. You will decide what to take in and what not.
Please comment on the inserted comments. Is the PASM-code still readable? From a beginners view!
If it is not readable for beginners I suggest to put the comments in an extra text near to the code (maybe code on the left page comment on the right page)
to have handy the explanation of what the code does.
The command djnz is predestinated for loops. So my opnion is if you want to introduce loops introduce to djnz which is almost analog to
spin Also for comparing the command cmp does what its name is. And in my opinion this is easy to understand.
keep the comments coming
best regards
Stefan
I understand that djnz (etc etc) is more efficient but in the first program the students needs to
see a usual construction and understand that it is easily implemented in PASM. Now
we are learning the basics. Later we make it fast and more elegant.
Thank you for the extended code and descriptions. I like them very much. Beginners
will also enjoy looking at the code in two ways.
Harprit
hm - oh yes !! I should ave written 'need a NOP here to distinguis between init with delay_value and counting up
Do you mean the label could be at adress of djnz itself eliminating the nop?
got to test this.... indeed
Works too! Cool ! Learned something new.
But squeezing it to this is not the first loop for beginners
keep the questions coming
best regards
Stefan
other google-suggestions
Verbdistinguish
differentiate
set apart
tell apart
So what is the main meaning of distinguish ?
And if you are not running Windows?