[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ROL Instruction



[Quiz: shortest 6502 code that swaps nibbles in accumulator]

On Wed, 17 Mar 2004 18:28:27 +0000 (UTC), lscharen@d.umn.edu wrote:

> Here's my entry (11 bytes)
> 
>  sta <00      ; 2 bytes
>  and #$F0     ; 4 bytes
>  clc          ; 5 bytes
>  adc <00      ; 6 bytes
>  rol          ; 7 bytes
>  rol          ; 8 bytes
>  rol          ; 9 bytes
>  rol          ; 10 bytes
> 
> Oops! The total count is 11 bytes, of course.  The adc <00 should count for 2.
> Can anyone do better than 11?

The obvious way, after Michael McMahon explained how to do a
carry-excluded ROL, takes 12 bytes:

    cmp #$80
    rol
    cmp #$80
    rol
    cmp #$80
    rol
    cmp #$80
    rol

Of course, you can loop: that takes only 8 bytes, but it uses up a
precious index register. I should have mentioned in the problem
statement that the use of X or Y is not allowed, otherwise it's
too easy:

   ldx #4
.1 cmp #$80
   rol
   dex
   bne .1

Here is a weird way to use the stack for looping (the same idea can be
used to loop 2^n times). It's really slow, though, and cannot be inlined,
so it's mostly a curiosity (10 bytes but you need to JSR to it, so +3):

   jsr .1
.1 jsr .2
.2 cmp #$80
   rol
   rts

Actually, in this case, it's faster and just as short to unroll once:

   jsr .1
.1 cmp #$80
   rol
   cmp #$80
   rol
   rts

Finally, here's my solution in 10 bytes, no index registers used. It's
similar to yours but the add is done later and shifts in the last bit
(from the carry) at the same time, so there's no need for a clc.

   asl
   rol 
   rol
   rol
   sta $00
   and #07
   adc $00

Paul Guertin
pg@sff.net