OSDN Git Service

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