目的
Tang-Nano-9Kの上位機種としてTang-Primer-20Kなるものが売られている事を聞きつけ、入手手配を行った。
GithubではTP20(Tang-Primer-20KをTP20、Tang-Nano-9KをTN9と以下略す)によるfpganesの動作例が掲示されている。
※fpganes fpga上でnesを動かすソフト。
※nes ファミコン(通称)の米国内での略称。
TP20クラスで無ければfpganesは無理だろうかな、いや、そんな事は無いだろう。
TN9だってできる子じゃ無いのかな。
◆◆◆ そうだ、Tang-Nano-9Kでfpganesを動かすぞ ◆◆◆
marioを動かすことでも目標にするかな。
TN9の内蔵RAM容量が心もとないが、気合で何とかなるだろう。
方針
FC(以下ファミコンをFCと略す)は、言わずと知れた日本発祥のゲーム機。
エミュレータも多数出ており、fpganesはその一種でFPGAで構成する。
FCは本体外のカートリッジに、プログラムROMとキャラクターROMを収めている。
一世を風靡したmarioの場合、プログラム32KB、キャラクター8KBで構成されている。
元ネタであるfpganesは、Nexys4の16MBの大容量疑似SRAMを、時分割で振り分けて動かしている。
※お値段もTN9の20倍ぐらいですが。
TN9の内蔵RAM容量は52KB(8bit換算)、これならいけると思うかもしれないが、ワークとして4KB、カラーテーブル等の内部処理に10KB必要であり、計54KB無いと動かせない。
※コンパイルしてエラーが発生してから気が付いた、お粗末な話ですが。
※プログラム16KB、キャラクター8KBの初期カートリッジなら内蔵RAMだけで動かせる。
そこで、プログラムエリアにはDDRAMを割り当て、RAM(32KB)をキャラクターに全振りする作戦に変更。
これは何とかうまく行った。marioがTN9単体で(一応)動作可能となっている。
※勿論、カートリッジデータは各自で用意が必要です。
下記に仕様を示す。
◇表示はHDMIポートに出力、VGAモニタは必要無し。
◇音声は疑似アナログ信号として出力、イヤーホン等で聴取可能。
◇プログラム(カートリッジデータ)は、起動時にPCよりダウンロード。※fpganesの基本仕様
◇コントローラーはPCのキーボードで代用。※fpganesではゲームコントローラーが前提
ご参考
「fpganes Tang-Nano-9K バージョン」
「fpganes Tang-Nano-9K ローダー」
「fpganes Tang-Nano-9K モニター」
必要な開発環境とLicense
□Tang-Nano-9K 2K円ちょいで入手可能(シ〇ゾーンは入荷待ち、秋〇は販売中)。
□開発ライセンス 「Tang Nano、Nano9KのIDEであるGowin EDAをインストール(Winのみ)」に詳しく書かれています。
□HDMIディスプレィ及びケーブル
動作クロック
FCを動作させるマスタークロックとして21.477MHzが必要だが、PLLで分周できないので21.6MHZで動作。
FCのCPU(6502)は之を12分周した1,8MHzで動作している。
HDMIには126MHzを与える事により、640x400のVGA信号相当がHDMIに表示可能になる。
DDRメモリには166MHZが欲しい所だが、TN9にはPLLが2個しか無いので、HDMIと兼用して126MHzを与えている。
プログラム用メモリ
PSRAM(内蔵DDRAM)を割り当て居ると言ったが、アクセスタイムの確保が悩みの種。
PSRAMはバースト(連続)アクセスにのみ対応で有り、1byteの読み込みにも32byteの読出しが必要となる。
バースト一回(BurstMode:16)には24cycl必要であり、インターフェースを83MHz(メモリは166MHz動作)で動作したとしたメモリ単体でのアクセスタイムは289nsと計算される。
※実機ではPLLの都合により83MHz(メモリ128MHz)で動作させており、アクセスは380nsと計算される。
※PSRAM自体はもう少し早く動くが、IPを使う限りはこうなる。
FCのCPUはシステムクロック21.6MHz(本来は21.477MHz)を12分周して1.8MHz(本来は1.789MHz)で動作、アクセスは555nsとなるのでこれならマージンが有る事になるが、制御の都合だろうがfpganesでは、8分周と16分周によるアクセスを交互に行っている。
8分周の場合アクセスは370nsとなり、PSRAMのアクセスタイムでは僅かに不足する。
これを補うために、回路の途中より制御信号を取り出し、DDRAMは常時12分周相当で動作させている。
※全体の動きを把握していないので、この取り出しが正解の自信は無い。
HDMI
画像はHDMIポートより出力している。
fpganesがVGAに準拠した信号を発生させていたので、多少の調整でHDMI表示が可能であった。
※sync信号を反転させ、blnk信号の追加により表示が出て来た。
但し、調整して無いので4:3の画像が9:6の画面に表示されている。
※marioがでぶっちょになっているが、別に問題は無いだろう。
音声出力
fpganesは16bitデジタル信号をシリアライズして、ステレオ信号として送出している。
※同一データをサンプルしており実質モノラル。
TN9はDACを持っていないので、これではこの音を変換する機器が別途必要となる。
そこで、16bitデジタル信号をでDeltaSigma処理でアナログ化しており、イヤーホン等での聴取が可能。
アナログ信号はTN9の30ピン(TN9背面に記載の数字)に出力している。
※聞くに堪えるレベルかどうかは疑わしいが。
※イヤーホン直接接続でも壊れなかったが、1KΩ程度の直列抵抗を入れるべきだろう。
※HDMIへの出力も技術的には可能と思うが、かなりの追加ロジックが必要のようだ。
ローダー
実行プログラムはPCのloader(DOSプログラム)からシリアル経由でダウンロードする。
※loaderはVS2017でコンパイルした。
VSでDOSのテンプレートを作成して、cppの中身を移し替えればコンパイル出来るだろう。(多分)
プログラムはカートリッジから吸い出した後、予めiNES形式のヘッダーを付けてファイル化しておく。
loaderの起動コマンドを下記に示す。
loader xxxx.nes COMx kb
xxxx.nes ロードするプログラム
COMx 通信に使うポート(ディフォはCOM4)
kb PCのkbをコントローラーとして使用する
TN9を起動させるとLEDが点滅を始める。
この状態では、HDMIは細い白縁のみが表示されている。
※何も出ない場合は、信号が出ていない可能性が高い。
loaderを起動し通信が始まると、点滅が早くなる。
※通信速度は115200bpsだが、もっと早くても良いかも。
完了するとLEDは点灯状態となり、HDMIへの表示が始まる(はず)。
※エラー又はkbを使用しない場合、DOS窓は即座に終了。
コントローラー
loaderでkb指定をしていた場合、PCはコントローラーの役目を担う。
※原本はxbox用のコントローラーがディフォらしいが、この時点では所持して無かったので。
ボタン設定は下記となっている。
'1'又は','が'A'釦
'2'又は'.'が'B'釦
'3'又は'SHIFT'が'SELECT'釦
'4'又は'ENTER'が'START'釦
カーソルキーで上下左右移動
'ESC'でloaderは終了する。
iNES形式
カセットからコピーしたデータは、動作の識別の為にヘッダーが必要になる。
16byteのiNESヘッダーを作成し、プログラム、キャラクターデータを繋げばファイルは完成。
ヘッダーの作りは、「TNESヘッダをiNESヘッダに変換」等に書かれています。
理解できなかった場合は、「NES研究室のサンプル」等を見れば判ると思います。
marioはプログラムが32KB、キャラクターが8KBなので、ヘッダーとして下記を設定。
4E 45 53 1A 02 01 00 00 00 00 00 00 00 00 00
ここで'02'はプログラムサイズ(16KBx02=32KB)、'01'はキャラクターサイズ(8KBx01=8KB)となり、合計で40,976byteのファイルとなります。
モニター
一応モニターも作りました。
mon.nesをロードすると、mango1(6502モニタ)が起動します。
※NES研究室のHello, World!に、mango1モニタを追加したものです。
※アセンブルにはNESASM3.exeが必要、
「nespowerpak.com/nesasm」の物を使ったが、ご使用は自己責任で。
※mango1はapple1モニタのもじりらしいが、今となっては何処から持って来たのか定かでない。
通信速度は115200bps、loaderを終了させてターミナル(teraterm等)の起動が必要。
起動時にターミナルに'#'が表示されます。FC画面はHello, World!が表示されます。
mango1モニタのコマンド
Rxxxx xxxx番地を読み込む。
Wxxxx xxxx番地に書き込む。
DDRAMのデバックには重宝したが、IOとして変な番地(4020)を使っているので邪魔なら外して下さい。
※2040-204f番地に定位している、動作に支障が出て無い事は一応確認している。
※nes.vの223行当たり。sarcsに'0'を代入すれば見えなくなる。
モニターを拡張する前にFCとして動いてしまったので、ショボいまま放置となった。
未解決事項
キャラクターエリアを32KBとし、CPU側のメモリを全てDDRAMにすると、marioが有り得ないワールドに行くと言う珍現象が発生。
※X-1とか、' '(キャラクターでは無い)-1とか。
ワークエリアの初期クリアとか、タイミング調整等を試みたが改善しなかった。
キャラクターエリアを16KBにし、CPUのワークをSRAMにすると、1-1ワールドからスタートするようになったので、そのまま放置。
※キャラクターエリアを32KBにすれば、dorakue1は起動するのだけど。
※nestang(fpganesのTP20への移植)でも同様の現象を確認、marioがミラーRAMを利用して居るのかも。
キャラクターエリアを32KBにしたい場合は、NES_TN9.vの先頭に記載の、//`define Use32Kのコメントを外せば32KBになるので、必要なら試されたい。
NESTang
TP20(Tang-Primer-20K)の入手に時間がかかると思っていたが、意外に早く入手できたので、ついでに味見
NESTangはfpganesのTP20へのインプリ。
元ネタのNexys4の疑似SRAMを、DDR3メモリで置き換えているとか。
※SRAMのアクセス速度を、DDR3で出すことがキモ。
※画面も4:3で表示されている。
※HDMIからの音声は確認できていない。
完動品なので追試の必要は無い筈だが、当方環境では多少の手入れが必要だった。
NESTangのプロジェクトでは初期のピンアサインはnestang.cstで指定している。
なので、ドックを使用している場合は、nestang_dock.cstを有効ににしないと画面が出ない。
初期画面の「colorful NES palette」とは、下記のパレット表示画面の事だろう。
XBOX用のUSB接続のコントローラーを入手したが認識せず。
これは、コントローラーがID=1と認識されており、ID=0が無いと判断されたもの。
※当方の環境の問題とも思われるが。
ID=1でも動作するutil(TP20).cppを添付しておく、必要なら差し替えてください。
※コントローラー無しでPCから操作する方が良かったかも。
感想
TP20到着までの繋ぎのつもりで着手したが、意外と早く動いてくれた。※TP20も意外と早く到着したが。
FPGAによるFCエミュは6年前にも手を付けており、この時は出来合いのソフト動かすだけであった。
今回はFPGAも異なる別ボードへの移植を行い、コア部分には手を付けて無いが、多少の改造も行った。
大した事無いと言われればそれまでだが、多少は技術が進歩していると言う事だろう。
FCのカートリッジは物によっては二束三文であり、fpgaのステップターゲットとしてfpganesは良い材料かも知れない。
なお、上記記載内容は全て無保証であり、各自の責任においてご利用願います。