にゃごすwiki

techhan/4.2


2章 MSX-VIDEOのアクセス


 前述のように、MSX-VIDEOはI/Oポートを通して直接(BIOSを使わず)アクセスすることが可能です。ここでは、その具体的な方法について説明しましょう。


 2.1 レジスタのアクセス


2.1.1 コントロール・レジスタへのデータ書き込み

 コントロール・レジスタは書き込み専用のレジスタです。前述のようにBASICからはVDP(n)を参照することによって、一部(R#0〜R#23)のコントロール・レジスタの内容を知ることができますが、これはレジスタへの書き込み時にRAM上のワークエリア(F3DFH〜F3E6H,FFE7H〜FFF6H)に記録しておいた値を読んでいるだけです。
 コントロール・レジスタにデータを書き込むには、以下に示す3種類の方法があります。ただし、MSXではスプライトの衝突発生などを調べるために、タイマ割り込みルーチン内でMSX-VIDEOをアクセスしているので、ここに述べた方法を用いてレジスタをアクセスする時には、割り込みを禁止してアクセスの手順が狂わないように注意してください。

(1) 直接指定によるデータ書き込み
 第1の方法は、レジスタの直接指定によるアクセスです。図4.2のように、ポート#1にまず書き込みたいデータを出力、続けて同じくポート#1に書き込みを行うレジスタ番号(上位2ピットは“10”としておく)を出力することによって行います。

    MSB   7   6   5   4   3   2   1   0  LSB
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
 Port#1│                              │  1.ポート#1にデータを出力する。
       └─┴─┴─┴─┴─┴─┴─┴─┘
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
 Port#1│ 1│ 0│R5│R4│R3│R2│R1│R0│  2.続けてポート#1にレジスタ番号の上位2ビットを“10”とした値を出力する。
       └─┴─┴─┴─┴─┴─┴─┴─┘
       └───┴───────────┘
          固定        レジスタ番号
         “10”         (0〜46)

図4.2 直接指定によるR#nのアクセス


 ポート#1は、2.2で述べるようにVRAMのアドレスを設定する場合にも用いられますが、どちらの動作を行うかは、このポートに2回目に送られるデータの最上位ビットを参照して選択されます。ここで述べたコントロール・レジスタへのデータ書き込みが実行されるのは、同ピットが“1”の時です。


(2) 間接指定によるデータ書き込み(非オートインクリメント・モード)
 第2の方法は、いったん目的とするレジスタの番号をR#17に書き込み、その値によって間接的に指定を行う方法です。まず、直接指定法を用いてR#17(コントロール・レジスタ間接指定レジスタ)にアクセスしたいレジスタの番号を設定します。以後は、ポート#3にデータを出力すれば目的のレジスタにデータを書き込むことができます。この方法はVDPコマンドの実行時など、同じレジスタに連続してデータを送る時に使用します。

1回目
    MSB   7   6   5   4   3   2   1   0  LSB
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
   R#17│ 1│ 0│R5│R4│R3│R2│R1│R0│  1.R#17にレジスタ番号nをセットする。上位2ビットは“10”としておく。
       └─┴─┴─┴─┴─┴─┴─┴─┘
       └───┴───────────┘
          固定             n
         “10”         (0〜46)
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
 Port#3│                              │  2.ポート#3にデータを出力する。このデータはレジスタR#nに格納される。
       └─┴─┴─┴─┴─┴─┴─┴─┘
2回目以降
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
 Port#3│                              │  2.以降はポート#3にデータを出力するだけでレジスタR#nにデータを書き込むことができる。
       └─┴─┴─┴─┴─┴─┴─┴─┘

図4.3 間接指定(非オートインクリメントモード)によるR#nのアクセス



(3)間接指定によるデータ書き込み(オートインクリメント・モード)
 間接指定法において、R#17に設定するレジスタ番号の上位2ピットを“OO”としておくと、ポート#3にデータを出力するたびにR#17の内容がインクリメントされます。この方法を用いると連続するコントロール・レジスタへのデータ書き込みが効率的に行えますから、スクリーンモードの変更時など、連続した多数のレジスタを一度に書き換える場合に役立ちます.

    MSB   7   6   5   4   3   2   1   0  LSB
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
   R#17│ 0│ 0│R5│R4│R3│R2│R1│R0│  1.R#17にレジスタ番号nをセットする。上位2ビットは“00”とする。
       └─┴─┴─┴─┴─┴─┴─┴─┘
       └───┴───────────┘
          固定             n
         “00”         (0〜46)
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
 Port#3│                              │  2.ポート#3にデータを出力する。このデータはレジスタR#nに格納される。
       └─┴─┴─┴─┴─┴─┴─┴─┘
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
 Port#3│                              │  3.次のポート#3にデータを出力すると、レジスタR#(n+1)に格納される。
       └─┴─┴─┴─┴─┴─┴─┴─┘
                      :                                                   :
                      :                                                   :

図4.4 間接指定(オートインクリメント・モード)によるR#nのアクセス



2.1.2 パレットの設定

 パレットを設定するには、次のようにR#16(パレット・レジスタ間接指定レジスタ)でパレット番号を指定し、ポート#2ヘデータを書き込みます。パレット・レジスタは9ビットの長さを持つため、まず赤の輝度と青の輝度、次に緑の輝度と,データは2回に分けて出力します。ポート#2へ2回データが送られると、R#16は自動的にインクリメントされます。この機能によって、全パレットの初期設定などを簡単に行うことができます。

    MSB   7   6   5   4   3   2   1   0  LSB
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
   R#16│ 0│ 0│ 0│ 0│R3│R2│R1│R0│  1.R#17にパレット番号nをセットする。
       └─┴─┴─┴─┴─┴─┴─┴─┘    上位4ビットは“0000”とする。
       └───────┴───────┘
              固定             n
            “0000”         (0〜15)
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
 Port#2│ 0│ 赤の輝度 │ 0│ 青の輝度 │  2.ポート#2に赤と青の輝度をを出力する。
       └─┴─┴─┴─┴─┴─┴─┴─┘
           └─────┘  └─────┘
                0〜7            0〜7
       ┌─┬─┬─┬─┬─┬─┬─┬─┐
 Port#2│ 0│ 0│ 0│ 0│ 0│ 緑の輝度 │  3.ポート#2に緑の輝度を出力する。
       └─┴─┴─┴─┴─┴─┴─┴─┘   ┌この時点でR#16はインクリメントされるので┐
                           └─────┘   │続けてポート#2にデータを出力することによ│
                                0〜7        └り、次のパレットの設定ができる。        ┘

図4.5 パレットの設定



2.1.3 ステータス・レジスタの読み出し

 ステータス・レジスタは読み出し専用のレジスタです.図4,6のようにR#15(ステータス・レジスタ間接指定レジスタ)にステータス・レジスタ番号を設定すると、ポート#1からその内容を読み出すことができます。ただしステータスレジスタをアクセスする前にはかならず割り込みを禁止し、そして目的の処理が終了した後でR#15の値を0にしてから割り込みを解除してください。

1.R#15にレジスタ番号nをセットする。
 上位4ビットは“0000”とする。
2.ポート#1からデータを読み出す。

図4.6 ステータス・レジスタのアクセス



 2.2 CPUからのVRAMアクセス

 VRAMの任意のアドレスをCPU側からアクセスする場合は,以下のような手順により行います。

?バンク切り換え
 VRAMの前半(OOOOOH〜0FFFFH)と拡張RAMは,MSX-VIDEOから見て同一のアドレスに存在しており、バンク切り換えによって両者を使い分けるようになっています。MSX2では拡張RAMは使用しませんから、常にVRAMのバンクを選択してください。バンクの切り換えはR#45のビット6によって行います。

R#45のビット6が側0"の場合VRAM、
“1”の場合拡張RAMが選択される。
O:VRAM
1:拡張RAM

図4.7 VRAM/拡彊RAMの選択


?VRAMのアドレス設定(上位3ビット)
 128KバイトのVRAMをアクセスするための17ビットのアドレス情報は、アドレス・カウンタ(A16〜A0)に設定されます。アドレス・カウンタの設定は、まず上位3ピットから行います。これにはR#14を用います。

R#14
R#14のビット2〜ビット0にアドレスカウンタの
上位3ビットをセットする。

図4.8 上位3ビットの設定


?VRAMのアドレス設定(下位14ビット)
 次に、アドレスの下位14ビットをポート#1に2回に分けて送り出します。?と?は、かならずこの順序で行わなくてはなりません。この時2回目に送るデータには、VRAMのデータを読み出したいのか/VRAMにデータを書き込みたいのか、という情報も付け加えておきます。


図4.9 下位14ビットとリード/ライト動作の設定



?VRAMの読み出し/書き込み
 アドレス・カウンタに値をセットし終えたら、ポート#0を通してデータの読み書きを行います。なおデータの読み出し/書き込みの指定は、前述のようにアドレス・カウンタのA13〜A8を設定する時に同時に行います。
 この時、データを1バイト読み書きすることに、アドレス・カウンタは自動的にインクリメントします。この機能を用いるとVRAMの連続したアドレスを簡単にアクセスできます。

VRAMのアクセスはポート#0を通して行う。
アドレスカウンタはオートインクリメントする。

図4.10 ポート#0を通したVRAMのアクセス