From 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Fri, 12 Aug 1983 17:53:34 -0700 Subject: MS-DOS v2.0 Release --- v2.0/source/FCB.ASM | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 512 insertions(+) create mode 100644 v2.0/source/FCB.ASM (limited to 'v2.0/source/FCB.ASM') diff --git a/v2.0/source/FCB.ASM b/v2.0/source/FCB.ASM new file mode 100644 index 0000000..11528f7 --- /dev/null +++ b/v2.0/source/FCB.ASM @@ -0,0 +1,512 @@ +; +; FCB management routines for MSDOS +; + +INCLUDE DOSSEG.ASM + +IFNDEF KANJI +KANJI EQU 0 ;FALSE +ENDIF + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME SS:DOSGROUP,CS:DOSGROUP + +.xlist +.xcref +INCLUDE DOSSYM.ASM +INCLUDE DEVSYM.ASM +.cref +.list + + i_need Name1,BYTE + i_need NumIO,BYTE + i_need DevFCB,BYTE + i_need Creating,BYTE + i_need ExtFCB,BYTE + i_need Attrib,BYTE + i_need SpaceFlag,BYTE + i_need Current_Country,WORD + + procedure MakeFcb,NEAR +DRVBIT EQU 2 +NAMBIT EQU 4 +EXTBIT EQU 8 + MOV BYTE PTR [SpaceFlag],0 + XOR DL,DL ; Flag--not ambiguous file name + TEST AL,DRVBIT ; Use current drive field if default? + JNZ DEFDRV + MOV BYTE PTR ES:[DI],0 ; No - use default drive +DEFDRV: + INC DI + MOV CX,8 + TEST AL,NAMBIT ; Use current name fields as defualt? + XCHG AX,BX ; Save bits in BX + MOV AL," " + JZ FILLB ; If not, go fill with blanks + ADD DI,CX + XOR CX,CX ; Don't fill any +FILLB: + REP STOSB + MOV CL,3 + TEST BL,EXTBIT ; Use current extension as default + JZ FILLB2 + ADD DI,CX + XOR CX,CX +FILLB2: + REP STOSB + XCHG AX,CX ; Put zero in AX + STOSW + STOSW ; Initialize two words after to zero + SUB DI,16 ; Point back at start + TEST BL,1 ; Scan off separators if not zero + JZ SKPSPC + CALL SCANB ; Peel off blanks and tabs + CALL DELIM ; Is it a one-time-only delimiter? + JNZ NOSCAN + INC SI ; Skip over the delimiter +SKPSPC: + CALL SCANB ; Always kill preceding blanks and tabs +NOSCAN: + CALL GETLET + JBE NODRV ; Quit if termination character + CMP BYTE PTR[SI],":" ; Check for potential drive specifier + JNZ NODRV + INC SI ; Skip over colon + SUB AL,"@" ; Convert drive letter to binary drive number + JBE BADDRV ; Valid drive numbers are <= NUMIO + CMP AL,BYTE PTR [NUMIO] + JBE HAVDRV +BADDRV: + MOV DL,-1 +HAVDRV: + STOSB ; Put drive specifier in first byte + INC SI + DEC DI ; Counteract next two instructions +NODRV: + DEC SI ; Back up + INC DI ; Skip drive byte +NORMSCAN: + MOV CX,8 + CALL GETWORD ; Get 8-letter file name + CMP BYTE PTR [SI],"." + JNZ NODOT + INC SI ; Skip over dot if present + MOV CX,3 ; Get 3-letter extension + CALL MUSTGETWORD +NODOT: + MOV AL,DL + return + +NONAM: + ADD DI,CX + DEC SI + return + +GETWORD: + CALL GETLET + JBE NONAM ; Exit if invalid character + DEC SI +; +; UGH!!! Horrible bug here that should be fixed at some point: +; If the name we are scanning is longer than CX, we keep on reading! +; +MUSTGETWORD: + CALL GETLET +; +; If spaceFlag is set then we allow spaces in a pathname +; + JB FILLNAM + JNZ MustCheckCX + TEST BYTE PTR [SpaceFlag],0FFh + JZ FILLNAM + CMP AL," " + JNZ FILLNAM + +MustCheckCX: + JCXZ MUSTGETWORD + DEC CX + CMP AL,"*" ; Check for ambiguous file specifier + JNZ NOSTAR + MOV AL,"?" + REP STOSB +NOSTAR: + STOSB + + IF KANJI + CALL TESTKANJ + JZ NOTDUAL3 + JCXZ BNDERR ; Attempt to straddle boundry + MOVSB ; Transfer second byte + DEC CX + JMP SHORT NOTDUAL3 +BNDERR: + MOV BYTE PTR ES:[DI-1]," " ; patch up that space + JMP MustGetWord ; go back and scan until delim + +NOTDUAL3: + ENDIF + + CMP AL,"?" + JNZ MUSTGETWORD + OR DL,1 ; Flag ambiguous file name + JMP MUSTGETWORD +FILLNAM: + MOV AL," " + REP STOSB + DEC SI + return + +SCANB: + LODSB + CALL SPCHK + JZ SCANB + DEC SI + return +MakeFCB ENDP + +; +; NameTrans is used by FindPath to scan off an element +; of a path. We must allow spaces in pathnames +; Inputs: SS - DOSGROUP +; DS:SI name +; Outputs: DS:SI advanced over spot +; ES:DI point to after Name1 +; registers modified: AX, BX, CX, DX +procedure NameTrans,near + MOV BYTE PTR [SpaceFlag],1 + PUSH SS + POP ES + MOV DI,OFFSET DOSGROUP:NAME1 + PUSH DI + MOV AL,' ' + MOV CX,11 + REP STOSB + XOR AL,AL + MOV DL,AL + STOSB + POP DI + CMP BYTE PTR [SI],'.' + + IF KANJI + JZ FOOBAR + CALL NORMSCAN + CMP [NAME1],0E5H + retnz + MOV [NAME1],5 + return +FOOBAR: + ELSE + JNZ NORMSCAN + ENDIF + + MOVSB + LODSB + CALL PATHCHRCMP + JZ GOTDOTNAME + OR AL,AL + JZ GOTDOTNAME + CMP AL,'.' + JNZ BADDOTS + STOSB + LODSB + CALL PATHCHRCMP + JZ GOTDOTNAME + OR AL,AL + JZ GOTDOTNAME + DEC SI +BADDOTS: + DEC SI +GOTDOTNAME: + DEC SI + XOR AL,AL + return +nametrans ENDP + +SUBTTL BUILDFCB -- MAKE A BLANK FCB FOR A DEVICE +PAGE + procedure BuildFCB,near +ASSUME DS:DOSGROUP,ES:DOSGROUP + +; Function: +; Build a blank FCB for I/O to a device +; Outputs: +; Same as GETNAME + + MOV AX," " + MOV DI,OFFSET DOSGROUP:DEVFCB+8 ; Point to extent field + STOSW + STOSB ; Blank out extent field + XOR AX,AX + MOV CX,10 + REP STOSW ; Fill FCB with zeros + STOSB + invoke DATE16 + MOV DI,OFFSET DOSGROUP:DEVFCB+22 + XCHG AX,DX + STOSW + XCHG AX,DX + STOSW + XCHG AX,BX ; But device number in AH + MOV BX,OFFSET DOSGROUP:DEVFCB + MOV SI,DI + XOR AL,AL ; Set zero, clear carry + return +BuildFCB ENDP + +SUBTTL MOVENAME, LODNAME -- EXAMINE FCB AND SETUP +PAGE + procedure FCB_move,NEAR + + entry MOVNAMENOSET + MOV DI,1 + JMP SHORT MOVSTART + + entry MOVNAME +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; DS, DX point to FCB or extended FCB +; Outputs: +; DS:DX point to normal FCB +; DS:SI point after end of NAME/EXT in FCB +; ES = DOSGROUP +; If file name OK: +; [NAME1] has name in upper case +; All registers destroyed +; Carry set if bad file name or drive + + XOR DI,DI +MOVSTART: + MOV WORD PTR [CREATING],0E500H ; Not creating, not DEL *.* + MOV SI,DX + LODSB + MOV [EXTFCB],AL ; Set flag if extended FCB in use + XOR AH,AH ; Set default attributes + CMP AL,-1 ; Is it an extended FCB? + JNZ HAVATTRB + ADD DX,7 ; Adjust to point to normal FCB + ADD SI,6 + MOV AH,[SI-1] ; Attribute byte + LODSB ; Get drive select byte +HAVATTRB: + invoke GETTHISDRV + retc + PUSH DS + PUSH DX + PUSH SI + PUSH AX +; +; DS:DX is pointer to good FCB +; DS:SI is same +; +; Move the file into Name1 and UCASE it +; + PUSH DI + context ES + MOV DI,OFFSET DOSGROUP:NAME1 + CALL LodName + POP DI + JC DrvNoSet + +; +; are we setting current dir info? +; + OR DI,DI + JNZ DrvNoSet ; do not set dir info + +; +; check for device name first, eliminating drive hits on devices +; + context DS + invoke DEVNAME + JNC DrvNoSet ; we have a device + +; +; make sure that everything is current +; + invoke FATREAD + ASSUME DS:NOTHING,ES:NOTHING + MOV BYTE PTR [ATTRIB],attr_directory+attr_hidden+attr_system + invoke GETCURRDIR +DrvNoSet: + POP AX + MOV BYTE PTR [ATTRIB],AH + + POP SI + POP DX + POP DS + context ES + MOV DI,OFFSET DOSGROUP:NAME1 + + entry LODNAME +; Inputs: DS:SI point to an FCB +; ES:DI point to an FCB +; Outputs: DS:SI point to after FCB +; ES:DI point to after FCB +; FCB from DS:SI copied and ucased to ES:DI +; Carry set if there was an error. +; Destroys AX,CX + CMP BYTE PTR [SI]," " ; Don't allow blank as first letter + STC ; In case of error + retz + + IF KANJI + MOV CX,8 + CMP BYTE PTR [SI],0E5H + JNZ MOVCHK + INC SI + MOV AL,5 + STOSB + MOVSB + MOV CX,6 +MOVCHK: + CALL GETLET + JB RET6 + JNZ STOLET ; Is it a delimiter? + CMP AL," " ; This is the only delimiter allowed + STC ; In case of error + JNZ RET6 +STOLET: + STOSB + CALL TESTKANJ + JZ MOVLP ;No + LODSB ;Get second byte + DEC CX + JZ BOUNDERR ;Attempt to cross boundry + STOSB +MOVLP: + LOOP MOVCHK + MOV CX,3 +MOVCHK2: + CALL GETLET + JB RET6 + JNZ STOLET2 ; Is it a delimiter? + CMP AL," " ; This is the only delimiter allowed + STC ; In case of error + retnz +STOLET2: + STOSB + CALL TESTKANJ + JZ MOVLP2 ;No + LODSB ;Get second byte + DEC CX + JNZ DOSTORE +BOUNDERR: ;Attempt to cross boundry + STC + return + +DOSTORE: + STOSB +MOVLP2: + LOOP MOVCHK2 + ELSE + MOV CX,11 +MOVCHK: + CALL GETLET + JB RET6 + JNZ STOLET ; Is it a delimiter? + CMP AL," " ; This is the only delimiter allowed + STC ; In case of error + retnz +STOLET: + STOSB + LOOP MOVCHK + ENDIF + + CLC ; Got through whole name - no error +RET6: return +FCB_Move ENDP + +SUBTTL GETLET, DELIM -- CHECK CHARACTERS AND CONVERT +PAGE + procedure GetLet,NEAR +; Get a byte from [SI], convert it to upper case, and compare for delimiter. +; ZF set if a delimiter, CY set if a control character (other than TAB). + LODSB + + CMP AL,"a" + JB CHK1 + CMP AL,"z" + JA CHK1 + SUB AL,20H ; Convert to upper case +CHK1: + PUSH SI + MOV SI,[Current_Country] + ADD SI,Map_call + PUSH CS ; CS for long return + CALL WORD PTR CS:[SI] + POP SI + entry CHK + CMP AL,"." + retz + CMP AL,'"' + retz + CALL PATHCHRCMP + retz + CMP AL,"[" + retz + CMP AL,"]" + retz + +DELIM: + CMP AL,":" ; Allow ":" as separator in IBM version + retz + + CMP AL,"<" + retz + CMP AL,"|" + retz + CMP AL,">" + retz + + CMP AL,"+" + retz + CMP AL,"=" + retz + CMP AL,";" + retz + CMP AL,"," + retz +SPCHK: + CMP AL,9 ; Filter out tabs too + retz +; WARNING! " " MUST be the last compare + CMP AL," " + return +GetLet ENDP + + procedure PATHCHRCMP,NEAR + CMP AL,'/' + retz + CMP AL,'\' + return +PathChrCMP ENDP + + IF KANJI + procedure TESTKANJ,NEAR + CMP AL,81H + JB NOTLEAD + CMP AL,9FH + JBE ISLEAD + CMP AL,0E0H + JB NOTLEAD + CMP AL,0FCH + JBE ISLEAD +NOTLEAD: + PUSH AX + XOR AX,AX ;Set zero + POP AX + return + +ISLEAD: + PUSH AX + XOR AX,AX ;Set zero + INC AX ;Reset zero + POP AX + return +TESTKANJ ENDP + ENDIF +do_ext + +CODE ENDS + END -- cgit v1.2.3