#6510 machine code, 29 28 bytes
6510 machine code, 29 28 bytes
sub routine;
takes input from A (lower bound) and X (upper bound) registers;
returns result in A (MSB) and Y (LSB)
machine code:
85 02 A0 00 84 FC E8 CA
E4 02 30 OD 8A F0 F8 46
90 FB E8 90 F8 E6 FC D0
F4 A5 FC 60
source code:
STA $02 store lower bound in $02
LDY #0 init result to 0 (Y = LSB, $FC=MSB)
STY $FC
INX increment upper bound
LOOP1: DEX decrement upper bound
CPX $02 compare to lower bound
BMI :FINISH if smaller, return
TXA copy X to A
LOOP2: BEQ :LOOP1 if 0, next outer loop
LSR shift right
BCC :LOOP2 if carry is clear, next inner loop
INY else increment result
BCC :LOOP2
INC $FC
BNE :LOOP2 next inner loop
FINISH: LDA $FC
RTS
notes
- With only 8 bit input possible, the maximum number of set bits is 1024; so incrementing the MSB (
INC $FC
) always has a non-zero result; henceBNE :LOOP
always branches. BEQ
following thatBNE
never branches, even not if the accumulator is zero (so I could actually add two to the BEQ parameter and save one cycle); but that doesn´t matter:LSR
will clear the carry and set the zero flag,BCC
will hop toLOOP2
and theBEQ
toLOOP1
.- I´m not completely sure (it´s been so long I actually coded on the C64), but it may fail if the range is larger than 127:
CPX $02
is actually a substraction; if the result is >127, the negative flag may be set, soBMI
would end the routine. - I hope I got the branching parameters correct - I assembled the machine code manually.