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

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

Commit 1/2 (Library, Configurators and Serial Server):

  • Changed Emulate.inc so that making 286 and 386 versions now works. Additionally, only one processor type define is needed in the makefile.
  • Minor optimizations.
  • Fixed spelling and did some cleaning.
File size: 13.4 KB
RevLine 
[2]1; Project name : File library
[162]2; Description : ASM library for DOS file handling.
[2]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.
[162]67;
[2]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.
[162]109;
[2]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.
[162]135;
[2]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.
[162]157;
[2]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:
[293]164; AX: Number of bytes actually read if successful (EOF check)
[2]165; DOS error code if CF set
[293]166; CF: Clear if successful
[2]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.
[162]189;
[2]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:
[293]196; AX: Number of bytes actually written if successful (EOF check)
[2]197; DOS error code if CF set
[293]198; CF: Clear if successful
[2]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.
[162]219;
[2]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
[293]226; CF: Clear if successful
[2]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.
[162]242;
[2]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.
[162]261;
[2]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;--------------------------------------------------------------------
[162]284; Checks are the potentially valid drive letters returned by
[2]285; File_SetDrive and File_GetDrive actually valid or not.
[162]286;
[2]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.
[162]313;
[2]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
[162]335 mov cl, dh ; Valid drv count to CX
[2]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.
[162]342;
[2]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
[162]351;--------------------------------------------------------------------
[2]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.
[162]369;
[2]370; File_ChangeDir
371; Parameters:
372; DS:DX Ptr to destination ASCIZ path name
373; Returns:
374; AX: DOS Error code
[293]375; CF: Clear if successful
[2]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.
[162]389;
[2]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.
[162]417;
[2]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.
[162]455;
[2]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.
[162]480;
[2]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.