from Ron Kreymborg and Mike Keitz
[ed: rough guess is that about 2200 instructions will be executed]
see also:
;****************************************************************** ; ; Test program for 32-bit unsigned binary to BCD and BCD to ASCII. ; ;****************************************************************** title "32-bit binary to ascii" list p=pic16f84,r=dec,n=80,x=off,st=off include <p16f84.inc> errorlevel -302 ; no bank warnings errorlevel -305 ; no default dest warnings #define number 123456789 loadd macro local m,n,p p = number / 16777216 mov W, #p mov bin, W m = (number - p * 16777216) / 65536 mov W, #m mov bin+1, W n = (number - p * 16777216 - m * 65536) / 256 mov W, #n mov bin+2, W mov W, #number - p * 16777216 - m * 65536 - n * 256 mov bin+3, W endm CBLOCK 0x0c bin:4 ; 32-bit binary number (unsigned) bcd:10 ; 10 BC digits or 10 ascii chars pti,pto ; pointers ii temp cnt ENDC loadd ; load test value <number> call b2bcd ; convert to 32-bit binary to 10 bcd call bcd2a ; convert 10 bcd to 10 ascii jmp $ ;****************************************************************** ; Convert the 10 binary coded digits (5 bytes) starting at ; <bcd> into an ascii string also starting at <bcd>. Original ; bcd digits are lost. bcd2a mov W, #bcd+9 mov pto, W ; destination pointer mov W, #bcd+4 mov pti, W ; source pointer mov W, #5 ; 5 bytes to process mov cnt, W bcd2a1 mov W, pti ; get current input pointer mov fsr, W dec pti ; prepare for next mov W, indf ; get 2 bcds mov temp, W ; save for later mov W, pto ; get current output pointer mov fsr, W dec pto ; prepare for next dec pto mov W, temp ; get digits back and W, #$0f ; process lsd ;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. ; addlw "0" mov Hack, W mov W, #"0" add W, Hack mov indf, W ; to output dec fsr mov W, <>temp ; process msd and W, #$0f ;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. ; addlw "0" mov Hack, W mov W, #"0" add W, Hack mov indf, W ; to output decsz cnt ; all digits? jmp bcd2a1 ret ; yes ;****************************************************************** ; Convert 32-bit binary number at <bin> into a bcd number ; at <bcd>. Uses Mike Keitz's procedure for handling bcd ; adjust; Modified Microchip AN526 for 32-bits. b2bcd mov W, #32 ; 32-bits mov ii, W ; make cycle counter clr bcd ; clear result area clr bcd+1 clr bcd+2 clr bcd+3 clr bcd+4 b2bcd2 mov W, #bcd ; make pointer mov fsr, W mov W, #5 mov cnt, W ; Mike's routine: b2bcd3 mov W, #$33 add indf, W ; add to both nybbles snb indf.3 ; test if low result > 7 and W, #$f0 ; low result >7 so take the 3 out snb indf.7 ; test if high result > 7 and W, #$0f ; high result > 7 so ok sub indf, W ; any results <= 7, subtract back inc fsr ; point to next decsz cnt jmp b2bcd3 rl bin+3 ; get another bit rl bin+2 rl bin+1 rl bin+0 rl bcd+4 ; put it into bcd rl bcd+3 rl bcd+2 rl bcd+1 rl bcd+0 decsz ii ; all done? jmp b2bcd2 ; no, loop ret ; yes end