Пример #1
0
void MM_FreePtr (memptr *baseptr)
{
	mmblocktype id0_far *scan,id0_far *last;

	last = mmhead;
	scan = last->next;

	if (baseptr == mmrover->useptr)	// removed the last allocated block
		mmrover = mmhead;

	// REFKEEN - Swap order of evaluation, fixes undefined behaviors in case scan == NULL
	// (originally observed while adding support for the 2015 port's data)
	while (scan && (scan->useptr != baseptr))
	//while (scan->useptr != baseptr && scan)
	{
		last = scan;
		scan = scan->next;
	}

	if (!scan)
		Quit ("MM_FreePtr: Block not found!");

	last->next = scan->next;

	FREEBLOCK(scan);
}
Пример #2
0
    void MM_FreePtr (memptr *baseptr)
    {
        mmblocktype id0_far *scan,id0_far *last;

        last = mmhead;
        scan = last->next;

        if (baseptr == mmrover->useptr)	// removed the last allocated block
            mmrover = mmhead;

        while (scan->useptr != baseptr && scan)
        {
            last = scan;
            scan = scan->next;
        }

        if (!scan)
            Quit ("MM_FreePtr: Block not found!");

        last->next = scan->next;

        FREEBLOCK(scan);
    }
Пример #3
0
    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);
    }
Пример #4
0
    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
    }
Пример #5
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.");
}