OSDN Git Service

main.c変数の宣言をまとめた
[heavyosecpu/HeavyOSECPU.git] / main.c
1 #include "osecpu.h"
2
3 void putKeybuf(int i)
4 {
5         if (keybuf_c < KEYBUFSIZ) {
6                 keybuf[keybuf_w] = i;
7                 keybuf_c++;
8                 keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1);
9         }
10         return;
11 }
12
13 int osecpuMain(int argc, char **argv)
14 {
15     FILE *fp, *fp2;
16     unsigned char *appbin, *up;
17     unsigned char *jitbuf, *sysjit00, *sysjit;
18     unsigned char *systmp0, *systmp1, *systmp2;
19     unsigned char *opTbl;
20     HOSECPU_LabelListTag *label;
21     int level;
22     int tmpsiz, i;
23     jmp_buf setjmpEnv;
24         double tm0, tm1, tm2;
25         HOSECPU_PointerControlTag *ptrCtrl;
26     unsigned char *syslib;
27     int appsiz0, appsiz1;
28     const char *argv1;
29     int argDebug = 0, stacksiz = 1;
30     const  char *cp;
31     HOSECPU_RuntimeEnvironment regs;
32         void(*jitfunc)(char *);
33     unsigned char *jp;
34     
35         appbin = malloc(APPSIZ1);
36         jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */
37         //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0;
38         // syslib.oseのjitc結果を格納する領域を確保。
39         sysjit00 = mallocRWE(SJITSIZ1);
40         // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス
41         sysjit = sysjit00;
42         systmp0 = malloc(SYSTMP0SIZ);
43         systmp1 = malloc(SYSTMP1SIZ);
44         systmp2 = malloc(1024 * 1024);
45     opTbl = malloc(256);
46         label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag));
47         level = JITC_LV_SLOWEST;
48         keybuf = malloc(KEYBUFSIZ * sizeof (int));
49         keybuf_r = keybuf_w = keybuf_c = 0;
50         ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag));
51
52         randStatInit((unsigned int)time(NULL));
53         for (i = 0; i < PTRCTRLSIZ; i++) {
54                 ptrCtrl[i].liveSign = 0;
55                 ptrCtrl[i].size = -1;
56         }
57         ptrCtrl[0].size = -2;
58
59         /* syslibの読み込み */
60         syslib = malloc(SYSLIBSIZ1);
61         fp = fopen(SYSLIB_OSE, "rb");
62         if (fp == NULL) {
63                 syslib[0] = '/';
64                 strcpy((char *)syslib + 1, argv[0]);
65                 up = syslib + 1;
66                 while (*up != '\0'){
67             up++;
68         }
69                 while (*up != '/' && *up != 0x5c){
70             up--;
71         }
72                 up++;
73                 strcpy((char *)up, SYSLIB_OSE);
74                 fp = fopen((char *)syslib + 1, "rb");
75         }
76         if (fp == NULL) {
77                 fputs("syslib-file fopen error.\n", stderr);
78                 return 1;
79         }
80         appsiz0 = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);
81         fclose(fp);
82         if (appsiz0 >= SYSLIBSIZ1 - 4) {
83                 fputs("syslib-file too large.\n", stderr);
84                 return 1;
85         }
86         if (syslib[0] == 0x05 && syslib[1] == 0xc1) {
87                 // 一体この部分ではなにをやっているのだろう?
88                 // OSECPUに0x05, 0x1bという命令はないが... ヘッダ?
89                 // どうせ初めからの32バイトは無視されるのだろうに...
90                 memcpy(systmp0, syslib, appsiz0);
91                 ComLib_main(systmp0 + 2, syslib + 2);
92                 syslib[0] = 0x05;
93                 syslib[1] = 0x1b;
94         }
95
96         fp2 = fopen("syslib_dbg.ose", "wb");
97         fwrite(syslib, 1, SYSLIBSIZ1, fp2);
98         fclose(fp2);
99
100         // jutc.cのerrHndl()をCALLするネィティブコードを挿入。
101         // sysjitの値は次の書き込み位置へずらされる。
102         // 元々のsysjitはsysjit00へ保存されている。
103         sysjit = jitCompInit(sysjit);
104
105         // sysjit (アドレス変数)は下の関数の実行で変更される(だから参照渡し)
106         // もちろんsysjitの値は次の書き込み位置へずらされる。
107         // labelはjitc0()内で初期化される。
108         i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_FASTEST, label);
109         if (i != 0){
110                 fputs("syslib-file JITC error.\n", stderr);
111                 return 1;
112         }
113
114         // エラー時にデバッグ用に表示する変数を加算
115         di1_serial++;
116
117         /* アプリバイナリの読み込み */
118         if (argc <= 1) {
119         return 0;
120     }
121         argv1 = argv[1];
122         if (argv1[0] == ':' && argv1[2] == ':') {
123                 level = argv1[1] - '0';
124                 if (level < 0 || level > 9){
125                         level = JITC_LV_SLOWEST;
126         }
127                 argv1 += 3;
128         }
129         fp = fopen(argv1, "rb");
130         if (fp == NULL) {
131                 fputs("app-file load error.\n", stderr);
132                 return 1;
133         }
134         appsiz1 = appsiz0 = fread(appbin, 1, APPSIZ1 - 4, fp);
135         fclose(fp);
136         if (appsiz0 >= APPSIZ1 - 4) {
137                 fputs("app-file too large.\n", stderr);
138                 return 1;
139         }
140         if (appsiz0 < 3) {
141 header_error:
142                 fputs("app-file header error.\n", stderr);
143                 return 1;
144         }
145
146         tm0 = clock() / (double)CLOCKS_PER_SEC;
147
148         if (appbin[2] == 0xf0) {
149 #if (USE_TEK5 != 0)
150                 appsiz1 = tek5Decomp(appbin + 2, appbin + appsiz0, systmp0) + 2;
151 #else
152                 appsiz1 = -9;
153 #endif
154                 if (appsiz1 < 0) {
155                         fputs("unsupported-format(tek5)\n", stderr);
156                         return 1;
157                 }
158         }
159         cp = searchArg(argc, (const char **)argv, "debug:", 0);
160         if (cp != NULL){
161         argDebug = *cp - '0';
162     }
163         cp = searchArg(argc, (const char **)argv, "stack:", 0);
164         if (cp != NULL){
165         stacksiz = strtol(cp, NULL, 0);
166     }
167         jp = jitbuf; /* JIT-pointer */
168
169         /* フロントエンドコードをバックエンドコードに変換する */
170         if ((appbin[2] & 0xf0) != 0) {
171                 systmp0[0] = appbin[0];
172                 systmp0[1] = appbin[1];
173                 regs.preg[2].p = systmp0 + 2;
174                 regs.preg[3].p = systmp0 + SYSTMP0SIZ;
175                 regs.preg[4].p = appbin + 2;
176                 regs.preg[5].p = appbin + appsiz1;
177                 regs.preg[6].p = systmp1;
178                 regs.preg[7].p = systmp1 + SYSTMP1SIZ;
179                 regs.preg[10].p = systmp2;
180                 int pxxFlag[64], typLabel[4096];
181                 regs.preg[0x0b].p = (void *)pxxFlag;
182                 regs.preg[0x0c].p = (void *)typLabel;
183                 regs.preg[0x0d].p = opTbl;
184                 jitfunc = (void *)sysjit;
185                 (*jitfunc)(((char *)&regs) + 128); /* サイズを節約するためにEBPを128バイトずらす */
186                 if (regs.ireg[0] != 0) {
187                         jp = regs.preg[2].p - 1;
188                         fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, regs.ireg[0]);
189                         if ((argDebug & 2) != 0) {
190                                 fp = fopen("debug2.bin", "wb");
191                                 fwrite(systmp0, 1, jp - systmp0 + 16, fp);
192                                 fclose(fp);
193                         }
194                         exit(1);
195                 }
196                 tmpsiz = regs.preg[2].p - systmp0;
197         } else{
198                 memcpy(systmp0, appbin, appsiz1);
199                 tmpsiz = appsiz1;
200         }
201
202         if ((argDebug & 2) != 0) {
203                 fp = fopen("debug2.bin", "wb");
204                 fwrite(systmp0, 1, tmpsiz, fp);
205                 fclose(fp);
206         }
207
208         i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, level, label);
209         if (i == 1){
210         goto header_error;
211     }
212         if (i != 0){
213         return 1;
214     }
215         di1_serial++;
216
217         int appsiz2 = jp - jitbuf;
218
219         unsigned char *p28 = jp;
220         jp = jitCompCallFunc(jp, &devFunc);
221
222         tm1 = clock() / (double)CLOCKS_PER_SEC;
223
224         /* レジスタ初期化 */
225         for (i = 0; i < 64; i++){
226                 regs.ireg[i] = 0;
227     }
228         for (i = 0; i < 64; i++) {
229                 regs.preg[i].p = NULL;
230                 regs.preg[i].typ = -1;
231                 regs.preg[i].p0 = NULL;
232                 regs.preg[i].p1 = NULL;
233         }
234
235         regs.argc = argc;
236         regs.argv = (const char **)argv;
237         regs.buf0 = regs.buf1 = NULL;
238         regs.preg[0x28].p = p28;
239         regs.preg[0x28].typ = 0; // TYP_CODE
240         regs.preg[0x28].p0 = p28;
241         regs.preg[0x28].p1 = p28 + 1;
242         //      regs.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32);
243         regs.junkStack = malloc(stacksiz << 20);
244         regs.junkStack1 = regs.junkStack + (stacksiz << 20);
245         regs.winClosed = 0;
246         regs.autoSleep = 0;
247         regs.setjmpEnv = &setjmpEnv;
248         regs.lastConsoleChar = '\n';
249
250         regs.label = label;
251         regs.maxLabels = JITC_MAXLABELS;
252         regs.jitbuf = jp;
253         regs.jitbuf1 = jitbuf + 1024 * 1024;
254         regs.errHndl = &errorHandler;
255         regs.dbgr = 0;
256         if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){
257         regs.dbgr = 1;
258     }
259
260         if ((argDebug & 1) != 0) {
261                 fp = fopen("debug1.bin", "wb");
262                 fwrite(jitbuf, 1, jp - jitbuf, fp);
263                 fclose(fp);
264         }
265
266         /* JITコード実行 */
267         jitfunc = (void *)jitbuf;
268         if (setjmp(setjmpEnv) == 0){
269                 (*jitfunc)(((char *)&regs) + 128); /* サイズを節約するためにEBPを128バイトずらす */
270     }
271         if (regs.autoSleep != 0) {
272                 if (vram != NULL){
273                         drv_flshWin(v_xsiz, v_ysiz, 0, 0);
274         }
275                 while (regs.winClosed == 0){
276                         drv_sleep(100);
277         }
278         }
279         if (regs.lastConsoleChar != '\n'){
280                 putchar('\n');
281     }
282
283         tm2 = clock() / (double)CLOCKS_PER_SEC;
284
285         /* 実行結果確認のためのレジスタダンプ */
286         if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) {
287                 printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1);
288                 printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", appsiz0, appsiz1, tmpsiz, appsiz2);
289                 printf("result:\n");
290                 printf("R00:0x%08X  R01:0x%08X  R02:0x%08X  R03:0x%08X\n", regs.ireg[0], regs.ireg[1], regs.ireg[2], regs.ireg[3]);
291         }
292 #if (USE_DEBUGGER != 0)
293         dbgrMain(&regs);
294 #endif
295         return 0;
296 }
297
298 int main(int argc, char **argv)
299 {
300         // Program entry point
301         return osecpuMain(argc, argv);
302 }