⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 funcs.fdo

📁 一个dos操作系统DRDOS的源码
💻 FDO
📖 第 1 页 / 共 5 页
字号:
;    File              : $FUNCS.FDO$
;
;    Description       :
;
;    Original Author   : DIGITAL RESEARCH
;
;    Last Edited By    : $CALDERA$
;
;-----------------------------------------------------------------------;
;    Copyright Work of Caldera, Inc. All Rights Reserved.
;      
;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
;    CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
;    *** Current Edit History ***
;    *** End of Current Edit History ***;
;    $Log$;
;    ENDLOG
;	General function include module for FDOS.A86

BDOS_CODE	cseg

	public fdos_entry

;==========
fdos_entry:			; FDOS module entry point
;==========
;	On Entry:
;		DS:DX -> parameter block
;	On exit:
;		AX = BX = return code
;		(DS/ES corrupted)
;	entry:	DS:DX = argument
;
;	exit:	AX,BX = return code

	mov	si,dx
	lodsw				; AX = FDOS number
	sub	ax,39h			; base it at zero
	 jc	fd_error		; stop if too low
	cmp	ax,FDOS_MAX		; check if function in range
	 jae	fd_error		; yes, continue

	push	ds			; save parameter segment
	push	dx			; save parameter offset
	push	ax			; save sub-function
	mov	bp,sp			; SS:BP -> working variables
	mov	bx,ax
	add	bx,ax
	add	bx,ax
	call	fdos_tbl[bx]
	add	sp,3*WORD		; clean up stack
	mov	ax,bx
	ret

fd_error:
	mov	ax,ED_FUNCTION		; return "invalid function"
	mov	bx,ax
	ret


fdos_tbl	dw	fdos_mkdir	; 39-make directory
		db	2
		dw	fdos_rmdir	; 3A-remove directory
		db	2
		dw	fdos_chdir	; 3B-change directory
		db	2
		dw	fdos_creat	; 3C-create file
		db	4
		dw	fdos_open	; 3D-open file
		db	4
		dw	fdos_close	; 3E-close file
		db	1
		dw	fdos_read	; 3F-read from file
		db	4
		dw	fdos_write	; 40-write to file
		db	4
		dw	fdos_unlink	; 41-delete file
		db	4
		dw	fdos_lseek	; 42-set file pointer
		db	4
		dw	fdos_chmod	; 43-get/set file attributes
		db	6
		dw	fdos_ioctl	; 44-IOCTL emulation
		db	3
		dw	fdos_dup	; 45-duplicate handle
		db	2
		dw	fdos_fdup	; 46-force duplicate handle
		db	2
		dw	fdos_curdir	; 47-get current directory
		db	3
		dw	fdos_getdpb	;*48*disk information
		db	4
		dw	fdos_flush	;*49*flush buffers
		db	0
		dw	fdos_select	;*4A*drive select
		db	1
		dw	fdos_exec	;*4B*create child PSP
		db	1
		dw	fdos_exit	;*4C*close child PSP
		db	0
		dw	fdos_fcb	;*4D*generic FCB call
		db	5
		dw	fdos_first	; 4E-find first matching file
		db	4
		dw	fdos_next	; 4F-find next matching file
		db	0
		dw	fdos_commit	;*50*commit file
		db	1
		dw	fdos_mknew	;*51*make new file
		db	4
		dw	fdos_lock	;*52*lock/unlock block
		db	6
		dw	fdos_mkddsc	; 53 build DDSC from BPB
		db	4
		dw	fdos_ddio	;*54*Int 25/26 emulation
		db	6
		dw	fdos_expand	;*55*expand file name
		db	6
		dw	fdos_move	; 56-rename file
		db	6
		dw	fdos_dattim	; 57-get/set file name
		db	4
		dw	fdos_reopen_fcb	; 58-FCB reopen support function
		db	5

FDOS_MAX	equ	(offset $ - offset fdos_tbl) / 3

	Public	local_disk

local_disk:	; continue execution within MXdisk semaphore
;----------
;	This function will make local copies of the parameters
;	and continue

	callf	ss:lock_tables
	pop	fdos_addr		; return address
	add	sp,2*WORD		; discard return from call fdos_tbl[bx]
					;    and function #
	pop	si			; get parameter offset
	pop	ax			; get parameter segment
	mov	sp_save,sp		; save for re-entry/errors
	mov	ds,ax			; DS:SI -> paremeter block
fdos_reenter:
	push ss ! pop es		; ES = local data segment
	mov	di,offset fdos_pb	; ES:DI -> local parameter block copy
	lodsw ! stosw			; load subfunction number
	mov	es:fdos_info,si		; save it for BDOS return
	mov	es:fdos_info+WORD,ds	; save parameter segment for return
	mov	bx,ax
	add	bx,ax
	add	bx,ax			; BX = function # * 3
	mov	cl,byte ptr fdos_tbl-(39h*(WORD+BYTE))+WORD[bx]
	mov	ch,0
					; get table of # of parameters
	mov	es:fdos_info+2*WORD,cx	; save the parameter count
	rep	movsw			; copy parameter block
	push es ! pop ds		; DS = SYSDAT
	mov	ioexerr,0FFh		; assume default error code
	mov	rwmode,0

	mov	finddfcb_mask,DA_VOLUME*256

	xor	ax,ax
	mov	fdos_ret,ax		; assume success unless proven otherwise
	call	fdos_addr		; call code following "call local_disk"
	mov	ax,fdos_ret		; get return code, fall thru to exit

	Public	fdos_error

fdos_error:
;----------
; AX = return code
	mov	sp,sp_save		; stack to entry value (for errors)
	mov	si,offset fdos_pb+2	; get local copy
	les	di,dword ptr fdos_info	; get parameter block address
	mov	cx,fdos_info+2*WORD	; get parameter block size
	rep	movsw			; copy return values
	mov	bx,ax
	callf	ss:unlock_tables
	ret				; return to BDOS, which copies BX to AX

	Public	fdos_restart

fdos_restart:	; we want to restart the function after an error
;------------	; we already have MXdisk
;
	mov	sp,sp_save		; break out from low levels
	lds	si,dword ptr fdos_info
	dec	si ! dec si		; DS:SI -> parameter block
	jmps	fdos_reenter		; try from scratch

fdos_ED_ROOM:
;-----------
	mov	ax,ED_ROOM		; no more files
	jmps	fdos_error

fdos_ED_DRIVE:
;-----------
	mov	ax,ED_DRIVE		; bad drive
	jmps	fdos_error

fdos_ED_PATH:
	mov	ax,ED_PATH		; invalid path or drive
	jmps	fdos_error

fdos_ED_PROTECT:
	mov	ax,ED_PROTECT		; write protect error
	jmps	fdos_error

	Public	fdos_ED_ACCESS

fdos_ED_ACCESS:
	mov	ax,ED_ACCESS		; access denied error
	jmps	fdos_error

eject
;	MAKE DIRECTORY (MKDIR)

;	+----+----+----+----+----+----+
;	|    39   |        name       |
;	+----+----+----+----+----+----+

;	entry:
;	------
;	name:	segmented address of ASCIIZ name

;	exit:
;	-----
;	AX:	0000 or error code ( < 0)

fdos_mkdir:
;----------
	call	redir_asciiz_offer
	call	local_disk		; get MXdisk, switch stack
	call	path_prep_chk		; parse path, walk down the tree
	call	finddfcbf		; find matching FCB
	 jnz	mkdir_access		; file/dir exists, "access denied"
	call	allocdir		; allocate a directory entry

	push	ax			; save pointer to directory entry
	lea	si,info_fcb+1		; SI -> file name
	xchg	ax,di			; DI -> DNAME
	mov	cx,11
	rep	movsb			; copy file name into directory buffer
;	lea	di,DATTS[si]
	mov	al,DA_DIR
	stosb				; mark it as a directory
	xor	ax,ax
	mov	cx,(32-12)
	rep	stosb			; zero remainder of new FCB
	pop	si			; SI -> directory

	call	stamp_dir_entry		; set time and date in FCB
	xor	ax,ax
	call	alloc_cluster		; Allocate a block
	 jc	mkdir_err		; Report Error(no room on disk)
	mov	si,dirp
	mov	DBLOCK1[si],ax		; Initialize 1st block of fcb
	push	ax			; save block
	call	update_fat		; Write the fat to disk
	call	update_dir		; Write the directory to disk
	pop	ax			; now initialise the sub-directory
	call	mkdir_init		;  '.' and '..' entries
	call	update_dir		; update directory entry
	mov	ax,5			; return a magic value for some
	mov	fdos_ret,ax		;  PD expansion program
	ret

mkdir_err:
;---------
	mov	bx,dirp			; can't make dir, no data space
	mov	DNAME[bx],0E5h		; so release our directory entry
	call	update_dir		; release this entry
mkdir_access:
	jmp	fdos_ED_ACCESS		; return "access denied" error

chk_no_dot:				; reject "." and ".." names
	cmp	info_fcb+1,'.'
	 je	mkdir_access
	ret

eject
;	REMOVE DIRECTORY (RMDIR)

;	+----+----+----+----+----+----+
;	|    3A   |        name       |
;	+----+----+----+----+----+----+

;	entry:
;	------
;	name:	segmented address of ASCIIZ name

;	exit:
;	-----
;	AX:	0000 or error code ( < 0)

fdos_rmdir:
;----------
	call	redir_asciiz_offer
	call	local_disk		; get MXdisk, switch stack
	call	path_prep_chk		; parse path to bottom level
	call	finddfcbf		; try to locate directory entry
	 jz	fdos_rmdir20		; skip if we can't find it
	test	DATTS[bx],DA_DIR	; check directory attribute
	 jz	fdos_rmdir30		; O.K. if a directory
	call	chkcds			; make sure no-where current
	 jnc    fdos_rmdir40
	call	path_prep		; redo as rmdir_ok may destroy info
	call	finddfcbf		; find the entry again
	call	rmdir_ok		; make sure not in use
	call	finddfcbf		; find the entry again
if PASSWORD
    call    check_pwd_any      
endif
kill_entry:
	call	kill_file		; actually delete entry
update_dir_fat:
	call	update_dir		; update directory entry
	jmp	update_fat		; update file allocation table

fdos_rmdir20:
	jmp	fdos_ED_PATH		; "invalid path"

fdos_rmdir30:
	jmp	fdos_ED_ACCESS		; "access denied"

fdos_rmdir40:
	mov	ax,ED_DIR
	jmp	fdos_error

eject
;	CHANGE DIRECTORY (CHDIR)

;	+----+----+----+----+----+----+
;	|    3B   |        name       |
;	+----+----+----+----+----+----+

;	entry:
;	------
;	name:	segmented address of ASCIIZ name

;	exit:
;	-----
;	AX:	0000 or error code ( < 0)


chdir_ED_PATH:
	jmp	fdos_ED_PATH		; all logical errors give "no path"

chdir_ED_DRIVE:
	mov	ax,ED_DRIVE		; bad drive error message
chdir_err:
	jmp	fdos_error

fdos_chdir:
;----------
	call	redir_asciiz_offer
	call	local_disk		; get MXdisk, switch stack
fdos_move_chdir:
;---------------
	mov	orig_drive,0FFFFh	; set drive to invalid
	les	di,dword ptr fdos_pb+2	; get string address
	call	get_path_drive		; from asciiz or default
	 jc	chdir_ED_DRIVE		;  continue if drive A: - Z:
	call	islocal			; reject networked drives
	 jc	chdir_ED_DRIVE		;  as bad drives
	call	path_prep_cont		; continue if drive legal
	 jc	chdir_err		; return error to application
	call	chk_no_dev		; no devices allowed
	call	chk_no_wild		; no wild cards allowed here
	cmp	orig_drive,0FFFFh	; check if assign to specified drive
	 jne	chdir10			; skip drive specified
	mov	ax,path_drive		; else same as path drive
	mov	orig_drive,ax
chdir10:
if JOIN
	call	offer_join		; are we opening a JOIN'd drive ?
	 jnc	chdir30			;  if so move to it and skip open_dir
endif
	call	chk_for_root		; check if we are in the root
	 je	chdir30			; if so, just skip the open_dir
	call	finddfcbf		; try to locate directory entry
	 jz	chdir_ED_PATH		; skip if no valid directory
	test	DATTS[bx],DA_DIR	; check directory attribute
	 jz	chdir_ED_PATH		; return if not a directory
if PASSWORD
	call	check_pwd_any		; check if PW prot'd & wrong PW
endif
	call	open_dir		; else open last directory
	 jc	chdir_ED_PATH		; return an error if we can't
chdir30:
	mov	ax,orig_drive		; get logical drive
	call	get_ldt			; ES:BX -> LDT_
	 jc	chdir10			; no LDT_, must be init time...
	mov	si,es:LDT_FLAGS[bx]	; normally we inherit parents
	mov	cx,es:LDT_ROOTLEN[bx]	; root block and drive
	mov	dx,es:word ptr LDT_NAME[bx]
	mov	bx,es:LDT_ROOT[bx] 	; if it's a "SUBST I: C:\PATH" form
	cmp	ax,path_drive		;  we pick up new root and drive
	 je	chdir50			;  like this
	mov	ax,path_drive		; ASCII drive from path drive
	mov	dx,'A'+256*':'		; make it into ASCII "C:"
	add	dx,ax			; in case LDT does not exist
	call	get_ldt			; get LDT_ in case it's subst'd
	 jc	chdir40
	mov	dx,es:word ptr LDT_NAME[bx]
chdir40:
	mov	bx,fdos_hds_blk		; root block from fdos_hds
chdir50:
	mov	di,offset pri_pathname	; build new LDT_ here
	or	si,LFLG_PHYSICAL	; drive is always physical
	mov	LDT_FLAGS[di],si
	mov	LDT_ROOTLEN[di],cx	; inherit rootlen from parent
	mov	LDT_ROOT[di],bx		; root as above
	mov	ax,fdos_hds_blk		; current block from HDS
	mov	LDT_BLK[di],ax
	mov	al,fdos_hds_drv		; current drive we from HDS
	mov	LDT_DRV[di],al
	mov	ax,word ptr current_ddsc
	mov	word ptr LDT_PDT[di],ax
	mov	ax,word ptr current_ddsc+WORD
	mov	word ptr LDT_PDT+WORD[di],ax
	push ss ! pop es		; now build ASCII path
;	lea	di,LDT_NAME[di]		; ES:DI -> name
	xchg	ax,dx
	stosw				; plant 'A:'
	mov	ax,'\'
	stosw				; make that 'A:\',0
	dec	di			; point at NUL
	mov	fdos_hds_root,0		; we want to go back to root
	mov	fdos_pb+6,di		; rebuild into LDT_ at the address
	mov	fdos_pb+8,es
	push ds ! pop es
chdir60:
	call	hdsblk			; get current block
if JOIN
	 jnz	chdir65			; if not at root unparse
	call	check_join		; check if drive is joined to another
	 jz	chdir80			; at root, unJOIN'd, so exit
					; we are at the root of this drive
	xchg	al,fdos_hds_drv		; update HDS drive so we can force
	push	es			;  an exit next time round
	call	get_ldt			; now copy the JOIN'd name
	push ds ! push es ! pop ds ! pop es	
	lea	si,LDT_NAME+3[bx]	; point to my JOIN data
	mov	di,offset save_area
	call	copy_asciiz
	push es ! pop ds
	pop	es
	jmps	chdir70			; copy this into place

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -