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

📄 floppy.txt

📁 DOS下直接读取软盘扇区的程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
Hi,	Find enclosed dma.asi, floppy.p, floppy.asm, floppy.asi.  Note thatthese functions do NOT automatically retry on an error; in particular ifyou get error #6 the main code should try again.Two parameter tables are supplied; the first does 1024 byte sectorsand the second does 256 byte sectors.  If you need 512 bytes fill in theparameters appropriately... most of them are similar to the BIOS parametersor you can read the existing tables and guess what to change.Have fun,David-----------------------------DMA.ASI (header)--------------------------------; These macros only work for channels 0 - 3;DMAMODE_SINGLE = 40hDMAXFER_VERIFY = 0DMAXFER_WRITE = 4DMAXFER_READ = 8MACRO	DMA_CLEARBYTEFF	out	0ch,alENDM	DMA_CLEARBYTEFFMACRO	DMA_WRITEBASE	low,high,channel	mov	al,low	out     00+2*channel,al	jmp	$+2	mov	al,high	out     00+2*channel,al	jmp	$+2ENDM	DMA_WRITEBASEMACRO	DMA_WRITECOUNT	low, high, channel	mov	al,low	out	01+2*channel,al	jmp	$+2	mov	al,high	out	01+2*channel,al	jmp	$+2ENDM	DMA_WRITECOUNTMACRO	DMA_MASKOFF	channel	mov	al,channel	out	0ah,alENDM	DMA_MASKOFFMACRO	DMA_MASKON	channel	mov	al,channel OR 2	out	0ah,alENDM	DMA_MASKONMACRO	DMA_GETMODE	mode,transfer,channel	mov	al,mode OR transfer OR channelENDM	DMA_GETMODEMACRO	DMA_SETMODE	out	0bh,alENDM	DMA_SETMODEMACRO	DMA_SETPAGE	data,channel	mov	al,data	if	channel eq 0	out	87h,al	else	if	channel eq 1	out	83h,al	else	if	channel eq 2	out	81h,al	else	if	channel eq 3	out	82h,al	endif	endif	endif	endif	jmp	$+2ENDM	DMA_SETPAGE--------------------------floppy.p (prototype file)----------------------/* MKLibHead 1.00 Wednesday October 25, 1995  22:13:16 */#ifdef __cplusplusextern "C" {#endif // __cplusplus                             /* Floppy.asm */   DiskSetInts(void);   DiskResetInts(void);   int FormatTrack(BYTE *buffer, int drive, int track, int head);   int DiskIO(BYTE *buffer, int drive, int track, int sector, int head, int towrite);   void Disk1024(void);#ifdef __cplusplus}#endif // __cplusplus--------------------------floppy.asi (header)------------------------------MOTORSELECT = 3f2hDISKSTATUS = 3f4hDISKDATA = 3f5hINPUTSTATUS = 3F6HRATECONFIG = 3F7HDK_WRITE = 2DK_READ = 1SPEC_NODMA = 1FLOPPY_DMA = 2HEADSEL_BIT = 2CMD_SPECIFY = 3CMD_RECALIBRATE = 7CMD_SENSE = 8CMD_SEEK = 0FHCMD_READID = 4ahCMD_FORMAT = 04DHCMD_WRITE = 045HCMD_READ = 066HCSR_READY = 80hCSR_READ = 40hCSR_IOINPROG = 20hMTR_NOSELECT = 0fchMTR_DMA	= 8MTR_NORESET = 4MTR_MASKOFF = 0fhDTIME_MUL = 182DTIME_DIV = 100CHANGEABLE = 80hMULTIHEAD = 1struc	stdparamscmd	db	?drivehead db	?cylinder db	?head	db	?sector	db	?size	db	?eot	db	?gaplen	db	?cusize	db	?ends	stdparamsSR0_UNUSED =	7SR0_ABTERM = 	6SR0_SEEK   =	5SR0_RECALFAIL =	4SR1_SECTOOBIG = 7SR1_CRC	=	5SR1_OVERRUN =	4SR1_NODATA  =	2SR1_WRITEPROT = 1SR1_NOADDRESS = 0SR2_BADSEC =	6SR2_CRC	=	5SR2_WRONGCYL =	4SR2_BADCYL =	1SR2_MISSADDRESS = 0struc	stdresponsesr0	db	?sr1	db 	?sr2	db	?cylinder db	?head	db	?sector	db	?size	db	?ends	stdresponseDERR_NONE	=	0DERR_INVFUNC	=	1DERR_NOADDRESS	=	2DERR_WRITEPROT	=	3DERR_NOSECT	=	4DERR_CHANGED	=	6DERR_DMAOVER	=	8DERR_DMABOUND	=	9DERR_BADMEDIA	=	0CHDERR_BADCRC	=	10HDERR_CTRLFAIL	=	20HDERR_SEEKFAIL	=	40HDERR_TIMEOUT	=	80HSTRUC	diskparmsteploadul	dw	4 DUP (?)media		db	4 DUP (?)turnoff		db	4 DUP (?)hptchange	db	4 DUP (?)tpd		db	4 DUP (?)bpsspt		dw	4 DUP (?)fglfill		dw	4 DUP (?)settle		db	4 DUP (?)pup		db	4 DUP (?)ENDS	diskparm--------------------------------floppy.asm-------------------------------;; floppy.asm (DMA version);; Function: 1.44MB floppy driver ( 4 drives);   Handles floppy interrupt;   Handles managing floppy controller and DMA system;   Handles read/write format;   Handles OS floppy calls;	IDEAL	model	large,C	P386	public	DiskSetInts,DiskResetInts,DiskIO,FormatTrack,Disk1024include "floppy.asi"include "dma.asi"	STACK	DATASEGdone	    dw	0			; Set true when an interrupt completessectorsize dw 256             		; Size of a sectortransfercount dw 0			; size to transferturnofftime dw	0			; Ticks till disk turnoffcountime    dw	0			; Ticks while delayingmotors	db	0			; Motor on specifierresponsebuf db	7 DUP (?)		; Controller response buffercalibrated db	0			; Calibration control flagserror	db	0			; Error foundtracks	db	4 DUP (?)		; Register current diskette tracks;; 256 byte sectors (default)parmtable dw	2a1h,2a1h,2a1h,2a1h	; Diskette params, see DISKPARAM struc	db	0,0,0,0	db	20,20,20,20	db	81h,81h,81h,81h	db	80,80,80,80	dw	2201h,2201h,2201h,2201h	dw	00028h,00028h,00028h,00028h	db	0fh,0fh,0fh,0fh	db	10,10,10,10;; 1024 byte sectors;parmtable2 dw	2a1h,2a1h,2a1h,2a1h	; Diskette params, see DISKPARAM struc	db	0,0,0,0	db	20,20,20,20	db	81h,81h,81h,81h	db	80,80,80,80	dw	0a03h,0a03h,0a03h,0a03h	dw	0c48ch,0c48ch,0c48ch,0c48ch	db	0fh,0fh,0fh,0fh	db	10,10,10,10sop = $ - parmtable2;; Tenths to ticks conversion;	CODESEGbufpos	dd	?multiplier dw	DTIME_MULdivisor	dw	DTIME_DIVoldint8	dd	?oldinte	dd	?cmd	db	DK_READ;; Timer interrupt;PROC	FloppyTimerInt	push	ax	push	ds	push	dgroup	pop	ds	test	[turnofftime],-1	; See if turnofftime active	jz	short noturnoff		; No	dec	[turnofftime]		; Yes, decrement	jnz	short noturnoff		; Not done	push	dx			; Else save dx	and	[motors],MTR_MASKOFF	; Kill all motors	mov	al,[motors]		; Inform controller	mov	dx,MOTORSELECT		;	out	dx,al			;	pop	dx			;noturnoff:	test	[countime],-1		; See if delaying	jz	short notcount		;	dec	[countime]		; Yes, decrement	jnz	short notcount		; Not done	or	[done],3		; Else inform tasknotcount:	mov	al,20h	out	20h,al	pop	ds	pop	ax	iretENDP	FloppyTimerInt;; Floppy controller interrupt, interrupts after certain commands;PROC	FloppyInt	push	ax	push	ds	push	DGROUP			;	pop	ds			;	or	[done],1		; Mark controller came	mov	al,20h	out	20h,al	pop	ds	pop	ax			; and ax	iretENDP	FloppyInt;; Stop the timer;PROC	StopTimer	mov	[countime],0		; Kill count time	and	[done],0		; Reset done flag	retENDP	StopTimer;; Start the timer;PROC	StartTimer	push	dx			; Convert to ticks	mul	[multiplier]		;	div	[divisor]		;	pop	dx			;SimpleStartTimer:	inc	ax			; Make sure at least 1	mov	[countime],ax		; Set timer	and	[done],0		; Reset done flag	retENDP	StartTimer;; Wait till done flag goes true;PROC	WaitDone	mov	ax,[done]	or	ax,ax	jz	WaitDone	retENDP	WaitDone;; Wait for controller to be ready;PROC	WaitControllerReady	mov	ax,2			; Give it two clock ticks	call	far SimpleStartTimer	;wcr_lp:	mov	dx,DISKSTATUS		; Poll status reg	in	al,dx			;	test	al,CSR_READY		; See if ready bit set	jnz	short wcr_ok		; Get out if so	test	[done],1	jz	wcr_lp			; Loop if not	call	StopTimer		; Timed out	mov	al,DERR_CTRLFAIL	; Mark controller fail	mov	[error],al		;	stc	retwcr_ok:	call	StopTimer		; Stop timer	clc				; Everything ok	retENDP	WaitControllerReady;; Read a byte from controller;PROC	ReadControllerData	call	WaitControllerReady	; Wait for ready	jc	short rcd_fail		; In case fail	mov	dx,DISKDATA		; Get data reg	in	al,dx			; Get data	clc				; Life is okrcd_fail:	retENDP	ReadControllerData;; Read the standard response from the controller;PROC	ReadSevenResponse	mov	cl,7			; 7 bytes to read	mov	di,offset responsebuf	; Get bufferReadRespLoop:	call	ReadControllerData	; Read a byte	jc	short rsr_fail		; if it is raining	mov	[di],al	    		; otherwise Save char in buf	inc	di			;	dec	cl			; Next byte	jnz	short ReadRespLoop	;	clc				; Everything finersr_fail:	retENDP	ReadSevenResponse;; Write data to controller;PROC	WriteControllerDataC	jc	short wcd_fail		; Skip out if previous errorWriteControllerData:	mov	bl,al			; bl gets the char	call	WaitControllerReady	; Wait for ready	jc	short wcd_fail2		; bail out if fail	test	al,CSR_READ		; Make sure direction = toward controller	mov	al,bl			; Get the char	jnz	short wcd_fail		; Bail out if wrong dir	mov	dx,DISKDATA		; Get data register	out	dx,al			; Output a byte	clc				; no errorswcd_fail2:	retwcd_fail:	call	ReadSevenResponse	; Wrong dir, empty controller output buf	mov	al,DERR_CTRLFAIL	; Signal a fail	mov	[error],al		;	stc				;	retENDP	WriteControllerDataC;; Turn on motor;PROC	MotorOn	mov	[turnofftime],0		; NEver turn off	and	[motors],MTR_NOSELECT	; Kill select	or	[motors],al		; Set new select	or	[motors],MTR_DMA OR MTR_NORESET ; ints and dma enabled	add	al,4			; Get motor bit to turn on	push	ax	push	cx	mov	cl,al	mov	ax,1	shl	ax,cl	pop	cx	test	[word ptr motors],ax	pushf	or	[word ptr motors],ax	mov	al,[motors]		; Which motors	mov	dx,MOTORSELECT		; Motor reg	out	dx,al			;	popf	pop	ax			;	jnz	short alreadyon         ; No waiting if already on	sub	al,4			; Else get drive pup value	and	eax,0ffffh	lea	edi,[eax + DISkPARM.PUP]	add	di,offset parmtable	; In parm table	movzx	ax,[byte ptr di]	;	call	StartTimer              ; Start the timer	call	WaitDone		; Wait for timeoutalreadyon:	clc				; Never an error with select	retENDP	MotorOn;; Check if disk change;PROC	Changed	and	eax,0ffffh	lea	edi,[eax+DISKPARM.HPTCHANGE]	add	di,offset parmtable	;	test	[byte ptr di],CHANGEABLE;	jz	short notchanging       ; No, just exit	push	ax			; Else read the digital input reg	mov	dx,RATECONFIG		;	in	al,dx			;	or	al,al			;	pop	ax                     ;	jns	short notchanging       ; Bit 7 is change line, 0=not changed	push	ax			; It changed, we have to have a head	push	cx			; move to reset the flipflop	mov	ch,7			;	call	far seek			;	pop	cx			;	pop	ax			;	push	ax			;	call	far home			; Now bring us back home	pop	ax			;	mov	ax,4			; Delay just a bit	call	far SimpleStartTimer        ;	call	WaitDone     		;	mov	dx,RATECONFIG           ; Read change line again	in	al,dx			;	or	al,al			;	mov	al,DERR_CHANGED		; Assume a disk present	jns	short missing		; yes, get out	mov	al,DERR_TIMEOUT		; Else no diskmissing:	stc				; We have an error	mov	[error],al		;	ret				;notchanging:	clc				; Life is fine	retENDP	Changed;; Send the disk specify command;PROC	Specify	and	eax,0ffffh	lea	esi,[eax*2 + DISKPARM.STEPLOADUl]	add	si,offset parmtable	;	mov	al,CMD_SPECIFY          ; Specify command	call	far WriteControllerData	;	lodsb				; Step and load time	call	WriteControllerDataC	;	lodsb				; Unload time;	or	al,SPEC_NODMA	call	WriteControllerDataC	;; No interrupt for this command	retENDP	Specify;; Find out if seek succeeded;PROC	SenseInterruptStatus	mov	al,CMD_SENSE		; Sense command	call	far WriteControllerData; No interrupt this command	jc	short sis_fail	call	ReadControllerData	; First response byte	jc	short sis_fail	mov	ah,al	call	ReadControllerData	; Second response bytesis_fail:	retENDP	SenseInterruptStatus;; Home the drive head;PROC	Home	push	ax	push	cx	mov	cx,ax	mov	ax,1	shl	ax,cl	pop	cx

⌨️ 快捷键说明

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