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

📄 bdosldr.a86

📁 DOS源码
💻 A86
📖 第 1 页 / 共 2 页
字号:
	inc	cluster_count		; else read one more cluster
	jmps	rd_file2		; try again with next cluster
rd_file3:				; CX = next chain, multi cluster read
	push	cx			; save start of next chain
	les	bx,dta_ptr		; ES:BX -> transfer address
	mov	cx,start_cluster	; previous contiguous chain starts here
	mov	dx,cluster_count	; length of chain in clusters
	call	rd_cluster		; read DX clusters
	mov	al,BT_sctr_per_cluster
	mov	ah,0			; AX = sectors per cluster
	mul	cluster_count		; AX = sectors in chain to read
	mul	BT_bytes_per_sector	; AX = bytes in chain to read
	add	dta_off,ax
	pop	cx			; CX = next (noncontiguous) cluster
	mov	start_cluster,cx	; start of new chain
	inc	cx			; was it end of file cluster number?
	 jnz	rd_file1		; go back for more if not
					; else all clusters done
	ret


get_FAT_byte:
;------------
;	entry:	BX = offset into FAT

	mov	ax,bx			; BX = offset into FAT
	sub	dx,dx			; AX/DX = 32 bit offset
	div	BT_bytes_per_sector	; AX = sector, DX = offset in sector
	push	dx			; save offset in sector
	call	locate_FAT		; read FAT sector AX
	pop	bx			; BX = offset in FAT sector
	mov	al,sector_buffer[bx]	; get byte from FAT buffer
	ret


locate_FAT:
;----------
;	entry:	AX = FAT sector to locate

	cmp	ax,current_fatsec	; AX = sector offset into FAT
	 je	locate_FAT_match	; O.K. if same as last time

	mov	current_fatsec,ax	; set new sector for next time
	push	cx ! push si		; preserve FAT index
	mov	cx,ax			; CX = sector number
	mov	bx,offset sector_buffer
	push	ds ! pop es		; ES:BX -> sector buffer
	mov	dx,1			; DX = single sector
	call	rd_sector_rel		; read FAT sector
	pop	si ! pop cx		; restore FAT index

locate_FAT_match:			; return with right sector in buffer
	ret


eject
;	reads sectors relative to start of DOS area on disk (start=0)
;	same parameters as rd_sector
rd_sector_rel:
;-------------
;	entry:	CX = sector address relative to first FAT sector
;		DX = sector count

	sub	bp,bp				;overflow word = 0
	add	cx,BT_reserved_sectors
	adc	bp,0
;	jmps	rd_sector
	

;	reads absolute sectors from hard disk using rom bios
rd_sector:
;---------
;	entry:	DX = number of sectors
;		ES:BX -> data transfer buffer
;		DS -> program global data segment
;		CX/BP = absolute sector # (32 bit) (low/high)

	push	cx ! push dx		; save parameters
	mov	req3_bufoff,bx		; save transfer offset
	mov	req3_bufseg,es		; save transfer segment
	mov	req3_count,dx		; set sector count
	mov	bx,offset req_hdr	; BX -> request header
	mov	ds:RH_CMD,CMD_INPUT	; read from disk device
	mov	req3_sector,cx		; set requested sector address
if DOS5
	mov	req_hdr,RH4_LEN
	mov	req3_sector32,cx	;  with 32 sector number
	mov	req3_sector32+2,bp
	test	bp,bp			; large sector number?
	 jz	rd_sec1			; no, normal request header
	mov	req3_sector,0FFFFh	; mark as a large request
rd_sec1:
else
	mov	req3_sector+2,bp	; (support large DOS drives)
	mov	req_hdr,24		; indicate large request
endif
	call	device_request		; tell it to read sectors
	pop	cx ! pop dx
	ret				; if CY, AH=error code


rd_cluster:
;----------
;	entry:	CX = DOS cluster number.
;		DX = cluster count
;		ES:BX -> transfer buffer

	push	bx ! push es

	mov	al,BT_sctr_per_cluster
	mov	ah,0			; AX = sectors per cluster
	mul	dx			; AX = sectors in all clusters
	push	ax			; save the sector count

	sub	cx,2			; cluster 2 is data area start
	mov	al,BT_sctr_per_cluster
	cbw
	mul	cx			; AX,DX = relative sector #
	mov	cx,ax
	mov	bp,dx			; CX,BP = data area sector #

	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	cx,ax
	adc	bp,dx			; CX,BP = end of FAT sectors

	mov	ax,32
	mul	BT_dirsize		; AX,DX = bytes in root directory
	mov	bx,BT_bytes_per_sector
	dec	bx
	add	ax,bx			; round up directory size
	adc	dx,0
	inc	bx
	div	bx			; AX = root directory sectors
	add	cx,ax
	adc	bp,0			; add root directory size

	add	cx,BT_reserved_sectors	; add in boot sector(s)
	adc	bp,0

	pop	dx ! pop es ! pop bx	; sector count, disk address

	jmp	rd_sector		; DX secs from CX/BP to ES:BX


;	Finds the NEXT cluster after the one passed in CX in an allocation
;	chain by using the FAT.  Returns the carry set if the end of chain
;	mark is found, otherwise returns the NEW cluster # in CX.
next_cluster:
;------------
	push	dx ! push bx		; save some registers
	cmp	fat16,0			; check if this is 12 bit media
	 je	next_cluster12		; skip if old fashioned 12 bit
	mov	ax,2
	mul	cx			; AX/DX = byte offset in FAT (max. 128K)
	div	BT_bytes_per_sector	; AX = FAT sector #, DX = byte offset
	push	dx			; save byte offset within sector
	call	locate_FAT		; get FAT sector AX
	pop	bx			; BX = offset within sector
	mov	cx,word ptr sector_buffer[bx]
					; get 16 bit from FAT

	cmp	cx,0FFF7h		; check if too large for #
	 jae	next_cluster_eof	; set carry, EOF
	clc
	jmps	next_cluster_ret	; good link

next_cluster12:				; DOS 2.x disk
	push	cx			; save cluster number
	mov	bx,cx
	add	bx,bx			; BX = cluster# * 2
	add	bx,cx			; BX = cluster# * 3
	shr	bx,1			; BX = cluster# * 1.5
	push	bx			; save offset in the FAT
	inc	bx			; BX = offset of high byte
	call	get_FAT_byte		; get the high byte in AL
	pop	bx			; BX = offset of low byte
	push	ax			; save high byte on stack
	call	get_FAT_byte		; get the low byte in AL
	pop	bx			; pop off high byte into BL
	mov	ah,bl			; set high byte, AX = word
	pop	cx			; restore cluster number
	shr	cx,1			; test if even or odd
	 jnc	even_fat		; if even entry, done
	mov	cl,4			; odd entry, shift down one nibble
	shr	ax,cl			; else need to justify
even_fat:				; even entry, strip off top bits
	and	ax,0fffh		; bx[0..11] are cluster
	mov	cx,ax			; CX = cluster number
	cmp	cx,0ff7h		; compare with largest legal 12 bit #
	 jae	next_cluster_eof	; check for end mark
	clc
	jmps	next_cluster_ret	; return value in CX, CY = 0
next_cluster_eof:
	mov	cx,-1			; indicate end of chain
	stc				; end of chain
next_cluster_ret:
	pop	bx ! pop dx
	ret


eject
;
;	INITIALIZED DATA SEGMENT
;	========================
INITDATA	dseg	'INITDATA'

		extrn	resdev_chain:dword	; resident device driver root
		extrn	current_dos:word	; current BDOS segment
		extrn	boot_device:dword	; device driver we boot from
		extrn	boot_drv:byte		; boot drive
		extrn	dos_name:byte		; name of BDOS file

strat_ptr	rd	0
strat_off	rw	1
strat_seg	rw	1

intrpt_ptr	rd	0
intrpt_off	rw	1
intrpt_seg	rw	1

dta_ptr		rd	0
dta_off		rw	1
dta_seg		rw	1

start_cluster	rw	1
cluster_count	rw	1

current_fatsec	dw	-1			; no FAT sector read yet
fat16		dw	0			; defaults to 12 bit FAT

;	single error message if BDOS can't be loaded:


include	initmsgs.def				; Include TFT Header File


;dos_msg	db	CR,LF,'Can''t load DOS file.$'


;	static request header for DOS device driver I/O

req_hdr		db	22
req_unit	rb	1
req_cmd		rb	1
req_status	rw	1
		rd	2
req_media	rb	1
		rb	16

req1_return	equ	byte ptr req_media+1
req1_volid	equ	word ptr req_media+2

req2_bufoff	equ	word ptr req_media+1
req2_bufseg	equ	word ptr req_media+3
req2_bpb	equ	word ptr req_media+5

req3_buffer	equ	dword ptr req_media+1
req3_bufoff	equ	word ptr req_media+1
req3_bufseg	equ	word ptr req_media+3
req3_count	equ	word ptr req_media+5
req3_sector	equ	word ptr req_media+7
req3_volid	equ	word ptr req_media+9
req3_sector32	equ	word ptr req_media+13

;	local copy of the BPB for the boot device

local_bpb		rb	0
BT_bytes_per_sector	rw	1
BT_sctr_per_cluster	rb	1
BT_reserved_sectors	rw	1
BT_nfats		rb	1
BT_dirsize		rw	1
BT_total_sectors	rw	1
BT_fatid		rb	1
BT_fat_size		rw	1
BT_sectors_per_track 	rw	1
BT_nheads		rw	1
BT_hidden_sectors	rw	2
BT_total_long		rw	2
BPB_LENGTH		equ	(offset $-offset local_bpb)

	extrn	sector_buffer:byte

	end

⌨️ 快捷键说明

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