OSDN Git Service

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