X1turbo Agency

X1turbo Agency ブログ

8bitコンピュータ X1turboの探求サイト

X1turbo Agency

X1turbo CRTCでの縦スクロールテスト

X1turbo CRTC制御による縦スクロールテスト

X1turboで縦方向のスムーズなスクロールは可能だろうか?
実現のきっかけは、スーパーターボさんがアップされていた以下の動画でした。

www.youtube.com

この中でX1turbo版ではカットされていた縦方向の画面スクロール部分を
CRTCで実現している箇所が衝撃的でした。
この動画を参考に、CRTCによる縦スクロール制御をテストを作ってみたのが以下の動画です。

www.youtube.com

CRTC縦スクロールの仕組み

CRTC 各レジスタを調整する事で縦スクロールを実現します。
まず レジスタR5を変更して、画面全体のラスタ位置調整して画面全体を上下させる事ができます。
しかしある程度の値を設定すると同期がずれて画面が崩れてしまいます。
次に、行のラスタを調整しているレジスタR9を書き換える事でラスタ総量を調整します。

例として、画面全体に1ライン下に下げる時は、R5値を+1して、
最終行のR9値を-1して全体のラスタ総量が変わらないようにします。

このレジスタR9を変更するのは走査線が最終行に差し掛かった時に行う必要があります。
それ以外のタイミングではR9を初期値に戻しておかないと同期ずれが発生します。

f:id:x1turbo_agency:20210404163438p:plain
CRTCレジスタ (「試験に出るX1」から引用)

これでラスタ単位の縦シフトが0-7まで実現できたので、あとは画面全体の8ドット単位のスクロールを
行います。CRTC R12,R13による描画開始位置を設定するのが処理負荷を下げやすいです。

R12,R13レジスタの値は、VSyncが終了する直前に設定されるので、画像表示期間中に変更しても
反映されません。即時反映する事ができれば、部分スクロールなどが実現できたのですが…
そうなるとティアリングで画面が壊れやすくなっていたでしょうね。

実装

最初のテスト版はVSyncや走査線チェックをCPUポーリングで行いました。
これらを非同期に行うため、その後CTC割込み版を実装しました。
上の図の緑色の吹き出しの箇所で割込みを発生させています。
CTC0を割込み中にリセットして再設定することで、より細かい制御が可能です。

サンプルプログラム

  • CRTCによるスムーズな縦スクロールのサンプルを githubに公開しました。
  • 検証やツッコミがあればレポートをお願いします。

2021/04/17 ソースファイルをgithubに公開しました。 github.com

f:id:x1turbo_agency:20210417225716p:plain
CRTC縦スクロールサンプル

TIPS

画面マスク

画面上部はCRTC R5レジスタ値を反映して何も表示されていません。
スクロールが見えないようにするためには、GRAMであれば描画量を調整し、
PCGであればマスクを上に載せる必要があります。
テスト版ではPCGの上にGRAMが表示されるように設定を行って、
スクロール値に合わせてマスクしています。

走査線の位置確認

走査線が今どの辺にあるかが判らないと調整しにくいです。
パレット0を一度黒以外の青とかに設定することで現在の走査線の位置を確認できます。
これを使ってどの走査線位置に割込みが起きているかを判定します。

パレット設定に失敗するタイミング

VSync中にパレットを変更するとパレットの反映が遅くなる事があるようです。
VSync中でない画像表示期間タイミングでパレット設定を行うと正常に設定されています。
この辺りはX1turboの機種によっても変わるかもしれません。

VSyncタイミング

1a01h pb7でVSyncの開始/終了を検知しています。
ところが、VSyncの終了検知したはずなのに、まだ VSyncが終わっていませんでした。
そこで、VSync開始時にタイマー割込みをセットして、VSync終了後最初の走査線に
差し掛かるタイミングを検出するようにしました。

VSync終了時に次のVSync割込みを設定しますが、
その際に一度HSyncを待たないと割込み位置が安定しませんでした。

HSyncを待つには

細かい走査線をチェックする上でHSyncを待たないといけない場面があります。
その場合は、PCG高速モードにして適当にCG読出しを行うと、HSyncを待つ事ができます。
HSync中でないとPCG/CGデータを読み出す事ができないためです。

動作検証とエミュレータ

動作検証はエミュレータ上では走査線ごとのCRTCレジスタ書換えに対応していないため、
実機で行う必要があります。
ただ、CRTCについては、かなりの再現度で武田さんのエミュレータは実機同様の動作を
しており、R9が即時反映されない以外は、VSyncタイミングのずれなども含めてほぼ完璧に
再現されています。

検証の度にFDDにプログラムを書込んでいたのでは検証に時間がかかるため、
X1turboRemoteMonitorでプログラムを転送/実行する機能を追加しています。
こちらは他機能が検証できたら公開したいと思います。

サウンド

CTCを画面制御に使っている関係で、サウンドの制御はVSyncタイミングで行えればと思っています。
X1turboのVSyncは15KHz,24KHzいずれも60fps丁度ではないので、サウンドのテンポの問題があります。

今後の改良

X1turbo用で解説していますがX1でも使用できるはずです。
CTCを搭載したX1で、HSyncをタイマー等で調整できれば同様に使えると思います。

今回はVSync中の処理時間もあって15KHzモードで実装しています。
24KHzでも一度試してみたいですね。