X-Git-Url: http://j8takagi.net/cgi-bin/gitweb.cgi?p=YACASL2.git;a=blobdiff_plain;f=src%2Fassemble.c;h=d8d8bc61be4fe83061e556dc49d61efee28cfc27;hp=366ccf9e1da4235d196c09e735ae9d1dadd891ea;hb=7b6d89e7273b49e335af425cbb1ecb2258bf15df;hpb=93f3bbbc043d2883610bd979556e0bae42e5c8b2 diff --git a/src/assemble.c b/src/assemble.c index 366ccf9..d8d8bc6 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -21,9 +21,6 @@ ASPTR *asptr; * アセンブルのエラー定義 */ static CERR cerr_assemble[] = { - { 101, "label already defined" }, - { 102, "label table is full" }, - { 103, "label not found" }, { 106, "operand mismatch in assemble command" }, { 107, "no label in START" }, { 108, "not command of operand \"r\"" }, @@ -59,7 +56,7 @@ void writeRPOP(PASS pass); bool cometcmd(const CMDLINE *cmdl, PASS pass); -bool writememory(WORD word, WORD adr, PASS pass); +void writememory(WORD word, WORD adr, PASS pass); void writestr(const char *str, bool literal, PASS pass); @@ -115,13 +112,12 @@ WORD getliteral(const char *str, PASS pass) /** * アセンブラ命令をメモリに書込 - * 実行に成功した場合はtrue、それ以外の場合はfalseを返す + * アセンブラ命令の場合はtrue、それ以外の場合はfalseを返す */ bool assemblecmd(const CMDLINE *cmdl, PASS pass) { int i = 0; ASCMDID cmdid = 0; - bool status = false; ASCMD ascmd[] = { { START, 0, 1, "START" }, { END, 0, 0, "END" }, @@ -134,7 +130,7 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass) if(strcmp(cmdl->cmd, ascmd[i].cmd) == 0) { if(cmdl->opd->opdc < ascmd[i].opdc_min || cmdl->opd->opdc > ascmd[i].opdc_max) { setcerr(106, NULL); /* operand count mismatch */ - return false; + return true; } cmdid = ascmd[i].cmdid; break; @@ -146,7 +142,7 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass) case START: if(cmdl->label == NULL) { setcerr(107, NULL); /* no label in START */ - return false; + return true; } /* プログラム名の設定 */ asptr->prog = strdup_chk(cmdl->label, "asptr.prog"); @@ -156,7 +152,6 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass) setcerr(103, cmdl->opd->opdv[0]); /* label not found */ } } - status = true; break; case END: /* 1回目のアセンブルの場合は、リテラル領域開始アドレスを設定 */ @@ -168,39 +163,33 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass) execptr->end = asptr->lptr; } FREE(asptr->prog); - status = true; break; case DS: for(i = 0; i < atoi(cmdl->opd->opdv[0]); i++) { writememory(0x0, (asptr->ptr)++, pass); if(cerr->num > 0) { - return false; + break; } } - status = true; break; case DC: for(i = 0; i < cmdl->opd->opdc; i++) { writeDC(cmdl->opd->opdv[i], pass); if(cerr->num > 0) { - return false; + break; } } - status = true; break; default: return false; } - if(cerr->num > 0) { - status = false; - } - return status; + return true; } /** * macrocmd - * マクロ命令をメモリに書込 - * 書込に成功した場合はtrue、それ以外の場合はfalseを返す + * マクロ命令をメモリに書込 + * マクロ命令の場合はtrue、それ以外の場合はfalseを返す */ bool macrocmd(const CMDLINE *cmdl, PASS pass) { @@ -220,7 +209,7 @@ bool macrocmd(const CMDLINE *cmdl, PASS pass) cmdl->opd->opdc > macrocmd[i].opdc_max) { setcerr(106, NULL); /* operand count mismatch */ - return false; + return true; } cmdid = macrocmd[i].cmdid; break; @@ -230,19 +219,20 @@ bool macrocmd(const CMDLINE *cmdl, PASS pass) { case IN: writeIN(cmdl->opd->opdv[0], cmdl->opd->opdv[1], pass); - return true; + break; case OUT: writeOUT(cmdl->opd->opdv[0], cmdl->opd->opdv[1], pass); - return true; + break; case RPUSH: writeRPUSH(pass); - return true; + break; case RPOP: writeRPOP(pass); - return true; + break; default: return false; } + return true; } /** @@ -354,8 +344,7 @@ void writeRPOP(PASS pass) */ bool cometcmd(const CMDLINE *cmdl, PASS pass) { - WORD cmd, adr, r1, r2, x; - bool status = false; + WORD cmd, r_r1, x_r2, adr; /* オペランドなし */ if(cmdl->opd->opdc == 0) { @@ -363,56 +352,48 @@ bool cometcmd(const CMDLINE *cmdl, PASS pass) setcerr(112, cmdl->cmd); /* not command of no operand */ return false; } - if(writememory(cmd, (asptr->ptr)++, pass) == true) { - status = true; - } + writememory(cmd, (asptr->ptr)++, pass); } /* 第1オペランドは汎用レジスタ */ - else if((r1 = getgr(cmdl->opd->opdv[0], false)) != 0xFFFF) { + else if((r_r1 = getgr(cmdl->opd->opdv[0], false)) != 0xFFFF) { /* オペランド数1 */ if(cmdl->opd->opdc == 1) { if((cmd = getcmdcode(cmdl->cmd, R_)) == 0xFFFF) { setcerr(108, cmdl->cmd); /* not command of operand "r" */ return false; } - cmd |= (r1 << 4); - if(writememory(cmd, (asptr->ptr)++, pass) == true) { - status = true; - } + cmd |= (r_r1 << 4); + writememory(cmd, (asptr->ptr)++, pass); } /* オペランド数2。第2オペランドは汎用レジスタ */ - else if(cmdl->opd->opdc == 2 && (r2 = getgr(cmdl->opd->opdv[1], false)) != 0xFFFF) { + else if(cmdl->opd->opdc == 2 && (x_r2 = getgr(cmdl->opd->opdv[1], false)) != 0xFFFF) { if((cmd = getcmdcode(cmdl->cmd, R1_R2)) == 0xFFFF) { setcerr(109, cmdl->cmd); /* not command of operand "r1,r2" */ return false; } - cmd |= ((r1 << 4) | r2); - if(cerr->num == 0 && writememory(cmd, (asptr->ptr)++, pass) == true) { - status = true; - } + cmd |= ((r_r1 << 4) | x_r2); /* 第1オペランド、第2オペランドともに汎用レジスタ */ + /* メモリへの書き込み */ + writememory(cmd, (asptr->ptr)++, pass); } - /* オペランド数2または3。第2オペランドはアドレス、 */ - /* 第3オペランドは指標レジスタとして用いる汎用レジスタ */ + /* オペランド数2または3 */ else if(cmdl->opd->opdc == 2 || cmdl->opd->opdc == 3) { if((cmd = getcmdcode(cmdl->cmd, R_ADR_X)) == 0xFFFF) { setcerr(110, cmdl->cmd); /* not command of operand "r,adr[,x]" */ return false; } - cmd |= (r1 << 4); - /* オペランド数3 */ - if(cmdl->opd->opdc == 3) { - if((x = getgr(cmdl->opd->opdv[2], true)) == 0xFFFF) { + cmd |= (r_r1 << 4); /* 第1オペランドは汎用レジスタ */ + /* オペランド数3の場合 */ + if(cmdl->opd->opdc == 3) { /* 第3オペランドは指標レジスタとして用いる汎用レジスタ */ + if((x_r2 = getgr(cmdl->opd->opdv[2], true)) == 0xFFFF) { setcerr(125, cmdl->cmd); /* not GR in operand x */ return false; } - cmd |= x; + cmd |= x_r2; } - adr = getadr(asptr->prog, cmdl->opd->opdv[1], pass); + adr = getadr(asptr->prog, cmdl->opd->opdv[1], pass); /* 第2オペランドはアドレス */ + /* メモリへの書き込み */ writememory(cmd, (asptr->ptr)++, pass); writememory(adr, (asptr->ptr)++, pass); - if(cerr->num == 0) { - status = true; - } } else { setcerr(113, cmdl->cmd); /* operand too many in COMET II command */ return false; @@ -424,13 +405,13 @@ bool cometcmd(const CMDLINE *cmdl, PASS pass) setcerr(111, cmdl->cmd); /* not command of operand "adr[,x]" */ return false; } - /* オペランド数2の場合、第2オペランドは指標レジスタとして用いる汎用レジスタ */ - if(cmdl->opd->opdc == 2) { - x = getgr(cmdl->opd->opdv[1], true); + /* オペランド数2の場合 */ + if(cmdl->opd->opdc == 2) { /* 第2オペランドは指標レジスタとして用いる汎用レジスタ */ + x_r2 = getgr(cmdl->opd->opdv[1], true); if(cerr->num > 0) { return false; } - cmd |= x; + cmd |= x_r2; } /* CALLの場合はプログラムの入口名を表すラベルを取得 */ /* CALL以外の命令の場合と、プログラムの入口名を取得できない場合は、 */ @@ -441,34 +422,27 @@ bool cometcmd(const CMDLINE *cmdl, PASS pass) if(cmd != 0x8000 || (pass == SECOND && adr == 0xFFFF)) { adr = getadr(asptr->prog, cmdl->opd->opdv[0], pass); } + /* メモリへの書き込み */ writememory(cmd, (asptr->ptr)++, pass); writememory(adr, (asptr->ptr)++, pass); - if(cerr->num == 0) { - status = true; - } } - return status; + return (cerr->num == 0) ? true : false; } /** * COMET IIのメモリにアドレス値を書き込む */ -bool writememory(WORD word, WORD adr, PASS pass) +void writememory(WORD word, WORD adr, PASS pass) { - bool status = false; - - /* COMET IIメモリオーバーの場合 */ + /* COMET IIメモリオーバーの場合、エラー発生 */ if(adr >= sys->memsize) { setcerr(119, word2n(adr)); /* out of COMET II memory */ + return; } - if(cerr->num == 0) { - (sys->memory)[adr] = word; - if(pass == SECOND && asmode.asdetail == true) { - fprintf(stdout, "\t#%04X\t#%04X\n", adr, word); - } - status = true; + (sys->memory)[adr] = word; + if(pass == SECOND && asmode.asdetail == true) { + fprintf(stdout, "\t#%04X\t#%04X\n", adr, word); } - return status; } /** @@ -529,32 +503,18 @@ void writeDC(const char *str, PASS pass) */ bool assembletok(const CMDLINE *cmdl, PASS pass) { - bool status = false; - /* 命令がない場合 */ if(cmdl->cmd == NULL){ - ; - } - /* アセンブラ命令の処理 */ - else if(cerr->num == 0 && assemblecmd(cmdl, pass) == true) { - ; - } - /* マクロ命令の書込 */ - else if(cerr->num == 0 && macrocmd(cmdl, pass) == true) { - ; - } - /* 機械語命令の書込 */ - else if(cerr->num == 0 && cometcmd(cmdl, pass) == true) { - ; - } - else if(cerr->num == 0) { - setcerr(113, cmdl->cmd); /* operand too many in COMET II command */ + return true; } - /* エラーが発生していないか確認 */ - if(cerr->num == 0) { - status = true; + /* アセンブラ命令またはマクロ命令の書込 */ + if(assemblecmd(cmdl, pass) == false && macrocmd(cmdl, pass) == false) { + /* COMET II命令の書込 */ + if(cometcmd(cmdl, pass) == false && cerr->num == 0) { + setcerr(113, cmdl->cmd); /* operand too many in COMET II command */ + } } - return status; + return (cerr->num == 0) ? true : false; } /** @@ -590,22 +550,23 @@ WORD getadr(const char *prog, const char *str, PASS pass) /** * 1行をアセンブル + * passが1の場合はラベルを登録し、2の場合はラベルからアドレスを読み込む */ bool assembleline(const char *line, PASS pass) { CMDLINE *cmdl; - bool status = true; + bool stat = true; int i; cmdl = linetok(line); - status = (cerr->num == 0) ? true : false; + stat = (cerr->num == 0) ? true : false; if(cmdl != NULL) { - if(status == true) { + if(stat == true) { if(pass == FIRST && cmdl->label != NULL) { - status = addlabel(asptr->prog, cmdl->label, asptr->ptr); + stat = addlabel(asptr->prog, cmdl->label, asptr->ptr); } - if(status == true) { - status = assembletok(cmdl, pass); + if(stat == true) { + stat = assembletok(cmdl, pass); } FREE(cmdl->label); } @@ -618,7 +579,7 @@ bool assembleline(const char *line, PASS pass) FREE(cmdl->cmd); } FREE(cmdl); - return status; + return stat; } /** @@ -634,25 +595,20 @@ void addcerrlist_assemble() /** * 指定された名前のファイルをアセンブル - * 2回実行される + * アセンブル完了時はtrue、エラー発生時はfalseを返す */ -void assemble(const char *file, PASS pass) +bool assemblefile(const char *file, PASS pass) { - int lineno = 0; - bool status = true; - char *line = malloc_chk(LINESIZE + 1, "assemble.line"); + int lineno = 1; + char *line; FILE *fp; if((fp = fopen(file, "r")) == NULL) { perror(file); - setcerr(127, NULL); - return; + return false; } - while(fgets(line, LINESIZE, fp)) { - lineno++; - if((pass == FIRST && asmode.src == true) || - (pass == SECOND && asmode.asdetail == true)) - { + for(line = malloc_chk(LINESIZE + 1, "assemble.line"); fgets(line, LINESIZE, fp); lineno++) { + if((pass == FIRST && asmode.src == true) || (pass == SECOND && asmode.asdetail == true)) { printline(stdout, file, lineno, line); } if(assembleline(line, pass) == false) { @@ -662,10 +618,10 @@ void assemble(const char *file, PASS pass) if(cerr->num > 0) { fprintf(stderr, "Assemble error - %d: %s\n", cerr->num, cerr->msg); printline(stderr, file, lineno, line); - status = false; } FREE(line); fclose(fp); + return (cerr->num == 0) ? true : false; } /**