Tang-Nano-9Kで(今更)CPM80を動かす

# 目的
　Tang-Nano-9Kで取り合えずBasicは動いた。
　次に何をするかとつらつら考えた、適当に大きくて適当に小さいシステム。
　◆◆◆　そうだＣＰＭ８０を動かしてみよう　◆◆◆
　ありゃ、SRAMが64KBも無いぞ、どうしょうかな。
　まあ、何とかなるだろう。
![cpm_sart.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/c129862c-3ab5-47aa-abc0-d5dcffcf3c3d.jpeg)

# 経緯
　CPM80は知る人は知ってるでしょうが、1976年に発売されたフロッピーベースのＯＳです。
　その頃は今のディスクトップパソコン並みの筐体で動いていました。
　今では玩具(失礼)の様なFPGAで動いてしまいます。
　　※形とか値段は玩具のようだが、機能は玩具じゃ無いけど。
　CPM80を動かすに当たり元ネタは下記。機能的には単なる焼き直しです。
　　「[CP/M on FPGA](http://searle.x10host.com/Multicomp/cpm/fpgaCPM.html)」
　　※Grantおじさんは一時期行方不明でしたが、戻って来てるようです。
　但し、Tang-Nano-9Kで動かすに当たり問題点が２点

　◇Ｔ８０がコンパイルできない。
　8080(Z80)CPUとしてT80が使われているが、xilinxのプリミティブが使われているようでGOWINではコンパイルでエラーとなる。
　　※RAM16X1Dが無いと言われる。
　　※alteraのquartusではコンパイル出来るんだけどね。
　　※GOWINが同名のプリミティブを用意して居ないって事だろう。
　　　別件で確認したら、RAM16SDP1と言う分散RAMで何とか出来るようだが、コンパチに出来る自信がない。
　TV80を使う事により解決。CPUそのものは40MHzで動作させている。
　　※仮に40MHzで動作させてそのまま、80MHzでも動くかも。
　　※FZ0も試したが、「Find logical loop signal」という訳の分からないwarningが大量に発生。

　◇メインメモリが足りない。
　そもそもTang-Nano-9KのSRAM(BSRAM)は56KBしかないし、全部使えるわけでも無い。
　48KCPMにするって手も有るが、OSの再構築が必要だし、アプリで動かないものが出てきそう。
　そこで、DRAMをメインメモリに割り当てる事で解決を図った。
　　※8MBのメモリの内、64K子だけ使う贅沢な使い方です。
　これで64KCPM80として動作出来る。


# 開発環境のインスツールとLicense取得
　「[Tang Nano、Nano4KのIDEであるGowin EDAインストール(Winのみ)](https://qiita.com/yosiaki/items/2e635e115ecedabecc35)」に詳しく書かれています。
　　※前回申請時は梨の礫だったが、今回は翌日にライセンスがstrato_license@gowinsemi.comから到着。
  　　Macアドレス記載時にハイフォン無しにしたのが効果有りかも。
　LicenseにはEXP_DATEの記載が有るから、１年間有効なのだろう。

# サンプルソフト
　一応Githubに上げて有ります。
　　「[CPM80 on Tang-Nano-9K](https://github.com/hi631/tang-nano-9K)」
　本ソフトとTang-Nano-9K基板、コンパイラが有れば試行できる。(多分)
　もちろん、ターミナル(TeraTerm等)は必要ですが、ハードはコンパイル環境のままで動きます。
　　※Tang-Nano-9KはUSBシリアルも内蔵している。

　通信速度は115200bpsを設定していますが、諸般の事情でこの速度は出ません。
　通信遅延として、1ms/字、100ms/行の遅延を入れてください。
　　※CPM側のソフトが処理しきれない。


# メインメモリ
　メインメモリ全てにDRAMを割り当てると、CPM80は動作しなくなります。
　これはDRAMのアクセス速度が遅く、SDカードのR/Wに追従できない事から発生します。

　◇DRAMへのアクセス
　DRAM(PSRAM)は(約)160MHzで動作しており、ユーザーはIPを介して80MHzでアクセスを行う。
　バースト(連続アクセス)モードしか無いので、1Byte読む場合もバースト動作が必要。
　バーストの一サイクルには20clock(32Byteアクセスの場合)程度必要となる。
　従って、DRAMメモリへのR/Wは、80MHz×20clock=4MHz相当になる。
　　※DRAMアクセス中はCPUにはWaitを入れており、実質4MHz相当に低下する。

　SDカードとR/Wする為に、バッファとして使う番地にはSRAMを割り当てた。
　　※0000-0FFF,D000-FFFFの16KBがSRAM配置エリア。
　　　1000-CFFFにDRAMを割り当てている。此処がバッファの場合は正常動作しないだろう。
　　　取り合えず、コンパイラは正常に動作するが、ソース増量時はどうなる事やら。

　◇キャッシュ
　少しでも速度を稼ぐために、リードバッファにヒットした場合はバッファから読み出す。
　　※焼け石に水かも知れん。
　バッファしている番地に書き込む場合、キャッシュはパージしている。
　　※同一番地にR/Wした場合、キャッシュは効かなくなる。

# ＣＰＭ８０システムディスク
　システムディスクは、Grant氏の記述通りに行えば出来るが大変でしょうから、動作品を添付した。

　◇利用方法
　サンプルソフトのimageディレクトリに有る、CPM_BDSC(128M).zipを解凍しSDに焼けば出来上がります。
　SDカードは256MB以上が必要となります。
　　※BDS-Cも入れときました。フリーソフトになっている筈です。
　　※データは128MBなのですが、管理エリアが有るので128MBでは納まらない。
　　　イメージはwin32diskimager等のソフトで焼きこむ。

　◇パソコン上での更新
　ネット上で流通しているCPM80フリーソフトをディスクに入れる場合は下記ソフトを使用します。
　　「 [CpmtoolsGUI](http://star.gmobb.jp/koji/cgi/wiki.cgi?page=CpmtoolsGUI) 」
　diskdefsファイルが必要なので、サンプルソフトのimageディレクトリに入れときました。
　　※あまり使っていませんので、ドライブEまでしか設定していません。

　◇システムの再構成
　　GrantはCPM80を再構成するためのファイルも用意してくれています。
　　氏のホームページの下の方、DOWNLOAD FILES HERE で落とした distrib に含まれています。
　　　※TASMは直接動かせないので、「[MS-DOS Player](http://takeda-toshiya.my.coocan.jp/msdos/)」を使います。
　　TASMはHEXファイルを出力するので、tang-nanoに書き込むにはmiファイルにします。
　　　※hex2mi.zip内のexeを使ってください。※自作ソフトです。
　　　　「hex2mi basic.hex basic.mi 8192」 なんて打つとmiが出来上がります。
　　バッチファイルだとこんな感じになります。
　　　msdos tasm -80 source\basMon.asm hexFiles\basMon.hex
　　　hex2mi hexFiles\basMon.hex miFiles\basMon.mi > nul
　　　copy miFiles\basMon.mi ..\Tang_Nano_9K\cpm80\src\ROM\basMon.mi


# ＢＤＳ－Ｃ
　BDS-CはCPM80上で動作するＣコンパイラです。
　16bitのintを、8bitで処理しているので速度は期待できないけど、
　今更ASMはつらい場合に使用すると楽になります。

　◇BDS-Cの使い方
　まず、適当なエディタでソースファイル(xxxx.c)を作ります。
　コンパイルします。
　　CC xxxx (xxxx.CRLが出来上がります)
　リンクします。
　　CLINK xxxx (xxxx.COMが出来上がります)
　実行します。
　　xxxx
　プログラムの参考として、text.cを添付しています。

　◇エディタ
　EDを使える方はそれで、ダメな方はTEを使いましょう。
　TE(Ent)で起動するので、ソースを入力する。
　　※通信遅延を入れとけば、コピペ出来るのでソースをパソコンで管理できる。
　(ESC)を押せばOPTIONSメニューが表示される。
　キー操作はH(HELP)を選択して確認。
　　※スクリーンエディタだが、キーボードのカーソルキーは使えない。
　　　ダイヤモンド配列に慣れましょう。
　S(Save)若しくはA(save As)でファイル名を指定する。
　X(eXit)で終了。
![bds-c.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/41d26aac-07e0-13a8-8cb1-c60ca06fa39f.jpeg)


# 注意事項

　メインモジュールはverilogに書き換えています。
　　※趣味の問題と言うか、VHDLは余り使っていないもので。

　UARTにはリセットコマンド($03)を追加している。
　これは上記とも絡むが、UARTが無反応となる事が有ったため。
　　※basMon.asmにも変更を加えているが、サンプルソースには反映していない。
    　必要なら自分でbasMon.asmに追加してくれ。

　他社のコンパイラでは問題無く動作した信号が、GOWINでは命令文の一部が動作しないという不思議現象が発生。
　assign文で作製していた信号を、always文でクロックを与えた所、正常に動作。
　　※カウンタ出力をassign文で合成すると、グリッチが発生しているような気がする。
　　　勿論、当方の命令文の使い方が誤っている可能性も十分有るけど。

　Analyzer Oscilloscopeは非常に便利というか、アマチュアは之が無いと開発が進まない。
　他社のものは出力されない信号は無くなるのが通例で、keepするのがすこぶる面倒くさい。
　でも、表示点数を増やすとトリガが掛からなくなるような気がする。
　32bitデータなんかを表示させようとした日には、止まらない事は確実。
　　※32bit表示をやめれば元に戻るので、之が原因なのは間違いない。
　　　何か制約が有って、されを見逃しているのかも知れないが。
　只のものに文句を付けるのは非常識な気もするが、回避手段は無いものか。
 
# 感想
　1ByteのR/Wに32Byteも使うのは余りに無駄だとは思うが、他に代替案が無い。
　まあ、我慢できる程度の速度で動作しているので、此処ではこのままとする。
　tang-nanoでUSBシリアル欲しいと言ったが9Kでは標準で付いているので、便利に使える。
　なお、上記記載内容は全て無保証であり、各自の責任においてご利用願います。