mirror of
https://github.com/Microsoft/MS-DOS.git
synced 2025-08-14 10:47:14 -07:00
MS-DOS v2.0 Release
This commit is contained in:
parent
fce0f75959
commit
80ab2fddfd
156 changed files with 56403 additions and 0 deletions
512
v2.0/source/FCB.ASM
Normal file
512
v2.0/source/FCB.ASM
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue