ソフトCRTC for SH7046


稼動中の全景

戻る


・発端

 SH2 50MHzクラスになると、ほとんどソフトのみ*1でモノクロビデオ信号を作れるのではないか、と思い試してみました。

 今回作ったのは128×96ドット、4階調のグラフィックを出力するものですが(P/ECEより縦8ドット多いです(笑))、このスペックだと16クロックぶんの時間で1ドット出力すればよいことになり、RISCチップであるSHには楽勝です。*2

 同じような試みは、昔トランジスタ技術誌にPICでソフトだけでブロックくずしゲームを作った例などがありましたが(すみません、何年の何月号か忘れてしまいました)、画面表示にほとんどCPUパワーを食われてしまい、それ以外の計算などの処理はわずかな垂直ブランク期間にしかできないためPICあたりだとかなり苦しく、あまり高度なことはできないと思います。
 今回使ったのはSH2クロック49.192MHzですが、単純計算して走査線263本のうち192本ぶんの時間を画面表示に費やしたとしても、49.152×(263-192)÷263=13.269であり、まだSH2クロック13MHz相当のCPUパワーがあることになります。*3
 SH2クロック13MHzと言えば、低く見積もってもH8/300Hのクロック25MHzに相当し、Z80ならクロック150MHz以上に相当します。画面表示にCPUパワーの大半を費やしていながらなお、少し古いマイコン(H8/300Hは現役ですが)と同等以上の余力を残しているのですから、あらためてSHってすごいCPUだなと感動します。

*1
 ソフトCRTCとは言っても実際にはデジタル→ビデオ信号変換のために若干の抵抗、コンデンサ、ダイオード、トランジスタを使った回路が必要ですが、あまりうるさいことを言うと「純粋にソフトだけで作れるものなんて実は何もない」ということになってしまいます。たとえば、いわゆる「ソフトウエアシンセサイザー」なんてのもアンプとスピーカーがなければ音は鳴らないわけです。今回の回路は本当に単純な信号レベル変換回路のみであり、以前作ったようなCPLDやRAMを使い100本以上も配線する複雑な回路←このリンク先の回路を使用するにはこのページの回路も作る必要があります)を組まなくてもビデオ信号が出せるのですから、「ソフトCRTC」と呼んでもさしつかえないと思います。
*2
SHは、ほぼ1命令1クロックと考えて問題ありません(パイプラインストールなどを考慮する必要はありますが)。一方、CISCであるH8/300Hは1命令2〜20クロックの時間がかかり、たとえ50MHzのH8があったとしてもソフトだけでビデオ信号を作るのは無理だと思います。
*3
実際には垂直ブランク期間中にも割り込みでほんの少しCPUパワーを食われています。一方、水平ブランク期間中にもCPUを開放していますので、計算するのは単純ではないです。



・原理

 ビデオ信号のタイミングを作るのにMTUを使います。63.5μ秒周期でタイマクリヤするように設定します。また、PWMモードにより通常は4.7μ秒、垂直同期時には63.5-4.7μ秒の幅のパルスを出します。
 垂直表示期間中は、水平同期パルスを出してから一定時間後、VRAMの内容が輝度信号となるようD/A変換機(今回作成したハードウエア)に送ります。

 実際にはMTUのチャネル3を使い、コンペアマッチDで水平周期を作りだし、コンペアマッチCで同期パルスの幅を決めています。コンペアマッチAでVRAM内容をD/Aに送る処理を起動します。

 割り込みはコンペアマッチDとコンペアマッチAでかけています。
 コンペアマッチDでPWM機能により同期信号がONになると同時に割り込みがかかります。割り込み処理(ラベル名はSYNINT)では今垂直表示期間なのか、垂直ブランク期間なのか、垂直同期期間なのかを判断し、垂直表示期間であれば表示割り込みを許可します。また、垂直同期期間であるか否かによってTGRC_3の値を設定し、同期パルスの幅を決めます。
 コンペアマッチAにより表示割り込み(ラベル名はDSPINT)がかかります。割り込みがかかったら現在のライン位置からVRAMの番地を計算し、1ドット16クロックで128ドット出力します。

 タイミングチャートをこのページに描きましたので参照してください。

 VRAM構成は、1バイトに4ドット詰め込んだパックトピクセル形式にしました。私はパックトピクセルは好きではないのですが、SH7046の内蔵RAMのサイズを考えると1ドット=1バイトにするとかの無駄なことはできません。
 VRAM容量は128×96÷4=3072バイトです。内蔵RAMの先頭、$FFFFD000番地から3072バイトをVRAMとして使用します。これだけVRAMに割いてもまだ内蔵RAMは9Kバイト残っており、H8/3052の内蔵RAMよりまだ多いです。BASICを走らせてもフリーエリアは7Kバイト以上残ります。


・ソフトCRTCのソース

 ソフトCRTC内蔵超ミニBASIC for SH7046の、ソフトCRTCに関する部分の抜粋です。長いので別ページにしました。


・ほんのちょっとだけ、ハード製作

 最初にも書きましたが、SH7046が出力する5Vレベルのデジタル信号をそのままテレビに入れるわけにはいかないので、ちょっとした変換回路が必要です。



 これが回路図です。CPLDも外付けRAMも要りません。この簡単な回路と、SH7046ボード、5Vの安定化された電源があれば、ビデオ信号が出力できるのです!

 CPUはポートEのビット8、9に2ビットのデータを出力します。それを電流加算型D/A変換機でアナログにします。PE8、PE9がともにLレベルのとき、出力は約0.3Vになります。ともにHのとき出力は約1.0Vになります。
 MTUのPWM機能によってTIOC3C端子(PE10)に同期パルスが出力されると、この回路の出力は0Vになります。

 前に作ったLCDC改造CRTCでは、同期パルスON時エミッタフォロワの出力をショートしていましたが、今回は入力側をショートしています。以前はCPLDで動かしていたので、たとえプログラムミスなどでCPUが暴走してもビデオ輝度信号と同期信号が同時にONになることはありませんでしたが、今回はソフトで動かしているので、暴走した場合同時にONになることもありえます。同時にONした場合、以前のようにエミッタフォロワの出力をショートする回路だと大電流が流れるので、入力側をショートするように変えました。



 今回は、CPUボードはビーリバーエレクトロニクス社のSH7046ボードを使用しました。ツクモのロボコン館で購入しました。

 部品面です(CPUボードは外しています)。5V電源を3端子レギュレータで作っています。2つのコネクタの間にあるのが信号レベル変換回路です。


 ハンダ面です。本当にこれだけの配線でビデオ信号が出せてしまうのです。


 毎度のことですが、できあがったらシツコイくらい徹底的に配線ミスがないかどうか確認します。配線に問題なければ、SH7046に「ソフトCRTC内蔵超ミニBASIC for SH7046」を書き込み、出力をテレビのビデオ入力端子につなぎます。
 また、SH7046ボードのシリアル端子はパソコンのRS−232C端子につなぎ(内蔵ROMに書き込む際パソコンから書き込んだのならすでにつながっているはずですのでそのままでOKです)、パソコンのシリアルターミナルソフトを立ち上げておきます。

 そして電源を入れます。シリアルターミナルソフトの画面には超ミニBASICの起動メッセージが表示されるはずです。何も出なければ何らかの異常ですので即SH7046の電源を切って配線等をチェックしてください。
 無事起動メッセージが出たら、シリアルターミナルから

と入力しENTERキーを押してください。テレビのほぼ画面いっぱいに白い長方形が表示されればOKです。


・画面表示例

 とりあえずアニメ調の女の子をを表示してみました。テレビとデジカメの相性が悪く、変なモアレが見えますが肉眼で見るとこのようなモアレはありません。


 3次関数のグラフを表示してみました(笑)
10 GCLEAR
20 FOR X=0 TO 127:PSET X,48,1:NEXT
30 FOR Y=0 TO 95:PSET 64,Y,1:NEXT
40 FOR X=-64 TO 63
50   Y=X*X*X
60   PSET X+64,48-Y/1000,3
70 NEXT



・ソフトCRTC内蔵超ミニBASIC for SH7046

 超ミニBASIC for SH7046の標準版に、ソフトCRTCを組み込みました。大急ぎで作ったので、まだグラフィック用の文はGCLEAR文とPSET文しかできていません。今後充実させていく予定です。
 ここではグラフィック関連の文について説明します。グラフィックと関係ない文・関数については標準版と全く同じですので、標準版をダウンロードして同梱されているテキストを参照してください。

追加された文

《 GCLEAR文 》

書式:

 画面をクリヤします。<輝度>を省略すると0(真っ黒)で、指定した場合は指定の輝度でクリヤします。<輝度>の範囲は0〜3で、数値が大きいほど明るくなります。範囲外の値を指定した場合3でANDをとった値が有効になります。

《 PSET文 》

書式:

 画面上の<X位置>,<Y位置>で指定される位置に、指定の輝度で点を打ちます。<X位置>の範囲は0〜127、<Y位置>の範囲は0〜95、<輝度>は0〜3です。パラメータの省略はできません。位置が範囲外の場合は何もしません。輝度は3でANDをとった値が有効になります。

・ダウンロード

ソフトCRTC内蔵超ミニBASIC for SH7046(cmb7046v.zip)をダウンロードする
(データコンバータ同梱)


ダウンロードしたファイルは+Lhaca、Winzipなどの解凍ソフトで解凍してください。
※このアーカイブ中にはソースプログラム(cmb7046v.asm)と実行プログラム(cmb7046v.s)、データコンバータ(cnvsoftcrtc.exe)しか入っていません。このページを見ていない人には使い方がわからないので、他で再配布しないでください。


・ソフトCRTCはどれだけCPUパワーを消費する?

 ソフトCRTCがどれだけCPUパワーを消費しているのか調べるために、超ミニBASIC for SH7046の標準版と比べてみました。いつものベンチマークです。

 結果は、驚いたことに、思ったほど速度低下しておらず、標準版の半分程度の速度です。1/3くらいになると思っていましたが意外でした。CPUパワーの大半を画面表示に食われているにもかかわらず、H8/3052よりはるかに高速です。

実行環境

CPUクロック

実行時間

超ミニBASIC for SH7046標準版

49.152MHz

約7秒

ソフトCRTC内蔵超ミニBASIC for SH7046

49.152MHz

約16秒

(参考)超ミニBASIC for H8/3052

25MHz

約38秒




(付録)データコンバータの使い方

 いつものように(笑)、BMP画像から超ミニBASIC用POKE文スクリプトを生成するデータコンバータを作りました。Windows用です。Windows98、WindowsXPで動作確認しました。今回はコンバータはソフトCRTC内蔵超ミニBASIC for SH7046のアーカイブに同梱しています。

 起動したら、Openボタンを押すとファイルを開くダイアログが出るので、開きたいファイルを選んでください。なお、変換できるのは幅が4〜128ドット、高さが4〜96ドットのBMPファイルです。幅は4で割り切れるサイズにしてください。

 ファイルを選ぶとその内容が表示され、Convertボタンが押せるようになります。

・変換前に、タイリングするか否か、出力ファイルの拡張子を .txt にするか .cmb にするか選択できます。

 拡張子 .cmb は要らないような気もするのですが、MSX時代からずっと愛着がある拡張子なので切り捨てられません


・今回のデータコンバータは、出力番地は$FFFFD000番地に固定で変更できません。
・出力テキストに行番号をつけることはできますが、内蔵RAMの容量が少ないのでRAM上では実行できません。スタートアップスクリプト上でなら実行できるはずです。

 Convertボタンを押すと変換後の白黒画像のプレビューが表示され、拡張子を .txt または .cmb に変えたテキストファイルが生成されます。


 こんなテキストファイルが出力されるので、BASICのコマンド待ちのときにこれをシリアルターミナルに貼りつけてやれば絵が出ます。
POKE $FFFFD000,$55,$15,$56,$AA,$AA,$AA,$AA,$AA,$A4,$15,$55,$55,$55,$54,$01,$55
POKE $FFFFD010,$55,$55,$55,$55,$55,$55,$55,$55,$50,$6A,$AA,$AA,$AA,$AA,$AA,$AA
POKE $FFFFD020,$55,$45,$46,$AA,$AA,$AA,$AA,$AA,$A4,$55,$55,$55,$55,$40,$55,$55
POKE $FFFFD030,$55,$55,$55,$55,$55,$55,$55,$55,$54,$1A,$AA,$AA,$AA,$AA,$AA,$AA
POKE $FFFFD040,$55,$05,$52,$AA,$AA,$AA,$AA,$AA,$A1,$55,$55,$55,$55,$01,$55,$55
POKE $FFFFD050,$55,$55,$55,$55,$55,$55,$55,$55,$55,$06,$AA,$AA,$AA,$AA,$AA,$AA
(以下略)