void MM_GetPtr (memptr *baseptr,id0_unsigned_long_t size) { mmblocktype *scan, *lastscan, *endscan, *purge, *next; id0_int_t search; id0_unsigned_t needed,startseg; needed = (size+15)/16; // convert size from bytes to paragraphs // Formerly known as GETNEWBLOCK if( !(mmnew=mmfree) ) { Quit("MM_GETNEWBLOCK: No free blocks!"); } mmfree=mmfree->next; // fill in start and next after a spot is found mmnew->length = needed; mmnew->useptr = baseptr; mmnew->attributes = BASEATTRIBUTES; for (search = 0; search<3; search++) { // // first search: try to allocate right after the rover, then on up // second search: search from the head pointer up to the rover // third search: compress memory, then scan from start if (search == 1 && mmrover == mmhead) search++; switch (search) { case 0: lastscan = mmrover; scan = mmrover->next; endscan = nullptr; break; case 1: lastscan = mmhead; scan = mmhead->next; endscan = mmrover; break; case 2: MM_SortMem (); lastscan = mmhead; scan = mmhead->next; endscan = nullptr; break; } startseg = lastscan->start + lastscan->length; while (scan != endscan) { if (scan->start - startseg >= needed) { // // got enough space between the end of lastscan and // the start of scan, so throw out anything in the middle // and allocate the new block // purge = lastscan->next; lastscan->next = mmnew; mmnew->start = startseg; *baseptr = EMULATED_SEG_TO_PTR(startseg); mmnew->next = scan; while ( purge != scan) { // free the purgable block next = purge->next; FREEBLOCK(purge); purge = next; // purge another if not at scan } mmrover = mmnew; return; // good allocation! } // // if this block is purge level zero or locked, skip past it // if ( (scan->attributes & LOCKBIT) || !(scan->attributes & PURGEBITS) ) { lastscan = scan; startseg = lastscan->start + lastscan->length; } scan=scan->next; // look at next line } } #ifdef REFKEEN_VER_KDREAMS_CGA_ALL Quit ("MM_GetPtr: Out of memory!"); #elif defined REFKEEN_VER_KDREAMS_ANYEGA_ALL Quit ("Out of memory! Please make sure you have enough free memory."); #endif }
void MM_SortMem (void) { mmblocktype id0_far *scan,id0_far *last,id0_far *next; id0_unsigned_t start,length,source,dest; VW_ColorBorder (15); // (REFKEEN) HACK: Actually show border color BE_ST_ShortSleep(); if (beforesort) beforesort(); scan = mmhead; while (scan) { if (scan->attributes & LOCKBIT) { // // block is locked, so try to pile later blocks right after it // start = scan->start + scan->length; } else { if (scan->attributes & PURGEBITS) { // // throw out the purgable block // next = scan->next; FREEBLOCK(scan); last->next = next; scan = next; continue; } else { // // push the non purgable block on top of the last moved block // if (scan->start != start) { length = scan->length; source = scan->start; dest = start; while (length > 0xf00) { memmove(EMULATED_SEG_TO_PTR(dest), EMULATED_SEG_TO_PTR(source), 0xf00*16); //movedata(source,0,dest,0,0xf00*16); length -= 0xf00; source += 0xf00; dest += 0xf00; } memmove(EMULATED_SEG_TO_PTR(dest), EMULATED_SEG_TO_PTR(source), length*16); //movedata(source,0,dest,0,length*16); scan->start = start; //*(id0_unsigned_t *)scan->useptr = start; *(scan->useptr) = EMULATED_SEG_TO_PTR(start); } start = scan->start + scan->length; } } last = scan; scan = scan->next; // go to next block } mmrover = mmhead; if (aftersort) aftersort(); VW_ColorBorder (0); }
void MM_GetPtr (memptr *baseptr,id0_unsigned_long_t size) { mmblocktype id0_far *scan,id0_far *lastscan,id0_far *endscan ,id0_far *purge,id0_far *next; id0_int_t search; id0_unsigned_t needed,startseg; needed = (size+15)/16; // convert size from bytes to paragraphs GETNEWBLOCK; // fill in start and next after a spot is found mmnew->length = needed; mmnew->useptr = baseptr; mmnew->attributes = BASEATTRIBUTES; for (search = 0; search<3; search++) { // // first search: try to allocate right after the rover, then on up // second search: search from the head pointer up to the rover // third search: compress memory, then scan from start if (search == 1 && mmrover == mmhead) search++; switch (search) { case 0: lastscan = mmrover; scan = mmrover->next; endscan = NULL; break; case 1: lastscan = mmhead; scan = mmhead->next; endscan = mmrover; break; case 2: MM_SortMem (); lastscan = mmhead; scan = mmhead->next; endscan = NULL; break; } startseg = lastscan->start + lastscan->length; while (scan != endscan) { if ((refkeen_current_gamever == BE_GAMEVER_KDREAMS2015) || (scan->start - startseg >= needed)) { // // got enough space between the end of lastscan and // the start of scan, so throw out anything in the middle // and allocate the new block // purge = lastscan->next; lastscan->next = mmnew; if (refkeen_current_gamever == BE_GAMEVER_KDREAMS2015) { // Add a few more bytes as a workaround for vanilla bugs // in places like CA_HuffExpand *baseptr = malloc(size+16); if (*baseptr == NULL) Quit ("Out of memory! Please make sure you have enough free memory."); } else { mmnew->start /*= *(id0_unsigned_t *)baseptr*/ = startseg; *baseptr = EMULATED_SEG_TO_PTR(startseg); } mmnew->next = scan; while ( purge != scan) { // free the purgable block next = purge->next; FREEBLOCK(purge); purge = next; // purge another if not at scan } mmrover = mmnew; return; // good allocation! } // // if this block is purge level zero or locked, skip past it // if ( (scan->attributes & LOCKBIT) || !(scan->attributes & PURGEBITS) ) { lastscan = scan; startseg = lastscan->start + lastscan->length; } scan=scan->next; // look at next line } } Quit ((current_gamever_int < 110) ? "MM_GetPtr: Out of memory!" : "Out of memory! Please make sure you have enough free memory."); }