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

📄 disk.asm

📁 DOS源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;---------
; On Entry:
;	ES:DI -> UDSC_
; On Exit:
;	ES:DI preserved
;	DL = owning drive (zero = no owner)
;
	xor	dx,dx			; assume one unit per physical drive
	mov	ax,es:UDSC_FLAGS[di]
	test	ax,UDF_HARD
	 jnz	set_owner40
	test	ax,UDF_VFLOPPY
	 jz	set_owner40
	mov	al,es:UDSC_DRIVE[di]
	mov	ah,es:UDSC_RUNIT[di]	; get ROS unit
	test	ah,ah			; is it unit zero ?
	 jnz	set_owner10
	push	ds
	mov	ds,dx			; DS -> low memory
		Assume	DS:IVECT
	mov	dual_byte,al		; set dual drive support byte
	pop	ds
		Assume	DS:CGROUP
set_owner10:
	push	ds
	lds	si,udsc_root
		Assume	DS:Nothing
set_owner20:
	cmp	ah,ds:UDSC_RUNIT[si]	; does this unit use the same drive ?
	 jne	set_owner30
	or	ds:UDSC_FLAGS[si],UDF_UNSURE+UDF_OWNER
	cmp	al,ds:UDSC_DRIVE[di]
	 je	set_owner30
	and	ds:UDSC_FLAGS[si],not UDF_OWNER
set_owner30:
	lds	si,ds:UDSC_NEXT[si]
	cmp	si,0FFFFh		; end of the line ?
	 jne	set_owner20
	pop	ds
		Assume	DS:CGROUP
	xchg	ax,dx			; DL = owning drive
	inc	dx			; make it one based
set_owner40:
	ret


ask_for_disk:		; make sure the right disk is in the floppy drive
;------------
	call	get_owner		; DL = owning drive
	dec	dx			; make DL zero based
	 js	askfdsk30		; stop if not a logical drive
	mov	dh,es:UDSC_DRIVE[di]	; DH = new drive, DL = old drive
	cmp	dl,dh			; do we own the drive ?
	 je	askfdsk30		; yes, stop now
	push	dx			; save for broadcast
	mov	dl,dh			; new owner in DL
	call	set_owner		; we are now the owner
	push	es
	push	di
	push	cs
    call    FullScreen      
	pop	di
	pop	es
	pop	dx
	mov	ax,4A00h		; should we prompt ?
	xor	cx,cx
	int	2Fh			; lets ask
	inc	cx			; CX = FFFF ?
	 jcxz	askfdsk30		; then skip prompt
ifdef JAPAN
	mov	ax,5001h		; get adaptor mode
	int	VIDEO_INT		; ..
	cmp	bx,81			; japanese mode ?
	mov	si,CG:disk_msgA_jpn	; get message to print for Japanese
	 je	askfdsk10		; yes
endif
	mov	si,CG:disk_msgA		; get message to print
askfdsk10:
	call	WriteASCIIZ		; output the string
	mov	al,es:UDSC_DRIVE[di]	; get drive letter for new drive
	add	al,'A'
	dec	si			; point to NUL
	call	WriteNext		; output char, stop at NUL
ifdef JAPAN
	mov	ax,5001h		; get adaptor mode
	int	VIDEO_INT		; ..
	cmp	bx,81			; japanese mode ?
	mov	si,CG:disk_msgB_jpn	; get message to print for Japanese
	 je	askfdsk20		; yes
endif
	mov	si,CG:disk_msgB		; get message to print
askfdsk20:
	call	WriteASCIIZ		; output the string
	mov	ah,0			; wait for any key to be pressed
	int	KEYBOARD_INT		; read one key from keyboard
askfdsk30:
	ret				; we've got the right drive

WriteNext:
	int	29h			; output via fastconsole entry
WriteASCIIZ:
	lods	cs:byte ptr [si]	; get next char
	test	al,al
	 jnz	WriteNext		; stop at NUL
	ret

FullScreen:
	xor	di,di
	mov	es,di
	mov	ax,1684h		; get the entry point
	mov	bx,21			;  for DOSMGR
	int	2Fh
	mov	bx,es
	or	bx,di			; anyone there ?
	 jz	FullScreen10
	mov	ax,1			; yes, go full screen please
	push	es			; fake a JMPF to ES:DI
	push	di
FullScreen10:
	retf


driver	endp


RCODE	ends				; end of device driver code

page

ICODE	segment	'ICODE'			; initialization code

	Assume	CS:CGROUP, DS:CGROUP, ES:Nothing, SS:Nothing

dd_init:	; 0-initialize driver
;-------

	call	hard_init		; setup hard disk units
	call	floppy_init		; setup floppy units

	les	bx,REQUEST[bp]
	mov	al,nunits		; get # of units installed
	mov	es:RH0_NUNITS[bx],al	; return value to the BDOS
	mov	NumDiskUnits,al		; also set it in device header

	mov	ax,endbios		; get pointer to last resident byte
	mov	es:RH0_RESIDENT[bx],ax	; set end of device driver
	mov	es:RH0_RESIDENT+2[bx],ds

	mov	ax,CG:bpbtbl
	mov	es:RH0_BPBOFF[bx],ax	; set BPB table array
	mov	es:RH0_BPBSEG[bx],ds

	sub	ax,ax			; initialization succeeded
	ret				; (BIOS init always does...)


floppy_init:
;-----------
	mov	nunits,0		; floppies start at drive A:
	mov	ah,ROS_RESET		; reset the disk system
	xor	dx,dx			; for NEAT hard disk boot bug
	int_____DISK_INT
	int	EQUIPMENT_INT		; determine equipment status
	mov	cl,6
	shr	ax,cl			; shift down floppy bits
	and 	ax,03h			; mask for floppy
	inc	ax			; correct 0 based code
	mov	nfloppy,al

	cmp	al,1			; if there is only one floppy
	 jne	equip_check_des		;   then use 2 designators
	inc	ax			;   this fakes a B: drive
equip_check_des:
	mov	cx,ax			; CX = # of units to set up
	xor	dx,dx			; DL = physical drive
equip_loop:
	push	cx

	call	new_unit		; ES:DI -> UDSC
	mov	es:UDSC_RUNIT[di],dl	; set physical drive (ROS code)

	call	floppy_type		; determine type, build default BPB

	cmp	nfloppy,1		; do we only have single drive?
	 je	equip_single		; yes, use same physical drive for all
	inc	dx			; else use new drive for each unit
equip_single:				; we only have one physical drive

	call	add_unit		; add ES:DI to list of UDSC_'s

	pop	cx
	loop	equip_loop		; repeat for all logical floppies

	pushx	<ds, es>

	push	ds			; DS -> i13_trap segment
	
	mov	di,ds
	mov	es,di
	sub	si,si
	mov	ds,si
	lds	si,78h[si]
	mov	di,CG:local_parms	; copy parameters to template
	mov	cx,11
	rep	movsb

	pop	es			; now ES -> i13_trap segment
	Assume	ES:CGROUP
	sub	ax,ax
	mov	ds,ax			; DS -> interrupt vectors
	Assume	DS:IVECT
	mov	ax,CG:Int2FTrap		; hook Int 2F
	mov	i2Foff,ax
	mov	i2Fseg,es
	mov	ax,CG:Int13Trap		; hook Int 13
	xchg	ax,i13off
	mov	es:i13off_save,ax
	mov	ax,es
	xchg	ax,i13seg
	mov	es:i13seg_save,ax

	mov	di,500h			; dual drive byte & friends live here
	mov	cx,20h/2		; zero some bytes at 50h:0
	sub	ax,ax			; get a quick zero
	mov	es,ax			; ES:DI -> 0:500h
	rep	stosw			; setup dual drive byte & friends

	Assume	DS:CGROUP, ES:Nothing
	popx	<es, ds>

	ret


floppy_type:
;-----------
;	entry:	DI -> unit descriptor

	mov	UDSC_TYPE[di],0		; assume 360K 5.25" floppy
	mov	UDSC_NCYL[di],40	; 40 tracks only
	mov	ah,ROS_GETTYPE		; "Read DASD type"
	int_____DISK_INT		; find out if disk change line available
	 jc	equip_no_chgline	; skip if function not supported
	cmp	ah,2			; floppy with disk change line?
	 jne	equip_no_chgline	; no, must be old 360K
	or	es:UDSC_FLAGS[di],UDF_CHGLINE
	mov	es:UDSC_TYPE[di],1	; assume 1.2Mb floppy
	mov	es:UDSC_NCYL[di],80	; 80 tracks
equip_no_chgline:
	pushx	<es, di, dx>		; save our registers
	mov	ah,ROS_PARAM		; read drive parameters
	int_____DISK_INT		; find out floppy type
	popx	<dx, di, es>
	 jc	equip_no_type		; skip if PC,XT,jr,AT before 10 Jan 84
	dec	bx			; make values 0 based
	 jns	equip_type		; (CMOS invalid - type = 0)
	xor	bx,bx			; assume 360K
	cmp	ch,4fh			; is it 80 track ?
	 jne	equip_no_type		; if not forget it
	mov	bl,1			; BL = 1 (ie. 1.2M)
	cmp	cl,15			; 15 spt ?
	 je	equip_type
	inc	bx			; BL = 2 (ie. 720k)
	cmp	cl,9			; 9 spt ?
	 je	equip_type
	inc	bx			; BL = 3 (ie. 1.4M)
	cmp	cl,18			; 18 spt ?
	 je	equip_type
	inc	bx
	inc	bx			; BL = 5 (ie. 2.8M)
	cmp	cl,36			; 36 spt ?
	 jne	equip_no_type		; don't recognise anything
equip_type:
	cmp	bl,3			; is it 1.44 Mb 3.5" type?
	 jb	equip_type_ok		; skip if 360K, 1.2Mb, 720K (0, 1, 2)
	mov	bl,7			; use reserved "Other" type
     je equip_type_ok      
	inc	bx			; else make it 2.88 Mb type 9
	inc	bx
equip_type_ok:
	mov	es:UDSC_TYPE[di],bl	; set the default drive type for format
equip_no_type:

	mov	al,es:UDSC_TYPE[di]	; AL = 0, 1, 2 or 7 (360/1.2/720/1.44)
	cbw				; make it a word
	xchg	ax,si			; SI = drive type
	shl	si,1			; SI = drive type * 2
	mov	si,bpbs[si]		; get default BPB for drive
	cmp	si,CG:bpb360		; is this is a 360 K drive?
	 jne	equip_360		; skip if any other type
	mov	bpbtbl[bx],CG:bpb720	; use larger default BPB
equip_360:	
	mov	cx,UDSC_BPB_LENGTH	; CX = size of BPB
	pushx	<es, di, si, cx>
	lea	di,es:UDSC_BPB[di]
	mov	ax,ds
	mov	es,ax			; ES = DS
	rep	movsb			; make default BPB current BPB in UDSC
	popx	<cx, si, di, es>
	pushx	<es, di>
	lea	di,es:UDSC_DEVBPB[di]
	rep	movsb			; copy default BPB device BPB in UDSC
	popx	<di, es>
	ret


	page

LOG_PRIM	equ	01h		; log in primary partitions
LOG_EXTD	equ	02h		; log in extended partitions

log_flag	dw	LOG_PRIM	; scan for primary only initially

hard_init:	; setup all hard disk units
;---------
;	mov	log_flag,LOG_PRIM	; log in primary only initially
	call	hardi0			; C: & D:
	mov	log_flag,LOG_EXTD	; log in extended only
;	call	hardi0
;	ret

hardi0:
	mov	ah,ROS_PARAM		; get hard disk parameters
	mov	dl,80h
	int_____DISK_INT		; get # of hard disks we have
	 jc	hardi9			; skip if hard disks not supported
	test	dl,dl			; test if any hard disks found
	 jz	hardi9			; skip if there weren't any
	mov	al,dl
	cbw
	xchg	ax,cx			; CX = # of hard disks
	mov	dl,80h			; start with first hard disk
hardi1:
	pushx	<cx, dx>		; save drive count, physical drive
	call	login_hdisk		; find all partitions on hard disk
	popx	<dx, cx>		; restore physical drive, drive count
	inc	dx			; next physical hard disk
	loop	hardi1			; next physical hard disk
hardi9:					; all hard disks done
	ret


login_hdisk:	; find all partitions on a hard disk
;-----------
;	entry:	DL = 80h, 81h for 1st/2nd hard disk

	push	log_flag		; save state for next drive

	mov	p_unit,dl		; save physical drive
	mov	cx,0001h		; track 0, sector 1
	mov	dh,0			; partition tables start on head 0
log_h1:
	mov	dl,p_unit		; get physical unit
	call	login_read_dx
	 jnc	log_h1a
	jmp	log_h9			; give up if disk error
log_h1a:
	push	cx
	push	dx

	mov	ah,ROS_PARAM
	int_____DISK_INT		; return disk drive parameters
	inc	dh			; DH = number of heads
	mov	nhead,dh		; set # of heads on drive
	and	cl,3Fh			; isolate sector count
	mov	nsect,cl		; set sectors per track

	pop	dx
	pop	cx

;;	cmp	local_id,0AA55h
;;	 jne	log_h9			; give up if not initialized

	test	log_flag,LOG_PRIM	; scanning for primary?
	 jz	log_h5			; no, ignore all primary partitions

	mov	si,CG:local_pt		; point to partition table
log_h2:
;** SECURE PARTITIONS **
	mov	al,init_runit
	test	al,al			; booting from a hard disk ?
;** SECURE PARTITIONS **
	mov	al,4[si]		; get system ID
;** SECURE PARTITIONS **
	 jns	log_h2a			; booting from a hard disk ?
	mov	ah,al			; yes, allow secure partitions
	and	ah,0F0h
	cmp	ah,SEC_ID
	 je	log_h02
	cmp	ah,SEC_ID2
	 jne	log_h2a
log_h02:
	sub	al,ah			; turn into a sensible partition ID
log_h2a:
;** SECURE PARTITIONS **
	cmp	al,DOS20_ID		; is this a DOS 2.x partition?
	 je	log_h3			; yes, try to log it in
	cmp	al,DOS30_ID		; is this a DOS 3.0/3.1/3.2 partition?
	 je	log_h3			; yes, try to log it in
	cmp	al,DOS331_ID		; is this a DOS 3.31/4.0 partition?
	 jne	log_h4			; skip if not a good partition
log_h3:
	push	si			; save partition table index
	pushx	<cx, dx>		; save partition table address
	call	login_primary		; login primary partition
	popx	<dx, cx>		; get partition table address
	call	login_read_dx		; re-read partition table
	pop	si			; get partition table index
	 jc	log_h9			; give up if error
log_h4:
	add	si,16			; next partition table entry
	cmp	si,CG:local_id		; all partitions checked?
	 jb	log_h2			; loop back if more

log_h5:					; primary partitions done
	test	log_flag,LOG_EXTD	; scanning for extended?
	 jz	log_h9			; skip if no extended scan

	or	log_flag,LOG_PRIM	; scan for both types now
	mov	si,CG:local_pt		; SI -> partition table
; RG-01
log_h6:
;** SECURE PARTITIONS **
	mov	al,init_runit
	test	al,al			; booting from a hard disk ?
;** SECURE PARTITIONS **
	mov	al,4[si]		; get system ID
;** SECURE PARTITIONS **
	 jns	log_h6a			; booting from a hard disk ?
	mov	ah,al			; yes, allow secure partitions
	and	ah,0F0h
	cmp	ah,SEC_ID
	 je	log_sec2
	cmp	ah,SEC_ID2
	 jne	log_h6a
log_sec2:
	sub	al,ah
log_h6a:
;** SECURE PARTITIONS **
	cmp	al,DOSEX_ID		; DOS 3.3 extended partition found?
	 jne	log_h7
log_h6b:
	mov	dh,1[si]		; get head # for next table
	mov	cx,2[si]		; get cylinder, sector for next table
	jmp	log_h1			; read & scan next partition table

log_h7:					; entry not an extended partition
	add	si,16			; next partition table entry
	cmp	si,CG:local_buffer+IDOFF; all partitions checked?
	 jb	log_h6			; loop back if more

log_h9:					; drive login done
	pop	log_flag		; restore state for next drive
	ret


login_primary:
;-------------
;	entry:	SI -> partition table entry

	mov	ax,12[si]		; get size of partition (low)
	mov	part_size,ax
	mov	ax,14[si]		; get size of partition (high)
	mov	part_size+2,ax
	mov	cl,2
	mov	bx,5[si]		; get last head/sector
	and	bx,1100000011000000b	; isolate cylinder bits 10..11,8..9
	rol	bl,cl			; bits 10..11 fr

⌨️ 快捷键说明

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