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

📄 fcbs.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 2 页
字号:
title 'FCB - DOS file system FCB support'
;    File              : $FCBS.A86$
;
;    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$
;    FCBS.A86 1.10 93/11/11 15:38:14
;    Chart Master fix - fcb_readblk over > 64k is truncated to 64k and
;    error 2 (Segment boundry overlap) is returned
;    FCBS.A86 1.9 93/10/18 17:37:06
;    fix for >255 open files (PNW Server)
;    ENDLOG

	eject ! include i:fdos.equ
	eject ! include i:msdos.equ
	eject ! include i:mserror.equ
	eject ! include i:doshndl.def	; DOS Handle Structures
	eject


BDOS_DATA	dseg	word

BDOS_CODE	cseg

	extrn	ifn2dhndl:near
	extrn	parse_one:near
	extrn	fdos_entry:near

	Public	fdos_exit

eject
;	TERMINATE CHILD (EXIT)

;	+----+----+
;	|    24   |
;	+----+----+

;	entry:
;	------
;	-none-

;	exit:
;	-----
;	-none-

; Close down all FCB handles associated with the current PSP
;
fdos_exit:
;---------
	push	ds
	push ss ! pop ds		; DS -> PCM_DSEG
	sub	ax,ax			; start with first DHNDL_
fdos_exit10:
	call	ifn2dhndl		; get DHNDL_
	 jc	fdos_exit40		; stop if we have run out
	mov	fcb_pb+2,ax		; we may close this IFN
	push	ax
	mov	cx,es:DHNDL_COUNT[bx]	; get the open count
	 jcxz	fdos_exit30		; skip if nothing to do
	mov	ax,current_psp		; get current PSP
	cmp	ax,es:DHNDL_PSP[bx]	; does it belong to this PSP
	 jne	fdos_exit30
	mov	ax,ss:machine_id	; get current process
    cmp ax,es:DHNDL_UID[bx] 
	 jne	fdos_exit30
	test	es:DHNDL_MODE[bx],DHM_FCB
	 jz	fdos_exit20		; skip close if not FCB
	push	es
	push	bx			; save the DHNDL
	mov	ax,MS_X_CLOSE
	call	fcb_fdos		; make the FDOS do the work
	pop	bx
	pop	es			; recover the DHNDL
fdos_exit20:
	mov	es:DHNDL_COUNT[bx],0	; always free the handle if it's ours
fdos_exit30:
	pop	ax
	inc	al			; onto next IFN
	 jnz	fdos_exit10
fdos_exit40:
	pop	ds
	ret





	Public	fdos_fcb
		
eject
;	GENERIC FCB FUNCTION (FCB)

;	+----+----+----+----+----+----+----+----+
;	|    22   |       fcbadr      |  count  |
;	+----+----+----+----+----+----+----+----+
;	|  func   |
;	+----+----+

;	entry:
;	------
;	fcbadr:	FCB address
;	count:	multi-sector count for read/write
;	func:	FCB sub-function

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

fdos_fcb:
;--------
	mov	bx,2[bp]		; BX -> parameter block
	mov	bx,8[bx]		; get subfunction code
	shl	bx,1			; make it word index
	sub	bl,15*WORD		; adjust to base address
	 jc	fcb_error		; reject if too low
	cmp	bl,FCB_MAX1		; is it in 1st block
	 jb	fdos_fcb10
	sub	bl,(33-24)*WORD		; adjust for gap
	 jc	fcb_error
	cmp	bl,FCB_MAX2		; is it in 2nd block
	 jb	fdos_fcb10
	sub	bl,(39-37)*WORD		; adjust for gap
	 jc	fcb_error
fdos_fcb10:
	cmp	bx,FCB_MAX3		; check the range
	 jae	fcb_error		; skip if invalid function
	jmp	fcb_table[bx]		; call the right function

fcb_error:
	mov	bx,ED_FUNCTION
	ret

fcb_table	dw	fcb_open	; 15-open file
		dw	fcb_close	; 16-close file
		dw	fcb_first	; 17-find first
		dw	fcb_next	; 18-find next
		dw	fcb_delete	; 19-delete file
		dw	fcb_read	; 20-read from file
		dw	fcb_write	; 21-write to file
		dw	fcb_make	; 22-make file
		dw	fcb_rename	; 23-rename file
FCB_MAX1	equ	(offset $ - offset fcb_table)
		dw	fcb_readrand	; 33-read from file
		dw	fcb_writerand	; 34-write to file
		dw	fcb_size	; 35-compute file size
		dw	fcb_setrecord	; 36-set relative record
FCB_MAX2	equ	(offset $ - offset fcb_table)
		dw	fcb_readblk	; 39-read from file
		dw	fcb_writeblk	; 40-write to file
FCB_MAX3	equ	(offset $ - offset fcb_table)

fcb_make:
;--------
	call	fcb_path_prep		; build pathname
	mov	ax,MS_X_CREAT
	jmps	fcb_open_make_common

fcb_open:
;--------
	call	fcb_path_prep		; build pathname
	mov	ax,MS_X_OPEN
fcb_open_make_common:
	mov	fcb_pb+6,DHM_RW+DHM_FCB	; open as an FCB for read/write
	call	fcb_fdos		; lets try and open the file
	 jnc	fcb_open10		; skip if we can't
	ret
fcb_open10:
	call	ifn2dhndl		; ES:BX -> DHNDL_ we have opened
	push	ds
	push es ! push bx		; save DHNDL_
	call	fcb_point		; ES:BX = FCB
	pop si ! pop ds			; DS:SI -> DHNDL_
	mov	es:MSF_IFN[bx],al	; store IFN away
	mov	es:MSF_BLOCK[bx],0	; current block number
	mov	es:MSF_RECSIZE[bx],128	; current logical record size
	call	fcb_update		; update misc changing fields
	mov	ax,ds:DHNDL_DEVOFF[si]
	mov	es:word ptr MSF_DEVPTR[bx],ax
	mov	ax,ds:DHNDL_DEVSEG[si]
	mov	es:word ptr MSF_DEVPTR+2[bx],ax
	mov	ax,ds:DHNDL_BLK1[si]
	mov	es:MSF_BLOCK1[bx],ax
	mov	al,ds:DHNDL_ATTR[si]
	mov	es:MSF_IOCTL[bx],al
	mov	al,es:MSF_DRIVE[bx]	; get drive from FCB
	dec	al			; was absolute drive specified ?
	 jns	fcb_open20		; if so use it
	mov	al,ss:current_dsk	; else use default drive
fcb_open20:
	inc	al			; make drive 1 rather than 0 based
	mov	es:MSF_DRIVE[bx],al	; drive code
if 0
	test	ds:DHNDL_DATRB[si],DA_VOLUME
else
	test	ss:fcb_pb+8,DA_VOLUME
endif
	pop	ds
	 jnz	fcb_close		; don't leave VOL label's open
	xor	bx,bx			; no errors !
	ret


fcb_update:
;----------
; On Entry:
;	DS:SI -> DHNDL_
;	ES:BX -> FCB
; On Exit:
;	DATE/TIME/SIZE/DBLK/DCNT fields updated
;
	mov	ax,ds:DHNDL_TIME[si]
	mov	es:MSF_TIME[bx],ax
	mov	ax,ds:DHNDL_DATE[si]
	mov	es:MSF_DATE[bx],ax
	mov	ax,ds:DHNDL_SIZELO[si]
	mov	es:MSF_SIZE[bx],ax
	mov	ax,ds:DHNDL_SIZEHI[si]
	mov	es:MSF_SIZE+2[bx],ax
	mov	ax,ds:DHNDL_DBLK[si]
	mov	es:MSF_DBLK[bx],ax
	mov	al,ds:DHNDL_DCNTLO[si]
	mov	ah,ds:DHNDL_DCNTHI[si]
	mov	es:MSF_DCNT[bx],ax
	ret

fcb_close:
;---------
; close file (DOS function 10h)
	call	fcb_point		; ES:BX -> FCB
	mov	al,0FFh
	cmp	al,es:MSF_IFN[bx]	; is it a multiple close ?
	 je	fcb_fdos_common10	;  don't re-open for this...
	call	fcb_handle_vfy		; verify we have a sensible handle
	mov	es:MSF_IFN[bx],al	; mark FCB as closed (it will be)
	mov	ax,MS_X_CLOSE		; now close it
;	jmps	fcb_fdos_common

fcb_fdos_common:
;---------------
	call	fcb_fdos		; make the FDOS do the work
	 jc	fcb_fdos_common20	; return any error codes
fcb_fdos_common10:
	xor	bx,bx			; else return zero
fcb_fdos_common20:
	ret



fcb_rename:
;----------
	call	fcb_path_prep
	call	fcb_path2_prep
	mov	ax,MS_X_RENAME		; it's a rename
	jmps	fcb_fdos_common

fcb_delete:
;----------
	call	fcb_path_prep
	mov	ax,MS_X_UNLINK		; it's a delete
	jmps	fcb_fdos_common


fcb_first:
;---------
	call	fcb_path_prep		; prepare pathname
	mov	ax,MS_X_FIRST		; we want to search 1st
	jmps	fcb_search_common

fcb_next:
;--------
	call	fcb_restore_search_state
	mov	ax,MS_X_NEXT
fcb_search_common:
	call	fcb_search		; 0 of OK, otherwise ED_..
	 jc	fcb_search_common10
	call	fcb_save_search_state	; save sucessful state
	xor	bx,bx			; return code in BX
fcb_search_common10:
	ret


fcb_setrecord:
;-------------
	call	fcb_point		; ES:BX -> FCB
	mov	ax,128			; multiply current block by 128
	mul	es:MSF_BLOCK[bx]	;  to give current record number
	xor	cx,cx
	mov	cl,es:MSF_CR[bx]	; Add in the current record
	add	ax,cx			;  to DX:AX to give the
	adc	dx,0			;  relative record
	mov	es:MSF_RR[bx],ax	; save the result
	mov	es:MSF_RR2[bx],dl
	xor	bx,bx			; we did OK
	ret

fcb_write:
;---------
	mov	ax,MS_X_WRITE		; make it a write
	jmps	fcb_seq_rw

fcb_read:
;--------
	mov	ax,MS_X_READ		; make it a read
fcb_seq_rw:
	call	fcb_handle_vfy		; verify we have a sensible handle
	push	ax			; save the operation
	call	fcb_get_count		; AX = bytes to read
	push	ax			; save byte count
	call	fcb_seek_seq		; Seek to position in the file
	pop	cx			; recover byte to xfer
	pop	ax			;  and the Operation Code
	 jc	fcb_seq_rw10
	call	fcb_rw			; do the Op
	 jc	fcb_seq_rw10
	push	bx			; save the error code
	call	fcb_update_seq		; update FCB filepos
	pop	bx			; recover error
fcb_seq_rw10:
	ret

fcb_rw:
; On Entry:
;	AX = operation code
;	CX = count
;	fcb_pb+2 = IFN
; On Exit:
;	BX = error code
	les	dx,ss:dword ptr dma_offset
	add	cx,dx			; see if we overflow
	 jc	fcb_rw20
	sub	cx,dx			; count back to normal
	push	cx			; save target count
	mov	fcb_pb+4,dx
	mov	fcb_pb+6,es		; setup buffer address
	mov	fcb_pb+8,cx		;  and target count
	call	fcb_fdos		; ask the FDOS to do the read/write
	 jc	fcb_rw10		; we got a real error...
	push	ds
	push	es
	mov	ax,fcb_pb+2		; get IFN
	call	ifn2dhndl		; ES:BX -> DHNDL_ we have open
	push es ! push bx		; save DHNDL_
	call	fcb_point		; ES:BX = FCB
	pop si ! pop ds			; DS:SI -> DHNDL_
	call	fcb_update		; update file size/time-stamp
	pop	es
	pop	ds
	pop	ax			; recover target count
	mov	cx,fcb_pb+8		; we xfered this much
	cmp	cx,ax			; did we xfer enough
	 jb	fcb_rw30		; nope..
	xor	bx,bx			; xfer went OK
	ret

fcb_rw10:
	pop	ax			; discard target count
	ret

fcb_rw20:
; Our DTA is too small - return 2
	mov	bx,2			; indicate the DTA is too small
;	stc				; error - don't update FCB
	ret

fcb_rw30:
; We have some form of EOF - lets look into it
	call	fcb_point		; ES:BX = FCB
	mov	bx,es:MSF_RECSIZE[bx]	; BX = record size
	mov	ax,cx
	xor	dx,dx			; DX:AX = bytes xfer'd
	div	bx			; did we xfer a complete
	test	dx,dx			;  number of records ?
	 jz	fcb_rw40		;  if so return 1
; Partial data was read - fill out with zero's and return 3
	inc	ax			; allow for incomplete record
	push	ax			; save rounded up xfer count
	les	di,ss:dword ptr dma_offset
	add	di,cx			; point to 1st byte after xfer
	mov	cx,bx			; this many in a record
	sub	cx,dx			; so this many weren't xfer'd
	xor	ax,ax			; fill them with zero's
	rep	stosb			; zap the bytes we didn't xfer to
	pop	ax			; recover xfer count
	mul	bx			;  and work out # bytes xfered
	xchg	ax,cx			; return bytes in CX
	mov	bx,3			; indicate EOF (partial read)
;	clc				; update FCB
	ret
		
fcb_rw40:
; No Data was xfered - return 1
	mov	bx,1			; indicate EOF (no data read)
;	clc				; update FCB
	ret

fcb_writerand:
;-------------
	mov	ax,MS_X_WRITE		; make it a write
	jmps	fcb_random_rw

fcb_readrand:
;------------
	mov	ax,MS_X_READ		; make it a read
fcb_random_rw:
	call	fcb_handle_vfy		; check the handle is OK
	push	ax			; save the code
	call	fcb_get_count		; AX = bytes to read
	push	ax			; save byte count
	xor	cx,cx			; cause update of seq posn from
	call	fcb_update_rr		;  random record position
	call	fcb_seek_rr		; Seek to position in the file
	pop	cx			; recover byte to xfer
	pop	ax			;  and the Operation Code
	 jc	fcb_random_rw10
	call	fcb_rw			; do the Op
fcb_random_rw10:
	ret
	
		
fcb_writeblk:
;------------
	mov	ax,MS_X_WRITE		; make it a write
	jmps	fcb_block_rw

fcb_readblk:
;-----------
	mov	ax,MS_X_READ		; make it a read
fcb_block_rw:
	call	fcb_handle_vfy		; check the handle is OK
	push	ax			; save the code
	call	fcb_get_count		; AX = bytes per record, CX = # records
	xchg	ax,cx			; CX = bytes per record
	mul	cx			; AX = bytes to xfer
	test	dx,dx			; more than 64K ?
	 jz	fcb_block_rw10		; then we should truncate it
	mov	ax,15			; AX = handy mask
	cwd				; DX = 0
	and	ax,ss:dma_offset	; get dma offset for para
	not	ax			; DX/AX = maximum bytes we can xfer
	div	cx			; AX = maximum blocks we can xfer
	mul	cx			; AX = bytes to xfer (now < 64K)
fcb_block_rw10:	
	push	ax			; save byte count
	call	fcb_seek_rr		; Seek to position in the file
	pop	cx			; recover byte to xfer
	pop	ax			;  and the Operation Code
	 jc	fcb_block_rw20
	call	fcb_rw			; do the Op
	 jc	fcb_block_rw20
	push	bx			; save the error code
	call	fcb_update_rr		; update FCB filepos, get records xferd
	mov	bx,2[bp]		; BX -> parameter block
	xchg	cx,6[bx]		; update amount xfered
	sub	cx,6[bx]		; CX = # we didn't xfer (normally 0)
	pop	bx			; recover (possible) error
	 jcxz	fcb_block_rw20		; skip if we read all we wanted to

⌨️ 快捷键说明

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