source: xtideuniversalbios/trunk/Configurator/Src/Libraries/file.asm @ 162

Last change on this file since 162 was 162, checked in by krille_n_@…, 13 years ago

Changes to all parts of the project:

  • Size optimizations, mostly by excluding code from the BIOS.
  • Cleaned the source a bit, fixed spelling and grammar mistakes.
File size: 13.4 KB
Line 
1; Project name  :   File library
2; Description   :   ASM library for DOS file handling.
3
4;--------------- Equates -----------------------------
5
6; DOS DTA (Disk Transfer Area)
7struc DTA
8    ; Undocumented fields
9    .reserved   resb    21
10    ; Documented fields
11    .bFileAttr  resb    1   ; 15h, Attribute of matching file
12    .wFileTime  resb    2   ; 16h, File time
13    .wFileDate  resb    2   ; 18h, File date
14    .dwFileSize resb    4   ; 1Ah, File size in bytes
15    .szFile     resb    13  ; 1Eh, ASCIZ filename + extension
16endstruc
17
18; Bits for file attribute byte
19FLG_FATTR_RDONLY    EQU     (1<<0)  ; Read only
20FLG_FATTR_HIDDEN    EQU     (1<<1)  ; Hidden
21FLG_FATTR_SYS       EQU     (1<<2)  ; System
22FLG_FATTR_LABEL     EQU     (1<<3)  ; Volume Label
23FLG_FATTR_DIR       EQU     (1<<4)  ; Directory
24FLG_FATTR_ARCH      EQU     (1<<5)  ; Archive
25
26; File access and sharing modes
27VAL_FACCS_READ      EQU     0       ; Read only
28VAL_FACCS_WRITE     EQU     1       ; Write only
29VAL_FACCS_RW        EQU     2       ; Read and Write
30
31; DOS File I/O error codes
32ERR_DOS_SUCCESS     EQU     0       ; No error
33ERR_DOS_FUNC        EQU     1       ; Function number invalid
34ERR_DOS_NOFILE      EQU     2       ; File not found
35ERR_DOS_NOPATH      EQU     3       ; Path not found
36ERR_DOS_TOOMANY     EQU     4       ; Too many open files
37ERR_DOS_DENIED      EQU     5       ; Access denied
38ERR_DOS_HANDLE      EQU     6       ; Invalid handle
39ERR_DOS_CODE        EQU     12      ; Access code invalid
40ERR_DOS_NOMORE      EQU     18      ; No more files
41
42
43;-------------- Private global variables -------------
44; Section containing initialized data
45;SECTION .data
46
47; DOS file I/O related error strings
48g_szNoErr:      db  "No error",STOP
49g_szFunc:       db  "Function number invalid",STOP
50g_szNoFile:     db  "File not found",STOP
51g_szNoPath:     db  "Path not found",STOP
52g_szTooMany:    db  "Too many open files",STOP
53g_szDenied:     db  "Access denied",STOP
54g_szHandle:     db  "Invalid handle",STOP
55g_szCode:       db  "Access code invalid",STOP
56g_szNoMore:     db  "No more files",STOP
57g_szUnknown:    db  "Unknown file I/O error",STOP
58
59
60;-------------- Public functions ---------------------
61; Section containing code
62SECTION .text
63
64;--------------------------------------------------------------------
65; Returns pointer to error string.
66; Pointer is always valid, even if error code is not.
67;
68; File_GetErrStr
69;   Parameters:
70;       AX:     DOS File I/O error code
71;   Returns:
72;       ES:DI:  Ptr to error string
73;   Corrupts registers:
74;       Nothing
75;--------------------------------------------------------------------
76ALIGN JUMP_ALIGN
77File_GetErrStr:
78    mov     di, g_szNoMore      ; Assume ERR_DOS_NOMORE
79    cmp     ax, ERR_DOS_NOMORE
80    je      .Return
81    mov     di, g_szCode        ; Assume ERR_DOS_CODE
82    cmp     ax, ERR_DOS_CODE
83    je      .Return
84    mov     di, g_szUnknown     ; Assume unknown error
85    cmp     ax, ERR_DOS_HANDLE  ; Can use lookup?
86    ja      .Return             ;  If not, return
87    mov     di, ax              ; Copy error code to DI
88    shl     di, 1               ; Shift for word lookup
89    mov     di, [cs:di+.rgwErrLookup]
90ALIGN JUMP_ALIGN
91.Return:
92    push    cs                  ; Copy CS...
93    pop     es                  ; ...to ES
94    ret
95ALIGN WORD_ALIGN
96.rgwErrLookup:
97    dw  g_szNoErr   ; 0
98    dw  g_szFunc    ; 1
99    dw  g_szNoFile  ; 2
100    dw  g_szNoPath  ; 3
101    dw  g_szTooMany ; 4
102    dw  g_szDenied  ; 5
103    dw  g_szHandle  ; 6
104
105
106;--------------------------------------------------------------------
107; Opens file for reading and writing.
108; File must be closed with File_Close when no longer needed.
109;
110; File_Open
111;   Parameters:
112;       AL:     File access and sharing mode:
113;                   VAL_FACCS_READ  Open file for reading
114;                   VAL_FACCS_WRITE Open file for writing
115;                   VAL_FACCS_RW    Open file for read and write
116;       DS:DX:  Ptr to destination ASCIZ file name
117;   Returns:
118;       AX:     DOS error code if CF set
119;       BX:     File handle if CF cleared
120;       CF:     Clear if file opened successfully
121;               Set if error
122;   Corrupts registers:
123;       AX, BX
124;--------------------------------------------------------------------
125ALIGN JUMP_ALIGN
126File_Open:
127    mov     ah, 3Dh             ; Open Existing File
128    int     21h
129    mov     bx, ax              ; Copy handle to BX
130    ret
131
132
133;--------------------------------------------------------------------
134; Closes file.
135;
136; File_Close
137;   Parameters:
138;       BX:     File handle
139;   Returns:
140;       AX:     DOS error code if CF set
141;       CF:     Clear if file closed successfully
142;               Set if error
143;   Corrupts registers:
144;       AX
145;--------------------------------------------------------------------
146ALIGN JUMP_ALIGN
147File_Close:
148    mov     ah, 3Eh             ; Open Existing File
149    int     21h
150    ret
151
152
153;--------------------------------------------------------------------
154; Reads binary data from file.
155; File position is updated so next read will start where
156; previous read stopped.
157;
158; File_Read
159;   Parameters:
160;       BX:     File handle
161;       CX:     Number of bytes to read
162;       ES:DI:  Ptr to destination buffer
163;   Returns:
164;       AX:     Number of bytes actually read if successfull (EOF check)
165;               DOS error code if CF set
166;       CF:     Clear if successfull
167;               Set if error
168;   Corrupts registers:
169;       Nothing
170;--------------------------------------------------------------------
171ALIGN JUMP_ALIGN
172File_Read:
173    push    ds
174    push    dx
175    push    es                  ; Copy ES...
176    pop     ds                  ; ...to DS
177    mov     dx, di              ; DS:DX now points to destination buffer
178    mov     ah, 3Fh             ; Read from File or Device
179    int     21h
180    pop     dx
181    pop     ds
182    ret
183
184
185;--------------------------------------------------------------------
186; Writes binary data to file.
187; File position is updated so next write will start where
188; previous write stopped.
189;
190; File_Write
191;   Parameters:
192;       BX:     File handle
193;       CX:     Number of bytes to write
194;       ES:DI:  Ptr to source buffer
195;   Returns:
196;       AX:     Number of bytes actually written if successfull (EOF check)
197;               DOS error code if CF set
198;       CF:     Clear if successfull
199;               Set if error
200;   Corrupts registers:
201;       Nothing
202;--------------------------------------------------------------------
203ALIGN JUMP_ALIGN
204File_Write:
205    push    ds
206    push    dx
207    push    es                  ; Copy ES...
208    pop     ds                  ; ...to DS
209    mov     dx, di              ; DS:DX now points to source buffer
210    mov     ah, 40h             ; Write to File or Device
211    int     21h
212    pop     dx
213    pop     ds
214    ret
215
216
217;--------------------------------------------------------------------
218; Sets current file position to wanted offset.
219;
220; File_SetFilePos
221;   Parameters:
222;       BX:     File handle
223;       CX:DX:  New offset (signed)
224;   Returns:
225;       AX:     DOS error code if CF set
226;       CF:     Clear if successfull
227;               Set if error
228;   Corrupts registers:
229;       Nothing
230;--------------------------------------------------------------------
231ALIGN JUMP_ALIGN
232File_SetFilePos:
233    push    dx
234    mov     ax, 42h<<8          ; Set Current File Position (from file start)
235    int     21h
236    pop     dx
237    ret
238
239
240;--------------------------------------------------------------------
241; Changes current default drive.
242;
243; File_SetDrive
244;   Parameters:
245;       DL:     New default drive (00h=A:, 01h=B: ...)
246;   Returns:
247;       AL:     Number of potentially valid drive letters available
248;   Corrupts registers:
249;       AH
250;--------------------------------------------------------------------
251ALIGN JUMP_ALIGN
252File_SetDrive:
253    mov     ah, 0Eh             ; Select Default Drive
254    int     21h
255    ret
256
257
258;--------------------------------------------------------------------
259; Returns current default drive and number of
260; potentially drive letters available.
261;
262; File_GetDrive
263;   Parameters:
264;       Nothing
265;   Returns:
266;       AL:     Number of potentially valid drive letters available
267;       AH:     Current default drive (00h=A:, 01h=B: ...)
268;   Corrupts registers:
269;       Nothing
270;--------------------------------------------------------------------
271ALIGN JUMP_ALIGN
272File_GetDrive:
273    push    dx
274    mov     ah, 19h             ; Get Current Default Drive
275    int     21h                 ; Get drive to AL
276    mov     dl, al              ; Copy drive number to DL
277    call    File_SetDrive       ; Set to current and get drive letter count
278    mov     ah, dl              ; Copy current drive to AH
279    pop     dx
280    ret
281
282
283;--------------------------------------------------------------------
284; Checks are the potentially valid drive letters returned by
285; File_SetDrive and File_GetDrive actually valid or not.
286;
287; File_IsDrive
288;   Parameters:
289;       DL:     Drive number (00h=A:, 01h=B: ...)
290;   Returns:
291;       AL:     00h if valid drive number, FFh if invalid drive number
292;       ZF:     Set if drive number is valid
293;               Cleared if drive number is invalid
294;   Corrupts registers:
295;       AH
296;--------------------------------------------------------------------
297ALIGN JUMP_ALIGN
298File_IsDrive:
299    push    ds
300    push    bx
301    inc     dx                  ; 00h=default drive, 01h=A:, 02h=B: ...
302    mov     ah, 32h             ; Get DOS Drive Parameter Block for Specific Drive
303    int     21h
304    dec     dx                  ; Restore DX
305    test    al, al              ; Set ZF according to result
306    pop     bx
307    pop     ds
308    ret
309
310
311;--------------------------------------------------------------------
312; Returns number of valid drive letters.
313;
314; File_GetValidDrvCnt
315;   Parameters:
316;       Nothing
317;   Returns:
318;       CX:     Number of valid drives
319;   Corrupts registers:
320;       AX, DX
321;--------------------------------------------------------------------
322ALIGN JUMP_ALIGN
323File_GetValidDrvCnt:
324    call    File_GetDrive       ; Get potential drive letters to AL
325    eMOVZX  cx, al              ; Letter count to CX
326    xor     dx, dx              ; Zero DX (DH=valid count, DL=drv num)
327ALIGN JUMP_ALIGN
328.LetterLoop:
329    call    File_IsDrive
330    not     al                  ; Invert return bits
331    and     al, 1               ; Clear all but bit 1
332    add     dh, al              ; Increment valid count
333    inc     dx                  ; Increment drive number
334    loop    .LetterLoop         ; Loop while drive letters left
335    mov     cl, dh              ; Valid drv count to CX
336    ret
337
338
339;--------------------------------------------------------------------
340; Return device number for Nth valid drive.
341; This function does not check if index in CX is valid.
342;
343; File_GetNthValidDrv
344;   Parameters:
345;       CX:     Index of valid drive to look for
346;   Returns:
347;       AX:     Drive letter (A, B...)
348;       DX:     Drive device number (00h=A:, 01h=B: ...)
349;   Corrupts registers:
350;       CX
351;--------------------------------------------------------------------
352ALIGN JUMP_ALIGN
353File_GetNthValidDrv:
354    inc     cx                  ; Index to count
355    mov     dx, -1              ; Dev num, increments to zero
356ALIGN JUMP_ALIGN
357.DrvLoop:
358    inc     dx                  ; Increment device number
359    call    File_IsDrive        ; Is drive valid?
360    jnz     .DrvLoop            ;  Loop if not
361    loop    .DrvLoop            ; Loop until wanted drive found
362    mov     ax, dx              ; Drive device number to AX
363    add     ax, 'A'             ; Dev number to drive letter
364    ret
365
366
367;--------------------------------------------------------------------
368; Changes current directory.
369;
370; File_ChangeDir
371;   Parameters:
372;       DS:DX   Ptr to destination ASCIZ path name
373;   Returns:
374;       AX:     DOS Error code
375;       CF:     Clear if successfull
376;               Set if error
377;   Corrupts registers:
378;       Nothing
379;--------------------------------------------------------------------
380ALIGN JUMP_ALIGN
381File_ChangeDir:
382    mov     ah, 3Bh             ; Set Current Directory
383    int     21h
384    ret
385
386
387;--------------------------------------------------------------------
388; Finds files from wanted path using search wildcard characters.
389;
390; File_FindAndCount
391;   Parameters:
392;       DS:DX   Ptr to ASCIZ path or file name (* and ? wildcards allowed)
393;   Returns:
394;       CX:     Number of files found
395;   Corrupts registers:
396;       AX
397;--------------------------------------------------------------------
398ALIGN JUMP_ALIGN
399File_IsFile:
400File_FindAndCount:
401    xor     cx, cx              ; Zero file count
402    call    File_FindFirst      ; Find first file
403    jc      .Return             ; Return if no files found
404ALIGN JUMP_ALIGN
405.IsNextLoop:
406    inc     cx                  ; Increment file count
407    call    File_FindNext       ; Find next file
408    jnc     .IsNextLoop         ; Loop while files left
409ALIGN JUMP_ALIGN
410.Return:
411    ret
412
413
414;--------------------------------------------------------------------
415; Finds files from wanted path using search wildcard characters.
416; Ptr to DTA is returned for wanted file.
417;
418; File_GetDTA
419;   Parameters:
420;       CX:     Index for file whose DTA is to be returned
421;       DS:DX   Ptr to ASCIZ path or file name (* and ? wildcards allowed)
422;   Returns:
423;       DS:BX:  Ptr to file DTA
424;       CF:     Set if file was not found
425;               Cleared if file found and DTA is returned
426;   Corrupts registers:
427;       AX, DX
428;--------------------------------------------------------------------
429ALIGN JUMP_ALIGN
430File_GetDTA:
431    call    File_FindFirst      ; Find first file
432    jc      .RetErr             ; Return if no files found
433    xor     dx, dx              ; Zero file index
434ALIGN JUMP_ALIGN
435.IsNextLoop:
436    cmp     cx, dx              ; Wanted file found?
437    je      .RetDTA             ;  If so, jump to return DTA
438    inc     dx                  ; Increment index for next file
439    call    File_FindNext       ; Find next file
440    jnc     .IsNextLoop         ; Loop while files left
441.RetErr:
442    ret
443ALIGN JUMP_ALIGN
444.RetDTA:
445    push    cs                  ; Push code segment
446    pop     ds                  ; CS to DS
447    mov     bx, 80h             ; DTA starts at DOS PSP:80h
448    ret
449
450
451;-------------- Private functions ---------------------
452
453;--------------------------------------------------------------------
454; Find first file or directory.
455;
456; File_FindFirst
457;   Parameters:
458;       DS:DX   Ptr to ASCIZ path or file name (* and ? wildcards allowed)
459;   Returns:
460;       AX:     DOS Error code
461;       CF:     Set if file was not found
462;               Cleared if file was found
463;   Corrupts registers:
464;       Nothing
465;--------------------------------------------------------------------
466ALIGN JUMP_ALIGN
467File_FindFirst:
468    push    cx
469    ;mov        cx, FLG_FATTR_DIR   ; Directories and files
470    xor     cx, cx
471    mov     ax, 4Eh<<8          ; Find First Matching File
472    int     21h
473    pop     cx
474    ret
475
476
477;--------------------------------------------------------------------
478; Find next file or directory. File_FindFirst must always be called
479; before calling File_FindNext.
480;
481; File_FindNext
482;   Parameters:
483;       Nothing
484;   Returns:
485;       AX:     DOS Error code
486;       CF:     Set if file was not found
487;               Cleared if file was found
488;   Corrupts registers:
489;       Nothing
490;--------------------------------------------------------------------
491ALIGN JUMP_ALIGN
492File_FindNext:
493    mov     ah, 4Fh             ; Find Next Matching File
494    int     21h
495    ret
Note: See TracBrowser for help on using the repository browser.