diff --git a/src/mem.c b/src/mem.c new file mode 100644 index 0000000..e3c276f --- /dev/null +++ b/src/mem.c @@ -0,0 +1,82 @@ +#include "config.h" +#include "types.h" +#include "error.h" +#include "lexer.h" +#include "ops.h" +#include "reg.h" +#include "mem.h" +#include "var.h" +#include "printf.h" +#include "printf.h" +#include "log.h" +/* + Shared data heap and code memory (total size bytes) + + 0 +------+ | + | Code | V (code.c) + | | + | | ^ + | Data | | (var.c) + +------+ size-1 +*/ +void MemInit(mem_t *M,int size,unsigned char *data) { +#if DEBUG > 0 + log(LOGDEBUG1,"MemInit (%d)\n",0,M->size); +#endif + if ((var_s%MEMALIGN)!=0) { + print_format("Error: MemInit: Variable structure not correctly aligned in memory (%d %% %d = %d)\n", + var_s,MEMALIGN,var_s%MEMALIGN); + } + M->size=size; + if (data==NULL) { + M->data=(unsigned char*)malloc(size); + } else M->data=data; // already allocated + // print_format("MEM %x\n",(long)M->data); + M->top=M->size-1; // empty! + M->bottom=0; + memset(M->data,0,M->size); + memset(M->segments,0,sizeof(segment_t)*MAXTASKS); +#if DEBUG > 0 + log(LOGDEBUG1,"MemInit[%d:%d](%d)\n",M->bottom,M->top,M->size); +#endif +} + +void MemReset(mem_t *M) { +#if DEBUG > 0 + log(LOGDEBUG1,"MemReset[%d:%d](%d)\n",M->bottom,M->top,M->size); +#endif + M->top=M->size-1; // empty! + M->bottom=0; + M->segment=NULL; + memset(M->segments,0,sizeof(segment_t)*MAXTASKS); + HeapInit(); +} + +segment_t *AllocSegment(mem_t *M) { + int i; + for(i=0;isegments[i].used) { + M->segments[i].used=1; + // new segment starts from current top of the code segment (i.e. bottom of M) + M->segments[i].top=M->segments[i].bottom=M->bottom; +#if DEBUG > 0 + log(LOGDEBUG2,"AllocSegment S[%d:%d] M[%d]\n",M->segments[i].bottom,M->segments[i].top,M->bottom); +#endif + return &M->segments[i]; + } + } +} + +int ReleaseSegment(mem_t *M, segment_t *s) { +#if DEBUG > 0 + log(LOGDEBUG1,"ReleaseSegment (ref=%d) S[%d:%d] M[%d:%d:%d]\n",s->refcount,s->bottom,s->top,M->bottom,M->top,M->size); +#endif + if (s->refcount) return 0; + s->used=0; + // TODO: maybe setting M->bottom=s->bottom is wrong!? check for other segments? + if ((s->top+1)==M->bottom) { + M->bottom=s->bottom; + s->top=s->bottom=0; + } + return 1; +}