summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/SEARCH.ASM
blob: 1f23942124541f1bd8e22439f55fdbda13e624e5 (plain) (blame)
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