石原 博の覚書

電子工作に関する日々の覚書を記載します

PPC

2021-07-17 22:09:08 | 日記

CP/Mが動くハードが何種類も出来たが、それだけでは面白くない。

有り難いことに、インターネット上に様々なソフトがある。
そこでいくつかダウンロードして動かしてみた。

CPMUG50

PPCはパスカルコンパイラ。整数しか扱えない、文法的に制約があるなど癖がある。(PPC.DOCに標準pascalとの差の記載あり)。

PPC.DOCにも記載はあるが、
・マイナスの数が使えない。(const x=-1; は不可)
・charタイプはない。(8charが入る alfaがある)
・ファイルタイプはない(入出力にはget#0, put#1等がある)
・レコードはない
・ランタイム(RTP.ASM)の中の掛け算や割り算が遅い
 (gagと記載されているが、出来るだけ単純にするため足し算や引き算の繰り返しで実現)

このため、CP/MでTurboPascalが使える今、使い勝手はあまり良くない。しかしセルフコンパイル出来るソースが含まれるという点で面白い。
特にコンパイラを変更した場合に、問題がないか確認するvaidate.subが含まれており、色々な実験を行なうことが容易に出来る。

セルフコンパイルすると成功する。
>submit validate
......
COMPARE.COM 1/8/78
FILES MATCH, LENGTH IS   6912  BYTES


ところが付属のTESTER.PASをコンパイルするとエラーになる。
(付属しているサンプルがコンパイル出来ないとはどういうこと?)
>SUBMIT PC TESTER

 if (a<>'abcd56gh') or (a[2]<>>>129<<'5'+>>129<<'6'*>>129<<256)>>129<< then
********

エラーコード を調べて見ると、129はタイプエラー


わからないままに、PPC.PASを修正
(A or B で、AのタイプとBのタイプが一致していないとエラー。
 根本的にどうすれば良いかわからないので、Bコンパイル前にタイプを初期化。これだと具合が悪いことが起きそうだけど、とりあえずの処理)

$ git diff PPC.PAS
diff --git a/PPC.PAS b/PPC.PAS
index cc973cc..aa2ab5f 100644
--- a/PPC.PAS
+++ b/PPC.PAS
@@ -652,7 +652,7 @@ procedure block(lev, plab: word);
                                if sym=andsym then
                                        gen(pshf,0,0);
                                mulop:=sym;
-                               getsym; factor;
+                               getsym; etyp:=dontcare; factor;
                                if mulop=times then gen(opr,0,4)
                                else if mulop=slash then gen(opr,0,5)
                                else gen(opr,0,15)
@@ -669,7 +669,7 @@ procedure block(lev, plab: word);
                                (sym=orsym) do begin
                                if sym=orsym then
                                        gen(pshf,0,0);
-                               addop:=sym; getsym; term;
+                               addop:=sym; getsym; etyp:=dontcare; term;
                                if addop=plus then gen(opr,0,2)
                                else if addop=minus then gen(opr,0,3)
                                else gen(opr,0,14)


本当にこれで大丈夫なのか不安というものの、とりあえずコンパイルエラーは回避出来た。
ところが実行結果がおかしい(どうも or や and で文字列の比較があると変)

そこでPFETのソースを読むと納得出来ないところが。。
flagtoaでフラグをAregに反映させるところでzフラグの反映がおかしい。
(andやorの場合、flagtoa, push pswで保存して、flagtoa, pop d, and(またはor) d で論理計算しているため、このルーチンを使う)

おかしい
-----------------
ifnz: ADI 255
 CMC
 SBB A

ifz: ADI 255
 SBB A

修正後
------------------
ifnz: MVI A,0
 JNZ $+4
 DCR A

ifz: MVI A,0
 JZ $+4
 DCR A

 

$ git diff PFET.PAS
diff --git a/PFET.PAS b/PFET.PAS
index 46a0ba9..ed8f6cd 100644
--- a/PFET.PAS
+++ b/PFET.PAS
@@ -221,10 +221,12 @@ procedure flagtoa;
        begin
        case lfl of
        ifnz:   begin
-               co4b(adi, 255, cmc, sbba)
+               co2b(mvia, 0);
+               coopad(jnz,coa+4); co1b(dcra)
                end; (* ifnz *)
        ifz:    begin
-               co3b(adi, 255, sbba)
+               co2b(mvia, 0);
+               coopad(jz,coa+4); co1b(dcra)
                end; (* ifz *)
        ifcz:   begin
                co2b(mvia, 0);

これでとりあえず正常に動くようになった。

ただ他にもいろいろ問題がありそう。コンパイラの勉強をするにはこのソフトは微妙かなあ。