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
5 ; Low level routines for parsing names into FCBs and analyzing
18 ; A000 version 4.00 Jan. 1988
22 ; get the appropriate segment definitions
34 CODE SEGMENT BYTE PUBLIC 'CODE'
35 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
40 include doscntry
.inc ;AN000; 2/12/KK
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
53 procedure MakeFcb
,NEAR
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?
62 MOV BYTE PTR ES:[DI],0 ; No - use default drive
66 TEST AL,NAMBIT
; Use current name fields as defualt?
67 XCHG AX,BX ; Save bits in BX
69 JZ FILLB
; If not, go fill with blanks
71 XOR CX,CX ; Don't fill any
75 TEST BL,EXTBIT
; Use current extension as default
81 XCHG AX,CX ; Put zero in AX
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
87 CALL SCANB
; Peel off blanks and tabs
88 CALL DELIM
; Is it a one-time-only delimiter?
90 INC SI ; Skip over the delimiter
92 CALL SCANB
; Always kill preceding blanks and tabs
95 JBE NODRV
; Quit if termination character
97 CALL TESTKANJ
;AN000;; 2/18/KK
98 JNE NODRV
;AN000;; 2/18/KK
100 CMP BYTE PTR[SI],":" ; Check for potential drive specifier
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
110 CMP [DrvErr
],error_not_DOS_disk
; if not FAt drive ;AN000;
111 JZ HavDrv
; assume ok ;AN000;
115 STOSB ; Put drive specifier in first byte
117 DEC DI ; Counteract next two instructions
120 INC DI ; Skip drive byte
125 CALL GETWORD
; Get 8-letter file name
126 CMP BYTE PTR [SI],"."
128 INC SI ; Skip over dot if present
129 TEST [DOS34_FLAG
],DBCS_VOLID2
;AN000;
131 MOVSB ; 2nd byte of DBCS ;AN000;
133 JMP SHORT contvol
;AN000;
135 MOV CX,3 ; Get 3-letter extension
149 JBE NONAM
; Exit if invalid character
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!
158 ; If spaceFlag is set then we allow spaces in a pathname
162 TEST BYTE PTR [SpaceFlag
],0FFh
170 CMP AL,"*" ; Check for ambiguous file specifier
178 CALL TESTKANJ
;AN000;
180 JCXZ BNDERR
; Attempt to straddle boundry ;AN000;
181 MOVSB ; Transfer second byte ;AN000;
183 JMP MUSTGETWORD
;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;
193 ;; INC CX ; Undo the store of the first byte
195 MOV AL," " ;PTM. ;AN000;
198 JMP MUSTGETWORD
;PTM. ;AN000;
205 OR DL,1 ; Flag ambiguous file name
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;
233 ; NameTrans is used by FindPath to scan off an element of a path. We must
234 ; allow spaces in pathnames
236 ; Inputs: DS:SI points to start of path element
237 ; Outputs: Name1 has unpacked name, uppercased
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
245 MOV DI,OFFSET DOSGROUP
:NAME1
250 REP STOSW ; Fill "FCB" at NAME1 with spaces
251 XOR AL,AL ; Set stuff for NORMSCAN
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
266 MOV [NAME1
],5 ; Magic name translation
271 Break <GETLET
, DELIM
-- CHECK CHARACTERS
AND CONVERT
>
281 Public FCB001S
,FCB001E
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
))>
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).
339 ; DOS 3.3 modification for file char upper case. F.C. 5/29/86
340 procedure GetLet
,NEAR
342 entry GetLet2
;AN000;; called by uCase
344 MOV BX,OFFSET DOSGROUP
:FILE_UCASE_TAB
+2
350 SUB AL,20H
; Convert to upper case
354 SUB AL,80H
;translate to upper case with this index
356 XLAT BYTE PTR CS:[BX]
360 MOV BX,OFFSET DOSGROUP
:CharType
361 XLAT BYTE PTR CS:[BX]
367 entry GetLet3
;AN000; called by uCase
391 MOV BX,OFFSET DOSGroup
:CharType
392 XLAT BYTE PTR CS:[BX]
421 MOV BX,OFFSET DOSGroup
:CharType
422 XLAT BYTE PTR CS:[BX]
428 CMP AL,9 ; Filter out tabs too
430 ; WARNING! " " MUST be the last compare
436 Procedure PATHCHRCMP
,NEAR
451 ;--------------------- 2/12/KK
452 ; Function: Check if an input byte is in the ranges of DBCS vectors.
454 ; Input: AL ; Code to be examined
456 ; Output: ZF = 1 : AL is SBCS ZF = 0 : AL is a DBCS leading byte
458 ; Register: All registers are unchanged except FL
460 procedure TESTKANJ
,NEAR ;AN000;
461 call Chk_DBCS
;AN000;
463 cmp AL,AL ; set ZF ;AN000;
467 XOR AX,AX ;Set ZF ;AN000;
468 INC AX ;Reset ZF ;AN000;
471 EndProc TESTKANJ
;AN000;
473 Chk_DBCS PROC
;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;
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;
489 JMP DBCS_EXIT
; try next DBCS Ev ;AN000;
492 JMP DBCS_LOOP
;AN000;
500 Chk_DBCS ENDP
;AN000;