/****************************************************************************/ /** **/ /** INT.c **/ /** **/ /** Stack and interrupt manipulation routines for DJGPP **/ /** **/ /** Copyright (C) Marcel de Kogel 1996,1997,1998 **/ /** You are not allowed to distribute this software commercially **/ /** Please, notify me, if you make any changes to this file **/ /****************************************************************************/ #include #include #include #include #include #include #include "INT.h" #define MIN_STACK_SIZE 1024 /* Minumum stack size */ #define MAX_STACK_SIZE 524288 /* Maximum stack size */ #define MIN_STACK_NR 4 /* Minimum number of stacks */ #define MAX_STACK_NR 256 /* Maximum number of stacks */ static unsigned **StackPtr; /* Pointer to an array of stack pointers */ static int StackSize; /* Size of a stack */ static int NumStacks; /* Number of stacks */ static int NumStacksUsed; /* Number of stacks currently used */ static int NumFailed; /* Number of allocations currently failed */ /* Number of calls to AllocStack() that failed */ static int TotalFailed=0; /* Number of calls to AllocStack() that succeeded */ static int TotalSuccess=0; /* Maximum number of stacks used simultaniously */ static int MaxStacksUsed=0; /* Maximum stack size used */ static int MaxStackSize=0; /* Lock variables */ static int LockData (void *addr,unsigned size) { unsigned long base; __dpmi_meminfo info; if (__dpmi_get_segment_base_address(_go32_my_ds(),&base)==-1) return 0; info.handle=0; info.address=base+(unsigned)addr; info.size=size; if (__dpmi_lock_linear_region(&info)==-1) return 0; return 1; } /* Unlock variables */ static int UnlockData (void *addr,unsigned size) { unsigned long base; __dpmi_meminfo info; if (__dpmi_get_segment_base_address(_go32_my_ds(),&base)==-1) return 0; info.handle=0; info.address=base+(unsigned)addr; info.size=size; if (__dpmi_unlock_linear_region(&info)==-1) return 0; return 1; } /****************************************************************************/ /*** GetStackInfo() ***/ /*** Get some info useful for debugging ***/ /****************************************************************************/ void GetStackInfo (int *nFailed,int *nSuccess,int *nUsed,int *nMaxSize) { *nFailed=TotalFailed; *nSuccess=TotalSuccess; *nUsed=MaxStacksUsed; *nMaxSize=MaxStackSize; } /****************************************************************************/ /*** ExitStacks() ***/ /*** Free all resources allocated by InitStacks() ***/ /****************************************************************************/ void ExitStacks (void) { int i,j; int maxsize=0; unsigned char *p; if (!StackPtr) return; for (i=0;iMAX_STACK_SIZE) size=MAX_STACK_SIZE; if (nrMAX_STACK_NR) nr=MAX_STACK_NR; if (size&3) size=(size&(~3))+4; /* stack must be dword-aligned */ StackPtr=malloc (nr*sizeof(unsigned*)); if (!StackPtr) return 0; if (!LockData (StackPtr,nr*sizeof(unsigned*))) return 0; StackSize=size; NumStacks=nr; for (i=0;ipm_offset)-((unsigned)(p+i+4)); i+=3; while (p[++i]!=FILL); *(unsigned*)(p+i)=(unsigned)oldinfo.pm_offset; *(unsigned short*)(p+i+4)=(unsigned short)oldinfo.pm_selector; i+=5; while (p[++i]!=FILL); *(unsigned*)(p+i)=((unsigned)FreeStack)-((unsigned)(p+i+4)); /* Fill the info structure */ info->pm_offset=(unsigned)p; info->pm_selector=_go32_my_cs(); /* Set the interrupt vector */ _go32_dpmi_set_protected_mode_interrupt_vector (nr,info); /* return success */ return 1; } /****************************************************************************/ /*** ResetInt() ***/ /*** Free resources allocated by SetInt() ***/ /****************************************************************************/ int ResetInt (int nr,_go32_dpmi_seginfo *info) { unsigned char *p; int i; /* get pointer */ p=(unsigned char*)info->pm_offset; /* make sure it's valid */ if (!p) return 0; /* check if it points to an interrupt handler */ if (*(unsigned*)p!=*(unsigned*)handler) return 0; /* get old interrupt vector */ i=-1; while (handler[++i]!=FILL); i+=3; while (handler[++i]!=FILL); i+=3; while (handler[++i]!=FILL); i+=3; while (handler[++i]!=FILL); info->pm_offset=*(unsigned*)(p+i); info->pm_selector=*(unsigned short*)(p+i+4); /* set old interrupt vector */ _go32_dpmi_set_protected_mode_interrupt_vector (nr,info); /* unlock and free memory */ UnlockData (p,sizeof(handler)); free (p); return 1; }