2024年10月18日金曜日

自作の6809SBCにOS-9を移植する試み(その3 とりあえずROM化に成功)

 とりあえずですがSBCでOS-9が動作しました

その2で報告しましたように、いくつかのモジュールを書き換えてみたり、並び順を変えたりしましたが、何をどうやっても動作しませんでした。

そこで、実際にFM-7上でOS-9Level1が動作している時のメモリ上のモジュールの状態を調べてみようと考えました。そのためにはメモリ内容をダンプするmdumpというコマンドが必要ですが、もちろん、標準コマンドにはありません。自作してもよいのですが、時間がかかりそうですので、既成のものがないかとネットも含めて探しましたが見つかりませんでした。

唯一見つけたのは、末尾に載せた参考文献1に掲載されているmdumpのソースリストです。しかし、これはかなり以前にソースを入力してアセンブルしてみたが、正常に動作しなかったというものです。今回はどうしてもこれが必要ということで、本気で取り組んでみました。本体の他に4つのルーチンが必要なのですが、その中のahexdだけが参考文献1には載っておらず、参考文献2の方に載っているのでそれを取り込んでアセンブルしました。結果、アセンブルはできたのですが、やはり正常に動作しません。ソースを調べたところ、一行抜けがあって2バイト分飛んでいます。参考文献にはmdumpの他にfdumpのソースもあるのですが、それも同様なルーチン中で同じ個所が飛んでいます。。。


参考文献の2冊


どんな処理を補うべきかを判断するのに丸3日(!)かかりましたが(当たり前ですが他の方の書かれたアセンブルリストを理解するのは本当に大変です...)、見つけました。それを補って無事に動作するmdump(とついでにfdumpも)を作成することができました。

作成したmdumpを使ってFM-7上のOS-9Level1のモジュールOS9p1の位置を確認したところ、何と元にしているROM化の記事中のアドレスと5バイトずれているではありませんか。記事ではOS9p1は$F3F3からとなっているのですが、実際には$F3EEから始まっているのです。(OS9p1は$87,$CDから始まり、サイズは$07F2バイト)


OS9p1の位置を確認


ということで、OS9p1を$F3EEからに配置し、OS9p1の直後に置くセカンドベクタと$FFF2からのベクタアドレスをすべて5バイト小さい値に変更して配置してみました。

なお、動作テストのために、前回までは10msのインターバルタイマとACIA用のクロックが生成されているかをオシロで確認していましたが、今回は、RWモジュール中にACIAの入出力ルーチンを書き込んでおいて、Windows機のTeraTermからのキー入力がそのままエコーバックするかどうかで確認できるようにしました。(ACIAの初期化ルーチンはSYSGO中に追加しました。)

結果ですが、希望通りキー入力がそのままエコーバックされてきましたので、とりあえずですが、ROM中に書き込んだOS-9のモジュールが正常に動作していることが確認できました。(三か月近くの苦労が報われました、、、)

なお、前回のその2でSCFをFM-8のものに差し替えたと書きましたが、FM-7のものに戻しても正常に動作しましたので、以降、FM-7のものを使うことにします。


これからすべきことなど

とりあえず、ACIAによる入出力ルーチンを直接書き込んで動作を確認したわけですが、OS-9の作法としては、SCFの下に来るべきACIAドライバルーチンを作成し、その下にACIA-1用とACIA-2用のデバイスディスクリプタを用意するという形になります。また、ディスクが無ければファイルの読み込み・書き出しもできないのでそのドライバも用意しなければなりません。

構想としては、以前、FM77AV40SXで常用しているLevel2でWindows機上に仮想ドライブを構築してそれをACIAを通して読み書きするというドライバを書いて使用していましたので、そのような形を考えています。そのためにACIAを2個用意してあるのでした。

ドライバ作成には時間がかかりそうですが、出来上がりましたら公開する予定です。とりあえず、ハードの方は完成ということで回路図を載せておきます。

動作確認ができたのは下記の8253を使用した回路です。

82C54バージョンの回路図


6809Pと6809EPの両方が使えるようにするためにクロック周りが複雑になっていますが、他には特に変わった部分はありません。8253ではなく8MHzをカウント可能な82C54を使用しています。そのカウンタ0をACIAのクロック生成に、カウンタ1をOS-9のインターバルタイマとして、カウンタ2をASSIST09モニタを使用する際のNMI割り込みに使用しています。

6840を使用した回路です。

63B40バージョンの回路図


回路図中のP-ROMのA14,A13に切り替えスイッチがついていますが、A14のスイッチが現在の基板からの変更点です。32KB以上のP-ROMを使用して、下図のようにOS-9システムとモニタプログラムを切り替えられるように考えています。OS-9システムは$4000~$7FFFの範囲の上位か下位のどちらかに入れ、モニタープログラムは$0000~$3FFFの範囲の上位と下位に自作モニターとASSIST09をそれぞれ入れる予定です。


P-ROM中のシステム配置

あとは、上記の回路図で基板を作り直し、I/O関係のモジュール(ACIAによる入出力ルーチンや仮想ドライブ用ルーチンなど)を作成すれば一応の完成となります。まだまだ時間がかかるかと思いますが、途中経過などをその都度報告をさせていただきます。


元にした記事 「追究特集 OS-9活用テクノロジー」(マイコンピュータNo.21)中の記事「OS-9のROM化」(P148~165)
参考文献1 「FM-7・8 OS-9Level1解析マニュアルⅠ(金井隆著)秀和システム社」
参考文献2 「OS-9/6809Level2解析マニュアル(金井隆著)秀和システム社」


2024年10月16日水曜日

自作の6809SBCにOS-9を移植する試み(その2 OS-9のモジュールを構成)

 OS-9Level1のモジュールのうち必要なものを構成しましたが...

移植しようとしているのはFM-7用のOS-9Level1です。

FM-7用のLevel1とFM77AV40用のLevel2を所有しているのですが、常用しているのはもちろんLevel2で、Level1はほとんど使用していないのでこれを移植しようと考えたわけです。

これが所有しているOS-9のLevel1とLevel2です。


OS-9L1とL2のシステムディスク

以前は、OS-9をディスクから読み込んで起動するものだと思い込んでいたので、起動プロセスのイメージがなかなかつかめなかったのですが、参考にした「OS-9をROM化する」によると、8KBのROM中にOS-9のカーネル(OS9P1,OS9P2)や必要なモジュールを書き込んでおいてOS9P1を起動するだけで、メモリ(ROM)中のモジュールを検索してシステムに登録してくれるとのことです。

OS-9の一般的な構造を下に示します。

OS-9の構造

今回のプリンタ・バッファのモジュール構成を下に示します。

モジュール構成

プリンタ・バッファとして必要なモジュールは下図のようにP-ROM中に配置されています。

モジュールの配置

必要なモジュールのうち、IOMAN,SCF,OS9P2,OS9P1は動作しているOS-9から取り出します。残りのうちのOS9P1より上のINITからIODRVまでの5つは今回用意されたもので、OS-9システムとして必ず必要なものです。OS9P1の下の5つはプリンタ・バッファとして必要なもので、今回はSBCとして最小限の動作を目標としているので不要と考えています。

この配置のうち、OS9P1の位置はFM-7でのOS9P1の配置と合わせてあり、それによって割り込みベクタの値を変えずに済むように考慮されていますので、これに倣うことにしましたが、何とこの配置に従って並べていくとOS9P1の位置が$F3F3よりも後ろになってしまうのです。その原因ですが、SCFのサイズが配置図中では$0438であるのに対して、現用のFM-7から取り出したSCFでは$0504と大きいのです。

手持ちのFM-7のOS-9Level1のバージョンは1.2でして、もしかしたら1.2以前のバージョンがあったのかもしれません。仕方がないので、モジュールを並べ替えてOS9P1の位置を合わせてROMに焼いて試してみましたがうまく行きません。

FM-8版OS-9を所有している知人にお願いしてモジュールのサイズを確認してもらったところ、FM-8版のSCFは$438バイトで記事中のものと一致しました。ということで、とりあえずこのSCFを使わせてもらうことにして上記の配置通りに並べてみました。結果ですが、やはり動作しませんでした。。。

そもそもこの記事はプリンタバッファの製作記ですので、I/Oとしてはパソコンから受け取ったデータをバッファに溜めておいてプリンタに書き出すという機能しかありません。製作したSBCは基本部分だけですのでI/Oがありません。動作しているかどうかは、CLOCKモジュールに書かれている10msのインターバルタイマが機能しているかどうかで判断しています。CLOCKモジュールが正常に動作していればカーネルまで正常に動作していると判断できます。

しかし、そのインターバルタイマが動作しているようにも見えるのですが、不安定なのです。電源を何度も入り切りしたり、リセットボタンを複数回押しているとタイマやACIAのクロックが現れたりするのです。その1に書きましたように、モニタが正常に動作することは確認済みですので、ハードに不具合はないはずです。

ということで、まだ動作しない原因は掴めていません。

その3に続きます。


2024年10月10日木曜日

自作の6809SBCにOS-9を移植する試み(その1 SBCの製作)

 OS-9を移植するための2種のSBCを作ってみましたがモニターを走らせるだけで一苦労

数年前から6809用OS-9をSBCで走らせたいと思っていましたが、考えているだけではちっとも進まないので、思い切って、まずハードの製作から始めました。

実は以前、OS-9と互換性があると言われているNitros9の資料中にSBC用のモニターのソースがありましたので、そのメモリマップに合わせて6809ボードを作成してみたのですが、残念ながらそのモニターは動作しませんでした。。。(ソースを読んでも良く分からない個所もあって、それ以上は先に進めずギブアップ。)

ということで、今回参考にしたのは「マイコンピュータ21(CQ出版社)」中の「OS-9のROM化ープリンタ・バッファを例としてー」という記事です。

この回路中の6809MPU、2個の6850ACIA、8253PIC、RAM、PROMの部分のみを取り出してSBCとしました。この構成ですと私が自作しているSBCとほとんど同じ構成ですので、ほぼI/Oマップの変更のみで作成できました。ただし、8253PICを使用したことがなかったので、使い慣れている6840PTMを使用するボードも作成しました。

下の画像が製作した2種のカードです。

左が68B40使用、右が82C54使用のもの


以前から作成してきた6802ボード、6809ボード、6802/6809デュアルボードを元にしていますので、6809と6809Eのどちらでも使用できます。OS-9Level1をROMに収めるために、ROM領域を$E100~$FFFFの8KB弱と拡げ、I/O領域を$E000~$E0FFに、RAM領域を$0000~$DFFFとなるように変更しました。
また、カウンタICとして今までは6840を使用していましたが、参考にした回路が8253を使用していましたので、8253を使用した回路も作成しました。左が6840使用の従来の回路に似た構成のもので、右が8253を使用したものですが、回路拡張のためのコネクタのスペースを確保するために128KBのRAMをSOCタイプに変更してあります。(なお、実際には6840は63B40を、6850は63B50を、8253は82C54を使用しています。)

(1)ハードの動作確認のために入れたモニターの不具合にハマる
まずハードが正常に動作するかを確認するためにROMにモニタープログラムを入れて走らせてみました。従来から使用してきている自作のモニターでは正常に動作しましたが、ASSIST09を入れてみたところ、なんとRコマンドに余計なものが表示されるという異常が生じました。
今まで普通に使用してきたASSIST09のI/Oのアドレスを変更してアセンブルし直しただけなのに不具合が生じるのは不思議で、ついにはソースを元の書籍「MC6809-MC6809Eマイクロプロセッサ プログラミング マニュアル」中のソースリストと比較することまでしてみましたが間違いはありません。
この原因を見つけるのに2週間ほど要しましたが、結局、使用している自作のクロスアセンブラのバグのために、FCB 'C,'C,0,9が$43,$43,$07,$09となってしまっていたのが原因でした。以前は正しく変換できていたのですが、'Cでも'C'でも変換できるように手直しをした際にバグが入り込んだようです。今はクロスアセンブラの修正をする時間がないので、とりあえずソースをFCB 'C,'C,00,9と変更して正しく変換されるようにしました。
結局、ハードは正常に動作していたのに、モニタの不具合で右往左往することになってしまいました...

(2)2種のカウンタICの使い方でハマる
また、2種のカウンタICの違いにも苦労させられました。
63B40を使用した今までのボードでは、通信用の63B50ACIAのクロック生成のためにシステムクロックの4倍値の8MHzを74HC161で13分周して615KHzを作り出すことで38400baudで通信していました。


74HC161による13分周回路


しかし、参考にした8253使用の回路では、ACIA用のクロックを8253で生成しているのです。同じように63B40でもクロックを生成できれば74HC161を省略できます。

ということで、82C54使用の回路では74HC161を実装せずに82C54のカウンタ0を使用してACIA用の615KHzを生成しています。(カウンタ1はOS-9用、2はASSIST09のTraceコマンド用)
ところが、63B40使用の回路では8MHzを13分周して615KHzを作り出すことができないのです。8253と比べて6840のプログラムは複雑なので、プログラムのミスかと思いあれこれと書き直してみるのですが、何をどうやってもうまく行きません。入力が2MHzだとプログラム通りの分周値が得られるのですが、8MHzだとダメです。挙句の果てには6840ユーザーマニュアル中のサンプルプログラム通りにプログラムしてみましたがやはりダメです。
どうなっているのだろうとネットで検索した結果、6840のカウンタはE入力と同期してカウントダウンしているので、Eよりも高い周波数の入力はカウントできないという書き込みを見つけました。
ということで、結局、63B40使用のボードではACIA用のクロックは従来のボードと同様74HC161で生成することになりました。

さらに、2種のカウンタICのプログラムの違いですが、8253ではコントロールワード中でカウンタ0,1,2の選択と動作モード等の設定が同時にできるので簡単に設定ができ、カウントデータのロードで下位バイトを先に、上位バイトを後に書き込むという順序を守るという注意点があるぐらいなのに対して、6840の方は2つのコントロールレジスタで3つのカウンタを制御しているために、カウンタ1と3ではまずカウンタを選択してからコントロールワードを書き込むという順序になること、そして、コントロールレジスタ1のビット0がソフトウエアリセットになっているので、0にしないと全てのカウンタが止まったままになること、さらにコントロールレジスタ2のビット0がカウンタ1と3の選択を兼ねているために、選択をする際にはカウンタ2のコントロールワードが書き換わらないようにしなければならないことなどがあるので、3つのカウンタの設定順序にも注意が必要です。
迂闊なことに、今までは3つあるカウンタの内の1つしか使用したことがなかったので、これらのことに気づくまでに何と数週間を必要としました。。。

以上のような苦労をした挙句、何とかボードが正常に動作することが確認できましたので、次はいよいよOS-9の移植ですが、実はまだ成功していません。分からないことが多すぎるためですが、現状をその2に書きます。



2024年8月2日金曜日

フロッピーエミュレータGOTEKを少しだけ使いやすくする工夫

 GOTEKのディスプレイとロータリーエンコーダを本体の外にも増設しました


私のFM77AVに内蔵してあるGOTEKには液晶ディスプレイとロータリーエンコーダを増設してあります。ソフトを切り替える場合にはディスプレイを見ながらエンコーダを操作するわけですが、私の場合、FM77AVを机の下に縦置きで設置していますので、ソフトを切り替える場合には机の下をのぞき込む必要がありましたし、ディスプレイの文字が小さいので私のような高齢者にはつらいものがありました。
この状態で2年近く使用してきましたが、流石に不便なので思い切って改善することにしました。
本体に内蔵してあるディスプレイとロータリーエンコーダを外部に引き出せば良いのでしょうが、本体はそのままで、同じものを本体から1mほど延長して増設したいと考えました。
(HxCには本体からケーブルで延長する形のものが製品として存在するので、GOTEKもそのような形で使用できればより使いやすいかもというイメージです。)

実施する前には、ロータリーエンコーダの方はデジタルスイッチ的なものだから、内蔵のエンコーダと並列に増設しても大丈夫だろうと予想していましたが、液晶ディスプレイの方は端子を見ると、SDA, SCL, VCC, GNDの4ピンなのでI2C通信のように見えます。
I2C通信だとするとスレーブ機器はそれぞれ固有のアドレスを持っているわけで、同じアドレスを持っている機器が並列に接続されている場合の動作については経験がありませんので全く分かりません。
ただ、今回の場合は本体から液晶ディスプレイへの表示データ送信が主で、ディスプレイが本体に返信するのはACKビットのみなので、何とかなるかなと甘いことを考えました。

ということで、まず全く同じ液晶ディスプレイを並列に2個接続してみたところ、両方の画面に同じものが正常に表示されましたので、これでいけるということでロータリーエンコーダも増設しました。

これが増設した状態です。
右上のケーブルが液晶ディスプレイとロータリーエンコーダに接続されています。
配線数は液晶ディスプレイが4本、ロータリーエンコーダも4本で計8本ですが、全て基板の裏面でハンダ付けしました。


右上が増設したケーブル


これがケースに格納した状態です。
左下のプリント基板上のフラットケーブルコネクタから外部に延長しています。
右の4線ケーブルはGOTEKとFDDのドライブ番号を切り替えるスイッチです。
(22年10月29日のブログ「FM77AV40SX用GOTEKのドライブ番号切り替えケーブルの製作」https://www.blogger.com/blog/post/edit/1662007451717538019/6000936869197817930
をAV1に適用したもの)

ケースに格納した状態


増設した外部コントローラです。
まだケースに収めておらずゴム足を付けただけですが、これを机上に置いて操作しています。当たり前ですが、以前と比べると格段に操作しやすくなりましたし、ディスプレイが近くに置けたので小さい文字でも見やすくなりました。(この形なら、大画面のディスプレイにも交換できそうです。)


外部コントローラ



目の前に77AVを置いておられる方には関係のない話でしょうが、私のようにスペースに余裕がなくて離れたところに設置せざるを得ない方やもう少し大きい液晶ディスプレイを使いたいと思っている方などに多少なりとも参考になれば幸いです。

また、今回の工作で、I2C機器を並列に接続しても正常に動作する場合があるという経験を得ることができたことも収穫でした。



2024年7月21日日曜日

FM77AV用CP/Mカード(Z80H 韋駄天)のメモリ周りを変更

Z80Hで使用している128KBのメモリをすべて利用する工夫をしました

未使用だった128KBメモリの残り半分を使用できるように回路を変更してみました。

これが製作した第2版の基板です。


完成したZ80H第2版



2020年12月19日のブログ「Z80カードの第4作は77AV用のZ80Hカード(韋駄天)」で報告したZ80Hカードですが、ほうめいさまによるオリジナルで使用されていた2個の32KBメモリを128KBメモリ1個に置き換えることで10x8cmのサイズに収めることができました。

しかし、そのために128KBのメモリの半分は使用されないという勿体ないことになっていました。

このカードはCP/Mを使用しない場合は64KBの拡張メモリとして使用できるように設計されています。
せっかく128KBのRAMを積んでいるのですから、これを有効活用したいところですがメモリマップを見る限り、拡張できるのは$20000~$2FFFFの64KBのみのようです。(40Pコネクタに出ているアドレスラインもA15までです。)


FM77AVのメモリマップ



ということで、128KBのメモリを有効活用するためには拡張RAM空間にバンクメモリという形で置くしかないようです。


拡張RAMの配置



実際にどのようにバンク切り替えを実現するかですが、Z80Hでは$FD64というアドレスのREAD/WRITEでZ80Hの動作を切り替えているのですが、その切り替えに使用しているLS138を利用してBANK0とBANK1を切り替えられると考えました。


バンク切り替え回路


具体的には、上記回路のようにLS74を追加すれば、その出力で128KBのメモリのA16端子を制御することで、$FD65のWRITEでBANK0、READでBANK1のように切り替えることができるはずです。
しかし、2020年12月19日のブログの画像でお判りのように、10cmx8cmの基板にICを追加する余裕はありません。そこで、DIP型のSRAMをSOP型に置き換えることで74LS74を置くスペースを確保することにしました。さらに、基板の高さが8cmではカバーとの間に余裕がなかったので高さを1mm低くして79mmにしました。

基板の設計にはKiCad、自動配線にはfreeroutingを使用しているのですが、前回の基板でもfreeroutingはかなり苦労して(!)配線してくれていましたが、今回はさらにICが増え、しかも高さも1mm低くしたためかfreeroutingによる自動配線が終了しないため、配線の混んでいる付近のIC等の配置をほんの少し移動して試してみるという作業を何度も繰り返すことでようやく配線を完了することができました。

出来上った基板を示します。追加・変更箇所は左上のLS74とSRAMだけなのですが、その他の部分も位置を細かく調整しています。


密度の高い基板


実際に切り替わっているかどうかを、Z80Hの動作確認用に用意されているTiny Monitorを書き換えて作成したテストプログラムを使用して確認してみました。

確認に使用したプログラムは下記のものです。
   
   


MMRを用いて拡張メモリの$20000~$20FFFの領域をCPU空間の$6000~$6FFFにマッピングし、そのうちの$6800からの16バイトにBANK0に$31~を、BANK1に$41~を書き込んだ後にそれぞれを読み出してみました。
その結果、簡単なテストではありますが、画像のようにそれぞれのBANKメモリに正しく書き込めて読み出せていることが確認できました。

実行結果



実際にどのような形でこのBANKメモリを活用できるかについては、これから考えることになるのですが、とりあえず、128KBのメモリをすべて使用できるようになりました。


2024年7月12日金曜日

FM77AV40用増設RAMカードの製作(その4)

 768KB容量のFM77AV40用増設RAMカードを製作してみました

【2024年9月14日訂正】下記のリンク先が間違っていましたので訂正しました。

 今までにFM77AV40用増設RAMカードとして、(1)512KBのSRAMを1個使用したもの、(2)512KBのSRAMを2個使用したもの、(3)(2)の上位256KBを無効にできるスイッチを追加したものという3種を製作してきました。

(1)https://flexonsbd.blogspot.com/2022/10/fm772040512kbram.html

(2)https://flexonsbd.blogspot.com/2023/07/fm77av401024kbram.html

(3)https://flexonsbd.blogspot.com/2024/03/fm-777rs232cft2451024kbram.html

 FM77AV40の拡張メモリ容量は最大768KBですので、512KBのSRAMを2個使用すると最上位の256KBの扱いが気になります。ただ無視されるだけならそれで良いとはいうものの、それでも勿体ないという気持ちも多少残ります。

 使用していて特に不都合はないので、それで良しとすればそれだけのことなのですが、気持ち的にすっきりしないので、いっそのこと128KBのSRAMを2個使用して、512KB+128KB+128KBで768KBの拡張RAMカードを作ってみることにしました。(秋月電子で128KBのSRAMが安かったというのもありますが、ちょっとやりすぎではありますね、、、)


製作したカードがこれです。SOPチップのハンダ付けにもだいぶ慣れてきたようです。なお、富士通の48ピンコネクタは現在ほとんど入手不可能です。ここでは知人が32ピンのコネクタ2個からニコイチで作成されたものをいただいて使用していますが、全く不都合はなく使用できています。表面にスモークのシートを貼っていただいているので、見かけも全く違和感がありません。


768KB拡張RAMカード

回路図を示します。

768KB拡張RAMカード

アドレスデコードについては前回同様GALを使用しましたが、そのプログラムを下記に示します。


GALのプログラム

OS-9LevelIIのmfreeコマンドで容量を確認しました。最上位の8KBが削られているのは今までのRAMカードと同様です。


容量を確認

これでFM77AV40の拡張RAMカードについては最終形にできそうです。


2024年4月25日木曜日

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

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



【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月20日土曜日

コンパイラ作成の試み その4 言語の拡張(FOR文の完成そして6809用へ)

 マイクロCコンパイラmccにようやくFOR文を拡張することができました。

2023年7月4日のブログ「コンパイラ作成の試み その2 言語の拡張(コメントとFOR文など)」(https://flexonsbd.blogspot.com/2023/07/for.html)の続きです。


ブログ用画像の表示のために置いてあります


その際には、繰り返し変数が初期値の次の値から始まってしまうという不具合があり、スタックを使用している言語のため、初期値、終了条件、増分を順に読んでいくしかないので、それが解消できないようだと書きました。

そのため、このマイクロCコンパイラを6809用に改造しようという意欲が失せてしまい、そのまま放置してあったのですが、GAMEインタプリタ・コンパイラの移植、TL/1コンパイラの移植が完了しましたので、これについても何とかしたいと考えていました。そんな時に手持ちの書籍(末尾の参考文献)を読んでいましたら、FORステートメントの実装の説明として、下図のFOR生成2のようなコード生成方式の方が実装が簡潔化できるとありました。


2つのFOR生成方式

なるほどと思い、この形で実装できないかと試みてみました。具体的には、必要な個所にラベルを設定し、そのラベルへのジャンプ命令を追加することで、処理の順序を変えることができました。

そのプログラムを示します。

    

このようなサンプルプログラムも正常に動作しました。

    


6809用コンパイラへ...とりあえずデータ幅8ビットで...

これで必要な(と思われる)拡張が済みましたので、次はいよいよ6809用コンパイラへの移植ですが、このコンパイラはデータ幅が16ビット、レジスタも16ビットを想定していますので、そのままでは6809への適用はかなり難しそうです。

しかし、TL/1コンパイラのようなデータ幅が8ビットのコンパイラもありますので、まず第一段階としてデータ幅やレジスタが8ビットでも動作しないだろうかと考えました。

それを確認するために、コンパイラが生成した仮想CPU用のアセンブルリストを手作業で6809のアセンブルリストに書き換えて走らせてみました。いくつかの注意点がありましたが、ほぼ機械的に書き換えることができました。使用したのは上記のサンプルプログラムからfor文を取り除いて短くしたものです。コンパイラが生成したアセンブルリスト(.CS)と手動で書き換えた6809用のリスト(.TXT)を示します。

仮想CPU用のアセンブルリストです。

    

手作業で書き換えた6809用アセンブルリストです。仮想レジスタR0、R1には2バイトずつ割り当ててありますが、当然1バイトずつしか使用されていません。
(機械的に置き換えただけで最適化を行っていないために、冗長な部分がかなり多いです。)

    

プログラム中に i * 2 という乗算がありますが、その結果が2バイトを超えていないので正常に動作しました。

このことから、もちろん制約はありますがデータ幅、レジスタ長が8ビットでも動作するようだという見込みが立ちましたので、まず第一段階の目標として、8ビット長の6809用コンパイラを目指すことにします。
時間がかかるとは思いますが、じっくりと取り組んでみたいと思います。


参考文献
・作りながら学ぶコンパイラ/インタプリタ 滝口政光著(CQ出版社)

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月25日月曜日

FM-7/77用の自作基板(RS232Cカード、FT245通信カード、1024KB拡張RAMカード)のプチ改良

 FM-7/77用の自作基板3枚を少しですが改良しました

改良版を製作したのは次の3カードです。

1.RS232Cカード

 D-Sub9ピンコネクタに加えてTTL-USB変換ケーブル用コネクタを増設

2.768KB拡張RAMカード(1024KB拡張RAMカード改め)

 512KBのSRAMを2個搭載で1024KBですが、最上位の256KBを切り離して768KBにするジャンパスイッチを増設

3.FT245高速通信カード

 制御・データアドレスとして使用しているアドレス$FDFD,FEを$FD06,07に変更


1.RS232Cカード

2019年10月26日のブログ「FM-7/77用RS-232Cカードの改良版」https://flexonsbd.blogspot.com/2019/10/fm-777rs-232c.html

などで紹介したものです。D-Sub9ピンコネクタが使用されているのですが、現在では、Windows機と接続するケーブルとしてはシリアル-USB変換ケーブルではなくTTL-USB変換ケーブルを使用する方が便利ですので、それ用の6ピンコネクタを増設しました。これに伴ってシリアル変換ICも実装不要になりました。

右上の6ピンソケットが増設したコネクタです。


RS232C_R1.2



右上が増設したコネクタ


回路的にはただ単に8251からコネクタへ信号線を引き出しただけです。


RS232C回路図


使用したケーブルは以下のようなものです。ピン配置は1番ピンから順にGND, RTS, VCC, RXD, TXD, CTSになっていますが、VCCは接続しないのでピンを抜いてあります。


使用したTTL-USB変換ケーブル



2.768KB拡張RAMカード

2023年7月16日のブログ「FM77AV40用1024KB増設RAMカードの製作」https://flexonsbd.blogspot.com/2023/07/fm77av401024kbram.html

で紹介したものです。対象のFM77AV40では増設できるメモリの最大値は768KBなので最上位の256KBは使用されません。無視されるだけで問題は無いとは思いますが、何となく気持ち的にすっきりしないので、回路的に最上位の256KBを無効にできるように切り替えスイッチを増設しました。


512KB拡張RAM

ちなみにこの48ピンコネクタは、知人が32ピンのコネクタ2個からニコイチで作成されたものをいただいて使用していますが、全く不都合はなく使用できています。


768KB拡張RAM回路図


3.FT245高速通信カード

2023年10月23日のブログ「FT245通信カードの新基板の製作」https://flexonsbd.blogspot.com/2023/10/ft245.html

などで紹介したものです。オリジナルでは制御・データアドレスとして$FDFD,FEを使用しているのですが、このアドレスを他のカードが使用している可能性があるので$FD06,07に変更したものを作成しました。このアドレスはRS232Cカードが使用しているものなので、他のカードとバッティングすることはないと考えました。また、FT245カードとRS232Cカードは使用目的が同じなので同時使用することはないだろうと判断しました。


FT245_R3

74LS04を1個増設しただけでアドレスを変更できました。


FT245_R3回路図

以上、自作のカードを少しでも使い易くするためにちょっとした改良を行ったという紹介でした。


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のコンパイラについては、以前のブログで公開する際に作者の了解を得てあります。)