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 |
ビデオ信号のタイミングを作るのに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内蔵超ミニ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した場合、以前のようにエミッタフォロワの出力をショートする回路だと大電流が流れるので、入力側をショートするように変えました。 |
と入力し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 |
超ミニBASIC for SH7046の標準版に、ソフトCRTCを組み込みました。大急ぎで作ったので、まだグラフィック用の文はGCLEAR文とPSET文しかできていません。今後充実させていく予定です。
ここではグラフィック関連の文について説明します。グラフィックと関係ない文・関数については標準版と全く同じですので、標準版をダウンロードして同梱されているテキストを参照してください。
書式:
画面をクリヤします。<輝度>を省略すると0(真っ黒)で、指定した場合は指定の輝度でクリヤします。<輝度>の範囲は0〜3で、数値が大きいほど明るくなります。範囲外の値を指定した場合3でANDをとった値が有効になります。
書式:
画面上の<X位置>,<Y位置>で指定される位置に、指定の輝度で点を打ちます。<X位置>の範囲は0〜127、<Y位置>の範囲は0〜95、<輝度>は0〜3です。パラメータの省略はできません。位置が範囲外の場合は何もしません。輝度は3でANDをとった値が有効になります。
ソフト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時代からずっと愛着がある拡張子なので切り捨てられません |
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 (以下略) |