Bugfixes to usermode 64-bit division, more work on GUI (now sizes almost correctly)
[tpg/acess2.git] / Modules / Storage / FDD / fdd.c
index 58fb824..f72e548 100644 (file)
 #define FDD_VERSION     ((0<<8)|(75))\r
 \r
 // --- Options\r
-#define USE_CACHE      0       // Use Sector Cache\r
-#define        CACHE_SIZE      32      // Number of cachable sectors\r
 #define FDD_SEEK_TIMEOUT       10      // Timeout for a seek operation\r
 #define MOTOR_ON_DELAY 500             // Miliseconds\r
 #define MOTOR_OFF_DELAY        2000    // Miliseconds\r
+#define        FDD_MAX_READWRITE_ATTEMPTS      16\r
 \r
 // === TYPEDEFS ===\r
 /**\r
  * \brief Representation of a floppy drive\r
  */\r
-typedef struct {\r
+typedef struct sFloppyDrive\r
+{\r
         int    type;\r
        volatile int    motorState;     //2 - On, 1 - Spinup, 0 - Off\r
         int    track[2];\r
@@ -52,6 +52,9 @@ typedef struct {
 static const char      *cFDD_TYPES[] = {"None", "360kB 5.25\"", "1.2MB 5.25\"", "720kB 3.5\"", "1.44MB 3.5\"", "2.88MB 3.5\"" };\r
 static const int       cFDD_SIZES[] = { 0, 360*1024, 1200*1024, 720*1024, 1440*1024, 2880*1024 };\r
 static const short     cPORTBASE[] = { 0x3F0, 0x370 };\r
+#if DEBUG\r
+static const char      *cFDD_STATUSES[] = {NULL, "Error", "Invalid command", "Drive not ready"};\r
+#endif\r
 \r
 enum FloppyPorts {\r
        PORT_STATUSA    = 0x0,\r
@@ -82,25 +85,21 @@ enum FloppyCommands {
 // === PROTOTYPES ===\r
 // --- Filesystem\r
  int   FDD_Install(char **Arguments);\r
+void   FDD_UnloadModule();\r
+// --- VFS Methods\r
 char   *FDD_ReadDir(tVFS_Node *Node, int pos);\r
 tVFS_Node      *FDD_FindDir(tVFS_Node *dirNode, char *Name);\r
  int   FDD_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
 Uint64 FDD_ReadFS(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
-// --- 1st Level Disk Access\r
+// --- Functions for IOCache/DrvUtil\r
 Uint   FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint Disk);\r
 // --- Raw Disk Access\r
  int   FDD_ReadSector(Uint32 disk, Uint64 lba, void *Buffer);\r
  int   FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer);\r
 // --- Helpers\r
 void   FDD_IRQHandler(int Num);\r
-void   FDD_WaitIRQ();\r
+inline void    FDD_WaitIRQ();\r
 void   FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl);\r
-inline void    FDD_AquireSpinlock();\r
-inline void    FDD_FreeSpinlock();\r
-#if USE_CACHE\r
-inline void FDD_AquireCacheSpinlock();\r
-inline void FDD_FreeCacheSpinlock();\r
-#endif\r
 void   FDD_int_SendByte(int base, char byte);\r
  int   FDD_int_GetByte(int base);\r
 void   FDD_Reset(int id);\r
@@ -112,10 +111,10 @@ void      FDD_int_StartMotor(int disk);
  int   FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt);\r
 \r
 // === GLOBALS ===\r
-MODULE_DEFINE(0, FDD_VERSION, FDD, FDD_Install, NULL, NULL);\r
+MODULE_DEFINE(0, FDD_VERSION, FDD, FDD_Install, NULL, "ISADMA", NULL);\r
 t_floppyDevice gFDD_Devices[2];\r
-volatile int   fdd_inUse = 0;\r
-volatile int   fdd_irq6 = 0;\r
+tSpinlock      glFDD;\r
+volatile int   gbFDD_IrqFired = 0;\r
 tDevFS_Driver  gFDD_DriverInfo = {\r
        NULL, "fdd",\r
        {\r
@@ -128,11 +127,6 @@ tDevFS_Driver      gFDD_DriverInfo = {
        .IOCtl = FDD_IOCtl\r
        }\r
 };\r
-#if USE_CACHE\r
-int    siFDD_CacheInUse = 0;\r
-int    siFDD_SectorCacheSize = CACHE_SIZE;\r
-t_floppySector sFDD_SectorCache[CACHE_SIZE];\r
-#endif\r
 \r
 // === CODE ===\r
 /**\r
@@ -151,7 +145,11 @@ int FDD_Install(char **Arguments)
        gFDD_Devices[0].track[0] = -1;\r
        gFDD_Devices[1].track[1] = -1;\r
        \r
-       Log("[FDD ] Detected Disk 0: %s and Disk 1: %s", cFDD_TYPES[data>>4], cFDD_TYPES[data&0xF]);\r
+       Log_Log("FDD", "Detected Disk 0: %s and Disk 1: %s", cFDD_TYPES[data>>4], cFDD_TYPES[data&0xF]);\r
+       \r
+       if( data == 0 ) {\r
+               return MODULE_ERR_NOTNEEDED;\r
+       }\r
        \r
        // Clear FDD IRQ Flag\r
        FDD_SensInt(0x3F0, NULL, NULL);\r
@@ -169,7 +167,7 @@ int FDD_Install(char **Arguments)
        gFDD_Devices[0].Node.Flags = 0;\r
        gFDD_Devices[0].Node.NumACLs = 0;\r
        gFDD_Devices[0].Node.Read = FDD_ReadFS;\r
-       gFDD_Devices[0].Node.Write = NULL;//fdd_writeFS;\r
+       gFDD_Devices[0].Node.Write = NULL;//FDD_WriteFS;\r
        memcpy(&gFDD_Devices[1].Node, &gFDD_Devices[0].Node, sizeof(tVFS_Node));\r
        \r
        gFDD_Devices[1].Node.Inode = 1;\r
@@ -179,50 +177,57 @@ int FDD_Install(char **Arguments)
        gFDD_Devices[1].Node.Size = cFDD_SIZES[data & 0xF];\r
        \r
        // Create Sector Cache\r
-       #if USE_CACHE\r
-       //sFDD_SectorCache = malloc(sizeof(*sFDD_SectorCache)*CACHE_SIZE);\r
-       //siFDD_SectorCacheSize = CACHE_SIZE;\r
-       #else\r
-       if( cFDD_SIZES[data >> 4] ) {\r
+       if( cFDD_SIZES[data >> 4] )\r
+       {\r
                gFDD_Devices[0].CacheHandle = IOCache_Create(\r
                        FDD_WriteSector, 0, 512,\r
                        gFDD_Devices[0].Node.Size / (512*4)\r
                        );      // Cache is 1/4 the size of the disk\r
        }\r
-       if( cFDD_SIZES[data & 15] ) {\r
+       if( cFDD_SIZES[data & 15] )\r
+       {\r
                gFDD_Devices[1].CacheHandle = IOCache_Create(\r
                        FDD_WriteSector, 0, 512,\r
                        gFDD_Devices[1].Node.Size / (512*4)\r
                        );      // Cache is 1/4 the size of the disk\r
        }\r
-       #endif\r
        \r
        // Register with devfs\r
        DevFS_AddDevice(&gFDD_DriverInfo);\r
        \r
-       return 1;\r
+       return MODULE_ERR_OK;\r
+}\r
+\r
+/**\r
+ * \brief Prepare the module for removal\r
+ */\r
+void FDD_UnloadModule()\r
+{\r
+        int    i;\r
+       //DevFS_DelDevice( &gFDD_DriverInfo );\r
+       LOCK(&glFDD);\r
+       for(i=0;i<4;i++) {\r
+               Time_RemoveTimer(gFDD_Devices[i].timer);\r
+               FDD_int_StopMotor(i);\r
+       }\r
+       RELEASE(&glFDD);\r
+       //IRQ_Clear(6);\r
 }\r
 \r
 /**\r
  * \fn char *FDD_ReadDir(tVFS_Node *Node, int pos)\r
  * \brief Read Directory\r
  */\r
-char *FDD_ReadDir(tVFS_Node *Node, int pos)\r
+char *FDD_ReadDir(tVFS_Node *Node, int Pos)\r
 {\r
        char    name[2] = "0\0";\r
-       //Update Accessed Time\r
-       //gFDD_DrvInfo.rootNode.atime = now();\r
-       \r
-       //Check for bounds\r
-       if(pos >= 2 || pos < 0)\r
-               return NULL;\r
+\r
+       if(Pos >= 2 || Pos < 0) return NULL;\r
        \r
-       if(gFDD_Devices[pos].type == 0)\r
-               return VFS_SKIP;\r
+       if(gFDD_Devices[Pos].type == 0) return VFS_SKIP;\r
        \r
-       name[0] += pos;\r
+       name[0] += Pos;\r
        \r
-       //Return\r
        return strdup(name);\r
 }\r
 \r
@@ -295,9 +300,7 @@ int FDD_IOCtl(tVFS_Node *Node, int ID, void *Data)
 */\r
 Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
 {\r
-        int    i = 0;\r
-        int    disk;\r
-       //Uint32        buf[128];\r
+        int    ret;\r
        \r
        ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);\r
        \r
@@ -311,78 +314,12 @@ Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                return -1;\r
        }\r
        \r
-       disk = Node->Inode;\r
-       \r
-       // Update Accessed Time\r
-       Node->ATime = now();\r
-       \r
-       #if 0\r
-       if((Offset & 0x1FF) || (Length & 0x1FF))\r
-       {\r
-               // Un-Aligned Offset/Length\r
-                int    startOff = Offset >> 9;\r
-                int    sectOff = Offset & 0x1FF;\r
-                int    sectors = (Length + 0x1FF) >> 9;\r
-       \r
-               LOG("Non-aligned Read");\r
-               \r
-               //Read Starting Sector\r
-               if(!FDD_ReadSector(disk, startOff, buf))\r
-                       return 0;\r
-               memcpy(Buffer, (char*)(buf+sectOff), Length > 512-sectOff ? 512-sectOff : Length);\r
-               \r
-               // If the data size is one sector or less\r
-               if(Length <= 512-sectOff)\r
-               {\r
-                       LEAVE('X', Length);\r
-                       return Length;  //Return\r
-               }\r
-               Buffer += 512-sectOff;\r
-       \r
-               //Read Middle Sectors\r
-               for( i = 1; i < sectors - 1; i++ )\r
-               {\r
-                       if(!FDD_ReadSector(disk, startOff+i, buf)) {\r
-                               LEAVE('i', -1);\r
-                               return -1;\r
-                       }\r
-                       memcpy(Buffer, buf, 512);\r
-                       Buffer += 512;\r
-               }\r
-       \r
-               //Read End Sectors\r
-               if(!FDD_ReadSector(disk, startOff+i, buf))\r
-                       return 0;\r
-               memcpy(Buffer, buf, (len&0x1FF)-sectOff);\r
-               
-               LEAVE('X', Length);\r
-               return Length;\r
-       }\r
-       else\r
-       {\r
-                int    count = Length >> 9;\r
-                int    sector = Offset >> 9;\r
-               LOG("Aligned Read");\r
-               //Aligned Offset and Length - Simple Code\r
-               for( i = 0; i < count; i ++ )\r
-               {\r
-                       FDD_ReadSector(disk, sector, buf);\r
-                       memcpy(buffer, buf, 512);\r
-                       buffer += 512;\r
-                       sector++;\r
-               }
-               LEAVE('i', Length);\r
-               return Length;\r
-       }\r
-       #endif\r
-       \r
-       i = DrvUtil_ReadBlock(Offset, Length, Buffer, FDD_ReadSectors, 512, disk);\r
-       LEAVE('i', i);\r
-       return i;\r
+       ret = DrvUtil_ReadBlock(Offset, Length, Buffer, FDD_ReadSectors, 512, Node->Inode);\r
+       LEAVE('i', ret);\r
+       return ret;\r
 }\r
 \r
 /**\r
- * \fn Uint FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint32 Disk)\r
  * \brief Reads \a Count contiguous sectors from a disk\r
  * \param SectorAddr   Address of the first sector\r
  * \param Count        Number of sectors to read\r
@@ -406,140 +343,195 @@ Uint FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint Disk)
        return ret;\r
 }\r
 \r
-/**\r
- * \fn int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)\r
- * \brief Read a sector from disk\r
- * \todo Make real-hardware safe (account for read errors)\r
-*/\r
-int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)\r
+int FDD_int_ReadWriteSector(Uint32 Disk, Uint64 SectorAddr, int Write, void *Buffer)\r
 {\r
         int    cyl, head, sec;\r
         int    spt, base;\r
         int    i;\r
         int    lba = SectorAddr;\r
+       Uint8   st0, st1, st2, rcy, rhe, rse, bps;      //      Status Values\r
        \r
-       ENTER("idisk Xlba pbuf", disk, lba, buf);\r
+       ENTER("iDisk XSectorAddr pBuffer", Disk, SectorAddr, Buffer);\r
        \r
-       #if USE_CACHE\r
-       FDD_AquireCacheSpinlock();\r
-       for( i = 0; i < siFDD_SectorCacheSize; i++ )\r
-       {\r
-               if(sFDD_SectorCache[i].timestamp == 0)  continue;\r
-               if(sFDD_SectorCache[i].disk == Disk\r
-               && sFDD_SectorCache[i].sector == lba) {\r
-                       LOG("Found %i in cache %i", lba, i);\r
-                       memcpy(Buffer, sFDD_SectorCache[i].data, 512);\r
-                       sFDD_SectorCache[i].timestamp = now();\r
-                       FDD_FreeCacheSpinlock();\r
-                       LEAVE('i', 1);\r
-                       return 1;\r
-               }\r
-       }\r
-       LOG("Read %i from Disk", lba);\r
-       FDD_FreeCacheSpinlock();\r
-       #else\r
-       if( IOCache_Read( gFDD_Devices[Disk].CacheHandle, SectorAddr, Buffer ) == 1 ) {\r
-               LEAVE('i', 1);\r
-               return 1;\r
-       }\r
-       #endif\r
-       \r
-       base = cPORTBASE[Disk>>1];\r
+       base = cPORTBASE[Disk >> 1];\r
        \r
        LOG("Calculating Disk Dimensions");\r
        // Get CHS position\r
-       if(FDD_int_GetDims(gFDD_Devices[Disk].type, lba, &cyl, &head, &sec, &spt) != 1) {\r
+       if(FDD_int_GetDims(gFDD_Devices[Disk].type, lba, &cyl, &head, &sec, &spt) != 1)\r
+       {\r
                LEAVE('i', -1);\r
                return -1;\r
        }\r
+       LOG("Cyl=%i, Head=%i, Sector=%i", cyl, head, sec);\r
        \r
-       // Remove Old Timer\r
-       Time_RemoveTimer(gFDD_Devices[Disk].timer);\r
-       // Check if Motor is on\r
-       if(gFDD_Devices[Disk].motorState == 0) {\r
-               FDD_int_StartMotor(Disk);\r
-       }\r
+       LOCK(&glFDD);   // Lock to stop the motor stopping on us\r
+       Time_RemoveTimer(gFDD_Devices[Disk].timer);     // Remove Old Timer\r
+       // Start motor if needed\r
+       if(gFDD_Devices[Disk].motorState != 2)  FDD_int_StartMotor(Disk);\r
+       RELEASE(&glFDD);\r
        \r
-       LOG("Wait for Motor Spinup");\r
+       LOG("Wait for the motor to spin up");\r
        \r
        // Wait for spinup\r
        while(gFDD_Devices[Disk].motorState == 1)       Threads_Yield();\r
        \r
-       LOG("C:%i,H:%i,S:%i", cyl, head, sec);\r
        LOG("Acquire Spinlock");\r
-       \r
-       FDD_AquireSpinlock();\r
+       LOCK(&glFDD);\r
        \r
        // Seek to track\r
-       outb(base+CALIBRATE_DRIVE, 0);\r
+       outb(base + CALIBRATE_DRIVE, 0);\r
        i = 0;\r
-       while(FDD_int_SeekTrack(Disk, head, (Uint8)cyl) == 0 && i++ < FDD_SEEK_TIMEOUT )        Threads_Yield();\r
+       while(FDD_int_SeekTrack(Disk, head, (Uint8)cyl) == 0 && i++ < FDD_SEEK_TIMEOUT )\r
+               Threads_Yield();\r
+       if( i > FDD_SEEK_TIMEOUT ) {\r
+               RELEASE(&glFDD);\r
+               LEAVE('i', 0);\r
+               return 0;\r
+       }\r
        //FDD_SensInt(base, NULL, NULL);        // Wait for IRQ\r
-       \r
+               \r
+       // Read Data from DMA\r
        LOG("Setting DMA for read");\r
+       DMA_SetChannel(2, 512, !Write); // Read 512 Bytes from channel 2\r
        \r
-       //Read Data from DMA\r
-       DMA_SetChannel(2, 512, 1);      // Read 512 Bytes\r
-       \r
-       LOG("Sending read command");\r
+       LOG("Sending command");\r
        \r
        //Threads_Wait(100);    // Wait for Head to settle\r
        Time_Delay(100);\r
-       FDD_int_SendByte(base, READ_SECTOR);    // Was 0xE6\r
-       FDD_int_SendByte(base, (head << 2) | (Disk&1));\r
-       FDD_int_SendByte(base, (Uint8)cyl);\r
-       FDD_int_SendByte(base, (Uint8)head);\r
-       FDD_int_SendByte(base, (Uint8)sec);\r
-       FDD_int_SendByte(base, 0x02);   // Bytes Per Sector (Real BPS=128*2^{val})\r
-       FDD_int_SendByte(base, spt);    // SPT\r
-       FDD_int_SendByte(base, 0x1B);   // Gap Length (27 is default)\r
-       FDD_int_SendByte(base, 0xFF);   // Data Length\r
        \r
-       // Wait for IRQ\r
-       LOG("Waiting for Data to be read");\r
-       FDD_WaitIRQ();\r
+       for( i = 0; i < FDD_MAX_READWRITE_ATTEMPTS; i ++ )\r
+       {\r
+               if( Write )\r
+                       FDD_int_SendByte(base, READ_SECTOR);    // Was 0xE6\r
+               else\r
+                       FDD_int_SendByte(base, READ_SECTOR);    // Was 0xE6\r
+               FDD_int_SendByte(base, (head << 2) | (Disk&1));\r
+               FDD_int_SendByte(base, (Uint8)cyl);\r
+               FDD_int_SendByte(base, (Uint8)head);\r
+               FDD_int_SendByte(base, (Uint8)sec);\r
+               FDD_int_SendByte(base, 0x02);   // Bytes Per Sector (Real BPS=128*2^{val})\r
+               FDD_int_SendByte(base, spt);    // SPT\r
+               FDD_int_SendByte(base, 0x1B);   // Gap Length (27 is default)\r
+               FDD_int_SendByte(base, 0xFF);   // Data Length\r
+               \r
+               // Wait for IRQ\r
+               if( Write ) {\r
+                       LOG("Writing Data");\r
+                       DMA_WriteData(2, 512, Buffer);\r
+                       LOG("Waiting for Data to be written");\r
+                       FDD_WaitIRQ();\r
+               }\r
+               else {\r
+                       LOG("Waiting for data to be read");\r
+                       FDD_WaitIRQ();\r
+                       LOG("Reading Data");\r
+                       DMA_ReadData(2, 512, Buffer);\r
+               }\r
+               \r
+               // Clear Input Buffer\r
+               LOG("Clearing Input Buffer");\r
+               // Status Values\r
+               st0 = FDD_int_GetByte(base);\r
+               st1 = FDD_int_GetByte(base);\r
+               st2 = FDD_int_GetByte(base);\r
+               \r
+               // Cylinder, Head and Sector (mutilated in some way\r
+               rcy = FDD_int_GetByte(base);\r
+               rhe = FDD_int_GetByte(base);\r
+               rse = FDD_int_GetByte(base);\r
+               // Should be the BPS set above (0x02)\r
+               bps = FDD_int_GetByte(base);\r
+               \r
+               // Check Status\r
+               // - Error Code\r
+               if(st0 & 0xC0) {\r
+                       LOG("Error (st0 & 0xC0) \"%s\"", cFDD_STATUSES[st0 >> 6]);\r
+                       continue;\r
+        }\r
+        // - Status Flags\r
+        if(st0 & 0x08) {       LOG("Drive not ready"); continue;       }\r
+        if(st1 & 0x80) {       LOG("End of Cylinder"); continue;       }\r
+               if(st1 & 0x20) {        LOG("CRC Error");       continue;       }\r
+               if(st1 & 0x10) {        LOG("Controller Timeout");      continue;       }\r
+               if(st1 & 0x04) {        LOG("No Data Found");   continue;       }\r
+               if(st1 & 0x01 || st2 & 0x01) {\r
+                       LOG("No Address mark found");\r
+                       continue;\r
+               }\r
+        if(st2 & 0x40) {       LOG("Deleted address mark");    continue;       }\r
+               if(st2 & 0x20) {        LOG("CRC error in data");       continue;       }\r
+               if(st2 & 0x10) {        LOG("Wrong Cylinder");  continue;       }\r
+               if(st2 & 0x04) {        LOG("uPD765 sector not found"); continue;       }\r
+               if(st2 & 0x02) {        LOG("Bad Cylinder");    continue;       }\r
+               \r
+               if(bps != 0x2) {\r
+                       LOG("Returned BPS = 0x%02x, not 0x02", bps);\r
+                       continue;\r
+               }\r
+               \r
+               if(st1 & 0x02) {\r
+                       LOG("Floppy not writable");\r
+                       i = FDD_MAX_READWRITE_ATTEMPTS+1;\r
+                       break;\r
+               }\r
+               \r
+               // Success!\r
+               break;\r
+       }\r
        \r
-       // Read Data from DMA\r
-       LOG(" FDD_ReadSector: Reading Data");\r
-       DMA_ReadData(2, 512, Buffer);\r
+       // Release Spinlock\r
+       LOG("Realeasing Spinlock and setting motor to stop");\r
+       RELEASE(&glFDD);\r
+       \r
+       if(i == FDD_MAX_READWRITE_ATTEMPTS) {\r
+               Log_Warning("FDD", "Exceeded %i attempts in %s the disk",\r
+                       FDD_MAX_READWRITE_ATTEMPTS,\r
+                       (Write ? "writing to" : "reading from")\r
+                       );\r
+       }\r
        \r
-       // Clear Input Buffer\r
-       LOG("Clearing Input Buffer");\r
-       FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base);\r
-       FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base);\r
+       // Don't turn the motor off now, wait for a while\r
+       gFDD_Devices[Disk].timer = Time_CreateTimer(MOTOR_OFF_DELAY, FDD_int_StopMotor, (void*)Disk);\r
+\r
+       if( i < FDD_MAX_READWRITE_ATTEMPTS ) {\r
+               LEAVE('i', 0);\r
+               return 0;\r
+       }\r
+       else {\r
+               LEAVE('i', 1);\r
+               return 1;\r
+       }\r
+}\r
+\r
+/**\r
+ * \fn int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)\r
+ * \brief Read a sector from disk\r
+ * \todo Make real-hardware safe (account for read errors)\r
+*/\r
+int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)\r
+{\r
+        int    ret;\r
        \r
-       LOG("Realeasing Spinlock and Setting motor to stop");\r
-       // Release Spinlock\r
-       FDD_FreeSpinlock();\r
+       ENTER("iDisk XSectorAddr pBuffer", Disk, SectorAddr, Buffer);\r
        \r
-       //Set timer to turn off motor affter a gap\r
-       gFDD_Devices[Disk].timer = Time_CreateTimer(MOTOR_OFF_DELAY, FDD_int_StopMotor, (void*)Disk);   //One Shot Timer
+       if( IOCache_Read( gFDD_Devices[Disk].CacheHandle, SectorAddr, Buffer ) == 1 ) {\r
+               LEAVE('i', 1);\r
+               return 1;\r
+       }\r
+       \r
+       // Pass to general function\r
+       ret = FDD_int_ReadWriteSector(Disk, SectorAddr, 0, Buffer);
 \r
-       #if USE_CACHE\r
-       {\r
-               FDD_AquireCacheSpinlock();\r
-               int oldest = 0;\r
-               for(i=0;i<siFDD_SectorCacheSize;i++)\r
-               {\r
-                       if(sFDD_SectorCache[i].timestamp == 0) {\r
-                               oldest = i;\r
-                               break;\r
-                       }\r
-                       if(sFDD_SectorCache[i].timestamp < sFDD_SectorCache[oldest].timestamp)\r
-                               oldest = i;\r
-               }\r
-               sFDD_SectorCache[oldest].timestamp = now();\r
-               sFDD_SectorCache[oldest].disk = Disk;\r
-               sFDD_SectorCache[oldest].sector = lba;\r
-               memcpy(sFDD_SectorCache[oldest].data, Buffer, 512);\r
-               FDD_FreeCacheSpinlock();\r
+       if( ret == 0 ) {\r
+               IOCache_Add( gFDD_Devices[Disk].CacheHandle, SectorAddr, Buffer );
+               LEAVE('i', 1);\r
+               return 1;\r
+       }\r
+       else {\r
+               LOG("Reading failed");\r
+               LEAVE('i', 0);\r
+               return 0;\r
        }\r
-       #else\r
-       IOCache_Add( gFDD_Devices[Disk].CacheHandle, SectorAddr, Buffer );\r
-       #endif\r
-
-       LEAVE('i', 1);\r
-       return 1;\r
 }\r
 \r
 /**\r
@@ -648,18 +640,18 @@ int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt)
  */\r
 void FDD_IRQHandler(int Num)\r
 {\r
-    fdd_irq6 = 1;\r
+    gbFDD_IrqFired = 1;\r
 }\r
 \r
 /**\r
  * \fn FDD_WaitIRQ()\r
  * \brief Wait for an IRQ6\r
  */\r
-void FDD_WaitIRQ()\r
+inline void FDD_WaitIRQ()\r
 {\r
        // Wait for IRQ\r
-       while(!fdd_irq6)        Threads_Yield();\r
-       fdd_irq6 = 0;\r
+       while(!gbFDD_IrqFired)  Threads_Yield();\r
+       gbFDD_IrqFired = 0;\r
 }\r
 \r
 void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl)\r
@@ -671,30 +663,6 @@ void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl)
        else    FDD_int_GetByte(base);\r
 }\r
 \r
-void FDD_AquireSpinlock()\r
-{\r
-       while(fdd_inUse)\r
-               Threads_Yield();\r
-       fdd_inUse = 1;\r
-}\r
-\r
-inline void FDD_FreeSpinlock()\r
-{\r
-       fdd_inUse = 0;\r
-}\r
-\r
-#if USE_CACHE\r
-inline void FDD_AquireCacheSpinlock()\r
-{\r
-       while(siFDD_CacheInUse) Threads_Yield();\r
-       siFDD_CacheInUse = 1;\r
-}\r
-inline void FDD_FreeCacheSpinlock()\r
-{\r
-       siFDD_CacheInUse = 0;\r
-}\r
-#endif\r
-\r
 /**\r
  * void FDD_int_SendByte(int base, char byte)\r
  * \brief Sends a command to the controller\r
@@ -713,8 +681,9 @@ void FDD_int_SendByte(int base, char byte)
         }\r
         inb(0x80);     //Delay\r
     }\r
+       \r
        #if WARN\r
-               Warning("FDD_int_SendByte - Timeout sending byte 0x%x to base 0x%x\n", byte, base);\r
+       Warning("FDD_int_SendByte - Timeout sending byte 0x%x to base 0x%x\n", byte, base);\r
        #endif\r
 }\r
 \r
@@ -828,23 +797,12 @@ void FDD_int_StartMotor(int disk)
 void FDD_int_StopMotor(int disk)\r
 {\r
        Uint8   state;\r
+       if( IS_LOCKED(&glFDD) ) return ;\r
+       ENTER("iDisk", disk);\r
+       \r
        state = inb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT );\r
        state &= ~( 1 << (4+disk) );\r
        outb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT, state );\r
     gFDD_Devices[disk].motorState = 0;\r
-}\r
-\r
-/**\r
- * \fn void ModuleUnload()\r
- * \brief Prepare the module for removal\r
- */\r
-void ModuleUnload()\r
-{\r
-       int i;\r
-       FDD_AquireSpinlock();\r
-       for(i=0;i<4;i++) {\r
-               Time_RemoveTimer(gFDD_Devices[i].timer);\r
-               FDD_int_StopMotor(i);\r
-       }\r
-       //IRQ_Clear(6);\r
+    LEAVE('-');\r
 }\r

UCC git Repository :: git.ucc.asn.au