Shop OBEX P1 Docs P2 Docs Learn Events
Trying to shift bits — Parallax Forums

Trying to shift bits

Chuck MintonChuck Minton Posts: 45
edited 2010-11-23 13:58 in Propeller 1
I am missing something here. I am trying to understand how to shift information in a table.
the data reads out... it just won't shift.

appreciate the help.
/Chuck

Comments

  • kwinnkwinn Posts: 8,697
    edited 2010-11-21 09:51
    Chuck, you should include the objects along with your code as an archive so we have everything needed to test your program.

    At a guess, it seems like you are expecting the "TEST1:= TEST1 >> 8" statement to shift the entire byte array and it is only shifting the data in the first byte. Put a character in the first byte and see if it ends up as 0 to verify this.
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-11-21 10:28
    As Kwinn already said, it looks like you missunderstood the shift instruction. The shift instruction only works at maximum on one native memory location which for a 32 bit processor is a long.

    Maybe you should better tell us what the goal of your program is, what data does it read ...

    test1[ 4 ] looks strange as well because the 4th byte of a long has the index 3.

    For reading 10 bytes into a buffer you could also use an index-variable and increase or decrease it - depending on the direction you want to use for writing:

    idx := 0
    repeat 10
    test1[ idx++ ] := DISPLAY.WAITBYTE

    or

    idx := 9
    repeat 10
    test1[ idx-- ] := DISPLAY.WAITBYTE
  • Chuck MintonChuck Minton Posts: 45
    edited 2010-11-21 10:49
    kwinn wrote: »
    Chuck, you should include the objects along with your code as an archive so we have everything needed to test your program.

    At a guess, it seems like you are expecting the "TEST1:= TEST1 >> 8" statement to shift the entire byte array and it is only shifting the data in the first byte. Put a character in the first byte and see if it ends up as 0 to verify this.

    Hi Kwinn,
    I did not post all the files 'cause it is a lot and I am not a very eloquent : Just trying to get to the core of my problem. ( I tried your suggestion of putting a value in the table: I put $FF into TEST1[1]. The data you see here in TEST1[4] is being read from a input sending a packet. In the past I have done what I call "Back Stacking" where:
    t[5]=t[4]
    t[4]:=t[3]
    t[3]:=t[2]
    t[2]:=t[1].......
    this builds data bytes into words or longs.
    I am trying to learn how to use tables or arrays instead of the long drawn out method I use now.
    You can see the $FF I put into the DAT : TEST[1] AND the read byte at TEST[4].
    Here is the data I get at PST: MY COMMENTS TO RIGHT.

    THE problem is I don't see a shift. (I also tried it as a VARIABLE TEST[10], with same result.

    0 255 0 0 128 0 0 0 0 0 ' FIRST TIME THROUGH : BYTE PLACED AT TEST[4]
    0 255 0 0 1 0 0 0 0 0 'SECOND READ: I EXPECT 128 TO SHIFT LEFT AND 1 @ TEST[4]
    0 255 0 0 5 0 0 0 0 0
    0 255 0 0 85 0 0 0 0 0
    0 255 0 0 132 0 0 0 0 0


    HERE IS TXT VERSION OF CODE : WITH SOME COMMENTS
    REPEAT
    REPEAT 10

    TEST1[4]:=DISPLAY.WAITBYTE 'READ IN BYTE OF PACKET DATA FROM DISPLAY
    REPEAT W FROM 0 TO 9 ' LOOP THROUGH THE TEST[W] ARRAY
    DEBUG.DEC(TEST1[W]) ' SEND BYTE OF ARRAY TEST[W] TO DISPLAY
    DEBUG.CHAR(32) ' INSERT A SPACE
    DEBUG.CHAR(13) ' CR TO DISPLAY

    TEST1:= TEST1 >> 8 ' THIS IS WHERE I AM TRYING TO SHIFT DATA

    DEBUG.CHAR(13) ' CR TO DISPLAY , THEN GET NEXT BYTE OF PACKET

    I can include extra progs if you really need.

    thanks
    Chuck
  • Chuck MintonChuck Minton Posts: 45
    edited 2010-11-21 10:55
    MagIO2 wrote: »
    As Kwinn already said, it looks like you missunderstood the shift instruction. The shift instruction only works at maximum on one native memory location which for a 32 bit processor is a long.

    Maybe you should better tell us what the goal of your program is, what data does it read ...

    test1[ 4 ] looks strange as well because the 4th byte of a long has the index 3.

    For reading 10 bytes into a buffer you could also use an index-variable and increase or decrease it - depending on the direction you want to use for writing:

    idx := 0
    repeat 10
    test1[ idx++ ] := DISPLAY.WAITBYTE

    or

    idx := 9
    repeat 10
    test1[ idx-- ] := DISPLAY.WAITBYTE

    I will try this.
    I think you are right. I thought you could stack up a row of data and then shift the entire stack!
    So , what you are saying is , if I wrote bytes into a long, then I could shift them to the extent of the long, but I can not shift bits of bytes stacked up against one-another???
  • kwinnkwinn Posts: 8,697
    edited 2010-11-21 11:24
    I will try this.
    So , what you are saying is , if I wrote bytes into a long, then I could shift them to the extent of the long, but I can not shift bits of bytes stacked up against one-another???
    Yes, this is correct. The spin program is interpreted by a PASM program running in a cog. When you specify a variable as a byte or an array of bytes the shift instruction operates only on the byte specified.

    For instance:

    TEST1[1] := 255
    TEST1[1] := TEST1[1] >> 1 ' TEST1[1] is now 127

    Only the eight bits in the byte at TEST1[1] are shifted right one position. A 0 bit is shifted in to the msb and the lsb is dropped.

    Specifying a shift for an entire array is not valid.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2010-11-22 08:06
    Chuck Minton,

    You can shift sections of memory (bytes in this case) using bytemove.

    bytemove(@test1, @test1 + 1, 9)

    will move nine bytes starting at the second element in the array down one byte so they start at the first element.

    I just tested to make sure you can move bytes on to the same section of memory you are moving them from.

    Duane
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-11-22 09:51
    Right, using bytemove would do the job, but adding or subtracting 1 ten times from an index-variable and write the byte to the place it belongs to should be faster than moving the buffer 10 times.
  • pgbpsupgbpsu Posts: 460
    edited 2010-11-22 12:06
    If Chuck Minton is trying to do "Back Stacking" as he indicated in the earlier post, why not move a large chunk of memory all at once, as Degn suggests with a single bytemove command? That would only leave the first or last element (depending on which direction things are moved) to be filled. That should be significantly faster than doing so in a repeat loop, shouldn't it?

    bytemove(@test1, @test1 + 1, 9)
    test1[9] := newValue
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-11-22 13:03
    I dont remember for sure, but isn't it bytemove (source, destination...)?
    If so you would not want to read into the last byte but into the first.
    Anyway, the original post looks like he wants to shift in the other direction.

    But still moving pointers is more clever than moving memory-blocks.
  • pgbpsupgbpsu Posts: 460
    edited 2010-11-22 16:39
    bytemove is (DestAddress, SrcAddress, Count)

    I may be reading his post incorrectly, but it looks to me like he wants to move things in his array "down":
    t[5]=t[4]
    t[4]:=t[3]
    t[3]:=t[2]
    t[2]:=t[1].......

    Rather than loop he can simply move things down:
    bytemove(@test[1],@test,length-1)
    test[0] := newValue
    

    If that's the wrong direction he can move things "up" by doing:
    bytemove(@test,@test[1],length-1)
    test[length-1]:= newValue
    

    That should work shouldn't it?

    I guess it depends on what he's trying to do. I don't think pointers is what his original post were about. They may be faster, but this seems pretty straight forward.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2010-11-22 19:39
    pgbpsu,

    Now that I reread the original post, I think your first example if correct. I had the buffer moving the wrong direction.

    When I needed to shift a buffer like this I had new data going in towards the end of the buffer and old data taken off the beginning. I finally took someone on this forum's advice (I think it was Phil) and learned how to use a circular buffer. I'm glad I took the time to figure out how to make a circular buffer because it has greatly streamlined my code.

    I still think it's pretty cool that the bytemove command lets you read and write to the same section of memory at once. I originally thought I'd have to move the data to a second location and then move it back to original location in it new shifted position.

    I've been learning PASM lately and really miss all the shortcuts Spin allows.

    Duane
  • pgbpsupgbpsu Posts: 460
    edited 2010-11-23 06:48
    Deng-

    I agree with MagIO that pointers are probably fastest. However I think conceptually this is a bit simpler. Once Chuck gets this working and he wants speed he probably should move to a circular buffer. Although, that decision probably depends a bit on what his program's overall purpose is.

    Learning circular buffers is very worthwhile. I just think doing things the most straight-forward way has benefits as well, especially when one is just learning how things work.

    Using the bytemove was your suggestion and a good one at that. I agree that PASM makes most thing easier than ASM, but it's also worth learning. I'm working on that myself.

    Cheers
  • Chuck MintonChuck Minton Posts: 45
    edited 2010-11-23 13:58
    WOW! THAHKS FOR ALL THE INPUT FOLKS!
    I will need a little direction and clairification on the concept of a circular buffer in the future, however, for the moment, as Kwinn clairified for me, I can shift the bits within a long: It works great and I am able to set pins when I see certain serial sequences pass through... That was my goal.

    Now I have a second problem. I originally was using ParallaxSerialTerminal. Because I was out of cogs, forum suggestions pointed to the PCFullDuplexSerial4FC. I got that going, but now I don't get proper reading from my serial sorces but It sees to transmit well. Most of the time I get the first byte of a long right, then the second and third byte seems to be usually wrong, and the forth byte is always right. I am thinking there must be a timing issue ... why else would PST read right all the time.
    The good part is if I can figure this out, I will be more or less to the completion point of my project... getting so close!
    I tried swithching baud from 115200 to 19200 ( my only options)... That was worse ... could write but would not read it at all.
    So, If any one is up on PCFullDuplexSerial4FC, and what may be causing this how I could tweek it I would appreciate it a whole lot.

    Thanks , also like conceptual info on circular buffer and what that means.
    Chuck
Sign In or Register to comment.