summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/DIR.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DOS/DIR.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/DOS/DIR.ASM')
-rw-r--r--v4.0/src/DOS/DIR.ASM445
1 files changed, 445 insertions, 0 deletions
diff --git a/v4.0/src/DOS/DIR.ASM b/v4.0/src/DOS/DIR.ASM
new file mode 100644
index 0000000..2a86997
--- /dev/null
+++ b/v4.0/src/DOS/DIR.ASM
@@ -0,0 +1,445 @@
1; SCCSID = @(#)dir.asm 1.1 85/04/10
2; SCCSID = @(#)dir.asm 1.1 85/04/10
3TITLE DIR - Directory and path cracking
4NAME Dir
5; Main Path cracking routines, low level search routines
6;
7; FindEntry
8; SEARCH
9; Srch
10; NEXTENT
11; MetaCompare
12; NEXTENTRY
13; GETENTRY
14; GETENT
15; SETDIRSRCH
16; SETROOTSRCH
17;
18; Revision history:
19;
20; A000 version 4.00 Jan. 1988
21;
22
23;
24; get the appropriate segment definitions
25;
26.xlist
27include dosseg.asm
28include fastopen.inc
29
30CODE SEGMENT BYTE PUBLIC 'CODE'
31 ASSUME SS:DOSGROUP,CS:DOSGROUP
32
33.xcref
34include dossym.inc
35.cref
36.list
37
38asmvar Kanji
39
40 i_need EntFree,WORD
41 i_need DirStart,WORD
42 i_need LastEnt,WORD
43 i_need ClusNum,WORD
44 i_need CurBuf,DWORD
45 i_need Attrib,BYTE
46 i_need DelAll,BYTE
47 i_need VolID,BYTE
48 i_need Name1,BYTE
49 i_need ThisDPB,DWORD
50 i_need EntLast,WORD
51 i_need Creating,BYTE
52 i_need SecClusPos,BYTE
53 i_need ClusFac,BYTE
54 i_need NxtClusNum,WORD
55 i_need DirSec,DWORD ;AN000;
56 I_need FastOpenFlg,BYTE ;AN000;
57 I_need HIGH_SECTOR,WORD ;AN000;
58
59Break <FINDENTRY -- LOOK FOR AN ENTRY>
60
61; Inputs:
62; [THISDPB] set
63; [SECCLUSPOS] = 0
64; [DIRSEC] = Starting directory sector number
65; [CLUSNUM] = Next cluster of directory
66; [CLUSFAC] = Sectors/Cluster
67; [NAME1] = Name to look for
68; Function:
69; Find file name in disk directory.
70; "?" matches any character.
71; Outputs:
72; Carry set if name not found
73; ELSE
74; Zero set if attributes match (always except when creating)
75; AH = Device ID (bit 7 set if not disk)
76; [THISDPB] = Base of drive parameters
77; DS = DOSGROUP
78; ES = DOSGROUP
79; [CURBUF+2]:BX = Pointer into directory buffer
80; [CURBUF+2]:SI = Pointer to First Cluster field in directory entry
81; [CURBUF] has directory record with match
82; [NAME1] has file name
83; [LASTENT] is entry number of the entry
84; All other registers destroyed.
85
86 procedure SEARCH,near
87
88 entry FindEntry
89 DOSAssume CS,<DS>,"FindEntry"
90 ASSUME ES:NOTHING
91
92 invoke STARTSRCH
93 MOV AL,Attrib
94 AND AL,NOT attr_ignore ; Ignore useless bits
95 CMP AL,attr_volume_id ; Looking for vol ID only ?
96 JNZ NOTVOLSRCH ; No
97 CALL SETROOTSRCH ; Yes force search of root
98NOTVOLSRCH:
99 CALL GETENTRY
100 JNC Srch
101 JMP SETESRET
102
103 entry Srch
104
105 PUSH DS
106 MOV DS,WORD PTR [CURBUF+2]
107ASSUME DS:NOTHING
108 MOV AH,BYTE PTR [BX]
109 OR AH,AH ; End of directory?
110 JZ FREE
111 CMP AH,BYTE PTR [DELALL] ; Free entry?
112 JZ FREE
113 TEST BYTE PTR [BX+11],attr_volume_id
114 ; Volume ID file?
115 JZ CHKFNAM ; NO
116 INC BYTE PTR [VOLID]
117CHKFNAM:
118; Context ES
119 ASSUME ES:DOSGroup
120 MOV SI,SS
121 MOV ES,SI
122 MOV SI,BX
123 MOV DI,OFFSET DOSGROUP:NAME1
124;;;;; 7/29/86
125 CMP BYTE PTR [NAME1],0E5H ; special char check
126 JNZ NO_E5
127 MOV BYTE PTR [NAME1],05H
128NO_E5:
129;;;;; 7/29/86
130 CALL MetaCompare
131 JZ FOUND
132 POP DS
133
134 entry NEXTENT
135 DOSAssume CS,<DS>,"NextEnt"
136
137 Assert ISDPB,<<WORD PTR THISDPB+2>,<WORD PTR THISDPB>>,"NextEnt"
138 LES BP,[THISDPB]
139ASSUME ES:NOTHING
140 CALL NEXTENTRY
141 JNC SRCH
142 JMP SHORT SETESRET
143
144FREE:
145 POP DS
146 DOSAssume CS,<DS>,"DIR/Free"
147 MOV CX,[LASTENT]
148 CMP CX,[ENTFREE]
149 JAE TSTALL
150 MOV [ENTFREE],CX
151TSTALL:
152 CMP AH,BYTE PTR [DELALL] ; At end of directory?
153NextEntJ:
154 JZ NEXTENT ; No - continue search
155 MOV [ENTLAST],CX
156 STC
157 JMP SHORT SETESRET
158
159FOUND:
160;
161; We have a file with a matching name. We must now consider the attributes:
162; ATTRIB Action
163; ------ ------
164; Volume_ID Is Volume_ID in test?
165; Otherwise If no create then Is ATTRIB+extra superset of test?
166; If create then Is ATTRIB equal to test?
167;
168 MOV CH,[SI] ; Attributes of file
169 POP DS
170 DOSAssume CS,<DS>,"DIR/found"
171 MOV AH,Attrib ; Attributes of search
172 AND AH,NOT attr_ignore
173 LEA SI,[SI+Dir_First-Dir_Attr] ; point to firclus field
174 TEST CH,attr_volume_id ; Volume ID file?
175 JZ check_one_volume_id ; Nope check other attributes
176 TEST AH,attr_volume_id ; Can we find Volume ID?
177 JZ NEXTENTJ ; Nope, (not even $FCB_CREATE)
178 XOR AH,AH ; Set zero flag for $FCB_CREATE
179 JMP SHORT RETFF ; Found Volume ID
180check_one_volume_id:
181 CMP AH,attr_volume_id ; Looking only for Volume ID?
182 JZ NEXTENTJ ; Yes, continue search
183 invoke MatchAttributes
184 JZ RETFF
185 TEST BYTE PTR [CREATING],-1 ; Pass back mismatch if creating
186 JZ NEXTENTJ ; Otherwise continue searching
187RETFF:
188 LES BP,[THISDPB]
189 MOV AH,ES:[BP.dpb_drive]
190SETESRET:
191 PUSH SS
192 POP ES
193 return
194EndProc Search
195
196; Inputs:
197; DS:SI -> 11 character FCB style name NO '?'
198; Typically this is a directory entry. It MUST be in upper case
199; ES:DI -> 11 character FCB style name with possible '?'
200; Typically this is a FCB or SFT. It MUST be in upper case
201; Function:
202; Compare FCB style names allowing for ? match to any char
203; Outputs:
204; Zero if match else NZ
205; Destroys CX,SI,DI all others preserved
206
207 procedure MetaCompare,near
208ASSUME DS:NOTHING,ES:NOTHING
209 MOV CX,11
210 IF DBCS ;AN000;
211;-------------------- Start of DBCS ;AN000;
212 CMP BYTE PTR DS:[SI],05H ;AN000;; Special case for lead byte of 05h
213 JNE WILDCRD2 ;AN000;; Compare as normal if not an 05h
214 CMP BYTE PTR ES:[DI],0E5H ;AN000;; 05h and 0E5h equivalent for lead byte
215 JNE WILDCRD2 ;AN000;; Compare as normal if not an 05h
216 DEC CX ;AN000;; One less byte to compare
217 INC SI ;AN000;; Bypass lead byte in source and
218 INC DI ;AN000;; destination when 05h and 0E5h found.
219WILDCRD2: ;AN000;
220 PUSH AX ;AN000;;KK. save ax
221cagain: ;AN000;;KK.
222 CMP CX,0 ;AN000;;KK. end of compare ?
223 JLE metaend2 ;AN000;;KK. yes
224 MOV AL,[SI] ;AN000;;KK. is it a Kanji
225 invoke testkanj ;AN000;;KK.
226 JZ notdb ;AN000;;KK. no
227 MOV AX,'??' ;AN000;;KK.
228 CMP ES:[DI],AX ;AN000;;KK. is es:di pointing to '??'
229 JNZ metaend3 ;AN000;;KK. no
230 ADD SI,2 ;AN000;;KK.
231 ADD DI,2 ;AN000;;KK. update pointers and count
232subcx: ;AN000;
233 SUB CX,2 ;AN000;;KK.
234 JMP cagain ;AN000;;KK.
235metaend3: ;AN000;;KK.
236 CMPSW ;AN000;;KK.
237 JNZ metaend2 ;AN000;;KK.
238 JMP subcx ;AN000;;KK.
239notdb: ;AN000;
240 CMPSB ;AN000;;KK. same code ?
241 JZ sameco ;AN000;;KK. yes
242 CMP BYTE PTR ES:[DI-1],"?" ;AN000;;KK. ?
243 JNZ metaend2 ;AN000;;KK. no
244sameco: ;AN000;
245 DEC CX ;AN000;;KK. decrement count
246 JMP cagain ;AN000;;KK.
247
248metaend2: ;AN000;
249 POP AX ;AN000;;KK.
250;-------------------- End of DBCS ;AN000; KK.
251 ELSE ;AN000;
252WILDCRD:
253 REPE CMPSB
254 JZ MetaRet ; most of the time we will fail.
255CHECK_META:
256 CMP BYTE PTR ES:[DI-1],"?"
257 JZ WildCrd
258MetaRet:
259 ENDIF ;AN000;
260 return ; Zero set, Match
261EndProc MetaCompare
262
263Break <NEXTENTRY -- STEP THROUGH DIRECTORY>
264
265; Inputs:
266; Same as outputs of GETENTRY, above
267; Function:
268; Update BX, and [LASTENT] for next directory entry.
269; Carry set if no more.
270
271Procedure NextEntry
272 DOSAssume CS,<DS>,"NextEntry"
273 ASSUME ES:NOTHING
274
275 MOV AX,[LASTENT]
276 CMP AX,[ENTLAST]
277 JZ NONE
278 INC AX
279 LEA BX,[BX+32]
280 CMP BX,DX
281 JB HAVIT
282 MOV BL,BYTE PTR [SECCLUSPOS]
283 INC BL
284 CMP BL,BYTE PTR [CLUSFAC]
285 JB SAMECLUS
286 MOV BX,[NXTCLUSNUM]
287 Invoke IsEOF
288 JAE NONE
289 CMP BX,2
290 JB NONE
291 JMP GETENT
292
293NONE:
294 STC
295 return
296
297HAVIT:
298 MOV [LASTENT],AX
299 CLC
300 return
301
302SAMECLUS:
303 MOV BYTE PTR [SECCLUSPOS],BL
304 MOV [LASTENT],AX
305 PUSH DS
306 LDS DI,[CURBUF]
307ASSUME DS:NOTHING
308 MOV DX,WORD PTR [DI.buf_sector+2] ;AN000; >32mb
309 MOV [HIGH_SECTOR],DX ;AN000; >32mb
310 MOV DX,WORD PTR [DI.buf_sector] ;AN000; >32mb
311
312 ADD DX,1 ;AN000; >32mb
313 ADC [HIGH_SECTOR],0 ;AN000; >32mb
314 POP DS
315 DOSAssume CS,<DS>,"DIR/SameClus"
316 invoke FIRSTCLUSTER
317 XOR BX,BX
318 JMP SETENTRY
319EndProc NextEntry
320
321; Inputs:
322; [LASTENT] has directory entry
323; ES:BP points to drive parameters
324; [DIRSEC],[CLUSNUM],[CLUSFAC],[ENTLAST] set for DIR involved
325; Function:
326; Locates directory entry in preparation for search
327; GETENT provides entry for passing desired entry in AX
328; Outputs:
329; [CURBUF+2]:BX = Pointer to next directory entry in CURBUF
330; [CURBUF+2]:DX = Pointer to first byte after end of CURBUF
331; [LASTENT] = New directory entry number
332; [NXTCLUSNUM],[SECCLUSPOS] set via DIRREAD
333; Carry set if error (currently user FAILed to I 24)
334
335Procedure GETENTRY,NEAR
336 DOSAssume CS,<DS>,"GetEntry"
337 ASSUME ES:NOTHING
338
339 MOV AX,[LASTENT]
340
341 entry GETENT
342
343 Assert ISDPB,<ES,BP>,"GetEntry/GetEnt"
344 MOV [LASTENT],AX
345;
346; Convert the entry number in AX into a byte offset from the beginning of the
347; directory.
348;
349 mov cl,5 ; shift left by 5 = mult by 32
350 rol ax,cl ; keep hight order bits
351 mov dx,ax
352 and ax, NOT (32-1) ; mask off high order bits
353 and dx, 32-1 ; mask off low order bits
354;
355; DX:AX contain the byte offset of the required directory entry from the
356; beginning of the directory. Convert this to a sector number. Round the
357; sector size down to a multiple of 32.
358;
359 MOV BX,ES:[BP.dpb_sector_size]
360 AND BL,255-31 ; Must be multiple of 32
361 DIV BX
362 MOV BX,DX ; Position within sector
363 PUSH BX
364 invoke DIRREAD
365 POP BX
366 retc
367SETENTRY:
368 MOV DX,WORD PTR [CURBUF]
369 ADD DX,BUFINSIZ
370 ADD BX,DX
371 ADD DX,ES:[BP.dpb_sector_size] ; Always clears carry
372 return
373EndProc GetEntry
374
375Break <SETDIRSRCH SETROOTSRCH -- Set Search environments>
376
377; Inputs:
378; BX cluster number of start of directory
379; ES:BP Points to DPB
380; DI next cluster number from fastopen extended info. DOS 3.3 only
381; Function:
382; Set up a directory search
383; Outputs:
384; [DIRSTART] = BX
385; [CLUSFAC],[CLUSNUM],[SECCLUSPOS],[DIRSEC] set
386; Carry set if error (currently user FAILed to I 24)
387; destroys AX,DX,BX
388
389 procedure SETDIRSRCH
390 DOSAssume CS,<DS>,"SetDirSrch"
391 ASSUME ES:NOTHING
392
393 Assert ISDPB,<ES,BP>,"SetDirSrch"
394 OR BX,BX
395 JZ SETROOTSRCH
396 MOV [DIRSTART],BX
397 MOV AL,ES:[BP.dpb_cluster_mask]
398 INC AL
399 MOV BYTE PTR [CLUSFAC],AL
400; DOS 3.3 for FastOPen F.C. 6/12/86
401 SaveReg <SI>
402 TEST [FastOpenFlg],Lookup_Success
403 JNZ UNP_OK
404
405; DOS 3.3 for FastOPen F.C. 6/12/86
406 invoke UNPACK
407 JNC UNP_OK
408 RestoreReg <SI>
409 return
410
411UNP_OK:
412 MOV [CLUSNUM],DI
413 MOV DX,BX
414 XOR BL,BL
415 MOV BYTE PTR [SECCLUSPOS],BL
416 invoke FIGREC
417 RestoreReg <SI>
418 PUSH DX ;AN000; >32mb
419 MOV DX,[HIGH_SECTOR] ;AN000; >32mb
420 MOV WORD PTR [DIRSEC+2],DX ;AN000; >32mb
421 POP DX ;AN000; >32mb
422 MOV WORD PTR [DIRSEC],DX
423 CLC
424 return
425
426entry SETROOTSRCH
427 DOSAssume CS,<DS>,"SetRootSrch"
428 ASSUME ES:NOTHING
429 XOR AX,AX
430 MOV [DIRSTART],AX
431 MOV BYTE PTR [SECCLUSPOS],AL
432 DEC AX
433 MOV [CLUSNUM],AX
434 MOV AX,ES:[BP.dpb_first_sector]
435 MOV DX,ES:[BP.dpb_dir_sector]
436 SUB AX,DX
437 MOV BYTE PTR [CLUSFAC],AL
438 MOV WORD PTR [DIRSEC],DX ;F.C. >32mb
439 MOV WORD PTR [DIRSEC+2],0 ;F.C. >32mb
440 CLC
441 return
442EndProc SETDIRSRCH
443
444CODE ENDS
445 END