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

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