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

📄 fcbs.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 2 页
字号:
	test	bx,bx			; did we have a partial read for
	 jnz	fcb_block_rw20		;  a reason like EOF ?
	mov	bx,2			; no, we must have truncated it
fcb_block_rw20:
	ret
	
		
fcb_size:
;--------
	call	fcb_path_prep
	mov	ax,MS_X_CHMOD		; it's a get info
	mov	fcb_pb+6,0
	call	fcb_fdos
	 jc	fcb_size40
	call	fcb_point		; ES:BX = FCB
	mov	cx,es:MSF_RECSIZE[bx]	; get the record size
	test	cx,cx			; is it non-zero ?
	 jnz	fcb_size10		;  if not
	mov	cx,128			;  make it 128 bytes
fcb_size10:
	mov	ax,fcb_pb+10
	mov	dx,fcb_pb+12		; DX:AX = file length in bytes
	call	div_32			; DX:AX = file length in records
	 jcxz	fcb_size20		; was there an overflow
	add	ax,1
	adc	dx,0			; include an extra record
fcb_size20:
	call	fcb_point		; ES:BX = FCB
	mov	es:MSF_RR[bx],ax	; low word of size
	mov	es:MSF_RR2[bx],dl	; hi byte of size
	cmp	es:MSF_RECSIZE[bx],64	; if record size < 64 bytes
	 jae	fcb_size30		;  then we use a 4 byte
	mov	es:MSF_RR2+1[bx],dh	;  random record position
fcb_size30:
	xor	bx,bx			; good return
fcb_size40:
	ret


; Utility FCB subroutines
;========================

fcb_handle_vfy:
;--------------
; Verify FCB is valid and open, do not return if it isn't
; nb. Called with nothing on stack
;
; On Entry:
;	FCB address in parameter block
; On Exit:
;	AX preserved
;	ES:BX -> FCB (skipping EXT bit if present)
;	fcb_pb+2 = IFN of handle
;	On Error - blow away caller and return error in BX
;

; DEBUG - on reopen we could do more checks to ensure we are re-opening the
; same file
	push	ax
	call	fcb_point
	cmp	es:MSF_RECSIZE[bx],0
	 jne	fcb_handle_vfy10
	mov	es:MSF_RECSIZE[bx],128
fcb_handle_vfy10:
	mov	al,es:MSF_IFN[bx]	; get IFN
	call	ifn2dhndl		; ES:BX -> DHNDL_
	 jc	fcb_handle_vfy20	; it must be a valid IFN
	test	es:DHNDL_MODE[bx],DHM_FCB
	 jz	fcb_handle_vfy20	; it must be an FCB..
	cmp	es:DHNDL_COUNT[bx],0
	 jne	fcb_handle_vfy30	; it must also be open..
fcb_handle_vfy20:
	call	fcb_point
	push	es:MSF_RECSIZE[bx]	; save current record size
	push	es:MSF_BLOCK[bx]	; save current block number
	push es ! push bx
	call	fcb_open		; try to re-open the file
	pop bx ! pop es			; point back at FCB
	pop	es:MSF_BLOCK[bx]	; restore current block number
	pop	es:MSF_RECSIZE[bx]	; restore record size
	 jc	fcb_handle_err
	mov	al,es:MSF_IFN[bx]	; get new IFN
fcb_handle_vfy30:
	xor	ah,ah
	mov	fcb_pb+2,ax		; set parameter block accordingly
	call	fcb_point		; ES:BX -> MSF_
	pop	ax
	clc
	ret

fcb_handle_err:
	add	sp,2*WORD		; discard AX and near return address
	cmp	ax,ED_HANDLE		; if we have run out of handles then
	 jne	fcb_handle_err10	;  say no FCB's, else return error
	mov	ax,ED_NOFCBS
fcb_handle_err10:
	xchg	ax,bx			; error code in BX
	stc
	ret


fcb_path2_prep:
;--------------
; On Entry:
;	FCB address in parameter block
; On Exit:
;	ES:BX -> FCB (skipping EXT bit if present)
;	fcb_pb+6/8 -> unparse name from FCB
;
	call	fcb_point		; point at the FCB
	mov	al,es:MSF_DRIVE[bx]	; get drive
	add	bx,16			; point at 2nd name in FCB
	mov	di,offset fcb_path2
	mov	fcb_pb+6,di
	mov	fcb_pb+8,ds		; point at buffer we want
	jmps	fcb_path_prep_common

fcb_path_prep:
;-------------
; On Entry:
;	FCB address in parameter block
; On Exit:
;	ES:BX -> FCB (skipping EXT bit if present)
;	fcb_pb+2/4 -> unparse name from FCB
;
	xor	ax,ax			; assume no attribute
	mov	bx,2[bp]		; BX -> parameter block
	les	bx,2[bx]		; ES:BX -> FCB
	cmp	es:MSF_EXTFLG[bx],0ffh	; is it an extended FCB
	 jne	fcb_path_prep10
	or	al,es:MSF_ATTRIB[bx]	; we can use file mode from XFCB
	add	bx,7			; skip EXT bit of FCB
fcb_path_prep10:
	mov	fcb_pb+8,ax		; remember the attribute
	mov	al,es:MSF_DRIVE[bx]	; get drive
	mov	di,offset fcb_path
	mov	fcb_pb+2,di
	mov	fcb_pb+4,ds		; point at buffer we want
fcb_path_prep_common:
	dec	al			; 0 = default drive
	 jns	fcb_path_prep20
	mov	al,current_dsk		; use default drive
fcb_path_prep20:
	push	ds
	push ds ! push es
	pop ds ! pop es			; ES:DI -> name buffer
	add	al,'A'			; make drive ASCII
	stosb
	mov	al,':'
	stosb				; now we have 'd:'
	lea	si,MSF_NAME[bx]		; DS:SI -> source name
	movsw ! movsw
	movsw ! movsw			; copy the name leaving spaces intact
	mov	al,'.'
	stosb
	movsw ! movsb			; copy the extention
	pop	ds
;	jmps	fcb_point		; point ES:BX at FCB again


fcb_point:
;---------
; On Entry:
;	FCB address in parameter block
; On Exit:
;	ES:BX -> FCB (skipping EXT bit if present)
;	(All other regs preserved)
;
	mov	bx,2[bp]		; BX -> parameter block
	les	bx,2[bx]		; ES:BX -> FCB
	cmp	es:MSF_EXTFLG[bx],0ffh	; is it an extended FCB
	 jne	fcb_point10
	add	bx,7			; skip EXT bit of FCB
fcb_point10:
	ret

fcb_get_count:
;-------------
; On Entry:
;	none
; On Exit:
;	AX = bytes per record
;	CX = callers CX count
;	All regs fair game
;
	call	fcb_point		; ES:BX -> FCB
	mov	si,2[bp]		; SI -> parameter block
	mov	cx,6[si]		; CX = count
	mov	ax,es:MSF_RECSIZE[bx]	; get record size
	ret

fcb_update_seq:
;--------------
; On Entry:
;	CX = byte count actually transferred
; On Exit:
;	CX = record count transferred
;	All other regs fair game
;	CR/BLOCK updated with new value
;
	mov	ax,cx
	xor	dx,dx			; DX:AX = byte count transfered
	call	fcb_point		; ES:BX -> FCB
	div	es:MSF_RECSIZE[bx]	; make records xfered
	push	ax			; save records xfered
	xchg	ax,cx			; also in CX for later
	mov	ax,128
	mul	es:MSF_BLOCK[bx]	; DX:AX = record of block
	add	ax,cx
	adc	dx,0			; add in amount just xfered
	mov	cl,es:MSF_CR[bx]
	xor	ch,ch			; now add in CR as a word
	add	ax,cx
	adc	dx,0			; DX:AX = record
	mov	dh,dl			; DH:AX = record for common code
	jmps	fcb_update_common


fcb_update_rr:
;-------------
; On Entry:
;	CX = byte count actually transferred
; On Exit:
;	CX = record count transferred
;	All other regs fair game
;	Random Record and CR/BLOCK updated with new value
;
	xchg	ax,cx
	xor	dx,dx			; DX:AX = byte count transfered
	call	fcb_point		; ES:BX -> FCB
	div	es:MSF_RECSIZE[bx]	; make records xfered
	push	ax			; save records xfered
	add	es:MSF_RR[bx],ax	; update the RR field
	adc	es:MSF_RR2[bx],0	;  and the overflow
	mov	ax,es:MSF_RR[bx]	; get low part of RR
	mov	dh,es:MSF_RR2[bx]	;  and the hi part
fcb_update_common:
	mov	dl,ah			; DX will be block number
	shl	al,1			; get top bit of CR into CY
	adc	dx,dx			; then into DX
	shr	al,1			; AL = CR (remember mod 128)
	mov	es:MSF_CR[bx],al	; set the CR field
	mov	es:MSF_BLOCK[bx],dx	;  and the block field
	pop	cx			; recover records xfered
	ret


fcb_seek_seq:
;------------
; Seek to position in file indicated by the RR position
; On Entry:
;	ES:BX -> FCB_
; On Exit:
;	CY clear if no problem, fcb_pb+2=IFN
;	else
;	CY set, AX = BX = error code
;	All other regs fair game
;
	call	fcb_point		; ES:BX -> FCB_
	mov	ax,128
	mul	es:MSF_BLOCK[bx]	; get record in DX:AX
	mov	cl,es:MSF_CR[bx]
	xor	ch,ch
	add	ax,cx			; add in CR
	adc	dx,0			; so DX:AX is really the record
	push	ax			; save low word of record
	mov	ax,dx
	mul	es:MSF_RECSIZE[bx]	; DX:AX = byte offset in file/10000h
	mov	cx,ax			; save the important word
	pop	ax			; recover low word of record
	jmps	fcb_seek_common

fcb_seek_rr:
;-----------
; Seek to position in file indicated by the RR position
; On Entry:
;	ES:BX -> FCB_
; On Exit:
;	CY clear if no problem, fcb_pb+2=IFN
;	else
;	CY set, AX = BX = error code
;	All other regs fair game
;
	call	fcb_point		; ES:BX -> FCB_
	mov	al,es:MSF_RR2[bx]
	xor	ah,ah
	mul	es:MSF_RECSIZE[bx]	; DX:AX = byte offset in file/10000h
	mov	cx,ax			; save the important word
	mov	ax,es:MSF_RR[bx]
fcb_seek_common:
	mul	es:MSF_RECSIZE[bx]	; DX:AX = byte offset in file
	add	dx,cx			; add the two bits together
	mov	fcb_pb+4,ax
	mov	fcb_pb+6,dx		; save position
	mov	fcb_pb+8,0		; seek from start
	xor	ax,ax
	mov	al,es:MSF_IFN[bx]	; AX = IFN
	mov	fcb_pb+2,ax		; save IFN
	mov	ax,MS_X_LSEEK
	jmp	fcb_fdos		; try and seek to this position


fcb_search:
;----------
; On Entry:
;	AX = operation to perform
; On Exit:
;	AX = 0, or ED_ error code (CY set if error)
	push	dma_offset
	push	dma_segment
	mov	dma_offset,offset fcb_search_buf
	mov	dma_segment,ds
	call	fcb_fdos			; do the search
	pop	dma_segment
	pop	dma_offset
	test	ax,ax				; was there an error
	stc					; assume there was
	 js	fcb_search10			; return the error
	xor	ax,ax				; no problems
fcb_search10:
	ret

fcb_save_search_state:
;---------------------
; On entry DS=PCMODE
	
	call	fcb_point
	lea	di,MSF_NAME[bx]		; ES:DI -> FCB name
	mov	si,offset fcb_search_buf
	lodsb				; get 1st byte = drive info
	mov	cx,20/WORD		; copy 20 bytes to FCB
	rep	movsw			; (the rest of the search template)
	stosb				; drive info byte follow them
	
	les	di,dword ptr dma_offset	; ES:DI -> search state in DMA address
	mov	si,2[bp]		; SI -> parameter block
	lds	si,2[si]		; DS:SI -> FCB_
	cmp	ds:MSF_EXTFLG[si],0ffh	; extended FCB ?
	 jne	fcb_sss10
	mov	cx,7			; copy extended FCB portions too
	rep	movsb			; we have copied up to name
fcb_sss10:
	stosb				; save drive byte info
	push	di
	mov	al,' '			; space fill name
	mov	cx,11
	rep	stosb			; all blanks now
	pop	di
	push ss ! pop ds		; DS:SI -> pathname
	mov	si,offset fcb_search_buf+1Eh

	push	di			; unparse knowing name is good
	mov	cx,8			; length of name field
fcb_sss20:		 
	lodsb				; treat '.' and '..' specially
	cmp	al,'.'			; is either possible ?
	 jne	fcb_sss30		; no, continue as normal
	stosb				; copy the '.'
	loop	fcb_sss20		; go around for another '.'
	jmps	fcb_sss40		; this name is rubbish!!
fcb_sss30:
	dec	si			; forget the non '.'
	call	parse_one		; parse just the name
fcb_sss40:
	pop	di
	add	di,8			; di -> fcb ext field
	cmp	al,'.'			; do we have an extention ?
	 jne	fcb_sss50
	mov	cx,3			; length of ext field
	push	di
	call	parse_one		; parse just extension
	pop	di
fcb_sss50:
	add	di,3			; di -> rest of fcb
	mov	si,offset fcb_search_buf+15h
	movsb				; copy the attribute field
	xor	ax,ax
	mov	cx,10/WORD
	rep	stosw			; 10 bytes of zeros
	movsw				; copy time
	movsw				; copy date
	mov	ax,word ptr srch_buf+21+DBLOCK1
	stosw				; 1st block
	movsw ! movsw			; copy filesize
	ret

fcb_restore_search_state:
;------------------------
; On entry DS=PCMODE
	push	ds
	call	fcb_point		; ES:BX -> FCB_
	push es ! push ds
	pop es ! pop ds			; swap DS/ES
	mov	di,offset fcb_search_buf+1
					; ES:DI -> internal state
	lea	si,1[bx]		; DS:SI -> FCB+1
	mov	cx,10
	rep	movsw			; copy info from FCB
	lodsb				; get "drive" info
	mov	es:fcb_search_buf,al	; it's the 1st byte in the srch state
	pop	ds
	ret

fcb_fdos:
;--------
; Make an FDOS call (NB. We don't have MX here, so it's OK)
; Set top bit of remote_call flag so we use IFN's not XFN's
; On Entry:
;	AX = FDOS operation
;	fcb_pb -> FDOS parameter block
; On Exit:
;	As FDOS call
;
	mov	fcb_pb,ax		; save operation type
	or	remote_call,DHM_FCB	; forget about PSP during FCB call
	mov	dx,offset fcb_pb	; DS:DX -> parameter block
	push	ds
	push	bp
	call	fdos_entry		; call the FDOS
	pop	bp
	pop	ds
	and	remote_call,not DHM_FCB	; FCB operation over
	cmp	ax,ED_LASTERROR
	cmc				; CY set if an error occurred
	ret

div_32:
;	Entry:	DX,AX = long dividend
;		CX = word divisor
;	Exit:	DX,AX = long result
;		CX = remainder

	jcxz	div0			; divide by 0
	cmp	cx,1
	 je	div1			; divide by 1
	push	di
	push	bx
	xor	bx,bx			; BX = 0
	xchg	ax,bx			; low word in BX, AX = 0
	xchg	ax,dx			; high word in DX:AX
	push	ax			; save high word
	div	cx			; divide high part
	mov	di,ax			; save result
	mul	cx			; AX = even divisor part
	pop	dx			; old high in DX
	sub	dx,ax			; eliminate even part
	xchg	ax,bx			; AX = low word
	div	cx			; low part in AX
	mov	cx,dx			; CX = remainder
	mov	dx,di			; high result in DX
	pop	bx
	pop	di
	ret

div0:
	mov	ax,-1
	mov	dx,ax
	ret
div1:
	dec	cx			; CX = remainder = 0
	ret


PCMODE_DATA	DSEG	WORD

extrn	fcb_pb:word
extrn	fcb_path:byte
extrn	fcb_path2:byte
extrn	fcb_search_buf:byte

extrn	current_dsk:byte
extrn	current_psp:word
extrn	dma_offset:word
extrn	dma_segment:word
extrn	machine_id:word
extrn	remote_call:word
extrn	srch_buf:byte

end

⌨️ 快捷键说明

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