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

📄 funcs.fdo

📁 一个dos操作系统DRDOS的源码
💻 FDO
📖 第 1 页 / 共 5 页
字号:
	pop	dx
	xchg	adrive,dl
	call	discard_all		; discard all buffers
	xchg	adrive,dl
	inc	dx			; onto next drive
	cmp	dl,phys_drv
	 jb	fdos_flush10
	mov	al,0FFh			; AL = all drives
	jmp	hshdscrd		; forget about our hashing
;	ret


eject
;	SELECT DRIVE

;	+----+----+----+----+
;	|    4A   |  drive  |
;	+----+----+----+----+

;	entry:
;	------
;	drive:	drive (zero based) to select as default drive

;	exit:
;	-----
;	current_dsk: drive (if legal)

fdos_select:
;-----------
	call	local_disk		; cheap way to get MX
	mov	ax,fdos_pb+WORD		; AL = drive
	call	get_ldt			; ES:BX -> LDT for drive A
	mov	dx,ax			; DL = logical drive
	 jc	fdos_select10		; no LDT, treat as physical=logical
	mov	ax,es:LDT_FLAGS[bx]	; get the LDT_FLAGS
	test	ax,LFLG_NETWRKD		; NETWORK drives are OK, but we must
	 jnz	fdos_select20		;  skip physical selection bit
	test	ax,LFLG_PHYSICAL
	 jz	fdos_select30		;  skip physical selection bit
if JOIN
	test	ax,LFLG_JOINED		; JOINed drives are bad news
	 jnz	fdos_select30		;  so don't select one
endif
	mov	al,es:LDT_NAME[bx]	; get ASCII drive letter
	call	toupper			; it was ascii
	sub	al,'A'			;  make it zero based
fdos_select10:
	call	get_ddsc		; ES:BX -> DDSC_ for drive
	 jc	fdos_select30		;  no, don't select
fdos_select20:
	mov	ss:current_dsk,dl	; new logical disk selected
fdos_select30:
	ret

eject
;	EXECUTE CHILD (EXEC)

;	+----+----+----+----+
;	|    4B   |  pspseg |
;	+----+----+----+----+

;	entry:
;	------
;	pspseg: segment of child PSP

;	exit:
;	-----
;	AX:	0000h

fdos_exec:
;---------
	call	local_disk		; get MXdisk, switch stack
	mov	cx,fdos_pb+2
	 jcxz	exec30			; no duplicate handles if no new PSP
	mov	di,offset PSP_XFT
	mov	es,cx			; get child PSP
	mov	cx,XFNMAX		; get # of handles in child PSP
	mov	PSP_XFNMAX,cx
	mov	PSP_XFTOFF,di
	mov	PSP_XFTSEG,es
	mov	al,0FFh			; assume all handles closed
	rep	stosb
	xor	si,si			; start with XFN 0
exec10:
	call	get_xftptr		; ES:DI -> XFN table
	 jc	exec30			; stop if none
	add	di,si
	mov	al,es:[di]		; get IFN of old handle
	call	ifn2dhndl		; ES:BX -> DHNDL_
	 jc	exec20
	mov	cx,es:DHNDL_COUNT[bx]	; skip files that aren't open
	 jcxz	exec20
	test	es:byte ptr DHNDL_WATTR+1[bx],DHAT_LOCAL/100h
	 jnz	exec20			; don't inherit private files
	test	es:byte ptr DHNDL_MODE+1[bx],DHM_FCB/100h
	 jnz	exec20			; don't inherit FCB's
	inc	cx
	mov	es:DHNDL_COUNT[bx],cx	; increment in-use count
	push	ax
	call	dup_dev			; inform device driver it's happened
	pop	ax
	mov	es,fdos_pb+2		; get child PSP
	mov	es:PSP_XFT[si],al	; inherit this IFN
exec20:
	inc	si			; next file handle
	cmp	si,XFNMAX
	 jb	exec10			; inherit all file handles
exec30:
	ret


eject
;	FIND FIRST FILE

;	+----+----+----+----+----+----+----+----+----+----+
;	|    4E   |        name       |  *****  |  attrib |
;	+----+----+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	name:	pointer to ASCIIZ file name
;	attrib:	attribute to be used in search
;		nb. API addition - attrib bit 7 set returns starting cluster
;	
;	exit:
;	-----
;	AX:	0000 or error code ( < 0)

;	Note:	This call returns matching files in
;		the current DMA address and also saves
;		the BDOS state in the there.
;

fdos_first:
;----------
	call	redir_asciiz_dev_offer	; offer it as a network device
	call	asciiz_dev_offer	; offer it as a local device
	call	redir_asciiz_file_offer	; offer it as a network file
	call	local_disk		; get MXdisk, switch stack
	call	path_prep		; parse path, walk down the tree
	call	check_device		; if it a device
	 jnc	fdos_first10
	mov	ax,fdos_pb+8		; get search attribute
	mov	attributes,al		; set for attribute match
	mov	dcnt,0FFFFh		; search from beginning
	jmps	search_next		; find next matching file

fdos_first10:
	jmp	first_dev		; return device name

next_deverr:				; NEXT after FIRST on device:
	mov	bx,ED_FILE		; "no more files"
	ret

eject
;	FIND NEXT FILE

;	+----+----+
;	|    4F   |
;	+----+----+

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

;	Note:	This call returns matching files in
;		the current DMA address and also saves
;		the BDOS state in the there.
;

fdos_next:
;---------
	push	ds
	call	lds_si_dmaptr		; DS:SI -> users DMA address
	lodsw
	xchg	ax,dx			; DH = local drive
	pop	ds
	cmp	dh,0FFh			; check if FIRST was character device
	 je	next_deverr		; "no more files" if device
	call	redir_snext_offer
	call	local_disk		; get MXdisk, switch stack
	call	select_from_DTA		; prepare for the search
;	jmp	search_next		; now go and look for next file

search_next:
;-----------
	mov	chdblk,0		; don't assume sequential access
	mov	al,attributes		; are we looking for a VOL label?
	test	al,DA_DIR+DA_SYSTEM+DA_HIDDEN
	 jnz	search_n10		; these bits take precedence
	test	al,DA_VOLUME		; searching for label?
	 jz	search_n10		; search for directory label only
if UNDELETE
	cmp	al,DA_DELWATCH+DA_VOLUME
	 jne	search_vol		; searching for pending delete entries?
	call	find_pending_delete	; did we find it ?
	 jz	search_next_err		; No, then skip
	jmps	search_n30		; save search state for user
search_vol:
endif
	call	find_label		; did we find it ?
	 jnz	search_n30		; save search state for user
search_next_err:
	jmp	fdos_ED_ROOM		; else end of directory

search_n10:
	call	finddfcb		; find next matching entry
	 jz	search_next_err		; if not found
	mov	al,attributes		; get attributes that we support
if PASSWORD
	cmp	word ptr DPWD[bx],0	; does it have a password?
	 jz	search_n20		; skip if not
	or	al,DA_HIDDEN		; else include hidden files
search_n20:
endif
	not	al			; attributes we don't support
	and	al,DA_DIR+DA_HIDDEN+DA_SYSTEM+DA_VOLUME
	test	DATTS[bx],al		; any attributes we don't support
	 jnz	search_n10		; then don't count this one
search_n30:
	push ss ! pop es
	mov	di,offset srch_buf	; ES:DI -> DMA search address
	push	di			; save for later
if JOIN
	mov	al,fdos_hds_drv		; save the PHYSICAL drive
else
	mov	al,byte ptr path_drive	; save the specified drive
endif
	inc	al
	stosb
	mov	dx,di			; remember start of name field
	mov	si,offset info_fcb+1	; point at search FCB
	mov	cx,11
	rep	movsb			; save name for search
	mov	al,attributes		; get search attribute
	stosb

	mov	ax,dcnt
	stosw				; save directory count
	mov	ax,fdos_hds_blk		; get the directory block
	stosw				; save the current block

	add	di,4			; skip 4 reserved bytes

	mov	si,dirp			; point to directory name
	test	attributes,DA_CLUSTER	; is the caller requesting
	 jz	search_n35		; the starting cluster ?
	mov	ax,DBLOCK1[si]		; pick it up from dir entry
	dec	di			;  and return at offset 13h
	dec	di			;  in DTA (WARNING - Lantastic
	stosw				; server uses these bytes too..)
search_n35:
    mov cx,32/WORD 
	rep	movsw			;  location (also used by FCB search)

	pop	si			; SI = offset srch_buf
	call	les_di_dmaptr		; ES:DI -> DMA address
	push ss ! pop ds		; DS:SI -> srch_buf
	mov	cx,21
	rep	movsb			; copy from buffer to user DMA
	mov	bx,dirp			; BX -> matching entry
	mov	al,DATTS[bx]
	stosb				; return directory attribute
	lea	si,DTIME[bx]
	movsw ! movsw			; return time, date
	inc	si
	inc	si			; skip starting cluster
	movsw ! movsw			; return file size
	jmp	unparse			; return file name

eject
;	COMMIT FILE (COMMIT)

;	+----+----+----+----+
;	|    50   |  handle |
;	+----+----+----+----+

;	entry:
;	------
;	handle:	open file handle to be flushed

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

file_updt20:				; NO-OP for clean files
commit_dev:				; NO-OP on character devices
	ret

fdos_commit:
;-----------
	call	vfy_dhndl_ptr		; check file handle
	call	redir_dhndl_offer
	call	local_disk		; get MXdisk, switch stack
	call	verify_handle		; check if legal file handle
	 jc	commit_dev
;	jmp	file_update		; update directory & FAT if written

;	Update directory & File Allocation Table (partial close)
;	entry:	ES:BX -> DHNDL_
;	exit:	ES:BX preserved

	Public	file_update

file_update:
;-----------
	test	es:DHNDL_ATTR[bx],DHAT_CLEAN
	 jnz	file_updt20		; skip if file is clean
	mov	al,es:DHNDL_DCNTLO[bx]	; get directory count
	mov	ah,es:DHNDL_DCNTHI[bx]
	dec	ax
	mov	dcnt,ax			; set search position
	xor	cx,cx			; find any entry
	mov	chdblk,cx		; non-sequential access
	push es ! push bx
	call	getdir			; read the directory entry
	pop bx ! pop es
	test	ax,ax			; did we find something?
	 jz	file_updt10		; skip if directory entry lost
	xchg	ax,di			; DI -> directory entry in buffer
	or	DATTS[di],DA_ARCHIVE	; mark file as modified
;;;	call	timestamp_dhndl		; record the current time
	mov	ax,es:DHNDL_BLK1[bx]	; AX = 1st block in file
	lea	di,DTIME[di]		; DI -> [time,date,block1,size]
	push es ! push bx
	push	ds
    lea si,DHNDL_TIME[bx]
	push ds ! push es
	pop ds ! pop es			; swap ES and DS
	movsw ! movsw			; copy time then date
	stosw				; now 1st cluster
	movsw ! movsw			; finally file size
	pop	ds
	call	update_dir		; update directory
	call	update_fat		; flush dirty FAT
	call	update_dat		; flush all dirty data buffers
	pop	bx ! pop es
	or	es:DHNDL_ATTR[bx],DHAT_CLEAN
	ret				; only mark as clean AFTER it's written

file_updt10:
	mov	ax,ED_H_MATCH		; can't find open file
	mov	fdos_ret,ax		; save error code
	ret



eject
;	CREATE NEW FILE

;	+----+----+----+----+----+----+----+----+
;	|    51   |        name       |  mode   |
;	+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	name:	segmented address of ASCIIZ name
;   mode:   attribute for file 

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

;	Note:	The function is identical to CREATE FILE
;		with the exception that an error is returned
;		if the specified file already exists.

fdos_mknew:
;----------
	call	redir_asciiz_offer
	call	local_disk		; get MXdisk, switch stack
	call	mustbe_free_handle	; make sure we have spare handle
	call	path_prep_chk		; parse path, walk down the tree
	call	finddfcbf		; check if we can find this one
	 jnz	mknew10
	test	byte ptr fdos_pb+8,DA_VOLUME
	 jz	mknew_nolbl		; skip if not volume label
	call	mustbe_nolbl		; do we have an existing label ?
mknew_nolbl:
	jmp	creat_new_file		; go ahead and create the file
mknew10:
    mov ax,ED_EXISTS        
	jmp	fdos_error

eject
;	LOCK/UNLOCK FILE DATA (LOCK/UNLOCK)

;	+----+----+----+----+----+----+----+----+
;	|    52   |  handle |       offset      |
;	+----+----+----+----+----+----+----+----+
;	|       length      |   lock  |
;	+----+----+----+----+----+----+

;	entry:
;	------
;	handle:	open file handle
;	offset:	long integer offset
;	length:	long integer byte count
;	lock:	0 = lock, 1 = unlock

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

fdos_lock:
;---------
	call	vfy_dhndl_ptr		; check file handle #
	test	es:DHNDL_WATTR[bx],DHAT_DEV
	 jnz	lock_dev		; skip if character device
	call	redir_dhndl_offer
	call	local_disk		; get MXdisk, switch stack
	call	check_handle		; check if legal file handle
	mov	ax,ED_ACCESS		; assume a problem
	 jc	lock_error		; can't lock/unlock device handles
	mov	di,offset fdos_pb
	callf	ss:share_stub+S_LOCKS	; call the stub routine
	 jnc	lock_ret		; return error if we got one
lock_error:
	jmp	fdos_error		; can't do locking

lock_dev:
	mov	bx,ED_ACCESS
lock_ret:
	ret

eject
;	BUILD DDSC FROM BPB

;	+----+----+----+----+----+----+----+----+----+----+
;	|    53   |       bpbptr      !      ddscptr      |
;	+----+----+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	bpbptr:		address of BPB
;	ddscptr:	address of DDSC to be built

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

fdos_mkddsc:
;-----------
	push	ds
	mov	si,2[bp]		; SI -> parameter block
	les	di,6[si]		; ES:DI -> DDSC
	lds	si,2[si]		; DS:SI -> BPB

	call	bpb2ddsc		; convert BPB to DDSC
	xor	bx,bx			; no error
	pop	ds			; restore segment register
	ret


bpb2ddsc:
;--------
; build a DDSC from a BPB, leavinf UNIT, RUNIT, DEVICE, FIRST, and LINK fields
; unchanged
; On Entry:
;	DS:SI -> source BPB
;	ES:DI -> destination DDSC

⌨️ 快捷键说明

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