FDC error: cannot find ID address mark

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
johank
Posts: 7
Joined: Sun Dec 20, 2009 5:25 pm

FDC error: cannot find ID address mark

Post by johank »

Hi all,

Frustratingly, I keep on encountering 'real PC' errors with my FDC code that do not encounter under Bochs, both when booting from an image file and when booting from floppy. When reading a sector, using a FDC_READ (0x06) command, all is well in Bochs but two PCs, both an old 486 and a new Pentium 4, complain of a missing ID address mark.

I use WinImage to create an image, inserting files to it, and either run Bochs to use the image or write the image on a floppy (using Windows XP) and boot from floppy. I found some issues on the web on Win XP and the above ID address mark error, but I doubt whether it denotes the same problem.

Here's the relevant part of the code:

Code: Select all

void floppy_read(unsigned char head, unsigned char cylinder, void *address)
{
	int i, retries = 5;
	while (retries)
	{
		set_system_timer(FDC_TIMER, 1000);			/* timeout on FDC activity */
		fdc_motor_on();
		if (!implied_seeks)							/* to be used on older drives */
			floppy_seek(head, cylinder);
		setup_DMA_channel(FDC_DMA, 0x44, 0x2400, (unsigned int) address);	
		/* to mem, single transfer, 0x2400 bytes = 18 sectors */
		fdc_sendbyte(FDC_READ | 0x60); 				/* read command MFM/SK set MT clear */
		fdc_sendbyte(head * 4);						/* bits 0 and 1 denote drive number ( = 0) */
		fdc_sendbyte(cylinder);						/* send head */
		fdc_sendbyte(head);							/* resend head */
		fdc_sendbyte(1);							/* first sector */
		fdc_sendbyte(2);							/* sector size = 512 */
		fdc_sendbyte(18);							/* 18 sectors per cylinder */
		fdc_sendbyte(27);							/* GPL gap length */
		fdc_sendbyte(0xFF);							/* DTL special code (ff = not used) */
		while ((get_system_timer(FDC_TIMER)) && (fdc_done == 0))
			;										/* wait till fdc isr signals fdc ready */
		fdc_done = 0;								/* reset fdc-done flag */
		if (!get_system_timer(FDC_TIMER))			/* timer zero's out - no good - retry */
		{
			panic(KERN_NOTICE, "Timeout on floppy read");
			floppy_error = FDC_READ_TIMEOUT;
			retries--;
			break;
		}
		
		for (i = 0; i < 7; i++)						/* get the status bytes */
			fdc_statusbytes[i] = fdc_readbyte();
		
		if ((fdc_statusbytes[0] & 0xC0) != 0x00)	/* any error indicated? */
		{
			panic(KERN_NOTICE, "Read error in FDC driver\n%s", FDC_status_error(fdc_statusbytes[0], 
				fdc_statusbytes[1], fdc_statusbytes[2]));
			panic(KERN_NOTICE, "Retrying to read");
			floppy_error = FDC_READ_ERROR;
			retries--;
		}
		else										/* all's well! */
		{
			floppy_error = NO_ERROR;
			retries = 0;
		}
	}
}
Has any of you encountered similar problems before?

Best,
Johan
M2004
Member
Member
Posts: 65
Joined: Sun Mar 07, 2010 2:12 am

Re: FDC error: cannot find ID address mark

Post by M2004 »

First thing that crosses my mind: Is the timer delay long enough?

regards
Mac2004
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: FDC error: cannot find ID address mark

Post by Brendan »

Hi,
johank wrote:Has any of you encountered similar problems before?
I vaguely remember writing some code to auto-detect media formats, where it'd try different data rates until it found one that was able to read the first sector of the disk. I'd assume that using the wrong data rate would cause a "missing address mark" error (as the drive can't read anything from the disk), and I also wouldn't be surprised if Bochs didn't emulate different data rates properly (e.g. just loads sectors without checking if you've set the data rate correctly).

Note: the default data rate is 250 Kbps, which is mostly useless (only used for 360 KiB single-sided floppies and 720 KiB double sided floppies). For 1200 KiB and 1440 KiB floppies you want to change the data rate to 500 Kbps (in the "data rate select register"). Every time you change the data rate you also need to calculate new values for HLT/HUT/SRT and set them with the "specify" command (which is a pain in the neck if you support dual drives with potentially different media).

Anyway, I'm only guessing - the problem could be something else, and could even be something like a faulty floppy disk.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: FDC error: cannot find ID address mark

Post by Brendan »

Hi,
mac2004 wrote:First thing that crosses my mind: Is the timer delay long enough?
Doh! Timing is a likely problem too - e.g. not having any delay after "fdc_motor_on();"...


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
M2004
Member
Member
Posts: 65
Joined: Sun Mar 07, 2010 2:12 am

Re: FDC error: cannot find ID address mark

Post by M2004 »

Brendan wrote: Doh! Timing is a likely problem too - e.g. not having any delay after "fdc_motor_on();"...
Floppies are slow and need quite long delays.

Regards
Mac2004
johank
Posts: 7
Joined: Sun Dec 20, 2009 5:25 pm

Re: FDC error: cannot find ID address mark

Post by johank »

Hi all,

thanks for your feedback up so far!

Re: timing: the motor_on function has a 0.5s delay (the calling process is put to sleep for 0.5s). The timeout is 50 seconds or so, which is reasonbly generous I think.

Re: data rate: indeed I had set it to 250 KiB and the error vanished!

However, a new error occurs: cannot find sector ID in st1 and wrong cylinder detected in st2...

But at least I'm getting somewhere!

best
Johan
Post Reply