home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_12 / 8n12042a < prev    next >
Text File  |  1990-10-15  |  4KB  |  123 lines

  1. /*
  2.  *  BLOCK.C
  3.  *
  4.  *  main interrupt routine
  5.  */
  6.  
  7. #include    <dos.h>
  8. #include    "block.h"
  9.  
  10. /*
  11.  *  normalize()
  12.  *
  13.  *  normalize() guarantees that the offset portion of a far
  14.  *  pointer is as small as possible.  A complete 20-bit address on
  15.  *  the processor can be calculated as
  16.  *
  17.  *      (segment * 16) + offset
  18.  *
  19.  *  thus, the offset can be kept to a value between 0 and 15.  I
  20.  *  use the FP_SEG and FP_OFF macro's in Microsoft's dos.h to
  21.  *  manipulate the segment and offset of the far pointer.  If your
  22.  *  compiler doesn't support such a facility, see the _rawscroll
  23.  *  routine in RAW.ASM, where I do it in assembly language.
  24.  *
  25.  *  The whole point of this is to allow a lot of pointer
  26.  *  incrementing, using just the offset, without worrying about
  27.  *  wrapping around.
  28.  */
  29.  
  30. static void normalize(p)
  31. int far     **p;
  32.     {
  33.     offset      = FP_OFF(*p);
  34.     FP_SEG(*p)  = FP_SEG(*p) + (offset >> 4);
  35.     FP_OFF(*p)  = offset & 017;
  36.     }
  37.  
  38.  
  39. /*
  40.  *  interrupt()
  41.  *
  42.  *  interrupt() takes care of the commands as they come in from
  43.  *  the request header.  Because of the size of the RAM disk
  44.  *  buffer, the driver initialization could not be appended to the
  45.  *  back of the driver, and is in-line like everything else.
  46.  */
  47.  
  48. void    interrupt()
  49.     {
  50.     command     = rh->command;
  51.     start       = rh->b18.io.start;
  52.     count       = rh->b18.io.count;
  53.     transfer    = (int far *) rh->b14.transfer;
  54.     switch (command)
  55.         {
  56.         case    0:      /* driver initialization */
  57.             source          = ram_disk;
  58.             FP_SEG(source)  = FP_SEG(source) + 0x1000;
  59.             normalize(&source);
  60.             rh->b14.transfer= (char far *) source;
  61.             rh->b18.bpb     = bpb_tab;
  62.             rh->data        = 1;
  63.             rh->status      = DONE;
  64.             break;
  65.         case    1:      /* media check */
  66.             rh->b14.media_change_code   = 1;    /* disk has
  67.                                         * not been changed */
  68.             rh->status      = DONE;
  69.             break;
  70.         case    2:      /* build parameter block */
  71.             rh->b18.bpb = &bpb;
  72.             break;
  73.         case    4:      /* read */
  74.         case    8:      /* write */
  75.         case    9:      /* write with verify */
  76.             if (start > MAX_BLK || count > MAX_BLK ||
  77.                 start + count > MAX_BLK)
  78.                 {
  79.                 rh->status = BLK_NOT_FOUND | ERROR;
  80.                 break;
  81.                 }
  82.             if (command == 4)
  83.                 {
  84.                 source  = ram_disk;
  85.                 normalize(&source);
  86.                 source  += (BLK_SIZE / sizeof(int)) * start;
  87.                 dest    = transfer;
  88.                 }
  89.             else
  90.                 {
  91.                 source  = transfer;
  92.                 dest    = ram_disk;
  93.                 normalize(&dest);
  94.                 dest    += (BLK_SIZE / sizeof(int)) * start;
  95.                 }
  96.             normalize(&dest);
  97.             normalize(&source);
  98.             for (k1 = 0; k1 < count; k1++)
  99.                 for (k2 = 0; k2 < BLK_SIZE / sizeof(int); k2++)
  100.                     *dest++ = *source++;
  101.             rh->status = DONE;
  102.             break;
  103.         case    15:     /* removable media check */
  104.             rh->status = DONE | BUSY;
  105.             break;
  106.         case    5:      /* non-destructive read */
  107.         case    6:      /* input status */
  108.         case    7:      /* flush input buffers */
  109.         case    10:     /* output status */
  110.         case    11:     /* flush output buffers */
  111.         case    13:     /* device open */
  112.         case    14:     /* device done */
  113.             rh->status = DONE;
  114.             break;
  115.         case    3:      /* ioctl read */
  116.         case    12:     /* ioctl write */
  117.         default:
  118.             rh->status = UNKNOWN_COMMAND | ERROR | DONE;
  119.             break;
  120.         }
  121.     }
  122.  
  123.