1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
|
; SCCSID = @(#)search.asm 1.1 85/04/10
TITLE SEARCH - Directory scan system calls
NAME SEARCH
;
;
; Directory search system calls. These will be passed direct text of the
; pathname from the user. They will need to be passed through the macro
; expander prior to being sent through the low-level stuff. I/O specs are
; defined in DISPATCH. The system calls are:
;
;
; $Dir_Search_First written
; $Dir_Search_Next written
; $Find_First written
; $Find_Next written
; PackName written
;
; Modification history:
;
; Created: ARR 4 April 1983
;
.xlist
;
; get the appropriate segment definitions
;
include dosseg.asm
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME SS:DOSGroup,CS:DOSGroup
.xcref
INCLUDE DOSSYM.INC
INCLUDE DEVSYM.INC
INCLUDE fastopen.inc
INCLUDE fastxxxx.inc
.cref
.list
i_need SEARCHBUF,53
i_need SATTRIB,BYTE
I_Need OpenBuf,128
I_need DMAAdd,DWORD
I_need THISFCB,DWORD
I_need CurDrv,BYTE
I_need EXTFCB,BYTE
I_need Fastopenflg,BYTE
I_need DOS34_FLAG,WORD
; Inputs:
; DS:DX Points to unopenned FCB
; Function:
; Directory is searched for first matching entry and the directory
; entry is loaded at the disk transfer address
; Returns:
; AL = -1 if no entries matched, otherwise 0
procedure $DIR_SEARCH_FIRST,NEAR
ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
MOV WORD PTR [THISFCB],DX
MOV WORD PTR [THISFCB+2],DS
MOV SI,DX
CMP BYTE PTR [SI],0FFH
JNZ NORMFCB4
ADD SI,7 ; Point to drive select byte
NORMFCB4:
SaveReg <[SI]> ; Save original drive byte for later
Context ES ; get es to address DOSGroup
MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer
invoke TransFCB ; convert the FCB, set SATTRIB EXTFCB
JNC SearchIt ; no error, go and look
RestoreReg <BX> ; Clean stack
;
; Error code is in AX
;
transfer FCB_Ret_Err ; error
SearchIt:
Context DS ; get ready for search
SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>>
MOV WORD PTR [DMAAdd],OFFSET DOSGroup:SEARCHBUF
MOV WORD PTR [DMAAdd+2],DS
invoke GET_FAST_SEARCH ; search
RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>>
JNC SearchSet ; no error, transfer info
RestoreReg <BX> ; Clean stack
;
; Error code is in AX
;
transfer FCB_Ret_Err
;
; The search was successful (or the search-next). We store the information
; into the user's FCB for continuation.
;
SearchSet:
MOV SI,OFFSET DOSGroup:SEARCHBUF
LES DI,[THISFCB] ; point to the FCB
TEST [EXTFCB],0FFH ;
JZ NORMFCB1
ADD DI,7 ; Point past the extension
NORMFCB1:
RestoreReg <BX> ; Get original drive byte
OR BL,BL
JNZ SearchDrv
MOV BL,[CurDrv]
INC BL
SearchDrv:
LODSB ; Get correct search contin drive byte
XCHG AL,BL ; Search byte to BL, user byte to AL
INC DI
; STOSB ; Store the correct "user" drive byte
; at the start of the search info
MOV CX,20/2
REP MOVSW ; Rest of search cont info, SI -> entry
XCHG AL,BL ; User drive byte back to BL, search
; byte to AL
STOSB ; Search contin drive byte at end of
; contin info
LES DI,[DMAAdd]
TEST [EXTFCB],0FFH
JZ NORMFCB2
MOV AL,0FFH
STOSB
INC AL
MOV CX,5
REP STOSB
MOV AL,[SATTRIB]
STOSB
NORMFCB2:
MOV AL,BL ; User Drive byte
STOSB
IF DBCS ;AN000;
MOVSW ; 2/13/KK ;AN000;
CMP BYTE PTR ES:[DI-2],5 ; 2/13/KK ;AN000;
JNZ NOTKTRAN ; 2/13/KK ;AN000;
MOV BYTE PTR ES:[DI-2],0E5H ; 2/13/KK ;AN000;
NOTKTRAN: ; 2/13/KK ;AN000;
MOV CX,15 ; 2/13/KK ;AN000;
ELSE ;AN000;
MOV CX,16 ; 32 / 2 words of dir entry ;AN000;
ENDIF ;AN000;
REP MOVSW
transfer FCB_Ret_OK
EndProc $DIR_SEARCH_FIRST
; Inputs:
; DS:DX points to unopenned FCB returned by $DIR_SEARCH_FIRST
; Function:
; Directory is searched for the next matching entry and the directory
; entry is loaded at the disk transfer address
; Returns:
; AL = -1 if no entries matched, otherwise 0
procedure $DIR_SEARCH_NEXT,NEAR
ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
MOV WORD PTR [THISFCB],DX
MOV WORD PTR [THISFCB+2],DS
MOV [SATTRIB],0
MOV [EXTFCB],0
Context ES
MOV DI,OFFSET DOSGroup:SEARCHBUF
MOV SI,DX
CMP BYTE PTR [SI],0FFH
JNZ NORMFCB6
ADD SI,6
LODSB
MOV [SATTRIB],AL
DEC [EXTFCB]
NORMFCB6:
LODSB ; Get original user drive byte
SaveReg <AX> ; Put it on stack
MOV AL,[SI+20] ; Get correct search contin drive byte
STOSB ; Put in correct place
MOV CX,20/2
REP MOVSW ; Transfer in rest of search contin info
Context DS
SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>>
MOV WORD PTR [DMAAdd],OFFSET DOSGroup:SEARCHBUF
MOV WORD PTR [DMAAdd+2],DS
invoke DOS_SEARCH_NEXT ; Find it
RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>>
JC SearchNoMore
JMP SearchSet ; Ok set return
SearchNoMore:
LES DI,[THISFCB]
TEST [EXTFCB],0FFH
JZ NORMFCB8
ADD DI,7 ; Point past the extension
NORMFCB8:
RestoreReg <BX> ; Get original drive byte
MOV ES:[DI],BL ; Store the correct "user" drive byte
; at the right spot
;
; error code is in AX
;
transfer FCB_Ret_Err
EndProc $DIR_SEARCH_NEXT
; Assembler usage:
; MOV AH, FindFirst
; LDS DX, name
; MOV CX, attr
; INT 21h
; ; DMA address has datablock
;
; Error Returns:
; AX = error_path_not_found
; = error_no_more_files
procedure $FIND_FIRST,NEAR
ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
MOV SI,DX ; get name in appropriate place
MOV [SATTRIB],CL ; Search attribute to correct loc
MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer
invoke TransPathSet ; convert the path
JNC Find_it ; no error, go and look
FindError:
error error_path_not_found ; error and map into one.
Find_it:
Context DS
SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>>
MOV WORD PTR [DMAAdd],OFFSET DOSGroup:SEARCHBUF
MOV WORD PTR [DMAAdd+2],DS
invoke GET_FAST_SEARCH ; search
RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>>
JNC FindSet ; no error, transfer info
transfer Sys_Ret_Err
FindSet:
MOV SI,OFFSET DOSGroup:SEARCHBUF
LES DI,[DMAAdd]
MOV CX,21
REP MOVSB
PUSH SI ; Save pointer to start of entry
MOV AL,[SI.dir_attr]
STOSB
ADD SI,dir_time
MOVSW ; dir_time
MOVSW ; dir_date
INC SI
INC SI ; Skip dir_first
MOVSW ; dir_size (2 words)
MOVSW
POP SI ; Point back to dir_name
IF DBCS ;AN000;
PUSH DI ; XXXX save dest name 2/13/KK ;AN000;
CALL PackName ;AN000;
POP DI ; XXXX Recover dest name 2/13/KK ;AN000;
CMP BYTE PTR ES:[DI],05H ; XXXX Need fix? 2/13/KK ;AN000;
JNZ FNXXX ; XXXX No 2/13/KK ;AN000;
MOV BYTE PTR ES:[DI],0E5H ; XXXX Yes, Fix 2/13/KK ;AN000;
FNXXX: ; 2/13/KK ;AN000;
ELSE ;AN000;
CALL PackName
ENDIF
transfer Sys_Ret_OK ; bye with no errors
EndProc $FIND_FIRST
procedure $FIND_NEXT,NEAR
ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
; Assembler usage:
; ; dma points at area returned by find_first
; MOV AH, findnext
; INT 21h
; ; next entry is at dma
;
; Error Returns:
; AX = error_no_more_files
Context ES
MOV DI,OFFSET DOSGroup:SEARCHBUF
LDS SI,[DMAAdd]
MOV CX,21
REP MOVSB ; Put the search continuation info
; in the right place
Context DS ; get ready for search
SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>>
MOV WORD PTR [DMAAdd],OFFSET DOSGroup:SEARCHBUF
MOV WORD PTR [DMAAdd+2],DS
invoke DOS_SEARCH_NEXT ; Find it
RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>>
JNC FindSet ; No error, set info
transfer Sys_Ret_Err
EndProc $FIND_NEXT
Break <PackName - convert file names from FCB to ASCIZ>
;
; PackName - transfer a file name from DS:SI to ES:DI and convert it to
; the ASCIZ format.
;
; Input: DS:SI points to an 11 character FCB or dir entry name
; ES:DI points to a destination area (13 bytes)
; Output: Above pointers advanced
; Registers modified: SI,DI,CX,AL
Procedure PackName,NEAR
ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
MOV CX,8 ; Pack the name
REP MOVSB ; Move all of it
main_kill_tail:
CMP BYTE PTR ES:[DI-1]," "
JNZ find_check_dot
DEC DI ; Back up over trailing space
INC CX
CMP CX,8
JB main_kill_tail
find_check_dot:
CMP WORD PTR [SI],(" " SHL 8) OR " "
JNZ got_ext ; Some chars in extension
CMP BYTE PTR [SI+2]," "
JZ find_done ; No extension
got_ext:
MOV AL,"."
STOSB
MOV CX,3
REP MOVSB
ext_kill_tail:
CMP BYTE PTR ES:[DI-1]," "
JNZ find_done
DEC DI ; Back up over trailing space
JMP ext_kill_tail
find_done:
XOR AX,AX
STOSB ; NUL terminate
return
EndProc PackName
procedure GET_FAST_SEARCH,NEAR
ASSUME DS:NOTHING,ES:NOTHING
OR [DOS34_FLAG],SEARCH_FASTOPEN ;FO.trigger fastopen ;AN000;
invoke DOS_SEARCH_FIRST
return
EndProc GET_FAST_SEARCH
CODE ENDS
END
|