home *** CD-ROM | disk | FTP | other *** search
- #include "..\MEMORY\MEMORY.HPP"
- #include <string.h>
- #include <io.h>
- #include <dos.h>
- #include <dir.h>
-
- // ------------------------------------------------------------------
- // File: DISK.CPP
- // Path: ...\REHACK\MEMORY\DISK.CPP
- // Version: 0.01
- // Author: Pat Reilly
- // CIS Id: 71333,2764
- // Created On: 6/28/93
- // Modified On:
- // Description: DiskMemory class for REHACK. See MEMORY.TXT for
- // more details.
- // Tabs: 4
- // ------------------------------------------------------------------
-
- char DefaultDiskMemDir[MAXPATH] = ".";
- int DiskFrameOrder = 0;
- // 0 = conventional, EMS
- // 1 = EMS, conventional
-
- int DiskMemory::handle = -1;
- bool DiskMemory::isInitialized = false;
- DiskMemory* DiskMemory::head = 0;
- long DiskMemory::lastAddr = 0L;
-
- // Function called at program exit to remove the temporary file.
- void ClearDisk()
- {
- if( DiskMemory::handle != 0 )
- {
- _dos_close(DiskMemory::handle);
- unlink( DefaultDiskMemDir );
- }
- }
-
- #pragma exit ClearDisk
-
- DiskMemory::DiskMemory()
- {
- init();
- }
-
- DiskMemory::DiskMemory(word sz)
- {
- init();
- allocate(sz);
- }
-
- bool DiskMemory::allocate(word sz)
- {
- if( handle < 0 || memsize != 0 || sz == 0 )
- return false;
-
- long aAddr = 0L;
- DiskMemory* parent = head;
- if( head != 0 )
- {
- aAddr = parent->addr+parent->memsize;
- while( parent->next != 0 )
- {
- aAddr = parent->addr + parent->memsize;
- if( fitsInto( aAddr, parent->next->addr, sz) )
- break;
- parent = parent->next;
- aAddr = parent->addr+parent->memsize;
- }
- }
- if( (parent == 0 || parent->next == 0) && !fitsInto(aAddr, lastAddr, sz) )
- {
- lseek(handle, aAddr+sz-1, SEEK_SET);
- char ch = ' ';
- unsigned nwritten;
- _dos_write( handle, &ch, 1, &nwritten );
- lastAddr = filelength(handle);
- if( !fitsInto(aAddr, lastAddr, sz) )
- return false;
- }
-
- if( parent == 0 )
- {
- next = 0;
- head = this;
- }
- else
- {
- next = parent->next;
- parent->next = this;
- }
- addr = aAddr;
- memsize = sz;
- return true;
- }
-
- void DiskMemory::free()
- {
- DiskMemory* ptr;
-
- if( memsize == 0 || lockflag != 0 )
- return;
-
- if( head == this )
- head = head->next;
- else
- for( ptr = head; ptr->next; ptr = ptr->next )
- if( ptr->next == this )
- {
- ptr->next = ptr->next->next;
- break;
- }
- addr = 0;
- next = 0;
- memsize = 0;
- }
-
- void FAR* DiskMemory::lock()
- {
- unsigned nread;
-
- if( memsize == 0 )
- return 0;
-
- if( !lockflag )
- {
- if( DiskFrameOrder == 0 )
- {
- // Try conventional memory first.
- frame = new ConvMemory( memsize );
- if( !frame || frame->memSize() != memsize )
- {
- delete frame;
- // Next try EMS memory.
- frame = new EmsMemory( memsize );
- if( !frame || frame->memSize() != memsize )
- {
- delete frame;
- frame = 0;
- return 0;
- }
- }
- }
- else
- {
- // Try EMS memory first.
- frame = new EmsMemory( memsize );
- if( !frame || frame->memSize() != memsize )
- {
- delete frame;
- // Next try conventional memory.
- frame = new ConvMemory( memsize );
- if( !frame || frame->memSize() != memsize )
- {
- delete frame;
- frame = 0;
- return 0;
- }
- }
- }
- // Lock the frame - will only fail if EMS memory.
- frameBuf = frame->lock();
- if( frameBuf == 0 )
- {
- frame->unlock();
- frame->free();
- delete frame;
- frame = 0;
- return 0;
- }
- lseek( handle, addr, SEEK_SET );
- _dos_read( handle, frameBuf, memsize, &nread );
- }
- lockflag++;
- return frameBuf;
- }
-
- void DiskMemory::unlock()
- {
- unsigned nwritten;
- if( !lockflag )
- return;
-
- lockflag--;
- if( lockflag == 0 )
- {
- lseek( handle, addr, SEEK_SET );
- _dos_write( handle, frameBuf, memsize, &nwritten );
- frame->unlock();
- frame->free();
- delete frame;
- frame = 0;
- }
- }
-
- long DiskMemory::memAvail()
- {
- // Note that this does NOT include any expansion space on the disk.
- if( handle < 0 )
- return 0L;
-
- long l = lastAddr;
- DiskMemory *ptr;
-
- for( ptr = head; ptr != 0; ptr = ptr->next )
- l -= ptr->memsize;
- return l;
- }
-
- long DiskMemory::maxAvail()
- {
- // Note that this does NOT include any expansion space on the disk.
- if( handle < 0 )
- return 0L;
-
- long tmp, l = 0;
- DiskMemory* ptr;
-
- if( head == 0 )
- l = lastAddr;
- else
- {
- for( ptr = head; ptr->next != 0; ptr = ptr->next )
- {
- tmp = ptr->next->addr - ptr->addr - ptr->memsize;
- if( tmp > l )
- l = tmp;
- }
- tmp = lastAddr - ptr->addr - ptr->memsize;
- if( tmp > l )
- l = tmp;
- }
- return l;
- }
-
- void DiskMemory::init()
- {
- if( !isInitialized )
- {
- isInitialized = true;
- char *ptr = DefaultDiskMemDir;
- while( *ptr ) ptr++;
- for( ptr--; *ptr != '\\' && ptr >= DefaultDiskMemDir; ptr-- );
- ptr[1] = 0;
- int i = strlen(DefaultDiskMemDir);
- if( i > 0 && DefaultDiskMemDir[i-1] != '\\' )
- DefaultDiskMemDir[i++] = '\\';
- strcpy( DefaultDiskMemDir+i, "TXXXXXX" );
- mktemp( DefaultDiskMemDir+i );
- if( _dos_creat(DefaultDiskMemDir, 0, &handle) )
- handle = -1;
- if( handle < 0 )
- return;
- lastAddr = 0;
- memsize = 0;
- }
- }
-
- bool DiskMemory::fitsInto(long addr, long next, word sz)
- {
- return bool(next >= addr+sz);
- }
-
-