;From Eli Bennett - Floating point prog

     .model small
     .STACK    200H
     .data
          Digits         DB   '0123456789'   ;hex to dec conversion string
          FP1o2          DW   0000H          ;store hole numbers
          FP2o2          DB   8    dup(0)    ;store fractional numbers
          MaxDecPlaces   DB   8              ;num of decimal places in
                                             ;variable FP2o2
     .code
BEGIN:
               MOV  AX,@DATA                 ;load ds with the data
               MOV  DS,AX                    ;segment
               MOV  AX,0B800H                ;LOAD ES WITH VIDEO SEGMENT
               MOV  ES,AX                    ;
               MOV  SI,OFFSET FP1o2          ;required by DivAndFloat
               XOR  CH,CH                    ;zero ch
               MOV  CL,MaxDecPlaces          ;required by DivAndFloat
               MOV  AX,1                     ;value to vivide
               MOV  DX,2                     ;value to divide by
               CALL DivAndFloat              ;do the math!
               ;---------Display numbers after decimal point-----------------
               XOR  CH,CH                    ;zero ch
               MOV  CL,MaxDecPlaces          ;required by DispNum
               MOV  DI,320                   ;WHERE TO START DISPLAYING
               CALL DispNum                  ;display the numbers after
                                             ;the decimal point
               ;-------------------------------------------------------------
               MOV  AX,4C00H                 ;return to dos
               INT  21H

;----------------------------------------------------------------------------
;                             DivAndFloat proc__
;    Must pass
;              CL = MaxDecPlaces   how many decimal places to calculate
;              AX =                value to divide
;              BX =                value to divide by
;    pointer   DS:SI               point to mem variable to hold final result
;----------------------------------------------------------------------------
DivAndFloat    PROC
               CMP  BX,0                     ;will the answere be 0
               JZ   DoneFloat
               CMP  AX,0                     ;will the answere be 0
               JZ   DoneFloat
               XOR  DX,DX                    ;zero dx
               CMP  BX,AX                    ;will there be a whole number?
               JG   FloatingP                ;if not go strait to the
                                             ;floating point process
StartDiv:      NOP
               DIV  BX                       ;divide
               MOV  WORD PTR [DS:SI],AX      ;store the whole number
               CMP  DX,0                     ;is their a remainder?
               JZ   DoneFloat                ;if not we are done
               INC  SI                       ;point to the fractional number
               INC  SI                       ;holding array
               JMP  FloatLoop                ;DX holds remainder already 
FloatingP:     NOP
               MOV  DX,AX                    ;The value to divide was the
                                             ;remainder
               INC  SI                       ;point to the fractional number
               INC  SI                       ;holding array
FloatLoop:     NOP
               MOV  AX,DX                    ;put remainder in AX to mul by 10
DoMulByTen:
               PUSH BX                       ;save value to divide by
               MOV  BX,000AH                 ;remainder will be less than BX
               MUL  BX                       ;so multiply by 10 then divide
                                             ;the remainder by BX
               POP  BX                       ;restore value to divide by
               CMP  AX,BX                    ;make sure divide will work
               JGE  DoneMul                  ;if so divide
               INC  SI                       ;if not mov a decimal place
               JMP  DoMulByTen               ;Multiply again
DoneMul:
               DIV  BX                       ;divide
               MOV  BYTE PTR [SI],AL         ;store the fractional number
               CMP  DX,0                     ;is their a remainder?
               JZ   DoneFloat                ;if not we are done
               INC  SI                       ;point to next decimal place
               LOOP FloatLoop
               JMP  DoneFloat                ;finished calculating
DoneFloat:     NOP
               RET                           ;return to caller
               ENDP                          ;end of DivAndFloat

;----------------------------------------------------------------------------
;              DispNum i a process to display the    (txt mode only)
;              values in FP2o2 
;
;    Must pass
;              cx = MaxDecPlaces
;    pointer   DI     WHERE TO START DISPLAYING on the screen
;              ES:    point to video segment
;              DS:    data segment
;    kills     BX
;              AX
;----------------------------------------------------------------------------
DispNum        PROC
               MOV  AL,'.'                   ;CHAR TO SHOW
               MOV  [ES:DI],AL               ;SHOW CHAR
               INC  DI                       ;POINT TO NEXT CHR
               INC  DI                       ;skip atr
               XOR  BX,BX                    ;zero ax
ShowNumLoop:
               XOR  DX,DX                    ;ZERO DX
               MOV  SI,OFFSET FP2o2          ;offset of FRACTION VALS
               MOV  DL,BL                    ;SI MUST POINT TO NEXT VAL TO
               ADD  SI,DX                    ;CONVERT
               MOV  BH,[DS:SI]               ;get the current fractional val
               INC  BL                       ;POINT TO NEW FRACT VAL
               MOV  SI,OFFSET Digits         ;POINT TO CONVERSION VARIABLE
               XOR  DX,DX                    ;ZERO DX
               MOV  DL,BH                    ;SI MUST POINT TO VAL TO
               ADD  SI,DX                    ;DISPLAY
               MOV  AH,[DS:SI]               ;GET ASCII VAL
               MOV  [ES:DI],AH               ;DISPLAY THE CHARACTER
               INC  DI                       ;POINT TO NEXT CHR
               INC  DI                       ;skip the atr 
               LOOP ShowNumLoop              ;is cx zero
               RET                           ;RETURN TO CALLER
               ENDP
;----------------------------------------------------------------------------

END            BEGIN

