News:

;) This forum is the property of Proton software developers

Main Menu

Storing 1,2,3 or 4 byte variables in a byte array

Started by kcsl, Apr 30, 2025, 04:47 PM

Previous topic - Next topic

kcsl

I'm looking for a way to store 1, 2, 3 or 4 byte variables on a byte by byte basis into a byte array.
I wrote something quick and dirty that worked, but thought it was horrible so started looking for a better way.

The smallest version I can come up with is this:

Proc WriteEEPROMBytes(pwAddress As Word, pnBytes As Byte, pdwValue As Dword)
    Dim rnLoop As Byte
   
    For rnLoop = 0 To pnBytes - 1
        gnEEPROM[ pwAddress ] = pdwValue & $FF   
        Inc pwAddress
        pdwValue = pdwValue >> 8
    Next rnLoop
EndProc
I think it would work, but it does an extra bitshift that's not needed at the end.
Also it just feels messy.

I can't just do this:
gnEEPROM[ pwAddress ] = pdwValue.byte0
gnEEPROM[ pwAddress+1 ] = pdwValue.byte1
gnEEPROM[ pwAddress+2 ] = pdwValue.byte2
gnEEPROM[ pwAddress+3 ] = pdwValue.byte3

as it would always write to four elements in the array irrespective of the variable size, and I'm also not sure what would be in the higher bytes of pdwValue when a smaller size variable is passed anyway.

Anybody got a suggestion ?

Regards,
Joe
There's no room for optimism in software or hardware engineering.

trastikata

#1
1. Create the 4-bytes array as heap
2. Alias a dummy dword variable to the first item in the array
3. Use the dummy variable to write in the array
4. Or you can write to parts of the dummy variable

Device = 18F14K50
Declare Xtal = 4

Dim baMyArray[4] As Byte Heap
Dim dwDummy As Dword At baMyArray#0
Dim wTemp As Word

Main:
    dwDummy = 0xFAFBFCFD
    dwDummy.Byte0 = 0xAB
    dwDummy.Word0 = 0xABCD
   
    wTemp = 0xBCDE
    dwDummy.Word0 = wTemp
    End

trastikata

Still the fastest and the cleanest way, in my opinion, is to set array element to variable bytes when needed instead of passing parameters ...  This takes only one Assembler mnemonic per byte and still happens anyway:

Dim baMyArray[4] As Byte Heap
Dim dwDummy As Dword At baMyArray#0
Dim wTemp As Word

Main:
    dwDummy = 0xFAFBFCFD
    dwDummy.Byte0 = 0xAB
    dwDummy.Word0 = 0xABCD
   
    wTemp = 0xBCDE
    dwDummy.Word0 = wTemp
   
    baMyArray#0 = wTemp.Byte0
    baMyArray#1 = wTemp.Byte1
    End

keytapper

I suppose that it's possible to store and retrieve the data as they're sized, except for strings.
Declare Hserout_baud = 9600
Dim MyWord As Dword = 3944005050
Dim StoredWord As Dword
Dim epos as Byte = 48

Ewrite[epos] MyWord
StoredWord = Eread[epos]

Hserout [StoredWord]

This is a sketch, I'm not correctly remember the keyword.
Ignorance comes with a cost

top204

You could try the C way, using pointers, but it is certainly not the fastest way, or the smallest. But that does not seem to matter in the world of C or C++. :-)

    Dim MyByteArray[4] As Byte Heap

'----------------------------------------------------------------------------
' The main program starts here
'
Main:
    Clear MyByteArray
    EE_WriteBytes(MyByteArray, 3, $FE123456)
    HRsoutLn IHex2 MyByteArray#3, ",", IHex2 MyByteArray#2, ",", IHex2 MyByteArray#1, ",", IHex2 MyByteArray#0

'----------------------------------------------------------------------------
' Load a byte array's elements with seperated bytes of a 32-bit integer variable passed to it
' Input     : pArrayAddr holds the address of the byte array to write too
'           : pAmount holds how many elements to write (1 to 4)
'           : pValue holds the value to split and write to the array
' Output    : The array passed to the "pArrayAddr" parameter, will contain the seperated bytes
' Notes     : None
'
Proc EE_WriteBytes(ByRef pArrayAddr As Word, pAmount As Byte, pValue As Dword)
    If pAmount = 0 Then ExitProc
    If pAmount > 4 Then ExitProc
    Repeat
        Ptr8(pArrayAddr++) = pValue     ' Load an element of the array passed in pArrayAddr, with Byte00 of pValue
        pValue = pValue >> 8            ' Shift the 32-bit value right to move to its next byte
        Dec pAmount                     ' \ Loop until pAmount is 0
    Until STATUSbits_Z = 1              ' /
EndProc

On the serial terminal, it will display:

$00,$12,$34,$56

Because it has been told to seperate the first 3 bytes from the value: $FE123456.

But, as Dyanko stated, aliasing and re-addressing is the fastest way, as long as it is always the same byte array holding the results.