OSDN Git Service

Merge branch 'master' of git.sourceforge.jp:/gitroot/heavyosecpu/HeavyOSECPU
[heavyosecpu/HeavyOSECPU.git] / main.c
diff --git a/main.c b/main.c
index cae2aa5..1849d16 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,5 +1,8 @@
 #include "osecpu.h"
 
+unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory);
+void LoadAppBin(HOSECPU_RuntimeEnvironment *env);
+
 void putKeybuf(int i)
 {
        if (keybuf_c < KEYBUFSIZ) {
@@ -10,28 +13,48 @@ void putKeybuf(int i)
        return;
 }
 
-int osecpuMain(int argc, char **argv)
+int HeavyOSECPUMain(int argc, char **argv)
 {
-       unsigned char *appbin = malloc(APPSIZ1), *up;
-       unsigned char *jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */
+    FILE *fp;
+    
+    unsigned char *jitbuf, *sysjit00, *sysjit;
+    unsigned char *systmp0, *systmp1, *systmp2;
+    unsigned char *opTbl;
+    HOSECPU_LabelListTag *label;
+    int tmpsiz, i;
+    jmp_buf setjmpEnv;
+       double tm0, tm1, tm2;
+       HOSECPU_PointerControlTag *ptrCtrl;
+    unsigned char *syslib;
+    int argDebug = 0, stacksiz = 1;
+    const  char *cp;
+    HOSECPU_RuntimeEnvironment env;
+       void(*jitfunc)(char *);
+    unsigned char *jp;
+    
+    //実行環境初期化
+    env.mainArgc = argc;
+    env.mainArgv = (const char **)argv;
+    env.appBin = malloc(APPSIZ1);
+    env.executionLevel = JITC_LV_SLOWEST;
+       jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */
        //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0;
-
        // syslib.oseのjitc結果を格納する領域を確保。
-       unsigned char *sysjit00 = mallocRWE(SJITSIZ1);
-
+       sysjit00 = mallocRWE(SJITSIZ1);
        // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス
-       unsigned char *sysjit = sysjit00;
-
-       unsigned char *systmp0 = malloc(SYSTMP0SIZ);
-       unsigned char *systmp1 = malloc(SYSTMP1SIZ);
-       unsigned char *systmp2 = malloc(1024 * 1024), *opTbl = malloc(256);
-       struct LabelTable *label = malloc(JITC_MAXLABELS * sizeof (struct LabelTable));
-       int level = JITC_LV_SLOWEST, tmpsiz, i;
+    // sysjit: 現在のjitc書き込み位置
+    // sysjit00: jitc結果の先頭
+       sysjit = sysjit00;
+    //ワークメモリを三つくらいもらう
+       systmp0 = malloc(SYSTMP0SIZ);   /* syslibのjitc用 */
+       systmp1 = malloc(SYSTMP1SIZ);
+       systmp2 = malloc(1024 * 1024);
+    
+    opTbl = malloc(256);
+       label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag));
        keybuf = malloc(KEYBUFSIZ * sizeof (int));
        keybuf_r = keybuf_w = keybuf_c = 0;
-       jmp_buf setjmpEnv;
-       double tm0, tm1, tm2;
-       struct PtrCtrl *ptrCtrl = malloc(PTRCTRLSIZ * sizeof (struct PtrCtrl));
+       ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag));
 
        randStatInit((unsigned int)time(NULL));
        for (i = 0; i < PTRCTRLSIZ; i++) {
@@ -40,45 +63,10 @@ int osecpuMain(int argc, char **argv)
        }
        ptrCtrl[0].size = -2;
 
-       /* syslibの読み込み */
-       unsigned char *syslib = malloc(SYSLIBSIZ1);
-       int appsiz0, appsiz1;
-       FILE *fp = fopen(SYSLIB_OSE, "rb");
-       if (fp == NULL) {
-               syslib[0] = '/';
-               strcpy(syslib + 1, argv[0]);
-               up = syslib + 1;
-               while (*up != '¥0') up++;
-               while (*up != '/' && *up != 0x5c) up--;
-               up++;
-               strcpy(up, SYSLIB_OSE);
-               fp = fopen(syslib + 1, "rb");
-       }
-       if (fp == NULL) {
-               fputs("syslib-file fopen error.¥n", stderr);
-               return 1;
-       }
-       appsiz0 = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);
-       fclose(fp);
-       if (appsiz0 >= SYSLIBSIZ1 - 4) {
-               fputs("syslib-file too large.¥n", stderr);
-               return 1;
-       }
-       if (syslib[0] == 0x05 && syslib[1] == 0xc1) {
-               
-               // 一体この部分ではなにをやっているのだろう?
-
-               memcpy(systmp0, syslib, appsiz0);
-               ComLib_main(systmp0 + 2, syslib + 2);
-               syslib[0] = 0x05;
-               syslib[1] = 0x1b;
-       }
-
-       FILE *fp2 = fopen("syslib_dbg.ose", "wb");
-       fwrite(syslib, 1, SYSLIBSIZ1, fp2);
-       fclose(fp2);
-
-       // jutc.cのerrHndl()をCALLするネィティブコードを挿入。
+       /* syslibの読み込み */
+       syslib = Init_LoadSysLib(argv[0], systmp0);
+    
+       // jitc.cのerrHndl()をCALLするネィティブコードを挿入。
        // sysjitの値は次の書き込み位置へずらされる。
        // 元々のsysjitはsysjit00へ保存されている。
        sysjit = jitCompInit(sysjit);
@@ -87,84 +75,64 @@ int osecpuMain(int argc, char **argv)
        // もちろんsysjitの値は次の書き込み位置へずらされる。
        // labelはjitc0()内で初期化される。
        i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_FASTEST, label);
-       if (i != 0) {
-               fputs("syslib-file JITC error.¥n", stderr);
+       if (i != 0){
+               fputs("syslib-file JITC error.\n", stderr);
                return 1;
        }
 
        // エラー時にデバッグ用に表示する変数を加算
        di1_serial++;
 
-       /* アプリバイナリの読み込み */
-       if (argc <= 1) { return 0; }
-       const unsigned char *argv1 = argv[1];
-       if (argv1[0] == ':' && argv1[2] == ':') {
-               level = argv1[1] - '0';
-               if (level < 0 || level > 9)
-                       level = JITC_LV_SLOWEST;
-               argv1 += 3;
-       }
-       fp = fopen(argv1, "rb");
-       if (fp == NULL) {
-               fputs("app-file load error.¥n", stderr);
-               return 1;
-       }
-       appsiz1 = appsiz0 = fread(appbin, 1, APPSIZ1 - 4, fp);
-       fclose(fp);
-       if (appsiz0 >= APPSIZ1 - 4) {
-               fputs("app-file too large.¥n", stderr);
-               return 1;
-       }
-       if (appsiz0 < 3) {
-       header_error:
-               fputs("app-file header error.¥n", stderr);
-               return 1;
-       }
-
+    /* アプリバイナリの読み込み */
+    LoadAppBin(&env);
+    
+    /* クロック初期化 */
        tm0 = clock() / (double)CLOCKS_PER_SEC;
 
-       if (appbin[2] == 0xf0) {
+       if (env.appBin[2] == 0xf0) {
+        // tek5圧縮がかかっている
 #if (USE_TEK5 != 0)
-               appsiz1 = tek5Decomp(appbin + 2, appbin + appsiz0, systmp0) + 2;
+               env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0) + 2;
 #else
-               appsiz1 = -9;
+               env.appSize1 = -9;
 #endif
-               if (appsiz1 < 0) {
-                       fputs("unsupported-format(tek5)¥n", stderr);
+               if (env.appSize1 < 0) {
+                       fputs("unsupported-format(tek5)\n", stderr);
                        return 1;
                }
        }
-
-       int argDebug = 0, stacksiz = 1;
-       const unsigned char *cp = searchArg(argc, argv, "debug:", 0);
-       if (cp != NULL) argDebug = *cp - '0';
-       cp = searchArg(argc, argv, "stack:", 0);
-       if (cp != NULL) stacksiz = strtol(cp, NULL, 0);
-
-       struct Regs regs;
-       void(*jitfunc)(char *);
-       unsigned char *jp = jitbuf; /* JIT-pointer */
+    //デバッグモード指定
+       cp = searchArg(argc, (const char **)argv, "debug:", 0);
+       if (cp != NULL){
+        argDebug = *cp - '0';
+    }
+    //スタックサイズ指定
+       cp = searchArg(argc, (const char **)argv, "stack:", 0);
+       if (cp != NULL){
+        stacksiz = strtol(cp, NULL, 0);
+    }
+       jp = jitbuf; /* JIT-pointer */
 
        /* フロントエンドコードをバックエンドコードに変換する */
-       if ((appbin[2] & 0xf0) != 0) {
-               systmp0[0] = appbin[0];
-               systmp0[1] = appbin[1];
-               regs.preg[2].p = systmp0 + 2;
-               regs.preg[3].p = systmp0 + SYSTMP0SIZ;
-               regs.preg[4].p = appbin + 2;
-               regs.preg[5].p = appbin + appsiz1;
-               regs.preg[6].p = systmp1;
-               regs.preg[7].p = systmp1 + SYSTMP1SIZ;
-               regs.preg[10].p = systmp2;
+       if ((env.appBin[2] & 0xf0) != 0) {
+               systmp0[0] = env.appBin[0];
+               systmp0[1] = env.appBin[1];
+               env.preg[2].p = systmp0 + 2;
+               env.preg[3].p = systmp0 + SYSTMP0SIZ;
+               env.preg[4].p = env.appBin + 2;
+               env.preg[5].p = env.appBin + env.appSize1;
+               env.preg[6].p = systmp1;
+               env.preg[7].p = systmp1 + SYSTMP1SIZ;
+               env.preg[10].p = systmp2;
                int pxxFlag[64], typLabel[4096];
-               regs.preg[0x0b].p = (void *)pxxFlag;
-               regs.preg[0x0c].p = (void *)typLabel;
-               regs.preg[0x0d].p = opTbl;
+               env.preg[0x0b].p = (void *)pxxFlag;
+               env.preg[0x0c].p = (void *)typLabel;
+               env.preg[0x0d].p = opTbl;
                jitfunc = (void *)sysjit;
-               (*jitfunc)(((char *)&regs) + 128); /* サイズを節約するためにEBPを128バイトずらす */
-               if (regs.ireg[0] != 0) {
-                       jp = regs.preg[2].p - 1;
-                       fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)¥n", *jp, jp - systmp0, regs.ireg[0]);
+               (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
+               if (env.ireg[0] != 0) {
+                       jp = env.preg[2].p - 1;
+                       fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]);
                        if ((argDebug & 2) != 0) {
                                fp = fopen("debug2.bin", "wb");
                                fwrite(systmp0, 1, jp - systmp0 + 16, fp);
@@ -172,11 +140,10 @@ int osecpuMain(int argc, char **argv)
                        }
                        exit(1);
                }
-               tmpsiz = regs.preg[2].p - systmp0;
-       }
-       else {
-               memcpy(systmp0, appbin, appsiz1);
-               tmpsiz = appsiz1;
+               tmpsiz = env.preg[2].p - systmp0;
+       } else{
+               memcpy(systmp0, env.appBin, env.appSize1);
+               tmpsiz = env.appSize1;
        }
 
        if ((argDebug & 2) != 0) {
@@ -185,9 +152,14 @@ int osecpuMain(int argc, char **argv)
                fclose(fp);
        }
 
-       i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, level, label);
-       if (i == 1) goto header_error;
-       if (i != 0) return 1;
+       i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label);
+       if (i == 1){
+        fputs("app-file header error.\n", stderr);
+               return 1;
+    }
+       if (i != 0){
+        return 1;
+    }
        di1_serial++;
 
        int appsiz2 = jp - jitbuf;
@@ -198,37 +170,40 @@ int osecpuMain(int argc, char **argv)
        tm1 = clock() / (double)CLOCKS_PER_SEC;
 
        /* レジスタ初期化 */
-       for (i = 0; i < 64; i++)
-               regs.ireg[i] = 0;
+       for (i = 0; i < 64; i++){
+               env.ireg[i] = 0;
+    }
        for (i = 0; i < 64; i++) {
-               regs.preg[i].p = NULL;
-               regs.preg[i].typ = -1;
-               regs.preg[i].p0 = NULL;
-               regs.preg[i].p1 = NULL;
+               env.preg[i].p = NULL;
+               env.preg[i].typ = -1;
+               env.preg[i].p0 = NULL;
+               env.preg[i].p1 = NULL;
        }
 
-       regs.argc = argc;
-       regs.argv = argv;
-       regs.buf0 = regs.buf1 = NULL;
-       regs.preg[0x28].p = p28;
-       regs.preg[0x28].typ = 0; // TYP_CODE
-       regs.preg[0x28].p0 = p28;
-       regs.preg[0x28].p1 = p28 + 1;
-       //      regs.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32);
-       regs.junkStack = malloc(stacksiz << 20);
-       regs.junkStack1 = regs.junkStack + (stacksiz << 20);
-       regs.winClosed = 0;
-       regs.autoSleep = 0;
-       regs.setjmpEnv = &setjmpEnv;
-       regs.lastConsoleChar = '¥n';
-
-       regs.label = label;
-       regs.maxLabels = JITC_MAXLABELS;
-       regs.jitbuf = jp;
-       regs.jitbuf1 = jitbuf + 1024 * 1024;
-       regs.errHndl = &errorHandler;
-       regs.dbgr = 0;
-       if (searchArg(argc, argv, "dbgr:1", 0) != NULL) regs.dbgr = 1;
+       env.argc = argc;
+       env.argv = (const char **)argv;
+       env.buf0 = env.buf1 = NULL;
+       env.preg[0x28].p = p28;
+       env.preg[0x28].typ = 0; // TYP_CODE
+       env.preg[0x28].p0 = p28;
+       env.preg[0x28].p1 = p28 + 1;
+       //      env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32);
+       env.junkStack = malloc(stacksiz << 20);
+       env.junkStack1 = env.junkStack + (stacksiz << 20);
+       env.winClosed = 0;
+       env.autoSleep = 0;
+       env.setjmpEnv = &setjmpEnv;
+       env.lastConsoleChar = '\n';
+
+       env.label = label;
+       env.maxLabels = JITC_MAXLABELS;
+       env.jitbuf = jp;
+       env.jitbuf1 = jitbuf + 1024 * 1024;
+       env.errHndl = &errorHandler;
+       env.dbgr = 0;
+       if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){
+        env.dbgr = 1;
+    }
 
        if ((argDebug & 1) != 0) {
                fp = fopen("debug1.bin", "wb");
@@ -238,35 +213,120 @@ int osecpuMain(int argc, char **argv)
 
        /* JITコード実行 */
        jitfunc = (void *)jitbuf;
-       if (setjmp(setjmpEnv) == 0)
-               (*jitfunc)(((char *)&regs) + 128); /* サイズを節約するためにEBPを128バイトずらす */
-       if (regs.autoSleep != 0) {
-               if (vram != NULL)
+       if (setjmp(setjmpEnv) == 0){
+               (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
+    }
+       if (env.autoSleep != 0) {
+               if (vram != NULL){
                        drv_flshWin(v_xsiz, v_ysiz, 0, 0);
-               while (regs.winClosed == 0)
+        }
+               while (env.winClosed == 0){
                        drv_sleep(100);
+        }
        }
-       if (regs.lastConsoleChar != '¥n')
-               putchar('¥n');
+       if (env.lastConsoleChar != '\n'){
+               putchar('\n');
+    }
 
        tm2 = clock() / (double)CLOCKS_PER_SEC;
 
        /* 実行結果確認のためのレジスタダンプ */
-       if (searchArg(argc, argv, "verbose:1", 0) != NULL) {
-               printf("time: JITC=%.3f[sec], exec=%.3f[sec]¥n", tm1 - tm0, tm2 - tm1);
-               printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d¥n", appsiz0, appsiz1, tmpsiz, appsiz2);
-               printf("result:¥n");
-               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]);
+       if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) {
+               printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1);
+               printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2);
+               printf("result:\n");
+               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]);
        }
 #if (USE_DEBUGGER != 0)
-       dbgrMain(&regs);
+       dbgrMain(&env);
 #endif
        return 0;
 }
 
-int main(int argc, char **argv)
+unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
 {
-       // Program entry point
+    unsigned char *syslib;
+    FILE *fp;
+    unsigned char *up;
+    int appsize;
+    
+    /* syslibの読み込み */
+       syslib = malloc(SYSLIBSIZ1);
+       fp = fopen(SYSLIB_OSE, "rb");
+       if (fp == NULL) {
+               syslib[0] = '/';
+               strcpy((char *)syslib + 1, argv0);
+               up = syslib + 1;
+               while (*up != '\0'){
+            up++;
+        }
+               while (*up != '/' && *up != 0x5c){
+            up--;
+        }
+               up++;
+               strcpy((char *)up, SYSLIB_OSE);
+               fp = fopen((char *)syslib + 1, "rb");
+       }
+       if (fp == NULL) {
+               fputs("syslib-file fopen error.\n", stderr);
+        exit(EXIT_FAILURE);
+       }
+       appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);
+       fclose(fp);
+       if (appsize >= SYSLIBSIZ1 - 4) {
+               fputs("syslib-file too large.\n", stderr);
+               exit(EXIT_FAILURE);
+       }
+       if (syslib[0] == 0x05 && syslib[1] == 0xc1) {
+               // 一体この部分ではなにをやっているのだろう?
+               // OSECPUに0x05, 0x1bという命令はないが... ヘッダ?
+               // どうせ初めからの32バイトは無視されるのだろうに...
+               memcpy(tmpWorkMemory, syslib, appsize);
+               ComLib_main(tmpWorkMemory + 2, syslib + 2);
+               syslib[0] = 0x05;
+               syslib[1] = 0x1b;
+       }
+    
+       fp = fopen("syslib_dbg.ose", "wb");
+       fwrite(syslib, 1, SYSLIBSIZ1, fp);
+       fclose(fp);
+    return syslib;
+}
 
-       return osecpuMain(argc, argv);
-}
\ No newline at end of file
+void LoadAppBin(HOSECPU_RuntimeEnvironment *env)
+{
+    FILE *fp;
+    const char *fileName;
+       /* アプリバイナリの読み込み */
+       if (env->mainArgc <= 1) {
+        //アプリ名未指定なので何事もなく終了
+        exit(EXIT_SUCCESS);
+    }
+       fileName = env->mainArgv[1];
+    //アプリ名先頭に:n:をつけることでレベルnでの実行が可能?
+       if (fileName[0] == ':' && fileName[2] == ':') {
+               env->executionLevel = fileName[1] - '0';
+               if (env->executionLevel < 0 || env->executionLevel > 9){
+                       env->executionLevel = JITC_LV_SLOWEST;
+        }
+               fileName += 3;
+       }
+    
+       fp = fopen(fileName, "rb");
+       if (fp == NULL) {
+               fputs("app-file load error.\n", stderr);
+               exit(EXIT_FAILURE);
+       }
+       env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp);
+    env->appSize1 = env->appSize0;
+       fclose(fp);
+    
+       if (env->appSize0 >= APPSIZ1 - 4) {
+               fputs("app-file too large.\n", stderr);
+               exit(EXIT_FAILURE);
+       }
+       if (env->appSize0 < 3) {
+               fputs("app-file header error.\n", stderr);
+               exit(EXIT_FAILURE);
+       }
+}