⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memmgr.c

📁 用C语言实现的DOS操作系统的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

	/* Initialize                                           */
	p = (mcb FAR *)(MK_FP(first_mcb, 0));

	/* Search through memory blocks                         */
	for(q = (mcb FAR *)0, *size = 0, found = FALSE; !found; )
	{
		/* check for corruption                         */
		if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
			return DE_MCBDESTRY;

		/* Test for largest fit/available               */
		if((p -> m_psp == FREE_PSP) && (p -> m_size > *size))
		{
			*size = p -> m_size;
			q = p;
		}
		/* not free - bump the pointer          */
		if(p -> m_type != MCB_LAST)
			p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
		/* was there no room (q == 0)?          */
		else if(p -> m_type == MCB_LAST && q == (mcb FAR *)0)
			return DE_NOMEM;
		/* something was found - continue       */
		else
			found = TRUE;
	}
	if( q != 0)
		return SUCCESS;
	else
		return DE_NOMEM;
}


COUNT 
DosMemFree (UWORD para)
{
	REG mcb FAR *p, FAR *q;
	COUNT i;

	/* Initialize                                           */
	p = (mcb FAR *)(MK_FP(para, 0));

	/* check for corruption                         */
	if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
		return DE_INVLDMCB;

	/* Mark the mcb as free so that we can later    */
	/* merge with other surrounding free mcb's      */
	p -> m_psp = FREE_PSP;
	for(i = 0; i < 8; i++)
		p -> m_name[i] = '\0';

	/* Now merge free blocks                        */
	for(p = (mcb FAR *)(MK_FP(first_mcb, 0)); p -> m_type != MCB_LAST; p = q)
	{
		/* make q a pointer to the next block   */
		q = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
		/* and test for corruption              */
		if(q -> m_type != MCB_NORMAL && q -> m_type != MCB_LAST)
			return DE_MCBDESTRY;
		if(p -> m_psp != FREE_PSP)
			continue;

		/* test if next is free - if so merge   */
		if(q -> m_psp == FREE_PSP)
		{
			/* Always flow type down on free */
			p -> m_type = q -> m_type;
			p -> m_size += q -> m_size + 1;
			/* and make pointers the same   */
			/* since the next free is now   */
			/* this block                   */
			q = p;
		}
	}
	return SUCCESS;
}

COUNT 
DosMemChange (UWORD para, UWORD size, UWORD *maxSize)
{
	REG mcb FAR *p, FAR *q;
	REG COUNT i;


	/* Initialize                                                   */
	p = (mcb FAR *)(MK_FP(--para, 0));

	/* check for corruption                                         */
	if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
		return DE_MCBDESTRY;

	/* check for wrong allocation                                   */
	if(size > p -> m_size)
	{
		REG UCOUNT delta;

		if (p -> m_type == MCB_LAST)
		{      
		    if (maxSize) *maxSize = p -> m_size + q -> m_size;
		    return DE_NOMEM;
		}

		/* make q a pointer to the next block                   */
		q = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);

		/* check for corruption                                         */
		if(q -> m_type != MCB_NORMAL && q -> m_type != MCB_LAST)
		    return DE_MCBDESTRY;

		/* if next mcb is not free, error no memory             */
		if(q -> m_psp != FREE_PSP)
		{        
			if (maxSize) *maxSize = p -> m_size;
			return DE_NOMEM;
		}
		/* reduce the size of q and add difference to p         */
		/* but check that q is big enough first                 */
		delta = size - p -> m_size;
		 
		if(q -> m_size < delta)
		{        
			
			if (maxSize) *maxSize = p -> m_size + q -> m_size;
			return DE_NOMEM;
		}
		
		q -> m_size -= delta;
		p -> m_size += delta;

		/* Now go back and adjust q, we'll make p new q         */
		p = MK_FP(far2para((VOID FAR *)q) + delta, 0);
		p -> m_type = q -> m_type;
		p -> m_psp  = q -> m_psp;
		p -> m_size = q -> m_size;
		
		for(i = 0; i < 8; i++)
		    p -> m_name[i] = q -> m_name[i];

		/* and finished                                         */
		return SUCCESS;
	}

	/* else, shrink it down                                         */
	else if(size < p -> m_size)
	{
		/* make q a pointer to the new next block               */
		q = MK_FP(far2para((VOID FAR *)p) + size + 1, 0);
		/* reduce the size of p and add difference to q         */
		q -> m_type = p -> m_type;
		q -> m_size = p -> m_size - size - 1;
		
		p -> m_size = size;

		/* Make certian the old psp is not last (if it was)     */
		p -> m_type = MCB_NORMAL;

		/* Mark the mcb as free so that we can later    */
		/* merge with other surrounding free mcb's      */
		q -> m_psp = FREE_PSP;
		for(i = 0; i < 8; i++)
			q -> m_name[i] = '\0';

		/* now free it so that we have a complete block */
		return DosMemFree(far2para((VOID FAR *)q));
	}

	/* otherwise, its a no-op                                       */
	else
		return SUCCESS;
}

COUNT 
DosMemCheck (void)
{
	REG mcb FAR *p;

	/* Initialize                                           */
	p = (mcb FAR *)(MK_FP(first_mcb, 0));

	/* Search through memory blocks                         */
	for( ; ; )
	{
		/* check for corruption                         */
		if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
			return DE_MCBDESTRY;

		/* not corrupted - if last we're OK!            */
		if(p -> m_type == MCB_LAST)
			return SUCCESS;

		/* not corrupted - but not end, bump the pointer */
		else if(p -> m_type != MCB_LAST)
			p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);

		/* totally lost - bad exit                      */
		else
			return DE_MCBDESTRY;
	}
}

COUNT 
FreeProcessMem (UWORD ps)
{
	mcb FAR *p;

	/* Initialize                                           */
	p = (mcb FAR *)(MK_FP(first_mcb, 0));

	/* Search through memory blocks                         */
	for( ; ; )
	{
		/* check for corruption                         */
		if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
			return DE_MCBDESTRY;

		if(p -> m_psp == ps) 
			DosMemFree( FP_SEG(p) );

		/* not corrupted - if last we're OK!            */
		if(p -> m_type == MCB_LAST) break;
		p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);

	}
	return SUCCESS;
}

COUNT
DosGetLargestBlock(UWORD FAR *block)
{
	UWORD sz = 0;
	mcb FAR *p;
	*block = sz;

	/* Initialize                                           */
	p = (mcb FAR *)(MK_FP(first_mcb, 0));

	/* Search through memory blocks                         */
	for( ; ; )
	{
		/* check for corruption                         */
		if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
			return DE_MCBDESTRY;

		if (p -> m_psp == FREE_PSP && p -> m_size > sz)
		    sz = p -> m_size;

		/* not corrupted - if last we're OK!            */
		if(p -> m_type == MCB_LAST) break;
		p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);

	}
	*block = sz;
	return SUCCESS;
}

VOID 
show_chain (void)
{
	mcb FAR *p = (mcb FAR *)(MK_FP(first_mcb, 0));

	for(;;)
	{
		mcb_print(p);
		if(p -> m_type == MCB_LAST || p -> m_type != MCB_NORMAL)
			return;
		else
			p = (mcb FAR *)(MK_FP(far2para((VOID FAR *)p)+p -> m_size+1,0));
	}
}


VOID 
mcb_print (mcb FAR *mcbp)
{
	static BYTE buff[9];
	VOID _fmemcpy();

	_fmemcpy((BYTE FAR *)buff, (BYTE FAR *)(mcbp -> m_name), 8);
	buff[8] = '\0';
	printf("%04x:%04x -> |%s| m_type = 0x%02x; m_psp = 0x%04x; m_size = 0x%04x\n",
		FP_SEG(mcbp),
		FP_OFF(mcbp),
		*buff == '\0' ? "*NO-ID*" : buff,
		mcbp -> m_type,
		mcbp -> m_psp,
		mcbp -> m_size);
}


VOID _fmemcpy(BYTE FAR *d, BYTE FAR *s, REG COUNT n)
{
	while(n--)
	      *d++ = *s++;

}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -