1 /* Project 16 Source Code~
2 * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
4 * This file is part of Project 16.
6 * Project 16 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Project 16 is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>, or
18 * write to the Free Software Foundation, Inc., 51 Franklin Street,
19 * Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "src/lib/16_head.h"
25 /* Function: Wait **********************************************************
\r
27 * Parameters: wait - time in microseconds
\r
29 * Description: pauses for a specified number of microseconds.
\r
32 void wait(clock_t wait){
\r
37 goal = wait + clock();
\r
38 while((goal > clock()) && !kbhit()) ;
\r
41 void __near* LargestFreeBlock(size_t* Size)
46 s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
47 while (s0 && (p = _nmalloc(s0)) == NULL)
56 if ((p = _nmalloc(s0 + s1)) != NULL)
63 while (s0 && (p = _nmalloc(s0)) == NULL)
70 size_t _coreleft(void)
73 void __near* pFirst = NULL;
74 void __near* pLast = NULL;
78 void __near* p = LargestFreeBlock(&largest);
79 if (largest < sizeof(void __near*))
85 *(void __near* __near*)p = NULL;
91 *(void __near* __near*)pLast = p;
95 while (pFirst != NULL)
97 void __near* p = *(void __near* __near*)pFirst;
104 void far* LargestFarFreeBlock(size_t* Size)
109 s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
110 while (s0 && (p = _fmalloc(s0)) == NULL)
119 if ((p = _fmalloc(s0 + s1)) != NULL)
126 while (s0 && (p = _fmalloc(s0)) == NULL)
133 size_t _farcoreleft(void)
136 void far* pFirst = NULL;
137 void far* pLast = NULL;
141 void far* p = LargestFarFreeBlock(&largest);
142 if (largest < sizeof(void far*))
148 *(void far* far*)p = NULL;
154 *(void far* far*)pLast = p;
158 while (pFirst != NULL)
160 void far* p = *(void far* far*)pFirst;
167 void huge* LargestHugeFreeBlock(size_t* Size)
172 s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
173 while (s0 && (p = halloc((dword)s0, 1)) == NULL)
182 if ((p = halloc((dword)(s0 + s1), 1)) != NULL)
189 while (s0 && (p = halloc((dword)s0, 1)) == NULL)
196 size_t _hugecoreleft(void)
199 void huge* pFirst = NULL;
200 void huge* pLast = NULL;
204 void huge* p = LargestHugeFreeBlock(&largest);
205 if (largest < sizeof(void huge*))
211 *(void huge* huge*)p = NULL;
217 *(void huge* huge*)pLast = p;
221 while (pFirst != NULL)
223 void huge* p = *(void huge* huge*)pFirst;
230 /*void __based(__self)* LargestBasedFreeBlock(size_t* Size)
234 void __based(__self)* p;
236 s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
237 while (s0 && (p = _bmalloc(segu, s0)) == NULL)
246 if ((p = _bmalloc(segu, s0 + s1)) != NULL)
253 while (s0 && (p = _bmalloc(segu, s0)) == NULL)
260 size_t _basedcoreleft(void)
264 void __based(segu)* pFirst = NULL;
265 void __based(segu)* pLast = NULL;
266 // allocate based heap
\r
267 segu = _bheapseg( 1024 );
\r
268 if( segu == _NULLSEG ) {
\r
269 printf( "Unable to allocate based heap\n" );
278 void __based(segu)* p = LargestBasedFreeBlock(&largest);
279 if (largest < sizeof(void far*))
285 *(void far* far*)p = NULL;
291 *(void far* far*)pLast = p;
295 while (pFirst != NULL)
297 void far* p = *(void far* far*)pFirst;
304 size_t GetFreeSize(void)
306 struct _heapinfo h_info;
308 size_t h_free=0, h_total=0, h_used=0;
310 h_info._pentry = NULL;
312 heap_status = _heapwalk( &h_info );
313 if( heap_status != _HEAPOK ) break;
314 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
315 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
316 h_total += h_info._size;
318 heapstat(heap_status);
322 size_t GetFarFreeSize(void)
324 struct _heapinfo fh_info;
326 size_t fh_free=0, fh_total=0, fh_used=0;
328 fh_info._pentry = NULL;
330 heap_status = _fheapwalk( &fh_info );
331 if( heap_status != _HEAPOK ) break;
332 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
333 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
334 fh_total += fh_info._size;
336 heapstat(heap_status);
340 size_t GetNearFreeSize(void)
342 struct _heapinfo nh_info;
344 size_t nh_free=0, nh_total=0, nh_used=0;
346 nh_info._pentry = NULL;
348 heap_status = _nheapwalk( &nh_info );
349 if( heap_status != _HEAPOK ) break;
350 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
351 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
352 nh_total += nh_info._size;
354 heapstat(heap_status);
361 long int save_pos, size_of_file;
\r
363 save_pos = ftell(fp);
\r
364 fseek(fp, 0L, SEEK_END);
\r
365 size_of_file = ftell(fp);
\r
366 fseek(fp, save_pos, SEEK_SET);
\r
367 return(size_of_file);
\r
370 void print_normal_entry(char *text, dword total, dword used, dword free)
372 printf("%-17s", text);
373 convert("%8sB ", total);
374 convert("%9sB ", used);
375 convert("%9sB\n", free);
379 * As for printf(), but format may only contain a single format specifier,
380 * which must be "%s" and is replaced with the string form of num with commas
381 * separating groups of three digits.
383 * e.g. convert("%s bytes", 1234567) -> "1,234,567 bytes"
385 void convert(const char *format, dword num)
388 char des[4*sizeof(dword)+3];
391 char mycountry[48]; /* probably 34 bytes are enough... */
392 char ksep = ','; /* or . */
395 sregs.ds = FP_SEG(&mycountry);
396 regs.x.dx = FP_OFF(&mycountry);
397 intdosx(®s,®s,&sregs);
398 if (regs.x.cflag == 0) {
399 ksep = mycountry[7]; /* 1000's separator */
400 /* dsep = mycountry[9]; ** decimal separator */
403 n = sprintf(des, "%lu", num);
404 /* insert commas in the string */
406 for (i = n - 3; i > 0; i--) {
408 for (j = n; j >= i; j--)
410 des[i]=ksep; /* ',' */
420 struct _heapinfo fh_info, nh_info, h_info;
422 size_t h_free, nh_free, fh_free, h_total, nh_total, fh_total, h_used, nh_used, fh_used;
424 printf("\n == default ==\n\n");
425 h_info._pentry = NULL;
426 h_free=0; h_total=0; h_used=0;
428 heap_status = _heapwalk( &h_info );
429 if( heap_status != _HEAPOK ) break;
430 printf( " %s block at %Fp of size %4.4X\n",
431 (h_info._useflag == _USEDENTRY ? "USED" : "FREE"),
432 h_info._pentry, h_info._size );
433 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
434 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
435 h_total += h_info._size;
437 heapstat(heap_status);
440 printf("\n == near ==\n\n");
441 nh_info._pentry = NULL;
442 nh_free=0; nh_total=0; nh_used=0;
444 heap_status = _nheapwalk( &nh_info );
445 if( heap_status != _HEAPOK ) break;
446 printf( " %s block at %Fp of size %4.4X\n",
447 (nh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
448 nh_info._pentry, nh_info._size );
449 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
450 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
451 nh_total += nh_info._size;
453 heapstat(heap_status);
456 printf("\n == far ==\n\n");
457 fh_info._pentry = NULL;
458 fh_free=0; fh_total=0; fh_used=0;
460 heap_status = _fheapwalk( &fh_info );
461 if( heap_status != _HEAPOK ) break;
462 printf( " %s block at %Fp of size %4.4X\n",
463 (fh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
464 fh_info._pentry, fh_info._size );
465 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
466 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
467 fh_total += fh_info._size;
469 heapstat(heap_status);
472 printf(kittengets(2,0,"Memory Type Total Used Free\n"));
473 printf( "---------------- -------- -------- --------\n");
474 print_normal_entry(kittengets(2,1,"Default"), (dword)h_total, (dword)h_used, (dword)h_free);
475 print_normal_entry(kittengets(2,1,"Near"), (dword)nh_total, (dword)nh_used, (dword)nh_free);
476 print_normal_entry(kittengets(2,1,"Far"), (dword)fh_total, (dword)fh_used, (dword)fh_free);
477 printf( "---------------- -------- -------- --------\n");
478 //printf("memavl = %lu\n", (dword)_memavl());
479 printf("stackavail = %u\n", stackavail());
482 void heapstat(int heap_status)
484 switch( heap_status ) {
486 //printf( "OK - end of heap\n" );
489 //printf( "OK - heap is empty\n" );
492 printf( "ERROR - heap is damaged\n" );
495 printf( "ERROR - bad pointer to heap\n" );
498 printf( "ERROR - bad node in heap\n" );
503 ///////////////////////////////////////////////////////////////////////////
\r
505 // US_CheckParm() - checks to see if a string matches one of a set of
\r
506 // strings. The check is case insensitive. The routine returns the
\r
507 // index of the string that matched, or -1 if no matches were found
\r
509 ///////////////////////////////////////////////////////////////////////////
\r
511 US_CheckParm(char *parm,char **strings)
\r
517 while (!isalpha(*parm)) // Skip non-alphas
\r
520 for (i = 0;*strings && **strings;i++)
\r
522 for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
\r
539 ==========================
\r
543 ==========================
\r
546 /*void Quit(char *error, ...)
\r
549 unsigned finscreen;
\r
553 va_start(ap,error);
\r
559 CA_CacheGrChunk (PIRACY);
\r
560 finscreen = (unsigned)grsegs[PIRACY];
\r
566 if (error && *error)
\r
575 movedata (finscreen,0,0xb800,0,4000);
\r
586 _argv[1] = "LAST.SHL";
\r
587 _argv[2] = "ENDSCN.SCN";
\r
589 if (execv("LOADSCN.EXE", _argv) == -1)
\r
592 puts("Couldn't find executable LOADSCN.EXE.\n");
\r