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

📄 disk.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 3 页
字号:
	mov	FD_PATHSEG,es
	xchg	ax,dx			; drive in AL
	cbw				; make that AX
	mov	FD_DRIVE,ax
	jmp	fdos_ax_crit		; return garbage in AH (SPJ bug)

;	*****************************
;	***    DOS Function 53    ***
;	***  Build DPB from BPB   ***
;	*****************************
;
;	This function takes the BPB at DS:SI and builds a DDSC at ES:BP
;	
	Public	func53
func53:
	call	set_retry_RF		; Valid to RETRY or FAIL
	mov	FD_BPBOFF,si		; Segment and Offset of BPB
	mov	FD_BPBSEG,es
	mov	FD_DDSCOFF,bp		; Segment and Offset of DDSC
	call	reload_ES
	mov	FD_DDSCSEG,es
	jmp	fdos_nocrit
;
;	*****************************
;	***    DOS Function 56    ***
;	***    Rename/Move a File ***
;	*****************************
;
	Public	func56
func56:
	call	set_retry_RF		; Valid to RETRY or FAIL
	mov	FD_NNAMEOFF,di		; New FileName
	push	es
	call	reload_ES		; callers ES:DI
	mov	FD_NNAMESEG,es		; point to new filename
	pop	es
	mov	FD_ONAMEOFF,dx		; Old FileName
	mov	FD_ONAMESEG,es
	cmp	ss:remote_call,0
	 jne	func56_10
	mov	cl,17h
func56_10:
	mov	FD_ATTRIB,cx
	jmp	fdos_crit

;	*****************************
;	***    DOS Function 57    ***
;	***   Get/Set File Time   ***
;	*****************************
;
	Public	func57
func57:
	call	set_retry_RF		; Valid to RETRY or FAIL
	mov	FD_DATE,dx
	mov	FD_TIME,cx
	mov	FD_SFLAG,ax
	cmp	al,1			; allow get/set only
	mov	ax,ED_FUNCTION		; all else fails horribly
	 ja	f57_error
	call	fdos_handle
	 jc	f57_error
    call    reload_registers  
	test	al,al
	 jnz	f57_exit
	mov	cx,FD_TIME
	call	return_CX		; return TIME in CX
	mov	dx,FD_DATE
	jmp	return_DX		; and DATE in DX

f57_exit:
	ret

f57_error:
	jmp	error_exit

;	*****************************
;	***    DOS Function 5A    ***
;	***   Create Unique File  ***
;	*****************************
;
	Public	func5A
func5A:
	mov	ax,ED_ACCESS		; assume we will have an error
	test	cx,DA_FIXED		;  because of silly attributes
	 jnz	func5A_40		; did we ?
	mov	si,dx			; find end of pathname
	xor	ax,ax			; no previous char
func5A_10:
	xchg	ax,bx			; BL = previous char
	lods	es:al			; get next char
	test	al,al			; is it the end of the string?
	 jz	func5A_20
	call	dbcs_lead		; is it a KANJI char?
	 jnz	func5A_10
	inc	si			; skip 2nd char of pair
	jmps	func5A_10
func5A_20:
	dec	si			; SI -> NUL
	cmp	bl,'\'			; was last char a '\' ?
	 je	func5A_30
	cmp	bl,'/'			; (or a '/' for unix freaks)
	 je	func5A_30
	mov	es:byte ptr [si],'\'	; append a '\' to name
	inc	si
func5A_30:
; Here ES:DX -> start of name, ES:SI -> position to append <unique name>,0
; CX = attribute for file.
; We generate a unique name based upon the time and date - if this already
; exists we keep retrying knowing the number of files is finite and we must
; succeed eventually
	push cx ! push dx ! push si	; append a unique'ish name
	call	func5A_append_unique_name
	pop si ! pop dx ! pop cx
	mov	ah,MS_X_MKNEW		; try to create unique file
	call	dos_entry
	 jnc	func5A_50		; exit if we succeeded
	mov	es:byte ptr [si],0	;  else forget extention
	cmp	ax,ED_EXISTS		; we only retry if it already exists 
	 je	func5A_30
func5A_40:
	jmp	error_exit		; return error to caller
func5A_50:
	jmp	return_AX_CLC		; return handle to caller

func5A_append_unique_name:
;-------------------------
; On Entry:
;	ES:DX -> start of name
;	ES:SI -> position to append <unique name>,0
;	CX = attribute for file.
; On Exit:
;	None
;
; We append a unique 8 character filename to this based upon the current
; date/time.
	push	si
	mov	ax,120dh
	int	2fh			; get date/time in AX & DX
	pop	di
	add	ax,unique_name_seed	; randomise the date otherwise we would
	inc	unique_name_seed	;  have one second wait between names
	call	func5A_app_AX		; store 4 ascii bytes
	xchg	ax,dx			; was DX = time
	call	func5A_app_AX		; store 4 ascii bytes
	xor	ax,ax
	stosb				; and a terminating NUL
	ret

func5A_app_AX:
; On Entry AX = word, ES:DI -> string
; Store 4 ASCII chars at ES:DI, based upon value in AX
	call	func5A_app_AL		; do low byte, falling thru to do high
func5A_app_AL:
	call	func5A_app_NIB		; low nibble, falling thru for high
func5A_app_NIB:
	push	ax
	and	al,0fh			; mask out a nibble
	add	al,'A'			; make it ASCII character
	stosb				; plant the string
	pop	ax
	mov	cl,4
	shr	ax,cl			; shift nibble
	ret


;	*****************************
;	***    DOS Function 60    ***
;	***Perform Name Processing***
;	*****************************
;
;	DS:SI point to a source string which contains a relative path
;	specification ES:DI points to a buffer which is at least 80
;	bytes longer than the source string.
;
;	The carry flag is set and AX contains an error code if the 
;	source string is mal formed. This function is used by the
;	Ryan-McFarland COBOL compiler.
;
	Public	func60
func60:
	call	set_retry_RF		; Valid to RETRY or FAIL
	mov	FD_FUNC,FD_EXPAND	; Expand a relative Path
	mov	FD_ONAMEOFF,si		; Initialise Source Pointer
	mov	FD_ONAMESEG,es
	mov	FD_NNAMEOFF,di		; Initialise Destination
	call	reload_ES		;  pointer
	mov	FD_NNAMESEG,es
	jmp	fdos_crit

;	*****************************
;	***    DOS Function 67    ***
;	***    Set/Handle Count   ***
;	*****************************
;
;	We impose a minimum of 20 handles regardless of what the caller
;	requests. If the request is <=20 we use the default handle table in
;	the PSP, else we allocate a memory block for the new table.
;	If the old handle table was in a memory block (ie. zero offset) we
;	will free that block up afterwards.
;	When shrinking the handle count the error ED_HANDLE will be given if
;	open files would have been lost.
;

	Public	func67
func67:
	push	ds
	mov	ds,current_psp		; DS -> current PSP blk
	cmp	bx,20			; force to minimum value of 20
	 jae	f67_10
	mov	bx,20			; never have less than 20 handles
f67_10:

	mov	cx,ds:PSP_XFNMAX	; we have this many handles
	sub	cx,bx			; are we growing ?
	 jbe	f67_20			; if shrinking make sure none open
	les	di,ds:PSP_XFTPTR	; point to existing handle table
	lea	di,[di+bx]		; point to 1st handle we will lose
	mov	al,0FFh			; they must all be closed
	repe	scasb			;  or we fail
	mov	ax,ED_HANDLE		; fail if we are in danger of losing
	 jne	f67_error		;  open handles
f67_20:
	
	push	bx			; save # of handles wanted
	push ds ! pop es
	mov	di,offset PSP_XFT	; ES:DI -> new handle table
	cmp	bx,20			;  if we are setting to the
	 je	f67_30			;   default size
	add	bx,15			; calculate memory required
	mov cl,4 ! shr bx,cl		; num of paragraphs required
	xor	di,di			;  offset will be zero
	mov	ah,MS_M_ALLOC		;  allocate the memory
	call	dos_entry
	mov	es,ax			; ES:DI -> new handle table
f67_30:
	pop	bx			; BX = # handles wanted
	 jc	f67_error		; ES:DI -> new handle table

	mov	cx,bx			; CX = new # handles
	xchg	cx,ds:PSP_XFNMAX	; Update the Handle Count	

	mov	si,di			; Update the Table Offset
	xchg	si,ds:PSP_XFTOFF
	mov	ax,es
	xchg	ax,ds:PSP_XFTSEG	; Update the Table Segment
	mov	ds,ax			; DS:SI -> old handle table
					; ES:DI -> new handle table
					; CX = # old handles to copy
					; BX = # new handles desired 

	sub	bx,cx			; BX = # extra "closed" handles
	 jae	f67_40			; negative if we are shrinking
	add	cx,bx			; CX = # handles we inherit
	xor	bx,bx			; BX = no extra "closed" handles
f67_40:

	push	si			; save offset old handle table
	rep	movsb			; Copy the existing Handles
	pop	si			; SI = offset old handle table

	mov	al,0FFh			; AL = unused handle
	mov	cx,bx			; mark extra handles as unused
	rep	stosb			; mark as unused

	test	si,si			; do we have memory to free ?
	 jnz	f67_50
	mov	ah,MS_M_FREE
	call	dos_entry		; free up old handle table DMD
f67_50:
	pop	ds
	jmp	return_AX_CLC		; clear carry on return

f67_error:
	pop	ds			; restore DS
	jmp	error_exit		;  and return error AX to caller

;	*****************************
;	***    DOS Function 68    ***
;	***      Commit File      ***
;	*****************************
;
	Public	func68
func68:
	call	set_retry_RF		; Valid to RETRY or FAIL
	mov	FD_FUNC,FD_COMMIT	; Close a File Handle
	jmp	fdos_handle


;	*****************************
;	***    DOS Function 6C    ***
;	***     Extended Open     ***
;	*****************************
;

	Public	func6C
func6C:
	mov	al,OK_RF		; Valid to RETRY or FAIL
	test	bh,20h			; should we allow critical errors ?
	 jz	f6C10
	or	al,NO_CRIT_ERRORS	; no, so remember that
f6C10:
	call	set_retry
	mov	ax,ED_FUNCTION		; assume an illegal action code
	test	dx,not 0113h		; now check for sensible bits
	 jnz	f6C_error
	inc	dx
	test	dl,4			; also reject bits 0-3 = 3
	 jnz	f6C_error
	dec	dx

	xchg	ax,si			; ES:AX -> name
	xchg	ax,dx			; AX = action, ES:DX -> name
	xchg	ax,bx			; AX = open mode, BX = action

	test	bl,010h			; should we create if not there ?
	 jz	f6C_open		; no, skip the attempt at make new

	and	ah,(DHM_COMMIT+DHM_NOCRIT)/100h
	mov	FD_FUNC,FD_NEW		; create only if not there
	call	funcExtendedOpenCreate	; try to open/create the file

	mov	cx,2			; CX = file created
	 jnc	f6C_exit		; return this if we succeeded

f6C_open:
	call	reload_registers	; all registers as per entry
	xchg	ax,si			; ES:AX -> name
	xchg	ax,dx			; AX = action, ES:DX -> name
	xchg	ax,bx			; AX = open mode, BX = action
	push	bx			; save action
	and	ah,(DHM_COMMIT+DHM_NOCRIT)/100h
	mov	FD_FUNC,MS_X_OPEN	; try an open an existing file
	call	funcExtendedOpenCreate
	pop	bx			; recover action
	 jc	f6C_error		; return error if we can't open file

	mov	cx,1			; CX = file opened
	test	bl,001h			; should we open if it exists ?
	 jnz	f6C_exit		; yes, return the handle

	xchg	ax,bx			; BX = handle, AX = action
	test	al,002h			; should we replace the file ?
	mov	ax,ED_EXISTS		; if not close and return error
	 jz	f6C_close_on_error
	mov	ah,MS_X_WRITE
	xor	cx,cx			; write zero bytes to truncate file
	call	dos_entry
	 jc	f6C_close_on_error	; on error AX = error code, return it
	xchg	ax,bx			; AX = handle
	mov	cx,3			; CX = file replaced
f6C_exit:
	jmp	return_CX		; return CX to caller

f6C_close_on_error:
; File exits, but open should be failed (error code in AX)
	push	ax
	mov	ah,MS_X_CLOSE
	call	dos_entry		; close that file
	pop	ax
f6C_error:
	jmp	error_exit		; generate critical error


PCMODE_DATA	DSEG	WORD
	extrn	current_psp:word
	extrn	current_dsk:byte
	extrn	dma_offset:word
	extrn	dma_segment:word
	extrn	int21regs_ptr:dword
	extrn	last_drv:byte
	extrn	remote_call:word
if DELWATCH
	extrn	fdos_stub:dword
endif

GLOBAL_DATA	dseg	word
; When creating unique files we use the date/time to make the name.
; We add this seed value to "randomise" things, INCing on failure so the next
; attempt usually succeeds.

unique_name_seed	dw	0	; so we don't have to wait 1 second

end

⌨️ 快捷键说明

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