home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / QC25-10.ZIP / SAMPLES / FILE.AS$ / FILE.bin
Encoding:
Text File  |  1989-04-27  |  28.6 KB  |  1,039 lines

  1.     .MODEL small, c
  2.     INCLUDE demo.inc
  3.     .CODE
  4.  
  5.  
  6. ;* ReadCharAttr - Reads character and display attribute at cursor location.
  7. ;*
  8. ;* Shows:   BIOS Interrupt - 10h, Function 8 (Read Character and Attribute
  9. ;*                 at Cursor)
  10. ;*
  11. ;* Uses:    vconfig - Video configuration structure, declared in the
  12. ;*        DEMO.INC include file. The structure must first be
  13. ;*        initialized by calling the GetVidConfig procedure.
  14. ;*
  15. ;* Params:  attr - Pointer to short integer for display attribute
  16. ;*
  17. ;* Return:  Short integer with ASCII value of character
  18.  
  19. ReadCharAttr PROC \
  20.     USES di, \
  21.     attr:PTR WORD
  22.  
  23.     mov    ah, 8            ; Function 8
  24.     mov    bh, vconfig.dpage    ; Current page
  25.     int    10h            ; Read Character and Attribute
  26.     sub    bh, bh
  27.     mov    bl, ah            ; BX = attribute
  28.     cbw                ; AX = character
  29.     LoadPtr es, di, attr        ; ES:DI = pointer to int
  30.     mov    es:[di], bx        ; Copy attribute
  31.     ret
  32.  
  33. ReadCharAttr ENDP
  34.  
  35.  
  36. ;* CopyFile - Copies a file from a specified directory to another. Allows
  37. ;* two different copy methods. See the OpenFile, CloseFile, ReadFile, and
  38. ;* WriteFile procedures for specific examples on opening, closing, reading
  39. ;* from, and writing to files.
  40. ;*
  41. ;* Shows:   DOS Functions - 3Ch (Create File)
  42. ;*                5Bh (Create New File)
  43. ;*        Instruction - clc
  44. ;*
  45. ;* Params:  imode  - 0 = Create new target file or overwrite existing file
  46. ;*             1 = Abort and return error code if target file already
  47. ;*             exists (only for DOS versions 3.0 and higher)
  48. ;*        fspec1 - Pointer to ASCIIZ source file specification
  49. ;*        fspec2 - Pointer to ASCIIZ target file specification
  50. ;*
  51. ;* Return:  Short integer with error code
  52. ;*        0 if successful
  53. ;*        1 if error
  54.  
  55.     .DATA
  56. buffer    DB    BUFFER_SIZE DUP(?)    ; Buffer for diskette read
  57.  
  58.     .CODE
  59.     EXTRN GetVer:PROC
  60.  
  61. CopyFile PROC \
  62.     USES ds si di, \
  63.     imode:WORD, fspec1:PTR BYTE, fspec2:PTR BYTE
  64.  
  65.     LOCAL eof_flag:BYTE
  66.  
  67. ; Open source file for read only
  68.  
  69.     LoadPtr ds, dx, fspec1        ; Point DS:DX to source file
  70.     mov    ax, 3D00h        ; AH = function #, AL = access code
  71.     int    21h            ; Open File (for read only)
  72.     jc    e_exit
  73.     mov    si, ax            ; SI = file handle for source
  74.  
  75. ; Open target file according to copy mode
  76.  
  77.     LoadPtr ds, dx, fspec2        ; Point DS:DX to target file
  78.     cmp    imode, 1        ; Determine DOS function
  79.     je    check            ; Imode = 1?
  80.     mov    ah, 3Ch         ; No?  Request Create File
  81.     jmp    SHORT set        ;   (destroy existing)
  82. check:    call    GetVer            ; Yes?    First check DOS version
  83.     cmp    ax, 300         ; 3.0 or higher?
  84.     jb    close            ; No?  Abort with error code
  85.     mov    ah, 5Bh         ; Request Create New File
  86.  
  87. set:    sub    cx, cx            ; Normal attribute for target
  88.     int    21h            ; DOS function for target file
  89.     jc    close            ; If open error, abort
  90.     mov    di, ax            ; DI = file handle for target
  91.  
  92. ; Both files successfully opened. Now read from source and copy to target.
  93.  
  94.     mov    ax, @data
  95.     mov    ds, ax            ; DS:DX = buffer. Read/write
  96.     mov    dx, OFFSET buffer    ;   to and from here.
  97.     mov    eof_flag, 0        ; Initialize end-of-file flag
  98. loop1:    mov    bx, si            ; Handle for source file
  99.     mov    cx, BUFFER_SIZE     ; CX = number of bytes to read
  100.     mov    ah, 3Fh         ; Request DOS read
  101.     int    21h            ; Read from File
  102.     jc    close            ; If error, exit
  103.     cmp    ax, cx            ; All bytes read successfully?
  104.     je    @F            ; Yes?    Continue
  105.     inc    eof_flag        ; No?  Raise flag
  106. @@:    mov    bx, di            ; Handle for target file
  107.     mov    cx, ax            ; Write number of bytes read
  108.     mov    ah, 40h         ; Request DOS write
  109.     int    21h            ; Write from buffer to target file
  110.     jc    close            ; If error, exit
  111.     cmp    eof_flag, 0        ; Finished?
  112.     je    loop1            ; No?  Loop to read next block
  113.     clc                ; Yes?    Clear CY to indicate
  114.                     ;   success
  115. close:    pushf                ; Preserve flags while closing
  116.     mov    bx, di            ; Handle for target file
  117.     mov    ah, 3Eh         ; Request DOS Function 3Eh
  118.     int    21h            ; Close File
  119.     sub    ax, ax            ; Clear error code
  120.     popf                ; Recover flags
  121.     jnc    exit            ; If successful, exit
  122.  
  123. e_exit: mov    ax, 1            ; Else set error code
  124. exit:    ret
  125.  
  126. CopyFile ENDP
  127.  
  128.  
  129. ;* ChangeDrive - Changes default drive.
  130. ;*
  131. ;* Shows:   DOS Function - 0Eh (Select Disk)
  132. ;*
  133. ;* Params:  drive - Uppercase letter designation for new drive
  134. ;*
  135. ;* Return:  None
  136.  
  137. ChangeDrive PROC \
  138.     drive:WORD
  139.  
  140.     mov    ah, 0Eh         ; DOS Function 0Eh
  141.     mov    dx, drive        ; Drive designation in DL,
  142.     sub    dl, 'A'         ;   0=A, 1=B, 2=C, etc
  143.     int    21h            ; Select Disk
  144.     ret
  145.  
  146. ChangeDrive ENDP
  147.  
  148.  
  149. ;* GetCurDisk - Gets designation of current disk.
  150. ;*
  151. ;* Shows:   DOS Function - 19h (Get Current Disk)
  152. ;*        Instruction - cbw
  153. ;*
  154. ;* Params:  None
  155. ;*
  156. ;* Return:  Short integer with drive designation
  157. ;*        0 = A, 1 = B, 2 = C, etc.
  158.  
  159. GetCurDisk PROC
  160.  
  161.     mov    ah, 19h         ; DOS Function 19h
  162.     int    21h            ; Get Current Disk
  163.     cbw                ; AX = drive designation
  164.     ret
  165.  
  166. GetCurDisk ENDP
  167.  
  168.  
  169. ;* SetDTA - Sets address for new Disk Transfer Area.
  170. ;*
  171. ;* Shows:   DOS Function - 1Ah (Set DTA Address)
  172. ;*
  173. ;* Params:  dta - Far pointer to new transfer address
  174. ;*
  175. ;* Return:  None
  176.  
  177. SetDTA    PROC \
  178.     USES ds, \
  179.     dta:FAR PTR BYTE
  180.  
  181.     lds    dx, [dta]        ; Point DS:DX to DTA
  182.     mov    ah, 1Ah         ; DOS Function 1Ah
  183.     int    21h            ; Set DTA Address
  184.     ret
  185.  
  186. SetDTA    ENDP
  187.  
  188.  
  189. ;* GetDTA - Gets address of current Disk Transfer Area.
  190. ;*
  191. ;* Shows:   DOS Function - 2Fh (Get DTA Address)
  192. ;*
  193. ;* Params:  dta - Far pointer to receive transfer address
  194. ;*
  195. ;* Return:  None
  196.  
  197. GetDTA    PROC \
  198.     dta:FAR PTR BYTE
  199.  
  200.     mov    ah, 2Fh         ; DOS Function 2Fh
  201.     int    21h            ; Get DTA Address in ES:BX
  202.     mov    ax, es            ; Save DTA segment
  203.     mov    dx, bx            ; Save DTA offset
  204.     les    bx, dta         ; Now ES:BX points to variable
  205.     mov    es:[bx], dx        ; Copy DTA address to
  206.     mov    es:[bx+2], ax        ;   dta variable
  207.     ret
  208.  
  209. GetDTA    ENDP
  210.  
  211.  
  212. ;* CreateFile - Creates file with specified attribute.
  213. ;*
  214. ;* Shows:   DOS Function - 3Ch (Create File)
  215. ;*
  216. ;* Params:  attr - Attribute code:  0 = normal          8 = volume label
  217. ;*                    1 = read only    16 = subdirectory
  218. ;*                    2 = hidden         32 = archive
  219. ;*                    4 = system
  220. ;*        fspec - Pointer to ASCIIZ file specification
  221. ;*
  222. ;* Return:  Short integer with file handle or -1 for error
  223.  
  224. CreateFile PROC \
  225.     USES ds, \
  226.     attr:WORD, fspec:PTR BYTE
  227.  
  228.     LoadPtr ds, dx, fspec        ; Point DS:DX to file spec
  229.     mov    cx, attr        ; CX = attribute
  230.     mov    ah, 3Ch         ; AH = function number
  231.     int    21h            ; Create file
  232.     jnc    exit            ; If ok, return AX = handle
  233.     mov    ax, -1            ; Else set error code
  234. exit:    ret
  235.  
  236. CreateFile ENDP
  237.  
  238.  
  239. ;* OpenFile - Opens specified file for reading or writing. See the CopyFile
  240. ;* procedure for another example of using DOS Function 3Dh to open files.
  241. ;*
  242. ;* Shows:   DOS Function - 3Dh (Open File)
  243. ;*
  244. ;* Params:  access - Access code:  0 = read    1 = write    2 = read/write
  245. ;*        fspec - Pointer to ASCIIZ file specification
  246. ;*
  247. ;* Return:  Short integer with file handle or -1 for error
  248.  
  249. OpenFile PROC \
  250.     USES ds, \
  251.     access:WORD, fspec:PTR BYTE
  252.  
  253.     LoadPtr ds, dx, fspec        ; Point DS:DX to file spec
  254.     mov    ax, access        ; AL = access code
  255.     mov    ah, 3Dh         ; AH = function number
  256.     int    21h            ; Open file
  257.     jnc    exit            ; If ok, return AX = handle
  258.     mov    ax, -1            ; Else set error code
  259. exit:    ret
  260.  
  261. OpenFile ENDP
  262.  
  263.  
  264. ;* CloseFile - Closes an open file, specified by handle. See the CopyFile
  265. ;* procedure for another example of using DOS Function 3Eh to close files.
  266. ;*
  267. ;* Shows:   DOS Function - 3EH (Close File)
  268. ;*
  269. ;* Params:  handle - File handle
  270. ;*
  271. ;* Return:  None
  272.  
  273. CloseFile PROC \
  274.     handle:WORD
  275.  
  276.     mov    bx, handle        ; BX = file handle
  277.     mov    ah, 3Eh         ; DOS Function 3Eh
  278.     int    21h            ; Close file
  279.     ret
  280.  
  281. CloseFile ENDP
  282.  
  283.  
  284. ;* ReadFile - Read from open file to specified buffer. See the CopyFile
  285. ;* procedure for another example of using DOS Function 3Fh to read files.
  286. ;*
  287. ;* Shows:   DOS Function - 3Fh (Read File or Device)
  288. ;*
  289. ;* Params:  handle - File handle
  290. ;*        len - Number of bytes to read
  291. ;*        pbuff - Pointer to buffer
  292. ;*
  293. ;* Return:  Short integer with number of bytes read, or 0 if read error
  294.  
  295. ReadFile PROC \
  296.     USES ds di, \
  297.     handle:WORD, len:WORD, pbuff:PTR BYTE
  298.  
  299.     LoadPtr ds, dx, pbuff        ; Point DS:DX to buffer
  300.     mov    di, dx            ; Keep string offset in DI
  301.     mov    bx, handle        ; BX = handle
  302.     mov    cx, len         ; CX = number of bytes to read
  303.     mov    ah, 3Fh         ; Request DOS read
  304.     int    21h            ; Read File
  305.     jnc    exit            ; If ok, exit with bytes read
  306.     sub    ax, ax            ; Else set error code
  307. exit:    ret
  308.     
  309. ReadFile ENDP
  310.  
  311.  
  312. ;* WriteFile - Write ASCIIZ string to file. If handle = 0, the string is
  313. ;* written to STDOUT (console). See the CopyFile procedure for another
  314. ;* example of using DOS Function 40h to write to files.
  315. ;*
  316. ;* Shows:   DOS Function - 40h (Write File or Device)
  317. ;*
  318. ;* Params:  handle - File handle
  319. ;*        str - Pointer to ASCIIZ string
  320. ;*
  321. ;* Return:  Short integer with error code
  322. ;*        0 if successful
  323. ;*        1 if write error
  324. ;*        2 if number of bytes written not equal to string length
  325.  
  326. WriteFile PROC \
  327.     USES ds di, \
  328.     handle:WORD, str:PTR BYTE
  329.  
  330.     LoadPtr es, di, str        ; Point ES:DI to string
  331.     push    di            ; Hold on to string pointer
  332.     mov    cx, -1            ; Set CX to maximum
  333.     sub    al, al            ; AL = 0
  334.     repne    scasb            ; Scan string for NULL
  335.     pop    dx            ; Recover string pointer
  336.     dec    di
  337.     sub    di, dx            ; Get string length (w/o NULL)
  338.     mov    cx, di            ; Put it into CX
  339.     mov    bx, handle        ; Load BX with handle
  340.     push    es            ; Set DS to ES to ensure
  341.     pop    ds            ;   DS:DX points to string
  342.     mov    ah, 40h         ; Request DOS write
  343.     int    21h            ; Write File or Device
  344.     mov    bx, ax            ; Get number of bytes written
  345.     mov    ax, 0            ; Set error code, preserve CY
  346.     jc    e_exit            ; If error, exit
  347.     cmp    bx, cx            ; All bytes written?
  348.     je    exit            ; Yes?    Exit, error code = 0
  349.     inc    ax            ; Else inc error code twice
  350. e_exit: inc    ax            ; Increment error code once
  351. exit:    ret
  352.  
  353. WriteFile ENDP
  354.  
  355.  
  356. ;* GetDiskSize - Gets size information from specified disk.
  357. ;*
  358. ;* Shows:   DOS Function - 36h (Get Drive Allocation Information)
  359. ;*
  360. ;* Params:  drive - Drive code (0 = default, 1 = A, 2 = B, etc.)
  361. ;*        disk  - Pointer to a structure with 4 short integer members:
  362. ;*            Member 1 - Total clusters on disk
  363. ;*            Member 2 - Number of available clusters
  364. ;*            Member 3 - Sectors/cluster (-1 if invalid drive)
  365. ;*            Member 4 - Bytes/sector
  366. ;*
  367. ;* Return:  None
  368.  
  369. GetDiskSize PROC \
  370.     USES di, \
  371.     drive:WORD, disk:PTR WORD
  372.  
  373.     mov    dx, drive        ; DL = drive code
  374.     mov    ah, 36h         ; DOS Function 36h
  375.     int    21h            ; Get Drive Allocation Information
  376.     LoadPtr es, di, disk        ; ES:DI = disk structure
  377.     mov    es:[di].total, dx    ; DX = total clusters
  378.     mov    es:[di].avail, bx    ; BX = number of free clusters
  379.     mov    es:[di].sects, ax    ; AX = sectors/cluster
  380.     mov    es:[di].bytes, cx    ; CX = bytes/sector
  381.     ret
  382.  
  383. GetDiskSize ENDP
  384.  
  385.  
  386. ;* MakeDir - Creates a specified subdirectory.
  387. ;*
  388. ;* Shows:   DOS Function - 39h (Create Directory)
  389. ;*
  390. ;* Params:  pspec - Pointer to ASCIIZ pathname of new subdirectory
  391. ;*
  392. ;* Return:  Short integer with error code
  393. ;*        0 if successful
  394. ;*        1 if create error
  395.  
  396. MakeDir PROC \
  397.     USES ds, \
  398.     pspec:PTR BYTE
  399.  
  400.     LoadPtr ds, dx, pspec        ; Point DS:DX to path spec
  401.     mov    ah, 39h         ; DOS Function 39h
  402.     int    21h            ; Create Directory
  403.     mov    ax, 0            ; Set error code, keep flags
  404.     jnc    exit            ; Exit if successful
  405.     inc    ax            ; Else set error code to 1
  406. exit:    ret
  407.  
  408. MakeDir ENDP
  409.  
  410.  
  411. ;* RemoveDir - Removes a specified subdirectory.
  412. ;*
  413. ;* Shows:   DOS Function - 3Ah (Delete Directory)
  414. ;*
  415. ;* Params:  pspec - Pointer to ASCIIZ pathname of subdirectory
  416. ;*
  417. ;* Return:  Short integer with error code
  418. ;*        0 if successful
  419. ;*        1 if delete error or subdirectory not empty
  420.  
  421. RemoveDir PROC \
  422.     USES ds, \
  423.     pspec:PTR BYTE
  424.  
  425.     LoadPtr ds, dx, pspec        ; Point DS:DX to path spec
  426.     mov    ah, 3Ah         ; DOS Function 3Ah
  427.     int    21h            ; Delete Directory
  428.     mov    ax, 0            ; Set error code, keep flags
  429.     jnc    exit            ; Exit if successful
  430.     inc    ax            ; Else set error code to 1
  431. exit:    ret
  432.  
  433. RemoveDir ENDP
  434.  
  435.  
  436. ;* ChangeDir - Changes current (default) directory.
  437. ;*
  438. ;* Shows:   DOS Function - 3Bh (Set Current Directory)
  439. ;*
  440. ;* Params:  pspec - Pointer to ASCIIZ pathname of target subdirectory
  441. ;*
  442. ;* Return:  Short integer with error code
  443. ;*        0 if successful
  444. ;*        1 if delete error or subdirectory not empty
  445.  
  446. ChangeDir PROC \
  447.     USES ds, \
  448.     pspec:PTR BYTE
  449.  
  450.     LoadPtr ds, dx, pspec        ; Point DS:DX to path spec
  451.     mov    ah, 3Bh         ; DOS Function 3Bh
  452.     int    21h            ; Set Current Directory
  453.     mov    ax, 0            ; Set error code, keep flags
  454.     jnc    exit            ; Exit if successful
  455.     inc    ax            ; Else set error code to 1
  456. exit:    ret
  457.  
  458. ChangeDir ENDP
  459.  
  460.  
  461. ;* DelFile - Deletes a specified file.
  462. ;*
  463. ;* Shows:   DOS Function - 41h (Delete File)
  464. ;*
  465. ;* Params:  fspec - Pointer to ASCIIZ file specification
  466. ;*
  467. ;* Return:  Short integer with error code
  468. ;*        0 if successful
  469. ;*        1 if delete error
  470.  
  471. DelFile PROC \
  472.     USES ds, \
  473.     fspec:PTR BYTE
  474.  
  475.     LoadPtr ds, dx, fspec        ; Point DS:DX to file spec
  476.     mov    ah, 41h         ; DOS Function 41h
  477.     int    21h            ; Delete File
  478.     mov    ax, 0            ; Set error code, keep flags
  479.     jnc    exit            ; Exit if successful
  480.     inc    ax            ; Else set error code to 1
  481. exit:    ret
  482.  
  483. DelFile ENDP
  484.  
  485.  
  486. ;* Rewind - Rewinds an open file, specified by handle. See the GetFileSize
  487. ;* procedure for an example of using Function 42h to determine file size.
  488. ;*
  489. ;* Shows:   DOS Function - 42h (Set File Pointer)
  490. ;*
  491. ;* Params:  handle - File handle
  492. ;*
  493. ;* Return:  None
  494.  
  495. Rewind    PROC \
  496.     handle:WORD
  497.  
  498.     mov    bx, handle        ; BX = file handle
  499.     mov    ax, 4200h        ; AH = function #,
  500.                     ; AL = move to beginning of
  501.     sub    cx, cx            ;      file plus offset
  502.     sub    dx, dx            ; CX:DX = offset (zero)
  503.     int    21h            ; Set File Pointer
  504.     ret
  505.  
  506. Rewind    ENDP
  507.  
  508.  
  509. ;* GetFileSize - Gets the size of an open file, specified by handle.
  510. ;*
  511. ;* Shows:   DOS Function - 42h (Set File Pointer)
  512. ;*
  513. ;* Params:  handle - File handle
  514. ;*
  515. ;* Return:  Long integer with file size in bytes
  516.  
  517. GetFileSize PROC \
  518.     handle:WORD
  519.  
  520.     mov    bx, handle        ; BX = file handle
  521.     mov    ax, 4202h        ; AH = function #,
  522.                     ; AL = move to end of
  523.     sub    cx, cx            ;      file plus offset
  524.     sub    dx, dx            ; CX:DX = offset (zero)
  525.     int    21h            ; Set File Pointer
  526.     mov    ax, dx            ; Set DX:AX = file size in
  527.     mov    dx, cx            ;   bytes, return long int
  528.     ret
  529.  
  530. GetFileSize ENDP
  531.  
  532.  
  533. ;* GetAttribute - Gets the attribute(s) of a specified file.
  534. ;*
  535. ;* Shows:   DOS Function - 43h (Get or Set File Attributes)
  536. ;*
  537. ;* Params:  fspec - Pointer to ASCIIZ file specification
  538. ;*
  539. ;* Return:  Short integer with file attribute bits set as follows:
  540. ;*           bit 0 = read-only         bit 3 = volume label
  541. ;*           bit 1 = hidden             bit 4 = subdirectory
  542. ;*           bit 2 = system             bit 5 = archive
  543. ;*         0 indicates normal data file
  544. ;*        -1 indicates error
  545.  
  546. GetAttribute PROC \
  547.     USES ds, \
  548.     fspec:PTR BYTE
  549.  
  550.     LoadPtr ds, dx, fspec        ; DS:DX = file specification
  551.     mov    ax, 4300h        ; AH = function #
  552.                     ; AL = 0 (return attribute)
  553.     int    21h            ; Get File Attributes
  554.     mov    ax, -1            ; Set code, keep flags
  555.     jc    exit            ; If read error, exit
  556.     mov    ax, cx            ; Else return with
  557. exit:    ret                ;   file attribute bits
  558.  
  559. GetAttribute ENDP
  560.  
  561.  
  562. ;* SetAttribute - Sets the attribute(s) of a specified file.
  563. ;*
  564. ;* Shows:   DOS Function - 43h (Get or Set File Attributes)
  565. ;*
  566. ;* Params:  attr - Attribute bits set as follows:
  567. ;*              bit 0 = read-only      bit 3 = volume label
  568. ;*              bit 1 = hidden         bit 4 = subdirectory
  569. ;*              bit 2 = system         bit 5 = archive
  570. ;*           (attr = 0 for normal data file)
  571. ;*        fspec - Pointer to ASCIIZ file specification
  572. ;*
  573. ;* Return:  Short integer with error code
  574. ;*        0 if successful
  575. ;*        1 if delete error
  576.  
  577. SetAttribute PROC \
  578.     USES ds, \
  579.     attr:WORD, fspec:PTR BYTE
  580.  
  581.     LoadPtr ds, dx, fspec        ; DS:DX = file specification
  582.     mov    cx, attr        ; Put attribute code in CX
  583.     mov    ax, 4301h        ; AH = function #
  584.                     ; AL = 1 (set attribute)
  585.     int    21h            ; Set File Attributes
  586.     mov    ax, 0            ; Clear code, keep flags
  587.     jnc    exit            ; If successful, exit
  588.     inc    ax            ; Else set error code
  589. exit:    ret
  590.  
  591. SetAttribute ENDP
  592.  
  593.  
  594. ;* GetCurDir - Gets the current directory of default drive.
  595. ;*
  596. ;* Shows:   DOS Function - 47h (Get Current Directory)
  597. ;*
  598. ;* Params:  spec - Pointer to 64-byte buffer to receive directory
  599. ;*        path. Path terminates with 0 but does not include
  600. ;*        drive and does not begin with backslash.
  601. ;*
  602. ;* Return:  Short integer with error code
  603. ;*        0 if successful
  604. ;*        1 if delete error or subdirectory not empty
  605.  
  606. GetCurDir PROC \
  607.     USES ds si, \
  608.     spec:PTR BYTE
  609.  
  610.     LoadPtr ds, si, spec        ; DS:SI = spec address
  611.     mov    ah, 47h         ; AH = function number
  612.     sub    dl, dl            ; DL = current drive (0)
  613.     int    21h            ; Get Current Directory
  614.     mov    ax, 0            ; Set error code, keep flags
  615.     jnc    exit            ; Exit if successful
  616.     inc    ax            ; Else set error code to 1
  617. exit:    ret
  618.  
  619. GetCurDir ENDP
  620.  
  621.  
  622. ;* FindFirst - Finds first entry in given directory matching specification.
  623. ;*
  624. ;* Shows:   DOS Function - 4Eh (Find First File)
  625. ;*        Keywords - USES
  626. ;*        Instructions - ret       pushf    popf
  627. ;*
  628. ;* Params:  attr - Attribute code (see header comments for CreateFile)
  629. ;*        fspec - Pointer to ASCIIZ file specification
  630. ;*        finfo - Pointer to 43-byte buffer to receive
  631. ;*            data from matched entry
  632. ;*
  633. ;* Return:  Short integer with error code
  634. ;*        0 if successful
  635. ;*        1 if no match found
  636.  
  637.     .DATA
  638. old_dta DD    WORD PTR ?        ; Storage for old DTA address
  639.  
  640.     .CODE
  641.  
  642. FindFirst PROC \
  643.     USES ds, \
  644.     attr:WORD, fspec:PTR BYTE, finfo:PTR BYTE
  645.  
  646.     push    ds            ; Pass far pointer
  647.     mov    ax, OFFSET @data:old_dta;   to old_dta
  648.     push    ax
  649.     call    GetDTA            ; Get current DTA address
  650.     add    sp, 4            ; Adjust stack
  651.  
  652.     mov    cx, attr        ; Load CX with file attribute
  653.     LoadPtr ds, dx, finfo        ; DS:DX points to 43-byte buffer
  654.     push    ds            ; Make this new DTA
  655.     push    dx
  656.     call    SetDTA            ; Set 43-byte buffer as DTA
  657.     add    sp, 4            ; Adjust stack
  658.     LoadPtr ds, dx, fspec        ; Point DS:DX to file spec
  659.     mov    ah, 4Eh         ; AH = function number
  660.     int    21h            ; Find First File
  661.  
  662.     pushf                ; Preserve flags
  663.     push    WORD PTR @data:old_dta[2] ; Pass far pointer to
  664.     push    WORD PTR @data:old_dta[0] ;   SetDTA procedure
  665.     call    SetDTA            ; Restore DTA address to orig
  666.     sub    ax, ax            ; Set error code
  667.     add    sp, 4            ; Adjust stack
  668.     popf                ; Recover flags
  669.     jnc    exit            ; Exit if successful match
  670.     inc    ax            ; Else set error code to 1
  671. exit:    ret
  672.  
  673. FindFirst ENDP
  674.  
  675.  
  676. ;* FindNext - Finds next entry in given directory matching specification.
  677. ;* (Should be called only after successfully calling the FindFirst procedure.)
  678. ;*
  679. ;* Shows:   DOS Function - 4Fh (Find Next File)
  680. ;*        Operator - OFFSET
  681. ;*
  682. ;* Params:  finfo - Pointer to 43-byte buffer. This must be the same buffer
  683. ;*            (or a duplicate) returned from the FindFirst procedure.
  684. ;*
  685. ;* Return:  Short integer with error code
  686. ;*        0 if successful
  687. ;*        1 if no more matches found
  688.  
  689. FindNext PROC \
  690.     USES ds, \
  691.     finfo:PTR BYTE
  692.  
  693.     push    ds            ; Pass far pointer
  694.     mov    ax, OFFSET @data:old_dta;   to old_dta
  695.     push    ax
  696.     call    GetDTA            ; Get current DTA address
  697.     add    sp, 4            ; Adjust stack
  698.  
  699.     LoadPtr ds, dx, finfo        ; DS:DX points to 43-byte buffer
  700.     push    ds            ; Make this new DTA
  701.     push    dx
  702.     call    SetDTA            ; Set 43-byte buffer as DTA
  703.     add    sp, 4            ; Adjust stack
  704.     mov    ah, 4Fh         ; AH = function number
  705.     int    21h            ; Find Next File
  706.  
  707.     pushf                ; Preserve flags
  708.     push    WORD PTR @data:old_dta[2] ; Pass far pointer to
  709.     push    WORD PTR @data:old_dta[0] ;   SetDTA procedure
  710.     call    SetDTA            ; Restore DTA address to orig
  711.     sub    ax, ax            ; Set error code
  712.     add    sp, 4            ; Adjust stack
  713.     popf                ; Recover flags
  714.     jnc    exit            ; Exit if successful match
  715.     inc    ax            ; Else set error code to 1
  716. exit:    ret
  717.  
  718. FindNext ENDP
  719.  
  720.  
  721. ;* RenameFile - Renames specified file.
  722. ;*
  723. ;* Shows:   DOS Function - 56h (Rename File)
  724. ;*
  725. ;* Params:  fspec1 - Pointer to old ASCIIZ file specification
  726. ;*        fspec2 - Pointer to new ASCIIZ file specification
  727. ;*
  728. ;*        The drive must be the same for both arguments, but the path
  729. ;*        does not. This allows files to be moved between directories.
  730. ;*
  731. ;* Return:  Short integer with error code
  732. ;*        0 if successful
  733. ;*        1 if error
  734.  
  735. RenameFile PROC \
  736.     USES ds di, \
  737.     fspec1:PTR BYTE, fspec2:PTR BYTE
  738.  
  739.     LoadPtr ds, dx, fspec1        ; Point DS:DX to old file spec
  740.     LoadPtr es, di, fspec2        ; Point ES:DI to new file spec
  741.     mov    ah, 56h         ; AH = function number
  742.     int    21h            ; Rename File
  743.     mov    ax, 0            ; Clear error code, keep flags
  744.     jnc    exit            ; Return code = 0 if no error
  745.     inc    ax            ; Else set error code
  746. exit:    ret
  747.  
  748. RenameFile ENDP
  749.  
  750.  
  751. ;* GetFileTime - Gets date/time for open file specified by handle.
  752. ;*
  753. ;* Shows:   DOS Function - 57h (Get or Set File Date and Time)
  754. ;*        Instructions - shl       shr
  755. ;*
  756. ;* Params:  handle - Handle of open file
  757. ;*        str - Pointer to 18-byte buffer to receive date/time
  758. ;*
  759. ;* Return:  Short integer with error code
  760. ;*        0 if successful
  761. ;*        1 if error
  762.  
  763. GetFileTime PROC \
  764.     USES di, \
  765.     handle:WORD, str:PTR BYTE
  766.  
  767.     mov    ax, 5700h        ; AH = function number
  768.                     ; AL = get request
  769.     mov    bx, handle        ; BX = file handle
  770.     int    21h            ; Get File Date and Time
  771.     mov    ax, 1            ; Set error code, keep flags
  772.     jc    exit            ; Return code = 1 if no error
  773.     mov    bx, cx            ; Else save time in BX
  774.     mov    al, bl            ; Get low byte of time
  775.     and    al, 00011111b        ; Mask to get 2-second incrs,
  776.     shl    al, 1            ;   convert to seconds
  777.     push    ax            ; Save seconds
  778.     mov    cl, 5
  779.     shr    bx, cl            ; Shift minutes into low byte
  780.     mov    al, bl            ; Get new low byte
  781.     and    al, 00111111b        ; Mask to get minutes
  782.     push    ax            ; Save minutes
  783.     mov    cl, 6
  784.     shr    bx, cl            ; Shift hours into low byte
  785.     push    bx            ; Save hours
  786.  
  787.     mov    bl, dl            ; Get low byte of date
  788.     and    bl, 00011111b        ; Mask to get day in BX
  789.     mov    cl, 5
  790.     shr    dx, cl            ; Shift month into low byte
  791.     mov    al, dl            ; Get new low byte
  792.     and    al, 00001111b        ; Mask to get month
  793.     mov    cl, 4
  794.     shr    dx, cl            ; Shift year into low byte
  795.     add    dx, 80            ; Year is relative to 1980
  796.     push    dx            ; Save year
  797.     push    bx            ; Save day
  798.     push    ax            ; Save month
  799.  
  800.     LoadPtr es, di, str        ; Point ES:DI to 18-byte
  801.     mov    cx, 6            ;   string
  802. loop1:    pop    ax            ; Get 6 numbers sequentially in AL
  803.     aam                ; Convert to unpacked BCD
  804.     xchg    al, ah            ; Switch bytes for word move
  805.     or    ax, '00'        ; Make ASCII numerals
  806.     stosw                ; Copy to string
  807.     mov    al, '-'         ; Separator for date text
  808.     cmp    cl, 4            ; First 3 iters are for date
  809.     jg    @F            ; If CX=6 or 5, insert hyphen
  810.     mov    al, ' '         ; Separator date and time
  811.     je    @F            ; If CX = 4, insert hyphen
  812.     mov    al, ':'         ; Separator for time text
  813.     cmp    cl, 1
  814.     je    eloop            ; If CX = 1, skip
  815. @@:    stosb                ; Copy separator to string
  816. eloop:    loop    loop1
  817.  
  818.     sub    ax, ax            ; Clear return code
  819.     stosb                ; Terminate string with null
  820. exit:    ret                ;    to make ASCIIZ
  821.  
  822. GetFileTime ENDP
  823.  
  824.  
  825. ;* UniqueFile - Creates and opens a new file with a name unique to the
  826. ;* specified directory. The name is manufactured from the current time,
  827. ;* making it useful for temporary files. For DOS versions 3.0 and higher.
  828. ;*
  829. ;* Shows:   DOS Function - 5Ah (Create Temporary File)
  830. ;*
  831. ;* Params:  attr - Attribute code (see header comments for CreateFile)
  832. ;*        fspec - Pointer to ASCIIZ path specification
  833. ;*
  834. ;* Return:  Short integer with file handle or -1 for error
  835.  
  836. UniqueFile PROC \
  837.     USES ds, \
  838.     attr:WORD, pspec:PTR BYTE
  839.  
  840.     call    GetVer            ; Get DOS version
  841.     cmp    ax, 300         ; 3.0 or higher?
  842.     jb    e_exit            ; No?  Quit with error
  843.     LoadPtr ds, dx, pspec        ; Point DS:DX to path spec
  844.     mov    cx, attr        ; CX = attribute
  845.     mov    ah, 5Ah         ; AH = function number
  846.     int    21h            ; Create Temporary File
  847.     jnc    exit            ; Return AX = handle if ok
  848. e_exit: mov    ax, -1            ; Else set error code
  849. exit:    ret
  850.  
  851. UniqueFile ENDP
  852.  
  853.  
  854. ;* CreateNewFile - Creates a new file with specified attribute. Differs
  855. ;* from the CreateFile procedure in that it returns an error if file
  856. ;* already exists. For DOS versions 3.0 and higher.
  857. ;*
  858. ;* Shows:   DOS Function - 5Bh (Create New File)
  859. ;*
  860. ;* Params:  attr - Attribute code (see header comments for CreateFile)
  861. ;*        fspec - Pointer to ASCIIZ file specification
  862. ;*
  863. ;* Return:  Short integer with file handle or -1 for error
  864.  
  865. CreateNewFile PROC \
  866.     USES ds, \
  867.     attr:WORD, fspec:PTR BYTE
  868.  
  869.     LoadPtr ds, dx, fspec        ; Point DS:DX to file spec
  870.     mov    cx, attr        ; CX = attribute
  871.     mov    ah, 5Bh         ; AH = function number
  872.     int    21h            ; Create New File
  873.     jnc    exit            ; Return AX = handle if ok
  874.     mov    ax, -1            ; Else set error code
  875. exit:    ret
  876.  
  877. CreateNewFile ENDP
  878.  
  879.  
  880. ;* StrCompare - Compares two strings for equality. See StrWrite, StrFindChar,
  881. ;* WinOpen, and WinClose procedures for other examples of string instructions.
  882. ;*
  883. ;* Shows:   Instructions - cmpsb     cmpsw     repe    test     jcxz
  884. ;*
  885. ;* Params:  str1 - Pointer to first string
  886. ;*        str2 - Pointer to second string
  887. ;*        len  - Length in bytes for comparison. Strings need not be of
  888. ;*           equal length; however if len is an even number, comparison
  889. ;*           is made on a word-by-word basis and thus is more efficient.
  890. ;*
  891. ;* Return:  Null pointer if strings match; else pointer to string #1 where
  892. ;*        match failed.
  893.  
  894. StrCompare PROC \
  895.     USES ds di si, \
  896.     str1:PTR BYTE, str2:PTR BYTE, len:WORD
  897.  
  898.     LoadPtr es, di, str1        ; ES:DI points to string #1
  899.     LoadPtr ds, si, str2        ; DS:SI points to string #2
  900.     mov    cx, len         ; Length of search in bytes
  901.     and    al, 0            ; Set ZR flag in case CX = 0
  902.     jcxz    nullp            ; Assume success if length = 0
  903.     test    cl, 1            ; Even number?
  904.     jz    wrdcmp            ; Yes?    Compare word-by-word
  905.     repe    cmpsb            ; No?  Compare byte-by-byte
  906.     jmp    SHORT nullp
  907.  
  908. wrdcmp: shr    cx, 1            ; Decrease count by half
  909.     repe    cmpsw            ; Compare word-by-word
  910.     sub    di, 2            ; Back up 2 characters
  911.     sub    si, 2
  912.     cmpsb                ; Match?
  913.     jne    nullp            ; No?  Then failure
  914.     cmpsb                ; Compare last characters
  915.  
  916. nullp:    mov    ax, 0            ; Set null pointer without
  917.     mov    dx, 0            ;   disturbing flags
  918.     je    exit            ; If strings match, exit
  919.     dec    di            ; Else point to failure
  920.     mov    ax, di
  921.     mov    dx, es
  922. exit:    ret
  923.  
  924. StrCompare ENDP
  925.  
  926.  
  927. ;* StrFindChar - Finds first occurence of character in given ASCIIZ string,
  928. ;* searching either from beginning or end of string. See StrWrite, WinOpen,
  929. ;* WinClose, and StrCompare procedures for other examples of string
  930. ;* instructions.
  931. ;*
  932. ;* Shows:   Instructions - repne     scasb    cld     std
  933. ;*
  934. ;* Params:  ichar - Character to search for
  935. ;*        str - Pointer to ASCIIZ string in which to search
  936. ;*        direct - Direction flag:
  937. ;*             0 = search from start to end
  938. ;*             1 = search from end to start
  939. ;*
  940. ;* Return:  Null pointer if character not found, else pointer to string where
  941. ;*        character first encountered
  942.  
  943. StrFindChar PROC \
  944.     USES ds di si, \
  945.     ichar:BYTE, str:PTR BYTE, direct:WORD
  946.  
  947.     LoadPtr es, di, str        ; ES:DI points to string
  948.     LoadPtr ds, si, str        ;   as does DS:SI
  949.     mov    cx, -1            ; Set scan counter to maximum
  950.     mov    bx, cx            ; BX = max string tail
  951.     cld                ; Assume head-to-tail search
  952.     cmp    direct, 0        ; Assumption correct?
  953.     je    loop1            ; Yes?    Continue
  954.     mov    bx, di            ; No?  Set BX to byte before
  955.     dec    bx            ;   string head and scan
  956.     sub    al, al            ;   string for null terminator
  957.     push    cx            ;   to find string tail
  958.     repne    scasb
  959.     pop    cx            ; Recover scan counter
  960.     dec    di            ; Backup pointer to last
  961.     dec    di            ;   character in string and
  962.     mov    si, di            ;   begin search from there
  963.     std                ; Set direction flag
  964.  
  965. loop1:    lodsb                ; Get first char from string
  966.     cmp    si, bx            ; At head limit?
  967.     je    xmatch            ; Yes?    Then no match
  968.     or    al, al            ; At tail limit?
  969.     je    xmatch            ; Yes?    Then no match
  970.     cmp    al, ichar        ; Character match?
  971.     je    match            ; Yes?    Then exit
  972.     loop    loop1            ; No?  Resume search
  973.  
  974. xmatch: sub    ax, ax            ; Set null pointer if no match
  975.     sub    dx, dx
  976.     jmp    SHORT exit
  977.  
  978. match:    mov    ax, si            ; If match, point to first
  979.     dec    ax            ;   occurence
  980.     cmp    direct, 0        ; Head-to-tail search?
  981.     je    exit            ; Yes?    Then exit
  982.     inc    ax            ; No?  Then adjust pointer
  983.     inc    ax            ;   forward
  984.     mov    dx, ds            ; Pointer segment
  985. exit:    ret
  986.  
  987. StrFindChar ENDP
  988.  
  989.  
  990. ;* GetStr - Gets a string of up to 128 characters from the user. Since
  991. ;* this function uses the DOS input mechanism, it can use the DOS editing
  992. ;* keys or the keys of a DOS command-line editor if one is loaded.
  993. ;*
  994. ;* Shows:   DOS Function - 0Ah (Buffered Keyboard Input)
  995. ;*
  996. ;* Params:  buffer - Pointer to area where input string will be placed
  997. ;*        maxlen - Maximum length (up to 128 characters) of string
  998. ;*
  999. ;* Return:  0 if successful, 1 if error (maxlen is too long)
  1000.  
  1001.     .DATA
  1002. MAXSTR    EQU    128
  1003. max    DB    MAXSTR
  1004. actual    DB    ?
  1005. string    DB    MAXSTR DUP (?)
  1006.  
  1007.     .CODE
  1008. GetStr    PROC \
  1009.     USES si di, \
  1010.     strbuf:PTR BYTE, maxlen:WORD
  1011.  
  1012.     mov    ax, 1            ; Assume error
  1013.     mov    cx, maxlen        ; Copy length to register
  1014.     jcxz    exit            ; Error if maxlen is zero
  1015.     cmp    cx, MAXSTR        
  1016.     ja    exit            ; Error if maxlen is too long
  1017.  
  1018.     mov    max, cl         ; Load maximum length
  1019.     mov    ah, 0Ah         ; Request DOS Function 0Ah
  1020.     mov    dx, OFFSET max        ; Load offset of string
  1021.     int    21h            ; Buffered Keyboard Input
  1022.  
  1023.     mov    bl, actual        ; Put number of characters read
  1024.     sub    bh, bh            ;   in BX
  1025.     mov    string[bx], 0        ; Null-terminate string
  1026.     mov    cx, bx            ; Put count in CX
  1027.     inc    cx            ; Plus one for the null terminator
  1028.  
  1029.     LoadPtr es, di, strbuf        ; ES:DI points to destination buffer
  1030.     mov    si, OFFSET string    ; DS:SI points to source string
  1031.     rep    movsb            ; Copy source to destination
  1032.     sub    ax, ax            ; Return 0 for success
  1033.  
  1034. exit:    ret
  1035.  
  1036. GetStr    ENDP
  1037.  
  1038.     END
  1039.