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? -Lucas [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 > 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 I've seen a variation of this in NES games where space is so important. They used it as a way of calling a subroutine with two different args without wasting space. i.e. lda #arg1 jsr .1 lda #arg2 .1 other code rts -Lucas Paul Guertin wrote: > Doing the same for ROR is slightly more involved. > The quickest and shortest way (I think) is > > LSR ; c contains lsb > BCC .1 ; lsb was clear, skip next instruction > ADC #$7F ; add #$80 to set high bit > .1 ; program continues here Five bytes, six or seven cycles. PHA ROR PLA ROR Four bytes, eleven cycles. TAX ROR TXA ROR Four bytes, eight cycles, but uses an index register > Quiz: what's the shortest 6502 code that will swap nibbles > in a byte (e.g. $6D will become $D6, $81 will become $18, etc.)? Simple code: CMP #$80 ROL ROL ROL ROL Six bytes, ten cycles TAX LDA TABLE,X Four bytes of CODE, but uses 256 bytes of data. -- Paul Monroe, Michigan USA > > Quiz: what's the shortest 6502 code that will swap nibbles > > in a byte (e.g. $6D will become $D6, $81 will become $18, etc.)? > > Simple code: > > CMP #$80 > ROL > ROL > ROL > ROL This doesn't work. All that done is the MSB is replicated and you are still missing bit 4 in the answer. To illustrate Let Accumulator = 10110110, carry = 0 cmp #$80; Acc = 10110110, carry = 1 rol; Acc = 01101101, carry = 1 rol; Acc = 11011011, carry = 0 rol; Acc = 10110110, carry = 1 rol; Acc = 01101101, carry = 1 So, we started with $B6 and ended with $6D. -Lucas Lucas wrote: >> > Quiz: what's the shortest 6502 code that will swap nibbles >> > in a byte (e.g. $6D will become $D6, $81 will become $18, etc.)? >> >> Simple code: >> >> CMP #$80 >> ROL >> ROL >> ROL >> ROL > >This doesn't work. All that done is the MSB is replicated and you are >still missing bit 4 in the answer. To illustrate > >Let Accumulator = 10110110, carry = 0 > >cmp #$80; Acc = 10110110, carry = 1 >rol; Acc = 01101101, carry = 1 >rol; Acc = 11011011, carry = 0 >rol; Acc = 10110110, carry = 1 >rol; Acc = 01101101, carry = 1 > >So, we started with $B6 and ended with $6D. Right. To make this scheme work, you need to put a CMP #$80 before each ROL, to keep the carry virtually out of the shift path. -michael Check out amazing quality sound for 8-bit Apples on my Home page: http://members.aol.com/MJMahon/ Paul Guertin wrote: >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 Nice, Paul! A great example of how the low bits of a byte can be shifted left independently of higher bits. I've been doing programming with exact timing requirements for so long that I am especially fond of non-branching code. (BTW, my name is "Mahon", minus the "Mc". ;-) -michael Check out amazing quality sound for 8-bit Apples on my Home page: http://members.aol.com/MJMahon/ On 18 Mar 2004 09:09:53 GMT, mjmahon@aol.com (Michael J. Mahon) wrote: > Nice, Paul! A great example of how the low bits of a > byte can be shifted left independently of higher bits. People interested in this sort of thing, mixing logical and arithmetic operations on bits, will probably enjoy a book called "Hacker's Delight" by Henry S. Warren, published by Addison-Wesley. The web site: http://www.hackersdelight.org/ Read reviews at Amazon: http://www.amazon.com/exec/obidos/tg/detail/-/0201914654/104-4013520-2511168?v=glance > (BTW, my name is "Mahon", minus the "Mc". ;-) Oops. Sorry about that. Paul McGuertin pg@sff.net