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

📄 bdosldr.a86

📁 Dos7.01的源代码
💻 A86
📖 第 1 页 / 共 2 页
字号:
;    File              : $BDOSLDR.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$
;
;    ENDLOG

	include i:reqhdr.equ
	include i:driver.equ
	include	config.equ

;	MISC constants
CR		equ	0dh			;the usual
LF		equ	0ah


DATTS		equ	byte ptr 11
 DA_VOLUME	equ	08h
 DA_DIR		equ	10h
DBLOCK1		equ	word ptr 26


eject
CGROUP		group	INITCODE, INITDATA

INITCODE	cseg	'INITCODE'

eject
if DOS5
VER_MUSTBE	equ	1072h
else
VER_MUSTBE	equ	1071h
endif

	Public	dos_version_check

	Public	read_dos		; read BDOS from disk

;--------
read_dos:	; read in the BDOS
;--------
	call	login_drive		; build BPB for the boot drive
	mov	si,offset dos_name	; get name of file to open
	call	open_file		; open the BDOS file
	call	read_file		; read in the system file
	ret

login_drive:
;-----------
	les	di,boot_device		; get device driver address
	mov	dl,boot_drv		; get the boot drive sub unit
	mov	ax,es
	or	ax,di			; make sure boot device is initialised
	 jnz	login_drive10
	jmp	dev_fail
login_drive10:
	mov	ax,es:6[di]		; get strategy offset
	mov	strat_off,ax
	mov	strat_seg,es		; get strategy segment
	mov	ax,es:8[di]		; get interrupt offset
	mov	intrpt_off,ax
	mov	intrpt_seg,es		; get interrupt segment

	mov	bx,offset req_hdr
	mov	ds:RH_UNIT,dl		; save logical unit to use
	mov	ds:RH_CMD,CMD_BUILD_BPB
	call	device_request		; tell it to build a BPB
	 jc	dev_fail		; return if can't determine BPB
	push	ds ! push si
	push	ds ! pop es
	mov	di,offset local_bpb	; ES:DI -> local BPB copy
	mov	cx,BPB_LENGTH
	lds	si,ds:RH2_BPB		; copy BPB to local memory
	rep	movsb
	pop	si ! pop ds

;	Now we have to figure out whether the media uses 12 or 16 bit FATs.
;	To that end, we need to compute the # of clusters on the drive:

	mov	fat16,0			; assume 12 bit FAT

	mov	al,BT_nfats		; compute FAT size
	mov	ah,0			; AX = # of FAT copies (usually 2)
	mul	BT_fat_size		; AX/DX = size of FAT in sectors

	add	ax,BT_reserved_sectors	; add in bootstrap sectors
	adc	dx,0
	mov	cx,ax			; CX/BP = sector address of root dir
	mov	bp,dx

	mov	ax,32			; compute root directory size
	mul	BT_dirsize		; AX/DX = bytes in directory
	mov	bx,BT_bytes_per_sector
	dec	bx			; BX = sector size - 1 for rounding
	add	ax,bx			; round up to next sector size
	adc	dx,0
	inc	bx			; BX = sector size in bytes
	div	bx			; AX = # of root directory sectors
	add	cx,ax			; CX/BP = sectors before data area
	adc	bp,0

	mov	ax,BT_total_sectors	; AX/DX = total disk size in sectors
	sub	dx,dx
	test	ax,ax			; is it actually larger than 65535?
	 jnz	dev_small		; no, AX/DX is correct
	mov	ax,BT_total_long	; else get real size from extension
	mov	dx,BT_total_long+2
dev_small:				; AX/DX = disk size in sectors
	sub	ax,cx			; AX/DX = data sectors
	sbb	dx,bp
					; now convert this to clusters
	mov	bl,BT_sctr_per_cluster
	mov	bh,0			; BX = sectors per clusters
	div	bx			; AX = # of data clusters
	inc	ax
	inc	ax			; cluster 0,1 are reserved
	cmp	ax,0FF6h		; is this too large for 12 bits?
	 jbe	dev_12bit		; skip if 12 bits will do
	mov	fat16,-1		; else we use 16 bits
dev_12bit:
	ret


dos_version_check:
;-----------------
	mov	ax,4452h
	int	21h			; try and get DRDOS version number
	 jc	dev_fail		;  it's not DRDOS !
	cmp	ax,VER_MUSTBE		; version check the DRDOS BDOS
	 jne	dev_fail		;  reject all but the one we want
	ret				; return now I'm happy

dev_fail:	; any error has occurred loading the BDOS
;--------
; Print '$' terminated message at offset DX to console without using the BDOS
;
	mov	dx,offset dos_msg
	les	di,resdev_chain		; get first device driver address
fail_scan:
	test	es:DH_ATTRIB[di],DA_CHARDEV
	 jz	fail_next		; skip if not a character device
	test	es:DH_ATTRIB[di],DA_ISCOT
	 jnz	fail_found		; skip if console device found
fail_next:
	les	di,es:[di]		; get next device
	jmps	fail_scan
fail_found:
	mov	ax,es:6[di]		; get strategy offset
	mov	strat_off,ax
	mov	strat_seg,es		; get strategy segment
	mov	ax,es:8[di]		; get interrupt offset
	mov	intrpt_off,ax
	mov	intrpt_seg,es		; get interrupt segment

	mov	bx,offset req_hdr
	mov	ds:RH_CMD,CMD_OUTPUT	; write to console
	mov	ds:RH_LEN,RH4_LEN	; set request header length
	mov	ds:RH4_BUFOFF,dx	; set address of string
	mov	ds:RH4_BUFSEG,ds
	mov	ds:RH4_COUNT,-1
	mov	si,dx			; now find the end of the string
fail_count_chars:
	inc	ds:RH4_COUNT		; print another char
	lodsb				; examine the next one
	cmp	al,'$'			; terminating char ?
	 jnz	fail_count_chars
	call	device_request		; call the console driver

	sti
	jmps	$			; wait for reboot


device_request:		; general device driver interface
;--------------
;	entry:	BX -> request header
;	exit:	CY = 1 if error

	push	ds ! push es
	push	ds ! pop es
	mov	ds,strat_seg
	callf	cs:strat_ptr
	callf	cs:intrpt_ptr
	pop	es ! pop ds
	test	ds:RH_STATUS,RHS_ERROR
	 jnz	devreq_err
	clc
	ret
devreq_err:
	jmp	dev_fail		; print error message


	ret
	
open_file:	; open BDOS system file
;---------
;	entry:	SI -> 11 byte file name

	mov	al,BT_nfats
	cbw
	mul	BT_fat_size		; DX:AX = # FAT sectors

	mov	cx,ax			; CX = rel_sctr dir start
	mov	dx,BT_dirsize		; dx = # entries to scan

open_f1: 				; CX = current dir sector
					; DX = current dir count
					; SI -> file name
	push	cx ! push dx ! push si
	push	ds ! pop es		; ES:BX -> sector buffer
	mov	bx,offset sector_buffer
	mov	dx,1			; read one directory sector
	call	rd_sector_rel		;     via disk driver
	pop	si ! pop dx ! pop cx
	inc	cx			; increment sector for next time

	sub	bx,bx			; start at beginning of sector
open_f2:
	lea	di,sector_buffer[bx]	; ES:DI -> directory entry
	push	si ! push di ! push cx	; save name ptr and count
	push	ds ! pop es
	mov	cx,11
	repe	cmpsb			; check if name matches
	pop	cx ! pop di ! pop si
	 jne	open_f3			; skip if name doesn't match
	test	DATTS[di],DA_DIR+DA_VOLUME
	 jz	open_foundit		; skip if matches
open_f3:
	dec	dx			; count down root directory entries
	 jz	open_fail		; skip if root directory done
	add	bx,32			; next entry in directory sector
	cmp	bx,BT_bytes_per_sector	; sector complete?
	 jb	open_f2			; loop back while more
	jmps	open_f1			; read next directory sector

open_fail:				; file not found
	jmp	dev_fail

open_foundit:				; found the open file handle
	mov	ax,DBLOCK1[di]		; get first disk block
	mov	start_cluster,ax	; save starting cluster
	xor	ax,ax
	ret				; return success


read_file:	; read BDOS files into memory at MEM_CURRENT:0000
;---------
	mov	ax,current_dos		; Get the Segment address to
	mov	dta_seg,ax		; load the BDOS at
	sub	ax,ax
	mov	dta_off,ax
rd_file1:
	mov	cluster_count,1		; we can read at least one cluster
	mov	cx,start_cluster
rd_file2:				; check if next cluster contiguous
	push	cx			; save current cluster number
	call	next_cluster		; get link to next cluster
	pop	dx			; get previous cluster #
	inc	dx			; is current cluster contiguous?
	cmp	cx,dx			; contiguos if CX == DX
	 jne	rd_file3		; no, need a separate read

⌨️ 快捷键说明

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