OutBufDXasDecimal: push ax push bx push si sub sp, 24h mov ax, dx ; value mov bx, 10 ; radix mov si, sp .repeat xor dx, dx div bx mov [si], dl inc si .until ax==0 .repeat dec si mov al, [si] add al, '0' stosb .until si==sp add sp, 24h pop si pop bx pop ax retn ;OutBufDXasDecimal ends
see
http://www.dattalo.com/technical/software/pic/bcd.txt
for notes on how this works. Plan on a headache. <GRIN>
[ed: quick guess at speed is that about 200 instructions will be executed]
;Takes hex number in NumH:NumL Returns decimal in ;TenK:Thou:Hund:Tens:Ones ;written by John Payson ;input ;=A3*163 + A2*162 + A1*161 + A0*160 ;=A3*4096 + A2*256 + A1*16 + A0 NumH DB 0 ;A3*16+A2 NumL DB 0 ;A1*16+A0 ;share variables ;=B4*104 + B3*103 + B2*102 + B1*101 + B0*100 ;=B4*10000 + B3*1000 + B2*100 + B1*10 + B0 TenK DB 0 ;B4 Thou DB 0 ;B3 Hund DB 0 ;B2 Tens DB 0 ;B1 Ones DB 0 ;B0 mov al, NumH ;swapf NumH,w ;al = A2*16+A3 shr al, 4 ;andlw $0F ;al = A3 *** PERSONALLY, I'D REPLACE THESE 2 add al, 0F0h ;addlw $F0 ;al = A3-16 *** LINES WITH "IORLW 11110000B" -AW mov Thou, al ;movwf Thou ;B3 = A3-16 add Thou, al ;addwf Thou,f ;B3 = 2*(A3-16) = 2A3 - 32 add al, 0E2h ;addlw $E2 ;al = A3-16 - 30 = A3-46 mov Hund, al ;movwf Hund ;B2 = A3-46 add al, 32h ;addlw $32 ;al = A3-46 + 50 = A3+4 mov Ones, al ;movwf Ones ;B0 = A3+4 mov al, NumH ;movf NumH,w ;al = A3*16+A2 and al, 0Fh ;andlw $0F ;al = A2 add Hund, al ;addwf Hund,f ;B2 = A3-46 + A2 = A3+A2-46 add Hund, al ;addwf Hund,f ;B2 = A3+A2-46 + A2 = A3+2A2-46 add Ones, al ;addwf Ones,f ;B0 = A3+4 + A2 = A3+A2+4 add al, 0E9h ;addlw $E9 ;al = A2 - 23 mov Tens, al ;movwf Tens ;B1 = A2-23 add Tens, al ;addwf Tens,f ;B1 = 2*(A2-23) add Tens, al ;addwf Tens,f ;B1 = 3*(A2-23) = 3A2-69 (Doh! thanks NG) mov al, NumL ;swapf NumL,w ;al = A0*16+A1 shr al, 4 ;andlw $0F ;al = A1 add Tens, al ;addwf Tens,f ;B1 = 3A2-69 + A1 = 3A2+A1-69 range -69...-9 add Ones, al ;addwf Ones,f ;B0 = A3+A2+4 + A1 = A3+A2+A1+4 and Carry = 0 (thanks NG) shl Tens, 1 ;rlf Tens,f ;B1 = 2*(3A2+A1-69) + C = 6A2+2A1-138 and Carry is now 1 as tens register had to be negitive rcl Ones, 1 ;rlf Ones,f ;B0 = 2*(A3+A2+A1+4) + C = 2A3+2A2+2A1+9 (+9 not +8 due to the carry from prev line, Thanks NG) xor Ones, 0FFh ;comf Ones,f ;B0 = ~(2A3+2A2+2A1+9) = -2A3-2A2-2A1-10 (ones complement plus 1 is twos complement. Thanks SD) ;;Nikolai Golovchenko [golovchenko at MAIL.RU] says: comf can be regarded like: ;; comf Ones, f ;; incf Ones, f ;; decf Ones, f ;;First two instructions make up negation. So, ;;Ones = -1 * Ones - 1 ;; = - 2 * (A3 + A2 + A1) - 9 - 1 ;; = - 2 * (A3 + A2 + A1) - 10 shl Ones, 1 ;rlf Ones,f ;B0 = 2*(-2A3-2A2-2A1-10) = -4A3-4A2-4A1-20 mov al, NumL ;movf NumL,w ;al = A1*16+A0 and al, 0Fh ;andlw $0F ;al = A0 add Ones, al ;addwf Ones,f ;B0 = -4A3-4A2-4A1-20 + A0 = A0-4(A3+A2+A1)-20 range -215...-5 Carry=0 shl Thou, 1 ;rlf Thou,f ;B3 = 2*(2A3 - 32) = 4A3 - 64 mov TenK, 7 ;movlw $07 ;al = 7 ;movwf TenK ;B4 = 7 ;B0 = A0-4(A3+A2+A1)-20 ;-5...-200 ;B1 = 6A2+2A1-138 ;-18...-138 ;B2 = A3+2A2-46 ;-1...-46 ;B3 = 4A3-64 ;-4...-64 ;B4 = 7 ;7 ; At this point, the original number is ; equal to TenK*10000+Thou*1000+Hund*100+Tens*10+Ones ; if those entities are regarded as two's compliment ; binary. To be precise, all of them are negative ; except TenK. Now the number needs to be normal- ; ized, but this can all be done with simple byte ; arithmetic. mov al, 0Ah ;movlw $0A ;al = 10 .repeat ;Lb1: ;do add Ones, al ;addwf Ones,f ; B0 += 10 dec Tens ;decf Tens,f ; B1 -= 1 .until Carry? ;btfss 3,0 ;skip no carry ;goto Lb1 ; while B0 < 0 ;jmp carry .repeat ;Lb2: ;do add Tens, al ;addwf Tens,f ; B1 += 10 dec Hund ;decf Hund,f ; B2 -= 1 .until Carry? ;btfss 3,0 ;goto Lb2 ; while B1 < 0 .repeat ;Lb3: ;do add Hund, al ;addwf Hund,f ; B2 += 10 dec Thou ;decf Thou,f ; B3 -= 1 .until Carry? ;btfss 3,0 ;goto Lb3 ; while B2 < 0 .repeat ;Lb4: ;do add Thou, al ;addwf Thou,f ; B3 += 10 dec TenK ;decf TenK,f ; B4 -= 1 .until Carry? ;btfss 3,0 ;goto Lb4 ; while B3 < 0 ret ;retlw 0 L@DX2A@EDIr10: ;Takes hex number in dh:dl returns decimal out at [edi] useing local TenK:Thou:Hund:Tens:Ones ;written by John Payson ;input ;=A3*163 + A2*162 + A1*161 + A0*160 ;=A3*4096 + A2*256 + A1*16 + A0 NumH textequ <dh> ;A3*16+A2 NumL textequ <dl> ;A1*16+A0 ;temp variables ;=B4*104 + B3*103 + B2*102 + B1*101 + B0*100 ;=B4*10000 + B3*1000 + B2*100 + B1*10 + B0 TenK textequ <BYTE PTR [edi-5]> ;B4 Thou textequ <BYTE PTR [edi-4]> ;B3 Hund textequ <BYTE PTR [edi-3]> ;B2 Tens textequ <BYTE PTR [edi-2]> ;B1 Ones textequ <BYTE PTR [edi-1]> ;B0 breakpoint xor al,al mov TenK, al mov Thou, al mov Hund, al mov Tens, al mov Ones, al mov al, NumH ;swapf NumH,w ;al = A2*16+A3 shr al, 4 ;andlw $0F ;al = A3 *** PERSONALLY, I'D REPLACE THESE 2 add al, 0F0h ;addlw $F0 ;al = A3-16 *** LINES WITH "IORLW 11110000B" -AW mov Thou, al ;movwf Thou ;B3 = A3-16 add Thou, al ;addwf Thou,f ;B3 = 2*(A3-16) = 2A3 - 32 add al, 0E2h ;addlw $E2 ;al = A3-16 - 30 = A3-46 mov Hund, al ;movwf Hund ;B2 = A3-46 add al, 32h ;addlw $32 ;al = A3-46 + 50 = A3+4 mov Ones, al ;movwf Ones ;B0 = A3+4 mov al, NumH ;movf NumH,w ;al = A3*16+A2 and al, 0Fh ;andlw $0F ;al = A2 add Hund, al ;addwf Hund,f ;B2 = A3-46 + A2 = A3+A2-46 add Hund, al ;addwf Hund,f ;B2 = A3+A2-46 + A2 = A3+2A2-46 add Ones, al ;addwf Ones,f ;B0 = A3+4 + A2 = A3+A2+4 add al, 0E9h ;addlw $E9 ;al = A2 - 23 mov Tens, al ;movwf Tens ;B1 = A2-23 add Tens, al ;addwf Tens,f ;B1 = 2*(A2-23) add Tens, al ;addwf Tens,f ;B1 = 3*(A2-23) = 3A2-69 (Doh! thanks NG) mov al, NumL ;swapf NumL,w ;al = A0*16+A1 shr al, 4 ;andlw $0F ;al = A1 add Tens, al ;addwf Tens,f ;B1 = 3A2-69 + A1 = 3A2+A1-69 range -69...-9 add Ones, al ;addwf Ones,f ;B0 = A3+A2+4 + A1 = A3+A2+A1+4 and Carry = 0 (thanks NG) shl Tens, 1 ;rlf Tens,f ;B1 = 2*(3A2+A1-69) + C = 6A2+2A1-138 ;Carry is now 1 as tens register had to be negitive rcl Ones, 1 ;rlf Ones,f ;B0 = 2*(A3+A2+A1+4) + C = 2A3+2A2+2A1+9 ;(+9 not +8 due to the carry from prev line, Thanks NG) xor Ones,0FFh ;comf Ones,f ;B0 = ~(2A3+2A2+2A1+9) = -2A3-2A2-2A1-10 ;ones complement plus 1 is twos complement. Thanks SD ;Nikolai Golovchenko [golovchenko at MAIL.RU] says: ;;comf can be regarded like: ;; comf Ones, f ;; incf Ones, f ;; decf Ones, f ;;First two instructions make up negation. So, ;;Ones = -1 * Ones - 1 ;; = - 2 * (A3 + A2 + A1) - 9 - 1 ;; = - 2 * (A3 + A2 + A1) - 10 shl Ones, 1 ;rlf Ones,f ;B0 = 2*(-2A3-2A2-2A1-10) = -4A3-4A2-4A1-20 mov al, NumL ;movf NumL,w ;al = A1*16+A0 and al, 0Fh ;andlw $0F ;al = A0 add Ones, al ;addwf Ones,f ;B0 = -4A3-4A2-4A1-20 + A0 = A0-4(A3+A2+A1)-20 ;range -215...-5 Carry=0 shl Thou, 1 ;rlf Thou,f ;B3 = 2*(2A3 - 32) = 4A3 - 64 mov TenK, 7 ;movlw $07 ;al = 7 ;movwf TenK ;B4 = 7 ;B0 = A0-4(A3+A2+A1)-20 ;-5...-200 ;B1 = 6A2+2A1-138 ;-18...-138 ;B2 = A3+2A2-46 ;-1...-46 ;B3 = 4A3-64 ;-4...-64 ;B4 = 7 ;7 ; At this point, the original number is ; equal to TenK*10000+Thou*1000+Hund*100+Tens*10+Ones ; if those entities are regarded as two's compliment ; binary. To be precise, all of them are negative ; except TenK. Now the number needs to be normal- ; ized, but this can all be done with simple byte ; arithmetic. mov al, 0Ah ;movlw $0A ;al = 10 .repeat ;Lb1: ;do add Ones, al ;addwf Ones,f ; B0 += 10 dec Tens ;decf Tens,f ; B1 -= 1 .until Carry?;btfss 3,0 ;skip no carry ;goto Lb1 ; while B0 < 0 ;jmp carry .repeat ;Lb2: ;do add Tens, al ;addwf Tens,f ; B1 += 10 dec Hund ;decf Hund,f ; B2 -= 1 .until Carry?;btfss 3,0 ;goto Lb2 ; while B1 < 0 .repeat ;Lb3: ;do add Hund, al ;addwf Hund,f ; B2 += 10 dec Thou ;decf Thou,f ; B3 -= 1 .until Carry?;btfss 3,0 ;goto Lb3 ; while B2 < 0 .repeat ;Lb4: ;do add Thou, al ;addwf Thou,f ; B3 += 10 dec TenK ;decf TenK,f ; B4 -= 1 .until Carry?;btfss 3,0 ;goto Lb4 ; while B3 < 0 retn ;retlw 0
file: /Techref/intel/16bit/math/radix/16b-5d.htm, 10KB, , updated: 2000/2/28 15:03, local time: 2024/11/16 06:01,
3.145.84.135:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/techref/intel/16bit/math/radix/16b-5d.htm"> intel 16bit math radix 16b-5d</A> |
Did you find what you needed? |