Programming the Floppy Disk Controller

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
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Programming the Floppy Disk Controller

Post by AlfaOmega08 »

I've just finished to program my fdc driver.
When I've tested it, it has worked on bochs (and I started jumping for the happiness), then on VMWare.

Here's the problem.
On VMWare it's like the interrupt never arrives. This happends on Resetting the fdc:

Code: Select all

void Floppy::Reset(Bit32u base, char drive) {
	outportb(base + FLOPPY_DOR, 0x00, true);	//Disable the controller
	outportb(base + FLOPPY_RSR, 0x00, true);	//Rate: 500Kb/s
	outportb(base + FLOPPY_DOR, 0x0C, true);	//Enable the controller

	cpu.waitForInterrupt(38);  //IT FREEZES HERE!!!

	{
		int st0, cyl;
		CheckInterrupt(base, &st0, &cyl);
	}

	outportb(base + FLOPPY_CCR, 0x00, true);
	ConfigureDrive(base);
	CalibrateDrive(base, drive);
}
the "true" at the end of some outportb stands for "inportb(80)" so there is a little delay...

Does anyone know why it doesn't work?

Thanks
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

Is the interrupt on the VM happening so fast that it happens before you get to:

Code: Select all

cpu.waitForInterrupt(38);



I have had a similar problem in a virtual environment before, where the hardware fires the interrupt instantaneously.

Cheers,
Adam
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

have the ISR print a message, so you know its worked
~ Lukem95 [ Cake ]
Release: 0.08b
Image
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

And, you could also implement a timeout, so when you are waiting it will return (and not just freeze), but displaying something to screen in the interrupt (Even if it's just writing a byte to the screen directly) will help determine if this is indeed your problem. Typically when I am waiting for an interrupt, I set the waiting flag BEFORE I send the command to the periferal, that way when I call my wait for interrupt, if the interrupt happens before my call to wait, the flag saying that it has triggered is already set and it immediately returns. Much nicer than missing interrupts and waiting for a timeout, then checking status to see what happened. So, it'd go something like this:

Code: Select all

volatile u32 IntTriggered[256]; //For interrupts

void Int38(void)
{
  IntTriggered[38] = 1;
}

void SetupIntWait(u32 which)
{
 IntTriggered[which] = 0;
}

u8 WaitInt(u32 which, u64 Timeout)
{
 Timeout+= GetCurrentMS();
  while (!IntTriggered[which] && Timeout > GetCurrentMS());
  return IntTriggered; //Return our status 1 = int triggered, 0 = timeout
}

void Floppy::Reset(Bit32u base, char drive) {
/* New */
   SetupIntWait(38);

   outportb(base + FLOPPY_DOR, 0x00, true);   //Disable the controller 
   outportb(base + FLOPPY_RSR, 0x00, true);   //Rate: 500Kb/s 
   outportb(base + FLOPPY_DOR, 0x0C, true);   //Enable the controller 

/* New */
   if (WaitInt(38,1000)) //Up to 1 second (1,000 ms)
   { 
      int st0, cyl; 
      CheckInterrupt(base, &st0, &cyl); 
   }
   else //Interrupt never fired, and timed out... problems
   {
      return; //Possibly an error code, or print to screen here!
   }

   outportb(base + FLOPPY_CCR, 0x00, true); 
   ConfigureDrive(base); 
   CalibrateDrive(base, drive); 
} 

Post Reply