|
|
View previous topic :: View next topic |
Author |
Message |
Tom Jetland
Joined: 23 Jun 2011 Posts: 31 Location: UK
|
Reading 6 bits from a byte |
Posted: Thu Jun 23, 2011 5:28 am |
|
|
Hi,
I'm storing some 6-bit Graphics in a Const char array (in Prog memory), but to be memory efficient I'm storing it consecutively: -
Code: | array [0] array [1]
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 ..... bit numbers in array
--------------- ---------------
1 0 0 1 0 1 0 1 0 0 1 0 1 1 0 1 ..... data in array
--------------- ---------------
5 4 3 2 1 0 5 4 3 2 1 0 5 4 3 2 ..... bit numbers for LCD |
Apart from bit scanning, is there a more efficient way of extracting the data from the array in 6 bit chunks??
I've posted my code to do this below : -
Code: |
for ( r = 0 ; r < sprite_height ; r++, curs_addr += 0x28 ) {
pix_count = 0;
bit_out = bit_offset; // This is offsetting the start bit of the sprite
cursor_position ( curs_addr );
for (;;) {
data_read = cursor_up[x]; // Fetching the gfx data from the ROM
for ( bit = 7 ; bit >= 0 ; bit--, bit_out-- ) {
if ( bit_test ( data_read, bit ) ) bit_set ( datatosend, bit_out);
pix_count++;
if ( pix_count == sprite_width );
else if ( bit_out != 0 ) continue;
bit_out = 6;
display_gfx ( datatosend );
datatosend = 0;
if (pix_count == sprite_width) break;
}
x++;
if ( pix_count == sprite_width ) break;
}
} |
I'm using PIC18F4620.
Any comments/suggestions on this code would be appreciated!
Thanks |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Thu Jun 23, 2011 7:28 am |
|
|
How about a different approach. This will require less shifting especially when combined with the swap instruction.
I refer to a sample as one of the 6 bit data values.
Store four samples (A,B,C,D) in three bytes as follows:
Sample A is stored in the lower six bits of location N
Sample B is stored in the lower six bits of location N+1
Sample C is stored in the lower six bits of location N+2
Sample D lower 2 bits is stored in the upper 2 bits of N
Sample D middle 2 bits is stored in the upper 2 bits of N+1
Sample D upper 2 bits is stored in the upper 2 bits of N+1
_________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Thu Jun 23, 2011 8:31 am |
|
|
Was about to post a couple of suggestions, and see Asmallri has posted half the same idea.
For an incoming 'object_number', you have:
Code: |
byte_address=object_number/4;
val=object_number&3;
byte_address+=byte_address*2;
byte_address+=start_of_array;
//Then byte_address is the address in the integer array you want to work
//relative to, and val, determines what number to fetch
switch (val) {
case 0:
val=*(byte_address) & 0x3F;
break;
//etc..
|
This gives very efficient calculation of whether you are dealing with value A,B,C or D, and calculation of the array starting byte from the object number (/4*3 - the first is done as a rotation, as is *2).
Cases, 1&2, are identical, with 1 or two byte offsets.
Case 3, would be the 'fiddliest', but even this, can be done quite efficiently, using standard instructions. Look at rotating the top two bits _right_ twice (CCS rotate_right function), then (as asmallri says) swapping the high and low nibble (swap), and or'ing the top two bits of this into place, and then rotating the top byte left by two.
Something like:
Code: |
int a,b,c;
a=*(byte_address) & 0xC0;
b=*(byte_address+1) & 0xC0;
c=*(byte_address+2) & 0xC0;
//This could be written using an array, but then increases the work later
rotate_right(&a,1);
rotate_right(&a,1);
swap(b);
rotate_left(&c,1);
rotate_left(&c,1);
a|=b;
a|=c;
|
Best Wishes |
|
|
Tom Jetland
Joined: 23 Jun 2011 Posts: 31 Location: UK
|
|
Posted: Fri Jun 24, 2011 2:23 am |
|
|
Thanks guys,
I'll try these methods out and see how they fit in with my application.
Thanks for the input and ideas :-) |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|