Shop OBEX P1 Docs P2 Docs Learn Events
Need Help Understanding ORG Directive — Parallax Forums

Need Help Understanding ORG Directive

Hey y'all,

I'm working on a serial interface program for my Propeller 2 chip. ORG seems like a really simple directive, but lately I've become confused on how to use it properly. For my PASM2 program, I want to store the program data in general purpose RAM in cog 0. In my mind you would simply write "ORG $000" at the beginning of the program code.

However, when I write "ORG $000" in my program, the assembler places the program code at $000 in HUB RAM. I find this confusing because I thought only ORGH could be used to put code/data in HUB RAM.

Additionally, now that I have my serial interface program written, I'd like to store some strings in cog 0's LUT RAM to be used for command recognition and interface responses. At the end of the file containing my program code, I write "ORG $210" and then use the BYTE directive to declare the strings in memory. This only stores the strings immediately after my program data in HUB RAM... Not at address $210 in LUT RAM.

So, my main questions are:
1. Why does ORG store my code in HUB RAM and not general purpose RAM of cog 0?
2. Can I use ORG to store data in LUT RAM or do I need to write PASM2 code to manually load LUT RAM with the data I want?
3. If you can use ORG to store data in LUT RAM, is ORG $200-$3FF the proper way to do so?
4. Can you use ORG more than once in a single PASM2 program file to store different parts of a program in different sections of memory? For example:
ORG $000
' All of my
' cool serial
' interface code.

ORG $210
BYTE 3,"RUN"
BYTE 4,"STOP"
BYTE 4,"LIST"
BYTE 4,"JOBS"
etc.

BTW, I'm using the official Propeller Tool program to view the memory space of my PASM2 programs. That's how I found out all my code was being loaded into HUB RAM. I later verified this when I wrote code to search for my data strings in LUT RAM and found out they were not present. I hope I'm not just misinterpreting the memory map... :#

Sorry for the long post! Any help would be greatly appreciated.

-BeeKing

Comments

  • I can feel your pain, sadly ORG (and ORGH) do not what you think they do.

    ORG xx
    gives the assembler the information to CODE the assembly instructions AS IF they where at that location, BUT does not put them there in the memory map.

    so ORG xx does just make sense if you relocate that code to that memory location in software at startup.

    ORGH is even weirder if using SPIN. Pure PASM without Spin is somehow usable when you need to create your own memory map.

    But Spin will give you a headache it is full relocate-able and you will have a hard time to find or define fixed addresses for anything in the memory map.

    Mike

  • evanhevanh Posts: 16,031
    edited 2022-10-26 08:56

    Mike's right. I'll just add that ORG is behaving as ORG has for all assemblers through history. It's not immediately intuitive and everyone seems to go through the same learning steps on this. ORG doesn't do anything to build a memory map but rather just informs the assembler where you're intending to use that code.

    In pure Pasm2 mode, the assembler builds a file to be loaded into hubRAM starting from address 0. ORGH can therefore be used to build a hubRAM memory map of sorts as the assembler fills out the file in accordance with the ORGH directives.

    ORGH is unique to the Propeller2.

    With the Propellers, the COGINIT instruction conveniently block copies to cogRAM, so a crafted copy routine to suit an ORG isn't needed as it would be for other architectures.

  • wasn't that ORGF filling the gap not ORGH where you need to patch the area in between ORGH's with zero bytes or so?

    Mike

  • I see. Thanks for the input. COGINIT is a good tip. Can I simply write "COGINIT #0, $000" at the beginning of my program to take advantage of this feature?

    I guess going forward I won't have to specify an address with the ORG directive...

  • evanhevanh Posts: 16,031

    @msrobots said:
    wasn't that ORGF filling the gap not ORGH where you need to patch the area in between ORGH's with zero bytes or so?

    Yes, ORGF fills, as does ORGH, but ORGF is for cog space so is applied an ORG block. Here's the full lists of directives from the "instructions.txt" file.

        ORGH    {hub_address}
        Set hub mode and an optional address to fill to with $00 bytes.
    
        ORG     {cog_address {,cog_address_limit}}
        Set cog mode with optional cog address and limit. Defaults to $000,$200.
        If $200..$3FF used for cog address, LUT range selected. Doesn't generate
        any data.
    
        ORGF    cog_address
        Fill to cog_address with $00 bytes. Must be in cog mode.
    
        RES     {cog_registers}
        Reserve cog registers. Defaults to 1. Doesn't generate any data. Must be
        in cog mode.
    
        FIT     {cog_address}
        Make sure cog code fits within cog address.
    
        ALIGNW/ALIGNL
        Align to next word/long in hub. Must be in hub mode.
    
  • evanhevanh Posts: 16,031
    edited 2022-10-27 06:35

    @BeeKing said:
    I see. Thanks for the input. COGINIT is a good tip. Can I simply write "COGINIT #0, $000" at the beginning of my program to take advantage of this feature?

    No need, the loader does exactly that to start your program.

    I guess going forward I won't have to specify an address with the ORG directive...

    True, in Prop2 architecture, it's pretty rare case to specify any address since COGINIT starts from cogRAM address 0. The most common case for specifying an address would be for pre-loading a selection of small functions into different places in a cog then calling them as needed. Like a mini optimised overlay mechanism that uses hubRAM as rapid retrieval of lots of tight loops.

  • Say I wanted the loader to start cog 0 in HUB RAM execution mode instead. How would I command the loader to do that? Would I just make a call to a program that resides in HUB RAM like you mentioned above?

    As for my data strings, I'm assuming I'll need to write code to manually load them into the LUT? Not hard to do, I just want to make sure I'm understanding the circumstances correctly.

    >

    I guess going forward I won't have to specify an address with the ORG directive...

    True, in Prop2 architecture, it's pretty rare case to specify any address since COGINIT starts from cogRAM address 0. The most common case for specifying an address would be for pre-loading a selection of small functions into different places in a cog then calling them as needed. Like a mini optimised overlay mechanism that uses hubRAM as rapid retrieval of lots of tight loops.

    I'm a little confused here. How does specifying an address for ORG help in this case since the loader isn't placing code at the specified ORG address? Does the benefit come from the assembler checking to making sure the functions would fit within COG RAM?

  • evanhevanh Posts: 16,031

    Looking around, I see my original pasm-only testing wrapper uses it for loading the support code into lutRAM. COGINIT doesn't touch lutRAM so, yes, that is a good example of where ORG is useful.

    Here's a cut'n'paste hack up of that source:

  • Thank you both for your help! This thread has explained a lot.

  • evanhevanh Posts: 16,031

    Cool.

Sign In or Register to comment.