home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / math / numvert.asm < prev    next >
Assembly Source File  |  1992-12-07  |  22KB  |  399 lines

  1. ;; NUMVERT.ASM 
  2. ;;  
  3. ;; Useful decimal, hexidecimal and binary conversion routines.
  4. ;;
  5. ;; This program can be assembled using the A86 or TASM assemblers 
  6. ;;
  7. ;; Not tested with Masm, should work?
  8. ;;
  9. ;; This code is "PUBLIC DOMAIN"
  10. ;;
  11. ;; by William Cravener 12/07/92
  12. ;;
  13. ;---------------------------------------------------------
  14. ;;
  15. code                    SEGMENT
  16. ASSUME          cs:code, ds:code, es:code, ss:code
  17. ORG             100h                              ; COM files begin here
  18. start:
  19.         jmp     begin
  20. ;;
  21. ;----------------------------------------------------------------
  22. ;;
  23. input_buffer            DB      18                ; maximum of 18 numbers
  24.                         DB      0                 ; actual length of input
  25.                         DB      19 DUP (0)        ; room for carriage
  26. ;;
  27. decimal                 DB      'DECIMAL = ', 0
  28. hexidecimal             DB      '    HEX = ', 0
  29. binary                  DB      ' BINARY = ', 0
  30. ;;
  31. explain                 DB      0dh, 0ah, 'Number Conversion by »-Swift-Ware-', 0dh, 0ah
  32.                         DB      0dh, 0ah, 'Decimal to - 65535'
  33.                         DB      0dh, 0ah, 'Hexidecimal to - FFFFH'
  34.                         DB      0dh, 0ah, 'Binary to - 1111111111111111B'
  35.                         DB      0dh, 0ah, 'Include H or B at end of number.'
  36.                         DB      0dh, 0ah, 0ah, 'Enter number: $' 
  37. ;;
  38. ;----------------------------------------------------------------;
  39. ;;
  40. begin:
  41.         call    clear_screen            ; first clear the screen
  42.         mov     dx, OFFSET explain      ; point to explanation
  43.         mov     ah, 9                   ; display string function
  44.         int     21h                     ; the interrupt
  45.         mov     dx, OFFSET input_buffer ; point to buffer storage
  46.         push    dx                      ; save pointer on stack
  47.         mov     ah, 0ah                 ; use DOS buffered input
  48.         int     21h                     ; the interrupt
  49.         pop     di                      ; pop pointer into DI
  50.         inc     di                      ; point to input length
  51.         push    di                      ; save new pointer location
  52.         mov     cl, BYTE PTR [di]       ; place input length in CL
  53.         add     di, cx                  ; add length to offset
  54.         cmp     BYTE PTR [di], 'a'      ; is it uppercase?
  55.         jb      isup                    ; if neccessary
  56.         cmp     BYTE PTR [di], 'z'      ; make it so
  57.         ja      isup                    ; by -
  58.         sub     BYTE PTR [di], 20h      ; subtraction
  59. isup:
  60.         cmp     BYTE PTR [di], 'B'      ; is it a binary number?
  61.         je      be_binary_number        ; yes - need binary convert
  62.         cmp     BYTE PTR [di], 'H'      ; is it a hexidecimal number
  63.         je      be_hexidecimal_number   ; yes - need hex convert
  64. be_decimal_number:
  65.         inc     di                      ; wasn't the above must be decimal
  66.         mov     BYTE PTR [di], 0        ; end input string with a "0"
  67.         pop     si                      ; pop saved pointer into SI
  68.         inc     si                      ; point to beginning of string
  69.         call    ascdec_2_bin            ; make it a binary value
  70.         jmp     show_the_numbers        ; show all three converted formats
  71. be_binary_number:
  72.         mov     BYTE PTR [di], 0        ; end input string with a "0"
  73.         pop     si                      ; pop saved pointer into SI
  74.         inc     si                      ; point to beginning of string
  75.         dec     cx                      ; binary routine needs number of chars
  76.         call    ascbin_2_bin            ; make it a binary value
  77.         jmp     show_the_numbers        ; show all three converted formats
  78. be_hexidecimal_number:
  79.         mov     BYTE PTR [di], 0        ; end input string with a "0"
  80.         pop     si                      ; pop saved pointer into SI
  81.         inc     si                      ; point to beginning of string
  82.         call    aschex_2_bin            ; make it a binary value
  83. show_the_numbers: 
  84.         call    cr_lf                   ; do a CR LF pair
  85.         call    show_decimal            ; display as a ASCII decimal 
  86.         call    show_hexidecimal        ; display as a ASCII hexidecimal
  87.         call    show_binary             ; display as a ASCII binary
  88.         int     20h                     ; finished exit to DOS
  89. ;----------------------------------
  90. show_decimal:                           ; routine displays ascii decimal
  91.         push    dx                      ; save binary value on stack
  92.         call    cr_lf                   ; do a CR LF pair 
  93.         push    si                      ; save buffer pointer 
  94.         mov     si, OFFSET decimal      ; point to DECIMAL =
  95.         call    write_string            ; write it to screen 
  96.         pop     si                      ; pop buffer pointer off stack
  97.         call    bin_2_ascdec            ; make DX value a ascii decimal
  98.         call    write_string            ; write it to screen
  99.         call    cr_lf                   ; do a CR LF pair
  100.         pop     dx                      ; retrieve binary value off stack
  101.         ret
  102. show_hexidecimal:                       ; routine displays ascii hexidecimal
  103.         push    dx                      ; save binary value on stack
  104.         call    cr_lf                   ; do a CR LF pair
  105.         push    si                      ; save buffer pointer
  106.         mov     si, OFFSET hexidecimal  ; point to HEX =
  107.         call    write_string            ; write it to screen
  108.         pop     si                      ; pop buffer pointer off stack
  109.         call    bin_2_aschex            ; make DX value a ascii decimal
  110.         call    write_string            ; write it to screen
  111.         call    cr_lf                   ; do a CR LF pair
  112.         pop     dx                      ; retrieve binary value off stack
  113.         ret
  114. show_binary:                            ; routine displays ascii binary
  115.         push    dx                      ; save binary value on stack
  116.         call    cr_lf                   ; do a CR LF pair
  117.         push    si                      ; save buffer pointer
  118.         mov     si, OFFSET binary       ; point to BINARY =
  119.         call    write_string            ; write it to screen
  120.         pop     si                      ; pop buffer pointer off stack
  121.         call    bin_2_ascbin            ; make DX value a ascii decimal
  122.         call    write_string            ; write it to screen
  123.         call    cr_lf                   ; do a CR LF pair
  124.         pop     dx                      ; retrieve binary value off stack
  125.         ret
  126. ;----------------------------------
  127. write_string:                           ; BIO's teletype function
  128.         push    si                      ; save SI on stack
  129.         mov     ah, 0eh                 ; to monitor
  130.         mov     bh, 0                   ; page 0
  131. num_jump:
  132.         lodsb                           ; get character
  133.         cmp     al, 0                   ; 0 if end of string
  134.         je      done                    ; done if so
  135.         int     10h
  136.         jmp     num_jump                ; get another character
  137. done:
  138.         pop     si                      ; retrieve SI from stack
  139.         ret
  140. ;----------------------------------
  141. cr_lf:                                  ; CR LF routine
  142.         mov     ah, 0eh                 ; BIO's teletype function
  143.         mov     bh, 0
  144.         mov     al, 0dh                 ; carriage
  145.         int     10h                     ; do it
  146.         mov     ah, 0eh
  147.         mov     al, 0ah                 ; linefeed
  148.         int     10h                     ; do it
  149.         ret
  150. ;----------------------------------
  151. clear_screen:                           ; clears screen routine
  152.         mov     ah, 8                   ; retrieve attribute function
  153.         mov     bh, 0                   ; page 0
  154.         int     10h
  155.         mov     bh, ah                  ; current screen color
  156.         mov     ah, 6                   ; scroll function
  157.         mov     al, 0                   ; whole screen
  158.         mov     cx, 0                   ; upper left
  159.         mov     dx, 184fh               ; lower right
  160.         int     10h
  161.         mov     ah, 2                   ; set cursor
  162.         mov     bh, 0                   ; page 0
  163.         mov     dx, 0                   ; top left
  164.         int     10h
  165.         ret
  166. ;================================================================;
  167. ;================================================================;
  168. ;    NUMBER CONVERTING SUBROUTINES FROM HERE DOWN.               ;
  169. ;                                                                ;
  170. ;       BIN_2_ASCDEC  -----  binary to ascii decimal.            ;
  171. ;                                                                ;
  172. ;       BIN_2_ASCHEX  -----  binary to ascii hexidecimal.        ;
  173. ;                                                                ;
  174. ;       BIN_2_ASCBIN  -----  binary to ascii binary.             ;
  175. ;                                                                ;
  176. ;       ASCDEC_2_BIN  -----  ascii decimal to binary.            ;
  177. ;                                                                ;
  178. ;       ASCHEX_2_BIN  -----  ascii hexidecimal to binary.        ;
  179. ;                                                                ;
  180. ;       ASCBIN_2_BIN  -----  ascii binary to binary.             ;
  181. ;                                                                ;
  182. ;================================================================;
  183. ;================================================================;
  184. ;----------------------------------------------------------------;
  185. ; Convert 16-bit binary in DX register to ASCII decimal number.  ;
  186. ;                                                                ;
  187. ; On entry:                                                      ;
  188. ;         SI - points to 6 byte output buffer.                   ;
  189. ;         DX = 16 bit binary number.                             ;
  190. ; On return:                                                     ;
  191. ;         SI - points to resulting ASCII decimal number.         ;
  192. ;----------------------------------------------------------------;
  193. bin_2_ascdec:
  194.         mov     di, si                  ; copy SI into DI
  195.         mov     cx, 6                   ; 6 digits to clear
  196.         mov     al, 0                   ; fill it with "0"s
  197.         cld                             ; forward direction
  198.         repe    stosb                   ; clear 6 places
  199.         sub     di, 2                   ; left 2 for start address
  200.         std                             ; store in reverse order
  201. make_it_ascii:  
  202.         mov     ax, dx                  ; add in numerator
  203.         mov     dx, 0                   ; clear top half
  204.         mov     cx, 10                  ; enter decimal divisor
  205.         div     cx                      ; perform division AX/CX
  206.         xchg    ax, dx                  ; get quotient
  207.         add     al, 30h                 ; make digit ASCII
  208.         stosb                           ; store digit in buffer
  209.         cmp     dx, 0                   ; test for end of binary
  210.         jnz     make_it_ascii           ; continue if not end
  211.         inc     di                      ; right 1 for beginning 
  212.         mov     si, di                  ; SI = start of number string
  213.         cld                             ; restore direction flag
  214.         ret
  215. ;----------------------------------------------------------------;
  216. ; Convert a 16-bit binary in the DX register to an ASCII         ;
  217. ;  hexadecimal number.                                           ;
  218. ;                                                                ;
  219. ; On entry:                                                      ;
  220. ;         SI - points to 6 byte output buffer.                   ;
  221. ;         DX = 16 bit binary number.                             ;
  222. ; On return:                                                     ;
  223. ;         SI - points to resulting ASCII hexidecimal number.     ;
  224. ;              ( number ends with H )                            ;
  225. ;----------------------------------------------------------------;
  226. bin_2_aschex:
  227.         mov     di, si                  ; copy SI into DI
  228.         push    di                      ; save user's buffer pointer
  229.         mov     cx, 6                   ; 6 digits to clear
  230.         mov     al, 0                   ; fill it with "0"s
  231.         cld                             ; forward direction
  232.         repe    stosb                   ; clear 6 places
  233.         sub     di, 2                   ; left 2 for "H"
  234.         mov     BYTE PTR [di], 'H'      ; place "H" in buffer
  235.         pop     di                      ; restore buffer pointer
  236.         mov     cx, 4                   ; count 4 digits
  237. hex_cvr:
  238.         push    cx                      ; save counter
  239.         mov     cl, 4                   ; 4 digits
  240.         rol     dx, cl                  ; rotate source left
  241.         mov     al, dl                  ; move digit into AL
  242.         and     al, 15                  ; clear high nibble
  243.         daa                             ; adjust AL if A through F
  244.         add     al, 240                 ; and bump the carry
  245.         adc     al, 40h                 ; convert hex to ASCII
  246.         stosb                           ; store in buffer
  247.         pop     cx                      ; restore digit counter
  248.         loop    hex_cvr                 ; continue with next digit
  249.         ret
  250. ;-------------------------------------------------------------------;
  251. ; Convert a 16-bit binary number in DX into 16 ASCII binary digits. ;
  252. ;                                                                   ;
  253. ; On entry:                                                         ;
  254. ;         SI - points to 18 byte output buffer.                     ;
  255. ;         DX = 16 bit binary number.                                ; 
  256. ; On return:                                                        ;
  257. ;         SI - points to resulting ASCII binary number.             ;
  258. ;              ( number ends with B )                               ;
  259. ;-------------------------------------------------------------------;
  260. bin_2_ascbin:
  261.         mov     di, si                  ; copy SI into DI
  262.         push    di                      ; save user's buffer pointer
  263.         mov     cx, 18                  ; 18 digits to clear
  264.         mov     al, 0                   ; fill it with "0"s
  265.         cld                             ; forward direction
  266.         repe    stosb                   ; clear 18 digits
  267.         sub     di, 2                   ; left 2 for "B"
  268.         mov     BYTE PTR [di], 'B'      ; place "B" in buffer
  269.         pop     di                      ; start of buffer
  270.         mov     cx, 8                   ; convert 8 bits of MSB
  271. bin_cvr_dh:
  272.         test    dh, 128                 ; test high-order bit
  273.         jnz     set_1_dh                ; go set bit 
  274.         mov     BYTE PTR [di], '0'      ; set bit to 0
  275.         jmp     next_bin_dh
  276. set_1_dh:
  277.         mov     BYTE PTR [di], '1'      ; set bit to 1
  278. next_bin_dh:
  279.         inc     di                      ; bump pointer
  280.         sal     dh, 1                   ; shift bits left once
  281.         loop    bin_cvr_dh              ; do all of DH
  282.         mov     cx, 8                   ; convert 8 bits of LSB
  283. bin_cvr_dl:
  284.         test    dl, 128                 ; test high-order bit
  285.         jnz     set_1_dl                ; go set bit 
  286.         mov     BYTE PTR [di], '0'      ; set bit to 0
  287.         jmp     next_bin_dl
  288. set_1_dl:
  289.         mov     BYTE PTR [di], '1'      ; set bit to 1
  290. next_bin_dl:
  291.         inc     di                      ; bump pointer
  292.         sal     dl, 1                   ; shift bits left once
  293.         loop    bin_cvr_dl              ; do all of DL
  294.         ret
  295. ;------------------------------------------------------;
  296. ; Convert an ASCII decimal number to a binary value.   ;
  297. ;                                                      ;
  298. ; On entry:                                            ; 
  299. ;         SI - points to 5 digit ASCII decimal string. ;
  300. ;              ( range 0 to 65535 )                    ;
  301. ; On return:                                           ;
  302. ;         DX = resulting binary value.                 ;
  303. ;------------------------------------------------------;
  304. ascdec_2_bin:
  305.         push    si                      ; save pointer to buffer
  306.         mov     dx, 0                   ; Clear binary output
  307. ascdecbin:
  308.         lodsb                           ; get ascii value into AL
  309.         sub     al, 30h                 ; ASCII to decimal
  310.         jl      not_ascii               ; exit if invalid ASCII
  311.         cmp     al, 9                   ; test for highest value
  312.         jg      not_ascii               ; exit if larger than 9
  313.         cbw                             ; byte to Word
  314.         push    ax                      ; save digit in stack
  315.         mov     ax, dx                  ; move into output register
  316.         mov     cx, 10                  ; decimal multiplier
  317.         mul     cx                      ; perform AX = AX * 10
  318.         mov     dx, ax                  ; move product to output register
  319.         pop     ax                      ; restore decimal digit
  320.         add     dx, ax                  ; add in digit
  321.         jmp     ascdecbin               ; continue
  322. not_ascii: 
  323.         pop     si                      ; restore start of buffer
  324.         ret
  325. ;----------------------------------------------------------;
  326. ; Convert an ASCII hexidecimal number to a binary value.   ;
  327. ;                                                          ;
  328. ; On entry:                                                ;
  329. ;         SI - points to 4 digit ASCII hexidecimal string. ;
  330. ;              ( range 0 to FFFF )                         ;
  331. ; On return:                                               ;
  332. ;         DX = resulting binary value.                     ;   
  333. ;----------------------------------------------------------;
  334. aschex_2_bin:
  335.         push    si                      ; save pointer to buffer
  336.         mov     dx, 0                   ; clear binary output
  337. aschexbin:
  338.         lodsb                           ; get ASCII digit
  339.         cmp     al, '0'                 ; is it less then "0"
  340.         jb      ascii_not               ; yes - invalid character
  341.         cmp     al, '9'                 ; equal or less then "9"
  342.         jbe     strip                   ; yes - go strip high 4 bits
  343.         and     al, 5fh                 ; make letter upper case
  344.         cmp     al, 'A'                 ; less then ascii "A"
  345.         jb      ascii_not               ; yes - invalid character
  346.         cmp     al, 'F'                 ; greater then ascii "F"
  347.         ja      ascii_not               ; yes - invalid character
  348.         add     al, 9                   ; its good add 9 for strip
  349. strip:
  350.         and     al, 0fh                 ; strip off the high 4 bits
  351.         mov     cl, 4                   ; set shift count
  352.         shl     dx, cl                  ; rotate DX 4 bits
  353.         xor     ah, ah                  ; zero out AH
  354.         add     dx, ax                  ; add digit to value
  355.         jmp     aschexbin               ; continue
  356. ascii_not: 
  357.         pop     si                      ; restore start of buffer
  358.         ret
  359. ;-----------------------------------------------------------;
  360. ; Convert a 16-digit ASCII binary number to a binary value. ;
  361. ;                                                           ;
  362. ; On entry:                                                 ;
  363. ;         SI - points to 16 character ASCII binary string.  ;
  364. ;              ( range 0 to 1111111111111111 )              ;
  365. ;         CX = Length of ASCII binary string.               ;
  366. ; On return:                                                ;
  367. ;         DX = resulting binary value.                      ;
  368. ;-----------------------------------------------------------;
  369. ascbin_2_bin:
  370.         mov     di, si                  ; copy SI into DI
  371.         add     di, cx                  ; point to end of string
  372.         mov     bx, 2                   ; 2 = binary base value
  373.         mov     cx, 1                   ; Initialize multiplier
  374.         xor     ax, ax                  ; zero out AX
  375. nxt_cvt:
  376.         cmp     di, si                  ; at front of string yet?
  377.         je      at_front                ; if equal - have it all!
  378.         dec     di                      ; next character to left
  379.         mov     dl, [di]                ; load the character
  380.         sub     dl, 30h                 ; convert to decimal
  381.         xor     dh, dh                  ; ZERO out DH
  382.         push    cx                      ; save CX on stack
  383.         xchg    ax, cx                  ; AX = multiplier
  384.                                         ; CX = partial value
  385.         mul     dx                      ; digit value * multiplier
  386.         add     cx, ax                  ; add to partial value
  387.         pop     ax                      ; restore multiplier
  388.         mul     bx                      ; base times multiplier
  389.         xchg    ax, cx                  ; AX = paritial value
  390.                                         ; CX = new multiplier
  391.         jmp     nxt_cvt                 ; go do next digit
  392. at_front: 
  393.         mov     dx, ax                  ; copy result into DX
  394.         ret
  395. ;------------------------------------------------------------
  396. code                    ENDS
  397.  
  398. END             start
  399.