見出し画像

X68000 V-SYNCがない??

 いろいろなことに興味を示しつつどれも中途半端なhonでございます。
ということで、Z80も実物が動くようになって一段落ついたので再びX68000へ戻ってきました。某ZUIKIの「Z-CLUB 部室放送」も100回を迎えたということ、めでたいですね。
 もう前回、何を書いたのか忘れている爺ではありますが、今回はリハビリも兼ねて再びV-SYNCです。

 X68000のハードウェア解説本を見てもV-SYNCの項目がありません。ゲームも主力にしていたX68000にV-SYNCがない??そんなことはあろうはずがございません。
 実際にV-SYNCの信号を使っていたのはファミコンくらいまでで、X68000の時代になるとV-DISP(各社名称は違う)という信号を使うのですね。(これだから素人は困ると言われるレベルです)
 V-SYNCで制御するより、V-DISPで制御する方が少しだけ使うことができる時間が長くなります。この少しがゲームの世界では重要なのです。

MFP (Multi Function Peripheral)

68901というICですが、キーボードとのやり取りや、各種割り込み制御を行っているICです。V-DISPもこのICが面倒見てくれます。
V-DISPの信号がどこで取得できるかといえば、アドレスE88001Hで取得できます(Read only)

GPIP データレジスタ 
E88001H
ビット: bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
信号名:
[H-SYNC][ (他) ][ (他) ][V-DISP][FMIRQ ][POW SW][EXPON ][ALARM]
 V-DISP
0:V-DISP ”L"  垂直帰線期間
1:V-DISP ”H" 垂直表示期間

スーパーバイザモード(特権モード)

上記のレジスタに触れようとするとユーザーモードでは例外が発生します。
ですから、ゲームは特権モードで動かすことになります。(そうしないとV-DISP信号が拾えない)

B_SUPER
    /* 下のコードは説明のための抜粋です */

    /* V-SYNC同期(ハードウェア直接監視)用のポインタと、スタック退避用の変数 */
    volatile unsigned char *gpip;
    int ssp; /* スーパーバイザ移行時のスタック退避用 */

    /* スーパーバイザモード(特権モード)へ移行します */
    /* これにより、システムI/O領域 $e88001 への直接読み取りが許可されます */
    ssp = B_SUPER(0);

    /* ハードウェアレジスタのアドレス設定 */
    gpip = (volatile unsigned char *)0xe88001;

    /* --- 同期フェーズ (V-SYNC) --- */
    while ((*gpip & 0x10) == 0) ;
    while ((*gpip & 0x10) != 0) ;
    /* ここで一気に描画します */

    /* ユーザーモード(通常の安全なモード)に戻します */
    B_SUPER(ssp);


メインループに入る前に、スーパーバイザモード(特権モード)へ移行します。
そして、最後にユーザーモードに戻してゲームを終えます。

繰り返しですが
MFP GPIPレジスタ ($E88001) の8ビットの構造:

ビット: bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
信号名:
[H-SYNC][ (他) ][ (他) ][V-DISP][FMIRQ ][POW SW][EXPON ][ALARM]
                                         ▲ここを見たい!

    volatile unsigned char *gpip;
    /* ハードウェアレジスタのアドレス設定 */
    gpip = (volatile unsigned char *)0xe88001;


*gpipのポインタにはvolatileという型修飾子が付いています。これはコンパイラに最適化させないということです。
while ((*gpip & 0x10) == 0){  } ; 説明のため{}を付けている
このwhileのループの中で*gpipはいじってないのでコンパイラが勝手に固定値として扱ってしまうのを防ぐためです。(*gpipの内容はハードウェアが書き込む内容)volatileを付けないと意図した動作にならなくなってしまいます。
ちなみに *gpip & 0x10の部分は、いつぞや書いた通りビット演算を行います。00010000(2進数)の位置のビットを拾っています。

そんな感じで、V-SYNC同期処理を行います。
これで、V-SYNC同期を行うためのすべての材料が手に入りました。
 それにしても、内容は変わってもいまだにV-SYNCという言い方が一般的なのが面白いところです。スマホの時代でも「写メ」っていうのと似てますね。

2026.8.7


いいなと思ったら応援しよう!

この記事が参加している募集