Valgrindで判明したメモリーに関する問題を修正
[YACASL2.git] / src / exec.c
index 1bc891e..c91fc86 100644 (file)
@@ -74,7 +74,7 @@ bool loadassemble(const char *file)
 
 /**
  * プログラムレジスタ(PR)を表す文字列を返す
- **/
+ */
 char *pr2str(WORD pr) {
     char *str = malloc_chk(CERRSTRSIZE + 1, "pr2str.pr");
 
@@ -100,7 +100,7 @@ void svcin()
             break;
         }
         if(sys->cpu->gr[1] + i > execptr->end) {
-            setcerr(208, NULL);    /* SVC input - memory overflow */
+            setcerr(208, "");    /* SVC input - memory overflow */
             break;
         }
         sys->memory[sys->cpu->gr[1]+i] = *(buffer + i);
@@ -119,12 +119,16 @@ void svcout()
 
     for(i = 0; i < sys->memory[sys->cpu->gr[2]]; i++) {
         if(sys->cpu->gr[1] + i > execptr->end) {
-            setcerr(209, NULL);    /* SVC output - memory overflow */
+            setcerr(209, "");    /* SVC output - memory overflow */
             return;
         }
-        /* 「文字の組」の符号表に記載された文字と、改行(CR)/タブを表示 */
+        /* 「JIS X 0201ラテン文字・片仮名用8ビット符号で規定する文字の符号表」
+           に記載された文字と、改行(CR)/タブを表示 */
         /* それ以外の文字は、「.」で表す */
-        if(((w = sys->memory[sys->cpu->gr[1]+i]) >= 0x20 && w <= 0x7E) || w == 0xA || w == '\t') {
+        if(((w = sys->memory[sys->cpu->gr[1]+i]) >= 0x20 && w <= 0x7E) ||    /* JIS X 0201ラテン文字 */
+           (w >= 0xA0 && w <= 0xFE) ||                                       /* JIS X 0201片仮名用8ビット符号 */
+           w == 0xA || w == '\t')
+        {
             putchar((char)w);
         } else {
             putchar('.');
@@ -154,8 +158,11 @@ void setfr(WORD adr)
 WORD get_r_r1(WORD oprx)
 {
     WORD r;
+    char *s;
+
     if((r = ((oprx & 0x00F0) >>4)) > GRSIZE - 1) {
-        setcerr(205, pr2str(sys->cpu->pr));    /* r/r1 in word #1 - not GR */
+        setcerr(205, s = pr2str(sys->cpu->pr));    /* r/r1 in word #1 - not GR */
+        FREE(s);
         return 0x0;
     }
     return r;
@@ -167,8 +174,11 @@ WORD get_r_r1(WORD oprx)
 WORD get_x_r2(WORD oprx)
 {
     WORD x;
+    char *s;
+
     if((x = (oprx & 0x000F)) > GRSIZE - 1) {
-        setcerr(206, pr2str(sys->cpu->pr));    /* r/r1 in word #1 - not GR */
+        setcerr(206, s = pr2str(sys->cpu->pr));    /* r/r1 in word #1 - not GR */
+        FREE(s);
         return 0x0;
     }
     return x;
@@ -193,8 +203,11 @@ WORD get_adr_x(WORD adr, WORD oprx)
 WORD get_val_adr_x(WORD adr, WORD oprx)
 {
     WORD a;
+    char *s;
+
     if((a = get_adr_x(adr, oprx)) >= sys->memsize) {
-        setcerr(207, pr2str(sys->cpu->pr + 1));    /* address in word #2 - out of memory */
+        setcerr(207, s = pr2str(sys->cpu->pr + 1));    /* address in word #2 - out of memory */
+        FREE(s);
         return 0x0;
     }
     return sys->memory[a];
@@ -202,6 +215,7 @@ WORD get_val_adr_x(WORD adr, WORD oprx)
 
 /**
  * NOP命令。語長1(OPのみ)
+ * \relates exec
  */
 void nop()
 {
@@ -210,6 +224,7 @@ void nop()
 
 /**
  * LD命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void ld_r_adr_x()
 {
@@ -222,6 +237,7 @@ void ld_r_adr_x()
 
 /**
  * LD命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void ld_r1_r2()
 {
@@ -233,6 +249,7 @@ void ld_r1_r2()
 
 /**
  * ST命令。語長2
+ * \relates exec
  */
 void st()
 {
@@ -245,6 +262,7 @@ void st()
 
 /**
  * LAD命令。語長2
+ * \relates exec
  */
 void lad()
 {
@@ -256,7 +274,7 @@ void lad()
 }
 
 /**
- * ADDA命令のテンプレート
+ * ADDA命令のテンプレート\n
  * 汎用レジスタrに値valを算術加算
  */
 void adda(WORD r, WORD val)
@@ -280,6 +298,7 @@ void adda(WORD r, WORD val)
 
 /**
  * ADDA命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void adda_r_adr_x()
 {
@@ -292,6 +311,7 @@ void adda_r_adr_x()
 
 /**
  * ADDA命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void adda_r1_r2()
 {
@@ -303,6 +323,7 @@ void adda_r1_r2()
 
 /**
  * SUBA命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void suba_r_adr_x()
 {
@@ -315,6 +336,7 @@ void suba_r_adr_x()
 
 /**
  * SUBA命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void suba_r1_r2()
 {
@@ -325,7 +347,7 @@ void suba_r1_r2()
 }
 
 /**
- * ADDL命令のテンプレート
+ * ADDL命令のテンプレート\n
  * 汎用レジスタrに値valを論理加算
  */
 void addl(WORD r, WORD val)
@@ -345,6 +367,7 @@ void addl(WORD r, WORD val)
 
 /**
  * ADDL命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void addl_r_adr_x()
 {
@@ -357,6 +380,7 @@ void addl_r_adr_x()
 
 /**
  * ADDL命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void addl_r1_r2()
 {
@@ -368,6 +392,7 @@ void addl_r1_r2()
 
 /**
  * SUBL命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void subl_r_adr_x()
 {
@@ -378,8 +403,10 @@ void subl_r_adr_x()
     sys->cpu->pr += 2;
 }
 
+
 /**
  * SUBL命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void subl_r1_r2()
 {
@@ -391,6 +418,7 @@ void subl_r1_r2()
 
 /**
  * AND命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void and_r_adr_x()
 {
@@ -403,6 +431,7 @@ void and_r_adr_x()
 
 /**
  * AND命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void and_r1_r2()
 {
@@ -414,6 +443,7 @@ void and_r1_r2()
 
 /**
  * OR命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void or_r_adr_x()
 {
@@ -426,6 +456,7 @@ void or_r_adr_x()
 
 /**
  * OR命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void or_r1_r2()
 {
@@ -437,6 +468,7 @@ void or_r1_r2()
 
 /**
  * XOR命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void xor_r_adr_x()
 {
@@ -449,6 +481,7 @@ void xor_r_adr_x()
 
 /**
  * XOR命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void xor_r1_r2()
 {
@@ -459,7 +492,7 @@ void xor_r1_r2()
 }
 
 /**
- * CPA命令のテンプレート
+ * CPA命令のテンプレート\n
  * 汎用レジスタrの内容と値valを算術比較
  */
 void cpa(WORD r, WORD val)
@@ -474,6 +507,7 @@ void cpa(WORD r, WORD val)
 
 /**
  * CPA命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void cpa_r_adr_x()
 {
@@ -486,6 +520,7 @@ void cpa_r_adr_x()
 
 /**
  * CPA命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void cpa_r1_r2()
 {
@@ -496,13 +531,11 @@ void cpa_r1_r2()
 }
 
 /**
- * CPL命令のテンプレート
+ * CPL命令のテンプレート\n
  * 汎用レジスタrの内容と値valを論理比較
  */
 void cpl(WORD r, WORD val)
 {
-    WORD w[1];
-    w[0] = sys->memory[sys->cpu->pr];
     sys->cpu->fr = 0x0;
     if(sys->cpu->gr[r] < val) {
         sys->cpu->fr = SF;
@@ -514,6 +547,7 @@ void cpl(WORD r, WORD val)
 
 /**
  * CPL命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void cpl_r_adr_x()
 {
@@ -526,6 +560,7 @@ void cpl_r_adr_x()
 
 /**
  * CPL命令 - オペランドr1,r2。語長1
+ * \relates exec
  */
 void cpl_r1_r2()
 {
@@ -536,8 +571,9 @@ void cpl_r1_r2()
 }
 
 /**
- * SLA命令 - オペランドr,adr,x。語長2
+ * SLA命令 - オペランドr,adr,x。語長2\n
  * 算術演算なので、第15ビットは送り出されない
+ * \relates exec
  */
 void sla()
 {
@@ -570,9 +606,10 @@ void sla()
 }
 
 /**
- * SRA命令 - オペランドr,adr,x。語長2
- * 算術演算なので、第15ビットは送り出されない
+ * SRA命令 - オペランドr,adr,x。語長2\n
+ * 算術演算なので、第15ビットは送り出されない\n
  * 空いたビット位置には符号と同じものが入る
+ * \relates exec
  */
 void sra()
 {
@@ -609,6 +646,7 @@ void sra()
 
 /**
  * SLL命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void sll()
 {
@@ -639,6 +677,7 @@ void sll()
 
 /**
  * SRL命令 - オペランドr,adr,x。語長2
+ * \relates exec
  */
 void srl()
 {
@@ -670,6 +709,7 @@ void srl()
 
 /**
  * JPL命令。語長2
+ * \relates exec
  */
 void jpl()
 {
@@ -685,6 +725,7 @@ void jpl()
 
 /**
  * JMI命令。語長2
+ * \relates exec
  */
 void jmi()
 {
@@ -700,6 +741,7 @@ void jmi()
 
 /**
  * JNZ命令。語長2
+ * \relates exec
  */
 void jnz()
 {
@@ -715,6 +757,7 @@ void jnz()
 
 /**
  * JZE命令。語長2
+ * \relates exec
  */
 void jze()
 {
@@ -730,6 +773,7 @@ void jze()
 
 /**
  * JOV命令。語長2
+ * \relates exec
  */
 void jov()
 {
@@ -745,6 +789,7 @@ void jov()
 
 /**
  * JUMP命令。語長2
+ * \relates exec
  */
 void jump()
 {
@@ -756,31 +801,42 @@ void jump()
 
 /**
  * PUSH命令。語長2
+ * \relates exec
  */
 void push()
 {
+    assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
     WORD w[2];
+
     w[0] = sys->memory[sys->cpu->pr];
     w[1] = sys->memory[sys->cpu->pr + 1];
-    assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
     sys->memory[--(sys->cpu->sp)] = get_adr_x(w[1], w[0]);
     sys->cpu->pr += 2;
 }
 
 /**
  * POP命令。語長1
+ * \relates exec
  */
 void pop()
 {
-    assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
-    WORD w[1];
-    w[0] = sys->memory[sys->cpu->pr];
-    sys->cpu->gr[get_r_r1(w[0])] = sys->memory[(sys->cpu->sp)++];
-    sys->cpu->pr += 1;
+    assert(sys->cpu->sp > execptr->end);
+    WORD w;
+    char *s;
+
+    if(sys->cpu->sp >= sys->memsize) {
+        setcerr(203, s = pr2str(sys->cpu->pr));        /* Stack Pointer (SP) - stack underflow */
+        FREE(s);
+    } else {
+        w = sys->memory[sys->cpu->pr];
+        sys->cpu->gr[get_r_r1(w)] = sys->memory[(sys->cpu->sp)++];
+        sys->cpu->pr += 1;
+    }
 }
 
 /**
  * CALL命令。語長2
+ * \relates exec
  */
 void call()
 {
@@ -794,6 +850,7 @@ void call()
 
 /**
  * RET命令。語長1(OPのみ)
+ * \relates exec
  */
 void ret()
 {
@@ -807,6 +864,7 @@ void ret()
 
 /**
  * SVC命令。語長2
+ * \relates exec
  */
 void svc()
 {
@@ -830,11 +888,13 @@ void svc()
 
 /**
  * 仮想マシンCOMET IIの実行
+ * \class exec
  */
 void exec()
 {
     clock_t clock_begin, clock_end;
     void (*cmdptr)();
+    char *s;
 
     create_code_type();                             /* 命令のコードとタイプがキーのハッシュ表を作成 */
     if(execmode.trace == true) {
@@ -854,21 +914,23 @@ void exec()
             }
             fprintf(stdout, "\n");
         }
-        /* プログラムレジスタとスタックポインタをチェック */
-        if(sys->cpu->pr >= sys->memsize || sys->cpu->sp > sys->memsize || sys->cpu->sp <= execptr->end) {
-            if(sys->cpu->pr >= sys->memsize) {
-                setcerr(201, pr2str(sys->cpu->pr));        /* Program Register (PR) - memory overflow */
-            } else if(sys->cpu->sp <= execptr->end) {
-                setcerr(202, pr2str(sys->cpu->pr));        /* Stack Pointer (SP) - stack overflow */
-            } else if(sys->cpu->sp > sys->memsize) {
-                setcerr(203, pr2str(sys->cpu->pr));        /* Stack Pointer (SP) - stack underflow */
-            }
+        /* プログラムレジスタをチェック */
+        if(sys->cpu->pr >= sys->memsize) {
+            setcerr(201, s = pr2str(sys->cpu->pr));        /* Program Register (PR) - memory overflow */
+            FREE(s);
+            goto execfin;
+        }
+        /* スタックポインタをチェック */
+        if(sys->cpu->sp <= execptr->end) {
+            setcerr(202, s = pr2str(sys->cpu->pr));        /* Stack Pointer (SP) - stack overflow */
+            FREE(s);
             goto execfin;
         }
         /* コードから命令を取得 */
         /* 取得できない場合はエラー終了 */
         if((cmdptr = getcmdptr(sys->memory[sys->cpu->pr] & 0xFF00)) == NULL) {
-            setcerr(204, pr2str(sys->cpu->pr));            /* OP in word #1 - not command code */
+            setcerr(204, s = pr2str(sys->cpu->pr));            /* OP in word #1 - not command code */
+            FREE(s);
             goto execfin;
         }
         /* 命令の実行 */