Shop OBEX P1 Docs P2 Docs Learn Events
Any way to force a byte array to start on a long 'border'? — Parallax Forums

Any way to force a byte array to start on a long 'border'?

homosapienhomosapien Posts: 147
edited 2013-07-06 15:56 in Propeller 1
I may be missing the obvious, but I am transferring data from EEPROM to a byte array in long-sized chunks (using longs for faster transfer than byes) using something like:
DAT
  dataBuffer    byte    $0[100]    'buffer for ASCII data

VAR
  long  longsData           'holds length (in longs) of data stream


PUB getIt  | x

  repeat x from 0 to (longsData/4)                                             
    long[@dataBuffer][x] := I2C.Readlong(P_EEPROM_SCL, $A0, EEPROM_ADDR_BASE + x*4)   


Is there any way to force SPIN to make the 'dataBuffer' array start on a long 'border'? (there may be other byte/word sized vars in the DAT section that change the position of the array). Currently I run the program and if the buffer is missing data due to non-long-alignment, I just add byte-sized vars in front of it to even it out. Is there a more elegant method to do this?




I know one can use this syntax to make a byte-sized array be long aligned:
DAT
  byte  long  dataBuffer

But as far as I can tell this syntax seems to make the array use every fourth byte in memory, which I do NOT want due to memory constraints.


Thanks for any input,
Nate

Comments

  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-07-05 11:00
    You may not be able to force a byte array to align with longs, but you can still use bytemove with a long to do what you want.
    bytemove(@array[lidx << 2], @theLong, 4)
    


    Where lidx is the long index used to control the loop. Index 0 would fill bytes 0..3, 1 would fill 4..7, etc. I often use bytemove this way.
  • localrogerlocalroger Posts: 3,451
    edited 2013-07-05 11:05
    As JohnnyMac said, just use a long array and use byte or bytemove to access the contents.
  • homosapienhomosapien Posts: 147
    edited 2013-07-05 11:26
    Unless I am not understanding, it seems that the bytemove would add a bunch of overhead, which I was trying to eliminate by using the longs in the first place. Are you suggesting to bring the long from EEPROM into a long in main memory, then use bytemove to transfer from the long to the byte array?

    After thinking about a bit, I think something like this would do what I want (doing the transfer from EEPROM to byte array as fast as possible), while only using up/wasting 1 long:
    DAT
      dummy0    byte  long    $0      'this byte will be long aligned
      dummy1    byte  $0                'filling the rest of the long
      dummy2    byte  $0
      dummy3    byte  $0
      dataBuffer  byte    $0[200]          'the byte array, starting where I want it and as long as these 5 lines of code are not interrupted, it will always be so
    

    No?
  • localrogerlocalroger Posts: 3,451
    edited 2013-07-05 11:38
    Actually, if your byte array is in a DAT block all you have to do is place it immediately following an aligned Long and it will be long-aligned. The compiler groups VARs together by type but DAT leaves them in the order you declare them.
  • homosapienhomosapien Posts: 147
    edited 2013-07-05 11:56
    This is one can of worms I kind of wished I didn't open...haha

    I usually use the VAR sections to define my (global) variables. It is my understanding that the the variables from a VAR section and a DAT section are the same except:

    1) You can seed the vars in the DAT section.

    2) DAT variables are shared among all instances of the object that defines them.

    3) Apparently, the compiler does what you said WRT to the ordering in memory.

    4) It is impossible to know for sure where in main memory any VAR or DAT variable will be located until the program is compiled. Then, if you know where one IN THE DAT sections is, you could count up/down to find the location of any other variable IN THE SAME DAT section.

    5) ANY variable in the VAR section would need to be located using the @ sign, even after compiling.

    Is this pretty much it?


    So, I think you are saying I could do something like this (and save a little typing over what I had before):

    DAT
      dummy0  long  long  $0            'get a long long-aligned
      dataBuffer  byte  $0[200]          'as long (bad pun) as this follows, it will be long aligned also
    
    

    I am just wondering, as the Propeller Tool that I am using is turning the screen a different shade of green at the 'l' of the second long, as if it thinks this is a new DAT section... It may be a glitch, I'll see if it complies and runs...


    Nate
  • localrogerlocalroger Posts: 3,451
    edited 2013-07-05 12:13
    You don't need the "long long," just "dummy0 long 0." Longs are always long aligned unless you use "byte long" to tell Spin that's not necessary.

    For that matter the first byte of each DAT section is guaranteed to be long-aligned, so if your byte array is the first thing after a DAT it should be aligned.

    While VARs are separated by type, within each type I think they are arranged in memory in the order they are declared, so within a type you should be able to use @ to locate the first of a group of named vars and then calculate where the others are from that.
  • homosapienhomosapien Posts: 147
    edited 2013-07-05 12:27
    Great info, thanks for all the help.

    Nate
  • AribaAriba Posts: 2,690
    edited 2013-07-05 12:41
    It's even simpler. In a DAT section you can force long alignement with just the word "long" without any values or labels. The follwing data line will be long aligned:
    DAT
                long
    dataBuffer  byte  $0[200]   'will be long aligned
    

    Andy
  • cavelambcavelamb Posts: 720
    edited 2013-07-06 00:11
    Ariba wrote: »
    It's even simpler. In a DAT section you can force long alignement with just the word "long" without any values or labels. The follwing data line will be long aligned:
    DAT
                long
    dataBuffer  byte  $0[200]   'will be long aligned
    

    Andy

    Would that also work with WORD for word alignment?
    (Assuming a bunch of bytes had been declared)
  • kuronekokuroneko Posts: 3,623
    edited 2013-07-06 00:58
    cavelamb wrote: »
    Would that also work with WORD for word alignment?
    Certainly.

    That said, the byte array could also be specified as a word/long array (forced alignment) and the elements then accessed as label.byte[idx] (byte elements).
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-07-06 15:56
    Another way to long align bytes in a DAT section is to use the "org" statement.
    DAT
        org
    byteArray    byte 0[ARRAY_SIZE]
    
Sign In or Register to comment.