home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / misc / disk_io.cpp < prev    next >
C/C++ Source or Header  |  1993-11-17  |  6KB  |  190 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/c/fips/source/cpp/RCS/disk_io.cpp 0.9.1.1 1993/11/17 17:51:04 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. /* Calculates physical sector number (Head, Cylinder, Sector).             */
  46. /* Log_sector is absolute logical sector number (0 = master boot record).  */
  47. /* ----------------------------------------------------------------------- */
  48.  
  49. physical_sector_no::physical_sector_no (dword log_sector,const drive_geometry &geometry)
  50. {
  51.     cylinder = log_sector / (geometry.heads * geometry.sectors);
  52.     head = (log_sector - (cylinder * geometry.heads * geometry.sectors)) / geometry.sectors;
  53.     sector = log_sector - (cylinder * geometry.heads * geometry.sectors) - (head * geometry.sectors) + 1;
  54. }
  55.  
  56. /* ----------------------------------------------------------------------- */
  57. /* Bios call get_drive_geometry, returns error status in var errorcode     */
  58. /* ----------------------------------------------------------------------- */
  59.  
  60. void physical_drive::get_geometry (void)
  61. {
  62.     union REGS regs;
  63.  
  64.     regs.h.ah = GET_DRIVE_PARAMS;
  65.     regs.h.dl = number;
  66.     int86 (DISK_INT,®s,®s);
  67.     if ((errorcode = regs.h.ah) != 0) return;
  68.     geometry.heads = (dword) regs.h.dh + 1;
  69.     geometry.sectors = (dword) regs.h.cl & 0x3f;
  70.     geometry.cylinders = ((dword) regs.h.ch | (((dword) regs.h.cl << 2) & 0x300)) + 1;
  71. }
  72.  
  73. /* ----------------------------------------------------------------------- */
  74. /* Bios call reset_drive, returns error status in var errorcode            */
  75. /* ----------------------------------------------------------------------- */
  76.  
  77. void physical_drive::reset (void)
  78. {
  79.     union REGS regs;
  80.  
  81.     regs.h.ah = RESET_DISK;
  82.     regs.h.dl = number;
  83.     int86 (DISK_INT,®s,®s);
  84.     errorcode = regs.h.ah;
  85. }
  86.  
  87. /* ----------------------------------------------------------------------- */
  88. /* Initialization physical_drive, requires drive number.                   */
  89. /* Calls get_drive_geometry, errorcode contains return status              */
  90. /* ----------------------------------------------------------------------- */
  91.  
  92. physical_drive::physical_drive (int number)
  93. {
  94.     physical_drive::number = number;
  95.     get_geometry ();
  96. };
  97.  
  98. /* ----------------------------------------------------------------------- */
  99. /* Initialization physical_drive with physical_drive object                */
  100. /* ----------------------------------------------------------------------- */
  101.  
  102. physical_drive::physical_drive (physical_drive &pd)
  103. {
  104.     number = pd.number;
  105.     errorcode = pd.errorcode;
  106.     geometry = pd.geometry;
  107. }
  108.  
  109. /* ----------------------------------------------------------------------- */
  110. /* Overloaded assignment operator for physical drive                       */
  111. /* ----------------------------------------------------------------------- */
  112.  
  113. void physical_drive::operator= (physical_drive &pd)
  114. {
  115.     number = pd.number;
  116.     errorcode = pd.errorcode;
  117.     geometry = pd.geometry;
  118. }
  119.  
  120. /* ----------------------------------------------------------------------- */
  121. /* Read sector                                                             */
  122. /* ----------------------------------------------------------------------- */
  123.  
  124. int sector::read (physical_drive *drive,dword sector)
  125. {
  126.     physical_sector_no p (sector,drive->geometry);
  127.  
  128.     boolean done=false;
  129.     for (int i=0;i<3;i++)
  130.     {
  131.         if (!biosdisk (READ_SECTOR,drive->number,p.head,p.cylinder,p.sector,1,data))
  132.         {
  133.             done=true;
  134.             break;
  135.         }
  136.         drive->reset ();
  137.     }
  138.     if (!done) return (-1);
  139.     return 0;
  140. }
  141.  
  142. /* ----------------------------------------------------------------------- */
  143. /* Verify sector CRC                                                       */
  144. /* ----------------------------------------------------------------------- */
  145.  
  146. int verify_sector (physical_drive *drive,dword head,dword cylinder,dword sector,byte *buffer)
  147. {
  148.     if (biosdisk (VERIFY_SECTOR,drive->number,head,cylinder,sector,1,buffer)) return (-1);
  149.     return 0;
  150. }
  151.  
  152. /* ----------------------------------------------------------------------- */
  153. /* Write sector with verify                                                */
  154. /* ----------------------------------------------------------------------- */
  155.  
  156. int sector::write (physical_drive *drive,dword sector)
  157. {
  158.     physical_sector_no p (sector,drive->geometry);
  159.  
  160.     boolean done=false;
  161.     for (int i=0;i<3;i++)
  162.     {
  163.         if (!biosdisk (WRITE_SECTOR,drive->number,p.head,p.cylinder,p.sector,1,data))
  164.         {
  165.             done=true;
  166.             break;
  167.         }
  168.         drive->reset ();
  169.     }
  170.     if (!done) return (-1);
  171.     return (verify_sector (drive,p.head,p.cylinder,p.sector,data));
  172. }
  173.  
  174. /* ----------------------------------------------------------------------- */
  175. /* Bios call get_disk_type - returns 0 if drive not present.               */
  176. /* Valid drive numbers: 0 - 255, result: 1 - floppy without disk change    */
  177. /* detection, 2 - floppy with disk change detection, 3 - harddisk          */
  178. /* ----------------------------------------------------------------------- */
  179.  
  180. int get_disk_type (int drive_number)
  181. {
  182.     union REGS regs;
  183.  
  184.     regs.h.ah = GET_DISK_TYPE;
  185.     regs.h.dl = drive_number;
  186.     int86 (DISK_INT,®s,®s);
  187.     if (regs.x.cflag) return 0;
  188.     return (regs.h.ah);                     // disk type
  189. }
  190.