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

📄 dosif.asm

📁 一个dos操作系统DRDOS的源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;	BYTE		Month
;	BYTE		Day
;	BYTE		Day of the Week (Ignored on SET DATE)

	Public	_ms_getdate
;-----------
_ms_getdate:
;-----------
	push	bp
	mov	bp,sp
	mov	dx,04[bp]		; Get the structure address
	mov	cl,T_GETDATE		; and call the BDOS
	call	bdos_entry
	pop	bp
	CRET	2

	Public	_ms_setdate
;----------
_ms_setdate:
;----------
	push	bp
	mov	bp,sp
	mov	dx,4[bp]		; and get the structure address
	mov	cl,T_SETDATE		; and call the BDOS to do the work
	call	bdos_entry		; Return 0 Good and FFFF Bad
	pop	bp
	CRET	2


;	Time information is passed and return in a structure which 
;	has the following format.
;
;	BYTE		Hours (0 - 23)
;	BYTE		Minutes (0 - 59)
;	BYTE		Seconds (0 - 59)
;	BYTE		Hundredths of a second (0 - 99)

	Public	_ms_gettime
;----------
_ms_gettime:
;----------
	push	bp
	mov	bp,sp
	mov	dx,04[bp]		; Get the Time Structure address
	mov	cl,T_GETTIME		; and call the OS
	call	bdos_entry
	pop	bp
	CRET	2

	Public _ms_settime
;----------
_ms_settime:
;----------
	push	bp
	mov	bp,sp
	mov	dx,4[bp]		; and get the structure address
	mov	cl,T_SETTIME		; and call the BDOS SET Time Function
	call	bdos_entry		; Return 0 Good and FFFF Bad
	pop	bp
	CRET	2

	Public	_ms_f_verify
;-----------
_ms_f_verify:
;-----------
	push	bp
	mov	bp,sp
	push	es
	mov	ax,04[bp]			; Get the required state
	les	bx,_pd				; Update the Verify flag in
	and	es:P_SFLAG[bx],not PSF_VERIFY	; current PD
	or	ax,ax				; Set the Flag
	jz	ms_fv10				; No
	or	es:P_SFLAG[bx],PSF_VERIFY	; Flag set in PD
ms_fv10:
	pop	es
	pop	bp
	ret

	Public	_ms_f_getverify
;--------------
_ms_f_getverify:
;--------------
	push	es
	xor	ax,ax				; Assume the flag is RESET
	les	bx,_pd				; now test the state of the
	test	es:P_SFLAG[bx],PSF_VERIFY	; flag in the current PD
	jz	ms_fgv10			; Verify = OFF
	inc	ax				; Verify = ON
ms_fgv10:
	pop	es
	ret

;
;	mem_alloc(BYTE FAR * NEAR * bufaddr, UWORD * bufsize, UWORD min, UWORD max);
;
;	max		10[bp]
;	min		08[bp]
;	bufsize		06[bp]
;	buffadr 	04[bp]
;
	Public _mem_alloc
;---------
_mem_alloc:
;---------
	push	bp
	mov	bp,sp

	mov	mpb_start,0
	mov	ax,08[bp]		; Get the Minimum and Maximum values
	mov	mpb_min,ax		; and fill in the parameter block
	mov	ax,10[bp]
	mov	mpb_max,ax
	mov	mpb_pdadr,0
	mov	mpb_flags,0
	
	mov	cx,M_ALLOC		; Call the Concurrent Allocate function
	mov	dx,dataOFFSET mpb_start	; 
	call	bdos_entry
	xor	cx,cx			; Assume that the function fails
	mov	dx,cx			; and zero the start and size fields
	cmp	ax,0
	jnz	mem_all10
	mov	cx,mpb_min		; Get the Allocation Size
	mov	dx,mpb_start		; and the starting segment

mem_all10:
	mov	bx,04[bp]		; Update the Buffer Address
	mov	word ptr 00[bx],0	; Offset 0
	mov	word ptr 02[bx],dx	; Segment DX
	mov	bx,06[bp]		; Now Update the Buffer Size
	mov	word ptr 00[bx],cx	; and return to the caller
	pop	bp
	ret
;
;	mem_free(BYTE FAR * NEAR * bufaddr);
;
;	buffadr 	04[bp]
;
	Public _mem_free
;---------
_mem_free:
;---------
	push	bp
	mov	bp,sp
	xor	ax,ax
	mov	bx,04[bp]		; Get the Buffer Pointer address
	xchg	ax,word ptr 02[bx]	; and from this the segment of the
	cmp	ax,0			; allocated memory. If the memory
	jz	mem_free10		; has already been freed the quit
	mov	mfpb_start,ax		; Otherwise Free the Memory
	mov	mfpb_res,0
	mov	cx,M_FREE
	mov	dx,dataOFFSET mfpb_start
	call	bdos_entry

mem_free10:
	pop	bp
	ret
;
;	findfile(BYTE *loadpath, UWORD *loadtype)
; 
	Public	_findfile
_findfile:
	push	bp
	mov	bp,sp
	mov	al,OK_RF		; Retry, Ignore or Fail
	call	fdos_retry
	mov	ax,word ptr 04[bp]
	mov	exec_pathoff,ax
	mov	exec_pathseg,ds
	mov	cx,P_PATH
	mov	dx,dataOFFSET exec_block
	call	ppath_entry
	or	ax,ax
	jnz	ff_error
	mov	al,exec_filetype
	cbw
	mov	bx,word ptr 06[bp]
	mov	word ptr [bx],ax
	xor	ax,ax
ff_error:	
	pop	bp
	ret

;
fdos_retry:
	xor	ah,ah
	mov	valid,ax		; Save the Valid Error responses
	pop	retry_ip		; Get the return Address
	mov	retry_sp,sp		; and Stack Pointer
	jmp	retry_ip
;
;	FDOS_ENTRY is an internal function entry point which makes the
;	F_DOS function call. As the F_DOS data area used by COMMAND.COM 
;	is always FDOS_DATA.
;
;	WORD PASCAL critical_error(error, valid, drive, mode, server);
;
;	critical_error will return an WORD response which (R,I,A,F)
;	after displaying the appropriate error message and get the
;	correct response from the user.
;
fdos_entry:
	mov	cl,F_DOS
	mov	dx,dataOFFSET fdos_data
ppath_entry:
	call	bdos_entry
	cmp	ax,ED_LASTERROR		; Did an Error Occur
	jb	fdos_exit		; No So Exit OK
	cmp	crit_flg,TRUE		; Already in handler
	jz	fdos_exit		; Yes Skip Critical Error
	cmp	ax,ED_PROTECT		; Is this a Physical Error
	jg	fdos_exit		; if so then simulate a 
	cmp	ax,ED_GENFAIL		; Critical Error by calling
	jge	fdos_e05		; the COMMAND routine Critical
					; error
	cmp	ax,ED_NETPWD		; Now check for DR-NET errors
	jg	fdos_exit		; if so then simulate a 
	cmp	ax,ED_NETLOG		; Critical Error by calling
	jge	fdos_e05		; the COMMAND routine Critical
					; error
fdos_exit:
	ret

fdos_e05:
	push	retry_ip		; Save Retry IP and SP and valid
	push	retry_sp		; responses
	push	valid
	mov	crit_flg,TRUE		; Start Critical Section
	mov	cx,es			; Save the Segment Regsiter
 	push	ax 			; Save the Error Code
	push	valid			; Save the Valid Responses (R,I,F)
	les	bx,_pd			; Get the PD address
	mov	es,es:P_UDA[bx]		; and then the UDA address
	xor	ah,ah			; Zero the top byte of AX and
	mov	al,es:byte ptr 15h ;;U_ERR_DRV		; Get the Failing Drive
	push	ax			; Save on the Stack
	mov	al,es:byte ptr 14h ;;U_ERR_RW		; Get the Error Mode
	push	ax			; and Save

	mov	ax,00FFH		; Default Server NO is (INVALID)
	les	bx,_pd			; Get the PD address Again
	mov	bx,es:P_NDA[bx]		; and then the NDA address
	cmp	bx,0			; Are we attached to DR-NET
	jz	fdos_e08		; NO
	mov	es,bx			; ES -> DR-Net NDA
	mov	al,es:byte ptr 0Ch 	;; NDA_CXRTN

fdos_e08:	
	push	ax			; Pass the DR-NET Server No.
	mov	es,cx			; Restore ES
	call	CRITICAL_ERR		; Handle the Critical Error. Parameters
					; are removed by the CALLEE
	mov	crit_flg,FALSE		; Critical Section complete
	pop	valid			; Restore our original RETRY IP
	pop	retry_sp		; and SP values which have been
	pop	retry_ip		; corrupted by the "CRITICAL_ERROR"
					; routine during message printing
	cmp	ax,0			; Ignore the Error
	jz	fdos_exit		; Then Exit with no Error

	cmp	ax,1			; Retry the Operation
	jnz	fdos_e10		; using information saved by FDOS_RETRY
	mov	sp,retry_sp		; Reset the Stack Pointer
	jmp	retry_ip		; and retry the Operation

fdos_e10:
	cmp	ax,3			; FAIL this function
	mov	ax,ED_FAIL		; Fail the function
	jz	fdos_exit		; Yes otherwise ABORT

	call	_int_break		; Simulate a Control C to terminate
					; We are never coming back
;
;	BDOS_ENTRY is the usual method of calling the Operating System.
;	In order to provide a DOS compatible environment this function.
;	does Control-C checking on function exit.
; 
bdos_entry:
	int	BDOS_INT
	push	es
	les	bx,_pd			; Get our process descriptor address
	test	es:P_SFLAG[bx],PSF_CTLC	; Check if a Control-C has been typed
	jnz	bdos_e10		; Jump to Abort Handler
	mov	bx,ax			; Restore BX and Return.
	pop	es
	ret

bdos_e10:
	and	es:P_SFLAG[bx],not PSF_CTLC
	pop	es
bdos_e20:
	mov	cl,C_RAWIO		; Flush the Character buffer until
	mov	dl,0FFh			; Return the character or 00 if queue
	int	BDOS_INT		; is empty. Repeat till the Keyboard
	or 	al,al			; Buffer has been flushed
	jnz	bdos_e20
	push	ds
	push	cs
	pop	ds
	mov	cl,C_WRITESTR
	mov	dx,offset break_str	; echo ^C to screen
	int	BDOS_INT
	pop	ds
	call	_int_break		; Place the Control Break Code on the 
					; Stack and the call the error handler
					; ** We will never return **

break_str	db	'^C$'

endif

ifndef DOSPLUS
	Public	__BDOS
;-------
__BDOS:
;-------
	push	bp
	mov	bp,sp
	push	si
	push	di
	mov	cl,4[bp]
	mov	dx,6[bp]
	int	BDOS_INT
	pop	di
	pop	si
	pop	bp
	ret
;
endif

ifdef DOSPLUS
ifndef EXT_SUBST
	Public	_physical_drvs		; Physical Drives returns a LONG
_physical_drvs:				; Vector with bits set for every drive
	mov	ax,0			; start with drive A:
	mov	cx,16			; check the first 16 drives
	mov	bx,0
p_d10:
	push	ax			; pass drive no. to _physical_drive
	call	_physical_drive		; call it
	cmp	ax,0			; check return value 
	pop	ax			; restore ax
	jz	p_d20			; if zero skip setting the bit in 
	or	bx,1			; the bitmap
p_d20:
	ror	bx,1			; shift bitmap right
	inc	ax			; next drive
	loop	p_d10			; Loop 16 Times
	mov	cx,10			; Finally check the last 10 drives
	mov	dx,0
p_d30:
	push	ax			; pass drive no. to _physical_drive
	call	_physical_drive		; call it
	cmp	ax,0			; check return val
	pop	ax			; restore ax
	jz	p_d40			; id zero skip setting the bit in 
	or	dx,1			; the bitmap
p_d40:
	ror	dx,1			; shift bitmap right
	inc	ax			; next drive
	loop	p_d30			; Loop 10 Times
	
	mov	cl,6			; Now rotate the contents of 
	ror	dx,cl			; DX 6 more times for correct
					; alignment of the Physical Drive Vector
	mov	ax,bx
	mov	bx,dx			; Return the long value in both
					; AX:BX and AX:DX
	ret

	Public	_logical_drvs		; Logical Drives returns a LONG
_logical_drvs:				; vector with bits set for every

	mov	cx,16			; check the first 16 drives
	mov	ax,0			; start with drive A:
	mov	bx,ax	

l_d10:
	push	ax			; pass the drive to _logical_drive
	call	_logical_drive		; call it
	cmp	ax,0			; check return value
	pop	ax			; restore ax
	jz	l_d20			; skip if zero return
	or	bx,1			; set bit in bitmap
l_d20:
	ror	bx,1			; shift bitmap right
	inc	ax			; next drive
	loop	l_d10			; Loop 16 Times

	mov	cx,10			; Finally check the last 10 drives
	mov	dx,0
l_d30:
	push	ax			; pass the drive to _logical_drive
	call	_logical_drive		; call it
	cmp	ax,0			; check return value
	pop	ax			; restore ax
	jz	l_d40			; skip if zero return
	or	dx,1			; set bit in bitmap
l_d40:
	ror	dx,1			; shift bitmap right
	inc	ax			; next drive
	loop	l_d30			; Loop 10 Times

	mov	cl,6			; Now rotate the contents of 
	ror	dx,cl			; DX 6 more times for correct
					; alignment of bits
	mov	ax,bx
	mov	bx,dx			; Return the long value in both
	ret				; AX:BX and AX:DX

	Public	_network_drvs		; Network Drives returns a LONG
_network_drvs:				; vector with bits set for every drive
	xor	ax,ax			; Start with BX:AX as
	mov	bx,ax			; zeros.
	mov	cx,'Z'-'A'		; We look at drives A-Z
n_d10:
	add	ax,ax			; we move the dword vector
	adc	bx,bx			;  one place left
	push	ax
	push	bx			; save the vector
	mov	ah,MS_X_IOCTL
	mov	al,9			; is device local ?
	mov	bl,cl			; drive number in BL
	int	DOS_INT
	pop	bx
	pop	ax			; recover the vector
	 jc	n_d20			; if an error skip network bit
	test	dx,1000h		; is device local ?
	 jz	n_d20			; if not then
	or	ax,1			;  set bit for this drive
n_d20:
	loop	n_d10
	mov	dx,bx			; long value in both AX:BX and AX:DX
	ret
	public	_physical_drive
_physical_drive	PROC NEAR

;	BOOLEAN	physical_drive(WORD);
;	returns true if given drive (0-25) is physical.
;
	push	bp
	mov	bp,sp
	push	ds
	push	es
	push	si
	push	di
	push	dx
	push	cx
	push	bx
	
	mov	bx,4[bp]	; get the drive number
	inc	bx		; A=1, B=2, etc
	mov	ax,4409h	; IOCTL Network/Local
	int	21h		; do it
	jc	not_phys	; carry means invalid drive
	and	dx,1000h	;
	cmp	dx,0
	jne	not_phys	; its a network drive

	mov	ax,cs
	mov	ds,ax
	mov	es,ax
	mov	si,offset func60_in
	mov	di,offset func60_out
	mov	ax,4[bp]	; insert drive letter in input string
	add	al,'A'
	mov	[si],al		;
	mov	ah,60h		; Expand Path string
	int	21h		; do it
	jc	not_phys	; carry set means invalid drive
	
	mov	ax,4[bp]	; if drive letter changes then drive is
	add	al,'A'		; substed
	cmp	al,cs:[func60_out]
	jne	not_phys	

	mov	ax,-1
	jmp 	phys_exit
not_phys:
	mov	ax,0
phys_exit:
	pop	bx
	pop	cx
	pop	dx
	pop	di
	pop	si
	pop	es
	pop	ds
	pop	bp
	ret 

func60_in	db "d:con",0
func60_out	db 0,0,0,0,0,0,0,0,0,0

_physical_drive	ENDP

;
;	This function translates a logical to physical drive.
;
	Public	_pdrive
;------
_pdrive:
;------
	push	bp
	mov	bp,sp
	push	ds
	push	es
	push	si
	push	di

	mov	ax,cs
	mov	ds,ax
	mov	es,ax
	mov	si,offset func60_in
	mov	di,offset func60_out
	mov	ax,4[bp]		; insert drive letter in input string
	add	al,'A'
	mov	[si],al
	mov	ah,60h			; Expand Path string
	int	21h			; do it
	mov	ax,4[bp]		; assume invalid, hence no change
	 jc	pdrive_exit		; carry set means invalid drive
	mov	al,cs:[func60_out]
	sub	al,'A'
pdrive_exit:
	pop	di
	pop	si
	pop	es
	pop	ds
	pop	bp
	CRET	2

	public	_logical_drive
_logical_drive	PROC NEAR

;	BOOLEAN	logical_drive(WORD);
;	returns TRUE if given drive (0-25) is logical
;
	push	bp
	mov	bp,sp
	push	ds
	push	es
	push	si
	push	di
	push	dx
	push	cx
	push	bx
	
	mov	bx,4[bp]	; get the drive number
	inc	bx		; A=1, B=2, etc
	mov	ax,4409h	; IOCTL Network/Local
	int	21h		; do it
	jc	not_logical	; carry means invalid drive
	and	dx,1000h	;
	cmp	dx,0
	jne	not_logical	; its a network drive

	mov	ax,cs
	mov	ds,ax
	mov	es,ax
	mov	si,offset func60_in
	mov	di,offset func60_out
	mov	ax,4[bp]	; insert drive letter in input string
	add	al,'A'
	mov	[si],al		;
	mov	ah,60h		; Expand Path string
	int	21h		; do it
	jc	not_logical	; carry set means invalid drive
	
	mov	ax,4[bp]	; if drive letter changes then drive is
	add	al,'A'		; substed
	cmp	al,cs:[func60_out]
	je	not_logical

	mov	ax,-1
	jmp 	logical_exit
not_logical:
	mov	ax,0
logical_exit:
	pop	bx

⌨️ 快捷键说明

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