]> wirehaze git hosting - MS-DOS.git/blob - v2.0/source/FCB.ASM

wirehaze git hosting

MS-DOS v2.0 Release
[MS-DOS.git] / v2.0 / source / FCB.ASM
1 ;
2 ; FCB management routines for MSDOS
3 ;
4
5 INCLUDE DOSSEG.ASM
6
7 IFNDEF KANJI
8 KANJI EQU 0 ;FALSE
9 ENDIF
10
11 CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14 .xlist
15 .xcref
16 INCLUDE DOSSYM.ASM
17 INCLUDE DEVSYM.ASM
18 .cref
19 .list
20
21 i_need Name1,BYTE
22 i_need NumIO,BYTE
23 i_need DevFCB,BYTE
24 i_need Creating,BYTE
25 i_need ExtFCB,BYTE
26 i_need Attrib,BYTE
27 i_need SpaceFlag,BYTE
28 i_need Current_Country,WORD
29
30 procedure MakeFcb,NEAR
31 DRVBIT EQU 2
32 NAMBIT EQU 4
33 EXTBIT EQU 8
34 MOV BYTE PTR [SpaceFlag],0
35 XOR DL,DL ; Flag--not ambiguous file name
36 TEST AL,DRVBIT ; Use current drive field if default?
37 JNZ DEFDRV
38 MOV BYTE PTR ES:[DI],0 ; No - use default drive
39 DEFDRV:
40 INC DI
41 MOV CX,8
42 TEST AL,NAMBIT ; Use current name fields as defualt?
43 XCHG AX,BX ; Save bits in BX
44 MOV AL," "
45 JZ FILLB ; If not, go fill with blanks
46 ADD DI,CX
47 XOR CX,CX ; Don't fill any
48 FILLB:
49 REP STOSB
50 MOV CL,3
51 TEST BL,EXTBIT ; Use current extension as default
52 JZ FILLB2
53 ADD DI,CX
54 XOR CX,CX
55 FILLB2:
56 REP STOSB
57 XCHG AX,CX ; Put zero in AX
58 STOSW
59 STOSW ; Initialize two words after to zero
60 SUB DI,16 ; Point back at start
61 TEST BL,1 ; Scan off separators if not zero
62 JZ SKPSPC
63 CALL SCANB ; Peel off blanks and tabs
64 CALL DELIM ; Is it a one-time-only delimiter?
65 JNZ NOSCAN
66 INC SI ; Skip over the delimiter
67 SKPSPC:
68 CALL SCANB ; Always kill preceding blanks and tabs
69 NOSCAN:
70 CALL GETLET
71 JBE NODRV ; Quit if termination character
72 CMP BYTE PTR[SI],":" ; Check for potential drive specifier
73 JNZ NODRV
74 INC SI ; Skip over colon
75 SUB AL,"@" ; Convert drive letter to binary drive number
76 JBE BADDRV ; Valid drive numbers are <= NUMIO
77 CMP AL,BYTE PTR [NUMIO]
78 JBE HAVDRV
79 BADDRV:
80 MOV DL,-1
81 HAVDRV:
82 STOSB ; Put drive specifier in first byte
83 INC SI
84 DEC DI ; Counteract next two instructions
85 NODRV:
86 DEC SI ; Back up
87 INC DI ; Skip drive byte
88 NORMSCAN:
89 MOV CX,8
90 CALL GETWORD ; Get 8-letter file name
91 CMP BYTE PTR [SI],"."
92 JNZ NODOT
93 INC SI ; Skip over dot if present
94 MOV CX,3 ; Get 3-letter extension
95 CALL MUSTGETWORD
96 NODOT:
97 MOV AL,DL
98 return
99
100 NONAM:
101 ADD DI,CX
102 DEC SI
103 return
104
105 GETWORD:
106 CALL GETLET
107 JBE NONAM ; Exit if invalid character
108 DEC SI
109 ;
110 ; UGH!!! Horrible bug here that should be fixed at some point:
111 ; If the name we are scanning is longer than CX, we keep on reading!
112 ;
113 MUSTGETWORD:
114 CALL GETLET
115 ;
116 ; If spaceFlag is set then we allow spaces in a pathname
117 ;
118 JB FILLNAM
119 JNZ MustCheckCX
120 TEST BYTE PTR [SpaceFlag],0FFh
121 JZ FILLNAM
122 CMP AL," "
123 JNZ FILLNAM
124
125 MustCheckCX:
126 JCXZ MUSTGETWORD
127 DEC CX
128 CMP AL,"*" ; Check for ambiguous file specifier
129 JNZ NOSTAR
130 MOV AL,"?"
131 REP STOSB
132 NOSTAR:
133 STOSB
134
135 IF KANJI
136 CALL TESTKANJ
137 JZ NOTDUAL3
138 JCXZ BNDERR ; Attempt to straddle boundry
139 MOVSB ; Transfer second byte
140 DEC CX
141 JMP SHORT NOTDUAL3
142 BNDERR:
143 MOV BYTE PTR ES:[DI-1]," " ; patch up that space
144 JMP MustGetWord ; go back and scan until delim
145
146 NOTDUAL3:
147 ENDIF
148
149 CMP AL,"?"
150 JNZ MUSTGETWORD
151 OR DL,1 ; Flag ambiguous file name
152 JMP MUSTGETWORD
153 FILLNAM:
154 MOV AL," "
155 REP STOSB
156 DEC SI
157 return
158
159 SCANB:
160 LODSB
161 CALL SPCHK
162 JZ SCANB
163 DEC SI
164 return
165 MakeFCB ENDP
166
167 ;
168 ; NameTrans is used by FindPath to scan off an element
169 ; of a path. We must allow spaces in pathnames
170 ; Inputs: SS - DOSGROUP
171 ; DS:SI name
172 ; Outputs: DS:SI advanced over spot
173 ; ES:DI point to after Name1
174 ; registers modified: AX, BX, CX, DX
175 procedure NameTrans,near
176 MOV BYTE PTR [SpaceFlag],1
177 PUSH SS
178 POP ES
179 MOV DI,OFFSET DOSGROUP:NAME1
180 PUSH DI
181 MOV AL,' '
182 MOV CX,11
183 REP STOSB
184 XOR AL,AL
185 MOV DL,AL
186 STOSB
187 POP DI
188 CMP BYTE PTR [SI],'.'
189
190 IF KANJI
191 JZ FOOBAR
192 CALL NORMSCAN
193 CMP [NAME1],0E5H
194 retnz
195 MOV [NAME1],5
196 return
197 FOOBAR:
198 ELSE
199 JNZ NORMSCAN
200 ENDIF
201
202 MOVSB
203 LODSB
204 CALL PATHCHRCMP
205 JZ GOTDOTNAME
206 OR AL,AL
207 JZ GOTDOTNAME
208 CMP AL,'.'
209 JNZ BADDOTS
210 STOSB
211 LODSB
212 CALL PATHCHRCMP
213 JZ GOTDOTNAME
214 OR AL,AL
215 JZ GOTDOTNAME
216 DEC SI
217 BADDOTS:
218 DEC SI
219 GOTDOTNAME:
220 DEC SI
221 XOR AL,AL
222 return
223 nametrans ENDP
224
225 SUBTTL BUILDFCB -- MAKE A BLANK FCB FOR A DEVICE
226 PAGE
227 procedure BuildFCB,near
228 ASSUME DS:DOSGROUP,ES:DOSGROUP
229
230 ; Function:
231 ; Build a blank FCB for I/O to a device
232 ; Outputs:
233 ; Same as GETNAME
234
235 MOV AX," "
236 MOV DI,OFFSET DOSGROUP:DEVFCB+8 ; Point to extent field
237 STOSW
238 STOSB ; Blank out extent field
239 XOR AX,AX
240 MOV CX,10
241 REP STOSW ; Fill FCB with zeros
242 STOSB
243 invoke DATE16
244 MOV DI,OFFSET DOSGROUP:DEVFCB+22
245 XCHG AX,DX
246 STOSW
247 XCHG AX,DX
248 STOSW
249 XCHG AX,BX ; But device number in AH
250 MOV BX,OFFSET DOSGROUP:DEVFCB
251 MOV SI,DI
252 XOR AL,AL ; Set zero, clear carry
253 return
254 BuildFCB ENDP
255
256 SUBTTL MOVENAME, LODNAME -- EXAMINE FCB AND SETUP
257 PAGE
258 procedure FCB_move,NEAR
259
260 entry MOVNAMENOSET
261 MOV DI,1
262 JMP SHORT MOVSTART
263
264 entry MOVNAME
265 ASSUME DS:NOTHING,ES:NOTHING
266
267 ; Inputs:
268 ; DS, DX point to FCB or extended FCB
269 ; Outputs:
270 ; DS:DX point to normal FCB
271 ; DS:SI point after end of NAME/EXT in FCB
272 ; ES = DOSGROUP
273 ; If file name OK:
274 ; [NAME1] has name in upper case
275 ; All registers destroyed
276 ; Carry set if bad file name or drive
277
278 XOR DI,DI
279 MOVSTART:
280 MOV WORD PTR [CREATING],0E500H ; Not creating, not DEL *.*
281 MOV SI,DX
282 LODSB
283 MOV [EXTFCB],AL ; Set flag if extended FCB in use
284 XOR AH,AH ; Set default attributes
285 CMP AL,-1 ; Is it an extended FCB?
286 JNZ HAVATTRB
287 ADD DX,7 ; Adjust to point to normal FCB
288 ADD SI,6
289 MOV AH,[SI-1] ; Attribute byte
290 LODSB ; Get drive select byte
291 HAVATTRB:
292 invoke GETTHISDRV
293 retc
294 PUSH DS
295 PUSH DX
296 PUSH SI
297 PUSH AX
298 ;
299 ; DS:DX is pointer to good FCB
300 ; DS:SI is same
301 ;
302 ; Move the file into Name1 and UCASE it
303 ;
304 PUSH DI
305 context ES
306 MOV DI,OFFSET DOSGROUP:NAME1
307 CALL LodName
308 POP DI
309 JC DrvNoSet
310
311 ;
312 ; are we setting current dir info?
313 ;
314 OR DI,DI
315 JNZ DrvNoSet ; do not set dir info
316
317 ;
318 ; check for device name first, eliminating drive hits on devices
319 ;
320 context DS
321 invoke DEVNAME
322 JNC DrvNoSet ; we have a device
323
324 ;
325 ; make sure that everything is current
326 ;
327 invoke FATREAD
328 ASSUME DS:NOTHING,ES:NOTHING
329 MOV BYTE PTR [ATTRIB],attr_directory+attr_hidden+attr_system
330 invoke GETCURRDIR
331 DrvNoSet:
332 POP AX
333 MOV BYTE PTR [ATTRIB],AH
334
335 POP SI
336 POP DX
337 POP DS
338 context ES
339 MOV DI,OFFSET DOSGROUP:NAME1
340
341 entry LODNAME
342 ; Inputs: DS:SI point to an FCB
343 ; ES:DI point to an FCB
344 ; Outputs: DS:SI point to after FCB
345 ; ES:DI point to after FCB
346 ; FCB from DS:SI copied and ucased to ES:DI
347 ; Carry set if there was an error.
348 ; Destroys AX,CX
349 CMP BYTE PTR [SI]," " ; Don't allow blank as first letter
350 STC ; In case of error
351 retz
352
353 IF KANJI
354 MOV CX,8
355 CMP BYTE PTR [SI],0E5H
356 JNZ MOVCHK
357 INC SI
358 MOV AL,5
359 STOSB
360 MOVSB
361 MOV CX,6
362 MOVCHK:
363 CALL GETLET
364 JB RET6
365 JNZ STOLET ; Is it a delimiter?
366 CMP AL," " ; This is the only delimiter allowed
367 STC ; In case of error
368 JNZ RET6
369 STOLET:
370 STOSB
371 CALL TESTKANJ
372 JZ MOVLP ;No
373 LODSB ;Get second byte
374 DEC CX
375 JZ BOUNDERR ;Attempt to cross boundry
376 STOSB
377 MOVLP:
378 LOOP MOVCHK
379 MOV CX,3
380 MOVCHK2:
381 CALL GETLET
382 JB RET6
383 JNZ STOLET2 ; Is it a delimiter?
384 CMP AL," " ; This is the only delimiter allowed
385 STC ; In case of error
386 retnz
387 STOLET2:
388 STOSB
389 CALL TESTKANJ
390 JZ MOVLP2 ;No
391 LODSB ;Get second byte
392 DEC CX
393 JNZ DOSTORE
394 BOUNDERR: ;Attempt to cross boundry
395 STC
396 return
397
398 DOSTORE:
399 STOSB
400 MOVLP2:
401 LOOP MOVCHK2
402 ELSE
403 MOV CX,11
404 MOVCHK:
405 CALL GETLET
406 JB RET6
407 JNZ STOLET ; Is it a delimiter?
408 CMP AL," " ; This is the only delimiter allowed
409 STC ; In case of error
410 retnz
411 STOLET:
412 STOSB
413 LOOP MOVCHK
414 ENDIF
415
416 CLC ; Got through whole name - no error
417 RET6: return
418 FCB_Move ENDP
419
420 SUBTTL GETLET, DELIM -- CHECK CHARACTERS AND CONVERT
421 PAGE
422 procedure GetLet,NEAR
423 ; Get a byte from [SI], convert it to upper case, and compare for delimiter.
424 ; ZF set if a delimiter, CY set if a control character (other than TAB).
425 LODSB
426
427 CMP AL,"a"
428 JB CHK1
429 CMP AL,"z"
430 JA CHK1
431 SUB AL,20H ; Convert to upper case
432 CHK1:
433 PUSH SI
434 MOV SI,[Current_Country]
435 ADD SI,Map_call
436 PUSH CS ; CS for long return
437 CALL WORD PTR CS:[SI]
438 POP SI
439 entry CHK
440 CMP AL,"."
441 retz
442 CMP AL,'"'
443 retz
444 CALL PATHCHRCMP
445 retz
446 CMP AL,"["
447 retz
448 CMP AL,"]"
449 retz
450
451 DELIM:
452 CMP AL,":" ; Allow ":" as separator in IBM version
453 retz
454
455 CMP AL,"<"
456 retz
457 CMP AL,"|"
458 retz
459 CMP AL,">"
460 retz
461
462 CMP AL,"+"
463 retz
464 CMP AL,"="
465 retz
466 CMP AL,";"
467 retz
468 CMP AL,","
469 retz
470 SPCHK:
471 CMP AL,9 ; Filter out tabs too
472 retz
473 ; WARNING! " " MUST be the last compare
474 CMP AL," "
475 return
476 GetLet ENDP
477
478 procedure PATHCHRCMP,NEAR
479 CMP AL,'/'
480 retz
481 CMP AL,'\'
482 return
483 PathChrCMP ENDP
484
485 IF KANJI
486 procedure TESTKANJ,NEAR
487 CMP AL,81H
488 JB NOTLEAD
489 CMP AL,9FH
490 JBE ISLEAD
491 CMP AL,0E0H
492 JB NOTLEAD
493 CMP AL,0FCH
494 JBE ISLEAD
495 NOTLEAD:
496 PUSH AX
497 XOR AX,AX ;Set zero
498 POP AX
499 return
500
501 ISLEAD:
502 PUSH AX
503 XOR AX,AX ;Set zero
504 INC AX ;Reset zero
505 POP AX
506 return
507 TESTKANJ ENDP
508 ENDIF
509 do_ext
510
511 CODE ENDS
512 END