3 int *keybuf, keybuf_r, keybuf_w, keybuf_c;
\r
4 HOSECPU_Device_Window mainWindow;
\r
5 //デバッグ用。プログラム中の随所で加算される変数
\r
7 HOSECPU_RuntimeEnvironment *dbg_env;
\r
11 unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory);
\r
12 void LoadAppBin(HOSECPU_RuntimeEnvironment *env);
\r
14 void putKeybuf(int i)
\r
16 // TODO : あふれた場合のことを考慮すべき
\r
17 if (keybuf_c < KEYBUFSIZ) {
\r
18 keybuf[keybuf_w] = i;
\r
20 keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1);
\r
25 int HeavyOSECPUMain(int argc, char **argv)
\r
27 HOSECPU_RuntimeEnvironment env;
\r
29 unsigned char *jitbuf, *sysjit00, *sysjit;
\r
30 unsigned char *systmp0, *systmp1, *systmp2;
\r
31 unsigned char *opTbl;
\r
32 HOSECPU_LabelListTag *label;
\r
34 double tm0, tm1, tm2;
\r
35 HOSECPU_PointerControlTag *ptrCtrl;
\r
36 unsigned char *syslib;
\r
37 int argDebug = 0, stacksiz = 1;
\r
39 void(*jitfunc)(char *);
\r
45 // Initialize mainWindow
\r
46 mainWindow.vram = NULL;
\r
47 mainWindow.xsize = 0;
\r
48 mainWindow.ysize = 0;
\r
52 env.mainArgc = argc;
\r
53 env.mainArgv = (const char **)argv;
\r
54 env.appBin = malloc(APPSIZ1);
\r
55 env.executionLevel = JITC_LV_SLOWEST;
\r
56 jitbuf = mallocRWE(APPJITSIZE); /* とりあえず1MBで */
\r
57 // syslib.oseのjitc結果を格納する領域を確保。
\r
58 sysjit00 = mallocRWE(SYSJITSIZ1);
\r
60 // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス
\r
61 // sysjit: 現在のjitc書き込み位置
\r
62 // sysjit00: jitc結果の先頭
\r
64 systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */
\r
65 systmp1 = malloc(SYSTMP1SIZ);
\r
66 systmp2 = malloc(1024 * 1024);
\r
68 opTbl = malloc(256);
\r
69 label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag));
\r
70 keybuf = malloc(KEYBUFSIZ * sizeof (int));
\r
71 keybuf_r = keybuf_w = keybuf_c = 0;
\r
72 ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag));
\r
74 randStatInit((unsigned int)time(NULL));
\r
75 for (i = 0; i < PTRCTRLSIZ; i++) {
\r
76 ptrCtrl[i].liveSign = 0;
\r
77 ptrCtrl[i].size = -1;
\r
79 ptrCtrl[0].size = -2;
\r
82 syslib = Init_LoadSysLib(argv[0], systmp0);
\r
84 sysjit = jitCompInit(sysjit);
\r
86 // labelはjitc0()内で初期化される。
\r
87 i = jitc0(&sysjit, sysjit00 + SYSJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label);
\r
89 fputs("syslib-file JITC error.\n", stderr);
\r
93 // エラー時にデバッグ用に表示する変数を加算
\r
100 tm0 = clock() / (double)CLOCKS_PER_SEC;
\r
102 if (env.appBin[2] == 0xf0) {
\r
104 #if (USE_TEK5 != 0)
\r
105 env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0);
\r
110 if (env.appSize1 < 0) {
\r
111 fputs("unsupported-format(tek5)\n", stderr);
\r
116 cp = searchArg(argc, (const char **)argv, "debug:", 0);
\r
118 argDebug = *cp - '0';
\r
121 cp = searchArg(argc, (const char **)argv, "stack:", 0);
\r
123 stacksiz = strtol(cp, NULL, 0);
\r
126 // jitbufは先頭。 jpは現在位置
\r
127 jp = jitbuf; /* JIT-pointer */
\r
129 /* フロントエンドコードをバックエンドコードに変換する */
\r
130 if ((env.appBin[2] & 0xf0) != 0) { // 3バイト目が00なら処理しない
\r
131 systmp0[0] = env.appBin[0];
\r
132 systmp0[1] = env.appBin[1];
\r
133 env.preg[2].p = systmp0 + 2;
\r
134 env.preg[3].p = systmp0 + SYSTMP0SIZ;
\r
135 env.preg[4].p = env.appBin + 2;
\r
136 env.preg[5].p = env.appBin + env.appSize1;
\r
137 env.preg[6].p = systmp1;
\r
138 env.preg[7].p = systmp1 + SYSTMP1SIZ;
\r
139 env.preg[10].p = systmp2;
\r
140 int pxxFlag[64], typLabel[4096];
\r
141 env.preg[0x0b].p = (void *)pxxFlag;
\r
142 env.preg[0x0c].p = (void *)typLabel;
\r
143 env.preg[0x0d].p = opTbl;
\r
144 jitfunc = (void *)sysjit00;
\r
145 jitcRunBinary(jitfunc, &env);
\r
146 if (env.ireg[0] != 0) {
\r
147 jp = env.preg[2].p - 1;
\r
148 fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]);
\r
149 if ((argDebug & 2) != 0) {
\r
150 fp = fopen("debug2.bin", "wb");
\r
151 fwrite(systmp0, 1, jp - systmp0 + 16, fp);
\r
156 tmpsiz = env.preg[2].p - systmp0;
\r
158 memcpy(systmp0, env.appBin, env.appSize1);
\r
159 tmpsiz = env.appSize1;
\r
162 if ((argDebug & 2) != 0) {
\r
163 /*変換後のバックエンドコードをファイルへ保存*/
\r
164 fp = fopen("debug2.bin", "wb");
\r
165 fwrite(systmp0, 1, tmpsiz, fp);
\r
170 i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label);
\r
172 fputs("app-file header error.\n", stderr);
\r
180 int appsiz2 = jp - jitbuf;
\r
182 unsigned char *p28 = jp;
\r
183 jp = jitCompCallFunc(jp, &devFunc);
\r
185 tm1 = clock() / (double)CLOCKS_PER_SEC;
\r
188 for (i = 0; i < 64; i++){
\r
191 for (i = 0; i < 64; i++) {
\r
192 env.preg[i].p = NULL;
\r
193 env.preg[i].typ = -1;
\r
194 env.preg[i].p0 = NULL;
\r
195 env.preg[i].p1 = NULL;
\r
198 env.buf0 = env.buf1 = NULL;
\r
200 // p28にapiをコールするアドレスを設定
\r
201 env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている
\r
202 env.preg[0x28].typ = 0; // TYP_CODE
\r
203 env.preg[0x28].p0 = p28; // アドレス演算できる範囲を制限
\r
204 env.preg[0x28].p1 = p28 + 1; // アドレス演算できる範囲を制限
\r
206 //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32);
\r
207 env.junkStack = malloc(stacksiz << 20);
\r
208 env.junkStack1 = env.junkStack + (stacksiz << 20);
\r
211 env.lastConsoleChar = '\n';
\r
214 env.maxLabels = JITC_MAXLABELS;
\r
216 env.jitbuf1 = jitbuf + 1024 * 1024;
\r
217 env.errHndl = &errorHandler;
\r
218 env.appReturnCode = 0;
\r
221 if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){
\r
225 if ((argDebug & 1) != 0) {
\r
226 fp = fopen("debug1.bin", "wb");
\r
227 fwrite(jitbuf, 1, jp - jitbuf, fp);
\r
232 jitfunc = (void *)jitbuf;
\r
233 if (setjmp(env.setjmpEnv) == 0){
\r
234 jitcRunBinary(jitfunc, &env);
\r
236 if (env.autoSleep != 0) {
\r
237 if (mainWindow.vram != NULL){
\r
238 drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
\r
240 while (env.winClosed == 0){
\r
244 if (env.lastConsoleChar != '\n'){
\r
248 tm2 = clock() / (double)CLOCKS_PER_SEC;
\r
250 /* 実行結果確認のためのレジスタダンプ */
\r
251 if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) {
\r
252 printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1);
\r
253 printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2);
\r
254 printf("result:\n");
\r
255 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]);
\r
257 #if (USE_DEBUGGER != 0)
\r
260 return env.appReturnCode;
\r
263 unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
\r
265 unsigned char *syslib;
\r
271 syslib = malloc(SYSLIBSIZ1);
\r
272 fp = fopen(SYSLIB_OSE, "rb");
\r
275 strcpy((char *)syslib + 1, argv0);
\r
277 while (*up != '\0'){
\r
280 while (*up != '/' && *up != 0x5c){
\r
284 strcpy((char *)up, SYSLIB_OSE);
\r
285 fp = fopen((char *)syslib + 1, "rb");
\r
288 fputs("syslib-file fopen error.\n", stderr);
\r
289 exit(EXIT_FAILURE);
\r
291 appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);
\r
293 if (appsize >= SYSLIBSIZ1 - 4) {
\r
294 fputs("syslib-file too large.\n", stderr);
\r
295 exit(EXIT_FAILURE);
\r
297 if (syslib[0] == 0x05 && syslib[1] == 0xc1) {
\r
298 // maklib のライブラリ形式である。
\r
299 memcpy(tmpWorkMemory, syslib, appsize);
\r
300 ComLib_main(tmpWorkMemory + 2, syslib + 2);
\r
305 fp = fopen("syslib_dbg.ose", "wb");
\r
306 fwrite(syslib, 1, SYSLIBSIZ1, fp);
\r
311 void LoadAppBin(HOSECPU_RuntimeEnvironment *env)
\r
314 const char *fileName;
\r
316 if (env->mainArgc <= 1) {
\r
317 //アプリ名未指定なので何事もなく終了
\r
318 exit(EXIT_SUCCESS);
\r
320 fileName = env->mainArgv[1];
\r
321 //アプリ名先頭に:n:をつけることでレベルnでの実行が可能?
\r
322 if (fileName[0] == ':' && fileName[2] == ':') {
\r
323 env->executionLevel = fileName[1] - '0';
\r
324 if (env->executionLevel < 0 || env->executionLevel > 9){
\r
325 env->executionLevel = JITC_LV_SLOWEST;
\r
330 fp = fopen(fileName, "rb");
\r
332 fputs("app-file load error.\n", stderr);
\r
333 exit(EXIT_FAILURE);
\r
335 env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp);
\r
336 env->appSize1 = env->appSize0;
\r
339 if (env->appSize0 >= APPSIZ1 - 4) {
\r
340 fputs("app-file too large.\n", stderr);
\r
341 exit(EXIT_FAILURE);
\r
343 if (env->appSize0 < 3) {
\r
344 fputs("app-file header error.\n", stderr);
\r
345 exit(EXIT_FAILURE);
\r