VideoDriver* LoadVideoDriver(char *FileName) { int filehandle=0; // Declare a file handle unsigned int driversegment=0; // Declare variable for driver segment unsigned int driveroffset=0; // Declare variable for driver offset unsigned long driversize=0; // Declare variable for file size VideoDriver *Drvr; VideoMode *Vid; char far *pointertodrivermem; Defaults.SetStdRoutines(); filehandle=open(FileName,O_RDONLY|O_BINARY); // Open the driver file if (filehandle==-1) return(False); // On driver open error exit driversize=filelength(filehandle); // Get the size of the file in bytes pointertodrivermem=(char far *) farmalloc(driversize+16L); if (pointertodrivermem==NULL) { close(filehandle); // Close the driver file return(False); // Can't allocate driver memory, exit } driversegment=FP_SEG(pointertodrivermem); // Get driver memory block segment driveroffset=FP_OFF(pointertodrivermem); // Get driver memory block offset if (driveroffset>16) // Is the memory offset > 1 segment driversegment+=(driveroffset/16); // Yes, calculate new segment size driversegment++; // Round up, account for remainder Drvr = (VideoDriver*) MK_FP(driversegment,0); if (read(filehandle, ((char*)Drvr), (uint) driversize)==-1) { // If the load does not work close(filehandle); // Close the driver file farfree(pointertodrivermem); // Free memory used by driver return(False); // Can't read driver file, exit } close(filehandle); // Close the driver file // Validate Here! if (!Drvr->Validate(100)) { farfree(pointertodrivermem); return(False); } // Routine Setup // This should check for NULL // - if NULL, replace the routine w/ a standard which calls a lower // level routine in the driver. // - if not NULL, then do the MemAdj. #define MemAdj(x) FP_SEG(x) = FP_SEG(Vid) int cnt; for(cnt=0,Vid=&(Drvr->FirstDriver);cnt<=Drvr->NumModes;cnt++,Vid++) { if (Vid->SetMode != NULL) MemAdj(Vid->SetMode); else Vid->SetMode=SetMode; if (Vid->Clear != NULL) MemAdj(Vid->Clear); else Vid->Clear=Clear; if (Vid->Point != NULL) MemAdj(Vid->Point); else Vid->Point=Point; if (Vid->GetCol != NULL) MemAdj(Vid->GetCol); else Vid->GetCol=GetCol; if (Vid->Rep1Col != NULL) MemAdj(Vid->Rep1Col); else Vid->Rep1Col=Rep1Col; if (Vid->Rep1ColRev != NULL) MemAdj(Vid->Rep1ColRev); else Vid->Rep1ColRev=Rep1ColRev; if (Vid->RepCols != NULL) MemAdj(Vid->RepCols); else Vid->RepCols = RepCols; if (Vid->RepColsRev != NULL) MemAdj(Vid->RepColsRev); else Vid->RepColsRev = RepColsRev; if (Vid->GetCols != NULL) MemAdj(Vid->GetCols); else Vid->GetCols = GetCols; if (Vid->GetColsRev != NULL) MemAdj(Vid->GetColsRev); else Vid->GetColsRev = GetColsRev; if (Vid->Line != NULL) MemAdj(Vid->Line); else Vid->Line = Line; if (Vid->Box != NULL) MemAdj(Vid->Box); else Vid->Box = Box; if (Vid->BoxFill != NULL) MemAdj(Vid->BoxFill); else Vid->BoxFill = BoxFill; if (Vid->DrawBlock != NULL) MemAdj(Vid->DrawBlock); else Vid->DrawBlock = DrawBlock; if (Vid->BCurve != NULL) MemAdj(Vid->BCurve); else Vid->BCurve = BCurve; if (Vid->SetAllPal != NULL) MemAdj(Vid->SetAllPal); else Vid->SetAllPal = SetAllPal; if (Vid->GetAllPal != NULL) MemAdj(Vid->GetAllPal); else Vid->GetAllPal = GetAllPal; if (Vid->SetAllPalTo != NULL) MemAdj(Vid->SetAllPalTo); else Vid->SetAllPalTo = SetAllPalTo; if (Vid->SetPal != NULL) MemAdj(Vid->SetPal); else Vid->SetPal = Palette; // No breakdown Setviewpos and writepage is feasible, so skip them. // If the user does not specify, it will call to a retf instruction // due to the driver organization. MemAdj(Vid->SetViewPos); MemAdj(Vid->SetWritePage); } #undef MemAdj return(Drvr); // Return with driver loaded flag }