home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mass61.zip / mass.zip / masm61 / DISK3 / SAMPLES / DEMOS / FILE.AS$ / FILE
Text File  |  1992-11-12  |  38KB  |  1,053 lines

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