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

Last change on this file since 122 was 2, checked in by Tomi Tilli, 14 years ago
File size: 13.5 KB
RevLine 
[2]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.