2015.2.21

前へ
次へ
ホームページトップへ戻る

MYCPU80でCP/Mを!
超巨大基板の8080互換HCMOS・CPUでCP/Mを走らせてしまおうという、なんとも狂気なプロジェクトです!


[第137回]


●BTKおよびBINファイル作成プログラム(3)

前回の続きです。

さて、プログラムがおかしいときは、デバッグ用のステートメントを挿入してみるとよろしい。
前回お見せしたプログラムにprintf文を2行挿入してみました。

                c=fgetc(htxfp);
                printf("%02X,",c);//test
                if(c==EOF)break;
                H=c;
                i++;
                c=fgetc(htxfp);
                printf("%02X,",c);//test
                if(c==EOF)break;

で、それをコンパイルして、実行してみましたら。



確かにおかしいじゃありませんか。
本来はあるはずの0Aの前の0Dがどういうわけか消えております。
そこに0Dがあるということは、前回実行したDEBUGコマンドでちゃんと確かめております。

あ。
余談でありますが。
最後に表示されておりますFFFFFFFFはファイルエンドマークです。
fgetc()はファイルエンドを見つけると−1を返します。
FFFFFFFFは−1です。
そしてEOFは−1です。

それはそれとしまして。
なぜかfgetc()が0Dを読み飛ばしてしまうらしいことがわかりました。
それはfgetc()の問題なのか?
いや、それは余りにおかしい。
そんなことがあったら、fgetc()は使いものになりませぬ。

まてよ。
以前に確かどこかで、何か読んだような…。
0D0AはCRLFなんだけど、0Dは¥rで0Aは¥n…。
ならば0D0Aは¥r¥nなんだけど、ふつうC++では改行は¥nだけを書く…。
じゃあ0Dは無視される…?

おお。
ひょっとしたら…!

ビンゴでありました。
実は、前回お見せしたプログラムリストは、以前に作ったファイルから文字列を読み込んでそれを変換するプログラムをもとにして、それを書き換えたものでしたので。

        htxfp=fopen(htxfname,"r");
        if(!htxfp){printf("%s cannot open\n",htxfname);return;}
        btkfp=fopen(btkfname,"wb");
        if(!btkfp){printf("%s cannot open\n",btkfname);fclose(htxfp);return;}
        binfp=fopen(binfname,"wb");
        if(!binfp){printf("%s cannot open\n",binfname);fclose(htxfp);fclose(btkfp);return;}

ついうっかりして、入力ファイルを”r”でopenしてしまっておりました。
これはテキストファイルに対する指定です。
確かに今回の入力ファイルはHTXなので、その実体はテキストファイルですから間違いではないのですけれど、fgetc()を使って1バイトずつ読み込んで、それを最終的にはバイナリに変換しているのですから、ここはバイナリファイルとして扱うべきでありましょう。
もちろん私の頭のなかではこのときの入力ファイルはテキストファイルなんだけれどバイナリファイルなのだ、という認識でありました。

そういうことですと、ここは
htxfp=fopen(htxfname,”rb”)
でなければいけないことになります。

そこで、そのように書き換えて再度実行してみましたら。

おお。
今度は期待通り0Dも読み込んでくれました。

どうやら(おそらくWindowsの場合には)テキストファイルとしてオープンすると、0Dコードは読み飛ばしてしまうようです(まったく余計なことを…)。

そういうことで、疑問は解消しましたが、このままでは0D0Aコードを読み込むと変換エラーが表示されてしまいますから(しかし出力ファイルは正しく作られます)、0D0Aに対する処理も書き加えて、最終的には下のプログラムとして仕上げました。

 // translate from htx to btx & bin
//15/2/17 2/19
//
#include <stdio.h>
#include <string.h>
        FILE *htxfp;
        FILE *btkfp;
        FILE *binfp;
        char htxfname[50];
        char btkfname[50];
        char binfname[50];
        int n;
        int c;
        int i;
        int j;
        int k;
        int H;
        int L;
        int x;
//
        int hextobin();
//
void main(){
        printf("infilename=");
        gets(htxfname);
        n=strlen(htxfname);
        i=0;
        while(i<n){
                btkfname[i]=htxfname[i];
                binfname[i]=htxfname[i];
                if(htxfname[i]==0x2e)break;
                i++;
                }
        if(i==n){
                strcat(htxfname,".htx");
                strcat(btkfname,".btk");
                strcat(binfname,".bin");
                }
        else{
                strcat(btkfname,"btk");
                strcat(binfname,"bin");
                }
        printf("infile=%s\n",htxfname);
        printf("outfile1=%s\n",btkfname);
        printf("outfile2=%s\n",binfname);
        htxfp=fopen(htxfname,"rb");
        if(!htxfp){printf("%s cannot open\n",htxfname);return;}
        btkfp=fopen(btkfname,"wb");
        if(!btkfp){printf("%s cannot open\n",btkfname);fclose(htxfp);return;}
        binfp=fopen(binfname,"wb");
        if(!binfp){printf("%s cannot open\n",binfname);fclose(htxfp);fclose(btkfp);return;}
//
        printf("start to convert\n");
        i=0;
        j=0;
        k=0;
        while(1){
                c=fgetc(htxfp);
                //printf("%02X,",c);//test
                if(c==0x0d||c==0x0a)continue;
                if(c==EOF)break;
                H=c;
                i++;
                //printf("%d,",i);//test
                c=fgetc(htxfp);
                //printf("%02X,",c);//test
                if(c==EOF)break;
                i++;
                //printf("%d,",i);//test
                L=c;
                if(!hextobin()){printf("\n***error! not HTX\n\n");break;};
                //printf("%02X\n",x);//test
                fputc(x,btkfp);
                j++;
                if(j>4){fputc(x,binfp);k++;}
                }
        fclose(htxfp);
        fclose(btkfp);
        fclose(binfp);
        if(i==0)printf("\n***error! file is empty\n\n");
        printf("%s=%dbytes\n",htxfname,i);
        printf("%s=%dbytes\n",btkfname,j);
        printf("%s=%dbytes\n",binfname,k);
        printf("end\n");
}
//
int hextobin(){
        if(H>=0x30 && H<=0x39)x=(H-0x30)*16;
        else if(H>=0x41 && H<=0x46)x=(H-0x37)*16;
        else return 0;
        if(L>=0x30 && L<=0x39)x=x+(L-0x30);
        else if(L>=0x41 && L<=0x46)x=x+(L-0x37);
        else return 0;
        return 1;
        }
//

MYCPU80でCP/Mを![第137回]
2015.2.21upload

前へ
次へ
ホームページトップへ戻る