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);
これでとりあえず正常に動くようになった。
ただ他にもいろいろ問題がありそう。コンパイラの勉強をするにはこのソフトは微妙かなあ。
※コメント投稿者のブログIDはブログ作成者のみに通知されます