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

📄 hdd.8

📁 tiny bios--了解BIOS非常好的资料
💻 8
📖 第 1 页 / 共 3 页
字号:
	;
	; Hard Disk BIOS
	;
	; (C)1997-2001 Pascal Dornier / PC Engines; All rights reserved.
	; This file is licensed pursuant to the COMMON PUBLIC LICENSE 0.5.
	;
	; Limitations:
	;
	; - HDD must support command EC (identify device).
	; - Read Long, Write Long (hardware-specific number of ECC bytes,
	;   rarely used) not supported
	; - Format not supported (not available on IDE drives)
	; - Only one drive supported
	; - Only AMI / Intel style of CHS translation supported.
	;   (simple bit shift would be simpler, but messes up sequential
	;   transfer rate)
	; - Extended disk address mode only works with drives that support
	;   LBA.
	;
	; Notes:
	;
	; - Storage of disk parameters requires read/write shadow during POST
	;   (can be write protected later). This code will break if shadow
	;   is write protected during drive configuration.
	;
	; pd 001019 - add option HD_EDD -> packet interface
	; pd 001019 - add functions 41 and 48 to support large drives.
	; pd 001017 - fix power saving HLT to avoid race conditions.
	; pd 001017 - don't limit cylinder number to 1023 in hd_lba
	;             (ensure correct result for function 15), do limit in
	;             function 08.
	; pd 000211 - recognize new SanDisk ID
	; pd 991020 - add hd_top variable, needed to support M-Systems
	; 	      DiskOnChip.
	; pd 990501 - add CDBOOT hook
	; pd 990427 - add ATAPI identify
	; pd 990214 - add hook for IDE speed initialization (cs_ide)
	; pd 990210 - add LBA mode support
	; pd 981010 - fix read handshake
	; pd 980710 - fix function 15: return 0 if drive not present

#if def	DEBUG
HD_DEBUG:			;& comment out for production code
#endif
	;
	; drive parameter structure (stored in data module)
	;
dpt_cyl	equ	0	;number of cylinders
dpt_head	equ	2	;number of heads
dpt_sig	equ	3	;signature, $A0
dpt_psec	equ	4	;physical sectors per track
dpt_mul	equ	5	;(precompensation) -> multiple count
dpt_shl	equ	7	;reserved -> shift count
dpt_ctl	equ	8	;drive control byte
dpt_pcyl	equ	9	;physical cylinders
dpt_phd	equ	11	;physical heads
dpt_lz	equ	12	;(landing zone)
dpt_sec	equ	14	;logical sectors per track
dpt_res	equ	15	;reserved
dpt_len	equ	16	;length of structure
	;
	; disk address packet for extended read/write/verify/seek
	;
#if def	HD_EDD
drq_len	equ	0	;packet size in bytes
drq_res	equ	1	;reserved, must be 0
drq_blk	equ	2	;number of blocks, max. 127
drq_res2	equ	3	;reserved, must be 0
drq_ofs	equ	4	;transfer buffer offset
drq_seg	equ	6	;transfer buffer segment
drq_lba	equ	8	;block number (8 bytes)
#endif
	
#if def	FLASHDISK
int40:	dec	dl	;correct floppy drive number
	int	40h	;execute floppy interrupt
	inc	dl	;restore drive number
	retf	2	;return, don't change status
intfld:	jmp	fldisk
	;
	; INT 13 entry
	;
int13hd:	sti
	and	dl,dl	;flash disk ?
	jz	intfld
	jns	int40	;:floppy
	and	ah,ah	;reset drive ?
	jnz	int13hd1	;:no
	cmp	dl,81h	;above valid HDD ?
	ja	int40	;-> floppy only
	int	40h	;reset floppy
	mov	ah,0
#else
#if def	CDBOOT

	; redirect to floppy or CD emulation as needed

int40:	test 	byte [cs:d_cdflag],1	;emulation enabled ?
	jz	int40a	;:no
	test	dl,dl	;drive 0 ?
	jnz	int40b	;:no
	jmp	cddisk

int40a:	int	40h	;execute floppy interrupt
	retf	2	;return, don't change status
	
int40b:	dec	dl	;correct floppy drive number
	int	40h	;execute floppy interrupt
	inc	dl	;restore drive number
	retf	2	;return, don't change status
#else
	; execute floppy interrupt

int40:	int	40h	;execute floppy interrupt
	retf	2	;return, don't change status
#endif
	;
	; INT 13 entry
	;
int13hd:	sti
	and	dl,dl	;HDD ?
	jns	int40	;:floppy
	cmp	dl,byte [cs:hd_top]	;compare with max drive number
	jae	int40	;:floppy or DiskOnChip
	and	ah,ah	;reset drive ?
	jnz	int13hd1	;:no
	cmp	dl,81h	;above valid HDD ?
	ja	int40	;-> floppy only
	int	40h	;reset floppy
	mov	ah,0
#endif
	;
	; dispatch disk commands
	;
int13hd1:	push	ds	;save registers
	push	es
	pusha
	mov	bp,sp	;access to stack frame
	xor	di,di	;access BIOS segment
	mov	ds,di
#if def	HD_DEBUG
;	test	byte [m_kbf],kb_fscrs	;scroll lock ?
;	jnz	int13dmp1	;yes: don't display
	call	v_dump	;& dump registers
int13dmp1:
#endif
	mov	di,ax	;command -> index
	shr	di,8
	add	di,di
	and	byte [bp+18h],0feh	;clear return carry
	cmp	di,hd_vec99-hd_vectab	;limit command vector
	jae	hd_badcmd	;:too high
	jmp	[cs:di.hd_vectab]	;jump to command	
	;
	; Illegal command
	;
hd_badcmd: mov	byte [m_hdstat],1	;illegal command
	;
	; AH=01: get status
	;
hd_status: mov	al,[m_hdstat]	;get old status
	mov	[bp._al],al	;return in AL
	;
	; return status
	;
hd_exit0:	mov	[m_hdstat],al	;set error code
	mov	[bp._ah],al	;return in AH
hd_exit1:	and	al,al	;error ?
	jz	hd_exit2	;:no
	or	byte [bp+18h],1	;yes: set carry
#if def	HD_DEBUG
	stc
hd_exit2:	pushf
	test	byte [m_kbf],kb_fscrs	;scroll lock ?
	jnz	int13dmp2	;yes: don't display
	call	v_dump2	;& dump registers
int13dmp2:	popf
#else
hd_exit2:
#endif
	popa		;restore registers
	pop	es
	pop	ds
	iret		;return from interrupt
	;
	; IDE vector table
	;
	even
hd_vectab: dw	hd_rst	;AH=00: recalibrate drive
	dw	hd_status	;AH=01: get status
	dw	hd_read	;AH=02: read
	dw	hd_write	;AH=03: write
	dw	hd_verify	;AH=04: verify
          dw	hd_badcmd	;AH=05: format track -> not supported
	dw	hd_badcmd	;AH=06: bad
	dw	hd_badcmd	;AH=07: bad
	dw	hd_getprm	;AH=08: read drive parameters
	dw	hd_setprm	;AH=09: set drive parameters
	dw	hd_badcmd	;AH=0A: read long -> not supported
	dw	hd_badcmd	;AH=0B: write long -> not supported
	dw	hd_seek	;AH=0C: seek
	dw	hd_rst2	;AH=0D: alternate disk reset (HD only)
	dw	hd_badcmd	;AH=0E: bad
	dw	hd_badcmd	;AH=0F: bad
	dw	hd_trdy	;AH=10: test drive ready
	dw	hd_recal	;AH=11: recalibrate
	dw	hd_badcmd	;AH=12: bad
	dw	hd_badcmd	;AH=13: bad
	dw	hd_diag	;AH=14: controller diagnostics
	dw	hd_gettyp	;AH=15: get drive type
	dw	hd_badcmd	;AH=16: bad
	dw	hd_badcmd	;AH=17: bad
	dw	hd_badcmd	;AH=18: bad
	dw	hd_badcmd	;AH=19: bad
	dw	hd_badcmd	;AH=1A: bad
	dw	hd_badcmd	;AH=1B: bad
	dw	hd_badcmd	;AH=1C: bad
	dw	hd_badcmd	;AH=1D: bad
	dw	hd_badcmd	;AH=1E: bad
	dw	hd_badcmd	;AH=1F: bad
	dw	hd_badcmd	;AH=20: bad
	dw	hd_badcmd	;AH=21: bad
	dw	hd_badcmd	;AH=22: bad
#if def	HD_TIME
	dw	hd_timer	;AH=23: set standby timer NON-STANDARD
#else
	dw	hd_badcmd
#endif
	dw	hd_setmul	;AH=24: set multiple mode
	dw	hd_id	;AH=25: identify drive
#if def	HD_EDD
	dw	hd_badcmd	;AH=26: bad
	dw	hd_badcmd	;AH=27: bad
	dw	hd_badcmd	;AH=28: bad
	dw	hd_badcmd	;AH=29: bad
	dw	hd_badcmd	;AH=2A: bad
	dw	hd_badcmd	;AH=2B: bad
	dw	hd_badcmd	;AH=2C: bad
	dw	hd_badcmd	;AH=2D: bad
	dw	hd_badcmd	;AH=2E: bad
	dw	hd_badcmd	;AH=2F: bad
	dw	hd_badcmd	;AH=30: bad
	dw	hd_badcmd	;AH=31: bad
	dw	hd_badcmd	;AH=32: bad
	dw	hd_badcmd	;AH=33: bad
	dw	hd_badcmd	;AH=34: bad
	dw	hd_badcmd	;AH=35: bad
	dw	hd_badcmd	;AH=36: bad
	dw	hd_badcmd	;AH=37: bad
	dw	hd_badcmd	;AH=38: bad
	dw	hd_badcmd	;AH=39: bad
	dw	hd_badcmd	;AH=3a: bad
	dw	hd_badcmd	;AH=3b: bad
	dw	hd_badcmd	;AH=3c: bad
	dw	hd_badcmd	;AH=3d: bad
	dw	hd_badcmd	;AH=3e: bad
	dw	hd_badcmd	;AH=3f: bad
	dw	hd_badcmd	;AH=40: bad
	dw	hd_edd41	;AH=41: detect extended interface
	dw	hd_xrd	;AH=42: extended read
	dw	hd_xwr	;AH=43: extended write
	dw	hd_xver	;AH=44: extended verify
	dw	hd_badcmd	;AH=45: bad (lock / unlock drive)
	dw	hd_badcmd	;AH=46: bad (eject removable media)
	dw	hd_xsk	;AH=47: extended seek
	dw	hd_edd48	;AH=48: get extended parameters
#endif
hd_vec99:			;end of table
	;
	; AH=00: reset hard disk drives
	; AH=0D: alternate reset (doesn't reset floppy)
	;
hd_rst:	
hd_rst2:	cli
	in	al,pic1+1	;enable HD interrupt
	and	al,0bfh
	out	iowait,ax
	out	pic1+1,al
	
	in	al,pic0+1	;enable cascade interrupt
	and	al,0fbh
	out	iowait,ax
	out	pic0+1,al
	sti

	mov	dx,hdc_ctrl
	mov	al,4	;soft reset
	out	dx,al
	out	iowait,ax	;wait a bit
	out	iowait,ax
	out	iowait,ax
	out	iowait,ax
	out	iowait,ax
	mov	al,0	;end of reset, interrupt enable
	out	dx,al	;hdc_ctrl
	call	hd_busy18	;wait while busy
	jb	hd_rst8	;:error
	mov	dx,hdc_err	;check error status
	in	al,dx
	and	al,7fh
	sub	al,1
	jnz	hd_rst8	;:bad status
	mov	al,0	;ok status
	jmp	hd_exit0	;return
	
hd_rst8:	mov	al,5	;reset failed
hd_rst9:	jmp	hd_exit0
	;
	; AH=02: read sectors
	;
hd_read:	call	hd_sel	;select drive
	jb	hd_read9
	call	hd_chs	;translate CHS
	jb	hd_read9
	mov	bl,[bp._al]	;get sector count
	cld		;forward mode
	mov	di,[bp._bx]	;get destination address
	mov	byte [m_hdflag],0	;clear interrupt flag
	mov	al,20h	;issue read command
	mov	dx,hdc_cmd
	out	dx,al
	
hd_read1:	call	hd_int	;wait for interrupt
	jb	hd_read9
	mov	dl,low(hdc_stat)	;read status
	in	al,dx
	mov	byte [m_hdflag],0	;clear interrupt flag for next
	test	al,1	;ERR ?
	jnz	hd_read8
	test	al,8	;DRQ ?
	jz	hd_read8	;:no
	mov	dl,low(hdc_dat)	;read 512 bytes from drive
	mov	cx,256
	rep	insw
	dec	bl	;another sector ?
	jnz	hd_read1	;:yes
hd_read8:	sub	byte [bp._al],bl	;adjust sector count to reality
	call	hd_stat	;get status
hd_read9:	jmp	hd_exit0
	;
	; AH=03: write sectors
	;
hd_write:	mov	si,bx	;source address
	call	hd_sel	;select drive
	jb	hd_writ9
	call	hd_chs	;translate CHS
	jb	hd_writ9
	mov	bl,[bp._al]	;get sector count
	cld		;forward mode
	mov	al,30h	;issue write command
	mov	dx,hdc_cmd
	out	dx,al
	
hd_writ1:	mov	dl,low(hdc_stat)	;read status
	xor	cx,cx
	mov	byte [m_hdflag],0	;clear interrupt flag for next
hd_writ2:	in	al,dx
	test	al,8	;DRQ ?
	jnz	hd_writ3	;:yes
	test	al,21h	;error ?
	jnz	hd_writ8
	loop	hd_writ2
	mov	al,80h	;time-out
	jmp	short hd_writ9
	
hd_writ3:	mov	dl,low(hdc_dat)	;write 512 bytes from drive
	mov	cx,256
	es: rep	outsw
	call	hd_int	;wait for interrupt
	jb	hd_writ9
	dec	bl	;another sector ?
	jnz	hd_writ1	;:yes
		
hd_writ8:	call	hd_stat	;get status
hd_writ9:	jmp	hd_exit0
	;
	; AH=04: verify sectors
	;
hd_verify: call	hd_sel	;select drive
	jb	hd_ver9
	call	hd_chs	;translate CHS
	mov	al,40h
	call	hd_cmd	;read verify command	
	jb	hd_ver9
	call	hd_stat	;get status
hd_ver9:	jmp	hd_exit0
	;
	; AH=08: get drive parameters
	;
hd_getprm: cmp	byte [m_hdcnt],0	;no drives ?
	jnz	hd_getp1
	jmp	hd_badcmd	;:bad command
	
hd_getp1:	call	hd_parm	;get ^parameters
	mov	al,7	;invalid drive number
	mov	cx,0	;return 0 size
	mov	dx,0
	jb	hd_getp9	;:not present

	mov	dh,[cs:di.dpt_head]	;DH = max head number
	dec	dh
	mov	dl,[m_hdcnt]	;DL = number of drives
	mov	cx,[cs:di.dpt_cyl]	;CX = max cylinders (swapped)
	dec	cx	;-2 for diag, max cyl
	dec	cx
	cmp	cx,1023	;limit cylinder to 1023
	jbe	hd_getp2
	mov	cx,1023
hd_getp2:	xchg	cl,ch
	shl	cl,6	;CL high 6 bits = cylinders high
	or	cl,[cs:di.dpt_sec]	;CL = number of sectors
	mov	al,0	;clear status

hd_getp9:	mov	[bp._cx],cx	;cylinder count
	mov	[bp._dx],dx	;number drives, heads
	jmp	hd_exit0
	;
	; AH=09: set drive parameters
	;
hd_setprm: call	hd_sel	;select drive
	jb	hd_setp9
	mov	ah,[cs:di.dpt_phd]	;number heads (physical)
	dec	ah
	mov	dx,hdc_drv	;set maximum heads
	in	al,dx
	or	al,ah
	out	dx,al
	mov	al,[cs:di.dpt_psec]	;(physical)
	mov	dl,low(hdc_cnt)	;sector count
	out	dx,al
	mov	al,91h	;set drive parameters
	call	hd_cmd
	jb	hd_setp9	;:error
	call	hd_stat	;check status		
hd_setp9:	jmp	hd_exit0
	;

⌨️ 快捷键说明

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