'===========================================================================
' Subject: MICROSOFT MBF SUPPORT              Date: 06-29-98 (16:58)       
'  Author: Dave Navarro, Jr.                  Code: PBCC                   
'  Origin: dave@powerbasic.com              Packet: PBCC.ABC
'===========================================================================
'*********** CVSMBF.ASM - PDQ replacement for BASIC's B$MCVS routine
'code by Ethan Winer using code derived from Cobb's Inside
'Assembler newsletter (after fixing the code to handle zero properly!)
'converted to PB/DLL 5.0 by Dave Navarro, Jr. (8/25/97)

FUNCTION CVMS (x AS STRING) EXPORT AS SINGLE

  LOCAL outp AS SINGLE

  ! mov EBX, x              ; EBX = string handle
  ! mov EBX, DWord Ptr [EBX] ; EBX = address of string data
  ! mov AX, Word Ptr [EBX]  ; grab the low word
  ! mov outp, AX            ; store it in the output

  ! mov AX, [EBX+2]         ; now grab the high word
  ! or  AH, AH              ; is the exponent zero?
  ! jz  notzero             ;

  ! sub AH, 2               ; fix the exponent
  ! rcl AL, 1               ; slide the sign bit into the carry flag
  ! rcr AX, 1               ; and then slide the sign and exponent into place
NotZero:
  ! mov outp[2], AX         ; store that in the output too

  FUNCTION = outp

END FUNCTION

'******** MKSMBF.ASM - PDQ replacement for BASIC's B$FMSF routine
'by Ethan Winer using code derived from Cobb's Inside Assembler newsletter
'(after fixing the code to handle zero properly!)
'converted to PB/DLL 5.0 by Dave Navarro, Jr. (8/25/97)

FUNCTION MKMS (BYVAL s AS SINGLE) EXPORT AS STRING

  LOCAL outp AS STRING PTR * 4

  ! mov AX, s[2]        ; convert the number to MBF in place on the stack
  ! rcl AX, 1           ; slide the sign bit into the carry flag
  ! rcr AL, 1           ; and then into the correct bit position for MBF

  ! or  AX, AX          ; is the exponent zero?
  ! je  itszero         ; yes, skip ahead
  ! add AH, 2           ; no, adjust the exponent bias
itszero:
  ! mov  s[2], AX       ; copy the adjusted value back onto the stack

  outp = VARPTR(s)      '
  FUNCTION = @outp      '

END FUNCTION

'******** CVDMBF.ASM - PDQ replacement for BASIC's B$FMSF routine
'by Ethan Winer using code derived from Cobb's Inside Assembler newsletter
'(after fixing the code to handle zero properly!)
'converted to PB/DLL 5.0 by Dave Navarro, Jr. (6/29/98)

FUNCTION CVMD(BYVAL x AS STRING) EXPORT AS SINGLE

  LOCAL outp AS SINGLE

  ! mov EBX, x              ; EBX = string handle
  ! mov EBX, DWORD PTR [EBX] ; EBX = address of string data

  ! mov  AX,[EBX+06]         ;load AX:DX:BX:DI with the four MBF words
  ! mov  DX,[EBX+04]
  ! mov  BX,[EBX+02]
  ! mov  DI,[EBX]

  ! mov  CX,3               ;the number of bits to shift

Do1:
  ! shr  AL,1               ;shift the mantissa right one place
  ! rcr  DX,1
  ! rcr  BX,1
  ! rcr  DI,1
  ! loop Do1

  ! or   AH,AH              ;is the exponent zero?
  ! jnz  F1                 ;no, continue
  ! mov  AL,AH              ;yes, assign all zeros
  ! mov  Outp,AX            ;store the lower three words here
  ! mov  Outp[02],AX        ;
  ! mov  Outp[04],AX      ;
  ! jmp  Short Zero         ;and skip ahead to assign the highest word
F1:
  ! mov  Outp, DI         ;store the lower three words
  ! mov  Outp[02],BX
  ! mov  Outp[04],DX

  ! mov  DL,AL              ;swap the sign and exponent bits
  ! mov  AL,AH
  ! sub  AH,AH
  ! add  AX,&H37E           ;adjust the exponent bias
  ! test DL,&H10            ;is the sign bit set?
  ! jz   F2                 ;no, skip ahead
  ! or   AH,8               ;yes, so set the IEEE sign bit too
F2:
  ! mov  CL,4
  ! shl  AX,CL
  ! and  DL,&H0F
  ! or   AL,DL

Zero:
  ! mov  Outp[06],AX      ;store the result

  FUNCTION = outp

END FUNCTION

'******** MKDMBF.ASM - PDQ replacement for BASIC's B$FMDF routine
'by Ethan Winer using code derived from Cobb's Inside Assembler newsletter
'(after fixing the code to handle zero properly!)
'converted to PB/DLL 5.0 by Dave Navarro, Jr. (6/29/98)

FUNCTION MKMD$(BYVAL d AS DOUBLE) EXPORT AS STRING

  LOCAL outp AS STRING PTR * 4

  ! mov  AX,Word Ptr d[6]       ;copy the high word into AX
  ! mov  DX,AX          ;keep a copy for later
  ! mov  CL,4           ;number of bits to shift
  ! shr  AX,CL          ;shift 'em good


  ! and  AX,&H7FF       ;mask off the sign bit
  ! jz   F3             ;if the exponent is zero skip over
  ! sub  AX,&H37E       ;adjust the exponent bias only if non-zero!

F3:
  ! mov  Byte Ptr d[7],AL       ;store just the exponent

  ! mov  AX,DX          ;load the copy of the high word into AX again
  ! mov  SI,Word Ptr d[0]       ;and then load the rest into DX:BX:SI
  ! mov  BX,Word Ptr d[2]
  ! mov  DX,Word Ptr d[4]
  ! mov  CX,3           ;the number of times to shift bits

F4:
  ! shl  SI,1           ;shift the mantissa left one place
  ! rcl  BX,1
  ! rcl  DX,1
  ! rcl  AL,1
  ! loop F4

  ! shl  AX,1           ;shift the sign bit into the Carry flag
  ! rcr  AL,1

  ! mov  Word Ptr d[0],SI       ;store the output back onto the stack
  ! mov  Word Ptr d[2],BX
  ! mov  Word Ptr d[4],DX
  ! mov  Byte Ptr d[6],AL

  outp = VARPTR(d)
  FUNCTION = @outp

END FUNCTION
