;*******************************************************************
;scale_hex2dec ; The purpose of this routine is to scale a hexadecimal byte to a ;decimal byte. In other words, if 'h' is a hexadecimal byte then ;the scaled decimal equivalent 'd' is: ; d = h * 100/256. ;Note that this can be simplified: ; d = h * 25 / 64 = h * 0x19 / 0x40 ;Multiplication and division can be expressed in terms of shift lefts ;and shift rights: ; d = [ (h<<4) + (h<<3) + h ] >> 6 ;The program divides the shifting as follows so that carries are automatically ;taken care of: ; d = (h + (h + (h>>3)) >> 1) >> 2 ; ;Inputs: W - should contain 'h', the hexadecimal value to be scaled ;Outputs: W - The scaled hexadecimal value is returned in W ;Memory: temp ;Calls: none scale_hex2dec mov temp, W ;Hex value is in W. clrb C ;Clear the Carry bit so it doesn't affect RRF ;Nikolai Golovchenko says: For better precision (especially for higher ;values of input byte), one more term should be added, so that ;d = (((h >> 3 + h) >> 3 + h) >> 1 + h) >> 2 = h * (1/4 + 1/8 + 1/64 + 1/512) ; ;This adds only 6 cycles, and reduces errors from 51 to 11 cases per ;all combinations of input (in both routines absolute errors are small,+-1). ; ; rr temp ; clrb C ; rr temp ; clrb C ; rr temp ; add temp, W rr temp clrb C rr temp clrb C rr temp ;temp = h>>3 add temp, W ;temp = h + (h>>3) rr temp ;temp = (h + (h>>3)) >> 1 add temp, W ;temp = h + ((h + (h>>3)) >> 1) rr temp clrb C mov W, >>temp ;d = W = (h + (h + (h>>3)) >> 1) >> 2 ret