summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/FCB.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/FCB.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/FCB.ASM')
-rw-r--r--v4.0/src/DOS/FCB.ASM504
1 files changed, 504 insertions, 0 deletions
diff --git a/v4.0/src/DOS/FCB.ASM b/v4.0/src/DOS/FCB.ASM
new file mode 100644
index 0000000..2b51da6
--- /dev/null
+++ b/v4.0/src/DOS/FCB.ASM
@@ -0,0 +1,504 @@
1; SCCSID = @(#)fcb.asm 1.2 85/07/23
2; SCCSID = @(#)fcb.asm 1.2 85/07/23
3TITLE FCB - FCB parse calls for MSDOS
4NAME 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
25include dosseg.asm
26
27
28TableLook equ -1
29
30Table Segment
31Zero label byte
32Table ENDS
33
34CODE SEGMENT BYTE PUBLIC 'CODE'
35 ASSUME SS:DOSGROUP,CS:DOSGROUP
36
37.xcref
38include dossym.inc
39include devsym.inc
40include 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
54ScanSeparator = 1
55DRVBIT EQU 2
56NAMBIT EQU 4
57EXTBIT 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
63DEFDRV:
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
72FILLB:
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
79FILLB2:
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
91SKPSPC:
92 CALL SCANB ; Always kill preceding blanks and tabs
93NOSCAN:
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;
112BADDRV:
113 MOV DL,-1
114HAVDRV:
115 STOSB ; Put drive specifier in first byte
116 INC SI
117 DEC DI ; Counteract next two instructions
118NODRV:
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;
134VOLOK:
135 MOV CX,3 ; Get 3-letter extension
136contvol:
137 CALL MUSTGETWORD
138NODOT:
139 MOV AL,DL
140 return
141
142NONAM:
143 ADD DI,CX
144 DEC SI
145 return
146
147GETWORD:
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;
155MUSTGETWORD:
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
167MustCheckCX:
168 JCXZ MUSTGETWORD
169 DEC CX
170 CMP AL,"*" ; Check for ambiguous file specifier
171 JNZ NOSTAR
172 MOV AL,"?"
173 REP STOSB
174NOSTAR:
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;
184BNDERR: ;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
192notvolumeid:
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
200NOTDUAL3: ;AN000;
201 ENDIF ;AN000;
202
203 CMP AL,"?"
204 JNZ MUSTGETWORD
205 OR DL,1 ; Flag ambiguous file name
206 JMP MUSTGETWORD
207FILLNAM:
208 MOV AL," "
209 REP STOSB
210 DEC SI
211 return
212
213SCANB:
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
230EndProc 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
241procedure 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
257IF 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
262notdbcs: ;AN000;
263ENDIF ;AN000;
264 CMP [NAME1],0E5H
265 retnz
266 MOV [NAME1],5 ; Magic name translation
267 return
268
269EndProc nametrans
270
271Break <GETLET, DELIM -- CHECK CHARACTERS AND CONVERT>
272
273If TableLook
274ChType Macro ch,bits
275 ORG CharType-Zero+ch
276 db bits
277 ENDM
278
279Table SEGMENT
280 PUBLIC CharType
281Public FCB001S,FCB001E
282FCB001S label byte
283CharType 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
332FCB001E label byte
333Table ENDS
334ENDIF
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
351CHK1:
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]
357If TableLook
358GOTIT:
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
371ELSE
372GOTIT:
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
384ENDIF
385
386entry DELIM
387
388IF 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
397ELSE
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
416ENDIF
417entry SPCHK
418IF 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
427ELSE
428 CMP AL,9 ; Filter out tabs too
429 retz
430; WARNING! " " MUST be the last compare
431 CMP AL," "
432 return
433ENDIF
434EndProc GetLet
435
436Procedure PATHCHRCMP,NEAR
437 CMP AL,'/'
438 JBE PathRet
439 CMP AL,'\'
440 return
441GotFor:
442 MOV AL,'\'
443 return
444PathRet:
445 JZ GotFor
446 return
447EndProc 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;
460procedure TESTKANJ,NEAR ;AN000;
461 call Chk_DBCS ;AN000;
462 jc TK_DBCS ;AN000;
463 cmp AL,AL ; set ZF ;AN000;
464 return ;AN000;
465TK_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;
471EndProc TESTKANJ ;AN000;
472;
473Chk_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;
481DBCS_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;
490DBCS01:
491 ADD SI,2 ;AN000;
492 JMP DBCS_LOOP ;AN000;
493NON_DBCS:
494 CLC ;AN000;
495DBCS_EXIT:
496 POP BX ;AN000;
497 POP SI ;AN000;
498 POP DS ;AN000;
499 RET ;AN000;
500Chk_DBCS ENDP ;AN000;
501 ENDIF ;AN000;
502CODE ENDS
503 END
504 ;AN000;