Shop OBEX P1 Docs P2 Docs Learn Events
Code Issue - Method vs. "Main" — Parallax Forums

Code Issue - Method vs. "Main"

Jon KeinathJon Keinath Posts: 146
edited 2012-07-10 21:21 in Propeller 1
I'm having an issue moving some of my code from my "main" method do a sub method. If I do everything in the main method it works as I would expect. The "main" structure is below:
DAT
   lH byte %10001, %10001, %10001, %11111, %10001, %10001, %10001, %00000
VAR
   long x[8]
   long x0, x1, x2, x3, x4, x5, x6, x7
PUB go
  x0 := ((lH[0] & |<0)<<0)+((lH[0] & |<1)<<2)+((lH[0] & |<2)<<4)+((lH[0] & |<3)<<6)+((lH[0] & |<4)<<8) 
  x1 := ((lH[1] & |<0)<<0)+((lH[1] & |<1)<<2)+((lH[1] & |<2)<<4)+((lH[1] & |<3)<<6)+((lH[1] & |<4)<<8)
  x2 := ((lH[2] & |<0)<<0)+((lH[2] & |<1)<<2)+((lH[2] & |<2)<<4)+((lH[2] & |<3)<<6)+((lH[2] & |<4)<<8)
  x3 := ((lH[3] & |<0)<<0)+((lH[3] & |<1)<<2)+((lH[3] & |<2)<<4)+((lH[3] & |<3)<<6)+((lH[3] & |<4)<<8)
  x4 := ((lH[4] & |<0)<<0)+((lH[4] & |<1)<<2)+((lH[4] & |<2)<<4)+((lH[4] & |<3)<<6)+((lH[4] & |<4)<<8)
  x5 := ((lH[5] & |<0)<<0)+((lH[5] & |<1)<<2)+((lH[5] & |<2)<<4)+((lH[5] & |<3)<<6)+((lH[5] & |<4)<<8)
  x6 := ((lH[6] & |<0)<<0)+((lH[6] & |<1)<<2)+((lH[6] & |<2)<<4)+((lH[6] & |<3)<<6)+((lH[6] & |<4)<<8)
  x7 := ((lH[7] & |<0)<<0)+((lH[7] & |<1)<<2)+((lH[7] & |<2)<<4)+((lH[7] & |<3)<<6)+((lH[7] & |<4)<<8) 

If I use the following program structure the outputs in x0 through x7 are not what I would expect.
PUB go
  convert(lH)

PUB convert(letter)
  x0 := (((letter[0] & |<0)<<0)+((letter[0] & |<1)<<2)+((letter[0] & |<2)<<4)+((letter[0] & |<3)<<6)+((letter[0] & |<4)<<8))
  x1 := (((letter[1] & |<0)<<0)+((letter[1] & |<1)<<2)+((letter[1] & |<2)<<4)+((letter[1] & |<3)<<6)+((letter[1] & |<4)<<8))
  x2 := (((letter[2] & |<0)<<0)+((letter[2] & |<1)<<2)+((letter[2] & |<2)<<4)+((letter[2] & |<3)<<6)+((letter[2] & |<4)<<8))
  x3 := (((letter[3] & |<0)<<0)+((letter[3] & |<1)<<2)+((letter[3] & |<2)<<4)+((letter[3] & |<3)<<6)+((letter[3] & |<4)<<8))
  x4 := (((letter[4] & |<0)<<0)+((letter[4] & |<1)<<2)+((letter[4] & |<2)<<4)+((letter[4] & |<3)<<6)+((letter[4] & |<4)<<8))
  x5 := (((letter[5] & |<0)<<0)+((letter[5] & |<1)<<2)+((letter[5] & |<2)<<4)+((letter[5] & |<3)<<6)+((letter[5] & |<4)<<8))
  x6 := (((letter[6] & |<0)<<0)+((letter[6] & |<1)<<2)+((letter[6] & |<2)<<4)+((letter[6] & |<3)<<6)+((letter[6] & |<4)<<8))
  x7 := (((letter[7] & |<0)<<0)+((letter[7] & |<1)<<2)+((letter[7] & |<2)<<4)+((letter[7] & |<3)<<6)+((letter[7] & |<4)<<8)) 

A separate PUB (and COG) takes the values in x0 through x7 and displays them on a matrix led board. For some reason x0 is correct in both instances but the remainder of the x terms are incorrect.

Any suggestions?

Comments

  • LawsonLawson Posts: 870
    edited 2012-07-09 16:58
    The first error I can see is that the second code is trying to pass an array as an argument. Spin doesn't support this, so only the first value of the letter array is passed into the code. Use "convert(@LH)" to pass a pointer to the array. Then use "BYTE[letter][0]" to access the array inside the method.

    Lawson
  • Jon KeinathJon Keinath Posts: 146
    edited 2012-07-09 17:07
    That worked great. Thanks!
  • kuronekokuroneko Posts: 3,623
    edited 2012-07-09 17:28
    Have you considered using a lookup table? Given the nature of this conversion it seems like a good idea, e.g.:
    PUB convert(addr) : n
    
      repeat 8
        x0[n++] := table[byte[addr][n]]          ' treat x0..x7 like an array, i.e. x0[8]
    
    DAT
    
    table   word     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15
            word    16, 17, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
    
    The table has to be filled with the expected bit patterns of course.
  • AribaAriba Posts: 2,690
    edited 2012-07-09 17:30
    You can also do the conversion with two loops:
    PUB convert(letter) : i | b
      repeat i from 0 to 7
        x0[i] := 0
        repeat b from 0 to 4
          x0[i] += (byte[letter][i] & |<b)<<(b*2)
    

    Andy
  • cavelambcavelamb Posts: 720
    edited 2012-07-09 22:48
    kuroneko wrote: »
    Have you considered using a lookup table? Given the nature of this conversion it seems like a good idea, e.g.:
    PUB convert(addr) : n
    
      repeat 8
        x0[n++] := table[byte[addr][n]]          ' treat x0..x7 like an array, i.e. x0[8]
    
    DAT
    
    table   word     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15
            word    16, 17, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
    
    The table has to be filled with the expected bit patterns of course.

    I think I almost understand that, kuro.

    All except the x0[n++].

    We are moving bytes into longs, right?
    One byte into each long?

    Is that how it reads?
  • kuronekokuroneko Posts: 3,623
    edited 2012-07-09 22:57
    cavelamb wrote: »
    All except the x0[n++].

    We are moving bytes into longs, right?
    One byte into each long?
    table is a word array, so anything of the form table[expr] returns a word. What we get are bytes from a character definition (byte[addr][n], assumed 0..31) which we use as a table index. Now this is assigned to the longs x0..x7. Provided their order in memory is not disturbed we can access them as an array based on x0, e.g. x0[5] would be x5.

    So what happends is we read a byte from the character definition, transform that into a word (table access) and assign it to a long. Does that make sense?

    n is an alias for result which starts at zero.
  • cavelambcavelamb Posts: 720
    edited 2012-07-10 12:12
    kuroneko wrote: »
    table is a word array, so anything of the form table[expr] returns a word. What we get are bytes from a character definition (byte[addr][n], assumed 0..31) which we use as a table index. Now this is assigned to the longs x0..x7. Provided their order in memory is not disturbed we can access them as an array based on x0, e.g. x0[5] would be x5.

    So what happend is we read a byte from the character definition, transform that into a word (table access) and assign it to a long. Does that make sense?

    n is an alias for result which starts at zero.


    Yes sir, although I skipped over the intermediate word conversion.
    Thank you.

    It was the :n in the PUB declaration that I am lacking.

    That colon shows up in Ariba's Convert pub also.
    PUB convert(letter) : i | b

    I have not seen that before.

    Richard
  • msrobotsmsrobots Posts: 3,709
    edited 2012-07-10 21:21
    cavelamb,

    the colon is another trick of spin.

    You can RETURN a value from your spin-method. lets say RETURN 10 or RETURN VarName. But you also can us a implicit existing variable named RESULT. So instead of RETURN 10 you can write RESULT:=10.

    and if you do not like the name RESULT for that implicit existing variable wich gets returned you can RENAME it.

    and that does that colon after the Method-name

    so

    PUB test | myvar
    myvar:=10
    RETURN myVar

    is the same as

    PUB test | myVar
    RESULT:=myVar

    is the same as

    PUB test : myReturn | myVar
    myVar:=10
    myReturn:=myVar


    And in opposite to all your local variables like myVar (wich are NOT initialized) RESULT is inirtialized as 0.

    Enjoy!

    Mike
Sign In or Register to comment.