#include <acess.h>
#include <modules.h>
#include <fs_devfs.h>
-#include <tpl_drv_disk.h>
+#include <api_drv_disk.h>
#include <dma.h>
#include <iocache.h>
int FDD_ReadSector(Uint32 disk, Uint64 lba, void *Buffer);
int FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer);
// --- Helpers
-void FDD_IRQHandler(int Num);
+void FDD_IRQHandler(int Num, void *Ptr);
inline void FDD_WaitIRQ();
void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl);
int FDD_int_SendByte(int base, Uint8 Byte);
int FDD_int_GetByte(int base, Uint8 *Byte);
int FDD_Reset(int id);
void FDD_Recalibrate(int disk);
+ int FDD_Reconfigure(int ID);
int FDD_int_SeekTrack(int disk, int head, int track);
void FDD_int_TimerCallback(void *Arg);
void FDD_int_StopMotor(void *Arg);
}
// Install IRQ6 Handler
- IRQ_AddHandler(6, FDD_IRQHandler);
+ IRQ_AddHandler(6, FDD_IRQHandler, NULL);
+
+ // Ensure the FDD version is 0x90
+ {
+ Uint8 tmp = 0;
+ FDD_int_SendByte(cPORTBASE[0], CMD_VERSION);
+ FDD_int_GetByte(cPORTBASE[0], &tmp);
+ if( tmp != 0x90 ) {
+ Log_Error("FDD", "Version(0x%2x) != 0x90", tmp);
+ return MODULE_ERR_NOTNEEDED;
+ }
+ }
+
+ // Configure
+ FDD_Reconfigure(0);
+
// Reset Primary FDD Controller
if( FDD_Reset(0) != 0 ) {
return MODULE_ERR_MISC;
*/
int FDD_int_SeekTrack(int disk, int head, int track)
{
- Uint8 sr0, cyl;
+ Uint8 sr0=0, cyl=0;
int base;
base = cPORTBASE[disk>>1];
// Set Track in structure
gFDD_Devices[disk].track[head] = track;
-
+
+ LOG("Time_Delay(100)");
// Wait for Head to settle
Time_Delay(100);
* \fn void FDD_IRQHandler(int Num)
* \brief Handles IRQ6
*/
-void FDD_IRQHandler(int Num)
+void FDD_IRQHandler(int Num, void *Ptr)
{
gbFDD_IrqFired = 1;
}
{
tTime end = now() + 1000; // 1s
- while( (inb(base + PORT_MAINSTATUS) & 0xC0) != 0x80 && now() < end )
+ while( (inb(base + PORT_MAINSTATUS) & 0x80) != 0x80 && now() < end )
Threads_Yield(); //Delay
+
+ if( inb(base + PORT_MAINSTATUS) & 0x40 ) {
+ Log_Warning("FDD", "FDD_int_SendByte: DIO set, is this ok?");
+ return -2;
+ }
if( now() < end )
{
{
tTime end = now() + 1000; // 1s
- while( (inb(base + PORT_MAINSTATUS) & 0xd0) != 0xd0 && now() < end )
+ while( (inb(base + PORT_MAINSTATUS) & 0x80) != 0x80 && now() < end )
Threads_Yield();
+ if( !(inb(base + PORT_MAINSTATUS) & 0x40) ) {
+ Log_Warning("FDD", "FDD_int_GetByte: DIO unset, is this ok?");
+ return -2;
+ }
+
if( now() < end )
{
Uint8 tmp = inb(base + PORT_DATA);
outb(base + PORT_DIGOUTPUT, 0); // Disable FDC
// Wait 4 microseconds - or use 1 thread delay
Threads_Yield();
- outb(base + PORT_DIGOUTPUT, 0x0C); // Re-enable FDC (DMA and Enable)
+ Threads_Yield();
+ outb(base + PORT_DIGOUTPUT, 8|4); // Re-enable FDC (DMA and Enable)
+ // Set the data rate
+ outb(base + PORT_DATARATE, 0); // Set data rate to 500K/s
+
+ // Wait for IRQ
LOG("Awaiting IRQ");
FDD_WaitIRQ();
+ LOG("4x SenseInterrupt");
FDD_SensInt(base, NULL, NULL);
FDD_SensInt(base, NULL, NULL);
FDD_SensInt(base, NULL, NULL);
FDD_SensInt(base, NULL, NULL);
- // Set the data rate
- outb(base + PORT_DATARATE, 0); // Set data rate to 500K/s
-
- // Configure
+ // Specify
FDD_int_SendByte(base, CMD_SPECIFY); // Step and Head Load Times
FDD_int_SendByte(base, 0xDF); // Step Rate Time, Head Unload Time (Nibble each)
FDD_int_SendByte(base, 0x02); // Head Load Time >> 1
+ // Recalibrate disks
+ LOG("Recalibrate disks (16x seek)");
retries = 16;
- while(FDD_int_SeekTrack(0, 0, 1) == 0 && retries --); // set track
- if(retries < 0) return -1;
+ while(FDD_int_SeekTrack(0, 0, 1) == 0 && retries --)
+ Threads_Yield(); // set track
+ if(retries < 0) LEAVE_RET('i', -1);
retries = 16;
- while(FDD_int_SeekTrack(0, 1, 1) == 0); // set track
- if(retries < 0) return -1;
+ while(FDD_int_SeekTrack(0, 1, 1) == 0 && retries --)
+ Threads_Yield(); // set track
+ if(retries < 0) LEAVE_RET('i', -1);
LOG("Recalibrating Disk");
FDD_Recalibrate((id<<1)|0);
FDD_Recalibrate((id<<1)|1);
- LEAVE('i',0);
- return 0;
+ LEAVE_RET('i', 0);
}
/**