Shop OBEX P1 Docs P2 Docs Learn Events
Should ORG imply ORGH? — Parallax Forums

Should ORG imply ORGH?

Ok,

I found what may be a problem with the ORG directive on the P2 (or if it is meant to work this way then it is VERY confusing!). The problem is that using ORG with a non-zero value appears to generate incorrect cog addresses. You can fix it by inserting a corresponding ORGH, but should this really be necessary?

For example, consider this code ...
DAT
        org      $0

cog_0   mov      cog_7,cog_6
cog_1   mov      cog_6,cog_8
cog_2   mov      cog_7,cog_8
cog_3   mov      cog_8,cog_6
cog_4   mov      cog_6,cog_7

cog_5   long     $55555555      ' force next cog address to be 6

cog_6   long     $66666666
cog_7   long     $77777777
cog_8   long     $88888888

Everything is fine here. But suppose we remove the long at cog_5 and instead use an ORG directive to instruct the assembler to put the next long at cog location 6 ...
DAT
        org      $0

cog_0   mov      cog_7,cog_6
cog_1   mov      cog_6,cog_8
cog_2   mov      cog_7,cog_8
cog_3   mov      cog_8,cog_6
cog_4   mov      cog_6,cog_7

        org      $6            ' force next cog address to be 6
'       orgh     $6*4          ' force next hub address to match cog address

cog_6   long     $66666666
cog_7   long     $77777777
cog_8   long     $88888888

Here, the code generated is correct, but the long labelled cog_6 actually appears at cog location 5. To make it work correctly, I have to uncomment the "cogh" directive.

I'm fairly sure this is not the expected behaviour .... but the P2 is such a strange beast that I am just not 100% sure! :(

By the way - PNUT and P2ASM both behave the same way.

Comments

  • Instead of
            org      $6            ' force next cog address to be 6
    
    Try
            orgf      $6            ' force next cog address to be 6
    
    

    orgf - "fill to"
  • It is meant to work that way. This is consistent with the way ORG works in the P1. The listing from p2asm looks like this:
                       DAT
    00000 000                  org      $0
    
    00000 000 f6000e06 cog_0   mov      cog_7,cog_6
    00004 001 f6000c08 cog_1   mov      cog_6,cog_8
    00008 002 f6000e08 cog_2   mov      cog_7,cog_8
    0000c 003 f6001006 cog_3   mov      cog_8,cog_6
    00010 004 f6000c07 cog_4   mov      cog_6,cog_7
    
    00014 006                  org      $6            ' force next cog address to be 6
                       '       orgh     $6*4          ' force next hub address to match cog address
    
    00014 006 66666666 cog_6   long     $66666666
    00018 007 77777777 cog_7   long     $77777777
    0001c 008 88888888 cog_8   long     $88888888
    
    The hub address increments by 4 and the cog address increments by 1 based on the value of the last ORG.
  • No, the "missing" longword in the original exampe is expected. I think you'll find that the original Spin for P1 behaves this way too. The ORG directive has never inserted anything in memory, it's always just meant "assume that the code after ORG X gets put into a COG at address X somehow, and treat the labels accordingly". ORGH is a very different beast, it means "assume that the code after this point is meant to be in HUB, not COG", and "ORGH X" will insert padding to make sure the address starts at X.

    Note that labels in P2 have two values, their "hub address" and their "default address". After ORGH these are always the same, but after ORG X the "default address" starts over at X but the hub address continues incrementing as before. "@ label" always refers to the hub address of a label, whereas just plain "label" is the default address.

    Finally, there are actually 3 assemblers for P2 -- PNut, P2ASM, and fastspin. They all treat ORG and ORGH the same way.
  • evanhevanh Posts: 15,916
    ORG is something that trips everyone up for a while. It's a regular assembler type directive yet I didn't make full sense of it until I actually needed it.
    ORGH and ORGF are Prop2 specials.
  • RossHRossH Posts: 5,462
    ersmith wrote: »
    No, the "missing" longword in the original exampe is expected. I think you'll find that the original Spin for P1 behaves this way too. The ORG directive has never inserted anything in memory, it's always just meant "assume that the code after ORG X gets put into a COG at address X somehow, and treat the labels accordingly". ORGH is a very different beast, it means "assume that the code after this point is meant to be in HUB, not COG", and "ORGH X" will insert padding to make sure the address starts at X.

    Well, at least it's consistent! I can't remember using ORG this way on the P1 ... but I am pretty sure I would have been both surprised and annoyed at behaviour like this :(
  • We did not use it this way because there was no executable HUB addressing, and COG execute always started at 0.

    On P2, a COG start can happen at non zero addresses, and a COG can go right into HUBEXEC on start too.

  • RossHRossH Posts: 5,462
    ozpropdev wrote: »
    Instead of
            org      $6            ' force next cog address to be 6
    
    Try
            orgf      $6            ' force next cog address to be 6
    
    

    orgf - "fill to"

    Yes, orgf does it. I don't remember that from my P1 days. Thanks.
Sign In or Register to comment.