home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / asmutil / bluebook.zip / BCD.ASM next >
Assembly Source File  |  1986-05-08  |  8KB  |  259 lines

  1.                                       COMMENT ~
  2. BCD.ASM -- BCD Conversion Routines
  3.  
  4.   From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
  5.         by Christopher L. Morgan
  6.         Copyright (C) 1984 by The Waite Group, Inc.
  7.  
  8.         >>>>>  See BCD.DOC for complete descriptions of routines.  <<<<<  
  9.  _____________________________________________________________________________ 
  10.  
  11.    Contents:
  12.    ---------
  13.    BCDIN    --  Convert from ASCII Decimal to BCD
  14.    BCDOUT    --  Convert from BCD to ASCII Decimal
  15.    BCD2I16    --  Convert from BCD to 16-bit Binary
  16.    I162BCD    --  Convert from 16-bit Binary to BCD
  17.  _____________________________________________________________________________ 
  18.                                                                               ~
  19. EXTRN    STDIN:FAR,STDOUT:FAR
  20. ;_____________________________________________________________________________ 
  21. ;        
  22. DATAS    SEGMENT    PUBLIC
  23.     BCDBUFF    DB    18 DUP(?)
  24. DATAS    ENDS 
  25. ;_____________________________________________________________________________ 
  26. ;        
  27. CODES    SEGMENT
  28.     PUBLIC BCDIN,BCDOUT,BCD2I16,I162BCD
  29. ASSUME CS:CODES,DS:DATAS
  30. ;______________________________ BCD ROUTINES _________________________________ 
  31. ;Routine to convert from ASCII decimal to internal BCD format.
  32. ;
  33. BCDIN      PROC     FAR
  34.  
  35.       PUSH     DS               ;Save registers
  36.       PUSH     DI
  37.       PUSH     DX
  38.       PUSH     CX
  39.       PUSH     AX
  40. ;
  41. ;Set up data segment
  42.       MOV     DX,DATAS           ;Point to data segment
  43.       MOV     DS,AX
  44. ;
  45. ;Clear BCD buffer
  46.       LEA     DI,BCDBUFF           ;Point to BCD buffer
  47.       MOV     AL,0               ;zero byte
  48.       MOV     CX,18               ;buffer SIze
  49. BCDIN1:
  50.       MOV     [DI],AL           ;zero the byte
  51.       INC     DI               ;Point to next byte
  52.       LOOP     BCDIN1
  53. BCDIN2:
  54. ;
  55. ; get the digit
  56.       CALL     STDIN               ;Digit comes in AL
  57.       SUB     AL,30H            ;Subract 30H
  58.       JL     BCDIN4            ;Check if too low
  59.       CMP     AL,9
  60.       JG     BCDIN4            ;Check if too high
  61. ;
  62. ;Multiply buffer by 10 and add new digit
  63.       LEA     DI,BCDBUFF           ;Point to BCD buffer
  64.       MOV     CX,18               ;buffer SIze
  65. BCDIN3:
  66.       PUSH     CX               ;Save counter
  67.       MOV     DL,AL               ;Save previous digit
  68.       MOV     AL,[DI]           ;Pick up byte from buffer
  69.       MOV     CL,4               ;for a count of 4
  70.       SAL     AX,CL               ;Shift byte left
  71.       OR     AL,DL               ;Combine with previous digit
  72.       MOV     [DI],AL           ;Result goes back
  73.       MOV     AL,AH               ;Prepare for next byte
  74.       AND     AL,0FH            ;Strip to byte
  75.       INC     DI               ;Point to next byte
  76.       POP     CX               ;Restore count
  77.       LOOP     BCDIN3
  78.       JMP     BCDIN2
  79. BCDIN4:
  80.       POP     AX               ;Restore registers
  81.       POP     CX
  82.       POP     DX
  83.       POP     DI
  84.       POP     DS
  85.       RET                   ;Return
  86. BCDIN      ENDP
  87. ;------------------------------------------------------------------------------
  88. ;Routine to convert from internal BCD to ASCII decimal
  89. ;
  90. BCDOUT      PROC     FAR
  91.       PUSH     DS               ;Save registers
  92.       PUSH     SI
  93.       PUSH     DX
  94.       PUSH     CX
  95.       PUSH     AX
  96. ;
  97. ;Set up data segment
  98.       MOV     AX,DATAS           ;Point to data segment
  99.       MOV     DS,AX
  100.       MOV     CX,18               ;for a count of 18
  101.       LEA     SI,BCDBUFF           ;Point ot BCD buffer
  102.       ADD     SI,17               ;Point ot end of BCD buffer
  103.       MOV     DH,0               ;Clear flag for leading zeros
  104. BCDOUT1:
  105.       PUSH     CX               ;Save loop count
  106.       MOV     AL,[SI]           ;get BCD byte
  107.       DEC     SI               ;And point to next
  108.       MOV     DL,AL               ;Save it
  109. ;
  110. ;Upper digit
  111.       MOV     CL,4               ;for a count of 4
  112.       ROL     AL,CL               ;  rotate byte
  113.       AND     AL,0FH            ;just the digit
  114.       OR     DH,AL               ;Leading zeros
  115.       JZ     BCDOUT2           ;if so skip digit
  116.       ADD     AL,30H            ;make ASCII
  117.       CALL     STDOUT            ;Send it out
  118. BCDOUT2:
  119.       POP     CX               ;Restore count
  120.       CMP     CX,1               ;Last digit ?
  121.       JNZ     BCDOUT3           ;Skip in not
  122.       MOV     DH,0FFH           ;  set flag if so
  123. BCDOUT3:
  124.       PUSH     CX               ;Save count
  125.       MOV     AL,DL               ;byte back
  126. ;
  127. ;Lower digit
  128.       AND     AL,0FH            ;just the digit
  129.       OR     DH,AL               ;Leading zeros ?
  130.       JZ     BCDOUT4           ;if so skip digit
  131.       ADD     AL,30H            ;make ASCII
  132.       CALL     STDOUT            ;Send it out
  133. BCDOUT4:
  134.       POP     CX               ;Restore loop count
  135.       LOOP     BCDOUT1
  136.       POP     AX               ;Restore registers
  137.       POP     CX
  138.       POP     DX
  139.       POP     SI
  140.       POP     DS
  141.       RET                   ;Return
  142. BCDOUT      ENDP
  143. ;------------------------------------------------------------------------------
  144. ;Routine to convert from internal BCD to internal 16-bit binary.
  145. ;
  146. BCD2I16   PROC     FAR
  147.       PUSH     DS               ;Save registers
  148.       PUSH     SI
  149.       PUSH     CX
  150.       PUSH     AX
  151. ;
  152. ;Set up data segment
  153.       MOV     AX,DATAS           ;Point of data segment
  154.       MOV     DS,AX
  155. ;
  156. ;Set up loop
  157.       MOV     CX,18               ;initialize counter
  158.       LEA     SI,BCDBUFF           ;Point to buffer
  159.       ADD     SI,17               ;Point to end of BCD buffer
  160.       MOV     DX,0               ;Set DX to zero
  161. BCD2I161:
  162.       PUSH     CX               ;Save loop count
  163.       MOV     AL,[SI]           ;get BCD byte
  164.       DEC     SI               ;And point to next
  165.       MOV     BL,AL               ;Save it
  166. ;
  167. ;Upper digit
  168.       MOV     CL,4               ;for a count of 4
  169.       ROL     AL,CL               ;  rotate byte
  170.       AND     AL,0FH            ;just the digit
  171.       CBW
  172.       PUSH     AX               ;Save digit
  173.       MOV     AX,DX
  174.       MOV     CX,10               ;multiplier of 10
  175.       MUL     CX               ;multiply
  176.       MOV     DX,AX               ;Result in DX
  177.       POP     AX               ;Restore digit
  178.       ADD     DX,AX               ;Add in digit
  179.       MOV     AL,BL               ;byte back
  180. ;
  181. ;Lower digit
  182.       AND     AL,0FH            ;just digit
  183.       CBW
  184.       PUSH     AX               ;Save digit
  185.       MOV     AX,DX
  186.       MOV     CX,10               ;miltiplier of 10
  187.       MUL     CX               ;multiply
  188.       MOV     DX,AX               ;Result in DX
  189.       POP     AX               ;Restore digit
  190.       ADD     DX,AX               ;Add in digit
  191.       POP     CX               ;Restore loop count
  192.       LOOP     BCD2I161
  193.       POP     AX               ;Restore registers
  194.       POP     CX
  195.       POP     SI
  196.       POP     DS
  197.       RET                   ;Return
  198. BCD2I16   ENDP
  199. ;-----------------------------------------------------------------------------
  200. ;Routine to convert from internal 16-bit binary to internal BCD.
  201. ;
  202. I162BCD   PROC     FAR
  203. ;
  204. ;A binary number is in DX
  205.       PUSH     DS               ;Save registers
  206.       PUSH     DI
  207.       PUSH     DX
  208.       PUSH     CX
  209.       PUSH     AX
  210. ;
  211. ;Set up data segment
  212.       MOV     AX,DATAS           ;Point to data segment
  213.       MOV     DS,AX
  214. ;
  215. ;Clear BCD buffer
  216.       LEA     DI,BCDBUFF           ;Point to buffer
  217.       MOV     AL,0               ;zero byte
  218.       MOV     CX,18               ;buffer SIze
  219. I162BCD1:
  220.       MOV     [DI],AL           ;Clear byte
  221.       INC     DI               ;next byte
  222.       LOOP     I162BCD1
  223. ;
  224. ;Put the digits in a buffer
  225.       LEA     DI,BCDBUFF           ;Point to buffer
  226. I162BCD2:
  227.       MOV     AX,DX               ;numerator
  228.       MOV     DX,0               ;Clear upper hALf
  229.       MOV     CX,10               ;Divisor of 10
  230.       DIV     CX               ;Divide
  231.       XCHG     AX,DX               ;get quotient
  232.       MOV     BL,AL               ;Save digit
  233.       MOV     AX,DX               ;numerator
  234.       MOV     DX,0               ;Clear upper hALf
  235.       MOV     CX,10               ;Divisor of 10
  236.       DIV     CX               ;Divide
  237.       XCHG     AX,DX               ;get quotient
  238.       MOV     CL,4               ;for a count of 4
  239.       ROL     AL,CL               ;  rotate digit
  240.       AND     AL,0F0H           ;just the digit
  241.       OR     AL,BL               ;Combine digits
  242.       MOV     [DI],AL           ;Put in buffer
  243.       INC     DI               ;next byte
  244.       CMP     DX,0               ;done ?
  245.       JNZ     I162BCD2
  246.       POP     AX               ;Restore registers
  247.       POP     CX
  248.       POP     DX
  249.       POP     DI
  250.       POP     DS
  251.       RET                   ;Return
  252. I162BCD   ENDP
  253. ;-----------------------------------------------------------------------------
  254. CODES    ENDS
  255. ;
  256.     END
  257. ;_____________________________________________________________________________ 
  258. ;>>>>> Physical EOF BCD.ASM <<<<<
  259.