diff --git a/emul_inst_decipher.c b/emul_inst_decipher.c index b05c629..e2931fe 100644 --- a/emul_inst_decipher.c +++ b/emul_inst_decipher.c @@ -106,6 +106,16 @@ emul_reg_set(Spc, pc+1); } +void emul_inst_dec_reset_pc() { + emul_reg_set(Spc, 0); + emul_inst_dec_update_pc(); +} + +/* ファイルからデータをロードする,ファイルは自動的にクローズされる + * Return: + * 0 = 失敗 + * 1 = 成功 + * */ int emul_inst_dec_load(const char *filename) { FILE *fp; int line; diff --git a/emul_inst_decipher.h b/emul_inst_decipher.h index 11b9b24..94ecdec 100644 --- a/emul_inst_decipher.h +++ b/emul_inst_decipher.h @@ -32,6 +32,8 @@ void emul_inst_dec_update_pc(); +void emul_inst_dec_reset_pc(); + int emul_inst_dec_get_token(char *token); /* Summary: diff --git a/emul_inst_exec.c b/emul_inst_exec.c index 01f2203..6623e98 100644 --- a/emul_inst_exec.c +++ b/emul_inst_exec.c @@ -19,12 +19,40 @@ return RunMode; } -// +// プロトタイプ +exitcode_t emul_inst_exec_pseudo(char token[LOAD_TOKEN_MAX]); +// load label +void emul_inst_exec_load_label() { + char token[LOAD_TOKEN_MAX]; + int ps_id; + // トークンを取得 + if ( emul_inst_dec_get_token(token) == 0 ) { + emul_out_std_err("Non exist next token\n"); + // 次のトークンが見つからない場合終了, pcのアドレスを初期化 + emul_inst_dec_reset_pc(); + return ; + } + emul_out_std_debug("[label] load token: %s\n", token); + // 疑似コードを取得 + ps_id = emul_inst_dec_get_pseudo(token); + // 疑似コードがLABELなら + if ( ps_id == LABEL ) { + // 疑似コードを実行 + emul_inst_exec_pseudo(token); + } + // 読み込めるトークンがなくなるまで実行 + emul_inst_exec_load_label(); +} int emul_inst_exec_load(char *filename) { - return emul_inst_dec_load(filename); + // ロードできないなら終了 + if ( emul_inst_dec_load(filename) == 0 ) return 0; + // できたらラベルも読み込み + emul_inst_exec_load_label(); + return 1; } + /* オペコード解読処理群 - START */ void emul_inst_exec_add(int r0, int r1, int r2) { emul_out_std_debug(" : add r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); @@ -93,10 +121,12 @@ emul_out_std_debug("Execute: sne r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } -void emul_inst_exec_j(int target) { - emul_out_std_debug(" : j target[%d];\n", target); - emul_reg_set(Spc, target); - emul_out_std_debug("Execute: j target[%d];\n", target); +void emul_inst_exec_j(char *label) { + int getted_address; + emul_out_std_debug(" : j label[%s];\n", label); + getted_address = emul_label_resolve(label); + emul_reg_set( Spc, getted_address ); + emul_out_std_debug("Execute: j label[%s];\n", label); } void emul_inst_exec_beq(int r0, int r1, char *label) { @@ -186,25 +216,38 @@ /* :RUN * SUMMARY: * 現在の状態から逐次実行に切り替える */ -void emul_inst_exec_pseudo_run() {} +void emul_inst_exec_pseudo_run() { + emul_inst_exec_set_runmode(Run); +} /* :STEP * SUMMARY: * 現在の状態からステップ実行に切り替える */ -void emul_inst_exec_pseudo_step() {} +void emul_inst_exec_pseudo_step() { + emul_inst_exec_set_runmode(Step); +} /* :INPUT * SUMMARY: * キーボート入力を待機し,結果をレジスタへ格納する */ -void emul_inst_exec_pseudo_input() {} +void emul_inst_exec_pseudo_input(int reg) { + int c; + emul_out_std_debug("wait to be inputed..."); + while ( (c = getchar()) == '\n' ); + emul_reg_set(reg, c); +} /* :OUTPUT * レジスタの値をASCII文字として画面に出力する,改行はない*/ -void emul_inst_exec_pseudo_output() {} +void emul_inst_exec_pseudo_output(int reg) { + emul_out_std("%c", (char)emul_reg_get(reg)); +} /* :CRLF * 画面へ改行コードを送信する,改行コードについて決まりはない */ -void emul_inst_exec_pseudo_crlf() {} +void emul_inst_exec_pseudo_crlf() { + emul_out_std("\n"); +} /* 疑似コード解読処理群 - END */ @@ -255,19 +298,27 @@ ); break; case RUN: - emul_inst_exec_set_runmode(Run); + emul_inst_exec_pseudo_run(); break; case STEP: - emul_inst_exec_set_runmode(Step); + emul_inst_exec_pseudo_step(); break; - //case INPUT: - // break; - //case OUTPUT: - // break; - //case CRLF: - // break; - //case EXIT: - // break; + case INPUT: + emul_inst_exec_pseudo_input( + emul_inst_dec_get_next_operand() + ); + break; + case OUTPUT: + emul_inst_exec_pseudo_output( + emul_inst_dec_get_next_operand() + ); + break; + case CRLF: + emul_inst_exec_pseudo_crlf(); + break; + case EXIT: + return Exit; + break; default: emul_out_std_debug("[疑似コード]まだ実装してないので待って!\n"); } @@ -395,8 +446,8 @@ emul_inst_exec_bne(temp_op[0], temp_op[1], label); break; case J : - temp_op[0] = emul_inst_dec_get_next_immediate(); - emul_inst_exec_j(temp_op[0]); + emul_inst_dec_get_token(label); + emul_inst_exec_j(label); break; case LW : temp_op[0] = emul_inst_dec_get_next_operand(); @@ -430,11 +481,16 @@ puts("...Wait for step, please input key enter."); getchar(); } + if (RunMode == Exit) { + emul_out_std_debug("Program Exit\n"); + return Success; + } } return exit_code; } int main(void) { + //emul_std_debug(2); emul_inst_exec_load("test_asm/test.asm"); emul_reg_init(); emul_inst_exec_run(); diff --git a/emul_inst_exec.h b/emul_inst_exec.h index 3cc4428..3b3c7e9 100644 --- a/emul_inst_exec.h +++ b/emul_inst_exec.h @@ -11,7 +11,8 @@ typedef enum { Failed, Success, - Stop + Stop, + Exit } exitcode_t; // ランモード diff --git a/test_asm/input.asm b/test_asm/input.asm new file mode 100644 index 0000000..96aadb0 --- /dev/null +++ b/test_asm/input.asm @@ -0,0 +1,13 @@ +:DUMP DEBUG0 +:RUN + +:INPUT $s0 +:INPUT $s1 +:INPUT $s2 +:INPUT $s3 +:REGCAT $s0 +:OUTPUT $s1 +:CRLF +:REGCAT $s2 +:OUTPUT $s3 +:CRLF diff --git a/test_asm/test.asm b/test_asm/test.asm index eebc433..eb93e80 100644 --- a/test_asm/test.asm +++ b/test_asm/test.asm @@ -1,20 +1,13 @@ :DUMP DEBUG0 :RUN -addi $s0 $zero 0 -:REGCAT $s0 -:STEP +addi $s0 $s0 33 :LABEL LOOP -addi $s0 $s0 1 -:REGCAT $s0 -slti $t0 $s0 10 -bne $t0 $zero LOOP - -:RUN -addi $s0 $zero 0 -:LABEL LOOP1 -addi $s0 $s0 1 -:REGCAT $s0 -slti $t0 $s0 10 -bne $t0 $zero LOOP1 +:INPUT $s1 +:OUTPUT $s1 +:CRLF +beq $s0 $s1 EXIT +j LOOP +:LABEL EXIT +:REGCAT $pc