home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / PAX20.ZIP / DISKTAPE.C < prev    next >
C/C++ Source or Header  |  1990-11-12  |  3KB  |  164 lines

  1. /* "tape on a disk" emulator subroutines for MS-DOS and OS/2.
  2.    Copyright (C) 1989 Kai Uwe Rommel */
  3.  
  4. /* DMA problems with 64k borders are not handled here but by OS/2 itself
  5.    and by the DOS DISKACC-API simulation routines in DISKACC\DISKAPI.C */
  6.  
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10.  
  11. #include "diskacc.h"
  12.  
  13.  
  14. static unsigned short handle, drive, sides, tracks, sectors;
  15. static unsigned long current, size;
  16.  
  17.  
  18. int dsk_open (char *path, int oflag, int mode)
  19. {
  20.   drive = *path - '0';
  21.  
  22.   handle = DskOpen(drive, &sides, &tracks, §ors);
  23.  
  24.   if ( handle == -1 )
  25.     return -1;
  26.  
  27.   size = 512L * sides * tracks * sectors;
  28.   current = 0L;
  29.  
  30.   return handle;
  31. }
  32.  
  33.  
  34. int dsk_close(int fildes)
  35. {
  36.   if ( fildes == handle)
  37.     DskClose(handle);
  38.  
  39.   return 0;
  40. }
  41.  
  42.  
  43. int dsk_read(int fildes, char *buf, unsigned nbyte)
  44. {
  45.   unsigned side, track, sector, nsects, ok, chunk, rc;
  46.  
  47.   if ( fildes != handle )
  48.     return -1;
  49.  
  50.   if ( nbyte % 512 != 0 )
  51.     return -1;
  52.  
  53.   sector = (unsigned) (current / 512L);
  54.  
  55.   track  = sector / sectors;
  56.   sector -= track * sectors;
  57.  
  58.   side   = track % sides;
  59.   track  /= sides;
  60.  
  61.   nsects = nbyte / 512;
  62.   ok = 0;
  63.  
  64.   while ( nsects != 0 )
  65.   {
  66.     if ( track >= tracks )
  67.       break;
  68.  
  69.     chunk = min(sectors - sector, nsects);
  70.  
  71.     if ( DskRead(handle, side, track, sector + 1, chunk, buf) != 0 )
  72.       break;
  73.  
  74.     ok += chunk;
  75.     nsects -= chunk;
  76.     sector = 0;
  77.  
  78.     if ( ++side >= sides )
  79.     {
  80.       side = 0;
  81.       track++;
  82.     }
  83.  
  84.     current += 512L * chunk;
  85.     buf += 512 * chunk;
  86.   }
  87.  
  88.   return ok * 512;
  89. }
  90.  
  91.  
  92. int dsk_write(int fildes, char *buf, unsigned nbyte)
  93. {
  94.   unsigned side, track, sector, nsects, ok, chunk, rc;
  95.  
  96.   if ( fildes != handle )
  97.     return -1;
  98.  
  99.   if ( nbyte % 512 != 0 )
  100.     return -1;
  101.  
  102.   sector = (unsigned) (current / 512L);
  103.  
  104.   track  = sector / sectors;
  105.   sector -= track * sectors;
  106.  
  107.   side   = track % sides;
  108.   track  /= sides;
  109.  
  110.   nsects = nbyte / 512;
  111.   ok = 0;
  112.  
  113.   while ( nsects != 0 )
  114.   {
  115.     if ( track >= tracks )
  116.       break;
  117.  
  118.     chunk = min(sectors - sector, nsects);
  119.  
  120.     if ( DskWrite(handle, side, track, sector + 1, chunk, buf) != 0 )
  121.       break;
  122.  
  123.     ok += chunk;
  124.     nsects -= chunk;
  125.     sector = 0;
  126.  
  127.     if ( ++side >= sides )
  128.     {
  129.       side = 0;
  130.       track++;
  131.     }
  132.  
  133.     current += 512L * chunk;
  134.     buf += 512 * chunk;
  135.   }
  136.  
  137.   return ok * 512;
  138. }
  139.  
  140.  
  141. long dsk_lseek(int fildes, long offset, int whence)
  142. {
  143.   if ( fildes != handle )
  144.     return -1;
  145.  
  146.   if ( offset % 512L != 0L )
  147.     return -1;
  148.  
  149.   switch ( whence )
  150.   {
  151.   case SEEK_SET:
  152.     current = offset;
  153.     break;
  154.   case SEEK_CUR:
  155.     current += offset;
  156.     break;
  157.   case SEEK_END:
  158.     current = size + offset;
  159.     break;
  160.   }
  161.  
  162.   return current;
  163. }
  164.