home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / masm / masm6 / demos / file.asm < prev    next >
Encoding:
Assembly Source File  |  1990-10-04  |  36.8 KB  |  1,052 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 (only for DOS versions 3.0 and higher)
  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      e_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 bytes not read successfully:
  105.         inc     eof_flag                ; Raise flag
  106.         .ENDIF
  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
  114. close:
  115.         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.         .IF     carry?
  122. e_exit:
  123.         mov     ax, 1                   ; Else set error code
  124.         .ENDIF
  125.         ret
  126.  
  127. CopyFile ENDP
  128.  
  129.  
  130. ;* ChangeDrive - Changes default drive.
  131. ;*
  132. ;* Shows:   DOS Function - 0Eh (Select Disk)
  133. ;*
  134. ;* Params:  Drive - Uppercase letter designation for new drive
  135. ;*
  136. ;* Return:  None
  137.  
  138. ChangeDrive PROC,
  139.         Drive:WORD
  140.  
  141.         mov     ah, 0Eh                 ; DOS Function 0Eh
  142.         mov     dx, Drive               ; Drive designation in DL,
  143.         sub     dl, 'A'                 ;   0=A, 1=B, 2=C, etc
  144.         int     21h                     ; Select Disk
  145.         ret
  146.  
  147. ChangeDrive ENDP
  148.  
  149.  
  150. ;* GetCurDrive - Gets designation of current drive.
  151. ;*
  152. ;* Shows:   DOS Function - 19h (Get Current Disk)
  153. ;*          Instruction - cbw
  154. ;*
  155. ;* Params:  None
  156. ;*
  157. ;* Return:  Short integer with drive designation
  158. ;*          0 = A, 1 = B, 2 = C, etc.
  159.  
  160. GetCurDrive PROC
  161.  
  162.         mov     ah, 19h                 ; DOS Function 19h
  163.         int     21h                     ; Get Current Disk
  164.         cbw                             ; AX = drive designation
  165.         ret
  166.  
  167. GetCurDrive ENDP
  168.  
  169.  
  170. ;* SetDTA - Sets address for new Disk Transfer Area.
  171. ;*
  172. ;* Shows:   DOS Function - 1Ah (Set DTA Address)
  173. ;*
  174. ;* Params:  Dta - Far pointer to new transfer address
  175. ;*
  176. ;* Return:  None
  177.  
  178. SetDTA  PROC USES ds,
  179.         Dta:FPBYTE
  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:FPBYTE
  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 USES ds,
  225.         Attr:WORD, Fspec:PBYTE
  226.  
  227.         LoadPtr ds, dx, Fspec           ; Point DS:DX to file spec
  228.         mov     cx, Attr                ; CX = attribute
  229.         mov     ah, 3Ch                 ; AH = function number
  230.         int     21h                     ; Create file
  231.         .IF     carry?
  232.         mov     ax, -1                  ; Set error code
  233.         .ENDIF
  234.         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 USES ds,
  250.         Access:WORD, Fspec:PBYTE
  251.  
  252.         LoadPtr ds, dx, Fspec           ; Point DS:DX to file spec
  253.         mov     ax, Access              ; AL = access code
  254.         mov     ah, 3Dh                 ; AH = function number
  255.         int     21h                     ; Open file
  256.         .IF     carry?
  257.         mov     ax, -1                  ; Set error code
  258.         .ENDIF
  259.         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 USES ds di,
  296.         Handle:WORD, Len:WORD, Pbuff:PBYTE
  297.  
  298.         LoadPtr ds, dx, Pbuff           ; Point DS:DX to buffer
  299.         mov     di, dx                  ; Keep string offset in DI
  300.         mov     bx, Handle              ; BX = handle
  301.         mov     cx, Len                 ; CX = number of bytes to read
  302.         mov     ah, 3Fh                 ; Request DOS read
  303.         int     21h                     ; Read File
  304.         .IF     carry?
  305.         sub     ax, ax                  ; Set error code
  306.         .ENDIF
  307.         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. ;*          Instructions - inc      dec
  318. ;*
  319. ;* Params:  Handle - File handle
  320. ;*          SPtr - Pointer to ASCIIZ string
  321. ;*
  322. ;* Return:  Short integer with error code
  323. ;*          0 if successful
  324. ;*          1 if write error
  325. ;*          2 if number of bytes written not equal to string length
  326.  
  327. WriteFile PROC USES ds di,
  328.         Handle:WORD, Sptr:PBYTE
  329.  
  330.         LoadPtr es, di, Sptr            ; 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 carry
  346.         .IF     carry?                   ; If carry:
  347.         inc     ax                      ; Increment once for write error
  348.         .ENDIF  ; carry
  349.         .IF     bx != cx                ; If bytes not all written:
  350.         inc     ax                      ; Increment twice
  351.         .ENDIF  ; bx ! cx
  352.         ret
  353.  
  354. WriteFile ENDP
  355.  
  356.  
  357. ;* GetDiskSize - Gets size information from specified disk.
  358. ;*
  359. ;* Shows:   DOS Function - 36h (Get Drive Allocation Information)
  360. ;*
  361. ;* Params:  Drive - Drive code (0 = default, 1 = A, 2 = B, etc.)
  362. ;*          Disk  - Pointer to a structure with 4 short integer members:
  363. ;*                      Member 1 - Total clusters on disk
  364. ;*                      Member 2 - Number of available clusters
  365. ;*                      Member 3 - Sectors/cluster (-1 if invalid drive)
  366. ;*                      Member 4 - Bytes/sector
  367. ;*
  368. ;* Return:  None
  369.  
  370. GetDiskSize PROC USES di,
  371.         Drive:WORD, Disk:PDISKSTAT
  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     (DISKSTAT PTR es:[di]).\
  378.                 total, dx               ; DX = total clusters
  379.         mov     (DISKSTAT PTR es:[di]).\
  380.                 avail, bx               ; BX = number of free clusters
  381.         mov     (DISKSTAT PTR es:[di]).\
  382.                 sects, ax               ; AX = sectors/cluster
  383.         mov     (DISKSTAT PTR es:[di]).\
  384.                 bytes, cx               ; CX = bytes/sector
  385.         ret
  386.  
  387. GetDiskSize ENDP
  388.  
  389.  
  390. ;* MakeDir - Creates a specified subdirectory.
  391. ;*
  392. ;* Shows:   DOS Function - 39h (Create Directory)
  393. ;*
  394. ;* Params:  Pspec - Pointer to ASCIIZ pathname of new subdirectory
  395. ;*
  396. ;* Return:  Short integer with error code
  397. ;*          0 if successful
  398. ;*          1 if create error
  399.  
  400. MakeDir PROC USES ds,
  401.         Pspec:PBYTE
  402.  
  403.         LoadPtr ds, dx, Pspec           ; Point DS:DX to path spec
  404.         mov     ah, 39h                 ; DOS Function 39h
  405.         int     21h                     ; Create Directory
  406.         mov     ax, 0                   ; Set error code, keep flags
  407.         .IF     carry?
  408.         inc     ax                      ; Set error code to 1
  409.         .ENDIF
  410.         ret
  411.  
  412. MakeDir ENDP
  413.  
  414.  
  415. ;* RemoveDir - Removes a specified subdirectory.
  416. ;*
  417. ;* Shows:   DOS Function - 3Ah (Delete Directory)
  418. ;*
  419. ;* Params:  Pspec - Pointer to ASCIIZ pathname of subdirectory
  420. ;*
  421. ;* Return:  Short integer with error code
  422. ;*          0 if successful
  423. ;*          1 if delete error or subdirectory not empty
  424.  
  425. RemoveDir PROC USES ds,
  426.         Pspec:PBYTE
  427.  
  428.         LoadPtr ds, dx, Pspec           ; Point DS:DX to path spec
  429.         mov     ah, 3Ah                 ; DOS Function 3Ah
  430.         int     21h                     ; Delete Directory
  431.         mov     ax, 0                   ; Set error code, keep flags
  432.         .IF     carry?
  433.         inc     ax                      ; Set error code to 1
  434.         .ENDIF
  435.         ret
  436.  
  437. RemoveDir ENDP
  438.  
  439.  
  440. ;* ChangeDir - Changes current (default) directory.
  441. ;*
  442. ;* Shows:   DOS Function - 3Bh (Set Current Directory)
  443. ;*
  444. ;* Params:  Pspec - Pointer to ASCIIZ pathname of target subdirectory
  445. ;*
  446. ;* Return:  Short integer with error code
  447. ;*          0 if successful
  448. ;*          1 if delete error or subdirectory not empty
  449.  
  450. ChangeDir PROC USES ds,
  451.         Pspec:PBYTE
  452.  
  453.         LoadPtr ds, dx, Pspec           ; Point DS:DX to path spec
  454.         mov     ah, 3Bh                 ; DOS Function 3Bh
  455.         int     21h                     ; Set Current Directory
  456.         mov     ax, 0                   ; Set error code, keep flags
  457.         .IF     carry?
  458.         inc     ax                      ; Set error code to 1
  459.         .ENDIF
  460.         ret
  461.  
  462. ChangeDir ENDP
  463.  
  464.  
  465. ;* DelFile - Deletes a specified file.
  466. ;*
  467. ;* Shows:   DOS Function - 41h (Delete File)
  468. ;*
  469. ;* Params:  Fspec - Pointer to ASCIIZ file specification
  470. ;*
  471. ;* Return:  Short integer with error code
  472. ;*          0 if successful
  473. ;*          1 if delete error
  474.  
  475. DelFile PROC USES ds,
  476.         Fspec:PBYTE
  477.  
  478.         LoadPtr ds, dx, Fspec           ; Point DS:DX to file spec
  479.         mov     ah, 41h                 ; DOS Function 41h
  480.         int     21h                     ; Delete File
  481.         mov     ax, 0                   ; Set error code, keep flags
  482.         .IF     carry?
  483.         inc     ax                      ; Set error code to 1
  484.         .ENDIF
  485.         ret
  486.  
  487. DelFile ENDP
  488.  
  489.  
  490. ;* Rewind - Rewinds an open file, specified by handle. See the GetFileSize
  491. ;* procedure for an example of using Function 42h to determine file size.
  492. ;*
  493. ;* Shows:   DOS Function - 42h (Set File Pointer)
  494. ;*
  495. ;* Params:  Handle - File handle
  496. ;*
  497. ;* Return:  None
  498.  
  499. Rewind  PROC,
  500.         Handle:WORD
  501.  
  502.         mov     bx, Handle              ; BX = file handle
  503.         mov     ax, 4200h               ; AH = function #,
  504.                                         ; AL = move to beginning of
  505.         sub     cx, cx                  ;      file plus offset
  506.         sub     dx, dx                  ; CX:DX = offset (zero)
  507.         int     21h                     ; Set File Pointer
  508.         ret
  509.  
  510. Rewind  ENDP
  511.  
  512.  
  513. ;* GetFileSize - Gets the size of an open file, specified by handle.
  514. ;*
  515. ;* Shows:   DOS Function - 42h (Set File Pointer)
  516. ;*
  517. ;* Params:  Handle - File handle
  518. ;*
  519. ;* Return:  Long integer with file size in bytes
  520.  
  521. GetFileSize PROC,
  522.         Handle:WORD
  523.  
  524.         mov     bx, Handle              ; BX = file handle
  525.         mov     ax, 4202h               ; AH = function #,
  526.                                         ; AL = move to end of
  527.         sub     cx, cx                  ;      file plus offset
  528.         sub     dx, dx                  ; CX:DX = offset (zero)
  529.         int     21h                     ; Set File Pointer
  530.         mov     ax, dx                  ; Set DX:AX = file size in
  531.         mov     dx, cx                  ;   bytes, return long int
  532.         ret
  533.  
  534. GetFileSize ENDP
  535.  
  536.  
  537. ;* GetAttribute - Gets the attribute(s) of a specified file.
  538. ;*
  539. ;* Shows:   DOS Function - 43h (Get or Set File Attributes)
  540. ;*
  541. ;* Params:  Fspec - Pointer to ASCIIZ file specification
  542. ;*
  543. ;* Return:  Short integer with file attribute bits set as follows:
  544. ;*                bit 0 = read-only              bit 3 = volume label
  545. ;*                bit 1 = hidden                 bit 4 = subdirectory
  546. ;*                bit 2 = system                 bit 5 = archive
  547. ;*          0 indicates normal data file
  548. ;*          -1 indicates error
  549.  
  550. GetAttribute PROC USES ds,
  551.         Fspec:PBYTE
  552.  
  553.         LoadPtr ds, dx, Fspec           ; DS:DX = file specification
  554.         mov     ax, 4300h               ; AH = function #
  555.                                         ; AL = 0 (return attribute)
  556.         int     21h                     ; Get File Attributes
  557.         mov     ax, -1                  ; Set code, keep flags
  558.         .IF     !carry?
  559.         mov     ax, cx                  ; Return with file attribute bits
  560.         .ENDIF
  561.         ret
  562.  
  563. GetAttribute ENDP
  564.  
  565.  
  566. ;* SetAttribute - Sets the attribute(s) of a specified file.
  567. ;*
  568. ;* Shows:   DOS Function - 43h (Get or Set File Attributes)
  569. ;*
  570. ;* Params:  Attr - Attribute bits set as follows:
  571. ;*                        bit 0 = read-only      bit 3 = volume label
  572. ;*                        bit 1 = hidden                 bit 4 = subdirectory
  573. ;*                        bit 2 = system                 bit 5 = archive
  574. ;*                 (Attr = 0 for normal data file)
  575. ;*          Fspec - Pointer to ASCIIZ file specification
  576. ;*
  577. ;* Return:  Short integer with error code
  578. ;*          0 if successful
  579. ;*          1 if delete error
  580.  
  581. SetAttribute PROC USES ds,
  582.         Attr:WORD,
  583.         Fspec:PBYTE
  584.  
  585.         LoadPtr ds, dx, Fspec           ; DS:DX = file specification
  586.         mov     cx, Attr                ; Put attribute code in CX
  587.         mov     ax, 4301h               ; AH = function #
  588.                                         ; AL = 1 (set attribute)
  589.         int     21h                     ; Set File Attributes
  590.         mov     ax, 0                   ; Clear code, keep flags
  591.         .IF     carry?
  592.         inc     ax                      ; Set error code to 1
  593.         .ENDIF
  594.         ret
  595.  
  596. SetAttribute ENDP
  597.  
  598.  
  599. ;* GetCurDir - Gets the current directory of default drive.
  600. ;*
  601. ;* Shows:   DOS Function - 47h (Get Current Directory)
  602. ;*
  603. ;* Params:  Spec - Pointer to 64-byte buffer to receive directory
  604. ;*          path. Path terminates with 0 but does not include
  605. ;*          drive and does not begin with backslash.
  606. ;*
  607. ;* Return:  Short integer with error code
  608. ;*          0 if successful
  609. ;*          1 if delete error or subdirectory not empty
  610.  
  611. GetCurDir PROC USES ds si,
  612.         Spec:PBYTE
  613.  
  614.         LoadPtr ds, si, Spec            ; DS:SI = spec address
  615.         mov     ah, 47h                 ; AH = function number
  616.         sub     dl, dl                  ; DL = current drive (0)
  617.         int     21h                     ; Get Current Directory
  618.         mov     ax, 0                   ; Set error code, keep flags
  619.         .IF     carry?
  620.         inc     ax                      ; Set error code to 1
  621.         .ENDIF
  622.         ret
  623.  
  624. GetCurDir ENDP
  625.  
  626.  
  627. ;* FindFirst - Finds first entry in given directory matching specification.
  628. ;*
  629. ;* Shows:   DOS Function - 4Eh (Find First File)
  630. ;*          Instructions - pushf    popf
  631. ;*
  632. ;* Params:  Attr - Attribute code (see header comments for CreateFile)
  633. ;*          Fspec - Pointer to ASCIIZ file specification
  634. ;*          Finfo - Pointer to 43-byte buffer to receive
  635. ;*                      data from matched entry
  636. ;*
  637. ;* Return:  Short integer with error code
  638. ;*          0 if successful
  639. ;*          1 if no match found
  640.  
  641.         .DATA
  642. OldDta  FPVOID  ?                       ; Storage for old DTA address
  643.  
  644.         .CODE
  645.  
  646. FindFirst PROC USES ds,
  647.         Attr:WORD,
  648.         Fspec:PBYTE,
  649.         Finfo:PFILEINFO
  650.  
  651.         ; Get current DTA address, pass address of pointer to hold value
  652.         INVOKE  GetDTA,
  653.                 ADDR OldDta
  654.  
  655.         mov     cx, Attr                ; Load CX with file attribute
  656.  
  657.         ; Set DTA address, pass pointer to structure
  658.         INVOKE  SetDTA,
  659.                 Finfo
  660.  
  661.         LoadPtr ds, dx, Fspec           ; Point DS:DX to file spec
  662.         mov     ah, 4Eh                 ; AH = function number
  663.         int     21h                     ; Find First File
  664.  
  665.         pushf                           ; Preserve flags
  666.  
  667.         ; Restore DTA address, pass pointer
  668.         INVOKE  SetDTA,
  669.                 OldDta
  670.  
  671.         sub     ax, ax                  ; Set error code
  672.         popf                            ; Recover flags
  673.         .IF     carry?
  674.         inc     ax                      ; Set error code to 1
  675.         .ENDIF
  676.         ret
  677.  
  678. FindFirst ENDP
  679.  
  680.  
  681. ;* FindNext - Finds next entry in given directory matching specification.
  682. ;* (Should be called only after successfully calling the FindFirst procedure.)
  683. ;*
  684. ;* Shows:   DOS Function - 4Fh (Find Next File)
  685. ;*          Operator - OFFSET
  686. ;*
  687. ;* Params:  Finfo - Pointer to 43-byte buffer. This must be the same buffer
  688. ;*                      (or a duplicate) returned from the FindFirst procedure.
  689. ;*
  690. ;* Return:  Short integer with error code
  691. ;*          0 if successful
  692. ;*          1 if no more matches found
  693.  
  694. FindNext PROC USES ds,
  695.         Finfo:PFILEINFO
  696.  
  697.         ; Get current DTA address, pass address of pointer to hold value
  698.         INVOKE  GetDTA,
  699.                 ADDR OldDta
  700.  
  701.         ; Set DTA address, pass pointer to structure
  702.         INVOKE  SetDTA,
  703.                 Finfo
  704.  
  705.         mov     ah, 4Fh                 ; AH = function number
  706.         int     21h                     ; Find Next File
  707.  
  708.         pushf                           ; Preserve flags
  709.  
  710.         ; Restore DTA address, pass pointer
  711.         INVOKE  SetDTA,
  712.                 OldDta
  713.  
  714.         sub     ax, ax                  ; Set error code
  715.         popf                            ; Recover flags
  716.         .IF     carry?
  717.         inc     ax                      ; Set error code to 1
  718.         .ENDIF
  719.         ret
  720.  
  721. FindNext ENDP
  722.  
  723.  
  724. ;* RenameFile - Renames specified file.
  725. ;*
  726. ;* Shows:   DOS Function - 56h (Rename File)
  727. ;*
  728. ;* Params:  Fspec1 - Pointer to old ASCIIZ file specification
  729. ;*          Fspec2 - Pointer to new ASCIIZ file specification
  730. ;*
  731. ;*          The drive must be the same for both arguments, but the path
  732. ;*          does not. This allows files to be moved between directories.
  733. ;*
  734. ;* Return:  Short integer with error code
  735. ;*          0 if successful
  736. ;*          1 if error
  737.  
  738. RenameFile PROC USES ds di,
  739.         Fspec1:PBYTE,
  740.         Fspec2:PBYTE
  741.  
  742.         LoadPtr ds, dx, Fspec1          ; Point DS:DX to old file spec
  743.         LoadPtr es, di, Fspec2          ; Point ES:DI to new file spec
  744.         mov     ah, 56h                 ; AH = function number
  745.         int     21h                     ; Rename File
  746.         mov     ax, 0                   ; Clear error code, keep flags
  747.         .IF     carry?
  748.         inc     ax                      ; Set error code to 1
  749.         .ENDIF
  750.         ret
  751.  
  752. RenameFile ENDP
  753.  
  754.  
  755. ;* GetFileTime - Gets date/time for open file specified by handle.
  756. ;*
  757. ;* Shows:   DOS Function - 57h (Get or Set File Date and Time)
  758. ;*          Instructions - shl     shr
  759. ;*
  760. ;* Params:  Handle - Handle of open file
  761. ;*          Sptr - Pointer to 18-byte buffer to receive date/time
  762. ;*
  763. ;* Return:  Short integer with error code
  764. ;*          0 if successful
  765. ;*          1 if error
  766.  
  767. GetFileTime PROC USES di,
  768.         Handle:WORD,
  769.         Sptr:PBYTE
  770.  
  771.         mov     ax, 5700h               ; AH = function number
  772.                                         ; AL = get request
  773.         mov     bx, Handle              ; BX = file handle
  774.         int     21h                     ; Get File Date and Time
  775.         mov     ax, 1                   ; Set error code, keep flags
  776.         .IF     !carry?                 ; If not carry, continue
  777.         mov     bx, cx                  ; Else save time in BX
  778.         mov     al, bl                  ; Get low byte of time
  779.         and     al, 00011111y           ; Mask to get 2-second incrs,
  780.         shl     al, 1                   ;   convert to seconds
  781.         push    ax                      ; Save seconds
  782.         mov     cl, 5
  783.         shr     bx, cl                  ; Shift minutes into low byte
  784.         mov     al, bl                  ; Get new low byte
  785.         and     al, 00111111y           ; Mask to get minutes
  786.         push    ax                      ; Save minutes
  787.         mov     cl, 6
  788.         shr     bx, cl                  ; Shift hours into low byte
  789.         push    bx                      ; Save hours
  790.  
  791.         mov     bl, dl                  ; Get low byte of date
  792.         and     bl, 00011111y           ; Mask to get day in BX
  793.         mov     cl, 5
  794.         shr     dx, cl                  ; Shift month into low byte
  795.         mov     al, dl                  ; Get new low byte
  796.         and     al, 00001111y           ; Mask to get month
  797.         mov     cl, 4
  798.         shr     dx, cl                  ; Shift year into low byte
  799.         add     dx, 80                  ; Year is relative to 1980
  800.         push    dx                      ; Save year
  801.         push    bx                      ; Save day
  802.         push    ax                      ; Save month
  803.  
  804.         LoadPtr es, di, Sptr            ; Point ES:DI to 18-byte
  805.         mov     cx, 6                   ;   string
  806.  
  807.         .REPEAT
  808.         pop     ax                      ; Get 6 numbers sequentially in AL
  809.         aam                             ; Convert to unpacked BCD
  810.         xchg    al, ah                  ; Switch bytes for word move
  811.         or      ax, '00'                ; Make ASCII numerals
  812.         stosw                           ; Copy to string
  813.         mov     al, '-'                 ; Separator for date text
  814.         cmp     cl, 4                   ; First 3 iters are for date
  815.         jg      @F                      ; If CX=6 or 5, insert hyphen
  816.         mov     al, ' '                 ; Separator date and time
  817.         je      @F                      ; If CX = 4, insert hyphen
  818.         mov     al, ':'                 ; Separator for time text
  819.         .IF     cl != 1
  820. @@:     stosb                           ; Copy separator to string
  821.         .ENDIF
  822.         .UNTILCXZ
  823.  
  824.         sub     ax, ax                  ; Clear return code
  825.         stosb                           ; Terminate string with null
  826.         .ENDIF                          ;   to make ASCIIZ
  827.         ret
  828.  
  829. GetFileTime ENDP
  830.  
  831.  
  832. ;* UniqueFile - Creates and opens a new file with a name unique to the
  833. ;* specified directory. The name is manufactured from the current time,
  834. ;* making it useful for temporary files. For DOS versions 3.0 and higher.
  835. ;*
  836. ;* Shows:   DOS Function - 5Ah (Create Temporary File)
  837. ;*
  838. ;* Params:  Attr - Attribute code (see header comments for CreateFile)
  839. ;*          Pspec - Pointer to ASCIIZ path specification
  840. ;*
  841. ;* Return:  Short integer with file handle or -1 for error
  842.  
  843. UniqueFile PROC USES ds,
  844.         Attr:WORD,
  845.         Pspec:PBYTE
  846.  
  847.         ; Get DOS version
  848.         INVOKE  GetVer
  849.  
  850.         cmp     ax, 300                 ; 3.0 or higher?
  851.         jb      e_exit                  ; No?  Quit with error
  852.         LoadPtr ds, dx, Pspec           ; Point DS:DX to path spec
  853.         mov     cx, Attr                ; CX = attribute
  854.         mov     ah, 5Ah                 ; AH = function number
  855.         int     21h                     ; Create Temporary File
  856.         .IF     carry?
  857. e_exit: mov     ax, -1                  ; Set error code
  858.         .ENDIF
  859.         ret
  860.  
  861. UniqueFile ENDP
  862.  
  863.  
  864. ;* CreateNewFile - Creates a new file with specified attribute. Differs
  865. ;* from the CreateFile procedure in that it returns an error if file
  866. ;* already exists. For DOS versions 3.0 and higher.
  867. ;*
  868. ;* Shows:   DOS Function - 5Bh (Create New File)
  869. ;*
  870. ;* Params:  Attr - Attribute code (see header comments for CreateFile)
  871. ;*          Fspec - Pointer to ASCIIZ file specification
  872. ;*
  873. ;* Return:  Short integer with file handle or -1 for error
  874.  
  875. CreateNewFile PROC USES ds,
  876.         Attr:WORD,
  877.         Fspec:PBYTE
  878.  
  879.         LoadPtr ds, dx, Fspec           ; Point DS:DX to file spec
  880.         mov     cx, Attr                ; CX = attribute
  881.         mov     ah, 5Bh                 ; AH = function number
  882.         int     21h                     ; Create New File
  883.         .IF     carry?
  884.         mov     ax, -1                  ; Set error code
  885.         .ENDIF
  886.         ret
  887.  
  888. CreateNewFile ENDP
  889.  
  890.  
  891. ;* StrCompare - Compares two strings for equality. See StrWrite, StrFindChar,
  892. ;* WinOpen, and WinClose procedures for other examples of string instructions.
  893. ;*
  894. ;* Shows:   Instructions - cmpsb     cmpsw     repe     jcxz
  895. ;*
  896. ;* Params:  Sptr1 - Pointer to first string
  897. ;*          Sptr2 - Pointer to second string
  898. ;*          Len  - Length in bytes for comparison. Strings need not be of
  899. ;*                 equal length; however if len is an even number, comparison
  900. ;*                 is made on a word-by-word basis and thus is more efficient.
  901. ;*
  902. ;* Return:  Null pointer if strings match; else pointer to string #1 where
  903. ;*          match failed.
  904.  
  905. StrCompare PROC USES ds di si,
  906.         Sptr1:PBYTE,
  907.         Sptr2:PBYTE,
  908.         Len:WORD
  909.  
  910.         LoadPtr es, di, Sptr1           ; ES:DI points to string #1
  911.         LoadPtr ds, si, Sptr2           ; DS:SI points to string #2
  912.         mov     cx, Len                 ; Length of search in bytes
  913.         and     al, 0                   ; Set ZR flag in case CX = 0
  914.         .IF     cx != 0                 ; If length is not 0:
  915.         .IF     !(cl & 1)               ; If not even number:
  916.         repe    cmpsb                   ; Compare byte-by-byte
  917.         .ELSE                           ; Else compare word-by-word
  918.         shr     cx, 1                   ; Decrease count by half
  919.         repe    cmpsw                   ; Compare word-by-word
  920.         sub     di, 2                   ; Back up 2 characters
  921.         sub     si, 2
  922.         cmpsb                           ; Match?
  923.         .IF     zero?                   ; No?  Then failure
  924.         cmpsb                           ; Compare last characters
  925.         .ENDIF  ; zero
  926.         .ENDIF  ; cl & 1
  927.         .ENDIF  ; cx != 0
  928.  
  929.         mov     ax, 0                   ; Set null pointer without
  930.         mov     dx, 0                   ;   disturbing flags
  931.         .IF     !zero?                  ; If no match:
  932.         dec     di                      ; Point to failure
  933.         mov     ax, di
  934.         mov     dx, es
  935.         .ENDIF
  936.         ret
  937.  
  938. StrCompare ENDP
  939.  
  940.  
  941. ;* StrFindChar - Finds first occurence of character in given ASCIIZ string,
  942. ;* searching either from beginning or end of string. See StrWrite, WinOpen,
  943. ;* WinClose, and StrCompare procedures for other examples of string
  944. ;* instructions.
  945. ;*
  946. ;* Shows:   Instructions - repne     scasb    cld     std
  947. ;*
  948. ;* Params:  Ichar - Character to search for
  949. ;*          Sptr - Pointer to ASCIIZ string in which to search
  950. ;*          Direct - Direction flag:
  951. ;*                       0 = search from start to end
  952. ;*                       1 = search from end to start
  953. ;*
  954. ;* Return:  Null pointer if character not found, else pointer to string where
  955. ;*          character first encountered
  956.  
  957. StrFindChar PROC USES ds di si,
  958.         IChar:SBYTE,
  959.         Sptr:PBYTE,
  960.         Direct:WORD
  961.  
  962.         LoadPtr es, di, Sptr            ; ES:DI points to string
  963.         LoadPtr ds, si, Sptr            ;   as does DS:SI
  964.         mov     cx, -1                  ; Set scan counter to maximum
  965.         mov     bx, cx                  ; BX = max string tail
  966.         cld                             ; Assume head-to-tail search
  967.  
  968.         .IF     Direct != 0             ; If assumption correct:
  969.         mov     bx, di                  ; Set BX to byte before
  970.         dec     bx                      ;   string head and scan
  971.         sub     al, al                  ;   string for null terminator
  972.         push    cx                      ;   to find string tail
  973.         repne   scasb
  974.         pop     cx                      ; Recover scan counter
  975.         dec     di                      ; Backup pointer to last
  976.         dec     di                      ;   character in string and
  977.         mov     si, di                  ;   begin search from there
  978.         std                             ; Set direction flag
  979.         .ENDIF
  980.  
  981.         .REPEAT
  982.         lodsb                           ; Get first char from string
  983.         .IF     (si == bx) || (al == 0) ; If at head or tail limit:
  984.         sub     ax, ax                  ; No match
  985.         sub     dx, dx                  ; Set null pointer
  986.         jmp     exit
  987.         .ENDIF
  988.         .UNTILCXZ al == IChar
  989.  
  990.         mov     ax, si                  ; Match, so point to first
  991.         dec     ax                      ;   occurence
  992.         .IF     Direct != 0             ; If head-to-tail search:
  993.         inc     ax                      ; Adjust pointer forward
  994.         inc     ax
  995.         mov     dx, ds                  ; Pointer segment
  996.         .ENDIF
  997. exit:
  998.         ret
  999.  
  1000. StrFindChar ENDP
  1001.  
  1002.  
  1003. ;* GetStr - Gets a string of up to 128 characters from the user. Since
  1004. ;* this function uses the DOS input mechanism, it can use the DOS editing
  1005. ;* keys or the keys of a DOS command-line editor if one is loaded.
  1006. ;*
  1007. ;* Shows:   DOS Function - 0Ah (Buffered Keyboard Input)
  1008. ;*          Directive    - EQU
  1009. ;*
  1010. ;* Params:  Strbuf - Pointer to area where input string will be placed
  1011. ;*          Maxlen - Maximum length (up to 128 characters) of string
  1012. ;*
  1013. ;* Return:  0 if successful, 1 if error (Maxlen is too long)
  1014.  
  1015.         .DATA
  1016. MAXSTR  EQU     128
  1017. max     BYTE    MAXSTR
  1018. actual  BYTE    ?
  1019. string  BYTE    MAXSTR DUP (?)
  1020.  
  1021.         .CODE
  1022. GetStr  PROC USES si di,
  1023.         Strbuf:PBYTE,
  1024.         Maxlen:WORD
  1025.  
  1026.         mov     ax, 1                   ; Assume error
  1027.         mov     cx, Maxlen              ; Copy length to register
  1028.  
  1029.         .IF (cx != 0) && (cx <= MAXSTR) ; Error if 0 or too long
  1030.         mov     max, cl                 ; Load maximum length
  1031.         mov     ah, 0Ah                 ; Request DOS Function 0Ah
  1032.         mov     dx, OFFSET max          ; Load offset of string
  1033.         int     21h                     ; Buffered Keyboard Input
  1034.  
  1035.         mov     bl, actual              ; Put number of characters read
  1036.         sub     bh, bh                  ;   in BX
  1037.         mov     string[bx], 0           ; Null-terminate string
  1038.         mov     cx, bx                  ; Put count in CX
  1039.         inc     cx                      ; Plus one for the null terminator
  1040.  
  1041.         LoadPtr es, di, Strbuf          ; ES:DI points to destination buffer
  1042.         mov     si, OFFSET string       ; DS:SI points to source string
  1043.         rep     movsb                   ; Copy source to destination
  1044.         sub     ax, ax                  ; Return 0 for success
  1045.         .ENDIF
  1046.  
  1047.         ret
  1048.  
  1049. GetStr  ENDP
  1050.  
  1051.         END
  1052.