OSDN Git Service

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