X-Git-Url: http://j8takagi.net/cgi-bin/gitweb.cgi?p=YACASL2.git;a=blobdiff_plain;f=src%2Fexec.c;h=b9f987157f1991cb8979bed1ca5fe099331cfc19;hp=d811c92611f94437274fdd8ce46120f7a40d2038;hb=ccc3acda4256e10a822e41e84f6c9991271c2f61;hpb=44cde08e6cf148928a219593c78a57abfd89b424 diff --git a/src/exec.c b/src/exec.c index d811c92..b9f9871 100644 --- a/src/exec.c +++ b/src/exec.c @@ -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,15 +33,15 @@ 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; } if(memory[GR[1]+i] == '\0') { break; } - /* 「文字の組」の符号表に記載された文字と、改行(CR)/タブを表示 - それ以外の文字は、「.」で表す */ + /* 「文字の組」の符号表に記載された文字と、改行(CR)/タブを表示 */ + /* それ以外の文字は、「.」で表す */ if(((c = (char)(memory[GR[1]+i])) >= 0x20 && c <= 0x7E) || c == 0xA || c == '\t') { putchar(c); } else { @@ -71,12 +71,11 @@ WORD adda(WORD val0, WORD val1) long temp; FR = 0x0; - temp = (short)val0 + (short)val1; + temp = (signed short)val0 + (signed short)val1; if(temp > 32767 || temp < -32768) { FR += OF; } - res = (WORD)(temp & 0xFFFF); - if((res & 0x8000) > 0x0) { + if(((res = (WORD)(temp & 0xFFFF)) & 0x8000) == 0x8000) { FR += SF; } else if(res == 0x0) { FR += ZF; @@ -97,12 +96,10 @@ WORD addl(WORD val0, WORD val1) WORD res; FR = 0x0; - temp = val0 + val1; - if(temp > 65535) { + if((temp = val0 + val1) < 0 || temp > 65535) { FR += OF; } - res = (WORD)(temp & 0xFFFF); - if((res & 0x8000) > 0x0) { + if(((res = (WORD)(temp & 0xFFFF)) & 0x8000) == 0x8000) { FR += SF; } else if(res == 0x0) { FR += ZF; @@ -113,21 +110,7 @@ WORD addl(WORD val0, WORD val1) /* 論理減算。フラグを設定して値を返す */ WORD subl(WORD val0, WORD val1) { - long temp; - WORD res; - FR = 0x0; - - temp = val0 - val1; - if(temp < 0) { - FR += OF; - } - res = (WORD)(temp & 0xFFFF); - if((res & 0x8000) > 0) { - FR += SF; - } else if(res == 0) { - FR += ZF; - } - return res; + return addl(val0, (~val1 + 1)); } /* 算術比較のフラグ設定。OFは常に0 */ @@ -152,8 +135,8 @@ void cpl(WORD val0, WORD val1) } } -/* 算術左シフト。フラグを設定して値を返す。 - 算術演算なので、第15ビットは送り出されない */ +/* 算術左シフト。フラグを設定して値を返す。 */ +/* 算術演算なので、第15ビットは送り出されない */ WORD sla(WORD val0, WORD val1) { FR = 0x0; @@ -184,7 +167,7 @@ WORD sra(WORD val0, WORD val1) res = (val0 & 0x7FFF) >> val1; /* 符号(第15ビット)が1の場合、符号と空いたビット位置に1を設定 COMET IIの仕様で、シフトの結果空いたビット位置には符号と同じものが入る */ - if((sign = val0 & 0x8000) > 0x0) { + if((sign = val0 & 0x8000) == 0x8000) { for(i = 0; i <= val1; i++) { res |= onbit; onbit >>= 1; @@ -237,7 +220,7 @@ WORD srl(WORD val0, WORD val1) FR += OF; } /* 第15ビットが1のとき、SFは1 */ - if((res & 0x8000) > 0x0) { + if((res & 0x8000) == 0x8000) { FR += SF; } /* 演算結果が0のとき、ZFは1 */ @@ -247,15 +230,16 @@ WORD srl(WORD val0, WORD val1) return res; } -/* 仮想マシンのリセット */ +/* COMET II仮想マシンのリセット */ void reset() { int i; - for(i = 0; i <= 7; i++) { + for(i = 0; i < REGSIZE; i++) { 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; } } @@ -266,23 +250,31 @@ void exec() WORD op, r_r1, x_r2, val; CMDTYPE cmdtype; char *errpr = malloc(8); - if(tracemode) { + clock_t clock_begin, clock_end; + + if((&execmode)->tracemode) { fprintf(stdout, "\nExecuting machine codes\n"); } /* フラグレジスタの初期値設定 */ FR = 0x0; - SP = MEMSIZE; + SP = memsize; PR = startptr; if(create_code_type() == false) { goto execerr; } /* 機械語の実行 */ 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); @@ -296,15 +288,15 @@ void exec() if(cerrno > 0) { goto execerr; } - if(tracemode){ + if((&execmode)->tracemode){ fprintf(stdout, "#%04X: Register::::\n", PR); dspregister(); } - if(dumpmode){ + if((&execmode)->dumpmode){ fprintf(stdout, "#%04X: Memory::::\n", PR); dumpmemory(); } - if(dumpmode || tracemode) { + if((&execmode)->dumpmode || (&execmode)->tracemode) { fprintf(stdout, "\n"); } PR++; @@ -322,7 +314,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; @@ -416,18 +408,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++]; @@ -448,6 +443,10 @@ void exec() default: break; } + do { + clock_end = clock(); + } 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);