2 bytes to word array variable - fastest way


Closed Thread
Results 1 to 16 of 16

Hybrid View

  1. #1
    Join Date
    Feb 2011
    Location
    Michigan, USA
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: 2 bytes to word array variable - fastest way

    Thanks Bert. I see what your getting at. ADRESH was a word.
    I just tried ADRESH as a byte and had an overflow. oops, I missed that one.
    I guess I'll use the temp variable way.

    There is another way I used before:
    adcData[index] = (ADRESH * 256) + ADRESL
    But I would put money on this way is slower than the temp variable way.

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: 2 bytes to word array variable - fastest way

    Hi,
    Have you tried:
    Code:
    adcData.lowbyte[index] = ADRESL
    adcData.lowbyte[index+1] = ADRESH
    Take a look at Melanies writeup, specifically section 5, for further details.

    /Henrik.

  3. #3
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 2 bytes to word array variable - fastest way

    Thanks for clearing that up Henrik. I knew there was a way, and I knew my guess was not correct. While I feel like the highbyte/lowbyte should work, I realize it does not. I feel like this is a shortcoming of PBP, adcdata.lowbyte[index+1] feels like it should be the lowbyte of the next word. Anyone agree or do I not have my mind wrapped around this just yet?

    It seems a little un-intuitive, but who cares, thats how it works.
    Last edited by cncmachineguy; - 8th June 2011 at 14:32. Reason: lexicdys
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: 2 bytes to word array variable - fastest way

    Actually I may have messed that up myself, based on this post I'm not sure it'll do what the OP wanted - to be honest.

    I agree it's a abit unituitive and I'll admit I haven't sat down and looked into what's really happening - until now. Before I go on I'll point out that I suck at ASM so if this is completely wrong then I applogise before hand and hope that whoever knows/understands better will correct me.

    When you declare an array of words PBP 'calculates' the start adress of that array in memory (where in the RAM memory the first byte in the array is located). If, somewhere in your program, you use the LOWBYTE,HIGHBYTE "modifiers" it also calculates where the lowbyte and highbyte of the first word in the array is. Glancing at the .lst file it might look something like this:
    Code:
    '00038 _myArray                        EQU     RAM_START + 01Dh
    '00043 _myArray??LOWBYTE               EQU     _myArray
    '00044 _myArray??HIGHBYTE              EQU     _myArray + 001h
    So all it really knows (and need to know) is where myArray starts. The .LOWBYTE of myArray is at the very same adress as the array starts and .HIGHBYTE is at the next adress. Makes sense.

    Now, let's say we do something like this:
    Code:
    myArray VAR WORD[3]
    myByte VAR BYTE
     
    myVar = myArray[0]
    myVar = myArray[1]
    What's going on here then? We're actually trying to stuff a WORD from the array into our BYTE-sized variable. The code generated looks like this:
    Code:
    movff   _myArray, _myVAR
    movff   _myArray + 00002h, _myVAR
    First it takes the byte at the start adress of the array (which is the low byte of word 0, right) and puts that in our BYTE-variable. Then it takes start-adress of the array, adds 2 to that adress and grabs the byte at that location. This is the third byte in our WORD-array so it's grabbing the low byte of word 1. This is pretty straight forward and intuitive - it simply truncates the word from the array into our byte variable.

    Now,
    Code:
    myVar = myArray.LowByte
    myVar = myArray.HighByte
    The above PBP code compiles:
    Code:
    movff _myArray??LOWBYTE, _myVAR
    movff _myArray??HIGHBYTE, _myVAR
    As we saw above myArray??LOWBYTE is the very same adress as the start of the array so this IS the low byte of the first word. myArray??HIGHBYTE is at the start adress of the array + 1 so we'll get the high byte of the first word. Still OK, what we wanted, and probably what we expected.

    Now lets start indexing into the array.
    Code:
    myVar = myArray.LowByte[0]
    myVar = myArray.HighByte[0]
    This code compiles to:
    Code:
    movff   ((_myArray??LOWBYTE) + (000h)), _myVAR
    movff   ((_myArray??HIGHBYTE) + (000h)), _myVAR
    As you can see this takes the adress of the lowbyte of the first word in the array, adds nothing (zero) to it, gets the byte at that adress and puts it in our byte variable. Then it takes the address of the highbyte of the first word in the array, adds nothing to that and gets the byte at that adress. This is still fine, what we wanted (perhaps) and what we might expect. But now it starts to get interesting.

    Code:
    myVar = myArray.LowByte[1]
    myVar = myArray.HighByte[1]
    From this we might, intuitively, expect to get the low and high byte of the second word the array but the above code compiles to:
    Code:
    movff   ((_myArray??LOWBYTE) + (001h)), _myVAR
    movff   ((_myArray??HIGHBYTE) + (001h)), _myVAR
    So, what's going on here... It takes the adress of the 'lowbyte' (the very first byte in our array, low byte of word 0), adds one to that address and gets the byte at that adress. What we're getting is actually the second byte in the array which is the high byte of the first word (word 0). Then it takes the adress of 'highbyte', adds one to that and gets the byte at that adress which is now the third byte in the array or the low byte of the second word (word 1). Not what one might expect but when you know what goes on under the hood it kind of makes sense.

    And, to illustrate it one more time:
    Code:
    MyVar = myArray.Lowbyte[2]
    myVar = myArray.HighByte[2]
    Intuitively we'd expect to get the low and high byte of the third word but we now know that ain't what's happening because we're telling it to index an array of words byte by byte. We tell it to get the byte at the adress of myArray.Lowbyte+2. myArray.Lowbyte is the very first byte in the array, add two to that and we'll end up the adress of the third byte in the array which is the low byte of word 1 - not word 2 as we intutively might think. And, obviously the same thing happends with myArray.HighByte[2] - it gets 4th byte in the array which is the high byte if word 1.

    What we need to do when working with word-arrays on a byte-by-byte-basis is to index, or step, thru them in steps of 2. Like....
    Code:
    accData VAR WORD[16]
    Index VAR BYTE
     
    For Index = 0 to 16 STEP 2
      accData[Index] = ADRESL 'Low byte  (bytes 0, 2, 4, 6...)
      accData[Index+1] = ADRESH  'High byte  (bytes 1, 3, 5, 7...)
    NEXT
    So, again, I'm not sure my earlier advice is actually going to work. It might work if the word indexed is first but it kind of screws up as we've seen above.

    /Henrik.
    Last edited by HenrikOlsson; - 8th June 2011 at 18:03.

  5. #5
    Join Date
    Feb 2011
    Location
    Michigan, USA
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: 2 bytes to word array variable - fastest way

    Hi Henrik,
    I understand your explanation and thank you. But in your last bit of code
    doesn't it need the ".lowbyte" part?
    Code:
     
    For Index = 0 to 16 STEP 2
      accData.lowbyte[Index] = ADRESL 'Low byte  (bytes 0, 2, 4, 6...)
      accData.lowbyte[Index+1] = ADRESH  'High byte  (bytes 1, 3, 5, 7...)
    NEXT

    This is more intuitive though at the cost of a word variable
    Code:
     
    for index = 0 to 16
      tempword.highbyte = ADRESH
      tempword.lowbyte = ADRESL
      adcdata[index] = tempword
    next
    Mike -
    Last edited by MikeWinston; - 8th June 2011 at 18:31.

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: 2 bytes to word array variable - fastest way

    Yes, you're quite right, otherwise it'll be as in the first example where the indexing is actually word based and we'll get the low byte of all the words instead of the low and high byte. Thanks for pointing that out!

    /Henrik.

    I wish I could edit my post and correct that but the 10 second window for doing that has passed.... :-(

  7. #7
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 2 bytes to word array variable - fastest way

    Again thank you Henrik. Yes knowing what goes on under the hood does make it make sense, But I stand by my statement that this is a shortcomming of PBP. I would almost go so far to call this a work around for word array indexing on a byte level. I think I will add a wish list thread for this. PBP should certainly be able to distinguish the intention. It would be even more intuitive to address it this way:
    Code:
    adcdata[index].lowbyte
    adcdata[index].highbyte
    But knowing is half the battle, again thanks for the very clear explanation.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts