home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 8 / CDACTUAL8.iso / install / fips / source / disk_io.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-11  |  6.8 KB  |  205 lines

  1. /* 
  2.     FIPS - the First nondestructive Interactive Partition Splitting program 
  3.  
  4.     Module disk_io.cpp 
  5.  
  6.     RCS - Header: 
  7.     $Header: c:/daten/fips/source/main/RCS/disk_io.cpp 1.1 1994/05/25 22:19:43 schaefer Exp schaefer $ 
  8.  
  9.     Copyright (C) 1993 Arno Schaefer 
  10.  
  11.     This program is free software; you can redistribute it and/or modify 
  12.     it under the terms of the GNU General Public License as published by 
  13.     the Free Software Foundation; either version 2 of the License, or 
  14.     (at your option) any later version. 
  15.  
  16.     This program is distributed in the hope that it will be useful, 
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of 
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  19.     GNU General Public License for more details. 
  20.  
  21.     You should have received a copy of the GNU General Public License 
  22.     along with this program; if not, write to the Free Software 
  23.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  24.  
  25.  
  26.     Report problems and direct all questions to: 
  27.  
  28.     schaefer@rbg.informatik.th-darmstadt.de 
  29. */ 
  30.  
  31. #include "disk_io.h" 
  32. #include <dos.h> 
  33. #include <bios.h> 
  34.  
  35. #define DISK_INT 0x13 
  36.  
  37. #define RESET_DISK 0 
  38. #define READ_SECTOR 2 
  39. #define WRITE_SECTOR 3 
  40. #define VERIFY_SECTOR 4 
  41. #define GET_DRIVE_PARAMS 8 
  42. #define GET_DISK_TYPE 0x15 
  43.  
  44. /* ----------------------------------------------------------------------- */ 
  45. /* Bios call to get the number of drives attached                          */ 
  46. /* ----------------------------------------------------------------------- */ 
  47.  
  48. int get_no_of_drives (void) 
  49.     union REGS regs; 
  50.  
  51.     regs.h.ah = GET_DRIVE_PARAMS; 
  52.     regs.h.dl = 0x80; 
  53.     int86 (DISK_INT,®s,®s); 
  54.     if (regs.h.ah != 0) return (1); // will be checked again 
  55.     return (regs.h.dl); 
  56.  
  57. /* ----------------------------------------------------------------------- */ 
  58. /* Calculates physical sector number (Head, Cylinder, Sector).             */ 
  59. /* Log_sector is absolute logical sector number (0 = master boot record).  */ 
  60. /* ----------------------------------------------------------------------- */ 
  61.  
  62. physical_sector_no::physical_sector_no (dword log_sector,const drive_geometry &geometry) 
  63.     cylinder = log_sector / (geometry.heads * geometry.sectors); 
  64.     head = (log_sector - (cylinder * geometry.heads * geometry.sectors)) / geometry.sectors; 
  65.     sector = log_sector - (cylinder * geometry.heads * geometry.sectors) - (head * geometry.sectors) + 1; 
  66.  
  67. /* ----------------------------------------------------------------------- */ 
  68. /* Bios call get_drive_geometry, returns error status in var errorcode     */ 
  69. /* ----------------------------------------------------------------------- */ 
  70.  
  71. void physical_drive::get_geometry (void) 
  72.     union REGS regs; 
  73.  
  74.     regs.h.ah = GET_DRIVE_PARAMS; 
  75.     regs.h.dl = number; 
  76.     int86 (DISK_INT,®s,®s); 
  77.     if ((errorcode = regs.h.ah) != 0) return; 
  78.     geometry.heads = (dword) regs.h.dh + 1; 
  79.     geometry.sectors = (dword) regs.h.cl & 0x3f; 
  80.     geometry.cylinders = ((dword) regs.h.ch | (((dword) regs.h.cl << 2) & 0x300)) + 1; 
  81.  
  82. /* ----------------------------------------------------------------------- */ 
  83. /* Bios call reset_drive, returns error status in var errorcode            */ 
  84. /* ----------------------------------------------------------------------- */ 
  85.  
  86. void physical_drive::reset (void) 
  87.     union REGS regs; 
  88.  
  89.     regs.h.ah = RESET_DISK; 
  90.     regs.h.dl = number; 
  91.     int86 (DISK_INT,®s,®s); 
  92.     errorcode = regs.h.ah; 
  93.  
  94. /* ----------------------------------------------------------------------- */ 
  95. /* Initialization physical_drive, requires drive number.                   */ 
  96. /* Calls get_drive_geometry, errorcode contains return status              */ 
  97. /* ----------------------------------------------------------------------- */ 
  98.  
  99. physical_drive::physical_drive (int number) 
  100.     physical_drive::number = number; 
  101.     get_geometry (); 
  102. }; 
  103.  
  104. /* ----------------------------------------------------------------------- */ 
  105. /* Initialization physical_drive with physical_drive object                */ 
  106. /* ----------------------------------------------------------------------- */ 
  107.  
  108. physical_drive::physical_drive (physical_drive &pd) 
  109.     number = pd.number; 
  110.     errorcode = pd.errorcode; 
  111.     geometry = pd.geometry; 
  112.  
  113. /* ----------------------------------------------------------------------- */ 
  114. /* Overloaded assignment operator for physical drive                       */ 
  115. /* ----------------------------------------------------------------------- */ 
  116.  
  117. void physical_drive::operator= (physical_drive &pd) 
  118.     number = pd.number; 
  119.     errorcode = pd.errorcode; 
  120.     geometry = pd.geometry; 
  121.  
  122. /* ----------------------------------------------------------------------- */ 
  123. /* Read sector                                                             */ 
  124. /* ----------------------------------------------------------------------- */ 
  125.  
  126. int sector::read (physical_drive *drive,dword sector) 
  127.     physical_sector_no p (sector,drive->geometry); 
  128.  
  129.     boolean done=false; 
  130.     for (int i=0;i<3;i++) 
  131.     { 
  132.         if (!biosdisk (READ_SECTOR,drive->number,p.head,p.cylinder,p.sector,1,data)) 
  133.         { 
  134.             done=true; 
  135.             break; 
  136.         } 
  137.         drive->reset (); 
  138.     } 
  139.     if (!done) return (-1); 
  140.     return 0; 
  141.  
  142. /* ----------------------------------------------------------------------- */ 
  143. /* Verify sector CRC                                                       */ 
  144. /* ----------------------------------------------------------------------- */ 
  145.  
  146. int verify_sector (physical_drive *drive,dword head,dword cylinder,dword sector,byte *buffer) 
  147.     if (biosdisk (VERIFY_SECTOR,drive->number,head,cylinder,sector,1,buffer)) return (-1); 
  148.     return 0; 
  149.  
  150. /* ----------------------------------------------------------------------- */ 
  151. /* Write sector with verify                                                */ 
  152. /* ----------------------------------------------------------------------- */ 
  153.  
  154. int sector::write (physical_drive *drive,dword sector) 
  155.     physical_sector_no p (sector,drive->geometry); 
  156.  
  157.     boolean done=false; 
  158.     for (int i=0;i<3;i++) 
  159.     { 
  160.         if (!biosdisk (WRITE_SECTOR,drive->number,p.head,p.cylinder,p.sector,1,data)) 
  161.         { 
  162.             done=true; 
  163.             break; 
  164.         } 
  165.         drive->reset (); 
  166.     } 
  167.     if (!done) return (-1); 
  168.     return (verify_sector (drive,p.head,p.cylinder,p.sector,data)); 
  169.  
  170. /* ----------------------------------------------------------------------- */ 
  171. /* Bios call get_disk_type - returns 0 if drive not present.               */ 
  172. /* Valid drive numbers: 0 - 255, result: 1 - floppy without disk change    */ 
  173. /* detection, 2 - floppy with disk change detection, 3 - harddisk          */ 
  174. /* ----------------------------------------------------------------------- */ 
  175.  
  176. int get_disk_type (int drive_number) 
  177.     union REGS regs; 
  178.  
  179.     regs.h.ah = GET_DISK_TYPE; 
  180.     regs.h.dl = drive_number; 
  181.     int86 (DISK_INT,®s,®s); 
  182.     if (regs.x.cflag) return 0; 
  183.     return (regs.h.ah);                     // disk type 
  184.