News:

;) This forum is the property of Proton software developers

Main Menu

Byte or Word shift

Started by RGV250, Today at 09:04 AM

Previous topic - Next topic

RGV250

Hi,
I think I will need to make a procedure for this but wondered if there was a byte or word equivalent to bit shift left or right.
I would like to load a value into an array and then when I load a new value in it shifts all the previous values left or right.
I could probably do it with indirect addressing (or is it indexed?) but always find that is difficult to keep track of.

Regards,
Bob

RGV250

Hi,
First attempt looks good, I will probably use a loop later. I wonder if there is a more efficient way of doing it.
'  ____/\\\\\\\\\_________/\\\\\\\\\\\\__/\\\________/\\\____/\\\\\\\\\_______/\\\\\\\\\\\\\\\______/\\\\\\\____       
'   __/\\\///////\\\_____/\\\//////////__\/\\\_______\/\\\__/\\\///////\\\____\/\\\///////////_____/\\\/////\\\__       
'    _\/\\\_____\/\\\____/\\\_____________\//\\\______/\\\__\///______\//\\\___\/\\\_______________/\\\____\//\\\_     
'     _\/\\\\\\\\\\\/____\/\\\____/\\\\\\\__\//\\\____/\\\_____________/\\\/____\/\\\\\\\\\\\\_____\/\\\_____\/\\\_     
'      _\/\\\//////\\\____\/\\\___\/////\\\___\//\\\__/\\\___________/\\\//______\////////////\\\___\/\\\_____\/\\\_   
'       _\/\\\____\//\\\___\/\\\_______\/\\\____\//\\\/\\\_________/\\\//____________________\//\\\__\/\\\_____\/\\\_   
'        _\/\\\_____\//\\\__\/\\\_______\/\\\_____\//\\\\\________/\\\/____________/\\\________\/\\\__\//\\\____/\\\__ 
'         _\/\\\______\//\\\_\//\\\\\\\\\\\\/_______\//\\\________/\\\\\\\\\\\\\\\_\//\\\\\\\\\\\\\/____\///\\\\\\\/___
'          _\///________\///___\////////////__________\///________\///////////////___\/////////////________\///////_____

    Include "amicus18.Inc"

    Dim ShiftArray[10] As Byte
    Dim count As Byte
   
    Do
    ShiftLeft(count)
    HSerOutLn [Dec ShiftArray[9]," : ", Dec ShiftArray[8]," : ",Dec ShiftArray[7]," : ",Dec ShiftArray[6]," : ",Dec ShiftArray[5]," : ",Dec ShiftArray[4]," : ",Dec ShiftArray[3]," : ",Dec ShiftArray[2]," : ",Dec ShiftArray[1]," : ",Dec ShiftArray[0]," : ",]       'for testing   
    DelayMS 1000
    Inc count
    Loop
   
Proc ShiftLeft(IndexData As Byte)
    ShiftArray[9] = ShiftArray[8]
    ShiftArray[8] = ShiftArray[7]
    ShiftArray[7] = ShiftArray[6]
    ShiftArray[6] = ShiftArray[5]
    ShiftArray[5] = ShiftArray[4]
    ShiftArray[4] = ShiftArray[3]
    ShiftArray[3] = ShiftArray[2]
    ShiftArray[2] = ShiftArray[1]
    ShiftArray[1] = ShiftArray[0]     
    ShiftArray[0] = IndexData
EndProc   

Regards,
Bob

Stephen Moss

I don't think there is a command for that, the following is some untested psuedo code to show how I would attempt it, first I create boolean value True and False as it can be more readable than using = 0 or = 1.
Then I call the shift procedure pasing it the new value and a boolean value indicating if a right (False) or left (True) shift is required.
Then I copy each element of the array to the next element in a loop with the highest value in the loop based on the Bound of the array before adding the new value to the applicable end of the array.
You could use Select Case (Select LeftShift) instead of If Then to determing the shift direction.

'Create Boolean values for True and False
Dim True as Bit = 1
Dim False as Bit = 0

'Call the Proceedure
Array_Shift(New_Data, True)

'-----  Procedure to shift the data  -----
PROC Array_Shift[New_Array_value as Byte, LeftShift as Bit]

Dim A_shift as Byte

If LeftShift = True then
'--- Shift Left ---
  For A_shift = 1 to Bound ArrayName
    ArrayName[A_shift - 1] = ArrayName[A_shift]
  Next

  ArrayName[A_shift] = New_Array_Value   'Add new value to the right end of the array

Else
'--- Right Shift ---
  For A_shift = (Bound ArrayName - 1) to 0 step -1
    ArrayName[A_shift] = ArrayName[A_shift + 1]
  Next

  ArrayName[A_shift] = New_Array_Value   'Add new value to the left end of the array
EndIf
End Proc

RGV250

Hi Stephen,
That is basically how I planned to do the next version IE with a loop. I am going to keep it simple and have 2 separate procedures rather than a selection.

Regards,
Bob

top204

Your question got me thinking Bob, so I have created a set of procedures to shift Byte, Word, Long, Dword, and Float arrays, left and right, after a value is added to them.

The code listing for the demo is below:
'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' A demonstration of a set of procedures to add a value to an array, and shift it left or right.
'
' Written for the Positron8 compiler by Les Johnson.
'
    Device = 18F25K20                                                   ' Tell the compiler what device to compile for
    Declare Xtal = 64                                                   ' Tell the compiler what frequency the device is operating at (in MHz)
    Declare Float_Display_Type = Fast                                   ' Use the compiler's faster floating point display routine
    Declare Auto_Heap_Arrays = On                                       ' Tell the compiler to create arrays above standard variables, so assembler code is more efficient
    Declare Auto_Heap_Strings = On                                      ' Tell the compiler to create Strings above standard variables, so assembler code is more efficient
    Declare Auto_Variable_Bank_Cross = On                               ' Tell the compiler to create any multi-byte variables in the same RAM bank. For more efficiency
'
' Setup USART1
'
    Declare Hserial_Baud = 9600                                         ' Set the Baud rate to 9600
    Declare HRSOut1_Pin  = PORTC.6                                      ' Set the TX pin
'
' Create Global variables here
'     
    Dim ByteArray[10]  As Byte  
    Dim WordArray[10]  As Word  
    Dim LongArray[10]  As Long 
    Dim DwordArray[10] As Dword
    Dim bIteration     As Byte                                          ' Holds the shift iterations
    Dim wIndex         As Word                                          ' Holds the index of an array
 
'-------------------------------------------------------------------------------------------------------------
' The main program starts here
' Add values, and shift arrays. Then display them on a serial terminal
' Uncomment the code blocks for the array types to demonstrate
'
Main:
    Setup()                                                             ' Setup the program and any peripherals
(*
'
' -------------------- Test the 8-bit Array Left Shift --------------------
'
' Display the unshifted array on a serial terminal
'
    ByteArray = 00, 11, 22, 33, 44, 55, 66, 77, 88, 99 
    HRSOut1Ln "Unshifted Elements"
    HRSOut1 "          "
    For wIndex = 0 To Bound(ByteArray)
        HRSOut1 Dec3 ByteArray[wIndex], ", "
    Next
    HRSOut1Ln 13, "--------------------------------------------------"
    '
    ' Shift the array for the amount of elements in it
    '
    HRSOut1Ln "8-bit Left Shifts..."
    For bIteration = 1 To SizeOf(ByteArray)
        HRSOut1 "Iter ", Dec2 bIteration, " : "
        Array_ShiftLeft8(ByteArray, SizeOf(ByteArray), bIteration)
        '
        ' Display the shifted array on a serial terminal
        '
        For wIndex = 0 To Bound(ByteArray)
            HRSOut1 Dec3 ByteArray[wIndex], ", "
        Next
        HRSOut1 13
    Next
'
' -------------------- Test the 8-bit Array Right Shift --------------------
'
' Display the unshifted array on a serial terminal
'
    ByteArray = 00, 11, 22, 33, 44, 55, 66, 77, 88, 99 
    HRSOut1Ln 13, "Unshifted Elements"
    HRSOut1 "          "
    For wIndex = 0 To Bound(ByteArray)
        HRSOut1 Dec3 ByteArray[wIndex], ", "
    Next
    HRSOut1Ln 13, "--------------------------------------------------"
    '
    ' Shift the array for the amount of elements in it
    '
    HRSOut1Ln "8-bit Right Shifts..."
    For bIteration = 1 To SizeOf(ByteArray)
        HRSOut1 "Iter ", Dec2 bIteration, " : "
        Array_ShiftRight8(ByteArray, SizeOf(ByteArray), bIteration)
        '
        ' Display the shifted array on a serial terminal
        '
        For wIndex = 0 To Bound(ByteArray)
            HRSOut1 Dec3 ByteArray[wIndex], ", "
        Next
        HRSOut1 13
    Next
*)     
'
' -------------------- Test the 16-bit Array Left Shift --------------------
'
' Display the unshifted array on a serial terminal
'
    WordArray = 0000, 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999
    HRSOut1Ln "Unshifted Elements"
    HRSOut1 "          "
    For wIndex = 0 To Bound(WordArray)
        HRSOut1 Dec5 WordArray[wIndex], ", "
    Next
    HRSOut1Ln 13, "--------------------------------------------------"
    '
    ' Shift the array for the amount of elements in it
    '
    HRSOut1Ln "16-bit Left Shifts..."
    For bIteration = 1 To SizeOf(WordArray)
        HRSOut1 "Iter ", Dec2 bIteration, " : "
        Array_ShiftLeft16(WordArray, SizeOf(WordArray), bIteration)
        '
        ' Display the shifted array on a serial terminal
        '
        For wIndex = 0 To Bound(WordArray)
            HRSOut1 Dec5 WordArray[wIndex], ", "
        Next
        HRSOut1 13
    Next
'
' -------------------- Test the 16-bit Array Right Shift --------------------
'
' Display the unshifted array on a serial terminal
'
    WordArray = 0000, 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999
    HRSOut1Ln 13, "Unshifted Elements"
    HRSOut1 "          "
    For wIndex = 0 To Bound(WordArray)
        HRSOut1 Dec5 WordArray[wIndex], ", "
    Next
    HRSOut1Ln 13, "--------------------------------------------------"
    '
    ' Shift the array for the amount of elements in it
    '
    HRSOut1Ln "16-bit Right Shifts..."
    For bIteration = 0 To Bound(WordArray)
        HRSOut1 "Iter ", Dec2 bIteration, " : "
        Array_ShiftRight16(WordArray, SizeOf(WordArray), bIteration)
        '
        ' Display the shifted array on a serial terminal
        '
        For wIndex = 1 To SizeOf(WordArray)
            HRSOut1 Dec5 WordArray[wIndex], ", "
        Next
        HRSOut1 13
    Next
(*
'
' -------------------- Test the 24-bit Array Left Shift --------------------
'
' Display the unshifted array on a serial terminal
'
    LongArray = 00000, 11111, 22222, 33333, 44444, 55555, 66666, 77777, 88888, 99999 
    HRSOut1Ln "Unshifted Elements"
    HRSOut1 "          "
    For wIndex = 0 To Bound(LongArray)
        HRSOut1 Dec5 LongArray[wIndex], ", "
    Next
    HRSOut1Ln 13, "--------------------------------------------------"
    '
    ' Shift the array for the amount of elements in it
    '
    HRSOut1Ln "24-bit Left Shifts..."
    For bIteration = 1 To SizeOf(LongArray)
        HRSOut1 "Iter ", Dec2 bIteration, " : "
        Array_ShiftLeft24(LongArray, SizeOf(LongArray), bIteration)
        '
        ' Display the shifted array on a serial terminal
        '
        For wIndex = 0 To Bound(LongArray)
            HRSOut1 Dec5 LongArray[wIndex], ", "
        Next
        HRSOut1 13
    Next
'
' -------------------- Test the 24-bit Array Right Shift --------------------
'
' Display the unshifted array on a serial terminal
'
    LongArray = 00000, 11111, 22222, 33333, 44444, 55555, 66666, 77777, 88888, 99999
    HRSOut1Ln 13, "Unshifted Elements"
    HRSOut1 "          "
    For wIndex = 0 To Bound(LongArray)
        HRSOut1 Dec5 LongArray[wIndex], ", "
    Next
    HRSOut1Ln 13, "--------------------------------------------------"
    '
    ' Shift the array for the amount of elements in it
    '
    HRSOut1Ln "24-bit Right Shifts..."
    For bIteration = 1 To SizeOf(LongArray)
        HRSOut1 "Iter ", Dec2 bIteration, " : "
        Array_ShiftRight24(LongArray, SizeOf(LongArray), bIteration)
        '
        ' Display the shifted array on a serial terminal
        '
        For wIndex = 0 To Bound(LongArray)
            HRSOut1 Dec5 LongArray[wIndex], ", "
        Next
        HRSOut1 13
    Next
*)
(*
'
' -------------------- Test the 32-bit Array Left Shift --------------------
'
' Display the unshifted array on a serial terminal
'
    DwordArray = 000000, 111111, 222222, 333333, 444444, 555555, 666666, 777777, 888888, 999999  
    HRSOut1Ln "Unshifted Elements"
    HRSOut1 "          "
    For wIndex = 0 To Bound(DwordArray)
        HRSOut1 Dec6 DwordArray[wIndex], ", "
    Next
    HRSOut1Ln 13, "--------------------------------------------------"
    '
    ' Shift the array for the amount of elements in it
    '
    HRSOut1Ln "32-bit Left Shifts..."
    For bIteration = 1 To SizeOf(DwordArray)
        HRSOut1 "Iter ", Dec2 bIteration, " : "
        Array_ShiftLeft32(DwordArray, SizeOf(DwordArray), bIteration)
        '
        ' Display the shifted array on a serial terminal
        '
        For wIndex = 0 To Bound(DwordArray)
            HRSOut1 Dec6 DwordArray[wIndex], ", "
        Next
        HRSOut1 13
    Next
'
' -------------------- Test the 32-bit Array Right Shift --------------------
'
' Display the unshifted array on a serial terminal
'
    DwordArray = 000000, 111111, 222222, 333333, 444444, 555555, 666666, 777777, 888888, 999999 
    HRSOut1Ln 13, "Unshifted Elements"
    HRSOut1 "          "
    For wIndex = 0 To Bound(DwordArray)
        HRSOut1 Dec6 DwordArray[wIndex], ", "
    Next
    HRSOut1Ln 13, "--------------------------------------------------"
    '
    ' Shift the array for the amount of elements in it
    '
    HRSOut1Ln "32-bit Right Shifts..."
    For bIteration = 1 To SizeOf(DwordArray)
        HRSOut1 "Iter ", Dec2 bIteration, " : "
        Array_ShiftRight32(DwordArray, SizeOf(DwordArray), bIteration)
        '
        ' Display the shifted array on a serial terminal
        '
        For wIndex = 0 To Bound(DwordArray)
            HRSOut1 Dec6 DwordArray[wIndex], ", "
        Next
        HRSOut1 13
    Next  
*)  
     
'------------------------------------------------------------------------------------------------
' Left Shift a Byte Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the (up to 8-bit) value to add to the last element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the lowest element is discarded, And pValue is placed in the highest element
'
Proc Array_ShiftLeft8(ByRef pArrayAddr As Word, pSize As Word, pValue As Word)
    Dim bTemp As Byte                                               ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = 0                                               ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Inc wAShift_Index                                           ' Move up an element
        wAShift_wElemAddr = (pArrayAddr + wAShift_Index)            ' Calculate an 8-bit element's RAM address
        bTemp = Ptr8(wAShift_wElemAddr)                             ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr - 1                   ' Move down the array
        Ptr8(wAShift_wElemAddr) = bTemp                             ' Write it back to the array       
    Until wAShift_Index = pSize                                     ' Loop until all the elements have been read/written
    Ptr8(wAShift_wElemAddr + 1) = pValue                            ' Place pValue into the last element
EndProc

'------------------------------------------------------------------------------------------------
' Left Shift a Word Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the (up to 16-Bit) value to add to the last element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the lowest element is discarded, and pValue is placed in the highest element
'
Proc Array_ShiftLeft16(ByRef pArrayAddr As Word, pSize As Word, pValue As Word)
    Dim wTemp As Word                                               ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = 0                                               ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Inc wAShift_Index                                           ' Move up an element
        wAShift_wElemAddr = (pArrayAddr + (wAShift_Index * 2))      ' Calculate a 16-bit element's RAM address
        wTemp = Ptr16(wAShift_wElemAddr)                            ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr - 2                   ' Move down the array
        Ptr16(wAShift_wElemAddr) = wTemp                            ' Write it back to the array        
    Until wAShift_Index = pSize                                     ' Loop until all the elements have been read/written
    Ptr16(wAShift_wElemAddr) = pValue                               ' Place pValue into the last element
EndProc

'------------------------------------------------------------------------------------------------
' Right Shift a Byte Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the (up to 8-Bit) value to add to the first element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the highest element is discarded, and pValue is placed in the lowest element
'
Proc Array_ShiftRight8(ByRef pArrayAddr As Word, pSize As Word, pValue As Byte)
    Dim bTemp As Byte                                               ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = pSize                                           ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Dec wAShift_Index                                           ' Move down an element
        wAShift_wElemAddr = (pArrayAddr + wAShift_Index)            ' Calculate an 8-bit element's RAM address
        bTemp = Ptr8(wAShift_wElemAddr)                             ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr + 1                   ' Move up the array
        Ptr8(wAShift_wElemAddr) = bTemp                             ' Write it back to the array
    Until wAShift_Index = 0                                         ' Loop until all the elements have been read/written
    Ptr8(pArrayAddr) = pValue                                       ' Place pValue into the last element
EndProc
  
'------------------------------------------------------------------------------------------------
' Right Shift a Word Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the (up to 16-Bit) value to add to the first element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the highest element is discarded, and pValue is placed in the lowest element
'
Proc Array_ShiftRight16(ByRef pArrayAddr As Word, pSize As Word, pValue As Word)
    Dim wTemp As Word                                               ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = pSize - 1                                       ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Dec wAShift_Index                                           ' Move down an element
        wAShift_wElemAddr = (pArrayAddr + (wAShift_Index * 2))      ' Calculate a 16-bit element's RAM address
        wTemp = Ptr16(wAShift_wElemAddr)                            ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr + 2                   ' Move up the array
        Ptr16(wAShift_wElemAddr) = wTemp                            ' Write it back to the array
    Until wAShift_Index = 0                                         ' Loop until all the elements have been read/written
    Ptr16(pArrayAddr) = pValue                                      ' Place pValue into the last element
EndProc

'------------------------------------------------------------------------------------------------
' Left Shift a Long Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the (up to 24-Bit) value to add to the last element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the lowest element is discarded, And pValue is placed in the highest element
'
Proc Array_ShiftLeft24(ByRef pArrayAddr As Word, pSize As Word, pValue As Long)
    Dim lTemp As Long                                               ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = 0                                               ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Inc wAShift_Index                                           ' Move up an element
        wAShift_wElemAddr = (pArrayAddr + (wAShift_Index * 3))      ' Calculate a 24-bit element's RAM address
        lTemp = Ptr24(wAShift_wElemAddr)                            ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr - 3                   ' Move down the array
        Ptr24(wAShift_wElemAddr) = lTemp                            ' Write it back to the array         
    Until wAShift_Index = pSize                                     ' Loop until all the elements have been read/written
    Ptr24(wAShift_wElemAddr) = pValue                               ' Place pValue into the last element
EndProc
  
'------------------------------------------------------------------------------------------------
' Right Shift a Long Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the (up to 24-Bit) value to add to the first element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the highest element is discarded, and pValue is placed in the lowest element
'
Proc Array_ShiftRight24(ByRef pArrayAddr As Word, pSize As Word, pValue As Long)
    Dim lTemp As Long                                               ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = pSize - 1                                       ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Dec wAShift_Index                                           ' Move down an element
        wAShift_wElemAddr = (pArrayAddr + (wAShift_Index * 3))      ' Calculate a 24-bit element's RAM address
        lTemp = Ptr24(wAShift_wElemAddr)                            ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr + 3                   ' Move up the array
        Ptr24(wAShift_wElemAddr) = lTemp                            ' Write it back to the array
    Until wAShift_Index = 0                                         ' Loop until all the elements have been read/written
    Ptr24(pArrayAddr) = pValue                                      ' Place pValue into the last element
EndProc

'------------------------------------------------------------------------------------------------
' Left Shift a Dword Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the (up to 32-Bit) value to add to the last element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the lowest element is discarded, And pValue is placed in the highest element
'
Proc Array_ShiftLeft32(ByRef pArrayAddr As Word, pSize As Word, pValue As Dword)
    Dim dTemp As Dword                                              ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = 0                                               ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Inc wAShift_Index                                           ' Move up an element
        wAShift_wElemAddr = (pArrayAddr + (wAShift_Index * 4))      ' Calculate a 32-bit element's RAM address
        dTemp = Ptr32(wAShift_wElemAddr)                            ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr - 4                   ' Move down the array
        Ptr32(wAShift_wElemAddr) = dTemp                            ' Write it back to the array         
    Until wAShift_Index = pSize                                     ' Loop until all the elements have been read/written
    Ptr32(wAShift_wElemAddr) = pValue                               ' Place pValue into the last element
EndProc
  
'------------------------------------------------------------------------------------------------
' Right Shift a Dword Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the (up to 32-Bit) value to add to the first element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the highest element is discarded, and pValue is placed in the lowest element
'
Proc Array_ShiftRight32(ByRef pArrayAddr As Word, pSize As Word, pValue As Dword)
    Dim dTemp As Dword                                              ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = pSize - 1                                       ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Dec wAShift_Index                                           ' Move down an element
        wAShift_wElemAddr = (pArrayAddr + (wAShift_Index * 4))      ' Calculate a 32-bit element's RAM address
        dTemp = Ptr32(wAShift_wElemAddr)                            ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr + 4                   ' Move up the array
        Ptr32(wAShift_wElemAddr) = dTemp                            ' Write it back to the array
    Until wAShift_Index = 0                                         ' Loop until all the elements have been read/written
    Ptr32(pArrayAddr) = pValue                                      ' Place pValue into the last element
EndProc

'------------------------------------------------------------------------------------------------
' Left Shift a Float Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the Floating Point value to add to the last element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the lowest element is discarded, And pValue is placed in the highest element
'
Proc Array_ShiftLeftF(ByRef pArrayAddr As Word, pSize As Word, pValue As Float)
    Dim fTemp As Float                                              ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = 0                                               ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Inc wAShift_Index                                           ' Move up an element
        wAShift_wElemAddr = (pArrayAddr + (wAShift_Index * 4))      ' Calculate a 32-bit element's RAM address
        fTemp = Ptr32(wAShift_wElemAddr)                            ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr - 4                   ' Move down the array
        Ptr32(wAShift_wElemAddr) = fTemp                            ' Write it back to the array         
    Until wAShift_Index = pSize                                     ' Loop until all the elements have been read/written
    Ptr32(wAShift_wElemAddr) = pValue                               ' Place pValue into the last element
EndProc
  
'------------------------------------------------------------------------------------------------
' Right Shift a DWord Array, after adding a value to it
' Input     : pArrayAddr holds the address of the array to shift
'           : pSize hold the size of the array
'           : pValue holds the Floating Point value to add to the first element of the array
' Output    : The address passed in pArrayAddr is shifted left one element
' None      : The value held in the highest element is discarded, and pValue is placed in the lowest element
'
Proc Array_ShiftRightF(ByRef pArrayAddr As Word, pSize As Word, pValue As Float)
    Dim fTemp As Float                                              ' Holds the value of an array's element
Global Dim wAShift_wElemAddr As Word Shared                         ' Holds the address on an array's element
Global Dim wAShift_Index     As Word Shared                         ' Holds the element index of the array
 
    wAShift_Index = pSize - 1                                       ' \ Create a loop for the size of the array to shift
    Repeat                                                          ' /
        Dec wAShift_Index                                           ' Move down an element
        wAShift_wElemAddr = (pArrayAddr + (wAShift_Index * 4))      ' Calculate a 32-bit element's RAM address
        fTemp = Ptr32(wAShift_wElemAddr)                            ' Read an element's value
        wAShift_wElemAddr = wAShift_wElemAddr + 4                   ' Move up the array
        Ptr32(wAShift_wElemAddr) = fTemp                            ' Write it back to the array
    Until wAShift_Index = 0                                         ' Loop until all the elements have been read/written
    Ptr32(pArrayAddr) = pValue                                      ' Place pValue into the last element
EndProc
'------------------------------------------------------------------------------------------------
' Setup the program and any peripherals
' Input     : None
' Output    : None
' Notes     : None
'
Proc Setup()
    Osc_64MHz()                                                         ' Set the microcontroller for internal 64MHz operation
'
' More setup code here
'
EndProc

'------------------------------------------------------------------------------------------------
' Set the microcontroller for internal 64MHz operation
' Input     : None
' Output    : None
' Notes     : For use with a PIC18F25K20 device
'
Proc Osc_64MHz()
    OSCCON = %01110000                                                  ' 16MHz HFINTOSC
    OSCTUNE = %01000000                                                 ' PLL enabled
    DelayMS 100                                                         ' Give time for clock stability
EndProc

'------------------------------------------------------------------------------------------------
' Setup the fuses to use the internal oscillator on a PIC18F25K20 device.
' OSC pins RA6 and RA7 are general purpose I/O.
'
Config_Start
    FOSC = INTIO67                                                      ' Internal oscillator block. General purpose I/O on RA6 and RA7
    FCMEN = Off                                                         ' Fail-Safe Clock Monitor disabled
    IESO = Off                                                          ' Internal/External Oscillator Switchover mode disabled
    PWRT = Off                                                          ' Power-Up Timer disabled
    BOREN = SBORDIS                                                     ' Brown-Out Reset enabled in hardware only (SBOREN is disabled)
    BORV = 18                                                           ' Brown Out Reset Voltage 1.8 V nominal
    WDTEN = Off                                                         ' Watchdog Timer controlled by SWDTEN bit of the WDTCON register
    WDTPS = 128                                                         ' Watchdog Timer Postscale Select 1:128
    CCP2MX = PORTC                                                      ' CCP2 input/output is multiplexed with RC1
    PBADEN = On                                                         ' PORTB<4:0> pins are configured as analogue input channels on Reset
    LPT1OSC = Off                                                       ' Timer1 configured for higher power operation
    HFOFST = On                                                         ' HFINTOSC starts clocking the CPU without waiting for the oscillator to stablise
    MCLRE = On                                                          ' MCLR pin enabled. RE3 input pin disabled
    STVREN = On                                                         ' Stack full/underflow will cause Reset
    LVP = On                                                            ' Single-Supply ICSP enabled
    XINST = Off                                                         ' Extended Instruction Set disabled
    Debug = Off                                                         ' Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
    Cp0 = Off                                                           ' Block 0 (000800-001FFF) not code-protected
    CP1 = Off                                                           ' Block 1 (002000-003FFF) not code-protected
    CP2 = Off                                                           ' Block 2 (004000-005FFF) not code-protected
    CP3 = Off                                                           ' Block 3 (006000-007FFF) not code-protected
    CPB = Off                                                           ' Boot block (000000-0007FF) not code-protected
    CPD = Off                                                           ' Data EEPROM not code-protected
    WRT0 = Off                                                          ' Block 0 (000800-001FFF) not write-protected
    WRT1 = Off                                                          ' Block 1 (002000-003FFF) not write-protected
    WRT2 = Off                                                          ' Block 2 (004000-005FFF) not write-protected
    WRT3 = Off                                                          ' Block 3 (006000-007FFF) not write-protected
    WRTC = Off                                                          ' Configuration registers (300000-3000FF) not write-protected
    WRTB = Off                                                          ' Boot Block (000000-0007FF) not write-protected
    WRTD = Off                                                          ' Data EEPROM not write-protected
    EBTR0 = Off                                                         ' Block 0 (000800-001FFF) not protected from table reads executed in other blocks
    EBTR1 = Off                                                         ' Block 1 (002000-003FFF) not protected from table reads executed in other blocks
    EBTR2 = Off                                                         ' Block 2 (004000-005FFF) not protected from table reads executed in other blocks
    EBTR3 = Off                                                         ' Block 3 (006000-007FFF) not protected from table reads executed in other blocks
    EBTRB = Off                                                         ' Boot Block (000000-0007FF) not protected from table reads executed in other blocks
Config_End

Uncomment a block in the 'Main:' section, to see the different array shifts working.

It will operate on enhanced 14-bit core devices, and 18F devices.

The demo 'as it stands' will transmit the text below, to a serial terminal:

Unshifted Elements
          00000, 01111, 02222, 03333, 04444, 05555, 06666, 07777, 08888, 09999,
--------------------------------------------------
16-bit Left Shifts...
Iter 01 : 01111, 02222, 03333, 04444, 05555, 06666, 07777, 08888, 09999, 00001,
Iter 02 : 02222, 03333, 04444, 05555, 06666, 07777, 08888, 09999, 00001, 00002,
Iter 03 : 03333, 04444, 05555, 06666, 07777, 08888, 09999, 00001, 00002, 00003,
Iter 04 : 04444, 05555, 06666, 07777, 08888, 09999, 00001, 00002, 00003, 00004,
Iter 05 : 05555, 06666, 07777, 08888, 09999, 00001, 00002, 00003, 00004, 00005,
Iter 06 : 06666, 07777, 08888, 09999, 00001, 00002, 00003, 00004, 00005, 00006,
Iter 07 : 07777, 08888, 09999, 00001, 00002, 00003, 00004, 00005, 00006, 00007,
Iter 08 : 08888, 09999, 00001, 00002, 00003, 00004, 00005, 00006, 00007, 00008,
Iter 09 : 09999, 00001, 00002, 00003, 00004, 00005, 00006, 00007, 00008, 00009,
Iter 10 : 00001, 00002, 00003, 00004, 00005, 00006, 00007, 00008, 00009, 00010,

Unshifted Elements
          00000, 01111, 02222, 03333, 04444, 05555, 06666, 07777, 08888, 09999,
--------------------------------------------------
16-bit Right Shifts...
Iter 00 : 00000, 01111, 02222, 03333, 04444, 05555, 06666, 07777, 08888, 00000,
Iter 01 : 00000, 00000, 01111, 02222, 03333, 04444, 05555, 06666, 07777, 00000,
Iter 02 : 00001, 00000, 00000, 01111, 02222, 03333, 04444, 05555, 06666, 00000,
Iter 03 : 00002, 00001, 00000, 00000, 01111, 02222, 03333, 04444, 05555, 00000,
Iter 04 : 00003, 00002, 00001, 00000, 00000, 01111, 02222, 03333, 04444, 00000,
Iter 05 : 00004, 00003, 00002, 00001, 00000, 00000, 01111, 02222, 03333, 00000,
Iter 06 : 00005, 00004, 00003, 00002, 00001, 00000, 00000, 01111, 02222, 00000,
Iter 07 : 00006, 00005, 00004, 00003, 00002, 00001, 00000, 00000, 01111, 00000,
Iter 08 : 00007, 00006, 00005, 00004, 00003, 00002, 00001, 00000, 00000, 00000,
Iter 09 : 00008, 00007, 00006, 00005, 00004, 00003, 00002, 00001, 00000, 00000,


The above code listing is also attached to this post below. It is named: 'Array_Shift_18F25K20.zip', and will unzip to a file named: 'Array_Shift_18F25K20.bas'

I'll create an include file for the array shifts, in the next free update to the compilers, so that all BASIC code listing can access them, once the inc file is included.

Best regards
Les

▲