ラベル 6800 の投稿を表示しています。 すべての投稿を表示
ラベル 6800 の投稿を表示しています。 すべての投稿を表示

2026年2月18日水曜日

必要に迫られて自作したツールソフトの紹介(第5回)

 最近修正したソフトなどをいくつか紹介します


[1]クロスアセンブラ

以前公開した6809用のクロスアセンブラですが、使っていただいた方からcmpa #'z+1のアセンブル結果がCMPA #'Z+1のバイナリになってしまうというご指摘を受けました。

私はソースを常に大文字で書いていたので全く気付いていませんでした。ソースが小文字の場合は大文字に変換するようにプログラムしてあったのですが、大文字にすべきでない箇所も変換してしまっていました。

ということで、それを修正したクロスアセンブラ4種を公開します。他のMPU用のものにも同様の修正を加えました。

(1)6809AsmWin.exe Ver2.5
(2)6800AsmWin.exe Ver2.3
(3)6801AsmWin.exe Ver2.0
(4)6303AsmWin.exe Ver2.0

例として6809AsmWin.exeの動作画面を示します


6809AsmWin.exe


[2]FT-245カード他を使用する通信ソフト

FM-7, FM77, FM-11機に装着されたFT245通信カード、オプションまたは標準の8251A使用のCOMカード、68B50使用の拡張COMカードの3通信経路を使用して、FM機とWindows機との間で2D, 2DD, 2HDディスクイメージを転送するソフトです。

(1)Windows側

            ft245drv.exe Ver2.5

以前のものに通信経路を追加しただけでなく、対応機種にFM-11を加え、扱えるディスクにも2HDを追加しました。

動作画面です

Windows機上でのft245drv.exe

(2)FM-7/77/11側

   F-Basicでのメインプログラムと機械語サブルーチンのセットです

        1.FT245F, FTDRV22F    FT-245カード用です
        2.FT245C, FTDRV22C    オプションカードまたは標準のCOM(8251A使用) 用です       
        3.FT245E, FTDRV22E    68B50使用のExCOMカード用です

最初は上記3つの通信経路用を一つのプログラムにまとめて、動作中に切り替えることができるように作成したのですが、それぞれ専用のプログラムの方が使い勝手が良いということで別々のプログラムも作成しました。

  4.FT245A, FTDRV22A 上記1~3を統一したプログラムです

例としてFT245Aの動作画面を示します


FM機上でのFM245A

なお、転送速度ですが

FM機からWindows機への読み込みでは、およその値で
 2Dでは1が1分、2,3が5分、2HDでは1が2分、2,3が13分20秒
Windows機からFM機への書き込みでは、およその値で
 2Dでは1が1分、2,3が5分、2HDでは1が11分30秒、2,3が13分20秒
で、現在のバージョンでは2HDの書き込みに時間がかかりすぎています。


(3)動作確認した機種、F-BASICのバージョン、メディア

        ・FM-7、FM77AV2、FM77AV40SX
        ・F-BASIC V3.0、V3.3、V3.4
        ・2D、2DD、2HDディスク

以上紹介したソフトをOneDriveに置いておきますので、使用した結果、不都合が生じても私は責任は負わないということを承知していただいたうえで自由にご使用ください。


2024年11月15日金曜日

必要に迫られて自作したツールソフト(クロスアセンブラ)の紹介(第3回)

 必要に迫られて自作したツールソフトのうちのクロスアセンブラを手直ししました

【12月24日追記】12月22日のコメントでご指摘頂いた点を修正した版を公開します。末尾のリンク先からダウンロードしてください。

4月25日のブログ「必要に迫られて自作したアセンブラ等のツールソフトの紹介(第2回)」で紹介しましたソフトのうちのクロスアセンブラのバグを修正しましたので、公開します。

修正したバグはFCB疑似命令のオペランドの解釈部です。ごく普通の書き方をしていればよいのですが、時に、式の解釈を間違えたりする場合があったのです。

例えば、10月10日のブログ「自作の6809SBCにOS-9を移植する試み(その1 SBCの製作)」にも書きましたように、assist09をアセンブルした際に誤変換が発生したのですが、それはFCBのオペランドとして「'A」と「'A'」の両方の書式に対応するように修正したために発生したバグでした。

FCB疑似命令の解釈ルーチンは6809用、6800用、6801用、6303用の全てのクロスアセンブラに共通ですので、この際、まとめて修正することにしました。

この解釈ルーチンは、最初は単純な書式のみに対応したものを作成し、必要に応じて徐々に拡張してきたものでしたが、ちょっと複雑な形のオペランドはどうしても式として解釈する必要があります。現在のものの拡張では括弧を含めた式にも対応させるのは無理と感じましたので、思い切って全面的に書き換えることとしました。

以前、ちょっとした電卓プログラム的なものを作成したことがありましたので、それを手直しして使うことにしました。式中に「$AB」のような16進数や「’C」のような文字コードが入っても大丈夫で、もちろん括弧も使えます。


修正したクロスアセンブラによる結果

6303AsmWin.exeによるアセンブル中の画面を示します。
FCB疑似命令の処理ルーチンは他のアセンブラ全てに共通ですので、全く同じ結果になります。

6303AsmWin.exeでアセンブル


テストデータとして使用したのは下記のようなコードです。

テストデータ



アセンブル結果です。

6303AsmWinによる結果


0014行はFCBのみでオペランドがありませんので当然、エラーが出ています。
その他の行では、「’A’」や「’A」のような書き方が混在していても正しく変換されています。
下から2行目はassist09からの引用ですが、「',」という書き方でも正しく変換されていますので、それを最下行のようにあえて「','」のように書き換える必要がありません。
注意点ですが、FCBのオペランドですので計算結果が$FFを超えた場合の上位桁は無視されます。

ちなみにアークピットさんのX6801では以下のような結果になりました。

X6801による結果


計算結果のオーバーフローに対してはちゃんとwarningが出ています。

書式として「'A'」のように書くことになっていますので、「'A」のような書き方では誤変換してしまうのは当然なのですが、エラーメッセージが出ないので注意が必要です。


今までは6303用や6801用のクロスアセンブラは公開していなかったのですが、先日LILBUGをアセンブルしてみて、それなりに使えることが分かりましたので、公開することにします。修正した4つのクロスアセンブラ(6809AsmWin.exe, 6800AsmWin.exe, 6801AsmWin.exe, 6303AsmWin.exe)をOneDriveに置いておきますので、使用した結果については自己責任ということを承知していただいたうえで、自由にご使用ください。

【12月24日追記】クロスアセンブラの12月24日修正版をここに置きました。


2024年4月25日木曜日

必要に迫られて自作したアセンブラ等のツールソフトの紹介(第2回)

 必要に迫られて自作したアセンブラ等のツールソフトの紹介(第2回)です


【11月15日追記】クロスアセンブラ(6809用、6800用)の修正版を11月15日のブログ「必要に迫られて自作したツールソフト(クロスアセンブラ)の紹介(第3回)」にアップしましたので、そちらの方を参照ください。また、6801用、6303用も同時に公開しました。


【5月23日追記】コメントでご指摘いただいた点を改善した6809AsmWin.exeと6800AsmWin.exeを公開しました。末尾を参照ください。


【4月30日追記】コメントでご指摘いただいた点を改善中です。かなり大幅に書き換えましたので、他の箇所でバグが発生していないかチェック中です。チェックが済みましたら改めて、6809AsmWin.exeと6800AsmWin.exeを公開する予定です。


2021年9月1日のブログ「必要に迫られて自作したアセンブラ等のツールソフトの紹介」https://www.blogger.com/blog/post/edit/1662007451717538019/137356729684879777

で私が日常使用しているいくつかの自作ソフトを紹介して公開しましたが、その後、必要に応じて修正を重ねてきましたので、ここで改めて最新のバージョンを紹介することにしました。

紹介するものはほぼ前回と同じです。

(1)クロスアセンブラ

 ・6809クロスアセンブラ 6809AsmWin.exe  

 ・6800クロスアセンブラ 6800AsmWin.exe 

クロスアセンブラの主な修正点はFCB疑似命令のオペランド処理の改善です。

「'A',-'B'」や「'A,-'B」のような両書式に対応しました。また、カンマ「,」やスペース「 」もそのまま「','」や「',」の形で使用できます。ただし、文末にカンマやスペースが来る場合は誤変換が生じる場合がありますので、「','」のように閉じの「'」をつける必要があります。


(2)クロス逆アセンブラ

 ・6809クロス逆アセンブラ 6809DasmWin.exe

 ・6800クロス逆アセンブラ 6800DasmWin.exe

逆アセンブラの修正点は、データ部をスキップさせる場合の範囲指定処理の改善です。


(3)転送ツール

 転送ツールとして良く使用するのは仮想ドライブ構築ソフトです。それぞれのDOS(?)に合わせて4種類制作しています。

 ・Flex9用のFlexDrvWin.exe

 ・OS-9用のOS9DrvWin.exe

 ・F-BASIC3.0用のFBasDrvWin.exe

 ・CP/M-80用のCpmDrvWin.exe

主な修正点は、扱えるファイル書式を.D77、.DSKに加えて、各セクタの先頭に16バイトのセクタデータを付加した.DAT形式に対応したことと、パソコンとの通信にRS232Cに加えてFT245高速通信カードに対応したことです。


(4)ツールソフト

 ・CnvTxtTl1Src.exe

  Windows機で作成したTL/1やGAMEのプログラムをTL/1形式やGAME形式に変換するソフト

 ・CvtMotHexBin.exe

  バイナリファイルをBin, Hex, Mot形式に変換するソフト

 ・CvtDskD77.exe

  フロッピィディスクイメージの形式を変換するソフト 


その他として、

(5)FT245高速通信カードを用いたFM-7とWindows機との間の高速通信ソフト

 ・ディスクコピープログラム(F-BASIC3.0用、OS-9用、FLEX用、CP/M用)

 ・ファイルコピープログラム(F-BASIC3.0用、OS-9用、FLEX用、CP/M用)

がありますが、その都度ブログで報告していますのでそれらをご参照ください。


各ソフトを画像で紹介しておきます。

(1)クロスアセンブラ

アセンブルしたいファイルを「ファイル名」ボックスにドラッグ&ドロップして「アセンブル実行」ボタンを押します。


6809AsmWin.exe


6800AsmWin.exe


(2)クロス逆アセンブラ

アセンブルしたいバイナリファイルを「ファイル名」ボックスにドラッグ&ドロップし、「オプション」メニュー中の「オフセット指定」でスタートアドレスを設定してから「逆アセンブル実行」ボタンを押します。

バイナリファイル中にデータ範囲があるようなら、その範囲を推定して「オプション」メニュー中の「スキップ範囲追加」で設定します。


6809DisAsmWin.exe



6800DisAsmWin.exe


(3)仮想ドライブ構築ソフト

 ドライブ0~3にディスクイメージファイルをドラッグ&ドロップすればその内容が左下のボックス中に一覧表示されます。イメージファイル形式ですがD77(D88)形式だけでなくDSK形式(単純にセクタデータを順番に並べたもの)やDAT形式(各セクタの先頭に16バイトのセクタ情報が付いた形式)も読み込めます。
左下のボックスにファイルをドラッグ&ドロップすればイメージファイル中に書き込まれます。ボックス中のファイルをマウスの左ボタンで選択して右ボタンでメニューを表示させることで、「読み出し」、「削除」、「名称変更」ができます。また、イメージファイル中の全ファイルを一気に読みだす場合はメニューの「編集」→「全ファイル読み出し」を用います。



FbasDrvWin.exe

 

Os9DrvWin.exe



CpmDrvWin.exe



FlexDrvWin.exe


FlexDrvWin.exeの例のように、FM-7等との通信を行う場合には、右のボックス中に送受信しているセクタの情報が R/W,Drv,Trk,Sctの順に表示されます。


(4)3種のツールソフト

(4-1)プログラムソースファイルをTL/1やGAME形式に変換します。

CnvTxtTl1Src.exe


(4-2)バイナリファイル変換ソフト
 Bin, Hex, Motファイル間の変換ソフトです。さらにFlex9のバイナリ形式にも変換できます。

CvtMotHexBin.exe


(4-1)ディスクイメージファイル変換ソフト
 普段はディスクイメージファイルの中を見やすいDSKファイルを使うことが多いのですが、XM7やGOTEKのためにはD77形式に変換する必要があります。今まではそれぞれのDOS用に制作したコンソールソフトを使用していたのですが、不便なので全DOSに対応したフォームソフトを制作しました。トラック数が40か80かは自動判別しますのでどちらでも使えます。

CvtDskD77.exe


これらをまとめてOneDriveに上げておきますので、もし使用されてみて動作がおかしいということがありましたらご一報いただけると有難いです。

(前回もこのような文を書いておきましたが、特に連絡をいただけることはありませんでしたので、恐らく使用されてみた方はいらっしゃらないのだとは思いますが、自分自身の試みの記録を兼ねてブログにアップしました。)


【5月23日追記】コメントでご指摘いただいた点を改善した6809AsmWin.exeと6800AsmWin.exeをOneDriveに公開しました。改善点などを記述した文書も添付してあります。


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上で動作させる場合の変更点も記してあります。


2024年3月24日日曜日

6800用GAMEインタプリタとコンパイラの6809への移植がようやく完成

 6800用のGAMEインタプリタとコンパイラの6809への移植がようやく完成しました

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

・2021年5月19日のブログ「6800用のGAMEインタプリタとコンパイラを6809に移植」https://www.blogger.com/blog/post/edit/1662007451717538019/285975797531168690

・2019年5月8日のブログ「6802基板でGAME68コンパイラを走らせる」https://www.blogger.com/blog/post/edit/1662007451717538019/2314144451913456377

できる限りオリジナルから改変せずに自作の6802/6809両用カードにインタプリタとコンパイラを移植することを目指したので、既に他の方々が実践されているような高速化・高機能化とは無縁ですが、移植過程の経験とソースを得られることが目標でした。

上記2回の報告では、とりあえず動作したというレベルでしたので、何とか完成させたいと折を見ながら取り組んできましたが、ようやく完成と言ってもよいものができあがりましたので紹介するとともに作成したファイルを公開します。


作成に使用した自作マイコンですが、以前のブログで紹介したものと同じ6802/6809両用カードを使用しています。(見出しに画像を表示させるために以前と同じ画像を張り付けてあります。)


6802/6809両用カード


1.GAME3インタプリタ

まずインタプリタですが、ASCII誌に連載されたオリジナルのGAME3に作者の大西氏が行編集機能を追加されたものを使用しています。

オリジナルのソースに追加する必要があるのはI/O関係の1文字入力、1文字出力、ブレーク判定ルーチンのみで、変更点はRUB,DELコード、RAM末アドレスなどですが、これらについてはソースプログラムを添付しますのでそれを見ていただければ分かると思います。


2.GAME3コンパイラ

前回のブログで紹介しましたが、ASCII誌に掲載された松島義明さんのH68/TR・TV用の「GAME68コンパイラ」を移植しました。(松島さんには申し訳ないのですが、名称をGAME3コンパイラに変更させていただきました。)

これはGAME3自身で記述されており、6809に移植しやすいということで使用しました。

基本的にはオリジナルのままで動作しますが、インタプリタ中のルーチンを使用していますので、上記のインタプリタとセットで使用します。

変更点は220行のモニタへのアドレス$F0B1と、オリジナルのままではコンパイル結果のバイナリを実行後に暴走しますので、80行の末尾にA:0)=$39を追加した2点のみです。


3.GAME9インタプリタ

6800用GAME3インタプリタを元にして、6809用GAME9インタプリタを作成するわけですが、以前のブログで報告しましたように、基本的にはソースプログラムが公開されていますのでその6800の命令を6809の命令に置き換えるだけです。

置き換えに当たってはスタックポインタをインデックスポインタとして使用している箇所や比較命令CPXを1バイトスキップに利用している箇所に注意するだけで良いはずなのですが、何と終了判定にプログラムコード中の$00を利用している箇所があり、6800と6809では命令の長さが異なるために判定位置がずれてしまうことに気づかず、最後まで悩まされました。

以上に注意しながらインタプリタのソースを書き換えた結果、正常に動作させることができました。出来上がったものは基本的にただ6800の命令を6809の命令に置き換えただけですので、他の方々が移植されたものとは速度や機能の面で劣りますが、とにかく正常に動作するソースが作成できたということで良しとします。


4.GAME9コンパイラ

続いて「GAME68コンパイラ」の移植に取り組みましたが、これも以前のブログで報告しましたが、まずランタイムルーチンのバイナリを逆アセンブルしてソースを起こし、それを6809の命令に書き換えました。

続いてコンパイラの移植ですが、まず、GAME自身で記述されているコンパイラのリスト中の、インタプリタ中のルーチンを呼んでいるアドレスを書き換え、次に、6800の命令コードを発行している箇所を見つけて6809の命令に置き換えました。 同じバイト数で置き換えられるものは単純に置き換えられるのですが、バイト数が変わる場合はそれに応じて、その周辺を書き換える必要がありました。

最後に、多少なりとも6809らしいコードを出力して欲しいということで、AccAとAccBの両方を使用している箇所をAccDに置き換える等を試みましたが、全てを置き換えることはできませんでした。

結果として作成したコンパイラですが、いくつかのサンプルプログラムを実行して正常にコンパイルできていることを確認し、最後にコンパイラ自身をコンパイルしてみました。

その結果、得られたバイナリが正常に動作しましたし、さらにそのバイナリでもう一度コンパイルしてみたところ、そのバイナリも正常に動作しました。

ただし、GAME9コンパイラ自身をコンパイルする過程では、最終行までコンパイルした後にハングアップしてしまいましたが、調べてみるとインタプリタに戻るアドレスが書き込まれていませんでしたので、手作業で該当の2個所に$0103を書き込むことで正常に動作するオブジェクトが得られました。

(この現象はGAME3でも同様でしたので、元のGAME68コンパイラに原因があるのではないかと思っていますが、コンパイルせずにそのまま使用した場合には正常に動作するので、原因については良く分かりません。)


以上により得られたファイルは次のようです。

[1]GAME3

・GAME3EX インタプリタ

・GAME3C  コンパイラ(GAME言語で書かれたもの)

・GAME3CC コンパイラオブジェクト(GAME3Cを自身でコンパイルしたもの)

・RELSUB3  コンパイラ用ランタイムルーチン($2000-212Aだが移動可能)

コンパイル結果のオブジェクトの実行開始アドレスはランタイムルーチンの先頭アドレス+$012Bです。


[2]GAME9

・GAME9EX インタプリタ

・GAME9C  コンパイラ(GAME言語で書かれたもの)

・GAME9CC コンパイラオブジェクト(GAME9Cを自身でコンパイルしたもの)

・RELSUB9 コンパイラ用ランタイムルーチン($2000-2106だが移動可能)

ランタイムルーチンがGAME3用よりも小さいのですが、操作を統一するためにコンパイル結果の実行開始アドレスをGAME3と同じランタイムルーチンの先頭アドレス+$012Bに揃えてあります。


メモリマップです。
もちろんソースプログラムの位置は変更可能です。
コンパイラの方は、ランタイムやコンパイル結果の配置も変更可能です。



メモリマップ

コンパイラの動作速度を知るために、参考までに、インタプリタで300行弱のコンパイラプログラムを実行(コンパイル)した場合と、コンパイル済みのオブジェクトでコンパイルした時の時間を測ってみました。

(1)GAME3

 ・インタプリタでは、パス1終了までに4分30秒、パス2終了までに10分30秒

 ・コンパイラでは、パス1終了までに約11秒、パス2終了までに約29秒

(2)GAME9

 ・インタプリタでは、パス1終了までに4分11秒、パス2終了までに9分27秒

 ・コンパイラでは、パス1終了までに約11秒、パス2終了までに約25秒

という結果でしたので、インタプリタとコンパイラの実行速度比はGAME3でおよそ22倍、GAME9でおよそ23倍となりました。

作成したGAME9インタプリタとコンパイラをGAME3のそれと一緒にOneDriveに上げておきます。(GAME3のコンパイラについては、以前のブログで公開する際に作者の了解を得てあります。)


2021年10月2日土曜日

紹介した6809/6800用クロス逆アセンブラの修正版

 6809/6800用クロス逆アセンブラを修正しました

9月1日のブログ「必要に迫られて自作したアセンブラ等のツールソフトの紹介」で紹介した自作ソフトの内のクロス逆アセンブラですが、不具合がありました。

公開したものより以前のバージョンでは、スキップ範囲で指定した部分が1バイトずつFCB疑似命令に置き換えられていたので、表示メッセージなどではそれを手作業でFCC疑似命令に置き換えていました。

例えば、スキップ範囲指定したデータが 36,38,30,39,53,59,53,54,45,4D や 0D,0A,04では
        FCB $36            FCB $0D
        FCB $38            FCB $0A
        FCB $30            FCB $04
        FCB $39
        FCB $53
        FCB $59
        FCB $53
        FCB $54
        FCB $45
        FCB $4D
となっていましたが、リストを見やすくするために、それを手作業で
        FCC /6809SYSTEM/ や FCB $0D,$0A,$04
と書き換えていました。

これを逆アセンブラ自身にさせたいということで、公開したものでは、スキップ範囲に指定したデータの先頭の値が$20~$7Fの表示可能データの場合にはFCC疑似命令に、それ以外の場合にはFCB疑似命令に置き換えるとともに複数バイト列を一つの疑似命令にまとめられるようにしました。

この置き換えが可能になるようにプログラムを書き換えたのですが、一つ忘れていたのは、結果として作成されるFCCやFCB疑似命令のオペランドの長さが不定であり、場合によってはかなり長くなることがあるということでした。特にFCB疑似命令の場合には1バイトのデータあたり4バイト必要になります。

ということで、公開したバージョンではスキップ範囲指定の範囲を大きくとりすぎるとオペランドを格納するための文字列変数のサイズを超えてしまってプログラムが落ちてしまいました。(動作テストではそれほど大きな範囲を指定していなかったので気づきませんでした... ちなみに、スキップ範囲指定は100個まで可能なので、細かく分ければこのバグを回避できます。)

今回公開する修正版では、スキップ範囲指定の入力時に長さをチェックして32バイトを超えた場合は32バイトに制限することにしました。


指定範囲が32バイトを超えている場合は


32バイトに縮小される


動作している様子を示します。FCC,FCB疑似命令のオペランドが複数バイトになっています。

まず6809版です。

6809版のLst


6800版も同様です。

6800版のLst


Asmリストはそのままアセンブラに入力することができます。画像は6800版の例ですが6809版も同様です。

6800版のAsmリスト

修正版をOneDriveに上げておきます。


2021年9月1日水曜日

必要に迫られて自作したアセンブラ等のツールソフトの紹介

 6809用のクロスアセンブラやクロス逆アセンブラなどを紹介します

【10月2日追記】6800・6809逆アセンブラの修正版を10月2日にアップしました。

私は主に6809のプログラムを作成して楽しんでいますが、その中で必要に迫られて作成したいくつかのプログラムを紹介します。

基本的にWindows上でソースを作成し、自作したクロスアセンブラでアセンブルした後、生成されたバイナリを6809SBCなどの実機に転送して実行するという手順を踏んでいますので、必要なものは

(1)クロスアセンブラ、クロス逆アセンブラ

(2)実機への転送ツール

(3)ファイル形式の変換ツール

というわけで、10年ほどのあいだに6800用と6809用ののクロスアセンブラ、クロス逆アセンブラなどを制作してきました。(その他にも必要に応じて6801用、6303用のクロスアセンブラも作りました。)

プログラムのうちのいくつかは今までのブログで紹介してきましたが、その後もあれこれと修正を加えているものがありますので、ここでまとめて紹介します。

紹介するものは

(1)アセンブラ・逆アセンブラ

 6809クロスアセンブラ 6809AsmWin.exe とクロス逆アセンブラ 6809DasmWin.exe 

 6800クロスアセンブラ 6800AsmWin.exe とクロス逆アセンブラ 6800DasmWin.exe

(2)転送ツール

 転送ツールとして良く使用するのは仮想ドライブ構築ソフトです。それぞれのDOS(?)に合わせて4種類制作しています。

 Flex9用のFlexDrvWin.exe

 OS-9用のOS9DrvWin.exe

 F-BASIC3.0用のFBasDrvWin.exe

 CP/M-80用のCpmDrvWinFT.exeとCpmDrvWinRS.exe

(3)その他のツールソフト

 フロッピィディスクイメージの形式を変換するソフトとして CvtDskD77.exe

 バイナリファイルをBin, Hex, Mot形式に変換するソフト CvtMotHexBin.exe

以上のソフトのうち、CvtMotHexBin.exe以外はすべてVC++2019でビルドしています。


各ソフトの簡単な説明を加えておきます。

(1)クロスアセンブラ

 ファイルを選択して「アセンブル実行」ボタンを押すだけですが、エラーだけを表示する機能やワーニング表示を止める機能などがあります。結果の保存形式はLST, BIN, MOT, HEXがあります。特長としてはローカルラベル機能があります。この機能を有効にすると、例えばLOOPのようなよく使われるラベルを複数箇所で宣言できます。


6809クロスアセンブラ


(2)クロス逆アセンブラ
 元ファイルとしてはBINだけでなくMOT, HEXファイルも読み込めます。右端の「スタートアドレス」はBINでは$0000ですが、MOT, HEXの場合はその先頭アドレスが表示されます。「オフセットアドレス」は、逆アセンブルする先頭アドレスを移動させる場合に用います。先頭アドレスはスタートアドレスとオフセットアドレスの和になります。
ラベルはL_1234のようなアドレスの頭に「L_」がついた形になります。
特徴と言えるのは、データエリアと推測される個所を「スキップアドレス範囲」として指定することで、その範囲がFCBまたはFCCという疑似命令として扱われることです。どちらになるかは、範囲の先頭バイトが$20~$7Fの場合にはFCCに、それ以外の場合はFCBになります。(安直な区分けですが...)
保存形式はASMとLSTですが、ASMファイルはそのままアセンブラにかけることができる形式です。


6809クロス逆アセンブラ


(3)仮想ドライブ構築ソフト
 最初に制作したFlex9用を下に示します。ドライブ0~3にディスクイメージファイルを設定すればその内容が左下のボックス中に一覧表示されます。イメージファイル形式ですがD77(D88)形式だけでなくDSK形式(単純にセクタデータを順番に並べたもの)も読み込めます。このボックスにファイルをドラッグ&ドロップすればイメージファイル中に書き込まれます。ボックス中のファイルをマウスの左ボタンで選択して右ボタンでメニューを表示させることで、「読み出し」、「削除」、「名称変更」ができます。全ファイルを一気に読みだす場合はメニューの「編集」→「全ファイル読み出し」を用います。



FlexDrvWin.exe

 
 6809SBCやFM-7等のマイコン・パソコンとの間の通信経路を用意すればマイコン・パソコンから普通のドライブと同様に読み書きできます。下図は6809SBCのFlex9から読み出している例です。モニタのFLEXコマンドでFlex9を起動し、Flex9のCATコマンドを実行しています。上図の右のボックスはSBCから送られているコマンドをR/W,Drv,Trk,Sct形式で表示しています。


6809SBCとの通信の様子


他のソフトの例として、CpmDrvWin.exeの画面を下に示します。
表示・操作面はすべて同じようですが、内部ではもちろん、それぞれのFMS(ファイルマネージメントシステム)に合わせて処理されています。


CpmDrvWin.exe


(4)ファイル形式変換ソフト
(4-1)ディスクイメージファイル変換ソフト
 普段はディスクイメージファイルの中を見やすいDSKファイルを使うことが多いのですが、XM7やGOTEKのためにはD77形式に変換する必要があります。今まではそれぞれのDOS用に制作したコンソールソフトを使用していたのですが、不便なので全DOSに対応したフォームソフトを制作しました。トラック数が40か80かは自動判別しますのでどちらでも使えます。



D77, DSK, DAT間変換ソフト


(4-2)バイナリファイル変換ソフト
 Bin, Hex, Motファイル間の変換ソフトです。さらにFlex9のバイナリ形式にも変換できます。


Bin, Hex, Mot間変換ソフト


 以上のソフトは、必要に迫られてここ10年ぐらいの間に制作したもので、特にアセンブラや逆アセンブラは標準的な構造など全く知らないのに自己流で作ったものですが、自分にとっては結構役に立っています。(たまに動作がおかしいと思った時などには他のアセンブラなどの結果と比較することがありますが、現在の版では問題がないと思っています。)

一応、6800用ではMikbug9, Mikbug20, TL1, TinyBasic(電大版)などがアセンブルできることを確認してあります。GAMEⅢでは1文字を「'」ではなく「"」で囲むという標準ではない書き方が多数ありますのでそれを修正(#”A”→#'A')する必要がありました。

6809用ではASSIST09のリストのミス(CPX→CMPX)と4箇所の#'(sp)を#'(sp)'のようにスペース後の「'」を追加することでアセンブルできました。

これらをOneDriveに上げておきますので、もし使用してみて動作がおかしいということがありましたらご一報いただけると有難いです。

【10月2日追記】6800/6809逆アセンブラの修正版を10月2日にアップしました。



2021年5月19日水曜日

6800用のGAMEインタプリタとコンパイラを6809に移植

 6800用のGAMEインタプリタだけでなく、コンパイラも移植してみました


動機

発注してあるプリント基板が未だに届かないので最近はソフトばかりいじっていますが、前回は6800用のTL1コンパイラを6809に移植することができましたので、その勢いで、今度はGAMEインタプリタとコンパイラの移植に挑戦してみました。

GAMEインタプリタの6809への移植は、既に1981年に藤原誠さんによる「GAME09インタプリタ」や、1984年の萩平哲さんによる「GAME-FMインタプリタ・コンパイラ」があり、いずれも実行速度や機能面で非常に優れたもので、私もインストールして使わせてもらっていました。しかし、いずれもソースは公開されておらずバイナリコードだけです。

移植するコンパイラは

今回移植しようと考えたものは、2019年5月8日のブログ「6802基板でGAME68コンパイラを走らせる」で紹介した「GAME68コンパイラ」で、松島義明さんがGAME自身で記述されたものです。

GAME自身で記述されているということは、コンパイラとしての論理構造は6800でも6809でも変わらず、コード生成の部分だけが異なっているということになります。

そして、生成されるコードは6800のバイナリであるわけですが、前回のTL1でも述べましたように、6809と6800のバイナリにはそれほど大きな違いはないので、異なっているものだけを書き換えるだけで済むのではないかと考えました。(安直ですね。)


コンパイラのランタイムルーチンを見ると


まず最初にランタイムルーチンを調べてみました。

GAMEインタプリタ内のルーチンを利用していることもあって、わずか300バイト足らずの小さなものですが、逆アセンブルしてみたところ、6809と異なっている命令はNOPとLDXのみでしたので、簡単に書き換えることができました。

しかし、インタプリタ内のルーチンを使用しているということは、実行時には6809版のインタプリタが必要ということになりますので、コンパイラより先にインタプリタの移植が必要だということになります...


インタプリタの移植が必要だった

ということで、まずインタプリタの移植に取り組むことになりました。

6800用インタプリタもTL1と同様にアセンブラソースが公開されていますので、TL1の時と同じようにスタック命令に注意しながら書き換えることで、それ程苦労せずに動作させることができました。(私の場合はハードもソフトも速さにはそれ程こだわらず、正常に動作すれば良しというスタンスですので、最適化などはほとんど行っていません。)


インタプリタの移植が済んだので

インタプリタの移植が済んで、コンパイラのランタイムルーチンが呼んでいるルーチンのアドレスが確定しましたので、GAME68自身で記述されているコンパイラの関係するアドレスを書き換えたものを作り、簡単なプログラムで生成されたコードを調べてみました。

すると、Xレジスタ関連の命令とPSH,PUL命令を書き換えただけで動くプログラムもあるではありませんか。

この結果に気を良くして、コンパイラのソースを読んでみた限りでは、コンパイラで生成される命令の中で、6800と6809とでコードが異なるものとしてはLDX, STX, INX, TAB, TBA, PSHA, PSHB, PULA, PULBの9種がありましたが、これらはバイト数が異なるものの、置き換えにはそれ程困難はなさそうです。しかし、それらに加えて一部にLDS, STSというスタック関係の命令も使われているようですので、これらについては注意が必要です。

[5月23日追記]訂正:LDS, STS命令は使われていませんでした。


GAME09コンパイラ(らしきもの)を作ってみた

とりあえず、スタック関係の命令はそのままにしておいて(GAMEのどの命令で使われるのかまだ分からないので...)その他の命令だけを置き換えたものを作成してみました。


動作環境の詳細

使用した6809ボードは前回と同じ6809/6802DualCPUボードです。


6809/6802 Dual CPUボード

メモリマップです。


メモリマップ

ソースプログラムの格納領域は、TL1コンパイラの場合と合わせて $3000 からにしています。

オリジナルのランタイムルーチンは $2100~$22BA ですが、その先頭に生成オブジェクトへのジャンプ命令(3バイト)を追加し、JMP $2100で実行できるようにしています。

それぞれのプログラムの読み込みですが、あらかじめMOT形式に変換しておいて、自作モニタの LコマンドやASSIST09の LOADコマンドでロードしています。

そのMOT形式への変換プログラムですが、前回のTL1コンパイラのソースの場合はエディタで行番号を付けずに作成したものを変換しましたが、GAMEのソースの場合は行番号が付いていますので、それをバイナリに変換して新たに格納アドレスを付加するように機能拡張しました。また、付加する行番号や格納するアドレスを指定できるようにもしました。


CvtTxtTl1Src.exe


コンパイルの実行手順

次のような手順でコンパイルを実行します。

1.モニタでGAME9インタプリタをロードする

       L GAME9EX

        拡張機能付きのGAME9が$0100からにロードされる

2.インタプリタを起動する(コールドスタートで)

        G 100

3.モニタに移動する

        >=$F800

4.ソースプログラムをロードする

        L (source file)

        ソースプログラムが $3000 からにロードされる

5.GAME9コンパイラとランタイムルーチンをロードする

        L GAME9CS

        ランタイムルーチンが$2100からに、コンパイラが $4000 からにロードされる

6.GAME9インタプリタに戻る(ホットスタートで)

        G 103

7.コンパイラをアクティブにする

        =$4000 (先頭アドレスのセット)

        ==          (末尾アドレスをサーチ)

8.コンパイルを実行する

        #=1


実行例

実行した例を示します。オリジナルではワークエリアなどいくつかの問い合わせに答えてからコンパイルが始まりますが、ソースプログラムの格納エリアなどを決め打ちしましたので、#=1ですぐにコンパイルが始まります。

実行例

コンパイルの終了後、GAME上で >=$2100 とすると生成されたオブジェクトが実行されます。


終わりに

まだ全ての6800命令を6809命令に書き換えてはいないのですが、いくつかのプログラムをコンパイルして正常に動作することを確認しました。

以前「GAME68コンパイラ」のブログを書いた際に、コンパイラの作者の松島義明さんから掲載の許可をいただいていますので、今回の6809へ書き換えたものも公開しても良いと思います。

今の時代にGAMEやTL1を使おうという奇特な方がおられるとは思えませんが、もしご希望があるようでしたら、書き換えられずにそのままになっているスタック関係の命令の書き換えが終了しましたら公開する予定です。変換プログラム CvtTxtTl1Src.exe についても同様です。

以上、私の単なる思い付きでやってみたことで、実用性はほとんどありませんが、巷間、6800と6809とはバイナリレベルの互換性が無いので云々という評価がありますが、全く異なっているわけではないので、違っている部分にだけ注意を払えばこんなこともできるというサンプルになれば幸いです。(と言っても、今どき、6800はおろか6809のプログラムですら化石時代の遺物みたいなものでしょうが...)


2021年5月9日日曜日

6809ボードマイコンにTL/1コンパイラを移植する


 今更ですが自作の6809SBCに、いにしえの6800用TL/1コンパイラを移植しました

TL/1コンパイラは1980年に大西博さんが制作された6800用のコンパイラで、その特徴は変数のサイズが1バイト(8ビット!)であることで、サイズも4kB余りとコンパクトなワンパスコンパイラです。大西さんがその前に制作されたGAME言語と同様、ソースが公開されていたので様々なパソコンに移植されました。私もFM-7に移植されたTL1-FM版を入力して使用していましたが、FM77に移行してからは使用することが少なくなりました。

いつかは自分なりの言語を作りたいと思っていて、あれこれ考えているのですが(考えているだけで全然進んでいない...)、1バイト変数なら比較的簡単に作れるのではないかと思い、まず6800用のTL/1を6809に移植することでコンパイラ作成に関する具体的な知識を得ようと思って始めましたが、何と一ヶ月近くもかかってしまいました。

多少なりともどなたかの参考になればと思い、ここに顛末を記しておきます。


移植の手順ですが次のように行いました。

(1)ソースプログラムの6800の命令コードを6809の命令コードに置き換える。

多くの命令は単純に置き換えることができますが、スタックの使い方が6800と6809とでは異なるので注意が必要です。特に、スタックを演算等に使用している部分は新たに書き換える必要があります。また、CPX命令($8C, $9C)を演算ではなく次命令のスキップに使用しているケースもあります。

(2)コンパイラの生成コードを6800用から6809用に置き換える。

6800と6809とではバイナリレベルでの互換性はないと言われているのですが、同じ命令コードのものが結構多くあります。異なっているものでも、LDX($DE→$9E)のようにすぐわかるものは良いのですが、同じような機能であるにもかかわらず、一部異なっているという命令があるので厄介です。(下に記述)


移植した6809ボードです。これは2018年10月15日のブログ「6809/6802両用基板が完成しました」で紹介したボードで、6809と6802をスイッチで切り替えることができます。切り替えた際、メモリはクリアされないので一方のCPUで作成したデータを他方のCPUで利用することができます。また、ACIAを2個搭載しており、一方はコンソール用で他方はデータ入出力用で、どちらも38400Baudで動作しています。



移植した6809/6802 DualBoard


具体的には、次のような手順で進めました。

準備として、オリジナルのTL/1ではGAMEで作成したソースファイルが$3000からにストアされているものとしてコンパイルしますが、毎回GAMEを起動するのは面倒ですし、行番号を付けるのも煩わしいので、Windows上のエディタでソースを作り、それをGAME形式に変換したうえでmot形式に変換するソフトCvtTxtTl1Src.exeを作成しました。機能としては、行番号の付加、その行番号のバイナリ変換、行末コードの$00への変換、ファイル末への$FFの付加、そしてmot形式への変換です。

下図のように、ファイルをドラッグ&ドロップするだけで変換結果が得られます。



CvtTxtTl1Src




作業手順


(1)自作6809SBCに搭載しているモニタのLコマンドでmot形式のソースを$3000からに読み込む。

(2)mot形式に変換した試作コンパイラを$1000からに読み込む。

(3)モニタのGコマンドで$1000から実行し、オブジェクトを生成する。

(4)生成途中でエラーが出たら、コンパイラのソースをチェックして関係ありそうな箇所を修正する。修正後(2)から繰り返す。

(5)無事にオブジェクトが生成されたら、Gコマンドで$2000から実行してみる。エラーが出たり、結果がおかしかったりしたらソースを修正して(2)から繰り返す。

(6)意図した通りの実行結果が得られたら完成。


このような手順で、変数への代入、制御構造の確認、関数や手続きのデータの受け渡しなどを順に確認していきましたが、最後まで手間取ったのは関数や手続きで2個以上のローカル変数があると動作がおかしくなるというバグでした。

使用した6809SBCは6802と6809のDualボードですので、正常に動作することが分かっている6800TL/1でオブジェクトを作成し、それと6809TL/1で作成したものとを比較しながらチェックを繰り返しましたが、例えばオリジナルのTL/1の記事中の8-QUEENのオブジェクトなどは6802と6809とで全く同等のものが作成されるようになったにもかかわらず、6802では正常に動作するのに対して6809ではハングアップしてしまいます。もちろん、ランタイムルーチンが正常に動作していることは確認してあります。

こんな状態が1~2週間ほど続き、いい加減倦んできて諦めようかと思ったりもしましたが、私のSBCには自作のモニタの他に6802にはMIKBUG2、6809にはASSIST09を搭載してありますので、TL/1の入出力をASSIST09に合うように書き換えてASSIST09に移行し、そのトレース命令を用いて、1命令実行するごとにワークエリアとオブジェクトのエリアをダンプしてチェックするという面倒な作業を繰り返すことで、ようやくバグの原因をつかむことができました。

バグの原因は、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バイト命令に置き換えることができ、これでバグを解消できました。

まだ全ての組み込み関数などのチェックを終えているわけではありませんが、現在の所は動作におかしな点は見つかっていません。

それにしても、オブジェクトコードを動作中に書き換えることでコンパクトなコードを生成できているわけですが、一方、この点でROM化できないという批判的評価があったことを思い返すと、6809特有の命令に置き換えることで図らずもこの点が解消されたのは嬉しいことでもあります。さらに、$2000からのランタイムルーチンを含めて、生成コードをポジション独立にすることができればOS-9上で動作させることも夢ではなくなるかもしれません。


この移植作業を通して、制御構造などに対するオブジェクトの生成法の理解が進みました。

しかし、ASSIST09のトレース命令はとても強力なツールですね。できれば私のモニタにも実装したいものです。

最終目標は、6809SBCにOS-9Level1をインプリメントして、その上でTL/1などの言語を走らせることですが、ほんの少しですが先に進めたような気がします。

確か、大西博さんは大学の先生で文系の方だったと思いますが、GAMEやTL/1の発想というか独創性には本当に感心します。


いつも参照している下記の2冊

・MC6809-MC6809E マイクロプロセッサ プログラミング マニュアル(Motorola)

・6809アセンブリプログラミング(末永朝雄著、サイエンス社)

に加えて、この本が大変参考になりました。特にオブジェクトの生成法の解説がTL/1の理解に役立ちました。

・Z80CPU対応 新言語オリジナルコンパイラ作成の技法(大貫広幸著、MIA社)



2019年5月8日水曜日

6802基板でGAME68コンパイラを走らせる

自作6802基板でGAME68コンパイラが動作しました


前回のブログで8080SBCでGAME80インタプリタを走らせることができたと報告しましたが、それに関連して、skyriverさんがCP/M上でGAME80コンパイラを動作させたとの連絡をいただきました。そこで、私もskyriverさんのブログを参考にしてGAME80コンパイラを走らせることができました。
中島聡さんが作られたこのGAME80コンパイラは、TK-80BSの他にもいろいろなマシンに移植されましたが、残念ながら68系にはなかなか移植されませんでした。
そんな中、ついにASCII誌1981年5月号で松島義明さんがH68用のGAME68コンパイラを発表されました。
私はGAME3を使用していたこともあり、このコンパイラを動かしたかったのですが、残念ながら当時の手作りマイコンでは動作させることはできませんでした。

しかし、現在の自作の6802基板なら可能ではないかと思い、移植してみることにしました。
現在の自作6802基板では既にGAME3が動作していますので、保存してあったASCII誌から手入力してみました。ASCII誌がない方も、作成者がブログで公開されていますので心配はありません。(後述します)

[1]必要なファイルを作成する


入力したファイルは、
・コンパイラのソース(GAME3のプログラム形式 $3E00~)
・リロケータブルサブルーチンパッケージ(バイナリ形式 $3C80~$3DAA)
・サブルーチンパッケージリロケータ(GAME3のプログラム形式 $3C00~)
の3つです。
私はこの3つを1つにまとめたファイルを作り、GAME3インタプリタと共にあらかじめ読み込ませる形で使用しています。ただし、GAME3のプログラムはメモリ中では行番号が2バイトバイナリに、行末の改行コードは$00に変換され、ファイル末には$FFが追加された形式で格納されますので、プログラムリストを予め変換しておく必要があります。
手順を下に示します。

コンパイラの作成手順

変換作業はWindows上で、Chglno.exeとCvtMotHex.exeを用いて行います。
例としてGAME3インタプリタの開発者の大西さんが用意されたサンプルであるACURVEというプログラムの処理を下に示します。


処理前のソースプログラム


Chglno.exeで変換します



処理後のソースプログラム


アドレスを指定してHEXファイルに変換して出来上がり


[2]コンパイルの手順


(1)GAME3インタプリタとGAME68CAコンパイラをメモリに読み込みます。
(2)GAME3インタプリタを起動します。
(3)ソースを読み込むアドレスを指定します。
    例 =$1500
(4)コンパイルしたいプログラムを入力します。
    手入力しても良いですが、コンパイラソースと同様に処理してあればファイル
    から読み込めます
    例 GAME3の最初の例である ACURVE
(5)コンパイラを起動します。
   最初に読み込んであるので、そのアドレス$3E00を指定するだけです。
    =$3E00 とアドレス指定して #=1 で起動します。
(6)以下はASCII誌の説明通りに進めます。
   GAME:に対しては $1500
   SUB:に対しては $2100
   STAT:に対しては$222B
   WORK:に対しては$1900
   STAC:に対しては$2080
   と入力するとコンパイルが始まります。
(7)サブルーチンを$2100からに移動します。
   =$3C00 とアドレス指定して #=1 で起動します。

[3]コンパイルしたマシン語を実行する


先頭の$2100 からがサブルーチンパッケージで、実行開始アドレスは $222B
   ですのでGAMEのダイレクトモードで >=$222B で実行できます。

ちょっと見苦しいですが、画面のテキストのコピーを下に示します。



+++OLOAD GAME3.CMD     FLEXに保存してあるファイルをメモリに
+++OLOAD GAME68CA.BIN   読み込んで
+++OLOAD ACURVE.BIN
+++

M6800 MONITOR Ver6.1     いったんモニタに戻って

>G 103             GAME3を起動(ソースが既にメモリ中にあるのでホットスタート)

*READY

:=$1500            コンパイルするプログラムのアドレスに

*READY            変更すると

:0               確かにソースが読み込まれている

   70***************************
   80*    A CURVE
   90***************************
  100 X=7 Y=0 Z=2
  110 Y=Y+Z X=X+Y
  120 ;=+Y=6 Z=-Z
  130 J=1,32
  140 $=(J=X*"*")+(J<>X*".")
  150 @=J+1 / #=110
  160**************************

*READY

:=$3E00            コンパイラのアドレスに変更して

*READY

:#=1              コンパイラを起動する

GAME:$1500          (入力)

48 BYT (10LINE)

SUB :$2100          (入力)

 END 222A

STAT:$222B          (入力)

WORK:$1900         (入力)

STAC:$2080          (入力) コンパイルが始まる

   70     222B     1500
   80     222B     151E
   90     222B     152D
  100     222B     154B
  110     223F     155A
  120     2257     1569
  130     2277     1578
  140     2287     1582
  150     22BC     159C
  160     22DC     15AD
   70     222B     1500
   80     222B     151E
   90     222B     152D
  100     222B     154B
  110     223F     155A
  120     2257     1569
2277
  130     2277     1578
  140     2287     1582
  150     22BC     159C
223F
  160     22DC     15AD
 SIZE: 177(222B-22DB)

END             正常に終了

*READY

:=$3C00           サブルーチン移動プログラムのアドレスに変更して

*READY

:#=1             実行 (資料ではここでアドレスを入力することに

                    なっているが、問い合わせてこない)

*READY            これでコンパイル&サブルーチン移動が完了

:>=$222B          できたマシン語を実行

........*.......................
............*...................
..................*.............
......................*.........
........................*.......
........................*.......
......................*.........
..................*.............
............*...................
........*.......................
......*.........................
......*.........................
........*.......................
............*...................

----------------------------------- 以上 -------------------------------------------

[4]終わりに


説明不足で良く分からないところがあったと思いますが、心配ありません。
何と、GAME68コンパイラを開発された方が、ブログで資料を公開されています。
詳しくはそちらを参照ください。
開発された方は、このコンパイラを仕事にも使われていたとのこと、スゴイです。

なお、開発された方が許可してくださいましたので、私が誌面から入力したコンパイラソース等のリストをOneDriveに公開いたします。入力ミスは多分ないと思いますので、どうぞご利用ください。また、使用したツールソフト(Chglno.exe, CvtMotHexBin.exe)も同梱しておきます。

2018年7月6日金曜日

FLEXシステムの作成方法(その3)・・・6800FLEXの場合

FLEXシステムの作成方法(その3)・・・6800FLEXの場合


6月27日に6809FLEXシステムの作成方法を説明しましたので、今回は6800用FLEXシステムの作成方法を説明します。

今更、誰が6800FLEXなんか使うんだという声もあるとは思いますが、マイコン初期の頃にVTL, TinyBasic, GAMEⅢ, TL1などのアマチュア的な言語に夢中になった思い出がある方もおられると思います。私もそうでした。
それらの言語を動かすためには、やはり、OSがあると何かと便利です。
(ディスクに保存しておいて起動して走らせるだけなら、WindowsパソコンにMOT形式で保存しておいて、MonitorのLoad, Saveコマンドで済むわけですが...)

それはそれとして、6800でもFLEXを動かしてみたいという、技術的な興味もあって6800FLEXを作成してみました。

6809の場合と同様に、SWTPCemu中の6800フォルダにあるDSKファイルからFLEX2.SYSを取り出して、それを元にFLEX2.CORを作ります。FLEX2.SYSは色々なDSKファイル中にありますが、Flex2-01.DSK中のものを使用することにします。このDSK中にはFLEX.CORやFLEX.SYSもありますが、これらは古いもののようですので使用せずにFLEX2.SYSから作ることにします。

具体的な手順

(以下のすべての数値は16進数表記です。)
 (1)FLEX.CORを得る
画像1 ディレクトリ

FLEX2-01.DSKをバイナリエディタで開き、アドレス410からのディレクトリを見ると、FLEX2.SYSはセクタのトラック、セクタ番号が01,0A~04,04の18セクタであることが分かります。

アドレスでは1300~2BFFですので、これをコピーして取り出してFLEX2.SYS名で保存します。



画像2 FLEX2.SYSの先頭部







画像3 FLEX2.SYSの最後尾




このFLEX2.SYSの最後尾を見ると、最後の3セクタが独立しているように見えます。
アドレス2900からの2セクタがDriver.bin、2B00からのセクタがI/Oのベクターです。

この3セクタを除いて282FFまでを取り出して保存したものがFLEX2.CORとなります。













(2)driver.bin, io.binを用意する
MicrosoftのOneDriveに必要なdriver.txtとio.txtを上げておきますので、それをダウンロードして、同梱の6800AsmWin.exeでアセンブルするとdriver.binとio.binが得られます。
6809FLEXとは異なり、このdriver.bin中にI/O関係のアドレスを書きます。
driver.txtを見ていただくと分かるように、BE80から始まるDriverのベクターの後ろ、アドレスBEA3に相当する個所からF000(INCH), F002(OUTCH), BEAFの位置にF838(MONITOR)を書き込んでおきます。
(実は、これだけではだめで、上書き用の io.txtも必要です。)


(3)BINファイルをパケット形式に変換する
得られたBINファイルをパケット形式に変換します。その方法は前回述べた通りで、空のDSKファイル(BLANK.DSK)を用意して、それをFlexDrvWin.exeのドライブにセットし、そこにbinファイルをドラッグ&ドロップするだけです。これで自動的にパケット形式に変換され、セクタ先頭にもセクタ情報が付加されます。

(3-1)driver.binを変換する
画像4 driver.bin と io.bin
FlexDrvWin.exeのStart Adrのボックス中の値を0xBE80にセットしてからdriver.binをドラッグ&ドロップします。実行アドレスは0x0000のままで良いので「はい」と答えるとdriver.binが指定したアドレスからのパケット形式で保存されます。
保存したBlank.binをバイナリエディタで開くと、アドレス2000からの2セクタに保存されていますので、これをコピーして取り出し、driver_dsk.bin名で保存します。

(3-2)io.binを変換する
6809の場合のconsole.binとは異なり、6800ではI/O関係のベクターはここではなく、driver.binの中に書いてありますので、これで十分なはずですが、このio.binは起動時の最後に読み込まれてdriver.bin中の値にセットされたメモリ上の該当箇所を更に上書きするためのもののようです。
(これが分からなくて、ずいぶん手間取りました。)
FlexDrvWin.exeに入れるときに、Start Adrを0xAD09に、Exec Adrを0xAD00にセットします。
この1セクタ分をコピーして取り出し、io_dsk.bin名で保存します。


(4)FLEX.CORにdriver_dsk.binとio_dsk.binをつなげる
新しいBLANK.DSKを用意し、FLEX2.CORを2000~35FFにコピーします。
その後ろの2セクタにdriver_dsk.binを、さらにその後ろの1セクタにio_dsk.binをコピーします。

(5)セクタ情報を書き換える

画像5 FLEX2.SYSの先頭部(左)と最後尾(右)
これで全セクタが揃ったので、各セクタ先頭のセクタ情報4バイトを整理します。
アドレス2000からの各セクタの先頭4バイトを、
01,02,00,01
01,03,00,02
      ...
01,19,00,18
00,00,00,19
に書き換えます。



(6)セクタ00,03のSIR(システムインフォメーションレコード)情報を書き換える
セクタ00,03(アドレス200)のオフセット1Dからの未使用領域開始セクタを01,1Aに、オフセット21からの残りセクタ数09,E0を09,C7に書き換えます


画像6 SIR情報




(7)セクタ00,05のディレクトリ情報を書き換える
セクタ00,05(アドレス400)のオフセット10からの24バイトをファイル名(8バイト)、拡張子(3バイト)、アトリビュート(1バイト,通常00)、未使用(1バイト,00)、スタートTrk,Sct(2バイト,01,01)、エンドTrk,Sct(2バイト,01,19)、サイズ(2バイト,00,19)、2バイト(00,00)、日付(3バイト,月,日,年を2進数で) のように書き込みます。

画像7 ディレクトリ


(8)最後に
以上でシステムディスクのベースが完成しました。あとは、SWTPCemuから必要なCMDファイルが入っているDSKファイルを探してFlexDrvWin.exeのドライブにセットして、システムディスクにコピーします。
例えば、COPY.CMDが入っているDSKがドライブ2に、コピーしたいCMDファイルが入っているDSKがドライブ1にセットされているとして、
  2.COPY (sp) 1 (sp) 0 (sp) .CMD (spはスペース)
でCMDファイルが全てドライブ0にコピーできます。
詳しくは、Documentationフォルダ中のTSCフォルダにあるドキュメントを参照してください。

(9)その他
・システムディスクの先頭2セクタ00,01と00,02にはBootLoaderを入れておく必要があります。6800用のモニター中のFLEXコマンド「X」は、この2セクタを読んでA100からにセットして実行を移す機能を持っています。(このBootLoaderのオフセット05,06にFLEX2.SYSの先頭セクタのTrk,Sct番号が書かれています。FLEXのLINKコマンドはSYSファイルを探して、その位置をここに書き込んでいます。これによって、SYSファイルがDSK上のどこにあっても正しくBootできるわけです。)

・AC07の値00を08に書き換えておくとBSキー時に削除文字が消えてくれますので、使い勝手が良くなります。このためにFLEX2.CORの先頭からのオフセット0F(アドレス200F)を08に変更します。

以上の作業に必要な、BootLoaderの入ったBLANK.DSK、driver.txt, io.txt, 6800AsmWin.exeをMicrosoftのOneDriveにMakeFLEX2というファイル名でアップしておきます。