]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/FCB.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / FCB.ASM
1 ; SCCSID = @(#)fcb.asm 1.2 85/07/23
2 ; SCCSID = @(#)fcb.asm 1.2 85/07/23
3 TITLE FCB - FCB parse calls for MSDOS
4 NAME FCB
5 ; Low level routines for parsing names into FCBs and analyzing
6 ; filename characters
7 ;
8 ; MakeFcb
9 ; NameTrans
10 ; PATHCHRCMP
11 ; GetLet
12 ; TESTKANJ
13 ; NORMSCAN
14 ; DELIM
15 ;
16 ; Revision history:
17 ;
18 ; A000 version 4.00 Jan. 1988
19 ;
20
21 ;
22 ; get the appropriate segment definitions
23 ;
24 .xlist
25 include dosseg.asm
26
27
28 TableLook equ -1
29
30 Table Segment
31 Zero label byte
32 Table ENDS
33
34 CODE SEGMENT BYTE PUBLIC 'CODE'
35 ASSUME SS:DOSGROUP,CS:DOSGROUP
36
37 .xcref
38 include dossym.inc
39 include devsym.inc
40 include doscntry.inc ;AN000; 2/12/KK
41 .cref
42 .list
43
44 i_need Name1,BYTE
45 i_need Creating,BYTE
46 i_need Attrib,BYTE
47 i_need SpaceFlag,BYTE
48 i_need FILE_UCASE_TAB,byte ;DOS 3.3
49 i_need COUNTRY_CDPG,byte ;AN000; 2/12/KK
50 i_need DrvErr,BYTE ;AN000; 2/12/KK
51 i_need DOS34_FLAG,WORD ;AN000; 2/12/KK
52
53 procedure MakeFcb,NEAR
54 ScanSeparator = 1
55 DRVBIT EQU 2
56 NAMBIT EQU 4
57 EXTBIT EQU 8
58 MOV BYTE PTR [SpaceFlag],0
59 XOR DL,DL ; Flag--not ambiguous file name
60 TEST AL,DRVBIT ; Use current drive field if default?
61 JNZ DEFDRV
62 MOV BYTE PTR ES:[DI],0 ; No - use default drive
63 DEFDRV:
64 INC DI
65 MOV CX,8
66 TEST AL,NAMBIT ; Use current name fields as defualt?
67 XCHG AX,BX ; Save bits in BX
68 MOV AL," "
69 JZ FILLB ; If not, go fill with blanks
70 ADD DI,CX
71 XOR CX,CX ; Don't fill any
72 FILLB:
73 REP STOSB
74 MOV CL,3
75 TEST BL,EXTBIT ; Use current extension as default
76 JZ FILLB2
77 ADD DI,CX
78 XOR CX,CX
79 FILLB2:
80 REP STOSB
81 XCHG AX,CX ; Put zero in AX
82 STOSW
83 STOSW ; Initialize two words after to zero
84 SUB DI,16 ; Point back at start
85 TEST BL,ScanSeparator; Scan off separators if not zero
86 JZ SKPSPC
87 CALL SCANB ; Peel off blanks and tabs
88 CALL DELIM ; Is it a one-time-only delimiter?
89 JNZ NOSCAN
90 INC SI ; Skip over the delimiter
91 SKPSPC:
92 CALL SCANB ; Always kill preceding blanks and tabs
93 NOSCAN:
94 CALL GETLET
95 JBE NODRV ; Quit if termination character
96 IF DBCS ;AN000;
97 CALL TESTKANJ ;AN000;; 2/18/KK
98 JNE NODRV ;AN000;; 2/18/KK
99 ENDIF ;AN000;
100 CMP BYTE PTR[SI],":" ; Check for potential drive specifier
101 JNZ NODRV
102 INC SI ; Skip over colon
103 SUB AL,"@" ; Convert drive letter to drive number (A=1)
104 JBE BADDRV ; Drive letter out of range
105
106 PUSH AX
107 Invoke GetVisDrv
108 POP AX
109 JNC HavDrv
110 CMP [DrvErr],error_not_DOS_disk ; if not FAt drive ;AN000;
111 JZ HavDrv ; assume ok ;AN000;
112 BADDRV:
113 MOV DL,-1
114 HAVDRV:
115 STOSB ; Put drive specifier in first byte
116 INC SI
117 DEC DI ; Counteract next two instructions
118 NODRV:
119 DEC SI ; Back up
120 INC DI ; Skip drive byte
121
122 entry NORMSCAN
123
124 MOV CX,8
125 CALL GETWORD ; Get 8-letter file name
126 CMP BYTE PTR [SI],"."
127 JNZ NODOT
128 INC SI ; Skip over dot if present
129 TEST [DOS34_FLAG],DBCS_VOLID2 ;AN000;
130 JZ VOLOK ;AN000;
131 MOVSB ; 2nd byte of DBCS ;AN000;
132 MOV CX,2 ;AN000;
133 JMP SHORT contvol ;AN000;
134 VOLOK:
135 MOV CX,3 ; Get 3-letter extension
136 contvol:
137 CALL MUSTGETWORD
138 NODOT:
139 MOV AL,DL
140 return
141
142 NONAM:
143 ADD DI,CX
144 DEC SI
145 return
146
147 GETWORD:
148 CALL GETLET
149 JBE NONAM ; Exit if invalid character
150 DEC SI
151 ;
152 ; UGH!!! Horrible bug here that should be fixed at some point:
153 ; If the name we are scanning is longer than CX, we keep on reading!
154 ;
155 MUSTGETWORD:
156 CALL GETLET
157 ;
158 ; If spaceFlag is set then we allow spaces in a pathname
159 ;
160 JB FILLNAM
161 JNZ MustCheckCX
162 TEST BYTE PTR [SpaceFlag],0FFh
163 JZ FILLNAM
164 CMP AL," "
165 JNZ FILLNAM
166
167 MustCheckCX:
168 JCXZ MUSTGETWORD
169 DEC CX
170 CMP AL,"*" ; Check for ambiguous file specifier
171 JNZ NOSTAR
172 MOV AL,"?"
173 REP STOSB
174 NOSTAR:
175 STOSB
176
177 IF DBCS ;AN000;
178 CALL TESTKANJ ;AN000;
179 JZ NOTDUAL3 ;AN000;
180 JCXZ BNDERR ; Attempt to straddle boundry ;AN000;
181 MOVSB ; Transfer second byte ;AN000;
182 DEC CX ;AN000;
183 JMP MUSTGETWORD ;AN000;
184 BNDERR: ;AN000;
185 TEST [DOS34_FLAG],DBCS_VOLID ;AN000;
186 JZ notvolumeid ;AN000;
187 TEST [DOS34_FLAG],DBCS_VOLID2 ;AN000;
188 JNZ notvolumeid ;AN000;
189 OR [DOS34_FLAG],DBCS_VOLID2 ;AN000;
190 JMP MUSTGETWORD ;AN000;
191
192 notvolumeid:
193 ;; INC CX ; Undo the store of the first byte
194 DEC DI
195 MOV AL," " ;PTM. ;AN000;
196 STOSB ;PTM. ;AN000;
197 INC SI ;PTM. ;AN000;
198 JMP MUSTGETWORD ;PTM. ;AN000;
199
200 NOTDUAL3: ;AN000;
201 ENDIF ;AN000;
202
203 CMP AL,"?"
204 JNZ MUSTGETWORD
205 OR DL,1 ; Flag ambiguous file name
206 JMP MUSTGETWORD
207 FILLNAM:
208 MOV AL," "
209 REP STOSB
210 DEC SI
211 return
212
213 SCANB:
214 LODSB
215 CALL SPCHK
216 JZ SCANB
217 IF DBCS ;AN000; ;AN000;
218 CMP AL,81H ;AN000;; 1ST BYTE OF DBCS BLANK 2/18/KK ;AN000;
219 JNE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000;
220 CALL TESTKANJ ;AN000;; 2/23/KK 3/31/KK revoved ;AN000;
221 JE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000;
222 CMP BYTE PTR [SI],40H;AN000;H ; 2ND BYTE OF DBCS BLANK 2/18/KK 3/31/KK revove;AN000;
223 JNE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000;
224 INC SI ;AN000;; 2/18/KK 3/31/KK revoved ;AN000;
225 JMP SCANB ;AN000;; 2/18/KK 3/31/KK revoved ;AN000;
226 SCANB_EXIT: ;AN000;; 2/18/KK 3/31/KK revoved ;AN000;
227 ENDIF ;AN000;
228 DEC SI
229 return
230 EndProc MakeFCB
231
232 ;
233 ; NameTrans is used by FindPath to scan off an element of a path. We must
234 ; allow spaces in pathnames
235 ;
236 ; Inputs: DS:SI points to start of path element
237 ; Outputs: Name1 has unpacked name, uppercased
238 ; ES = DOSGroup
239 ; DS:SI advanced after name
240 ; Registers modified: DI,AX,DX,CX
241 procedure NameTrans,near
242 ASSUME DS:NOTHING,ES:NOTHING
243 MOV BYTE PTR [SpaceFlag],1
244 context ES
245 MOV DI,OFFSET DOSGROUP:NAME1
246 PUSH DI
247 MOV AX,' '
248 MOV CX,5
249 STOSB
250 REP STOSW ; Fill "FCB" at NAME1 with spaces
251 XOR AL,AL ; Set stuff for NORMSCAN
252 MOV DL,AL
253 STOSB
254 POP DI
255
256 CALL NORMSCAN
257 IF DBCS ;AN000;;KK.
258 MOV AL,[NAME1] ;AN000;;KK. check 1st char
259 invoke testkanj ;AN000;;KK. dbcs ?
260 JZ notdbcs ;AN000;;KK. no
261 return ;AN000;;KK. yes
262 notdbcs: ;AN000;
263 ENDIF ;AN000;
264 CMP [NAME1],0E5H
265 retnz
266 MOV [NAME1],5 ; Magic name translation
267 return
268
269 EndProc nametrans
270
271 Break <GETLET, DELIM -- CHECK CHARACTERS AND CONVERT>
272
273 If TableLook
274 ChType Macro ch,bits
275 ORG CharType-Zero+ch
276 db bits
277 ENDM
278
279 Table SEGMENT
280 PUBLIC CharType
281 Public FCB001S,FCB001E
282 FCB001S label byte
283 CharType DB 256 dup (-1)
284 ChType ".", <LOW (NOT ( fChk))>
285 ChType '"', <LOW (NOT (fFCB+fChk))>
286 ChType "/", <LOW (NOT (fFCB+fChk))>
287 ChType "\", <LOW (NOT (fFCB+fChk))>
288 ChType "[", <LOW (NOT (fFCB+fChk))>
289 ChType "]", <LOW (NOT (fFCB+fChk))>
290 ChType ":", <LOW (NOT (fFCB+fChk+fDelim))>
291 ChType "<", <LOW (NOT (fFCB+fChk+fDelim))>
292 ChType "|", <LOW (NOT (fFCB+fChk+fDelim))>
293 ChType ">", <LOW (NOT (fFCB+fChk+fDelim))>
294 ChType "+", <LOW (NOT (fFCB+fChk+fDelim))>
295 ChType "=", <LOW (NOT (fFCB+fChk+fDelim))>
296 ChType ";", <LOW (NOT (fFCB+fChk+fDelim))>
297 ChType ",", <LOW (NOT (fFCB+fChk+fDelim))>
298 ChType 0, <LOW (NOT (fFCB+fChk))> ; NUL
299 ChType 1, <LOW (NOT (fFCB+fChk))> ; ^A
300 ChType 2, <LOW (NOT (fFCB+fChk))> ; ^b
301 ChType 3, <LOW (NOT (fFCB+fChk))> ; ^c
302 ChType 4, <LOW (NOT (fFCB+fChk))> ; ^d
303 ChType 5, <LOW (NOT (fFCB+fChk))> ; ^e
304 ChType 6, <LOW (NOT (fFCB+fChk))> ; ^f
305 ChType 7, <LOW (NOT (fFCB+fChk))> ; ^g
306 ChType 8, <LOW (NOT (fFCB+fChk))> ; ^h
307 ChType 9, <LOW (NOT (fFCB+fChk+fDelim+fSpChk))> ; Tab
308 ChType 10, <LOW (NOT (fFCB+fChk))> ; ^j
309 ChType 11, <LOW (NOT (fFCB+fChk))> ; ^k
310 ChType 12, <LOW (NOT (fFCB+fChk))> ; ^l
311 ChType 13, <LOW (NOT (fFCB+fChk))> ; ^m
312 ChType 14, <LOW (NOT (fFCB+fChk))> ; ^n
313 ChType 15, <LOW (NOT (fFCB+fChk))> ; ^o
314 ChType 16, <LOW (NOT (fFCB+fChk))> ; ^p
315 ChType 17, <LOW (NOT (fFCB+fChk))> ; ^q
316 ChType 18, <LOW (NOT (fFCB+fChk))> ; ^r
317 ChType 19, <LOW (NOT (fFCB+fChk))> ; ^s
318 ChType 20, <LOW (NOT (fFCB+fChk))> ; ^t
319 ChType 21, <LOW (NOT (fFCB+fChk))> ; ^u
320 ChType 22, <LOW (NOT (fFCB+fChk))> ; ^v
321 ChType 23, <LOW (NOT (fFCB+fChk))> ; ^w
322 ChType 24, <LOW (NOT (fFCB+fChk))> ; ^x
323 ChType 25, <LOW (NOT (fFCB+fChk))> ; ^y
324 ChType 26, <LOW (NOT (fFCB+fChk))> ; ^z
325 ChType 27, <LOW (NOT (fFCB+fChk))> ; ^[
326 ChType 28, <LOW (NOT (fFCB+fChk))> ; ^\
327 ChType 29, <LOW (NOT (fFCB+fChk))> ; ^]
328 ChType 30, <LOW (NOT (fFCB+fChk))> ; ^^
329 ChType 31, <LOW (NOT (fFCB+fChk))> ; ^_
330 ChType " ", <LOW (NOT ( fChk+fDelim+fSpChk))>
331 ChType 255, -1
332 FCB001E label byte
333 Table ENDS
334 ENDIF
335 ;
336 ; Get a byte from [SI], convert it to upper case, and compare for delimiter.
337 ; ZF set if a delimiter, CY set if a control character (other than TAB).
338 ;
339 ; DOS 3.3 modification for file char upper case. F.C. 5/29/86
340 procedure GetLet,NEAR
341 LODSB
342 entry GetLet2 ;AN000;; called by uCase
343 PUSH BX
344 MOV BX,OFFSET DOSGROUP:FILE_UCASE_TAB+2
345 getget:
346 CMP AL,"a"
347 JB CHK1
348 CMP AL,"z"
349 JA CHK1
350 SUB AL,20H ; Convert to upper case
351 CHK1:
352 CMP AL,80H ; DOS 3.3
353 JB GOTIT ; DOS 3.3
354 SUB AL,80H ;translate to upper case with this index
355 ;
356 XLAT BYTE PTR CS:[BX]
357 If TableLook
358 GOTIT:
359 PUSH AX
360 MOV BX,OFFSET DOSGROUP:CharType
361 XLAT BYTE PTR CS:[BX]
362
363 TEST AL,fChk
364 POP AX
365 POP BX
366 RET
367 entry GetLet3 ;AN000; called by uCase
368 PUSH BX ;AN000;
369 JMP getget ;AN000;
370
371 ELSE
372 GOTIT:
373 POP BX
374 CMP AL,"."
375 retz
376 CMP AL,'"'
377 retz
378 CALL PATHCHRCMP
379 retz
380 CMP AL,"["
381 retz
382 CMP AL,"]"
383 retz
384 ENDIF
385
386 entry DELIM
387
388 IF TableLook
389 PUSH AX
390 PUSH BX
391 MOV BX,OFFSET DOSGroup:CharType
392 XLAT BYTE PTR CS:[BX]
393 TEST AL,fDelim
394 POP BX
395 POP AX
396 RET
397 ELSE
398 CMP AL,":"
399 retz
400
401 CMP AL,"<"
402 retz
403 CMP AL,"|"
404 retz
405 CMP AL,">"
406 retz
407
408 CMP AL,"+"
409 retz
410 CMP AL,"="
411 retz
412 CMP AL,";"
413 retz
414 CMP AL,","
415 retz
416 ENDIF
417 entry SPCHK
418 IF TableLook
419 PUSH AX
420 PUSH BX
421 MOV BX,OFFSET DOSGroup:CharType
422 XLAT BYTE PTR CS:[BX]
423 TEST AL,fSpChk
424 POP BX
425 POP AX
426 RET
427 ELSE
428 CMP AL,9 ; Filter out tabs too
429 retz
430 ; WARNING! " " MUST be the last compare
431 CMP AL," "
432 return
433 ENDIF
434 EndProc GetLet
435
436 Procedure PATHCHRCMP,NEAR
437 CMP AL,'/'
438 JBE PathRet
439 CMP AL,'\'
440 return
441 GotFor:
442 MOV AL,'\'
443 return
444 PathRet:
445 JZ GotFor
446 return
447 EndProc PathChrCMP
448
449
450 IF DBCS
451 ;--------------------- 2/12/KK
452 ; Function: Check if an input byte is in the ranges of DBCS vectors.
453 ;
454 ; Input: AL ; Code to be examined
455 ;
456 ; Output: ZF = 1 : AL is SBCS ZF = 0 : AL is a DBCS leading byte
457 ;
458 ; Register: All registers are unchanged except FL
459 ;
460 procedure TESTKANJ,NEAR ;AN000;
461 call Chk_DBCS ;AN000;
462 jc TK_DBCS ;AN000;
463 cmp AL,AL ; set ZF ;AN000;
464 return ;AN000;
465 TK_DBCS:
466 PUSH AX ;AN000;
467 XOR AX,AX ;Set ZF ;AN000;
468 INC AX ;Reset ZF ;AN000;
469 POP AX ;AN000;
470 return ;AN000;
471 EndProc TESTKANJ ;AN000;
472 ;
473 Chk_DBCS PROC ;AN000;
474 PUSH DS ;AN000;
475 PUSH SI ;AN000;
476 PUSH BX ;AN000;
477 Context DS ;AN000;
478 MOV BX,offset DOSGROUP:COUNTRY_CDPG.ccSetDBCS ;AN000;
479 LDS SI,[BX+1] ; set EV address to DS:SI ;AN000;
480 ADD SI,2 ; Skip length ;AN000;
481 DBCS_LOOP:
482 CMP WORD PTR [SI],0 ; terminator ? ;AN000;
483 JE NON_DBCS ; if yes, no DBCS ;AN000;
484 CMP AL,[SI] ; else ;AN000;
485 JB DBCS01 ; check if AL is ;AN000;
486 CMP AL,[SI+1] ; in a range of Ev ;AN000;
487 JA DBCS01 ; if yes, DBCS ;AN000;
488 STC ; else ;AN000;
489 JMP DBCS_EXIT ; try next DBCS Ev ;AN000;
490 DBCS01:
491 ADD SI,2 ;AN000;
492 JMP DBCS_LOOP ;AN000;
493 NON_DBCS:
494 CLC ;AN000;
495 DBCS_EXIT:
496 POP BX ;AN000;
497 POP SI ;AN000;
498 POP DS ;AN000;
499 RET ;AN000;
500 Chk_DBCS ENDP ;AN000;
501 ENDIF ;AN000;
502 CODE ENDS
503 END
504 ;AN000;