2018年11月17日土曜日

I2C通信でLCD表示器に文字表示ができましたが...

LCD表示器に文字表示ができましたが、標準の書き方ではなく...


使用したのはスイッチサイエンスで購入した8文字2行表示のAQM0802A(5V版)です。
5V版なので、10月27日に公開したRTCの回路にそのまま追加しました。

接続図


コマンド・データの書き込み手順


コントロールICはST7032iで、そのマニュアルによると、コマンドやデータはいずれもコントロールバイトとデータバイトの2バイトのセットで書き込むようになっています。

コマンドの場合 複数連続して書き込む場合 :$80+1byte(コマンドコード)
        単独又は最後に書き込む場合:$00+1byte(コマンドコード)
データの場合 複数連続して書き込む場合 :$C0+1byte(データコード)
       単独又は最後に書き込む場合:$40+1byte(データコード)

$00+1byteや$40+1byteの後には必ずI2Cのストップコンディションが続いて終了することになっています。


連続書き込みでは$80や$C0を毎回書くのですが...


実際にプログラムを作って試してみると、
S+ADR+($80+CmdCode)+($80+CmdCode)+...+($00+CmdCode)+P

S+ADR+($C0+Data)+($C0+Data)+($C0+Data)+...+($40+Data)+P
 (S:スタートコンディション、ADR:スレーブアドレス、P:ストップコンディション)
という書式で確かに書き込みができました。

しかし、ネット検索をしてみますと、$80や$C0を用いて連続書き込みをするのではなく、$00や$40を用いて1byteずつ書き込む例も結構見られます。例えばArduinoのC言語であれば、Wireライブラリを用いて、

コマンド書き込みの場合は
Wire.beginTransmission()とWire.endTransmission()で挟んで
Wire.write()で$00と1byteのコマンドを書く。

データ書き込みの場合は
Wire.beginTransmission()とWire.endTransmission()で挟んで
Wire.write()で$40と1byteのデータを書く。

というような形式です。(この例のbeginTransmission()とendTransmission()はそれぞれS+ADRとPだと思われます。)


もう少し効率的に連続書き込みをする方法がありました


確かに、1文字の書き込みなら$00や$40を用いるのがマニュアル通りの書き方なので良いのですが、複数バイトのコマンドやデータを書き込みたい場合には、スタートコンディション、スレーブアドレス、ストップコンディションを1byte毎に書くことになり、いかにも非効率です。
かといって、連続書き込み用の$80や$C0を1byte毎に書くのもあまり効率が良いとは言えません。スタートコンディション、スレーブアドレス、ストップコンディションは1回で済むという利点はありますが。(これしか方法がないのなら仕方がないのですが)

他の書き込み方はないのかと色々と試行錯誤した結果、下記のような書式で書き込めることを確認しました。

コマンド書き込みの場合
S+ADR+$00+(複数のコマンドコードを順に)+P

データ書き込みの場合
S+ADR+$40+(複数のデータを順に)+P


この書き方は、明らかにマニュアルで説明されている書式とは異なっているのですが、画像のようにちゃんと書き込めています。

AQM0802A表示例


最後に

なぜST7032iのマニュアルに載っていない書式で連続書き込みができるのかは分かりませんし、マニュアルを熟読すればどこかに記載されているのかもしれませんが、あくまでもAQM0802Aの一使用例として見ていただければと思います。
何か勘違いや間違い等ありましたらご指摘いただけるとありがたいです。

6809のアセンブラでLCDWR.TXT,LCDWR1.TXT,LCDWR2.TXTの3つのプログラムを作成し、いずれも正常に書き込みできることを確認しました。

LCDWR.TXTの書式(最も短い)
  command : S+ADR+$00+cmd1+cmd2+...+lastcmd+P
  data         : S+ADR+$40+dat1+dat2+...+lastdat+P
LCDWR1.TXTの書式(初期化コマンドのみ短い)
  command : S+ADR+$00+cmd1+cmd2+...+lastcmd+P
  data         : S+ADR+($C0+dat1)+($C0+dat2)+...+($40+lastdat)+P
LCDWR2.TXTの書式(標準の書式)
  command : S+ADR+($80+cmd1)+($80+cmd2)+...+($00+lastcmd)+P
  data         : S+ADR+($C0+dat1)+($C0+dat2)+...+($40+lastdat)+P

参考になるかどうかわかりませんが、作成した3つのプログラムのソースをMicrosoftのOneDriveに上げておきます。


2018年11月3日土曜日

PIAのみでRTCからの時刻の読み書きができました

PIAに接続したRTCから時刻を読み書きするアセンブラのプログラムが完成


前回(10月27日)はRTCモジュールから時刻を読み込むまででしたが、時刻の書き込みもできるようになりました。
読み込み・書き込みプログラムはそれぞれRTC_RD.CMD、RTC_WR.CMDですが、読み込みプログラムに、FLEX9の起動時に時刻をRTCモジュールから読み込んでFLEX9の日付を設定する機能を追加したSETDATE.CMDを用意しました。

RTC_RD.CMDとRTC_WR.CMDはFLEX9上のコマンドとして使用します。


FLEX9システムに組み込んで使用する


SETDATE.CMDはFLEX9の起動時に自動的に実行されるように、STARTUP.TXTに書き込んでおいて使用しますが、FLEX9の起動時にデフォルトで実行される日付入力ルーチンが不要になりますので、FLEX9のシステムを一箇所変更します。

FLEX9システムをTrk01,Sct01から保存した場合、初期化ルーチンはSct08にあります。
そのうちの日付入力ルーチンはオフセット$76からのBD,CA,AC (JSR $CAAC) ですので、このBDを39 (RTS)に変更します。

初期化ルーチン(変更前)
初期化ルーチン(変更後)

これによって、起動時に日付を問い合わせてくることは無くなり、代わりに、STARTUP.TXTに書き込んだSETDATE.CMDがRTCモジュールから取得した日付を設定してくれることになります。

その様子を下図に示します。


起動画面(従来のもの)

今までは、起動時に日付を「月、日、年」の順に入力する必要がありました。
(FLEX9では時刻は管理していませんので、年月日のみです。)
それに対して、SETDATE.CMDを組み込むと、

起動画面(RTCモジュールから読み込み)

日付を問い合わせてくることなく、RTCモジュールから取得した日付と時刻を表示してそのままコマンド入力待ちになります。DATEコマンドを入力してみると、確かに日付が設定されていることが分かります。
なお、RTCモジュールが無い場合には、デフォルトの日付入力ルーチンが呼び出されて手動で日付を入力することになります。

起動画面(RTCモジュールが無い場合)

作成したRTC_RD.CMD, RTC_WR.CMD, SETDATE.CMDのソースをOneDriveに上げておきます。
入出力ルーチンなど一部にFLEX9のシステムルーチンを使用していますが、I2C通信部分は一般的な6809のアセンブラですので、I2C機能を持たないマイコンで、しかもアセンブラでI2C通信をしたいという場合の参考になれば嬉しいです。
(I2Cの解説も、DS3231のマニュアルも、もう少し分かりやすく書いてもらえればこんなに苦労しなくても済んだかもしれないのに...愚痴でした。)

2018年10月27日土曜日

アセンブラでのPIAとRTCの間のI2C通信に成功しました

アセンブラでPIAを経由してRTCの時刻の読み出しができました


使用したRTCモジュールはアマゾンで入手したHiLetgoのZS-042です。このモジュールにはDS3231というチップが使われており、I2C通信で時刻の設定や読み出しを行うようになっています。
I2C通信については、名前を知っているだけで具体的なことは全く知らなかったのですが、FLEXの起動時の日付の入力が煩わしいので、RTCからの自動読み込みに挑戦することにしました。

しかし、ネット上の情報は多くがArduinoとの接続の場合で、しかもWireライブラリを使うものがほとんどで、私もRTCモジュールが動作するかどうかをArduinoで確認しましたが、30分もあればできるという簡便さは誠にありがたいのですが(ライブラリを作成してくれた方には感謝です...)、6809のアセンブラでI2C通信プログラムを書きたい場合には全く役に立ちません。

また、PICやAVRなどのマイコンのアセンブラでI2C通信をしているものも幾つか見つけましたが、これらもマイコン自身にI2C通信機能を備えたものを使用している場合がほとんどで、これも役には立ちません。また、I2C通信機能を持たないPICやAVRでのケースもありましたが、これらのマイコンはポートのビット処理命令を持っているので、ビット処理命令を持たない6809ではプログラムの参考にはあまりなりませんでした。

ということで、結局、I2C通信の解説とDS3231のデータシートを読みながら、自力でプログラムを組むことになりました。

6821とRTC間の接続

6821とRTC間は下図のように配線しました。
図中のプルアップ抵抗はPortAの内蔵抵抗で代用しています。
6821のPortAはオープンドレインで、しかも5kΩの抵抗でプルアップされていますので、I2C通信に適しているということと、入出力の切り替えが不要で、出力に設定したままで入力も可能(但し、予めHを出力しておく必要あり)なので、プログラムが書きやすいと考えました。

RTC配線図


ロジアナを所有していないので、デジタルオシロで波形を見ながら試行錯誤を続けましたが、手順の最初のスレーブアドレスの書き込みからして成功しているのかどうかも分からず、全くACKが返ってこない状態が続き、間にPICでも挟まないとダメかとあきらめかけたこともありました。

最終的には、SDA信号は、Lowは0を出力するのに対して、Highは1を出力するのではなく開放、つまりHi-Zにするのだということに気づき、それに対応するように書き直すことで、ようやく読み込みができるようになりました。

読み出しに成功

下図で表示されたデータは、RTCの最初の7レジスタを読んだもので、順に、秒、分、時、曜日、日、月、年を表しています。

RTCから日付と時刻を読み取り

現段階では、ようやく読み取りができたというところまでですが、あとは書き込みルーチンを作成し、それを常駐プログラムの形式にして、FLEXの初期化ルーチン中の日付入力ルーチンと置き換えれば完成です。
(完成しましたらプログラムは公開します。)

[11月4日 追加] 完成したプログラムは11月3日のブログで公開しています。

2018年10月15日月曜日

6809/6802両用基板が完成しました

6809/6802両用基板を修正しました


最初に製作した6809/6802両用基板は、9月15日の投稿で述べたように、修正箇所があったこととPIA(6821)を載せたかったので修正基板を製作しました。

これは最初に製作した基板ですが、

6809 / 6802 両用基板の第1作


このようにPIA(6821)を外付けすると修正基板と同機能となります。


6821を追加しました


ブレッドボード風に使用できるようにピンを立ててみました。

6821基板


これが修正基板です。

修正基板(6821を追加しました)



回路図を掲載します。
6809と6802の切り替え部を簡略化し、それに応じて不要になった74HC08を除き、空いたスペースを利用して68B21を追加しました。



修正基板の回路図


これで当初の目標であった、シングルボードコンピュータで6809用、6800用のFLEXを動作させることができるようになりました。

===== 一応の完成! =====

あと残っている課題ですが、FM77AV40SX上のFLEXを使っていた時には、起動時に、内蔵されているリアルタイムクロックから現在時刻を取得して起動時の日付の入力を自動化していましたので、同様なことができないだろうかと考え、arduinoなどで使われているRTC基板ZS-042と6821との間でI2C通信を試みているのですが、今のところうまくいっていません。
(2MHzのMPUではI2Cの推奨の最低値である100KHzはとても無理で50KHz程度の速度しか出ないようなのですが、これが原因ではないとは思いますが。。。)


RTCとの通信実験中


これができたら、基板の製作は一応打ち止めにして、あとはFLEX上のソフトを活用して、プログラムの制作に本腰を入れようかと思います。

実現したいものとしては、まずはツール類の充実と、あとは願望ですが、
 MC09の改造、6809用コンパイラの自作、OS-9Level1の移植
などがあるのですが、いずれも難度が高いものばかりですので、どうなりますやら。。。

(いずれにしても趣味の世界ですので、無駄な「タイヤの再発明」をモットーとしており、ツール類を始めとしてアセンブラや逆アセンブラ等もすべて自作したものを使用することにしていますので、言語類も自作したいのです。。。究極はOSの自作でしょうか。)

OS-9の移植ですが、手元にFM-7用Level1、FM77AV40用Level2のライセンスがあり、Level1の方は今は使用していないので、これを使えればと考えています。
(以前、FM77AV40上でOS-9用のROM,RAMディスクとWindows上の仮想ドライブを製作した経験がありますので、それを生かせれば何とかなるかなあ。。。)


2018年9月15日土曜日

FLEX9にコマンド履歴機能を追加

FLEX9にコマンド履歴(ヒストリー)機能を追加しました


FLEXは単純なOSの割には言語やユーティリティも充実していて使いやすいと思っていますが、もちろん不満も色々あります。
その一つがコマンドヒストリー機能がないことです。プログラムを作成する中で、何度も同じようなコマンドの入力を繰り返すのは苦痛でもあります。特にアセンブラの場合は繰り返し頻度が特に高いので、ストレスが溜まります。

繰り返し入力を少しでも軽減するために、アセンブラやMicroCによるプログラム開発の場合に使うMAKEA.CMDやMAKEC.CMDを作成して使用しています。


MAKEA.CMDの使用例



MAKEC.CMDの使用例

いずれもシステム(ASMB.CMD, MC09.CMDなど)がドライブ0に、対象ファイルがドライブ1にあると決め打ちしていますが、それなりに役に立ちます。
参考までに、それぞれのメイクファイル(MKFILEA.TXT, MKFILEC.TXT)の内容を下に示します。&1や&の位置に、対象ファイル名が読み込まれて実行されます。


メイクファイルの中身

しかし、このような特定の場合以外ではどうしてもヒストリー機能が必要です。

FLEXのコマンド入力をフックしてヒストリー機能を実現する


FLEXのソースを読むと、$CE2Bからがコマンド入力ルーチンなのですが、バックスペース(BS)位しか編集機能がありません。そこで、ここをフックして自作のコマンド入力ルーチンに置き換えます。
自作の入力ルーチンの置き場所ですが、$CC2B,2CのMemory Endの値を入力ルーチンのサイズの分だけ小さくしてシステムに使われない領域を作り、そこに置きます。
このようにして作成したのがSET_LIN.CMDです。


SET_LIN.CMDを常駐させる

コマンド入力待ちの状態でSET_LINと入力すると常駐し、もう一度SET_LINと入力すると常駐が解除されます。
編集機能としては、
 Ctrl-A  ヒストリー呼び出し。(履歴機能)
      コマンド入力途中では、その位置以降を呼び出す。(補完機能)
 Ctrl-E  カーソル位置以降を消去。
 ↑    コマンド文字列の先頭にジャンプ。
 ↓    コマンド文字列の最後尾にジャンプ。
 ←    一文字左に移動。
 →    一文字右に移動。
 BS    カーソル位置の左の一文字を削除。
 DEL   カーソル位置の一文字を削除。
 CR    編集終了。入力文字列をコマンドとして処理する。
があります。
直前のコマンドしか呼び出せないなど、ヒストリー機能としてはWindowsに慣れている私たちから見ると不十分ですが、これでも随分とストレスが軽減されます。

制作に関して


実は、FM77AV40SXでFLEX9やOS-9Level2を使っていた頃に、OS-9のヒストリー機能をFLEXでも実現すべく簡単なSET_LIN.CMDを作成して使用していました。(上記の機能のCtrl-Aの補完機能や↑,↓機能のないもの)
これでもOS-9の超単純なヒストリー機能よりも使いやすいものでした。
FM77のBIOSやSubSystemを用いて機能を実現したため、当然、矢印キーが使えましたので、今回制作するにあたっても、是非矢印キーによる処理を実現したかったのですが、ここで最も苦労しました。

TeraTermでの画面制御にエスケープシーケンスを用いているのですが、矢印キーを扱おうとすると$1B,$5B,$41(↑キー)のような3文字を扱うことになります。また、テンキー部のキーも全て3文字となるので、その扱いもプログラムで処理しなければなりませんでした。(矢印キーのみ3文字扱いでも仕方がないとして、その他は単純に1文字扱いできないものでしょうか?)
プログラムサイズもFM77での430バイト程度に対して、BIOSやSubSystemの編集機能もプログラムで実現しなければならないため1Kバイト位と倍以上になってしまいました。

もうしばらく使い続けて不具合がないことを確認してから公開する予定です。


6809基板と6802基板を一体化して

6809/6802両用基板を作りました


6809基板と6802基板が完成したので、これらを二段重ねして電源コードとシリアル端子2個を差し替えて使用していました。


上が6802基板、下が6809基板


しかし、これは結構面倒ですし、プロフィールに書きましたように、元々は6802と6809を切り替えられるようにした自作コンピュータを最近まで使用していましたので、6809と6802をスイッチで切り替えて使える両用基板を製作することにしました。
できたのがこれです。


6809/6802両用基板の第1作

今までのようなFusionPCBの10㎝×10㎝の格安基板にはとても収まらず、15cm×13㎝の大きさになりました。(基板だけでなく送料も高かった...)

間違いがありますが、とりあえず修正前の回路図を載せておきます。
(修正後のものは修正基板と一緒に載せます)

修正前の回路図(間違いあり)


動いていた自作コンピュータの回路を元にしたのですが、改良(?)した部分がまずかったのか6809と6802の切り替えがうまくいかず、あれこれと変更してようやく動作するようになりました。しかし...

基板裏の修正の様子

こんなに修正する必要がありました。また、ゲートICも一つ不要となってしまいました。

これで、スイッチで6809と6802を選択してリセットボタンを押すとモニタも連動して切り替わりますので、随分と使いやすくなりました。

さらに改良・追加基板を製作


拡張コネクタも用意しましたし、HD63B40も追加したのでASSIST09のトレースコマンドも使えるようになり、これでOKとしても良かったのですが、せっかくIC1個分のスペースが空きましたし、これにPIA(6821)を載せればシングルボードコンピュータとしては完成形になるのにと思えてきたので、もう一度基板を製作することにしました。
10㎝×10㎝基板2枚に分割できないかと試みたのですが、片方だけでも動作するようにはとてもできず、結局同じサイズの基板になりました。(現在発注中...)

(独り言:ゲートICにはソケットを使わない主義なので、この基板でもゲートICは直付けです。新しい基板が完成したら、この基板は不要になってしまう...勿体ない...さらに同じ基板がまだ4枚もある...ああ勿体ない...)



2018年8月2日木曜日

MS-BASICがLOAD, SAVEコマンド付きで動きました

6809SBDでMicrosoft BASICを動かしてみました


VintagechipsさんのSBC6809でMS-BASICが動いています。(移植されたのはtomi9jpさん
私のメイン環境であるFlex9上ではTSC社のBASICコンパイラなどもありますので、特に必要はないのですが、PC-8801の頃に使っていたMS-BASICですので、懐かしさもあってFlex9に移植してみました。

まずはVintagechipsさんのOneDriveからBASIC9.zipをダウンロードし、その中のBASIC9.asmのACIAのアドレスを$F0BC,BDに変え、さらにスタートアドレスを$A000に、メモリ末を$9FFFに変えてFlexDrvWinに放り込み、Flex9のアセンブラASMBでアセンブルします。
アセンブラの書式の違いから大量のエラーが出ますので、手作業で修正していきます。
例 CMPA #'E' -> CMPA #'E

また、Flex9のASMBにはラベルを6文字まででしか区別していないという問題があり、例えば、TOK_INPUTとTOK_INKEYが同じラベルだという分かりにくいエラーが出ます。
衝突している3つのラベルの名称を変更します。
例 TOK_INPUTと衝突しているので TOK_INKEY  -> TOK_IK

その他、多少の修正はありましたが、無事にアセンブルできてBASIC9.CMDができました。実行すると懐かしいMicrosoft BASICのメッセージが。。。


BASIC9

しかし何と、PRINT USING が動作しない!!!(ROMサイズの制限で削ったのでしょうか?)
また、作ったプログラムをSAVE, LOADできないのはつらい!

ということで、元になっているGrant'sさんのサイトにあるExBasRomを移植し、SAVE, LOADコマンドを追加してみました。


ExBasRomを移植し、SAVE, LOADを追加しました


まずGrant'sさんのサイトからExBasRom.zipをダウンロードし、その中のExBasRom.asmを取り出します。ACIAのアドレスを$F0BC,BDに変え、SAVE, LOADルーチンが増えますのでスタートアドレスを$9000に、メモリ末を$8FFFに変えます。その他の修正も上記と同様に行います。

次に、SAVE, LOADルーチンを追加するために、590行あたりにある、
  FCC "EDI" 9E
  FCB $80+'T
の次に以下の4行
  FCC "SAV" 9F
  FCB $80+'E
  FCC "LOA" A0
  FCB $80+'D
を追加します。それに伴って、これ以降の"TAB”~TOK_USINGまでがずれてきますので、$9F->$A1, ... $B1->$B3 のように12ヶ所ほどを+2した値に変更します。
さらに、745行あたりにある、
  FDB EDIT 9E と
  TOK_HIGH_EXEC EQU ... の間に、以下の2行
  FDB SAVE 9F
  FDB LOAD A0
を挿入します。
最後に、5400行あたりにある、
*LINE
LINE CMPA ...
  LBEQ ...
  JMP LB277
の次に SAVE, LOADルーチンの本体を置きます。

SAVEの範囲ですが、プログラム本体はワークエリアのTXTTAB($0019,1A)に先頭番地が、VARTAB($001B,1C) に最終番地+1が入っていますが、他のワークエリアの値も保存するために、$0000番地からVARTABの値-1までを保存しています。     

以上の修正を行ったExBasRom.asmをFlexDrvWinに放り込み、Flex9のアセンブラASMBでアセンブルします。
これでPRINT USING が機能し、SAVE, LOADコマンドが使えるMS-BASICが完成です。
サイズですが、$9000~$B595の$2596(9622)バイトでした。

ExBasRom

SAVE, LOADルーチンも正常に動作しています。保存先は、ドライブを指定していない場合はFlex9のワークドライブです。

SAVE, LOAD付きExBasRom

この移植にあたっては、Vintagechipsさん、tomi9jpさんの移植作業が大変参考になりました。これらの方々の努力と成果が無ければもっともっと手間がかかっていたと思います。感謝いたします。

このFlex9用に改変したPRINT USING, SAVE, LOAD付きのソースExBasROM_KAI.TXTをMicrosoftのOneDriveに上げておきます。

2018年7月27日金曜日

6809SBDの新しい基板を作りました

新しい基板は6809Pと6809EPの両用基板です

今までの基板は6809P用に設計したので、6809EPを搭載する際にはEPアダプターを使用していました。
これで09Pと09EPの両方が使用できて特に不都合はないわけですが、ICソケットの上にEPアダプターが重なっているのを見ていると、やっぱり何とかしたいということで、両用基板を作成することにしました。

EPアダプター上に載せていた、信号QとEを作るための74HC74を基板に移し、切り替えの3Pジャンパーを7個と6809と6309の切り替え用の1個の計8個を載せれば良いのですが、10x10cmのサイズではもうギリギリでしたが、RAMを128KBを1個にして何とか収まりました。

6809P/EP両用基板に09Pを搭載


6809P/EP両用基板に09EPを搭載


左上の2段になっている3Pジャンパー6個と2個が切り替え用です。
左端の1個は6809と6309の切り替え用で、XTAL端子(39番ピン)をGNDに落とすか開放するかを切り替えるものです。残りの7個は、全てを上に置くと09P対応、下に置くと09EP対応となります。
画像は63C09Pを搭載した例と63C09RP(EP相当)を搭載した例です。

現状、eBayなどでも本物の63C09Pは中々入手できず(秋葉原などでは買えるようですが、結構高額…)、63C09EPやRPなら比較的入手しやすいので、どちらでも使えるこんな基板もありかなと。
私の手持ちも、頂き物の63C09Pが2個で、あとはEPとRPばかりです。



6809SBD-V3回路図

回路図を示します。
10x10cmのFusionpcb特価基板ではこれが限界のようです。
現在は、もう少し大きな基板で6809/6802デュアルCPU基板を設計中です。
(これができれば、68系のソフトが全て走る...かな)



2018年7月24日火曜日

MicroCを使う(その2)・・・MC09を作成して使う

MC09の作成方法をより具体的に

「MicroCを使う(5月4日公開)」ではMC09の作成方法を説明しましたが、それは2014年に当時のUbuntuで作成した記録を元にして書いたものでした。
書いた時には、現在使用しているUbuntu16では作成できないようだとは思っていましたが、本当にできないのかどうかを確認していませんでした。
その後、Ubuntu16や最新の18で試みてみましたが、どうしてもうまくいきませんでした。
ということで、以前のバージョンのUbuntuをインストールして、改めてMC09を作成しました。
インストールしたのは、Ubuntu10で、使用したisoファイルはUbuntu-10.04.4-desktop-i386.isoです。(ドジってしまって、Windows7とUbuntu16のデュアルブートで動作していた環境を壊してしまった...(泣))

Ubuntu10上で、前回の説明のように竹岡さんのサイトからmc09.tgzとas09.tgzをダウンロードし、それぞれを展開します。私は、デスクトップにmc09_as09というフォルダを作り、その中にmc09, as09というフォルダを作ってその中に展開しました。

ファイルを収めたフォルダ




(1)6809用アセンブラas09を作成する

フォルダas09中に展開されたファイルの中にmakefileがありますので、基本的にはその通りにビルドしていけばよいのですが、BSD用のファイルですのでLinuxでは以下の修正が必要です。

as09用makefile(修正後)

・makefileのCFLAGS=の次行にcc=gccを追加する。
・関数名のバッティングを避けるために次の2関数の名称を変更する。
  as68.c中のgetline()を全てgetline2()に変更
  as68.c中のindex()を全てindex2()に変更
修正した後、makeを実行すると実行ファイルas09が作成されます。
(makefile中のlint:...行以降は実行されませんが、結果には影響ありません。)

as09作成後
このas09をフォルダmc09にコピーしておきます。


(2)mc09を作成する

フォルダmc09に移動します。以降はこのフォルダで作業します。
makefileを修正します。
・DESTDIR=の次行に cc=gccを追加する
・mc mc2.cの先頭に ./を追加する ./mc mc2.c
・as09 c.txt -o mc2.o -v -Oの先頭に ./を追加する ./as09 c.txt -o mc2.o -v -O
・関数名のバッティングを避けるために次の2関数の名称を変更する。
  mc.c中の getline()を全て getline2()に変更
  mc.c中の index()を全て index2()に変更


mc09用makefile (修正後)


ここまでの変更で、makefile中のgcc mc.c -o mcでmcが作られる。
このmcはLinux上でのクロスコンパイラとして使用できるものですが、
このままでは、コンパイルはできても出力(C.OUT)が得られません。
さらに次の変更をします。
・mc.c中の printf( を全て fprintf(obuf, に変更する。

以上の変更によって、makefile中の
gcc mc.c -o mc でクロスコンパイラ mcが作られ、そのmcを用いた ./mc mc2.c でmc2.cをコンパイルした結果の c.out(6809のアセンブラ言語)が得られるので、これを./as09 c.txt -o mc2.o -v -O で6809の機械語にアセンブルすることでFlex上での実行ファイルmc2.o(モトローラS形式)が得られる。(c.outは c.txtのアセンブル中に読み込まれて一緒にアセンブルされる。)
(各行ごとの実行でなく、makeを実行した場合は lint:...行以降は実行されませんが、結果には影響ありません。)


4通りのmc2.o作成後


最後に、mc2.oをS形式からバイナリに変換して、Flexに読み込ませて名称をMC09.CMDに変更すれば出来上がりです。私は、以前公開した CvtMotHexBin.exeでバイナリに変更し(StartAdr, ExeAdr共に0x0100に設定)、FlexDrvWin.exeに放り込みました。

蛇足
アセンブラ as09のオプション -vと -Oの効果が良く分からなかったので、オプションなしの場合(mc2.o)、-vのみ付けた場合(mc2v.o)、-Oのみ付けた場合(mc2o.o)、-vと-Oの両方を付けた場合(mc2vo.o)の4通りを作成してみました。
結果:mc2.oとmc2v.oは同じでバイナリで31KB、mc2o.oとmc2vo.oは同じで29KBでした。-Oはサイズの最適化と思われますが、-vは分かりませんでした。

あとは、前回説明しましたように、
C.TXT、そしてライブラリc.txt, stdio.txt, stdio2.txt, alloc.txt, fileio.txt, fileio2.txt. scanf.txt, string.txt、そしてユーティリティuf.cをFlexのドライブにコピーすれば完成です。(ライブラリはドライブ0のシステムディスクに、C.TXTはドライブ1のワークディスクにコピーします。)コンパイルするファイルはC.TXTのあるワークドライブに作成します。この配置で、例えば
MC09 (sp) -O1.C.OUT (sp) file.c (sp)はスペース
で、file.cがコンパイルされてC.OUT(6809のアセンブル言語)が作られるので、Flex上のアセンブラASMB.CMDで
ASMB (sp) C (sp) file.CMD +YLS (CはC.TXTのこと)
でアセンブルされた実行ファイルfile.CMDができあがります。
これは$100からに配置されて$100から実行開始されるファイルです。

MC09を使う際の注意

前回も書きましたが、追加も含めてもう一度書いておきます。
(1)ソースファイル作成では
・必ず stdio.txt, alloc.txt をインクルードする。ファイル名は大文字で。
 #include "STDIO.TXT"
 #include "ALLOC.TXT" (入れないとアセンブル時に initheapエラーが出る)
・TABコード($09)はFlexでは意味が異なるので、スペースに変換しておく。
・行末コードは$0Dのみなので、Windows上でファイルを作成した場合は$0D,$0Aの$0Aを削除してからFlexに転送する。

(2)関数の引数の書き方では
古いコンパイラですので、引数のタイプを次行に書くというKRスタイルです。
 例 main (argc, argv)
       int argc;
       char *argv[];
   {

   }

古いスタイルで書かなければならないことやエラーメッセージが不親切など、使いにくい面も多々ありますが、特にファイルI/Oのあるユーティリティなどを短時間で書きたい時などには便利ではないかと思います。

以上ですが、Linuxのどのディストリビューションのどのバージョンで作成できるかは、私にはとても確認できませんので、私の作成したサイズ31KBのMC09.CMDと29KBのMC09O.CMDの両方と、古いスタイルのCファイルの例として自作コマンドLISTN.CとMOT2CMD.CをMicrosoftのOneDriveに上げておきます。




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というファイル名でアップしておきます。





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に上げておきます。

FLEXシステムの作成方法(その2)・・・より具体的に

FLEXシステムの作成方法 ・・・ より具体的に

以前の「FLEXシステムの作成方法」(2018/05/04公開)をより具体的に説明します。
フォルダFLEX6809中の100近いファイルのほとんどはFLEXの9.0や2.9等の以前のバージョンで、3.01とは若干構造が異なり、前回説明した手順がそのままでは適用できません。(9.0や2.9の構造は6800用のFLEX2と似ています。)
必要なバージョンV3.01はFLEXSSB.DSKの中だけにあります。
このDSK中にはFLEX.CORはありませんが、FLEX.SYSがFLEX.CORの後ろにDRIVER.BINとCONSOLE.BINをつなげた形になっているので、これらを取り除けばFLEX.CORが得られるわけです。得られたFLEX.CORにこのシステム用のDRIVER.BINとCONSOLE.BINをつなげればFLEX.SYSとなります。

具体的な手順

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

FLEXSSB.DSKをバイナリエディタで開き、アドレス410からのディレクトリを見ると、FLEX.SYSはセクタのトラック、セクタ番号が01,0A~01,21の18セクタであることが分かります。
アドレスでは2D00~44FFですので、これをコピーして取り出してFLEX.SYS名で保存します。






画像2 FLEX.SYSの先頭部


このFLEX.SYSの最後尾を見ると、最後の2セクタが独立しているように見えます。
アドレス4300のセクタがDRIVER.BIN、4400のセクタがCONSOLE.BINです。
(DRIVER.BINが簡単なのは他の部分に実体があるからです。)
この2セクタを除いて42FFまでを取り出して保存したものがFLEX.CORとなります。


画像3 FLEX.SYSの最後尾




























(2)Driver.bin, Console.binを用意する
まず前回のページで紹介しているGitHubへ行き、Cloneordownloadボタンを押し、DownloadZIPを選択すると、6809_6800_FLEX-master.zipがダウンロードできますので、これを展開します。
この中のDRIVER.TXTとCONSOLE.TXTを同梱の6809AsmWin.exeでアセンブルするとDRIVER.BINとCONSOLE.BINが得られます。

(3)binファイルをパケット形式に変換する
得られたBINファイルはそのままではDSKファイルに入れることはできません。
「シングルボードコンピュータとFLEXシステムの詳細」(2018年5月4日公開)で述べたように、FLEXシステムではベタのBINファイルは存在できませんので、パケット形式に変換します。その方法ですが、空のDSKファイル(BLANK.DSK)を用意して、それをFlexDrvWin.exeのドライブにセットし、そこにBINファイルをドラッグ&ドロップするだけです。これで自動的にパケット形式に変換され、セクタ先頭にもセクタ情報が付加されます。

(3-1)DRIVER.BINを変換する
画像4 DRIVER.BINとCONSOLE.BIN

FlexDrvWin.exeのファイル内容表示ボックスにDRIVER.BINをドラッグ&ドロップすると
先頭アドレスを聞いてきますので、「いいえ」で抜けて、バイナリファイルのStart Adrのボックス中の値を0xDE00にセットし、もう一度ドロップします。実行アドレスは0x0000のままで良いので「はい」と答えるとDRIBER.BINが指定したアドレスからのパケット形式で保存されます。
保存したBLANK.DSKをバイナリエディタで開くと、アドレス2000からの2セクタに保存されていますので、これをコピーして取り出し、DRIVER_DSK.BIN名で保存します。









(3-2)CONSOLE.BINを変換する

画像5 CONSOLE.BINを編集

方法は上と同様なのですが、注意すべき点があります。CONSOLE.TXTを見ると分かるように、前半はD3E5からのI/Oのベクタ値の並び、後半がD370からのI/Oプログラムの実体と分かれています。これをそのままFlexDrvWin.exeに放り込むと全体がD3E5からということになってしまいます。
(画像5の上部)





別々に処理して最後に合体させる手もありますが、そうサイズも大きくないので、手作業で修正することにして、そのまま、先頭アドレスを0xD3E5に、実行アドレスを0xCD00にセットしてCONSOLE.BINを放り込みます。
(実行アドレスを指定するのは、最後尾に16,CD,00を追加させるためです。)

そして次の2箇所を変更します。(画像5下部の2箇所の赤枠部)
・ベクター部分は18バイトなので、02,D3,E5の次の57を18に変更する。
・D3,70からの24バイトの後ろに、02,D3,70,3Fを挿入する。
この1セクタ分をコピーして取り出し、CONSOLE_DSK.BIN名で保存します。

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

画像6 FLEX.SYSの先頭部(左)と最後尾(右)
(5)セクタ情報を書き換える
これで全セクタが揃ったので、各セクタ先頭のセクタ情報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に書き換えます

画像7 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進数で) のように書き込む。

画像8 ディレクトリ


(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を入れておく必要があります。ASSIST09中のFLEXコマンドは、この2セクタを読んでC100からにセットして実行を移す機能を持っています。(このBootLoaderのオフセット05,06にFLEX.SYSの先頭セクタのTrk,Sct番号が書かれています。FLEXのLINKコマンドはSYSファイルを探して、その位置をここに書き込んでいます。これによって、SYSファイルがDSK上のどこにあっても正しくBootできるわけです。)

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

以上の作業に必要なBootLoaderの入ったBLANK.DSK、DRIVER_DSK.BINとCONSOLE_DSK.BINをMicrosoftのOneDriveにMakeFLEXというファイル名でアップしておきます。