home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / ARCH / PAX20-2 / DISKTAPE.C < prev    next >
C/C++ Source or Header  |  1993-12-24  |  5KB  |  246 lines

  1. /* DISKTAPE.C
  2.  *
  3.  * "tape on a disk" emulator for MS-DOS and OS/2.
  4.  *
  5.  * Autor:    Kai Uwe Rommel
  6.  * Datum:    Thu 28-Dec-1989
  7.  * Stand:    Sun 14-Jan-1990
  8.  *
  9.  * Compiler: MS C ab 5.00
  10.  * System:   OS/2 ab 1.1
  11.  *
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <errno.h>
  17. #include <ctype.h>
  18.  
  19. #ifndef min
  20. #define min(a, b) ((a) < (b) ? (a) : (b))
  21. #endif
  22.  
  23. #ifdef __32BIT__
  24. #include "diskacc2.h"
  25. #else
  26. #include "diskacc.h"
  27. #endif
  28.  
  29. #define SLOTS 4
  30.  
  31.  
  32. struct slot
  33. {
  34.   int handle;
  35.   unsigned sides, tracks, sectors;
  36.   unsigned long current, size;
  37. };
  38.  
  39. static struct slot tbl[SLOTS];
  40.  
  41.  
  42. int dsk_isdev(char *path)
  43. {
  44.   return (isalpha(path[0]) && path[1] == ':' && path[2] == 0) ||
  45.          (path[0] == '$' && isdigit(path[1]) && path[2] == ':' && path[3] == 0);
  46. }
  47.  
  48.  
  49. int dsk_open(char *path, int oflag)
  50. {
  51.   int cnt, fd;
  52.  
  53.   for ( cnt = 0; cnt < SLOTS; cnt++ )
  54.     if ( tbl[cnt].handle == 0 )
  55.       break;
  56.  
  57.   if ( cnt == SLOTS )
  58.     return -1;
  59.  
  60.   fd = DskOpen(path, &tbl[cnt].sides, &tbl[cnt].tracks, &tbl[cnt].sectors);
  61.  
  62.   if ( fd < 0 )
  63.     return -1;
  64.  
  65.   tbl[cnt].handle = fd;
  66.   tbl[cnt].current = 0L;
  67.   tbl[cnt].size = 512L * tbl[cnt].sides * tbl[cnt].tracks * tbl[cnt].sectors;
  68.  
  69.   return cnt;
  70. }
  71.  
  72.  
  73. int dsk_close(int handle)
  74. {
  75.   if ( (handle < 0) || (SLOTS <= handle) )
  76.     return -1;
  77.  
  78.   if ( tbl[handle].handle == 0 )
  79.     return -1;
  80.  
  81.   DskClose(tbl[handle].handle);
  82.   tbl[handle].handle = 0;
  83.  
  84.   return 0;
  85. }
  86.  
  87.  
  88. int dsk_read(int handle, char *buf, unsigned nbyte)
  89. {
  90.   unsigned side, track, sector, nsects, ok, chunk;
  91.  
  92.   if ( (handle < 0) || (SLOTS <= handle) )
  93.     return -1;
  94.  
  95.   if ( tbl[handle].handle == 0 )
  96.     return -1;
  97.  
  98.   if ( nbyte % 512 != 0 )
  99.     return -1;
  100.  
  101.   sector = (unsigned) (tbl[handle].current / 512L);
  102.  
  103.   track  = sector / tbl[handle].sectors;
  104.   sector -= track * tbl[handle].sectors;
  105.  
  106.   side   = track % tbl[handle].sides;
  107.   track  /= tbl[handle].sides;
  108.  
  109.   nsects = nbyte / 512;
  110.   ok = 0;
  111.  
  112.   while ( nsects != 0 )
  113.   {
  114.     if ( track >= tbl[handle].tracks )
  115.       break;
  116.  
  117.     chunk = min(tbl[handle].sectors - sector, nsects);
  118.  
  119.     if ( DskRead(tbl[handle].handle, side, track, sector + 1, chunk, buf) != 0 )
  120.       break;
  121.  
  122.     ok += chunk;
  123.     nsects -= chunk;
  124.     sector = 0;
  125.  
  126.     if ( ++side >= tbl[handle].sides )
  127.     {
  128.       side = 0;
  129.       track++;
  130.     }
  131.  
  132.     tbl[handle].current += 512L * chunk;
  133.     buf += 512 * chunk;
  134.   }
  135.  
  136.   return ok * 512;
  137. }
  138.  
  139.  
  140. int dsk_write(int handle, char *buf, unsigned nbyte)
  141. {
  142.   unsigned side, track, sector, nsects, ok, chunk;
  143.  
  144.   if ( (handle < 0) || (SLOTS <= handle) )
  145.     return -1;
  146.  
  147.   if ( tbl[handle].handle == 0 )
  148.     return -1;
  149.  
  150.   if ( nbyte % 512 != 0 )
  151.     return -1;
  152.  
  153.   sector = (unsigned) (tbl[handle].current / 512L);
  154.  
  155.   track  = sector / tbl[handle].sectors;
  156.   sector -= track * tbl[handle].sectors;
  157.  
  158.   side   = track % tbl[handle].sides;
  159.   track  /= tbl[handle].sides;
  160.  
  161.   nsects = nbyte / 512;
  162.   ok = 0;
  163.  
  164.   while ( nsects != 0 )
  165.   {
  166.     if ( track >= tbl[handle].tracks )
  167.       break;
  168.  
  169.     chunk = min(tbl[handle].sectors - sector, nsects);
  170.  
  171.     if ( DskWrite(tbl[handle].handle, side, track, sector + 1, chunk, buf) != 0 )
  172.       break;
  173.  
  174.     ok += chunk;
  175.     nsects -= chunk;
  176.     sector = 0;
  177.  
  178.     if ( ++side >= tbl[handle].sides )
  179.     {
  180.       side = 0;
  181.       track++;
  182.     }
  183.  
  184.     tbl[handle].current += 512L * chunk;
  185.     buf += 512 * chunk;
  186.   }
  187.  
  188.   if ( nsects != 0 )
  189.     errno = ENOSPC;
  190.  
  191.   return ok * 512;
  192. }
  193.  
  194.  
  195. long dsk_lseek(int handle, long offset, int where)
  196. {
  197.   if ( (handle < 0) || (SLOTS <= handle) )
  198.     return -1;
  199.  
  200.   if ( tbl[handle].handle == 0 )
  201.     return -1;
  202.  
  203.   if ( offset % 512L != 0L )
  204.     return -1;
  205.  
  206.   switch ( where )
  207.   {
  208.   case SEEK_SET:
  209.     tbl[handle].current = offset;
  210.     break;
  211.   case SEEK_CUR:
  212.     tbl[handle].current += offset;
  213.     break;
  214.   case SEEK_END:
  215.     tbl[handle].current = tbl[handle].size + offset;
  216.     break;
  217.   }
  218.  
  219.   if ( tbl[handle].current > tbl[handle].size )
  220.   {
  221.     tbl[handle].current = 0L;
  222.     errno = EINVAL;
  223.     return -1L;
  224.   }
  225.  
  226.   return tbl[handle].current;
  227. }
  228.  
  229.  
  230. int dsk_size(int handle, long *total, long *cylinder)
  231. {
  232.   if ( (handle < 0) || (SLOTS <= handle) )
  233.     return -1;
  234.  
  235.   if ( tbl[handle].handle == 0 )
  236.     return -1;
  237.  
  238.   *total = tbl[handle].size;
  239.   *cylinder = (long) tbl[handle].sides * tbl[handle].sectors;
  240.  
  241.   return 0;
  242. }
  243.  
  244.  
  245. /* Ende DISKTAPE.C */
  246.