diff --git a/filelist b/filelist index 9f4f989..2e48287 100644 --- a/filelist +++ b/filelist @@ -146,6 +146,7 @@ */*/sys/bin2c.c */*/sys/makefile */*/sys/sys.c +*/*/sys/talloc.c */*/utils/echoto.bat */*/utils/exeflat.c */*/utils/indent.ini diff --git a/sys/makefile b/sys/makefile index 4fab1f2..ed4aad9 100644 --- a/sys/makefile +++ b/sys/makefile @@ -14,7 +14,8 @@ NASMFLAGS = -DSYS=1 SYS_EXE_dependencies = \ sys.obj \ fdkrncfg.obj \ - prf.obj + prf.obj \ + talloc.obj # *Explicit Rules* production: bin2c.com ..\bin\sys.com @@ -42,6 +43,8 @@ prf.obj: ..\kernel\prf.c fdkrncfg.obj: fdkrncfg.c ..\hdr\kconfig.h +talloc.obj: talloc.c + sys.com: $(SYS_EXE_dependencies) $(CL) $(CFLAGST) $(TINY) $(SYS_EXE_dependencies) diff --git a/sys/sys.c b/sys/sys.c index 0988788..a7fa29f 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -75,7 +75,24 @@ extern WORD CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...); #else -extern long filelength(int __handle); +long filelength(int __handle); +#pragma aux filelength = \ + "mov ax, 0x4202" \ + "xor cx, cx" \ + "xor dx, dx" \ + "int 0x21" \ + "push ax" \ + "push dx" \ + "mov ax, 0x4200" \ + "xor cx, cx" \ + "xor dx, dx" \ + "int 0x21" \ + "pop dx" \ + "pop ax" \ + parm [bx] \ + modify [cx] \ + value [dx ax]; + extern int unlink(const char *pathname); /* some non-conforming functions to make the executable smaller */ diff --git a/sys/talloc.c b/sys/talloc.c new file mode 100644 index 0000000..0e3601f --- /dev/null +++ b/sys/talloc.c @@ -0,0 +1,221 @@ +/** + ** TALLOC.C + ** + ** lean_and_mean malloc()/free implementation + ** by tom ehlert, te@drivesnapshot.de + ** + ** please be careful: + ** + ** this is only slightly tested and has NO ERRORCHECCKING AT ALL + ** no internal checking. no stack checking. nothing !! + ** + ** use it only, if your programs are already debugged !! + **/ + +#include +#include + +#ifdef __TURBOC__ +extern void *__brklvl; +#define sbrk(x) __brklvl +#define brk(newbrk) \ + (((char *)(newbrk) > (char *)(&length) - 0x200) ? \ + -1 : \ + (__brklvl = (newbrk), 0)) +#endif + +#ifdef __WATCOMC__ +#include +#define brk(newbrk) ((int)__brk((unsigned)(newbrk))) +#endif + +#ifdef __GNUC__ +#include +#endif + +#define BUSY (sizeof(size_t)-1) /* Bit set if memory block in use*/ +#define isbusy(x) ((x->length)&BUSY) + + +/** +*** _memavl() +*** return max. memory available +*** Q & D +**/ + +#ifdef DEBUG +extern int printf(const char *x, ...); +#define dbprintf(x) printf x +#else +#define dbprintf(x) +#endif +/*#define printf getch() != ' ' ? exit(0) : printf*/ + +typedef union { + size_t length; + char data[1]; +} block; + +void *malloc(size_t length) +{ + static block *alloc_bottom = NULL; + + block *akt, *next; + block *ltop = sbrk(0); + + if (alloc_bottom == NULL) + alloc_bottom = ltop; + + length = (length + sizeof(size_t) + BUSY) & ~BUSY; + + akt = alloc_bottom; + for (;;) + { + if (akt == ltop) + { + /* end of initialized memory */ + next = (block *)&akt->data[length]; + if (next < akt || brk(next) == -1) + return NULL; + break; + } + dbprintf(("follow [%x] = %x\n",akt, akt->length)); + next = (block *)(&akt->data[akt->length & ~BUSY]); + if (next == ltop || isbusy(akt)) + { + akt = next; /* next block */ + } + else if (isbusy(next)) + { + size_t size = akt->length; + if (size >= length) /* try to split */ + { + if (size > length) /* split */ + { + ((block *)&akt->data[length])->length = + size - length; + } + break; + } + akt = next; /* next block */ + } + else + { + /* merge 2 blocks */ + akt->length += next->length; + } + } + akt->length = length | BUSY; + dbprintf(("set [%x] = %x\n",akt,akt->length)); + return &akt->data[sizeof(size_t)]; +} + +#ifdef __WATCOMC__ +void *_nmalloc(unsigned length) +{ + return malloc(length); +} +#endif + +/** + ** reset busy-bit + **/ + +void free(void *ptr) +{ + if (ptr) + ((char *) ptr)[-sizeof(size_t)] &= ~BUSY; +} + +#ifdef TALLOC_NEED_REALLOC + +/* there isn't often need for realloc ;) + */ + +void* realloc(void *ptr,size_t newlength) +{ + size_t oldlength = ((size_t*)ptr)[-1] & ~BUSY; + void *newptr; + + newptr = malloc(newlength); + + if (newptr == NULL) + { + if (newlength <= oldlength) + return ptr; + } + else + { + memcpy(newptr,ptr,oldlength); + } + + free(ptr); + return newptr; +} +#endif + +#ifdef TEST +#include + +int gallocated = 0; + +void *testalloc(size_t length) +{ + void *p; + + printf("alloc %x bytes - ",length); + + p = malloc(length); + + if (p) gallocated += length,printf("at %x - sum=%x\n",p,gallocated); + else printf("failed\n"); + return p; +} +void testfree(void* p) +{ + gallocated -= ((size_t*)p)[-1] & ~BUSY; + printf("free %x \n",p); + + free(p); +} + + + +main() +{ + char *s1,*s2,*s3,*s4,*s5,*s6; + unsigned size; + + s1 = testalloc(1); + s2 = testalloc(2); + s3 = testalloc(0x10); + s4 = testalloc(0x100); + s5 = testalloc(0x1000); + s6 = testalloc(0xfff0); + + testfree(s3); + s3 = testalloc(6); + testfree(s2); + testalloc(8); + +#ifdef __GNUC__ + for(size = 0xe0000000; size;) +#else + for(size = 0xe000; size;) +#endif + { + if (testalloc(size)) + ; + else + size >>= 1; + } + + + testfree(s1); + testfree(s5); + testfree(s4); + testfree(s6); + + return 1; +} +#endif