+++ /dev/null
-/**\r
- * \file drv_bochsvbe.c\r
- * \brief BGA (Bochs Graphic Adapter) Driver\r
- * \note for AcessOS Version 1\r
- * \warning This driver does NOT support the Bochs PCI VGA driver\r
-*/\r
-#include <common.h>\r
-#include <modules.h>\r
-#include <vfs.h>\r
-#include <fs_devfs.h>\r
-#include <drv_pci.h>\r
-#include <tpl_drv_video.h>\r
-\r
-#define DEBUG 0\r
-#if DEBUG\r
-# define DEBUGS(v...) SysDebug(v)\r
-#else\r
-# define DEBUGS(v...)\r
-#endif\r
-\r
-//#define INT static\r
-#define INT\r
-\r
-// === TYPEDEFS ===\r
-typedef struct {\r
- Uint16 width;\r
- Uint16 height;\r
- Uint16 bpp;\r
- Uint16 flags;\r
- Uint32 fbSize;\r
-} t_bga_mode;\r
-\r
-// === CONSTANTS ===\r
-enum eMode_Flags {\r
- MODEFLAG_TEXT = 1\r
-};\r
-#define BGA_LFB_MAXSIZE (1024*768*4)\r
-#define VBE_DISPI_BANK_ADDRESS 0xA0000\r
-#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000\r
-#define VBE_DISPI_IOPORT_INDEX 0x01CE\r
-#define VBE_DISPI_IOPORT_DATA 0x01CF\r
-#define VBE_DISPI_DISABLED 0x00\r
-#define VBE_DISPI_ENABLED 0x01\r
-#define VBE_DISPI_LFB_ENABLED 0x40\r
-#define VBE_DISPI_NOCLEARMEM 0x80\r
-enum {\r
- VBE_DISPI_INDEX_ID,\r
- VBE_DISPI_INDEX_XRES,\r
- VBE_DISPI_INDEX_YRES,\r
- VBE_DISPI_INDEX_BPP,\r
- VBE_DISPI_INDEX_ENABLE,\r
- VBE_DISPI_INDEX_BANK,\r
- VBE_DISPI_INDEX_VIRT_WIDTH,\r
- VBE_DISPI_INDEX_VIRT_HEIGHT,\r
- VBE_DISPI_INDEX_X_OFFSET,\r
- VBE_DISPI_INDEX_Y_OFFSET\r
-};\r
-\r
-\r
-// === PROTOTYPES ===\r
-// Driver\r
- int BGA_Install(char **Arguments);\r
-void BGA_Uninstall();\r
-// Internal\r
-void BGA_int_WriteRegister(Uint16 reg, Uint16 value);\r
-Uint16 BGA_int_ReadRegister(Uint16 reg);\r
-void BGA_int_SetBank(Uint16 bank);\r
-void BGA_int_SetMode(Uint16 width, Uint16 height);\r
- int BGA_int_UpdateMode(int id);\r
- int BGA_int_FindMode(tVideo_IOCtl_Mode *info);\r
- int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info);\r
- int BGA_int_MapFB(void *Dest);\r
-// Filesystem\r
-Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
-Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
- int BGA_Ioctl(tVFS_Node *node, int id, void *data);\r
-\r
-// === GLOBALS ===\r
-MODULE_DEFINE(0, 0x0032, BochsVBE, BGA_Install, NULL, NULL);\r
-tDevFS_Driver gBGA_DriverStruct = {\r
- NULL, "BochsGA",\r
- {\r
- .Read = BGA_Read,\r
- .Write = BGA_Write,\r
- .IOCtl = BGA_Ioctl\r
- }\r
-};\r
- int giBGA_CurrentMode = -1;\r
- int giBGA_DriverId = -1;\r
-Uint *gBGA_Framebuffer;\r
-t_bga_mode gBGA_Modes[] = {\r
- {},\r
- { 80,25, 32, MODEFLAG_TEXT, 80*25*8}, // 640 x 480\r
- {100,37, 32, MODEFLAG_TEXT, 100*37*8}, // 800 x 600\r
- {640,480,8, 0, 640*480},\r
- {640,480,32, 0, 640*480*4},\r
- {800,600,8, 0, 800*600},\r
- {800,600,32, 0, 800*600*4},\r
-};\r
-#define BGA_MODE_COUNT (sizeof(gBGA_Modes)/sizeof(gBGA_Modes[0]))\r
-\r
-// === CODE ===\r
-/**\r
- * \fn int BGA_Install(char **Arguments)\r
- */\r
-int BGA_Install(char **Arguments)\r
-{\r
- int bga_version = 0;\r
- \r
- // Check BGA Version\r
- bga_version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID);\r
- // NOTE: This driver was written for 0xB0C4, but they seem to be backwards compatable\r
- if(bga_version < 0xB0C4 || bga_version > 0xB0C5) {\r
- Warning("[BGA ] Bochs Adapter Version is not 0xB0C4 or 0xB0C5, instead 0x%x", bga_version);\r
- return 0;\r
- }\r
- \r
- // Install Device\r
- giBGA_DriverId = DevFS_AddDevice( &gBGA_DriverStruct );\r
- if(giBGA_DriverId == -1) {\r
- Warning("[BGA ] Unable to register with DevFS, maybe already loaded?");\r
- return 0;\r
- }\r
- \r
- // Map Framebuffer to hardware address\r
- gBGA_Framebuffer = (void *) MM_MapHWPage(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768); // 768 pages (3Mb)\r
- \r
- return 1;\r
-}\r
-\r
-/**\r
- * \fn void BGA_Uninstall()\r
- */\r
-void BGA_Uninstall()\r
-{\r
- //DevFS_DelDevice( giBGA_DriverId );\r
- MM_UnmapHWPage( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\r
-}\r
-\r
-/**\r
- * \fn Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
- * \brief Read from the framebuffer\r
- */\r
-Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
-{\r
- // Check Mode\r
- if(giBGA_CurrentMode == -1) return -1;\r
- \r
- // Check Offset and Length against Framebuffer Size\r
- if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize)\r
- return -1;\r
- \r
- // Copy from Framebuffer\r
- memcpy(buffer, (void*)((Uint)gBGA_Framebuffer + (Uint)off), len);\r
- return len;\r
-}\r
-\r
-/**\r
- * \fn Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
- * \brief Write to the framebuffer\r
- */\r
-Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
-{ \r
- ENTER("xoff xlen", off, len);\r
- \r
- // Check Mode\r
- if(giBGA_CurrentMode == -1) {\r
- LEAVE('i', -1);\r
- return -1;\r
- }\r
- \r
- // Check Input against Frambuffer Size\r
- if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize) {\r
- LEAVE('i', -1);\r
- return -1;\r
- }\r
- \r
- // Text Mode\r
- if( gBGA_Modes[giBGA_CurrentMode].flags & MODEFLAG_TEXT )\r
- {\r
- tVT_Char *chars = buffer;\r
- int pitch = gBGA_Modes[giBGA_CurrentMode].width * giVT_CharWidth;\r
- Uint32 *dest;\r
- dest = (void*)gBGA_Framebuffer;\r
- dest += off * giVT_CharWidth;\r
- len /= sizeof(tVT_Char);\r
- while(len--)\r
- {\r
- VT_Font_Render(\r
- chars->Ch,\r
- dest, pitch,\r
- VT_Colour12to24(chars->BGCol),\r
- VT_Colour12to24(chars->FGCol)\r
- );\r
- dest += giVT_CharWidth;\r
- chars++;\r
- }\r
- }\r
- else\r
- {\r
- Uint8 *destBuf = (Uint8*) ((Uint)gBGA_Framebuffer + (Uint)off);\r
- \r
- LOG("buffer = %p\n", buffer);\r
- LOG("Updating Framebuffer (%p to %p)\n", \r
- destBuf, destBuf + (Uint)len);\r
- \r
- \r
- // Copy to Frambuffer\r
- memcpy(destBuf, buffer, len);\r
- \r
- LOG("BGA Framebuffer updated\n");\r
- }\r
- \r
- LEAVE('i', len);\r
- return len;\r
-}\r
-\r
-/**\r
- * \fn INT int BGA_Ioctl(tVFS_Node *node, int id, void *data)\r
- * \brief Handle messages to the device\r
- */\r
-INT int BGA_Ioctl(tVFS_Node *node, int id, void *data)\r
-{\r
- int ret = -2;\r
- ENTER("pNode iId pData", node, id, data);\r
- \r
- switch(id)\r
- {\r
- case DRV_IOCTL_TYPE:\r
- ret = DRV_TYPE_VIDEO;\r
- break;\r
- case DRV_IOCTL_IDENT:\r
- memcpy(data, "BGA1", 4);\r
- ret = 1;\r
- break;\r
- case DRV_IOCTL_VERSION:\r
- ret = 0x100;\r
- break;\r
- case DRV_IOCTL_LOOKUP: // TODO: Implement\r
- ret = 0;\r
- break;\r
- \r
- case VIDEO_IOCTL_SETMODE:\r
- ret = BGA_int_UpdateMode(*(int*)(data));\r
- break;\r
- \r
- case VIDEO_IOCTL_GETMODE:\r
- ret = giBGA_CurrentMode;\r
- break;\r
- \r
- case VIDEO_IOCTL_FINDMODE:\r
- ret = BGA_int_FindMode((tVideo_IOCtl_Mode*)data);\r
- break;\r
- \r
- case VIDEO_IOCTL_MODEINFO:\r
- ret = BGA_int_ModeInfo((tVideo_IOCtl_Mode*)data);\r
- break;\r
- \r
- // Request Access to LFB\r
- case VIDEO_IOCTL_REQLFB:\r
- ret = BGA_int_MapFB( *(void**)data );\r
- break;\r
- \r
- default:\r
- LEAVE('i', -2);\r
- return -2;\r
- }\r
- \r
- LEAVE('i', ret);\r
- return ret;\r
-}\r
-\r
-//== Internal Functions ==\r
-/**\r
- * \fn void BGA_int_WriteRegister(Uint16 reg, Uint16 value)\r
- * \brief Writes to a BGA register\r
- */\r
-void BGA_int_WriteRegister(Uint16 reg, Uint16 value)\r
-{\r
- outw(VBE_DISPI_IOPORT_INDEX, reg);\r
- outw(VBE_DISPI_IOPORT_DATA, value);\r
-}\r
-\r
-INT Uint16 BGA_int_ReadRegister(Uint16 reg)\r
-{\r
- outw(VBE_DISPI_IOPORT_INDEX, reg);\r
- return inw(VBE_DISPI_IOPORT_DATA);\r
-}\r
-\r
-#if 0\r
-INT void BGA_int_SetBank(Uint16 bank)\r
-{\r
- BGA_int_WriteRegister(VBE_DISPI_INDEX_BANK, bank);\r
-}\r
-#endif\r
-\r
-/**\r
- * \fn void BGA_int_SetMode(Uint16 width, Uint16 height, Uint16 bpp)\r
- * \brief Sets the video mode from the dimensions and bpp given\r
- */\r
-void BGA_int_SetMode(Uint16 width, Uint16 height)\r
-{\r
- DEBUGS("BGA_int_SetMode: (width=%i, height=%i, bpp=%i)\n", width, height, bpp);\r
- BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);\r
- BGA_int_WriteRegister(VBE_DISPI_INDEX_XRES, width);\r
- BGA_int_WriteRegister(VBE_DISPI_INDEX_YRES, height);\r
- BGA_int_WriteRegister(VBE_DISPI_INDEX_BPP, 32);\r
- BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM | VBE_DISPI_LFB_ENABLED);\r
- //BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM);\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_UpdateMode(int id)\r
- * \brief Set current vide mode given a mode id\r
- */\r
-int BGA_int_UpdateMode(int id)\r
-{\r
- // Sanity Check\r
- if(id < 0 || id >= BGA_MODE_COUNT) return -1;\r
- \r
- // Check if it is a text mode\r
- if( gBGA_Modes[id].flags & MODEFLAG_TEXT )\r
- BGA_int_SetMode(\r
- gBGA_Modes[id].width*giVT_CharWidth,\r
- gBGA_Modes[id].height*giVT_CharHeight);\r
- else // Graphics?\r
- BGA_int_SetMode(\r
- gBGA_Modes[id].width,\r
- gBGA_Modes[id].height);\r
- \r
- giBGA_CurrentMode = id;\r
- return id;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_FindMode(tVideo_IOCtl_Mode *info)\r
- * \brief Find a mode matching the given options\r
- */\r
-int BGA_int_FindMode(tVideo_IOCtl_Mode *info)\r
-{\r
- int i;\r
- int best = -1, bestFactor = 1000;\r
- int factor, tmp;\r
- int rqdProduct = info->width * info->height * info->bpp;\r
- \r
- DEBUGS("BGA_int_FindMode: (info={width:%i,height:%i,bpp:%i})\n", info->width, info->height, info->bpp);\r
- \r
- for(i = 0; i < BGA_MODE_COUNT; i++)\r
- {\r
- #if DEBUG >= 2\r
- LogF("Mode %i (%ix%ix%i), ", i, gBGA_Modes[i].width, gBGA_Modes[i].height, gBGA_Modes[i].bpp);\r
- #endif\r
- \r
- if(gBGA_Modes[i].width == info->width\r
- && gBGA_Modes[i].height == info->height\r
- && gBGA_Modes[i].bpp == info->bpp)\r
- {\r
- #if DEBUG >= 2\r
- LogF("Perfect!\n");\r
- #endif\r
- best = i;\r
- break;\r
- }\r
- \r
- tmp = gBGA_Modes[i].width * gBGA_Modes[i].height * gBGA_Modes[i].bpp;\r
- tmp -= rqdProduct;\r
- tmp = tmp < 0 ? -tmp : tmp;\r
- factor = tmp * 100 / rqdProduct;\r
- \r
- #if DEBUG >= 2\r
- LogF("factor = %i\n", factor);\r
- #endif\r
- \r
- if(factor < bestFactor)\r
- {\r
- bestFactor = factor;\r
- best = i;\r
- }\r
- }\r
- info->id = best;\r
- info->width = gBGA_Modes[best].width;\r
- info->height = gBGA_Modes[best].height;\r
- info->bpp = gBGA_Modes[best].bpp;\r
- return best;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
- * \brief Get mode information\r
- */\r
-int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
-{\r
- if(!info) return -1;\r
- if(MM_GetPhysAddr((Uint)info) == 0)\r
- return -1;\r
- \r
- if(info->id < 0 || info->id >= BGA_MODE_COUNT) return -1;\r
- \r
- info->width = gBGA_Modes[info->id].width;\r
- info->height = gBGA_Modes[info->id].height;\r
- info->bpp = gBGA_Modes[info->id].bpp;\r
- \r
- return 1;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_MapFB(void *Dest)\r
- * \brief Map the framebuffer into a process's space\r
- * \param Dest User address to load to\r
- */\r
-int BGA_int_MapFB(void *Dest)\r
-{\r
- Uint i;\r
- Uint pages;\r
- \r
- // Sanity Check\r
- if((Uint)Dest > 0xC0000000) return 0;\r
- if(gBGA_Modes[giBGA_CurrentMode].bpp < 15) return 0; // Only non-pallete modes are supported\r
- \r
- // Count required pages\r
- pages = (gBGA_Modes[giBGA_CurrentMode].fbSize + 0xFFF) >> 12;\r
- \r
- // Check if there is space\r
- for( i = 0; i < pages; i++ )\r
- {\r
- if(MM_GetPhysAddr( (Uint)Dest + (i << 12) ))\r
- return 0;\r
- }\r
- \r
- // Map\r
- for( i = 0; i < pages; i++ )\r
- MM_Map( (Uint)Dest + (i<<12), VBE_DISPI_LFB_PHYSICAL_ADDRESS + (i<<12) );\r
- \r
- return 1;\r
-}\r
* AcessOS 0.1\r
* Floppy Disk Access Code\r
*/\r
-#define DEBUG 1\r
+#define DEBUG 0\r
#include <common.h>\r
#include <modules.h>\r
#include <fs_devfs.h>\r
\r
#define WARN 0\r
\r
-// Version Information\r
-#define FDD_VER_MAJ 0\r
-#define FDD_VER_MIN 75\r
+// === CONSTANTS ===\r
+// --- Current Version\r
+#define FDD_VERSION ((0<<8)|(75))\r
\r
+// --- Options\r
#define USE_CACHE 1 // 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_OFF_DELAY 2000 // Miliseconds\r
\r
// === TYPEDEFS ===\r
+/**\r
+ * \brief Representation of a floppy drive\r
+ */\r
typedef struct {\r
int type;\r
volatile int motorState; //2 - On, 1 - Spinup, 0 - Off\r
int track[2];\r
int timer;\r
- char Name[2];\r
tVFS_Node Node;\r
} t_floppyDevice;\r
\r
+/**\r
+ * \brief Cached Sector\r
+ */\r
typedef struct {\r
Uint64 timestamp;\r
Uint16 disk;\r
Uint16 sector; // Allows 32Mb of addressable space (Plenty for FDD)\r
- char data[512];\r
+ Uint8 data[512];\r
} t_floppySector;\r
\r
// === CONSTANTS ===\r
-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
+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
\r
enum FloppyPorts {\r
PORT_STATUSA = 0x0,\r
};\r
\r
// === PROTOTYPES ===\r
+// --- Filesystem\r
+ int FDD_Install(char **Arguments);\r
char *FDD_ReadDir(tVFS_Node *Node, int pos);\r
tVFS_Node *FDD_FindDir(tVFS_Node *dirNode, char *Name);\r
-static int fdd_readSector(int disk, int lba, void *buf);\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
+// --- Raw Disk Access\r
+ int FDD_ReadSector(int disk, int lba, void *buf);\r
+// --- Helpers\r
+void FDD_IRQHandler(int Num);\r
void FDD_WaitIRQ();\r
void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl);\r
-static void FDD_AquireSpinlock();\r
-static void inline FDD_FreeSpinlock();\r
+inline void FDD_AquireSpinlock();\r
+inline void FDD_FreeSpinlock();\r
#if USE_CACHE\r
-static inline void FDD_AquireCacheSpinlock();\r
-static inline void FDD_FreeCacheSpinlock();\r
+inline void FDD_AquireCacheSpinlock();\r
+inline void FDD_FreeCacheSpinlock();\r
#endif\r
-static void sendbyte(int base, char byte);\r
-static int getbyte(int base);\r
-static int seekTrack(int disk, int head, int track);\r
-static void stop_motor(int disk);\r
-static void start_motor(int disk);\r
-static int get_dims(int type, int lba, int *c, int *h, int *s, int *spt);\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
- int FDD_Install(char **Arguments);\r
+void FDD_int_SendByte(int base, char byte);\r
+ int FDD_int_GetByte(int base);\r
+void FDD_Reset(int id);\r
+void FDD_Recalibrate(int disk);\r
+ int FDD_int_SeekTrack(int disk, int head, int track);\r
+void FDD_int_TimerCallback(int arg);\r
+void FDD_int_StopMotor(int disk);\r
+void FDD_int_StartMotor(int disk);\r
+ int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt);\r
\r
// === GLOBALS ===\r
-MODULE_DEFINE(0, 0x004B, FDD, FDD_Install, NULL, NULL);\r
-static t_floppyDevice fdd_devices[2];\r
-static volatile int fdd_inUse = 0;\r
-static volatile int fdd_irq6 = 0;\r
+MODULE_DEFINE(0, FDD_VERSION, FDD, FDD_Install, NULL, NULL);\r
+t_floppyDevice gFDD_Devices[2];\r
+volatile int fdd_inUse = 0;\r
+volatile int fdd_irq6 = 0;\r
tDevFS_Driver gFDD_DriverInfo = {\r
NULL, "fdd",\r
{\r
}\r
};\r
#if USE_CACHE\r
-static int siFDD_CacheInUse = 0;\r
-static int siFDD_SectorCacheSize = CACHE_SIZE;\r
-static t_floppySector sFDD_SectorCache[CACHE_SIZE];\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
+ * \fn int FDD_Install(char **Arguments)\r
+ * \brief Installs floppy driver\r
+ */\r
+int FDD_Install(char **Arguments)\r
+{\r
+ Uint8 data;\r
+ \r
+ // Determine Floppy Types (From CMOS)\r
+ outb(0x70, 0x10);\r
+ data = inb(0x71);\r
+ gFDD_Devices[0].type = data >> 4;\r
+ gFDD_Devices[1].type = data & 0xF;\r
+ gFDD_Devices[0].track[0] = -1;\r
+ gFDD_Devices[1].track[1] = -1;\r
+ \r
+ // Clear FDD IRQ Flag\r
+ FDD_SensInt(0x3F0, NULL, NULL);\r
+ // Install IRQ6 Handler\r
+ IRQ_AddHandler(6, FDD_IRQHandler);\r
+ // Reset Primary FDD Controller\r
+ FDD_Reset(0);\r
+ \r
+ Log("[FDD ] Detected Disk 0: %s and Disk 1: %s\n", cFDD_TYPES[data>>4], cFDD_TYPES[data&0xF]);\r
+ \r
+ // Initialise Root Node\r
+ gFDD_DriverInfo.RootNode.CTime = gFDD_DriverInfo.RootNode.MTime\r
+ = gFDD_DriverInfo.RootNode.ATime = now();\r
+ \r
+ // Initialise Child Nodes\r
+ gFDD_Devices[0].Node.Inode = 0;\r
+ 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
+ memcpy(&gFDD_Devices[1].Node, &gFDD_Devices[0].Node, sizeof(tVFS_Node));\r
+ \r
+ gFDD_Devices[1].Node.Inode = 1;\r
+ \r
+ // Set Lengths\r
+ gFDD_Devices[0].Node.Size = cFDD_SIZES[data >> 4];\r
+ 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
+ #endif\r
+ \r
+ // Register with devfs\r
+ DevFS_AddDevice(&gFDD_DriverInfo);\r
+ \r
+ return 0;\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
{\r
+ char name[2] = "0\0";\r
//Update Accessed Time\r
//gFDD_DrvInfo.rootNode.atime = now();\r
\r
if(pos >= 2 || pos < 0)\r
return NULL;\r
\r
- if(fdd_devices[pos].type == 0)\r
+ if(gFDD_Devices[pos].type == 0)\r
return VFS_SKIP;\r
\r
+ name[0] += pos;\r
+ \r
//Return\r
- return fdd_devices[pos].Name;\r
+ return strdup(name);\r
}\r
\r
/**\r
*/\r
tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *filename)\r
{\r
- int i;\r
+ int i;\r
\r
ENTER("sfilename", filename);\r
\r
- if(filename == NULL) return NULL;\r
+ // Sanity check string\r
+ if(filename == NULL) {\r
+ LEAVE('n');\r
+ return NULL;\r
+ }\r
\r
- //Check string length (should be 1)\r
- if(filename[0] == '\0') return NULL;\r
- if(filename[1] != '\0') return NULL;\r
+ // Check string length (should be 1)\r
+ if(filename[0] == '\0' || filename[1] != '\0') {\r
+ LEAVE('n');\r
+ return NULL;\r
+ }\r
\r
- //Get First char\r
+ // Get First character\r
i = filename[0] - '0';\r
\r
// Check for 1st disk and if it is present return\r
- if(i == 0 && fdd_devices[0].type != 0)\r
- return &fdd_devices[0].Node;\r
+ if(i == 0 && gFDD_Devices[0].type != 0) {\r
+ LEAVE('p', &gFDD_Devices[0].Node);\r
+ return &gFDD_Devices[0].Node;\r
+ }\r
\r
// Check for 2nd disk and if it is present return\r
- if(i == 1 && fdd_devices[1].type != 0)\r
- return &fdd_devices[1].Node;\r
+ if(i == 1 && gFDD_Devices[1].type != 0) {\r
+ LEAVE('p', &gFDD_Devices[1].Node);\r
+ return &gFDD_Devices[1].Node;\r
+ }\r
\r
// Else return null\r
+ LEAVE('n');\r
return NULL;\r
}\r
\r
+/**\r
+ * \fn int FDD_IOCtl(tVFS_Node *node, int id, void *data)\r
+ * \brief Stub ioctl function\r
+ */\r
+int FDD_IOCtl(tVFS_Node *node, int id, void *data)\r
+{\r
+ switch(id)\r
+ {\r
+ case DRV_IOCTL_TYPE: return DRV_TYPE_DISK;\r
+ case DRV_IOCTL_IDENT: memcpy(data, "FDD\0", 4); return 1;\r
+ case DRV_IOCTL_VERSION: return FDD_VERSION;\r
+ default: return 0;\r
+ }\r
+}\r
+\r
/**\r
* \fn Uint64 fdd_readFS(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
* \brief Read Data from a disk\r
LOG("Non-aligned Read");\r
\r
//Read Starting Sector\r
- if(!fdd_readSector(disk, startOff, buf))\r
+ if(!FDD_ReadSector(disk, startOff, buf))\r
return 0;\r
memcpy(buffer, (char*)(buf+sectOff), len>512-sectOff?512-sectOff:len);\r
\r
\r
//Read Middle Sectors\r
for(i=1;i<sectors-1;i++) {\r
- if(!fdd_readSector(disk, startOff+i, buf)) {\r
+ if(!FDD_ReadSector(disk, startOff+i, buf)) {\r
LEAVE('i', -1);\r
return -1;\r
}\r
}\r
\r
//Read End Sectors\r
- if(!fdd_readSector(disk, startOff+i, buf))\r
+ if(!FDD_ReadSector(disk, startOff+i, buf))\r
return 0;\r
memcpy(buffer, buf, (len&0x1FF)-sectOff);\r
//Aligned Offset and Length - Simple Code\r
for(i=0;i<count;i++)\r
{\r
- fdd_readSector(disk, sector, buf);\r
+ FDD_ReadSector(disk, sector, buf);\r
memcpy(buffer, buf, 512);\r
buffer += 512;\r
sector++;\r
}\r
\r
/**\r
- * \fn static int fdd_readSector(int disk, int lba, void *buf)\r
+ * \fn int FDD_ReadSector(int disk, int lba, void *buf)\r
* \fn Read a sector from disk\r
*/\r
-int fdd_readSector(int disk, int lba, void *buf)\r
+int FDD_ReadSector(int disk, int lba, void *buf)\r
{\r
int cyl, head, sec;\r
int spt, base;\r
\r
LOG("Calculating Disk Dimensions");\r
//Get CHS position\r
- if(get_dims(fdd_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
LEAVE('i', -1);\r
return -1;\r
}\r
\r
// Remove Old Timer\r
- Time_RemoveTimer(fdd_devices[disk].timer);\r
+ Time_RemoveTimer(gFDD_Devices[disk].timer);\r
// Check if Motor is on\r
- if(fdd_devices[disk].motorState == 0) {\r
- start_motor(disk);\r
+ if(gFDD_Devices[disk].motorState == 0) {\r
+ FDD_int_StartMotor(disk);\r
}\r
\r
LOG("Wait for Motor Spinup");\r
\r
// Wait for spinup\r
- while(fdd_devices[disk].motorState == 1) Threads_Yield();\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
// Seek to track\r
outb(base+CALIBRATE_DRIVE, 0);\r
i = 0;\r
- while(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 ) Threads_Yield();\r
//FDD_SensInt(base, NULL, NULL); // Wait for IRQ\r
\r
LOG("Setting DMA for read");\r
\r
//Threads_Wait(100); // Wait for Head to settle\r
Time_Delay(100);\r
- sendbyte(base, READ_SECTOR); // Was 0xE6\r
- sendbyte(base, (head << 2) | (disk&1));\r
- sendbyte(base, (Uint8)cyl);\r
- sendbyte(base, (Uint8)head);\r
- sendbyte(base, (Uint8)sec);\r
- sendbyte(base, 0x02); // Bytes Per Sector (Real BPS=128*2^{val})\r
- sendbyte(base, spt); // SPT\r
- sendbyte(base, 0x1B); // Gap Length (27 is default)\r
- sendbyte(base, 0xFF); // Data Length\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
\r
// Read Data from DMA\r
- LOG(" fdd_readSector: Reading Data");\r
+ LOG(" FDD_ReadSector: Reading Data");\r
DMA_ReadData(2, 512, buf);\r
\r
// Clear Input Buffer\r
LOG("Clearing Input Buffer");\r
- getbyte(base); getbyte(base); getbyte(base);\r
- getbyte(base); getbyte(base); getbyte(base); getbyte(base);\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
\r
LOG("Realeasing Spinlock and Setting motor to stop");\r
// Release Spinlock\r
FDD_FreeSpinlock();\r
\r
//Set timer to turn off motor affter a gap\r
- fdd_devices[disk].timer = Time_CreateTimer(MOTOR_OFF_DELAY, stop_motor, (void*)disk); //One Shot Timer
+ gFDD_Devices[disk].timer = Time_CreateTimer(MOTOR_OFF_DELAY, FDD_int_StopMotor, (void*)disk); //One Shot Timer
\r
#if USE_CACHE\r
{\r
}\r
\r
/**\r
- * \fn static int seekTrack(int disk, int track)\r
+ * \fn int FDD_int_SeekTrack(int disk, int track)\r
* \brief Seek disk to selected track\r
*/\r
-static int seekTrack(int disk, int head, int track)\r
+int FDD_int_SeekTrack(int disk, int head, int track)\r
{\r
Uint8 sr0, cyl;\r
int base;\r
base = cPORTBASE[disk>>1];\r
\r
// Check if seeking is needed\r
- if(fdd_devices[disk].track[head] == track)\r
+ if(gFDD_Devices[disk].track[head] == track)\r
return 1;\r
\r
// - Seek Head 0\r
- sendbyte(base, SEEK_TRACK);\r
- sendbyte(base, (head<<2)|(disk&1));\r
- sendbyte(base, track); // Send Seek command\r
+ FDD_int_SendByte(base, SEEK_TRACK);\r
+ FDD_int_SendByte(base, (head<<2)|(disk&1));\r
+ FDD_int_SendByte(base, track); // Send Seek command\r
FDD_WaitIRQ();\r
FDD_SensInt(base, &sr0, &cyl); // Wait for IRQ\r
if((sr0 & 0xF0) != 0x20) {
if(cyl != track) return 0;\r
\r
// Set Track in structure\r
- fdd_devices[disk].track[head] = track;\r
+ gFDD_Devices[disk].track[head] = track;\r
return 1;\r
}\r
\r
/**\r
- * \fn static int get_dims(int type, int lba, int *c, int *h, int *s, int *spt)\r
+ * \fn int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt)\r
* \brief Get Dimensions of a disk\r
*/\r
-static int get_dims(int type, int lba, int *c, int *h, int *s, int *spt)\r
+int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt)\r
{\r
switch(type) {\r
case 0:\r
}\r
\r
/**\r
- * \fn int FDD_IOCtl(tVFS_Node *node, int id, void *data)\r
- * \brief Stub ioctl function\r
- */\r
-int FDD_IOCtl(tVFS_Node *node, int id, void *data)\r
-{\r
- switch(id)\r
- {\r
- case DRV_IOCTL_TYPE: return DRV_TYPE_DISK;\r
- case DRV_IOCTL_IDENT: memcpy(data, "FDD\0", 4); return 1;\r
- case DRV_IOCTL_VERSION: return (FDD_VER_MAJ<<8)|FDD_VER_MIN;\r
- default: return 0;\r
- }\r
-}\r
-\r
-/**\r
- * \fn void fdd_handler(int unused)\r
+ * \fn void FDD_IRQHandler(int Num)\r
* \brief Handles IRQ6\r
*/\r
-void fdd_handler(int unused)\r
+void FDD_IRQHandler(int Num)\r
{\r
fdd_irq6 = 1;\r
}\r
\r
void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl)\r
{\r
- sendbyte(base, CHECK_INTERRUPT_STATUS);\r
- if(sr0) *sr0 = getbyte(base);\r
- else getbyte(base);\r
- if(cyl) *cyl = getbyte(base);\r
- else getbyte(base);\r
+ FDD_int_SendByte(base, CHECK_INTERRUPT_STATUS);\r
+ if(sr0) *sr0 = FDD_int_GetByte(base);\r
+ else FDD_int_GetByte(base);\r
+ if(cyl) *cyl = FDD_int_GetByte(base);\r
+ else FDD_int_GetByte(base);\r
}\r
\r
void FDD_AquireSpinlock()\r
#endif\r
\r
/**\r
- * void sendbyte(int base, char byte)\r
+ * void FDD_int_SendByte(int base, char byte)\r
* \brief Sends a command to the controller\r
*/\r
-static void sendbyte(int base, char byte)\r
+void FDD_int_SendByte(int base, char byte)\r
{\r
volatile int state;\r
int timeout = 128;\r
inb(0x80); //Delay\r
}\r
#if WARN\r
- Warning("FDD_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
/**\r
- * int getbyte(int base, char byte)\r
+ * int FDD_int_GetByte(int base, char byte)\r
* \brief Receive data from fdd controller\r
*/\r
-static int getbyte(int base)\r
+int FDD_int_GetByte(int base)\r
{\r
volatile int state;\r
int timeout;\r
return -1;\r
}\r
\r
+/**\r
+ * \brief Recalibrate the specified disk\r
+ */\r
void FDD_Recalibrate(int disk)\r
{\r
ENTER("idisk", disk);\r
\r
LOG("Starting Motor");\r
- start_motor(disk);\r
+ FDD_int_StartMotor(disk);\r
// Wait for Spinup\r
- while(fdd_devices[disk].motorState == 1) Threads_Yield();\r
+ while(gFDD_Devices[disk].motorState == 1) Threads_Yield();\r
\r
LOG("Sending Calibrate Command");\r
- sendbyte(cPORTBASE[disk>>1], CALIBRATE_DRIVE);\r
- sendbyte(cPORTBASE[disk>>1], disk&1);\r
+ FDD_int_SendByte(cPORTBASE[disk>>1], CALIBRATE_DRIVE);\r
+ FDD_int_SendByte(cPORTBASE[disk>>1], disk&1);\r
\r
LOG("Waiting for IRQ");\r
FDD_WaitIRQ();\r
FDD_SensInt(cPORTBASE[disk>>1], NULL, NULL);\r
\r
LOG("Stopping Motor");\r
- stop_motor(disk);\r
+ FDD_int_StopMotor(disk);\r
LEAVE('-');\r
}\r
\r
+/**\r
+ * \brief Reset the specified FDD controller\r
+ */\r
void FDD_Reset(int id)\r
{\r
int base = cPORTBASE[id];\r
\r
LOG("Setting Driver Info");\r
outb(base + PORT_DATARATE, 0); // Set data rate to 500K/s\r
- sendbyte(base, FIX_DRIVE_DATA); // Step and Head Load Times\r
- sendbyte(base, 0xDF); // Step Rate Time, Head Unload Time (Nibble each)\r
- sendbyte(base, 0x02); // Head Load Time >> 1\r
- while(seekTrack(0, 0, 1) == 0); // set track\r
- while(seekTrack(0, 1, 1) == 0); // set track\r
+ FDD_int_SendByte(base, FIX_DRIVE_DATA); // Step and Head Load Times\r
+ FDD_int_SendByte(base, 0xDF); // Step Rate Time, Head Unload Time (Nibble each)\r
+ FDD_int_SendByte(base, 0x02); // Head Load Time >> 1\r
+ while(FDD_int_SeekTrack(0, 0, 1) == 0); // set track\r
+ while(FDD_int_SeekTrack(0, 1, 1) == 0); // set track\r
\r
LOG("Recalibrating Disk");\r
FDD_Recalibrate((id<<1)|0);\r
}\r
\r
/**\r
- * \fn void fdd_timer()\r
+ * \fn void FDD_int_TimerCallback()\r
* \brief Called by timer\r
*/\r
-static void fdd_timer(int arg)\r
+void FDD_int_TimerCallback(int arg)\r
{\r
ENTER("iarg", arg);\r
- if(fdd_devices[arg].motorState == 1)\r
- fdd_devices[arg].motorState = 2;\r
- Time_RemoveTimer(fdd_devices[arg].timer);\r
- fdd_devices[arg].timer = -1;\r
+ if(gFDD_Devices[arg].motorState == 1)\r
+ gFDD_Devices[arg].motorState = 2;\r
+ Time_RemoveTimer(gFDD_Devices[arg].timer);\r
+ gFDD_Devices[arg].timer = -1;\r
LEAVE('-');\r
}\r
\r
/**\r
- * \fn void start_motor(char disk)\r
+ * \fn void FDD_int_StartMotor(char disk)\r
* \brief Starts FDD Motor\r
*/\r
-static void start_motor(int disk)\r
+void FDD_int_StartMotor(int disk)\r
{\r
Uint8 state;\r
state = inb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT );\r
state |= 1 << (4+disk);\r
outb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT, state );\r
- fdd_devices[disk].motorState = 1;\r
- fdd_devices[disk].timer = Time_CreateTimer(MOTOR_ON_DELAY, fdd_timer, (void*)disk); //One Shot Timer\r
+ gFDD_Devices[disk].motorState = 1;\r
+ gFDD_Devices[disk].timer = Time_CreateTimer(MOTOR_ON_DELAY, FDD_int_TimerCallback, (void*)disk); //One Shot Timer\r
}\r
\r
/**\r
- * \fn void stop_motor(int disk)\r
+ * \fn void FDD_int_StopMotor(int disk)\r
* \brief Stops FDD Motor\r
*/\r
-static void stop_motor(int disk)\r
+void FDD_int_StopMotor(int disk)\r
{\r
Uint8 state;\r
state = inb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT );\r
state &= ~( 1 << (4+disk) );\r
outb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT, state );\r
- fdd_devices[disk].motorState = 0;\r
-}\r
-\r
-/**\r
- * \fn int FDD_Install(char **Arguments)\r
- * \brief Installs floppy driver\r
- */\r
-int FDD_Install(char **Arguments)\r
-{\r
- Uint8 data;\r
- \r
- // Determine Floppy Types (From CMOS)\r
- outb(0x70, 0x10);\r
- data = inb(0x71);\r
- fdd_devices[0].type = data >> 4;\r
- fdd_devices[1].type = data & 0xF;\r
- fdd_devices[0].track[0] = -1;\r
- fdd_devices[1].track[1] = -1;\r
- \r
- // Clear FDD IRQ Flag\r
- FDD_SensInt(0x3F0, NULL, NULL);\r
- // Install IRQ6 Handler\r
- IRQ_AddHandler(6, fdd_handler);\r
- // Reset Primary FDD Controller\r
- FDD_Reset(0);\r
- \r
- Log("[FDD ] Detected Disk 0: %s and Disk 1: %s\n", cFDD_TYPES[data>>4], cFDD_TYPES[data&0xF]);\r
- \r
- // Initialise Root Node\r
- gFDD_DriverInfo.RootNode.CTime = gFDD_DriverInfo.RootNode.MTime\r
- = gFDD_DriverInfo.RootNode.ATime = now();\r
- \r
- // Initialise Child Nodes\r
- fdd_devices[0].Name[0] = '0'; fdd_devices[0].Name[1] = '\0';\r
- fdd_devices[0].Node.Inode = 0;\r
- fdd_devices[0].Node.Flags = 0;\r
- fdd_devices[0].Node.NumACLs = 0;\r
- fdd_devices[0].Node.Read = FDD_ReadFS;\r
- fdd_devices[0].Node.Write = NULL;//fdd_writeFS;\r
- memcpy(&fdd_devices[1].Node, &fdd_devices[0].Node, sizeof(tVFS_Node));\r
- fdd_devices[1].Name[0] = '1';\r
- fdd_devices[1].Node.Inode = 1;\r
- \r
- // Set Lengths\r
- fdd_devices[0].Node.Size = cFDD_SIZES[data >> 4];\r
- fdd_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
- #endif\r
- \r
- // Register with devfs\r
- DevFS_AddDevice(&gFDD_DriverInfo);\r
- \r
- return 0;\r
+ gFDD_Devices[disk].motorState = 0;\r
}\r
\r
/**\r
int i;\r
FDD_AquireSpinlock();\r
for(i=0;i<4;i++) {\r
- Time_RemoveTimer(fdd_devices[i].timer);\r
- stop_motor(i);\r
+ Time_RemoveTimer(gFDD_Devices[i].timer);\r
+ FDD_int_StopMotor(i);\r
}\r
//IRQ_Clear(6);\r
}\r