home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / diskacc.zip / diskapi.c < prev    next >
C/C++ Source or Header  |  1987-10-01  |  5KB  |  240 lines

  1. /* DISKAPI.C
  2.  *
  3.  * Autor:    Kai Uwe Rommel
  4.  * Datum:    Thu 28-Dec-1989
  5.  * Stand:    Tue 7-Aug-1990
  6.  *
  7.  * Compiler: MS C ab 5.10
  8.  * System:   PC/MS-DOS ab 3.20
  9.  *
  10.  * Direct disk access library for OS/2 protected mode and MS-DOS.
  11.  *
  12.  * - API simulation for MS-DOS.
  13.  */
  14.  
  15. #include <dos.h>
  16.  
  17. #include "diskacc.h"
  18.  
  19.  
  20. #define RETRIES        3
  21. #define DSTEP(x)       (* (char far *) (0x00400090L + (x)))
  22. #define INC(ptr, x)    (ptr = (PVOID) ((PBYTE) ptr + x * 512))
  23.  
  24.  
  25. #ifdef DOSBUG
  26. static int dosbug;
  27. #endif
  28.  
  29.  
  30. extern int diskint(int service, int drive, int head, int track,
  31.                    int sector, int nsects, PBYTE buffer);
  32.  
  33.  
  34. static int test_sector(int drive, int side, int track, int sector)
  35. {
  36.   return (diskint(4, drive, side, track, sector, 1, NULL) == 0);
  37. }
  38.  
  39.  
  40. INT APIENTRY DskOpen(USHORT drive, PUSHORT sides,
  41.                      PUSHORT tracks, PUSHORT sectors)
  42. {
  43.   int cnt, erg;
  44.  
  45.   if ( drive > 1 )
  46.     return -1;
  47.  
  48.   diskint(0, drive, 0, 0, 0, 0, NULL);
  49.  
  50.   for ( cnt = 0; cnt < 3; cnt++ )
  51.     if ( erg = test_sector(drive, 0, 0, 1) )
  52.       break;
  53.  
  54.   if ( ! erg )
  55.     return -1;
  56.  
  57.   for ( cnt = 8; cnt <= 10; cnt ++ )
  58.     if ( test_sector(drive, 0, 0, cnt) )
  59.       *sectors = cnt;
  60.     else
  61.       break;
  62.  
  63.   if ( *sectors == 10 )
  64.     for ( cnt = 15; cnt <= 20; cnt ++ )
  65.       if ( test_sector(drive, 0, 0, cnt) )
  66.         *sectors = cnt;
  67.       else
  68.         break;
  69.  
  70.   *sides = test_sector(drive, 1, 0, 1) ? 2 : 1;
  71.  
  72.   if ( DSTEP(drive) & 0x20 )
  73.     if ( !test_sector(drive, 0, 1, 1) )
  74.     {
  75.        DSTEP(drive) &= ~0x20;
  76.  
  77.        if ( !test_sector(drive, 0, 1, 1) )
  78.           return -1;
  79.     }
  80.  
  81.   *tracks = (DSTEP(drive) & 0x20) ? 40 : 80;
  82.  
  83. #ifdef DOSBUG
  84.   if ( *sectors > 9 )
  85.     dosbug = diskint(4, drive, 1, 0, 9, 2, NULL);
  86.   else
  87.     dosbug = 0; 
  88. #endif
  89.  
  90.   return drive + 1;
  91. }
  92.  
  93.  
  94. VOID APIENTRY DskClose(USHORT handle)
  95. {
  96.   if ( (handle < 1) || (2 < handle) )
  97.     return;
  98.  
  99.   diskint(0, handle - 1, 0, 0, 0, 0, NULL);
  100. }
  101.  
  102.  
  103. static int dmaborder(PVOID buf, USHORT nsects)
  104. {
  105.   unsigned long lo, hi;
  106.  
  107.   lo = ((long) FP_SEG(buf) << 4) + (long) FP_OFF(buf);
  108.   hi = lo + nsects * 512L - 1;
  109.  
  110.   if ( (lo & 0xFFFF0000) == (hi & 0xFFFF0000) )
  111.     return -1;
  112.  
  113.   return (int) (((hi & 0xFFFF0000) - lo) / 512L);
  114. }
  115.  
  116.  
  117. int diskint3r(int f, int drive, int head, int track,
  118.               int sector, int nsects, PBYTE buf)
  119. {
  120.   int cnt, rc;
  121.  
  122.   for ( cnt = 0; cnt < RETRIES; cnt++ )
  123.   {
  124. #ifdef DOSBUG
  125.     if ( dosbug && (sector < 10) && (sector + nsects > 10) )
  126.     {              /* what an ugly bug in several DOS versions ... */
  127.       rc  = diskint(f, drive, head, track, sector, 10 - sector, buf);
  128.       rc += diskint(f, drive, head, track, 10, sector + nsects - 10,
  129.                    buf + (10 - sector) * 512);
  130.     }
  131.     else
  132. #endif
  133.       rc = diskint(f, drive, head, track, sector, nsects, buf);
  134.  
  135.     if ( rc == 0 )
  136.       return 0;
  137.     else
  138.       diskint(0, drive, 0, 0, 0, 0, NULL);
  139.   }
  140.  
  141.   return -1;
  142. }
  143.  
  144.  
  145. INT APIENTRY DskRead(USHORT handle, USHORT side, USHORT  track,
  146.                      USHORT sector, USHORT nsects, PVOID buf)
  147. {
  148.   char buffer[1024], *ptr;
  149.   int dma, cnt;
  150.  
  151.   if ( (handle < 1) || (2 < handle) )
  152.     return -1;
  153.  
  154.   if ( (dma = dmaborder(buf, nsects)) == -1 )
  155.   {
  156.     if ( diskint3r(2, handle - 1, side, track, sector, nsects, buf) )
  157.       return -1;
  158.   }
  159.   else
  160.   {
  161.     ptr = (dmaborder(buffer, 1) == -1) ? buffer : buffer + 512;
  162.  
  163.     if ( dma > 0 )
  164.     {
  165.       if ( diskint3r(2, handle - 1, side, track, sector, dma, buf) )
  166.         return -1;
  167.  
  168.       INC(buf, dma);
  169.       sector += dma;
  170.       nsects -= dma;
  171.     }
  172.  
  173.     if ( diskint3r(2, handle - 1, side, track, sector, 1, ptr) )
  174.       return -1;
  175.  
  176.     for ( cnt = 0; cnt < 512; cnt++ )
  177.       ((PBYTE) buf)[cnt] = ptr[cnt];
  178.  
  179.     INC(buf, 1);
  180.     sector++;
  181.     nsects--;
  182.  
  183.     if ( nsects > 0 )
  184.       if ( diskint3r(2, handle - 1, side, track, sector, nsects, buf) )
  185.         return -1;
  186.   }
  187.  
  188.   return 0;
  189. }
  190.  
  191.  
  192. INT APIENTRY DskWrite(USHORT handle, USHORT side, USHORT  track,
  193.                       USHORT sector, USHORT nsects, PVOID buf)
  194. {
  195.   char buffer[1024], *ptr;
  196.   int dma, cnt;
  197.  
  198.   if ( (handle < 1) || (2 < handle) )
  199.     return -1;
  200.  
  201.   if ( (dma = dmaborder(buf, nsects)) == -1 )
  202.   {
  203.     if ( diskint3r(3, handle - 1, side, track, sector, nsects, buf) )
  204.       return -1;
  205.   }
  206.   else
  207.   {
  208.     ptr = (dmaborder(buffer, 1) == -1) ? buffer : buffer + 512;
  209.  
  210.     if ( dma > 0 )
  211.     {
  212.       if ( diskint3r(3, handle - 1, side, track, sector, dma, buf) )
  213.         return -1;
  214.  
  215.       INC(buf, dma);
  216.       sector += dma;
  217.       nsects -= dma;
  218.     }
  219.  
  220.     for ( cnt = 0; cnt < 512; cnt++ )
  221.       ptr[cnt] = ((PBYTE) buf)[cnt];
  222.  
  223.     if ( diskint3r(3, handle - 1, side, track, sector, 1, ptr) )
  224.       return -1;
  225.  
  226.     INC(buf, 1);
  227.     sector++;
  228.     nsects--;
  229.  
  230.     if ( nsects > 0 )
  231.       if ( diskint3r(3, handle - 1, side, track, sector, nsects, buf) )
  232.         return -1;
  233.   }
  234.  
  235.   return 0;
  236. }
  237.  
  238.  
  239. /* Ende DISKAPI.C */
  240.