Shop OBEX P1 Docs P2 Docs Learn Events
Can I pass arrays to assembly? — Parallax Forums

Can I pass arrays to assembly?

swampie777swampie777 Posts: 33
edited 2009-05-29 18:25 in Propeller 1
{{ dual-pulse-read.spin }}

CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

VAR
        long stack[noparse][[/noparse]72]
        
        long xxx1
        long iii
        long Idx
        long xsum
        long iii2
        long xsum2
        long Cog  
        
OBJ
  Num   :       "Numbers"
  TV    :       "TV_Terminal"

  
PUB Main
  xxx1[noparse][[/noparse]0] := 0
  iii  := 0
  xsum := 0

  xxx1  := 0
  iii2  := 0
  xsum2 := 0


Num.Init              'Initialize Numbers   
TV.Start(12)          'Start TV Terminal

 Cog := cognew(@pulse_,@xxx1)
 TV.Str(Num.ToStr(Cog, Num#DDEC))
 TV.Out(13)   
          repeat while Idx < 10
  
           xxx1 := -1
           
            repeat  while xxx1 == -1                              
            xsum := xsum + xxx1
             TV.Str(Num.ToStr(xxx1[noparse][[/noparse]0], Num#DDEC))
             TV.Str(Num.ToStr(xsum/(Idx+1), Num#DDEC))                                                      
             TV.Out(13)
             TV.Str(Num.ToStr(xxx1, Num#DDEC))
             TV.Str(Num.ToStr(xsum2/(Idx+1), Num#DDEC))                                                      
             TV.Out(13)

             Idx++
           TV.Str(string(" 11 "))
           TV.Out(13)
         
DAT
pulse_                  org        0                                                                           
:loop                   waitpeq   zero,mask
                        waitpne   zero,mask
                        mov       xx1, cnt
                        waitpeq   zero,mask
                        mov       yy1, cnt
                        sub       yy1, xx1
                        wrlong    yy1, PAR                                                         
                        waitpeq   zero,mask2
                        waitpne   zero,mask2
                        mov       xx2, cnt
                        waitpeq   zero,mask2
                        mov       yy2, cnt
                        sub       yy2, xx2
                        wrlong    yy2,(PAR+4)
                        jmp       #pulse_

zero           long    0
mask           long    |<25
xx1            res     1 
yy1            res     1 
Mem            res     1
lll            long    0
mask2          long    |<24
xx2            res     1 
yy2            res     1 




Yeah I know you've seen this before( I don't give up easy). I can get the first variable in the array to pass but the second one gets lost in the shuffle. When I tried this with two variables, well you can't pass two variables with one PAR and get the SPIN side to go along with it. The (PAR + 4) ( a C language trick) does not cause the compiler to barf, but the info fails to pass as well.

Any help is appreciated.

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-29 17:41
    You have to copy the content of PAR register and really add 4 to the content. What you did is adding 4 to the adress of PAR. So you wrote to the adress that the 4th register after PAR pointed to. Got the differnece?

    Ehm ... and you did not learn your lesson! Don't mix long and res in the DAT section. First long, then res!

    Would look like this:
    pulse_ org 0
         add    parplus4, par
    ....
    
         wrlong yy2, parplus4
    
    ....
    
    
    mask2      long |<24
    parplus4   long 4
    ' here come all the res
    ....
    
  • swampie777swampie777 Posts: 33
    edited 2009-05-29 18:13
    I thought PAR was the address of the array xxx1[noparse][[/noparse]0] which I passed to it. When I pass an address of an array, is the array just mapped to consecutive 32 bit registers? In C if you pass an address, the address to the next variable in an array is the length in bytes plus the original address. Is that not how propeller chips work.?

    Thanks for your patience
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-29 18:25
    Nope ... PAR itself is a replacement of a adress. It's an COG-RAM-adress somewhere around $49x ... dunno x without looking up ;o)

    If you call a PASM routine, the cognew command will copy whatever you have as second parameter to the COG RAM register at adress $49x. If you pass a 10 you will find a 10 there. If you pass the adress of a variable (which you did in your code) then you find the adress of that variable in PAR-register.
    The instruction rdlong x, PAR expects a register as second parameter which holds an adress and then uses this adress for the read - same for wrlong.

    So, in your first wrlong everything is fine. But in the second wrlong you add 4 to PAR itself, which is equal to the adress $49x+4, so your wrlong wants to find the adress in ($49x+4). That's the adress of an OUTB or INB register ... again ... would need to look that up.

    So, now that you know that PAR is equal to a register adress in COG-RAM that holds the HUB-RAM-adress (because you used @var in cognew), I think it's clear what I do in my code correction. Copy content of PAR to another register (as we need again PAR in the next loop) ... ehmmm ... OK, actually I do the copy and add in one step.

    PS:·And yes, you are right. A long array in HUB-RAM will be arranged in a row and you can access each element by ADRESS of the first element + 4*number of element you want starting from 0.
    But be aware that this is not true for COG-RAM. HUB-RAM adresses are byte-adresses, COG-RAM adresses are long-adresses. So, if you have an array of longs inside of the COG you don't multiply by 4.

    Post Edited (MagIO2) : 5/29/2009 6:33:59 PM GMT
Sign In or Register to comment.