Oh how I spend my Friday nights
In order to help me understand what's going on in that one-byte original version, I decided it would be helpful to write a version that didn't loop at all:
Code:
; first char: A = 0..255
; 2xx -> %10
; 1xx -> %01
; 0xx -> %00
cmp #200
bcc @1 ; A = 0..199
sbc #200 ; A = 0..55
@1 rol outchar ; %1,%0
; A = 0..199 or 0..55
cmp #100
bcc @2 ; A = 0..99
sbc #100 ; A = 0..99
@2 rol outchar ; %10,%01,%00
tax
lda outchar
and #$03
ora #$30
jsr output
txa
; second char: A = 0..99
; 9x -> %1001
; 8x -> %1000
; 7x -> %0111
; 6x -> %0110
; 5x -> %0101
; 4x -> %0100
; 3x -> %0011
; 2x -> %0010
; 1x -> %0001
; 0x -> %0000
cmp #80
bcc @3 ; A = 0..79
sbc #80 ; A = 0..19
@3 rol outchar ; %1,%0
; A = 0..79 or 0..19
cmp #40
bcc @4 ; A = 0..39
sbc #40 ; A = 0..39
@4 rol outchar ; %10,%01,%00
; A = 0..39
cmp #20
bcc @5 ; A = 0..19
sbc #20 ; A = 0..19
@5 rol outchar ; %100,%011,%010,%000
; A = 0..19
cmp #10
bcc @6 ; A = 0..9
sbc #10 ; A = 0..9
@6 rol outchar ; %1001,%1000,%0111,%0110
; %0101,%0100,%0011,%0010,%0000
tax
lda outchar
and #$0F
ora #$30
jsr output
txa
; third char: A = 0..9
; 9 -> %1001
; 8 -> %1000
; 7 -> %0111
; 6 -> %0110
; 5 -> %0101
; 4 -> %0100
; 3 -> %0011
; 2 -> %0010
; 1 -> %0001
; 0 -> %0000
cmp #8
bcc @7 ; A = 0..7
sbc #8 ; A = 0..1
@7 rol outchar ; %1,%0
; A = 0..7 or 0..1
cmp #4
bcc @8 ; A = 0..3
sbc #4 ; A = 0..3
@8 rol outchar ; %10,%01,%00
; A = 0..3
cmp #2
bcc @9 ; A = 0..1
sbc #2 ; A = 0..1
@9 rol outchar ; %100,%011,%010,%000
; A = 0..1
cmp #1
bcc @10 ; A = 0
sbc #1 ; A = 0
@10 rol outchar ; %1001,%1000,%0111,%0110
; %0101,%0100,%0011,%0010,%0000
lda outchar
and #$0F
ora #$30
jsr output
rts
; alternatively:
; A = 0..1
; cmp #1 (or) lsr
; rol outchar
So that was helpful. A looping version pretty easily follows:
Code:
ldy #$00
sty outchar
ldy #2
ldx #10-1
@1 cmp table,x
bcc @2
sbc table,x
@2 rol outchar
dex
dey
bne @1
tay
lda outchar
and #$0F
ora #$30
jsr output
tya
ldy #4
cpx #-1
bne @1
rts
table: byte 1,2,4,8,10,20,40,80,100,200
... or something like that...