2024年4月14日日曜日

6800用TL/1コンパイラの6809マイコンへの移植がようやく完了

 

 6800用のTL/1コンパイラの自作6809ボードへの移植がようやく完了しました


時代錯誤ではありますが、折を見ながら昔のマイコン時代に使用していた6800用TL/1言語を6809に移植する試みを続けていまして、今までに1回報告しています。

・2021年5月9日のブログ「6809ボードマイコンにTL/1コンパイラを移植する」
https://flexonsbd.blogspot.com/2021/05/6809tl1.html

その報告ではバグの原因であるインデックス命令をアキュムレータオフセット命令で置き替えることでバグを解消できたと書きました。

その記述がこれです。
===== ここから =====

バグの原因は、STA n,Xというインデックス命令でした。6800ではnは8ビット範囲であるのに対して、6809ではnが0~7Fの範囲では5ビット命令となるのです。TL/1ではSTA n,Xのnを動作中に書き換えるというコードを多用していますが、例えばnを0から1ずつ増やしていくと15までは正値ですが、その次は負値の-16になってしまうのです。

6809ではアキュムレータオフセット命令がありますので、

  6800での命令        →  6809での命令

  (2命令で計5バイト)       (1命令で2バイト)

  STB xxxx  (xxxxはnのアドレス)   STA B,X

  STA n,X

という計5バイトの命令を2バイト命令に置き換えることができ、これでバグを解消できました。

===== ここまで =====

しかしもちろん、上記のようなAccBの値を使うインデックス命令の他にも通常のインデックス命令も多用されており、それらを単純にSTA n,X (A7 n) やLDA n,X (A6 n)などで置き換えてもnの値が15を超えると異常動作をすることになってしまいます。
ということで、これらの命令をA7 88 nやA6 88 nという8ビットオフセット命令に置き換えなければなりません。
ソースを検索すると$A7は直値で書かれている箇所が見つかりますが、$A6は見つかりません。にもかかわらず生成コード中にはA6 nという命令が作られているのです。
この原因を掴むのに数週間を要しましたが(他の方の作られたアセンブラソースはなかなか理解できない...)ようやく、AccAに直値で$86を入れておいてそれに$20を加えて$A6にしている箇所を見つけ、それをA6 88 nに書き換えることでバグを解消することができました。
他にもCMP, ADD, SUBなどのインデックスモード命令も直値として記述されていないので該当箇所を見つけるためにソースプログラムを何度も読むことになりましたが、最後まで見つけにくかったのがインデックスモード命令ではないABA($1B)命令でこれもPSHS B($34 $04); ADDA ,S+($AB $E0)の4バイト命令に書き換える必要がありました。
前回の報告ではASSIST09のステップ動作を利用して不具合の原因を掴むことができましたが、上記のようなバグの原因はこれでは掴めず、コンパイル結果を書き出して逆アセンブルし、そのリストを正常に動作することが分かっている6800用TL/1の結果と比較するという手間のかかる手順を何度も何度も繰り返すことで、何とかバグを解消することができました。

これらによるバグは雑誌に掲載されていたサンプルプログラムの8QUEENやMIYAMAでは現れることはなく、移植が完了したと思い込んで、試しに作成しようとしたメモリダンププログラム(MDUMP)で現れました。MDUMPでは通常の変数の他に複数の配列を使用しましたが、その配列の要素を一つ目の変数の先頭に置かれたポインタ(グローバルポインタGBやローカルポインタLB)からのオフセットで指示しますので、変数や配列の数が多くなって15までのオフセットで収まらなくなってバグが現れたというわけです。


使用した6802/6809デュアルボード
(ブログの画像表示のために入れてあります)


MDUMPも正常に動作しましたし、現在のところ不具合は見つかっていませんので移植は完了したものと考えています。
そもそも移植の目的が6800用TL/1のソースの最小限の変更で6809用のソースを得ることでしたが、単なる6800命令の6809命令への置き換えだけでは済まなかったために、結構変更箇所が多くなってしまいました。最小限の変更ということで高速化や機能拡張などとは全く無縁ですし、また、メモリ配置もほとんど変更していません。
(オリジナルの6800用TL/1のソースも同梱しておきますので、比較していただけると変更箇所が分かります。)

メモリ配置を示します。

メモリ配置図


左図のように、オリジナルの6800用TL/1ではコンパイラ本体を$1000からに置き、ソースプログラムを$3000からに入れてコンパイルし、その結果を$216Bからに生成するようになっていますので、公開する6809TL/1でもほとんど同じ配置にしてありますが、これらはもちろん変更可能で、その場合はソースの先頭のアドレス設定(RUNBEG、SRCB、START)で変更します。変更した例が右図です。なお、いずれの場合もGAMEインタプリタはTL/1の動作には無関係ですので、ソースをGAMEで作成する場合以外は不要です。

私の場合のプログラム作成・コンパイル・実行手順を次に示します。


プログラム作成・コンパイル・実行手順


慣れてしまえばGAMEインタプリタの行編集機能で修正するよりも楽ですし、Windows上にソースが必ず保存されることになるので、TL/1を使用する場合にはGAMEを使うことはありません。

参考までに、私が作成しましたメモリダンププログラム(MDUMP.TL1)を示します。


見ていただくとお分かりのように、複数の配列に加えて手続き(PROCEDURE)や関数(FUNCTION)も使用しており、当然ですが正常に使用できています。

この2か月ほどの間、GAMEインタプリタ・コンパイラの移植とTL/1コンパイラの移植にほとんどかかりきりになってしまいました。他の方から見ると、今時何を無意味なことに時間をかけているのかと不思議に思われることでしょうが、目的は6809用のコンパイラを自作することで、そのための実装に関する知識を得ることでした。今回の経験をぜひコンパイラ作成に生かしたいと考えているのですが。。。

作成したTL/1コンパイラのソースやサンプルプログラム(8QUEEN、MIYAMA、MDUMP)、使用したツール類(CvtTxtTl1Src.exe、CvtMotHexBin.exe)などをOneDriveに上げておきます。なお、私は自作モニタで使用していますが、ASSIST09上で動作させる場合の変更点も記してあります。

0 件のコメント:

コメントを投稿