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

📄 disk.asm

📁 DOS源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;    File              : $DISK.ASM$
;
;    Description       :
;
;    Original Author   : 
;
;    Last Edited By    : $Author: RGROSS$
;
;-----------------------------------------------------------------------;
;    Copyright Unpublished Work of Novell, Inc. All Rights Reserved.
;      
;    THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
;    PROPRIETARY AND TRADE SECRET INFORMATION OF NOVELL, INC.
;    ACCESS TO THIS WORK IS RESTRICTED TO (I) NOVELL, INC. EMPLOYEES
;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN NOVELL, INC. WHO
;    HAVE ENTERED INTO APPROPRIATE LICENSE AGREEMENTS. 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 NOVELL, 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: $
;    DISK.ASM 1.1 93/11/18 17:20:12 RGROSS
;    
;    DISK.ASM 1.41 93/11/18 17:20:25 IJACK
;    
;    DISK.ASM 1.40 93/11/10 00:28:12 IJACK
;    Format changes so you can format your hard disk
;    DISK.ASM 1.39 93/11/08 21:47:25 IJACK
;    Add hidden sectors to ioctl format etc of hard disks
;    DISK.ASM 1.38 93/11/02 16:09:29 IJACK
;    Always zero BPB_HIDDEN_SECTORS on floppies - problem with PCW free disk which
;    has garbage in those fields.
;    DISK.ASM 1.37 93/10/18 17:33:18 IJACK
;    format c: fix
;    DISK.ASM 1.36 93/10/11 18:37:24 IJACK
;    media-change checks serial-numbers for 3.5" disks
;    DISK.ASM 1.35 93/10/06 22:09:16 IJACK
;    vec_save extrn replaced by orgInt13 extrn
;    DISK.ASM 1.34 93/09/03 20:13:32 IJACK
;    Fix bug in disk formatting
;    DISK.ASM 1.33 93/09/01 17:40:31 IJACK
;    update UDSC_TIMER after media check forced by drive change
;    (DBASE IV slow installation problem)
;    DISK.ASM 1.32 93/08/12 15:33:07 IJACK
;    Handle DMA error from multi-track read (ancient PC-XT hard disk)
;    DISK.ASM 1.31 93/08/03 15:29:01 IJACK
;    use serial numbers for media change detection
;    DISK.ASM 1.30 93/08/02 18:44:50 IJACK
;    don't trust the changeline if switching drives
;    DISK.ASM 1.29 93/08/02 18:38:19 IJACK
;    
;    DISK.ASM 1.28 93/08/02 14:47:38 IJACK
;    
;    DISK.ASM 1.27 93/07/29 21:00:24 IJACK
;    get rid of genpb_ptr and genpb_minor
;    DISK.ASM 1.26 93/07/26 21:18:25 IJACK
;    Correctly return UDSC_ root from Int 2F/0803
;    DISK.ASM 1.25 93/07/26 18:07:21 IJACK
;    Switch ms-windows to full screen when prompting for disk
;    DISK.ASM 1.24 93/07/23 17:34:27 IJACK
;    fix floppy/driver.sys support
;    DISK.ASM 1.23 93/07/22 20:37:42 IJACK
;    
;    DISK.ASM 1.22 93/07/22 19:43:46 IJACK
;    switch over to REQUEST.EQU
;    change floppy drive order, add get/set serial number
;    DISK.ASM 1.21 93/07/19 18:57:21 IJACK
;    Add header
;
;    ENDLOG

	include BIOSGRPS.EQU
	include	DRMACROS.EQU		; standard DR macros
	include	IBMROS.EQU		; ROM BIOS equates
	include	REQUEST.EQU		; request header equates
	include	BPB.EQU			; BIOS parameter block equates
	include	UDSC.EQU		; unit descriptor equates
	include	DRIVER.EQU		; device driver equates


int_____DISK_INT macro
	call	Int13
	endm

FASTSETTLE	equ	FALSE		; disable "head settle == 0 ms"

RETRY_MAX	equ	3		; do 3 retries if we get an error
MAX_SPT		equ	40		; maximum sectors per track

SECSIZE		equ	512
IDOFF		equ	SECSIZE-2	; last word in boot sector is ID
PTOFF		equ	IDOFF-40h	; 4*16 bytes for partition def's

DOS20_ID	equ	1		; DOS 2.0 partition, < 4086 clusters
DOS30_ID	equ	4		; DOS 3.0 partition, < 65536 sectors
DOSEX_ID	equ	5		; DOS 3.3 extended partition
DOS331_ID	equ	6		; COMPAQ DOS 3.31 partition > 32 Mb

; Now for the secure partition types
SEC_ID          equ     0C0h            ; New DR secure partition types
SEC_ID2         equ     0D0h            ; Old DR secure partition types

page
CGROUP	group	CODE, RCODE, ICODE, RESBIOS, IDATA

CG	equ	offset CGROUP

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

IVECT	segment	at 0000h

		org	0013h*4
i13off		dw	?
i13seg		dw	?

		org	001Eh*4
i1eptr		dd	?

		org	002Fh*4
i2Foff		dw	?
i2Fseg		dw	?

		org	0472h
reset_flag	dw	?

		org	0504h
dual_byte	db	?		; multiple drive byte at 50:4

IVECT	ends

ROS	segment	at 0F000h
	org	0FFF0h
reset	proc	far
reset	endp
ROS	ends

CODE	segment	'CODE'

	extrn	endbios:word		; for device driver INIT function
	extrn	read_system_ticks:near	; get system tick count in CX/DX
	extrn	Int13Trap:near
	extrn	Int2FTrap:near
	extrn	orgInt13:dword
	extrn	i13pointer:dword
	extrn	i13off_save:word
	extrn	i13seg_save:word

	extrn	NumDiskUnits:byte
	extrn	DeblockSeg:word
	extrn	local_parms:byte
	extrn	parms_spt:byte
	extrn	parms_gpl:byte
	extrn	local_buffer:byte
	extrn	local_pt:word
	extrn	local_id:word
	extrn	layout_table:word
	extrn	bpbs:word
	extrn	bpb160:byte
	extrn	bpb360:byte
	extrn	bpb720:byte
	extrn	NBPBS:abs
	extrn	bpbtbl:word
	extrn	req_off:word
	extrn	req_seg:word


udsc_root	label	dword
		dw	-1,-1

orig_int1e_off	dw	522h
orig_int1e_seg	dw	0

new_int1e_off	dw	522h
new_int1e_seg	dw	0


	Public	i13_AX
i13_AX		label	word
i13_size	db	?		; number of sectors to xfer
i13_op		db	?		; Int13 Operation
i13_dma_ptr	label	dword
i13_dma_off	dw	?
i13_dma_seg	dw	?

activeRosUnit	db	?		; currently active ROS unit

include	biosmsgs.def				; Include TFT Header File


ifdef JAPAN
		extrn	disk_msgA_jpn	:byte
		extrn	disk_msgB_jpn	:byte
endif

;disk_msgA	db	13,10,'Insert disk for drive '
;disk_msgB	db	': any press any key when ready ', 0

page
	Assume	DS:nothing, SS:nothing, ES:nothing

CODE	ends

RCODE	segment	'RCODE'

	extrn	DataSegment:word

even
Int13	proc	near
	clc
	push	bp
	int	DISK_INT
	pop	bp
	ret
Int13	endp

ros_errors	db	03h, 80h, 08h, 10h, 40h, 04h, 06h, 00h
dos_errors	db	00h, 02h, 04h, 04h, 06h, 08h, 0Fh, 0Ch
NUMROSERR	equ	dos_errors - ros_errors

;	The following  code  is required  in order  to cope  with
;	application  programs  invoking  Int  13h  directly.   It
;	handles applications  that format floppies  or access the
;	disk via Int 13h after a floppy disk change.

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


	Public	Int13Unsure
;----------
Int13Unsure	proc	far
;----------
	sti
	cld
	push	ds
	mov	ds,cs:DataSegment
			Assume DS:CGROUP
	call	i13_unsure		; no longer sure of this drive
	pop	ds
	ret
Int13Unsure	endp

	Public	Int13Deblock

;-----------
Int13Deblock	proc	far
;-----------
; handle user programs formatting the disk
	sti
	cld
	push	ds
	mov	ds,cs:DataSegment
			Assume DS:CGROUP

	pushx	<es, bx, cx, si, di>	; save work registers
	mov	i13_dma_off,bx
	mov	i13_dma_seg,es
i13_deblock10:
	pushx	<cx, dx>
	mov	cl,4
	mov	ax,i13_dma_seg		; get transfer address
	shl	ax,cl			; get A4..A15 from segment
	add	ax,i13_dma_off		; combine with A0..A15 from offset
	not	ax			; AX = # of bytes left in 64K bank
	xor	dx,dx
	mov	cx,SECSIZE
	div	cx			; convert this to physical sectors
	mov	dl,i13_size		; see if we can xfer amount wanted
	cmp	al,dl			; capable of more than requested?
	 jb	i13_deblock20		; skip if we can do it all
	xchg	ax,dx			; we can do them all
i13_deblock20:
	les	bx,i13_dma_ptr		; do the xfer to here
	popx	<dx, cx>
	mov	ah,i13_op		; get read/write/verify operation
	test	al,al			; if zero length possible
	 jz	i13_deblock30		;  then deblock
	mov	di,es			; get transfer address
	cmp	di,DeblockSeg		;  is this in high memory ?
	 jb	i13_deblock50		;  then force through deblock buffer
i13_deblock30:
	push	ds			; if deblocking then we'd better
	pop	es			;  point at local buffer we
	mov	bx,CG:local_buffer	;  will be using for actual I/O
	cmp	i13_op,ROS_WRITE
	 jne	i13_deblock40		; skip data copy if not writing to disk
	push	ds
	push	cx
	mov	di,bx			; ES:DI -> local buffer
	lds	si,i13_dma_ptr		; DS:SI -> data to write
	mov	cx,SECSIZE/2
	rep	movsw			; copy to deblocking buffer
	pop	cx
	pop	ds
i13_deblock40:
	mov	al,1			; do a single sector via buffer
	clc
	pushf				; fake an Int
	call	i13pointer		;  to the track handler
	 jc	i13_deblock90		; stop on error
	mov	al,1			; restore AL for buggy bios's
	cmp	i13_op,ROS_READ		; if we are reading then we'll
	 jne	i13_deblock60		;  have to copy data out of
	push	cx			;  the deblocking buffer
	les	di,i13_dma_ptr		; ES:DI -> dest for data
	mov	si,CG:local_buffer	; point at local buffer which
	mov	cx,SECSIZE/2		;  contains actual data
	rep	movsw			; copy from deblocking buffer
	pop	cx
	jmps	i13_deblock60
	
i13_deblock50:
	push	ax			; save # sectors in xfer
	clc
	pushf				; fake an Int
	call	i13pointer		; do the operation
	pop	bx
	mov	al,bl			; restore AL for buggy bios's
	 jc	i13_deblock90		; stop on error
i13_deblock60:				; we succeeded in doing AL sectors
	sub	i13_size,al		; forget about those we have done
	 jbe	i13_deblock90		;  and do more if there are any
	push	ax
	mov	ah,SECSIZE/16
	mul	ah			; AX = paras to inc DMA address
	add	i13_dma_seg,ax		;  up DMA address by this amount
	pop	ax
	call	i13_point_unit		; ES:DI -> UDSC_
	 jc	i13_deblock90		; exit if we can't find it
	mov	bx,cx			; get sector/cylinder in BX
	and	bx,0003Fh		; BX = sector
	and	cx,0FFC0h		; CX = mandled cylinder bits
	add	bl,al			; work out new sector
i13_deblock70:
	mov	ax,es:UDSC_BPB+BPB_SPT[di]
	cmp	bx,ax			; still on the same track ?
	 jbe	i13_deblock80		; easy if no overflow onto next track
	sub	bx,ax			; subtract a tracks worth
	inc	dh			;  and move onto next head
	mov	al,dh			; isolate head from cylinder
	and	ax,003Fh		;  bits 10/11
	cmp	ax,es:UDSC_BPB+BPB_HEADS[di]
	 jb	i13_deblock70		; onto next track yet ?
	and	dh,0C0h			; back to head zero
	add	ch,1			; onto next track (bits 0-7)
	 jnc	i13_deblock70		; overflow to bits 8-9 ?
	add	cl,040h			; yes, "inc" bits 8/9 of cylinder
	 jnc	i13_deblock70		; overflow to bits 10-11 ?
	add	dh,040h			; yes, "inc" bits 10/11 of cylinder
	jmps	i13_deblock70

i13_deblock80:
	or	cx,bx			; recombine sector/cylinder
	jmp	i13_deblock10		;  and do some more

i13_deblock90:
	popx	<di, si, cx, bx, es>	; restore work registers
	pop	ds			; recover user DS
	ret	2			; return to user with result

i13_point_unit	proc	near
;-------------
; On Entry:
;	DL = ROS unit
; On Exit:
;	ES:DI -> UDSC_ for that unit
;	All other regs preserved
;
	les	di,udsc_root		; ES:DI -> 1st es:UDSC_
i13_point_unit10:
	cmp	dl,es:UDSC_RUNIT[di]	; find the physical unit
	 je	i13_point_unit20
	les	di,es:UDSC_NEXT[di]
	cmp	di,0FFFFh		; else try the next es:UDSC_
	 jne	i13_point_unit10
	mov	ah,09h			; return DMA error to caller as we
	stc				;  don't know about this unit
i13_point_unit20:
	ret
i13_point_unit	endp

Int13Deblock	endp

i13_unsure	proc	near
;---------
; mark physical drive DL as unsure
;
	pushx	<ds, si>
	lds	si,udsc_root
i13_unsure10:
	cmp	dl,ds:UDSC_RUNIT[si]	; does it match ROS drive?
	 jne	i13_unsure20		; skip if not
	or	ds:UDSC_FLAGS[si],UDF_UNSURE
i13_unsure20:				; next drive
	lds	si,ds:UDSC_NEXT[si]
	cmp	si,0FFFFh
	 jne	i13_unsure10
	popx	<si, ds>		; restore registers
	ret

i13_unsure	endp

	Assume	DS:Nothing, SS:Nothing, ES:Nothing

	Public	Int2FHandler

Int2FHandler	proc	far
;-----------
; On Entry we have offset/seg of next in chain on the stack
; (ie. we can pass on by a RETF)
;
	cmp	ah,8				; DRIVER.SYS support
	 je	i2F_driver
	cmp	ah,13h				; int13 intercept
	 jne	i2F_iret
;
; Int 13 interception support
; ---------------------------
;
; On Entry:
;	DS:DX -> New Int 13 vector
;	ES:BX -> Int 13 vector restored by Int 19
;
; On Exit:
;	DS:DX -> Old Int 13 vector
;	ES:BX -> Old Int 13 vector restored by Int 19
;
i2F_i13_intercept:
	mov	ax,ds
	mov	ds,cs:DataSegment
			Assume DS:CGROUP
	xchg	dx,ds:i13off_save
	xchg	ax,ds:i13seg_save
	push	ax
	xchg	bx,ds:word ptr orgInt13
	mov	ax,es
	xchg	ax,ds:word ptr orgInt13+2
	mov	es,ax
	pop	ds
			Assume DS:Nothing
i2F_iret:
	iret


;
; DRIVER.SYS support
; -------------------
;
; On Entry:
;	AX=0800, installation check
;	AX=0801, add new block device at DS:SI
;	AX=0802, execute driver request at ES:BX
;	AX=0803, return address of first es:UDSC_
;
i2F_driver:
	cmp	al,1
	 jb	i2F_driver_check
	 je	i2F_driver_add
	cmp	al,3
	 jb	i2F_driver_req
	 je	i2F_driver_point

⌨️ 快捷键说明

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