home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / bios / biosdisk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  3.4 KB  |  174 lines

  1. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  2. /*
  3.  * BIOSDISK.C.
  4.  *
  5.  * Modified by Peter Sulyok 1995 <sulyok@math.klte.hu>.
  6.  *
  7.  * This file is distributed WITHOUT ANY WARRANTY; without even the implied
  8.  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9.  *
  10.  */
  11.  
  12. #include <libc/stubs.h>
  13. #include <bios.h>
  14. #include <go32.h>
  15. #include <dpmi.h>
  16. #include <stdlib.h>
  17.  
  18. static int dos_segment = 0;
  19. static int dos_selector = 0;
  20.  
  21. static void free_dos_buffer(void);
  22. static void
  23. free_dos_buffer(void)
  24. {
  25.   __dpmi_free_dos_memory(dos_selector);
  26.   dos_segment = dos_selector = 0;
  27. }
  28.  
  29. static void alloc_dos_buffer(void);
  30. static void
  31. alloc_dos_buffer(void)
  32. {
  33.   if (dos_segment)
  34.     return;
  35.   dos_segment = __dpmi_allocate_dos_memory(18*512/16, &dos_selector);
  36.   if (dos_segment == -1)
  37.   {
  38.     dos_segment = 0;
  39.     return;
  40.   }
  41.   atexit(free_dos_buffer);
  42. }
  43.  
  44. int
  45. biosdisk(int cmd, int drive, int head, int track,
  46.      int sector, int nsects, void *buffer)
  47. {
  48.   int seg=0, ofs=0, xfer=0, before=0;
  49.   __dpmi_regs r;
  50.   switch (cmd)
  51.   {
  52.   case 2:
  53.     xfer = 512 * nsects;
  54.     before = 0;
  55.     break;
  56.   case 3:
  57.     xfer = 512 * nsects;
  58.     before = 1;
  59.     break;
  60.   case 5:
  61.     xfer = 2 * 256;
  62.     before = 1;
  63.     break;
  64.   case 0x0a:
  65.     xfer = (512+7) * nsects;
  66.     before = 0;
  67.     break;
  68.   case 0x0b:
  69.     xfer = (512+7) * nsects;
  70.     before = 1;
  71.     break;
  72.   case 0x0e:
  73.     xfer = 512;
  74.     before = 0;
  75.     break;
  76.   case 0x0f:
  77.     xfer = 512;
  78.     before = 1;
  79.     break;
  80.   }
  81.   if (xfer)
  82.   {
  83.     if (xfer > 18*512)
  84.       return 1;            /* bad command */
  85.     if (xfer > _go32_info_block.size_of_transfer_buffer)
  86.     {
  87.       alloc_dos_buffer();
  88.       if (dos_segment == 0)
  89.     return 0xbb;        /* undefined error */
  90.       seg = dos_segment;
  91.       ofs = 0;
  92.     }
  93.     else
  94.     {
  95.       seg = __tb >> 4;
  96.       ofs = __tb & 15;
  97.     }
  98.   }
  99.   r.h.ah = cmd;
  100.   r.h.al = nsects;
  101.   r.x.es = seg;
  102.   r.x.bx = ofs;
  103.   r.h.ch = track & 0xff;
  104.   r.h.cl = sector | ((track >> 2) & 0xc0);
  105.   r.h.dh = head;
  106.   r.h.dl = drive;
  107.   if (xfer && before)
  108.     dosmemput(buffer, xfer, seg*16+ofs);
  109.   __dpmi_int(0x13, &r);
  110.   if (xfer && !before)
  111.     dosmemget(seg*16+ofs, xfer, buffer);
  112.   if (cmd == 0x08)
  113.   {
  114.     ((short *)buffer)[0] = r.x.cx;
  115.     ((short *)buffer)[1] = r.x.dx;
  116.   }
  117.   return r.h.ah;
  118. }
  119.  
  120. unsigned 
  121. _bios_disk(unsigned _cmd, struct diskinfo_t *_di)
  122. {
  123.   int seg=0, ofs=0, xfer=0, before=0;
  124.   __dpmi_regs r;
  125.  
  126.   switch( _cmd )
  127.   {
  128.   case 2:
  129.     xfer = 512 * _di->nsectors;
  130.     before = 0;
  131.     break;
  132.   case 3:
  133.     xfer = 512 * _di->nsectors;
  134.     before = 1;
  135.     break;
  136.   case 5:
  137.     xfer = 2 * 256;
  138.     before = 1;
  139.     break;
  140.   }
  141.   if (xfer)
  142.   {
  143.     if (xfer > 18*512)
  144.       return 1;            /* bad command */
  145.     if (xfer > _go32_info_block.size_of_transfer_buffer)
  146.     {
  147.       alloc_dos_buffer();
  148.       if (dos_segment == 0)
  149.         return 0xbb;      /* undefined error */
  150.       seg = dos_segment;
  151.       ofs = 0;
  152.     }
  153.     else
  154.     {
  155.       seg = __tb >> 4;
  156.       ofs = __tb & 15;
  157.     }
  158.   }
  159.   r.h.ah = _cmd;
  160.   r.h.al = _di->nsectors;
  161.   r.x.es = seg;
  162.   r.x.bx = ofs;
  163.   r.h.ch = _di->track & 0xff;
  164.   r.h.cl = _di->sector | ((_di->track >> 2) & 0xc0);
  165.   r.h.dh = _di->head;
  166.   r.h.dl = _di->drive;
  167.   if (xfer && before)
  168.     dosmemput(_di->buffer, xfer, seg*16+ofs);
  169.   __dpmi_int(0x13, &r);
  170.   if (xfer && !before)
  171.     dosmemget(seg*16+ofs, xfer, _di->buffer);
  172.   return r.x.ax;
  173. }
  174.