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);
}