Help with %masking

MORA99

Senior Member
I have 7bytes where I need to pick a few bits from each and combine to less bytes, is this possible with the %masking ?

Right now I am using if, but the compiler says im 50bytes over limit :/

The 7 bytes are like this
%01000100

I need to make 2 new bytes with the two ones, bit2 and 6 I think.

I would like to have it in a loop, and can handle the assignment of the variables, and shifting of the positions inside the 2 new bytes, so its just if its possible to take 2 bits from a byte and place somewhere else in a newbyte withoit removeing what is already in that byte.

 

hippy

Ex-Staff (retired)
You can do it, but the best way depends on a lot of factors. If you can put the data bytes sequentially into b1 and use b0 to build up the result in you can do some fancy tricks with the 'bit0..bit15' variables. The alternative is multiplying or dividing to do the shifting, with ANDing and ORing as required.

If the byte data is coming in from 'pins' then re-assigning the I/O lines can often work wonders if that's an available option.

The optimum code would depend very much on which bits need to be set in the result from which bits in the data bytes.
 

evanh

Senior Member
Example of non-looping bit concatination. NOTE: Untested.

' Fills bit's 15 to 2 of w0. (X1/X2 parts)
w0 = InputA&64<<9 + InputA&4<<12 + InputB&64<<7 + InputB&4<<10 + InputC&64<<5 + InputC&4<<8 + InputD&64<<3 + InputD&4<<6 + InputE&64<<1 + InputE&4<<4 + InputF&64>>1 + InputF&4<<2 + InputG&64>>3 + InputG&4

' Fills bit's 15 to 2 of w0. (Non-X1/X2 parts)
w0 = InputA&64*512 + InputA&4*4096 + InputB&64*128 + InputB&4*1024 + InputC&64*32 + InputC&4*256 + InputD&64*8 + InputD&4*64 + InputE&64*2 + InputE&4*16 + InputF&64/2 + InputF&4*4 + InputG&64/8 + InputG&4
 

inglewoodpete

Senior Member
I think we'll need a bit more detail of your problem in order to help.

(You are probably aware of this already but...) The 4 basic methods used in bit masking are:

<code><pre><font size=2 face='Courier'>1. Setting a bit:
b0 = %00010000
b1 = %00000001 'The mask
b0 = b0 OR b1 'Result: b0 = %00010001
'
2. Clearing a bit:
b0 = %00010001
b1 = %11101111 'The mask
b0 = b0 AND b1 'Result: b0 = %00000001
'
3. Shifting a mask left:
b1 = %00000001 'The mask
b1 = b1 * 2 'Result: b1 = %00000010
'
4. Shifting a mask right:
b1 = %00000010 'The mask
b1 = b1 / 2 'Result: b1 = %00000001 </font></pre></code>

Of course, this works equally as well when using word variables.

If you need to process 7 bytes in a sequence, it depends where they are (or where they are coming from).

The simplest method to handle 7 bytes would be if they are stored in sequential locations in RAM.

Other methods are reading an 8-bit input (b0 = pins) repeatedly or receiving serial data into a byte or word variable via a single pin.

Tell us more.

-Peter

Edited by - inglewoodpete on 20/06/2007 01:48:57

Edited by - inglewoodpete on 20/06/2007 01:49:26
 

MORA99

Senior Member
Thanks for the comments, I will look into them tomorro, time for bed :)

Heres the code I use now for more details, the 7bytes are as you can see in ram so easy to loop trough.



<code><pre><font size=2 face='Courier'>
for b12=82 to 89

'SerTxd(&quot;DEBUG &quot;,#bit15,#bit14,#bit13,#bit12,#bit11,#bit10,#bit9,#bit8,#bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0,CR,LF )
pause 1000

if b12 &gt; 82 then
w0=w0/4 'Shift 2 places
endif

peek b12,b13'XRGBXRGB
b6= b13 and %00000100
if b6 = %00000100 then
bit14=1
else
bit14=0
endif

b6= b13 and %01000000
if b6 = %01000000 then
bit15=1
else
bit15=0
endif

next
</font></pre></code>
 

boriz

Senior Member
Not sure how much help this is, but your code:

<code><pre><font size=2 face='Courier'>
b6= b13 and %00000100
if b6 = %00000100 then
bit14=1
else
bit14=0
endif
b6= b13 and %01000000
if b6 = %01000000 then
bit15=1
else
bit15=0
endif
</font></pre></code>

Can be replaced with:

<code><pre><font size=2 face='Courier'>
b13=b13/4
bit14=b13 and 1
b13=b13/16
bit15=b13 and 1
</font></pre></code>
 

inglewoodpete

Senior Member
Or instead of:
<code><pre><font size=2 face='Courier'>
b6= b13 and %00000100
if b6 = %00000100 then
bit14=1
else
bit14=0
endif
b6= b13 and %01000000
if b6 = %01000000 then
bit15=1
else
bit15=0
endif </font></pre></code>

Try:

<code><pre><font size=2 face='Courier'>
b1 = b13 AND %00000100 * 16 'Set or clear bit14
b1 = b13 AND %01000000 * 2 'Set or clear bit15
</font></pre></code>
 

hippy

Ex-Staff (retired)
evanh : <i>w0 = InputA&amp;64*512 + InputA&amp;4*4096 + ... </i>

Although that doesn't take into account that the PICAXE only does its maths strictly left to right without any precedence.

inglewoodpete : <i>Try: b1 = b13 AND %00000100 * 16 ... </i>

Or, bit12 = b13 / 4 &amp; 1
 

evanh

Senior Member
Oops! o_O

w0 = InputA&amp;64*512
w0 = InputA&amp;4*4096 + w0
w0 = InputB&amp;64*128 + w0
w0 = InputB&amp;4*1024 + w0
w0 = InputC&amp;64*32 + w0
w0 = InputC&amp;4*256 + w0
w0 = InputD&amp;64*8 + w0
w0 = InputD&amp;4*64 + w0
w0 = InputE&amp;64*2 + w0
w0 = InputE&amp;4*16 + w0
w0 = InputF&amp;64/2 + w0
w0 = InputF&amp;4*4 + w0
w0 = InputG&amp;64/8 + w0
w0 = InputG&amp;4 + w0
 

MORA99

Senior Member
Thanks all, I got it working (Based on the code boriz wrote).

Its some handling for the 15RGB leds, which have become 12leds(due to width of the perfboard), and probaly a 28X1 instead :)
 
Top