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

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


2023年8月20日日曜日

MC09でASSIST09など用のPL/0の実行ファイルを作成する(補足)

 MC09でASSIST09など用のPL/0の実行ファイルを作成していて気付いたこと

前回のブログで、MC09でコンパイルした実行ファイルをASSIST09などで走らせる方法を紹介しました。

その中で、wnoy さんのサイト「小さな言語」中でPL/0をMC09でコンパイルしてMPB6809のモニター上で走らせておられたので、それを私も走らせてみたと書きましたが、実際には、それはMPB6809のモニターを実装してサイト中のバイナリリストを入力したものを、そのまま走らせたということでした。


前回も掲載した画像ですが


上記サイトにはMC09でコンパイルした結果のアセンブルリストが掲載されていたので、その中のI/O関係を自分の環境に合わせて書き換えてアセンブルすれば実行ファイルが生成されるはずです。

しかし、実はこのようにして生成された実行ファイルは、最初は正常に動作しませんでした。

私が通常使用している6809用のアセンブラはFLEX09上のASMBと自作のWindows上で動作するクロスアセンブラです。加えて、リファレンス用としてアークピットさんのX6809を使用しています。

残念ながらPL/0のアセンブルリストはラベルの長さが6文字を超えているためにASMBではアセンブルできないので、自作のクロスアセンブラでアセンブルしていましたが、結果がwnoyさんのものと異なってしまうのです。これは自作のソフトのバグかと疑って、X6809でアセンブルしてみても結果は自作のものと全く同じでした。


LEAX 2,PC という命令の変換結果がおかしい!

誤変換されてしまう命令を示します。MC09によるコンパイル結果のアセンブルソースでは、文字列の表示に下記のパターンが多用されています。(十数か所あります!)

LEAX 2,PC

BRA ZZZZ <- 表示ルーチンへ

FCB $xx1,$xx2,$xx3,...,$xxn

ZZZZ (表示ルーチン)

これは、LEAX 2,PCで表示すべき文字列の先頭のアドレスをXに入れておいて、BRA命令で表示ルーチンへ飛んでいるわけですが、問題は先頭行の LEAX 2,PC で、これが正しく変換されていないのが正常に動作しない原因でした。

wnoyさんのサイトでは、変換結果は 30 8C 02 であるのに対して、自作のアセンブラやアークピットさんのX6809ではいずれも 30 8D XXXX となりますし、LEAX <2,PC と書き換えてみても X6809では 30 8C XX となるのですが、XXは02にはなりませんでした。

参考までに、X6809でのアセンブル結果を示します。 

 


このLEAX命令の意味としては、LEAX命令の位置のPC値に2を加えた値をXの値とするということですから、EFFEやF2という値は明らかにおかしくて0002や02にならなければなりません。

結局、自作のクロスアセンブラを修正することになった

めったに使うことのない命令でしたので気づくのが遅れましたが、自作のクロスアセンブラを正しく変換できるように修正し、改めてPL/0のアセンブルリストをアセンブルし直した結果、正しく動作する実行ファイルが得られました。ということで、ようやくPL/0をASSIST09や自作モニター上で走らせることができました。(長かった、、、)

ちなみに、この変換結果はアークピットさんのX6809だけでなく、FLEX09上のASMBでも同様で上記と全く同じ結果となります。ということは、これは誤変換ということではなく、このLEAX命令の解釈としては上記の変換結果の方が正しいということを意味するのでしょうか。しかし、実際に実行してみると、30 8C 02 でないと正しく動作しないのですが,,,

(wnoyさんがどのアセンブラを使用されたのかは分かりませんが、アセンブルリストの行末記号が$0Aですので、おそらくLinux上のクロスアセンブラas09を使用されたのだと推測しています。)


2023年8月16日水曜日

FLEX09上のMC09でASSIST09などのモニター下で動作する実行ファイルを作成する

 FLEX09上のMC09を用いてFLEX09がない環境で動作する実行ファイルを作成する

FLEX09には高機能で使いやすいアセンブラASMBがあって便利に使っています。さらに有名な整数型CコンパイラMC09もあります。

ASMBで作成した実行ファイルはもちろんFLEX09のない環境に移行して動作させることができるので、しばしばそのような使い方をしているのですが、MC09については、生成された実行ファイルがFLEX09と密接に関連していて、他の環境で動作させることはできないと思い込んでいました。

しかし以前、「小さな言語」というwnoy さんのサイトがありまして、そこではMPB6809というボードマイコンとそれ用のモニタープログラムが公開されていました。

(現在このサイトは存在しませんが、その内容を保存された方が紹介されています。「MPB6809」で検索するとヒットします。)

このサイトでは他にもForthの移植やTinyBasicの解析などもされているのですが、何とPL/0をMC09でコンパイルして移植しておられるのです。

私もこのモニタープログラムを入力してROMに焼き、自作の6809マイコンでPL/0を走らせてみました。PL/0は実用を目指したコンパイラではないので、特に使い続けるつもりはありませんでしたが、MC09でコンパイルした実行ファイルをMPB6809というマイコンに移植したという点に興味を持ちました。

FLEX09に依存しているファイルI/Oを使わないプログラムならFLEX09がなくても動作するのは当然ではありますが、初めて見る実例でした。このサイトを知ったのは十年以上前なのですが、それ以来、時々ですがMC09でコンパイルした結果のソースリストをいじって自作のマイコンで走らないかと試していました。

PL/0のソースは大幅に書き換えないとそのままではMC09でコンパイルできないので、まだPL/0をコンパイルすることはできていないのですが、他のプログラムについては、最近ようやく何とか動くようになりました。

動作試験に用いたマイコンは下画像のもので、2MHz動作の63B09と68B02を切り替えて使用しています。モニターは6809では自作のものとASSIST09を、6802では自作のものとMIKBUG2をROMに入れてあり、FlexDrvWin.exeという仮想ドライブ構築ソフトを用いることで6809のFLEX09と6800のFLEX2が走っています。


使用したボードマイコン


MC09での実行ファイル作成手順

MC09でコンパイルした結果はC.OUTというアセンブルリストとして出力され、それをMC09に標準で添付されているC.TXTというアセンブルリスト中に読み込んで、全体をアセンブルすることで実行ファイルが生成されます。

MC09 oooo.C --> アセンブルリスト C.OUTが作られる。

ASMB C.TXT oooo.CMD --> C.TXT中にC.OUTが読み込まれ、実行ファイル oooo.CMDが生成される。


C.TXTを書き換えれば良いはず

このC.TXT中にコンソールI/OやファイルI/Oなどが書き込まれているので、コンソールI/Oを自分の環境に合うように書き換え、ファイルI/Oは不要ということで削除すれば良いはずなのですが、エラーの連発でなかなかうまくいかず、試行錯誤の連続でしたが、wnoyさんのPL/0のアセンブルリストを参考にしながら何とか動作するものを作ることができました。

もちろん、FLEX09のファイルI/Oを必要とするプログラムはダメですが、ファイルI/OがないプログラムならMC09で作成して、マイコン等で走らせることができます。サンプルとしてメモリダンププログラム mdump.c を作成してみました。


ASSIST09用と自作モニター用の2種を作成した

作成したのは、私の自作マイコンにインストールしてある自作モニター用のC_SBC.TXTとモトローラ社のモニターASSIST09用のC_ASSIST.TXTの2種です。

これらを標準のC.TXTの代わりに用いることで、自作モニタ―上やASSIST09上で動作する実行ファイルが得られます。

MC09 -O1.C.OUT oooo.C --> アセンブルリスト C.OUTがドライブ1に作成される

ASMB C_SBC oooo.BIN +YLS または ASMB C_ASSIST oooo.BIN +YLS --> 実行ファイル oooo.BIN がドライブ1に作成される

この実行ファイルをFLEX09のディスクから取り出してマイコン側にインストールして、$100から実行します。

(C.TXTにORG $100と書いてあるので、MC09で作成した実行ファイルは$100から実行することになっていますが、実は、アドレス依存のコードではないのでどのアドレスに置いても実行できます。)

作成したC.SBC.TXTとC.ASSIST.TXTを下記に示します。基本的にI/O関係のアドレスが異なるだけですが、ASSIST09のI/OルーチンはSWI命令を使っているのに対して、私の自作モニターは普通にJSR命令を使っているので、コールの仕方もそれぞれに合わせています。


以下にC.ASSIST.TXTとC.SBC.TXTのリストを示します

C_SBC.TXT 

  
 


C_ASSIST.TXT 

  
 


(以下省略)の部分は標準のC.TXTの192行目以降と同じです。


参考までに、サンプルとして作成した mdump.c を示しておきます。このような、ファイルI/OがないプログラムはFLEX09がなくても動作するわけです。

mdump.c 

  
 

出来あがった mdump.bin のサイズは4.2KBほどでした。サイズは大きくなりますが、アセンブラで書くよりも作成時間が短くなるので、サイズがそれほど問題にならない場合にはMC09を使用するメリットはあると思います。


参考までに、私の場合の具体的な実行ファイル作成・実行手順を示します。

1.WindowsPC上のエディタでソースプログラムを作成する。

2.FlexDrvWin.exe中のイメージファイル(.DSKまたは.D77)にソースをドラッグ&ドロップする。

3.MC09でコンパイル、ASMBでアセンブルする。

4.出来あがった実行ファイル(.BIN)をイメージファイルからWindowsPCへ読み出す。

5.バイナリ形式の実行ファイルを自作の変換ソフトCvtMotHexBin.exeを用いてモトローラ形式(.MOT)に変換する。

6.モニターのLoadコマンドでモトローラ形式の実行ファイルを読み込む。

7.モニターのGoコマンドで実行する。


以上ですが、作成・使用したファイル(C_ASSIST.TXT, C_SBC.TXT, 最新版のFlexDrvWin.exe, CvtMotHexBin.exe, サンプルのmdump.c)をOneDriveに上げておきます。なお、FLEX09やMC09の作成手順は以前のブログで紹介しております。


2022年10月20日木曜日

FM-7にPTMを増設してASSIST09のトレースコマンドを実現

 FM-7にPTM(68B40)を増設してASSIST09のトレースコマンドを実現しました

【2022年12月7日】回路図を再修正しました

FM-7でASSIST09を使う方法については、2022年9月15日に「自作クロスアセンブラの修正とASSIST09のFM-7への移植」で紹介しましたが、FM-7にはPTM(Programmable Timer Module)がないので、そのままではトレースコマンドが使えませんでした。

機械語プログラムのデバッグには必須の強力なコマンドですので、何とか使えるようにしたいという事で、FM-7にPTM(68B40)を増設することにしました。

ASSIST09ではPTMの出力によってNMIを発行していますが、残念ながら32PスロットにはNMI端子が出ていません。背面の50PのI/O拡張ポートには出ていますが、普段は拡張基板を接続していますので、使いたくありません。という事で、40PのZ80用スロットに目を付けました。このスロットはZ80カード、63C09カード、Arduino2560カードで使用していますが、機械語のデバッグ時にはこれらのカードを外せば良いと考えたわけです。

早速、KiCadで回路図を作成して基板を発注しました。出来上がった基板がこれです。


PTM-PIAカード

上右の28ピンICがPTM(63B40)で、その左の40ピンICがPIA(68B21)です。以前、拡張用にPIAカードを作ったのですが、それにPTMを追加するような形で製作しました。

回路図を示します。

(下に動作しなかった原因を述べてありますが、この回路図はその修正等を加えてあります。【2022年12月7日再修正しました】)


PTM-PIAカード(再修正済)


ASSIST09の方の変更は、「自作クロスアセンブラの修正とASSIST09のFM-7への移植」中の拡張ROMのプログラム中のPTMのアドレスをこの基板に合わせて$FDF0に書き換えるだけです。

早速、実行してみましたが動作しません。(いつものことですが。。。)

最初に使用していた68B40が不調だったりしましたが、交換しても変わりがありません。回路にも間違いはないようですし、プリント基板のパターンも全て確認しましたが、回路図と違いはありませんでした。


動作しない原因が判明

色々調べた挙句、ようやく原因が分かりました。何と、Z80用スロットのNMI、IRQやFIRQ端子はメインCPUへの入力端子ではなく、逆向きのZ80カードへの出力端子だったのです。(他にEやQも通常とは逆向きのようです。)事前調査不足でした。。。

結局、FM-7にPTMを増設するには、背面の50P拡張ポートを使用するしかないという事になりましたので、基板の作り直しが必要になってしまったわけですが、とりあえず、製作した基板を使用するために、下画像のような変換アダプタを製作しました。


変換アダプタ

40Pメスコネクタは、以前FM-7をばらした際に基板から外して保存してあったものです。これを接続して、画像のような形で使用します。


使用形態


これで、無事に動作しました。

トレースコマンド実行画面


いつものようにミスをしながらも、何とか動作させることができましたので、FM-7での機械語プログラムのデバッグが楽になると期待しています。

そもそもスロットの端子名だけで使えると誤解した私の知識不足が原因であるわけですが、少しでもどなたかの参考になればと思い、あえて紹介することにしました。


2022年9月15日木曜日

自作クロスアセンブラの修正とASSIST09のFM-7への移植

 ASSIST09がアセンブルできるように自作クロスアセンブラを修正し、FM-7に移植してみました

【9月20日訂正】末尾に訂正が一個所あります。

発注しているプリント基板ができあがるまでハードいじりは措いておいて、いつかは直そうと思っていたソフトの修正に取り掛かりました。

まずは6809用のクロスアセンブラですが、以前、「必要に迫られて自作したアセンブラ等のツールソフトの紹介(2021年9月1日)」で紹介したもので、ASSIST09のソースをアセンブルする際にはそのままではアセンブルできず、ソースを修正する必要がありました。

例えばASSIST09のソースの1684行は

FCB 'H,$01,'H,$01,'H,$00,',,$00 --> $48,$01,$48,$01,$48,$00,$2C,$00 になって欲しい

となっていますが、この中の「',」が$2Cとならずに区切り記号と解釈されてしまうのです。ですので、アセンブルする際には「',」を$2Cと置き換えてアセンブルしていました。

ちなみに、使用者が多いと思われるアークピットさんのX6809でもこれは正常にアセンブルされません。アセンブル結果は次のようになります。

$48,$2C,$24,$30,$31,$2C,$00,$01,$48,$2C,$24,$30,$30,$2C,$00,$00

これは、X6809では1文字は「'」で囲んで「','」にしなければならないという仕様になっているからです。

私の自作アセンブラ(6809用、6800用)でも、最初はそのような仕様にしていたのですが、ASSIST09だけではなく他のソースでも後ろの「'」のない書き方が多いようなので、どちらの書き方にも対応するように変更した結果、「',,」が正常に変換されないというバグが発生していました。

もう一つの不具合も FCB疑似命令に関するもので、負数がちゃんと変換されないというもので、FCBのオペランド中での負数の処理にバグがありました。そのため、やはりアセンブル前にソースのFCBのオペランド中の-1を$FF,-2を$FEのように書き換えていました。

上記の2つの不具合はいずれもFCBのオペランド文字列の解釈に関するものでしたので、それを修正したVer1.92を作成しました。これによって「',」でも「','」のどちらでも正しく変換できるようになりました。


Ver1.92でのアセンブル結果


WARNINGが出ている


ASSIST09をアセンブルするために

以上で自作クロスアセンブラでASSIST09をアセンブルできるようになったのですが、実はソースそのものを何箇所か変更する必要があります。

私が以前から使用していたものは、書籍「MC6809-MC6809Eマイクロプロセッサ プログラミング マニュアル」中のソースではなくバイナリを手入力したもので、必要な個所を直接書き換えて使用していました。当時はアセンブラを所有していなかったので、ソースをアセンブルできなかったのです。

その後、ネットからソースを入手しましたが、そのソースが書籍のものと何箇所か異なっていることに気づいてはいましたが、ちゃんとソースを読んでいませんでした。

最近、ソースをアセンブルしてバイナリを得る必要があったので、書籍と見比べた結果、やはり書籍版を使用することにして、書籍版に合わせてネット版ソースを変更しました。

(私は今まで書籍版のバイナリを使い続けており、ネット版をそのままアセンブルしたものを使用したことがありませんので、動作にどんな違いがあるのかは分かりません。)

変更したのは下記の4箇所です。

1.825行からのCIDTAルーチン

2.870行からのCODTAOルーチン

3.1085行のCPX命令は6800の命令なのでCMPXに変更

4.1619行のCBKADDルーチンのDECBを変更

以上の変更を加えたソースを自作クロスアセンブラでアセンブルすると6つのWarningが出ますが、これはExtend命令と解釈したがDirect命令に変更できるよという警告ですので、該当の6箇所のオペランドの先頭にDirect命令を指示する「<」を付加します。改めてアセンブルするとWarningも出ずに、書籍と同じバイナリが生成されました。

以前は、Direct命令に変更できる場合は常に変更したコードを生成するようにしていたのですが、これではまずい場合がありましたので現在のような仕様にしているのですが、元のソースを書き換える必要があるのは嬉しくないので、変更するかしないかを選択できるようにしたVer1.93を作成しました。プログラムソースをかなり書き換えたので、正常に動作するかどうかをテスト中です。


FM-7へのASSIST09の移植

以前、ASSIST09に関するブログを書いた際には、もう既に移植済みのASSIST09にコマンドを追加したという内容でした。

「ASSIST09に追加したLoad, Saveコマンドを改良しました」(2018年6月27日)

「ASSIST09にLoad, Saveコマンドを追加」(2018年5月26日)

今さらとは思いますが、マイコンなどへの移植はネットでもいくつか見ますが(私も昔から自作マイコンで使用しています)、FM-7への移植はあまり見たことがないので、ここでFM-7へのASSIST09の移植の手順について書いてみたいと思います。

なお、以下の移植の手順についてはインターフェース誌1982年4月号の「ASSIST09の詳細とFM-8への移植(高橋豊)」をほとんどそのままFM-7に適用したものです。高橋豊さんに感謝いたします。

[1]最も簡単な移植(入出力にACIAを使用、領域圧縮なし、拡張ROMなし、アドレス$F800からに配置)

アセンブラが使用できればソースを変更してバイナリを生成できますので、ソースの24行、25行のACIAとPTMのアドレスを変更し、配置するアドレスを20行に書いてアセンブルするだけです。PTMが実装されていない場合はアドレスに$0000を書いておきます。

しかし、これでは2KBのASSIST09の他に6KBもの使われないエリアが生じて無駄が多くなりますし、そもそも、FM-7のようなパソコンの$F800からには移植できません...

[2]簡単な移植(入出力にACIAを使用、領域圧縮なし、拡張ROMなし、任意のアドレスに配置)

任意のアドレスに配置する場合には、20行目のROMBEG(スタートアドレス)を書き換えます。さらに[1]の設定に加えて、SWIやNMIのベクターアドレスをASSIST09用に再設定する必要があります。ベクターアドレスについては直接設定することになります。

[3]未使用領域を圧縮して移植(拡張ROMあり、他は[2]と同様)

拡張ROMを使用する場合は、それを用いて必要な再設定をすることができます。図のFM-7への配置例で示したものでは、$6800~$6FFFにASSIST09を配置し、その下に$100バイトの拡張ROMを置き、その下からがスタック/ワークエリアとしています。ソースの変更箇所はROMBEG(スタートアドレス)とRAMOFS(拡張ROMのオフセット)のみで、他は拡張ROM中で設定できます。


ASSIST09の配置例


ASSIST09は拡張を容易にするために、自身のアドレスから2KB下に$20,$FE(BRA *)があると、拡張ROMがあるとみなし、ASSIST09の起動前に$20,$FEの次のアドレスにサブルーチンジャンプすることで、ユーザの初期化プログラムなどを実行することができます。図では、2KB下ではなく$100バイト下に設定しています。

この初期化プログラム中で必要な処理を書くわけですが、最小限必要な処理は以下の2つです。

・1文字入力ルーチン、1文字出力ルーチンをFM-7のそれに置き換える。

・SWI、NMIルーチンをASSIST09用に置き換える。

SWIはASSIST09の内部でサブルーチンコールなどのために使用しています。NMIはBREAKキーでF-BASICに戻るために使います。

その他、コマンドの拡張もここで行うことができます。


拡張ROMの例を下に示します。まず最小限のものです。

 

コマンドの拡張は非常に有用ですので、高橋豊さんの例をそのままお借りしてコマンド拡張方法の具体例を示します。

 


配置例にあるように、拡張ROM($6700~$67FF)とASSIST09($6800~$6FFF)を一つにまとめておいて、
 CLEAR ,&H6000
 LOADM "ASSIST" <-- ASSIST09とExROMを合体したファイル
 EXEC &H67E0
その後
 MON でASSIST09が起動します。ASSIST09から抜ける場合はBREAKキーを押します。

FM-7への移植手順は以上ですが、改めてインターフェース誌で情報を公開して下さった高橋豊さんに感謝いたします。

修正した6809用クロスアセンブラについてはチェックが終わり次第公開します。
それにしても、6809の命令一覧表には載っていない命令(例えば、LEA命令のプログラムカウンタ相対のDirectモード命令)が存在したりして、情報不足のせいか今一つ理解できないことがいくつかあるのが悩ましいところです。
【9月20日訂正】私の勘違い(&知識不足)でした。Directモード命令ではなく、プログラムカウンタ相対の8ビットオフセットか16ビットオフセットかの違いでした。

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社)



2018年6月27日水曜日

ASSIST09に追加したLoad, Saveコマンドを改良しました

ASSIST09に追加したLoad, Saveコマンドは使いにくかった


5月26日のブログで公開したASSIST09の追加コマンドLoad, Saveですが、使用していると使い勝手が悪いところが目に付いてきましたので、改良しました。

使いにくい点は
(1)毎回、Windows側のslwin.exeを起動しなければならない。
(2)末尾が0でないアドレスからSaveし始めると、その値から16バイトずつ保存していくので、メモリのダンプ値と比較しにくい。

ということで、コマンドプロンプト画面でWindows側のソフトを起動すれば、その画面を閉じない限り、繰り返しLoad, Saveコマンドが使えるように改良しました。
また、アドレスが切りの良い値でSaveされるように一行目の保存バイト数を調整しました。


コマンド発行の様子



コマンドの使い方は全く同じです。











Windows側の様子





一度起動するだけで、連続してLoad, Saveコマンドが使えます。終了するにはQを入力して少し待ちます。








作成されたMOTファイル




Saveコマンドで保存されたMOTファイルの中身です。
2行目からは切りの良いアドレス値で保存されています。















残念な点...
ASSIST09側のプログラムもそれに合わせて若干の手直しをしましたので、モニタROMの焼き直しが必要となってしまいました。

ASSIST09側のプログラムとWindows側のプログラム(slwinr.exeと改名)をMicrosoftのOneDriveに上げておきます。

2018年5月26日土曜日

ASSIST09にLoad, Saveコマンドを追加

WindowsへのLoad,Saveコマンドを追加しました


ASSIST09のLoad,Punchコマンドはテープが対象なので、実用にはなりません。
私はFLEXを常用しているので、モニターはメモリ内容を変更、確認する場合ぐらいにしか利用していなかったのですが、よく考えてみると、ファイルの単純なLoad,SaveぐらいならわざわざOSを起動しなくてもモニターのみで良いのではないかと思えてきました。


ASSIST09はコマンドの追加が簡単にできますので、Windows上にファイルをモトローラのS-formatでSave,Loadできる拡張コマンドを作ってみました。

動作のイメージ

ASSIST09側:LOAD, SAVE(拡張コマンドとして内蔵)
Windows側 :slwin.exe(あらかじめ起動しておく)

コマンド入力の様子

書式


Windows側で動作するプログラム
Saveコマンド:SAVE(ret)
その後、ファイル名、先頭アドレス、終了アドレス、実行アドレスの順に入力すると確認を求めてきますのでYを入力するとメモリの指定範囲の内容がモトローラのS-formatで保存されます。

Loadコマンド:LOAD(ret)
その後、ファイル名を入力すると保存されているファイルがもとの位置に読み込まれ、実行開始アドレスを表示して終了します。




Windows側ではコマンドプロンプト画面を開いておき、ファイルを保存したいフォルダに移動して、slwin.exeを起動します。起動オプションとしてポート番号、ボーレートと保存フォルダが指定できますので、

slwin p=4 b=38400 path

のように指定します。省略時は、ポート番号は1、ボーレートは38400boud、保存フォルダはカレントディレクトリとなります。
(slwin.exeをGitHubに上げておきます。) GitHubへのファイルの追加の仕方が分からない。。。分かりましたらアップしておきます。
(5月29日追記)追加方法が結局分からなかったので、とりあえずMicrosoftのOneDriveに上げておきます。


ファイルの書式変換

モトローラのS-formatは実行アドレスが保存できるので便利なのですが、他の書式に変換したい場合もあると思います。私も、例えばROMライターにデータを送る際にはインテルのhex-formatを用いています。
私は自作のS-format, Hex-format, Binary相互間の書式変換ができるソフトCvtMotHexBin.exeを使っています。
CvtMotHexBin.exeもGitHubに上げておきます。) GitHubへのファイルの追加の仕方が分からない。。。分かりましたらアップしておきます。
(5月29日追記)追加方法が結局分からなかったので、とりあえずMicrosoftのOneDriveに上げておきます。
(5月31日追記)不具合のあるバージョンを上げてしまっていましたので、修正版に差し替えました。