News:

;) This forum is the property of Proton software developers

Main Menu

Bitwise Reverse

Started by Giuseppe MPO, Oct 30, 2023, 12:47 AM

Previous topic - Next topic

Giuseppe MPO

I'm going crazy with a very simple piece of program that doesn't give me the desired results. To try to understand, I cut pieces of code until I got to these few lines, but it doesn't seem like the correct result. I also tried entering the code indicated in the manual but the result is different. What I read on the display is, on the first line 10101100 which is the right value, but on the second line I read 00000011
I just can't understand or am I missing something?

Device 18F25K22

Declare Xtal = 64   
All_Digital = On
Declare Optimiser_Level = 0
               
  Include "18F25K22.inc"
 
Declare LCD_DTPin PORTB.0
Declare LCD_RSPin PORTB.4
Declare LCD_ENPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2

                   
OSCCON =  %01111100         ' Set 16MHz internal osc frequency
OSCCON2 = %00000100         ' Select PLL as osc source
OSCTUNE = %01000000         ' PLL is enabled

Dim Temp As Byte

While
Cls
Temp = %10101100
Print At 1,1,Bin8 Temp
Temp = Temp @ 4
Print At 2,1,Bin8 Temp
DelayMS 1000
Wend
End

Pepe

Try This

Dim Temp As Byte
Dim Temp1 As Byte

While
Cls
Temp = %10101100
Print At 1,1,Bin8 Temp
Temp1 = Temp @ 4
Print At 2,1,Bin8 Temp1
DelayMS 1000
Wend


RGV250

#2
Was going to suggest the bitwise reverse but it looks like you are alreasdy using it.

Looking at what you are trying to do I think you need to "and" your result to mask the higher bits, what happens if you try
Temp = Temp @ 4
Temp = Temp & %00001111

or maybe I am reading your request wrong, if you want to reverse all 8 bits I think you need
Temp = Temp @ 8

Bob

Giuseppe MPO

Quote from: Pepe on Oct 30, 2023, 02:06 AMTry This

Dim Temp    As Byte
Dim Temp1    As Byte
   
    While
        Cls
        Temp = %10101100
        Print At 1,1,Bin8 Temp
        Temp1 = Temp @ 4
        Print At 2,1,Bin8 Temp1
        DelayMS 1000
    Wend
   


I had already tried this way and the result is the same.

Giuseppe MPO

Quote from: RGV250 on Oct 30, 2023, 07:57 AMWas going to suggest the bitwise reverse but it looks like you are alreasdy using it.

Looking at what you are trying to do I think you need to "and" your result to mask the higher bits, what happens if you try
Temp = Temp @ 4
Temp = Temp & %00001111

or maybe I am reading your request wrong, if you want to reverse all 8 bits I think you need
Temp = Temp @ 8

Bob

At this moment I just wanted to understand how the @ works, after various tests I got to the point of trying as it is written in the manual but the result is different. The @4 instruction should only invert the last 4 bits leaving the others unchanged, but I see that this is not the case.

Giuseppe MPO

#5
Quote from: RGV250 on Oct 30, 2023, 07:57 AMTemp = Temp @ 8

Bob

I also tried @8 and the result is even stranger, it doesn't invert all the 8bits but from what I see it swaps the last 4bits with the first 4bits.
I have a result like this 00110101. In fact it makes me mirror the original 8bit

Stephen Moss

#6
Sorry, I did not realize Les had already covered what I was going to say.

Quote from: Giuseppe MPO on Oct 30, 2023, 08:37 AMI also tried @8 and the result is even stranger, it doesn't invert all the 8bits but from what I see it swaps the last 4bits with the first 4bits.
I have a result like this 00110101. In fact it makes me mirror the original 8bit
Are you sure, if your original byte value was...
10101100 then the reverse would be
00110101 as the bits order has been reversed which is what the command is supposed to do. Bit 0 is now bit 7, bit 1 is now bit 6 and so on. Thus it looks right to me, I am not sure why @ 4 was not correct though as I don't recall using the reverse command for anything other than 8 bits myself.

Quote from: Giuseppe MPO on Oct 30, 2023, 08:37 AMI also tried @8 and the result is even stranger, it doesn't invert all the 8bits
If you want the bits inverted, changing 1's to 0's and 0's to 1's you need to use the Compliment function which is an ~, not an @, but it changes all the bits, you cannot select a number of bits to invert.
Otherwise, try not to interchange reverse or invert as with the compiler having an invert (Compliment) command that could get confusing with regard to what it is you want to achieve/are expecting the result to be.

top204

#7
The reverse operator will reverse the bits required in a variable, and the result will be the amount of bits required only. The other bits will be cleared. I've just checked it out in the BASIC Stamp II syntax and it follows what it did. The compiler's original syntax was to mimic the BASIC Stamp II syntax about 22 years ago, but as a compiler and not an interpreter!

For example, the code listing below:

    ByteIn = %11100001
    HRsoutLn "In:       ", Bin8 ByteIn
    ByteOut = ByteIn @ 8
    HRsoutLn "Reversed: ", Bin8 ByteOut

Will reverse all the 8 bits of the ByteIn variable into the ByteOut variable and will display on the serial terminal:

In:       11100001
Reversed: 10000111

And the code listing below:

    ByteIn = %11100001
    HRsoutLn "In:       ", Bin8 ByteIn
    ByteOut = ByteIn @ 4
    HRsoutLn "Reversed: ", Bin8 ByteOut

Will reverse the first 4 bits (LSB) and display:

In:       11100001
Reversed: 00001000

The other bits are cleared because the reverse operator was told to only use 4 bits of the ByteIn variable.


Giuseppe MPO

Hi Les thanks for the reply.
My doubt is this:

Because if I write

  ByteIn =%10101100
  ByteOut = ByteIn @ 4
  Print At 2,1,Bin8 ByteOut

ByteOut equals %00000011

While if I write:

  ByteOut = %10101100 @ 4
  Print At 2,1,Bin8 ByteOut

In this case ByteOut is equal to %10101100

Giuseppe MPO

There is something wrong with @,

in this line:

ByteOut = %11100001 @ XYZ

after @ I can put any number or any letter, when compiling, I don't receive any type of error.
Anything is ignored.
I'm using the latest version of Positron and a PIC18F25K22

RGV250

#10
Hi,
I have had a play and it appears to work fine if you use @ 8 (for a byte variable) but anything less and it does not copy the most significant bits.

after @ I can put any number or any letter, when compiling, I don't receive any type of error.
I am using 4.0.3.3 and get an error.

Bob

tumbleweed

#11
QuoteWhile if I write:
  ByteOut = %10101100 @ 4
In this case ByteOut is equal to %10101100


ByteOut = %11100001 @ XYZ
after @ I can put any number or any letter, when compiling, I don't receive any type of error.

The '@' operator requires a variable to operate on, and not a const value (ie must be 'bvar @ 4')

If you specify a constant it doesn't do any reversal, so it doesn't even check the syntax of '%11100001 @ XYZ'

Quote...and it appears to work fine if you use @ 8 (for a byte variable) but anything less and it does not copy the most significant bits.
per Les in post 7 '...and the result will be the amount of bits required only. The other bits will be cleared.'

I just tried this with an 18FK22 and it appears to produce the expected values...
Dim bytein As Byte
Dim byteout As Byte

ByteIn = %10101100
ByteOut = ByteIn @ 8        ' 00110101
ByteOut = ByteIn @ 4        ' 00000011
ByteOut = ByteIn @ 6        ' 00001101




Pepe

Why does it say otherwise in the manual?

16-bit Example
Device = 18F26K40 ' Select the device to compile for
Declare Xtal = 16 ' Tell the compiler the device will be operating at 16MHz
Declare Hserial_Baud = 9600 ' Set the Baud rate for HRsoutLn
Dim MyWord as Word ' Holds the result of the reverse
MyWord = 0b10101100 @ 4 ' Sets MyWord to 10100011 <---
HRsoutLn Bin8 MyWord ' Send the result to a serial terminal

tumbleweed

That's just what I observed from looking at the compiled results.
If it's meant to do otherwise then it doesn't seem to match the documentation, at least not for a K22.

top204

#14
That was down to my mistake in taking out the error message of "Unnecessary Reverse expression of two constant values"

However, I have created a simple loop in the compiler's interpreter section that deals with constant only expressions that will reverse with two constants:

    unsigned long Value = ReturnInteger;
    unsigned long BitsAmount = Interpreter_Term();
    unsigned long ReversedValue = 0;
    unsigned long BitCount;
//
// Reverse the bits of the value held in "Value"
//
    for(BitCount = 0; BitCount < BitsAmount; BitCount++)
        {
            if((Value & (1 << BitCount)) > 0)
                {
                    ReversedValue = ReversedValue | (1 << ((BitsAmount - 1) - BitCount));
                }
        }
    ReturnInteger = ReversedValue;

I will upload an update ASAP.