Page 1 of 1

i/o floppy doesn't work everywhere

Posted: Fri Nov 02, 2007 4:23 am
by sevobal
Hi,
I've written a simple routine to read a sector from a floppy disc (in protected mode). On some real PCs it's working on some not. And Bochs gives me also an error saying "<< PANIC >> write 0x03f5: receiving new command 0x46, old one (0x0f) pending."

Here is the code:

Code: Select all

;turn motor a on, disable IRQ and DMA, select drive 00h (A:)
	mov dx, 0x3f2
	mov al, 00010100b
	out dx, al
	
	;Seek Track command
	mov dx, 0x3f5
	mov al, 00001111b
	out dx, al
	
	mov al, 00000100b	; Select Head 1 on drive 00
	out dx, al
	
	mov al, 0x00		;Cylinder 0
	out dx, al

	mov dx,3F4h
	in al,dx 
	
	mov cl, 0x01
	mov bl, 0x00
	
	;Read sector command
	mov dx, 0x3f5
	mov al, 01000110b
	out dx, al
	
	mov al, 00000100b	; Select Head 1 on drive 00
	out dx, al
	
	mov al, bl			; Cylinder 0
	out dx, al
	
	mov al, 0x01		; Head 1
	out dx, al
	
	mov al, cl		; Sector 1
	out dx, al
	
	mov al, 0x02		; 512 Bytes per sector
	out dx, al
	
	mov al, 0x12		; 18 sectors per track
	out dx, al
	
	mov al, 0x1B		; length of GAP (27 normal so 0x1B)
	out dx, al
	
	mov al, 0xff		; must be 0xff
	out dx, al
		
	mov edi, [vbe_lfb]
	
	mov dx, 0x3F5
	mov ecx, 512
	mov di, [es:edi]
	rep insb
What should I change to get this 100% work. What I'm doing wrong? The commands should be correct, I've got them form the intel document for fdc's

Posted: Fri Nov 02, 2007 4:59 am
by AJ
Hi,

It strikes me as odd that there are absolutely no delays in there whatsoever. I haven't written a FD driver myself, but it frequently comes up on the forum that if a floppy driver sometimes works in emulation but not on a real machine, you need to introduce delays (I believe that even 500msec after spin-up is not a bad idea). I would say that Bochs' error message seems to tie in with this theory quite nicely.

Also, you cannot assume that on a floppy the read will work on the first attempt. You need to be reading in 5-6 times to ensure that you are getting valid data.

HTH
Adam

Posted: Fri Nov 02, 2007 5:04 am
by sevobal
I don't know how to delay in nasm :( or how to write a delay function. But the error message said, that he is still at the seek command and so he cannot perform the read command.

Posted: Fri Nov 02, 2007 5:23 am
by AJ
OK - I believe you have a few options:

1) A crude way - introduce a big loop in to your code.
2) A nicer way - if your OS can handle interrupts nicely, write a sleep() system call, which can either wait for a time limit *or*
3) Get the floppy drive to issue an interrupt when it has completed the seek (could someone who knows more than me confirm that this can happen?). If you are multitasking, the floppy drive-reading task can be woken from its sleep() when the command has completed.

Cheers,
Adam