;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; BSTRING.ASM :- Converts ASCIIZ string to Basic string.
;
;   Helper function for QuickBasic 4.5, Basic PDS 7.1 and
;   Visual Basic for DOS version 1.0.
;
;   You need to use MASM 6 to assemble the program.  To assemble,
;
;           ML  /D<NEAR_STRING | FAR_STRING> /c bstring.asm
;               Default will be FAR_STRING.
;
;
;   Author  : CWLim
;
;   Copyright (c) Creative Technology Ltd, 1993, All rights reserved
;
;
;   Important Note:
;       This source code is only intended as a supplement to the
;       existing Basic functions to facilitate the use of SBK
;       library.
;
;       You can use and modify these functions in any way you find
;       useful, provided that you agree that Creative Technology Ltd
;       has no warranty obligations or liability for any functions
;       which are modified.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      .MODEL large, BASIC

      .DATA

        dwDescriptor  DD  0     ; basic string descriptor

        IFDEF NEAR_STRING  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ; For near string, it is always in near data segment.
          ; Therefore, reserve space on near data segment
          ; for transfering string need to be converted to
          ; near data segment.
          ;
          ; NOTE:
          ;   This only keep the latest string made via
          ;   MakeBasicString$().  Subsequent call to
          ;   MakeBasicString$() will overlay into this
          ;   memory location.

          szNearString  DB  128 DUP(0)

        ENDIF     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      .CODE   CT_TEXT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IFDEF  NEAR_STRING     ;; near string; assemble to string model!!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   Converts ASCIIZ to Basic string.
;
;   FUNCTION sbkMakeBasicString$ (BYVAL lpCString&)
;
;   Entry :
;       lpCString& :- far pointer to null-terminated string
;
;   Exit  :
;       Basic string
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sbkMakeBasicString  PROC    <LOADDS>   USES es si di, lpCString : FAR PTR BYTE

        PUSHF
        CLD
        LES   DI,lpCString

        MOV   CX,0FFFFH                 ; determine string length
        XOR   AL,AL                     ; scan for null character
        REPNE SCASB
        NOT   CX
        DEC   CX
        MOV   AX,CX
        PUSH  DS
                                        ; transfer string to near data segment.
        MOV   BX,SEG    szNearString    ; destination
        MOV   ES,BX
        MOV   DI,OFFSET szNearString
        LDS   SI,lpCString              ; source
        REP   MOVSB
        POP   DS

        LEA   BX,dwDescriptor           ; make string descriptor
        MOV   WORD PTR [BX],AX          ; string length
        LEA   AX,szNearString
        MOV   WORD PTR [BX+2], AX       ; string offset

        MOV   AX,BX                     ; return string descriptor
        POPF
        RET
sbkMakeBasicString  ENDP


ELSE    ;;;;;;;;;;;;  default to far string  ;;;;;;;;;;;;;;;;;;;;;;;;;;

sbkMakeBasicString  PROC    <LOADDS>     USES es di,    lpCString : FAR PTR BYTE

        PUSHF
        CLD
        LES   DI,lpCString
        PUSH  ES                        ; param 1 for StringAssign
        PUSH  DI                        ; param 2

        MOV   CX,0FFFFH                 ; determine string length
        XOR   AL,AL                     ; scan for null character
        REPNE SCASB
        NOT   CX
        DEC   CX
        PUSH  CX                        ; param 3; indicates fixed length

        PUSH  DS                        ; param 4
        LEA   AX,dwDescriptor           
        PUSH  AX                        ; param 5
        XOR   AX,AX
        PUSH  AX                        ; param 6; indicates variable length

        EXTERN StringAssign: PROTO FAR  ; Basic routine
        CALL  StringAssign

        LEA   AX,dwDescriptor           ; return string descriptor
        POPF
        RET
sbkMakeBasicString  ENDP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   Releases string created with sbkMakeBasicString$()
;
;   SUB sbkReleaseBasicString ()
;
;   Entry :
;
;   Exit  :
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sbkReleaseBasicString  PROC    <LOADDS>

        LEA   BX,dwDescriptor
        MOV   AX,WORD PTR [BX]
        OR    AX,AX                     ; any string created previously?
        JZ    @@1
        PUSH  BX                        ; preserve BX

        PUSH  BX
        EXTERN StringRelease: PROTO FAR ; Basic routine
        CALL  StringRelease

        POP   BX
        MOV   WORD PTR [BX],0           ; indicates string is released.
@@1:
        RET
sbkReleaseBasicString  ENDP


ENDIF   ;;;;;;;;;;;;;  End string defined  ;;;;;;;;;;;;;;;;;;;

	    END
