; HEXA TO DECIMAL
;
; HEXA INPUT 8 BYTES AT                XX0.XX1.XX2.XX3.XX4.XX5.XX6.XX7
; USES AS DECIMAL NUMBER ADDER:        YY0.YY1.YY2.YY3.YY4.YY5.YY6.YY7.YY8
; DECIMAL OUTPUT 9 BYTES AT:           ZZ0.ZZ1.ZZ2.ZZ3.ZZ4.ZZ5.ZZ6.ZZ7.ZZ8
;
; In my case, the yy8 and zz8 is never used in this routine, but all
; this 26 bytes are consecutive in address, being xx0 the lowest one.
;
; A 8051 running at 7.3MHz:
; Execution Time:  3.98ms for x'00 00 00 00 0F FF'
; Execution Time:  5.20ms for x'00 00 00 01 FF FF'
; Execution Time:  7.50ms for x'00 00 01 FF FF FF'
; Execution Time:  9.10ms for x'00 01 FF FF FF FF'
; Execution Time: 10.65ms for x'01 FF FF FF FF FF'
;            Aparently its 2ms per byte
;
X2D:         CALL  CLEARYZ             ;;Clear All YY and ZZ bytes
             MOV   YY0,#1              ;;DECIMAL ADDER = 1
             ;                         ;;
             MOV   R0,#XX7             ;;LOCATE HOW MANY BYTES WITH DATA
             MOV   B,#8                ;;POSSIBLE 8 BYTES W/DATA ON XX
BITS1:       MOV   A,@R0               ;;GET BYTE FROM INPUT REGISTER
             CJNE  A,#0,BITS2          ;;JUMP IF FOUND THE FIRST NON ZERO
             DEC   R0                  ;;GO TO LOWER BYTE
             DJNZ  B,BITS1             ;;ONE BYTE DONE, GO AGAIN
                                       ;;
BITS2:       MOV   A,#8                ;;8 BITS PER BYTE, B CONTAINS BYTE #
             MUL   AB                  ;;A = QUANTITY OF BITS W/DATA
             MOV   BITS,A              ;;SAVE
             CJNE  A,#0,X2DMAIN2       ;;B = NUMBER OF DIGITS W/DATA
             RET                       ;;RETURN IF ONLY ZEROS AT XX
                                       ;;
X2DMAIN1:    CALL  X2DSHIFTD           ;;SHIFT DECIMAL RESULT
X2DMAIN2:    CALL  X2DSHIFTH           ;;SHIFT HEXA
             JNC   X2DMAIN3            ;;IF NOT CARRY, JUST SKIP IT
             CALL  X2DADD              ;;ADD NEW RESULT
X2DMAIN3:    DJNZ  BITS,X2DMAIN1       ;;ONE BIT DONE, GO AGAIN
             RET                       ;;GENERAL EXIT FROM THIS ROUTINE
                                       ;;ZZ0 - ZZ7 CONTAINS DECIMAL RESULT
                                       ;;
X2DSHIFTD:   MOV   R0,#YY0             ;;YY * 2  (DECIMAL)
             MOV   B,#8                ;;NUMBER OF BYTES
             CLR   C                   ;;NEED CARRY ZERO
X2DSHIFTD1:  MOV   A,@R0               ;;IGNORE LAST CARRY
             ADDC  A,@R0               ;;ADD BYTE TO ITSELF
             DA    A                   ;;DECIMAL ADJUST
             MOV   @R0,A               ;;PUT IT BACK
             INC   R0                  ;;GO TO UPPER BYTE
             DJNZ  B,X2DSHIFTD1        ;;DO IT 8 BYTES
             RET                       ;;RETURN
                                       ;;
X2DSHIFTH:   MOV   R0,#XX7             ;;SHIFT XX7 --> XX0 RIGHT 1 BIT
             MOV   B,#8                ;;NUMBER OF BYTES
SHIFTR0B:    CLR   C                   ;;NEED CARRY ZERO
SHIFTR0B1:   MOV   A,@R0               ;;GET BYTE
             RRC   A                   ;;ROTATE RIGHT THROUGH CARRY BIT
             MOV   @R0,A               ;;SAVE IT BACK
             DEC   R0                  ;;GO TO LOWER BYTE
             DJNZ  B,SHIFTR0B1         ;;DO IT AGAIN "B" TIMES
             RET                       ;;RETURN
                                       ;;
X2DADD:      MOV   R0,#ZZ0             ;; GET RESULT ZZ 8 BYTES REGISTER
             MOV   B,#8                ;; 8 BYTES
             MOV   R1,#YY0             ;; GET YY OPERATOR
             CLR   C                   ;; NEED CARRY OFF
X2DADD1:     MOV   A,@R0               ;; ZZ = ZZ + YY (8BYTES) W/DAA
             ADDC  A,@R1               ;; ADD BYTE TO BYTE 8 TIMES
             DA    A                   ;; DECIMAL ADJUST
             MOV   @R0,A               ;; PUT IT BACK
             INC   R0                  ;; BUMP POINTER NEXT BYTE
             INC   R1                  ;; BUMP POINTER NEXT BYTE
             DJNZ  B,X2DADD1           ;; ONE BYTE DONE, GO AGAIN
             MOV  A,ZZ8                ;; LAST CARRY TO 9TH BYTE OF ZZ
             ADDC A,#0                 ;; JUST CARRY TO ZZ8
             MOV  ZZ8,A                ;;
             RET                       ;; RETURN
