Shop OBEX P1 Docs P2 Docs Learn Events
PASM - Examples of each instruction anywhere? — Parallax Forums

PASM - Examples of each instruction anywhere?

bill190bill190 Posts: 769
edited 2010-09-03 03:49 in Propeller 1
Is there any document which shows examples of how each PASM instruction might be used?

Like for the djnz instruction, it would show something like the following and explain that sub is subtracting 1 (Edit: 2, see below) each time through the loop, and so long as "Delay" has a value greater than 0, it will continue to loop. But when 0, it would continue on to the next line (not loop).

DJNZ
:loop           sub Delay, #1
                djnz Delay,  #:loop

Perhaps examples like this, but for every assembly instruction, would be helpful?
«1

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-09-01 22:09
    Most such examples already exist in the Propeller Manual.
  • AleAle Posts: 2,363
    edited 2010-09-02 02:31
    There are several tutorials in the propeller wiki propeller.wikispaces.org
    I recommend the one I wrote about MATH, many code examples are there explained.
    propeller.wikispaces.org/MATH

    Suggestions are welcome, of course.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-09-02 07:26
    Bill,

    I agree with Mike that you can find examples for most of the instructions in the Prop manual. It is interesting that it doesn't give an example for djnz where it describes that instruction, but there are several commented examples of djnz scattered throughout the manual. You just have to do a search in the Prop manual to quickly locate the examples.

    BTW, your example of using djnz is a little "different". You are actually decrementing Delay twice in each pass through the loop. If Delay started out as an odd value the loop would never exit.

    Dave
  • K2K2 Posts: 693
    edited 2010-09-02 07:56
    I agree with bill190 that it would be very helpful to have a document that contains an example and a brief explanation for every PASM instruction. The very fact that bill190's example of djnz was "a little different" is testimony to the need for just such a document.

    All the time I run into instructions that use wc and wz when I don't think they should, and don't use them when I do think they should. Of course, such uses are NEVER documented. They just sit there as a puzzle.

    If I had more time, perhaps I would attempt to get to the bottom of the mystery. But I never seem to have the time. Instead I just copy and paste the relevant examples into my code and move on. I've finally realized that Parallax will never document things the way I think they should. One can either live with the documentation that exists or one can use a different chip.
  • Mike GreenMike Green Posts: 23,101
    edited 2010-09-02 08:08
    Regarding the uses of WC and WZ (and NR sometimes):

    The C and Z bits are results from the execution of the instruction and the way these results are calculated is documented in the Propeller Manual and datasheets. Whether you need these results for your code and how you might use them is a completely different question. It's not the responsibility of Parallax to document all the many different ways to use the various bits and pieces of the Propeller's instructions. It might be the subject of an advanced Propeller programming guide that goes into "did you notice that you could do this cool trick" sort of things.
  • jazzedjazzed Posts: 11,803
    edited 2010-09-02 08:16
    K2 wrote: »
    One can either live with the documentation that exists or one can use a different chip.

    Maybe you can cite the example that satisfies your needs? We might all learn something from that. I could be wrong, but I suspect you already know the example well and are entrenched in it. If the documentation is actually better than what Parallax has provided, maybe Parallax can learn something too.
  • LeonLeon Posts: 7,620
    edited 2010-09-02 08:19
    Microchip is one company that does it properly. The programmer's reference manual for each chip family has about a page for each instruction with one or two examples showing in detail how the instruction is used, with the relevant register contents (working and status) before and after execution. It's a 374 page document for the 16-bit devices:

    http://ww1.microchip.com/downloads/en/DeviceDoc/70157D.pdf

    Parallax needs to do something similar, especially if they wish to attract professional users.
  • wjsteelewjsteele Posts: 697
    edited 2010-09-02 08:41
    I honestly don't see any additional information that isn't already included the Propeller Manual (which is 399 pages.) All the instructions are documented, with a truth table showing both input and output of the registers and conditions.

    I'm not sure how much more information is requried here. I've found it to be quite sufficient for developing on the Propeller.

    Bill
  • bill190bill190 Posts: 769
    edited 2010-09-02 08:49
    Dave Hein wrote: »
    BTW, your example of using djnz is a little "different". You are actually decrementing Delay twice in each pass through the loop. If Delay started out as an odd value the loop would never exit.

    Hey you found my timing problem!

    I was using the quick reference and was thinking djnz was "do jump not zero"...

    When all else fails, read the instructions...

    I see it is "Decrement value and jump to address if not zero"!

    So I don't even need the "sub Delay, #1" line.

    Thanks for pointing that out!
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-09-02 08:51
    Leon,

    I don't think professional users require the type of examples that Bill is asking for. The ALU and program sequencer portion of a COG is very straightforward. A profession user understands that the COG's processor is simply just a state machine that responds to each instruction and external inputs. I think the documentation of the instruction set in the Prop manual is more than adequate for a profesional user. However, there are other portions of the Prop that need more user documentation and examples, such as the use of the video registers.

    With that being said, I do agree with your suggestion for inexperienced new users. A lot of newbies don't grasp the concept of how a microcontroller functions in detail. They rely more on examples than on the precise specification of an instruction. That's how I am with C++ code. I can modify C++ code, but I have difficulties writing it from scratch.

    Dave

    Edit: Bill, I'm glad I was able to help solve your timing problem.
  • bill190bill190 Posts: 769
    edited 2010-09-02 08:57
    Leon wrote: »
    Microchip is one company that does it properly. The programmer's reference manual for each chip family has about a page for each instruction with one or two examples showing in detail how the instruction is used, with the relevant register contents (working and status) before and after execution...


    Right. That is the type of thing I had in mind. With other documentation I have seen, they also show an example for each instruction.
  • K2K2 Posts: 693
    edited 2010-09-02 09:02
    @Mike: The words used in the manual to explain WC and WZ are precisely what have made certain implementations of them confusing to me.

    Yesterday, in a Ron Czapala thread, kuroneko did a fantastic job of illustrating a couple of PASM instructions - and it hardly required any words. That's exactly and precisely what I wished existed for every instruction, directive, condition, and effect. If it did, the manual might be 50 pages instead of 400. And busy professionals wouldn't have to do so much sorting of words and piecing together of clues.

    @Jazzed: When I have a bit more time I'll extract some of the specific code snippets that have been confusing to me, and post them here. I contemplated doing just that back when I encountered them, but simply didn't have the time then, either.
  • bill190bill190 Posts: 769
    edited 2010-09-02 09:37
    Don't take away the long 400 page manual! I need every word of that when I am trying to understand how something works...

    Perhaps examples could be located elsewhere? I was thinking to include them in the manual making it even larger. :lol:

    Maybe this could be a forum thing? A topic area just for PASM instructions. No new topics allowed. And topics provided alphabetical starting with...

    ABS
    ABSNEG
    ADD
    ADDABS
    Etc.

    Then as people explain each of these in the regular forum, they could add their explanation in the PASM area in the appropriate topic too.

    Over time each instruction would have an example and discussion in that area.
  • Heater.Heater. Posts: 21,230
    edited 2010-09-02 09:39
    K2:
    The words used in the manual to explain WC and WZ are precisely what have made certain implementations of them confusing to me.

    K2, I'm curious to know which implementations are confusing you.

    Picking the ADD instruction, I find the Prop manual describes WC and WZ as follows:
    If the WZ effect is specified, the Z flag is set (1) if Value1 + Value2 equals zero. If the WC effect is specified, the C flag is set (1) if the summation resulted in an unsigned carry (32-bit overflow). The result is written to Value1 unless the NR effect is specified.

    Which seems pretty complete to me. It does not actually say the flags are unset (0) if the stated conditions are not met. But that seems like a natural assumption to me.

    A beginner to programming might wonder what "an unsigned carry" might mean. But that's not where we are at, is it?

    Comparing the PASM section of the manual to other instruction set documentation I have seen it stands up very well to me. Try finding out how exactly DAA behaves in the venerable Z80 microprocessor and you'll see that examples don't help:)

    My personal wish is to have the PASM section of the manual in it's own separate document.
  • K2K2 Posts: 693
    edited 2010-09-02 10:07
    @bill190: Wow, that's a great idea! The forum's structure of threads and posts doesn't yield itself well to the creation of such a document. But if there were a way to create such a collaborative document, I have no doubt it would coalesce very quickly, and with great examples of every instruction.

    @Heater: Seems pretty complete to me too. Then I look at a piece of code where someone is using neither wc nor wz yet is conditionally branching. But the code works. So I copy the relevant line(s) into my code, and my code works too. Pretty soon I stop using the manual. Don't have the time for that sort of monkey business. I'm sure the answers are all there. Somewhere. Somewhere in 400 pages. But not on the page describing wc and wz. And not in any sort of quick-to-grasp form.

    BTW, I vote for a separate PASM document, too.
  • Bob Lawrence (VE1RLL)Bob Lawrence (VE1RLL) Posts: 1,720
    edited 2010-09-02 10:26
    @K2 Re: "@bill190: Wow, that's a great idea! The forum's structure of threads and posts doesn't yield itself well to the creation of such a document. But if there were a way to create such a collaborative document, I have no doubt it would coalesce very quickly, and with great examples of every instruction."


    Why not make an online asm examples wiki

    http://en.wikipedia.org/wiki/Parallax_Propeller
  • Heater.Heater. Posts: 21,230
    edited 2010-09-02 10:26
    K2,
    Seems pretty complete to me too.
    Hmmm, so the manual is not the problem then.
    ...piece of code where someone is using neither wc nor wz yet is conditionally branching. But the code works.
    If they are conditionally branching, then the code has to depend on Z and C for it's operation. And I bet if the code works Z and C are set (with wc/wz) somewhere.

    There is no reason why wc/wz should be on the instruction immediately preceding the conditional branch. I for sure have code where the flags are set a long way away from where they are used.

    So "copy the relevant line(s) into my code, and my code works too.", if they include conditional execution but are not setting the flags, is a sure recipe for disaster. Possibly seemingly random failures that you can't track down.
    Pretty soon I stop using the manual. Don't have the time for that sort of monkey business.
    At that point you are doomed. Unless you have the capacity to remember every detail in the whole thing. Which I do not.
    ...But not on the page describing wc and wz. And not in any sort of quick-to-grasp form.
    But didn't we just agree the descriptions of wc and wz were perfectly adequate and complete?
  • ericballericball Posts: 774
    edited 2010-09-02 11:12
    I agree with Heater - cut and paste PASM programming is a recipe for failure, precisely because the flags are under complete programmer control.

    For example, in my AES-128 routines I originally had something like the following:
    doloop		stuff
    	if_z	JMP	#endif
    		stuff
    endif		stuff
    		TEST	x, #4	wz
    	if_z	CALL	#sub
    		DJNZ	count, #doloop
    
    The problem is the subroutine also used the flags. I had to reorganize my code to do the test twice. (And then later fix the tests because AND #4 didn't do what I needed.)

    On most other microprocessors the flags are implicitly updated (and there's usually a few more of them), but on the Propeller you have to explicitly update the flags and explicitly make any instruction dependent on those flags. And because the Propeller only has two flags, for some instructions the Z & C flags may not be "result is zero" or "overflow/carry".

    In most cases the 2 page instruction table in the Datasheet provides a good summary of the instruction and the flags. But I still want the manual if I want a little more detail.
  • K2K2 Posts: 693
    edited 2010-09-02 11:16
    Heater; you've just illustrated what is so frustrating about the Propeller, with its manual being but a symptom.

    Last week the problem was that the very first variable used in a DAT file was never initialized - neither in SPIN nor in ASM. Nowhere in the entire code listing. Come to find out, it's initialized in the cog loader inside the chip. Gee, I should have known that! How stupid can I be? How silly was I to look for it in the listing?! (Or the manual!)

    Just now I find out that one might set an effect and then use it 100 lines of code later. Perhaps this little tidbit of relevant information is actually mentioned in the manual. I don't know. What search keywords would I use in Adobe Acrobat to track it down? How many false leads would I have to follow in the process?

    The documentation is what it is. For many it would appear to be entirely adequate. Super.

    EDIT: Here's a precious jewel just extracted from the Manual:

    "For any effect not specified next to the instruction in code, the default behavior remains as indicated by the corresponding bit (Z, C, or R) in the ZCRI field of the instruction’s opcode."
  • jazzedjazzed Posts: 11,803
    edited 2010-09-02 12:21
    K2 wrote: »
    "For any effect not specified next to the instruction in code, the default behavior remains as indicated by the corresponding bit (Z, C, or R) in the ZCRI field of the instruction’s opcode."
    That's where you get stuff like CMP, TEST and the *new* TESTN instructions.

    The only draw-back for me now seems to be that I keep expecting to find such luxuries in the AVR instruction set :)

    Was your DAT COG variable a LONG or a RES ? LONG (or WORD/BYTE) can be pre-initialized to any value, RES is a weird and different story.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-09-02 12:36
    The description for each instruction contains an "Explanation" section. This normally consists of two paragraphs. The first paragraph says what the instruction does. The second paragraph says how the flags are set if WC or WZ is specified.

    It seems very clear to me. Perhaps there is too much information in the document and newbies are being overwelmed by it.
  • Heater.Heater. Posts: 21,230
    edited 2010-09-02 12:39
    K2:
    Last week the problem was that the very first variable used in a DAT file was never initialized
    "The very first variable" - I don't understand. They are always initialized for me, as described for the COGINIT PASM instruction:

    The second field, bits 17:4, holds the upper 14-bits of a 16-bit long address pointing to the desired assembly program to load into the cog. Cog registers $000 through $1EF will be loaded sequentially starting at this address, the special purpose registers will be cleared to zero (0), and the cog will start executing the code at register $000.

    Doesn't that tell you that whatever you point the COGINIT instruction at will be loaded to COG. i.e initialized.

    ...now I find out that one might set an effect and then use it 100 lines of code later.
    Hmmm, but if I turn the light on in my living room and then go out I expect it to still be on when I get back. Flip-flops are like that. If the documentation says Z or C is set only if WZ or WC is specified why would I assume that not to be true 1, 10 , 100, 1000 instructions later?

    Some things just don't need writing down. If I say "A is true, B is true, C is true" should the reader assume that D, E, F... are also true. Should I specifically say it does not imply so? You are right, what is the search term for all those things that are not supposed to be in the book?

    "For any effect not specified next to the instruction in code, the default behavior remains as indicated by the corresponding bit (Z, C, or R) in the ZCRI field of the instruction’s opcode."

    Sounds clear to me, just check the ZCRI fields in the instructions opcodes.

    Generally the Prop architecture, and the manual are renowned for the lack of "surprises".





  • Heater.Heater. Posts: 21,230
    edited 2010-09-02 12:52
    I just realized.

    Including the instructions opcode, the Z,C and R bits, the indirect bit and the condition bits there are 14 bits specifying each instruction.

    That is 16384 different instructions/variants.

    This "examples of each instruction" document is going to be huge:)
  • Mike GreenMike Green Posts: 23,101
    edited 2010-09-02 13:22
    @K2,
    This is not unique to the Propeller. It's not particularly different from setting a mode variable somewhere in a program and testing it 1000 lines later. This type of programming has existed since the beginnings of programmable machines. Some computer architectures make it more useful as a programming technique and some do not. In the IBM360 series machines, the condition code was used so much for so many things that it was impractical to use it over much more than a few instructions. Almost all instructions would set it and changing it was not optional. In the case of the Propeller, you have to explicitly choose to set C and Z.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-09-02 13:44
    Heater - :smilewinkgrin:

    I think much of this boils down to learning style and learning preference. It's not the size of the book that matters, it's the characters in its contents right? :smilewinkgrin: ... And you can't just rely on one book to get the point across, you must study the subject at hand using multiple sources and cross-correlate the data from various sources in your head to be an effective programmer.

    One of my favorite books ... "PC Assembly Language: Step by Step (Developer's Series)" (ISBN - 1-55755-096-4) which covers processors 8086,8088,80286,80386,and 80486 and is less descriptive by far than the Propeller manual but still a very effective tool. There are also many other books relating to the same subject I had to plow through before I had an aha moment.

    ... bottom line ... simply Study the information. It wasn't immediate for us at first, and still isn't at times. We all do it because it's a challenge less we forget.
  • ericballericball Posts: 774
    edited 2010-09-02 13:48
    Heater. wrote: »
    Including the instructions opcode, the Z,C and R bits, the indirect bit and the condition bits there are 14 bits specifying each instruction.
    Not indirect - immediate.

    6 bit opcode, 4 bit ZCRI flags, 4 bit condition, 9 bit destination register, 9 bit source register = 32 bits. The PASM ISA really is a matter of form follows function. The 4 condition bits mean every combination of the Z & C flags can be specified. The 9 bit source & destination means COG RAM can only be 512 words and why immediate values can only be 9 bits wide.

    However, for the most part the flags ZC & I flags are the same across all instructions. The R flag is implicit with most opcodes being WR, but some NR. (i.e. TEST is AND NR). The condition codes are also the same for all opcodes save NOP which is implicitly if_never.

    So there's no need to give examples for all 2^14 combinations, although there would be some value in showing how the flags can be used (i.e. CMPSUB NR for C:= D >= S).

    There are also some unused opcodes and HUBOP uses the S value as an opcode extension.
  • K2K2 Posts: 693
    edited 2010-09-02 14:50
    "Was your DAT COG variable a LONG or a RES ? LONG (or WORD/BYTE) can be pre-initialized to any value, RES is a weird and different story. "

    It was a SPIN variable. Declared but never initialized. Its address was passed to PAR. First line of DAT used PAR to load a LONG. For a newbie to ASM, this does not aid comprehension of the SPIN/PASM interaction. ;)

    BTW, COGINIT is not used in the Object in question, and even if it were, how would I know to look at COGINIT for information on initializing variables in SPIN? Besides, I still wasn't sure how PAR worked....and a SPIN variable that was magically initialized didn't help explain it.

    Back to my original comment re. wc and wz, I'm still not sure which it is. Does a prior use of wc and wz carry some sort of memory with it like Heater seemed to imply, or is the excerpt from the manual correct? Or can the two be rationalized?

    "Including the instructions opcode, the Z,C and R bits, the indirect bit and the condition bits there are 14 bits specifying each instruction. That is 16384 different instructions/variants. This "examples of each instruction" document is going to be huge"

    Let's not be disingenuous, Heater, I never asked for all combination and permutation of Z, C, and R. Furthermore, to suggest that since there isn't room for 16,384 examples there should be no examples is folly. "Just the basics, Ma'am."

    I intend to address more of the comments made, but I'll have to do it later today.
  • K2K2 Posts: 693
    edited 2010-09-02 14:55
    "It seems very clear to me."

    I'm happy for you, Dave. But isn't it axiomatic that once you know something, it is clear?
  • ericballericball Posts: 774
    edited 2010-09-02 15:22
    K2 wrote: »
    Back to my original comment re. wc and wz, I'm still not sure which it is. Does a prior use of wc and wz carry some sort of memory with it like Heater seemed to imply, or is the excerpt from the manual correct? Or can the two be rationalized?

    Each COG has two bits of state (Z and C) in addition to the Program Counter. In many other microprocessors there are explicit registers which contain this state information. On the Prop each instruction can change the Z & C bits. Unlike many other microprocessors, on the Prop whether Z & C flags are changed (and the destination register) is under the control of the programmer.

    For example the ADD instruction calculates S+D and implicitly updates D with the result, unless NR (not result) is specified. If WZ is specified, then the Z flag is set when the result is zero (e.g. $0000_0001 + $FFFF_FFFF) even if NR is also specified. If the result is not zero (and WZ is specified) then the Z flag is cleared. If WC is specified, then the C flag is set when an unsigned overflow occurs (e.g. $0000_0001 + $FFFF_FFFF), and cleared if not.

    The condition codes (e.g. if_z) control whether an instruction is executed based upon the specified flags. For example:
    ' if ( a == 1 || a == 2 || a == 3 )
    		CMP	A, #1	  wz
    	if_nz	CMP	A, #2	  wz
    	if_nz	CMP	A, #3	  wz
    	if_z	JMP	#iftrue
    
    Note: CMP is equivalent to SUB nr
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-09-02 15:42
    K2 wrote: »
    "It seems very clear to me."

    I'm happy for you, Dave. But isn't it axiomatic that once you know something, it is clear?
    K2,

    Your missing the point of my comment. The "Explanation" part of each instruction description is clear to me. Here's the explanation for the DJNZ instruction. It states what the instruction does, and how the flags are affected if WZ or WC is specified. This is the same format that is used to describe all the instructions. K2, what part is not clear to you?

    Dave

    Explanation

    DJNZ decrements the Value register and jumps to Address if the result is not zero.

    When the WZ effect is specified, the Z flag is set (1) if the decremented Value is zero. When the WC effect is specified, the C flag is set (1) if the decrement results in an unsigned borrow (32-bit overflow). The decremented result is written to Value unless the NR effect is specified.

    DJNZ requires a different amount of clock cycles depending on whether or not it has to jump. If it must jump it takes 4 clock cycles, if no jump occurs it takes 8 clock cycles. Since loops utilizing DJNZ need to be fast, it is optimized in this way for speed.
Sign In or Register to comment.