home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / pascal / rehack / memory / disk.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-29  |  5.1 KB  |  265 lines

  1. #include "..\MEMORY\MEMORY.HPP"
  2. #include <string.h>
  3. #include <io.h>
  4. #include <dos.h>
  5. #include <dir.h>
  6.  
  7. // ------------------------------------------------------------------
  8. // File:        DISK.CPP
  9. // Path:        ...\REHACK\MEMORY\DISK.CPP
  10. // Version:        0.01
  11. // Author:        Pat Reilly
  12. // CIS Id:        71333,2764
  13. // Created On:    6/28/93
  14. // Modified On:
  15. // Description:    DiskMemory class for REHACK. See MEMORY.TXT for
  16. //                more details.
  17. // Tabs:        4
  18. // ------------------------------------------------------------------
  19.  
  20. char DefaultDiskMemDir[MAXPATH] = ".";
  21. int DiskFrameOrder = 0;
  22. // 0 = conventional, EMS
  23. // 1 = EMS, conventional
  24.  
  25. int DiskMemory::handle = -1;
  26. bool DiskMemory::isInitialized = false;
  27. DiskMemory* DiskMemory::head = 0;
  28. long DiskMemory::lastAddr = 0L;
  29.  
  30. // Function called at program exit to remove the temporary file.
  31. void ClearDisk()
  32. {
  33.     if( DiskMemory::handle != 0 )
  34.         {
  35.         _dos_close(DiskMemory::handle);
  36.         unlink( DefaultDiskMemDir );
  37.         }
  38. }
  39.  
  40. #pragma exit ClearDisk
  41.  
  42. DiskMemory::DiskMemory()
  43. {
  44.     init();
  45. }
  46.  
  47. DiskMemory::DiskMemory(word sz)
  48. {
  49.     init();
  50.     allocate(sz);
  51. }
  52.  
  53. bool DiskMemory::allocate(word sz)
  54. {
  55.     if( handle < 0 || memsize != 0 || sz == 0 )
  56.         return false;
  57.  
  58.     long aAddr = 0L;
  59.     DiskMemory* parent = head;
  60.     if( head != 0 )
  61.         {
  62.         aAddr = parent->addr+parent->memsize;
  63.         while( parent->next != 0 )
  64.             {
  65.             aAddr = parent->addr + parent->memsize;
  66.             if( fitsInto( aAddr, parent->next->addr, sz) )
  67.                 break;
  68.             parent = parent->next;
  69.             aAddr = parent->addr+parent->memsize;
  70.             }
  71.         }
  72.     if( (parent == 0 || parent->next == 0) && !fitsInto(aAddr, lastAddr, sz) )
  73.         {
  74.         lseek(handle, aAddr+sz-1, SEEK_SET);
  75.         char ch = ' ';
  76.         unsigned nwritten;
  77.         _dos_write( handle, &ch, 1, &nwritten );
  78.         lastAddr = filelength(handle);
  79.         if( !fitsInto(aAddr, lastAddr, sz) )
  80.             return false;
  81.         }
  82.  
  83.     if( parent == 0 )
  84.         {
  85.         next = 0;
  86.         head = this;
  87.         }
  88.     else
  89.         {
  90.         next = parent->next;
  91.         parent->next = this;
  92.         }
  93.     addr = aAddr;
  94.     memsize = sz;
  95.     return true;
  96. }
  97.  
  98. void DiskMemory::free()
  99. {
  100.     DiskMemory* ptr;
  101.  
  102.     if( memsize == 0 || lockflag != 0 )
  103.         return;
  104.  
  105.     if( head == this )
  106.         head = head->next;
  107.     else
  108.         for( ptr = head; ptr->next; ptr = ptr->next )
  109.             if( ptr->next == this )
  110.                 {
  111.                 ptr->next = ptr->next->next;
  112.                 break;
  113.                 }
  114.     addr = 0;
  115.     next = 0;
  116.     memsize = 0;
  117. }
  118.  
  119. void FAR* DiskMemory::lock()
  120. {
  121.     unsigned nread;
  122.  
  123.     if( memsize == 0 )
  124.         return 0;
  125.  
  126.     if( !lockflag )
  127.         {
  128.         if( DiskFrameOrder == 0 )
  129.             {
  130.             // Try conventional memory first.
  131.             frame = new ConvMemory( memsize );
  132.             if( !frame || frame->memSize() != memsize )
  133.                 {
  134.                 delete frame;
  135.                 // Next try EMS memory.
  136.                 frame = new EmsMemory( memsize );
  137.                 if( !frame || frame->memSize() != memsize )
  138.                     {
  139.                     delete frame;
  140.                     frame = 0;
  141.                     return 0;
  142.                     }
  143.                 }
  144.             }
  145.         else
  146.             {
  147.             // Try EMS memory first.
  148.             frame = new EmsMemory( memsize );
  149.             if( !frame || frame->memSize() != memsize )
  150.                 {
  151.                 delete frame;
  152.                 // Next try conventional memory.
  153.                 frame = new ConvMemory( memsize );
  154.                 if( !frame || frame->memSize() != memsize )
  155.                     {
  156.                     delete frame;
  157.                     frame = 0;
  158.                     return 0;
  159.                     }
  160.                 }
  161.             }
  162.         // Lock the frame - will only fail if EMS memory.
  163.         frameBuf = frame->lock();
  164.         if( frameBuf == 0 )
  165.             {
  166.             frame->unlock();
  167.             frame->free();
  168.             delete frame;
  169.             frame = 0;
  170.             return 0;
  171.             }
  172.         lseek( handle, addr, SEEK_SET );
  173.         _dos_read( handle, frameBuf, memsize, &nread );
  174.         }
  175.     lockflag++;
  176.     return frameBuf;
  177. }
  178.  
  179. void DiskMemory::unlock()
  180. {
  181.     unsigned nwritten;
  182.     if( !lockflag )
  183.         return;
  184.  
  185.     lockflag--;
  186.     if( lockflag == 0 )
  187.         {
  188.         lseek( handle, addr, SEEK_SET );
  189.         _dos_write( handle, frameBuf, memsize, &nwritten );
  190.         frame->unlock();
  191.         frame->free();
  192.         delete frame;
  193.         frame = 0;
  194.         }
  195. }
  196.  
  197. long DiskMemory::memAvail()
  198. {
  199.     // Note that this does NOT include any expansion space on the disk.
  200.     if( handle < 0 )
  201.         return 0L;
  202.  
  203.     long l = lastAddr;
  204.     DiskMemory *ptr;
  205.  
  206.     for( ptr = head; ptr != 0; ptr = ptr->next )
  207.         l -= ptr->memsize;
  208.     return l;
  209. }
  210.  
  211. long DiskMemory::maxAvail()
  212. {
  213.     // Note that this does NOT include any expansion space on the disk.
  214.     if( handle < 0 )
  215.         return 0L;
  216.  
  217.     long tmp, l = 0;
  218.     DiskMemory* ptr;
  219.  
  220.     if( head == 0 )
  221.         l = lastAddr;
  222.     else
  223.         {
  224.         for( ptr = head; ptr->next != 0; ptr = ptr->next )
  225.             {
  226.             tmp = ptr->next->addr - ptr->addr - ptr->memsize;
  227.             if( tmp > l )
  228.                 l = tmp;
  229.             }
  230.         tmp = lastAddr - ptr->addr - ptr->memsize;
  231.         if( tmp > l )
  232.             l = tmp;
  233.         }
  234.     return l;
  235. }
  236.  
  237. void DiskMemory::init()
  238. {
  239.     if( !isInitialized )
  240.         {
  241.         isInitialized = true;
  242.         char *ptr = DefaultDiskMemDir;
  243.         while( *ptr )    ptr++;
  244.         for( ptr--; *ptr != '\\' && ptr >= DefaultDiskMemDir; ptr-- );
  245.         ptr[1] = 0;
  246.         int i = strlen(DefaultDiskMemDir);
  247.         if( i > 0 && DefaultDiskMemDir[i-1] != '\\' )
  248.             DefaultDiskMemDir[i++] = '\\';
  249.         strcpy( DefaultDiskMemDir+i, "TXXXXXX" );
  250.         mktemp( DefaultDiskMemDir+i );
  251.         if( _dos_creat(DefaultDiskMemDir, 0, &handle) )
  252.             handle = -1;
  253.         if( handle < 0 )
  254.             return;
  255.         lastAddr = 0;
  256.         memsize = 0;
  257.         }
  258. }
  259.  
  260. bool DiskMemory::fitsInto(long addr, long next, word sz)
  261. {
  262.     return bool(next >= addr+sz);
  263. }
  264.  
  265.