OSDN Git Service

those programs are messy! wwww
[proj16/16.git] / src / lib / 16_head.c
1 /* Project 16 Source Code~
2  * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
3  *
4  * This file is part of Project 16.
5  *
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.
10  *
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.
15  *
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.
20  *
21  */
22
23 #include "src/lib/16_head.h"
24
25 /* Function: Wait **********************************************************\r
26 *\r
27 *     Parameters:    wait - time in microseconds\r
28 *\r
29 *     Description:    pauses for a specified number of microseconds.\r
30 *\r
31 */\r
32 void wait(clock_t wait){\r
33         clock_t goal;\r
34 \r
35         if(!wait) return;\r
36 \r
37         goal = wait + clock();\r
38         while((goal > clock()) && !kbhit()) ;\r
39 } /* End of wait */
40
41 void __near* LargestFreeBlock(size_t* Size)
42 {
43         size_t s0, s1;
44         void __near* p;
45
46         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
47         while (s0 && (p = _nmalloc(s0)) == NULL)
48                 s0 >>= 1;
49
50         if (p)
51                 _nfree(p);
52
53         s1 = s0 >> 1;
54         while (s1)
55         {
56                 if ((p = _nmalloc(s0 + s1)) != NULL)
57                 {
58                         s0 += s1;
59                         _nfree(p);
60                 }
61         s1 >>= 1;
62         }
63         while (s0 && (p = _nmalloc(s0)) == NULL)
64                 s0 ^= s0 & -s0;
65
66         *Size = s0;
67         return p;
68 }
69
70 size_t _coreleft(void)
71 {
72         size_t total = 0;
73         void __near* pFirst = NULL;
74         void __near* pLast = NULL;
75         for(;;)
76         {
77                 size_t largest;
78                 void __near* p = LargestFreeBlock(&largest);
79                 if (largest < sizeof(void __near*))
80                 {
81                         if (p != NULL)
82                         _nfree(p);
83                         break;
84                 }
85                 *(void __near* __near*)p = NULL;
86                 total += largest;
87                 if (pFirst == NULL)
88                         pFirst = p;
89
90                 if (pLast != NULL)
91                         *(void __near* __near*)pLast = p;
92                 pLast = p;
93         }
94
95         while (pFirst != NULL)
96         {
97                 void __near* p = *(void __near* __near*)pFirst;
98                 _nfree(pFirst);
99                 pFirst = p;
100         }
101         return total;
102 }
103
104 void far* LargestFarFreeBlock(size_t* Size)
105 {
106         size_t s0, s1;
107         void far* p;
108
109         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
110         while (s0 && (p = _fmalloc(s0)) == NULL)
111                 s0 >>= 1;
112
113         if (p)
114                 _ffree(p);
115
116         s1 = s0 >> 1;
117         while (s1)
118         {
119                 if ((p = _fmalloc(s0 + s1)) != NULL)
120                 {
121                         s0 += s1;
122                         _ffree(p);
123                 }
124         s1 >>= 1;
125         }
126         while (s0 && (p = _fmalloc(s0)) == NULL)
127                 s0 ^= s0 & -s0;
128
129         *Size = s0;
130         return p;
131 }
132
133 size_t _farcoreleft(void)
134 {
135         size_t total = 0;
136         void far* pFirst = NULL;
137         void far* pLast = NULL;
138         for(;;)
139         {
140                 size_t largest;
141                 void far* p = LargestFarFreeBlock(&largest);
142                 if (largest < sizeof(void far*))
143                 {
144                         if (p != NULL)
145                         _ffree(p);
146                         break;
147                 }
148                 *(void far* far*)p = NULL;
149                 total += largest;
150                 if (pFirst == NULL)
151                         pFirst = p;
152
153                 if (pLast != NULL)
154                         *(void far* far*)pLast = p;
155                 pLast = p;
156         }
157
158         while (pFirst != NULL)
159         {
160                 void far* p = *(void far* far*)pFirst;
161                 _ffree(pFirst);
162                 pFirst = p;
163         }
164         return total;
165 }
166
167 void huge* LargestHugeFreeBlock(size_t* Size)
168 {
169         size_t s0, s1;
170         void huge* p;
171
172         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
173         while (s0 && (p = halloc((dword)s0, 1)) == NULL)
174                 s0 >>= 1;
175
176         if (p)
177                 hfree(p);
178
179         s1 = s0 >> 1;
180         while (s1)
181         {
182                 if ((p = halloc((dword)(s0 + s1), 1)) != NULL)
183                 {
184                         s0 += s1;
185                         hfree(p);
186                 }
187         s1 >>= 1;
188         }
189         while (s0 && (p = halloc((dword)s0, 1)) == NULL)
190                 s0 ^= s0 & -s0;
191
192         *Size = s0;
193         return p;
194 }
195
196 size_t _hugecoreleft(void)
197 {
198         size_t total = 0;
199         void huge* pFirst = NULL;
200         void huge* pLast = NULL;
201         for(;;)
202         {
203                 size_t largest;
204                 void huge* p = LargestHugeFreeBlock(&largest);
205                 if (largest < sizeof(void huge*))
206                 {
207                         if (p != NULL)
208                         hfree(p);
209                         break;
210                 }
211                 *(void huge* huge*)p = NULL;
212                 total += largest;
213                 if (pFirst == NULL)
214                         pFirst = p;
215
216                 if (pLast != NULL)
217                         *(void huge* huge*)pLast = p;
218                 pLast = p;
219         }
220
221         while (pFirst != NULL)
222         {
223                 void huge* p = *(void huge* huge*)pFirst;
224                 hfree(pFirst);
225                 pFirst = p;
226         }
227         return total;
228 }
229
230 /*void __based(__self)* LargestBasedFreeBlock(size_t* Size)
231 {
232         __segment segu;
233         size_t s0, s1;
234         void __based(__self)* p;
235
236         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
237         while (s0 && (p = _bmalloc(segu, s0)) == NULL)
238                 s0 >>= 1;
239
240         if (p)
241                 _ffree(p);
242
243         s1 = s0 >> 1;
244         while (s1)
245         {
246                 if ((p = _bmalloc(segu, s0 + s1)) != NULL)
247                 {
248                         s0 += s1;
249                         _ffree(p);
250                 }
251         s1 >>= 1;
252         }
253         while (s0 && (p = _bmalloc(segu, s0)) == NULL)
254                 s0 ^= s0 & -s0;
255
256         *Size = s0;
257         return p;
258 }
259
260 size_t _basedcoreleft(void)
261 {
262         __segment segu;
263         size_t total = 0;
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" );
270                 return 0;\r
271                 //exit( 1 );\r
272         }
273         else
274
275         for(;;)
276         {
277                 size_t largest;
278                 void __based(segu)* p = LargestBasedFreeBlock(&largest);
279                 if (largest < sizeof(void far*))
280                 {
281                         if (p != NULL)
282                         _ffree(p);
283                         break;
284                 }
285                 *(void far* far*)p = NULL;
286                 total += largest;
287                 if (pFirst == NULL)
288                         pFirst = p;
289
290                 if (pLast != NULL)
291                         *(void far* far*)pLast = p;
292                 pLast = p;
293         }
294
295         while (pFirst != NULL)
296         {
297                 void far* p = *(void far* far*)pFirst;
298                 _ffree(pFirst);
299                 pFirst = p;
300         }
301         return total;
302 }*/
303
304 size_t GetFreeSize(void)
305 {
306         struct _heapinfo h_info;
307         int heap_status;
308         size_t h_free=0, h_total=0, h_used=0;
309
310         h_info._pentry = NULL;
311         for(;;) {
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;
317         }
318         heapstat(heap_status);
319         return h_free;
320 }
321
322 size_t GetFarFreeSize(void)
323 {
324         struct _heapinfo fh_info;
325         int heap_status;
326         size_t fh_free=0, fh_total=0, fh_used=0;
327
328         fh_info._pentry = NULL;
329         for(;;) {
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;
335         }
336         heapstat(heap_status);
337         return fh_free;
338 }
339
340 size_t GetNearFreeSize(void)
341 {
342         struct _heapinfo nh_info;
343         int heap_status;
344         size_t nh_free=0, nh_total=0, nh_used=0;
345
346         nh_info._pentry = NULL;
347         for(;;) {
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;
353         }
354         heapstat(heap_status);
355         return nh_free;
356 }
357
358 long int
359 filesize(FILE *fp)\r
360 {\r
361         long int save_pos, size_of_file;\r
362 \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
368 }
369
370 void print_normal_entry(char *text, dword total, dword used, dword free)
371 {
372         printf("%-17s", text);
373         convert("%8sB ", total);
374         convert("%9sB ", used);
375         convert("%9sB\n", free);
376 }
377
378 /*
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.
382  *
383  * e.g. convert("%s bytes", 1234567) -> "1,234,567 bytes"
384  */
385 void convert(const char *format, dword num)
386 {
387     int c, i, j, n;
388     char des[4*sizeof(dword)+3];
389     union REGS regs;
390     struct SREGS sregs;
391     char mycountry[48]; /* probably 34 bytes are enough... */
392     char ksep = ',';    /* or . */
393
394     regs.x.ax = 0x3800;
395     sregs.ds = FP_SEG(&mycountry);
396     regs.x.dx = FP_OFF(&mycountry);
397     intdosx(&regs,&regs,&sregs);
398     if (regs.x.cflag == 0) {
399       ksep = mycountry[7];        /* 1000's separator  */
400       /* dsep = mycountry[9];     ** decimal separator */
401     }
402
403     n = sprintf(des, "%lu", num);
404     /* insert commas in the string */
405     c = 3;
406     for (i = n - 3; i > 0; i--) {
407         if (c%3==0) {
408             for (j = n; j >= i; j--)
409                 des[j+1] = des[j];
410             des[i]=ksep;        /* ',' */
411             n++;
412         }
413         c++;
414     }
415     printf(format, des);
416 }
417
418 void heapdump(void)
419 {
420         struct _heapinfo fh_info, nh_info, h_info;
421         int heap_status;
422         size_t h_free, nh_free, fh_free, h_total, nh_total, fh_total, h_used, nh_used, fh_used;
423
424         printf("\n      == default ==\n\n");
425         h_info._pentry = NULL;
426         h_free=0; h_total=0; h_used=0;
427         for(;;) {
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;
436         }
437         heapstat(heap_status);
438
439         //near
440         printf("\n      == near ==\n\n");
441         nh_info._pentry = NULL;
442         nh_free=0; nh_total=0; nh_used=0;
443         for(;;) {
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;
452         }
453         heapstat(heap_status);
454
455         //far
456         printf("\n      == far ==\n\n");
457         fh_info._pentry = NULL;
458         fh_free=0; fh_total=0; fh_used=0;
459         for(;;) {
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;
468         }
469         heapstat(heap_status);
470
471 printf("\n");
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("coreleft = %lu\n", (dword)_coreleft());
479 printf("farcoreleft = %lu\n", (dword)_farcoreleft());
480 printf("GetFreeSize = %lu\n", (dword)GetFreeSize());
481 printf("GetNearFreeSize = %lu\n", (dword)GetNearFreeSize());
482 printf("GetFarFreeSize = %lu\n", (dword)GetFarFreeSize());
483 printf("memavl = %lu\n", (dword)_memavl());
484 printf("stackavail = %u\n", stackavail());
485 }
486
487 void heapstat(int heap_status)
488 {
489         switch( heap_status ) {
490                 case _HEAPEND:
491                         //printf( "OK - end of heap\n" );
492                 break;
493                 case _HEAPEMPTY:
494                         //printf( "OK - heap is empty\n" );
495                 break;
496                 case _HEAPBADBEGIN:
497                         printf( "ERROR - heap is damaged\n" );
498                 break;
499                 case _HEAPBADPTR:
500                         printf( "ERROR - bad pointer to heap\n" );
501                 break;
502                 case _HEAPBADNODE:
503                         printf( "ERROR - bad node in heap\n" );
504         }
505 }
506
507
508 ///////////////////////////////////////////////////////////////////////////\r
509 //\r
510 //      US_CheckParm() - checks to see if a string matches one of a set of\r
511 //              strings. The check is case insensitive. The routine returns the\r
512 //              index of the string that matched, or -1 if no matches were found\r
513 //\r
514 ///////////////////////////////////////////////////////////////////////////\r
515 int\r
516 US_CheckParm(char *parm,char **strings)\r
517 {\r
518         char    cp,cs,\r
519                         *p,*s;\r
520         int             i;\r
521 \r
522         while (!isalpha(*parm)) // Skip non-alphas\r
523                 parm++;\r
524 \r
525         for (i = 0;*strings && **strings;i++)\r
526         {\r
527                 for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)\r
528                 {\r
529                         cs = *s++;\r
530                         if (!cs)\r
531                                 return(i);\r
532                         cp = *p++;\r
533 \r
534                         if (isupper(cs))\r
535                                 cs = tolower(cs);\r
536                         if (isupper(cp))\r
537                                 cp = tolower(cp);\r
538                 }\r
539         }\r
540         return(-1);\r
541 }
542
543 /*\r
544 ==========================\r
545 =\r
546 = Quit\r
547 =\r
548 ==========================\r
549 */\r
550 \r
551 /*void Quit(char *error, ...)\r
552 {\r
553         short exit_code=0;\r
554         unsigned        finscreen;\r
555 \r
556         va_list ap;\r
557 \r
558         va_start(ap,error);\r
559 \r
560 #ifndef CATALOG\r
561         if (!error)\r
562         {\r
563                 CA_SetAllPurge ();\r
564                 CA_CacheGrChunk (PIRACY);\r
565                 finscreen = (unsigned)grsegs[PIRACY];\r
566         }\r
567 #endif\r
568 \r
569         //ShutdownId ();\r
570 \r
571         if (error && *error)\r
572         {\r
573                 vprintf(error,ap);\r
574                 exit_code = 1;\r
575         }\r
576 #ifndef CATALOG\r
577         else\r
578         if (!NoWait)\r
579         {\r
580                 movedata (finscreen,0,0xb800,0,4000);\r
581                 bioskey (0);\r
582         }\r
583 #endif\r
584 \r
585         va_end(ap);\r
586 \r
587 #ifndef CATALOG\r
588         if (!error)\r
589         {\r
590                 _argc = 2;\r
591                 _argv[1] = "LAST.SHL";\r
592                 _argv[2] = "ENDSCN.SCN";\r
593                 _argv[3] = NULL;\r
594                 if (execv("LOADSCN.EXE", _argv) == -1)\r
595                 {\r
596                         clrscr();\r
597                         puts("Couldn't find executable LOADSCN.EXE.\n");\r
598                         exit(1);\r
599                 }\r
600         }\r
601 #endif\r
602 \r
603         exit(exit_code);\r
604 }*/