引数の変更
authorj8takagi <j8takagi@nifty.com>
Thu, 21 Jan 2010 14:11:09 +0000 (23:11 +0900)
committerj8takagi <j8takagi@nifty.com>
Thu, 21 Jan 2010 14:11:09 +0000 (23:11 +0900)
-M: メモリーサイズの指定
-C: クロック周波数を指定
-o: アセンブラ結果をファイルに出力し、実行。出力先のデフォルトは、a.o
-O: アセンブラ結果をファイルに出力し、終了。出力先のデフォルトは、a.o

include/casl2.h
src/assemble.c
src/casl2.c
src/cerr.c
src/comet2.c
src/exec.c
src/struct.c

index 70e25c5..47461dc 100644 (file)
@@ -13,8 +13,8 @@
 enum {
     CMDSIZE = 4,      /* 命令の最大文字数 */
     REGSIZE = 8,      /* 汎用レジスタの数 */
-    MEMSIZE = 512,    /* メモリ容量。COMET II規格では、65536語 */
-    CLOCKS = 5000000  /* クロック周波数。COMET II規格では、未定義 */
+    DEFAULT_MEMSIZE = 512,    /* デフォルトのメモリ容量。COMET II規格では、65536語 */
+    DEFAULT_CLOCKS = 5000000  /* デフォルトのクロック周波数。COMET II規格では、未定義 */
 };
 
 /* ハッシュ値を取得する */
@@ -24,7 +24,7 @@ unsigned hash(const char *key, int size);
 typedef unsigned short WORD;
 
 /* COMET IIのメモリ */
-extern WORD memory[MEMSIZE];
+extern WORD *memory;
 
 /* COMET IIのCPUレジスタ */
 extern WORD GR[REGSIZE], SP, PR, FR;
@@ -57,12 +57,21 @@ extern bool srcmode;
 /* ラベル表を表示する場合はTRUE */
 extern bool labelmode;
 
+/* ラベル表を表示して終了する場合はTRUE */
+extern bool onlylabelmode;
+
 /* アセンブラ詳細結果を表示するならTRUE */
 extern bool asdetailmode;
 
 /* アセンブルだけを行う場合はTRUE */
 extern bool onlyassemblemode;
 
+/* メモリーサイズ */
+extern int memsize;
+
+/* クロック周波数 */
+extern int clocks;
+
 /* 実行開始番地 */
 extern WORD startptr;
 
index 3549c61..3b91398 100644 (file)
@@ -92,7 +92,7 @@ bool writememory(WORD word, WORD adr, PASS pass)
 {
     bool status = false;
     /* COMET IIメモリオーバーの場合 */
-    if(adr >= MEMSIZE) {
+    if(adr >= memsize) {
         setcerr(119, wtoa(adr));    /* out of COMET II memory */
     }
     if(cerrno == 0) {
@@ -153,7 +153,7 @@ void writestr(const char *str, bool literal, PASS pass)
 void writeDC(const char *str, PASS pass)
 {
     WORD adr = 0x0;
-    if(*str == '\''){
+    if(*str == '\'') {
         writestr(str, false, pass);
     } else {
         if(*str == '#') {
@@ -202,7 +202,7 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass)
             setcerr(107, NULL);    /* no label in START */
             return false;
         }
-       /* オペランドがある場合、実行開始番地を設定 */
+        /* オペランドがある場合、実行開始番地を設定 */
         if(pass == SECOND && cmdl->opd->opdc == 1) {
             if((startptr = getlabel(cmdl->opd->opdv[0])) == 0xFFFF) {
                 setcerr(103, cmdl->opd->opdv[0]);    /* label not found */
@@ -366,7 +366,7 @@ bool cometcmd(const CMDLINE *cmdl, PASS pass)
     }
     /* オペランド数1〜2。第1オペランドはアドレス */
     else if(cmdl->opd->opdc == 1 || cmdl->opd->opdc == 2) {
-        if((cmd = getcmdcode(cmdl->cmd, ADR_X)) == 0xFFFF) {                
+        if((cmd = getcmdcode(cmdl->cmd, ADR_X)) == 0xFFFF) {
             setcerr(111, cmdl->cmd);    /* not command of operand "adr[,x]" */
             return false;
         }
index 2d17acd..f4c8f88 100644 (file)
@@ -16,17 +16,21 @@ void outassemble(char *file) {
 }
 
 static struct option longopts[] = {
+    {"source", no_argument, NULL, 's'},
+    {"label", no_argument, NULL, 'l'},
+    {"labelonly", no_argument, NULL, 'L'},
+    {"assembledetail", no_argument, NULL, 'a'},
+    {"assembledetailonly", no_argument, NULL, 'A'},
+    {"assembleout", optional_argument, NULL, 'o'},
+    {"assembleoutonly", optional_argument, NULL, 'O'},
     {"trace", no_argument, NULL, 't'},
     {"tracearithmetic", no_argument, NULL, 't'},
     {"tracelogical", no_argument, NULL, 'T'},
     {"dump", no_argument, NULL, 'd'},
-    {"source", no_argument, NULL, 's'},
-    {"label", no_argument, NULL, 'l'},
-    {"assembledetail", no_argument, NULL, 'a'},    
-    {"onlyassemble", optional_argument, NULL, 'o'},
-    {"assembledetailonly", no_argument, NULL, 'A'},
+    {"memsize", required_argument, NULL, 'M'},
+    {"clocks", required_argument, NULL, 'C'},
     {"help", no_argument, NULL, 'h'},
-    {0, 0, 0, 0}
+    {0, 0, 0, 0},
 };
 
 int main(int argc, char *argv[])
@@ -36,39 +40,57 @@ int main(int argc, char *argv[])
     bool status = false;
     WORD beginptr[argc];
     char *objfile = NULL;
-    const char *usage = "Usage: %s [-tTdslaAh] [-o <OUTFILE>] FILE ...\n";
+    const char *default_objfile = "a.o";
+    const char *usage = "Usage: %s [-slLaAtTdh] [-oO<OUTFILE>] [-M <memsize>] [-C <clocks>] FILE ...\n";
 
-    while((opt = getopt_long(argc, argv, "tTdslao:Ah", longopts, NULL)) != -1) {
+    while((opt = getopt_long(argc, argv, "tTdslLao::O::AM:C:h", longopts, NULL)) != -1) {
         switch(opt) {
-        case 't':
-            tracemode = true;
-            break;
-        case 'T':
-            tracemode = true;
-            logicalmode = true;
-            break;
-        case 'd':
-            dumpmode = true;
-            break;
         case 's':
             srcmode = true;
             break;
         case 'l':
             labelmode = true;
             break;
+        case 'L':
+            onlylabelmode = true;
+            break;
         case 'a':
             asdetailmode = true;
             break;
-        case 'o':
+        case 'A':
             onlyassemblemode = true;
-            if(optarg != NULL) {
+            asdetailmode = true;
+            break;
+        case 'o':
+            if(optarg == NULL) {
+                objfile = strdup(default_objfile);
+            } else {
                 objfile = strdup(optarg);
             }
             break;
-        case 'A':
+        case 'O':
             onlyassemblemode = true;
-            objfile = NULL;
-            asdetailmode = true;
+            if(optarg == NULL) {
+                objfile = strdup(default_objfile);
+            } else {
+                objfile = strdup(optarg);
+            }
+            break;
+        case 't':
+            tracemode = true;
+            break;
+        case 'T':
+            tracemode = true;
+            logicalmode = true;
+            break;
+        case 'd':
+            dumpmode = true;
+            break;
+        case 'M':
+            memsize = atoi(optarg);
+            break;
+        case 'C':
+            clocks = atoi(optarg);
             break;
         case 'h':
             fprintf(stdout, usage, argv[0]);
@@ -78,6 +100,12 @@ int main(int argc, char *argv[])
             exit(-1);
         }
     }
+    if(argv[optind] == NULL) {
+       fprintf(stderr, "source file is not specified\n");
+        exit(-1);
+    }
+    /* ソースファイルが指定されていない場合は終了 */
+    reset();
     /* アセンブル。ラベル表作成のため、2回行う */
     for(pass = FIRST; pass <= SECOND; pass++) {
         for(i = optind; i < argc; i++) {
@@ -99,18 +127,20 @@ int main(int argc, char *argv[])
                 exit(-1);
             }
         }
-        if(pass == FIRST && labelmode == true) {
+        if(pass == FIRST && (labelmode == true || onlylabelmode == true)) {
             fprintf(stdout, "\nLabel::::\n");
             printlabel();
+            if(onlylabelmode == true) {
+                return 0;
+            }
         }
     }
     freelabel();    /* ラベル表の解放 */
     if(status == true) {
-        if(onlyassemblemode) {
-            if(objfile != NULL) {
-                outassemble(objfile);
-            }
-        } else {
+        if(objfile != NULL) {
+            outassemble(objfile);
+        }
+        if(onlyassemblemode == false) {
             exec();    /* プログラム実行 */
         }
     }
index 250ad80..74dec44 100644 (file)
@@ -33,7 +33,8 @@ CERRARRAY cerr[] = {
     { 203, "SVC output - out of COMET II memory" },
     { 204, "Program Register (PR) - out of COMET II memory" },
     { 205, "Stack Pointer (SP) - cannot allocate stack buffer" },
-    { 206, "Address - out of COMET II memory" }
+    { 206, "Address - out of COMET II memory" },
+    { 207, "Stack Pointer (SP) - out of COMET II memory" },
 };
 
 /* WORD値を文字列に変換 */
index 0312035..24040b3 100644 (file)
@@ -6,11 +6,12 @@
 /* 指定されたファイルからCOMET II仮想メモリ(アセンブル結果)を読込 */
 bool inassemble(char *file) {
     FILE *fp;
+    reset();
     if((fp = fopen(file, "r")) == NULL) {
         perror(file);
         return false;
     }
-    fread(memory, sizeof(WORD), MEMSIZE, fp);
+    fread(memory, sizeof(WORD), memsize, fp);
     fclose(fp);
     return true;
 }
@@ -20,6 +21,8 @@ static struct option longopts[] = {
     {"tracearithmetic", no_argument, NULL, 't'},
     {"tracelogical", no_argument, NULL, 'T'},
     {"dump", no_argument, NULL, 'd'},
+    {"memsize", required_argument, NULL, 'M'},
+    {"clocks", required_argument, NULL, 'C'},
     {"help", no_argument, NULL, 'h'},
     {0, 0, 0, 0}
 };
@@ -27,9 +30,9 @@ static struct option longopts[] = {
 int main(int argc, char *argv[])
 {
     int opt;
-    const char *usage = "Usage: %s [-tTdh] FILE\n";
+    const char *usage = "Usage: %s [-tTdh] [-M<memsize>] [-C<clocks>] FILE\n";
 
-    while((opt = getopt_long(argc, argv, "tTdh", longopts, NULL)) != -1) {
+    while((opt = getopt_long(argc, argv, "tTdM:C:h", longopts, NULL)) != -1) {
         switch(opt) {
         case 't':
             tracemode = true;
@@ -41,6 +44,12 @@ int main(int argc, char *argv[])
         case 'd':
             dumpmode = true;
             break;
+        case 'M':
+            memsize = atoi(optarg);
+            break;
+        case 'C':
+            clocks = atoi(optarg);
+            break;
         case 'h':
             fprintf(stdout, usage, argv[0]);
             exit(-1);
index 19be801..25d6c38 100644 (file)
@@ -17,7 +17,7 @@ void svcin()
             --i;
             break;
         }
-        if(GR[1] + i >= MEMSIZE - 1) {
+        if(GR[1] + i >= memsize - 1) {
             setcerr(202, NULL);    /* SVC input - out of Input memory */
             break;
         }
@@ -33,7 +33,7 @@ void svcout()
     char c;
 
     for(i = 0; i < GR[2]; i++) {
-        if(GR[1] + i >= MEMSIZE - 1) {
+        if(GR[1] + i >= memsize - 1) {
             setcerr(203, NULL);    /* SVC output - out of Comet II memory */
             return;
         }
@@ -255,7 +255,8 @@ void reset()
         GR[i] = 0x0;
     }
     SP = PR = FR = 0x0;
-    for(i = 0; i < MEMSIZE; i++) {
+    memory = malloc(memsize);
+    for(i = 0; i < memsize; i++) {
         memory[i] = 0x0;
     }
 }
@@ -273,7 +274,7 @@ void exec()
     }
     /* フラグレジスタの初期値設定 */
     FR = 0x0;
-    SP = MEMSIZE;
+    SP = memsize;
     PR = startptr;
     if(create_code_type() == false) {
         goto execerr;
@@ -282,10 +283,15 @@ void exec()
     for (; ; ) {
         clock_begin = clock();
         /* プログラムレジスタのアドレスが主記憶の範囲外の場合はエラー */
-        if(PR >= MEMSIZE) {
+        if(PR >= memsize) {
             sprintf(errpr, "PR:#%04X", PR);
             setcerr(204, errpr);    /* Program Register (PR) - out of COMET II memory */
         }
+        /* スタック領域のアドレスが主記憶の範囲外の場合はエラー */
+        if(SP > memsize) {
+            sprintf(errpr, "PR:#%04X", PR);
+            setcerr(207, errpr);    /* Stack Pointer (SP) - out of COMET II memory */
+        }
         /* スタック領域を確保できない場合はエラー */
         if(SP <= endptr) {
             sprintf(errpr, "PR:#%04X", PR);
@@ -325,7 +331,7 @@ void exec()
             }
             /* ロード/算術論理演算命令/比較演算命令では、アドレスに格納されている内容を取得 */
             if(cmdtype == R_ADR_X_) {
-                if(val >= MEMSIZE) {
+                if(val >= memsize) {
                     sprintf(errpr, "PR:#%04X", PR-1);
                     setcerr(206, errpr);    /* Address - out of COMET II memory */
                     goto execerr;
@@ -419,18 +425,21 @@ void exec()
             }
             break;
         case 0x7000:  /* PUSH */
+            assert(SP > endptr && SP <= memsize);
             memory[--SP] = val;
             break;
         case 0x7100:  /* POP */
+            assert(SP > endptr && SP <= memsize);
             GR[r_r1] = memory[SP++];
             break;
         case 0x8000:  /* CALL */
+            assert(SP > endptr && SP <= memsize);
             memory[--SP] = PR;
             PR = val;
             break;
         case 0x8100:  /* RET */
-            assert(SP > endptr && SP <= MEMSIZE);
-            if(SP == MEMSIZE) {
+            assert(SP > endptr && SP <= memsize);
+            if(SP == memsize) {
                 return;
             } else {
                 PR = memory[SP++];
@@ -453,7 +462,8 @@ void exec()
         }
         do {
             clock_end = clock();
-        } while(clock_end - clock_begin < CLOCKS_PER_SEC / CLOCKS);
+        } while(clock_end - clock_begin < CLOCKS_PER_SEC / clocks);
+/*        printf("PR:%04X; time: %f\n", PR, (double)((clock_end - clock_begin) * CLOCKS_PER_SEC)); */
     }
 execerr:
     fprintf(stderr, "Execute error - %d: %s\n", cerrno, cerrmsg);
index dc1f358..7f6fd41 100644 (file)
@@ -1,7 +1,7 @@
 #include "casl2.h"
 
 /* COMET IIのメモリ */
-WORD memory[MEMSIZE];
+WORD *memory;
 
 /* COMET IIのCPUレジスタ */
 WORD GR[REGSIZE], SP, PR, FR;
@@ -13,7 +13,7 @@ char *cerrmsg;
 /* レジストリの内容を表示する場合はtrue */
 bool tracemode = false;
 
-/* レジストリの内容を論理値(0〜65535)で表示する場合はTRUE */
+/* レジストリの内容を論理値(0〜65535)で表示する場合はtrue */
 bool logicalmode = false;
 
 /* メモリの内容を表示する場合はtrue */
@@ -25,12 +25,21 @@ bool srcmode = false;
 /* ラベル表を表示する場合はtrue */
 bool labelmode = false;
 
+/* ラベル表を表示して終了する場合はtrue */
+bool onlylabelmode = false;
+
 /* アセンブラ詳細結果を表示する場合はtrue */
 bool asdetailmode = false;
 
 /* アセンブルだけを行う場合はtrue */
 bool onlyassemblemode = false;
 
+/* メモリーサイズ */
+int memsize = DEFAULT_MEMSIZE;
+
+/* クロック周波数 */
+int clocks = DEFAULT_CLOCKS;
+
 /* 実行開始番地 */
 WORD startptr = 0x0;