A nibble table look ahead, just 16 bytes, or 8 if you accept to deal
with 4 bits tables.
For top possible speed at cost of some memory, a 256 bytes look ahead
table.
Wagner
>
> I'm sure I saw an easy way to reverse a byte some time ago in this list, but
> I've forgotten it..
>
> I want to change b7 b6 b5 b4 b3 b2 b1 b0 to b0 b1 b2 b3 b4 b5 b6 b7.
>
> Quickest & most code efficient??
>
> Jim
> ---
Jim,
Your choices are likely to be fast execution and big code usage OR slow
execution and small code usage.
As Wagner suggested, fastest would be a 256 byte lookup table (but it
uses up 256 bytes for the lookup table).
A small, slower approach is to rotate the source byte right one bit
(putting the rightmost bit in the carry flag), then rotate the
destination byte left one bit (putting the carry flag in the rightmost
bit of your destination register). Repeat this cycle 8 times. Your
destination byte will have to be a temp register, then when done move the
temp register back to the original source register. I would estimate
this could be done in 10 to 15 bytes of code and 50 to 70 instruction
cycles.
Obviously I am thinking like the C programmer I am and someone like
Dimitry could probably give you a method for accomplishing the same thing
in 5 bytes of code and 10 cycles. :-)
> I'm sure I saw an easy way to reverse a byte some time ago in this
> list, but
> I've forgotten it..
>
> I want to change b7 b6 b5 b4 b3 b2 b1 b0 to b0 b1 b2 b3 b4 b5
> b6 b7.
>
> Quickest & most code efficient??
>
> Jim
> ---
___________________________________________________________________
Get the Internet just the way you want it.
Free software, free e-mail, and free Internet access for a month!
Try Juno Web: dl.http://www.juno.com/dynoget/tagj.
If I'm not mistaken you could use a 16 byte lookup for the nybbles and then
use the efficency of the swap instruction, quicker I believe than rotating
all 8 bits and less code space than the full lookup table.
I colleague of mine has extoled the virtues of
using lookup tables as a means of improving
speed for as long as I can remember. Just about
every time I have ever asked him, "How can I make
this faster", he usually replies: "use a table".
Ever wonder how they got so many of those video
games on the 1Mhz "pre-Nintendo-era" game units
to animate smoothly?
I tend to agree that this technique is often
underused. But, Of course, there are plenty of
situations where the use of a table may not be
practical.
Just my $.02
Dan
On Fri, 29 Oct 1999 17:12:13 +0200, Douglas Burkett wrote:
>If I'm not mistaken you could use a 16 byte lookup for the nybbles and then
>use the efficency of the swap instruction, quicker I believe than rotating
>all 8 bits and less code space than the full lookup table.
>
>Doug
>
>{Original Message removed}
Adam Bryant wrote:
> A small, slower approach is to rotate the source byte right one bit
> (putting the rightmost bit in the carry flag), then rotate the
> destination byte left one bit (putting the carry flag in the rightmost
> bit of your destination register). Repeat this cycle 8 times. Your
> destination byte will have to be a temp register, then when done move the
> temp register back to the original source register. I would estimate
> this could be done in 10 to 15 bytes of code and 50 to 70 instruction
> cycles.
>
> Obviously I am thinking like the C programmer I am and someone like
> Dimitry could probably give you a method for accomplishing the same thing
> in 5 bytes of code and 10 cycles. :-)
Adam is correct about the options, but even in assembler:
1) A direct flow routine:
8 instructions shifting bits out
8 instructions shifting bits in
1 instruction swapping bytes
Total Program Instructions: 17
Total Instructions Executed: 17
2) A loop routine:
1 instruction setting loop count = 8
1 instruction shifting bit out
1 instruction shifting bit in
1 instruction decrementing count and looping back
1 instruction to swap bytes
Total Program Instructions: 5
Total Instructions Executed: 26
3) Lookahead table (16 bytes of nibbles):
1 instruction to set the lookahead base address
1 instruction to save the original byte
1 instruction to AND the original byte lower nibble
1 instruction to get the table nibble
1 instruction to save this table byte
1 instruction to retrieve the original byte
1 instruction to swap original byte nibbles
1 instruction to AND the original byte lower nibble
1 instruction to get the table nibble
1 instruction to OR with previous table nibble
1 instruction to swap final byte nibbles
Total Program Instructions: 11 + 16 (table)
Total Instructions Executed: 11
4) Lookahead table (256 bytes):
1 instruction to set the lookahead base address
1 instruction to get the table byte
Total Program Instructions: 2 + 256
Total Instructions Executed: 2
As you can see, execution speed cost a lot, always.
> 3) Lookahead table (16 bytes of nibbles):
> 1 instruction to set the lookahead base address
> 1 instruction to save the original byte
> 1 instruction to AND the original byte lower nibble
> 1 instruction to get the table nibble
> 1 instruction to save this table byte
> 1 instruction to retrieve the original byte
> 1 instruction to swap original byte nibbles
> 1 instruction to AND the original byte lower nibble
> 1 instruction to get the table nibble
> 1 instruction to OR with previous table nibble
> 1 instruction to swap final byte nibbles
> Total Program Instructions: 11 + 16 (table)
> Total Instructions Executed: 11
I made it Total Program Instructions: 7 + 19 (table)
&Total Instructions executed: 7
>I'm sure I saw an easy way to reverse a byte some time ago in this list, but
>I've forgotten it..
>
>I want to change b7 b6 b5 b4 b3 b2 b1 b0 to b0 b1 b2 b3 b4 b5 b6 b7.
I've seen a lot of replies, but to me, the simple 'brute force and
ignorance' technique seems to make the most sense.
rlf arg1,1 ;shift out a bit
rrf arg2,1 ;shift it in
rlf arg1,1 ;shift out a bit
rrf arg2,1 ;shift it in
rlf arg1,1 ;shift out a bit
rrf arg2,1 ;shift it in
rlf arg1,1 ;shift out a bit
rrf arg2,1 ;shift it in
rlf arg1,1 ;shift out a bit
rrf arg2,1 ;shift it in
rlf arg1,1 ;shift out a bit
rrf arg2,1 ;shift it in
rlf arg1,1 ;shift out a bit
rrf arg2,1 ;shift it in
rlf arg1,1 ;shift out a bit
rrf arg2,1 ;shift it in
Kind of long, but this should reverge arg1 and store it in arg2. At the
same time, it will also reverse arg2 and store it in arg1.
>>I'm sure I saw an easy way to reverse a byte some time ago in this list, but
>>I've forgotten it..
>>
>>I want to change b7 b6 b5 b4 b3 b2 b1 b0 to b0 b1 b2 b3 b4 b5 b6 b7.
>
>I've seen a lot of replies, but to me, the simple 'brute force and
>ignorance' technique seems to make the most sense.
>
> clrf dest
> btfsc source,0
> bsf dest,7
> btfsc source,1
> bsf dest,6
> btfsc source,2
> bsf dest,5
> btfsc source,3
> bsf dest,4
> btfsc source,4
> bsf dest,3
> btfsc source,5
> bsf dest,2
> btfsc source,6
> bsf dest,1
> btfsc source,7
> bsf dest,0
>
>17 instructions, 17 cycles
>
>dwayne
>
>
>Dwayne Reid <EraseMEdwaynerspam_OUTTakeThisOuTplanet.eon.net>
>Trinity Electronics Systems Ltd Edmonton, AB, CANADA
>(780) 489-3199 voice (780) 487-6397 fax
>
>Celebrating 15 years of Engineering Innovation (1984 - 1999)
>
>* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
>Do NOT send unsolicited commercial email to this email address.
>My posting messages to Usenet neither grants consent to receive
>unsolicited commercial email nor is intended to solicit commercial
>email.
>
>
-----------------------------------------------------------------
Sent from the desk of:
Terry Allen Steen, EE engineeringspam_OUTmarinapower.com
332 McLaws Circle, Ste 111 757-258-8800 (Voice)
Williamsburg, Va 23185 757-258-8805 (FAX)
-----------------------------------------------------------------
!I AM A WHALE MAIL USER! If you have a large file to send, goto http://www.whalemail.com send them to: mplengineer
Give me your account and I will use it also
-----------------------------------------------------------------
Visit our web-site: http://www.marinapower.com
-----------------------------------------------------------------
movwf source a b c d e f g h
btfsc source,0
xorlw h'41' a b+h c d e f g 0
btfsc source,6
xorlw h'41' a h c d e f g b
btfsc source,1
xorlw h'22' a h c+g d e f 0 b
btfsc source,5
xorlw h'22' a h g d e f c b
btfsc source,2
xorlw h'14' a h g d+f e 0 c b
btfsc source,4
xorlw h'14' a h g f e d c b
Cute, but you haven't completed the reverse - a rotate *without*
carry is required. That's going to take two more cycles at least.
--
Cheers,
Paul B.
This would probably waste too much port space but you could reverse the 'w'
register in two instructions if you wired two ports together like this:
RA0->RB7
RA1->RB6
RA2->RB5
RA3->RB4
RA4->RB3
RA5->RB2
RA6->RB1
RA7->RB0
and executed the code sequence
mov RA,W
mov w,RB
The piece of code that Tracy posted (from John Payson) does what it was
originally meant to do BUT is NOT correct for the present problem.
Here we require
76543210 --> 01234567
John's solution is for a 7 bit swap ignoring B7.
ie x6543210 --> x0123456
As a consequence B7 & B3 is untouched and there are only 3 swaps needed
making the code shorter.
Rewriting it for an 8 bit swap as required here, produces -
17 instructions, time varies depending on data but fairly quick.
Operation may not be initially obvious.
It implements
For N = 0 to 3
If bN = 1 then invert bits bN and b(7-N)
If b(7-N) = 1 then invert bits bN and b(7-N)
Next N
Worst case, if both bits in a pair are set it inverts them both twice.
Best case, if neither is set it takes no action.
This suggests that a more cunning test for "both bits set" may allow a small
reduction in run time but intuition suggests that the testing overhead would
be excessive..
John's solution is elegant but a little hard on the brain.
I prefer Dwayne Reids more brute force -
> Are you sure this works? I've tried it with CC5X
> and haven't sucess.
>
> uns8 source;
> MOVLW (0b.1101.1001); // this value is just
> for test
> MOVWF (source);
> BTFSC (source.0);
> XORLW (0x41); // 0100.0001
> BTFSC (source.6);
> XORLW (0x41); // 0100.0001
> BTFSC (source.1);
> XORLW (0x22); // 0010.0001
> BTFSC (source.5);
> XORLW (0x22); // 0010.0001
> BTFSC (source.2);
> XORLW (0x14); // 0001.0100
> BTFSC (source.4);
> XORLW (0x14); // 0001.0100
>
> It is very ingenious, but seens to have a bug
> somewhere.
Well it doesn't have a bug, it was intended to reverse
seven bits and not eight. I'm no Payson, but it looks
like for one more cycle you could do this:
On Fri, 29 Oct 1999 15:10:14 -0700 Keith Causey <RemoveMEffightTakeThisOuTGEOCITIES.COM>
writes:
>This would probably waste too much port space but you could reverse
>the 'w'
>register in two instructions if you wired two ports together like
>this:
>RA0->RB7
>RA1->RB6
>RA2->RB5
>RA3->RB4
>RA4->RB3
>RA5->RB2
>RA6->RB1
>RA7->RB0
>and executed the code sequence
>mov RA,W
>mov w,RB
Aha! A hardware solution! Just like adding a multiplier to the
chip! Here's bit reverser hardware... I normally am squeezing
everything I can out of I/O though...
___________________________________________________________________
Get the Internet just the way you want it.
Free software, free e-mail, and free Internet access for a month!
Try Juno Web: dl.http://www.juno.com/dynoget/tagj.
> John's solution is elegant but a little hard on the brain.
> I prefer Dwayne Reids more brute force -
> because it's much easier for trhe average person to see what is happening at
> a glance (or a few glances :-) - YMMV).
The shift-out-shift-in method is also pretty easy to follow. It is also 1
instruction shorter because you don't have to clear the destination register
at the beginning.
> Lookup tables have the possible advantage of having a constant
> implementation time.
The test-each-bit method and the shift-out-shift-in method also have constant
execute times.
> This would probably waste too much port space but you could reverse the 'w'
> register in two instructions if you wired two ports together like this:
Alternately, wait for this beast: http://www.atmel.com/atmel/products/prod39.htm
(it's an AVR with dual UART, no ADC, FPGA on chip) looks good for custom
protocol interfacing at high speed, multiple channel, Video processing ....
I want one to play with now, it would make a beaut logic analyser, just add
SIMM & graphics LCD
regards,
Graham Daniel.
part 0 1626 bytes - 16 cycles
- 16 words
- uses 1 addition byte or RAM.
- Enter with byte to be reversed in WREG, ends with reversed byte in
WREG.
- Isochronous.
> - 16 cycles
> - 16 words
> - uses 1 addition byte or RAM.
> - Enter with byte to be reversed in WREG, ends with
> reversed byte in
> WREG.
> - Isochronous.
This is a variation of something Steve Hardy posted
several years ago. Except Steve's version would
reverse two bytes and worked on the Midrange pics as
well.
IIRC:
; reverse r1 r2
rlf r1,f ; get carry bit and put r1.7 into carry
rrf r2,f ; get r1.7 and put r2.0 into carry
rlf r1,f ; get r2.0 and put r1.6 into carry
rrf r2,f
rlf r1,f
rrf r2,f
rlf r1,f
rrf r2,f
rlf r1,f
rrf r2,f
rlf r1,f
rrf r2,f
rlf r1,f
rrf r2,f
rlf r1,f
rrf r2,f
rlf r1,f ; get r2.7 and put the original
; carry bit back.
17 cycles to reverse two bytes
.lo
=====
__________________________________________________
Do You Yahoo!?
Bid and sell for free at http://auctions.yahoo.com
> - Enter with byte to be reversed in WREG, ends with reversed byte in
> WREG.
No, it ends with the reversed byte in W, not WREG as written, or in
Reverse if you specify F as destination. Unless you're talking of a PIC
with which I'm not familiar.