Shop OBEX P1 Docs P2 Docs Learn Events
problem to start the cog at a defined RAM adress — Parallax Forums

problem to start the cog at a defined RAM adress

ImmNekImmNek Posts: 29
edited 2008-09-13 18:51 in Propeller 1
Hi,

please don't worry about my really bad english. I'm a Swiss and I don't mastered the English language yet.

My problem is, that I want to start some assembly code in a cog from a self defined RAM adress using the org statement.

This is a symple code starting at the adress 0:
org     0
'-------------------------------------------------------------------------------
'assembly code entry point
asmEntry            mov     dira,               #$FF
                    mov     asmTime,            cnt
                    add     asmTime,            asmCycles
'-------------------------------------------------------------------------------
'toggle P0...P7
:loop               waitcnt asmTime,            asmCycles
                    xor     outa,               #$FF
                    jmp     #:loop
                    fit
'-------------------------------------------------------------------------------
'constants
asmCycles           long    80_000
'-------------------------------------------------------------------------------
'momory reservation for symbols
asmTime             res     1


This code work properly.

But when I use an ohter RAM address, the code doesn't work:
org     $FF
'-------------------------------------------------------------------------------
'assembly code entry point
asmEntry            mov     dira,               #$FF
                    mov     asmTime,            cnt
                    add     asmTime,            asmCycles
'-------------------------------------------------------------------------------
'toggle P0...P7
:loop               waitcnt asmTime,            asmCycles
                    xor     outa,               #$FF
                    jmp     #:loop
                    fit
'-------------------------------------------------------------------------------
'constants
asmCycles           long    80_000
'-------------------------------------------------------------------------------
'momory reservation for symbols
asmTime             res     1


This code doesn't work. I don't have any idea, why this code doesn't work properly and I realy hope someone can help me.

regards
Immanuel

Comments

  • AleAle Posts: 2,363
    edited 2008-09-09 14:05
    ORG sets the current address pointer to the specified address. It is not useful to set the start point of a COG. The COG will always start to execute at COG RAM address 0, regardless of what you have at that address. If you want to start something at another address as a way to reserve space... use a jmp instruction at address 0 to where your routine is.

    
    PUB start
    
      cognew(@mycogroutimne, 0)
    
    
    DAT
    
       org  ' set address pointer to 0, so symbols can be used (they will be COG addresses)
    
    mycogroutine
       jmp  #echte_routine
    
       long 0, 0, 0, 0  ' reserved space
    
    echte_routine
      < here your code >
    
    
    



    mycogroutine is a symbol with two addresses, one use inside the DAT (that later will be loaded to COG RAM via cognew) and one "public" used in the spin code and accessed via the @ operator. cognew starts to load from mycogroutine into COG RAM at address 0, so it is useful to have a match between the location of the symbols as defined in your program and the real position within COG memory. For that it is important that the address you give cognew is the zero address in what will be your COG program, ORG is useful exactly for that.

    echte_routine has also two addresses, but only one is used here (in the jmp instruction)

    I hope it is clear...

    Post Edited (Ale) : 9/9/2008 2:18:10 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2008-09-09 14:53
    Keep in mind that you can use the space occupied by the JMP instruction for data later in your program. The JMP will only be used when the cog is first started.
  • ImmNekImmNek Posts: 29
    edited 2008-09-09 15:30
    First thanks a lot for this fast answers. Now I understand that the org statement only set the address pointer to the speciefied address. I read in the manual about the org statement, but there it isn't clear what this command do exactly (or I'm an idiot).
    Propeller Manual 1.01 said...

    ORG
    Directive: Adjust compile-time cog address pointer.
    ORG 〈Address〉
    • Address is an optional Cog RAM address (0-495) to assemble the following assembly
    code into. If Address is not given, the value 0 is used.
    Explanation
    The ORG (origin) directive sets the Propeller Tool’s assembly pointer to a new value
    representing the Cog RAM position to use for the following assembly code. ORG typically
    appears at the start of any new assembly code intended for a cog.
    When assembly code is launched into a cog, the cog begins execution at Cog RAM address 0
    so it is critical to assemble at least one instruction for that position. Usually an entire
    assembly program begins at location 0. For example:

    DAT
    ORG 0
    Toggle mov dira, Pin
    :Loop mov outa, Pin
    mov outa, #0
    jmp #:Loop

    The ORG statement in this example sets the assembly pointer to zero (0), so the next
    instruction, mov dira, Pin, is assembled into Cog RAM location 0, the instruction after that
    is assembled into Cog RAM location 1, etc.

    As Ale guessed I want to use some space in the RAM for data. In Ale's code this is done with a jump to the "real" routine. I hope I'm right, when I think, that the first 4 bytes in the cog RAM are used for the jmp command. Then you reserve 4 longs (16 bytes) for data and initialize this longs with 0, is this right? The "real" (in German: echte) routine is placed after this 4 longs and you jump directly to this routine. I hope I understood it correct, please tell me, if I understood something wrong.

    @Ale: Do you speak German?
  • ImmNekImmNek Posts: 29
    edited 2008-09-09 15:32
    @ Mike Green:
    Thanks a lot for this tip.
  • AleAle Posts: 2,363
    edited 2008-09-09 16:01
    It is as you said, the jm
  • Paul BakerPaul Baker Posts: 6,351
    edited 2008-09-09 16:19
    Another tip is that reserving an array can be done this way:

    LONG 0[noparse][[/noparse] 4 ]

    This reserves 4 longs and initializes them to 0.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

  • OwenSOwenS Posts: 173
    edited 2008-09-09 16:31
    Another tip: Code space can be reused as data. Say you need 16 longs at the start of Cog ram for some purpose, then you could do
    JMP #start
    LONG 0[noparse][[/noparse]15]
    start 'your code here

    Just be aware that the first address will be junk at startup

    (I have actually used this technique myself [noparse]:)[/noparse] )
  • AribaAriba Posts: 2,687
    edited 2008-09-09 17:37
    Because a long 0 is a NOP for the propeller CPU, you can also write:
    LONG 0[noparse][[/noparse]16]
    start 'your code here

    Welcome ImmNek

    I'm glad to see that other Swiss works with the Propeller chip!
    Do you know the German Forum for the Propeller: propellerforum.sps-welt.de/portal.php ?
    And here can you find my tools for the Propeller: www.insonix.ch/propeller

    Andy
  • ImmNekImmNek Posts: 29
    edited 2008-09-10 08:17
    Hi Ariba

    Yes, i know about this forum, but i decided to ask here, because here we have som Ingeneers from Parallax.

    Are you the developer of PASD?
  • AleAle Posts: 2,363
    edited 2008-09-10 08:36
    I do not know about those forums, but avoid mikrocontroller.net, either people there is too pissed off or they are simply not *that* nett wink.gif
  • ImmNekImmNek Posts: 29
    edited 2008-09-10 10:33
    Yes I know, the people on mikrocontroller.net aren't very kind.
    If somebody is a beginner, this forum isn't very helpful.
  • ImmNekImmNek Posts: 29
    edited 2008-09-10 13:09
    Hi on the other side ;-D

    So, I tried to write a assembly code which toggles all IO-pins with a frequency of 1kHz.
    And, as you guess, I didn't it well.

    This is my code:
    CON
        _clkmode = xtal1 + pll16x                           
        _xinfreq = 5_000_000
    
    
    PUB Main
        cognew(@entry, 0)
        
    
    DAT '***************************************************************************
                        org     0
    '-------------------------------------------------------------------------------
    'assembly code entry point
    entry               jmp     #asmRealEntry                       'jump to "real" assymbly code (address is $000)
    '-------------------------------------------------------------------------------
    'some data
                        long    $0000_0000                          'all pins low (address is $004)
                        long    $FFFF_FFFF                          'all pins high (address is $008)
    '-------------------------------------------------------------------------------
    'real routine
    asmRealEntry        mov     asmData,            $008            'get the data from the second long (all bits are 1)             
                        mov     dira,               $008            'set all pins as outputs
                        mov     asmTime,            cnt             'prepare the wait loop
                        add     asmTime,            asmCycles
    '-------------------------------------------------------------------------------
    'toggle P0...P7
    asmToggleLoop       waitcnt asmTime,            asmCycles       'achieve the delay
                        mov     outa,               asmData         'write the data to the output
                        cmp     outa,               $004        wz  'check if the outa register is 0 (all pins low)
            if_z        mov     asmData,            $008            'get the data from the second long (all pins high)
            if_nz       mov     asmData,            $004            'get the data from the first long (all pins low)
                        jmp     #asmToggleLoop
    '-------------------------------------------------------------------------------
    'constants
    asmCycles           long    40_000
    '-------------------------------------------------------------------------------
    'momory reservation for symbols
    asmTime             res     1
    asmData             res     1
    '-------------------------------------------------------------------------------
                        fit
    '-------------------------------------------------------------------------------
    'The signal I want to generate on each IO:
    '                   +-------+       +-------+
    'P0...P31           |       |       |       |
    '               ----+       +-------+       +-------+
    '                   |       1ms     |
    '                   |<------------->|
    '
    'I hope you it's clear what my code should do, but he didn't.
    '*******************************************************************************
    
    



    This code is runing on the Propeller DEMO REF F

    I hope somebody can explain me my mistake in this code.

    Thanks a lot
    Immanuel

    Post Edited (ImmNek) : 9/10/2008 1:21:12 PM GMT
  • ImmNekImmNek Posts: 29
    edited 2008-09-10 13:47
    So, I fixed the bug.

    This code works:
    CON
        _clkmode = xtal1 + pll16x                           
        _xinfreq = 5_000_000
    
        
    PUB Main
        cognew(@entry, 0)
        
    
    DAT '***************************************************************************
                        org     0
    '-------------------------------------------------------------------------------
    'assembly code entry point
    entry               jmp     #asmRealEntry                       'jump to "real" assymbly code
    '-------------------------------------------------------------------------------
    'some data
    data1               long    $0000_0000                          'all pins low
    data2               long    $FFFF_FFFF                          'all pins high
    '-------------------------------------------------------------------------------
    'real routine
    asmRealEntry        mov     asmData,            data2           'get the data from the second long (all bits are 1)             
                        mov     dira,               data2           'set all pins as outputs
                        mov     asmTime,            cnt             'prepare the wait loop
                        add     asmTime,            asmCycles
    '-------------------------------------------------------------------------------
    'toggle P0...P31
    asmToggleLoop       waitcnt asmTime,            asmCycles       'achieve the delay
                        mov     outa,               asmData         'write the data to the output
                        cmp     outa,               data1       wz  'check if the outa register is 0 (all pins low)
            if_z        mov     asmData,            data2           'get the data from the second long (all pins high)
            if_nz       mov     asmData,            data1           'get the data from the first long (all pins low) }}
                        jmp     #asmToggleLoop
    '-------------------------------------------------------------------------------
    'constants
    asmCycles           long    40_000
    '-------------------------------------------------------------------------------
    'momory reservation for symbols
    asmTime             res     1
    asmData             res     1
    '-------------------------------------------------------------------------------
                        fit
    '-------------------------------------------------------------------------------
    'The signal on each IO pin:
    '                   +-------+       +-------+
    'P0...P31           |       |       |       |
    '               ----+       +-------+       +----
    '                   |       1ms     |
    '                   |<------------->|
    '*******************************************************************************
    
    



    What I have done is using labels instead of the addresses from the cog RAM.
    But why doesn't work my code with the direct RAM adresses? Can someone explaine it to me?

    Thanks a lot
    Immanuel

    Post Edited (ImmNek) : 9/10/2008 1:56:26 PM GMT
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-09-10 16:38
    I usually put my code at the beginning of the cog and my data at the end. Is there a good reason for putting data before code and then jumping over it?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."

    - Bjarne Stroustrup
  • mparkmpark Posts: 1,305
    edited 2008-09-10 17:01
    ImmNek,
    The first long (data1) is at address 1, not 4. Addresses in cogs refer to 32-bit cells, not bytes.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Michael Park

    PS, BTW, and FYI:
    To search the forum, use search.parallax.com (do not use the Search button).
    Check out the Propeller Wiki: propeller.wikispaces.com/
  • AribaAriba Posts: 2,687
    edited 2008-09-10 17:20
    Hello ImmNek

    Yes I'm the author of PASD, and I think that would be the right tool for you to test your assembly code.
    You can see what addresses the data1/data2 have and you see also every change in the asmData and outa register (CogRAM Viewer,
    Pin Viewer), if you single step thru the code.
    The included example makes something very similar to your Blink test code.

    Andy
  • ImmNekImmNek Posts: 29
    edited 2008-09-11 05:12
    @mpark:
    Thank you for you answer, I will test ist with the address you told me.
    I thougt the cogRAM is like the hubRAM and the cells refer to bytes (8-bit cells). Now it is clear, why this code toggled the IO's in such a strange way.
    But is it right, that the cells are physical 8-bit cells?

    @Ariba:
    You have done a greate work with PASD and now I'm using this tool.
    But when I using the PASD, I have to insert the debug kernel at the begin of my ASM-code
    and this effects, that my addresses are wrong.
    What I think is a pity in PASD, is that you cant debug selfmodifieing code
    (I guess this is in cause of your debug kernel), because such code is
    very useful.
    But anyway, your tool PASD is a greate software, thanks a lot.
  • AribaAriba Posts: 2,687
    edited 2008-09-11 19:12
    ImmNek

    Yes you can't use the first 12 longs with PASD, but normally one reserve the memory for variables and tables at the end
    of the code anyway.
    PASD is able to debug selfmodifying code, and shows also the modified value at single stepping. You only can not set a Breakpoint
    on an address which will be modified. (Set it one instruction before and make an additional single step).

    The CogRAM is organized as 512 x 32 bits, you can not access single bytes or words direct. For that you have to read the full long
    and extract the byte or word with shifts and masks. Thats why you work normally only with long variables in assembly.

    Andy
  • ImmNekImmNek Posts: 29
    edited 2008-09-13 18:51
    Thanks a lot to all of you for your helpful answers and tips.
Sign In or Register to comment.