How to address 2 bits in same byte
in Propeller 1
PUB GetByte2Bits(plByteAddr, pbB1Pos, pbB2Pos)
'
>| pbB1Pos
>| pbB2Pos
_Mask := (pbB1Pos | pbB2Pos)
'
Return ((Byte[plByteAddr] & _Mask) == _Mask)
'
'END PUB
If I ran the above method,
Would I receive return values of 0, 1, 2 or 3 back?
Is the logic correct/wrong?
If wrong, where did I go wrong?
If correct, is there a more better/standardised way of doing this?
Comments
Byte[plByteAddr].[bitnumber]
Enjoy!
Mike
pub get_2bits(value, b1pos, b0pos) result := ((value >> (b1pos-1)) & 1) | ((value >> b0pos) & 1)
Then you could use it like this:
myVar := get_2bits(myVar, b1, b0)
Or am I missing something and you just want to isolate two bits in the same byte without moving their position. If so...
pub isolate2(value, b1pos, b0pos) result := value & ((1 << b1pos) | (1 << b0pos))
I've run into trouble tying to do bit operations on bytes using the Propeller 1 so I also perform the bit operations on a long and then save the value back to the byte.
Am I imagining things or is this concern justified?
myWord.byte[1] &= %0000_0011
Hiya msrobots,
Thank you, I look forward to using Spin2 with the new P2 microcontroller,
Currently I'm delving into P1.
Thank You JonnyMac,
I think your way is better since its only one statement (cycle?)
and mine is more unfortunately...
I'm kind of having a foray into designing a framework for the P1
Similar to this... an013-gui-graphics-series-menus-and-messaging-with-the-propeller-window-manager-framework
And so I have some settings which I need to access and modify at run time.
Kind of like this...
Byte _bCoreFlags1 '* Primary window flags (CoreFlags1 structure) ' Layer bit0 'Window layer (up 4 layers supported) (00=layer1/01=layer2) ' Layer bit1 '(use with above) (10=layer3/11=layer4) ' BorderStyle bit2 'Window borderstyle (upto 4 styles supported) (00=none/01=single) ' BorderStyle bit3 ' (10=double/11=user defined) ' Reserved bit4 ' Reserved bit5 ' Reserved bit6 ' Reserved bit7
And I wanted to be able to read-in the settings, and then change & save them back to the settings.
So hence I wrote the function above, which, since I lack enough knowledge was unsure if the function would return what I expected.
I expected to be returned the value 0, 1, 2, 3 and since no one has pointed out any mistakes, I will assume the function will work, but I will change it to how you advised as that seems much better because its less cycles.
Now taking it for granted that the function at the top of this thread returns 0, 1, 2, 3 how would I then write back new values to the byte?
Currently I'm using the function below, which although not optimal, would still work...
I'm sure it could be optimised with better code than mine below...
PUB SetByte2Bits(plByteAddr, pbB1Pos, pbB2Pos, pbNewValue) ' If (pbNewValue == 3) SetByteBit(plByteAddr, pbB1Pos) SetByteBit(plByteAddr, pbB2Pos) ElseIf (pbNewValue == 2) ClrByteBit(plByteAddr, pbB1Pos) SetByteBit(plByteAddr, pbB2Pos) ElseIf (pbNewValue == 1) SetByteBit(plByteAddr, pbB1Pos) ClrByteBit(plByteAddr, pbB2Pos) Else ClrByteBit(plByteAddr, pbB1Pos) ClrByteBit(plByteAddr, pbB2Pos) 'End If ' 'End PUB
Also to answer your question, I think I don't need to pass the address of the byte, its just there because originally I had that code in a separate object, hence I passed the address of the byte so it could be modified directly, If I pass the value of the byte (byval as opposed to byref) then I wouldn't be able to change the value in that specific byte directly I guess..... So having said that then maybe yes I do need to pass the address?
Does that sound right? you will have to excuse my lack of understanding/knowledge.
PUB getLayer return _bCoreFlags1 & %11 ' return 2 lowest bits PUB setLayer(layer) _bCoreFlags1 &= !%11 ' clear 2 lowest bits _bCoreFlags1 |= (layer & %11) ' write new bits PUB getBorder return _bCoreFlags1 >> 2 & %11 PUB setBorder(border) _bCoreFlags1 &= !%1100 _bCoreFlags1 |= (layer & %11) << 2
Alternately, you can take advantage of the Prop's unused B registers - while the Prop1 only has 32 I/O pins, it still has dirB and outB registers that you can use.dirb := _bCoreFlags1 layer := dirb[1..0] ' read layer border := dirb[3..2] ' read border dirb[1..0] := new_layer ' set layer dirb[3..2] := new_border ' set border _bCoreFlags1 := dirb
Thank you Chris,
I've saved your example in a notepad file, my intention is to complete the various modules then replace the calls to the SetByte2Bits() function with inline statements like the ones in your example and hopefully on recompile it will reduce the filesize of the final program.
I tried to avoid using the PortB registers since I'm sure I read in the forums somewhere that PortB won't be supported on P2
Hi ersmith,
I would hazard a guess my program (when its finished) will be very constrained for space.
I had started with individual bytes, words, longs for everything and sized the field according to value length.
And in order to save space in the compiled code and also final space when I save objects to ram I've used bits where there is a simple Y/N, T/F or 1/0 as a value.
There are a lot more modules, the one in the code sample above is just a simplified version from one module.
Keep it simple. Start out with the most straightforward solution first, and don't worry about optimizing (for either time or space) until you find out that you need to optimize. Donald Knuth once wrote that "premature optimization is the root of all evil", and he is a very wise man.