OSDN Git Service

updated copyleft and need to test and fix newer version of open watcom
[proj16/16.git] / src / lib / 16_head.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2022 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
3  *\r
4  * This file is part of Project 16.\r
5  *\r
6  * Project 16 is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Project 16 is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
19  * Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  */\r
22 \r
23 #include "src/lib/16_head.h"\r
24 \r
25 //cpu reg stuff for _AX, _BX, _CX, _DX\r
26 #ifdef __WATCOMC__\r
27 union regs CPURegs;\r
28 #endif\r
29 \r
30 // big global status text buffer\r
31 char global_temp_status_text[512];\r
32 char global_temp_status_text2[512];\r
33 \r
34 long int\r
35 filesize(FILE *fp)\r
36 {\r
37         long int save_pos, size_of_file;\r
38 \r
39         save_pos = ftell(fp);\r
40         fseek(fp, 0L, SEEK_END);\r
41         size_of_file = ftell(fp);\r
42         fseek(fp, save_pos, SEEK_SET);\r
43         return(size_of_file);\r
44 }\r
45 \r
46 // clrstdin() clear any leftover chars tha may be in stdin stream //\r
47 void clrstdin()\r
48 {\r
49    int ch = 0;\r
50    while( ( ch = getchar() ) != '\n' && ch != EOF );\r
51 }\r
52 \r
53 //from http://stackoverflow.com/questions/2736753/how-to-remove-extension-from-file-name\r
54 // remove_ext: removes the "extension" from a file spec.\r
55 //   mystr is the string to process.\r
56 //   dot is the extension separator.\r
57 //   sep is the path separator (0 means to ignore).\r
58 // Returns an allocated string identical to the original but\r
59 //   with the extension removed. It must be freed when you're\r
60 //   finished with it.\r
61 // If you pass in NULL or the new string can't be allocated,\r
62 //   it returns NULL.\r
63 \r
64 char *remove_ext (char* mystr, char dot, char sep) {\r
65         char *retstr, *lastdot, *lastsep;\r
66 \r
67         // Error checks and allocate string.\r
68         if (mystr == NULL)\r
69                 return NULL;\r
70         if ((retstr = malloc(strlen (mystr) + 1)) == NULL)\r
71                 return NULL;\r
72 \r
73         // Make a copy and find the relevant characters.\r
74 \r
75         strcpy (retstr, mystr);\r
76         lastdot = strrchr (retstr, dot);\r
77         lastsep = (sep == 0) ? NULL : strrchr (retstr, sep);\r
78 \r
79         // If it has an extension separator.\r
80 \r
81         if (lastdot != NULL) {\r
82                 // and it's before the extenstion separator.\r
83 \r
84                 if (lastsep != NULL) {\r
85                         if (lastsep < lastdot) {\r
86                                 // then remove it.\r
87 \r
88                                 *lastdot = '\0';\r
89                         }\r
90                 } else {\r
91                         // Has extension separator with no path separator.\r
92 \r
93                         *lastdot = '\0';\r
94                 }\r
95         }\r
96 \r
97         // Return the modified string.\r
98         free(mystr);\r
99         return retstr;\r
100 }\r
101 \r
102 \r
103 //from http://quiz.geeksforgeeks.org/c-program-cyclically-rotate-array-one/\r
104 void rotateR(byte *arr, byte n)\r
105 {\r
106         byte x = arr[n-1], i;\r
107         for (i = n-1; i > 0; i--)\r
108                 arr[i] = arr[i-1];\r
109         arr[0] = x;\r
110 }\r
111 \r
112 void rotateL(byte *arr, byte n)\r
113 {\r
114         byte x = arr[n+1], i;\r
115         for (i = n+1; i > 0; i++)\r
116                 arr[i] = arr[i+1];\r
117         arr[0] = x;\r
118 }\r
119 \r
120 void printmeminfoline(byte *strc, const byte *pee, size_t h_total, size_t h_used, size_t h_free)\r
121 {\r
122         byte str[64];\r
123         strcat(strc,pee); strcat(strc,"            "); ultoa((dword)h_total,str,10); strcat(strc,str);\r
124         if(strlen(str)<=4) strcat(strc,"        "); //printf("%u\n", strlen(str));\r
125         strcat(strc,"   "); ultoa((dword)h_used,str,10); strcat(strc,str); strcat(strc,"        "); strcat(strc,"  ");\r
126         ultoa((dword)h_free,str,10); strcat(strc,str);\r
127         strcat(strc,"\n");\r
128 }\r
129 \r
130 ///////////////////////////////////////////////////////////////////////////\r
131 //\r
132 //      US_CheckParm() - checks to see if a string matches one of a set of\r
133 //              strings. The check is case insensitive. The routine returns the\r
134 //              index of the string that matched, or -1 if no matches were found\r
135 //\r
136 ///////////////////////////////////////////////////////////////////////////\r
137 int\r
138 US_CheckParm(char *parm,char **strings)\r
139 {\r
140         char    cp,cs,\r
141                         *p,*s;\r
142         int             i;\r
143 \r
144         while (!isalpha(*parm)) // Skip non-alphas\r
145                 parm++;\r
146 \r
147         for (i = 0;*strings && **strings;i++)\r
148         {\r
149                 for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)\r
150                 {\r
151                         cs = *s++;\r
152                         if (!cs)\r
153                                 return(i);\r
154                         cp = *p++;\r
155 \r
156                         if (isupper(cs))\r
157                                 cs = tolower(cs);\r
158                         if (isupper(cp))\r
159                                 cp = tolower(cp);\r
160                 }\r
161         }\r
162         return(-1);\r
163 }\r
164 \r
165 // for input test //\r
166 byte dirchar(byte in)\r
167 {\r
168         byte out;\r
169         switch(in)\r
170         {\r
171                 case 0: //up\r
172                         out = 0x1E;\r
173                 break;\r
174                 case 4: //down\r
175                         out = 0x1F;\r
176                 break;\r
177                 case 1: //left\r
178                         out = 0x11;\r
179                 break;\r
180                 case 3: //right\r
181                         out = 0x10;\r
182                 break;\r
183                 default: //null\r
184                         out = 0xB3;\r
185                 break;\r
186         }\r
187         return out;\r
188 }\r
189 \r
190 //from: http://stackoverflow.com/questions/5349896/print-a-struct-in-c\r
191 void print_mem(void const *vp, size_t n)\r
192 {\r
193         size_t i;\r
194         unsigned char const *p = vp;\r
195         for (i=0; i<n; i++)\r
196         {\r
197                 printf("%02x", p[i]);\r
198                 //printf("%c", p[i]);\r
199                 if((!(i%16)) && i) printf("\n");\r
200                 else printf(" ");\r
201                 //printf("%u%%40=%u\n", i, i%40);\r
202         }\r
203         putchar('\n');\r
204         printf("\nstruct size is %zu bytes\n", n);\r
205 };\r
206 \r
207 //from: https://groups.google.com/forum/#!topic/comp.lang.asm.x86/QtuVXl43nDo\r
208 void hres (void)\r
209 {\r
210         __asm {\r
211                 mov     ax,3\r
212                 int     10h\r
213                 mov     ax,1112h\r
214                 xor     bx,bx\r
215                 int     10h\r
216         }\r
217 }\r
218 \r
219 //#define REGIDUMP_HEX\r
220 #define REGIDUMP_DUMPFLAGS\r
221 //#define REGIDUMP_USE_CAPS     //uncomment to use the assembly\r
222 //regester dump~\r
223 void regidump()\r
224 {\r
225         //GENERAL PURPOSE\r
226         unsigned short _ax,_bx,_cx,_dx;\r
227 #ifndef __BORLANDC__\r
228         unsigned short _cflag;\r
229 #endif\r
230         unsigned char _al,_ah,_bl,_bh,_cl,_ch,_dl,_dh;\r
231 \r
232         unsigned short _bp,_si,_di,_sp;\r
233 \r
234         unsigned short _cs_,_ds_,_es_,_ss_;     //SEGMENT\r
235 //      unsigned short _ip;     //SPECIAL PURPOSE\r
236         _ax=_bx=_cx=_dx=_si=_di=_bp=_sp=_cs_=_ds_=_es_=_ss_=0;\r
237 #ifndef __BORLANDC__\r
238         _cflag=0;\r
239 #endif\r
240         _ah=_al=_bh=_bl=_ch=_cl=_dh=_dl=0;\r
241 \r
242 #ifndef REGIDUMP_USE_CAPS\r
243         __asm {\r
244                 mov _ax,ax\r
245                 mov _bx,bx\r
246                 mov _cx,cx\r
247                 mov _dx,dx\r
248 \r
249                 mov _si,si\r
250                 mov _di,di\r
251 \r
252                 /*mov _ip,ip\r
253 \r
254                 mov _cf,cf\r
255                 mov _pf,pf\r
256                 mov _af,af\r
257                 mov _zf,zf\r
258                 mov _sf,sf\r
259                 mov _tf,tf\r
260                 mov _if,if\r
261                 mov _df,df\r
262                 mov _of,of*/\r
263                 mov _ah,ah\r
264                 mov _al,al\r
265                 mov _bh,bh\r
266                 mov _bl,bl\r
267                 mov _ch,ch\r
268                 mov _cl,cl\r
269                 mov _dh,dh\r
270                 mov _dl,dl\r
271         }\r
272 #else\r
273 _ax=_AX;\r
274 _bx=_BX;\r
275 _cx=_CX;\r
276 _dx=_DX;\r
277 \r
278 _si=_SI;\r
279 _di=_DI;\r
280 \r
281 _ah=_AH;\r
282 _al=_AL;\r
283 _bh=_BH;\r
284 _bl=_BL;\r
285 _ch=_CH;\r
286 _cl=_CL;\r
287 _dh=_DH;\r
288 _dl=_DL;\r
289 #endif\r
290 #ifndef __BORLANDC__\r
291         _cflag=_CFLAG;\r
292 #endif\r
293         __asm {\r
294                 mov _bp,bp\r
295                 mov _sp,sp\r
296 \r
297                 mov _cs_,cs\r
298                 mov _ds_,ds\r
299                 mov _es_,es\r
300                 mov _ss_,ss\r
301         }\r
302 //      printf("integer values: ax=%04d bx=%04d cx=%04d dx=%04d\n", a, b, c, d);\r
303 //      printf("unsigned values:ax=%04u bx=%04u cx=%04u dx=%04u\n", a, b, c, d);\r
304         printf("================================================================================");\r
305         printf("16 bit 8088 register values\n");\r
306         printf("================================================================================");\r
307         printf("general purpose:\n");\r
308 #ifndef REGIDUMP_HEX\r
309         printf("        ax=%04u\n       bx=%04u\n       cx=%04u\n       dx=%04u\n\n", _ax, _bx, _cx, _dx);\r
310         printf("        si=%04u\n       di=%04u\n       bp=%04u\n       sp=%04u\n", _si, _di, _bp, _sp);\r
311 #else\r
312         printf("        ax=%04x\n       bx=%04x\n       cx=%04x\n       dx=%04x\n\n", _ax, _bx, _cx, _dx);\r
313         printf("        si=%04x\n       di=%04x\n       bp=%04x\n       sp=%04x\n", _si, _di, _bp, _sp);\r
314 #endif\r
315         printf("                ---------------------------------------\n");\r
316 \r
317 \r
318 \r
319         printf("segment:\n");\r
320 #ifndef REGIDUMP_HEX\r
321         //printf("      cs=%04u\n       ds=%04u\n       es=%04u\n       ss=%04u\n", _cs_, _ds, _es_, _ss_);\r
322         printf("        cs=%04u\n", _cs_);      printf("        ds=%04u\n", _ds_);      printf("        es=%04u\n", _es_);      printf("        ss=%04u\n", _ss_);\r
323 #else\r
324         //printf("      cs=%04x\n       ds=%04x\n       es=%04x\n       ss=%04x\n", _cs_, _ds_, _es_, _ss_);\r
325         printf("        cs=%04x\n", _cs_);      printf("        ds=%04x\n", _ds_);      printf("        es=%04x\n", _es_);      printf("        ss=%04x\n", _ss_);\r
326 #endif\r
327         printf("                ---------------------------------------\n");\r
328 \r
329 \r
330 #ifndef __BORLANDC__\r
331         printf("cflags:\n");\r
332 /*      printf("        ip=%04u\n\n", _ip);\r
333         printf("        cf=%04u\npf=%04u\naf=%04u\nzf=%04u\nsf=%04u\ntf=%04u\nif=%04u\ndf=%04u\nof=%04u\n", _cf, _pf, _af, _zf, _sf, _tf, _if, _df, _of);\r
334         printf("                ---------------------------------------\n");*/\r
335 #ifdef REGIDUMP_DUMPFLAGS\r
336 #ifndef REGIDUMP_HEX\r
337 //      printf("        ip=%04u\n\n", _IP);\r
338 //      printf("        cf=%04u\npf=%04u\naf=%04u\nzf=%04u\nsf=%04u\ntf=%04u\nif=%04u\ndf=%04u\nof=%04u\n", _CF, _PF, _AF, _ZF, _SF, _TF, _IF, _DF, _OF);\r
339 \r
340         printf("cflag: "BYTE_TO_BINARY_PATTERN""BYTE_TO_BINARY_PATTERN"\n",             BYTE_TO_BINARY(_cflag>>8), BYTE_TO_BINARY(_cflag));\r
341 #else\r
342 //      printf("        ip=%04x\n\n", _IP);\r
343 //      printf("        cf=%04x\npf=%04x\naf=%04x\nzf=%04x\nsf=%04x\ntf=%04x\nif=%04x\ndf=%04x\nof=%04x\n", _CF, _PF, _AF, _ZF, _SF, _TF, _IF, _DF, _OF);\r
344         printf("cflag: %016x\n",(_cflag));\r
345         printf("        ahl=%016x", _al|(_ah<<4));\r
346 #endif\r
347         printf("testing\n");\r
348 //      printf("dx: "NIBBLE_TO_BINARY_PATTERN""NIBBLE_TO_BINARY_PATTERN"\n",            NIBBLE_TO_BINARY(_dx>>4), NIBBLE_TO_BINARY(_dx));\r
349 //      printf("dx: "BYTE_TO_BINARY_PATTERN""BYTE_TO_BINARY_PATTERN"\n",                BYTE_TO_BINARY(_dx>>8), BYTE_TO_BINARY(_dx));\r
350         printf("dx: "WORD_TO_BINARY_PATTERN"\n",                WORD_TO_BINARY(_dx));\r
351         printf("                ---------------------------------------\n");\r
352 #endif\r
353 #endif\r
354 \r
355         printf("for more info see\n     http://stackoverflow.com/questions/9130349/how-many-registers-are-there-in-8086-8088\n");\r
356         printf("================================================================================");\r
357 }\r