Can I pass arrays to assembly?
swampie777
Posts: 33
{{ 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
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:
Thanks for your patience
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