From: j8takagi Date: Sun, 28 Mar 2010 16:03:48 +0000 (+0900) Subject: グローバル変数のリファクタリング X-Git-Tag: v0.1p15~30 X-Git-Url: https://j8takagi.net/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=288d61424576d1aae956ea8e4b5fb89dc25909db;p=YACASL2.git グローバル変数のリファクタリング --- diff --git a/include/casl2.h b/include/casl2.h index 93d3d1f..fa8ec3b 100644 --- a/include/casl2.h +++ b/include/casl2.h @@ -25,12 +25,6 @@ enum { DEFAULT_CLOCKS = 5000000, /* デフォルトのクロック周波数。COMET II規格では、未定義 */ }; -/* COMET IIのメモリ */ -extern WORD *memory; - -/* メモリサイズ */ -extern int memsize; - /* COMET II フラグのマスク値 */ enum { OF = 0x4, /* Overflow Flag */ @@ -46,11 +40,15 @@ typedef struct { WORD fr; /* フラグレジスタ */ } CPU; -/* COMET IIのCPU */ -extern CPU *cpu; +/* COMET IIの仮装実行マシンシステム */ +typedef struct { + CPU *cpu; /* CPU */ + WORD *memory; /* メモリ */ + int memsize; /* メモリサイズ */ + int clocks; /* クロック周波数 */ +} SYSTEM; -/* クロック周波数 */ -extern int clocks; +extern SYSTEM *sys; /* COMET II 命令 */ /* 命令タイプは、オペランドにより6種類に分類 */ @@ -106,10 +104,10 @@ typedef struct { WORD end; /* プログラムの終了番地 */ } PROGPROP; -extern PROGPROP *progprop; +extern PROGPROP *prog; /* COMET II仮想マシンのリセット */ -void reset(); +void reset(int memsize, int clocks); /* COMET II仮想マシンのシャットダウン */ void shutdown(); diff --git a/include/cerr.h b/include/cerr.h index e6e8ddf..ee44ee4 100644 --- a/include/cerr.h +++ b/include/cerr.h @@ -15,6 +15,10 @@ /* エラーを出力して終了 */ void *malloc_chk(size_t size, char *tag); +/* callocを実行し、メモリを確保できない場合は */ +/* エラーを出力して終了 */ +void *calloc_chk(size_t nmemb, size_t size, char *tag); + /* malloc_chkを実行してメモリを確保してから、 */ /* コピーした文字列を返す */ char *strdup_chk(const char *s, char *tag); @@ -41,6 +45,9 @@ enum { CERRMSGSIZE = 70, /* エラーメッセージのサイズ */ }; +/* エラーの初期化 */ +void cerr_init(); + /* エラーリストを作成・追加する */ bool addcerrlist(int cerrc, CERR cerrv[]); diff --git a/src/assemble.c b/src/assemble.c index 7dcd888..42ef345 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -86,11 +86,11 @@ bool writememory(WORD word, WORD adr, PASS pass) bool status = false; /* COMET IIメモリオーバーの場合 */ - if(adr >= memsize) { + if(adr >= sys->memsize) { setcerr(119, word2n(adr)); /* out of COMET II memory */ } if(cerr->num == 0) { - memory[adr] = word; + (sys->memory)[adr] = word; if(pass == SECOND && asmode.asdetail == true) { fprintf(stdout, "\t#%04X\t#%04X\n", adr, word); } @@ -199,7 +199,7 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass) asprop->prog = strdup_chk(cmdl->label, "asprop.prog"); /* オペランドがある場合、実行開始番地を設定 */ if(pass == SECOND && cmdl->opd->opdc == 1) { - if((progprop->start = getlabel(asprop->prog, cmdl->opd->opdv[0])) == 0xFFFF) { + if((prog->start = getlabel(asprop->prog, cmdl->opd->opdv[0])) == 0xFFFF) { setcerr(103, cmdl->opd->opdv[0]); /* label not found */ } } @@ -212,7 +212,7 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass) } /* 実行終了番地と次のプログラムの実行開始番地を設定 */ else if(pass == SECOND) { - progprop->end = asprop->lptr; + prog->end = asprop->lptr; } asprop->prog = NULL; status = true; diff --git a/src/casl2.c b/src/casl2.c index f66decd..40001ea 100644 --- a/src/casl2.c +++ b/src/casl2.c @@ -40,7 +40,7 @@ void outassemble(const char *file) { perror(file); exit(-1); } - fwrite(memory, sizeof(WORD), progprop->end, fp); + fwrite(sys->memory, sizeof(WORD), prog->end, fp); fclose(fp); } @@ -54,7 +54,8 @@ const char *objfile_name(const char *str) /* casl2コマンドのメイン */ int main(int argc, char *argv[]) { - int opt, i, status = 0; + int memsize = DEFAULT_MEMSIZE, clocks = DEFAULT_CLOCKS; + int status = 0, opt, i; PASS pass; bool res = false; WORD beginptr[argc]; @@ -62,8 +63,7 @@ int main(int argc, char *argv[]) const char *usage = "Usage: %s [-slLaAtTdh] [-oO[]] [-M ] [-C ] FILE1[ FILE2 ...]\n"; - /* エラーの初期化 */ - cerr = malloc_chk(sizeof(CERR), "cerr"); + cerr_init(); addcerrlist_casl2(); /* オプションの処理 */ while((opt = getopt_long(argc, argv, "tTdslLao::O::AM:C:h", longopts, NULL)) != -1) { @@ -123,7 +123,7 @@ int main(int argc, char *argv[]) exit(-1); } /* COMET II仮想マシンのリセット */ - reset(); + reset(memsize, clocks); /* アセンブル。ラベル表作成のため、2回行う */ for(pass = FIRST; pass <= SECOND; pass++) { if(pass == FIRST) { @@ -137,6 +137,7 @@ int main(int argc, char *argv[]) } else if(pass == SECOND) { asprop->ptr = beginptr[i]; } + asprop->prog = NULL; if(execmode.trace == true || execmode.dump == true || asmode.src == true || asmode.label == true || asmode.asdetail == true) { diff --git a/src/cerr.c b/src/cerr.c index 973881d..9906739 100644 --- a/src/cerr.c +++ b/src/cerr.c @@ -13,6 +13,26 @@ void *malloc_chk(size_t size, char *tag) return p; } +/* callocを実行し、メモリを確保できない場合は */ +/* エラーを出力して終了 */ +void *calloc_chk(size_t nmemb, size_t size, char *tag) +{ + void *p; + + if((p = calloc(nmemb, size)) == NULL) { + fprintf(stderr, "%s: cannot allocate memory\n", tag); + exit(-1); + } + return p; +} + +/* エラーの初期化 */ +void cerr_init() +{ + cerr = malloc_chk(sizeof(CERR), "cerr"); + cerr->num = 0; +} + /* malloc_chkを実行してメモリを確保してから、 */ /* コピーした文字列を返す */ char *strdup_chk(const char *s, char *tag) diff --git a/src/cmd.c b/src/cmd.c index 04d32aa..eff58de 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -69,7 +69,7 @@ bool create_cmdtype_code() int i; cmdtabsize = comet2cmdsize; - cmdtype_code = malloc_chk(cmdtabsize * sizeof(CMDTAB *), "cmdtype_code"); + cmdtype_code = calloc_chk(cmdtabsize, sizeof(CMDTAB *), "cmdtype_code"); for(i = 0; i < cmdtabsize; i++) { *(cmdtype_code + i) = NULL; } @@ -140,7 +140,7 @@ bool create_code_type() int i; cmdtabsize = comet2cmdsize; - code_type = malloc_chk(cmdtabsize * sizeof(CMDTAB *), "code_type"); + code_type = calloc_chk(cmdtabsize, sizeof(CMDTAB *), "code_type"); for(i = 0; i < cmdtabsize; i++) { *(code_type + i) = NULL; } diff --git a/src/comet2.c b/src/comet2.c index 6ab8693..fedf895 100644 --- a/src/comet2.c +++ b/src/comet2.c @@ -34,9 +34,9 @@ bool loadassemble(char *file) { perror(file); return false; } - progprop->end = progprop->start + - fread(memory, sizeof(WORD), memsize-progprop->start, fp); - if(progprop->end == memsize) { + prog->end = prog->start + + fread(sys->memory, sizeof(WORD), sys->memsize - prog->start, fp); + if(prog->end == sys->memsize) { setcerr(201, NULL); /* Load object file - full of COMET II memory */ fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg); status = false; @@ -48,11 +48,11 @@ bool loadassemble(char *file) { /* comet2コマンド */ int main(int argc, char *argv[]) { + int memsize = DEFAULT_MEMSIZE, clocks = DEFAULT_CLOCKS; int opt, status = 0; const char *usage = "Usage: %s [-tTdh] [-M ] [-C ] FILE\n"; - /* エラーの初期化 */ - cerr = malloc_chk(sizeof(CERR), "cerr"); + cerr_init(); addcerrlist_comet2(); /* オプションの処理 */ while((opt = getopt_long(argc, argv, "tTdM:C:h", longopts, NULL)) != -1) { @@ -86,8 +86,9 @@ int main(int argc, char *argv[]) fprintf(stderr, "comet2 error - %d: %s\n", cerr->num, cerr->msg); exit(-1); } - reset(); - progprop->start = 0; + /* COMET II仮想マシンのリセット */ + reset(memsize, clocks); + prog->start = 0; if(loadassemble(argv[optind]) == true) { create_code_type(); /* 命令と命令タイプがキーのハッシュ表を作成 */ exec(); /* プログラム実行 */ diff --git a/src/dump.c b/src/dump.c index 60ca21d..17ff7bc 100644 --- a/src/dump.c +++ b/src/dump.c @@ -7,17 +7,17 @@ void dumpmemory() const int col = 16; int i; /* Header */ - fprintf(stdout, "#%04X: adr :", cpu->pr); - for(i = 0; i < memsize && i < col; i++) { + fprintf(stdout, "#%04X: adr :", sys->cpu->pr); + for(i = 0; i < sys->memsize && i < col; i++) { fprintf(stdout, " %04X", i); } fprintf(stdout, "\n"); /* Memory */ - for(i = 0; i < memsize; i++) { + for(i = 0; i < sys->memsize; i++) { if(i % col == 0) { - fprintf(stdout, "#%04X: %04X: ", cpu->pr, i); + fprintf(stdout, "#%04X: %04X: ", sys->cpu->pr, i); } - fprintf(stdout, "%04X", memory[i]); + fprintf(stdout, "%04X", (sys->memory)[i]); if(i > 0 && (i + 1) % col == 0) { fprintf(stdout, "\n"); } else { @@ -31,13 +31,13 @@ void dspregister() { int i; for(i = 0; i < GRSIZE; i++ ) { - fprintf(stdout, "#%04X: GR%d: ", cpu->pr, i); - print_dumpword(cpu->gr[i], (&execmode)->logical); + fprintf(stdout, "#%04X: GR%d: ", sys->cpu->pr, i); + print_dumpword(sys->cpu->gr[i], (&execmode)->logical); } fprintf(stdout, "#%04X: SP: %6d = #%04X = %s\n", - cpu->pr, cpu->sp, cpu->sp, word2bit(cpu->sp)); + sys->cpu->pr, sys->cpu->sp, sys->cpu->sp, word2bit(sys->cpu->sp)); fprintf(stdout, "#%04X: PR: %6d = #%04X = %s\n", - cpu->pr, cpu->pr, cpu->pr, word2bit(cpu->pr)); + sys->cpu->pr, sys->cpu->pr, sys->cpu->pr, word2bit(sys->cpu->pr)); fprintf(stdout, "#%04X: FR (OF SF ZF): %s\n", - cpu->pr, (word2bit(cpu->fr)+13)); + sys->cpu->pr, (word2bit(sys->cpu->fr)+13)); } diff --git a/src/dumpword.c b/src/dumpword.c index 5ce0ec4..dd49cd5 100644 --- a/src/dumpword.c +++ b/src/dumpword.c @@ -16,7 +16,7 @@ int main(int argc, char *argv[]) WORD word; const char *usage = "Usage: %s [-alh] WORD\n"; - cerr = malloc_chk(sizeof(CERR), "cerr"); + cerr_init(); while((opt = getopt_long(argc, argv, "alh", longopts, NULL)) != -1) { switch(opt) { case 'l': diff --git a/src/exec.c b/src/exec.c index 0d3863b..32913f5 100644 --- a/src/exec.c +++ b/src/exec.c @@ -26,7 +26,7 @@ void svcin() char *buffer = malloc_chk(INSIZE + 1,"svcin.buffer"); if(fgets(buffer, INSIZE, stdin) == NULL) { - memory[cpu->gr[1]] = memory[cpu->gr[2]] = 0x0; + sys->memory[sys->cpu->gr[1]] = sys->memory[sys->cpu->gr[2]] = 0x0; return; } for(i = 0; i < INSIZE; i++) { @@ -34,13 +34,13 @@ void svcin() --i; break; } - if(cpu->gr[1] + i >= memsize - 1) { + if(sys->cpu->gr[1] + i >= sys->memsize - 1) { setcerr(202, NULL); /* SVC input - out of Input memory */ break; } - memory[cpu->gr[1]+i] = *(buffer + i); + sys->memory[sys->cpu->gr[1]+i] = *(buffer + i); } - memory[cpu->gr[2]] = i + 1; + sys->memory[sys->cpu->gr[2]] = i + 1; } /* 標準出力へ文字データを書出(SVC 2) */ @@ -49,14 +49,14 @@ void svcout() int i; WORD w; - for(i = 0; i < memory[cpu->gr[2]]; i++) { - if(cpu->gr[1] + i >= memsize - 1) { + for(i = 0; i < sys->memory[sys->cpu->gr[2]]; i++) { + if(sys->cpu->gr[1] + i >= sys->memsize - 1) { setcerr(203, NULL); /* SVC output - out of Comet II memory */ return; } /* 「文字の組」の符号表に記載された文字と、改行(CR)/タブを表示 */ /* それ以外の文字は、「.」で表す */ - if(((w = memory[cpu->gr[1]+i]) >= 0x20 && w <= 0x7E) || w == 0xA || w == '\t') { + if(((w = sys->memory[sys->cpu->gr[1]+i]) >= 0x20 && w <= 0x7E) || w == 0xA || w == '\t') { putchar((char)w); } else { putchar('.'); @@ -67,14 +67,14 @@ void svcout() /* ロード/論理積/論理和/排他的論理和のフラグ設定。OFは常に0 */ void setfr(WORD val) { - cpu->fr = 0x0; + sys->cpu->fr = 0x0; /* 第15ビットが1のとき、SFは1 */ if((val & 0x8000) > 0x0) { - cpu->fr += SF; + sys->cpu->fr += SF; } /* 演算結果が0のとき、ZFは1 */ if(val == 0x0) { - cpu->fr += ZF; + sys->cpu->fr += ZF; } } @@ -83,16 +83,16 @@ WORD adda(WORD val0, WORD val1) { WORD res; long temp; - cpu->fr = 0x0; + sys->cpu->fr = 0x0; temp = (signed short)val0 + (signed short)val1; if(temp > 32767 || temp < -32768) { - cpu->fr += OF; + sys->cpu->fr += OF; } if(((res = (WORD)(temp & 0xFFFF)) & 0x8000) == 0x8000) { - cpu->fr += SF; + sys->cpu->fr += SF; } else if(res == 0x0) { - cpu->fr += ZF; + sys->cpu->fr += ZF; } return res; } @@ -108,15 +108,15 @@ WORD addl(WORD val0, WORD val1) { long temp; WORD res; - cpu->fr = 0x0; + sys->cpu->fr = 0x0; if((temp = val0 + val1) < 0 || temp > 65535) { - cpu->fr += OF; + sys->cpu->fr += OF; } if(((res = (WORD)(temp & 0xFFFF)) & 0x8000) == 0x8000) { - cpu->fr += SF; + sys->cpu->fr += SF; } else if(res == 0x0) { - cpu->fr += ZF; + sys->cpu->fr += ZF; } return res; } @@ -130,22 +130,22 @@ WORD subl(WORD val0, WORD val1) /* 算術比較のフラグ設定。OFは常に0 */ void cpa(WORD val0, WORD val1) { - cpu->fr = 0x0; + sys->cpu->fr = 0x0; if((short)val0 < (short)val1) { - cpu->fr = SF; + sys->cpu->fr = SF; } else if(val0 == val1) { - cpu->fr = ZF; + sys->cpu->fr = ZF; } } /* 論理比較のフラグ設定。OFは常に0 */ void cpl(WORD val0, WORD val1) { - cpu->fr = 0x0; + sys->cpu->fr = 0x0; if(val0 < val1) { - cpu->fr = SF; + sys->cpu->fr = SF; } else if(val0 == val1) { - cpu->fr = ZF; + sys->cpu->fr = ZF; } } @@ -156,7 +156,7 @@ WORD sla(WORD val0, WORD val1) WORD sign, res, last = 0x0; int i; - cpu->fr = 0x0; + sys->cpu->fr = 0x0; sign = val0 & 0x8000; res = val0 & 0x7FFF; for(i = 0; i < val1; i++) { @@ -166,15 +166,15 @@ WORD sla(WORD val0, WORD val1) res = sign | (res & 0x7FFF); /* OFに、レジスタから最後に送り出されたビットの値を設定 */ if(last > 0x0) { - cpu->fr += OF; + sys->cpu->fr += OF; } /* 符号(第15ビット)が1のとき、SFは1 */ if(sign > 0x0) { - cpu->fr += SF; + sys->cpu->fr += SF; } /* 演算結果が0のとき、ZFは1 */ if(res == 0x0) { - cpu->fr += ZF; + sys->cpu->fr += ZF; } return res; } @@ -187,7 +187,7 @@ WORD sra(WORD val0, WORD val1) WORD sign, res, last = 0x0; int i; - cpu->fr = 0x0; + sys->cpu->fr = 0x0; sign = val0 & 0x8000; res = val0 & 0x7FFF; for(i = 0; i < val1; i++) { @@ -200,15 +200,15 @@ WORD sra(WORD val0, WORD val1) res = sign | res; /* OFに、レジスタから最後に送り出されたビットの値を設定 */ if(last > 0x0) { - cpu->fr += OF; + sys->cpu->fr += OF; } /* 符号(第15ビット)が1のとき、SFは1 */ if(sign > 0x0) { - cpu->fr += SF; + sys->cpu->fr += SF; } /* 演算結果が0のとき、ZFは1 */ if(res == 0x0) { - cpu->fr += ZF; + sys->cpu->fr += ZF; } return res; } @@ -219,22 +219,22 @@ WORD sll(WORD val0, WORD val1) WORD res = val0, last = 0x0; int i; - cpu->fr = 0x0; + sys->cpu->fr = 0x0; for(i = 0; i < val1; i++) { last = res & 0x8000; res <<= 1; } /* OFに、レジスタから最後に送り出されたビットの値を設定 */ if(last > 0x0) { - cpu->fr += OF; + sys->cpu->fr += OF; } /* 第15ビットが1のとき、SFは1 */ if((res & 0x8000) > 0x0) { - cpu->fr += SF; + sys->cpu->fr += SF; } /* 演算結果が0のとき、ZFは1 */ if(res == 0x0) { - cpu->fr += ZF; + sys->cpu->fr += ZF; } return res; } @@ -245,22 +245,22 @@ WORD srl(WORD val0, WORD val1) WORD res = val0, last = 0x0; int i; - cpu->fr = 0x0; + sys->cpu->fr = 0x0; for(i = 0; i < val1; i++) { last = res & 0x0001; res >>= 1; } /* OFに、レジスタから最後に送り出されたビットの値を設定 */ if(last > 0x0) { - cpu->fr += OF; + sys->cpu->fr += OF; } /* 第15ビットが1のとき、SFは1 */ if((res & 0x8000) > 0x0) { - cpu->fr += SF; + sys->cpu->fr += SF; } /* 演算結果が0のとき、ZFは1 */ if(res == 0x0) { - cpu->fr += ZF; + sys->cpu->fr += ZF; } return res; } @@ -278,73 +278,73 @@ bool exec() fprintf(stdout, "\nExecuting machine codes\n"); } /* フラグレジスタの初期値設定 */ - cpu->fr = 0x0; - cpu->sp = memsize; - cpu->pr = progprop->start; + sys->cpu->fr = 0x0; + sys->cpu->sp = sys->memsize; + sys->cpu->pr = prog->start; /* 機械語の実行 */ for (; ; ) { clock_begin = clock(); /* プログラムレジスタのアドレスが主記憶の範囲外の場合はエラー */ - if(cpu->pr >= memsize) { - sprintf(errpr, "PR:#%04X", cpu->pr); + if(sys->cpu->pr >= sys->memsize) { + sprintf(errpr, "PR:#%04X", sys->cpu->pr); setcerr(204, errpr); /* Program Register (PR) - out of COMET II memory */ } /* スタック領域のアドレスが主記憶の範囲外の場合はエラー */ - if(cpu->sp > memsize) { - sprintf(errpr, "PR:#%04X", cpu->pr); + if(sys->cpu->sp > sys->memsize) { + sprintf(errpr, "PR:#%04X", sys->cpu->pr); setcerr(207, errpr); /* Stack Pointer (SP) - out of COMET II memory */ } /* スタック領域を確保できない場合はエラー */ - if(cpu->sp <= progprop->end) { - sprintf(errpr, "PR:#%04X", cpu->pr); + if(sys->cpu->sp <= prog->end) { + sprintf(errpr, "PR:#%04X", sys->cpu->pr); setcerr(205, errpr); /* Stack Pointer (SP) - cannot allocate stack buffer */ } /* 命令の取り出し */ - op = memory[cpu->pr] & 0xFF00; + op = sys->memory[sys->cpu->pr] & 0xFF00; /* 命令の解読 */ cmdtype = getcmdtype(op); - r_r1 = (memory[cpu->pr] >> 4) & 0xF; - x_r2 = memory[cpu->pr] & 0xF; + r_r1 = (sys->memory[sys->cpu->pr] >> 4) & 0xF; + x_r2 = sys->memory[sys->cpu->pr] & 0xF; /* エラー発生時は終了 */ if(cerr->num > 0) { goto execerr; } /* traceオプション指定時、レジスタを出力 */ if(execmode.trace){ - fprintf(stdout, "#%04X: Register::::\n", cpu->pr); + fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr); dspregister(); } /* dumpオプション指定時、メモリを出力 */ if(execmode.dump){ - fprintf(stdout, "#%04X: Memory::::\n", cpu->pr); + fprintf(stdout, "#%04X: Memory::::\n", sys->cpu->pr); dumpmemory(); } /* どちらかのオプション指定時、改行を出力 */ if(execmode.dump || execmode.trace) { fprintf(stdout, "\n"); } - cpu->pr++; + sys->cpu->pr++; /* オペランドの取り出し */ if(cmdtype == R1_R2) { assert(x_r2 < GRSIZE); - val = cpu->gr[x_r2]; + val = sys->cpu->gr[x_r2]; } else if(cmdtype == R_ADR_X || cmdtype == R_ADR_X_ || cmdtype == ADR_X) { assert(x_r2 < GRSIZE); /* 実効アドレス(値または値が示す番地)を取得 */ - val = memory[cpu->pr++]; + val = sys->memory[sys->cpu->pr++]; /* 指標アドレスを加算 */ if(x_r2 > 0x0) { - val += cpu->gr[x_r2]; + val += sys->cpu->gr[x_r2]; } /* ロード/算術論理演算命令/比較演算命令では、アドレスに格納されている内容を取得 */ if(cmdtype == R_ADR_X_) { - if(val >= memsize) { - sprintf(errpr, "PR:#%04X", cpu->pr-1); + if(val >= sys->memsize) { + sprintf(errpr, "PR:#%04X", sys->cpu->pr-1); setcerr(206, errpr); /* Address - out of COMET II memory */ goto execerr; } - val = memory[val]; + val = sys->memory[val]; } } /* 主オペランドが1〜4の場合、第2ビットを無視 */ @@ -357,100 +357,100 @@ bool exec() case 0x0: /* NOP */ break; case 0x1000: /* LD */ - setfr(cpu->gr[r_r1] = val); + setfr(sys->cpu->gr[r_r1] = val); break; case 0x1100: /* ST */ - memory[val] = cpu->gr[r_r1]; + sys->memory[val] = sys->cpu->gr[r_r1]; break; case 0x1200: /* LAD */ - cpu->gr[r_r1] = val; + sys->cpu->gr[r_r1] = val; break; case 0x2000: /* ADDA */ - cpu->gr[r_r1] = adda(cpu->gr[r_r1], val); + sys->cpu->gr[r_r1] = adda(sys->cpu->gr[r_r1], val); break; case 0x2100: /* SUBA */ - cpu->gr[r_r1] = suba(cpu->gr[r_r1], val); + sys->cpu->gr[r_r1] = suba(sys->cpu->gr[r_r1], val); break; case 0x2200: /* ADDL */ - cpu->gr[r_r1] = addl(cpu->gr[r_r1], val); + sys->cpu->gr[r_r1] = addl(sys->cpu->gr[r_r1], val); break; case 0x2300: /* SUBL */ - cpu->gr[r_r1] = subl(cpu->gr[r_r1], val); + sys->cpu->gr[r_r1] = subl(sys->cpu->gr[r_r1], val); break; case 0x3000: /* AND */ - setfr(cpu->gr[r_r1] &= val); + setfr(sys->cpu->gr[r_r1] &= val); break; case 0x3100: /* OR */ - setfr(cpu->gr[r_r1] |= val); + setfr(sys->cpu->gr[r_r1] |= val); break; case 0x3200: /* XOR */ - setfr(cpu->gr[r_r1] ^= val); + setfr(sys->cpu->gr[r_r1] ^= val); break; case 0x4000: /* CPA */ - cpa(cpu->gr[r_r1], val); + cpa(sys->cpu->gr[r_r1], val); break; case 0x4100: /* CPL */ - cpl(cpu->gr[r_r1], val); + cpl(sys->cpu->gr[r_r1], val); break; case 0x5000: /* SLA */ - cpu->gr[r_r1] = sla(cpu->gr[r_r1], val); + sys->cpu->gr[r_r1] = sla(sys->cpu->gr[r_r1], val); break; case 0x5100: /* SRA */ - cpu->gr[r_r1] = sra(cpu->gr[r_r1], val); + sys->cpu->gr[r_r1] = sra(sys->cpu->gr[r_r1], val); break; case 0x5200: /* SLL */ - cpu->gr[r_r1] = sll(cpu->gr[r_r1], val); + sys->cpu->gr[r_r1] = sll(sys->cpu->gr[r_r1], val); break; case 0x5300: /* SRL */ - cpu->gr[r_r1] = srl(cpu->gr[r_r1], val); + sys->cpu->gr[r_r1] = srl(sys->cpu->gr[r_r1], val); break; case 0x6100: /* JMI */ - if((cpu->fr & SF) > 0) { - cpu->pr = val; + if((sys->cpu->fr & SF) > 0) { + sys->cpu->pr = val; } break; case 0x6200: /* JNZ */ - if((cpu->fr & ZF) == 0) { - cpu->pr = val; + if((sys->cpu->fr & ZF) == 0) { + sys->cpu->pr = val; } break; case 0x6300: /* JZE */ - if((cpu->fr & ZF) > 0) { - cpu->pr = val; + if((sys->cpu->fr & ZF) > 0) { + sys->cpu->pr = val; } break; case 0x6400: /* JUMP */ - cpu->pr = val; + sys->cpu->pr = val; break; case 0x6500: /* JPL */ - if((cpu->fr & (SF | ZF)) == 0) { - cpu->pr = val; + if((sys->cpu->fr & (SF | ZF)) == 0) { + sys->cpu->pr = val; } break; case 0x6600: /* JOV */ - if((cpu->fr & OF) > 0) { - cpu->pr = val; + if((sys->cpu->fr & OF) > 0) { + sys->cpu->pr = val; } break; case 0x7000: /* PUSH */ - assert(cpu->sp > progprop->end && cpu->sp <= memsize); - memory[--cpu->sp] = val; + assert(sys->cpu->sp > prog->end && sys->cpu->sp <= sys->memsize); + sys->memory[--(sys->cpu->sp)] = val; break; case 0x7100: /* POP */ - assert(cpu->sp > progprop->end && cpu->sp <= memsize); - cpu->gr[r_r1] = memory[cpu->sp++]; + assert(sys->cpu->sp > prog->end && sys->cpu->sp <= sys->memsize); + sys->cpu->gr[r_r1] = sys->memory[(sys->cpu->sp)++]; break; case 0x8000: /* CALL */ - assert(cpu->sp > progprop->end && cpu->sp <= memsize); - memory[--(cpu->sp)] = cpu->pr; - cpu->pr = val; + assert(sys->cpu->sp > prog->end && sys->cpu->sp <= sys->memsize); + sys->memory[--(sys->cpu->sp)] = sys->cpu->pr; + sys->cpu->pr = val; break; case 0x8100: /* RET */ - assert(cpu->sp > progprop->end && cpu->sp <= memsize); - if(cpu->sp == memsize) { + assert(sys->cpu->sp > prog->end && sys->cpu->sp <= sys->memsize); + if(sys->cpu->sp == sys->memsize) { return true; } else { - cpu->pr = memory[(cpu->sp)++]; + sys->cpu->pr = sys->memory[(sys->cpu->sp)++]; break; } case 0xF000: /* SVC */ @@ -470,7 +470,7 @@ bool exec() } do { clock_end = clock(); - } while(clock_end - clock_begin < CLOCKS_PER_SEC / clocks); + } while(clock_end - clock_begin < CLOCKS_PER_SEC / sys->clocks); } return true; execerr: diff --git a/src/struct.c b/src/struct.c index 1fb4326..8e60601 100644 --- a/src/struct.c +++ b/src/struct.c @@ -1,44 +1,38 @@ #include "casl2.h" -/* COMET IIのメモリ */ -WORD *memory; +/* COMET IIの仮装実行マシンシステム */ +SYSTEM *sys; -/* メモリサイズ */ -int memsize = DEFAULT_MEMSIZE; - -/* COMET IIのCPU */ -CPU *cpu; - -/* クロック周波数 */ -int clocks = DEFAULT_CLOCKS; - -/* CASL2プログラムのプロパティ */ -PROGPROP *progprop; +/* CASL IIプログラムのプロパティ */ +PROGPROP *prog; /* COMET II仮想マシンのリセット */ -void reset() +void reset(int memsize, int clocks) { int i; + sys = malloc_chk(sizeof(SYSTEM), "sys"); + /* メモリサイズの設定 */ + sys->memsize = memsize; + /* クロック周波数の設定 */ + sys->clocks = clocks; /* メモリの初期化 */ - memory = malloc_chk(memsize * sizeof(WORD), "memory"); - for(i = 0; i < memsize; i++) { - memory[i] = 0x0; - } + sys->memory = calloc_chk(sys->memsize, sizeof(WORD), "memory"); /* CPUの初期化 */ - cpu = malloc_chk(sizeof(CPU), "cpu"); + sys->cpu = malloc_chk(sizeof(CPU), "cpu"); for(i = 0; i < GRSIZE; i++) { - cpu->gr[i] = 0x0; + sys->cpu->gr[i] = 0x0; } - cpu->sp = cpu->pr = cpu->fr = 0x0; + sys->cpu->sp = sys->cpu->pr = sys->cpu->fr = 0x0; /* CASL2プログラムのプロパティ */ - progprop = malloc_chk(sizeof(PROGPROP), "progprop"); + prog = malloc_chk(sizeof(PROGPROP), "prog"); } /* COMET II仮想マシンのシャットダウン */ void shutdown() { - free(progprop); - free(cpu); - free(memory); + free(prog); + free(sys->memory); + free(sys->cpu); + free(sys); } diff --git a/src/word.c b/src/word.c index 9371758..cf841ce 100644 --- a/src/word.c +++ b/src/word.c @@ -73,8 +73,12 @@ WORD nh2word(const char *str) /* WORD値を10進数の文字列に変換 */ char *word2n(WORD word) { - char *p = malloc_chk(6, "word2n.p"), *q = malloc_chk(6, "word2n.q"); + enum { + MAXLEN = 6, /* WORD値を10進数で表したときの最大桁数 */ + }; + char *p = malloc_chk(MAXLEN, "word2n.p"), *q = malloc_chk(MAXLEN, "word2n.q"); int i = 0, j; + do{ *(p + i++) = word % 10 + '0'; } while((word /= 10) > 0); @@ -88,9 +92,13 @@ char *word2n(WORD word) /* WORD値を2進数の文字列に変換 */ char *word2bit(const WORD word) { + enum { + MAXLEN = 16, /* WORD値を2進数で表したときの最大桁数 */ + }; WORD mask = 0x8000; - char *bit = malloc_chk(16 + 1, "word2bit.bit"), *p; - p = bit; + char *bit, *p; + + p = bit = malloc_chk(MAXLEN + 1, "word2bit.bit"); do { *p++ = (word & mask) ? '1' : '0'; } while((mask >>= 1) > 0);