home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 8 / IOPROG_8.ISO / install / fips / source / disk_io.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-25  |  6.9 KB  |  268 lines

  1. /*
  2.  
  3.     FIPS - the First nondestructive Interactive Partition Splitting program
  4.  
  5.  
  6.  
  7.     Module disk_io.cpp
  8.  
  9.  
  10.  
  11.     RCS - Header:
  12.  
  13.     $Header: c:/daten/fips/source/main/RCS/disk_io.cpp 1.4 1995/01/19 00:00:51 schaefer Exp schaefer $
  14.  
  15.  
  16.  
  17.     Copyright (C) 1993 Arno Schaefer
  18.  
  19.  
  20.  
  21.     This program is free software; you can redistribute it and/or modify
  22.  
  23.     it under the terms of the GNU General Public License as published by
  24.  
  25.     the Free Software Foundation; either version 2 of the License, or
  26.  
  27.     (at your option) any later version.
  28.  
  29.  
  30.  
  31.     This program is distributed in the hope that it will be useful,
  32.  
  33.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  34.  
  35.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  36.  
  37.     GNU General Public License for more details.
  38.  
  39.  
  40.  
  41.     You should have received a copy of the GNU General Public License
  42.  
  43.     along with this program; if not, write to the Free Software
  44.  
  45.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  46.  
  47.  
  48.  
  49.  
  50.  
  51.     Report problems and direct all questions to:
  52.  
  53.  
  54.  
  55.     schaefer@rbg.informatik.th-darmstadt.de
  56.  
  57. */
  58.  
  59.  
  60.  
  61. #include "disk_io.h"
  62.  
  63. #include <dos.h>
  64.  
  65. #include <bios.h>
  66.  
  67.  
  68.  
  69. #define DISK_INT 0x13
  70.  
  71.  
  72.  
  73. #define RESET_DISK 0
  74.  
  75. #define READ_SECTOR 2
  76.  
  77. #define WRITE_SECTOR 3
  78.  
  79. #define VERIFY_SECTOR 4
  80.  
  81. #define GET_DRIVE_PARAMS 8
  82.  
  83. #define GET_DISK_TYPE 0x15
  84.  
  85.  
  86.  
  87.  
  88.  
  89. /* ----------------------------------------------------------------------- */
  90.  
  91. /* Bios call to get the number of drives attached                          */
  92.  
  93. /* ----------------------------------------------------------------------- */
  94.  
  95.  
  96.  
  97. int get_no_of_drives (void)
  98.  
  99. {
  100.  
  101.     union REGS regs;
  102.  
  103.  
  104.  
  105.     regs.h.ah = GET_DRIVE_PARAMS;
  106.  
  107.     regs.h.dl = 0x80;
  108.  
  109.     int86 (DISK_INT, ®s, ®s);
  110.  
  111.  
  112.  
  113.     if (regs.h.ah != 0) return (1); // will be checked again
  114.  
  115.     return (regs.h.dl);
  116.  
  117. }
  118.  
  119.  
  120.  
  121.  
  122.  
  123. /* ----------------------------------------------------------------------- */
  124.  
  125. /* Calculates physical sector number (Head, Cylinder, Sector).             */
  126.  
  127. /* Log_sector is absolute logical sector number (0 = master boot record).  */
  128.  
  129. /* ----------------------------------------------------------------------- */
  130.  
  131.  
  132.  
  133. physical_sector_no::physical_sector_no
  134.  
  135. (
  136.  
  137.     dword logical_sector,
  138.  
  139.     const drive_geometry &geometry
  140.  
  141. )
  142.  
  143. {
  144.  
  145.     cylinder =
  146.  
  147.         logical_sector
  148.  
  149.         / (geometry.heads * geometry.sectors);
  150.  
  151.  
  152.  
  153.     head =
  154.  
  155.     (
  156.  
  157.         logical_sector
  158.  
  159.         - (cylinder * geometry.heads * geometry.sectors)
  160.  
  161.     )
  162.  
  163.     / geometry.sectors;
  164.  
  165.  
  166.  
  167.     sector =
  168.  
  169.         logical_sector
  170.  
  171.         - (cylinder * geometry.heads * geometry.sectors)
  172.  
  173.         - (head * geometry.sectors)
  174.  
  175.         + 1;
  176.  
  177. }
  178.  
  179.  
  180.  
  181.  
  182.  
  183. /* ----------------------------------------------------------------------- */
  184.  
  185. /* Bios call get_drive_geometry, returns error status in var errorcode     */
  186.  
  187. /* ----------------------------------------------------------------------- */
  188.  
  189.  
  190.  
  191. void physical_drive::get_geometry (void)
  192.  
  193. {
  194.  
  195.     union REGS regs;
  196.  
  197.  
  198.  
  199.     regs.h.ah = GET_DRIVE_PARAMS;
  200.  
  201.     regs.h.dl = number;
  202.  
  203.     int86 (DISK_INT, ®s, ®s);
  204.  
  205.  
  206.  
  207.     if ((errorcode = regs.h.ah) != 0) return;
  208.  
  209.  
  210.  
  211.     geometry.heads = (dword) regs.h.dh + 1;
  212.  
  213.     geometry.sectors = (dword) regs.h.cl & 0x3f;
  214.  
  215.     geometry.cylinders =
  216.  
  217.     (
  218.  
  219.         (dword) regs.h.ch
  220.  
  221.         | (((dword) regs.h.cl << 2) & 0x300)
  222.  
  223.     ) + 1;
  224.  
  225. }
  226.  
  227.  
  228.  
  229.  
  230.  
  231. /* ----------------------------------------------------------------------- */
  232.  
  233. /* Bios call reset_drive, returns error status in var errorcode            */
  234.  
  235. /* ----------------------------------------------------------------------- */
  236.  
  237.  
  238.  
  239. void physical_drive::reset (void)
  240.  
  241. {
  242.  
  243.     union REGS regs;
  244.  
  245.  
  246.  
  247.     regs.h.ah = RESET_DISK;
  248.  
  249.     regs.h.dl = number;
  250.  
  251.     int86 (DISK_INT, ®s, ®s);
  252.  
  253.  
  254.  
  255.     errorcode = regs.h.ah;
  256.  
  257. }
  258.  
  259.  
  260.  
  261.  
  262.  
  263. /* ----------------------------------------------------------------------- */
  264.  
  265. /* Initialization physical_drive, requires drive number.                   */
  266.  
  267. /* Calls get_drive_geometry, errorcode contains return status              */
  268.  
  269. /* ----------------------------------------------------------------------- */
  270.  
  271.  
  272.  
  273. physical_drive::physical_drive (int number)
  274.  
  275. {
  276.  
  277.     physical_drive::number = number;
  278.  
  279.     get_geometry ();
  280.  
  281. };
  282.  
  283.  
  284.  
  285.  
  286.  
  287. /* ----------------------------------------------------------------------- */
  288.  
  289. /* Initialization physical_drive with physical_drive object                */
  290.  
  291. /* ----------------------------------------------------------------------- */
  292.  
  293.  
  294.  
  295. physical_drive::physical_drive (physical_drive &pd)
  296.  
  297. {
  298.  
  299.     number = pd.number;
  300.  
  301.     errorcode = pd.errorcode;
  302.  
  303.     geometry = pd.geometry;
  304.  
  305. }
  306.  
  307.  
  308.  
  309.  
  310.  
  311. /* ----------------------------------------------------------------------- */
  312.  
  313. /* Assignment operator for physical drive                                  */
  314.  
  315. /* ----------------------------------------------------------------------- */
  316.  
  317.  
  318.  
  319. void physical_drive::operator= (physical_drive &pd)
  320.  
  321. {
  322.  
  323.     number = pd.number;
  324.  
  325.     errorcode = pd.errorcode;
  326.  
  327.     geometry = pd.geometry;
  328.  
  329. }
  330.  
  331.  
  332.  
  333.  
  334.  
  335. /* ----------------------------------------------------------------------- */
  336.  
  337. /* Read sector                                                             */
  338.  
  339. /* ----------------------------------------------------------------------- */
  340.  
  341.  
  342.  
  343. int physical_drive::read_sector (struct sector *sector, dword sector_number)
  344.  
  345. {
  346.  
  347.     physical_sector_no p (sector_number, geometry);
  348.  
  349.  
  350.  
  351.     boolean done = false;
  352.  
  353.  
  354.  
  355.     for (int i=0; i<3; i++)
  356.  
  357.     {
  358.  
  359.         if (biosdisk
  360.  
  361.         (
  362.  
  363.             READ_SECTOR,
  364.  
  365.             number,
  366.  
  367.             p.head,
  368.  
  369.             p.cylinder,
  370.  
  371.             p.sector,
  372.  
  373.             1,
  374.  
  375.             sector->data
  376.  
  377.         ) == 0)
  378.  
  379.         {
  380.  
  381.             done=true;
  382.  
  383.             break;
  384.  
  385.         }
  386.  
  387.  
  388.  
  389.         reset ();
  390.  
  391.     }
  392.  
  393.  
  394.  
  395.     if (!done) return (-1);
  396.  
  397.     return 0;
  398.  
  399. }
  400.  
  401.  
  402.  
  403.  
  404.  
  405. /* ----------------------------------------------------------------------- */
  406.  
  407. /* Write sector with verify                                                */
  408.  
  409. /* ----------------------------------------------------------------------- */
  410.  
  411.  
  412.  
  413. int physical_drive::write_sector (struct sector *sector, dword sector_number)
  414.  
  415. {
  416.  
  417.     physical_sector_no p (sector_number,geometry);
  418.  
  419.  
  420.  
  421.     boolean done = false;
  422.  
  423.  
  424.  
  425.     for (int i=0; i<3; i++)
  426.  
  427.     {
  428.  
  429.         if (biosdisk
  430.  
  431.         (
  432.  
  433.             WRITE_SECTOR,
  434.  
  435.             number,
  436.  
  437.             p.head,
  438.  
  439.             p.cylinder,
  440.  
  441.             p.sector,
  442.  
  443.             1,
  444.  
  445.             sector->data
  446.  
  447.         ) == 0)
  448.  
  449.         {
  450.  
  451.             done=true;
  452.  
  453.             break;
  454.  
  455.         }
  456.  
  457.  
  458.  
  459.         reset ();
  460.  
  461.     }
  462.  
  463.  
  464.  
  465.     if (!done) return (-1);
  466.  
  467.  
  468.  
  469.     if (biosdisk
  470.  
  471.     (
  472.  
  473.         VERIFY_SECTOR,
  474.  
  475.         number,
  476.  
  477.         p.head,
  478.  
  479.         p.cylinder,
  480.  
  481.         p.sector,
  482.  
  483.         1,
  484.  
  485.         sector->data
  486.  
  487.  
  488.  
  489.     ) != 0) return (-1);
  490.  
  491.  
  492.  
  493.     return 0;
  494.  
  495. }
  496.  
  497.  
  498.  
  499.  
  500.  
  501. /* ----------------------------------------------------------------------- */
  502.  
  503. /* Bios call get_disk_type - returns 0 if drive not present.               */
  504.  
  505. /* Valid drive numbers: 0 - 255, result: 1 - floppy without disk change    */
  506.  
  507. /* detection, 2 - floppy with disk change detection, 3 - harddisk          */
  508.  
  509. /* ----------------------------------------------------------------------- */
  510.  
  511.  
  512.  
  513. int get_disk_type (int drive_number)
  514.  
  515. {
  516.  
  517.     union REGS regs;
  518.  
  519.  
  520.  
  521.     regs.h.ah = GET_DISK_TYPE;
  522.  
  523.     regs.h.dl = drive_number;
  524.  
  525.     int86 (DISK_INT, ®s, ®s);
  526.  
  527.  
  528.  
  529.     if (regs.x.cflag) return 0;
  530.  
  531.     return (regs.h.ah);                     // disk type
  532.  
  533. }
  534.  
  535.