; MBF - Copyright (c) 1991 by Gary Meeker (07/14/1991) ;+-------------------------------------------------------------------------+ ;| Functions to convert Microsoft Basic Format Singles & Doubles to/from | ;| Long Integers (Replaces MKSMBF$, MKDMBF$, CVSMBF & CVDMBF) | ;| | ;| Syntax - DECLARE FUNCTION Long2Sng$(Num&) | ;| DECLARE FUNCTION Long2Dbl$(Num&) | ;| DECLARE FUNCTION Sng2Long&(Num$) | ;| DECLARE FUNCTION Dbl2Long&(Num$) | ;| | ;| Usage: | ;| A$ = Long2Sng$(Num&) | ;| A$ = Long2Dbl$(Num&) | ;| A& = Sng2Long&(Num$) 'Num$ must be 4 bytes long! | ;| A& = Dbl2Long&(Num$) 'Num$ must be 8 bytes long! | ;| | ;+-------------------------------------------------------------------------+ .Model Medium .Data Desc DW ? ;either 4 or 8 bytes long DW OFFSET OurStr ;Point to our String OurStr DW 4 DUP (?) ;Here is our string .Code Include Mixed.Inc HProc Long2Sng, , Num:Ptr Mov Desc, 4 ;Set the length of return String to 4 Mov BX,Num ;Point to Num& CALL Long2MBF ;Convert it HRet ; HEndp HProc Long2Dbl, , Num:Ptr Mov Desc, 8 ;Set the length of return String to 8 Mov BX,Num ;Point to Num& CALL Long2MBF ;Convert it HRet ; HEndp Long2MBF Proc Near Push DS ;ES needs to point to DS Pop ES ; Cld ;Forward String Directives Xor AX,AX ;Zero our Low Word Mov SI,[BX] ;Get the Low Word of Num& Mov DX,[BX+2] ;Get the High Word of Num& Mov BX,AX ;Zero Lowest Word too Mov CX,SI ;Is it Zero? Or CX,DX ;Maybe, let's see Jcxz LongExit ; Yes, so were done Mov CH,152 ;load the Exponent Mov CL,80h ;We want the sign only And CL,DH ;Get the sign Jns Not_Neg ;It's a Positive Number Not BX ;It's a Negative Number Not AX ; So let's Not SI ; do a 2's Not DX ; compliment Add BX,1 ; of the Adc AX,0 ; whole Adc SI,0 ; 64 bit Adc DX,0 ; number Not_Neg: And DH,7Fh ;strip the sign from DX Cmp DX,7Fh ;Is it above 007FFFFFh ja Above ;Yes Below: ;No Or DL,DL ;Loop until xx80xxxxh (or we hit Zero) Js LongExit ; Done Dec CH ;Decrement the Exponent Shl AX,1 ;Shl DX/SI/AX Rcl SI,1 ; Rcl DX,1 ; Mov DI,AX ;Test DX/SI/AX for Zero Or DI,SI ; Or DI,DX ; Jz LongExit ;If Zero the exit Jmp Below ;Else Loop Above: Or DH,DH ;Loop until 00xxxxxxh Jz LongExit ; Done Inc CH ;Increment Exponent Shr DX,1 ;Shr DX/SI/AX Rcr SI,1 ; Rcr AX,1 ; Jmp Above ;Loop LongExit: And DL,7Fh ;Clear any overflow into sign Or CL,DL ;Combine Sign with High byte Xchg AX,BX ;We need BX first then AX Mov DI, OFFSET OurStr ;Point to our String Cmp Desc, 4 ;Is it Single or Double Je LongSingle ;Single Stosw ;Double so this was BX - stuff it Mov AX,BX ;Now get what was AX Stosw ;Stuff it LongSingle: Mov AX,SI ;Next Word Stosw ;Stuff it Mov AX,CX ;Finally the High Byte, Sign & Exponent Stosw ;Stuff it Mov AX, OFFSET Desc ;Point to our Descriptor for Return Ret Long2MBF Endp HProc Sng2Long, NumStr:Ptr Mov BX,NumStr ;Point to Num$ Descriptor Mov Desc, 4 ;Set the length of return String to 4 CALL MBF2Long ;Convert it HRet ; HEndp HProc Dbl2Long, NumStr:Ptr Mov BX,NumStr ;Point to Num$ Descriptor Mov Desc, 8 ;Set the length of return String to 8 CALL MBF2Long ;Convert it HRet ; HEndp MBF2Long Proc Near Mov CX,[BX] ;Get the Length of Num$ Mov SI,[BX+2] ;Point to Num$ Cmp CX,Desc ;Is it proper length? Je Is_OK ;Yes, so convert Error: Xor AX,AX ;No, Return 0 Mov DX,AX ; Jmp SHORT MBFExit2 ; Is_OK: Cld ;Forward String Directives Cmp Desc,4 ;Single or Double Je MBFSingle ;Single Lodsw ;Double, Get Low word Mov BX,AX Lodsw ;Get 2nd word Mov DI,AX MBFSingle: Lodsw ;Get 3rd word (Or Low Word for Single) Mov DX,AX Lodsw ;Get High Word Mov SI,AX Xchg DX,SI ;High Word to DX, 3rd to SI And DX,007Fh ;Mask off Exponent & Sign Or DX,0080h ;Set High Bit Xor CH,CH ;Zero CH Mov CL,AH ;Exponent to CX And AX,0080h ;Just sign in AX Sub CX,152 ;Adust it - Is Exponent < 152 Jcxz MBFExit ;Done if Exp = 0 Jl Negative ;Yes, so Shr ABS(Exponent) Positive: ;No, so Shl Exponent Shl BX,1 ;Shl DX/SI/DI/BX Rcl DI,1 ; Rcl SI,1 ; Rcl DX,1 ; Or DX,DX ;Test for overflow Js Error ;If overflow then error Loop Positive ; Loop until CX = 0 Jmp SHORT MBFExit Negative: Neg CX ;Make Exponent Positive N2: Shr DX,1 ;Shr DX/SI/DI/BX Rcr SI,1 ; Rcr DI,1 ; Rcr BX,1 ; Loop N2 ; Loop until CX = 0 MBFExit: And AL,080h ;Get sign Mov AX,SI ;Low Word to AX for return, High Word is in DX Jz MBFExit2 ;Done if Positive Not DX ;Other wise Not AX ; do a 2's compliment Add AX,1 ; of the Adc DX,0 ; 32 bit number MBFExit2: Ret MBF2Long Endp End