mirror of
https://github.com/Microsoft/MS-DOS.git
synced 2025-08-21 05:53:37 -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
907
v2.0/source/XENIX.ASM
Normal file
907
v2.0/source/XENIX.ASM
Normal file
|
@ -0,0 +1,907 @@
|
|||
;
|
||||
; xenix file calls 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
|
||||
|
||||
TITLE XENIX - IO system to mimic UNIX
|
||||
NAME XENIX
|
||||
|
||||
i_need NoSetDir,BYTE
|
||||
i_need CURDRV,BYTE
|
||||
i_need IOCALL,BYTE
|
||||
i_need IOMED,BYTE
|
||||
i_need IOSCNT,WORD
|
||||
i_need IOXAD,DWORD
|
||||
i_need DIRSTART,WORD
|
||||
i_need ATTRIB,BYTE
|
||||
i_need THISFCB,DWORD
|
||||
i_need AuxStack,BYTE
|
||||
i_need Creating,BYTE
|
||||
i_need ThisDRV,BYTE
|
||||
i_need NAME1,BYTE
|
||||
i_need LastEnt,WORD
|
||||
i_need ThisDPB,DWORD
|
||||
i_need EntLast,WORD
|
||||
i_need CurrentPDB,WORD
|
||||
i_need sft_addr,DWORD ; pointer to head of table
|
||||
i_need CURBUF,DWORD ; pointer to current buffer
|
||||
i_need DMAADD,DWORD ; pointer to current dma address
|
||||
|
||||
BREAK <Local data>
|
||||
|
||||
CODE ENDS
|
||||
DATA SEGMENT BYTE PUBLIC 'DATA'
|
||||
|
||||
open_name DW ?
|
||||
DW ?
|
||||
open_access DB ?
|
||||
open_jfn DW ? ; accessed as DD
|
||||
open_jfn_b DW ? ; accessed as DD with above
|
||||
open_sfn DW ?
|
||||
open_sfoff DW ? ; accessed as DD
|
||||
open_sfn_b DW ? ; accessed as DD with above
|
||||
open_devid DB ?
|
||||
Cr_read_only DB ?
|
||||
rename_source DD ?
|
||||
rename_dest DD ?
|
||||
|
||||
DATA ENDS
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
|
||||
BREAK <Validate_path - check to see if there are meta characters in path>
|
||||
|
||||
;
|
||||
; Input: DS:DX is an ASCIZ path
|
||||
; Output: Carry set if meta-characters present or path malformed and
|
||||
; Zero is set if the only problem is that meta-characters
|
||||
; are present in the last element of the path
|
||||
procedure Validate_path,near
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
PUSH AX
|
||||
PUSH CX
|
||||
PUSH SI
|
||||
MOV SI,DX
|
||||
MOV CX,0FFH ;No path seps yet
|
||||
MOV AX,[SI] ; Get first two bytes
|
||||
OR AL,AL
|
||||
JZ validate_malformed ; NUL path
|
||||
CMP AH,':'
|
||||
JNZ validate_loop ; OK so far
|
||||
CMP BYTE PTR [SI+2],0
|
||||
JZ validate_malformed ; NUL path (just d:)
|
||||
validate_loop:
|
||||
LODSB
|
||||
validate_loop1:
|
||||
|
||||
IF KANJI
|
||||
invoke TESTKANJ
|
||||
JZ NOTKANJ6
|
||||
INC SI
|
||||
JMP validate_loop
|
||||
|
||||
NOTKANJ6:
|
||||
ENDIF
|
||||
|
||||
OR AL,AL
|
||||
JZ validate_end
|
||||
CMP AL,"?"
|
||||
JZ validate_error
|
||||
CMP AL,"*"
|
||||
JZ validate_error
|
||||
invoke PathChrCmp
|
||||
JNZ validate_loop
|
||||
JCXZ validate_malformed ;If path sep, cannot have meta yet
|
||||
LODSB ;Look ahead one char
|
||||
OR AL,AL
|
||||
JZ validate_checktslsh ;Trailing path sep
|
||||
invoke PathChrCmp
|
||||
JNZ validate_loop1 ;Double path sep?
|
||||
validate_malformed:
|
||||
INC CX
|
||||
OR CX,CX ;Reset zero
|
||||
JMP SHORT validate_set_carry
|
||||
|
||||
validate_error:
|
||||
XOR CX,CX ;Flag metas found
|
||||
JMP validate_loop
|
||||
|
||||
validate_checktslsh:
|
||||
;A bizarre case, "/" is OK, "d:/" is OK, anything else is an error
|
||||
SUB SI,DX
|
||||
CMP SI,2
|
||||
JZ validate_end ;Two chars, the '/' and the NUL
|
||||
CMP SI,4
|
||||
JNZ validate_malformed ;Four chars, "D:/<NUL>"
|
||||
MOV SI,DX
|
||||
CMP BYTE PTR [SI+1],':'
|
||||
JNZ validate_malformed ;Second char must be a ':'
|
||||
|
||||
validate_end:
|
||||
OR CX,CX ;Clears carry
|
||||
JNZ validate_ok ;No metas found, leave carry clear
|
||||
validate_set_carry:
|
||||
STC
|
||||
validate_ok:
|
||||
POP SI
|
||||
POP CX
|
||||
POP AX
|
||||
return
|
||||
validate_path ENDP
|
||||
|
||||
BREAK <Access_path - determine if file found>
|
||||
|
||||
;
|
||||
; Input: DS:DX point to a path
|
||||
; Output: Carry reset - outputs of GetPath
|
||||
; carry set - AL has error code
|
||||
;
|
||||
procedure Access_path,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
CALL Validate_path
|
||||
JC access_no_path
|
||||
MOV SI,DX
|
||||
invoke GetPath
|
||||
retnc
|
||||
MOV AL,error_file_not_found
|
||||
OR CL,CL
|
||||
JNZ access_ret
|
||||
access_no_path:
|
||||
MOV AL,error_path_not_found
|
||||
access_ret:
|
||||
STC
|
||||
return
|
||||
access_path ENDP
|
||||
|
||||
BREAK <Find_free_jfn - return a free jfn in users PDB>
|
||||
;
|
||||
; system file table data
|
||||
;
|
||||
|
||||
;
|
||||
; The system file table is two linear tables. The first table is the
|
||||
; DOS initialization table containing a default number of FCBs. The
|
||||
; first word in the table is a link to the second table, which
|
||||
; SYSINIT sets up, the second word is the number of FCBs in the table.
|
||||
;
|
||||
|
||||
;
|
||||
; find_free_jfn
|
||||
; input: none
|
||||
; output: JNC <found>
|
||||
; ES:DI is pointer to free JFN
|
||||
; JC <no free jfns>
|
||||
; ES,DI indeterminate
|
||||
;
|
||||
procedure Find_free_jfn,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
PUSH AX
|
||||
PUSH CX
|
||||
MOV AL,0FFh
|
||||
MOV ES,[CurrentPDB]
|
||||
MOV DI,PDB_JFN_Table
|
||||
MOV CX,FilPerProc
|
||||
REPNE SCASB
|
||||
STC
|
||||
JNZ Find_jfn_ret
|
||||
DEC DI
|
||||
CLC
|
||||
Find_jfn_ret:
|
||||
POP CX
|
||||
POP AX
|
||||
return
|
||||
Find_free_jfn ENDP
|
||||
|
||||
BREAK <find_free_sfn - return a free sfn and sf pointer>
|
||||
;
|
||||
; find_free_sfn
|
||||
; input: none
|
||||
; output: JNC <found>
|
||||
; ES:DI is free sf entry
|
||||
; SI is sfn
|
||||
; JC <not found>
|
||||
; ES,DI,SI indeterminate
|
||||
;
|
||||
; sft_addr --> (link) count (fcbs)
|
||||
; links = -1 means end of list
|
||||
;
|
||||
procedure Find_free_sfn,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
LES BX,sft_addr ; head of chain of tables
|
||||
XOR SI,SI ; count of sfn
|
||||
|
||||
; ES:BX points to table... search through table
|
||||
Find_sfn_in_table:
|
||||
CMP BX,-1 ; end of chain
|
||||
JZ Find_no_free_sfns
|
||||
MOV DI,sft_table ; offset to sf entry
|
||||
MOV CX,ES:[BX].sft_count ; count of fcbs in table
|
||||
|
||||
Find_sfn:
|
||||
CMP ES:BYTE PTR [BX+DI].sf_ref_count,0h
|
||||
JZ Find_got_sfn ; ref count is 0 -> free entry
|
||||
ADD DI,SIZE sf_entry ; look to next entry
|
||||
INC SI ; bump sfn
|
||||
LOOP Find_sfn
|
||||
LES BX,ES:[BX].sft_link ; link to next
|
||||
JMP SHORT Find_sfn_in_table ; look for more
|
||||
|
||||
Find_no_free_sfns:
|
||||
STC
|
||||
JMP SHORT find_ret
|
||||
Find_got_sfn:
|
||||
ADD DI,BX
|
||||
CLC
|
||||
Find_ret:
|
||||
POP CX
|
||||
POP BX
|
||||
RET
|
||||
Find_free_sfn ENDP
|
||||
|
||||
BREAK <$Open - open a file handle>
|
||||
;
|
||||
; Assembler usage:
|
||||
; LDS DX, Name
|
||||
; MOV AH, Open
|
||||
; MOV AL, access
|
||||
; INT int_command
|
||||
;
|
||||
; ACCESS Function
|
||||
; ------ --------
|
||||
; open_for_read file is opened for reading
|
||||
; open_for_write file is opened for writing
|
||||
; open_for_both file is opened for both reading and writing.
|
||||
;
|
||||
; Error returns:
|
||||
; AX = error_invalid_access
|
||||
; = error_file_not_found
|
||||
; = error_access_denied
|
||||
; = error_too_many_open_files
|
||||
;
|
||||
|
||||
procedure $Open,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
MOV [Cr_read_only],0
|
||||
Open_create:
|
||||
CMP AL,open_for_both ; validate access
|
||||
JBE OPEN_get_jfn
|
||||
error error_invalid_access
|
||||
|
||||
OPEN_get_jfn:
|
||||
MOV [open_name+2],DS
|
||||
context DS
|
||||
MOV open_name,DX
|
||||
MOV open_access,AL
|
||||
|
||||
invoke Find_free_jfn ; scan through user's area
|
||||
; ES:DI is the jfn entry
|
||||
JNC OPEN_get_sfn
|
||||
OPEN_too_many:
|
||||
error error_too_many_open_files
|
||||
|
||||
OPEN_get_sfn:
|
||||
MOV OPEN_jfn_b,ES
|
||||
MOV OPEN_jfn,DI
|
||||
invoke Find_free_sfn ; get a free sft entry
|
||||
; ES:DI is the SFT entry that's free, SI is the sfn
|
||||
JC OPEN_too_many
|
||||
|
||||
OPEN_file:
|
||||
MOV OPEN_sfn,SI
|
||||
MOV OPEN_sfoff,DI
|
||||
MOV OPEN_sfn_b,ES
|
||||
;
|
||||
; open the file
|
||||
;
|
||||
PUSH DS
|
||||
LDS DX,DWORD PTR [open_name]
|
||||
ASSUME DS:NOTHING
|
||||
CALL access_path
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
JNC open_check_access ; carry set -> error
|
||||
transfer SYS_RET_ERR
|
||||
|
||||
open_check_access:
|
||||
MOV ES,WORD PTR [CURBUF+2] ; get buffer location
|
||||
MOV open_devid,AH
|
||||
TEST AH,080h
|
||||
JNZ open_set_FCB_dev ;is a device
|
||||
MOV AL,ES:[BX].dir_attr
|
||||
TEST AL,attr_directory ; can't open directories
|
||||
JZ open_try_volid
|
||||
|
||||
open_bad_access:
|
||||
error error_access_denied
|
||||
|
||||
open_try_volid:
|
||||
TEST AL,attr_volume_id ; can't open volume ids
|
||||
JNZ open_bad_access
|
||||
TEST AL,attr_read_only ; check write on read only
|
||||
JZ open_set_FCB
|
||||
CMP [Cr_read_only],0
|
||||
JNZ open_set_FCB ; ok if creating read only file
|
||||
CMP open_access, open_for_read
|
||||
JNZ open_bad_access ; writing on a read only file
|
||||
JMP SHORT open_set_FCB
|
||||
|
||||
open_set_FCB_dev:
|
||||
PUSH SS
|
||||
POP ES ;Device opens are DOSGROUP relative
|
||||
|
||||
open_set_FCB:
|
||||
MOV CX,11 ; copy name into FCB...
|
||||
PUSH SI ; ES:BX is source, must change
|
||||
MOV SI,BX ; ES:SI is source
|
||||
MOV DI,open_sfoff ; ??:DI is dest
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
MOV ES,open_sfn_b ; ES:DI is dest
|
||||
POP DS ; DS:SI is source
|
||||
ASSUME DS:NOTHING
|
||||
;
|
||||
; need to save attribute for the close operation
|
||||
;
|
||||
MOV AH,DS:[BX.dir_attr] ; save attribute for close
|
||||
MOV ES:[DI.sf_attr],AH
|
||||
|
||||
ADD DI,sf_fcb+1 ; point to name
|
||||
|
||||
IF KANJI
|
||||
MOVSB
|
||||
CMP BYTE PTR ES:[DI-1],5
|
||||
JNZ NOTKTRAN
|
||||
MOV BYTE PTR ES:[DI-1],0E5H
|
||||
NOTKTRAN:
|
||||
DEC CX
|
||||
ENDIF
|
||||
|
||||
REP MOVSB ; move in parsed name
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
POP SI
|
||||
LES DI,DWORD PTR [open_sfoff]
|
||||
ADD DI,sf_fcb ; offset on fcb in sf entry
|
||||
MOV AH,open_devid
|
||||
invoke DOOPEN ; let open code fill in blanks
|
||||
context DS
|
||||
LES DI,DWORD PTR [open_sfoff]
|
||||
INC ES:[DI].sf_ref_count ; reference this FCB
|
||||
MOV AL,open_access ; stash the access
|
||||
MOV ES:BYTE PTR [DI].sf_mode,AL
|
||||
XOR AX,AX
|
||||
MOV ES:WORD PTR [DI.sf_FCB.fcb_RR],AX ; beginning of file
|
||||
MOV ES:WORD PTR [DI.sf_FCB.fcb_RR+2],AX
|
||||
INC AX
|
||||
MOV ES:WORD PTR [DI.sf_FCB.fcb_RECSIZ],AX ; byte io only
|
||||
LES DI,DWORD PTR [open_jfn]
|
||||
MOV AX,open_sfn
|
||||
MOV ES:BYTE PTR [DI],AL ; stash sfn in PDB
|
||||
SUB DI,PDB_jfn_table ; get jfn for user
|
||||
MOV AX,DI
|
||||
transfer SYS_RET_OK
|
||||
$Open ENDP
|
||||
|
||||
|
||||
BREAK <$UNLINK - delete a file entry>
|
||||
;
|
||||
; Assembler usage:
|
||||
; LDS DX, name
|
||||
; MOV AH, Unlink
|
||||
; INT 21h
|
||||
;
|
||||
; Error returns:
|
||||
; AX = error_file_not_found
|
||||
; = error_access_denied
|
||||
;
|
||||
procedure $UNLINK,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
CALL access_path
|
||||
JNC unlink_check_attr
|
||||
transfer SYS_RET_ERR
|
||||
|
||||
unlink_check_attr:
|
||||
JZ unlink_dir
|
||||
LDS DI,DWORD PTR [CURBUF] ; get directory entry
|
||||
TEST DS:[BX.dir_attr],attr_read_only
|
||||
JZ unlink_doit
|
||||
|
||||
unlink_dir:
|
||||
error error_access_denied
|
||||
|
||||
unlink_doit:
|
||||
MOV BYTE PTR DS:[BX.dir_name],0E5h ; delete dir entry
|
||||
MOV BYTE PTR DS:[DI.BUFDIRTY],1 ; dirty the buffer
|
||||
LODSW
|
||||
MOV BX,AX
|
||||
AND BX,0FFFh
|
||||
context DS
|
||||
JZ unlink_flush
|
||||
invoke RELEASE
|
||||
unlink_flush:
|
||||
MOV AL,BYTE PTR ES:[BP.DPB_drive]
|
||||
invoke FLUSHBUF
|
||||
transfer SYS_RET_OK
|
||||
$UNLINK ENDP
|
||||
|
||||
BREAK <$CREAT - creat a new file and open him for input>
|
||||
;
|
||||
; Assembler usage:
|
||||
; LDS DX, name
|
||||
; MOV AH, Creat
|
||||
; MOV CX, access
|
||||
; INT 21h
|
||||
; ; AX now has the handle
|
||||
;
|
||||
; Error returns:
|
||||
; AX = error_access_denied
|
||||
; = error_path_not_found
|
||||
; = error_too_many_open_files
|
||||
;
|
||||
|
||||
|
||||
procedure $CREAT,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
CALL Validate_path
|
||||
JNC unlink_do_make
|
||||
error error_path_not_found
|
||||
unlink_do_make:
|
||||
PUSH DX
|
||||
PUSH DS
|
||||
context DS
|
||||
MOV WORD PTR [CREATING],0E5FFh
|
||||
MOV WORD PTR [ThisFCB+2],SS
|
||||
MOV WORD PTR [ThisFCB],OFFSET DOSGROUP:AUXSTACK-40
|
||||
MOV SI,DX
|
||||
MOV AL,CL
|
||||
AND CL,attr_read_only
|
||||
MOV [Cr_read_only],CL
|
||||
POP DS
|
||||
PUSH DS
|
||||
ASSUME DS:NOTHING
|
||||
invoke MakeNode
|
||||
POP DS
|
||||
POP DX
|
||||
OR AL,AL
|
||||
JZ creat_open
|
||||
CMP AL,3
|
||||
JZ creat_open
|
||||
creat_no_access:
|
||||
error error_access_denied
|
||||
creat_open:
|
||||
MOV AL,open_for_both
|
||||
JMP Open_create
|
||||
|
||||
$CREAT ENDP
|
||||
|
||||
|
||||
BREAK <$DUP - duplicate a jfn>
|
||||
;
|
||||
; Assembler usage:
|
||||
; MOV BX, fh
|
||||
; MOV AH, Dup
|
||||
; INT int_command
|
||||
; AX has the returned handle
|
||||
; Errors:
|
||||
; AX = dup_invalid_handle
|
||||
; = dup_too_many_open_files
|
||||
procedure $DUP,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
context DS
|
||||
invoke Find_free_jfn
|
||||
JC dup_no_free_handles
|
||||
|
||||
dup_force:
|
||||
PUSH ES
|
||||
PUSH DI
|
||||
invoke Get_sf_from_jfn
|
||||
POP SI
|
||||
POP DS
|
||||
JC dup_bad_handle
|
||||
; ES:DI is pointer to sf entry
|
||||
; DS:DI is pointer to jfn
|
||||
INC ES:[DI].sf_ref_count ; another jfn reference...
|
||||
MOV AL,[BX].PDB_JFN_table ; get old sfn
|
||||
MOV [SI],AL ; store in new place
|
||||
SUB SI,PDB_JFN_table ; get jfn
|
||||
MOV AX,SI
|
||||
transfer SYS_RET_OK
|
||||
|
||||
dup_no_free_handles:
|
||||
error error_too_many_open_files
|
||||
|
||||
dup_bad_handle:
|
||||
error error_invalid_handle
|
||||
$DUP ENDP
|
||||
|
||||
BREAK <$DUP2 - force a dup on a particular jfn>
|
||||
;
|
||||
; Assembler usage:
|
||||
; MOV BX, fh
|
||||
; MOV CX, newfh
|
||||
; MOV AH, Dup2
|
||||
; INT int_command
|
||||
; Error returns:
|
||||
; AX = error_invalid_handle
|
||||
;
|
||||
procedure $DUP2,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
XCHG BX,CX ; BX < destination jfn
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
invoke $CLOSE ; close BX
|
||||
context DS
|
||||
POP CX
|
||||
POP BX
|
||||
invoke Get_jfn_pointer
|
||||
XCHG BX,CX
|
||||
JNC dup_force
|
||||
lseek_bad_handle:
|
||||
error error_invalid_handle
|
||||
$DUP2 ENDP
|
||||
|
||||
|
||||
BREAK <$CHMOD - change file attributes>
|
||||
;
|
||||
; Assembler usage:
|
||||
; LDS DX, name
|
||||
; MOV CX, attributes
|
||||
; INT 21h
|
||||
; Error returns:
|
||||
; AX = error_path_not_found
|
||||
; AX = error_access_denied
|
||||
;
|
||||
procedure $CHMOD,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
CMP AL,1
|
||||
JBE chmod_save
|
||||
error error_invalid_function
|
||||
chmod_save:
|
||||
JB chmod_try_file
|
||||
MOV BX,CX
|
||||
AND BX,NOT attr_changeable
|
||||
JZ chmod_try_file
|
||||
|
||||
chmod_bad:
|
||||
error error_access_denied
|
||||
|
||||
chmod_bye:
|
||||
transfer SYS_RET_ERR
|
||||
chmod_try_file:
|
||||
PUSH CX
|
||||
PUSH AX
|
||||
CALL access_path
|
||||
POP DX
|
||||
POP CX
|
||||
JC chmod_bye
|
||||
LES DI,[CURBUF]
|
||||
context DS
|
||||
OR DL,DL
|
||||
JZ chmod_fetch
|
||||
AND BYTE PTR ES:[BX].dir_attr,NOT attr_changeable
|
||||
OR BYTE PTR ES:[BX].dir_attr,CL
|
||||
MOV ES:[DI.BUFDIRTY],1
|
||||
MOV AL,-1
|
||||
invoke FlushBuf
|
||||
transfer SYS_RET_OK
|
||||
chmod_fetch:
|
||||
XOR CX,CX
|
||||
MOV CL,BYTE PTR ES:[BX].dir_attr
|
||||
invoke Get_user_stack
|
||||
MOV [SI.user_CX],CX
|
||||
transfer SYS_RET_OK
|
||||
$chmod ENDP
|
||||
|
||||
BREAK <$CURRENT_DIR - dump the current directory into user space>
|
||||
;
|
||||
; Assembler usage:
|
||||
; LDS SI,area
|
||||
; MOV DL,drive
|
||||
; INT 21h
|
||||
; ; DS:SI is a pointer to 64 byte area that contains drive
|
||||
; ; current directory.
|
||||
; Error returns:
|
||||
; AX = error_invalid_drive
|
||||
;
|
||||
procedure $CURRENT_DIR,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
PUSH DS
|
||||
PUSH BX
|
||||
PUSH SI
|
||||
invoke $get_DPB
|
||||
;
|
||||
; ES:BP points to DPB. DS:SI points to user stack, unless error
|
||||
;
|
||||
CMP AL,0FFh
|
||||
JNZ current_copy
|
||||
POP AX ; Clean Stack
|
||||
POP AX
|
||||
POP AX
|
||||
error error_invalid_drive
|
||||
|
||||
current_copy:
|
||||
POP DI ; where to move to
|
||||
POP [SI.user_BX] ; restore old BX
|
||||
POP BX
|
||||
MOV [SI.user_DS],BX ; and restore old DS
|
||||
;
|
||||
; ES:BP is pointer to DPB. BX:DI is pointer to destination
|
||||
;
|
||||
CMP ES:[BP.dpb_current_dir],-1
|
||||
JNZ current_ok
|
||||
PUSH BX
|
||||
PUSH DI
|
||||
MOV [ATTRIB],attr_all
|
||||
invoke GETCURRDIR
|
||||
POP DI
|
||||
POP BX
|
||||
current_ok:
|
||||
MOV SI,BP ; ES:SI is source
|
||||
PUSH ES
|
||||
POP DS ; DS:SI is source
|
||||
MOV ES,BX ; ES:DI is destination
|
||||
CMP [SI.dpb_current_dir],0
|
||||
JNZ current_move
|
||||
MOV BYTE PTR [SI.dpb_dir_text],0
|
||||
|
||||
current_move:
|
||||
ADD SI,dpb_dir_text
|
||||
MOV CX,DIRSTRLEN
|
||||
current_loop:
|
||||
LODSB
|
||||
STOSB
|
||||
OR AL,AL
|
||||
LOOPNZ current_loop
|
||||
transfer SYS_RET_OK
|
||||
$CURRENT_DIR ENDP
|
||||
|
||||
|
||||
BREAK <$RENAME - move directory entries around>
|
||||
;
|
||||
; Assembler usage:
|
||||
; LDS DX, source
|
||||
; LES DI, dest
|
||||
; MOV AH, Rename
|
||||
; INT 21h
|
||||
;
|
||||
; Error returns:
|
||||
; AX = error_file_not_found
|
||||
; = error_not_same_device
|
||||
; = error_access_denied
|
||||
procedure $RENAME,near
|
||||
|
||||
MOV WORD PTR [rename_source],DX
|
||||
MOV WORD PTR [rename_source+2],DS
|
||||
MOV WORD PTR [rename_dest],DI
|
||||
MOV WORD PTR [rename_dest+2],ES
|
||||
CALL Access_path
|
||||
JNC rename_check_dir
|
||||
transfer SYS_RET_ERR
|
||||
|
||||
rename_check_dir:
|
||||
JZ rename_no_access
|
||||
MOV DS,WORD PTR [CurBuf+2]
|
||||
PUSH [BX.dir_date]
|
||||
PUSH [BX.dir_first]
|
||||
PUSH [BX.dir_size_h]
|
||||
PUSH [BX.dir_size_l]
|
||||
PUSH [BX.dir_time]
|
||||
PUSH WORD PTR [BX.dir_attr]
|
||||
PUSH WORD PTR [ThisDrv]
|
||||
LDS SI,[rename_dest]
|
||||
invoke GetPath
|
||||
POP AX
|
||||
JC rename_check_drives
|
||||
rename_bad_access:
|
||||
ADD SP,12
|
||||
rename_no_access:
|
||||
error error_access_denied
|
||||
rename_check_drives:
|
||||
CMP AL,[ThisDrv]
|
||||
JZ rename_create
|
||||
ADD SP,12
|
||||
error error_not_same_device
|
||||
rename_create:
|
||||
LDS SI,[rename_dest]
|
||||
POP AX
|
||||
PUSH AX
|
||||
MOV WORD PTR [Creating],0E5FFh
|
||||
MOV WORD PTR [ThisFCB+2],SS
|
||||
MOV WORD PTR [ThisFCB],OFFSET DOSGROUP:AUXStack-40
|
||||
invoke MakeNode
|
||||
JC rename_bad_access
|
||||
LDS SI,[CurBuf]
|
||||
POP AX
|
||||
MOV [BX.dir_attr],AL
|
||||
POP [BX.dir_time]
|
||||
POP [BX.dir_size_l]
|
||||
POP [BX.dir_size_h]
|
||||
POP [BX.dir_first]
|
||||
POP [BX.dir_date]
|
||||
MOV [SI.BUFDIRTY],1
|
||||
LDS SI,[rename_source]
|
||||
invoke GetPath
|
||||
LDS SI,[CurBuf]
|
||||
MOV BYTE PTR [BX],0E5h
|
||||
MOV [SI.BUFDIRTY],1
|
||||
context DS
|
||||
MOV AL,0FFh
|
||||
invoke FlushBuf
|
||||
transfer SYS_RET_OK
|
||||
|
||||
$RENAME ENDP
|
||||
|
||||
BREAK <$FIND_FIRST - find first matching xenix filename>
|
||||
;
|
||||
; Assembler usage:
|
||||
; MOV AH, FindFirst
|
||||
; LDS DX, name
|
||||
; MOV CX, attr
|
||||
; INT 21h
|
||||
; ; DMA address has datablock
|
||||
;
|
||||
; Error Returns:
|
||||
; AX = error_file_not_found
|
||||
; = error_no_more_files
|
||||
;
|
||||
procedure $FIND_FIRST,near
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
CALL Validate_path
|
||||
JNC find_get
|
||||
JZ find_get
|
||||
error error_file_not_found
|
||||
find_get:
|
||||
MOV SI,DX
|
||||
PUSH CX
|
||||
INC BYTE PTR [NoSetDir] ; if we find a dir, don't change to it
|
||||
MOV WORD PTR [Creating],0E500h
|
||||
CALL GetPath
|
||||
POP CX
|
||||
MOV [Attrib],CL
|
||||
find_check:
|
||||
JNC find_check_attr
|
||||
find_no_more:
|
||||
error error_no_more_files
|
||||
find_check_attr:
|
||||
MOV DS,WORD PTR [CURBUF+2]
|
||||
MOV CH,[BX.dir_attr]
|
||||
invoke MatchAttributes
|
||||
JZ found_it
|
||||
PUSH [LastEnt]
|
||||
MOV BX,[DirStart]
|
||||
JMP find_it_next
|
||||
found_it:
|
||||
LES DI,[DMAADD]
|
||||
MOV AL,[Attrib]
|
||||
STOSB ; find_buf 0 = attribute in search
|
||||
MOV AL,[ThisDrv]
|
||||
STOSB ; find_buf 1 = drive
|
||||
MOV CX,11
|
||||
PUSH BX
|
||||
MOV SI,OFFSET DOSGROUP:NAME1; find_buf 2 = formatted name
|
||||
PUSH DS
|
||||
PUSH SS
|
||||
POP DS
|
||||
|
||||
IF KANJI
|
||||
MOVSB
|
||||
CMP BYTE PTR ES:[DI-1],5
|
||||
JNZ NOTKANJB
|
||||
MOV BYTE PTR ES:[DI-1],0E5H
|
||||
NOTKANJB:
|
||||
DEC CX
|
||||
ENDIF
|
||||
|
||||
REP MOVSB
|
||||
POP DS
|
||||
MOV AX,[LastEnt]
|
||||
STOSW ; find_buf 13 = LastEnt
|
||||
MOV AX,WORD PTR [ThisDPB]
|
||||
STOSW ; find_buf 15 = ThisDPB
|
||||
MOV AX,WORD PTR [ThisDPB+2]
|
||||
STOSW
|
||||
MOV AX,[DirStart]
|
||||
STOSW ; find_buf 19 = DirStart
|
||||
MOV AL,[BX].dir_attr
|
||||
STOSB ; find_buf 21 = attribute found
|
||||
MOV AX,[BX].dir_time
|
||||
STOSW ; find_buf 22 = time
|
||||
MOV AX,[BX].dir_date
|
||||
STOSW ; find_buf 24 = date
|
||||
MOV AX,[BX].dir_size_l
|
||||
STOSW ; find_buf 26 = low(size)
|
||||
MOV AX,[BX].dir_size_h
|
||||
STOSW ; find_buf 28 = high(size)
|
||||
POP SI
|
||||
MOV CX,8 ; find_buf 30 = packed name
|
||||
find_loop_name:
|
||||
LODSB
|
||||
STOSB
|
||||
CMP AL," "
|
||||
LOOPNZ find_loop_name
|
||||
JNZ find_check_dot
|
||||
DEC DI
|
||||
find_check_dot:
|
||||
ADD SI,CX
|
||||
CMP BYTE PTR [SI]," "
|
||||
JZ find_done
|
||||
MOV AL,"."
|
||||
STOSB
|
||||
MOV CX,3
|
||||
find_loop_ext:
|
||||
LODSB
|
||||
STOSB
|
||||
CMP AL," "
|
||||
LOOPNZ find_loop_ext
|
||||
JNZ find_done
|
||||
DEC DI
|
||||
find_done:
|
||||
XOR AL,AL
|
||||
STOSB
|
||||
transfer SYS_RET_OK
|
||||
$FIND_FIRST ENDP
|
||||
|
||||
BREAK <$FIND_NEXT - scan for match in directory>
|
||||
;
|
||||
; Assembler usage:
|
||||
; ; dma points at area returned by find_first
|
||||
; MOV AH, findnext
|
||||
; INT 21h
|
||||
; ; next entry is at dma
|
||||
;
|
||||
; Error Returns:
|
||||
; AX = error_no_more_files
|
||||
;
|
||||
procedure $FIND_NEXT,near
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
LDS SI,[DMAADD]
|
||||
MOV DX,SI
|
||||
INC DX
|
||||
PUSH SI
|
||||
invoke MOVNAMENOSET
|
||||
POP SI
|
||||
JNC find_load
|
||||
findnext_no_more:
|
||||
error error_no_more_files
|
||||
find_load:
|
||||
MOV AX,[SI.find_buf_LastEnt]
|
||||
LES BP,[SI.find_buf_ThisDPB]
|
||||
OR AX,AX
|
||||
JS findnext_no_more
|
||||
MOV BX,[SI.find_buf_DirStart]
|
||||
MOV DL,[SI.find_buf_sattr]
|
||||
MOV [Attrib],DL
|
||||
PUSH AX
|
||||
MOV WORD PTR [ThisDPB],BP
|
||||
MOV WORD PTR [ThisDPB+2],ES
|
||||
find_it_next:
|
||||
invoke SetDirSrch
|
||||
ASSUME DS:DOSGROUP
|
||||
POP AX
|
||||
MOV [ENTLAST],-1
|
||||
invoke GetEnt
|
||||
invoke NextEnt
|
||||
JMP find_check
|
||||
$find_next ENDP
|
||||
|
||||
do_ext
|
||||
|
||||
CODE ENDS
|
||||
END
|
||||
|