Posts Tagged with "Ultra96"

既に発行済みのブログであっても適宜修正・追加することがあります。
Even in the already published blog, we may modify and add appropriately.

6809 IPの修正(2)

posted by sakurai on October 3, 2019

6809 IPは、Verilogステートマシン設計されているため、Vivadoのロジックシミュレータでステート毎に値をチェックして行きました。飛び先である\$FF12を用意されているものの、PCに書き込まれていないことが判りました。とは言え、JMP命令は正しくデコードされ、内部信号のop_JMP(JMP命令であることを示すデコード信号)は正しく出力されています。

図%%.1
図162.1 修正前の6809CPUの動作

ステート遷移を修正し、レジスタ書き込みで終わっている箇所をジャンプステートに修正し、さらに、PCへの書き込みアサートを追加しました。

ステートの遷移は、修正前が、0f,16, 17, 18, 19, 11, 12, (09=次の命令フェッチ)のようになっているのに対して、修正後は0f, 16, 17, 18, 19, 1b, (09=次の命令フェッチ)のように遷移し、かつ、オレンジ色で示したk_write_pc信号がアサートされ、new_pcである\$FF12\$FF12がPCにセットされています。結果として正しく\$FF12にジャンプしています。

図%%.2
図162.2 修正後の6809CPUの動作

修正前は誤ってステートが、\$11(SEQ_GRAL_ALU), \$12(SEQ_GRAL_WBACK)と、レジスタ書き込みのステート遷移となっているのに対して、修正後は\$1b(SEQ_JMP_LOAD_PC)と、JMP命令のステートに遷移しています。

例えばメインフレームのような大型機をどのようにテストしているかと言えば、もちろん単体命令をひとつづつテストすることも行いますが、キャッシュ、仮想記憶、ページングの記憶階層があります。そのためのタイミングによるバグの可能性があるので、ランダム試験を実施します。命令を乱数で発生し、ただし不正命令とはならないように制約をかけ、ソフトシミュレータで正解値を取得します。これを論理シミュレータにかけ、結果値であるレジスタの値やメモリの値が正しいかをチェックします。メモリの値はひとつずつチェックすることなく、領域のチェックサムを取ることで確認します。

さらにこれを発展させ、実機にランダムプログラム生成プログラムを載せて、実行時に正解値を生成しチェックします。一見バグ値どうしを比較してOKとなりそうですが、いろいろと条件を変え、命令をページクロスさせて前半と後半でキャッシュやページのヒットミスを変えることで、演算値が変わることがあり得ます。これはプロセッサがパイプライン動作していることから、バグによってはタイミングによって結果が変わることがありうるためです。

ということで、メインフレーム並みの信頼性を保証するなら、上記のようなテストを実施しなければなりません。


左矢前のブログ 次のブログ右矢

6809 IPの修正

posted by sakurai on September 27, 2019

FM=7のハードウェアエミュレーションをFPGAで実行するプロジェクトを遂行していましたが、FM-7のROMイメージもZ80カードI/Fを用いることにより、すんなり抜き出すことができました。

それをVivadoに持ち込むにあたって、COEファイルという形式に変換し、OpenCoresからダウンロードした6809を動かしたのですが、動作しないようです。実機の動作と比較するために、実機にはロジックアナライザを接続しました。

前記事のArduino-Z80I/FカードにはFM-7の内部バスが現れているので、実はArduinoは動かさなくても、ロジックアナライザを接続すれば、メインCPUである6809の動作が把握できます。ロジックアナライザも昔は数百万円したかと思いますが、私の購入したものは17,000円くらいでした。これで32CH 200K 400MSa/sですから、アドレス、データ、主要制御信号を観測するのに十分です。

●Arduinoマイコンが870円(送料別) https://www.banggood.com/RobotDyn-Mega-2560-PRO-Embed-CH340G-ATmega2560-16AU-Development-Module-Board-With-Pin-Headers-For-Arduino-p-1397734.html

●ボード作成が5枚で4.9 USD https://www.fusionpcb.jp/

●コネクタは少々高くて743円(送料別) https://jp.rs-online.com/web/p/pcb-headers/6020498/

●ロジックアナライザは消耗品ではないので高いですが、それでも17,299円 https://www.banggood.com/Hantek-4032L-Logic-Analyzer-32Channels-USB-Oscilloscope-Handheld-2G-Memory-Depth-Osciloscopio-Portat-p-1376105.html

のように比較的気軽に試すことができます。

さて、このような環境でFPGAのシミュレーションを実行したら、おかしな点を見つけました。具体的にはJMP命令が動作しません。著者に連絡を取り、報告したところ、「It doesn't surprise me that a couple (or more) things do not work.」とのことで、自分でなんとかするしかなさそうです。FM-7システムの中で6809をデバッグするのは大変なので、新たに図のような単体テスト環境を作成しました。

図%%.1
図161.1 6809 IP単体試験回路図

6809 CPUに、リセット、クロック、ROMを接続しただけです。RAMはありません。このROMに以下のようなテストプログラムを置き、実行させたところ、

FF00         start  org   \$ff00
           
FF00 8EFF12         ldx   #lab1
           ;    jmp   0,x
FF03 6E00          fcb   \$6e,\$00
           
FF05 8EFF15     lab2  ldx   #lab3
FF08 6E01          jmp   1,x
               
FF0A 8EFF12     lab4  ldx   #lab1
FF0D 6E84          jmp   ,x
FF0F 7EFF0F         jmp *
               
FF12 7EFF05     lab1  jmp   lab2
FF15 12       lab3  nop
FF16 7EFF0A         jmp   lab4
           
FFFE             org   \$fffe
FFFE FF00          fdb   start
           ;
0000             end

最初の\$FF03番地のJMPを、JMPせずに実行してしまいます。JMP命令でもインデックスアドレシングのみ動作しないようです。ちなみに、JMP ,XとJMP 0,Xは動作は同じですが、オペコードは異なります(\$6E,\$00と\$6E,\$84)。が、動作が同じであるため、JMP ,Xと書いてもJMP 0,Xのオペコードがアセンブラから出力されるため、やむなく上記のようにFCBで記述しました。


左矢前のブログ 次のブログ右矢

FM7 ROM吸出し器の製作(5)

posted by sakurai on August 29, 2019

サブシステムのROM吸出しの際に、サブシステムの動作確認をするために、Arduinoからランダムなボックスフィルを実行してみました。いかにもFBASICで描画しているように見えますが、Z80カードのエミュレーションをArduinoがやっています。その様子を図160.1に示します。

図%%.1
図160.1 サブシステムの動作

以下の動作をするスケッチを作成しました。

  • \$FD05のMSBが0になるのを待つ
  • \$FD05のMSBを1に(サブシステムをHALT)、LSBを1に(メインシステムをHALTしZ80側に)するーつまり\$FD05に\$81をwrite
  • 共有メモリにLineコマンド及びランダムな座標パラメータを書き込む
  • \$FD05のMSBを0に(サブシステムHALTの解除)、LSBを1に(メインシステムをZ80側のまま)するーつまり\$FD05に\$01をwrite
  • 最初に戻りループ

左矢前のブログ 次のブログ右矢

FM7 ROM吸出し器の製作(4)

posted by sakurai on August 28, 2019

メインシステムROMの吸出しは非常に単純で、アドレスをセットして、データをリードするだけでしたが、サブシステムのROMはサブシステム側に依頼しないと読み出せません。従って、前に述べたように、メンテナンスコマンド(いわゆるYAMAUCHIコマンド$\dagger$)を用いてブロックコピーし、分割読み出しすることになります。これは、サブシステムのROMが10,240バイトもあるのに比べて、窓である共有メモリがわずか128バイトしかなく、コマンドにいくらか使用するため、データ転送用の窓を64バイトとしているためです。そのため、この転送を160回繰り返します。64バイト毎に16進ダンプを行います。

FM-7/8 Subシステムメンテナンスコマンドのページを参考にスケッチを作成します。作成したスケッチをここに置きました。

図%%.1
図159.1 サブROMコピーの動作図

いちいちサブシステムを止めてコマンドを(2度)発行してダンプを行うので、かなり面倒でしたが、このスケッチにより得られたダンプ画面の最初と最後を示します。

d800 00 00 00 00 00 00 00 00 70 40 70 1a 7a 0e 0a 0a
d810 70 40 70 12 74 08 14 22 70 40 70 42 74 08 14 22
d820 70 40 70 40 7e 04 04 04 e0 80 e0 8c f2 12 12 0d
d830 20 50 70 52 54 18 14 12 70 48 70 4c 74 04 04 07
:
ffc0 02 10 ae a4 10 9f 47 bd b5 9c bd 9b 35 be 01 82
ffd0 20 d3 be 01 84 ae 02 20 a9 bd 02 69 34 ff 86 00
ffe0 1f 8b 10 ff 03 16 10 fe 03 16 bd 9b 35 86 2a 8d
fff0 e0 00 e0 00 e0 00 fd ac e0 6e e0 00 fe bf e0 00

同じくネットで入手したSubrom_c.romと比較したところ、全てのバイトが一致しました。若干疑問なのは、スクラッチから作成したと言われているROMデータが実ROMデータを全て一致するということがあるのだろうかということです。とりあえず、実機から抜き出したROMデータを使用している分には問題が無いので、気にしないことにします。

$\dagger$山内さんは入社した時の課内ソフトウェアグループのサブシステムチームのリーダでした。


左矢前のブログ 次のブログ右矢

FM7 ROM吸出し器の製作(3)

posted by sakurai on August 27, 2019

Arduino Mega 2560 Proの端子図を図158.1及び図158.2に示します。

図%%.1
図158.1 Arduino Mega 2560 Proの端子図

図%%.2
図158.2 Arduino Mega 2560 Proの端子図(右側の端子)

アドレス、データ、制御信号を全てソフトコントロールしています。スケッチはここに置きました。ただし、初版からデータピンの位置を変更しているため、ボードの版数に合わせて適宜修正する必要があります。

これにより吸い出したfbasic30 ROM(\$8000~\$FBFF)生データの一部を示します。

8000 8e 80 13 ce 01 f9 c6 0a bd 85 97 8e 80 26 c6 0a
8010 7e 85 97 06 80 1d 80 5a 09 80 1d 80 77 a0 a0 a0
8020 a0 a0 a0 a0 a0 a0 06 80 30 80 5a 01 80 71 80 77
8030 43 48 41 49 ce 45 52 41 53 c5 4c 4c 49 53 d4 4c
:
:
fbc0 e1 7e 9b 50 7e 8d d1 7e af 1a 7e 96 63 7e b2 34
fbd0 7e b0 ee 7e af 11 7e cc 37 7e af 97 7e ce dc 7e
fbe0 ce df 7e b0 44 7e e3 4d 7e da f9 7e da ef 7e d4
fbf0 df 7e c2 8c 7e c6 7a 7e da f6 f1 7d 86 84 84 8b

このままCOEファイルに変換するか、あるいはバイナリにすれば、前稿のスクリプトが使えますが、簡単なのでこのままawkによりCOE化することにします。

ネットで入手したFM7エミュレータ用のROMデータと実機から吸い上げた生データを比較したところ、fbasic30.coeは全てのバイトが一致しました。 一方boot.coeは末尾の2 lineが不一致となりました。エミュレータ用のROMでは0xffとなっていますが、実機のROMは割込みベクタが置かれているためにデータが入っています。

エミュレータ用ROMの末尾32バイト:

ffe0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
fff0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

実機ROMの末尾32バイト:

ffe0 ff ff ff ff ff ff 01 04 ff ff ff ff ff ff ff ff
fff0 ff ff 01 d1 01 d4 01 e0 01 dd 01 d7 01 da fe 00

ところが、「FM-7ユーザーズマニュアルシステム仕様」を見ると、\$FFE0~\$FFFFはベクトル領域となっており、boot ROMではないため、これで全てのバイトが一致しました。

末尾32バイトはベクトル領域というRAM領域でジャンプテーブルとなっています。飛び先のRAMの内容を含めて表にまとめます。

図%%.3
図158.3 割込みベクタまとめ表

FIRQ割込みハンドラは\$C953から、IRQ割込みハンドラは\$D2FCからのようです。本カードにより(メインCPUを停止し)\$AAを書き込んだところ、以下のようになったため、\$FFE0~\$FFFDはRAM、\$FFFE~$\$FFFFはROMのようです。

ffe0 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
fff0 aa aa aa aa aa aa aa aa aa aa aa aa aa aa fe 00


左矢前のブログ 次のブログ右矢

FM7 ROM吸出し器の製作(2)

posted by sakurai on August 26, 2019

ArduinoとPCはUSBケーブルで接続し、それを通じてプログラムするのですが、そのケーブルを通じて通信することができます。具体的にはArduino側でprintln()関数を実行すると、PC側でArduino IDEの機能であるシリアルモニターを立ち上げておけば、データを表示することができるので、これを利用します。ちなみに、Arduino IDEの機能であるシリアルプロッターという便利なものがあり、Arduino側でデータを出力すれば、IDE側でグラフをリアルタイムで書いてくれ、オートスケールまでしてくれます。

面倒なのはArduino側で並列データの概念が無く、bitの入出力しかないため、アドレスのライトはbitに分解し、データのリードはbitを統合してやる必要があることです。以下にパラシリ、シリパラ変換を示します。

16ビットアドレスの分解(パラ⇒シリ)

int apb = 54;
boolean b;
unsigned address = 0x8000;
unsigned ad;
 :
ad = address;
for (int i = 0; i < 16; i++) {
 b = ad & 1;
 digitalWrite(apb+i, b);
 ad = ad >> 1;
}

このコードの動作図を図157.1に示します。

図%%.1
図157.1 パラシリ動作図解

8ビットデータの組み上げ(シリ⇒パラ)

int dpb = 39;
boolean b;
unsigned data;
 :
data = 0;
for (int i = 0; i < 8; i++) {
 data = data << 1;
 b = digitalRead(dpb-i);
 data = data | b;
}

このコードの動作図を図157.2に示します。

図%%.2
図157.2 シリパラ動作図解


左矢前のブログ 次のブログ右矢

FM7 ROM吸出し器の製作

posted by sakurai on August 24, 2019

設計編はこちらです。

FusionPCBからベースボードが届きました。今回はベンダによる部品実装は無しで、2層ボードのみの製造なので4.9 USD+配送料と、格安です。 今回は製造に6.85日、DHLによる配送に3.34日かかりました。

図%%.1
図156.1 FM7ROM吸出しベースボード

ベースボードとArduino Mega 2560 Proボード及び40pinコネクタの写真です。この他に動作確認用のLED及びそのドライバTr、抵抗があります。

費用は配送料別で、Arduino Mega 2650 Proが975円、基板が上記のように522円、コネクタが(写真のコネクタではなく、純正のFCN-365P040-AU)が743円、合計2,240円でした。この他に配送料が若干かかっていますが、2つの目的である、

  • FM7側にソフトウェアを置かないこと(FM7側にはファイルシステムが無いため管理できない)
  • 価格が安いこと

が達成できました。

図%%.2
図156.2 部品一式

組み立てました。動作確認をするため、基本動作に無関係なLED等は未実装としています。

図%%.3
図156.3 FM7 ROM吸出し器


左矢前のブログ 次のブログ右矢

6809の割込み動作(8)

posted by sakurai on August 23, 2019

IRQ/FIRQが正常動作したので、メインCPUとサブCPUの協調動作を実行してみます。

  1. メインCPU
  • サブCPUのreadyを待つ
  • サブCPUをhaltする
  • 共有メモリにデータを書き込む
  • 共有メモリの先頭のMSB=0で指示とする
  • サブCPUのhaltを解除する
  1. サブCPU
  • リセット後サブCPUの状態はハード的にbusy
  • サブCPUの状態をreadyにする
  • 共有メモリの先頭のMSB==0となるのを待つ
  • サブCPUの状態をbusyにする
  • 共有メモリの内容をデコードする

図%%.1
図155.1 協調動作フローチャート

このフローに基づき、協調動作のシミュレーションを行ったところ、正しく動作しました。


左矢前のブログ 次のブログ右矢

6809の割込み動作(7)

posted by sakurai on August 22, 2019

タイムチャートを見直すと、例外処理中でEフラグをクリアする処理は入っていますが、一方のセット信号が初期状態からずっと不定です。このため、Eフラグが不定となっているようです。従って、セット信号を初期状態でネゲートします。

図%%.1
図154.1 割込みタイムチャート

k_set_eの初期化をしたところ、正しく動作しました。このIPは総じて割込みの実装が中途半端にしかされておらず、割込みは実質テストしていないようです。プロセッサにおいて割込みが動作しないのは致命的であり、使い物になりません。


左矢前のブログ 次のブログ右矢

6809の割込み動作(6)

posted by sakurai on August 21, 2019

次にFIRQを実装します。同様にFフラグセット、クリア論理を入れましたが、割込みハンドラまでは正しく動作するものの、RTI命令の実行時にスタックを過剰に回復しています。積んだ以上に回復するという、いわゆるスタックアンダーフローを起こしてしまいます。

図%%.1
図153.1 割込みタイムチャート

まず、FIRQの動作を見てみると図153.2のようになります。Eフラグをクリアしてからpushすると書かれていますが、クリアされずXとなっています。

図%%.2
図153.2 FIRQの動作

次に、RTIの動作を見てみると図153.2のようになります。Eフラグは0であるべきなので、スタックからはCCR及びPCのみが回復されるはずです。が、タイムチャートではさらに他のレジスタも回復しているようです。

図%%.3
図153.3 RTIの動作

この誤動作の原因は、CCR[7]のEフラグが不定となっていることです。従って、図153.2にあるとおり、例外処理中でEフラグをクリアする処理を入れれば動作するはずです。


左矢前のブログ 次のブログ右矢


ページ: