static Bit8u EMM_AllocateSystemHandle(Bit16u pages) { /* Check for enough free pages */ if ((MEM_FreeTotal()/ 4) < pages) { return EMM_OUT_OF_LOG;} Bit16u handle = 0; // emm system handle (reserved for OS usage) /* Release memory if already allocated */ if (emm_handles[handle].pages != NULL_HANDLE) { MEM_ReleasePages(emm_handles[handle].mem); } MemHandle mem = MEM_AllocatePages(pages*4,false); if (!mem) E_Exit("EMS:System handle memory allocation failure"); emm_handles[handle].pages = pages; emm_handles[handle].mem = mem; return EMM_NO_ERROR; }
static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; if (emm_handles[handle].pages != 0) { /* Check for enough pages */ if (!MEM_ReAllocatePages(emm_handles[handle].mem,pages*4,false)) return EMM_OUT_OF_LOG; } else { MemHandle mem = MEM_AllocatePages(pages*4,false); if (!mem) E_Exit("EMS:Memory allocation failure during reallocation"); emm_handles[handle].mem = mem; } /* Update size */ emm_handles[handle].pages=pages; return EMM_NO_ERROR; }
Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) { // size = kb /* Find free handle */ Bit16u index=1; while (!xms_handles[index].free) { if (++index>=XMS_HANDLES) return XMS_OUT_OF_HANDLES; } MemHandle mem; if (size!=0) { Bitu pages=(size/4) + ((size & 3) ? 1 : 0); mem=MEM_AllocatePages(pages,true); if (!mem) return XMS_OUT_OF_SPACE; } else { mem=MEM_GetNextFreePage(); if (mem==0) LOG(LOG_MISC,LOG_ERROR)("XMS:Allocate zero pages with no memory left"); } xms_handles[index].free=false; xms_handles[index].mem=mem; xms_handles[index].locked=0; xms_handles[index].size=size; handle=index; return 0; }
static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle,bool can_allocate_zpages) { /* Check for 0 page allocation */ if (!pages) { if (!can_allocate_zpages) return EMM_ZERO_PAGES; } /* Check for enough free pages */ if ((MEM_FreeTotal()/ 4) < pages) { return EMM_OUT_OF_LOG;} Bit16u handle = 1; /* Check for a free handle */ while (emm_handles[handle].pages != NULL_HANDLE) { if (++handle >= EMM_MAX_HANDLES) {return EMM_OUT_OF_HANDLES;} } MemHandle mem = 0; if (pages) { mem = MEM_AllocatePages(pages*4,false); if (!mem) E_Exit("EMS:Memory allocation failure"); } emm_handles[handle].pages = pages; emm_handles[handle].mem = mem; /* Change handle only if there is no error. */ dhandle = handle; return EMM_NO_ERROR; }
bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) { if (handle<=0) { if (!pages) return true; handle=MEM_AllocatePages(pages,sequence); return (handle>0); } if (!pages) { MEM_ReleasePages(handle); handle=-1; return true; } MemHandle index=handle; MemHandle last;Bitu old_pages=0; while (index>0) { old_pages++; last=index; index=memory.mhandles[index]; } if (old_pages == pages) return true; if (old_pages > pages) { /* Decrease size */ pages--;index=handle;old_pages--; while (pages) { index=memory.mhandles[index]; pages--;old_pages--; } MemHandle next=memory.mhandles[index]; memory.mhandles[index]=-1; index=next; while (old_pages) { next=memory.mhandles[index]; memory.mhandles[index]=0; index=next; old_pages--; } return true; } else { /* Increase size, check for enough free space */ Bitu need=pages-old_pages; if (sequence) { index=last+1; Bitu free=0; while ((index<(MemHandle)memory.pages) && !memory.mhandles[index]) { index++;free++; } if (free>=need) { /* Enough space allocate more pages */ index=last; while (need) { memory.mhandles[index]=index+1; need--;index++; } memory.mhandles[index]=-1; return true; } else { /* Not Enough space allocate new block and copy */ MemHandle newhandle=MEM_AllocatePages(pages,true); if (!newhandle) return false; MEM_BlockCopy(newhandle*4096,handle*4096,old_pages*4096); MEM_ReleasePages(handle); handle=newhandle; return true; } } else { MemHandle rem=MEM_AllocatePages(need,false); if (!rem) return false; memory.mhandles[last]=rem; return true; } } return 0; }