;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  @@ Source Documentation           *** MASM 6.0 Version ***
;;
;;  Title   :   FILEIO.ASM
;;
;;  DOS file I/O helper functions for QuickBasic 4.5, Basic PDS 7.1,
;;  Visual Basic for DOS version 1.0, Turbo Pascal 6.0, Turbo Pascal 7.0.
;;  and Turbo C 2.0.
;;
;;  Functions are:
;;      sbkDosOpen
;;      sbkDosCreate
;;      sbkDosClose
;;      DosRead
;;      DosWrite
;;      sbkDosLSeek
;;      sbkFileSize
;;      sbkFindFile
;;      sbkFindFirst
;;      sbkFindNext
;;
;;
;;  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.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

INCLUDE     sbkmodel.inc

            .CODE   CodeSegmentName

    dwTempStore     DD      ?       ; temporary storage


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Open an existing file via DOS interrupt 21H function 3DH.
;;
;;  function sbkDosOpen (char far * lpFilename)
;;
;;  Entry:
;;      lpFilename :- far pointer to the name of the file to be opened.
;;
;;  Exit:
;;      File handle if successful, else returns -1.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   sbkDosOpen	    PROC    <loaddsIF>	    lpFilename : far ptr byte

    mov     ax, 3D00H
    lds     dx, lpFilename
    int     21H

    ; carry flag set if error
    JNC     pass1
    mov     ax, -1

pass1:
    ret

sbkDosOpen  ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Creates a new file via DOS interrupt 21H function 3CH.
;;
;;  function sbkDosCreate (char far * lpFilename)
;;
;;  Entry:
;;      lpFilename :- far pointer to the name of the file to be created.
;;
;;  Exit:
;;      File handle if successful, else returns -1.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   sbkDosCreate    PROC    <loaddsIF>	    lpFilename : far ptr byte

    mov     ax, 3C00H
    mov     cx, 20H
    lds     dx, lpFilename
    int     21H

    ; carry flag set if error
    JNC     pass2
    mov     ax, -1

pass2:
    ret

sbkDosCreate	ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Closes a file.
;;
;;  procedure sbkDosClose (word wFileHandle)
;;
;;  Entry:
;;      wFileHandle :- handle of file to be closed.
;;
;;  Exit:
;;      none.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   sbkDosClose     PROC    <loaddsIF>	    wFileHandle : word

    push    bx
    mov     ax, 3E00H
    mov     bx,	wFileHandle
    int     21H
    pop     bx
    ret

sbkDosClose	ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Read data from file into buffer.
;;
;;  function DosRead (wFileHandle%, wSegment%, wOffset%, wSize%)
;;
;;  Entry:
;;      wFileHandle% :- handle of file to read
;;      wSegment%    :- segment address of the memory buffer
;;      wOffset%     :- offset address of the memory buffer
;;      wSize%       :- number of bytes to read
;;
;;  Exit:
;;      Number of bytes read if sucessful, else returns 0.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   DosRead	    PROC    <loaddsIF>	    wFileHandle : word,
                                        wSegment : word,
                                        wOffset : word,
                                        wSize   : word

    push    bx
    push    cx

    mov     ax, 3F00H
    mov     bx,	wFileHandle
    mov     cx, wSize
    mov     ds, wSegment
    mov     dx, wOffset
    int     21H

    ; carry flag set if error
    jnc     pass3
    mov     ax, 0

pass3:
    pop     cx
    pop     bx
    ret

DosRead     ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Writes data from buffer to file.
;;
;;  function DosWrite (wFileHandle%, wSegment%, wOffset%, wSize%)
;;
;;  Entry:
;;      wFileHandle% :- handle of file to write
;;      wSegment%    :- segment address of the memory buffer
;;      wOffset%     :- offset address of the memory buffer
;;      wSize%       :- number of bytes to write
;;
;;  Exit:
;;      Number of bytes written if sucessful, else returns 0.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   DosWrite	    PROC    <loaddsIF>	    wFileHandle : word,
                                            wSegment : word,
                                            wOffset : word,
                                            wSize : word

    push    bx
    push    cx

    mov     ax, 4000H
    mov     bx, wFileHandle
    mov     cx, wSize
    mov     ds, wSegment
    mov     dx, wOffset
    int     21H

    ; carry flag set if error
    jnc     pass4
    mov     ax, 0

pass4:
    pop     cx
    pop     bx
    ret

DosWrite	ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Moves file pointer.
;;
;;  function sbkDosLSeek (wFileHandle%, dwOffset&, wMoveMode%)
;;
;;  Entry:
;;      wFileHandle%  :- handle of file
;;      dwOffset&     :- offset to move in bytes
;;      wMoveMode%    :- move method:
;;                       0 = starts from beginning of file
;;                       1 = starts from current location
;;                       2 = starts from end of file
;;
;;  Exit:
;;      Returns new file pointer position (DX:AX) with reference to
;;      beginnig of file if successful, else returns -1.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   sbkDosLSeek     PROC    <loaddsIF>	    wFileHandle : word,
                                            dwOffset : dword,
                                            wMoveMode : word

    push    bx
    push    cx

    mov     ax, wMoveMode
    and     ax, 0FFH
    add     ax, 4200H
    mov     bx, wFileHandle

    ; hi-word of offset in cx and lo-word in dx
    mov     cx, word ptr dwOffset + 2
    mov     dx, word ptr dwOffset
    int     21H

    ; carry flag set if error
    jnc     pass5
    mov     ax, 0FFFFH
    mov     dx, 0FFFFH

pass5:
    pop     cx
    pop     bx
    ret

sbkDosLSeek	ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Determines the size of a file.
;;
;;  function sbkFileSize (wFileHandle%)
;;
;;  Entry:
;;      wFileHandle%  :- handle of file
;;
;;   Exit:
;;      Returns the size of file if successful, else returns -1.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   sbkFileSize     PROC    <loaddsIF>	    wFileHandle : word

    push    bx
    push    cx

    ;; gets current file pointer position
    mov     ax, 4200H + 1
    mov     bx, wFileHandle

    ; hi-word of offset in cx and lo-word in dx
    mov     cx, 0
    mov     dx, 0
    int     21H

    jnc     pass6
    mov     ax, 0FFFFH
    mov     dx, 0FFFFH
    jmp     short finis1

pass6:
    ; preserves current file pointer position
    mov     word ptr cs:[dwTempStore], ax
    mov     word ptr cs:[dwTempStore + 2], dx

    ;; gets file size
    mov     ax, 4200H + 2
    mov     bx, wFileHandle

    ; hi-word of offset in cx and lo-word in dx
    mov     cx, 0
    mov     dx, 0
    int     21H

    jnc     pass7
    mov     ax, 0FFFFH
    mov     dx, 0FFFFH
    jmp     short finis1

pass7:
    ; save file size
    push    dx		    ; hi-word
    push    ax		    ; lo-word
    ; restore previous file pointer position
    mov     dx, word ptr cs:[dwTempStore]
    mov     cx, word ptr cs:[dwTempStore + 2]
    mov     ax, 4200H
    mov     bx, wFileHandle
    int     21H

    pop     ax
    pop     dx
    jnc     finis1
    mov     ax, 0FFFFH
    mov     dx, 0FFFFH

finis1:
    pop     cx
    pop     bx
    ret

sbkFileSize	ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Checks the existence of a file.
;;
;;  function sbkFindFile (lpFilename&)
;;
;;  Entry:
;;      lpFilename :- far pointer to the file to be searched.
;;
;;  Exit:
;;      Non-zero if successful, else returns 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   sbkFindFile     PROC    <loaddsIF>	    lpFilename : far ptr byte

    push    cx

    mov     ax, 4E00H
    lds     dx, lpFilename
    mov     cx, 20H
    int     21H

    mov     ax,1
    jnc     pass8
    mov     ax, 0

pass8:
    pop     cx
    ret
	    
sbkFindFile	ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Find first matching file
;;
;;  function sbkFindFirst (lpFileSpec&, wAttribute%, SearchRec)
;;
;;  Entry :
;;      lpFileSpec :- far pointer to the file specification.
;;      wAttribute :- file attributes.
;;      SerchRec   :- in which to store the result of the directory search.
;;              SearchRec structure
;;                  reserved    db  21 dup(?)
;;                  Attrib  db  ?
;;                  Time    dw  ?
;;                  Date    dw  ?
;;                  Size    dd  ?
;;                  Name    db  13 dup (?)
;;              End of structure
;;
;;  Exit :
;;      0  :- successful.
;;      2  :- file not found.
;;      18 :- no more files.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   sbkFindFirst    PROC    <loaddsIF>	    Uses es ds si di,
                                            lpFileSpec : far ptr byte,
                                            wAttribute : word,
                                            SearchRec : far ptr byte
    push    bx
    push    cx
    push    dx

    mov     ax, 4E00h		; find first match
    lds     dx, lpFileSpec
    mov     cx, wAttribute
    int     21h
    jc	    finis2

    mov     ax, 2F00h		; get DTA address
    int     21h

    cld
    mov     cx, es
    mov     ds, cx          ; source
    mov     si, bx
    les     di, SearchRec	; destination
    mov     cx, 44          ; length
    rep     movsb           ; copy string

    mov     ax, 0

finis2:
    pop     dx
    pop     cx
    pop     bx

    ret

sbkFindFirst	ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Find next matching file
;;
;;  function sbkFindNext (SearchRec)
;;
;;  Entry :
;;      SerchRec   :- search result as returned from previous sbkFindFirst
;;
;;  Exit :
;;      0  :- successful.
;;      2  :- file not found.
;;      18 :- no more files.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%   sbkFindNext     PROC    <loaddsIF>	    Uses es ds si di,
                                            SearchRec : far ptr byte

    push    bx
    push    cx

    mov     ax, 2F00h		; get DTA address
    int     21h

    cld
    lds     si, SearchRec	; source ds:si
    mov     di, bx          ; destination es:di
    mov     cx, 44          ; length
    rep     movsb           ; copy string

    mov     ax, 4F00h		; find next match
    int     21h

    cmp     ax, 0
    jne     finis3

    mov     ax, 2F00h		; get DTA address
    int     21h

    cld
    mov     cx, es
    mov     ds, cx          ; source
    mov     si, bx
    les     di, SearchRec	; destination
    mov     cx, 44          ; length
    rep     movsb           ; copy string

    mov     ax, 0

finis3:
    pop     cx
    pop     bx

    ret

sbkFindNext	ENDP

        END                 ; End of code
